summaryrefslogtreecommitdiffstats
path: root/include/asm-sparc
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-sparc')
-rw-r--r--include/asm-sparc/a.out.h96
-rw-r--r--include/asm-sparc/asi.h117
-rw-r--r--include/asm-sparc/asi4m.h29
-rw-r--r--include/asm-sparc/asmmacro.h196
-rw-r--r--include/asm-sparc/atomic.h115
-rw-r--r--include/asm-sparc/atops.h22
-rw-r--r--include/asm-sparc/auxio.h70
-rw-r--r--include/asm-sparc/bitops.h482
-rw-r--r--include/asm-sparc/bsderrno.h94
-rw-r--r--include/asm-sparc/bugs.h47
-rw-r--r--include/asm-sparc/byteorder.h91
-rw-r--r--include/asm-sparc/cache.h123
-rw-r--r--include/asm-sparc/checksum.h163
-rw-r--r--include/asm-sparc/clock.h54
-rw-r--r--include/asm-sparc/contregs.h53
-rw-r--r--include/asm-sparc/cprefix.h15
-rw-r--r--include/asm-sparc/cypress.h79
-rw-r--r--include/asm-sparc/delay.h42
-rw-r--r--include/asm-sparc/dma.h207
-rw-r--r--include/asm-sparc/ecc.h122
-rw-r--r--include/asm-sparc/eeprom.h9
-rw-r--r--include/asm-sparc/elf.h34
-rw-r--r--include/asm-sparc/errno.h133
-rw-r--r--include/asm-sparc/fbio.h279
-rw-r--r--include/asm-sparc/fcntl.h60
-rw-r--r--include/asm-sparc/floppy.h359
-rw-r--r--include/asm-sparc/head.h143
-rw-r--r--include/asm-sparc/idprom.h36
-rw-r--r--include/asm-sparc/io.h110
-rw-r--r--include/asm-sparc/ioctl.h43
-rw-r--r--include/asm-sparc/ioctls.h128
-rw-r--r--include/asm-sparc/iommu.h120
-rw-r--r--include/asm-sparc/irq.h139
-rw-r--r--include/asm-sparc/kbio.h44
-rw-r--r--include/asm-sparc/kdebug.h79
-rw-r--r--include/asm-sparc/kgdb.h90
-rw-r--r--include/asm-sparc/machines.h69
-rw-r--r--include/asm-sparc/mbus.h100
-rw-r--r--include/asm-sparc/memerr.h32
-rw-r--r--include/asm-sparc/memreg.h52
-rw-r--r--include/asm-sparc/mman.h49
-rw-r--r--include/asm-sparc/mmu_context.h14
-rw-r--r--include/asm-sparc/mostek.h120
-rw-r--r--include/asm-sparc/mpmbox.h67
-rw-r--r--include/asm-sparc/msi.h31
-rw-r--r--include/asm-sparc/mxcc.h133
-rw-r--r--include/asm-sparc/openprom.h346
-rw-r--r--include/asm-sparc/openpromio.h70
-rw-r--r--include/asm-sparc/oplib.h297
-rw-r--r--include/asm-sparc/page.h180
-rw-r--r--include/asm-sparc/param.h3
-rw-r--r--include/asm-sparc/pconf.h25
-rw-r--r--include/asm-sparc/pgtable.h520
-rw-r--r--include/asm-sparc/pgtsrmmu.h268
-rw-r--r--include/asm-sparc/pgtsun4.h10
-rw-r--r--include/asm-sparc/pgtsun4c.h151
-rw-r--r--include/asm-sparc/posix_types.h111
-rw-r--r--include/asm-sparc/processor.h249
-rw-r--r--include/asm-sparc/psr.h133
-rw-r--r--include/asm-sparc/ptrace.h197
-rw-r--r--include/asm-sparc/reg.h79
-rw-r--r--include/asm-sparc/resource.h38
-rw-r--r--include/asm-sparc/ross.h174
-rw-r--r--include/asm-sparc/rtc.h27
-rw-r--r--include/asm-sparc/sbus.h101
-rw-r--r--include/asm-sparc/segment.h89
-rw-r--r--include/asm-sparc/semaphore.h42
-rw-r--r--include/asm-sparc/shmparam.h45
-rw-r--r--include/asm-sparc/sigcontext.h42
-rw-r--r--include/asm-sparc/signal.h176
-rw-r--r--include/asm-sparc/smp.h172
-rw-r--r--include/asm-sparc/smp_lock.h60
-rw-r--r--include/asm-sparc/smpprim.h54
-rw-r--r--include/asm-sparc/socket.h32
-rw-r--r--include/asm-sparc/sockios.h13
-rw-r--r--include/asm-sparc/solerrno.h132
-rw-r--r--include/asm-sparc/stat.h41
-rw-r--r--include/asm-sparc/statfs.h26
-rw-r--r--include/asm-sparc/string.h493
-rw-r--r--include/asm-sparc/svr4.h119
-rw-r--r--include/asm-sparc/swift.h94
-rw-r--r--include/asm-sparc/sysen.h15
-rw-r--r--include/asm-sparc/system.h311
-rw-r--r--include/asm-sparc/termbits.h208
-rw-r--r--include/asm-sparc/termios.h168
-rw-r--r--include/asm-sparc/timer.h82
-rw-r--r--include/asm-sparc/traps.h159
-rw-r--r--include/asm-sparc/tsunami.h60
-rw-r--r--include/asm-sparc/types.h50
-rw-r--r--include/asm-sparc/uaccess.h261
-rw-r--r--include/asm-sparc/ultra.h52
-rw-r--r--include/asm-sparc/unaligned.h19
-rw-r--r--include/asm-sparc/unistd.h475
-rw-r--r--include/asm-sparc/user.h60
-rw-r--r--include/asm-sparc/vac-ops.h192
-rw-r--r--include/asm-sparc/vaddrs.h55
-rw-r--r--include/asm-sparc/version.h1
-rw-r--r--include/asm-sparc/viking.h198
-rw-r--r--include/asm-sparc/vuid_event.h41
-rw-r--r--include/asm-sparc/wim.h56
-rw-r--r--include/asm-sparc/winmacro.h129
101 files changed, 9762 insertions, 2129 deletions
diff --git a/include/asm-sparc/a.out.h b/include/asm-sparc/a.out.h
new file mode 100644
index 000000000..6443e7612
--- /dev/null
+++ b/include/asm-sparc/a.out.h
@@ -0,0 +1,96 @@
+/* $Id: a.out.h,v 1.9 1996/05/29 13:44:54 ecd Exp $ */
+#ifndef __SPARC_A_OUT_H__
+#define __SPARC_A_OUT_H__
+
+#define SPARC_PGSIZE 0x2000 /* Thanks to the sun4 architecture... */
+#define SEGMENT_SIZE SPARC_PGSIZE /* whee... */
+
+struct exec {
+ unsigned char a_dynamic:1; /* A __DYNAMIC is in this image */
+ unsigned char a_toolversion:7;
+ unsigned char a_machtype;
+ unsigned short a_info;
+ unsigned long a_text; /* length of text, in bytes */
+ unsigned long a_data; /* length of data, in bytes */
+ unsigned long a_bss; /* length of bss, in bytes */
+ unsigned long a_syms; /* length of symbol table, in bytes */
+ unsigned long a_entry; /* where program begins */
+ unsigned long a_trsize;
+ unsigned long a_drsize;
+};
+
+/* Where in the file does the text information begin? */
+#define N_TXTOFF(x) (N_MAGIC(x) == ZMAGIC ? 0 : sizeof (struct exec))
+
+/* Where do the Symbols start? */
+#define N_SYMOFF(x) (N_TXTOFF(x) + (x).a_text + \
+ (x).a_data + (x).a_trsize + \
+ (x).a_drsize)
+
+/* Where does text segment go in memory after being loaded? */
+#define N_TXTADDR(x) (((N_MAGIC(x) == ZMAGIC) && \
+ ((x).a_entry < SPARC_PGSIZE)) ? \
+ 0 : SPARC_PGSIZE)
+
+/* And same for the data segment.. */
+#define N_DATADDR(x) (N_MAGIC(x)==OMAGIC ? \
+ (N_TXTADDR(x) + (x).a_text) \
+ : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
+
+#define N_TRSIZE(a) ((a).a_trsize)
+#define N_DRSIZE(a) ((a).a_drsize)
+#define N_SYMSIZE(a) ((a).a_syms)
+
+/*
+ * Sparc relocation types
+ */
+enum reloc_type
+{
+ RELOC_8,
+ RELOC_16,
+ RELOC_32, /* simplest relocs */
+ RELOC_DISP8,
+ RELOC_DISP16,
+ RELOC_DISP32, /* Disp's (pc-rel) */
+ RELOC_WDISP30,
+ RELOC_WDISP22, /* SR word disp's */
+ RELOC_HI22,
+ RELOC_22, /* SR 22-bit relocs */
+ RELOC_13,
+ RELOC_LO10, /* SR 13&10-bit relocs */
+ RELOC_SFA_BASE,
+ RELOC_SFA_OFF13, /* SR S.F.A. relocs */
+ RELOC_BASE10,
+ RELOC_BASE13,
+ RELOC_BASE22, /* base_relative pic */
+ RELOC_PC10,
+ RELOC_PC22, /* special pc-rel pic */
+ RELOC_JMP_TBL, /* jmp_tbl_rel in pic */
+ RELOC_SEGOFF16, /* ShLib offset-in-seg */
+ RELOC_GLOB_DAT,
+ RELOC_JMP_SLOT,
+ RELOC_RELATIVE /* rtld relocs */
+};
+
+/*
+ * Format of a relocation datum.
+ */
+struct relocation_info /* used when header.a_machtype == M_SPARC */
+{
+ unsigned long r_address; /* relocation addr */
+ unsigned int r_index:24; /* segment index or symbol index */
+ unsigned int r_extern:1; /* if F, r_index==SEG#; if T, SYM idx */
+ int r_pad:2; /* <unused> */
+ enum reloc_type r_type:5; /* type of relocation to perform */
+ long r_addend; /* addend for relocation value */
+};
+
+#define N_RELOCATION_INFO_DECLARED 1
+
+#ifdef __KERNEL__
+
+#define STACK_TOP TASK_SIZE
+
+#endif
+
+#endif /* __SPARC_A_OUT_H__ */
diff --git a/include/asm-sparc/asi.h b/include/asm-sparc/asi.h
index 4a404573d..f81ab33b9 100644
--- a/include/asm-sparc/asi.h
+++ b/include/asm-sparc/asi.h
@@ -1,43 +1,108 @@
+/* $Id: asi.h,v 1.16 1996/04/25 06:12:43 davem Exp $ */
#ifndef _SPARC_ASI_H
#define _SPARC_ASI_H
/* asi.h: Address Space Identifier values for the sparc.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * Pioneer work for sun4m: Paul Hatchman (paul@sfe.com.au)
+ * Joint edition for sun4c+sun4m: Pete A. Zaitcev <zaitcev@ipmce.su>
+ */
+
+/* The first batch are for the sun4c. */
+
+#define ASI_NULL1 0x00
+#define ASI_NULL2 0x01
+
+/* sun4c and sun4 control registers and mmu/vac ops */
+#define ASI_CONTROL 0x02
+#define ASI_SEGMAP 0x03
+#define ASI_PTE 0x04
+#define ASI_HWFLUSHSEG 0x05
+#define ASI_HWFLUSHPAGE 0x06
+#define ASI_REGMAP 0x06
+#define ASI_HWFLUSHCONTEXT 0x07
+
+#define ASI_USERTXT 0x08
+#define ASI_KERNELTXT 0x09
+#define ASI_USERDATA 0x0a
+#define ASI_KERNELDATA 0x0b
+
+/* VAC Cache flushing on sun4c and sun4 */
+#define ASI_FLUSHSEG 0x0c
+#define ASI_FLUSHPG 0x0d
+#define ASI_FLUSHCTX 0x0e
- Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
-*/
+/* SPARCstation-5: only 6 bits are decoded. */
+/* wo = Write Only, rw = Read Write; */
+/* ss = Single Size, as = All Sizes; */
+#define ASI_M_RES00 0x00 /* Don't touch... */
+#define ASI_M_UNA01 0x01 /* Same here... */
+#define ASI_M_MXCC 0x02 /* Access to TI VIKING MXCC registers */
+#define ASI_M_FLUSH_PROBE 0x03 /* Reference MMU Flush/Probe; rw, ss */
+#define ASI_M_MMUREGS 0x04 /* MMU Registers; rw, ss */
+#define ASI_M_TLBDIAG 0x05 /* MMU TLB only Diagnostics */
+#define ASI_M_DIAGS 0x06 /* Reference MMU Diagnostics */
+#define ASI_M_IODIAG 0x07 /* MMU I/O TLB only Diagnostics */
+#define ASI_M_USERTXT 0x08 /* Same as ASI_USERTXT; rw, as */
+#define ASI_M_KERNELTXT 0x09 /* Same as ASI_KERNELTXT; rw, as */
+#define ASI_M_USERDATA 0x0A /* Same as ASI_USERDATA; rw, as */
+#define ASI_M_KERNELDATA 0x0B /* Same as ASI_KERNELDATA; rw, as */
+#define ASI_M_TXTC_TAG 0x0C /* Instruction Cache Tag; rw, ss */
+#define ASI_M_TXTC_DATA 0x0D /* Instruction Cache Data; rw, ss */
+#define ASI_M_DATAC_TAG 0x0E /* Data Cache Tag; rw, ss */
+#define ASI_M_DATAC_DATA 0x0F /* Data Cache Data; rw, ss */
-/* These are sun4c, beware on other architectures. Although things should
- * be similar under regular sun4's.
+/* The following cache flushing ASIs work only with the 'sta'
+ * instruction. Results are unpredictable for 'swap' and 'ldstuba',
+ * so don't do it.
*/
-#include <linux/config.h>
-#ifdef CONFIG_SUN4M
-#include "asi4m.h"
-#else
+/* These ASI flushes affect external caches too. */
+#define ASI_M_FLUSH_PAGE 0x10 /* Flush I&D Cache Line (page); wo, ss */
+#define ASI_M_FLUSH_SEG 0x11 /* Flush I&D Cache Line (seg); wo, ss */
+#define ASI_M_FLUSH_REGION 0x12 /* Flush I&D Cache Line (region); wo, ss */
+#define ASI_M_FLUSH_CTX 0x13 /* Flush I&D Cache Line (context); wo, ss */
+#define ASI_M_FLUSH_USER 0x14 /* Flush I&D Cache Line (user); wo, ss */
-#define ASI_NULL1 0x0
-#define ASI_NULL2 0x1
+/* Block-copy operations are available only on certain V8 cpus. */
+#define ASI_M_BCOPY 0x17 /* Block copy */
-/* sun4c and sun4 control registers and mmu/vac ops */
-#define ASI_CONTROL 0x2
-#define ASI_SEGMAP 0x3
-#define ASI_PTE 0x4
-#define ASI_HWFLUSHSEG 0x5 /* These are to initiate hw flushes of the cache */
-#define ASI_HWFLUSHPAGE 0x6
-#define ASI_HWFLUSHCONTEXT 0x7
+/* These affect only the ICACHE and are Ross HyperSparc specific. */
+#define ASI_M_IFLUSH_PAGE 0x18 /* Flush I Cache Line (page); wo, ss */
+#define ASI_M_IFLUSH_SEG 0x19 /* Flush I Cache Line (seg); wo, ss */
+#define ASI_M_IFLUSH_REGION 0x1A /* Flush I Cache Line (region); wo, ss */
+#define ASI_M_IFLUSH_CTX 0x1B /* Flush I Cache Line (context); wo, ss */
+#define ASI_M_IFLUSH_USER 0x1C /* Flush I Cache Line (user); wo, ss */
+/* Block-fill operations are available on certain V8 cpus */
+#define ASI_M_BFILL 0x1F
-#define ASI_USERTXT 0x8
-#define ASI_KERNELTXT 0x9
-#define ASI_USERDATA 0xa
-#define ASI_KERNELDATA 0xb
+/* This allows direct access to main memory, actually 0x20 to 0x2f are
+ * the available ASI's for physical ram pass-through, but I don't have
+ * any idea what the other ones do....
+ */
-/* VAC Cache flushing on sun4c and sun4 */
+#define ASI_M_BYPASS 0x20 /* Reference MMU bypass; rw, as */
+#define ASI_M_FBMEM 0x29 /* Graphics card frame buffer access */
+#define ASI_M_VMEUS 0x2A /* VME user 16-bit access */
+#define ASI_M_VMEPS 0x2B /* VME priv 16-bit access */
+#define ASI_M_VMEUT 0x2C /* VME user 32-bit access */
+#define ASI_M_VMEPT 0x2D /* VME priv 32-bit access */
+#define ASI_M_SBUS 0x2E /* Direct SBus access */
+#define ASI_M_CTL 0x2F /* Control Space (ECC and MXCC are here) */
+
+
+/* This is ROSS HyperSparc only. */
+#define ASI_M_FLUSH_IWHOLE 0x31 /* Flush entire ICACHE; wo, ss */
+
+/* Tsunami/Viking i/d cache flash clear. */
+#define ASI_M_IC_FLCLEAR 0x36
+#define ASI_M_DC_FLCLEAR 0x37
-#define ASI_FLUSHSEG 0xc /* These are for "software" flushes of the cache */
-#define ASI_FLUSHPG 0xd
-#define ASI_FLUSHCTX 0xe
+#define ASI_M_DCDR 0x39 /* Data Cache Diagnostics Register rw, ss */
+#define ASI_M_ACTION 0x4c /* Breakpoint Action Register (GNU/Viking) */
-#endif /* CONFIG_SUN4M */
#endif /* _SPARC_ASI_H */
diff --git a/include/asm-sparc/asi4m.h b/include/asm-sparc/asi4m.h
deleted file mode 100644
index 68b1d21e7..000000000
--- a/include/asm-sparc/asi4m.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _SPARC_ASI4M_H
-#define _SPARC_ASI4M_H
-
-/* asi4m.h: Address Space Identifier values for sun4m
-
- Copyright (C) 1995 Paul Hatchman (paul@sfe.com.au)
-*/
-
-#define ASI_PTE 0x0
-
-#define ASI_NULL1 0x0
-#define ASI_NULL2 0x1
-#define ASI_CONTROL 0x4 /* hmm? */
-#define ASI_USERTXT 0x8 /* user text */
-#define ASI_KERNELTXT 0x9 /* kernel text */
-#define ASI_USERDATA 0xA /* user data */
-#define ASI_KERNELDATA 0xB /* kernel data */
-
-/* cache flushing */
-#define ASI_FLUSHPG 0x10
-#define ASI_FLUSHSEG 0x11
-#define ASI_FLUSHRGN 0x12
-#define ASI_FLUSHCTX 0x13
-
-/* MMU REGS */
-#define SRMMU_CTL 0x000
-#define SRMMU_CTP 0x100 /* set/get context pointer */
-#define SRMMU_CTX 0x200 /* get/set context */
-#endif _SPARC_ASI4M_H
diff --git a/include/asm-sparc/asmmacro.h b/include/asm-sparc/asmmacro.h
new file mode 100644
index 000000000..8bf441c27
--- /dev/null
+++ b/include/asm-sparc/asmmacro.h
@@ -0,0 +1,196 @@
+/* asmmacro.h: Assembler macros.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu)
+ */
+
+#ifndef _SPARC_ASMMACRO_H
+#define _SPARC_ASMMACRO_H
+
+/* #define SMP_DEBUG */
+
+#define GET_PROCESSOR_ID(reg) \
+ rd %tbr, %reg; \
+ srl %reg, 12, %reg; \
+ and %reg, 3, %reg;
+
+#define GET_PROCESSOR_MID(reg, tmp) \
+ GET_PROCESSOR_ID(reg) \
+ set C_LABEL(mid_xlate), %tmp; \
+ ldub [%tmp + %reg], %reg;
+
+#define GET_PROCESSOR_OFFSET(reg) \
+ rd %tbr, %reg; \
+ srl %reg, 10, %reg; \
+ and %reg, 0xc, %reg;
+
+#define PROCESSOR_OFFSET_TO_ID(reg) \
+ srl %reg, 2, %reg;
+
+#define PROCESSOR_ID_TO_OFFSET(reg) \
+ sll %reg, 2, %reg;
+
+/* All trap entry points _must_ begin with this macro or else you
+ * lose. It makes sure the kernel has a proper window so that
+ * c-code can be called.
+ */
+#ifndef SMP_DEBUG
+#define SAVE_ALL \
+ sethi %hi(trap_setup), %l4; \
+ jmpl %l4 + %lo(trap_setup), %l6; \
+ nop;
+#else
+#define SAVE_ALL \
+ GET_PROCESSOR_ID(l4); \
+ set C_LABEL(trap_log), %l5; \
+ sll %l4, 11, %l6; \
+ add %l5, %l6, %l5; \
+ set C_LABEL(trap_log_ent), %l6; \
+ sll %l4, 2, %l4; \
+ add %l6, %l4, %l6; \
+ ld [%l6], %l6; \
+ sll %l6, 3, %l6; \
+ st %l1, [%l5 + %l6]; \
+ add %l5, 4, %l5; \
+ st %l0, [%l5 + %l6]; \
+ set C_LABEL(trap_log_ent), %l5; \
+ add %l5, %l4, %l5; \
+ srl %l6, 3, %l6; \
+ add %l6, 1, %l6; \
+ and %l6, 255, %l6; \
+ st %l6, [%l5]; \
+ sethi %hi(trap_setup), %l4; \
+ jmpl %l4 + %lo(trap_setup), %l6; \
+ nop;
+#endif
+
+/* All traps low-level code here must end with this macro.
+ * For SMP configurations the ret_trap_entry routine will
+ * have to appropriate code to actually release the kernel
+ * entry lock.
+ */
+#define RESTORE_ALL b ret_trap_entry; clr %l6;
+
+#ifndef __SMP__
+
+#define ENTER_SYSCALL
+#define LEAVE_SYSCALL
+#define ENTER_IRQ
+#define LEAVE_IRQ
+
+#else
+
+#define INCREMENT_COUNTER(symbol, tmp1, tmp2) \
+ set C_LABEL(symbol), %tmp1; \
+ ld [%tmp1], %tmp2; \
+ add %tmp2, 1, %tmp2; \
+ st %tmp2, [%tmp1];
+
+#define DECREMENT_COUNTER(symbol, tmp1, tmp2) \
+ set C_LABEL(symbol), %tmp1; \
+ ld [%tmp1], %tmp2; \
+ sub %tmp2, 1, %tmp2; \
+ st %tmp2, [%tmp1];
+
+ /* This is so complicated I suggest you don't look at it. */
+#define ENTER_MASK(mask) \
+ GET_PROCESSOR_OFFSET(l4) \
+ set C_LABEL(smp_proc_in_lock), %l5; \
+ ld [%l5 + %l4], %l6; \
+ or %l6, mask, %l6; \
+ st %l6, [%l5 + %l4]; \
+1: \
+ set C_LABEL(kernel_flag), %l5; \
+ ldstub [%l5], %l6; \
+ cmp %l6, 0; \
+ be 3f; \
+ nop; \
+ set C_LABEL(active_kernel_processor), %l5; \
+ GET_PROCESSOR_ID(l4) \
+ ldub [%l5], %l6; \
+ cmp %l6, %l4; \
+ be 4f; \
+ nop; \
+2: \
+ GET_PROCESSOR_MID(l4, l5) \
+ set C_LABEL(sun4m_interrupts), %l5; \
+ ld [%l5], %l5; \
+ sll %l4, 12, %l4; \
+ add %l5, %l4, %l5; \
+ ld [%l5], %l4; \
+ sethi %hi(0x80000000), %l6; \
+ andcc %l6, %l4, %g0; \
+ be 5f; \
+ nop; \
+ st %l6, [%l5 + 4]; \
+ nop; nop; nop; \
+ ld [%l5], %g0; \
+ nop; nop; nop; \
+ or %l0, PSR_PIL, %l4; \
+ wr %l4, 0x0, %psr; \
+ nop; nop; nop; \
+ wr %l4, PSR_ET, %psr; \
+ nop; nop; nop; \
+ call C_LABEL(smp_message_irq); \
+ nop; \
+ wr %l0, 0x0, %psr; \
+ nop; nop; nop; \
+5: \
+ set C_LABEL(kernel_flag), %l5; \
+ ldub [%l5], %l6; \
+ cmp %l6, 0; \
+ bne 2b; \
+ nop; \
+ b 1b; \
+ nop; \
+3: \
+ GET_PROCESSOR_ID(l4) \
+ set C_LABEL(active_kernel_processor), %l5; \
+ stb %l4, [%l5]; \
+ GET_PROCESSOR_MID(l4, l5) \
+ set C_LABEL(irq_rcvreg), %l5; \
+ ld [%l5], %l5; \
+ st %l4, [%l5]; \
+4: \
+
+#define ENTER_SYSCALL \
+ ENTER_MASK(SMP_FROM_SYSCALL) \
+ INCREMENT_COUNTER(kernel_counter, l6, l5) \
+ INCREMENT_COUNTER(syscall_count, l6, l5)
+
+#define ENTER_IRQ \
+ ENTER_MASK(SMP_FROM_INT) \
+ INCREMENT_COUNTER(kernel_counter, l6, l5)
+
+#define LEAVE_MASK(mask) \
+ GET_PROCESSOR_OFFSET(l4) \
+ set C_LABEL(smp_proc_in_lock), %l5; \
+ ld [%l5 + %l4], %l6; \
+ andn %l6, mask, %l6; \
+ st %l6, [%l5 + %l4];
+
+#define LEAVE_SYSCALL \
+ LEAVE_MASK(SMP_FROM_SYSCALL) \
+ DECREMENT_COUNTER(syscall_count, l6, l5) \
+ set C_LABEL(kernel_counter), %l6; \
+ ld [%l6], %l5; \
+ subcc %l5, 1, %l5; \
+ st %l5, [%l6]; \
+ bne 1f; \
+ nop; \
+ set C_LABEL(active_kernel_processor), %l6; \
+ mov NO_PROC_ID, %l5; \
+ stb %l5, [%l6]; \
+ set C_LABEL(kernel_flag), %l6; \
+ stb %g0, [%l6]; \
+1:
+
+#define LEAVE_IRQ \
+ LEAVE_MASK(SMP_FROM_INT) \
+ INCREMENT_COUNTER(syscall_count, l6, l5)
+
+
+#define RESTORE_ALL_FASTIRQ b,a ret_irq_entry;
+
+#endif /* !(__SMP__) */
+
+#endif /* !(_SPARC_ASMMACRO_H) */
diff --git a/include/asm-sparc/atomic.h b/include/asm-sparc/atomic.h
new file mode 100644
index 000000000..3e46c262e
--- /dev/null
+++ b/include/asm-sparc/atomic.h
@@ -0,0 +1,115 @@
+/* atomic.h: These really suck for now.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __ARCH_SPARC_ATOMIC__
+#define __ARCH_SPARC_ATOMIC__
+
+typedef int atomic_t;
+
+#ifdef __KERNEL__
+#include <asm/system.h>
+#include <asm/psr.h>
+
+/*
+ * Make sure gcc doesn't try to be clever and move things around
+ * on us. We need to use _exactly_ the address the user gave us,
+ * not some alias that contains the same information.
+ */
+#define __atomic_fool_gcc(x) ((struct { int a[100]; } *)x)
+
+static __inline__ void atomic_add(atomic_t i, atomic_t *v)
+{
+ __asm__ __volatile__("
+ rd %%psr, %%g2
+ andcc %%g2, %2, %%g0
+ be,a 1f
+ wr %%g2, %2, %%psr
+1: ld [%0], %%g3
+ add %%g3, %1, %%g3
+ andcc %%g2, %2, %%g0
+ st %%g3, [%0]
+ be,a 1f
+ wr %%g2, 0x0, %%psr
+1: nop; nop;
+ "
+ : : "r" (__atomic_fool_gcc(v)), "r" (i), "i" (PSR_PIL)
+ : "g2", "g3");
+}
+
+static __inline__ void atomic_sub(atomic_t i, atomic_t *v)
+{
+ __asm__ __volatile__("
+ rd %%psr, %%g2
+ andcc %%g2, %2, %%g0
+ be,a 1f
+ wr %%g2, %2, %%psr
+1: ld [%0], %%g3
+ sub %%g3, %1, %%g3
+ andcc %%g2, %2, %%g0
+ st %%g3, [%0]
+ be,a 1f
+ wr %%g2, 0x0, %%psr
+1: nop; nop;
+ "
+ : : "r" (__atomic_fool_gcc(v)), "r" (i), "i" (PSR_PIL)
+ : "g2", "g3");
+}
+
+static __inline__ int atomic_add_return(atomic_t i, atomic_t *v)
+{
+ __asm__ __volatile__("
+ rd %%psr, %%g2
+ andcc %%g2, %3, %%g0
+ be,a 1f
+ wr %%g2, %3, %%psr
+1: ld [%1], %%g3
+ add %%g3, %2, %0
+ andcc %%g2, %3, %%g0
+ st %0, [%1]
+ be,a 1f
+ wr %%g2, 0x0, %%psr
+1: nop; nop;
+ "
+ : "=&r" (i)
+ : "r" (__atomic_fool_gcc(v)), "0" (i), "i" (PSR_PIL)
+ : "g2", "g3");
+
+ return i;
+}
+
+static __inline__ int atomic_sub_return(atomic_t i, atomic_t *v)
+{
+ __asm__ __volatile__("
+ rd %%psr, %%g2
+ andcc %%g2, %3, %%g0
+ be,a 1f
+ wr %%g2, %3, %%psr
+1: ld [%1], %%g3
+ sub %%g3, %2, %0
+ andcc %%g2, %3, %%g0
+ st %0, [%1]
+ be,a 1f
+ wr %%g2, 0x0, %%psr
+1: nop; nop;
+ "
+ : "=&r" (i)
+ : "r" (__atomic_fool_gcc(v)), "0" (i), "i" (PSR_PIL)
+ : "g2", "g3");
+
+ return i;
+}
+
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+#define atomic_inc(v) atomic_add(1,(v))
+#define atomic_dec(v) atomic_sub(1,(v))
+
+#endif /* !(__KERNEL__) */
+
+#endif /* !(__ARCH_SPARC_ATOMIC__) */
diff --git a/include/asm-sparc/atops.h b/include/asm-sparc/atops.h
new file mode 100644
index 000000000..0bb70752d
--- /dev/null
+++ b/include/asm-sparc/atops.h
@@ -0,0 +1,22 @@
+/* atops.h: Atomic SPARC operations.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_ATOPS_H
+#define _SPARC_ATOPS_H
+
+#ifdef __SMP__
+
+extern __inline__ __volatile__ unsigned char ldstub(volatile unsigned char *lock)
+{
+ volatile unsigned char retval;
+
+ __asm__ __volatile__("ldstub [%1], %0\n\t" :
+ "=&r" (retval) :
+ "r" (lock));
+ return retval;
+}
+
+#endif
+
+#endif
diff --git a/include/asm-sparc/auxio.h b/include/asm-sparc/auxio.h
new file mode 100644
index 000000000..be4107408
--- /dev/null
+++ b/include/asm-sparc/auxio.h
@@ -0,0 +1,70 @@
+/* $Id: auxio.h,v 1.14 1996/10/31 06:29:10 davem Exp $
+ * auxio.h: Definitions and code for the Auxiliary I/O register.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_AUXIO_H
+#define _SPARC_AUXIO_H
+
+#include <asm/system.h>
+#include <asm/vaddrs.h>
+
+extern unsigned char *auxio_register;
+
+/* This register is an unsigned char in IO space. It does two things.
+ * First, it is used to control the front panel LED light on machines
+ * that have it (good for testing entry points to trap handlers and irq's)
+ * Secondly, it controls various floppy drive parameters.
+ */
+#define AUXIO_ORMEIN 0xf0 /* All writes must set these bits. */
+#define AUXIO_ORMEIN4M 0xc0 /* sun4m - All writes must set these bits. */
+#define AUXIO_FLPY_DENS 0x20 /* Floppy density, high if set. Read only. */
+#define AUXIO_FLPY_DCHG 0x10 /* A disk change occurred. Read only. */
+#define AUXIO_EDGE_ON 0x10 /* sun4m - On means Jumper block is in. */
+#define AUXIO_FLPY_DSEL 0x08 /* Drive select/start-motor. Write only. */
+#define AUXIO_LINK_TEST 0x08 /* sun4m - On means TPE Carrier detect. */
+
+/* Set the following to one, then zero, after doing a pseudo DMA transfer. */
+#define AUXIO_FLPY_TCNT 0x04 /* Floppy terminal count. Write only. */
+
+/* Set the following to zero to eject the floppy. */
+#define AUXIO_FLPY_EJCT 0x02 /* Eject floppy disk. Write only. */
+#define AUXIO_LED 0x01 /* On if set, off if unset. Read/Write */
+
+#define AUXREG ((volatile unsigned char *)(auxio_register))
+
+/* These are available on sun4c */
+#define TURN_ON_LED if (AUXREG) *AUXREG = (*AUXREG | AUXIO_ORMEIN | AUXIO_LED)
+#define TURN_OFF_LED if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) & (~AUXIO_LED))
+#define FLIP_LED if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) ^ AUXIO_LED)
+#define FLPY_MOTORON if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) | AUXIO_FLPY_DSEL)
+#define FLPY_MOTOROFF if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) & (~AUXIO_FLPY_DSEL))
+#define FLPY_TCNTON if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) | AUXIO_FLPY_TCNT)
+#define FLPY_TCNTOFF if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) & (~AUXIO_FLPY_TCNT))
+
+#ifndef __ASSEMBLY__
+extern __inline__ void set_auxio(unsigned char bits_on, unsigned char bits_off)
+{
+ unsigned char regval;
+ unsigned long flags;
+
+ save_flags(flags); cli();
+
+ switch(sparc_cpu_model) {
+ case sun4c:
+ regval = *AUXREG;
+ *AUXREG = ((regval | bits_on) & ~bits_off) | AUXIO_ORMEIN;
+ break;
+ case sun4m:
+ regval = *AUXREG;
+ *AUXREG = ((regval | bits_on) & ~bits_off) | AUXIO_ORMEIN4M;
+ break;
+ default:
+ panic("Can't set AUXIO register on this machine.");
+ };
+
+ restore_flags(flags);
+}
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_SPARC_AUXIO_H) */
diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h
index 241e5e8c1..85d86c6dd 100644
--- a/include/asm-sparc/bitops.h
+++ b/include/asm-sparc/bitops.h
@@ -1,121 +1,202 @@
+/* $Id: bitops.h,v 1.36 1996/09/29 22:57:21 davem Exp $
+ * bitops.h: Bit string operations on the Sparc.
+ *
+ * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright 1996 Eddie C. Dost (ecd@skynet.be)
+ */
+
#ifndef _SPARC_BITOPS_H
#define _SPARC_BITOPS_H
-/*
- * Copyright 1994, David S. Miller (davem@caip.rutgers.edu).
- */
+#include <linux/kernel.h>
+#ifndef __KERNEL__
-/* Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0'
- * is in the highest of the four bytes and bit '31' is the high bit
- * within the first byte. Sparc is BIG-Endian. Unless noted otherwise
- * all bit-ops return 0 if bit was previously clear and != 0 otherwise.
+/* User mode bitops, defined here for convenience. Note: these are not
+ * atomic, so packages like nthreads should do some locking around these
+ * themself.
*/
-/* For now, the sun4c implementation will disable and enable traps
- * in order to insure atomicity. Things will have to be different
- * for sun4m (ie. SMP) no doubt.
- */
+#define __SMPVOL
-extern __inline__ unsigned int set_bit(unsigned int nr, void *addr)
+extern __inline__ unsigned long set_bit(unsigned long nr, void *addr)
{
- register unsigned long retval, tmp, mask, psr;
-
- __asm__ __volatile__("or %%g0, 0x1, %3\n\t" /* produce the mask */
- "sll %3, %4, %3\n\t"
- "rd %%psr, %5\n\t" /* read the psr */
- "wr %5, 0x20, %%psr\n\t" /* traps disabled */
- "ld [%1], %2\n\t" /* critical section */
- "and %3, %2, %0\n\t"
- "or %3, %2, %2\n\t"
- "st %2, [%1]\n\t"
- "wr %5, 0x0, %%psr\n\t" : /* re-enable traps */
- "=r" (retval) :
- "r" (addr), "r" (tmp=0), "r" (mask=0),
- "r" (nr), "r" (psr=0));
-
- return retval; /* confuse gcc :-) */
-
+ int mask;
+ unsigned long *ADDR = (unsigned long *) addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ __asm__ __volatile__("
+ ld [%0], %%g3
+ or %%g3, %2, %%g2
+ st %%g2, [%0]
+ and %%g3, %2, %0
+ "
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g2", "g3");
+
+ return (unsigned long) ADDR;
}
-extern __inline__ unsigned int clear_bit(unsigned int nr, void *addr)
+extern __inline__ unsigned long clear_bit(unsigned long nr, void *addr)
{
- register unsigned long retval, tmp, mask, psr;
-
- __asm__ __volatile__("or %%g0, 0x1, %3\n\t"
- "sll %3, %4, %3\n\t"
- "rd %%psr, %5\n\t"
- "wr %5, 0x20, %%psr\n\t" /* disable traps */
- "ld [%1], %2\n\t"
- "and %2, %3, %0\n\t" /* get old bit */
- "andn %2, %3, %2\n\t" /* set new val */
- "st %2, [%1]\n\t"
- "wr %5, 0x0, %%psr\n\t" : /* enable traps */
- "=r" (retval) :
- "r" (addr), "r" (tmp=0), "r" (mask=0),
- "r" (nr), "r" (psr=0));
-
- return retval; /* confuse gcc ;-) */
-
+ int mask;
+ unsigned long *ADDR = (unsigned long *) addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ __asm__ __volatile__("
+ ld [%0], %%g3
+ andn %%g3, %2, %%g2
+ st %%g2, [%0]
+ and %%g3, %2, %0
+ "
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g2", "g3");
+
+ return (unsigned long) ADDR;
}
-extern __inline__ unsigned int change_bit(unsigned int nr, void *addr)
+extern __inline__ unsigned long change_bit(unsigned long nr, void *addr)
{
- register unsigned long retval, tmp, mask, psr;
+ int mask;
+ unsigned long *ADDR = (unsigned long *) addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ __asm__ __volatile__("
+ ld [%0], %%g3
+ xor %%g3, %2, %%g2
+ st %%g2, [%0]
+ and %%g3, %2, %0
+ "
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g2", "g3");
+
+ return (unsigned long) ADDR;
+}
- __asm__ __volatile__("or %%g0, 0x1, %3\n\t"
- "sll %3, %4, %3\n\t"
- "rd %%psr, %5\n\t"
- "wr %5, 0x20, %%psr\n\t" /* disable traps */
- "ld [%1], %2\n\t"
- "and %3, %2, %0\n\t" /* get old bit val */
- "xor %3, %2, %2\n\t" /* set new val */
- "st %2, [%1]\n\t"
- "wr %5, 0x0, %%psr\n\t" : /* enable traps */
- "=r" (retval) :
- "r" (addr), "r" (tmp=0), "r" (mask=0),
- "r" (nr), "r" (psr=0));
+#else /* __KERNEL__ */
- return retval; /* confuse gcc ;-) */
+#include <asm/system.h>
-}
+#ifdef __SMP__
+#define __SMPVOL volatile
+#else
+#define __SMPVOL
+#endif
-/* The following routine need not be atomic. */
+/* Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0'
+ * is in the highest of the four bytes and bit '31' is the high bit
+ * within the first byte. Sparc is BIG-Endian. Unless noted otherwise
+ * all bit-ops return 0 if bit was previously clear and != 0 otherwise.
+ */
-extern __inline__ unsigned int test_bit(int nr, void *addr)
+extern __inline__ unsigned long set_bit(unsigned long nr, __SMPVOL void *addr)
{
- register unsigned long retval, tmp;
-
- __asm__ __volatile__("ld [%1], %2\n\t"
- "or %%g0, 0x1, %0\n\t"
- "sll %0, %3, %0\n\t"
- "and %0, %2, %0\n\t" :
- "=r" (retval) :
- "r" (addr), "r" (tmp=0),
- "r" (nr));
+ int mask;
+ unsigned long *ADDR = (unsigned long *) addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ __asm__ __volatile__("
+ rd %%psr, %%g3
+ andcc %%g3, %3, %%g0
+ be,a 1f
+ wr %%g3, %3, %%psr
+1: ld [%0], %%g4
+ or %%g4, %2, %%g2
+ andcc %%g3, %3, %%g0
+ st %%g2, [%0]
+ be,a 1f
+ wr %%g3, 0x0, %%psr
+1: nop
+ and %%g4, %2, %0
+ "
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask), "i" (PSR_PIL)
+ : "g2", "g3", "g4");
+
+ return (unsigned long) ADDR;
+}
- return retval; /* confuse gcc :> */
+extern __inline__ unsigned long clear_bit(unsigned long nr, __SMPVOL void *addr)
+{
+ int mask;
+ unsigned long *ADDR = (unsigned long *) addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ __asm__ __volatile__("
+ rd %%psr, %%g3
+ andcc %%g3, %3, %%g0
+ be,a 1f
+ wr %%g3, %3, %%psr
+1: ld [%0], %%g4
+ andn %%g4, %2, %%g2
+ andcc %%g3, %3, %%g0
+ st %%g2, [%0]
+ be,a 1f
+ wr %%g3, 0x0, %%psr
+1: nop
+ and %%g4, %2, %0
+ "
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask), "i" (PSR_PIL)
+ : "g2", "g3", "g4");
+
+ return (unsigned long) ADDR;
+}
+extern __inline__ unsigned long change_bit(unsigned long nr, __SMPVOL void *addr)
+{
+ int mask;
+ unsigned long *ADDR = (unsigned long *) addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ __asm__ __volatile__("
+ rd %%psr, %%g3
+ andcc %%g3, %3, %%g0
+ be,a 1f
+ wr %%g3, %3, %%psr
+1: ld [%0], %%g4
+ xor %%g4, %2, %%g2
+ andcc %%g3, %3, %%g0
+ st %%g2, [%0]
+ be,a 1f
+ wr %%g3, 0x0, %%psr
+1: nop
+ and %%g4, %2, %0
+ "
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask), "i" (PSR_PIL)
+ : "g2", "g3", "g4");
+
+ return (unsigned long) ADDR;
}
-/* There has to be a faster way to do this, sigh... */
+#endif /* __KERNEL__ */
-extern __inline__ unsigned long ffz(unsigned long word)
+/* The following routine need not be atomic. */
+extern __inline__ unsigned long test_bit(int nr, __const__ __SMPVOL void *addr)
{
- register unsigned long cnt, tmp, tmp2;
-
- cnt = 0;
+ return 1UL & (((__const__ unsigned int *) addr)[nr >> 5] >> (nr & 31));
+}
- __asm__("or %%g0, %3, %2\n\t"
- "1: and %2, 0x1, %1\n\t"
- "srl %2, 0x1, %2\n\t"
- "cmp %1, 0\n\t"
- "bne,a 1b\n\t"
- "add %0, 0x1, %0\n\t" :
- "=r" (cnt) :
- "r" (tmp=0), "r" (tmp2=0), "r" (word));
+/* The easy/cheese version for now. */
+extern __inline__ unsigned long ffz(unsigned long word)
+{
+ unsigned long result = 0;
- return cnt;
+ while(word & 1) {
+ result++;
+ word >>= 1;
+ }
+ return result;
}
/* find_next_zero_bit() finds the first zero bit in a bit string of length
@@ -125,40 +206,38 @@ extern __inline__ unsigned long ffz(unsigned long word)
extern __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
{
- unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
- unsigned long result = offset & ~31UL;
- unsigned long tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= 31UL;
- if (offset)
- {
- tmp = *(p++);
- tmp |= ~0UL >> (32-offset);
- if (size < 32)
- goto found_first;
- if (~tmp)
- goto found_middle;
- size -= 32;
- result += 32;
- }
- while (size & ~32UL)
- {
- if (~(tmp = *(p++)))
- goto found_middle;
- result += 32;
- size -= 32;
- }
- if (!size)
- return result;
- tmp = *p;
+ unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+ unsigned long result = offset & ~31UL;
+ unsigned long tmp;
+
+ if (offset >= size)
+ return size;
+ size -= result;
+ offset &= 31UL;
+ if (offset) {
+ tmp = *(p++);
+ tmp |= ~0UL >> (32-offset);
+ if (size < 32)
+ goto found_first;
+ if (~tmp)
+ goto found_middle;
+ size -= 32;
+ result += 32;
+ }
+ while (size & ~31UL) {
+ if (~(tmp = *(p++)))
+ goto found_middle;
+ result += 32;
+ size -= 32;
+ }
+ if (!size)
+ return result;
+ tmp = *p;
found_first:
- tmp |= ~0UL << size;
+ tmp |= ~0UL << size;
found_middle:
- return result + ffz(tmp);
+ return result + ffz(tmp);
}
/* Linus sez that gcc can optimize the following correctly, we'll see if this
@@ -168,6 +247,169 @@ found_middle:
#define find_first_zero_bit(addr, size) \
find_next_zero_bit((addr), (size), 0)
+#ifndef __KERNEL__
+
+extern __inline__ int __ext2_set_bit(int nr, void *addr)
+{
+ int mask;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ __asm__ __volatile__("
+ ldub [%0], %%g3
+ or %%g3, %2, %%g2
+ stb %%g2, [%0]
+ and %%g3, %2, %0
+ "
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g2", "g3");
+
+ return (int) ADDR;
+}
+
+extern __inline__ int __ext2_clear_bit(int nr, void *addr)
+{
+ int mask;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ __asm__ __volatile__("
+ ldub [%0], %%g3
+ andn %%g3, %2, %%g2
+ stb %%g2, [%0]
+ and %%g3, %2, %0
+ "
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g2", "g3");
+
+ return (int) ADDR;
+}
+
+#else /* __KERNEL__ */
+
+/* Now for the ext2 filesystem bit operations and helper routines. */
+
+extern __inline__ int __ext2_set_bit(int nr,void * addr)
+{
+ int mask;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ __asm__ __volatile__("
+ rd %%psr, %%g3
+ andcc %%g3, %3, %%g0
+ be,a 1f
+ wr %%g3, %3, %%psr
+1: ldub [%0], %%g4
+ or %%g4, %2, %%g2
+ andcc %%g3, %3, %%g0
+ stb %%g2, [%0]
+ be,a 1f
+ wr %%g3, 0x0, %%psr
+1: nop
+ and %%g4, %2, %0
+ "
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask), "i" (PSR_PIL)
+ : "g2", "g3", "g4");
+
+ return (int) ADDR;
+}
+
+extern __inline__ int __ext2_clear_bit(int nr, void * addr)
+{
+ int mask;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ __asm__ __volatile__("
+ rd %%psr, %%g3
+ andcc %%g3, %3, %%g0
+ be,a 1f
+ wr %%g3, %3, %%psr
+1: ldub [%0], %%g4
+ andn %%g4, %2, %%g2
+ andcc %%g3, %3, %%g0
+ stb %%g2, [%0]
+ be,a 1f
+ wr %%g3, 0x0, %%psr
+1: nop
+ and %%g4, %2, %0
+ "
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask), "i" (PSR_PIL)
+ : "g2", "g3", "g4");
+
+ return (int) ADDR;
+}
+
+#endif /* __KERNEL__ */
+
+extern __inline__ int __ext2_test_bit(int nr, __const__ void * addr)
+{
+ int mask;
+ __const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ return ((mask & *ADDR) != 0);
+}
+
+extern __inline__ unsigned short __swab16(unsigned short value)
+{
+ return ((value >> 8) | (value << 8));
+}
+
+extern __inline__ unsigned long __swab32(unsigned long value)
+{
+ return ((value >> 24) | ((value >> 8) & 0xff00) |
+ ((value << 8) & 0xff0000) | (value << 24));
+}
+
+#define __ext2_find_first_zero_bit(addr, size) \
+ __ext2_find_next_zero_bit((addr), (size), 0)
+
+extern __inline__ unsigned long __ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+ unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+ unsigned long result = offset & ~31UL;
+ unsigned long tmp;
+
+ if (offset >= size)
+ return size;
+ size -= result;
+ offset &= 31UL;
+ if(offset) {
+ tmp = *(p++);
+ tmp |= __swab32(~0UL >> (32-offset));
+ if(size < 32)
+ goto found_first;
+ if(~tmp)
+ goto found_middle;
+ size -= 32;
+ result += 32;
+ }
+ while(size & ~31UL) {
+ if(~(tmp = *(p++)))
+ goto found_middle;
+ result += 32;
+ size -= 32;
+ }
+ if(!size)
+ return result;
+ tmp = *p;
+
+found_first:
+ return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+ return result + ffz(__swab32(tmp));
+}
#endif /* defined(_SPARC_BITOPS_H) */
diff --git a/include/asm-sparc/bsderrno.h b/include/asm-sparc/bsderrno.h
new file mode 100644
index 000000000..54a75be43
--- /dev/null
+++ b/include/asm-sparc/bsderrno.h
@@ -0,0 +1,94 @@
+/* $Id: bsderrno.h,v 1.3 1996/04/25 06:12:47 davem Exp $
+ * bsderrno.h: Error numbers for NetBSD binary compatibility
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_BSDERRNO_H
+#define _SPARC_BSDERRNO_H
+
+#define BSD_EPERM 1 /* Operation not permitted */
+#define BSD_ENOENT 2 /* No such file or directory */
+#define BSD_ESRCH 3 /* No such process */
+#define BSD_EINTR 4 /* Interrupted system call */
+#define BSD_EIO 5 /* Input/output error */
+#define BSD_ENXIO 6 /* Device not configured */
+#define BSD_E2BIG 7 /* Argument list too long */
+#define BSD_ENOEXEC 8 /* Exec format error */
+#define BSD_EBADF 9 /* Bad file descriptor */
+#define BSD_ECHILD 10 /* No child processes */
+#define BSD_EDEADLK 11 /* Resource deadlock avoided */
+#define BSD_ENOMEM 12 /* Cannot allocate memory */
+#define BSD_EACCES 13 /* Permission denied */
+#define BSD_EFAULT 14 /* Bad address */
+#define BSD_ENOTBLK 15 /* Block device required */
+#define BSD_EBUSY 16 /* Device busy */
+#define BSD_EEXIST 17 /* File exists */
+#define BSD_EXDEV 18 /* Cross-device link */
+#define BSD_ENODEV 19 /* Operation not supported by device */
+#define BSD_ENOTDIR 20 /* Not a directory */
+#define BSD_EISDIR 21 /* Is a directory */
+#define BSD_EINVAL 22 /* Invalid argument */
+#define BSD_ENFILE 23 /* Too many open files in system */
+#define BSD_EMFILE 24 /* Too many open files */
+#define BSD_ENOTTY 25 /* Inappropriate ioctl for device */
+#define BSD_ETXTBSY 26 /* Text file busy */
+#define BSD_EFBIG 27 /* File too large */
+#define BSD_ENOSPC 28 /* No space left on device */
+#define BSD_ESPIPE 29 /* Illegal seek */
+#define BSD_EROFS 30 /* Read-only file system */
+#define BSD_EMLINK 31 /* Too many links */
+#define BSD_EPIPE 32 /* Broken pipe */
+#define BSD_EDOM 33 /* Numerical argument out of domain */
+#define BSD_ERANGE 34 /* Result too large */
+#define BSD_EAGAIN 35 /* Resource temporarily unavailable */
+#define BSD_EWOULDBLOCK EAGAIN /* Operation would block */
+#define BSD_EINPROGRESS 36 /* Operation now in progress */
+#define BSD_EALREADY 37 /* Operation already in progress */
+#define BSD_ENOTSOCK 38 /* Socket operation on non-socket */
+#define BSD_EDESTADDRREQ 39 /* Destination address required */
+#define BSD_EMSGSIZE 40 /* Message too long */
+#define BSD_EPROTOTYPE 41 /* Protocol wrong type for socket */
+#define BSD_ENOPROTOOPT 42 /* Protocol not available */
+#define BSD_EPROTONOSUPPORT 43 /* Protocol not supported */
+#define BSD_ESOCKTNOSUPPORT 44 /* Socket type not supported */
+#define BSD_EOPNOTSUPP 45 /* Operation not supported */
+#define BSD_EPFNOSUPPORT 46 /* Protocol family not supported */
+#define BSD_EAFNOSUPPORT 47 /* Address family not supported by protocol family */
+#define BSD_EADDRINUSE 48 /* Address already in use */
+#define BSD_EADDRNOTAVAIL 49 /* Can't assign requested address */
+#define BSD_ENETDOWN 50 /* Network is down */
+#define BSD_ENETUNREACH 51 /* Network is unreachable */
+#define BSD_ENETRESET 52 /* Network dropped connection on reset */
+#define BSD_ECONNABORTED 53 /* Software caused connection abort */
+#define BSD_ECONNRESET 54 /* Connection reset by peer */
+#define BSD_ENOBUFS 55 /* No buffer space available */
+#define BSD_EISCONN 56 /* Socket is already connected */
+#define BSD_ENOTCONN 57 /* Socket is not connected */
+#define BSD_ESHUTDOWN 58 /* Can't send after socket shutdown */
+#define BSD_ETOOMANYREFS 59 /* Too many references: can't splice */
+#define BSD_ETIMEDOUT 60 /* Operation timed out */
+#define BSD_ECONNREFUSED 61 /* Connection refused */
+#define BSD_ELOOP 62 /* Too many levels of symbolic links */
+#define BSD_ENAMETOOLONG 63 /* File name too long */
+#define BSD_EHOSTDOWN 64 /* Host is down */
+#define BSD_EHOSTUNREACH 65 /* No route to host */
+#define BSD_ENOTEMPTY 66 /* Directory not empty */
+#define BSD_EPROCLIM 67 /* Too many processes */
+#define BSD_EUSERS 68 /* Too many users */
+#define BSD_EDQUOT 69 /* Disc quota exceeded */
+#define BSD_ESTALE 70 /* Stale NFS file handle */
+#define BSD_EREMOTE 71 /* Too many levels of remote in path */
+#define BSD_EBADRPC 72 /* RPC struct is bad */
+#define BSD_ERPCMISMATCH 73 /* RPC version wrong */
+#define BSD_EPROGUNAVAIL 74 /* RPC prog. not avail */
+#define BSD_EPROGMISMATCH 75 /* Program version wrong */
+#define BSD_EPROCUNAVAIL 76 /* Bad procedure for program */
+#define BSD_ENOLCK 77 /* No locks available */
+#define BSD_ENOSYS 78 /* Function not implemented */
+#define BSD_EFTYPE 79 /* Inappropriate file type or format */
+#define BSD_EAUTH 80 /* Authentication error */
+#define BSD_ENEEDAUTH 81 /* Need authenticator */
+#define BSD_ELAST 81 /* Must be equal largest errno */
+
+#endif /* !(_SPARC_BSDERRNO_H) */
diff --git a/include/asm-sparc/bugs.h b/include/asm-sparc/bugs.h
index 55f5434ad..534ce05ff 100644
--- a/include/asm-sparc/bugs.h
+++ b/include/asm-sparc/bugs.h
@@ -1,48 +1,7 @@
-/* include/asm-sparc/bugs.h: Sparc probes for various bugs.
+/* $Id: bugs.h,v 1.5 1995/11/25 02:31:18 davem Exp $
+ * include/asm-sparc/bugs.h: Sparc probes for various bugs.
*
* Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
*/
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- * void check_bugs(void);
- */
-
-#define CONFIG_BUGSPARC
-
-#include <asm/openprom.h>
-
-extern struct linux_romvec *romvec;
-extern int tbase_needs_unmapping; /* We do the bug workaround in pagetables.c */
-
-static void check_mmu(void)
-{
- register struct linux_romvec *lvec;
- register int root_node;
- unsigned int present;
-
- lvec = romvec;
-
- root_node = (*(romvec->pv_nodeops->no_nextnode))(0);
- tbase_needs_unmapping=0;
-
- present = 0;
- (*(romvec->pv_nodeops->no_getprop))(root_node, "buserr-type",
- (char *) &present);
- if(present == 1)
- {
- tbase_needs_unmapping=1;
- printk("MMU bug found: not allowing trapbase to be cached\n");
- }
-
- return;
-}
-
-
-static void
-check_bugs(void)
-{
- check_mmu();
-}
+static void check_bugs(void) { }
diff --git a/include/asm-sparc/byteorder.h b/include/asm-sparc/byteorder.h
index b734cf8a6..4f1cd2e65 100644
--- a/include/asm-sparc/byteorder.h
+++ b/include/asm-sparc/byteorder.h
@@ -1,85 +1,24 @@
+/* $Id: byteorder.h,v 1.9 1996/08/30 05:21:34 davem Exp $ */
#ifndef _SPARC_BYTEORDER_H
#define _SPARC_BYTEORDER_H
-#undef ntohl
-#undef ntohs
-#undef htonl
-#undef htons
+#define ntohl(x) x
+#define ntohs(x) x
+#define htonl(x) x
+#define htons(x) x
-#define BIG_ENDIAN
-#define BIG_ENDIAN_BITFIELD
+/* Some programs depend upon these being around. */
+#define __constant_ntohl(x) x
+#define __constant_ntohs(x) x
+#define __constant_htonl(x) x
+#define __constant_htons(x) x
-extern unsigned long int ntohl(unsigned long int);
-extern unsigned short int ntohs(unsigned short int);
-extern unsigned long int htonl(unsigned long int);
-extern unsigned short int htons(unsigned short int);
-
-extern unsigned long int __ntohl(unsigned long int);
-extern unsigned short int __ntohs(unsigned short int);
-extern unsigned long int __constant_ntohl(unsigned long int);
-extern unsigned short int __constant_ntohs(unsigned short int);
-
-/*
- * The constant and non-constant versions here are the same.
- * Maybe I'll come up with an alpha-optimized routine for the
- * non-constant ones (the constant ones don't need it: gcc
- * will optimize it to the correct constant)
- */
-
-extern __inline__ unsigned long int
-__ntohl(unsigned long int x)
-{
- return (((x & 0x000000ffU) << 24) |
- ((x & 0x0000ff00U) << 8) |
- ((x & 0x00ff0000U) >> 8) |
- ((x & 0xff000000U) >> 24));
-}
-
-extern __inline__ unsigned long int
-__constant_ntohl(unsigned long int x)
-{
- return (((x & 0x000000ffU) << 24) |
- ((x & 0x0000ff00U) << 8) |
- ((x & 0x00ff0000U) >> 8) |
- ((x & 0xff000000U) >> 24));
-}
-
-extern __inline__ unsigned short int
-__ntohs(unsigned short int x)
-{
- return (((x & 0x00ff) << 8) |
- ((x & 0xff00) >> 8));
-}
-
-extern __inline__ unsigned short int
-__constant_ntohs(unsigned short int x)
-{
- return (((x & 0x00ff) << 8) |
- ((x & 0xff00) >> 8));
-}
-
-#define __htonl(x) __ntohl(x)
-#define __htons(x) __ntohs(x)
-#define __constant_htonl(x) __constant_ntohl(x)
-#define __constant_htons(x) __constant_ntohs(x)
+#ifndef __BIG_ENDIAN
+#define __BIG_ENDIAN 4321
+#endif
-#ifdef __OPTIMIZE__
-# define ntohl(x) \
-(__builtin_constant_p((long)(x)) ? \
- __constant_ntohl((x)) : \
- __ntohl((x)))
-# define ntohs(x) \
-(__builtin_constant_p((short)(x)) ? \
- __constant_ntohs((x)) : \
- __ntohs((x)))
-# define htonl(x) \
-(__builtin_constant_p((long)(x)) ? \
- __constant_htonl((x)) : \
- __htonl((x)))
-# define htons(x) \
-(__builtin_constant_p((short)(x)) ? \
- __constant_htons((x)) : \
- __htons((x)))
+#ifndef __BIG_ENDIAN_BITFIELD
+#define __BIG_ENDIAN_BITFIELD
#endif
#endif /* !(_SPARC_BYTEORDER_H) */
diff --git a/include/asm-sparc/cache.h b/include/asm-sparc/cache.h
new file mode 100644
index 000000000..f537c5cc3
--- /dev/null
+++ b/include/asm-sparc/cache.h
@@ -0,0 +1,123 @@
+/* $Id: cache.h,v 1.5 1996/08/29 09:48:06 davem Exp $
+ * cache.h: Cache specific code for the Sparc. These include flushing
+ * and direct tag/data line access.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_CACHE_H
+#define _SPARC_CACHE_H
+
+#include <asm/asi.h>
+
+/* Direct access to the instruction cache is provided through and
+ * alternate address space. The IDC bit must be off in the ICCR on
+ * HyperSparcs for these accesses to work. The code below does not do
+ * any checking, the caller must do so. These routines are for
+ * diagnostics only, but could end up being useful. Use with care.
+ * Also, you are asking for trouble if you execute these in one of the
+ * three instructions following a %asr/%psr access or modification.
+ */
+
+/* First, cache-tag access. */
+extern __inline__ unsigned int get_icache_tag(int setnum, int tagnum)
+{
+ unsigned int vaddr, retval;
+
+ vaddr = ((setnum&1) << 12) | ((tagnum&0x7f) << 5);
+ __asm__ __volatile__("lda [%1] %2, %0\n\t" :
+ "=r" (retval) :
+ "r" (vaddr), "i" (ASI_M_TXTC_TAG));
+ return retval;
+}
+
+extern __inline__ void put_icache_tag(int setnum, int tagnum, unsigned int entry)
+{
+ unsigned int vaddr;
+
+ vaddr = ((setnum&1) << 12) | ((tagnum&0x7f) << 5);
+ __asm__ __volatile__("sta %0, [%1] %2\n\t" : :
+ "r" (entry), "r" (vaddr), "i" (ASI_M_TXTC_TAG) :
+ "memory");
+}
+
+/* Second cache-data access. The data is returned two-32bit quantities
+ * at a time.
+ */
+extern __inline__ void get_icache_data(int setnum, int tagnum, int subblock,
+ unsigned int *data)
+{
+ unsigned int value1, value2, vaddr;
+
+ vaddr = ((setnum&0x1) << 12) | ((tagnum&0x7f) << 5) |
+ ((subblock&0x3) << 3);
+ __asm__ __volatile__("ldda [%2] %3, %%g2\n\t"
+ "or %%g0, %%g2, %0\n\t"
+ "or %%g0, %%g3, %1\n\t" :
+ "=r" (value1), "=r" (value2) :
+ "r" (vaddr), "i" (ASI_M_TXTC_DATA) :
+ "g2", "g3");
+ data[0] = value1; data[1] = value2;
+}
+
+extern __inline__ void put_icache_data(int setnum, int tagnum, int subblock,
+ unsigned int *data)
+{
+ unsigned int value1, value2, vaddr;
+
+ vaddr = ((setnum&0x1) << 12) | ((tagnum&0x7f) << 5) |
+ ((subblock&0x3) << 3);
+ value1 = data[0]; value2 = data[1];
+ __asm__ __volatile__("or %%g0, %0, %%g2\n\t"
+ "or %%g0, %1, %%g3\n\t"
+ "stda %%g2, [%2] %3\n\t" : :
+ "r" (value1), "r" (value2),
+ "r" (vaddr), "i" (ASI_M_TXTC_DATA) :
+ "g2", "g3", "memory" /* no joke */);
+}
+
+/* Different types of flushes with the ICACHE. Some of the flushes
+ * affect both the ICACHE and the external cache. Others only clear
+ * the ICACHE entries on the cpu itself. V8's (most) allow
+ * granularity of flushes on the packet (element in line), whole line,
+ * and entire cache (ie. all lines) level. The ICACHE only flushes are
+ * ROSS HyperSparc specific and are in ross.h
+ */
+
+/* Flushes which clear out both the on-chip and external caches */
+extern __inline__ void flush_ei_page(unsigned int addr)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_FLUSH_PAGE) :
+ "memory");
+}
+
+extern __inline__ void flush_ei_seg(unsigned int addr)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_FLUSH_SEG) :
+ "memory");
+}
+
+extern __inline__ void flush_ei_region(unsigned int addr)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_FLUSH_REGION) :
+ "memory");
+}
+
+extern __inline__ void flush_ei_ctx(unsigned int addr)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_FLUSH_CTX) :
+ "memory");
+}
+
+extern __inline__ void flush_ei_user(unsigned int addr)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_FLUSH_USER) :
+ "memory");
+}
+
+#endif /* !(_SPARC_CACHE_H) */
diff --git a/include/asm-sparc/checksum.h b/include/asm-sparc/checksum.h
new file mode 100644
index 000000000..a11777025
--- /dev/null
+++ b/include/asm-sparc/checksum.h
@@ -0,0 +1,163 @@
+/* $Id: checksum.h,v 1.22 1996/11/10 21:28:25 davem Exp $ */
+#ifndef __SPARC_CHECKSUM_H
+#define __SPARC_CHECKSUM_H
+
+/* checksum.h: IP/UDP/TCP checksum routines on the Sparc.
+ *
+ * Copyright(C) 1995 Linus Torvalds
+ * Copyright(C) 1995 Miguel de Icaza
+ * Copyright(C) 1996 David S. Miller
+ * Copyright(C) 1996 Eddie C. Dost
+ *
+ * derived from:
+ * Alpha checksum c-code
+ * ix86 inline assembly
+ * RFC1071 Computing the Internet Checksum
+ */
+
+/* computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+extern unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum);
+
+/* the same as csum_partial, but copies from fs:src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern unsigned int csum_partial_copy(char *src, char *dst, int len, int sum);
+
+#define csum_partial_copy_fromuser(s, d, l, w) \
+ csum_partial_copy((char *) (s), (d), (l), (w))
+
+/* ihl is always 5 or greater, almost always is 5, and iph is word aligned
+ * the majority of the time.
+ */
+extern __inline__ unsigned short ip_fast_csum(__const__ unsigned char *iph,
+ unsigned int ihl)
+{
+ unsigned short sum;
+
+ /* Note: We must read %2 before we touch %0 for the first time,
+ * because GCC can legitimately use the same register for
+ * both operands.
+ */
+ __asm__ __volatile__("sub\t%2, 4, %%g4\n\t"
+ "ld\t[%1 + 0x00], %0\n\t"
+ "ld\t[%1 + 0x04], %%g2\n\t"
+ "ld\t[%1 + 0x08], %%g3\n\t"
+ "addcc\t%%g2, %0, %0\n\t"
+ "addxcc\t%%g3, %0, %0\n\t"
+ "ld\t[%1 + 0x0c], %%g2\n\t"
+ "ld\t[%1 + 0x10], %%g3\n\t"
+ "addxcc\t%%g2, %0, %0\n\t"
+ "addx\t%0, %%g0, %0\n"
+ "1:\taddcc\t%%g3, %0, %0\n\t"
+ "add\t%1, 4, %1\n\t"
+ "addxcc\t%0, %%g0, %0\n\t"
+ "subcc\t%%g4, 1, %%g4\n\t"
+ "be,a\t2f\n\t"
+ "sll\t%0, 16, %%g2\n\t"
+ "b\t1b\n\t"
+ "ld\t[%1 + 0x10], %%g3\n"
+ "2:\taddcc\t%0, %%g2, %%g2\n\t"
+ "srl\t%%g2, 16, %0\n\t"
+ "addx\t%0, %%g0, %0\n\t"
+ "xnor\t%%g0, %0, %0"
+ : "=r" (sum), "=&r" (iph)
+ : "r" (ihl), "1" (iph)
+ : "g2", "g3", "g4");
+ return sum;
+}
+
+/* computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+extern __inline__ unsigned short csum_tcpudp_magic(unsigned long saddr,
+ unsigned long daddr,
+ unsigned int len,
+ unsigned short proto,
+ unsigned int sum)
+{
+ __asm__ __volatile__("addcc\t%1, %0, %0\n\t"
+ "addxcc\t%2, %0, %0\n\t"
+ "addxcc\t%3, %0, %0\n\t"
+ "addx\t%0, %%g0, %0\n\t"
+ "sll\t%0, 16, %1\n\t"
+ "addcc\t%1, %0, %0\n\t"
+ "srl\t%0, 16, %0\n\t"
+ "addx\t%0, %%g0, %0\n\t"
+ "xnor\t%%g0, %0, %0"
+ : "=r" (sum), "=r" (saddr)
+ : "r" (daddr), "r" ((proto<<16)+len), "0" (sum),
+ "1" (saddr));
+ return sum;
+}
+
+/* Fold a partial checksum without adding pseudo headers. */
+extern __inline__ unsigned int csum_fold(unsigned int sum)
+{
+ unsigned int tmp;
+
+ __asm__ __volatile__("addcc\t%0, %1, %1\n\t"
+ "srl\t%1, 16, %1\n\t"
+ "addx\t%1, %%g0, %1\n\t"
+ "xnor\t%%g0, %1, %0"
+ : "=&r" (sum), "=r" (tmp)
+ : "0" (sum), "1" (sum<<16));
+ return sum;
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+
+static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
+ struct in6_addr *daddr,
+ __u16 len,
+ unsigned short proto,
+ unsigned int sum)
+{
+ __asm__ __volatile__ ("
+ addcc %3, %4, %%g4
+ addxcc %5, %%g4, %%g4
+ ld [%2 + 0x0c], %%g2
+ ld [%2 + 0x08], %%g3
+ addxcc %%g2, %%g4, %%g4
+ ld [%2 + 0x04], %%g2
+ addxcc %%g3, %%g4, %%g4
+ ld [%2 + 0x00], %%g3
+ addxcc %%g2, %%g4, %%g4
+ ld [%1 + 0x0c], %%g2
+ addxcc %%g3, %%g4, %%g4
+ ld [%1 + 0x08], %%g3
+ addxcc %%g2, %%g4, %%g4
+ ld [%1 + 0x04], %%g2
+ addxcc %%g3, %%g4, %%g4
+ ld [%1 + 0x00], %%g3
+ addxcc %%g2, %%g4, %%g4
+ addxcc %%g3, %%g4, %0
+ addx 0, %0, %0
+ "
+ : "=&r" (sum)
+ : "r" (saddr), "r" (daddr),
+ "r"(htonl((__u32) (len))), "r"(htonl(proto)), "r"(sum)
+ : "g2", "g3", "g4");
+
+ return csum_fold(sum);
+}
+
+/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */
+extern __inline__ unsigned short ip_compute_csum(unsigned char * buff, int len)
+{
+ return csum_fold(csum_partial(buff, len, 0));
+}
+
+#endif /* !(__SPARC_CHECKSUM_H) */
diff --git a/include/asm-sparc/clock.h b/include/asm-sparc/clock.h
index ce5ce6762..e708e6b50 100644
--- a/include/asm-sparc/clock.h
+++ b/include/asm-sparc/clock.h
@@ -1,53 +1,11 @@
-/* clock.h: Definitions for the clock/timer chips on the Sparc.
+/* $Id: clock.h,v 1.3 1995/11/25 02:31:25 davem Exp $
+ * clock.h: Definitions for clock operations on the Sparc.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
+#ifndef _SPARC_CLOCK_H
+#define _SPARC_CLOCK_H
-/* Clock timer structures. The interrupt timer has two properties which
- * are the counter (which is handled in do_timer in sched.c) and the limit.
- * This limit is where the timer's counter 'wraps' around. Oddly enough,
- * the sun4c timer when it hits the limit wraps back to 1 and not zero
- * thus when calculating the value at which it will fire a microsecond you
- * must adjust by one. Thanks SUN for designing such great hardware ;(
- */
-
-/* Note that I am only going to use the timer that interrupts at
- * Sparc IRQ 10. There is another one available that can fire at
- * IRQ 14. If I can think of some creative uses for it this may
- * change. It might make a nice kernel/user profiler etc.
- */
-
-struct sparc_timer_info {
- unsigned int cur_count10;
- unsigned int timer_limit10;
- unsigned int cur_count14;
- unsigned int timer_limit14;
-};
-
-struct sparc_clock_info {
- unsigned char hsec;
- unsigned char hr;
- unsigned char min;
- unsigned char sec;
- unsigned char mon;
- unsigned char day;
- unsigned char yr;
- unsigned char wkday;
- unsigned char ram_hsec;
- unsigned char ram_hr;
- unsigned char ram_min;
- unsigned char ram_sec;
- unsigned char ram_mon;
- unsigned char ram_day;
- unsigned char ram_year;
- unsigned char ram_wkday;
- unsigned char intr_reg;
- unsigned char cmd_reg;
- unsigned char foo[14];
-};
-
-#define TIMER_PHYSADDR 0xf3000000
-
-/* YUCK YUCK YUCK, grrr... */
-#define TIMER_STRUCT ((struct sparc_timer_info *)((struct sparc_clock_info *) TIMER_VADDR))
+/* Foo for now. */
+#endif /* !(_SPARC_CLOCK_H) */
diff --git a/include/asm-sparc/contregs.h b/include/asm-sparc/contregs.h
index 326e888ff..adf4718a2 100644
--- a/include/asm-sparc/contregs.h
+++ b/include/asm-sparc/contregs.h
@@ -1,19 +1,50 @@
+/* $Id: contregs.h,v 1.6 1995/11/25 02:31:27 davem Exp $ */
#ifndef _SPARC_CONTREGS_H
#define _SPARC_CONTREGS_H
/* contregs.h: Addresses of registers in the ASI_CONTROL alternate address
- space. These are for the mmu's context register, etc.
+ * space. These are for the mmu's context register, etc.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
- Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
-*/
+/* 4=sun4 (as in sun4 sysmaint student book), c=sun4c (according to davem) */
-#define AC_CONTEXT 0x30000000 /* current mmu-context, handy for invalidate()'s ;-) */
-#define AC_SENABLE 0x40000000 /* system dvma/cache enable, plus special reset poking */
-#define AC_CACHETAGS 0x80000000 /* direct access to the VAC cache, unused... */
-#define AC_SYNC_ERR 0x60000000 /* what type of synchronous memory error happened */
-#define AC_SYNC_VA 0x60000004 /* what virtual address caused the error to occur */
-#define AC_ASYNC_ERR 0x60000008 /* what type of asynchronous mem-error happened */
-#define AC_ASYNC_VA 0x6000000c /* what virtual address caused the async-err to happen */
-#define AC_CACHEDDATA 0x90000000 /* where the actual VAC cached data sits */
+#define AC_IDPROM 0x00000000 /* 4 ID PROM, R/O, byte, 32 bytes */
+#define AC_CONTEXT 0x30000000 /* 4c current mmu-context */
+#define AC_SENABLE 0x40000000 /* 4c system dvma/cache/reset enable reg */
+#define AC_UDVMA_ENB 0x50000000 /* 4 Not used on Sun boards, byte */
+#define AC_BUS_ERROR 0x60000000 /* 4 Cleared on read, byte. */
+#define AC_SYNC_ERR 0x60000000 /* c fault type */
+#define AC_SYNC_VA 0x60000004 /* c fault virtual address */
+#define AC_ASYNC_ERR 0x60000008 /* c asynchronous fault type */
+#define AC_ASYNC_VA 0x6000000c /* c async fault virtual address */
+#define AC_LEDS 0x70000000 /* 4 Zero turns on LEDs, byte */
+#define AC_CACHETAGS 0x80000000 /* 4c direct access to the VAC tags */
+#define AC_CACHEDDATA 0x90000000 /* c direct access to the VAC data */
+#define AC_UDVMA_MAP 0xD0000000 /* 4 Not used on Sun boards, byte */
+#define AC_VME_VECTOR 0xE0000000 /* 4 For non-Autovector VME, byte */
+#define AC_BOOT_SCC 0xF0000000 /* 4 bypass to access Zilog 8530. byte. */
+
+/* s=Swift, h=Ross_HyperSPARC, v=TI_Viking, t=Tsunami, r=Ross_Cypress */
+#define AC_M_PCR 0x0000 /* shv Processor Control Reg */
+#define AC_M_CTPR 0x0100 /* shv Context Table Pointer Reg */
+#define AC_M_CXR 0x0200 /* shv Context Register */
+#define AC_M_SFSR 0x0300 /* shv Synchronous Fault Status Reg */
+#define AC_M_SFAR 0x0400 /* shv Synchronous Fault Address Reg */
+#define AC_M_AFSR 0x0500 /* hv Asynchronous Fault Status Reg */
+#define AC_M_AFAR 0x0600 /* hv Asynchronous Fault Address Reg */
+#define AC_M_RESET 0x0700 /* hv Reset Reg */
+#define AC_M_RPR 0x1000 /* hv Root Pointer Reg */
+#define AC_M_TSUTRCR 0x1000 /* s TLB Replacement Ctrl Reg */
+#define AC_M_IAPTP 0x1100 /* hv Instruction Access PTP */
+#define AC_M_DAPTP 0x1200 /* hv Data Access PTP */
+#define AC_M_ITR 0x1300 /* hv Index Tag Register */
+#define AC_M_TRCR 0x1400 /* hv TLB Replacement Control Reg */
+#define AC_M_SFSRX 0x1300 /* s Synch Fault Status Reg prim */
+#define AC_M_SFARX 0x1400 /* s Synch Fault Address Reg prim */
+#define AC_M_RPR1 0x1500 /* h Root Pointer Reg (entry 2) */
+#define AC_M_IAPTP1 0x1600 /* h Instruction Access PTP (entry 2) */
+#define AC_M_DAPTP1 0x1700 /* h Data Access PTP (entry 2) */
#endif /* _SPARC_CONTREGS_H */
diff --git a/include/asm-sparc/cprefix.h b/include/asm-sparc/cprefix.h
index 439c7c671..61cde329a 100644
--- a/include/asm-sparc/cprefix.h
+++ b/include/asm-sparc/cprefix.h
@@ -6,15 +6,18 @@
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
+#ifndef __SPARC_CPREFIX_H
+#define __SPARC_CPREFIX_H
-
-#ifndef __svr4__
-#define C_LABEL_PREFIX _
-#else
+#if defined(__svr4__) || defined(__ELF__)
#define C_LABEL_PREFIX
+#else
+#define C_LABEL_PREFIX _
#endif
-#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a##b
-#define C_LABEL(name) CONCAT1(C_LABEL_PREFIX, name)
+#define C_LABEL(name) CONCAT(C_LABEL_PREFIX, name)
+
+#endif /* !(__SPARC_CPREFIX_H) */
diff --git a/include/asm-sparc/cypress.h b/include/asm-sparc/cypress.h
new file mode 100644
index 000000000..fc92fc839
--- /dev/null
+++ b/include/asm-sparc/cypress.h
@@ -0,0 +1,79 @@
+/* $Id: cypress.h,v 1.6 1996/08/29 09:48:09 davem Exp $
+ * cypress.h: Cypress module specific definitions and defines.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_CYPRESS_H
+#define _SPARC_CYPRESS_H
+
+/* Cypress chips have %psr 'impl' of '0001' and 'vers' of '0001'. */
+
+/* The MMU control register fields on the Sparc Cypress 604/605 MMU's.
+ *
+ * ---------------------------------------------------------------
+ * |implvers| MCA | MCM |MV| MID |BM| C|RSV|MR|CM|CL|CE|RSV|NF|ME|
+ * ---------------------------------------------------------------
+ * 31 24 23-22 21-20 19 18-15 14 13 12 11 10 9 8 7-2 1 0
+ *
+ * MCA: MultiChip Access -- Used for configuration of multiple
+ * CY7C604/605 cache units.
+ * MCM: MultiChip Mask -- Again, for multiple cache unit config.
+ * MV: MultiChip Valid -- Indicates MCM and MCA have valid settings.
+ * MID: ModuleID -- Unique processor ID for MBus transactions. (605 only)
+ * BM: Boot Mode -- 0 = not in boot mode, 1 = in boot mode
+ * C: Cacheable -- Indicates whether accesses are cacheable while
+ * the MMU is off. 0=no 1=yes
+ * MR: MemoryReflection -- Indicates whether the bus attached to the
+ * MBus supports memory reflection. 0=no 1=yes (605 only)
+ * CM: CacheMode -- Indicates whether the cache is operating in write
+ * through or copy-back mode. 0=write-through 1=copy-back
+ * CL: CacheLock -- Indicates if the entire cache is locked or not.
+ * 0=not-locked 1=locked (604 only)
+ * CE: CacheEnable -- Is the virtual cache on? 0=no 1=yes
+ * NF: NoFault -- Do faults generate traps? 0=yes 1=no
+ * ME: MmuEnable -- Is the MMU doing translations? 0=no 1=yes
+ */
+
+#define CYPRESS_MCA 0x00c00000
+#define CYPRESS_MCM 0x00300000
+#define CYPRESS_MVALID 0x00080000
+#define CYPRESS_MIDMASK 0x00078000 /* Only on 605 */
+#define CYPRESS_BMODE 0x00004000
+#define CYPRESS_ACENABLE 0x00002000
+#define CYPRESS_MRFLCT 0x00000800 /* Only on 605 */
+#define CYPRESS_CMODE 0x00000400
+#define CYPRESS_CLOCK 0x00000200 /* Only on 604 */
+#define CYPRESS_CENABLE 0x00000100
+#define CYPRESS_NFAULT 0x00000002
+#define CYPRESS_MENABLE 0x00000001
+
+extern __inline__ void cypress_flush_page(unsigned long page)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (page), "i" (ASI_M_FLUSH_PAGE));
+}
+
+extern __inline__ void cypress_flush_segment(unsigned long addr)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_FLUSH_SEG));
+}
+
+extern __inline__ void cypress_flush_region(unsigned long addr)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_FLUSH_REGION));
+}
+
+extern __inline__ void cypress_flush_context(void)
+{
+ __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
+ "i" (ASI_M_FLUSH_CTX));
+}
+
+/* XXX Displacement flushes for buggy chips and initial testing
+ * XXX go here.
+ */
+
+#endif /* !(_SPARC_CYPRESS_H) */
diff --git a/include/asm-sparc/delay.h b/include/asm-sparc/delay.h
index d6c4b360e..71e1154a0 100644
--- a/include/asm-sparc/delay.h
+++ b/include/asm-sparc/delay.h
@@ -1,40 +1,28 @@
+/* $Id: delay.h,v 1.8 1996/01/28 02:09:21 davem Exp $
+ * delay.h: Linux delay routines on the Sparc.
+ *
+ * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu).
+ */
+
#ifndef __SPARC_DELAY_H
#define __SPARC_DELAY_H
extern unsigned long loops_per_sec;
-/*
- * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu).
- *
- * Delay quick inlined code using 'loops_per_second' which is
- * calculated in calibrate_delay() in main.c (ie. BogoMIPS :-)
- */
-
-extern __inline__ void __delay(unsigned int loops)
+extern __inline__ void __delay(unsigned long loops)
{
- __asm__ __volatile__("\n1:\tcmp %0, 0\n\t"
- "bne,a 1b\n\t"
- "sub %0, 1, %0\n": "=&r" (loops) : "0" (loops));
+ __asm__ __volatile__("cmp %0, 0\n\t"
+ "1: bne 1b\n\t"
+ "subcc %0, 1, %0\n" :
+ "=&r" (loops) :
+ "0" (loops));
}
-/* udelay(usecs) is used for very short delays up to 1 millisecond. */
-
-extern __inline__ void udelay(unsigned int usecs)
-{
- usecs *= 0x000010c6; /* Sparc is 32-bit just like ix86 */
-
- __asm__("sethi %hi(_loops_per_sec), %o1\n\t"
- "ld [%o1 + %lo(_loops_per_sec)], %o1\n\t"
- "call ___delay\n\t"
- "umul %o1, %o0, %o0\n\t");
-}
+/* This is too messy with inline asm on the Sparc. */
+extern void udelay(unsigned long usecs);
/* calibrate_delay() wants this... */
-
-extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
-{
- return ((a*b)/c);
-}
+#define muldiv(a, b, c) (((a)*(b))/(c))
#endif /* defined(__SPARC_DELAY_H) */
diff --git a/include/asm-sparc/dma.h b/include/asm-sparc/dma.h
index 138e7a445..a86379a71 100644
--- a/include/asm-sparc/dma.h
+++ b/include/asm-sparc/dma.h
@@ -1,20 +1,209 @@
-/*
+/* $Id: dma.h,v 1.22 1996/10/17 05:29:01 davem Exp $
* include/asm-sparc/dma.h
*
- * Don't even ask, I am figuring out how this crap works
- * on the Sparc. It may end up being real hairy to plug
- * into this code, maybe not, we'll see.
- *
- * Copyright (C) David S. Miller (davem@caip.rutgers.edu)
+ * Copyright 1995 (C) David S. Miller (davem@caip.rutgers.edu)
*/
+#ifndef _ASM_SPARC_DMA_H
+#define _ASM_SPARC_DMA_H
+
+#include <linux/kernel.h>
+
#include <asm/vac-ops.h> /* for invalidate's, etc. */
+#include <asm/sbus.h>
+#include <asm/delay.h>
+#include <asm/oplib.h>
+/* These are irrelevant for Sparc DMA, but we leave it in so that
+ * things can compile.
+ */
#define MAX_DMA_CHANNELS 8
-#define MAX_DMA_ADDRESS 0x0
+#define MAX_DMA_ADDRESS (~0UL)
+#define DMA_MODE_READ 1
+#define DMA_MODE_WRITE 2
-#ifndef _ASM_SPARC_DMA_H
-#define _ASM_SPARC_DMA_H
+/* Useful constants */
+#define SIZE_16MB (16*1024*1024)
+#define SIZE_64K (64*1024)
+
+/* Structure to describe the current status of DMA registers on the Sparc */
+struct sparc_dma_registers {
+ __volatile__ unsigned long cond_reg; /* DMA condition register */
+ __volatile__ char * st_addr; /* Start address of this transfer */
+ __volatile__ unsigned long cnt; /* How many bytes to transfer */
+ __volatile__ unsigned long dma_test; /* DMA test register */
+};
+
+/* DVMA chip revisions */
+enum dvma_rev {
+ dvmarev0,
+ dvmaesc1,
+ dvmarev1,
+ dvmarev2,
+ dvmarev3,
+ dvmarevplus,
+ dvmahme
+};
+
+#define DMA_HASCOUNT(rev) ((rev)==dvmaesc1)
+
+/* Linux DMA information structure, filled during probe. */
+struct Linux_SBus_DMA {
+ struct Linux_SBus_DMA *next;
+ struct linux_sbus_device *SBus_dev;
+ struct sparc_dma_registers *regs;
+
+ /* Status, misc info */
+ int node; /* Prom node for this DMA device */
+ int running; /* Are we doing DMA now? */
+ int allocated; /* Are we "owned" by anyone yet? */
+
+ /* Transfer information. */
+ unsigned long addr; /* Start address of current transfer */
+ int nbytes; /* Size of current transfer */
+ int realbytes; /* For splitting up large transfers, etc. */
+
+ /* DMA revision */
+ enum dvma_rev revision;
+};
+
+extern struct Linux_SBus_DMA *dma_chain;
+
+/* Broken hardware... */
+#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev1)
+#define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1)
+
+/* Main routines in dma.c */
+extern void dump_dma_regs(struct sparc_dma_registers *);
+extern unsigned long dvma_init(struct linux_sbus *, unsigned long);
+
+/* Fields in the cond_reg register */
+/* First, the version identification bits */
+#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */
+#define DMA_VERS0 0x00000000 /* Sunray DMA version */
+#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */
+#define DMA_VERS1 0x80000000 /* DMA rev 1 */
+#define DMA_VERS2 0xa0000000 /* DMA rev 2 */
+#define DMA_VERHME 0xb0000000 /* DMA hme gate array */
+#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */
+
+#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */
+#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */
+#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */
+#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */
+#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */
+#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */
+#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */
+#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */
+#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */
+#define DMA_ST_WRITE 0x00000100 /* write from device to memory */
+#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */
+#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */
+#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */
+#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */
+#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */
+#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */
+#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */
+#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */
+#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */
+#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */
+#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */
+#define DMA_E_BURST8 0x00040000 /* ENET: SBUS r/w burst size */
+#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */
+#define DMA_BRST64 0x00080000 /* SCSI: 64byte bursts (HME on UltraSparc only) */
+#define DMA_BRST32 0x00040000 /* SCSI: 32byte bursts */
+#define DMA_BRST16 0x00000000 /* SCSI: 16byte bursts */
+#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */
+#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */
+#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */
+#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */
+#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */
+#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */
+#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */
+#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */
+#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */
+#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */
+#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */
+
+/* Values describing the burst-size property from the PROM */
+#define DMA_BURST1 0x01
+#define DMA_BURST2 0x02
+#define DMA_BURST4 0x04
+#define DMA_BURST8 0x08
+#define DMA_BURST16 0x10
+#define DMA_BURST32 0x20
+#define DMA_BURST64 0x40
+#define DMA_BURSTBITS 0x7f
+
+/* Determine highest possible final transfer address given a base */
+#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL))
+
+/* Yes, I hack a lot of elisp in my spare time... */
+#define DMA_ERROR_P(regs) ((((regs)->cond_reg) & DMA_HNDL_ERROR))
+#define DMA_IRQ_P(regs) ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)))
+#define DMA_WRITE_P(regs) ((((regs)->cond_reg) & DMA_ST_WRITE))
+#define DMA_OFF(regs) ((((regs)->cond_reg) &= (~DMA_ENABLE)))
+#define DMA_INTSOFF(regs) ((((regs)->cond_reg) &= (~DMA_INT_ENAB)))
+#define DMA_INTSON(regs) ((((regs)->cond_reg) |= (DMA_INT_ENAB)))
+#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV))
+#define DMA_SETSTART(regs, addr) ((((regs)->st_addr) = (char *) addr))
+#define DMA_BEGINDMA_W(regs) \
+ ((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB))))
+#define DMA_BEGINDMA_R(regs) \
+ ((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE)))))
+
+/* For certain DMA chips, we need to disable ints upon irq entry
+ * and turn them back on when we are done. So in any ESP interrupt
+ * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT
+ * when leaving the handler. You have been warned...
+ */
+#define DMA_IRQ_ENTRY(dma, dregs) do { \
+ if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \
+ } while (0)
+
+#define DMA_IRQ_EXIT(dma, dregs) do { \
+ if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
+ } while(0)
+
+/* Pause until counter runs out or BIT isn't set in the DMA condition
+ * register.
+ */
+extern __inline__ void sparc_dma_pause(struct sparc_dma_registers *regs,
+ unsigned long bit)
+{
+ int ctr = 50000; /* Let's find some bugs ;) */
+
+ /* Busy wait until the bit is not set any more */
+ while((regs->cond_reg&bit) && (ctr>0)) {
+ ctr--;
+ __delay(5);
+ }
+
+ /* Check for bogus outcome. */
+ if(!ctr)
+ panic("DMA timeout");
+}
+
+/* Reset the friggin' thing... */
+#define DMA_RESET(dma) do { \
+ struct sparc_dma_registers *regs = dma->regs; \
+ /* Let the current FIFO drain itself */ \
+ sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN)); \
+ /* Reset the logic */ \
+ regs->cond_reg |= (DMA_RST_SCSI); /* assert */ \
+ __delay(400); /* let the bits set ;) */ \
+ regs->cond_reg &= ~(DMA_RST_SCSI); /* de-assert */ \
+ sparc_dma_enable_interrupts(regs); /* Re-enable interrupts */ \
+ /* Enable FAST transfers if available */ \
+ if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS; \
+ dma->running = 0; \
+} while(0)
+
+#define for_each_dvma(dma) \
+ for((dma) = dma_chain; (dma); (dma) = (dma)->next)
+extern int get_dma_list(char *);
+extern int request_dma(unsigned int, __const__ char *);
+extern void free_dma(unsigned int);
#endif /* !(_ASM_SPARC_DMA_H) */
diff --git a/include/asm-sparc/ecc.h b/include/asm-sparc/ecc.h
new file mode 100644
index 000000000..8e27ceccb
--- /dev/null
+++ b/include/asm-sparc/ecc.h
@@ -0,0 +1,122 @@
+/* $Id: ecc.h,v 1.3 1996/04/25 06:12:57 davem Exp $
+ * ecc.h: Definitions and defines for the external cache/memory
+ * controller on the sun4m.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_ECC_H
+#define _SPARC_ECC_H
+
+/* These registers are accessed through the SRMMU passthrough ASI 0x20 */
+#define ECC_ENABLE 0x00000000 /* ECC enable register */
+#define ECC_FSTATUS 0x00000008 /* ECC fault status register */
+#define ECC_FADDR 0x00000010 /* ECC fault address register */
+#define ECC_DIGNOSTIC 0x00000018 /* ECC diagnostics register */
+#define ECC_MBAENAB 0x00000020 /* MBus arbiter enable register */
+#define ECC_DMESG 0x00001000 /* Diagnostic message passing area */
+
+/* ECC MBus Arbiter Enable register:
+ *
+ * ----------------------------------------
+ * | |SBUS|MOD3|MOD2|MOD1|RSV|
+ * ----------------------------------------
+ * 31 5 4 3 2 1 0
+ *
+ * SBUS: Enable MBus Arbiter on the SBus 0=off 1=on
+ * MOD3: Enable MBus Arbiter on MBus module 3 0=off 1=on
+ * MOD2: Enable MBus Arbiter on MBus module 2 0=off 1=on
+ * MOD1: Enable MBus Arbiter on MBus module 1 0=off 1=on
+ */
+
+#define ECC_MBAE_SBUS 0x00000010
+#define ECC_MBAE_MOD3 0x00000008
+#define ECC_MBAE_MOD2 0x00000004
+#define ECC_MBAE_MOD1 0x00000002
+
+/* ECC Fault Control Register layout:
+ *
+ * -----------------------------
+ * | RESV | ECHECK | EINT |
+ * -----------------------------
+ * 31 2 1 0
+ *
+ * ECHECK: Enable ECC checking. 0=off 1=on
+ * EINT: Enable Interrupts for correctable errors. 0=off 1=on
+ */
+#define ECC_FCR_CHECK 0x00000002
+#define ECC_FCR_INTENAB 0x00000001
+
+/* ECC Fault Address Register Zero layout:
+ *
+ * -----------------------------------------------------
+ * | MID | S | RSV | VA | BM |AT| C| SZ |TYP| PADDR |
+ * -----------------------------------------------------
+ * 31-28 27 26-22 21-14 13 12 11 10-8 7-4 3-0
+ *
+ * MID: ModuleID of the faulting processor. ie. who did it?
+ * S: Supervisor/Privileged access? 0=no 1=yes
+ * VA: Bits 19-12 of the virtual faulting address, these are the
+ * superset bits in the virtual cache and can be used for
+ * a flush operation if necessary.
+ * BM: Boot mode? 0=no 1=yes This is just like the SRMMU boot
+ * mode bit.
+ * AT: Did this fault happen during an atomic instruction? 0=no
+ * 1=yes. This means either an 'ldstub' or 'swap' instruction
+ * was in progress (but not finished) when this fault happened.
+ * This indicated whether the bus was locked when the fault
+ * occurred.
+ * C: Did the pte for this access indicate that it was cacheable?
+ * 0=no 1=yes
+ * SZ: The size of the transaction.
+ * TYP: The transaction type.
+ * PADDR: Bits 35-32 of the physical address for the fault.
+ */
+#define ECC_FADDR0_MIDMASK 0xf0000000
+#define ECC_FADDR0_S 0x08000000
+#define ECC_FADDR0_VADDR 0x003fc000
+#define ECC_FADDR0_BMODE 0x00002000
+#define ECC_FADDR0_ATOMIC 0x00001000
+#define ECC_FADDR0_CACHE 0x00000800
+#define ECC_FADDR0_SIZE 0x00000700
+#define ECC_FADDR0_TYPE 0x000000f0
+#define ECC_FADDR0_PADDR 0x0000000f
+
+/* ECC Fault Address Register One layout:
+ *
+ * -------------------------------------
+ * | Physical Address 31-0 |
+ * -------------------------------------
+ * 31 0
+ *
+ * You get the upper 4 bits of the physical address from the
+ * PADDR field in ECC Fault Address Zero register.
+ */
+
+/* ECC Fault Status Register layout:
+ *
+ * ----------------------------------------------
+ * | RESV|C2E|MULT|SYNDROME|DWORD|UNC|TIMEO|BS|C|
+ * ----------------------------------------------
+ * 31-18 17 16 15-8 7-4 3 2 1 0
+ *
+ * C2E: A C2 graphics error occurred. 0=no 1=yes (SS10 only)
+ * MULT: Multiple errors occurred ;-O 0=no 1=prom_panic(yes)
+ * SYNDROME: Controller is mentally unstable.
+ * DWORD:
+ * UNC: Uncorrectable error. 0=no 1=yes
+ * TIMEO: Timeout occurred. 0=no 1=yes
+ * BS: C2 graphics bad slot access. 0=no 1=yes (SS10 only)
+ * C: Correctable error? 0=no 1=yes
+ */
+
+#define ECC_FSR_C2ERR 0x00020000
+#define ECC_FSR_MULT 0x00010000
+#define ECC_FSR_SYND 0x0000ff00
+#define ECC_FSR_DWORD 0x000000f0
+#define ECC_FSR_UNC 0x00000008
+#define ECC_FSR_TIMEO 0x00000004
+#define ECC_FSR_BADSLOT 0x00000002
+#define ECC_FSR_C 0x00000001
+
+#endif /* !(_SPARC_ECC_H) */
diff --git a/include/asm-sparc/eeprom.h b/include/asm-sparc/eeprom.h
new file mode 100644
index 000000000..a8ff7496d
--- /dev/null
+++ b/include/asm-sparc/eeprom.h
@@ -0,0 +1,9 @@
+/* $Id: eeprom.h,v 1.3 1995/11/25 02:31:38 davem Exp $
+ * eeprom.h: Definitions for the Sun eeprom.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/* The EEPROM and the Mostek Mk48t02 use the same IO address space
+ * for their registers/data areas. The IDPROM lives here too.
+ */
diff --git a/include/asm-sparc/elf.h b/include/asm-sparc/elf.h
new file mode 100644
index 000000000..46cd67f37
--- /dev/null
+++ b/include/asm-sparc/elf.h
@@ -0,0 +1,34 @@
+/* $Id: elf.h,v 1.5 1996/08/08 00:06:13 ecd Exp $ */
+#ifndef __ASMSPARC_ELF_H
+#define __ASMSPARC_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef unsigned long elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x) == EM_SPARC)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_ARCH EM_SPARC
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2MSB;
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 4096
+
+
+#endif /* !(__ASMSPARC_ELF_H) */
diff --git a/include/asm-sparc/errno.h b/include/asm-sparc/errno.h
new file mode 100644
index 000000000..3348a3833
--- /dev/null
+++ b/include/asm-sparc/errno.h
@@ -0,0 +1,133 @@
+/* $Id: errno.h,v 1.5 1996/07/13 02:05:13 tridge Exp $ */
+#ifndef _SPARC_ERRNO_H
+#define _SPARC_ERRNO_H
+
+/* These match the SunOS error numbering scheme. */
+#define EPERM 1 /* Operation not permitted */
+#define ENOENT 2 /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* I/O error */
+#define ENXIO 6 /* No such device or address */
+#define E2BIG 7 /* Arg list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file number */
+#define ECHILD 10 /* No child processes */
+#define EAGAIN 11 /* Try again */
+#define ENOMEM 12 /* Out of memory */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+#define ENOTBLK 15 /* Block device required */
+#define EBUSY 16 /* Device or resource busy */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* No such device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* File table overflow */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Not a typewriter */
+#define ETXTBSY 26 /* Text file busy */
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+#define EDOM 33 /* Math argument out of domain of func */
+#define ERANGE 34 /* Math result not representable */
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#define EINPROGRESS 36 /* Operation now in progress */
+#define EALREADY 37 /* Operation already in progress */
+#define ENOTSOCK 38 /* Socket operation on non-socket */
+#define EDESTADDRREQ 39 /* Destination address required */
+#define EMSGSIZE 40 /* Message too long */
+#define EPROTOTYPE 41 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 42 /* Protocol not available */
+#define EPROTONOSUPPORT 43 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
+#define EOPNOTSUPP 45 /* Op not supported on transport endpoint */
+#define EPFNOSUPPORT 46 /* Protocol family not supported */
+#define EAFNOSUPPORT 47 /* Address family not supported by protocol */
+#define EADDRINUSE 48 /* Address already in use */
+#define EADDRNOTAVAIL 49 /* Cannot assign requested address */
+#define ENETDOWN 50 /* Network is down */
+#define ENETUNREACH 51 /* Network is unreachable */
+#define ENETRESET 52 /* Net dropped connection because of reset */
+#define ECONNABORTED 53 /* Software caused connection abort */
+#define ECONNRESET 54 /* Connection reset by peer */
+#define ENOBUFS 55 /* No buffer space available */
+#define EISCONN 56 /* Transport endpoint is already connected */
+#define ENOTCONN 57 /* Transport endpoint is not connected */
+#define ESHUTDOWN 58 /* No send after transport endpoint shutdown */
+#define ETOOMANYREFS 59 /* Too many references: cannot splice */
+#define ETIMEDOUT 60 /* Connection timed out */
+#define ECONNREFUSED 61 /* Connection refused */
+#define ELOOP 62 /* Too many symbolic links encountered */
+#define ENAMETOOLONG 63 /* File name too long */
+#define EHOSTDOWN 64 /* Host is down */
+#define EHOSTUNREACH 65 /* No route to host */
+#define ENOTEMPTY 66 /* Directory not empty */
+#define EPROCLIM 67 /* SUNOS: Too many processes */
+#define EUSERS 68 /* Too many users */
+#define EDQUOT 69 /* Quota exceeded */
+#define ESTALE 70 /* Stale NFS file handle */
+#define EREMOTE 71 /* Object is remote */
+#define ENOSTR 72 /* Device not a stream */
+#define ETIME 73 /* Timer expired */
+#define ENOSR 74 /* Out of streams resources */
+#define ENOMSG 75 /* No message of desired type */
+#define EBADMSG 76 /* Not a data message */
+#define EIDRM 77 /* Identifier removed */
+#define EDEADLK 78 /* Resource deadlock would occur */
+#define ENOLCK 79 /* No record locks available */
+#define ENONET 80 /* Machine is not on the network */
+#define ERREMOTE 81 /* SunOS: Too many lvls of remote in path */
+#define ENOLINK 82 /* Link has been severed */
+#define EADV 83 /* Advertise error */
+#define ESRMNT 84 /* Srmount error */
+#define ECOMM 85 /* Communication error on send */
+#define EPROTO 86 /* Protocol error */
+#define EMULTIHOP 87 /* Multihop attempted */
+#define EDOTDOT 88 /* RFS specific error */
+#define EREMCHG 89 /* Remote address changed */
+#define ENOSYS 90 /* Function not implemented */
+
+/* The rest have no SunOS equivalent. */
+#define ESTRPIPE 91 /* Streams pipe error */
+#define EOVERFLOW 92 /* Value too large for defined data type */
+#define EBADFD 93 /* File descriptor in bad state */
+#define ECHRNG 94 /* Channel number out of range */
+#define EL2NSYNC 95 /* Level 2 not synchronized */
+#define EL3HLT 96 /* Level 3 halted */
+#define EL3RST 97 /* Level 3 reset */
+#define ELNRNG 98 /* Link number out of range */
+#define EUNATCH 99 /* Protocol driver not attached */
+#define ENOCSI 100 /* No CSI structure available */
+#define EL2HLT 101 /* Level 2 halted */
+#define EBADE 102 /* Invalid exchange */
+#define EBADR 103 /* Invalid request descriptor */
+#define EXFULL 104 /* Exchange full */
+#define ENOANO 105 /* No anode */
+#define EBADRQC 106 /* Invalid request code */
+#define EBADSLT 107 /* Invalid slot */
+#define EDEADLOCK 108 /* File locking deadlock error */
+#define EBFONT 109 /* Bad font file format */
+#define ELIBEXEC 110 /* Cannot exec a shared library directly */
+#define ENODATA 111 /* No data available */
+#define ELIBBAD 112 /* Accessing a corrupted shared library */
+#define ENOPKG 113 /* Package not installed */
+#define ELIBACC 114 /* Can not access a needed shared library */
+#define ENOTUNIQ 115 /* Name not unique on network */
+#define ERESTART 116 /* Interrupted syscall should be restarted */
+#define EUCLEAN 117 /* Structure needs cleaning */
+#define ENOTNAM 118 /* Not a XENIX named type file */
+#define ENAVAIL 119 /* No XENIX semaphores available */
+#define EISNAM 120 /* Is a named type file */
+#define EREMOTEIO 121 /* Remote I/O error */
+#define EILSEQ 122 /* Illegal byte sequence */
+#define ELIBMAX 123 /* Atmpt to link in too many shared libs */
+#define ELIBSCN 124 /* .lib section in a.out corrupted */
+
+#endif
diff --git a/include/asm-sparc/fbio.h b/include/asm-sparc/fbio.h
new file mode 100644
index 000000000..b7eb21003
--- /dev/null
+++ b/include/asm-sparc/fbio.h
@@ -0,0 +1,279 @@
+#ifndef __LINUX_FBIO_H
+#define __LINUX_FBIO_H
+
+/* Constants used for fbio SunOS compatibility */
+/* (C) 1996 Miguel de Icaza */
+
+/* Frame buffer types */
+#define FBTYPE_NOTYPE -1
+#define FBTYPE_SUN1BW 0 /* mono */
+#define FBTYPE_SUN1COLOR 1
+#define FBTYPE_SUN2BW 2
+#define FBTYPE_SUN2COLOR 3
+#define FBTYPE_SUN2GP 4
+#define FBTYPE_SUN5COLOR 5
+#define FBTYPE_SUN3COLOR 6
+#define FBTYPE_MEMCOLOR 7
+#define FBTYPE_SUN4COLOR 8
+
+#define FBTYPE_NOTSUN1 9
+#define FBTYPE_NOTSUN2 10
+#define FBTYPE_NOTSUN3 11
+
+#define FBTYPE_SUNFAST_COLOR 12 /* cg6 */
+#define FBTYPE_SUNROP_COLOR 13
+#define FBTYPE_SUNFB_VIDEO 14
+#define FBTYPE_SUNGIFB 15
+#define FBTYPE_SUNGPLAS 16
+#define FBTYPE_SUNGP3 17
+#define FBTYPE_SUNGT 18
+#define FBTYPE_SUNLEO 19 /* zx Leo card */
+#define FBTYPE_MDICOLOR 20 /* cg14 */
+#define FBTYPE_TCXCOLOR 21 /* SUNW,tcx card */
+
+#define FBTYPE_LASTPLUSONE 21 /* This is not last + 1 in fact... */
+
+/* fbio ioctls */
+/* Returned by FBIOGTYPE */
+struct fbtype {
+ int fb_type; /* fb type, see above */
+ int fb_height; /* pixels */
+ int fb_width; /* pixels */
+ int fb_depth;
+ int fb_cmsize; /* color map entries */
+ int fb_size; /* fb size in bytes */
+};
+#define FBIOGTYPE _IOR('F', 0, struct fbtype)
+
+/* Used by FBIOPUTCMAP */
+struct fbcmap {
+ int index; /* first element (0 origin) */
+ int count;
+ unsigned char *red;
+ unsigned char *green;
+ unsigned char *blue;
+};
+
+#define FBIOPUTCMAP _IOW('F', 3, struct fbcmap)
+#define FBIOGETCMAP _IOW('F', 4, struct fbcmap)
+
+/* # of device specific values */
+#define FB_ATTR_NDEVSPECIFIC 8
+/* # of possible emulations */
+#define FB_ATTR_NEMUTYPES 4
+
+struct fbsattr {
+ int flags;
+ int emu_type; /* -1 if none */
+ int dev_specific[FB_ATTR_NDEVSPECIFIC];
+};
+
+struct fbgattr {
+ int real_type; /* real frame buffer type */
+ int owner; /* unknown */
+ struct fbtype fbtype; /* real frame buffer fbtype */
+ struct fbsattr sattr;
+ int emu_types[FB_ATTR_NEMUTYPES]; /* supported emulations */
+};
+#define FBIOSATTR _IOW('F', 5, struct fbgattr) /* Unsupported: */
+#define FBIOGATTR _IOR('F', 6, struct fbgattr) /* supported */
+
+#define FBIOSVIDEO _IOW('F', 7, int)
+#define FBIOGVIDEO _IOR('F', 8, int)
+
+/* Cursor position */
+struct fbcurpos {
+#ifdef __KERNEL__
+ short fbx, fby;
+#else
+ short x, y;
+#endif
+};
+
+/* Cursor operations */
+#define FB_CUR_SETCUR 0x01 /* Enable/disable cursor display */
+#define FB_CUR_SETPOS 0x02 /* set cursor position */
+#define FB_CUR_SETHOT 0x04 /* set cursor hotspot */
+#define FB_CUR_SETCMAP 0x08 /* set color map for the cursor */
+#define FB_CUR_SETSHAPE 0x10 /* set shape */
+#define FB_CUR_SETALL 0x1F /* all of the above */
+
+struct fbcursor {
+ short set; /* what to set, choose from the list above */
+ short enable; /* cursor on/off */
+ struct fbcurpos pos; /* cursor position */
+ struct fbcurpos hot; /* cursor hot spot */
+ struct fbcmap cmap; /* color map info */
+ struct fbcurpos size; /* cursor bit map size */
+ char *image; /* cursor image bits */
+ char *mask; /* cursor mask bits */
+};
+
+/* set/get cursor attributes/shape */
+#define FBIOSCURSOR _IOW('F', 24, struct fbcursor)
+#define FBIOGCURSOR _IOWR('F', 25, struct fbcursor)
+
+/* set/get cursor position */
+#define FBIOSCURPOS _IOW('F', 26, struct fbcurpos)
+#define FBIOGCURPOS _IOW('F', 27, struct fbcurpos)
+
+/* get max cursor size */
+#define FBIOGCURMAX _IOR('F', 28, struct fbcurpos)
+
+/* wid manipulation */
+struct fb_wid_alloc {
+#define FB_WID_SHARED_8 0
+#define FB_WID_SHARED_24 1
+#define FB_WID_DBL_8 2
+#define FB_WID_DBL_24 3
+ __u32 wa_type;
+ __s32 wa_index; /* Set on return */
+ __u32 wa_count;
+};
+struct fb_wid_item {
+ __u32 wi_type;
+ __s32 wi_index;
+ __u32 wi_attrs;
+ __u32 wi_values[32];
+};
+struct fb_wid_list {
+ __u32 wl_flags;
+ __u32 wl_count;
+ struct fb_wid_item *wl_list;
+};
+
+#define FBIO_WID_ALLOC _IOWR('F', 30, struct fb_wid_alloc)
+#define FBIO_WID_FREE _IOW('F', 31, struct fb_wid_alloc)
+#define FBIO_WID_PUT _IOW('F', 32, struct fb_wid_list)
+#define FBIO_WID_GET _IOWR('F', 33, struct fb_wid_list)
+
+/* Cg14 ioctls */
+#define MDI_IOCTL ('M'<<8)
+#define MDI_RESET (MDI_IOCTL|1)
+#define MDI_GET_CFGINFO (MDI_IOCTL|2)
+#define MDI_SET_PIXELMODE (MDI_IOCTL|3)
+# define MDI_32_PIX 32
+# define MDI_16_PIX 16
+# define MDI_8_PIX 8
+
+struct mdi_cfginfo {
+ int mdi_ncluts; /* Number of implemented CLUTs in this MDI */
+ int mdi_type; /* FBTYPE name */
+ int mdi_height; /* height */
+ int mdi_width; /* widht */
+ int mdi_size; /* available ram */
+ int mdi_mode; /* 8bpp, 16bpp or 32bpp */
+ int mdi_pixfreq; /* pixel clock (from PROM) */
+};
+
+/* SparcLinux specific ioctl for the MDI, should be replaced for
+ * the SET_XLUT/SET_CLUTn ioctls instead
+ */
+#define MDI_CLEAR_XLUT (MDI_IOCTL|9)
+
+/* leo ioctls */
+struct leo_clut_alloc {
+ __u32 clutid; /* Set on return */
+ __u32 flag;
+ __u32 index;
+};
+
+struct leo_clut {
+#define LEO_CLUT_WAIT 0x00000001 /* Not yet implemented */
+ __u32 flag;
+ __u32 clutid;
+ __u32 offset;
+ __u32 count;
+ char * red;
+ char * green;
+ char * blue;
+};
+#define LEO_CLUTALLOC _IOWR('L', 53, struct leo_clut_alloc)
+#define LEO_CLUTFREE _IOW('L', 54, struct leo_clut_alloc)
+#define LEO_CLUTREAD _IOW('L', 55, struct leo_clut)
+#define LEO_CLUTPOST _IOW('L', 56, struct leo_clut)
+#define LEO_SETGAMMA _IOW('L', 68, int) /* Not yet implemented */
+#define LEO_GETGAMMA _IOR('L', 69, int) /* Not yet implemented */
+
+#ifdef __KERNEL__
+/* Addresses on the fd of a cgsix that are mappable */
+#define CG6_FBC 0x70000000
+#define CG6_TEC 0x70001000
+#define CG6_BTREGS 0x70002000
+#define CG6_FHC 0x70004000
+#define CG6_THC 0x70005000
+#define CG6_ROM 0x70006000
+#define CG6_RAM 0x70016000
+#define CG6_DHC 0x80000000
+
+#define CG3_MMAP_OFFSET 0x4000000
+
+/* Addresses on the fd of a tcx that are mappable */
+#define TCX_RAM8BIT 0x00000000
+#define TCX_RAM24BIT 0x01000000
+#define TCX_UNK3 0x10000000
+#define TCX_UNK4 0x20000000
+#define TCX_CONTROLPLANE 0x28000000
+#define TCX_UNK6 0x30000000
+#define TCX_UNK7 0x38000000
+#define TCX_TEC 0x70000000
+#define TCX_BTREGS 0x70002000
+#define TCX_THC 0x70004000
+#define TCX_DHC 0x70008000
+#define TCX_ALT 0x7000a000
+#define TCX_SYNC 0x7000e000
+#define TCX_UNK2 0x70010000
+
+/* CG14 definitions */
+
+/* Offsets into the OBIO space: */
+#define CG14_REGS 0 /* registers */
+#define CG14_CURSORREGS 0x1000 /* cursor registers */
+#define CG14_DACREGS 0x2000 /* DAC registers */
+#define CG14_XLUT 0x3000 /* X Look Up Table -- ??? */
+#define CG14_CLUT1 0x4000 /* Color Look Up Table */
+#define CG14_CLUT2 0x5000 /* Color Look Up Table */
+#define CG14_CLUT3 0x6000 /* Color Look Up Table */
+#define CG14_AUTO 0xf000
+
+#endif /* KERNEL */
+
+/* These are exported to userland for applications to use */
+/* Mappable offsets for the cg14: control registers */
+#define MDI_DIRECT_MAP 0x10000000
+#define MDI_CTLREG_MAP 0x20000000
+#define MDI_CURSOR_MAP 0x30000000
+#define MDI_SHDW_VRT_MAP 0x40000000
+
+/* Mappable offsets for the cg14: frame buffer resolutions */
+/* 32 bits */
+#define MDI_CHUNKY_XBGR_MAP 0x50000000
+#define MDI_CHUNKY_BGR_MAP 0x60000000
+
+/* 16 bits */
+#define MDI_PLANAR_X16_MAP 0x70000000
+#define MDI_PLANAR_C16_MAP 0x80000000
+
+/* 8 bit is done as CG3 MMAP offset */
+/* 32 bits, planar */
+#define MDI_PLANAR_X32_MAP 0x90000000
+#define MDI_PLANAR_B32_MAP 0xa0000000
+#define MDI_PLANAR_G32_MAP 0xb0000000
+#define MDI_PLANAR_R32_MAP 0xc0000000
+
+/* Mappable offsets on leo */
+#define LEO_SS0_MAP 0x00000000
+#define LEO_LC_SS0_USR_MAP 0x00800000
+#define LEO_LD_SS0_MAP 0x00801000
+#define LEO_LX_CURSOR_MAP 0x00802000
+#define LEO_SS1_MAP 0x00803000
+#define LEO_LC_SS1_USR_MAP 0x01003000
+#define LEO_LD_SS1_MAP 0x01004000
+#define LEO_UNK_MAP 0x01005000
+#define LEO_LX_KRN_MAP 0x01006000
+#define LEO_LC_SS0_KRN_MAP 0x01007000
+#define LEO_LC_SS1_KRN_MAP 0x01008000
+#define LEO_LD_GBL_MAP 0x01009000
+#define LEO_UNK2_MAP 0x0100a000
+
+#endif /* __LINUX_FBIO_H */
diff --git a/include/asm-sparc/fcntl.h b/include/asm-sparc/fcntl.h
new file mode 100644
index 000000000..792e29b56
--- /dev/null
+++ b/include/asm-sparc/fcntl.h
@@ -0,0 +1,60 @@
+/* $Id: fcntl.h,v 1.8 1996/10/27 08:55:26 davem Exp $ */
+#ifndef _SPARC_FCNTL_H
+#define _SPARC_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_RDONLY 0x0000
+#define O_WRONLY 0x0001
+#define O_RDWR 0x0002
+#define O_ACCMODE 0x0003
+#define O_NDELAY 0x0004
+#define O_APPEND 0x0008
+#define FASYNC 0x0040 /* fcntl, for BSD compatibility */
+#define O_CREAT 0x0200 /* not fcntl */
+#define O_TRUNC 0x0400 /* not fcntl */
+#define O_EXCL 0x0800 /* not fcntl */
+#define O_SYNC 0x2000
+#define O_NONBLOCK 0x4000
+#define O_NOCTTY 0x8000 /* not fcntl */
+
+#define F_DUPFD 0 /* dup */
+#define F_GETFD 1 /* get f_flags */
+#define F_SETFD 2 /* set f_flags */
+#define F_GETFL 3 /* more flags (cloexec) */
+#define F_SETFL 4
+#define F_GETOWN 5 /* for sockets. */
+#define F_SETOWN 6 /* for sockets. */
+#define F_GETLK 7
+#define F_SETLK 8
+#define F_SETLKW 9
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK 1
+#define F_WRLCK 2
+#define F_UNLCK 3
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK 4 /* or 3 */
+#define F_SHLCK 8 /* or 4 */
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH 1 /* shared lock */
+#define LOCK_EX 2 /* exclusive lock */
+#define LOCK_NB 4 /* or'd with one of the above to prevent
+ blocking */
+#define LOCK_UN 8 /* remove lock */
+
+struct flock {
+ short l_type;
+ short l_whence;
+ off_t l_start;
+ off_t l_len;
+ pid_t l_pid;
+ short __unused;
+};
+
+#endif
diff --git a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h
new file mode 100644
index 000000000..3ccc79766
--- /dev/null
+++ b/include/asm-sparc/floppy.h
@@ -0,0 +1,359 @@
+/* asm-sparc/floppy.h: Sparc specific parts of the Floppy driver.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __ASM_SPARC_FLOPPY_H
+#define __ASM_SPARC_FLOPPY_H
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/idprom.h>
+#include <asm/machines.h>
+#include <asm/oplib.h>
+#include <asm/auxio.h>
+#include <asm/irq.h>
+
+/* References:
+ * 1) Netbsd Sun floppy driver.
+ * 2) NCR 82077 controller manual
+ * 3) Intel 82077 controller manual
+ */
+struct sun_flpy_controller {
+ volatile unsigned char status_82072; /* Main Status reg. */
+#define dcr_82072 status_82072 /* Digital Control reg. */
+#define status1_82077 status_82072 /* Auxiliary Status reg. 1 */
+
+ volatile unsigned char data_82072; /* Data fifo. */
+#define status2_82077 data_82072 /* Auxiliary Status reg. 2 */
+
+ volatile unsigned char dor_82077; /* Digital Output reg. */
+ volatile unsigned char tapectl_82077; /* What the? Tape control reg? */
+
+ volatile unsigned char status_82077; /* Main Status Register. */
+#define drs_82077 status_82077 /* Digital Rate Select reg. */
+
+ volatile unsigned char data_82077; /* Data fifo. */
+ volatile unsigned char ___unused;
+ volatile unsigned char dir_82077; /* Digital Input reg. */
+#define dcr_82077 dir_82077 /* Config Control reg. */
+};
+
+/* You'll only ever find one controller on a SparcStation anyways. */
+static struct sun_flpy_controller *sun_fdc = NULL;
+volatile unsigned char *fdc_status;
+
+struct sun_floppy_ops {
+ unsigned char (*fd_inb)(int port);
+ void (*fd_outb)(unsigned char value, int port);
+};
+
+static struct sun_floppy_ops sun_fdops;
+
+#define fd_inb(port) sun_fdops.fd_inb(port)
+#define fd_outb(value,port) sun_fdops.fd_outb(value,port)
+#define fd_enable_dma() sun_fd_enable_dma()
+#define fd_disable_dma() sun_fd_disable_dma()
+#define fd_request_dma() (0) /* nothing... */
+#define fd_free_dma() /* nothing... */
+#define fd_clear_dma_ff() /* nothing... */
+#define fd_set_dma_mode(mode) sun_fd_set_dma_mode(mode)
+#define fd_set_dma_addr(addr) sun_fd_set_dma_addr(addr)
+#define fd_set_dma_count(count) sun_fd_set_dma_count(count)
+#define fd_enable_irq() /* nothing... */
+#define fd_disable_irq() /* nothing... */
+#define fd_cacheflush(addr, size) /* nothing... */
+#define fd_request_irq() sun_fd_request_irq()
+#define fd_free_irq() /* nothing... */
+#if 0 /* P3: added by Alain, these cause a MMU corruption. 19960524 XXX */
+#define fd_dma_mem_alloc(size) ((unsigned long) vmalloc(size))
+#define fd_dma_mem_free(addr,size) (vfree((void *)(addr)))
+#endif
+
+#define FLOPPY_MOTOR_MASK 0x10
+
+/* It's all the same... */
+#define virt_to_bus(x) (x)
+#define bus_to_virt(x) (x)
+
+/* XXX This isn't really correct. XXX */
+#define get_dma_residue(x) (0)
+
+#define FLOPPY0_TYPE 4
+#define FLOPPY1_TYPE 0
+
+/* Super paranoid... */
+#undef HAVE_DISABLE_HLT
+
+/* Here is where we catch the floppy driver trying to initialize,
+ * therefore this is where we call the PROM device tree probing
+ * routine etc. on the Sparc.
+ */
+#define FDC1 sun_floppy_init()
+
+static int FDC2=-1;
+
+#define N_FDC 1
+#define N_DRIVE 8
+
+/* No 64k boundary crossing problems on the Sparc. */
+#define CROSS_64KB(a,s) (0)
+
+/* Routines unique to each controller type on a Sun. */
+static unsigned char sun_82072_fd_inb(int port)
+{
+ switch(port & 7) {
+ default:
+ printk("floppy: Asked to read unknown port %d\n", port);
+ panic("floppy: Port bolixed.");
+ case 4: /* FD_STATUS */
+ return sun_fdc->status_82072 & ~STATUS_DMA;
+ case 5: /* FD_DATA */
+ return sun_fdc->data_82072;
+ case 7: /* FD_DIR */
+ return (*AUXREG & AUXIO_FLPY_DCHG)? 0x80: 0;
+ };
+ panic("sun_82072_fd_inb: How did I get here?");
+}
+
+static void sun_82072_fd_outb(unsigned char value, int port)
+{
+ switch(port & 7) {
+ default:
+ printk("floppy: Asked to write to unknown port %d\n", port);
+ panic("floppy: Port bolixed.");
+ case 2: /* FD_DOR */
+ /* Oh geese, 82072 on the Sun has no DOR register,
+ * the functionality is implemented via the AUXIO
+ * I/O register. So we must emulate the behavior.
+ *
+ * ASSUMPTIONS: There will only ever be one floppy
+ * drive attached to a Sun controller
+ * and it will be at drive zero.
+ */
+ {
+ unsigned bits = 0;
+ if (value & 0x10) bits |= AUXIO_FLPY_DSEL;
+ if ((value & 0x80) == 0) bits |= AUXIO_FLPY_EJCT;
+ set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT));
+ }
+ break;
+ case 5: /* FD_DATA */
+ sun_fdc->data_82072 = value;
+ break;
+ case 7: /* FD_DCR */
+ sun_fdc->dcr_82072 = value;
+ break;
+ case 4: /* FD_STATUS */
+ sun_fdc->status_82072 = value;
+ break;
+ };
+ return;
+}
+
+static unsigned char sun_82077_fd_inb(int port)
+{
+ switch(port & 7) {
+ default:
+ printk("floppy: Asked to read unknown port %d\n", port);
+ panic("floppy: Port bolixed.");
+ case 4: /* FD_STATUS */
+ return sun_fdc->status_82077 & ~STATUS_DMA;
+ case 5: /* FD_DATA */
+ return sun_fdc->data_82077;
+ case 7: /* FD_DIR */
+ /* XXX: Is DCL on 0x80 in sun4m? */
+ return sun_fdc->dir_82077;
+ };
+ panic("sun_82072_fd_inb: How did I get here?");
+}
+
+static void sun_82077_fd_outb(unsigned char value, int port)
+{
+ switch(port & 7) {
+ default:
+ printk("floppy: Asked to write to unknown port %d\n", port);
+ panic("floppy: Port bolixed.");
+ case 2: /* FD_DOR */
+ /* Happily, the 82077 has a real DOR register. */
+ sun_fdc->dor_82077 = value;
+ break;
+ case 5: /* FD_DATA */
+ sun_fdc->data_82077 = value;
+ break;
+ case 7: /* FD_DCR */
+ sun_fdc->dcr_82077 = value;
+ break;
+ case 4: /* FD_STATUS */
+ sun_fdc->status_82077 = value;
+ break;
+ };
+ return;
+}
+
+/* For pseudo-dma (Sun floppy drives have no real DMA available to
+ * them so we must eat the data fifo bytes directly ourselves) we have
+ * three state variables. doing_pdma tells our inline low-level
+ * assembly floppy interrupt entry point whether it should sit and eat
+ * bytes from the fifo or just transfer control up to the higher level
+ * floppy interrupt c-code. I tried very hard but I could not get the
+ * pseudo-dma to work in c-code without getting many overruns and
+ * underruns. If non-zero, doing_pdma encodes the direction of
+ * the transfer for debugging. 1=read 2=write
+ */
+char *pdma_vaddr;
+unsigned long pdma_size;
+volatile int doing_pdma = 0;
+
+/* This is software state */
+char *pdma_base = 0;
+unsigned long pdma_areasize;
+
+/* Common routines to all controller types on the Sparc. */
+static __inline__ void virtual_dma_init(void)
+{
+ /* nothing... */
+}
+
+static __inline__ void sun_fd_disable_dma(void)
+{
+ doing_pdma = 0;
+ if (pdma_base) {
+ mmu_unlockarea(pdma_base, pdma_areasize);
+ pdma_base = 0;
+ }
+}
+
+static __inline__ void sun_fd_set_dma_mode(int mode)
+{
+ switch(mode) {
+ case DMA_MODE_READ:
+ doing_pdma = 1;
+ break;
+ case DMA_MODE_WRITE:
+ doing_pdma = 2;
+ break;
+ default:
+ printk("Unknown dma mode %d\n", mode);
+ panic("floppy: Giving up...");
+ }
+}
+
+static __inline__ void sun_fd_set_dma_addr(char *buffer)
+{
+ pdma_vaddr = buffer;
+}
+
+static __inline__ void sun_fd_set_dma_count(int length)
+{
+ pdma_size = length;
+}
+
+static __inline__ void sun_fd_enable_dma(void)
+{
+ pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
+ pdma_base = pdma_vaddr;
+ pdma_areasize = pdma_size;
+}
+
+/* Our low-level entry point in arch/sparc/kernel/entry.S */
+extern void floppy_hardint(int irq, void *unused, struct pt_regs *regs);
+
+static int sun_fd_request_irq(void)
+{
+ static int once = 0;
+ int error;
+
+ if(!once) {
+ once = 1;
+ error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, SA_INTERRUPT, "floppy");
+ return ((error == 0) ? 0 : -1);
+ } else return 0;
+}
+
+static struct linux_prom_registers fd_regs[2];
+
+static int sun_floppy_init(void)
+{
+ char state[128];
+ int tnode, fd_node, num_regs;
+
+ use_virtual_dma = 1;
+
+ FLOPPY_IRQ = 11;
+ /* Forget it if we aren't on a machine that could possibly
+ * ever have a floppy drive.
+ */
+ if((sparc_cpu_model != sun4c && sparc_cpu_model != sun4m) ||
+ ((idprom->id_machtype == (SM_SUN4C | SM_4C_SLC)) ||
+ (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC)))) {
+ /* We certainly don't have a floppy controller. */
+ goto no_sun_fdc;
+ }
+ /* Well, try to find one. */
+ tnode = prom_getchild(prom_root_node);
+ fd_node = prom_searchsiblings(tnode, "obio");
+ if(fd_node != 0) {
+ tnode = prom_getchild(fd_node);
+ fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo");
+ } else {
+ fd_node = prom_searchsiblings(tnode, "fd");
+ }
+ if(fd_node == 0) {
+ goto no_sun_fdc;
+ }
+
+ /* The sun4m lets us know if the controller is actually usable. */
+ if(sparc_cpu_model == sun4m) {
+ prom_getproperty(fd_node, "status", state, sizeof(state));
+ if(!strcmp(state, "disabled")) {
+ goto no_sun_fdc;
+ }
+ }
+ num_regs = prom_getproperty(fd_node, "reg", (char *) fd_regs, sizeof(fd_regs));
+ num_regs = (num_regs / sizeof(fd_regs[0]));
+ prom_apply_obio_ranges(fd_regs, num_regs);
+ sun_fdc = (struct sun_flpy_controller *) sparc_alloc_io(fd_regs[0].phys_addr,
+ 0x0,
+ fd_regs[0].reg_size,
+ "floppy",
+ fd_regs[0].which_io,
+ 0x0);
+ /* Last minute sanity check... */
+ if(sun_fdc->status_82072 == 0xff) {
+ sun_fdc = NULL;
+ goto no_sun_fdc;
+ }
+
+ if(sparc_cpu_model == sun4c) {
+ sun_fdops.fd_inb = sun_82072_fd_inb;
+ sun_fdops.fd_outb = sun_82072_fd_outb;
+ fdc_status = &sun_fdc->status_82072;
+ /* printk("AUXIO @0x%p\n", auxio_register); */ /* P3 */
+ } else {
+ sun_fdops.fd_inb = sun_82077_fd_inb;
+ sun_fdops.fd_outb = sun_82077_fd_outb;
+ fdc_status = &sun_fdc->status_82077;
+ /* printk("DOR @0x%p\n", &sun_fdc->dor_82077); */ /* P3 */
+ }
+
+ /* Success... */
+ return (int) sun_fdc;
+
+no_sun_fdc:
+ return -1;
+}
+
+static int sparc_eject(void)
+{
+ set_dor(0x00, 0xff, 0x90);
+ udelay(500);
+ set_dor(0x00, 0x6f, 0x00);
+ udelay(500);
+ return 0;
+}
+
+#define fd_eject(drive) sparc_eject()
+
+#endif /* !(__ASM_SPARC_FLOPPY_H) */
diff --git a/include/asm-sparc/head.h b/include/asm-sparc/head.h
index b26067623..f89e41fc8 100644
--- a/include/asm-sparc/head.h
+++ b/include/asm-sparc/head.h
@@ -1,75 +1,114 @@
+/* $Id: head.h,v 1.30 1996/07/29 21:00:28 miguel Exp $ */
#ifndef __SPARC_HEAD_H
#define __SPARC_HEAD_H
-#define KERNSIZE 134217728 /* this is how much of a mapping the prom promises */
-#define PAGESIZE 4096 /* luckily this is the same on sun4c's and sun4m's */
-#define PAGESHIFT 12
-#define PROM_BASE -1568768 /* casa 'de PROM */
-#define LOAD_ADDR 0x4000 /* prom jumps to us here */
-#define C_STACK 96
+#define KERNBASE 0xf0000000 /* First address the kernel will eventually be */
+#define LOAD_ADDR 0x4000 /* prom jumps to us here unless this is elf /boot */
#define SUN4C_SEGSZ (1 << 18)
-#define USRSTACK 0x0 /* no joke, this is temporary, trust me */
-#define INT_ENABLE_REG_PHYSADR 0xf5000000
-#define INTS_ENAB 0x01
+#define SRMMU_L1_KBASE_OFFSET ((KERNBASE>>24)<<2) /* Used in boot remapping. */
+#define INTS_ENAB 0x01 /* entry.S uses this. */
-#define BOOT_MSG_LEN 61
-#define BOOT_MSG2_LEN 50
+#define NCPUS 4 /* Architectural limit of sun4m. */
+#define SUN4_PROM_VECTOR 0xFFE81000 /* To safely die on a SUN4 */
+#define SUN4_PRINTF 0x84 /* Offset into SUN4_PROM_VECTOR */
-#define WRITE_PAUSE nop; nop; nop;
-
-#define PAGE_SIZE 4096
+#define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */
+#define NOP_INSN 0x01000000 /* Used to patch sparc_save_state */
/* Here are some trap goodies */
-
/* Generic trap entry. */
-
#define TRAP_ENTRY(type, label) \
- mov (type), %l3; b label; rd %psr, %l0; nop;
+ rd %psr, %l0; b label; rd %wim, %l3; nop;
+
+/* Data/text faults. Defaults to sun4c version at boot time. */
+#define SPARC_TFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 1, %l7;
+#define SPARC_DFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 0, %l7;
+#define SRMMU_TFAULT rd %psr, %l0; rd %wim, %l3; b C_LABEL(srmmu_fault); mov 1, %l7;
+#define SRMMU_DFAULT rd %psr, %l0; rd %wim, %l3; b C_LABEL(srmmu_fault); mov 0, %l7;
+
+/* This is for traps we should NEVER get. */
+#define BAD_TRAP(num) \
+ rd %psr, %l0; mov num, %l7; b bad_trap_handler; rd %wim, %l3;
+
+/* Notice that for the system calls we pull a trick. We load up a
+ * different pointer to the system call vector table in %l7, but call
+ * the same generic system call low-level entry point. The trap table
+ * entry sequences are also HyperSparc pipeline friendly ;-)
+ */
+
+/* Software trap for Linux system calls. */
+#define LINUX_SYSCALL_TRAP \
+ sethi %hi(C_LABEL(sys_call_table)), %l7; \
+ or %l7, %lo(C_LABEL(sys_call_table)), %l7; \
+ b linux_sparc_syscall; \
+ rd %psr, %l0;
+
+/* Software trap for SunOS4.1.x system calls. */
+#define SUNOS_SYSCALL_TRAP \
+ rd %psr, %l0; \
+ sethi %hi(C_LABEL(sunos_sys_table)), %l7; \
+ b linux_sparc_syscall; \
+ or %l7, %lo(C_LABEL(sunos_sys_table)), %l7;
+
+/* Software trap for Slowaris system calls. */
+#define SOLARIS_SYSCALL_TRAP \
+ sethi %hi(C_LABEL(sys_call_table)), %l7; \
+ or %l7, %lo(C_LABEL(sys_call_table)), %l7; \
+ b solaris_syscall; \
+ rd %psr, %l0;
+
+#define INDIRECT_SOLARIS_SYSCALL(x) \
+ sethi %hi(C_LABEL(sys_call_table)), %l7; \
+ or %g0,%lo(x),%g1; \
+ b solaris_indirect_syscall; \
+ rd %psr, %l0;
+
+#define BREAKPOINT_TRAP \
+ b breakpoint_trap; \
+ rd %psr,%l0; \
+ nop; \
+ nop;
+
+/* Software trap for Sparc-netbsd system calls. */
+#define NETBSD_SYSCALL_TRAP \
+ sethi %hi(C_LABEL(sys_call_table)), %l7; \
+ or %l7, %lo(C_LABEL(sys_call_table)), %l7; \
+ b bsd_syscall; \
+ rd %psr, %l0;
+
+/* The Get Condition Codes software trap for userland. */
+#define GETCC_TRAP \
+ b getcc_trap_handler; mov %psr, %l0; nop; nop;
+
+/* The Set Condition Codes software trap for userland. */
+#define SETCC_TRAP \
+ b setcc_trap_handler; mov %psr, %l0; nop; nop;
/* This is for hard interrupts from level 1-14, 15 is non-maskable (nmi) and
* gets handled with another macro.
*/
-
#define TRAP_ENTRY_INTERRUPT(int_level) \
- mov int_level, %l3; b stray_irq_entry; rd %psr, %l0; nop;
-
-/* Here is the macro for soft interrupts (ie. not as urgent as hard ones)
- * which need to jump to a different handler.
+ mov int_level, %l7; rd %psr, %l0; b real_irq_entry; rd %wim, %l3;
+
+/* NMI's (Non Maskable Interrupts) are special, you can't keep them
+ * from coming in, and basically if you get one, the shows over. ;(
+ * On the sun4c they are usually asynchronous memory errors, on the
+ * the sun4m they could be either due to mem errors or a software
+ * initiated interrupt from the prom/kern on an SMP box saying "I
+ * command you to do CPU tricks, read your mailbox for more info."
*/
+#define NMI_TRAP \
+ rd %wim, %l3; b linux_trap_nmi_sun4c; mov %psr, %l0; nop;
-#define TRAP_ENTRY_INTERRUPT_SOFT(int_level, ident) \
- mov int_level, %l3; rd %psr, %l0; b stray_irq_entry; mov ident, %l4;
-
-/* The above two macros are for generic traps. The following is made
- * especially for timer interrupts at IRQ level 14.
- */
-
-#define TRAP_ENTRY_TIMER \
- mov 10, %l3; rd %psr, %l0; b sparc_timer; nop;
-
-/* Non-maskable interrupt entry macro. You have to turn off all interrupts
- * to not receive this. This is usually due to a asynchronous memory error.
- * All we can really do is stop the show. :-(
- */
-
-#define TRAP_ENTRY_INTERRUPT_NMI(t_type, jmp_to) \
- mov t_type, %l3; b jmp_to; rd %psr, %l0; nop;
-
-/* Trap entry code in entry.S needs the offsets into task_struct
- * to get at the thread_struct goodies during window craziness.
- *
- * NOTE: We need to keep these values under 0x3ff in order to do
- * efficient load/stores in the window fill/spill handlers.
- * See TRAP_WIN_CLEAN in entry.S for details.
+/* Window overflows/underflows are special and we need to try to be as
+ * efficient as possible here....
*/
+#define WINDOW_SPILL \
+ rd %psr, %l0; rd %wim, %l3; b spill_window_entry; andcc %l0, PSR_PS, %g0;
-#define THREAD_UWINDOWS 0x3bc
-#define THREAD_WIM 0x3c0
-#define THREAD_W_SAVED 0x3c4
-#define THREAD_KSP 0x3c8
-#define THREAD_USP 0x3cc
-#define THREAD_REG_WINDOW 0x3d4
+#define WINDOW_FILL \
+ rd %psr, %l0; rd %wim, %l3; b fill_window_entry; andcc %l0, PSR_PS, %g0;
#endif __SPARC_HEAD_H
diff --git a/include/asm-sparc/idprom.h b/include/asm-sparc/idprom.h
index e7a136891..d856e640a 100644
--- a/include/asm-sparc/idprom.h
+++ b/include/asm-sparc/idprom.h
@@ -1,21 +1,33 @@
-/* idprom.h: Macros and defines for idprom routines
+/* $Id: idprom.h,v 1.6 1996/08/04 10:35:07 ecd Exp $
+ * idprom.h: Macros and defines for idprom routines
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
-extern struct linux_romvec *romvec;
+#ifndef _SPARC_IDPROM_H
+#define _SPARC_IDPROM_H
-#define IDPROM_ADDR (0xffd04000 + 0x7d8)
-#define IDPROM_SIZE 36
+/* Offset into the EEPROM where the id PROM is located on the 4c */
+#define IDPROM_OFFSET 0x7d8
-struct idp_struct
+/* On sun4m; physical. */
+/* MicroSPARC(-II) does not decode 31rd bit, but it works. */
+#define IDPROM_OFFSET_M 0xfd8
+
+struct idprom
{
- unsigned char id_f_id; /* format identifier */
- unsigned char id_machtype; /* Machine type */
- unsigned char id_eaddr[6]; /* hardware ethernet address */
- long id_domf; /* Date when this machine was manufactured */
- unsigned int id_sernum:24; /* Unique serial number */
- unsigned char id_cksum; /* XXX */
- unsigned char dummy[16]; /* XXX */
+ unsigned char id_format; /* Format identifier (always 0x01) */
+ unsigned char id_machtype; /* Machine type */
+ unsigned char id_ethaddr[6]; /* Hardware ethernet address */
+ long id_date; /* Date of manufacture */
+ unsigned int id_sernum:24; /* Unique serial number */
+ unsigned char id_cksum; /* Checksum - xor of the data bytes */
+ unsigned char reserved[16];
};
+extern struct idprom *idprom;
+extern void idprom_init(void);
+
+#define IDPROM_SIZE (sizeof(struct idprom))
+
+#endif /* !(_SPARC_IDPROM_H) */
diff --git a/include/asm-sparc/io.h b/include/asm-sparc/io.h
index 5aa1a3fac..88adf1621 100644
--- a/include/asm-sparc/io.h
+++ b/include/asm-sparc/io.h
@@ -1,7 +1,11 @@
+/* $Id: io.h,v 1.10 1996/08/29 09:48:14 davem Exp $ */
#ifndef __SPARC_IO_H
#define __SPARC_IO_H
+#include <linux/kernel.h>
+
#include <asm/page.h> /* IO address mapping routines need this */
+#include <asm/system.h>
/*
* Defines for io operations on the Sparc. Whether a memory access is going
@@ -10,91 +14,129 @@
* space only works on sun4's
*/
-extern inline unsigned long inb_local(unsigned long addr)
+extern __inline__ unsigned long inb_local(unsigned long addr)
{
- return 0;
+ return 0;
}
-extern inline void outb_local(unsigned char b, unsigned long addr)
+extern __inline__ void outb_local(unsigned char b, unsigned long addr)
{
- return;
+ return;
}
-extern inline unsigned long inb(unsigned long addr)
+extern __inline__ unsigned long inb(unsigned long addr)
{
- return 0;
+ return 0;
}
-extern inline unsigned long inw(unsigned long addr)
+extern __inline__ unsigned long inw(unsigned long addr)
{
- return 0;
+ return 0;
}
-extern inline unsigned long inl(unsigned long addr)
+extern __inline__ unsigned long inl(unsigned long addr)
{
- return 0;
+ return 0;
}
-extern inline void outb(unsigned char b, unsigned long addr)
+extern __inline__ void outb(unsigned char b, unsigned long addr)
{
- return;
+ return;
}
-extern inline void outw(unsigned short b, unsigned long addr)
+extern __inline__ void outw(unsigned short b, unsigned long addr)
{
- return;
+ return;
}
-extern inline void outl(unsigned int b, unsigned long addr)
+extern __inline__ void outl(unsigned int b, unsigned long addr)
{
- return;
+ return;
}
/*
* Memory functions
*/
-extern inline unsigned long readb(unsigned long addr)
+extern __inline__ unsigned long readb(unsigned long addr)
{
- return 0;
+ return 0;
}
-extern inline unsigned long readw(unsigned long addr)
+extern __inline__ unsigned long readw(unsigned long addr)
{
- return 0;
+ return 0;
}
-extern inline unsigned long readl(unsigned long addr)
+extern __inline__ unsigned long readl(unsigned long addr)
{
- return 0;
+ return 0;
}
-extern inline void writeb(unsigned short b, unsigned long addr)
+extern __inline__ void writeb(unsigned short b, unsigned long addr)
{
- return;
+ return;
}
-extern inline void writew(unsigned short b, unsigned long addr)
+extern __inline__ void writew(unsigned short b, unsigned long addr)
{
- return;
+ return;
}
-extern inline void writel(unsigned int b, unsigned long addr)
+extern __inline__ void writel(unsigned int b, unsigned long addr)
{
- return;
+ return;
}
#define inb_p inb
#define outb_p outb
-extern inline void mapioaddr(unsigned long physaddr, unsigned long virt_addr)
+extern void sun4c_mapioaddr(unsigned long, unsigned long, int bus_type, int rdonly);
+extern void srmmu_mapioaddr(unsigned long, unsigned long, int bus_type, int rdonly);
+
+extern __inline__ void mapioaddr(unsigned long physaddr, unsigned long virt_addr,
+ int bus, int rdonly)
{
- unsigned long page_entry;
+ switch(sparc_cpu_model) {
+ case sun4c:
+ sun4c_mapioaddr(physaddr, virt_addr, bus, rdonly);
+ break;
+ case sun4m:
+ case sun4d:
+ case sun4e:
+ srmmu_mapioaddr(physaddr, virt_addr, bus, rdonly);
+ break;
+ default:
+ printk("mapioaddr: Trying to map IO space for unsupported machine.\n");
+ printk("mapioaddr: sparc_cpu_model = %d\n", sparc_cpu_model);
+ printk("mapioaddr: Halting...\n");
+ halt();
+ };
+ return;
+}
- page_entry = physaddr >> PAGE_SHIFT;
- page_entry |= (PTE_V | PTE_ACC | PTE_NC | PTE_IO); /* kernel io addr */
+extern void srmmu_unmapioaddr(unsigned long virt);
+extern void sun4c_unmapioaddr(unsigned long virt);
- put_pte(virt_addr, page_entry);
- return;
+extern __inline__ void unmapioaddr(unsigned long virt_addr)
+{
+ switch(sparc_cpu_model) {
+ case sun4c:
+ sun4c_unmapioaddr(virt_addr);
+ break;
+ case sun4m:
+ case sun4d:
+ case sun4e:
+ srmmu_unmapioaddr(virt_addr);
+ break;
+ default:
+ printk("unmapioaddr: sparc_cpu_model = %d, halt...\n", sparc_cpu_model);
+ halt();
+ };
+ return;
}
+extern void *sparc_alloc_io (void *, void *, int, char *, int, int);
+extern void sparc_free_io (void *, int);
+extern void *sparc_dvma_malloc (int, char *);
+
#endif /* !(__SPARC_IO_H) */
diff --git a/include/asm-sparc/ioctl.h b/include/asm-sparc/ioctl.h
new file mode 100644
index 000000000..e6c645fff
--- /dev/null
+++ b/include/asm-sparc/ioctl.h
@@ -0,0 +1,43 @@
+/* $Id: ioctl.h,v 1.5 1996/05/17 03:31:09 davem Exp $ */
+#ifndef _SPARC_IOCTL_H
+#define _SPARC_IOCTL_H
+
+#define _IOC_NRBITS 8
+#define _IOC_TYPEBITS 8
+#define _IOC_SIZEBITS 8
+#define _IOC_RESVBITS 5
+#define _IOC_DIRBITS 3
+
+#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
+#define _IOC_RESVMASK ((1 << _IOC_RESVBITS)-1)
+#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT 0
+#define _IOC_TYPESHIFT (_IOC_NRSHIFT + _IOC_NRBITS)
+#define _IOC_SIZESHIFT (_IOC_TYPESHIFT + _IOC_TYPEBITS)
+#define _IOC_RESVSHIFT (_IOC_SIZESHIFT + _IOC_SIZEBITS)
+#define _IOC_DIRSHIFT (_IOC_RESVSHIFT + _IOC_RESVBITS)
+
+#define _IOC_NONE 1U
+#define _IOC_READ 2U
+#define _IOC_WRITE 4U
+
+#define _IOC(dir,type,nr,size) \
+ (((dir) << _IOC_DIRSHIFT) | \
+ ((type) << _IOC_TYPESHIFT) | \
+ ((nr) << _IOC_NRSHIFT) | \
+ ((size) << _IOC_SIZESHIFT))
+
+#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+#endif /* !(_SPARC_IOCTL_H) */
diff --git a/include/asm-sparc/ioctls.h b/include/asm-sparc/ioctls.h
new file mode 100644
index 000000000..80eff02ea
--- /dev/null
+++ b/include/asm-sparc/ioctls.h
@@ -0,0 +1,128 @@
+#ifndef _ASM_SPARC_IOCTLS_H
+#define _ASM_SPARC_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+/* Big T */
+#define TCGETA _IOR('T', 1, struct termio)
+#define TCSETA _IOW('T', 2, struct termio)
+#define TCSETAW _IOW('T', 3, struct termio)
+#define TCSETAF _IOW('T', 4, struct termio)
+#define TCSBRK _IO('T', 5)
+#define TCXONC _IO('T', 6)
+#define TCFLSH _IO('T', 7)
+#define TCGETS _IOR('T', 8, struct termios)
+#define TCSETS _IOW('T', 9, struct termios)
+#define TCSETSW _IOW('T', 10, struct termios)
+#define TCSETSF _IOW('T', 11, struct termios)
+
+/* Note that all the ioctls that are not available in Linux have a
+ * double underscore on the front to: a) avoid some programs to
+ * thing we support some ioctls under Linux (autoconfiguration stuff)
+ */
+/* Little t */
+#define TIOCGETD _IOR('t', 0, int)
+#define TIOCSETD _IOW('t', 1, int)
+#define __TIOCHPCL _IO('t', 2) /* SunOS Specific */
+#define __TIOCMODG _IOR('t', 3, int) /* SunOS Specific */
+#define __TIOCMODS _IOW('t', 4, int) /* SunOS Specific */
+#define __TIOCGETP _IOR('t', 8, struct sgttyb) /* SunOS Specific */
+#define __TIOCSETP _IOW('t', 9, struct sgttyb) /* SunOS Specific */
+#define __TIOCSETN _IOW('t', 10, struct sgttyb) /* SunOS Specific */
+#define TIOCEXCL _IO('t', 13)
+#define TIOCNXCL _IO('t', 14)
+#define __TIOCFLUSH _IOW('t', 16, int) /* SunOS Specific */
+#define __TIOCSETC _IOW('t', 17, struct tchars) /* SunOS Specific */
+#define __TIOCGETC _IOR('t', 18, struct tchars) /* SunOS Specific */
+#define __TIOCTCNTL _IOW('t', 32, int) /* SunOS Specific */
+#define __TIOCSIGNAL _IOW('t', 33, int) /* SunOS Specific */
+#define __TIOCSETX _IOW('t', 34, int) /* SunOS Specific */
+#define __TIOCGETX _IOR('t', 35, int) /* SunOS Specific */
+#define TIOCCONS _IO('t', 36)
+#define __TIOCSSIZE _IOW('t', 37, struct sunos_ttysize) /* SunOS Specific */
+#define __TIOCGSIZE _IOR('t', 38, struct sunos_ttysize) /* SunOS Specific */
+#define TIOCGSOFTCAR _IOR('t', 100, int)
+#define TIOCSSOFTCAR _IOW('t', 101, int)
+#define __TIOCUCNTL _IOW('t', 102, int) /* SunOS Specific */
+#define TIOCSWINSZ _IOW('t', 103, struct winsize)
+#define TIOCGWINSZ _IOR('t', 104, struct winsize)
+#define __TIOCREMOTE _IOW('t', 105, int) /* SunOS Specific */
+#define TIOCMGET _IOR('t', 106, int)
+#define TIOCMBIC _IOW('t', 107, int)
+#define TIOCMBIS _IOW('t', 108, int)
+#define TIOCMSET _IOW('t', 109, int)
+#define __TIOCSTART _IO('t', 110) /* SunOS Specific */
+#define __TIOCSTOP _IO('t', 111) /* SunOS Specific */
+#define TIOCPKT _IOW('t', 112, int)
+#define TIOCNOTTY _IO('t', 113)
+#define TIOCSTI _IOW('t', 114, char)
+#define TIOCOUTQ _IOR('t', 115, int)
+#define __TIOCGLTC _IOR('t', 116, struct ltchars) /* SunOS Specific */
+#define __TIOCSLTC _IOW('t', 117, struct ltchars) /* SunOS Specific */
+/* 118 is the non-posix setpgrp tty ioctl */
+/* 119 is the non-posix getpgrp tty ioctl */
+#define __TIOCCDTR _IO('t', 120) /* SunOS Specific */
+#define __TIOCSDTR _IO('t', 121) /* SunOS Specific */
+#define __TIOCCBRK _IO('t', 122) /* SunOS Specific */
+#define __TIOCSBRK _IO('t', 123) /* SunOS Specific */
+#define __TIOCLGET _IOW('t', 124, int) /* SunOS Specific */
+#define __TIOCLSET _IOW('t', 125, int) /* SunOS Specific */
+#define __TIOCLBIC _IOW('t', 126, int) /* SunOS Specific */
+#define __TIOCLBIS _IOW('t', 127, int) /* SunOS Specific */
+#define __TIOCISPACE _IOR('t', 128, int) /* SunOS Specific */
+#define __TIOCISIZE _IOR('t', 129, int) /* SunOS Specific */
+#define TIOCSPGRP _IOW('t', 130, int)
+#define TIOCGPGRP _IOR('t', 131, int)
+#define TIOCSCTTY _IO('t', 132)
+
+/* Little f */
+#define FIOCLEX _IO('f', 1)
+#define FIONCLEX _IO('f', 2)
+#define FIOASYNC _IOW('f', 125, int)
+#define FIONBIO _IOW('f', 126, int)
+#define FIONREAD _IOR('f', 127, int)
+#define TIOCINQ FIONREAD
+
+/* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it
+ * someday. This is completely bogus, I know...
+ */
+#define __TCGETSTAT _IO('T', 200) /* Rutgers specific */
+#define __TCSETSTAT _IO('T', 201) /* Rutgers specific */
+
+/* Linux specific, no SunOS equivalent. */
+#define TIOCLINUX 0x541C
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TCSBRKP 0x5425
+#define TIOCTTYGSTRUCT 0x5426
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
+#define TIOCSERGETLSR 0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+/* Kernel definitions */
+#ifdef __KERNEL__
+#define TIOCGETC __TIOCGETC
+#define TIOCGETP __TIOCGETP
+#define TIOCGLTC __TIOCGLTC
+#define TIOCSLTC __TIOCSLTC
+#define TIOCSETP __TIOCSETP
+#define TIOCSETN __TIOCSETN
+#define TIOCSETC __TIOCSETC
+#endif
+
+/* Used for packet mode */
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+
+#endif /* !(_ASM_SPARC_IOCTLS_H) */
diff --git a/include/asm-sparc/iommu.h b/include/asm-sparc/iommu.h
new file mode 100644
index 000000000..cf1d5b794
--- /dev/null
+++ b/include/asm-sparc/iommu.h
@@ -0,0 +1,120 @@
+/* iommu.h: Definitions for the sun4m IOMMU.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_IOMMU_H
+#define _SPARC_IOMMU_H
+
+#include <asm/page.h>
+
+/* The iommu handles all virtual to physical address translations
+ * that occur between the SBUS and physical memory. Access by
+ * the cpu to IO registers and similar go over the mbus so are
+ * translated by the on chip SRMMU. The iommu and the srmmu do
+ * not need to have the same translations at all, in fact most
+ * of the time the translations they handle are a disjunct set.
+ * Basically the iommu handles all dvma sbus activity.
+ */
+
+/* The IOMMU registers occupy three pages in IO space. */
+struct iommu_regs {
+ /* First page */
+ volatile unsigned long control; /* IOMMU control */
+ volatile unsigned long base; /* Physical base of iopte page table */
+ volatile unsigned long _unused1[3];
+ volatile unsigned long tlbflush; /* write only */
+ volatile unsigned long pageflush; /* write only */
+ volatile unsigned long _unused2[1017];
+ /* Second page */
+ volatile unsigned long afsr; /* Async-fault status register */
+ volatile unsigned long afar; /* Async-fault physical address */
+ volatile unsigned long _unused3[2];
+ volatile unsigned long sbuscfg0; /* SBUS configuration registers, per-slot */
+ volatile unsigned long sbuscfg1;
+ volatile unsigned long sbuscfg2;
+ volatile unsigned long sbuscfg3;
+ volatile unsigned long mfsr; /* Memory-fault status register */
+ volatile unsigned long mfar; /* Memory-fault physical address */
+ volatile unsigned long _unused4[1014];
+ /* Third page */
+ volatile unsigned long mid; /* IOMMU module-id */
+};
+
+#define IOMMU_CTRL_IMPL 0xf0000000 /* Implementation */
+#define IOMMU_CTRL_VERS 0x0f000000 /* Version */
+#define IOMMU_CTRL_RNGE 0x0000001c /* Mapping RANGE */
+#define IOMMU_RNGE_16MB 0x00000000 /* 0xff000000 -> 0xffffffff */
+#define IOMMU_RNGE_32MB 0x00000004 /* 0xfe000000 -> 0xffffffff */
+#define IOMMU_RNGE_64MB 0x00000008 /* 0xfc000000 -> 0xffffffff */
+#define IOMMU_RNGE_128MB 0x0000000c /* 0xf8000000 -> 0xffffffff */
+#define IOMMU_RNGE_256MB 0x00000010 /* 0xf0000000 -> 0xffffffff */
+#define IOMMU_RNGE_512MB 0x00000014 /* 0xe0000000 -> 0xffffffff */
+#define IOMMU_RNGE_1GB 0x00000018 /* 0xc0000000 -> 0xffffffff */
+#define IOMMU_RNGE_2GB 0x0000001c /* 0x80000000 -> 0xffffffff */
+#define IOMMU_CTRL_ENAB 0x00000001 /* IOMMU Enable */
+
+#define IOMMU_AFSR_ERR 0x80000000 /* LE, TO, or BE asserted */
+#define IOMMU_AFSR_LE 0x40000000 /* SBUS reports error after transaction */
+#define IOMMU_AFSR_TO 0x20000000 /* Write access took more than 12.8 us. */
+#define IOMMU_AFSR_BE 0x10000000 /* Write access received error acknowledge */
+#define IOMMU_AFSR_SIZE 0x0e000000 /* Size of transaction causing error */
+#define IOMMU_AFSR_S 0x01000000 /* Sparc was in supervisor mode */
+#define IOMMU_AFSR_RESV 0x00f00000 /* Reserver, forced to 0x8 by hardware */
+#define IOMMU_AFSR_ME 0x00080000 /* Multiple errors occurred */
+#define IOMMU_AFSR_RD 0x00040000 /* A read operation was in progress */
+#define IOMMU_AFSR_FAV 0x00020000 /* IOMMU afar has valid contents */
+
+#define IOMMU_SBCFG_SAB30 0x00010000 /* Phys-address bit 30 when bypass enabled */
+#define IOMMU_SBCFG_BA16 0x00000004 /* Slave supports 16 byte bursts */
+#define IOMMU_SBCFG_BA8 0x00000002 /* Slave supports 8 byte bursts */
+#define IOMMU_SBCFG_BYPASS 0x00000001 /* Bypass IOMMU, treat all addresses
+ produced by this device as pure
+ physical. */
+
+#define IOMMU_MFSR_ERR 0x80000000 /* One or more of PERR1 or PERR0 */
+#define IOMMU_MFSR_S 0x01000000 /* Sparc was in supervisor mode */
+#define IOMMU_MFSR_CPU 0x00800000 /* CPU transaction caused parity error */
+#define IOMMU_MFSR_ME 0x00080000 /* Multiple parity errors occurred */
+#define IOMMU_MFSR_PERR 0x00006000 /* high bit indicates parity error occurred
+ on the even word of the access, low bit
+ indicated odd word caused the parity error */
+#define IOMMU_MFSR_BM 0x00001000 /* Error occurred while in boot mode */
+#define IOMMU_MFSR_C 0x00000800 /* Address causing error was marked cacheable */
+#define IOMMU_MFSR_RTYP 0x000000f0 /* Memory request transaction type */
+
+#define IOMMU_MID_SBAE 0x001f0000 /* SBus arbitration enable */
+#define IOMMU_MID_SE 0x00100000 /* Enables SCSI/ETHERNET arbitration */
+#define IOMMU_MID_SB3 0x00080000 /* Enable SBUS device 3 arbitration */
+#define IOMMU_MID_SB2 0x00040000 /* Enable SBUS device 2 arbitration */
+#define IOMMU_MID_SB1 0x00020000 /* Enable SBUS device 1 arbitration */
+#define IOMMU_MID_SB0 0x00010000 /* Enable SBUS device 0 arbitration */
+#define IOMMU_MID_MID 0x0000000f /* Module-id, hardcoded to 0x8 */
+
+/* The format of an iopte in the page tables */
+#define IOPTE_PAGE 0x07ffff00 /* Physical page number (PA[30:12]) */
+#define IOPTE_CACHE 0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */
+#define IOPTE_WRITE 0x00000004 /* Writeable */
+#define IOPTE_VALID 0x00000002 /* IOPTE is valid */
+#define IOPTE_WAZ 0x00000001 /* Write as zeros */
+
+struct iommu_struct {
+ struct iommu_regs *regs;
+ iopte_t *page_table;
+ iopte_t *lowest; /* to speed up searches... */
+ unsigned long plow;
+ /* For convenience */
+ unsigned long start; /* First managed virtual address */
+ unsigned long end; /* Last managed virtual address */
+};
+
+extern __inline__ void iommu_invalidate(struct iommu_regs *regs)
+{
+ regs->tlbflush = 0;
+}
+
+extern __inline__ void iommu_invalidate_page(struct iommu_regs *regs, unsigned long page)
+{
+ regs->pageflush = (page & PAGE_MASK);
+}
+
+#endif /* !(_SPARC_IOMMU_H) */
diff --git a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h
index 0e96ffb8c..7b1a13efb 100644
--- a/include/asm-sparc/irq.h
+++ b/include/asm-sparc/irq.h
@@ -1,43 +1,126 @@
-#ifndef _ALPHA_IRQ_H
-#define _ALPHA_IRQ_H
-
-/*
- * linux/include/asm-sparc/irq.h
+/* $Id: irq.h,v 1.14 1996/08/29 09:48:18 davem Exp $
+ * irq.h: IRQ registers on the Sparc.
*
- * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
+#ifndef _SPARC_IRQ_H
+#define _SPARC_IRQ_H
+
#include <linux/linkage.h>
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
+#include <asm/system.h> /* For NCPUS */
+
+#define NR_IRQS 15
+
+/* Dave Redman (djhr@tadpole.co.uk)
+ * changed these to function pointers.. it saves cycles and will allow
+ * the irq dependencies to be split into different files at a later date
+ * sun4c_irq.c, sun4m_irq.c etc so we could reduce the kernel size.
+ */
+extern void (*disable_irq)(unsigned int);
+extern void (*enable_irq)(unsigned int);
+extern void (*clear_clock_irq)( void );
+extern void (*clear_profile_irq)( void );
+extern void (*load_profile_irq)( unsigned int timeout );
+extern void (*init_timers)(void (*lvl10_irq)(int, void *, struct pt_regs *));
+extern void claim_ticker14(void (*irq_handler)(int, void *, struct pt_regs *),
+ int irq,
+ unsigned int timeout);
+
+#ifdef __SMP__
+extern void (*set_cpu_int)(int, int);
+extern void (*clear_cpu_int)(int, int);
+extern void (*set_irq_udt)(int);
+#endif
+
+extern int request_fast_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, __const__ char *devname);
+
+/* On the sun4m, just like the timers, we have both per-cpu and master
+ * interrupt registers.
+ */
+
+/* These registers are used for sending/receiving irqs from/to
+ * different cpu's.
+ */
+struct sun4m_intreg_percpu {
+ unsigned int tbt; /* Interrupts still pending for this cpu. */
-#define __STR(x) #x
-#define STR(x) __STR(x)
-
-#define SAVE_ALL "xx"
+ /* These next two registers are WRITE-ONLY and are only
+ * "on bit" sensitive, "off bits" written have NO affect.
+ */
+ unsigned int clear; /* Clear this cpus irqs here. */
+ unsigned int set; /* Set this cpus irqs here. */
+ unsigned char space[PAGE_SIZE - 12];
+};
-#define SAVE_MOST "yy"
+/*
+ * djhr
+ * Actually the clear and set fields in this struct are misleading..
+ * according to the SLAVIO manual (and the same applies for the SEC)
+ * the clear field clears bits in the mask which will ENABLE that IRQ
+ * the set field sets bits in the mask to DISABLE the IRQ.
+ *
+ * Also the undirected_xx address in the SLAVIO is defined as
+ * RESERVED and write only..
+ *
+ * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor
+ * sun4m machines, for MP the layout makes more sense.
+ */
+struct sun4m_intregs {
+ struct sun4m_intreg_percpu cpu_intregs[NCPUS];
+ unsigned int tbt; /* IRQ's that are still pending. */
+ unsigned int irqs; /* Master IRQ bits. */
-#define RESTORE_MOST "zz"
+ /* Again, like the above, two these registers are WRITE-ONLY. */
+ unsigned int clear; /* Clear master IRQ's by setting bits here. */
+ unsigned int set; /* Set master IRQ's by setting bits here. */
-#define ACK_FIRST(mask) "aa"
+ /* This register is both READ and WRITE. */
+ unsigned int undirected_target; /* Which cpu gets undirected irqs. */
+};
-#define ACK_SECOND(mask) "dummy"
+extern struct sun4m_intregs *sun4m_interrupts;
+
+/*
+ * Bit field defines for the interrupt registers on various
+ * Sparc machines.
+ */
+
+/* The sun4c interrupt register. */
+#define SUN4C_INT_ENABLE 0x01 /* Allow interrupts. */
+#define SUN4C_INT_E14 0x80 /* Enable level 14 IRQ. */
+#define SUN4C_INT_E10 0x20 /* Enable level 10 IRQ. */
+#define SUN4C_INT_E8 0x10 /* Enable level 8 IRQ. */
+#define SUN4C_INT_E6 0x08 /* Enable level 6 IRQ. */
+#define SUN4C_INT_E4 0x04 /* Enable level 4 IRQ. */
+#define SUN4C_INT_E1 0x02 /* Enable level 1 IRQ. */
+
+/* Dave Redman (djhr@tadpole.co.uk)
+ * The sun4m interrupt registers.
+ */
+#define SUN4M_INT_ENABLE 0x80000000
+#define SUN4M_INT_E14 0x00000080
+#define SUN4M_INT_E10 0x00080000
-#define UNBLK_FIRST(mask) "dummy"
+#define SUN4M_HARD_INT(x) (0x000000001 << (x))
+#define SUN4M_SOFT_INT(x) (0x000010000 << (x))
-#define UNBLK_SECOND(mask) "dummy"
+#define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */
+#define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */
+#define SUN4M_INT_M2S_WRITE 0x20000000 /* write buffer error */
+#define SUN4M_INT_ECC 0x10000000 /* ecc memory error */
+#define SUN4M_INT_FLOPPY 0x00400000 /* floppy disk */
+#define SUN4M_INT_MODULE 0x00200000 /* module interrupt */
+#define SUN4M_INT_VIDEO 0x00100000 /* onboard video */
+#define SUN4M_INT_REALTIME 0x00080000 /* system timer */
+#define SUN4M_INT_SCSI 0x00040000 /* onboard scsi */
+#define SUN4M_INT_AUDIO 0x00020000 /* audio/isdn */
+#define SUN4M_INT_ETHERNET 0x00010000 /* onboard ethernet */
+#define SUN4M_INT_SERIAL 0x00008000 /* serial ports */
+#define SUN4M_INT_KBDMS 0x00004000 /* keyboard/mouse */
+#define SUN4M_INT_SBUSBITS 0x00003F80 /* sbus int bits */
-#define IRQ_NAME2(nr) nr##_interrupt(void)
-#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
-#define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
-#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
-
-#define BUILD_IRQ(chip,nr,mask) \
-asmlinkage void IRQ_NAME(nr); \
-asmlinkage void FAST_IRQ_NAME(nr); \
-asmlinkage void BAD_IRQ_NAME(nr); \
-asm code comes here
+#define SUN4M_INT_SBUS(x) (1 << (x+7))
#endif
diff --git a/include/asm-sparc/kbio.h b/include/asm-sparc/kbio.h
new file mode 100644
index 000000000..7382d396f
--- /dev/null
+++ b/include/asm-sparc/kbio.h
@@ -0,0 +1,44 @@
+#ifndef __LINUX_KBIO_H
+#define __LINUX_KBIO_H
+
+/* Return keyboard type */
+#define KIOCTYPE _IOR('k', 9, int)
+/* Return Keyboard layout */
+#define KIOCLAYOUT _IOR('k', 20, int)
+
+enum {
+ TR_NONE,
+ TR_ASCII, /* keyboard is in regular state */
+ TR_EVENT, /* keystrokes sent as firm events */
+ TR_UNTRANS_EVENT /* EVENT+up and down+no translation */
+};
+
+/* Return the current keyboard translation */
+#define KIOCGTRANS _IOR('k', 5, int)
+/* Set the keyboard translation */
+#define KIOCTRANS _IOW('k', 0, int)
+
+/* Send a keyboard command */
+#define KIOCCMD _IOW('k', 8, int)
+
+/* Return if keystrokes are being sent to /dev/kbd */
+
+/* Set routing of keystrokes to /dev/kbd */
+#define KIOCSDIRECT _IOW('k', 10, int)
+
+/* Set keyboard leds */
+#define KIOCSLED _IOW('k', 14, unsigned char)
+
+/* Get keyboard leds */
+#define KIOCGLED _IOR('k', 15, unsigned char)
+
+/* Top bit records if the key is up or down */
+#define KBD_UP 0x80
+
+/* Usable information */
+#define KBD_KEYMASK 0x7f
+
+/* All keys up */
+#define KBD_IDLE 0x75
+
+#endif /* __LINUX_KBIO_H */
diff --git a/include/asm-sparc/kdebug.h b/include/asm-sparc/kdebug.h
new file mode 100644
index 000000000..8607d9b5c
--- /dev/null
+++ b/include/asm-sparc/kdebug.h
@@ -0,0 +1,79 @@
+/* $Id: kdebug.h,v 1.9 1996/05/10 19:52:35 davem Exp $
+ * kdebug.h: Defines and definitions for debugging the Linux kernel
+ * under various kernel debuggers.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_KDEBUG_H
+#define _SPARC_KDEBUG_H
+
+#include <asm/openprom.h>
+
+/* The debugger lives in 1MB of virtual address space right underneath
+ * the boot prom.
+ */
+
+#define DEBUG_FIRSTVADDR 0xffc00000
+#define DEBUG_LASTVADDR LINUX_OPPROM_BEGVM
+
+/* Breakpoints are enter through trap table entry 126. So in sparc assembly
+ * if you want to drop into the debugger you do:
+ *
+ * t DEBUG_BP_TRAP
+ */
+
+#define DEBUG_BP_TRAP 126
+
+#ifndef __ASSEMBLY__
+/* The debug vector is passed in %o1 at boot time. It is a pointer to
+ * a structure in the debuggers address space. Here is its format.
+ */
+
+typedef unsigned int (*debugger_funct)(void);
+
+struct kernel_debug {
+ /* First the entry point into the debugger. You jump here
+ * to give control over to the debugger.
+ */
+ unsigned long kdebug_entry;
+ unsigned long kdebug_trapme; /* Figure out later... */
+ /* The following is the number of pages that the debugger has
+ * taken from to total pool.
+ */
+ unsigned long *kdebug_stolen_pages;
+ /* Ok, after you remap yourself and/or change the trap table
+ * from what you were left with at boot time you have to call
+ * this synchronization function so the debugger can check out
+ * what you have done.
+ */
+ debugger_funct teach_debugger;
+}; /* I think that is it... */
+
+extern struct kernel_debug *linux_dbvec;
+
+/* Use this macro in C-code to enter the debugger. */
+extern __inline__ void sp_enter_debugger(void)
+{
+ __asm__ __volatile__("jmpl %0, %%o7\n\t"
+ "nop\n\t" : :
+ "r" (linux_dbvec) : "o7", "memory");
+}
+
+#define SP_ENTER_DEBUGGER do { \
+ if((linux_dbvec!=0) && ((*(short *)linux_dbvec)!=-1)) \
+ sp_enter_debugger(); \
+ } while(0)
+
+#endif /* !(__ASSEMBLY__) */
+
+/* Some nice offset defines for assembler code. */
+#define KDEBUG_ENTRY_OFF 0x0
+#define KDEBUG_DUNNO_OFF 0x4
+#define KDEBUG_DUNNO2_OFF 0x8
+#define KDEBUG_TEACH_OFF 0xc
+
+/* ugh... */
+#define TRAP_TRACE(reg1, reg2) \
+
+
+#endif /* !(_SPARC_KDEBUG_H) */
diff --git a/include/asm-sparc/kgdb.h b/include/asm-sparc/kgdb.h
new file mode 100644
index 000000000..79534dac8
--- /dev/null
+++ b/include/asm-sparc/kgdb.h
@@ -0,0 +1,90 @@
+/* $Id: kgdb.h,v 1.7 1995/11/27 02:43:18 davem Exp $
+ * kgdb.h: Defines and declarations for serial line source level
+ * remote debugging of the Linux kernel using gdb.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_KGDB_H
+#define _SPARC_KGDB_H
+
+#ifndef __ASSEMBLY__
+/* To init the kgdb engine. */
+extern void set_debug_traps(void);
+
+/* To enter the debugger explicitly. */
+extern void breakpoint(void);
+
+/* For convenience we define the format of a kgdb trap breakpoint
+ * frame here also.
+ */
+struct kgdb_frame {
+ unsigned long globals[8];
+ unsigned long outs[8];
+ unsigned long locals[8];
+ unsigned long ins[8];
+ unsigned long fpregs[32];
+ unsigned long y;
+ unsigned long psr;
+ unsigned long wim;
+ unsigned long tbr;
+ unsigned long pc;
+ unsigned long npc;
+ unsigned long fpsr;
+ unsigned long cpsr;
+};
+#endif /* !(__ASSEMBLY__) */
+
+/* Macros for assembly usage of the kgdb breakpoint frame. */
+#define KGDB_G0 0x000
+#define KGDB_G1 0x004
+#define KGDB_G2 0x008
+#define KGDB_G4 0x010
+#define KGDB_G6 0x018
+#define KGDB_I0 0x020
+#define KGDB_I2 0x028
+#define KGDB_I4 0x030
+#define KGDB_I6 0x038
+#define KGDB_Y 0x100
+#define KGDB_PSR 0x104
+#define KGDB_WIM 0x108
+#define KGDB_TBR 0x10c
+#define KGDB_PC 0x110
+#define KGDB_NPC 0x114
+
+#define SAVE_KGDB_GLOBALS(reg) \
+ std %g0, [%reg + REGWIN_SZ + KGDB_G0]; \
+ std %g2, [%reg + REGWIN_SZ + KGDB_G2]; \
+ std %g4, [%reg + REGWIN_SZ + KGDB_G4]; \
+ std %g6, [%reg + REGWIN_SZ + KGDB_G6];
+
+#define SAVE_KGDB_INS(reg) \
+ std %i0, [%reg + REGWIN_SZ + KGDB_I0]; \
+ std %i2, [%reg + REGWIN_SZ + KGDB_I2]; \
+ std %i4, [%reg + REGWIN_SZ + KGDB_I4]; \
+ std %i6, [%reg + REGWIN_SZ + KGDB_I6];
+
+#define SAVE_KGDB_SREGS(reg, reg_y, reg_psr, reg_wim, reg_tbr, reg_pc, reg_npc) \
+ st %reg_y, [%reg + REGWIN_SZ + KGDB_Y]; \
+ st %reg_psr, [%reg + REGWIN_SZ + KGDB_PSR]; \
+ st %reg_wim, [%reg + REGWIN_SZ + KGDB_WIM]; \
+ st %reg_tbr, [%reg + REGWIN_SZ + KGDB_TBR]; \
+ st %reg_pc, [%reg + REGWIN_SZ + KGDB_PC]; \
+ st %reg_npc, [%reg + REGWIN_SZ + KGDB_NPC];
+
+#define LOAD_KGDB_GLOBALS(reg) \
+ ld [%reg + REGWIN_SZ + KGDB_G1], %g1; \
+ ldd [%reg + REGWIN_SZ + KGDB_G2], %g2; \
+ ldd [%reg + REGWIN_SZ + KGDB_G4], %g4; \
+ ldd [%reg + REGWIN_SZ + KGDB_G6], %g6;
+
+#define LOAD_KGDB_INS(reg) \
+ ldd [%reg + REGWIN_SZ + KGDB_I0], %i0; \
+ ldd [%reg + REGWIN_SZ + KGDB_I2], %i2; \
+ ldd [%reg + REGWIN_SZ + KGDB_I4], %i4; \
+ ldd [%reg + REGWIN_SZ + KGDB_I6], %i6;
+
+#define LOAD_KGDB_SREGS(reg, reg_y_and_psr, reg_pc_and_npc) \
+ ldd [%reg + REGWIN_SZ + KGDB_Y], %reg_y_and_psr; \
+ ldd [%reg + REGWIN_SZ + KGDB_PC], %reg_pc_and_npc;
+
+#endif /* !(_SPARC_KGDB_H) */
diff --git a/include/asm-sparc/machines.h b/include/asm-sparc/machines.h
new file mode 100644
index 000000000..d831350f5
--- /dev/null
+++ b/include/asm-sparc/machines.h
@@ -0,0 +1,69 @@
+/* $Id: machines.h,v 1.4 1995/11/25 02:31:58 davem Exp $
+ * machines.h: Defines for taking apart the machine type value in the
+ * idprom and determining the kind of machine we are on.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_MACHINES_H
+#define _SPARC_MACHINES_H
+
+struct Sun_Machine_Models {
+ char *name;
+ unsigned char id_machtype;
+};
+
+/* Current number of machines we know about that has an IDPROM
+ * machtype entry including one entry for the 0x80 OBP machines.
+ */
+#define NUM_SUN_MACHINES 15
+
+extern struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES];
+
+/* The machine type in the idprom area looks like this:
+ *
+ * ---------------
+ * | ARCH | MACH |
+ * ---------------
+ * 7 4 3 0
+ *
+ * The ARCH field determines the architecture line (sun4, sun4c, etc).
+ * The MACH field determines the machine make within that architecture.
+ */
+
+#define SM_ARCH_MASK 0xf0
+#define SM_SUN4 0x20
+#define SM_SUN4C 0x50
+#define SM_SUN4M 0x70
+#define SM_SUN4M_OBP 0x80
+
+#define SM_TYP_MASK 0x0f
+/* Sun4 machines */
+#define SM_4_260 0x01 /* Sun 4/200 series */
+#define SM_4_110 0x02 /* Sun 4/100 series */
+#define SM_4_330 0x03 /* Sun 4/300 series */
+#define SM_4_470 0x04 /* Sun 4/400 series */
+
+/* Sun4c machines Full Name - PROM NAME */
+#define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */
+#define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */
+#define SM_4C_SS1PLUS 0x03 /* Sun4c SparcStation 1+ - Sun 4/65 */
+#define SM_4C_SLC 0x04 /* Sun4c SparcStation SLC - Sun 4/20 */
+#define SM_4C_SS2 0x05 /* Sun4c SparcStation 2 - Sun 4/75 */
+#define SM_4C_ELC 0x06 /* Sun4c SparcStation ELC - Sun 4/25 */
+#define SM_4C_IPX 0x07 /* Sun4c SparcStation IPX - Sun 4/50 */
+
+/* Sun4m machines, these predate the OpenBoot. These values only mean
+ * something if the value in the ARCH field is SM_SUN4M, if it is
+ * SM_SUN4M_OBP then you have the following situation:
+ * 1) You either have a sun4d, a sun4e, or a recently made sun4m.
+ * 2) You have to consult OpenBoot to determine which machine this is.
+ */
+#define SM_4M_SS60 0x01 /* Sun4m SparcSystem 600 */
+#define SM_4M_SS50 0x02 /* Sun4m SparcStation 10 */
+#define SM_4M_SS40 0x03 /* Sun4m SparcStation 5 */
+
+/* Sun4d machines -- N/A */
+/* Sun4e machines -- N/A */
+/* Sun4u machines -- N/A */
+
+#endif /* !(_SPARC_MACHINES_H) */
diff --git a/include/asm-sparc/mbus.h b/include/asm-sparc/mbus.h
new file mode 100644
index 000000000..e5e5a18c8
--- /dev/null
+++ b/include/asm-sparc/mbus.h
@@ -0,0 +1,100 @@
+/* $Id: mbus.h,v 1.8 1996/08/29 09:48:21 davem Exp $
+ * mbus.h: Various defines for MBUS modules.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_MBUS_H
+#define _SPARC_MBUS_H
+
+#include <asm/ross.h> /* HyperSparc stuff */
+#include <asm/cypress.h> /* Cypress Chips */
+#include <asm/viking.h> /* Ugh, bug city... */
+
+enum mbus_module {
+ HyperSparc = 0,
+ Cypress = 1,
+ Cypress_vE = 2,
+ Cypress_vD = 3,
+ Swift_ok = 4,
+ Swift_bad_c = 5,
+ Swift_lots_o_bugs = 6,
+ Tsunami = 7,
+ Viking_12 = 8,
+ Viking_2x = 9,
+ Viking_30 = 10,
+ Viking_35 = 11,
+ Viking_new = 12,
+ SRMMU_INVAL_MOD = 13,
+};
+
+extern enum mbus_module srmmu_modtype;
+extern unsigned int viking_rev, swift_rev, cypress_rev;
+
+/* HW Mbus module bugs we have to deal with */
+#define HWBUG_COPYBACK_BROKEN 0x00000001
+#define HWBUG_ASIFLUSH_BROKEN 0x00000002
+#define HWBUG_VACFLUSH_BITROT 0x00000004
+#define HWBUG_KERN_ACCBROKEN 0x00000008
+#define HWBUG_KERN_CBITBROKEN 0x00000010
+#define HWBUG_MODIFIED_BITROT 0x00000020
+#define HWBUG_PC_BADFAULT_ADDR 0x00000040
+#define HWBUG_SUPERSCALAR_BAD 0x00000080
+#define HWBUG_PACINIT_BITROT 0x00000100
+
+extern unsigned int hwbug_bitmask;
+
+/* First the module type values. To find out which you have, just load
+ * the mmu control register from ASI_M_MMUREG alternate address space and
+ * shift the value right 28 bits.
+ */
+/* IMPL field means the company which produced the chip. */
+#define MBUS_VIKING 0x4 /* bleech, Texas Instruments Module */
+#define MBUS_LSI 0x3 /* LSI Logics */
+#define MBUS_ROSS 0x1 /* Ross is nice */
+#define MBUS_FMI 0x0 /* Fujitsu Microelectronics/Swift */
+
+/* Ross Module versions */
+#define ROSS_604_REV_CDE 0x0 /* revisions c, d, and e */
+#define ROSS_604_REV_F 0x1 /* revision f */
+#define ROSS_605 0xf /* revision a, a.1, and a.2 */
+#define ROSS_605_REV_B 0xe /* revision b */
+
+/* TI Viking Module versions */
+#define VIKING_REV_12 0x1 /* Version 1.2 or SPARCclassic's CPU */
+#define VIKING_REV_2 0x2 /* Version 2.1, 2.2, 2.3, and 2.4 */
+#define VIKING_REV_30 0x3 /* Version 3.0 */
+#define VIKING_REV_35 0x4 /* Version 3.5 */
+
+/* LSI Logics. */
+#define LSI_L64815 0x0
+
+/* Fujitsu */
+#define FMI_AURORA 0x4 /* MB8690x, a Swift module... */
+
+/* For multiprocessor support we need to be able to obtain the CPU id and
+ * the MBUS Module id.
+ */
+
+/* The CPU ID is encoded in the trap base register, 20 bits to the left of
+ * bit zero, with 2 bits being significant.
+ */
+#define TBR_ID_SHIFT 20
+
+extern __inline__ int get_cpuid(void)
+{
+ register int retval;
+ __asm__ __volatile__("rd %%tbr, %0\n\t"
+ "srl %0, %1, %0\n\t" :
+ "=r" (retval) :
+ "i" (TBR_ID_SHIFT));
+ return (retval & 3);
+}
+
+extern __inline__ int get_modid(void)
+{
+ return (get_cpuid() | 0x8);
+}
+
+
+#endif /* !(_SPARC_MBUS_H) */
diff --git a/include/asm-sparc/memerr.h b/include/asm-sparc/memerr.h
deleted file mode 100644
index cd0ca3264..000000000
--- a/include/asm-sparc/memerr.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _SPARC_MEMERR_H
-#define _SPARC_MEMERR_H
-
-/* memerr.h: Bit fields in the asynchronous and synchronous memory error
- registers used to determine what 'type' of error has just
- induced a trap.
-
- Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
-*/
-
-/* synchronous error register fields come first... */
-
-#define SYNCER_WRITE 0x8000 /* write error... */
-#define SYNCER_INVAL 0x0080 /* invalid page access was attempted */
-#define SYNCER_PROT 0x0040 /* protection violation */
-#define SYNCER_TIMEOUT 0x0020 /* mem-bus access timeout (mem does not exist). */
-#define SYNCER_SBUSERR 0x0010 /* same as above, but for an SBUS access */
-#define SYNCER_MEMERR 0x0008 /* Bus parity error, lose lose... panic time */
-#define SYNCER_SZERR 0x0002 /* an attempted access was of BAD size, whoops */
-#define SYNCER_WATCHDOG 0x0001 /* although we never see these, the prom will.. */
-
-/* asynchronous error bits go here */
-
-#define ASYNCER_WBINVAL 0x80 /* situation arose where the cache tried to write
- * back a page for which the valid bit was not set
- * within the mmu. This is due to bad mm kernel bugs.
- */
-
-#define ASYNCER_TIMEOUT 0x20 /* mem-access bus timeout... */
-#define ASYNCER_DVMAERR 0x10 /* dvma transfer to/from memory bombed... */
-
-#endif /* _SPARC_MEMERR_H */
diff --git a/include/asm-sparc/memreg.h b/include/asm-sparc/memreg.h
new file mode 100644
index 000000000..c0498d3ba
--- /dev/null
+++ b/include/asm-sparc/memreg.h
@@ -0,0 +1,52 @@
+/* $Id: memreg.h,v 1.8 1996/08/29 09:48:23 davem Exp $ */
+#ifndef _SPARC_MEMREG_H
+#define _SPARC_MEMREG_H
+/* memreg.h: Definitions of the values found in the synchronous
+ * and asynchronous memory error registers when a fault
+ * occurs on the sun4c.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/* First the synchronous error codes, these are usually just
+ * normal page faults.
+ */
+
+#define SUN4C_SYNC_WDRESET 0x0001 /* watchdog reset */
+#define SUN4C_SYNC_SIZE 0x0002 /* bad access size? whuz this? */
+#define SUN4C_SYNC_PARITY 0x0008 /* bad ram chips caused a parity error */
+#define SUN4C_SYNC_SBUS 0x0010 /* the SBUS had some problems... */
+#define SUN4C_SYNC_NOMEM 0x0020 /* translation to non-existent ram */
+#define SUN4C_SYNC_PROT 0x0040 /* access violated pte protections */
+#define SUN4C_SYNC_NPRESENT 0x0080 /* pte said that page was not present */
+#define SUN4C_SYNC_BADWRITE 0x8000 /* while writing something went bogus */
+
+#define SUN4C_SYNC_BOLIXED \
+ (SUN4C_SYNC_WDRESET | SUN4C_SYNC_SIZE | SUN4C_SYNC_SBUS | \
+ SUN4C_SYNC_NOMEM | SUN4C_SYNC_PARITY)
+
+/* Now the asynchronous error codes, these are almost always produced
+ * by the cache writing things back to memory and getting a bad translation.
+ * Bad DVMA transactions can cause these faults too.
+ */
+
+#define SUN4C_ASYNC_BADDVMA 0x0010 /* error during DVMA access */
+#define SUN4C_ASYNC_NOMEM 0x0020 /* write back pointed to bad phys addr */
+#define SUN4C_ASYNC_BADWB 0x0080 /* write back points to non-present page */
+
+/* Memory parity error register with associated bit constants. */
+#ifndef __ASSEMBLY__
+extern __volatile__ unsigned long *sun4c_memerr_reg;
+#endif
+
+#define SUN4C_MPE_ERROR 0x80 /* Parity error detected. (ro) */
+#define SUN4C_MPE_MULTI 0x40 /* Multiple parity errors detected. (ro) */
+#define SUN4C_MPE_TEST 0x20 /* Write inverse parity. (rw) */
+#define SUN4C_MPE_CHECK 0x10 /* Enable parity checking. (rw) */
+#define SUN4C_MPE_ERR00 0x08 /* Parity error in bits 0-7. (ro) */
+#define SUN4C_MPE_ERR08 0x04 /* Parity error in bits 8-15. (ro) */
+#define SUN4C_MPE_ERR16 0x02 /* Parity error in bits 16-23. (ro) */
+#define SUN4C_MPE_ERR24 0x01 /* Parity error in bits 24-31. (ro) */
+#define SUN4C_MPE_ERRS 0x0F /* Bit mask for the error bits. (ro) */
+
+#endif /* !(_SPARC_MEMREG_H) */
diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h
new file mode 100644
index 000000000..68bc526a1
--- /dev/null
+++ b/include/asm-sparc/mman.h
@@ -0,0 +1,49 @@
+/* $Id: mman.h,v 1.8 1996/10/27 08:55:28 davem Exp $ */
+#ifndef __SPARC_MMAN_H__
+#define __SPARC_MMAN_H__
+
+/* SunOS'ified... */
+
+#define PROT_READ 0x1 /* page can be read */
+#define PROT_WRITE 0x2 /* page can be written */
+#define PROT_EXEC 0x4 /* page can be executed */
+#define PROT_NONE 0x0 /* page can not be accessed */
+
+#define MAP_SHARED 0x01 /* Share changes */
+#define MAP_PRIVATE 0x02 /* Changes are private */
+#define MAP_TYPE 0x0f /* Mask for type of mapping */
+#define MAP_FIXED 0x10 /* Interpret addr exactly */
+#define MAP_ANONYMOUS 0x20 /* don't use a file */
+#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */
+#define MAP_NORESERVE 0x40 /* don't reserve swap pages */
+#define MAP_INHERIT 0x80 /* SunOS doesn't do this, but... */
+#define MAP_LOCKED 0x100 /* lock the mapping */
+#define _MAP_NEW 0x80000000 /* Binary compatibility is fun... */
+
+#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
+#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
+
+#define MS_ASYNC 1 /* sync memory asynchronously */
+#define MS_INVALIDATE 2 /* invalidate the caches */
+#define MS_SYNC 4 /* synchronous memory sync */
+
+#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */
+#define MCL_FUTURE 0x4000 /* lock all additions to address space */
+
+/* XXX Need to add flags to SunOS's mctl, mlockall, and madvise system
+ * XXX calls.
+ */
+
+/* SunOS sys_mctl() stuff... */
+#define MC_SYNC 1 /* Sync pages in memory with storage (usu. a file) */
+#define MC_LOCK 2 /* Lock pages into core ram, do not allow swapping of them */
+#define MC_UNLOCK 3 /* Unlock pages locked via previous mctl() with MC_LOCK arg */
+#define MC_LOCKAS 5 /* Lock an entire address space of the calling process */
+#define MC_UNLOCKAS 6 /* Unlock entire address space of calling process */
+
+/* compatibility flags */
+#define MAP_ANON MAP_ANONYMOUS
+#define MAP_FILE 0
+
+#endif /* __SPARC_MMAN_H__ */
diff --git a/include/asm-sparc/mmu_context.h b/include/asm-sparc/mmu_context.h
new file mode 100644
index 000000000..f9074dfae
--- /dev/null
+++ b/include/asm-sparc/mmu_context.h
@@ -0,0 +1,14 @@
+#ifndef __SPARC_MMU_CONTEXT_H
+#define __SPARC_MMU_CONTEXT_H
+
+/* For now I still leave the context handling in the
+ * switch_to() macro, I'll do it right soon enough.
+ */
+#define get_mmu_context(x) do { } while (0)
+
+/* Initialize the context related info for a new mm_struct
+ * instance.
+ */
+#define init_new_context(mm) ((mm)->context = NO_CONTEXT)
+
+#endif /* !(__SPARC_MMU_CONTEXT_H) */
diff --git a/include/asm-sparc/mostek.h b/include/asm-sparc/mostek.h
new file mode 100644
index 000000000..12baee12a
--- /dev/null
+++ b/include/asm-sparc/mostek.h
@@ -0,0 +1,120 @@
+/* $Id: mostek.h,v 1.8 1996/11/04 00:45:30 ecd Exp $
+ * mostek.h: Describes the various Mostek time of day clock registers.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
+ */
+
+#ifndef _SPARC_MOSTEK_H
+#define _SPARC_MOSTEK_H
+
+#include <asm/idprom.h>
+
+/* M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ)
+ *
+ * Data
+ * Address Function
+ * Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0
+ * 7ff - - - - - - - - Year 00-99
+ * 7fe 0 0 0 - - - - - Month 01-12
+ * 7fd 0 0 - - - - - - Date 01-31
+ * 7fc 0 FT 0 0 0 - - - Day 01-07
+ * 7fb KS 0 - - - - - - Hours 00-23
+ * 7fa 0 - - - - - - - Minutes 00-59
+ * 7f9 ST - - - - - - - Seconds 00-59
+ * 7f8 W R S - - - - - Control
+ *
+ * * ST is STOP BIT
+ * * W is WRITE BIT
+ * * R is READ BIT
+ * * S is SIGN BIT
+ * * FT is FREQ TEST BIT
+ * * KS is KICK START BIT
+ */
+
+/* The Mostek 48t02 real time clock and NVRAM chip. The registers
+ * other than the control register are in binary coded decimal. Some
+ * control bits also live outside the control register.
+ */
+
+struct mostek48t02 {
+ volatile char eeprom[2008]; /* This is the eeprom, don't touch! */
+ struct idprom idprom; /* The idprom lives here. */
+ volatile unsigned char creg; /* Control register */
+ volatile unsigned char sec; /* Seconds (0-59) */
+ volatile unsigned char min; /* Minutes (0-59) */
+ volatile unsigned char hour; /* Hour (0-23) */
+ volatile unsigned char dow; /* Day of the week (1-7) */
+ volatile unsigned char dom; /* Day of the month (1-31) */
+ volatile unsigned char month; /* Month of year (1-12) */
+ volatile unsigned char year; /* Year (0-99) */
+};
+
+extern struct mostek48t02 *mstk48t02_regs;
+
+/* Control register values. */
+#define MSTK_CREG_WRITE 0x80 /* Must set this before placing values. */
+#define MSTK_CREG_READ 0x40 /* Stop updates to allow a clean read. */
+#define MSTK_CREG_SIGN 0x20 /* Slow/speed clock in calibration mode. */
+
+/* Control bits that live in the other registers. */
+#define MSTK_STOP 0x80 /* Stop the clock oscillator. (sec) */
+#define MSTK_KICK_START 0x80 /* Kick start the clock chip. (hour) */
+#define MSTK_FREQ_TEST 0x40 /* Frequency test mode. (day) */
+
+#define MSTK_YEAR_ZERO 1968 /* If year reg has zero, it is 1968. */
+#define MSTK_CVT_YEAR(yr) ((yr) + MSTK_YEAR_ZERO)
+
+/* Masks that define how much space each value takes up. */
+#define MSTK_SEC_MASK 0x7f
+#define MSTK_MIN_MASK 0x7f
+#define MSTK_HOUR_MASK 0x3f
+#define MSTK_DOW_MASK 0x07
+#define MSTK_DOM_MASK 0x3f
+#define MSTK_MONTH_MASK 0x1f
+#define MSTK_YEAR_MASK 0xff
+
+/* Binary coded decimal conversion macros. */
+#define MSTK_REGVAL_TO_DECIMAL(x) (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
+#define MSTK_DECIMAL_TO_REGVAL(x) ((((x) / 0x0A) << 0x04) + ((x) % 0x0A))
+
+/* Generic register set and get macros for internal use. */
+#define MSTK_GET(regs,var,mask) (MSTK_REGVAL_TO_DECIMAL(regs->var & MSTK_ ## mask ## _MASK))
+#define MSTK_SET(regs,var,value,mask) do { regs->var &= ~(MSTK_ ## mask ## _MASK); regs->var |= MSTK_DECIMAL_TO_REGVAL(value) & (MSTK_ ## mask ## _MASK); } while (0)
+
+/* Macros to make register access easier on our fingers. These give you
+ * the decimal value of the register requested if applicable. You pass
+ * the a pointer to a 'struct mostek48t02'.
+ */
+#define MSTK_REG_CREG(regs) (regs->creg)
+#define MSTK_REG_SEC(regs) MSTK_GET(regs,sec,SEC)
+#define MSTK_REG_MIN(regs) MSTK_GET(regs,min,MIN)
+#define MSTK_REG_HOUR(regs) MSTK_GET(regs,hour,HOUR)
+#define MSTK_REG_DOW(regs) MSTK_GET(regs,dow,DOW)
+#define MSTK_REG_DOM(regs) MSTK_GET(regs,dom,DOM)
+#define MSTK_REG_MONTH(regs) MSTK_GET(regs,month,MONTH)
+#define MSTK_REG_YEAR(regs) MSTK_GET(regs,year,YEAR)
+
+#define MSTK_SET_REG_SEC(regs,value) MSTK_SET(regs,sec,value,SEC)
+#define MSTK_SET_REG_MIN(regs,value) MSTK_SET(regs,min,value,MIN)
+#define MSTK_SET_REG_HOUR(regs,value) MSTK_SET(regs,hour,value,HOUR)
+#define MSTK_SET_REG_DOW(regs,value) MSTK_SET(regs,dow,value,DOW)
+#define MSTK_SET_REG_DOM(regs,value) MSTK_SET(regs,dom,value,DOM)
+#define MSTK_SET_REG_MONTH(regs,value) MSTK_SET(regs,month,value,MONTH)
+#define MSTK_SET_REG_YEAR(regs,value) MSTK_SET(regs,year,value,YEAR)
+
+
+/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the
+ * same (basically) layout of the 48t02 chip except for the extra
+ * NVRAM on board (8 KB against the 48t02's 2 KB).
+ */
+struct mostek48t08 {
+ char offset[6*1024]; /* Magic things may be here, who knows? */
+ struct mostek48t02 regs; /* Here is what we are interested in. */
+};
+extern struct mostek48t08 *mstk48t08_regs;
+
+enum sparc_clock_type { MSTK48T02, MSTK48T08, MSTK_INVALID };
+extern enum sparc_clock_type sp_clock_typ;
+
+#endif /* !(_SPARC_MOSTEK_H) */
diff --git a/include/asm-sparc/mpmbox.h b/include/asm-sparc/mpmbox.h
new file mode 100644
index 000000000..0e1bc5801
--- /dev/null
+++ b/include/asm-sparc/mpmbox.h
@@ -0,0 +1,67 @@
+/* $Id: mpmbox.h,v 1.4 1996/04/25 06:13:19 davem Exp $
+ * mpmbox.h: Interface and defines for the OpenProm mailbox
+ * facilities for MP machines under Linux.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_MPMBOX_H
+#define _SPARC_MPMBOX_H
+
+/* The prom allocates, for each CPU on the machine an unsigned
+ * byte in physical ram. You probe the device tree prom nodes
+ * for these values. The purpose of this byte is to be able to
+ * pass messages from one cpu to another.
+ */
+
+/* These are the main message types we have to look for in our
+ * Cpu mailboxes, based upon these values we decide what course
+ * of action to take.
+ */
+
+/* The CPU is executing code in the kernel. */
+#define MAILBOX_ISRUNNING 0xf0
+
+/* Another CPU called romvec->pv_exit(), you should call
+ * prom_stopcpu() when you see this in your mailbox.
+ */
+#define MAILBOX_EXIT 0xfb
+
+/* Another CPU called romvec->pv_enter(), you should call
+ * prom_cpuidle() when this is seen.
+ */
+#define MAILBOX_GOSPIN 0xfc
+
+/* Another CPU has hit a breakpoint either into kadb or the prom
+ * itself. Just like MAILBOX_GOSPIN, you should call prom_cpuidle()
+ * at this point.
+ */
+#define MAILBOX_BPT_SPIN 0xfd
+
+/* Oh geese, some other nitwit got a damn watchdog reset. The party's
+ * over so go call prom_stopcpu().
+ */
+#define MAILBOX_WDOG_STOP 0xfe
+
+#ifndef __ASSEMBLY__
+
+/* Handy macro's to determine a cpu's state. */
+
+/* Is the cpu still in Power On Self Test? */
+#define MBOX_POST_P(letter) ((letter) >= 0x00 && (letter) <= 0x7f)
+
+/* Is the cpu at the 'ok' prompt of the PROM? */
+#define MBOX_PROMPROMPT_P(letter) ((letter) >= 0x80 && (letter) <= 0x8f)
+
+/* Is the cpu spinning in the PROM? */
+#define MBOX_PROMSPIN_P(letter) ((letter) >= 0x90 && (letter) <= 0xef)
+
+/* Sanity check... This is junk mail, throw it out. */
+#define MBOX_BOGON_P(letter) ((letter) >= 0xf1 && (letter) <= 0xfa)
+
+/* Is the cpu actively running an application/kernel-code? */
+#define MBOX_RUNNING_P(letter) ((letter) == MAILBOX_ISRUNNING)
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_SPARC_MPMBOX_H) */
diff --git a/include/asm-sparc/msi.h b/include/asm-sparc/msi.h
new file mode 100644
index 000000000..b69543dd3
--- /dev/null
+++ b/include/asm-sparc/msi.h
@@ -0,0 +1,31 @@
+/* $Id: msi.h,v 1.3 1996/08/29 09:48:25 davem Exp $
+ * msi.h: Defines specific to the MBus - Sbus - Interface.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
+ */
+
+#ifndef _SPARC_MSI_H
+#define _SPARC_MSI_H
+
+/*
+ * Locations of MSI Registers.
+ */
+#define MSI_MBUS_ARBEN 0xe0001008 /* MBus Arbiter Enable register */
+
+/*
+ * Useful bits in the MSI Registers.
+ */
+#define MSI_ASYNC_MODE 0x80000000 /* Operate the MSI asynchronously */
+
+
+extern __inline__ void msi_set_sync(void)
+{
+ __asm__ __volatile__ ("lda [%0] %1, %%g3\n\t"
+ "andn %%g3, %2, %%g3\n\t"
+ "sta %%g3, [%0] %1\n\t" : :
+ "r" (MSI_MBUS_ARBEN),
+ "i" (ASI_M_CTL), "r" (MSI_ASYNC_MODE) : "g3");
+}
+
+#endif /* !(_SPARC_MSI_H) */
diff --git a/include/asm-sparc/mxcc.h b/include/asm-sparc/mxcc.h
new file mode 100644
index 000000000..87947bc0f
--- /dev/null
+++ b/include/asm-sparc/mxcc.h
@@ -0,0 +1,133 @@
+/* $Id: mxcc.h,v 1.6 1996/08/29 09:48:27 davem Exp $
+ * mxcc.h: Definitions of the Viking MXCC registers
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_MXCC_H
+#define _SPARC_MXCC_H
+
+/* These registers are accessed through ASI 0x2. */
+#define MXCC_DATSTREAM 0x1C00000 /* Data stream register */
+#define MXCC_SRCSTREAM 0x1C00100 /* Source stream register */
+#define MXCC_DESSTREAM 0x1C00200 /* Destination stream register */
+#define MXCC_RMCOUNT 0x1C00300 /* Count of references and misses */
+#define MXCC_STEST 0x1C00804 /* Internal self-test */
+#define MXCC_CREG 0x1C00A04 /* Control register */
+#define MXCC_SREG 0x1C00B00 /* Status register */
+#define MXCC_RREG 0x1C00C04 /* Reset register */
+#define MXCC_EREG 0x1C00E00 /* Error code register */
+#define MXCC_PREG 0x1C00F04 /* Address port register */
+
+/* Some MXCC constants. */
+#define MXCC_STREAM_SIZE 0x20 /* Size in bytes of one stream r/w */
+
+/* The MXCC Control Register:
+ *
+ * ----------------------------------------------------------------------
+ * | | RRC | RSV |PRE|MCE|PARE|ECE|RSV|
+ * ----------------------------------------------------------------------
+ * 31 10 9 8-6 5 4 3 2 1-0
+ *
+ * RRC: Controls what you read from MXCC_RMCOUNT reg.
+ * 0=Misses 1=References
+ * PRE: Prefetch enable
+ * MCE: Multiple Command Enable
+ * PARE: Parity enable
+ * ECE: External cache enable
+ */
+
+#define MXCC_CTL_RRC 0x00000200
+#define MXCC_CTL_PRE 0x00000020
+#define MXCC_CTL_MCE 0x00000010
+#define MXCC_CTL_PARE 0x00000008
+#define MXCC_CTL_ECE 0x00000004
+
+/* The MXCC Error Register:
+ *
+ * --------------------------------------------------------
+ * |ME| RSV|CE|PEW|PEE|ASE|EIV| MOPC|ECODE|PRIV|RSV|HPADDR|
+ * --------------------------------------------------------
+ * 31 30 29 28 27 26 25 24-15 14-7 6 5-3 2-0
+ *
+ * ME: Multiple Errors have occurred
+ * CE: Cache consistency Error
+ * PEW: Parity Error during a Write operation
+ * PEE: Parity Error involving the External cache
+ * ASE: ASynchronous Error
+ * EIV: This register is toast
+ * MOPC: MXCC Operation Code for instance causing error
+ * ECODE: The Error CODE
+ * PRIV: A privileged mode error? 0=no 1=yes
+ * HPADDR: High PhysicalADDRess bits (35-32)
+ */
+
+#define MXCC_ERR_ME 0x80000000
+#define MXCC_ERR_CE 0x20000000
+#define MXCC_ERR_PEW 0x10000000
+#define MXCC_ERR_PEE 0x08000000
+#define MXCC_ERR_ASE 0x04000000
+#define MXCC_ERR_EIV 0x02000000
+#define MXCC_ERR_MOPC 0x01FF8000
+#define MXCC_ERR_ECODE 0x00007F80
+#define MXCC_ERR_PRIV 0x00000040
+#define MXCC_ERR_HPADDR 0x0000000f
+
+/* The MXCC Port register:
+ *
+ * -----------------------------------------------------
+ * | | MID | |
+ * -----------------------------------------------------
+ * 31 21 20-18 17 0
+ *
+ * MID: The moduleID of the cpu your read this from.
+ */
+
+extern __inline__ void mxcc_set_stream_src(unsigned long *paddr)
+{
+ unsigned long data0 = paddr[0];
+ unsigned long data1 = paddr[1];
+
+ __asm__ __volatile__ ("or %%g0, %0, %%g2\n\t"
+ "or %%g0, %1, %%g3\n\t"
+ "stda %%g2, [%2] %3\n\t" : :
+ "r" (data0), "r" (data1),
+ "r" (MXCC_SRCSTREAM),
+ "i" (ASI_M_MXCC) : "g2", "g3");
+}
+
+extern __inline__ void mxcc_set_stream_dst(unsigned long *paddr)
+{
+ unsigned long data0 = paddr[0];
+ unsigned long data1 = paddr[1];
+
+ __asm__ __volatile__ ("or %%g0, %0, %%g2\n\t"
+ "or %%g0, %1, %%g3\n\t"
+ "stda %%g2, [%2] %3\n\t" : :
+ "r" (data0), "r" (data1),
+ "r" (MXCC_DESSTREAM),
+ "i" (ASI_M_MXCC) : "g2", "g3");
+}
+
+extern __inline__ unsigned long mxcc_get_creg(void)
+{
+ unsigned long mxcc_control;
+
+ __asm__ __volatile__("set -1, %%g2\n\t"
+ "set -1, %%g3\n\t"
+ "stda %%g2, [%1] %2\n\t"
+ "lda [%3] %2, %0\n\t" :
+ "=r" (mxcc_control) :
+ "r" (MXCC_EREG), "i" (ASI_M_MXCC),
+ "r" (MXCC_CREG) : "g2", "g3");
+ return mxcc_control;
+}
+
+extern __inline__ void mxcc_set_creg(unsigned long mxcc_control)
+{
+ __asm__ __volatile__("sta %0, [%1] %2\n\t" : :
+ "r" (mxcc_control), "r" (MXCC_CREG),
+ "i" (ASI_M_MXCC));
+}
+
+#endif /* !(_SPARC_MXCC_H) */
diff --git a/include/asm-sparc/openprom.h b/include/asm-sparc/openprom.h
index ca6d9e36d..34f5d3c33 100644
--- a/include/asm-sparc/openprom.h
+++ b/include/asm-sparc/openprom.h
@@ -1,304 +1,210 @@
+/* $Id: openprom.h,v 1.19 1996/09/25 03:51:08 davem Exp $ */
#ifndef __SPARC_OPENPROM_H
#define __SPARC_OPENPROM_H
/* openprom.h: Prom structures and defines for access to the OPENBOOT
- prom routines and data areas.
-
- Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
-*/
+ * prom routines and data areas.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
-/* In the v0 interface of the openboot prom we could traverse a nice
- little list structure to figure out where in vm-space the prom had
- mapped itself and how much space it was taking up. In the v2 prom
- interface we have to rely on 'magic' values. :-( Most of the machines
- I have checked on have the prom mapped here all the time though.
-*/
+/* Empirical constants... */
+#define KADB_DEBUGGER_BEGVM 0xffc00000 /* Where kern debugger is in virt-mem */
#define LINUX_OPPROM_BEGVM 0xffd00000
#define LINUX_OPPROM_ENDVM 0xfff00000
-
#define LINUX_OPPROM_MAGIC 0x10010407
-/* The device functions structure for the v0 prom. Nice and neat, open,
- close, read & write divvied up between net + block + char devices. We
- also have a seek routine only usable for block devices. The divide
- and conquer strategy of this struct becomes unnecessary for v2.
-
- V0 device names are limited to two characters, 'sd' for scsi-disk,
- 'le' for local-ethernet, etc. Note that it is technically possible
- to boot a kernel off of a tape drive and use the tape as the root
- partition! In order to do this you have to have 'magic' formatted
- tapes from Sun supposedly :-)
-*/
-
+#ifndef __ASSEMBLY__
+/* V0 prom device operations. */
struct linux_dev_v0_funcs {
- int (*v0_devopen)(char *device_str);
- int (*v0_devclose)(int dev_desc);
- int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char* buf);
- int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char* buf);
- int (*v0_wrnetdev)(int dev_desc, int num_bytes, char* buf);
- int (*v0_rdnetdev)(int dev_desc, int num_bytes, char* buf);
- int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char* buf);
- int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char* buf);
- int (*v0_seekdev)(int dev_desc, long logical_offst, int from);
+ int (*v0_devopen)(char *device_str);
+ int (*v0_devclose)(int dev_desc);
+ int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
+ int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
+ int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf);
+ int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf);
+ int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
+ int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
+ int (*v0_seekdev)(int dev_desc, long logical_offst, int from);
};
-/* The OpenBoot Prom device operations for version-2 interfaces are both
- good and bad. They now allow you to address ANY device whatsoever
- that is in the machine via these funny "device paths". They look like
- this:
-
- "/sbus/esp@0,0xf004002c/sd@3,1"
-
- You can basically reference any device on the machine this way, and
- you pass this string to the v2 dev_ops. Producing these strings all
- the time can be a pain in the rear after a while. Why v2 has memory
- allocations in here are beyond me. Perhaps they figure that if you
- are going to use only the prom's device drivers then your memory
- management is either non-existent or pretty sad. :-)
-*/
-
+/* V2 and later prom device operations. */
struct linux_dev_v2_funcs {
- int (*v2_aieee)(int d); /* figure this out later... */
-
- /* "dumb" prom memory management routines, probably
- only safe to use for mapping device address spaces...
- */
-
- char* (*v2_dumb_mem_alloc)(char* va, unsigned sz);
- void (*v2_dumb_mem_free)(char* va, unsigned sz);
-
- /* "dumb" mmap() munmap(), copy on write? what's that? */
- char* (*v2_dumb_mmap)(char* virta, int asi, unsigned prot, unsigned sz);
- void (*v2_dumb_munmap)(char* virta, unsigned size);
-
- /* Basic Operations, self-explanatory */
- int (*v2_dev_open)(char *devpath);
- void (*v2_dev_close)(int d);
- int (*v2_dev_read)(int d, char* buf, int nbytes);
- int (*v2_dev_write)(int d, char* buf, int nbytes);
- void (*v2_dev_seek)(int d, int hi, int lo);
-
- /* huh? */
- void (*v2_wheee2)(void);
- void (*v2_wheee3)(void);
+ int (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */
+ char * (*v2_dumb_mem_alloc)(char *va, unsigned sz);
+ void (*v2_dumb_mem_free)(char *va, unsigned sz);
+
+ /* To map devices into virtual I/O space. */
+ char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz);
+ void (*v2_dumb_munmap)(char *virta, unsigned size);
+
+ int (*v2_dev_open)(char *devpath);
+ void (*v2_dev_close)(int d);
+ int (*v2_dev_read)(int d, char *buf, int nbytes);
+ int (*v2_dev_write)(int d, char *buf, int nbytes);
+ int (*v2_dev_seek)(int d, int hi, int lo);
+
+ /* Never issued (multistage load support) */
+ void (*v2_wheee2)(void);
+ void (*v2_wheee3)(void);
};
-/* Just like the device ops, they slightly screwed up the mem-list
- from v0 to v2. Probably easier on the prom-writer dude, sucks for
- us though. See above comment about prom-vm mapped address space
- magic numbers. :-(
-*/
-
struct linux_mlist_v0 {
- struct linux_mlist_v0 *theres_more;
- char* start_adr;
+ struct linux_mlist_v0 *theres_more;
+ char *start_adr;
unsigned num_bytes;
};
-/* The linux_mlist_v0's are pointer by this structure. One list
- per description. This means one list for total physical memory,
- one for prom's address mapping, and one for physical mem left after
- the kernel is loaded.
- */
struct linux_mem_v0 {
- struct linux_mlist_v0 **v0_totphys; /* all of physical */
- struct linux_mlist_v0 **v0_prommap; /* addresses map'd by prom */
- struct linux_mlist_v0 **v0_available; /* what phys. is left over */
+ struct linux_mlist_v0 **v0_totphys;
+ struct linux_mlist_v0 **v0_prommap;
+ struct linux_mlist_v0 **v0_available; /* What we can use */
};
/* Arguments sent to the kernel from the boot prompt. */
-
struct linux_arguments_v0 {
- char *argv[8]; /* argv format for boot string */
- char args[100]; /* string space */
- char boot_dev[2]; /* e.g., "sd" for `b sd(...' */
- int boot_dev_ctrl; /* controller # */
- int boot_dev_unit; /* unit # */
- int dev_partition; /* partition # */
- char *kernel_file_name; /* kernel to boot, e.g., "vmunix" */
- void *aieee1; /* give me some time :> */
+ char *argv[8];
+ char args[100];
+ char boot_dev[2];
+ int boot_dev_ctrl;
+ int boot_dev_unit;
+ int dev_partition;
+ char *kernel_file_name;
+ void *aieee1; /* XXX */
};
-/* Prom version-2 gives us the raw strings for boot arguments and
- boot device path. We also get the stdin and stdout file pseudo
- descriptors for use with the mungy v2 device functions.
-*/
+/* V2 and up boot things. */
struct linux_bootargs_v2 {
- char **bootpath; /* V2: Path to boot device */
- char **bootargs; /* V2: Boot args */
- int *fd_stdin; /* V2: Stdin descriptor */
- int *fd_stdout; /* V2: Stdout descriptor */
+ char **bootpath;
+ char **bootargs;
+ int *fd_stdin;
+ int *fd_stdout;
};
-/* This is the actual Prom Vector from which everything else is accessed
- via struct and function pointers, etc. The prom when it loads us into
- memory plops a pointer to this master structure in register %o0 before
- it jumps to the kernel start address. I will update this soon to cover
- the v3 semantics (cpu_start, cpu_stop and other SMP fun things). :-)
-*/
+/* The top level PROM vector. */
struct linux_romvec {
/* Version numbers. */
- unsigned int pv_magic_cookie; /* Magic Mushroom... */
- unsigned int pv_romvers; /* iface vers (0, 2, or 3) */
- unsigned int pv_plugin_revision; /* revision relative to above vers */
- unsigned int pv_printrev; /* print revision */
-
- /* Version 0 memory descriptors (see below). */
- struct linux_mem_v0 pv_v0mem; /* V0: Memory description lists. */
+ unsigned int pv_magic_cookie;
+ unsigned int pv_romvers;
+ unsigned int pv_plugin_revision;
+ unsigned int pv_printrev;
- /* Node operations (see below). */
- struct linux_nodeops *pv_nodeops; /* node functions, gets device data */
+ /* Version 0 memory descriptors. */
+ struct linux_mem_v0 pv_v0mem;
- char **pv_bootstr; /* Boot command, eg sd(0,0,0)vmunix */
+ /* Node operations. */
+ struct linux_nodeops *pv_nodeops;
- struct linux_dev_v0_funcs pv_v0devops; /* V0: device ops */
+ char **pv_bootstr;
+ struct linux_dev_v0_funcs pv_v0devops;
- /*
- * PROMDEV_* cookies. I fear these may vanish in lieu of fd0/fd1
- * (see below) in future PROMs, but for now they work fine.
- */
- char *pv_stdin; /* stdin cookie */
- char *pv_stdout; /* stdout cookie */
+ char *pv_stdin;
+ char *pv_stdout;
#define PROMDEV_KBD 0 /* input from keyboard */
#define PROMDEV_SCREEN 0 /* output to screen */
#define PROMDEV_TTYA 1 /* in/out to ttya */
#define PROMDEV_TTYB 2 /* in/out to ttyb */
/* Blocking getchar/putchar. NOT REENTRANT! (grr) */
- int (*pv_getchar)(void);
- void (*pv_putchar)(int ch);
+ int (*pv_getchar)(void);
+ void (*pv_putchar)(int ch);
- /* Non-blocking variants that return -1 on error. */
- int (*pv_nbgetchar)(void);
- int (*pv_nbputchar)(int ch);
+ /* Non-blocking variants. */
+ int (*pv_nbgetchar)(void);
+ int (*pv_nbputchar)(int ch);
- /* Put counted string (can be very slow). */
- void (*pv_putstr)(char *str, int len);
+ void (*pv_putstr)(char *str, int len);
/* Miscellany. */
- void (*pv_reboot)(char *bootstr);
- void (*pv_printf)(const char *fmt, ...);
- void (*pv_abort)(void); /* BREAK key abort */
- int *pv_ticks; /* milliseconds since last reset */
- void (*pv_halt)(void); /* End the show */
- void (**pv_synchook)(void); /* "sync" ptr to function */
-
- /*
- * This eval's a FORTH string. Unfortunately, its interface
- * changed between V0 and V2, which gave us much pain.
- */
+ void (*pv_reboot)(char *bootstr);
+ void (*pv_printf)(__const__ char *fmt, ...);
+ void (*pv_abort)(void);
+ __volatile__ int *pv_ticks;
+ void (*pv_halt)(void);
+ void (**pv_synchook)(void);
+
+ /* Evaluate a forth string, not different proto for V0 and V2->up. */
union {
- void (*v0_eval)(int len, char *str);
- void (*v2_eval)(char *str);
+ void (*v0_eval)(int len, char *str);
+ void (*v2_eval)(char *str);
} pv_fortheval;
- struct linux_arguments_v0 **pv_v0bootargs; /* V0: Boot args */
+ struct linux_arguments_v0 **pv_v0bootargs;
- /* Extract Ethernet address from network device. */
- unsigned int (*pv_enaddr)(int d, char *enaddr);
+ /* Get ether address. */
+ unsigned int (*pv_enaddr)(int d, char *enaddr);
- struct linux_bootargs_v2 pv_v2bootargs; /* V2: Boot args+std-in/out */
- struct linux_dev_v2_funcs pv_v2devops; /* V2: device operations */
+ struct linux_bootargs_v2 pv_v2bootargs;
+ struct linux_dev_v2_funcs pv_v2devops;
- int whatzthis[15]; /* huh? */
+ int filler[15];
- /*
- * The following is machine-dependent.
- *
- * The sun4c needs a PROM function to set a PMEG for another
- * context, so that the kernel can map itself in all contexts.
- * It is not possible simply to set the context register, because
- * contexts 1 through N may have invalid translations for the
- * current program counter. The hardware has a mode in which
- * all memory references go to the PROM, so the PROM can do it
- * easily.
- */
- void (*pv_setctxt)(int ctxt, char* va, int pmeg);
+ /* This one is sun4c/sun4 only. */
+ void (*pv_setctxt)(int ctxt, char *va, int pmeg);
/* Prom version 3 Multiprocessor routines. This stuff is crazy.
* No joke. Calling these when there is only one cpu probably
* crashes the machine, have to test this. :-)
- */
+ */
/* v3_cpustart() will start the cpu 'whichcpu' in mmu-context
* 'thiscontext' executing at address 'prog_counter'
- *
- * XXX Have to figure out what 'cancontext' means.
- */
-
- int (*v3_cpustart)(unsigned int whichcpu, int cancontext,
- int thiscontext, char* prog_counter);
+ */
+ int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr,
+ int thiscontext, char *prog_counter);
/* v3_cpustop() will cause cpu 'whichcpu' to stop executing
* until a resume cpu call is made.
*/
-
int (*v3_cpustop)(unsigned int whichcpu);
/* v3_cpuidle() will idle cpu 'whichcpu' until a stop or
* resume cpu call is made.
*/
-
int (*v3_cpuidle)(unsigned int whichcpu);
/* v3_cpuresume() will resume processor 'whichcpu' executing
* starting with whatever 'pc' and 'npc' were left at the
* last 'idle' or 'stop' call.
*/
-
int (*v3_cpuresume)(unsigned int whichcpu);
+};
+/* Routines for traversing the prom device tree. */
+struct linux_nodeops {
+ int (*no_nextnode)(int node);
+ int (*no_child)(int node);
+ int (*no_proplen)(int node, char *name);
+ int (*no_getprop)(int node, char *name, char *val);
+ int (*no_setprop)(int node, char *name, char *val, int len);
+ char * (*no_nextprop)(int node, char *name);
};
-/*
- * In addition to the global stuff defined in the PROM vectors above,
- * the PROM has quite a collection of `nodes'. A node is described by
- * an integer---these seem to be internal pointers, actually---and the
- * nodes are arranged into an N-ary tree. Each node implements a fixed
- * set of functions, as described below. The first two deal with the tree
- * structure, allowing traversals in either breadth- or depth-first fashion.
- * The rest deal with `properties'.
- *
- * A node property is simply a name/value pair. The names are C strings
- * (NUL-terminated); the values are arbitrary byte strings (counted strings).
- * Many values are really just C strings. Sometimes these are NUL-terminated,
- * sometimes not, depending on the the interface version; v0 seems to
- * terminate and v2 not. Many others are simply integers stored as four
- * bytes in machine order: you just get them and go. The third popular
- * format is an `address', which is made up of one or more sets of three
- * integers as defined below.
- *
- * One uses these functions to traverse the device tree to see what devices
- * this machine has attached to it.
- *
- * N.B.: for the `next' functions, next(0) = first, and next(last) = 0.
- * Whoever designed this part had good taste. On the other hand, these
- * operation vectors are global, rather than per-node, yet the pointers
- * are not in the openprom vectors but rather found by indirection from
- * there. So the taste balances out.
- */
-struct linux_prom_addr {
- int oa_space; /* address space (may be relative) */
- unsigned int oa_base; /* address within space */
- unsigned int oa_size; /* extent (number of bytes) */
+/* More fun PROM structures for device probing. */
+#define PROMREG_MAX 16
+#define PROMVADDR_MAX 16
+#define PROMINTR_MAX 15
+
+struct linux_prom_registers {
+ int which_io; /* is this in OBIO space? */
+ char *phys_addr; /* The physical address of this register */
+ int reg_size; /* How many bytes does this register take up? */
};
-struct linux_nodeops {
- /*
- * Tree traversal.
- */
- int (*no_nextnode)(int node); /* next(node) */
- int (*no_child)(int node); /* first child */
+struct linux_prom_irqs {
+ int pri; /* IRQ priority */
+ int vector; /* This is foobar, what does it do? */
+};
- /*
- * Property functions. Proper use of getprop requires calling
- * proplen first to make sure it fits. Kind of a pain, but no
- * doubt more convenient for the PROM coder.
- */
- int (*no_proplen)(int node, char* name);
- int (*no_getprop)(int node, char* name, char* val);
- int (*no_setprop)(int node, char* name, char* val, int len);
- char* (*no_nextprop)(int node, char* name);
+/* Element of the "ranges" vector */
+struct linux_prom_ranges {
+ unsigned int ot_child_space;
+ unsigned int ot_child_base; /* Bus feels this */
+ unsigned int ot_parent_space;
+ unsigned int ot_parent_base; /* CPU looks from here */
+ unsigned int or_size;
};
+#endif /* !(__ASSEMBLY__) */
+
#endif /* !(__SPARC_OPENPROM_H) */
diff --git a/include/asm-sparc/openpromio.h b/include/asm-sparc/openpromio.h
new file mode 100644
index 000000000..8989909de
--- /dev/null
+++ b/include/asm-sparc/openpromio.h
@@ -0,0 +1,70 @@
+#ifndef _SPARC_OPENPROMIO_H
+#define _SPARC_OPENPROMIO_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/*
+ * SunOS and Solaris /dev/openprom definitions. The ioctl values
+ * were chosen to be exactly equal to the SunOS equivalents.
+ */
+
+struct openpromio
+{
+ u_int oprom_size; /* Actual size of the oprom_array. */
+ char oprom_array[1]; /* Holds property names and values. */
+};
+
+#define OPROMMAXPARAM 4096 /* Maximum size of oprom_array. */
+
+#define OPROMGETOPT 0x20004F01
+#define OPROMSETOPT 0x20004F02
+#define OPROMNXTOPT 0x20004F03
+#define OPROMSETOPT2 0x20004F04
+#define OPROMNEXT 0x20004F05
+#define OPROMCHILD 0x20004F06
+#define OPROMGETPROP 0x20004F07
+#define OPROMNXTPROP 0x20004F08
+#define OPROMU2P 0x20004F09
+#define OPROMGETCONS 0x20004F0A
+#define OPROMGETFBNAME 0x20004F0B
+#define OPROMGETBOOTARGS 0x20004F0C
+
+/*
+ * Return values from OPROMGETCONS:
+ */
+
+#define OPROMCONS_NOT_WSCONS 0
+#define OPROMCONS_STDIN_IS_KBD 0x1 /* stdin device is kbd */
+#define OPROMCONS_STDOUT_IS_FB 0x2 /* stdout is a framebuffer */
+#define OPROMCONS_OPENPROM 0x4 /* supports openboot */
+
+
+/*
+ * NetBSD/OpenBSD /dev/openprom definitions.
+ */
+
+struct opiocdesc
+{
+ int op_nodeid; /* PROM Node ID (value-result) */
+ int op_namelen; /* Length of op_name. */
+ char *op_name; /* Pointer to the property name. */
+ int op_buflen; /* Length of op_buf (value-result) */
+ char *op_buf; /* Pointer to buffer. */
+};
+
+#define OPIOCGET _IOWR('O', 1, struct opiocdesc)
+#define OPIOCSET _IOW('O', 2, struct opiocdesc)
+#define OPIOCNEXTPROP _IOWR('O', 3, struct opiocdesc)
+#define OPIOCGETOPTNODE _IOR('O', 4, int)
+#define OPIOCGETNEXT _IOWR('O', 5, int)
+#define OPIOCGETCHILD _IOWR('O', 6, int)
+
+
+#ifdef __KERNEL__
+int openprom_init(void);
+#endif
+
+
+#endif /* _SPARC_OPENPROMIO_H */
+
diff --git a/include/asm-sparc/oplib.h b/include/asm-sparc/oplib.h
new file mode 100644
index 000000000..84248e0eb
--- /dev/null
+++ b/include/asm-sparc/oplib.h
@@ -0,0 +1,297 @@
+/* $Id: oplib.h,v 1.12 1996/10/31 06:29:13 davem Exp $
+ * oplib.h: Describes the interface and available routines in the
+ * Linux Prom library.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __SPARC_OPLIB_H
+#define __SPARC_OPLIB_H
+
+#include <asm/openprom.h>
+
+/* The master romvec pointer... */
+extern struct linux_romvec *romvec;
+
+/* Enumeration to describe the prom major version we have detected. */
+enum prom_major_version {
+ PROM_V0, /* Original sun4c V0 prom */
+ PROM_V2, /* sun4c and early sun4m V2 prom */
+ PROM_V3, /* sun4m and later, up to sun4d/sun4e machines V3 */
+ PROM_P1275, /* IEEE compliant ISA based Sun PROM, only sun4u */
+ PROM_AP1000, /* actually no prom at all */
+};
+
+extern enum prom_major_version prom_vers;
+/* Revision, and firmware revision. */
+extern unsigned int prom_rev, prom_prev;
+
+/* Root node of the prom device tree, this stays constant after
+ * initialization is complete.
+ */
+extern int prom_root_node;
+
+/* Pointer to prom structure containing the device tree traversal
+ * and usage utility functions. Only prom-lib should use these,
+ * users use the interface defined by the library only!
+ */
+extern struct linux_nodeops *prom_nodeops;
+
+/* The functions... */
+
+/* You must call prom_init() before using any of the library services,
+ * preferably as early as possible. Pass it the romvec pointer.
+ */
+extern void prom_init(struct linux_romvec *rom_ptr);
+
+/* Boot argument acquisition, returns the boot command line string. */
+extern char *prom_getbootargs(void);
+
+/* Device utilities. */
+
+/* Map and unmap devices in IO space at virtual addresses. Note that the
+ * virtual address you pass is a request and the prom may put your mappings
+ * somewhere else, so check your return value as that is where your new
+ * mappings really are!
+ *
+ * Another note, these are only available on V2 or higher proms!
+ */
+extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes);
+extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
+
+/* Device operations. */
+
+/* Open the device described by the passed string. Note, that the format
+ * of the string is different on V0 vs. V2->higher proms. The caller must
+ * know what he/she is doing! Returns the device descriptor, an int.
+ */
+extern int prom_devopen(char *device_string);
+
+/* Close a previously opened device described by the passed integer
+ * descriptor.
+ */
+extern int prom_devclose(int device_handle);
+
+/* Do a seek operation on the device described by the passed integer
+ * descriptor.
+ */
+extern void prom_seek(int device_handle, unsigned int seek_hival,
+ unsigned int seek_lowval);
+
+/* Machine memory configuration routine. */
+
+/* This function returns a V0 format memory descriptor table, it has three
+ * entries. One for the total amount of physical ram on the machine, one
+ * for the amount of physical ram available, and one describing the virtual
+ * areas which are allocated by the prom. So, in a sense the physical
+ * available is a calculation of the total physical minus the physical mapped
+ * by the prom with virtual mappings.
+ *
+ * These lists are returned pre-sorted, this should make your life easier
+ * since the prom itself is way too lazy to do such nice things.
+ */
+extern struct linux_mem_v0 *prom_meminfo(void);
+
+/* Miscellaneous routines, don't really fit in any category per se. */
+
+/* Reboot the machine with the command line passed. */
+extern void prom_reboot(char *boot_command);
+
+/* Evaluate the forth string passed. */
+extern void prom_feval(char *forth_string);
+
+/* Enter the prom, with possibility of continuation with the 'go'
+ * command in newer proms.
+ */
+extern void prom_cmdline(void);
+
+/* Enter the prom, with no chance of continuation for the stand-alone
+ * which calls this.
+ */
+extern void prom_halt(void);
+
+/* Set the PROM 'sync' callback function to the passed function pointer.
+ * When the user gives the 'sync' command at the prom prompt while the
+ * kernel is still active, the prom will call this routine.
+ *
+ * XXX The arguments are different on V0 vs. V2->higher proms, grrr! XXX
+ */
+typedef void (*sync_func_t)(void);
+extern void prom_setsync(sync_func_t func_ptr);
+
+/* Acquire the IDPROM of the root node in the prom device tree. This
+ * gets passed a buffer where you would like it stuffed. The return value
+ * is the format type of this idprom or 0xff on error.
+ */
+extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
+
+/* Get the prom major version. */
+extern int prom_version(void);
+
+/* Get the prom plugin revision. */
+extern int prom_getrev(void);
+
+/* Get the prom firmware revision. */
+extern int prom_getprev(void);
+
+/* Character operations to/from the console.... */
+
+/* Non-blocking get character from console. */
+extern int prom_nbgetchar(void);
+
+/* Non-blocking put character to console. */
+extern int prom_nbputchar(char character);
+
+/* Blocking get character from console. */
+extern char prom_getchar(void);
+
+/* Blocking put character to console. */
+extern void prom_putchar(char character);
+
+/* Prom's internal printf routine, don't use in kernel/boot code. */
+void prom_printf(char *fmt, ...);
+
+/* Query for input device type */
+
+enum prom_input_device {
+ PROMDEV_IKBD, /* input from keyboard */
+ PROMDEV_ITTYA, /* input from ttya */
+ PROMDEV_ITTYB, /* input from ttyb */
+ PROMDEV_I_UNK,
+};
+
+extern enum prom_input_device prom_query_input_device(void);
+
+/* Query for output device type */
+
+enum prom_output_device {
+ PROMDEV_OSCREEN, /* to screen */
+ PROMDEV_OTTYA, /* to ttya */
+ PROMDEV_OTTYB, /* to ttyb */
+ PROMDEV_O_UNK,
+};
+
+extern enum prom_output_device prom_query_output_device(void);
+
+/* Multiprocessor operations... */
+
+/* Start the CPU with the given device tree node, context table, and context
+ * at the passed program counter.
+ */
+extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
+ int context, char *program_counter);
+
+/* Stop the CPU with the passed device tree node. */
+extern int prom_stopcpu(int cpunode);
+
+/* Idle the CPU with the passed device tree node. */
+extern int prom_idlecpu(int cpunode);
+
+/* Re-Start the CPU with the passed device tree node. */
+extern int prom_restartcpu(int cpunode);
+
+/* PROM memory allocation facilities... */
+
+/* Allocated at possibly the given virtual address a chunk of the
+ * indicated size.
+ */
+extern char *prom_alloc(char *virt_hint, unsigned int size);
+
+/* Free a previously allocated chunk. */
+extern void prom_free(char *virt_addr, unsigned int size);
+
+/* Sun4/sun4c specific memory-management startup hook. */
+
+/* Map the passed segment in the given context at the passed
+ * virtual address.
+ */
+extern void prom_putsegment(int context, unsigned long virt_addr,
+ int physical_segment);
+
+/* PROM device tree traversal functions... */
+
+/* Get the child node of the given node, or zero if no child exists. */
+extern int prom_getchild(int parent_node);
+
+/* Get the next sibling node of the given node, or zero if no further
+ * siblings exist.
+ */
+extern int prom_getsibling(int node);
+
+/* Get the length, at the passed node, of the given property type.
+ * Returns -1 on error (ie. no such property at this node).
+ */
+extern int prom_getproplen(int thisnode, char *property);
+
+/* Fetch the requested property using the given buffer. Returns
+ * the number of bytes the prom put into your buffer or -1 on error.
+ */
+extern int prom_getproperty(int thisnode, char *property,
+ char *prop_buffer, int propbuf_size);
+
+/* Acquire an integer property. */
+extern int prom_getint(int node, char *property);
+
+/* Acquire an integer property, with a default value. */
+extern int prom_getintdefault(int node, char *property, int defval);
+
+/* Acquire a boolean property, 0=FALSE 1=TRUE. */
+extern int prom_getbool(int node, char *prop);
+
+/* Acquire a string property, null string on error. */
+extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
+
+/* Does the passed node have the given "name"? YES=1 NO=0 */
+extern int prom_nodematch(int thisnode, char *name);
+
+/* Puts in buffer a prom name in the form name@x,y or name (x for which_io
+ * and y for first regs phys address
+ */
+extern int prom_getname(int node, char *buf, int buflen);
+
+/* Search all siblings starting at the passed node for "name" matching
+ * the given string. Returns the node on success, zero on failure.
+ */
+extern int prom_searchsiblings(int node_start, char *name);
+
+/* Return the first property type, as a string, for the given node.
+ * Returns a null string on error.
+ */
+extern char *prom_firstprop(int node);
+
+/* Returns the next property after the passed property for the given
+ * node. Returns null string on failure.
+ */
+extern char *prom_nextprop(int node, char *prev_property);
+
+/* Returns 1 if the specified node has given property. */
+extern int prom_node_has_property(int node, char *property);
+
+/* Set the indicated property at the given node with the passed value.
+ * Returns the number of bytes of your value that the prom took.
+ */
+extern int prom_setprop(int node, char *prop_name, char *prop_value,
+ int value_size);
+
+extern int prom_pathtoinode(char *path);
+extern int prom_inst2pkg(int);
+
+/* Dorking with Bus ranges... */
+
+/* Adjust reg values with the passed ranges. */
+extern void prom_adjust_regs(struct linux_prom_registers *regp, int nregs,
+ struct linux_prom_ranges *rangep, int nranges);
+
+/* Adjust child ranges with the passed parent ranges. */
+extern void prom_adjust_ranges(struct linux_prom_ranges *cranges, int ncranges,
+ struct linux_prom_ranges *pranges, int npranges);
+
+/* Apply promlib probed OBIO ranges to registers. */
+extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs);
+
+/* Apply ranges of any prom node (and optionally parent node as well) to registers. */
+extern void prom_apply_generic_ranges(int node, int parent,
+ struct linux_prom_registers *sbusregs, int nregs);
+
+
+#endif /* !(__SPARC_OPLIB_H) */
diff --git a/include/asm-sparc/page.h b/include/asm-sparc/page.h
index a048ac76c..43bbf1847 100644
--- a/include/asm-sparc/page.h
+++ b/include/asm-sparc/page.h
@@ -1,31 +1,42 @@
-/* page.h: Various defines and such for MMU operations on the Sparc for
- the Linux kernel.
-
- Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
-*/
+/* $Id: page.h,v 1.30 1996/10/27 08:55:30 davem Exp $
+ * page.h: Various defines and such for MMU operations on the Sparc for
+ * the Linux kernel.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
#ifndef _SPARC_PAGE_H
#define _SPARC_PAGE_H
-#include <asm/asi.h> /* for get/set segmap/pte routines */
-#include <asm/contregs.h> /* for switch_to_context */
+#include <asm/head.h> /* for KERNBASE */
-#define PAGE_SHIFT 12 /* This is the virtual page... */
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (1 << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+#ifdef __KERNEL__
#ifndef __ASSEMBLY__
-#define PAGE_SIZE (1UL << PAGE_SHIFT)
-/* to mask away the intra-page address bits */
-#define PAGE_MASK (~(PAGE_SIZE-1))
+#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
-#ifdef __KERNEL__
+extern unsigned long page_offset;
+
+#define PAGE_OFFSET (page_offset)
+
+/* translate between physical and virtual addresses */
+extern unsigned long (*mmu_v2p)(unsigned long);
+extern unsigned long (*mmu_p2v)(unsigned long);
+
+#define __pa(x) mmu_v2p(x)
+#define __va(x) mmu_p2v(x)
/* The following structure is used to hold the physical
- * memory configuration of the machine. This is filled
- * in probe_memory() and is later used by mem_init() to
- * set up mem_map[]. We statically allocate 14 of these
- * structs, this is arbitrary. The entry after the last
- * valid one has num_bytes==0.
+ * memory configuration of the machine. This is filled in
+ * probe_memory() and is later used by mem_init() to set up
+ * mem_map[]. We statically allocate SPARC_PHYS_BANKS of
+ * these structs, this is arbitrary. The entry after the
+ * last valid one has num_bytes==0.
*/
struct sparc_phys_banks {
@@ -33,148 +44,95 @@ struct sparc_phys_banks {
unsigned long num_bytes;
};
-#define CONFIG_STRICT_MM_TYPECHECKS
+#define SPARC_PHYS_BANKS 32
+
+extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
+
+/* Cache alias structure. Entry is valid if context != -1. */
+struct cache_palias {
+ unsigned long vaddr;
+ int context;
+};
+
+extern struct cache_palias *sparc_aliases;
-#ifdef CONFIG_STRICT_MM_TYPECHECKS
+/* passing structs on the Sparc slow us down tremendously... */
+
+/* #define STRICT_MM_TYPECHECKS */
+
+#ifdef STRICT_MM_TYPECHECKS
/*
* These are used to make use of C type-checking..
*/
typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long iopte; } iopte_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long ctxd; } ctxd_t;
typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct { unsigned long iopgprot; } iopgprot_t;
#define pte_val(x) ((x).pte)
+#define iopte_val(x) ((x).iopte)
#define pmd_val(x) ((x).pmd)
#define pgd_val(x) ((x).pgd)
+#define ctxd_val(x) ((x).ctxd)
#define pgprot_val(x) ((x).pgprot)
+#define iopgprot_val(x) ((x).iopgprot)
#define __pte(x) ((pte_t) { (x) } )
+#define __iopte(x) ((iopte_t) { (x) } )
#define __pmd(x) ((pmd_t) { (x) } )
#define __pgd(x) ((pgd_t) { (x) } )
+#define __ctxd(x) ((ctxd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
+#define __iopgprot(x) ((iopgprot_t) { (x) } )
#else
/*
* .. while these make it easier on the compiler
*/
typedef unsigned long pte_t;
+typedef unsigned long iopte_t;
typedef unsigned long pmd_t;
typedef unsigned long pgd_t;
+typedef unsigned long ctxd_t;
typedef unsigned long pgprot_t;
+typedef unsigned long iopgprot_t;
#define pte_val(x) (x)
+#define iopte_val(x) (x)
#define pmd_val(x) (x)
#define pgd_val(x) (x)
+#define ctxd_val(x) (x)
#define pgprot_val(x) (x)
+#define iopgprot_val(x) (x)
#define __pte(x) (x)
+#define __iopte(x) (x)
#define __pmd(x) (x)
#define __pgd(x) (x)
+#define __ctxd(x) (x)
#define __pgprot(x) (x)
+#define __iopgprot(x) (x)
#endif
-/* The current va context is global and known, so all that is needed to
- * do an invalidate is flush the VAC.
- */
+#define copy_page(from,to) memcpy((void *) to, (void *) from, PAGE_SIZE)
-#define invalidate() flush_vac_context() /* how conveeeiiiiinnnient :> */
+extern unsigned long sparc_unmapped_base;
-#define copy_page(from,to) memcpy((void *) to, (void *) from, PAGE_SIZE)
+#define TASK_UNMAPPED_BASE (sparc_unmapped_base)
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-#define PAGE_OFFSET 0
-#define MAP_NR(addr) (((unsigned long)(addr)) >> PAGE_SHIFT)
-#define MAP_PAGE_RESERVED (1<<15)
-
-
-#endif /* !(__ASSEMBLY__) */
-
-/* The rest is kind of funky because on the sparc, the offsets into the mmu
- * entries are encoded in magic alternate address space tables. I will
- * probably find some nifty inline assembly routines to do the equivalent.
- * Much thought must go into this code. (davem@caip.rutgers.edu)
+/* Now, to allow for very large physical memory configurations we
+ * place the page pool both above the kernel and below the kernel.
*/
+#define MAP_NR(addr) ((((unsigned long) (addr)) - PAGE_OFFSET) >> PAGE_SHIFT)
-/* Bitfields within a Sparc sun4c PTE (page table entry). */
-
-#define PTE_V 0x80000000 /* valid bit */
-#define PTE_ACC 0x60000000 /* access bits */
-#define PTE_W 0x40000000 /* writable bit */
-#define PTE_P 0x20000000 /* privileged page */
-#define PTE_NC 0x10000000 /* page is non-cacheable */
-#define PTE_TYP 0x0c000000 /* page type field */
-#define PTE_RMEM 0x00000000 /* type == on board real memory */
-#define PTE_IO 0x04000000 /* type == i/o area */
-#define PTE_VME16 0x08000000 /* type == 16-bit VME area */
-#define PTE_VME32 0x0c000000 /* type == 32-bit VME area */
-#define PTE_R 0x02000000 /* page has been referenced */
-#define PTE_M 0x01000000 /* page has been modified */
-#define PTE_RESV 0x00f80000 /* reserved bits */
-#define PTE_PHYPG 0x0007ffff /* phys pg number, sun4c only uses 16bits */
-
-extern __inline__ unsigned long get_segmap(unsigned long addr)
-{
- register unsigned long entry;
-
- __asm__ __volatile__("lduba [%1] 0x3, %0" :
- "=r" (entry) :
- "r" (addr));
-
- return (entry&0x7f);
-}
-
-extern __inline__ void put_segmap(unsigned long addr, unsigned long entry)
-{
-
- __asm__ __volatile__("stba %1, [%0] 0x3" : : "r" (addr), "r" (entry&0x7f));
-
- return;
-}
-
-extern __inline__ unsigned long get_pte(unsigned long addr)
-{
- register unsigned long entry;
-
- __asm__ __volatile__("lda [%1] 0x4, %0" :
- "=r" (entry) :
- "r" (addr));
- return entry;
-}
-
-extern __inline__ void put_pte(unsigned long addr, unsigned long entry)
-{
- __asm__ __volatile__("sta %1, [%0] 0x4" : :
- "r" (addr),
- "r" (entry));
-
- return;
-}
-
-extern __inline__ void switch_to_context(int context)
-{
- __asm__ __volatile__("stba %0, [%1] 0x2" : :
- "r" (context),
- "r" (0x30000000));
-
- return;
-}
-
-extern __inline__ int get_context(void)
-{
- register int ctx;
-
- __asm__ __volatile__("lduba [%1] 0x2, %0" :
- "=r" (ctx) :
- "r" (0x30000000));
-
- return ctx;
-}
-
-typedef unsigned short mem_map_t;
+#endif /* !(__ASSEMBLY__) */
#endif /* __KERNEL__ */
diff --git a/include/asm-sparc/param.h b/include/asm-sparc/param.h
index 45a9133af..7e14a410e 100644
--- a/include/asm-sparc/param.h
+++ b/include/asm-sparc/param.h
@@ -1,3 +1,4 @@
+/* $Id: param.h,v 1.3 1995/11/25 02:32:18 davem Exp $ */
#ifndef _ASMSPARC_PARAM_H
#define _ASMSPARC_PARAM_H
@@ -5,7 +6,7 @@
#define HZ 100
#endif
-#define EXEC_PAGESIZE 4096
+#define EXEC_PAGESIZE 8192 /* Thanks for sun4's we carry baggage... */
#ifndef NGROUPS
#define NGROUPS 32
diff --git a/include/asm-sparc/pconf.h b/include/asm-sparc/pconf.h
new file mode 100644
index 000000000..d73c1f1c4
--- /dev/null
+++ b/include/asm-sparc/pconf.h
@@ -0,0 +1,25 @@
+/* $Id: pconf.h,v 1.3 1996/04/25 06:13:25 davem Exp $
+ * pconf.h: pathconf() and fpathconf() defines for SunOS
+ * system call compatibility.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_PCONF_H
+#define _SPARC_PCONF_H
+
+#include <linux/fs.h>
+#include <linux/limits.h>
+
+#define _PCONF_LINK 1 /* Max number of links to an object */
+#define _PCONF_CANON 2 /* TTY input buffer line size */
+#define _PCONF_INPUT 3 /* Biggest packet a tty can imbibe at once */
+#define _PCONF_NAME 4 /* Filename length max */
+#define _PCONF_PATH 5 /* Max size of a pathname */
+#define _PCONF_PIPE 6 /* Buffer size for a pipe */
+#define _PCONF_CHRESTRICT 7 /* Can only root chown files? */
+#define _PCONF_NOTRUNC 8 /* Are pathnames truncated if too big? */
+#define _PCONF_VDISABLE 9 /* Magic char to disable special tty chars */
+#define _PCONF_MAXPCONF 9
+
+#endif /* !(_SPARC_PCONF_H) */
diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
index 45b652108..02435d788 100644
--- a/include/asm-sparc/pgtable.h
+++ b/include/asm-sparc/pgtable.h
@@ -1,3 +1,4 @@
+/* $Id: pgtable.h,v 1.51 1996/10/27 08:55:32 davem Exp $ */
#ifndef _SPARC_PGTABLE_H
#define _SPARC_PGTABLE_H
@@ -7,100 +8,133 @@
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
-/* PMD_SHIFT determines the size of the area a second-level page table can map */
-#define PMD_SHIFT 18
-#define PMD_SIZE (1UL << PMD_SHIFT)
-#define PMD_MASK (~(PMD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT 18
-#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK (~(PGDIR_SIZE-1))
-#define PGDIR_ALIGN(addr) (((addr)+PGDIR_SIZE-1)&PGDIR_MASK)
+#include <linux/mm.h>
+#include <asm/asi.h>
+#include <asm/pgtsun4c.h>
+#include <asm/pgtsrmmu.h>
+#include <asm/vac-ops.h>
+#include <asm/oplib.h>
+#include <asm/sbus.h>
+
+extern void load_mmu(void);
+extern int io_remap_page_range(unsigned long from, unsigned long to,
+ unsigned long size, pgprot_t prot, int space);
+
+extern void (*quick_kernel_fault)(unsigned long);
+
+/* Allocate a block of RAM which is aligned to its size.
+ This procedure can be used until the call to mem_init(). */
+extern void *sparc_init_alloc(unsigned long *kbrk, unsigned long size);
+
+/* mmu-specific process creation/cloning/etc hooks. */
+extern void (*mmu_exit_hook)(void);
+extern void (*mmu_flush_hook)(void);
+
+/* translate between physical and virtual addresses */
+extern unsigned long (*mmu_v2p)(unsigned long);
+extern unsigned long (*mmu_p2v)(unsigned long);
+
+/* Routines for data transfer buffers. */
+extern char *(*mmu_lockarea)(char *, unsigned long);
+extern void (*mmu_unlockarea)(char *, unsigned long);
+
+/* Routines for getting a dvma scsi buffer. */
+struct mmu_sglist {
+ char *addr;
+ char *__dont_touch;
+ unsigned int len;
+ char *dvma_addr;
+};
+extern char *(*mmu_get_scsi_one)(char *, unsigned long, struct linux_sbus *sbus);
+extern void (*mmu_get_scsi_sgl)(struct mmu_sglist *, int, struct linux_sbus *sbus);
+extern void (*mmu_release_scsi_one)(char *, unsigned long, struct linux_sbus *sbus);
+extern void (*mmu_release_scsi_sgl)(struct mmu_sglist *, int, struct linux_sbus *sbus);
+
+extern void (*mmu_map_dma_area)(unsigned long addr, int len);
+
+extern unsigned int pmd_shift;
+extern unsigned int pmd_size;
+extern unsigned int pmd_mask;
+extern unsigned int (*pmd_align)(unsigned int);
+
+extern unsigned int pgdir_shift;
+extern unsigned int pgdir_size;
+extern unsigned int pgdir_mask;
+extern unsigned int (*pgdir_align)(unsigned int);
+
+extern unsigned int ptrs_per_pte;
+extern unsigned int ptrs_per_pmd;
+extern unsigned int ptrs_per_pgd;
+
+extern unsigned int ptrs_per_page;
+
+extern unsigned long (*(vmalloc_start))(void);
+
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_START vmalloc_start()
+
+extern pgprot_t page_none;
+extern pgprot_t page_shared;
+extern pgprot_t page_copy;
+extern pgprot_t page_readonly;
+extern pgprot_t page_kernel;
+
+#define PMD_SHIFT (pmd_shift)
+#define PMD_SIZE (pmd_size)
+#define PMD_MASK (pmd_mask)
+#define PMD_ALIGN (pmd_align)
+#define PGDIR_SHIFT (pgdir_shift)
+#define PGDIR_SIZE (pgdir_size)
+#define PGDIR_MASK (pgdir_mask)
+#define PGDIR_ALIGN (pgdir_align)
+#define PTRS_PER_PTE (ptrs_per_pte)
+#define PTRS_PER_PMD (ptrs_per_pmd)
+#define PTRS_PER_PGD (ptrs_per_pgd)
+
+#define PAGE_NONE (page_none)
+#define PAGE_SHARED (page_shared)
+#define PAGE_COPY (page_copy)
+#define PAGE_READONLY (page_readonly)
+#define PAGE_KERNEL (page_kernel)
+#define PAGE_INVALID (page_invalid)
+
+/* Top-level page directory */
+extern pgd_t swapper_pg_dir[1024];
-/*
- * Just following the i386 lead, because it works on the Sparc sun4c
- * machines. Two-level, therefore there is no real PMD.
+/* Page table for 0-4MB for everybody, on the Sparc this
+ * holds the same as on the i386.
*/
+extern pte_t pg0[1024];
-#define PTRS_PER_PTE 1024
-#define PTRS_PER_PMD 1
-#define PTRS_PER_PGD 1024
+extern unsigned long ptr_in_current_pgd;
/* the no. of pointers that fit on a page: this will go away */
#define PTRS_PER_PAGE (PAGE_SIZE/sizeof(void*))
-/* Just any arbitrary offset to the start of the vmalloc VM area: the
- * current 8MB value just means that there will be a 8MB "hole" after the
- * physical memory until the kernel virtual memory starts. That means that
- * any out-of-bounds memory accesses will hopefully be caught.
- * The vmalloc() routines leaves a hole of 4kB between each vmalloced
- * area for the same reason. ;)
- */
-#define VMALLOC_OFFSET (8*1024*1024)
-#define VMALLOC_START ((high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
-#define VMALLOC_VMADDR(x) (TASK_SIZE + (unsigned long)(x))
-
-/*
- * Sparc page table fields.
- */
-
-#define _PAGE_VALID 0x80000000 /* valid page */
-#define _PAGE_WRITE 0x40000000 /* can be written to */
-#define _PAGE_PRIV 0x20000000 /* bit to signify privileged page */
-#define _PAGE_NOCACHE 0x10000000 /* non-cacheable page */
-#define _PAGE_REF 0x02000000 /* Page has been accessed/referenced */
-#define _PAGE_DIRTY 0x01000000 /* Page has been modified, is dirty */
-#define _PAGE_COW 0x00800000 /* COW page, hardware ignores this bit (untested) */
-
-
-/* Sparc sun4c mmu has only a writable bit. Thus if a page is valid it can be
- * read in a load, and executed as code automatically. Although, the memory fault
- * hardware does make a distinction between date-read faults and insn-read faults
- * which is determined by which trap happened plus magic sync/async fault register
- * values which must be checked in the actual fault handler.
+/* Here is a trick, since mmap.c need the initializer elements for
+ * protection_map[] to be constant at compile time, I set the following
+ * to all zeros. I set it to the real values after I link in the
+ * appropriate MMU page table routines at boot time.
*/
-
-/* We want the swapper not to swap out page tables, thus dirty and writable
- * so that the kernel can change the entries as needed. Also valid for
- * obvious reasons.
- */
-#define _PAGE_TABLE (_PAGE_VALID | _PAGE_WRITE | _PAGE_DIRTY)
-#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_REF | _PAGE_DIRTY)
-
-#define PAGE_NONE __pgprot(_PAGE_VALID | _PAGE_REF)
-#define PAGE_SHARED __pgprot(_PAGE_VALID | _PAGE_WRITE | _PAGE_REF)
-#define PAGE_COPY __pgprot(_PAGE_VALID | _PAGE_REF | _PAGE_COW)
-#define PAGE_READONLY __pgprot(_PAGE_VALID | _PAGE_REF)
-#define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_WRITE | _PAGE_NOCACHE | _PAGE_REF | _PAGE_PRIV)
-#define PAGE_INVALID __pgprot(_PAGE_PRIV)
-
-#define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | _PAGE_REF | (x))
-
-/* I define these like the i386 does because the check for text or data fault
- * is done at trap time by the low level handler. Maybe I can set these bits
- * then once determined. I leave them like this for now though.
- */
-#define __P000 PAGE_NONE
-#define __P001 PAGE_READONLY
-#define __P010 PAGE_COPY
-#define __P011 PAGE_COPY
-#define __P100 PAGE_READONLY
-#define __P101 PAGE_READONLY
-#define __P110 PAGE_COPY
-#define __P111 PAGE_COPY
-
-#define __S000 PAGE_NONE
-#define __S001 PAGE_READONLY
-#define __S010 PAGE_SHARED
-#define __S011 PAGE_SHARED
-#define __S100 PAGE_READONLY
-#define __S101 PAGE_READONLY
-#define __S110 PAGE_SHARED
-#define __S111 PAGE_SHARED
-
-
-extern unsigned long pg0[1024];
+#define __P000 __pgprot(0)
+#define __P001 __pgprot(0)
+#define __P010 __pgprot(0)
+#define __P011 __pgprot(0)
+#define __P100 __pgprot(0)
+#define __P101 __pgprot(0)
+#define __P110 __pgprot(0)
+#define __P111 __pgprot(0)
+
+#define __S000 __pgprot(0)
+#define __S001 __pgprot(0)
+#define __S010 __pgprot(0)
+#define __S011 __pgprot(0)
+#define __S100 __pgprot(0)
+#define __S101 __pgprot(0)
+#define __S110 __pgprot(0)
+#define __S111 __pgprot(0)
+
+extern int num_contexts;
/*
* BAD_PAGETABLE is used when we need a bogus page-table, while
@@ -112,231 +146,219 @@ extern unsigned long pg0[1024];
extern pte_t __bad_page(void);
extern pte_t * __bad_pagetable(void);
-extern unsigned long __zero_page(void);
-
+extern unsigned long empty_zero_page;
#define BAD_PAGETABLE __bad_pagetable()
#define BAD_PAGE __bad_page()
-#define ZERO_PAGE __zero_page()
+#define ZERO_PAGE ((unsigned long)(&(empty_zero_page)))
/* number of bits that fit into a memory pointer */
-#define BITS_PER_PTR (8*sizeof(unsigned long)) /* better check this stuff */
+#define BITS_PER_PTR (8*sizeof(unsigned long))
/* to align the pointer to a pointer address */
#define PTR_MASK (~(sizeof(void*)-1))
-
#define SIZEOF_PTR_LOG2 2
+extern unsigned long (*pte_page)(pte_t);
+extern unsigned long (*pmd_page)(pmd_t);
+extern unsigned long (*pgd_page)(pgd_t);
-/* to set the page-dir
- *
- * On the Sparc the page segments hold 64 pte's which means 256k/segment.
- * Therefore there is no global idea of 'the' page directory, although we
- * make a virtual one in kernel memory so that we can keep the stats on
- * all the pages since not all can be loaded at once in the mmu.
- */
-
-#define SET_PAGE_DIR(tsk,pgdir)
+extern void (*sparc_update_rootmmu_dir)(struct task_struct *, pgd_t *pgdir);
+#define SET_PAGE_DIR(tsk,pgdir) sparc_update_rootmmu_dir(tsk, pgdir)
+
/* to find an entry in a page-table */
#define PAGE_PTR(address) \
((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
-extern unsigned long high_memory;
+extern int (*pte_none)(pte_t);
+extern int (*pte_present)(pte_t);
+extern void (*pte_clear)(pte_t *);
-extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
-extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_VALID; }
-extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] > 1; }
-extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; }
-extern inline void pte_reuse(pte_t *ptep)
-{
- if(!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED))
- mem_map[MAP_NR(ptep)]++;
-}
+extern int (*pmd_none)(pmd_t);
+extern int (*pmd_bad)(pmd_t);
+extern int (*pmd_present)(pmd_t);
+extern void (*pmd_clear)(pmd_t *);
-extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); }
-extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE || pmd_val(pmd) > high_memory; }
-extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_VALID; }
-extern inline int pmd_inuse(pmd_t *pmdp) { return 0; }
-extern inline void pmd_clear(pmd_t *pmdp) { pmd_val(*pmdp) = 0; }
-extern inline void pmd_reuse(pmd_t * pmdp) { }
-
-extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); }
-extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & ~PAGE_MASK) != _PAGE_TABLE || pgd_val(pgd) > high_memory; }
-extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_VALID; }
-extern inline int pgd_inuse(pgd_t *pgdp) { return mem_map[MAP_NR(pgdp)] > 1; }
-extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; }
-extern inline void pgd_reuse(pgd_t *pgdp)
-{
- if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED))
- mem_map[MAP_NR(pgdp)]++;
-}
+extern int (*pgd_none)(pgd_t);
+extern int (*pgd_bad)(pgd_t);
+extern int (*pgd_present)(pgd_t);
+extern void (*pgd_clear)(pgd_t *);
/*
* The following only work if pte_present() is true.
* Undefined behaviour if not..
*/
-extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_VALID; }
-extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
-extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_VALID; }
-extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_REF; }
-extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_REF; }
-extern inline int pte_cow(pte_t pte) { return pte_val(pte) & _PAGE_COW; }
-
-extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_WRITE; return pte; }
-extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_VALID; return pte; }
-extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_VALID; return pte; }
-extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_REF; return pte; }
-extern inline pte_t pte_uncow(pte_t pte) { pte_val(pte) &= ~_PAGE_COW; return pte; }
-extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return pte; }
-extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_VALID; return pte; }
-extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_VALID; return pte; }
-extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_REF; return pte; }
-extern inline pte_t pte_mkcow(pte_t pte) { pte_val(pte) |= _PAGE_COW; return pte; }
+extern int (*pte_write)(pte_t);
+extern int (*pte_dirty)(pte_t);
+extern int (*pte_young)(pte_t);
+
+extern pte_t (*pte_wrprotect)(pte_t);
+extern pte_t (*pte_mkclean)(pte_t);
+extern pte_t (*pte_mkold)(pte_t);
+extern pte_t (*pte_mkwrite)(pte_t);
+extern pte_t (*pte_mkdirty)(pte_t);
+extern pte_t (*pte_mkyoung)(pte_t);
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
-extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
-{ pte_t pte; pte_val(pte) = page | pgprot_val(pgprot); return pte; }
-
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
-
-extern inline unsigned long pte_page(pte_t pte) { return pte_val(pte) & PAGE_MASK; }
-
-extern inline unsigned long pmd_page(pmd_t pmd) { return pmd_val(pmd) & PAGE_MASK; }
-
-extern inline unsigned long pgd_page(pgd_t pgd) { return pgd_val(pgd) & PAGE_MASK; }
+extern pte_t (*mk_pte)(unsigned long, pgprot_t);
+extern pte_t (*mk_pte_phys)(unsigned long, pgprot_t);
+extern pte_t (*mk_pte_io)(unsigned long, pgprot_t, int);
-extern inline void pgd_set(pgd_t * pgdp, pte_t * ptep)
-{ pgd_val(*pgdp) = _PAGE_TABLE | (unsigned long) ptep; }
+extern void (*pgd_set)(pgd_t *, pmd_t *);
-/* to find an entry in a page-table-directory */
-#define PAGE_DIR_OFFSET(tsk,address) \
-((((unsigned long)(address)) >> 22) + (pgd_t *) (tsk)->tss.cr3)
+extern pte_t (*pte_modify)(pte_t, pgprot_t);
/* to find an entry in a page-table-directory */
-extern inline pgd_t * pgd_offset(struct task_struct * tsk, unsigned long address)
-{
- return (pgd_t *) tsk->tss.cr3 + (address >> PGDIR_SHIFT);
-}
+extern pgd_t * (*pgd_offset)(struct mm_struct *, unsigned long);
/* Find an entry in the second-level page table.. */
-extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
-{
- return (pmd_t *) dir;
-}
+extern pmd_t * (*pmd_offset)(pgd_t *, unsigned long);
/* Find an entry in the third-level page table.. */
-extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
-{
- return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
-}
-
+extern pte_t * (*pte_offset)(pmd_t *, unsigned long);
/*
* Allocate and free page tables. The xxx_kernel() versions are
* used to allocate a kernel page table - this turns on ASN bits
* if any, and marks the page tables reserved.
*/
-extern inline void pte_free_kernel(pte_t * pte)
-{
- mem_map[MAP_NR(pte)] = 1;
- free_page((unsigned long) pte);
-}
+extern void (*pte_free_kernel)(pte_t *);
-extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
-{
- address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
- if (pmd_none(*pmd)) {
- pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
- if (pmd_none(*pmd)) {
- if (page) {
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
- mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED;
- return page + address;
- }
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
- return NULL;
- }
- free_page((unsigned long) page);
- }
- if (pmd_bad(*pmd)) {
- printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + address;
-}
+extern pte_t * (*pte_alloc_kernel)(pmd_t *, unsigned long);
/*
* allocating and freeing a pmd is trivial: the 1-entry pmd is
* inside the pgd, so has no extra memory associated with it.
*/
-extern inline void pmd_free_kernel(pmd_t * pmd)
-{
-}
+extern void (*pmd_free_kernel)(pmd_t *);
-extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
-{
- return (pmd_t *) pgd;
-}
+extern pmd_t * (*pmd_alloc_kernel)(pgd_t *, unsigned long);
-extern inline void pte_free(pte_t * pte)
-{
- free_page((unsigned long) pte);
-}
+extern void (*pte_free)(pte_t *);
-extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
-{
- address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
- if (pmd_none(*pmd)) {
- pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
- if (pmd_none(*pmd)) {
- if (page) {
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
- return page + address;
- }
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
- return NULL;
- }
- free_page((unsigned long) page);
- }
- if (pmd_bad(*pmd)) {
- printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + address;
-}
+extern pte_t * (*pte_alloc)(pmd_t *, unsigned long);
/*
* allocating and freeing a pmd is trivial: the 1-entry pmd is
* inside the pgd, so has no extra memory associated with it.
*/
-extern inline void pmd_free(pmd_t * pmd)
-{
-}
+extern void (*pmd_free)(pmd_t *);
-extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
-{
- return (pmd_t *) pgd;
-}
+extern pmd_t * (*pmd_alloc)(pgd_t *, unsigned long);
+
+extern void (*pgd_free)(pgd_t *);
+
+extern pgd_t * (*pgd_alloc)(void);
+
+/* Fine grained cache/tlb flushing. */
+
+#ifdef __SMP__
+extern void (*local_flush_cache_all)(void);
+extern void (*local_flush_cache_mm)(struct mm_struct *);
+extern void (*local_flush_cache_range)(struct mm_struct *, unsigned long start,
+ unsigned long end);
+extern void (*local_flush_cache_page)(struct vm_area_struct *, unsigned long address);
+
+extern void (*local_flush_tlb_all)(void);
+extern void (*local_flush_tlb_mm)(struct mm_struct *);
+extern void (*local_flush_tlb_range)(struct mm_struct *, unsigned long start,
+ unsigned long end);
+extern void (*local_flush_tlb_page)(struct vm_area_struct *, unsigned long address);
+
+extern void (*local_flush_page_to_ram)(unsigned long address);
-extern inline void pgd_free(pgd_t *pgd)
+extern void smp_flush_cache_all(void);
+extern void smp_flush_cache_mm(struct mm_struct *mm);
+extern void smp_flush_cache_range(struct mm_struct *mm,
+ unsigned long start,
+ unsigned long end);
+extern void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
+
+extern void smp_flush_tlb_all(void);
+extern void smp_flush_tlb_mm(struct mm_struct *mm);
+extern void smp_flush_tlb_range(struct mm_struct *mm,
+ unsigned long start,
+ unsigned long end);
+extern void smp_flush_tlb_page(struct vm_area_struct *mm, unsigned long page);
+extern void smp_flush_page_to_ram(unsigned long page);
+#endif
+
+extern void (*flush_cache_all)(void);
+extern void (*flush_cache_mm)(struct mm_struct *);
+extern void (*flush_cache_range)(struct mm_struct *, unsigned long start,
+ unsigned long end);
+extern void (*flush_cache_page)(struct vm_area_struct *, unsigned long address);
+
+extern void (*flush_tlb_all)(void);
+extern void (*flush_tlb_mm)(struct mm_struct *);
+extern void (*flush_tlb_range)(struct mm_struct *, unsigned long start, unsigned long end);
+extern void (*flush_tlb_page)(struct vm_area_struct *, unsigned long address);
+
+extern void (*flush_page_to_ram)(unsigned long page);
+
+/* The permissions for pgprot_val to make a page mapped on the obio space */
+extern unsigned int pg_iobits;
+
+/* MMU context switching. */
+extern void (*switch_to_context)(struct task_struct *tsk);
+
+/* Certain architectures need to do special things when pte's
+ * within a page table are directly modified. Thus, the following
+ * hook is made available.
+ */
+
+#if 0 /* XXX try this soon XXX */
+extern void (*set_pte)(struct vm_area_struct *vma, unsigned long address,
+ pte_t *pteptr, pte_t pteval);
+#else
+extern void (*set_pte)(pte_t *pteptr, pte_t pteval);
+#endif
+
+extern char *(*mmu_info)(void);
+
+/* Fault handler stuff... */
+#define FAULT_CODE_PROT 0x1
+#define FAULT_CODE_WRITE 0x2
+#define FAULT_CODE_USER 0x4
+extern void (*update_mmu_cache)(struct vm_area_struct *vma, unsigned long address, pte_t pte);
+
+extern int invalid_segment;
+
+#define SWP_TYPE(entry) (((entry)>>2) & 0x7f)
+#define SWP_OFFSET(entry) (((entry) >> 9) & 0x7ffff)
+#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << 9))
+
+struct ctx_list {
+ struct ctx_list *next;
+ struct ctx_list *prev;
+ unsigned int ctx_number;
+ struct mm_struct *ctx_mm;
+};
+
+extern struct ctx_list *ctx_list_pool; /* Dynamically allocated */
+extern struct ctx_list ctx_free; /* Head of free list */
+extern struct ctx_list ctx_used; /* Head of used contexts list */
+
+#define NO_CONTEXT -1
+
+extern __inline__ void remove_from_ctx_list(struct ctx_list *entry)
{
- free_page((unsigned long) pgd);
+ entry->next->prev = entry->prev;
+ entry->prev->next = entry->next;
}
-extern inline pgd_t *pgd_alloc(void)
+
+extern __inline__ void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry)
{
- return (pgd_t *) get_free_page(GFP_KERNEL);
+ entry->next = head;
+ (entry->prev = head->prev)->next = entry;
+ head->prev = entry;
}
-
-extern pgd_t swapper_pg_dir[1024];
+#define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry)
+#define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry)
#endif /* !(_SPARC_PGTABLE_H) */
diff --git a/include/asm-sparc/pgtsrmmu.h b/include/asm-sparc/pgtsrmmu.h
new file mode 100644
index 000000000..f8ca14944
--- /dev/null
+++ b/include/asm-sparc/pgtsrmmu.h
@@ -0,0 +1,268 @@
+/* $Id: pgtsrmmu.h,v 1.24 1996/10/07 03:03:06 davem Exp $
+ * pgtsrmmu.h: SRMMU page table defines and code.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_PGTSRMMU_H
+#define _SPARC_PGTSRMMU_H
+
+#include <linux/config.h>
+#include <asm/page.h>
+
+#if CONFIG_AP1000
+#include <asm/ap1000/apreg.h>
+#endif
+
+/* PMD_SHIFT determines the size of the area a second-level page table can map */
+#define SRMMU_PMD_SHIFT 18
+#define SRMMU_PMD_SIZE (1UL << SRMMU_PMD_SHIFT)
+#define SRMMU_PMD_MASK (~(SRMMU_PMD_SIZE-1))
+#define SRMMU_PMD_ALIGN(addr) (((addr)+SRMMU_PMD_SIZE-1)&SRMMU_PMD_MASK)
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define SRMMU_PGDIR_SHIFT 24
+#define SRMMU_PGDIR_SIZE (1UL << SRMMU_PGDIR_SHIFT)
+#define SRMMU_PGDIR_MASK (~(SRMMU_PGDIR_SIZE-1))
+#define SRMMU_PGDIR_ALIGN(addr) (((addr)+SRMMU_PGDIR_SIZE-1)&SRMMU_PGDIR_MASK)
+
+#define SRMMU_PTRS_PER_PTE 64
+#define SRMMU_PTRS_PER_PMD 64
+#define SRMMU_PTRS_PER_PGD 256
+
+#define SRMMU_PTE_TABLE_SIZE 0x100 /* 64 entries, 4 bytes a piece */
+#define SRMMU_PMD_TABLE_SIZE 0x100 /* 64 entries, 4 bytes a piece */
+#define SRMMU_PGD_TABLE_SIZE 0x400 /* 256 entries, 4 bytes a piece */
+
+#define SRMMU_VMALLOC_START (0xfe300000)
+
+/* Definition of the values in the ET field of PTD's and PTE's */
+#define SRMMU_ET_MASK 0x3
+#define SRMMU_ET_INVALID 0x0
+#define SRMMU_ET_PTD 0x1
+#define SRMMU_ET_PTE 0x2
+#define SRMMU_ET_REPTE 0x3 /* AIEEE, SuperSparc II reverse endian page! */
+
+/* Physical page extraction from PTP's and PTE's. */
+#define SRMMU_CTX_PMASK 0xfffffff0
+#define SRMMU_PTD_PMASK 0xfffffff0
+#define SRMMU_PTE_PMASK 0xffffff00
+
+/* The pte non-page bits. Some notes:
+ * 1) cache, dirty, valid, and ref are frobbable
+ * for both supervisor and user pages.
+ * 2) exec and write will only give the desired effect
+ * on user pages
+ * 3) use priv and priv_readonly for changing the
+ * characteristics of supervisor ptes
+ */
+#define SRMMU_CACHE 0x80
+#define SRMMU_DIRTY 0x40
+#define SRMMU_REF 0x20
+#define SRMMU_EXEC 0x08
+#define SRMMU_WRITE 0x04
+#define SRMMU_VALID 0x02 /* SRMMU_ET_PTE */
+#define SRMMU_PRIV 0x1c
+#define SRMMU_PRIV_RDONLY 0x18
+
+#define SRMMU_CHG_MASK (0xffffff00 | SRMMU_REF | SRMMU_DIRTY)
+
+/* Some day I will implement true fine grained access bits for
+ * user pages because the SRMMU gives us the capabilities to
+ * enforce all the protection levels that vma's can have.
+ * XXX But for now...
+ */
+#define SRMMU_PAGE_NONE __pgprot(SRMMU_VALID | SRMMU_CACHE | \
+ SRMMU_PRIV | SRMMU_REF)
+#define SRMMU_PAGE_SHARED __pgprot(SRMMU_VALID | SRMMU_CACHE | \
+ SRMMU_EXEC | SRMMU_WRITE | SRMMU_REF)
+#define SRMMU_PAGE_COPY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
+ SRMMU_EXEC | SRMMU_REF)
+#define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
+ SRMMU_EXEC | SRMMU_REF)
+#define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
+ SRMMU_DIRTY | SRMMU_REF)
+
+/* SRMMU Register addresses in ASI 0x4. These are valid for all
+ * current SRMMU implementations that exist.
+ */
+#define SRMMU_CTRL_REG 0x00000000
+#define SRMMU_CTXTBL_PTR 0x00000100
+#define SRMMU_CTX_REG 0x00000200
+#define SRMMU_FAULT_STATUS 0x00000300
+#define SRMMU_FAULT_ADDR 0x00000400
+
+/*
+ * "normal" sun systems have their memory on bus 0. This means the top
+ * 4 bits of 36 bit physical addresses are 0. We use this define to
+ * determine if a piece of memory might be normal memory, or if its
+ * definately some sort of device memory.
+ *
+ * On the AP+ normal memory is on bus 8. Why? Ask Fujitsu :-)
+*/
+#if CONFIG_AP1000
+#define MEM_BUS_SPACE 8
+#else
+#define MEM_BUS_SPACE 0
+#endif
+
+/* Accessing the MMU control register. */
+extern __inline__ unsigned int srmmu_get_mmureg(void)
+{
+ unsigned int retval;
+ __asm__ __volatile__("lda [%%g0] %1, %0\n\t" :
+ "=r" (retval) :
+ "i" (ASI_M_MMUREGS));
+ return retval;
+}
+
+extern __inline__ void srmmu_set_mmureg(unsigned long regval)
+{
+ __asm__ __volatile__("sta %0, [%%g0] %1\n\t" : :
+ "r" (regval), "i" (ASI_M_MMUREGS) : "memory");
+
+}
+
+extern __inline__ void srmmu_set_ctable_ptr(unsigned long paddr)
+{
+ paddr = ((paddr >> 4) & SRMMU_CTX_PMASK);
+#if MEM_BUS_SPACE
+ paddr |= (MEM_BUS_SPACE<<28);
+#endif
+ __asm__ __volatile__("sta %0, [%1] %2\n\t" : :
+ "r" (paddr), "r" (SRMMU_CTXTBL_PTR),
+ "i" (ASI_M_MMUREGS) :
+ "memory");
+}
+
+extern __inline__ unsigned long srmmu_get_ctable_ptr(void)
+{
+ unsigned int retval;
+
+ __asm__ __volatile__("lda [%1] %2, %0\n\t" :
+ "=r" (retval) :
+ "r" (SRMMU_CTXTBL_PTR),
+ "i" (ASI_M_MMUREGS));
+ return (retval & SRMMU_CTX_PMASK) << 4;
+}
+
+extern __inline__ void srmmu_set_context(int context)
+{
+ __asm__ __volatile__("sta %0, [%1] %2\n\t" : :
+ "r" (context), "r" (SRMMU_CTX_REG),
+ "i" (ASI_M_MMUREGS) : "memory");
+#if CONFIG_AP1000
+ /* The AP1000+ message controller also needs to know
+ the current task's context. */
+ MSC_OUT(MSC_PID, context);
+#endif
+}
+
+extern __inline__ int srmmu_get_context(void)
+{
+ register int retval;
+ __asm__ __volatile__("lda [%1] %2, %0\n\t" :
+ "=r" (retval) :
+ "r" (SRMMU_CTX_REG),
+ "i" (ASI_M_MMUREGS));
+ return retval;
+}
+
+extern __inline__ unsigned int srmmu_get_fstatus(void)
+{
+ unsigned int retval;
+
+ __asm__ __volatile__("lda [%1] %2, %0\n\t" :
+ "=r" (retval) :
+ "r" (SRMMU_FAULT_STATUS), "i" (ASI_M_MMUREGS));
+ return retval;
+}
+
+extern __inline__ unsigned int srmmu_get_faddr(void)
+{
+ unsigned int retval;
+
+ __asm__ __volatile__("lda [%1] %2, %0\n\t" :
+ "=r" (retval) :
+ "r" (SRMMU_FAULT_ADDR), "i" (ASI_M_MMUREGS));
+ return retval;
+}
+
+/* This is guaranteed on all SRMMU's. */
+extern __inline__ void srmmu_flush_whole_tlb(void)
+{
+#if CONFIG_AP1000
+ extern void mc_tlb_flush_all(void);
+ mc_tlb_flush_all();
+#endif
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
+ "r" (0x400), /* Flush entire TLB!! */
+ "i" (ASI_M_FLUSH_PROBE) : "memory");
+
+}
+
+/* These flush types are not available on all chips... */
+extern __inline__ void srmmu_flush_tlb_ctx(void)
+{
+#if CONFIG_AP1000
+ mc_tlb_flush_ctx();
+#endif
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
+ "r" (0x300), /* Flush TLB ctx.. */
+ "i" (ASI_M_FLUSH_PROBE) : "memory");
+
+}
+
+extern __inline__ void srmmu_flush_tlb_region(unsigned long addr)
+{
+#if CONFIG_AP1000
+ mc_tlb_flush_region();
+#endif
+ addr &= SRMMU_PGDIR_MASK;
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
+ "r" (addr | 0x200), /* Flush TLB region.. */
+ "i" (ASI_M_FLUSH_PROBE) : "memory");
+
+}
+
+
+extern __inline__ void srmmu_flush_tlb_segment(unsigned long addr)
+{
+#if CONFIG_AP1000
+ mc_tlb_flush_segment();
+#endif
+ addr &= SRMMU_PMD_MASK;
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
+ "r" (addr | 0x100), /* Flush TLB segment.. */
+ "i" (ASI_M_FLUSH_PROBE) : "memory");
+
+}
+
+extern __inline__ void srmmu_flush_tlb_page(unsigned long page)
+{
+#if CONFIG_AP1000
+ mc_tlb_flush_page(page);
+#endif
+ page &= PAGE_MASK;
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
+ "r" (page), /* Flush TLB page.. */
+ "i" (ASI_M_FLUSH_PROBE) : "memory");
+
+}
+
+extern __inline__ unsigned long srmmu_hwprobe(unsigned long vaddr)
+{
+ unsigned long retval;
+
+ vaddr &= PAGE_MASK;
+ __asm__ __volatile__("lda [%1] %2, %0\n\t" :
+ "=r" (retval) :
+ "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));
+
+ return retval;
+}
+
+extern unsigned long (*srmmu_read_physical)(unsigned long paddr);
+extern void (*srmmu_write_physical)(unsigned long paddr, unsigned long word);
+
+#endif /* !(_SPARC_PGTSRMMU_H) */
diff --git a/include/asm-sparc/pgtsun4.h b/include/asm-sparc/pgtsun4.h
new file mode 100644
index 000000000..4161526c0
--- /dev/null
+++ b/include/asm-sparc/pgtsun4.h
@@ -0,0 +1,10 @@
+/* $Id: pgtsun4.h,v 1.2 1995/11/25 02:32:26 davem Exp $
+ * pgtsun4.c: Regular Sun4 MMU support goes in here.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_PGTSUN4_H
+#define _SPARC_PGTSUN4_H
+
+#endif /* !(_SPARC_PGTSUN4_H) */
diff --git a/include/asm-sparc/pgtsun4c.h b/include/asm-sparc/pgtsun4c.h
new file mode 100644
index 000000000..c54a6079d
--- /dev/null
+++ b/include/asm-sparc/pgtsun4c.h
@@ -0,0 +1,151 @@
+/* $Id: pgtsun4c.h,v 1.27 1996/10/30 06:01:32 davem Exp $
+ * pgtsun4c.h: Sun4c specific pgtable.h defines and code.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_PGTSUN4C_H
+#define _SPARC_PGTSUN4C_H
+
+#include <asm/contregs.h>
+
+/* PMD_SHIFT determines the size of the area a second-level page table can map */
+#define SUN4C_PMD_SHIFT 22
+#define SUN4C_PMD_SIZE (1UL << SUN4C_PMD_SHIFT)
+#define SUN4C_PMD_MASK (~(SUN4C_PMD_SIZE-1))
+#define SUN4C_PMD_ALIGN(addr) (((addr)+SUN4C_PMD_SIZE-1)&SUN4C_PMD_MASK)
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define SUN4C_PGDIR_SHIFT 22
+#define SUN4C_PGDIR_SIZE (1UL << SUN4C_PGDIR_SHIFT)
+#define SUN4C_PGDIR_MASK (~(SUN4C_PGDIR_SIZE-1))
+#define SUN4C_PGDIR_ALIGN(addr) (((addr)+SUN4C_PGDIR_SIZE-1)&SUN4C_PGDIR_MASK)
+
+/* To represent how the sun4c mmu really lays things out. */
+#define SUN4C_REAL_PGDIR_SHIFT 18
+#define SUN4C_REAL_PGDIR_SIZE (1UL << SUN4C_REAL_PGDIR_SHIFT)
+#define SUN4C_REAL_PGDIR_MASK (~(SUN4C_REAL_PGDIR_SIZE-1))
+#define SUN4C_REAL_PGDIR_ALIGN(addr) (((addr)+SUN4C_REAL_PGDIR_SIZE-1)&SUN4C_REAL_PGDIR_MASK)
+
+/*
+ * To be efficient, and not have to worry about allocating such
+ * a huge pgd, we make the kernel sun4c tables each hold 1024
+ * entries and the pgd similarly just like the i386 tables.
+ */
+#define SUN4C_PTRS_PER_PTE 1024
+#define SUN4C_PTRS_PER_PMD 1
+#define SUN4C_PTRS_PER_PGD 1024
+
+/* On the sun4c the physical ram limit is 128MB. We set up our I/O
+ * translations at KERNBASE + 128MB for 1MB, then we begin the VMALLOC
+ * area, makes sense. This works out to the value below.
+ */
+#define SUN4C_VMALLOC_START (0xfe300000)
+
+/*
+ * Sparc SUN4C pte fields.
+ */
+#define _SUN4C_PAGE_VALID 0x80000000 /* valid page */
+#define _SUN4C_PAGE_WRITE 0x40000000 /* can be written to */
+#define _SUN4C_PAGE_PRIV 0x20000000 /* bit to signify privileged page */
+#define _SUN4C_PAGE_USER 0x00000000 /* User page */
+#define _SUN4C_PAGE_NOCACHE 0x10000000 /* non-cacheable page */
+#define _SUN4C_PAGE_IO 0x04000000 /* I/O page */
+#define _SUN4C_PAGE_REF 0x02000000 /* Page has been accessed/referenced */
+#define _SUN4C_PAGE_DIRTY 0x01000000 /* Page has been modified, is dirty */
+#define _SUN4C_PAGE_PRESENT 0x00400000 /* present (known) page */
+
+#define _SUN4C_PAGE_CHG_MASK (0xffff | _SUN4C_PAGE_REF | _SUN4C_PAGE_DIRTY)
+
+#define SUN4C_PAGE_NONE __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_PRIV | \
+ _SUN4C_PAGE_REF)
+#define SUN4C_PAGE_SHARED __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_WRITE | \
+ _SUN4C_PAGE_USER | _SUN4C_PAGE_REF)
+#define SUN4C_PAGE_COPY __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_USER | \
+ _SUN4C_PAGE_REF)
+#define SUN4C_PAGE_READONLY __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_USER | \
+ _SUN4C_PAGE_REF)
+#define SUN4C_PAGE_KERNEL __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_WRITE | \
+ _SUN4C_PAGE_PRIV | _SUN4C_PAGE_DIRTY | \
+ _SUN4C_PAGE_REF | _SUN4C_PAGE_NOCACHE)
+
+extern __inline__ unsigned long sun4c_get_synchronous_error(void)
+{
+ unsigned long sync_err;
+
+ __asm__ __volatile__("lda [%1] %2, %0\n\t" :
+ "=r" (sync_err) :
+ "r" (AC_SYNC_ERR), "i" (ASI_CONTROL));
+ return sync_err;
+}
+
+extern __inline__ unsigned long sun4c_get_synchronous_address(void)
+{
+ unsigned long sync_addr;
+
+ __asm__ __volatile__("lda [%1] %2, %0\n\t" :
+ "=r" (sync_addr) :
+ "r" (AC_SYNC_VA), "i" (ASI_CONTROL));
+ return sync_addr;
+}
+
+/* SUN4C pte, segmap, and context manipulation */
+extern __inline__ unsigned long sun4c_get_segmap(unsigned long addr)
+{
+ register unsigned long entry;
+
+ __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" :
+ "=r" (entry) :
+ "r" (addr), "i" (ASI_SEGMAP));
+
+ return entry;
+}
+
+extern __inline__ void sun4c_put_segmap(unsigned long addr, unsigned long entry)
+{
+
+ __asm__ __volatile__("\n\tstba %1, [%0] %2\n\t" : :
+ "r" (addr), "r" (entry),
+ "i" (ASI_SEGMAP));
+
+ return;
+}
+
+extern __inline__ unsigned long sun4c_get_pte(unsigned long addr)
+{
+ register unsigned long entry;
+
+ __asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" :
+ "=r" (entry) :
+ "r" (addr), "i" (ASI_PTE));
+ return entry;
+}
+
+extern __inline__ void sun4c_put_pte(unsigned long addr, unsigned long entry)
+{
+ __asm__ __volatile__("\n\tsta %1, [%0] %2\n\t" : :
+ "r" (addr),
+ "r" (entry), "i" (ASI_PTE));
+
+ return;
+}
+
+extern __inline__ int sun4c_get_context(void)
+{
+ register int ctx;
+
+ __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" :
+ "=r" (ctx) :
+ "r" (AC_CONTEXT), "i" (ASI_CONTROL));
+
+ return ctx;
+}
+
+extern __inline__ int sun4c_set_context(int ctx)
+{
+ __asm__ __volatile__("\n\tstba %0, [%1] %2\n\t" : :
+ "r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL));
+
+ return ctx;
+}
+
+#endif /* !(_SPARC_PGTSUN4C_H) */
diff --git a/include/asm-sparc/posix_types.h b/include/asm-sparc/posix_types.h
new file mode 100644
index 000000000..1df2f62d2
--- /dev/null
+++ b/include/asm-sparc/posix_types.h
@@ -0,0 +1,111 @@
+#ifndef __ARCH_SPARC_POSIX_TYPES_H
+#define __ARCH_SPARC_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc. Also, we cannot
+ * assume GCC is being used.
+ */
+
+/* When cross-compilation is no longer an issue, fix this. */
+#if defined(__svr4__) || defined(__ELF__)
+typedef unsigned int __kernel_size_t;
+#else
+typedef long unsigned int __kernel_size_t;
+#endif /* !(__svr4__ || __ELF__) */
+
+typedef int __kernel_ssize_t;
+typedef long int __kernel_ptrdiff_t;
+typedef long __kernel_time_t;
+typedef long __kernel_clock_t;
+typedef int __kernel_pid_t;
+typedef unsigned short __kernel_ipc_pid_t;
+typedef unsigned short __kernel_uid_t;
+typedef unsigned short __kernel_gid_t;
+typedef unsigned short __kernel_dev_t;
+typedef unsigned long __kernel_ino_t;
+typedef unsigned short __kernel_mode_t;
+typedef unsigned short __kernel_umode_t;
+typedef short __kernel_nlink_t;
+typedef long __kernel_daddr_t;
+typedef long __kernel_off_t;
+typedef char * __kernel_caddr_t;
+
+#ifdef __GNUC__
+typedef long long __kernel_loff_t;
+#endif
+
+typedef struct {
+ int val[2];
+} __kernel_fsid_t;
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+ unsigned long _tmp = fd / __NFDBITS;
+ unsigned long _rem = fd % __NFDBITS;
+ fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+ unsigned long _tmp = fd / __NFDBITS;
+ unsigned long _rem = fd % __NFDBITS;
+ fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
+{
+ unsigned long _tmp = fd / __NFDBITS;
+ unsigned long _rem = fd % __NFDBITS;
+ return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant cases (8 or 32 longs,
+ * for 256 and 1024-bit fd_sets respectively)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set *p)
+{
+ unsigned long *tmp = p->fds_bits;
+ int i;
+
+ if (__builtin_constant_p(__FDSET_LONGS)) {
+ switch (__FDSET_LONGS) {
+ case 32:
+ tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+ tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+ tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+ tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
+ tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0;
+ tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0;
+ tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0;
+ tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0;
+ return;
+ case 16:
+ tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+ tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+ tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+ tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
+ return;
+ case 8:
+ tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+ tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+ return;
+ case 4:
+ tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+ return;
+ }
+ }
+ i = __FDSET_LONGS;
+ while (i) {
+ i--;
+ *tmp = 0;
+ tmp++;
+ }
+}
+
+#endif /* !(__ARCH_SPARC_POSIX_TYPES_H) */
diff --git a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h
index 7e18bfb2f..dd5a0dfcf 100644
--- a/include/asm-sparc/processor.h
+++ b/include/asm-sparc/processor.h
@@ -1,4 +1,5 @@
-/* include/asm-sparc/processor.h
+/* $Id: processor.h,v 1.48 1996/10/27 08:55:36 davem Exp $
+ * include/asm-sparc/processor.h
*
* Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
*/
@@ -6,151 +7,159 @@
#ifndef __ASM_SPARC_PROCESSOR_H
#define __ASM_SPARC_PROCESSOR_H
+#include <linux/a.out.h>
+
+#include <asm/psr.h>
+#include <asm/ptrace.h>
+#include <asm/head.h>
+#include <asm/signal.h>
+#include <asm/segment.h>
+
/*
* Bus types
*/
-#define EISA_bus 1
+#define EISA_bus 0
#define EISA_bus__is_a_macro /* for versions in ksyms.c */
#define MCA_bus 0
#define MCA_bus__is_a_macro /* for versions in ksyms.c */
/*
- * Write Protection works right in supervisor mode on the Sparc
+ * The sparc has no problems with write protection
*/
-
#define wp_works_ok 1
#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
-/*
- * User space process size: 3GB. This is hardcoded into a few places,
- * so don't change it unless you know what you are doing.
- *
- * "this is gonna have to change to 1gig for the sparc" - David S. Miller
- */
-#define TASK_SIZE (0xC0000000UL)
+/* Whee, this is STACK_TOP and the lowest kernel address too... */
+#define TASK_SIZE (page_offset)
-/*
- * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
- */
-#define IO_BITMAP_SIZE 32
-
-/* The first five entries here MUST be the first four. This allows me to
- * do %lo(offset) loads and stores in entry.S. See TRAP_WIN_CLEAN to see
- * why.
- */
+/* Ok this is hot. Sparc exception save area. */
+struct exception_struct {
+ unsigned long count; /* Exception count */
+ unsigned long pc; /* Callers PC for copy/clear user */
+ unsigned long expc; /* Where to jump when exception signaled */
+ unsigned long address; /* Saved user base address for transfer */
+};
+/* The Sparc processor specific thread struct. */
struct thread_struct {
- unsigned long uwindows; /* how many user windows are in the set */
- unsigned long wim; /* user's window invalid mask */
- unsigned long w_saved; /* how many windows saved in reg_window[] */
- unsigned long ksp; /* kernel stack pointer */
- unsigned long usp; /* user's sp, throw reg windows here */
- unsigned long psr; /* save for condition codes */
- unsigned long reg_window[16*24];
- unsigned long cr3; /* why changed from ptbr? */
- unsigned int pcc;
- unsigned int asn;
- unsigned long unique;
+ unsigned long uwinmask __attribute__ ((aligned (8)));
+ struct pt_regs *kregs;
+
+ /* For signal handling */
+ unsigned long sig_address __attribute__ ((aligned (8)));
+ unsigned long sig_desc;
+
+ /* Context switch saved kernel state. */
+ unsigned long ksp __attribute__ ((aligned (8)));
+ unsigned long kpc;
+ unsigned long kpsr;
+ unsigned long kwim;
+
+ /* Special child fork kpsr/kwim values. */
+ unsigned long fork_kpsr __attribute__ ((aligned (8)));
+ unsigned long fork_kwim;
+
+ /* A place to store user windows and stack pointers
+ * when the stack needs inspection.
+ */
+#define NSWINS 8
+ struct reg_window reg_window[NSWINS] __attribute__ ((aligned (8)));
+ unsigned long rwbuf_stkptrs[NSWINS] __attribute__ ((aligned (8)));
+ unsigned long w_saved;
+
+ /* Floating point regs */
+ unsigned long float_regs[64] __attribute__ ((aligned (8)));
+ unsigned long fsr;
+ unsigned long fpqdepth;
+ struct fpq {
+ unsigned long *insn_addr;
+ unsigned long insn;
+ } fpqueue[16];
+ struct sigstack sstk_info;
unsigned long flags;
- unsigned long res1, res2;
- unsigned long pc; /* program counter */
- unsigned long npc; /* next program counter */
-
-/* 8 local registers + 8 in registers * 24 register windows.
- * Most sparcs I know of only have 8 windows implemented,
- * we determine how many at boot time and store that value
- * in nwindows.
- */
- unsigned long globl_regs[8]; /* global regs need to be saved too */
- unsigned long yreg;
- unsigned long float_regs[64]; /* V8 and below have 32, V9 has 64 */
+ struct exception_struct ex __attribute__ ((aligned (8)));
+ int current_ds;
+ struct exec core_exec; /* just what it says. */
};
-#define INIT_MMAP { &init_task, 0x0, 0x40000000, \
- PAGE_SHARED , VM_READ | VM_WRITE | VM_EXEC }
+#define SPARC_FLAG_KTHREAD 0x1 /* task is a kernel thread */
+#define SPARC_FLAG_UNALIGNED 0x2 /* is allowed to do unaligned accesses */
+
+#define INIT_MMAP { &init_mm, (0), (0), \
+ __pgprot(0x0) , VM_READ | VM_WRITE | VM_EXEC }
#define INIT_TSS { \
- 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, 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, 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, }, \
+/* uwinmask, kregs, sig_address, sig_desc, ksp, kpc, kpsr, kwim */ \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+/* fork_kpsr, fork_kwim */ \
+ 0, 0, \
+/* reg_window */ \
+{ { { 0, }, { 0, } }, }, \
+/* rwbuf_stkptrs */ \
+{ 0, 0, 0, 0, 0, 0, 0, 0, }, \
+/* w_saved */ \
+ 0, \
+/* FPU regs */ { 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, }, \
+/* FPU status, FPU qdepth, FPU queue */ \
+ 0, 0, { { 0, 0, }, }, \
+/* sstk_info */ \
+{ 0, 0, }, \
+/* flags, ex, current_ds, */ \
+ SPARC_FLAG_KTHREAD, { 0, }, USER_DS, \
+/* core_exec */ \
+{ 0, }, \
}
-/* The thread_frame is what needs to be set up in certain circumstances
- * upon entry to a trap. It is also loaded sometimes during a window
- * spill if things don't go right (bad user stack pointer). In reality
- * it is not per-process per se, it just sits in the kernel stack while
- * the current process is in a handler then it is basically forgotten
- * about.
- */
-
-struct thread_frame {
- unsigned int thr_psr;
- unsigned int thr_pc;
- unsigned int thr_npc;
- unsigned int thr_y;
- unsigned int thr_globals[8];
- unsigned int thr_outs[8];
-};
-
-/*
- * These are the "cli()" and "sti()" for software interrupts
- * They work by increasing/decreasing the "intr_count" value,
- * and as such can be nested arbitrarily.
- */
-extern inline void start_bh_atomic(void)
+/* Return saved PC of a blocked thread. */
+extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t)
{
- unsigned long dummy, psr;
- __asm__ __volatile__("rd %%psr, %2\n\t"
- "wr %2, 0x20, %%psr\n\t" /* disable traps */
- "ld %1,%0\n\t"
- "add %0,1,%0\n\t"
- "st %0,%1\n\t"
- "wr %2, 0x0, %%psr\n\t" /* enable traps */
- : "=r" (dummy), "=m" (intr_count)
- : "0" (0), "r" (psr=0));
+ return t->kpc;
}
-extern inline void end_bh_atomic(void)
+/* Do necessary setup to start up a newly executed thread. */
+extern __inline__ void start_thread(struct pt_regs * regs, unsigned long pc,
+ unsigned long sp)
{
- unsigned long dummy, psr;
- __asm__ __volatile__("rd %%psr, %2\n\t"
- "wr %2, 0x20, %%psr\n\t"
- "ld %1,%0\n\t"
- "sub %0,1,%0\n\t"
- "st %0,%1\n\t"
- "wr %2, 0x0, %%psr\n\t"
- : "=r" (dummy), "=m" (intr_count)
- : "0" (0), "r" (psr=0));
+ register unsigned long zero asm("g1");
+
+ regs->psr = (regs->psr & (PSR_CWP)) | PSR_S;
+ regs->pc = ((pc & (~3)) - 4);
+ regs->npc = regs->pc + 4;
+ regs->y = 0;
+ zero = 0;
+ __asm__ __volatile__("std\t%%g0, [%0 + %3 + 0x00]\n\t"
+ "std\t%%g0, [%0 + %3 + 0x08]\n\t"
+ "std\t%%g0, [%0 + %3 + 0x10]\n\t"
+ "std\t%%g0, [%0 + %3 + 0x18]\n\t"
+ "std\t%%g0, [%0 + %3 + 0x20]\n\t"
+ "std\t%%g0, [%0 + %3 + 0x28]\n\t"
+ "std\t%%g0, [%0 + %3 + 0x30]\n\t"
+ "st\t%1, [%0 + %3 + 0x38]\n\t"
+ "st\t%%g0, [%0 + %3 + 0x3c]"
+ : : "r" (regs), "r" (sp - REGWIN_SZ), "r" (zero),
+ "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0])));
}
-#endif /* __ASM_SPARC_PROCESSOR_H */
+#define release_thread(tsk) do { } while(0)
+
+#ifdef __KERNEL__
+extern unsigned long (*alloc_kernel_stack)(struct task_struct *tsk);
+extern void (*free_kernel_stack)(unsigned long stack);
+extern struct task_struct *(*alloc_task_struct)(void);
+extern void (*free_task_struct)(struct task_struct *tsk);
+#endif
+
+/*
+ * Return_address is a replacement for __builtin_return_address(count)
+ * which on certain architectures cannot reasonably be implemented in GCC
+ * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386).
+ * Note that __builtin_return_address(x>=1) is forbidden because the GCC
+ * aborts compilation on some CPUs. It's simply not possible to unwind
+ * some CPU's stackframes.
+ */
+#define return_address() __builtin_return_address(0)
+#endif /* __ASM_SPARC_PROCESSOR_H */
diff --git a/include/asm-sparc/psr.h b/include/asm-sparc/psr.h
index 60b9757ad..829ca47b6 100644
--- a/include/asm-sparc/psr.h
+++ b/include/asm-sparc/psr.h
@@ -1,36 +1,23 @@
-/* psr.h: This file holds the macros for masking off various parts of
- the processor status register on the Sparc. This is valid
- for Version 8. On the V9 this is renamed to the PSTATE
- register and its members are accessed as fields like
- PSTATE.PRIV for the current CPU privilege level.
-
- Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
-*/
+/* $Id: psr.h,v 1.12 1996/09/30 02:23:19 davem Exp $
+ * psr.h: This file holds the macros for masking off various parts of
+ * the processor status register on the Sparc. This is valid
+ * for Version 8. On the V9 this is renamed to the PSTATE
+ * register and its members are accessed as fields like
+ * PSTATE.PRIV for the current CPU privilege level.
+ *
+ * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ */
#ifndef __LINUX_SPARC_PSR_H
#define __LINUX_SPARC_PSR_H
-#define __LINUX_SPARC_V8 /* duh */
-
-#ifdef __LINUX_SPARC_V8
-
/* The Sparc PSR fields are laid out as the following:
-
- ------------------------------------------------------------------------
- | impl | vers | icc | resv | EC | EF | PIL | S | PS | ET | CWP |
-bits| 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6 | 5 | 4-0 |
- ------------------------------------------------------------------------
-
- The PSR can only be directly be written/read by the privileged instructions
- 'rd' and 'wr'. Certain fields are changed as a side effect due to the 'Ticc',
- 'save', 'restore', and 'rett' instructions. Also the integer condition codes
- 'icc' are modified by various arithmetic instructions.
-
- For example: wr %o2, or'd_bit_pattern, %psr
- rd %psr, %o3
-
-*/
-
+ *
+ * ------------------------------------------------------------------------
+ * | impl | vers | icc | resv | EC | EF | PIL | S | PS | ET | CWP |
+ * | 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6 | 5 | 4-0 |
+ * ------------------------------------------------------------------------
+ */
#define PSR_CWP 0x0000001f /* current window pointer */
#define PSR_ET 0x00000020 /* enable traps field */
#define PSR_PS 0x00000040 /* previous privilege level */
@@ -38,6 +25,7 @@ bits| 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6 | 5 | 4-0 |
#define PSR_PIL 0x00000f00 /* processor interrupt level */
#define PSR_EF 0x00001000 /* enable floating point */
#define PSR_EC 0x00002000 /* enable co-processor */
+#define PSR_LE 0x00008000 /* SuperSparcII little-endian */
#define PSR_ICC 0x00f00000 /* integer condition codes */
#define PSR_C 0x00100000 /* carry bit */
#define PSR_V 0x00200000 /* overflow bit */
@@ -46,54 +34,45 @@ bits| 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6 | 5 | 4-0 |
#define PSR_VERS 0x0f000000 /* cpu-version field */
#define PSR_IMPL 0xf0000000 /* cpu-implementation field */
-#endif /* !(__LINUX_SPARC_V8) */
-
-#ifdef __LINUX_SPARC_V9
-
-/* The information available in the %psr on the V8 is spread amongst
- a whole bunch of registers on the V9. The main one being PSTATE.
-
- --------------------------------------------------------
- | CLE | TLE | MM | RED | PEF | AM | PRIV | IE | AG |
-bits | 9 | 8 | 7-6 | 5 | 4 | 3 | 2 | 1 | 0 |
- --------------------------------------------------------
-
- Writes and reads to PSTATE are done via 'wrpr' and 'rdpr' instructions.
-
- For example: wrpr %o2, or'd_bit_pattern, %pstate
- rdpr %pstate, %o3
-*/
-
-#define PSTATE_AG 0x001 /* Alternate Globals */
-#define PSTATE_IE 0x002 /* Interrupt Enable */
-#define PSTATE_PRIV 0x004 /* Current privilege level */
-#define PSTATE_AM 0x008 /* Address mask (data reads can */
- /* be chosen to be either big or */
- /* little endian on V9). */
-#define PSTATE_PEF 0x010 /* enable floating point */
-#define PSTATE_RED 0x020 /* RED trap state (set if trap */
- /* trap_level == max_tl). */
-#define PSTATE_MM 0x0c0 /* Memory model (Total Store */
- /* Order=0, Partial Store Order */
- /* =1 or Relaxed Memory Order=2) */
-#define PSTATE_TLE 0x100 /* Trap Little Endian */
-#define PSTATE_CLE 0x200 /* Current Little Endian */
-
-
-/* The Version Register holds vendor information for the chip:
-
- ---------------------------------------------------------------------------
- | manufacturer | implementation | mask | reserved | maxtl | resv | maxwin |
-bits| 63-48 | 47-32 | 31-24| 23-16 | 15-8 | 7-5 | 4-0 |
- ---------------------------------------------------------------------------
-
-*/
-
-#define VERS_MAXWIN 0x000000000000001f /* 'nwindows' on this chip */
-#define VERS_MAXTL 0x00000000000ff000 /* Maximum Trap-level supported */
-#define VERS_MASK 0x0000000ff0000000 /* impl. dep. chip mask revision */
-#define VERS_MANUF 0xffff000000000000 /* Manufacturer ID code */
-
-#endif /* !(__LINUX_SPARC_V9) */
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+/* Get the %psr register. */
+extern __inline__ unsigned int get_psr(void)
+{
+ unsigned int psr;
+ __asm__ __volatile__("rd\t%%psr, %0" :
+ "=r" (psr));
+ return psr;
+}
+
+extern __inline__ void put_psr(unsigned int new_psr)
+{
+ __asm__ __volatile__("wr\t%0, 0x0, %%psr\n\t"
+ "nop; nop; nop;" : :
+ "r" (new_psr));
+}
+
+/* Get the %fsr register. Be careful, make sure the floating point
+ * enable bit is set in the %psr when you execute this or you will
+ * incur a trap.
+ */
+
+extern unsigned int fsr_storage;
+
+extern __inline__ unsigned int get_fsr(void)
+{
+ unsigned int fsr = 0;
+
+ __asm__ __volatile__("st\t%%fsr, %1\n\t"
+ "ld\t%1, %0" :
+ "=r" (fsr) :
+ "m" (fsr_storage));
+ return fsr;
+}
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* (__KERNEL__) */
#endif /* !(__LINUX_SPARC_PSR_H) */
diff --git a/include/asm-sparc/ptrace.h b/include/asm-sparc/ptrace.h
index 70fb8d5df..d357ab034 100644
--- a/include/asm-sparc/ptrace.h
+++ b/include/asm-sparc/ptrace.h
@@ -1,32 +1,195 @@
+/* $Id: ptrace.h,v 1.22 1996/10/27 08:55:38 davem Exp $ */
#ifndef _SPARC_PTRACE_H
#define _SPARC_PTRACE_H
-/* I have not looked enough into how this should be done. Without playing
- * lots of tricks to optimize I think we need to save the whole register
- * window frame plus the floating-point registers. We'll see...
+#include <asm/psr.h>
+
+/* This struct defines the way the registers are stored on the
+ * stack during a system call and basically all traps.
*/
-/* this struct defines the way the registers are stored on the
- stack during a system call. */
+#ifndef __ASSEMBLY__
struct pt_regs {
- unsigned long ps; /* previous supervisor, same as alpha I believe */
- unsigned long pc; /* current and next program counter */
+ unsigned long psr;
+ unsigned long pc;
unsigned long npc;
- unsigned long sp; /* stack and frame pointer */
- unsigned long fp;
- unsigned long psr; /* for condition codes */
- unsigned long nuwin; /* number of user windows */
- /* not sure yet whether all regs are necessary
- * but this is how it is traditionally done on the sparc.
- */
- unsigned long u_regs[24*16];
- unsigned long f_regs[64]; /* yuck yuck yuck */
+ unsigned long y;
+ unsigned long u_regs[16]; /* globals and ins */
+};
+
+#define UREG_G0 0
+#define UREG_G1 1
+#define UREG_G2 2
+#define UREG_G3 3
+#define UREG_G4 4
+#define UREG_G5 5
+#define UREG_G6 6
+#define UREG_G7 7
+#define UREG_I0 8
+#define UREG_I1 9
+#define UREG_I2 10
+#define UREG_I3 11
+#define UREG_I4 12
+#define UREG_I5 13
+#define UREG_I6 14
+#define UREG_I7 15
+#define UREG_WIM UREG_G0
+#define UREG_FADDR UREG_G0
+#define UREG_FP UREG_I6
+#define UREG_RETPC UREG_I7
+
+/* A register window */
+struct reg_window {
+ unsigned long locals[8];
+ unsigned long ins[8];
};
+/* A Sparc stack frame */
+struct sparc_stackf {
+ unsigned long locals[8];
+ unsigned long ins[6];
+ struct sparc_stackf *fp;
+ unsigned long callers_pc;
+ char *structptr;
+ unsigned long xargs[6];
+ unsigned long xxargs[1];
+};
+
+#define TRACEREG_SZ sizeof(struct pt_regs)
+#define STACKFRAME_SZ sizeof(struct sparc_stackf)
+#define REGWIN_SZ sizeof(struct reg_window)
+
#ifdef __KERNEL__
-#define user_mode(regs) (0x0) /* if previous supervisor is 0, came from user */
+#define user_mode(regs) (!((regs)->psr & PSR_PS))
+#define instruction_pointer(regs) ((regs)->pc)
extern void show_regs(struct pt_regs *);
#endif
+#else /* __ASSEMBLY__ */
+/* For assembly code. */
+#define TRACEREG_SZ 0x50
+#define STACKFRAME_SZ 0x60
+#define REGWIN_SZ 0x40
#endif
+
+/* First generic task_struct offsets. sizeof(task_struct)=1616 */
+#define TASK_STATE 0x000
+#define TASK_PRIORITY 0x008
+#define TASK_SIGNAL 0x00c
+#define TASK_BLOCKED 0x010
+#define TASK_FLAGS 0x014
+#define TASK_SAVED_KSTACK 0x054
+#define TASK_KSTACK_PG 0x058
+
+/* Thread stuff. */
+#define THREAD_UMASK 0x210
+#define THREAD_SADDR 0x218
+#define THREAD_SDESC 0x21c
+#define THREAD_KSP 0x220
+#define THREAD_KPC 0x224
+#define THREAD_KPSR 0x228
+#define THREAD_KWIM 0x22c
+#define THREAD_FORK_KPSR 0x230
+#define THREAD_FORK_KWIM 0x234
+#define THREAD_REG_WINDOW 0x238
+#define THREAD_STACK_PTRS 0x438
+#define THREAD_W_SAVED 0x458
+#define THREAD_FLOAT_REGS 0x460
+#define THREAD_FSR 0x560
+#define THREAD_SIGSTK 0x5e8
+#define THREAD_FLAGS 0x5f0
+#define THREAD_EX_COUNT 0x5f8
+#define THREAD_EX_PC 0x5fc
+#define THREAD_EX_EXPC 0x600
+#define THREAD_EX_ADDR 0x604
+#define THREAD_DS 0x608
+#define THREAD_MM 0x638
+#define THREAD_MM_CTX 0x008
+
+/* These are for pt_regs. */
+#define PT_PSR 0x0
+#define PT_PC 0x4
+#define PT_NPC 0x8
+#define PT_Y 0xc
+#define PT_G0 0x10
+#define PT_WIM PT_G0
+#define PT_G1 0x14
+#define PT_G2 0x18
+#define PT_G3 0x1c
+#define PT_G4 0x20
+#define PT_G5 0x24
+#define PT_G6 0x28
+#define PT_G7 0x2c
+#define PT_I0 0x30
+#define PT_I1 0x34
+#define PT_I2 0x38
+#define PT_I3 0x3c
+#define PT_I4 0x40
+#define PT_I5 0x44
+#define PT_I6 0x48
+#define PT_FP PT_I6
+#define PT_I7 0x4c
+
+/* Reg_window offsets */
+#define RW_L0 0x00
+#define RW_L1 0x04
+#define RW_L2 0x08
+#define RW_L3 0x0c
+#define RW_L4 0x10
+#define RW_L5 0x14
+#define RW_L6 0x18
+#define RW_L7 0x1c
+#define RW_I0 0x20
+#define RW_I1 0x24
+#define RW_I2 0x28
+#define RW_I3 0x2c
+#define RW_I4 0x30
+#define RW_I5 0x34
+#define RW_I6 0x38
+#define RW_I7 0x3c
+
+/* Stack_frame offsets */
+#define SF_L0 0x00
+#define SF_L1 0x04
+#define SF_L2 0x08
+#define SF_L3 0x0c
+#define SF_L4 0x10
+#define SF_L5 0x14
+#define SF_L6 0x18
+#define SF_L7 0x1c
+#define SF_I0 0x20
+#define SF_I1 0x24
+#define SF_I2 0x28
+#define SF_I3 0x2c
+#define SF_I4 0x30
+#define SF_I5 0x34
+#define SF_FP 0x38
+#define SF_PC 0x3c
+#define SF_RETP 0x40
+#define SF_XARG0 0x44
+#define SF_XARG1 0x48
+#define SF_XARG2 0x4c
+#define SF_XARG3 0x50
+#define SF_XARG4 0x54
+#define SF_XARG5 0x58
+#define SF_XXARG 0x5c
+
+/* Stuff for the ptrace system call */
+#define PTRACE_SUNATTACH 10
+#define PTRACE_SUNDETACH 11
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+#define PTRACE_READDATA 16
+#define PTRACE_WRITEDATA 17
+#define PTRACE_READTEXT 18
+#define PTRACE_WRITETEXT 19
+#define PTRACE_GETFPAREGS 20
+#define PTRACE_SETFPAREGS 21
+
+#define PTRACE_GETUCODE 29 /* stupid bsd-ism */
+
+
+#endif /* !(_SPARC_PTRACE_H) */
diff --git a/include/asm-sparc/reg.h b/include/asm-sparc/reg.h
new file mode 100644
index 000000000..ed60ebec5
--- /dev/null
+++ b/include/asm-sparc/reg.h
@@ -0,0 +1,79 @@
+/*
+ * linux/asm-sparc/reg.h
+ * Layout of the registers as expected by gdb on the Sparc
+ * we should replace the user.h definitions with those in
+ * this file, we don't even use the other
+ * -miguel
+ *
+ * The names of the structures, constants and aliases in this file
+ * have the same names as the sunos ones, some programs rely on these
+ * names (gdb for example).
+ *
+ */
+
+#ifndef __SPARC_REG_H
+#define __SPARC_REG_H
+
+struct regs {
+ int r_psr;
+#define r_ps r_psr
+ int r_pc;
+ int r_npc;
+ int r_y;
+ int r_g1;
+ int r_g2;
+ int r_g3;
+ int r_g4;
+ int r_g5;
+ int r_g6;
+ int r_g7;
+ int r_o0;
+ int r_o1;
+ int r_o2;
+ int r_o3;
+ int r_o4;
+ int r_o5;
+ int r_o6;
+ int r_o7;
+};
+
+struct fpq {
+ unsigned long *addr;
+ unsigned long instr;
+};
+
+struct fq {
+ union {
+ double whole;
+ struct fpq fpq;
+ } FQu;
+};
+
+#define FPU_REGS_TYPE unsigned int
+#define FPU_FSR_TYPE unsigned
+
+struct fp_status {
+ union {
+ FPU_REGS_TYPE Fpu_regs[32];
+ double Fpu_dregs[16];
+ } fpu_fr;
+ FPU_FSR_TYPE Fpu_fsr;
+ unsigned Fpu_flags;
+ unsigned Fpu_extra;
+ unsigned Fpu_qcnt;
+ struct fq Fpu_q[16];
+};
+
+#define fpu_regs f_fpstatus.fpu_fr.Fpu_regs
+#define fpu_dregs f_fpstatus.fpu_fr.Fpu_dregs
+#define fpu_fsr f_fpstatus.Fpu_fsr
+#define fpu_flags f_fpstatus.Fpu_flags
+#define fpu_extra f_fpstatus.Fpu_extra
+#define fpu_q f_fpstatus.Fpu_q
+#define fpu_qcnt f_fpstatus.Fpu_qcnt
+
+struct fpu {
+ struct fp_status f_fpstatus;
+};
+
+#endif /* __SPARC_REG_H */
diff --git a/include/asm-sparc/resource.h b/include/asm-sparc/resource.h
new file mode 100644
index 000000000..61a137b48
--- /dev/null
+++ b/include/asm-sparc/resource.h
@@ -0,0 +1,38 @@
+/* $Id: resource.h,v 1.5 1995/11/25 02:32:35 davem Exp $
+ * resource.h: Resource definitions.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_RESOURCE_H
+#define _SPARC_RESOURCE_H
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU 0 /* CPU time in ms */
+#define RLIMIT_FSIZE 1 /* Maximum filesize */
+#define RLIMIT_DATA 2 /* max data size */
+#define RLIMIT_STACK 3 /* max stack size */
+#define RLIMIT_CORE 4 /* max core file size */
+#define RLIMIT_RSS 5 /* max resident set size */
+#define RLIMIT_NOFILE 6 /* max number of open files */
+#define RLIMIT_NPROC 7 /* max number of processes */
+#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
+#define RLIM_NLIMITS 9
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS \
+{ \
+ {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \
+ {LONG_MAX, LONG_MAX}, {_STK_LIM, _STK_LIM}, \
+ { 0, LONG_MAX}, {LONG_MAX, LONG_MAX}, \
+ {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER}, {NR_OPEN, NR_OPEN}, \
+ {LONG_MAX, LONG_MAX}, \
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* !(_SPARC_RESOURCE_H) */
diff --git a/include/asm-sparc/ross.h b/include/asm-sparc/ross.h
new file mode 100644
index 000000000..e6b0ddc26
--- /dev/null
+++ b/include/asm-sparc/ross.h
@@ -0,0 +1,174 @@
+/* $Id: ross.h,v 1.11 1996/08/29 09:48:40 davem Exp $
+ * ross.h: Ross module specific definitions and defines.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_ROSS_H
+#define _SPARC_ROSS_H
+
+#include <asm/asi.h>
+
+/* Ross made Hypersparcs have a %psr 'impl' field of '0001'. The 'vers'
+ * field has '1111'.
+ */
+
+/* The MMU control register fields on the HyperSparc.
+ *
+ * -----------------------------------------------------------------
+ * |implvers| RSV |CWR|SE|WBE| MID |BM| C|CS|MR|CM|RSV|CE|RSV|NF|ME|
+ * -----------------------------------------------------------------
+ * 31 24 23-22 21 20 19 18-15 14 13 12 11 10 9 8 7-2 1 0
+ *
+ * Phew, lots of fields there ;-)
+ *
+ * CWR: Cache Wrapping Enabled, if one cache wrapping is on.
+ * SE: Snoop Enable, turns on bus snooping for cache activity if one.
+ * WBE: Write Buffer Enable, one turns it on.
+ * MID: The ModuleID of the chip for MBus transactions.
+ * BM: Boot-Mode. One indicates the MMU is in boot mode.
+ * C: Indicates whether accesses are cachable while the MMU is
+ * disabled.
+ * CS: Cache Size -- 0 = 128k, 1 = 256k
+ * MR: Memory Reflection, one indicates that the memory bus connected
+ * to the MBus supports memory reflection.
+ * CM: Cache Mode -- 0 = write-through, 1 = copy-back
+ * CE: Cache Enable -- 0 = no caching, 1 = cache is on
+ * NF: No Fault -- 0 = faults trap the CPU from supervisor mode
+ * 1 = faults from supervisor mode do not generate traps
+ * ME: MMU Enable -- 0 = MMU is off, 1 = MMU is on
+ */
+
+#define HYPERSPARC_CWENABLE 0x00200000
+#define HYPERSPARC_SBENABLE 0x00100000
+#define HYPERSPARC_WBENABLE 0x00080000
+#define HYPERSPARC_MIDMASK 0x00078000
+#define HYPERSPARC_BMODE 0x00004000
+#define HYPERSPARC_ACENABLE 0x00002000
+#define HYPERSPARC_CSIZE 0x00001000
+#define HYPERSPARC_MRFLCT 0x00000800
+#define HYPERSPARC_CMODE 0x00000400
+#define HYPERSPARC_CENABLE 0x00000100
+#define HYPERSPARC_NFAULT 0x00000002
+#define HYPERSPARC_MENABLE 0x00000001
+
+
+/* The ICCR instruction cache register on the HyperSparc.
+ *
+ * -----------------------------------------------
+ * | | FTD | ICE |
+ * -----------------------------------------------
+ * 31 1 0
+ *
+ * This register is accessed using the V8 'wrasr' and 'rdasr'
+ * opcodes, since not all assemblers understand them and those
+ * that do use different semantics I will just hard code the
+ * instruction with a '.word' statement.
+ *
+ * FTD: If set to one flush instructions executed during an
+ * instruction cache hit occurs, the corresponding line
+ * for said cache-hit is invalidated. If FTD is zero,
+ * an unimplemented 'flush' trap will occur when any
+ * flush is executed by the processor.
+ *
+ * ICE: If set to one, the instruction cache is enabled. If
+ * zero, the cache will not be used for instruction fetches.
+ *
+ * All other bits are read as zeros, and writes to them have no
+ * effect.
+ *
+ * Wheee, not many assemblers understand the %iccr register nor
+ * the generic asr r/w instructions.
+ *
+ * 1000 0011 0100 0111 1100 0000 0000 0000 ! rd %iccr, %g1
+ *
+ * 0x 8 3 4 7 c 0 0 0 ! 0x8347c000
+ *
+ * 1011 1111 1000 0000 0110 0000 0000 0000 ! wr %g1, 0x0, %iccr
+ *
+ * 0x b f 8 0 6 0 0 0 ! 0xbf806000
+ *
+ */
+
+#define HYPERSPARC_ICCR_FTD 0x00000002
+#define HYPERSPARC_ICCR_ICE 0x00000001
+
+extern __inline__ unsigned int get_ross_icr(void)
+{
+ unsigned int icreg;
+
+ __asm__ __volatile__(".word 0x8347c000\n\t" /* rd %iccr, %g1 */
+ "mov %%g1, %0\n\t" :
+ "=r" (icreg) : :
+ "g1", "memory");
+
+ return icreg;
+}
+
+extern __inline__ void put_ross_icr(unsigned int icreg)
+{
+ __asm__ __volatile__("or %%g0, %0, %%g1\n\t"
+ ".word 0xbf806000\n\t" /* wr %g1, 0x0, %iccr */
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t" : :
+ "r" (icreg) :
+ "g1", "memory");
+
+ return;
+}
+
+/* HyperSparc specific cache flushing. */
+
+/* This is for the on-chip instruction cache. */
+extern __inline__ void hyper_flush_whole_icache(void)
+{
+ __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
+ "i" (ASI_M_FLUSH_IWHOLE));
+ return;
+}
+
+extern int vac_cache_size;
+extern int vac_line_size;
+
+extern __inline__ void hyper_clear_all_tags(void)
+{
+ unsigned long addr;
+
+ for(addr = 0; addr < vac_cache_size; addr += vac_line_size)
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_DATAC_TAG));
+}
+
+extern __inline__ void hyper_flush_unconditional_combined(void)
+{
+ unsigned long addr;
+
+ for(addr = 0; addr < vac_cache_size; addr += vac_line_size)
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_FLUSH_CTX));
+}
+
+extern __inline__ void hyper_flush_cache_user(void)
+{
+ unsigned long addr;
+
+ for(addr = 0; addr < vac_cache_size; addr += vac_line_size)
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_FLUSH_USER));
+}
+
+extern __inline__ void hyper_flush_cache_page(unsigned long page)
+{
+ unsigned long end;
+
+ page &= PAGE_MASK;
+ end = page + PAGE_SIZE;
+ while(page < end) {
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (page), "i" (ASI_M_FLUSH_PAGE));
+ page += vac_line_size;
+ }
+}
+
+#endif /* !(_SPARC_ROSS_H) */
diff --git a/include/asm-sparc/rtc.h b/include/asm-sparc/rtc.h
new file mode 100644
index 000000000..f4f261dde
--- /dev/null
+++ b/include/asm-sparc/rtc.h
@@ -0,0 +1,27 @@
+/* $Id: rtc.h,v 1.2 1996/08/21 23:17:39 ecd Exp $
+ *
+ * rtc.h: Definitions for access to the Mostek real time clock
+ *
+ * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
+ */
+
+#ifndef _RTC_H
+#define _RTC_H
+
+#include <linux/ioctl.h>
+
+struct rtc_time
+{
+ int sec; /* Seconds (0-59) */
+ int min; /* Minutes (0-59) */
+ int hour; /* Hour (0-23) */
+ int dow; /* Day of the week (1-7) */
+ int dom; /* Day of the month (1-31) */
+ int month; /* Month of year (1-12) */
+ int year; /* Year (0-99) */
+};
+
+#define RTCGET _IOR('p', 20, struct rtc_time)
+#define RTCSET _IOW('p', 21, struct rtc_time)
+
+#endif
diff --git a/include/asm-sparc/sbus.h b/include/asm-sparc/sbus.h
new file mode 100644
index 000000000..cc9e75ae6
--- /dev/null
+++ b/include/asm-sparc/sbus.h
@@ -0,0 +1,101 @@
+/* $Id: sbus.h,v 1.11 1996/10/31 06:29:12 davem Exp $
+ * sbus.h: Defines for the Sun SBus.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_SBUS_H
+#define _SPARC_SBUS_H
+
+#include <asm/oplib.h>
+#include <asm/iommu.h>
+
+/* We scan which devices are on the SBus using the PROM node device
+ * tree. SBus devices are described in two different ways. You can
+ * either get an absolute address at which to access the device, or
+ * you can get a SBus 'slot' number and an offset within that slot.
+ */
+
+/* The base address at which to calculate device OBIO addresses. */
+#define SUN_SBUS_BVADDR 0xf8000000
+#define SBUS_OFF_MASK 0x01ffffff
+
+/* These routines are used to calculate device address from slot
+ * numbers + offsets, and vice versa.
+ */
+
+extern __inline__ unsigned long sbus_devaddr(int slotnum, unsigned long offset)
+{
+ return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<25)+(offset));
+}
+
+extern __inline__ int sbus_dev_slot(unsigned long dev_addr)
+{
+ return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>25);
+}
+
+extern __inline__ unsigned long sbus_dev_offset(unsigned long dev_addr)
+{
+ return (unsigned long) (((dev_addr)-SUN_SBUS_BVADDR)&SBUS_OFF_MASK);
+}
+
+struct linux_sbus;
+
+/* Linux SBUS device tables */
+struct linux_sbus_device {
+ struct linux_sbus_device *next; /* next device on this SBus or null */
+ struct linux_sbus_device *child; /* For ledma and espdma on sun4m */
+ struct linux_sbus *my_bus; /* Back ptr to sbus */
+ int prom_node; /* PROM device tree node for this device */
+ char prom_name[64]; /* PROM device name */
+ char linux_name[64]; /* Name used internally by Linux */
+
+ struct linux_prom_registers reg_addrs[PROMREG_MAX];
+ int num_registers;
+
+ struct linux_prom_irqs irqs[PROMINTR_MAX];
+ int num_irqs;
+
+ unsigned long sbus_addr; /* Absolute base address for device. */
+ unsigned long sbus_vaddrs[PROMVADDR_MAX];
+ unsigned long num_vaddrs;
+ unsigned long offset; /* Offset given by PROM */
+ int slot;
+};
+
+/* This struct describes the SBus(s) found on this machine. */
+struct linux_sbus {
+ struct linux_sbus *next; /* next SBus, if more than one SBus */
+ struct linux_sbus_device *devices; /* Link to devices on this SBus */
+ struct iommu_struct *iommu; /* IOMMU for this sbus if applicable */
+ int prom_node; /* PROM device tree node for this SBus */
+ char prom_name[64]; /* Usually "sbus" or "sbi" */
+ int clock_freq;
+ struct linux_prom_ranges sbus_ranges[PROMREG_MAX];
+ int num_sbus_ranges;
+};
+
+extern struct linux_sbus *SBus_chain;
+
+extern __inline__ int
+sbus_is_slave(struct linux_sbus_device *dev)
+{
+ /* Have to write this for sun4c's */
+ return 0;
+}
+
+/* Device probing routines could find these handy */
+#define for_each_sbus(bus) \
+ for((bus) = SBus_chain; (bus); (bus)=(bus)->next)
+
+#define for_each_sbusdev(device, bus) \
+ for((device) = (bus)->devices; (device); (device)=(device)->next)
+
+#define for_all_sbusdev(device, bus) \
+ for((bus) = SBus_chain, (device) = (bus)->devices; (bus); (device)=((device)->next ? (device)->next : ((bus) = (bus)->next, (bus) ? (bus)->devices : 0)))
+
+/* Apply promlib probed SBUS ranges to registers. */
+extern void prom_apply_sbus_ranges(struct linux_sbus *sbus,
+ struct linux_prom_registers *sbusregs, int nregs);
+
+#endif /* !(_SPARC_SBUS_H) */
diff --git a/include/asm-sparc/segment.h b/include/asm-sparc/segment.h
index 27489b3e5..a1b7ffc9e 100644
--- a/include/asm-sparc/segment.h
+++ b/include/asm-sparc/segment.h
@@ -1,87 +1,6 @@
-#ifndef _ASM_SEGMENT_H
-#define _ASM_SEGMENT_H
+#ifndef __SPARC_SEGMENT_H
+#define __SPARC_SEGMENT_H
-#define KERNEL_CS 0x0
-#define KERNEL_DS 0x0
+/* Only here because we have some old header files that expect it.. */
-#define USER_CS 0x1
-#define USER_DS 0x1
-
-#include <linux/string.h>
-#include <asm/vac-ops.h>
-
-static inline unsigned char get_user_byte(const char * addr)
-{
- return *addr;
-}
-
-#define get_fs_byte(addr) get_user_byte((char *)(addr))
-
-static inline unsigned short get_user_word(const short *addr)
-{
- return *addr;
-}
-
-#define get_fs_word(addr) get_user_word((short *)(addr))
-
-static inline unsigned long get_user_long(const int *addr)
-{
- return *addr;
-}
-
-#define get_fs_long(addr) get_user_long((int *)(addr))
-
-static inline unsigned long get_user_quad(const long *addr)
-{
- return *addr;
-}
-
-#define get_fs_quad(addr) get_user_quad((long *)(addr))
-
-static inline void put_user_byte(char val,char *addr)
-{
- *addr = val;
-}
-
-#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))
-
-static inline void put_user_word(short val,short * addr)
-{
- *addr = val;
-}
-
-#define put_fs_word(x,addr) put_user_word((x),(short *)(addr))
-
-static inline void put_user_long(unsigned long val,int * addr)
-{
- *addr = val;
-}
-
-#define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
-
-static inline void put_user_quad(unsigned long val,long * addr)
-{
- *addr = val;
-}
-
-#define put_fs_quad(x,addr) put_user_quad((x),(long *)(addr))
-
-#define memcpy_fromfs(to, from, n) memcpy((to),(from),(n))
-
-#define memcpy_tofs(to, from, n) memcpy((to),(from),(n))
-
-static inline unsigned long get_fs(void)
-{
- return 0;
-}
-
-static inline unsigned long get_ds(void)
-{
- return 0;
-}
-
-static inline void set_fs(unsigned long val)
-{
-}
-
-#endif /* _ASM_SEGMENT_H */
+#endif
diff --git a/include/asm-sparc/semaphore.h b/include/asm-sparc/semaphore.h
new file mode 100644
index 000000000..4892ccb26
--- /dev/null
+++ b/include/asm-sparc/semaphore.h
@@ -0,0 +1,42 @@
+#ifndef _SPARC_SEMAPHORE_H
+#define _SPARC_SEMAPHORE_H
+
+/* Dinky, good for nothing, just barely irq safe, Sparc semaphores.
+ *
+ * I'll write better ones later.
+ */
+
+#include <asm/atomic.h>
+
+struct semaphore {
+ atomic_t count;
+ atomic_t waiting;
+ struct wait_queue * wait;
+};
+
+#define MUTEX ((struct semaphore) { 1, 0, NULL })
+#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL })
+
+extern void __down(struct semaphore * sem);
+extern void __up(struct semaphore * sem);
+
+/*
+ * This isn't quite as clever as the x86 side, but the gp register
+ * makes things a bit more complicated on the alpha..
+ */
+extern inline void down(struct semaphore * sem)
+{
+ for (;;) {
+ if (atomic_dec_return(&sem->count) >= 0)
+ break;
+ __down(sem);
+ }
+}
+
+extern inline void up(struct semaphore * sem)
+{
+ if (atomic_inc_return(&sem->count) <= 0)
+ __up(sem);
+}
+
+#endif /* !(_SPARC_SEMAPHORE_H) */
diff --git a/include/asm-sparc/shmparam.h b/include/asm-sparc/shmparam.h
new file mode 100644
index 000000000..54420d89d
--- /dev/null
+++ b/include/asm-sparc/shmparam.h
@@ -0,0 +1,45 @@
+/* $Id: shmparam.h,v 1.3 1995/11/25 02:32:42 davem Exp $ */
+#ifndef _ASMSPARC_SHMPARAM_H
+#define _ASMSPARC_SHMPARAM_H
+
+/* address range for shared memory attaches if no address passed to shmat() */
+#define SHM_RANGE_START 0x10000000
+#define SHM_RANGE_END 0x20000000
+
+/*
+ * Format of a swap-entry for shared memory pages currently out in
+ * swap space (see also mm/swap.c).
+ *
+ * SWP_TYPE = SHM_SWP_TYPE
+ * SWP_OFFSET is used as follows:
+ *
+ * bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
+ * bits 7..21: index of page within shared memory segment (SHM_IDX)
+ * (actually fewer bits get used since SHMMAX is so low)
+ */
+
+/*
+ * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
+ * there is a static array of size SHMMNI.
+ */
+#define _SHM_ID_BITS 7
+#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1)
+
+#define SHM_IDX_SHIFT (_SHM_ID_BITS)
+#define _SHM_IDX_BITS 15
+#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)
+
+/*
+ * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
+ * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
+ */
+
+#define SHMMAX (1024 * 1024) /* max shared seg size (bytes) */
+#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */
+#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */
+#define SHMALL /* max shm system wide (pages) */ \
+ (1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
+#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
+#define SHMSEG SHMMNI /* max shared segs per process */
+
+#endif /* _ASMSPARC_SHMPARAM_H */
diff --git a/include/asm-sparc/sigcontext.h b/include/asm-sparc/sigcontext.h
new file mode 100644
index 000000000..c7a9993fe
--- /dev/null
+++ b/include/asm-sparc/sigcontext.h
@@ -0,0 +1,42 @@
+/* $Id: sigcontext.h,v 1.9 1996/10/27 08:55:42 davem Exp $ */
+#ifndef _ASMsparc_SIGCONTEXT_H
+#define _ASMsparc_SIGCONTEXT_H
+
+#include <asm/ptrace.h>
+
+#define SUNOS_MAXWIN 31
+
+#ifndef __ASSEMBLY__
+
+/* SunOS system call sigstack() uses this arg. */
+struct sunos_sigstack {
+ unsigned long sig_sp;
+ int onstack_flag;
+};
+
+/* This is what SunOS does, so shall I. */
+struct sigcontext {
+ int sigc_onstack; /* state to restore */
+ int sigc_mask; /* sigmask to restore */
+ int sigc_sp; /* stack pointer */
+ int sigc_pc; /* program counter */
+ int sigc_npc; /* next program counter */
+ int sigc_psr; /* for condition codes etc */
+ int sigc_g1; /* User uses these two registers */
+ int sigc_o0; /* within the trampoline code. */
+
+ /* Now comes information regarding the users window set
+ * at the time of the signal.
+ */
+ int sigc_oswins; /* outstanding windows */
+
+ /* stack ptrs for each regwin buf */
+ char *sigc_spbuf[SUNOS_MAXWIN];
+
+ /* Windows to restore after signal */
+ struct reg_window sigc_wbuf[SUNOS_MAXWIN];
+};
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_ASMsparc_SIGCONTEXT_H) */
+
diff --git a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h
index 2e599e18d..2cc321d13 100644
--- a/include/asm-sparc/signal.h
+++ b/include/asm-sparc/signal.h
@@ -1,11 +1,177 @@
+/* $Id: signal.h,v 1.29 1996/10/27 08:55:45 davem Exp $ */
#ifndef _ASMSPARC_SIGNAL_H
#define _ASMSPARC_SIGNAL_H
-struct sigcontext_struct {
- /*
- * Have to find out what SUNOS and Solaris do. This could
- * get real ugly. David S. Miller (davem@caip.rutgers.edu)
- */
+#include <asm/sigcontext.h>
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+#include <linux/personality.h>
+#endif
+#endif
+
+/* On the Sparc the signal handlers get passed a 'sub-signal' code
+ * for certain signal types, which we document here.
+ */
+#define _NSIG 32
+#define NSIG _NSIG
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SUBSIG_STACK 0
+#define SUBSIG_ILLINST 2
+#define SUBSIG_PRIVINST 3
+#define SUBSIG_BADTRAP(t) (0x80 + (t))
+
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+
+#define SIGEMT 7
+#define SUBSIG_TAG 10
+
+#define SIGFPE 8
+#define SUBSIG_FPDISABLED 0x400
+#define SUBSIG_FPERROR 0x404
+#define SUBSIG_FPINTOVFL 0x001
+#define SUBSIG_FPSTSIG 0x002
+#define SUBSIG_IDIVZERO 0x014
+#define SUBSIG_FPINEXACT 0x0c4
+#define SUBSIG_FPDIVZERO 0x0c8
+#define SUBSIG_FPUNFLOW 0x0cc
+#define SUBSIG_FPOPERROR 0x0d0
+#define SUBSIG_FPOVFLOW 0x0d4
+
+#define SIGKILL 9
+#define SIGBUS 10
+#define SUBSIG_BUSTIMEOUT 1
+#define SUBSIG_ALIGNMENT 2
+#define SUBSIG_MISCERROR 5
+
+#define SIGSEGV 11
+#define SUBSIG_NOMAPPING 3
+#define SUBSIG_PROTECTION 4
+#define SUBSIG_SEGERROR 5
+
+#define SIGSYS 12
+
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGURG 16
+
+/* SunOS values which deviate from the Linux/i386 ones */
+#define SIGSTOP 17
+#define SIGTSTP 18
+#define SIGCONT 19
+#define SIGCHLD 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGIO 23
+#define SIGPOLL SIGIO /* SysV name for SIGIO */
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGLOST 29
+#define SIGUSR1 30
+#define SIGUSR2 31
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long sigset_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+#endif
+
+/* A SunOS sigstack */
+struct sigstack {
+ char *the_stack;
+ int cur_status;
};
+/* Sigvec flags */
+#define SV_SSTACK 1 /* This signal handler should use sig-stack */
+#define SV_INTR 2 /* Sig return should not restart system call */
+#define SV_RESET 4 /* Set handler to SIG_DFL upon taken signal */
+#define SV_IGNCHILD 8 /* Do not send SIGCHLD */
+
+/*
+ * sa_flags values: SA_STACK is not currently supported, but will allow the
+ * usage of signal stacks by using the (now obsolete) sa_restorer field in
+ * the sigaction structure as a stack pointer. This is now possible due to
+ * the changes in signal handling. LBT 010493.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
+ */
+#define SA_NOCLDSTOP SV_IGNCHILD
+#define SA_STACK SV_SSTACK
+#define SA_RESTART SV_INTR
+#define SA_ONESHOT SV_RESET
+#define SA_INTERRUPT 0x10
+#define SA_NOMASK 0x20
+#define SA_SHIRQ 0x40
+
+#define SIG_BLOCK 0x01 /* for blocking signals */
+#define SIG_UNBLOCK 0x02 /* for unblocking signals */
+#define SIG_SETMASK 0x04 /* for setting the signal mask */
+
+#ifdef __KERNEL__
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ *
+ * DJHR
+ * SA_STATIC_ALLOC is used for the SPARC system to indicate that this
+ * interrupt handler's irq structure should be statically allocated
+ * by the request_irq routine.
+ * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge
+ * of interrupt usage and that sucks. Also without a flag like this
+ * it may be possible for the free_irq routine to attempt to free
+ * statically allocated data.. which is NOT GOOD.
+ *
+ */
+#define SA_PROBE SA_ONESHOT
+#define SA_SAMPLE_RANDOM SA_RESTART
+#define SA_STATIC_ALLOC 0x80
+#endif
+
+/* Type of a signal handler. */
+#ifdef __KERNEL__
+typedef void (*__sighandler_t)(int, int, struct sigcontext *, char *);
+#else
+typedef void (*__sighandler_t)(int);
#endif
+
+#define SIG_DFL ((__sighandler_t)0) /* default signal handling */
+#define SIG_IGN ((__sighandler_t)1) /* ignore signal */
+#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */
+
+struct sigaction {
+ __sighandler_t sa_handler;
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer) (void); /* not used by Linux/SPARC yet */
+};
+
+#ifdef __KERNEL__
+
+/* use the following macro to get the size of a sigaction struct
+ when copying to/from userland */
+#define SIGACTION_SIZE(personality) (((personality) & PER_BSD)?\
+ sizeof(struct sigaction)-sizeof(void *):\
+ sizeof(struct sigaction))
+
+#endif /* __KERNEL__ */
+
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_ASMSPARC_SIGNAL_H) */
diff --git a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h
new file mode 100644
index 000000000..0d1cab1eb
--- /dev/null
+++ b/include/asm-sparc/smp.h
@@ -0,0 +1,172 @@
+/* smp.h: Sparc specific SMP stuff.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_SMP_H
+#define _SPARC_SMP_H
+
+#ifndef __ASSEMBLY__
+/* PROM provided per-processor information we need
+ * to start them all up.
+ */
+
+struct prom_cpuinfo {
+ int prom_node;
+ int mid;
+};
+#endif /* !(__ASSEMBLY__) */
+
+#ifdef __SMP__
+
+#ifndef __ASSEMBLY__
+
+extern struct prom_cpuinfo linux_cpus[NCPUS];
+
+/* Per processor Sparc parameters we need. */
+
+struct cpuinfo_sparc {
+ unsigned long udelay_val; /* that's it */
+};
+
+extern struct cpuinfo_sparc cpu_data[NR_CPUS];
+
+typedef __volatile__ unsigned char klock_t;
+extern klock_t kernel_flag;
+
+#define KLOCK_HELD 0xff
+#define KLOCK_CLEAR 0x00
+
+/*
+ * Private routines/data
+ */
+
+extern int smp_found_cpus;
+extern unsigned char boot_cpu_id;
+extern unsigned long cpu_present_map;
+extern __volatile__ unsigned long smp_invalidate_needed[NR_CPUS];
+extern __volatile__ unsigned long kernel_counter;
+extern __volatile__ unsigned char active_kernel_processor;
+extern void smp_message_irq(void);
+extern unsigned long ipi_count;
+extern __volatile__ unsigned long kernel_counter;
+extern __volatile__ unsigned long syscall_count;
+
+extern void print_lock_state(void);
+
+typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long,
+ unsigned long, unsigned long);
+
+/*
+ * General functions that each host system must provide.
+ */
+
+extern void smp_callin(void);
+extern void smp_boot_cpus(void);
+extern void smp_store_cpu_info(int id);
+extern void smp_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4, unsigned long arg5);
+extern void smp_capture(void);
+extern void smp_release(void);
+
+extern __inline__ void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); }
+extern __inline__ void xc1(smpfunc_t func, unsigned long arg1)
+{ smp_cross_call(func, arg1, 0, 0, 0, 0); }
+extern __inline__ void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
+{ smp_cross_call(func, arg1, arg2, 0, 0, 0); }
+extern __inline__ void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3)
+{ smp_cross_call(func, arg1, arg2, arg3, 0, 0); }
+extern __inline__ void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4)
+{ smp_cross_call(func, arg1, arg2, arg3, arg4, 0); }
+extern __inline__ void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4, unsigned long arg5)
+{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); }
+
+extern __volatile__ int cpu_number_map[NR_CPUS];
+extern __volatile__ int cpu_logical_map[NR_CPUS];
+
+extern __inline__ int smp_processor_id(void)
+{
+ int cpuid;
+
+ __asm__ __volatile__("rd %%tbr, %0\n\t"
+ "srl %0, 12, %0\n\t"
+ "and %0, 3, %0\n\t" :
+ "=&r" (cpuid));
+ return cpuid;
+}
+
+
+extern __volatile__ unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */
+extern __volatile__ int smp_process_available;
+
+extern __inline__ int smp_swap(volatile int *addr, int value)
+{
+ __asm__ __volatile__("swap [%2], %0\n\t" :
+ "=&r" (value) :
+ "0" (value), "r" (addr));
+ return value;
+}
+
+extern __inline__ __volatile__ void inc_smp_counter(volatile int *ctr)
+{
+ int tmp;
+
+ while((tmp = smp_swap(ctr, -1)) == -1)
+ while(*ctr == -1)
+ ;
+
+ *ctr = (tmp + 1);
+}
+
+extern __inline__ __volatile__ void dec_smp_counter(volatile int *ctr)
+{
+ int tmp;
+
+ while((tmp = smp_swap(ctr, -1)) == -1)
+ while(*ctr == -1)
+ ;
+
+ *ctr = (tmp - 1);
+}
+
+extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr)
+{
+ int value;
+
+ while((value = *ctr) == -1)
+ ;
+
+ return value;
+}
+
+#endif /* !(__ASSEMBLY__) */
+
+/* Sparc specific messages. */
+#define MSG_CAPTURE 0x0004 /* Park a processor. */
+#define MSG_CROSS_CALL 0x0005 /* run func on cpus */
+
+/* Empirical PROM processor mailbox constants. If the per-cpu mailbox
+ * contains something other than one of these then the ipi is from
+ * Linux's active_kernel_processor. This facility exists so that
+ * the boot monitor can capture all the other cpus when one catches
+ * a watchdog reset or the user enters the monitor using L1-A keys.
+ */
+#define MBOX_STOPCPU 0xFB
+#define MBOX_IDLECPU 0xFC
+#define MBOX_IDLECPU2 0xFD
+#define MBOX_STOPCPU2 0xFE
+
+
+#define NO_PROC_ID 0xFF
+
+#define PROC_CHANGE_PENALTY 20
+
+#define SMP_FROM_INT 1
+#define SMP_FROM_SYSCALL 2
+
+#endif /* !(__SMP__) */
+
+#endif /* !(_SPARC_SMP_H) */
diff --git a/include/asm-sparc/smp_lock.h b/include/asm-sparc/smp_lock.h
new file mode 100644
index 000000000..7ce71d8ff
--- /dev/null
+++ b/include/asm-sparc/smp_lock.h
@@ -0,0 +1,60 @@
+/* smp_lock.h: Locking and unlocking the kernel on the Sparc.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __SPARC_SMPLOCK_H
+#define __SPARC_SMPLOCK_H
+
+#include <asm/smp.h>
+#include <asm/bitops.h>
+#include <asm/atops.h>
+#include <asm/pgtable.h>
+
+#ifdef __SMP__
+
+/*
+ * Locking the kernel
+ */
+
+/* Knock knock... */
+extern __inline__ void lock_kernel(void)
+{
+ unsigned long flags;
+ int proc = smp_processor_id();
+
+ save_flags(flags); cli(); /* need this on sparc? */
+ while(ldstub(&kernel_flag)) {
+ if(proc == active_kernel_processor)
+ break;
+ do {
+#ifdef __SMP_PROF__
+ smp_spins[smp_processor_id()]++;
+#endif
+ barrier();
+ } while(kernel_flag); /* Don't lock the bus more than we have to. */
+ }
+ active_kernel_processor = proc;
+ kernel_counter++;
+ restore_flags(flags);
+}
+
+/* I want out... */
+extern __inline__ void unlock_kernel(void)
+{
+ unsigned long flags;
+
+ save_flags(flags); cli(); /* need this on sparc? */
+ if(kernel_counter == 0)
+ panic("Bogus kernel counter.\n");
+
+ if(!--kernel_counter) {
+ active_kernel_processor = NO_PROC_ID;
+ kernel_flag = KLOCK_CLEAR;
+ }
+ restore_flags(flags);
+}
+
+#endif /* !(__SPARC_SMPLOCK_H) */
+
+#endif /* (__SMP__) */
diff --git a/include/asm-sparc/smpprim.h b/include/asm-sparc/smpprim.h
new file mode 100644
index 000000000..9b9c28ed7
--- /dev/null
+++ b/include/asm-sparc/smpprim.h
@@ -0,0 +1,54 @@
+/* $Id: smpprim.h,v 1.5 1996/08/29 09:48:49 davem Exp $
+ * smpprim.h: SMP locking primitives on the Sparc
+ *
+ * God knows we won't be actually using this code for some time
+ * but I thought I'd write it since I knew how.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __SPARC_SMPPRIM_H
+#define __SPARC_SMPPRIM_H
+
+/* Test and set the unsigned byte at ADDR to 1. Returns the previous
+ * value. On the Sparc we use the ldstub instruction since it is
+ * atomic.
+ */
+
+extern __inline__ __volatile__ char test_and_set(void *addr)
+{
+ char state = 0;
+
+ __asm__ __volatile__("ldstub [%0], %1 ! test_and_set\n\t"
+ "=r" (addr), "=r" (state) :
+ "0" (addr), "1" (state) : "memory");
+
+ return state;
+}
+
+/* Initialize a spin-lock. */
+extern __inline__ __volatile__ smp_initlock(void *spinlock)
+{
+ /* Unset the lock. */
+ *((unsigned char *) spinlock) = 0;
+
+ return;
+}
+
+/* This routine spins until it acquires the lock at ADDR. */
+extern __inline__ __volatile__ smp_lock(void *addr)
+{
+ while(test_and_set(addr) == 0xff)
+ ;
+
+ /* We now have the lock */
+ return;
+}
+
+/* This routine releases the lock at ADDR. */
+extern __inline__ __volatile__ smp_unlock(void *addr)
+{
+ *((unsigned char *) addr) = 0;
+}
+
+#endif /* !(__SPARC_SMPPRIM_H) */
diff --git a/include/asm-sparc/socket.h b/include/asm-sparc/socket.h
new file mode 100644
index 000000000..1c5348030
--- /dev/null
+++ b/include/asm-sparc/socket.h
@@ -0,0 +1,32 @@
+/* $Id: socket.h,v 1.6 1996/04/04 12:51:26 davem Exp $ */
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET 0xffff
+
+#define SO_DEBUG 0x0001
+#define SO_REUSEADDR 0x0004
+#define SO_KEEPALIVE 0x0008
+#define SO_DONTROUTE 0x0010
+#define SO_BROADCAST 0x0020
+#define SO_LINGER 0x0080
+#define SO_OOBINLINE 0x0100
+/* To add :#define SO_REUSEPORT 0x0200 */
+#define SO_BSDCOMPAT 0x0400
+
+/* wha!??? */
+#define SO_DONTLINGER (~SO_LINGER) /* Older SunOS compat. hack */
+
+#define SO_SNDBUF 0x1001
+#define SO_RCVBUF 0x1002
+#define SO_ERROR 0x1007
+#define SO_TYPE 0x1008
+
+/* Linux specific, keep the same. */
+#define SO_NO_CHECK 0x000b
+#define SO_PRIORITY 0x000c
+
+#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-sparc/sockios.h b/include/asm-sparc/sockios.h
new file mode 100644
index 000000000..0c01b597b
--- /dev/null
+++ b/include/asm-sparc/sockios.h
@@ -0,0 +1,13 @@
+#ifndef _ASM_SPARC_SOCKIOS_H
+#define _ASM_SPARC_SOCKIOS_H
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906 /* Get stamp */
+
+#endif /* !(_ASM_SPARC_SOCKIOS_H) */
+
diff --git a/include/asm-sparc/solerrno.h b/include/asm-sparc/solerrno.h
new file mode 100644
index 000000000..8abce7e46
--- /dev/null
+++ b/include/asm-sparc/solerrno.h
@@ -0,0 +1,132 @@
+/* $Id: solerrno.h,v 1.5 1996/04/25 06:13:32 davem Exp $
+ * solerrno.h: Solaris error return codes for compatibility.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_SOLERRNO_H
+#define _SPARC_SOLERRNO_H
+
+#define SOL_EPERM 1 /* Required superuser access perms */
+#define SOL_ENOENT 2 /* File or directory does not exist */
+#define SOL_ESRCH 3 /* Process did not exist */
+#define SOL_EINTR 4 /* System call was interrupted */
+#define SOL_EIO 5 /* An i/o error occurred */
+#define SOL_ENXIO 6 /* Device or Address does not exist */
+#define SOL_E2BIG 7 /* Too many arguments were given */
+#define SOL_ENOEXEC 8 /* Header of executable was munged */
+#define SOL_EBADF 9 /* Bogus file number */
+#define SOL_ECHILD 10 /* No children of process exist */
+#define SOL_EAGAIN 11 /* beep beep, "try again later" */
+#define SOL_ENOMEM 12 /* No memory available */
+#define SOL_EACCES 13 /* Access not allowed */
+#define SOL_EFAULT 14 /* Address passed was invalid */
+#define SOL_ENOTBLK 15 /* blkdev op on non-block device */
+#define SOL_EBUSY 16 /* Mounted device was busy */
+#define SOL_EEXIST 17 /* File specified already exists */
+#define SOL_EXDEV 18 /* Link request across diff devices */
+#define SOL_ENODEV 19 /* Device does not exist on system */
+#define SOL_ENOTDIR 20 /* Dir operation on non-directory */
+#define SOL_EISDIR 21 /* File was of directory type */
+#define SOL_EINVAL 22 /* Argument passed was invalid */
+#define SOL_ENFILE 23 /* No more room in file table */
+#define SOL_EMFILE 24 /* Proc has too many files open */
+#define SOL_ENOTTY 25 /* Ioctl was invalid for req device */
+#define SOL_ETXTBSY 26 /* Text file in busy state */
+#define SOL_EFBIG 27 /* Too big of a file for operation */
+#define SOL_ENOSPC 28 /* Disk is full */
+#define SOL_ESPIPE 29 /* Seek attempted on non-seeking dev*/
+#define SOL_EROFS 30 /* Write attempted on read-only fs */
+#define SOL_EMLINK 31 /* Too many links in file search */
+#define SOL_EPIPE 32 /* Call a plumber */
+#define SOL_EDOM 33 /* Argument was out of fct domain */
+#define SOL_ERANGE 34 /* Could not represent math result */
+#define SOL_ENOMSG 35 /* Message of req type doesn't exist */
+#define SOL_EIDRM 36 /* Identifier has been removed */
+#define SOL_ECHRNG 37 /* Req channel number out of range */
+#define SOL_EL2NSYNC 38 /* Could not sync at run level 2 */
+#define SOL_EL3HLT 39 /* Halted at run level 3 */
+#define SOL_EL3RST 40 /* Reset at run level 3 */
+#define SOL_ELNRNG 41 /* Out of range link number */
+#define SOL_EUNATCH 42 /* Driver for protocol not attached */
+#define SOL_ENOCSI 43 /* CSI structure not around */
+#define SOL_EL2HLT 44 /* Halted at run level 2 */
+#define SOL_EDEADLK 45 /* Deadlock condition detected */
+#define SOL_ENOLCK 46 /* Record locks unavailable */
+#define SOL_ECANCELED 47 /* Cancellation of oper. happened */
+#define SOL_ENOTSUP 48 /* Attempt of unsupported operation */
+#define SOL_EDQUOT 49 /* Users disk quota exceeded */
+#define SOL_EBADE 50 /* Invalid exchange */
+#define SOL_EBADR 51 /* Request descriptor was invalid */
+#define SOL_EXFULL 52 /* Full exchange */
+#define SOL_ENOANO 53 /* ano does not exist */
+#define SOL_EBADRQC 54 /* Req code was invalid */
+#define SOL_EBADSLT 55 /* Bad slot number */
+#define SOL_EDEADLOCK 56 /* Deadlock in fs error */
+#define SOL_EBFONT 57 /* Font file format invalid */
+/* YOW, I LOVE SYSV STREAMS!!!! */
+#define SOL_ENOSTR 60 /* Stream-op on non-stream dev */
+#define SOL_ENODATA 61 /* No data avail at this time */
+#define SOL_ETIME 62 /* Expiration of time occurred */
+#define SOL_ENOSR 63 /* Streams resources exhausted */
+#define SOL_ENONET 64 /* No network connected */
+#define SOL_ENOPKG 65 /* Non-installed package */
+#define SOL_EREMOTE 66 /* Object was on remote machine */
+#define SOL_ENOLINK 67 /* Cut link */
+#define SOL_EADV 68 /* Error in advertise */
+#define SOL_ESRMNT 69 /* Some magic srmount problem */
+#define SOL_ECOMM 70 /* During send, comm error occurred */
+#define SOL_EPROTO 71 /* Protocol botch */
+#define SOL_EMULTIHOP 74 /* Multihop attempted */
+#define SOL_EBADMSG 77 /* Message was unreadable */
+#define SOL_ENAMETOOLONG 78 /* Too long of a path name */
+#define SOL_EOVERFLOW 79 /* Data type too small for datum */
+#define SOL_ENOTUNIQ 80 /* Logical name was not unique */
+#define SOL_EBADFD 81 /* Op cannot be performed on fd */
+#define SOL_EREMCHG 82 /* Remote address is now different */
+#define SOL_ELIBACC 83 /* Shared lib could not be accessed */
+#define SOL_ELIBBAD 84 /* ShLib is corrupted in some way */
+#define SOL_ELIBSCN 85 /* A.out ShLib problems */
+#define SOL_ELIBMAX 86 /* Exceeded ShLib linkage limit */
+#define SOL_ELIBEXEC 87 /* Execution of ShLib attempted */
+#define SOL_EILSEQ 88 /* Bad byte sequence found */
+#define SOL_ENOSYS 89 /* Invalid filesystem operation */
+#define SOL_ELOOP 90 /* Detected loop in symbolic links */
+#define SOL_ERESTART 91 /* System call is restartable */
+#define SOL_ESTRPIPE 92 /* Do not sleep in head of stream */
+#define SOL_ENOTEMPTY 93 /* Rmdir of non-empty directory */
+#define SOL_EUSERS 94 /* Over abundance of users for ufs */
+#define SOL_ENOTSOCK 95 /* Sock-op on non-sock */
+#define SOL_EDESTADDRREQ 96 /* No dest addr given, but needed */
+#define SOL_EMSGSIZE 97 /* Msg too big */
+#define SOL_EPROTOTYPE 98 /* Bad socket protocol */
+#define SOL_ENOPROTOOPT 99 /* Unavailable protocol */
+#define SOL_EPROTONOSUPPORT 120 /* Unsupported protocol */
+#define SOL_ESOCKTNOSUPPORT 121 /* Unsupported socket type */
+#define SOL_EOPNOTSUPP 122 /* Unsupported sock-op */
+#define SOL_EPFNOSUPPORT 123 /* Unsupported protocol family */
+#define SOL_EAFNOSUPPORT 124 /* Unsup addr family for protocol */
+#define SOL_EADDRINUSE 125 /* Req addr is already in use */
+#define SOL_EADDRNOTAVAIL 126 /* Req addr not available right now */
+#define SOL_ENETDOWN 127 /* Your subnet is on fire */
+#define SOL_ENETUNREACH 128 /* Someone playing with gateway and */
+ /* did not tell you he was going to */
+#define SOL_ENETRESET 129 /* Buy less-buggy ethernet cards */
+#define SOL_ECONNABORTED 130 /* Aborted connection due to sw */
+#define SOL_ECONNRESET 131 /* Your peers reset your connection */
+#define SOL_ENOBUFS 132 /* No buffer space available */
+#define SOL_EISCONN 133 /* Connect on already connected */
+ /* socket attempted */
+#define SOL_ENOTCONN 134 /* Comm on non-connected socket */
+#define SOL_ESHUTDOWN 143 /* Op attempted after sock-shutdown */
+#define SOL_ETOOMANYREFS 144 /* Reference limit exceeded */
+#define SOL_ETIMEDOUT 145 /* Timed out connection */
+#define SOL_ECONNREFUSED 146 /* Connection refused by remote host*/
+#define SOL_EHOSTDOWN 147 /* Remote host is up in flames */
+#define SOL_EHOSTUNREACH 148 /* Make a left at Easton Ave..... */
+#define SOL_EWOULDBLOCK EAGAIN /* Just an alias */
+#define SOL_EALREADY 149 /* Operation is already occurring */
+#define SOL_EINPROGRESS 150 /* Operation is happening now */
+#define SOL_ESTALE 151 /* Fungus growth on NFS file handle */
+
+#endif /* !(_SPARC_SOLERRNO_H) */
diff --git a/include/asm-sparc/stat.h b/include/asm-sparc/stat.h
new file mode 100644
index 000000000..35f929c56
--- /dev/null
+++ b/include/asm-sparc/stat.h
@@ -0,0 +1,41 @@
+/* $Id: stat.h,v 1.7 1996/10/27 08:55:48 davem Exp $ */
+#ifndef _SPARC_STAT_H
+#define _SPARC_STAT_H
+
+#include <linux/types.h>
+
+struct __old_kernel_stat {
+ unsigned short st_dev;
+ unsigned short st_ino;
+ unsigned short st_mode;
+ unsigned short st_nlink;
+ unsigned short st_uid;
+ unsigned short st_gid;
+ unsigned short st_rdev;
+ unsigned long st_size;
+ unsigned long st_atime;
+ unsigned long st_mtime;
+ unsigned long st_ctime;
+};
+
+struct stat {
+ dev_t st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ short st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+ dev_t st_rdev;
+ off_t st_size;
+ time_t st_atime;
+ unsigned long __unused1;
+ time_t st_mtime;
+ unsigned long __unused2;
+ time_t st_ctime;
+ unsigned long __unused3;
+ off_t st_blksize;
+ off_t st_blocks;
+ unsigned long __unused4[2];
+};
+
+#endif
diff --git a/include/asm-sparc/statfs.h b/include/asm-sparc/statfs.h
new file mode 100644
index 000000000..91a19b92a
--- /dev/null
+++ b/include/asm-sparc/statfs.h
@@ -0,0 +1,26 @@
+/* $Id: statfs.h,v 1.4 1996/06/07 00:41:05 ecd Exp $ */
+#ifndef _SPARC_STATFS_H
+#define _SPARC_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t fsid_t;
+
+#endif
+
+struct statfs {
+ long f_type;
+ long f_bsize;
+ long f_blocks;
+ long f_bfree;
+ long f_bavail;
+ long f_files;
+ long f_ffree;
+ __kernel_fsid_t f_fsid;
+ long f_namelen; /* SunOS ignores this field. */
+ long f_spare[6];
+};
+
+#endif
diff --git a/include/asm-sparc/string.h b/include/asm-sparc/string.h
index 6e0bfc1f7..856e96f6d 100644
--- a/include/asm-sparc/string.h
+++ b/include/asm-sparc/string.h
@@ -1,367 +1,178 @@
-/* string.h: External definitions for optimized assembly string
- routines for the Linux Kernel.
+/* $Id: string.h,v 1.27 1996/10/27 08:55:50 davem Exp $
+ * string.h: External definitions for optimized assembly string
+ * routines for the Linux Kernel.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
- Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
-*/
+#ifndef __SPARC_STRING_H__
+#define __SPARC_STRING_H__
-extern inline size_t strlen(const char * str)
-{
- register size_t retval = 0;
- register char tmp = 0;
- register char * lstr;
-
- lstr = (char *) str;
-
- __asm__("ldub [%1], %2\n\t"
- "or %%g0, %%g0, %0\n\t"
- "orcc %2, %%g0, %%g0\n\t"
- "be 2f\n\t"
- "add %1, 0x1, %1\n\t"
- "1: ldub [%1], %2\n\t"
- "add %0, 0x1, %0\n\t"
- "orcc %2, %%g0, %%g0\n\t"
- "bne 1b\n\t"
- "add %1, 0x1, %1\n\t"
- "2:" :
- "=r" (retval), "=r" (lstr), "=r" (tmp) :
- "0" (retval), "1" (lstr), "2" (tmp));
-
- return retval;
-}
-
-extern __inline__ int strcmp(const char* str1, const char* str2)
-{
- register unsigned int tmp1=0, tmp2=0;
- register int retval=0;
-
- __asm__("ldub [%1], %3\n\t"
- "ldub [%2], %4\n\t"
- "1: add %2, 0x1, %2\n\t"
- "cmp %3, %4\n\t"
- "bne,a 2f\n\t"
- "sub %2, 0x1, %2\n\t"
- "ldub [%1], %3\n\t"
- "add %1, 0x1, %1\n\t"
- "cmp %3, 0x0\n\t"
- "bne,a 1b\n\t"
- "ldub [%2], %4\n\t"
- "b 3f\n\t"
- "or %%g0, %%g0, %0\n\t"
- "2: ldub [%1], %3\n\t"
- "ldub [%2], %4\n\t"
- "sub %3, %4, %0\n\t"
- "3: \n\t" :
- "=r" (retval), "=r" (str1), "=r" (str2), "=r" (tmp1), "=r" (tmp2) :
- "0" (retval), "1" (str1), "2" (str2),
- "3" (tmp1), "4" (tmp2));
-
- return retval;
-}
-
-extern __inline__ int strncmp(const char* str1, const char* str2, size_t strlen)
-{
- register int retval=0;
-
- __asm__("cmp %3, 0x0\n\t"
- "be 2f\n\t"
- "ldub [%2], %%g3\n\t"
- "1: ldub [%1], %%g2\n\t"
- "sub %%g2, %%g3, %0\n\t"
- "cmp %0, 0x0\n\t"
- "bne 2f\n\t"
- "add %2, 0x1, %2\n\t"
- "cmp %%g2, 0x0\n\t"
- "be 2f\n\t"
- "add %1, 0x1, %1\n\t"
- "addcc %3, -1, %3\n\t"
- "bne,a 1b\n\t"
- "ldub [%2], %%g3\n\t"
- "2: " :
- "=r" (retval), "=r" (str1), "=r" (str2), "=r" (strlen) :
- "0" (retval), "1" (str1), "2" (str2), "3" (strlen) :
- "%g2", "%g3");
-
- return retval;
-}
+/* Really, userland/ksyms should not see any of this stuff. */
+#if defined(__KERNEL__) && !defined(EXPORT_SYMTAB)
-extern __inline__ char *strcpy(char* dest, const char* source)
-{
- register char tmp;
- register char *retval;
-
- __asm__("or %%g0, %2, %0\n\t"
- "ldub [%1], %3\n\t"
- "1: stb %3, [%2]\n\t"
- "cmp %3, 0x0\n\t"
- "bne,a 1b\n\t"
- "ldub [%1], %3\n\t" :
- "=r" (retval), "=r" (source), "=r" (dest), "=r" (tmp) :
- "0" (retval), "1" (source), "2" (dest), "3" (tmp));
-
- return retval;
-}
+/* First the mem*() things. */
+#define __HAVE_ARCH_BCOPY
+#define __HAVE_ARCH_MEMMOVE
+#define __HAVE_ARCH_MEMCPY
+extern void *__memcpy(void *,const void *,__kernel_size_t);
-extern __inline__ char *strncpy(char *dest, const char *source, size_t cpylen)
+extern inline void *__constant_memcpy(void *to, const void *from, __kernel_size_t n)
{
- register char tmp;
- register char *retval;
-
- __asm__("or %%g0, %1, %0\n\t"
- "1: cmp %4, 0x0\n\t"
- "be 2f\n\t"
- "ldub [%1], %3\n\t"
- "add %1, 0x1, %1\n\t"
- "stb %3, [%2]\n\t"
- "sub %4, 0x1, %4\n\t"
- "ba 1\n\t"
- "add %2, 0x1, %2\n\t" :
- "=r" (retval), "=r" (dest), "=r" (source), "=r"(tmp), "=r" (cpylen) :
- "0" (retval), "1" (dest), "2" (source),
- "3" (tmp), "4" (cpylen));
-
- return retval;
-}
-
-extern __inline__ char *strcat(char *dest, const char *src)
-{
- register char *retval;
- register char temp=0;
-
- __asm__("or %%g0, %1, %0\n\t"
- "1: ldub [%1], %3\n\t"
- "cmp %3, 0x0\n\t"
- "bne,a 1b\n\t"
- "add %1, 0x1, %1\n\t"
- "2: ldub [%2], %3\n\t"
- "stb %3, [%1]\n\t"
- "add %1, 0x1, %1\n\t"
- "cmp %3, 0x0\n\t"
- "bne 2b\n\t"
- "add %2, 0x1, %2\n\t" :
- "=r" (retval), "=r" (dest), "=r" (src), "=r" (temp) :
- "0" (retval), "1" (dest), "2" (src), "3" (temp));
-
- return retval;
-}
-
-extern __inline__ char *strncat(char *dest, const char *src, size_t len)
-{
- register char *retval;
- register char temp=0;
-
- __asm__("or %%g0, %1, %0\n\t"
- "1: ldub [%1], %3\n\t"
- "cmp %3, 0x0\n\t"
- "bne,a 1b\n\t"
- "add %1, 0x1, %1\n\t"
- "2: ldub [%2], %3\n\t"
- "stb %3, [%1]\n\t"
- "add %1, 0x1, %1\n\t"
- "add %3, -1, %3\n\t"
- "cmp %3, 0x0\n\t"
- "bne 2b\n\t"
- "add %2, 0x1, %2\n\t" :
- "=r" (retval), "=r" (dest), "=r" (src), "=r" (len), "=r" (temp) :
- "0" (retval), "1" (dest), "2" (src), "3" (len), "4" (temp));
-
- return retval;
+ extern void __copy_1page(void *, const void *);
+
+ if(n <= 32) {
+ __builtin_memcpy(to, from, n);
+ } else {
+ switch(n) {
+ case 4096:
+ __copy_1page(to, from);
+ break;
+ default:
+ __memcpy(to, from, n);
+ break;
+ }
+ }
+ return to;
}
-extern __inline__ char *strchr(const char *src, int c)
+extern inline void *__nonconstant_memcpy(void *to, const void *from, __kernel_size_t n)
{
- register char temp=0;
- register char *trick=0;
-
- __asm__("1: ldub [%0], %2\n\t"
- "cmp %2, %1\n\t"
- "bne,a 1b\n\t"
- "add %0, 0x1, %0\n\t"
- "or %%g0, %0, %3\n\t" :
- "=r" (src), "=r" (c), "=r" (temp), "=r" (trick), "=r" (src) :
- "0" (src), "1" (c), "2" (temp), "3" (trick), "4" (src));
-
- return trick;
+ __memcpy(to, from, n);
+ return to;
}
-extern __inline__ char *strpbrk(const char *cs, const char *ct)
-{
- register char temp1, temp2;
- register char *scratch;
- register char *trick;
-
- __asm__("or %%g0, %1, %4\n\t"
- "1: ldub [%0], %2\n\t"
- "2: ldub [%1], %3\n\t"
- "cmp %3, %2\n\t"
- "be 3f\n\t"
- "nop\n\t"
- "cmp %3, 0x0\n\t"
- "bne 2b\n\t"
- "add %1, 0x1, %1\n\t"
- "or %%g0, %4, %1\n\t"
- "b 1b\n\t"
- "add %0, 0x1, %0\n\t"
- "or %%g0, %0, %5\n\t" :
- "=r" (cs) :
- "r" (ct), "r" (temp1), "r" (temp2), "r" (scratch), "r" (trick=0),
- "0" (cs), "1" (ct));
+#undef memcpy
+#define memcpy(t, f, n) \
+(__builtin_constant_p(n) ? \
+ __constant_memcpy((t),(f),(n)) : \
+ __nonconstant_memcpy((t),(f),(n)))
- return trick;
-
-}
+#define __HAVE_ARCH_MEMSET
+extern void *__memset(void *,int,__kernel_size_t);
-
-extern __inline__ size_t strspn(const char *s, const char *accept)
+extern inline void *__constant_c_and_count_memset(void *s, char c, size_t count)
{
- register char temp1, temp2;
- register char* scratch;
- register size_t trick;
-
- __asm__("or %%g0, %1, %4\n\t"
- "1: ldub [%0], %2\n\t"
- "2: ldub [%1], %3\n\t"
- "cmp %3, 0x0\n\t"
- "be 3f\n\t"
- "cmp %3, %2"
- "bne 2b\n\t"
- "add %1, 0x1, %1\n\t"
- "add %0, 0x1, %0\n\t"
- "b 1b\n\t"
- "add %5, 0x1, %5\n\t"
- "3: or %%g0, %0, %4\n\t" :
- "=r" (s) :
- "r" (accept), "r" (temp1), "r" (temp2),
- "r" (scratch), "r" (trick=0), "0" (s));
-
- return trick;
-
-}
-
-extern __inline__ char *strtok(char *s, const char *ct)
-{
- static char* old; /* frob this kludge for now */
- register char *tok;
-
- if (s == (char *) 0)
- {
- if (old == (char *) 0)
- {
- return (char *) 0;
+ extern void *bzero_1page(void *);
+ extern void *__bzero(void *, size_t);
+
+ if(!c) {
+ if(count == 4096)
+ bzero_1page(s);
+ else
+ __bzero(s, count);
+ } else {
+ __memset(s, c, count);
}
- else
- s = old;
- }
-
- s += strspn(s, ct);
- if(*s == '\0')
- {
- old = (char *) 0;
- return (char *) 0;
- }
-
- tok = s;
- s = strpbrk(tok, ct);
- if (s == (char *) 0)
- old = (char *) 0;
- else
- {
- *s = '\0';
- old = s + 1;
- }
- return tok;
-}
-
-
-extern __inline__ void *memset(void *src, int c, size_t count)
-{
- register void *retval;
-
- __asm__("or %%g0, %1, %0\n\t"
- "1: add %1, 0x1, %1\n\t"
- "2: add %3, -1, %3\n\t"
- "cmp %3, -1\n\t"
- "bne,a 1b\n\t"
- "stb %2, [%1]\n\t" :
- "=r" (retval), "=r" (src), "=r" (c), "=r" (count) :
- "0" (retval), "1" (src), "2" (c), "3" (count));
-
- return retval;
+ return s;
}
-extern __inline__ void *memcpy(void *dest, const void *src, size_t count)
+extern inline void *__constant_c_memset(void *s, char c, size_t count)
{
- register void *retval;
- register char tmp;
+ extern void *__bzero(void *, size_t);
- __asm__("or %%g0, %1, %0\n\t"
- "add %3, -1, %3\n\t"
- "cmp %3, -1\n\t"
- "be 2f\n\t"
- "1: ldub [%2], %4\n\t"
- "add %2, 0x1, %2\n\t"
- "add %3, -1, %3\n\t"
- "cmp %3, -1\n\t"
- "stb %4, [%1]\n\t"
- "bne 1b\n\t"
- "add %1, 0x1, %1\n\t"
- "2: " :
- "=r" (retval), "=r" (dest), "=r" (src), "=r" (count), "=r" (tmp) :
- "0" (retval), "1" (dest), "2" (src), "3" (count), "4" (tmp));
-
- return retval;
+ if(!c)
+ __bzero(s, count);
+ else
+ __memset(s, c, count);
+ return s;
}
-extern __inline__ void *memmove(void *dest, const void *src, size_t count)
+#undef memset
+#define memset(s, c, count) \
+(__builtin_constant_p(c) ? (__builtin_constant_p(count) ? \
+ __constant_c_and_count_memset((s), (c), (count)) : \
+ __constant_c_memset((s), (c), (count))) \
+ : __memset((s), (c), (count)))
+
+#define __HAVE_ARCH_MEMSCAN
+
+#undef memscan
+#define memscan(__arg0, __char, __arg2) \
+({ \
+ extern void *__memscan_zero(void *, size_t); \
+ extern void *__memscan_generic(void *, int, size_t); \
+ void *__retval, *__addr = (__arg0); \
+ size_t __size = (__arg2); \
+ \
+ if(__builtin_constant_p(__char) && !(__char)) \
+ __retval = __memscan_zero(__addr, __size); \
+ else \
+ __retval = __memscan_generic(__addr, (__char), __size); \
+ \
+ __retval; \
+})
+
+#define __HAVE_ARCH_MEMCMP
+
+/* Now the str*() stuff... */
+#define __HAVE_ARCH_STRLEN
+
+#define __HAVE_ARCH_STRNCMP
+
+extern int __strncmp(const char *, const char *, __kernel_size_t);
+
+extern inline int __constant_strncmp(const char *src, const char *dest, __kernel_size_t count)
{
- register void *retval;
- register char tmp;
-
- __asm__("or %%g0, %1, %1\n\t"
- "add %3, -1, %3\n\t"
- "cmp %3, -1\n\t"
- "be 2f\n\t"
- "1: ldub [%2], %4\n\t"
- "add %2, 0x1, %2\n\t"
- "add %3, -1, %3\n\t"
- "cmp %3, -1\n\t"
- "stb %4, [%1]\n\t"
- "bne 1b\n\t"
- "add %1, 0x1, %1\n\t"
- "2: " :
- "=r" (retval), "=r" (dest), "=r" (src), "=r" (count), "=r" (tmp) :
- "0" (retval), "1" (dest), "2" (src), "3" (count), "4" (tmp));
-
- return retval;
+ register int retval;
+ switch(count) {
+ case 0: return 0;
+ case 1: return (src[0] - dest[0]);
+ case 2: retval = (src[0] - dest[0]);
+ if(!retval && src[0])
+ retval = (src[1] - dest[1]);
+ return retval;
+ case 3: retval = (src[0] - dest[0]);
+ if(!retval && src[0]) {
+ retval = (src[1] - dest[1]);
+ if(!retval && src[1])
+ retval = (src[2] - dest[2]);
+ }
+ return retval;
+ case 4: retval = (src[0] - dest[0]);
+ if(!retval && src[0]) {
+ retval = (src[1] - dest[1]);
+ if(!retval && src[1]) {
+ retval = (src[2] - dest[2]);
+ if (!retval && src[2])
+ retval = (src[3] - dest[3]);
+ }
+ }
+ return retval;
+ case 5: retval = (src[0] - dest[0]);
+ if(!retval && src[0]) {
+ retval = (src[1] - dest[1]);
+ if(!retval && src[1]) {
+ retval = (src[2] - dest[2]);
+ if (!retval && src[2]) {
+ retval = (src[3] - dest[3]);
+ if (!retval && src[3])
+ retval = (src[4] - dest[4]);
+ }
+ }
+ }
+ return retval;
+ default:
+ retval = (src[0] - dest[0]);
+ if(!retval && src[0]) {
+ retval = (src[1] - dest[1]);
+ if(!retval && src[1]) {
+ retval = (src[2] - dest[2]);
+ if(!retval && src[2])
+ retval = __strncmp(src+3,dest+3,count-3);
+ }
+ }
+ return retval;
+ }
}
-extern __inline__ int memcmp(const void *cs, const void *ct, size_t count)
-{
- register int retval;
- register unsigned long tmp1, tmp2;
-
- __asm__("or %%g0, %1, %0\n\t"
- "cmp %3, 0x0\n\t"
- "ble,a 3f\n\t"
- "or %%g0, %%g0, %0\n\t"
- "1: ldub [%1], %4\n\t"
- "ldub [%2], %5\n\t"
- "cmp %4, %5\n\t"
- "be,a 2f\n\t"
- "add %1, 0x1, %1\n\t"
- "bgeu 3f\n\t"
- "or %%g0, 0x1, %0\n\t"
- "b 3f\n\t"
- "or %%g0, -1, %0\n\t"
- "2: add %3, -1, %3\n\t"
- "cmp %3, 0x0\n\t"
- "bg 1b\n\t"
- "add %2, 0x1, %2\n\t"
- "or %%g0, %%g0, %0\n\t"
- "3: " :
- "=r" (retval) :
- "r" (cs), "r" (ct), "r" (count), "r" (tmp1=0), "r" (tmp2=0));
+#undef strncmp
+#define strncmp(__arg0, __arg1, __arg2) \
+(__builtin_constant_p(__arg2) ? \
+ __constant_strncmp(__arg0, __arg1, __arg2) : \
+ __strncmp(__arg0, __arg1, __arg2))
- return retval;
-}
+#endif /* (__KERNEL__) && !(_KSYMS_INTERNEL) */
+#endif /* !(__SPARC_STRING_H__) */
diff --git a/include/asm-sparc/svr4.h b/include/asm-sparc/svr4.h
new file mode 100644
index 000000000..7eb1c3aad
--- /dev/null
+++ b/include/asm-sparc/svr4.h
@@ -0,0 +1,119 @@
+/* Solaris/SPARC constants and definitions --
+ * (C) 1996 Miguel de Icaza
+ *
+ * This file is not meant to be included by user level applications
+ * but the solaris syscall emulator
+ */
+
+#ifndef _SPARC_SVR4_H
+#define _SPARC_SVR4_H
+
+/* Signals as used by svr4 */
+typedef struct { /* signal set type */
+ ulong sigbits[4];
+} svr4_sigset_t;
+
+/* Values for siginfo.code */
+#define SVR4_SINOINFO 32767
+/* Siginfo, sucker expects bunch of information on those parameters */
+typedef union {
+ char total_size [128];
+ struct {
+ int signo;
+ int code;
+ int error;
+ union {
+ } data;
+ } siginfo;
+} svr4_siginfo_t;
+
+/* Context definition */
+
+/* Location of the user stored registers into a greg_t */
+enum {
+ SVR4_PSR, SVR4_PC, SVR4_NPC, SVR4_Y,
+ SVR4_G1, SVR4_G2, SVR4_G3, SVR4_G4,
+ SVR4_G5, SVR4_G6, SVR4_G7, SVR4_O0,
+ SVR4_O1, SVR4_O2, SVR4_O3, SVR4_O4,
+ SVR4_O5, SVR4_O6, SVR4_O7
+};
+
+/* sizeof (regs) / sizeof (greg_t), defined in the ABI */
+#define SVR4_NREGS 19
+#define SVR4_MAXWIN 31
+
+typedef struct {
+ uint rwin_lo[8];
+ uint rwin_in[8];
+} svr4_rwindow_t;
+
+typedef struct {
+ int count;
+ int *winptr [SVR4_MAXWIN]; /* pointer to the windows */
+ svr4_rwindow_t win[SVR4_MAXWIN]; /* the windows */
+} svr4_gwindows_t;
+
+typedef int svr4_gregset_t[SVR4_NREGS];
+
+typedef struct {
+ double fpu_regs[32];
+ void *fp_q;
+ unsigned fp_fsr;
+ u_char fp_nqel;
+ u_char fp_nqsize;
+ u_char inuse; /* if fpu is in use */
+} svr4_fregset_t;
+
+typedef struct {
+ uint id; /* if this holds "xrs" string => ptr is valid */
+ caddr_t ptr;
+} svr4_xrs_t;
+
+/* Machine dependant context */
+typedef struct {
+ svr4_gregset_t greg; /* registers 0..19 (see top) */
+ svr4_gwindows_t *gwin; /* may point to register windows */
+ svr4_fregset_t freg; /* floating point registers */
+ svr4_xrs_t xrs; /* mhm? */
+ long pad[19];
+} svr4_mcontext_t;
+
+/* flags for stack_t.flags */
+enum svr4_stack_flags {
+ SS_ONSTACK,
+ SVR4_SS_DISABLE,
+};
+
+/* signal stack exection place, unsupported */
+typedef struct svr4_stack_t {
+ char *sp;
+ int size;
+ int flags;
+} svr4_stack_t;
+
+/* Context used by getcontext and setcontext */
+typedef struct svr4_ucontext_t {
+ u_long flags; /* context flags, indicate what is loaded */
+ struct svr4_ucontext *link;
+ svr4_sigset_t sigmask;
+ svr4_stack_t stack;
+ svr4_mcontext_t mcontext;
+ long pad[23];
+} svr4_ucontext_t;
+
+/* windows hold the windows as they were at signal time,
+ * ucontext->mcontext holds a pointer to them.
+ * addresses for uc and si are passed as parameters to svr4 signal
+ * handler
+ */
+
+/* This is the signal frame that is passed to the signal handler */
+typedef struct {
+ svr4_gwindows_t gw; /* windows */
+ svr4_ucontext_t uc; /* machine context */
+ svr4_siginfo_t si; /* siginfo */
+} svr4_signal_frame_t;
+
+#define SVR4_SF_ALIGNED (((sizeof (svr4_signal_frame_t) + 7) & (~7)))
+
+#endif /* include control */
diff --git a/include/asm-sparc/swift.h b/include/asm-sparc/swift.h
new file mode 100644
index 000000000..c3e2ffe2d
--- /dev/null
+++ b/include/asm-sparc/swift.h
@@ -0,0 +1,94 @@
+/* swift.h: Specific definitions for the _broken_ Swift SRMMU
+ * MMU module.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_SWIFT_H
+#define _SPARC_SWIFT_H
+
+/* Swift is so brain damaged, here is the mmu control register. */
+#define SWIFT_ST 0x00800000 /* SW tablewalk enable */
+#define SWIFT_WP 0x00400000 /* Watchpoint enable */
+
+/* Branch folding (buggy, disable on production systems!) */
+#define SWIFT_BF 0x00200000
+#define SWIFT_PMC 0x00180000 /* Page mode control */
+#define SWIFT_PE 0x00040000 /* Parity enable */
+#define SWIFT_PC 0x00020000 /* Parity control */
+#define SWIFT_AP 0x00010000 /* Graphics page mode control (TCX/SX) */
+#define SWIFT_AC 0x00008000 /* Alternate Cacheability (see viking.h) */
+#define SWIFT_BM 0x00004000 /* Boot mode */
+#define SWIFT_RC 0x00003c00 /* DRAM refresh control */
+#define SWIFT_IE 0x00000200 /* Instruction cache enable */
+#define SWIFT_DE 0x00000100 /* Data cache enable */
+#define SWIFT_SA 0x00000080 /* Store Allocate */
+#define SWIFT_NF 0x00000002 /* No fault mode */
+#define SWIFT_EN 0x00000001 /* MMU enable */
+
+/* Bits [13:5] select one of 512 instruction cache tags */
+extern __inline__ void swift_inv_insn_tag(unsigned long addr)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_TXTC_TAG));
+}
+
+/* Bits [12:4] select one of 512 data cache tags */
+extern __inline__ void swift_inv_data_tag(unsigned long addr)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_DATAC_TAG));
+}
+
+extern __inline__ void swift_flush_dcache(void)
+{
+ unsigned long addr;
+
+ for(addr = 0; addr < 0x2000; addr += 0x10)
+ swift_inv_data_tag(addr);
+}
+
+extern __inline__ void swift_flush_icache(void)
+{
+ unsigned long addr;
+
+ for(addr = 0; addr < 0x4000; addr += 0x20)
+ swift_inv_insn_tag(addr);
+}
+
+extern __inline__ void swift_idflash_clear(void)
+{
+ unsigned long addr;
+
+ for(addr = 0; addr < 0x2000; addr += 0x10) {
+ swift_inv_insn_tag(addr<<1);
+ swift_inv_data_tag(addr);
+ }
+}
+
+/* Swift is so broken, it isn't even safe to use the following. */
+extern __inline__ void swift_flush_page(unsigned long page)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (page), "i" (ASI_M_FLUSH_PAGE));
+}
+
+extern __inline__ void swift_flush_segment(unsigned long addr)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_FLUSH_SEG));
+}
+
+extern __inline__ void swift_flush_region(unsigned long addr)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (addr), "i" (ASI_M_FLUSH_REGION));
+}
+
+extern __inline__ void swift_flush_context(void)
+{
+ __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
+ "i" (ASI_M_FLUSH_CTX));
+}
+
+#endif /* !(_SPARC_SWIFT_H) */
diff --git a/include/asm-sparc/sysen.h b/include/asm-sparc/sysen.h
index f72b40c67..692fa6f22 100644
--- a/include/asm-sparc/sysen.h
+++ b/include/asm-sparc/sysen.h
@@ -1,14 +1,15 @@
+/* $Id: sysen.h,v 1.3 1995/11/25 02:32:58 davem Exp $
+ * sysen.h: Bit fields within the "System Enable" register accessed via
+ * the ASI_CONTROL address space at address AC_SYSENABLE.
+ *
+ * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ */
+
#ifndef _SPARC_SYSEN_H
#define _SPARC_SYSEN_H
-/* sysen.h: Bit fields within the "System Enable" register accessed via
- the ASI_CONTROL address space at address AC_SYSENABLE.
-
- Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
-*/
-
#define SENABLE_DVMA 0x20 /* enable dvma transfers */
#define SENABLE_CACHE 0x10 /* enable VAC cache */
-#define SENABLE_RESET 0x04 /* reset the whole machine, danger Will Robinson */
+#define SENABLE_RESET 0x04 /* reset whole machine, danger Will Robinson */
#endif /* _SPARC_SYSEN_H */
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h
index 3c4a62c9a..34800571c 100644
--- a/include/asm-sparc/system.h
+++ b/include/asm-sparc/system.h
@@ -1,135 +1,250 @@
+/* $Id: system.h,v 1.42 1996/09/30 02:23:21 davem Exp $ */
#ifndef __SPARC_SYSTEM_H
#define __SPARC_SYSTEM_H
-#include <asm/segment.h>
+#include <linux/kernel.h>
-/*
- * System defines.. Note that this is included both from .c and .S
- * files, so it does only defines, not any C code.
- */
-
-/*
- * I wish the boot time image was as beautiful as the Alpha's
- * but no such luck. The icky PROM loads us at 0x0, and jumps
- * to magic address 0x4000 to start thing going. This means that
- * I can stick the pcb and user/kernel stacks in the area from
- * 0x0-0x4000 and be reasonably sure that this is sane.
- *
- * Sorry, I can't impress people with cool looking 64-bit values
- * yet. ;-)
- */
+#include <asm/segment.h>
-#include <asm/openprom.h>
+#ifdef __KERNEL__
+#include <asm/page.h>
+#include <asm/oplib.h>
#include <asm/psr.h>
+#endif
-#define INIT_PCB 0x00011fe0
-#define INIT_STACK 0x00013fe0
-#define START_ADDR 0x00004000
-#define START_SIZE (32*1024)
-#define EMPTY_PGT 0x00001000
-#define EMPTY_PGE 0x00001000
-#define ZERO_PGE 0x00001000
-
-#define IRQ_ENA_ADR 0x2000 /* This is a bitmap of all activated IRQ's
- * which is mapped in head.S during boot.
- */
+#define EMPTY_PGT (&empty_bad_page)
+#define EMPTY_PGE (&empty_bad_page_table)
#ifndef __ASSEMBLY__
-extern void wrent(void *, unsigned long);
-extern void wrkgp(unsigned long);
-extern struct linux_romvec *romvec;
+/*
+ * Sparc (general) CPU types
+ */
+enum sparc_cpu {
+ sun4 = 0x00,
+ sun4c = 0x01,
+ sun4m = 0x02,
+ sun4d = 0x03,
+ sun4e = 0x04,
+ sun4u = 0x05, /* V8 ploos ploos */
+ sun_unknown = 0x06,
+};
+
+extern enum sparc_cpu sparc_cpu_model;
+
+extern unsigned long empty_bad_page;
+extern unsigned long empty_bad_page_table;
+extern unsigned long empty_zero_page;
-#define halt() { romvec->pv_halt(); }
-#define move_to_user_mode() halt()
-#define switch_to(x) halt()
+extern struct linux_romvec *romvec;
+#define halt() romvec->pv_halt()
-#ifndef stbar /* store barrier Sparc insn to synchronize stores in PSO */
-#define stbar() __asm__ __volatile__("stbar": : :"memory")
+/* When a context switch happens we must flush all user windows so that
+ * the windows of the current process are flushed onto its stack. This
+ * way the windows are all clean for the next process and the stack
+ * frames are up to date.
+ */
+extern void flush_user_windows(void);
+extern void synchronize_user_stack(void);
+extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
+ void *fpqueue, unsigned long *fpqdepth);
+
+#ifdef __SMP__
+#define SWITCH_ENTER \
+ cli(); \
+ if(prev->flags & PF_USEDFPU) { \
+ fpsave(&prev->tss.float_regs[0], &prev->tss.fsr, \
+ &prev->tss.fpqueue[0], &prev->tss.fpqdepth); \
+ prev->flags &= ~PF_USEDFPU; \
+ prev->tss.kregs->psr &= ~PSR_EF; \
+ } \
+ prev->lock_depth = syscall_count; \
+ kernel_counter += (next->lock_depth - prev->lock_depth); \
+ syscall_count = next->lock_depth;
+
+#define SWITCH_EXIT sti();
+#define SWITCH_DO_LAZY_FPU
+#else
+#define SWITCH_ENTER
+#define SWITCH_EXIT
+#define SWITCH_DO_LAZY_FPU if(last_task_used_math != next) next->tss.kregs->psr&=~PSR_EF;
#endif
-/* Changing the PIL on the sparc is a bit hairy. I'll figure out some
- * more optimized way of doing this soon. This is bletcherous code.
+ /* Much care has gone into this code, do not touch it. */
+#define switch_to(prev, next) do { \
+ __label__ here; \
+ register unsigned long task_pc asm("o7"); \
+ SWITCH_ENTER \
+ SWITCH_DO_LAZY_FPU \
+ __asm__ __volatile__( \
+ ".globl\tflush_patch_switch\nflush_patch_switch:\n\t" \
+ "save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \
+ "save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \
+ "save %sp, -0x40, %sp\n\t" \
+ "restore; restore; restore; restore; restore; restore; restore"); \
+ if(!(next->tss.flags & SPARC_FLAG_KTHREAD) && \
+ !(next->flags & PF_EXITING)) \
+ switch_to_context(next); \
+ task_pc = ((unsigned long) &&here) - 0x8; \
+ __asm__ __volatile__( \
+ "rd\t%%psr, %%g4\n\t" \
+ "std\t%%sp, [%%g6 + %3]\n\t" \
+ "rd\t%%wim, %%g5\n\t" \
+ "wr\t%%g4, 0x20, %%psr\n\t" \
+ "std\t%%g4, [%%g6 + %2]\n\t" \
+ "mov\t%1, %%g6\n\t" \
+ "ldd\t[%%g6 + %2], %%g4\n\t" \
+ "st\t%1, [%0]\n\t" \
+ "wr\t%%g4, 0x20, %%psr\n\t" \
+ "ldd\t[%%g6 + %3], %%sp\n\t" \
+ "wr\t%%g5, 0x0, %%wim\n\t" \
+ "ldd\t[%%sp + 0x00], %%l0\n\t" \
+ "ldd\t[%%sp + 0x08], %%l2\n\t" \
+ "ldd\t[%%sp + 0x10], %%l4\n\t" \
+ "ldd\t[%%sp + 0x18], %%l6\n\t" \
+ "ldd\t[%%sp + 0x20], %%i0\n\t" \
+ "ldd\t[%%sp + 0x28], %%i2\n\t" \
+ "ldd\t[%%sp + 0x30], %%i4\n\t" \
+ "ldd\t[%%sp + 0x38], %%i6\n\t" \
+ "wr\t%%g4, 0x0, %%psr\n\t" \
+ "nop\n\t" \
+ "jmpl\t%%o7 + 0x8, %%g0\n\t" \
+ " nop\n\t" : : "r" (&(current_set[smp_processor_id()])), "r" (next), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.kpsr)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ksp)), \
+ "r" (task_pc) : "g4", "g5"); \
+here: SWITCH_EXIT } while(0)
+
+/* Changing the IRQ level on the Sparc. We now avoid writing the psr
+ * whenever possible.
*/
+extern __inline__ void setipl(unsigned long __orig_psr)
+{
+ __asm__ __volatile__("wr\t%0, 0x0, %%psr\n\t"
+ "nop; nop; nop;" : : "r" (__orig_psr) : "memory");
+}
-#define swpipl(__new_ipl) \
-({ unsigned long psr, retval; \
-__asm__ __volatile__( \
- "rd %%psr, %0\n\t" : "=&r" (psr)); \
-retval = psr; \
-psr = (psr & ~(PSR_PIL)); \
-psr |= ((__new_ipl << 8) & PSR_PIL); \
-__asm__ __volatile__( \
- "wr %0, 0x0, %%psr\n\t" \
- : : "r" (psr)); \
-retval = ((retval>>8)&15); \
-retval; })
-
-#define cli() swpipl(15) /* 15 = no int's except nmi's */
-#define sti() swpipl(0) /* I'm scared */
-#define save_flags(flags) do { flags = swpipl(15); } while (0)
-#define restore_flags(flags) swpipl(flags)
-
-#define iret() __asm__ __volatile__ ("jmp %%l1\n\t" \
- "rett %%l2\n\t": : :"memory")
-
-#define _set_gate(gate_addr,type,dpl,addr) \
-__asm__ __volatile__ ("nop\n\t")
-
-#define set_intr_gate(n,addr) \
- _set_gate(&idt[n],14,0,addr)
-
-#define set_trap_gate(n,addr) \
- _set_gate(&idt[n],15,0,addr)
+extern __inline__ void cli(void)
+{
+ unsigned long tmp;
+
+ __asm__ __volatile__("rd\t%%psr, %0\n\t"
+ "andcc\t%0, %1, %%g0\n\t"
+ "be,a\t1f\n\t"
+ " wr\t%0, %1, %%psr\n"
+ "1:\tnop; nop"
+ : "=r" (tmp)
+ : "i" (PSR_PIL)
+ : "memory");
+}
-#define set_system_gate(n,addr) \
- _set_gate(&idt[n],15,3,addr)
+extern __inline__ void sti(void)
+{
+ unsigned long tmp;
+
+ __asm__ __volatile__("rd\t%%psr, %0\n\t"
+ "andcc\t%0, %1, %%g0\n\t"
+ "bne,a\t1f\n\t"
+ " wr\t%0, %1, %%psr\n"
+ "1:\tnop; nop"
+ : "=r" (tmp)
+ : "i" (PSR_PIL)
+ : "memory");
+}
-#define set_call_gate(a,addr) \
- _set_gate(a,12,3,addr)
+extern __inline__ unsigned long getipl(void)
+{
+ unsigned long retval;
+ __asm__ __volatile__("rd\t%%psr, %0" : "=r" (retval));
+ return retval;
+}
-extern inline unsigned int get_psr(void)
+extern __inline__ unsigned long swap_pil(unsigned long __new_psr)
{
- unsigned int ret_val;
- __asm__("rd %%psr, %0\n\t" :
- "=r" (ret_val));
- return ret_val;
+ unsigned long retval, tmp1, tmp2;
+
+ __asm__ __volatile__("rd\t%%psr, %0\n\t"
+ "and\t%0, %4, %1\n\t"
+ "and\t%3, %4, %2\n\t"
+ "xorcc\t%1, %2, %%g0\n\t"
+ "bne,a\t1f\n\t"
+ " wr %0, %4, %%psr\n"
+ "1:\tnop; nop"
+ : "=r" (retval), "=r" (tmp1), "=r" (tmp2)
+ : "r" (__new_psr), "i" (PSR_PIL)
+ : "memory");
+ return retval;
}
-extern inline void put_psr(unsigned int new_psr)
+extern __inline__ unsigned long read_psr_and_cli(void)
{
- __asm__("wr %0, 0x0, %%psr\n\t" : :
- "r" (new_psr));
+ unsigned long retval;
+
+ __asm__ __volatile__("rd\t%%psr, %0\n\t"
+ "andcc\t%0, %1, %%g0\n\t"
+ "be,a\t1f\n\t"
+ " wr\t%0, %1, %%psr\n"
+ "1:\tnop; nop"
+ : "=r" (retval)
+ : "i" (PSR_PIL)
+ : "memory");
+ return retval;
}
-/* Must this be atomic? */
+extern char spdeb_buf[256];
-extern inline void *xchg_u32(int * m, unsigned long val)
-{
- unsigned long dummy;
-
- __asm__ __volatile__(
- "ld %1,%2 ! xchg_u32() is here\n\t"
- "st %0, %1\n\t"
- "or %%g0, %2, %0"
- : "=r" (val), "=m" (*m), "=r" (dummy)
- : "0" (val));
- return (void *) val;
-}
+#define save_flags(flags) ((flags) = getipl())
+#define save_and_cli(flags) ((flags) = read_psr_and_cli())
+#define restore_flags(flags) setipl((flags))
+/* XXX Change this if we ever use a PSO mode kernel. */
+#define mb() __asm__ __volatile__ ("" : : : "memory")
-/* pointers are 32 bits on the sparc (at least the v8, and they'll work
- * on the V9 none the less). I don't need the xchg_u64 routine for now.
- */
+#define nop() __asm__ __volatile__ ("nop");
-extern inline void *xchg_ptr(void *m, void *val)
+extern __inline__ unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
{
- return (void *) xchg_u32((int *) m, (unsigned long) val);
+ __asm__ __volatile__("
+ rd %%psr, %%g3
+ andcc %%g3, %3, %%g0
+ be,a 1f
+ wr %%g3, %3, %%psr
+1: ld [%1], %%g2
+ andcc %%g3, %3, %%g0
+ st %2, [%1]
+ be,a 1f
+ wr %%g3, 0x0, %%psr
+1: nop
+ mov %%g2, %0
+ "
+ : "=&r" (val)
+ : "r" (m), "0" (val), "i" (PSR_PIL)
+ : "g2", "g3");
+
+ return val;
}
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define tas(ptr) (xchg((ptr),1))
+
+extern void __xchg_called_with_bad_pointer(void);
+static __inline__ unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
+{
+ switch (size) {
+ case 4:
+ return xchg_u32(ptr, x);
+ };
+ __xchg_called_with_bad_pointer();
+ return x;
+}
#endif /* __ASSEMBLY__ */
-#endif
+/*
+ * Reset the machine.
+ */
+extern void hard_reset_now(void);
+
+#endif /* !(__SPARC_SYSTEM_H) */
diff --git a/include/asm-sparc/termbits.h b/include/asm-sparc/termbits.h
new file mode 100644
index 000000000..9a078c619
--- /dev/null
+++ b/include/asm-sparc/termbits.h
@@ -0,0 +1,208 @@
+#ifndef _SPARC_TERMBITS_H
+#define _SPARC_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned long tcflag_t;
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+#define NCCS 17
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+#ifdef __KERNEL__
+#define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t))
+ cc_t _x_cc[2]; /* We need them to hold vmin/vtime */
+#endif
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VEOL 5
+#define VEOL2 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+
+
+
+#define VSUSP 10
+#define VDSUSP 11 /* SunOS POSIX nicety I do believe... */
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+
+/* Kernel keeps vmin/vtime separated, user apps assume vmin/vtime is
+ * shared with eof/eol
+ */
+#ifdef __KERNEL__
+#define VMIN 16
+#define VTIME 17
+#else
+#define VMIN VEOF
+#define VTIME VEOL
+#endif
+
+/* c_iflag bits */
+#define IGNBRK 0x00000001
+#define BRKINT 0x00000002
+#define IGNPAR 0x00000004
+#define PARMRK 0x00000008
+#define INPCK 0x00000010
+#define ISTRIP 0x00000020
+#define INLCR 0x00000040
+#define IGNCR 0x00000080
+#define ICRNL 0x00000100
+#define IUCLC 0x00000200
+#define IXON 0x00000400
+#define IXANY 0x00000800
+#define IXOFF 0x00001000
+#define IMAXBEL 0x00002000
+
+/* c_oflag bits */
+#define OPOST 0x00000001
+#define OLCUC 0x00000002
+#define ONLCR 0x00000004
+#define OCRNL 0x00000008
+#define ONOCR 0x00000010
+#define ONLRET 0x00000020
+#define OFILL 0x00000040
+#define OFDEL 0x00000080
+#define NLDLY 0x00000100
+#define NL0 0x00000000
+#define NL1 0x00000100
+#define CRDLY 0x00000600
+#define CR0 0x00000000
+#define CR1 0x00000200
+#define CR2 0x00000400
+#define CR3 0x00000600
+#define TABDLY 0x00001800
+#define TAB0 0x00000000
+#define TAB1 0x00000800
+#define TAB2 0x00001000
+#define TAB3 0x00001800
+#define XTABS 0x00001800
+#define BSDLY 0x00002000
+#define BS0 0x00000000
+#define BS1 0x00002000
+#define VTDLY 0x00004000
+#define VT0 0x00000000
+#define VT1 0x00004000
+#define FFDLY 0x00008000
+#define FF0 0x00000000
+#define FF1 0x00008000
+#define PAGEOUT 0x00010000 /* SUNOS specific */
+#define WRAP 0x00020000 /* SUNOS specific */
+
+/* c_cflag bit meaning */
+#define CBAUD 0x0000000f
+#define B0 0x00000000 /* hang up */
+#define B50 0x00000001
+#define B75 0x00000002
+#define B110 0x00000003
+#define B134 0x00000004
+#define B150 0x00000005
+#define B200 0x00000006
+#define B300 0x00000007
+#define B600 0x00000008
+#define B1200 0x00000009
+#define B1800 0x0000000a
+#define B2400 0x0000000b
+#define B4800 0x0000000c
+#define B9600 0x0000000d
+#define B19200 0x0000000e
+#define B38400 0x0000000f
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0x00000030
+#define CS5 0x00000000
+#define CS6 0x00000010
+#define CS7 0x00000020
+#define CS8 0x00000030
+#define CSTOPB 0x00000040
+#define CREAD 0x00000080
+#define PARENB 0x00000100
+#define PARODD 0x00000200
+#define HUPCL 0x00000400
+#define CLOCAL 0x00000800
+/* We'll never see these speeds with the Zilogs' but for completeness... */
+#define CBAUDEX 0x00010000
+#define B57600 0x00010001
+#define B115200 0x00010002
+#define B230400 0x00010003
+#define B460800 0x00010004
+#define CIBAUD 0x000f0000 /* input baud rate (not used) */
+#define CRTSCTS 0x80000000 /* flow control */
+
+/* c_lflag bits */
+#define ISIG 0x00000001
+#define ICANON 0x00000002
+#define XCASE 0x00000004
+#define ECHO 0x00000008
+#define ECHOE 0x00000010
+#define ECHOK 0x00000020
+#define ECHONL 0x00000040
+#define NOFLSH 0x00000080
+#define TOSTOP 0x00000100
+#define ECHOCTL 0x00000200
+#define ECHOPRT 0x00000400
+#define ECHOKE 0x00000800
+#define DEFECHO 0x00001000 /* SUNOS thing, what is it? */
+#define FLUSHO 0x00002000
+#define PENDIN 0x00004000
+#define IEXTEN 0x00008000
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#endif /* !(_SPARC_TERMBITS_H) */
diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h
new file mode 100644
index 000000000..e2991ecf7
--- /dev/null
+++ b/include/asm-sparc/termios.h
@@ -0,0 +1,168 @@
+/* $Id: termios.h,v 1.20 1996/10/31 00:59:54 davem Exp $ */
+#ifndef _SPARC_TERMIOS_H
+#define _SPARC_TERMIOS_H
+
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
+
+#if defined(__KERNEL__) || defined(__DEFINE_BSD_TERMIOS)
+struct sgttyb {
+ char sg_ispeed;
+ char sg_ospeed;
+ char sg_erase;
+ char sg_kill;
+ short sg_flags;
+};
+
+struct tchars {
+ char t_intrc;
+ char t_quitc;
+ char t_startc;
+ char t_stopc;
+ char t_eofc;
+ char t_brkc;
+};
+
+struct ltchars {
+ char t_suspc;
+ char t_dsuspc;
+ char t_rprntc;
+ char t_flushc;
+ char t_werasc;
+ char t_lnextc;
+};
+#endif /* __KERNEL__ */
+
+struct sunos_ttysize {
+ int st_lines; /* Lines on the terminal */
+ int st_columns; /* Columns on the terminal */
+};
+
+/* Used for packet mode */
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+/* line disciplines */
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+
+#ifdef __KERNEL__
+
+/*
+ * c_cc characters in the termio structure. Oh, how I love being
+ * backwardly compatible. Notice that character 4 and 5 are
+ * interpreted differently depending on whether ICANON is set in
+ * c_lflag. If it's set, they are used as _VEOF and _VEOL, otherwise
+ * as _VMIN and V_TIME. This is for compatibility with OSF/1 (which
+ * is compatible with sysV)...
+ */
+#define _VMIN 4
+#define _VTIME 5
+
+
+#include <linux/string.h>
+
+/* intr=^C quit=^\ erase=del kill=^U
+ eof=^D eol=\0 eol2=\0 sxtc=\0
+ start=^Q stop=^S susp=^Z dsusp=^Y
+ reprint=^R discard=^U werase=^W lnext=^V
+ vmin=\1 vtime=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\000\000\000\021\023\032\031\022\025\027\026\001\000"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+extern __inline__ void trans_from_termio(struct termio * termio,
+ struct termios * termios)
+{
+#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y))
+ SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
+ SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
+ SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
+ SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
+#undef SET_LOW_BITS
+ memcpy (termios->c_cc, termio->c_cc, NCC);
+}
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ *
+ * Note the "fun" _VMIN overloading.
+ */
+extern __inline__ void trans_to_termio(struct termios * termios,
+ struct termio * termio)
+{
+ termio->c_iflag = termios->c_iflag;
+ termio->c_oflag = termios->c_oflag;
+ termio->c_cflag = termios->c_cflag;
+ termio->c_lflag = termios->c_lflag;
+ termio->c_line = termios->c_line;
+ memcpy(termio->c_cc, termios->c_cc, NCC);
+ if (!(termios->c_lflag & ICANON)) {
+ termio->c_cc[_VMIN] = termios->c_cc[VMIN];
+ termio->c_cc[_VTIME] = termios->c_cc[VTIME];
+ }
+}
+
+/* Note that in this case DEST is a user buffer and thus the checking
+ * and this ugly macro to avoid header file problems.
+ */
+#define termios_to_userland(d, s) \
+do { \
+ struct termios *dest = (d); \
+ struct termios *source = (s); \
+ put_user(source->c_iflag, &dest->c_iflag); \
+ put_user(source->c_oflag, &dest->c_oflag); \
+ put_user(source->c_cflag, &dest->c_cflag); \
+ put_user(source->c_lflag, &dest->c_lflag); \
+ put_user(source->c_line, &dest->c_line); \
+ copy_to_user(dest->c_cc, source->c_cc, NCCS); \
+ if (!(source->c_lflag & ICANON)){ \
+ put_user(source->c_cc[VMIN], &dest->c_cc[_VMIN]); \
+ put_user(source->c_cc[VTIME], &dest->c_cc[_VTIME]); \
+ } else { \
+ put_user(source->c_cc[VEOF], &dest->c_cc[VEOF]); \
+ put_user(source->c_cc[VEOL], &dest->c_cc[VEOL]); \
+ } \
+} while(0)
+
+/* termios to termios handling SunOS overloading of eof,eol/vmin,vtime
+ * In this case we are only working with kernel buffers so direct
+ * accesses are ok.
+ */
+extern __inline__ void termios_from_userland(struct termios * source,
+ struct termios * dest)
+{
+ dest->c_iflag = source->c_iflag;
+ dest->c_oflag = source->c_oflag;
+ dest->c_cflag = source->c_cflag;
+ dest->c_lflag = source->c_lflag;
+ dest->c_line = source->c_line;
+ memcpy(dest->c_cc, source->c_cc, NCCS);
+ if (dest->c_lflag & ICANON){
+ dest->c_cc [VEOF] = source->c_cc [VEOF];
+ dest->c_cc [VEOL] = source->c_cc [VEOL];
+ } else {
+ dest->c_cc[VMIN] = source->c_cc[_VMIN];
+ dest->c_cc[VTIME] = source->c_cc[_VTIME];
+ }
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _SPARC_TERMIOS_H */
diff --git a/include/asm-sparc/timer.h b/include/asm-sparc/timer.h
new file mode 100644
index 000000000..3820794e7
--- /dev/null
+++ b/include/asm-sparc/timer.h
@@ -0,0 +1,82 @@
+/* $Id: timer.h,v 1.13 1996/08/29 09:48:59 davem Exp $
+ * timer.h: Definitions for the timer chips on the Sparc.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_TIMER_H
+#define _SPARC_TIMER_H
+
+#include <asm/system.h> /* For NCPUS */
+
+/* Timer structures. The interrupt timer has two properties which
+ * are the counter (which is handled in do_timer in sched.c) and the limit.
+ * This limit is where the timer's counter 'wraps' around. Oddly enough,
+ * the sun4c timer when it hits the limit wraps back to 1 and not zero
+ * thus when calculating the value at which it will fire a microsecond you
+ * must adjust by one. Thanks SUN for designing such great hardware ;(
+ */
+
+/* Note that I am only going to use the timer that interrupts at
+ * Sparc IRQ 10. There is another one available that can fire at
+ * IRQ 14. Currently it is left untouched, we keep the PROM's limit
+ * register value and let the prom take these interrupts. This allows
+ * L1-A to work.
+ */
+
+struct sun4c_timer_info {
+ __volatile__ unsigned int cur_count10;
+ __volatile__ unsigned int timer_limit10;
+ __volatile__ unsigned int cur_count14;
+ __volatile__ unsigned int timer_limit14;
+};
+
+#define SUN4C_TIMER_PHYSADDR 0xf3000000
+
+/* A sun4m has two blocks of registers which are probably of the same
+ * structure. LSI Logic's L64851 is told to _decrement_ from the limit
+ * value. Aurora behaves similarly but its limit value is compacted in
+ * other fashion (it's wider). Documented fields are defined here.
+ */
+
+/* As with the interrupt register, we have two classes of timer registers
+ * which are per-cpu and master. Per-cpu timers only hit that cpu and are
+ * only level 14 ticks, master timer hits all cpus and is level 10.
+ */
+
+#define SUN4M_PRM_CNT_L 0x80000000
+#define SUN4M_PRM_CNT_LVALUE 0x7FFFFC00
+
+struct sun4m_timer_percpu_info {
+ __volatile__ unsigned int l14_timer_limit; /* Initial value is 0x009c4000 */
+ __volatile__ unsigned int l14_cur_count;
+
+ /* This register appears to be write only and/or inaccessible
+ * on Uni-Processor sun4m machines.
+ */
+ __volatile__ unsigned int l14_limit_noclear; /* Data access error is here */
+
+ __volatile__ unsigned int cntrl; /* =1 after POST on Aurora */
+ __volatile__ unsigned char space[PAGE_SIZE - 16];
+};
+
+struct sun4m_timer_regs {
+ struct sun4m_timer_percpu_info cpu_timers[NCPUS];
+ volatile unsigned int l10_timer_limit;
+ volatile unsigned int l10_cur_count;
+
+ /* Again, this appears to be write only and/or inaccessible
+ * on uni-processor sun4m machines.
+ */
+ volatile unsigned int l10_limit_noclear;
+
+ /* This register too, it must be magic. */
+ volatile unsigned int foobar;
+
+ volatile unsigned int cfg; /* equals zero at boot time... */
+};
+
+extern struct sun4m_timer_regs *sun4m_timers;
+extern __volatile__ unsigned int *master_l10_counter;
+extern __volatile__ unsigned int *master_l10_limit;
+
+#endif /* !(_SPARC_TIMER_H) */
diff --git a/include/asm-sparc/traps.h b/include/asm-sparc/traps.h
new file mode 100644
index 000000000..3a3940df2
--- /dev/null
+++ b/include/asm-sparc/traps.h
@@ -0,0 +1,159 @@
+/* $Id: traps.h,v 1.8 1996/05/17 10:38:53 davem Exp $
+ * traps.h: Format of entries for the Sparc trap table.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_TRAPS_H
+#define _SPARC_TRAPS_H
+
+#define NUM_SPARC_TRAPS 255
+
+#ifndef __ASSEMBLY__
+
+/* This is for V8 and V9 compliant Sparc CPUS */
+struct tt_entry {
+ unsigned long inst_one;
+ unsigned long inst_two;
+ unsigned long inst_three;
+ unsigned long inst_four;
+};
+
+/* We set this to _start in system setup. */
+extern struct tt_entry *sparc_ttable;
+
+/* This for V9 compliant Sparc CPUS */
+struct tt_v9_entry {
+ unsigned long inst_one;
+ unsigned long inst_two;
+ unsigned long inst_three;
+ unsigned long inst_four;
+ unsigned long inst_five;
+ unsigned long inst_six;
+ unsigned long inst_seven;
+ unsigned long inst_eight;
+};
+
+/* V9 has multiple trap tables, which one is used depends
+ * upon how deep within multiple traps you are.
+ * I believe the UltraSparc supports two levels now.
+ */
+extern struct tt_v9_entry *sparc_v9_ttablel0;
+extern struct tt_v9_entry *sparc_v9_ttablel1;
+
+extern __inline__ unsigned long get_tbr(void)
+{
+ unsigned long tbr;
+
+ __asm__ __volatile__("rd %%tbr, %0\n\t" : "=r" (tbr));
+ return tbr;
+}
+
+#endif /* !(__ASSEMBLY__) */
+
+/* For patching the trap table at boot time, we need to know how to
+ * form various common Sparc instructions. Thus these macros...
+ */
+
+#define SPARC_MOV_CONST_L3(const) (0xa6102000 | (const&0xfff))
+
+/* The following assumes that the branch lies before the place we
+ * are branching to. This is the case for a trap vector...
+ * You have been warned.
+ */
+#define SPARC_BRANCH(dest_addr, inst_addr) \
+ (0x10800000 | (((dest_addr-inst_addr)>>2)&0x3fffff))
+
+#define SPARC_RD_PSR_L0 (0xa1480000)
+#define SPARC_RD_WIM_L3 (0xa7500000)
+#define SPARC_NOP (0x01000000)
+
+/* Various interesting trap levels. */
+/* First, hardware traps. */
+#define SP_TRAP_TFLT 0x1 /* Text fault */
+#define SP_TRAP_II 0x2 /* Illegal Instruction */
+#define SP_TRAP_PI 0x3 /* Privileged Instruction */
+#define SP_TRAP_FPD 0x4 /* Floating Point Disabled */
+#define SP_TRAP_WOVF 0x5 /* Window Overflow */
+#define SP_TRAP_WUNF 0x6 /* Window Underflow */
+#define SP_TRAP_MNA 0x7 /* Memory Address Unaligned */
+#define SP_TRAP_FPE 0x8 /* Floating Point Exception */
+#define SP_TRAP_DFLT 0x9 /* Data Fault */
+#define SP_TRAP_TOF 0xa /* Tag Overflow */
+#define SP_TRAP_WDOG 0xb /* Watchpoint Detected */
+#define SP_TRAP_IRQ1 0x11 /* IRQ level 1 */
+#define SP_TRAP_IRQ2 0x12 /* IRQ level 2 */
+#define SP_TRAP_IRQ3 0x13 /* IRQ level 3 */
+#define SP_TRAP_IRQ4 0x14 /* IRQ level 4 */
+#define SP_TRAP_IRQ5 0x15 /* IRQ level 5 */
+#define SP_TRAP_IRQ6 0x16 /* IRQ level 6 */
+#define SP_TRAP_IRQ7 0x17 /* IRQ level 7 */
+#define SP_TRAP_IRQ8 0x18 /* IRQ level 8 */
+#define SP_TRAP_IRQ9 0x19 /* IRQ level 9 */
+#define SP_TRAP_IRQ10 0x1a /* IRQ level 10 */
+#define SP_TRAP_IRQ11 0x1b /* IRQ level 11 */
+#define SP_TRAP_IRQ12 0x1c /* IRQ level 12 */
+#define SP_TRAP_IRQ13 0x1d /* IRQ level 13 */
+#define SP_TRAP_IRQ14 0x1e /* IRQ level 14 */
+#define SP_TRAP_IRQ15 0x1f /* IRQ level 15 Non-maskable */
+#define SP_TRAP_RACC 0x20 /* Register Access Error ??? */
+#define SP_TRAP_IACC 0x21 /* Instruction Access Error */
+#define SP_TRAP_CPDIS 0x24 /* Co-Processor Disabled */
+#define SP_TRAP_BADFL 0x25 /* Unimplemented Flush Instruction */
+#define SP_TRAP_CPEXP 0x28 /* Co-Processor Exception */
+#define SP_TRAP_DACC 0x29 /* Data Access Error */
+#define SP_TRAP_DIVZ 0x2a /* Divide By Zero */
+#define SP_TRAP_DSTORE 0x2b /* Data Store Error ??? */
+#define SP_TRAP_DMM 0x2c /* Data Access MMU Miss ??? */
+#define SP_TRAP_IMM 0x3c /* Instruction Access MMU Miss ??? */
+
+/* Now the Software Traps... */
+#define SP_TRAP_SUNOS 0x80 /* SunOS System Call */
+#define SP_TRAP_SBPT 0x81 /* Software Breakpoint */
+#define SP_TRAP_SDIVZ 0x82 /* Software Divide-by-Zero trap */
+#define SP_TRAP_FWIN 0x83 /* Flush Windows */
+#define SP_TRAP_CWIN 0x84 /* Clean Windows */
+#define SP_TRAP_RCHK 0x85 /* Range Check */
+#define SP_TRAP_FUNA 0x86 /* Fix Unaligned Access */
+#define SP_TRAP_IOWFL 0x87 /* Integer Overflow */
+#define SP_TRAP_SOLARIS 0x88 /* Solaris System Call */
+#define SP_TRAP_NETBSD 0x89 /* NetBSD System Call */
+#define SP_TRAP_LINUX 0x90 /* Linux System Call */
+
+/* Names used for compatibility with SunOS */
+#define ST_SYSCALL 0x00
+#define ST_BREAKPOINT 0x01
+#define ST_DIV0 0x02
+#define ST_FLUSH_WINDOWS 0x03
+#define ST_CLEAN_WINDOWS 0x04
+#define ST_RANGE_CHECK 0x05
+#define ST_FIX_ALIGN 0x06
+#define ST_INT_OVERFLOW 0x07
+
+/* Special traps... */
+#define SP_TRAP_KBPT1 0xfe /* KADB/PROM Breakpoint one */
+#define SP_TRAP_KBPT2 0xff /* KADB/PROM Breakpoint two */
+
+/* Handy Macros */
+/* Is this a trap we never expect to get? */
+#define BAD_TRAP_P(level) \
+ ((level > SP_TRAP_WDOG && level < SP_TRAP_IRQ1) || \
+ (level > SP_TRAP_IACC && level < SP_TRAP_CPDIS) || \
+ (level > SP_TRAP_BADFL && level < SP_TRAP_CPEXP) || \
+ (level > SP_TRAP_DMM && level < SP_TRAP_IMM) || \
+ (level > SP_TRAP_IMM && level < SP_TRAP_SUNOS) || \
+ (level > SP_TRAP_LINUX && level < SP_TRAP_KBPT1))
+
+/* Is this a Hardware trap? */
+#define HW_TRAP_P(level) ((level > 0) && (level < SP_TRAP_SUNOS))
+
+/* Is this a Software trap? */
+#define SW_TRAP_P(level) ((level >= SP_TRAP_SUNOS) && (level <= SP_TRAP_KBPT2))
+
+/* Is this a system call for some OS we know about? */
+#define SCALL_TRAP_P(level) ((level == SP_TRAP_SUNOS) || \
+ (level == SP_TRAP_SOLARIS) || \
+ (level == SP_TRAP_NETBSD) || \
+ (level == SP_TRAP_LINUX))
+
+#endif /* !(_SPARC_TRAPS_H) */
diff --git a/include/asm-sparc/tsunami.h b/include/asm-sparc/tsunami.h
new file mode 100644
index 000000000..384ea6e68
--- /dev/null
+++ b/include/asm-sparc/tsunami.h
@@ -0,0 +1,60 @@
+/* $Id: tsunami.h,v 1.5 1996/08/29 09:49:03 davem Exp $
+ * tsunami.h: Module specific definitions for Tsunami V8 Sparcs
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_TSUNAMI_H
+#define _SPARC_TSUNAMI_H
+
+#include <asm/asi.h>
+
+/* The MMU control register on the Tsunami:
+ *
+ * -----------------------------------------------------------------------
+ * | implvers |SW|AV|DV|MV| RSV |PC|ITD|ALC| RSV |PE| RC |IE|DE|RSV|NF|ME|
+ * -----------------------------------------------------------------------
+ * 31 24 23 22 21 20 19-18 17 16 14 13-12 11 10-9 8 7 6-2 1 0
+ *
+ * SW: Enable Software Table Walks 0=off 1=on
+ * AV: Address View bit
+ * DV: Data View bit
+ * MV: Memory View bit
+ * PC: Parity Control
+ * ITD: ITBR disable
+ * ALC: Alternate Cacheable
+ * PE: Parity Enable 0=off 1=on
+ * RC: Refresh Control
+ * IE: Instruction cache Enable 0=off 1=on
+ * DE: Data cache Enable 0=off 1=on
+ * NF: No Fault, same as all other SRMMUs
+ * ME: MMU Enable, same as all other SRMMUs
+ */
+
+#define TSUNAMI_SW 0x00800000
+#define TSUNAMI_AV 0x00400000
+#define TSUNAMI_DV 0x00200000
+#define TSUNAMI_MV 0x00100000
+#define TSUNAMI_PC 0x00020000
+#define TSUNAMI_ITD 0x00010000
+#define TSUNAMI_ALC 0x00008000
+#define TSUNAMI_PE 0x00001000
+#define TSUNAMI_RCMASK 0x00000C00
+#define TSUNAMI_IENAB 0x00000200
+#define TSUNAMI_DENAB 0x00000100
+#define TSUNAMI_NF 0x00000002
+#define TSUNAMI_ME 0x00000001
+
+extern __inline__ void tsunami_flush_icache(void)
+{
+ __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
+ "i" (ASI_M_IC_FLCLEAR) : "memory");
+}
+
+extern __inline__ void tsunami_flush_dcache(void)
+{
+ __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
+ "i" (ASI_M_DC_FLCLEAR) : "memory");
+}
+
+#endif /* !(_SPARC_TSUNAMI_H) */
diff --git a/include/asm-sparc/types.h b/include/asm-sparc/types.h
index c7b65be7a..d8334325a 100644
--- a/include/asm-sparc/types.h
+++ b/include/asm-sparc/types.h
@@ -1,62 +1,46 @@
+/* $Id: types.h,v 1.10 1996/08/29 09:49:04 davem Exp $ */
#ifndef _SPARC_TYPES_H
#define _SPARC_TYPES_H
/*
* _xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space <-- Linus sez this
+ * header files exported to user space.
*/
-/* NOTE: I will have to change these when the V9 sparcs come into play,
- * however this won't be for a while.
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue. However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
*/
-#ifndef _SIZE_T
-#define _SIZE_T
-#ifdef __svr4__
-typedef unsigned int size_t; /* solaris sucks */
-#else
-typedef long unsigned int size_t; /* sunos is much better */
-#endif /* !(__svr4__) */
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef int ssize_t;
-#endif
-
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef int ptrdiff_t;
-#endif
+typedef unsigned short umode_t;
-typedef signed char __s8;
+typedef __signed__ char __s8;
typedef unsigned char __u8;
-typedef signed short __s16;
+typedef __signed__ short __s16;
typedef unsigned short __u16;
-typedef signed int __s32;
+typedef __signed__ int __s32;
typedef unsigned int __u32;
-/* Only 32-bit sparcs for now so.... */
-
-typedef signed long long __s64;
+typedef __signed__ long long __s64;
typedef unsigned long long __u64;
#ifdef __KERNEL__
-typedef signed char s8;
+typedef __signed__ char s8;
typedef unsigned char u8;
-typedef signed short s16;
+typedef __signed__ short s16;
typedef unsigned short u16;
-typedef signed int s32;
+typedef __signed__ int s32;
typedef unsigned int u32;
-/* Again, only have to worry about 32-bits */
-
-typedef signed long long s64;
+typedef __signed__ long long s64;
typedef unsigned long long u64;
#endif /* __KERNEL__ */
diff --git a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h
new file mode 100644
index 000000000..53eb75cae
--- /dev/null
+++ b/include/asm-sparc/uaccess.h
@@ -0,0 +1,261 @@
+/* $Id: uaccess.h,v 1.2 1996/10/31 00:59:56 davem Exp $ */
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+
+#ifdef __KERNEL__
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <asm/vac-ops.h>
+#endif
+
+#ifndef __ASSEMBLY__
+
+/* Sparc is not segmented, however we need to be able to fool verify_area()
+ * when doing system calls from kernel mode legitimately.
+ *
+ * "For historical reasons, these macros are grossly misnamed." -Linus
+ */
+#define KERNEL_DS 0
+#define USER_DS 1
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+#define get_fs() (current->tss.current_ds)
+#define get_ds() (KERNEL_DS)
+#define set_fs(val) ((current->tss.current_ds) = (val))
+
+#define __user_ok(addr,size) (((size) <= page_offset)&&((addr) <= page_offset-(size)))
+#define __kernel_ok (get_fs() == KERNEL_DS)
+#define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size)))
+#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+ return access_ok(type,addr,size)?0:-EFAULT;
+}
+
+/* Uh, these should become the main single-value transfer routines..
+ * They automatically use the right size if we just have the right
+ * pointer type..
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the uglyness from the user.
+ */
+#define put_user(x,ptr) ({ \
+unsigned long __pu_addr = (unsigned long)(ptr); \
+__put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
+
+#define get_user(x,ptr) ({ \
+unsigned long __gu_addr = (unsigned long)(ptr); \
+__get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
+
+/*
+ * The "__xxx" versions do not do address space checking, useful when
+ * doing multiple accesses to the same area (the user has to do the
+ * checks by hand with "access_ok()")
+ */
+#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr)))
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) ((struct __large_struct *)(x))
+
+#define __put_user_check(x,addr,size) ({ \
+register int __pu_ret asm("g1"); \
+__pu_ret = -EFAULT; \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __put_user_8(x,addr,__pu_ret); break; \
+case 2: __put_user_16(x,addr,__pu_ret); break; \
+case 4: __put_user_32(x,addr,__pu_ret); break; \
+default: __pu_ret = __put_user_bad(); break; \
+} } __pu_ret; })
+
+#define __put_user_nocheck(x,addr,size) ({ \
+register int __pu_ret asm("g1"); \
+__pu_ret = -EFAULT; \
+switch (size) { \
+case 1: __put_user_8(x,addr,__pu_ret); break; \
+case 2: __put_user_16(x,addr,__pu_ret); break; \
+case 4: __put_user_32(x,addr,__pu_ret); break; \
+default: __pu_ret = __put_user_bad(); break; \
+} __pu_ret; })
+
+#define __put_user_8(x,addr,ret) \
+__asm__ __volatile( \
+ "/* Put user 8, inline. */\n\t" \
+ "ld [%%g6 + %3], %%g2\n\t" \
+ "set 1f, %0\n\t" \
+ "add %%g2, 1, %%g3\n\t" \
+ "st %0, [%%g6 + %4]\n\t" \
+ "st %%g3, [%%g6 + %3]\n\t" \
+ "stb %1, [%2]\n\t" \
+ "mov 0, %0\n\t" \
+ "st %%g2, [%%g6 + %3]\n" \
+"1:\n" : "=&r" (ret) : "r" (x), "r" (__m(addr)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.count)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.expc)) \
+ : "g2", "g3")
+
+#define __put_user_16(x,addr,ret) \
+__asm__ __volatile( \
+ "/* Put user 16, inline. */\n\t" \
+ "ld [%%g6 + %3], %%g2\n\t" \
+ "set 1f, %0\n\t" \
+ "add %%g2, 1, %%g3\n\t" \
+ "st %0, [%%g6 + %4]\n\t" \
+ "st %%g3, [%%g6 + %3]\n\t" \
+ "sth %1, [%2]\n\t" \
+ "mov 0, %0\n\t" \
+ "st %%g2, [%%g6 + %3]\n" \
+"1:\n" : "=&r" (ret) : "r" (x), "r" (__m(addr)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.count)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.expc)) \
+ : "g2", "g3")
+
+#define __put_user_32(x,addr,ret) \
+__asm__ __volatile( \
+ "/* Put user 32, inline. */\n\t" \
+ "ld [%%g6 + %3], %%g2\n\t" \
+ "set 1f, %0\n\t" \
+ "add %%g2, 1, %%g3\n\t" \
+ "st %0, [%%g6 + %4]\n\t" \
+ "st %%g3, [%%g6 + %3]\n\t" \
+ "st %1, [%2]\n\t" \
+ "mov 0, %0\n\t" \
+ "st %%g2, [%%g6 + %3]\n" \
+"1:\n" : "=&r" (ret) : "r" (x), "r" (__m(addr)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.count)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.expc)) \
+ : "g2", "g3")
+
+extern int __put_user_bad(void);
+
+#define __get_user_check(x,addr,size,type) ({ \
+register int __gu_ret asm("g1"); \
+register unsigned long __gu_val = 0; \
+__gu_ret = -EFAULT; \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __get_user_8(__gu_val,addr,__gu_ret); break; \
+case 2: __get_user_16(__gu_val,addr,__gu_ret); break; \
+case 4: __get_user_32(__gu_val,addr,__gu_ret); break; \
+default: __gu_ret = __get_user_bad(); break; \
+} } x = (type) __gu_val; __gu_ret; })
+
+#define __get_user_nocheck(x,addr,size,type) ({ \
+register int __gu_ret asm("g1"); \
+register unsigned long __gu_val = 0; \
+__gu_ret = -EFAULT; \
+switch (size) { \
+case 1: __get_user_8(__gu_val,addr,__gu_ret); break; \
+case 2: __get_user_16(__gu_val,addr,__gu_ret); break; \
+case 4: __get_user_32(__gu_val,addr,__gu_ret); break; \
+default: __gu_ret = __get_user_bad(); break; \
+} x = (type) __gu_val; __gu_ret; })
+
+#define __get_user_8(x,addr,ret) \
+__asm__ __volatile__( \
+ "/* Get user 8, inline. */\n\t" \
+ "ld [%%g6 + %3], %%g2\n\t" \
+ "set 1f, %0\n\t" \
+ "add %%g2, 1, %%g3\n\t" \
+ "st %0, [%%g6 + %4]\n\t" \
+ "st %%g3, [%%g6 + %3]\n\t" \
+ "ldub [%2], %1\n\t" \
+ "mov 0, %0\n\t" \
+ "st %%g2, [%%g6 + %3]\n" \
+"1:\n" : "=&r" (ret), "=&r" (x) : "r" (__m(addr)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.count)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.expc)) \
+ : "g2", "g3")
+
+#define __get_user_16(x,addr,ret) \
+__asm__ __volatile__( \
+ "/* Get user 16, inline. */\n\t" \
+ "ld [%%g6 + %3], %%g2\n\t" \
+ "set 1f, %0\n\t" \
+ "add %%g2, 1, %%g3\n\t" \
+ "st %0, [%%g6 + %4]\n\t" \
+ "st %%g3, [%%g6 + %3]\n\t" \
+ "lduh [%2], %1\n\t" \
+ "mov 0, %0\n\t" \
+ "st %%g2, [%%g6 + %3]\n" \
+"1:\n" : "=&r" (ret), "=&r" (x) : "r" (__m(addr)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.count)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.expc)) \
+ : "g2", "g3")
+
+#define __get_user_32(x,addr,ret) \
+__asm__ __volatile__( \
+ "/* Get user 32, inline. */\n\t" \
+ "ld [%%g6 + %3], %%g2\n\t" \
+ "set 1f, %0\n\t" \
+ "add %%g2, 1, %%g3\n\t" \
+ "st %0, [%%g6 + %4]\n\t" \
+ "st %%g3, [%%g6 + %3]\n\t" \
+ "ld [%2], %1\n\t" \
+ "mov 0, %0\n\t" \
+ "st %%g2, [%%g6 + %3]\n" \
+"1:\n" : "=&r" (ret), "=&r" (x) : "r" (__m(addr)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.count)), \
+ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.expc)) \
+ : "g2", "g3")
+
+extern int __get_user_bad(void);
+
+extern int __copy_to_user(unsigned long to, unsigned long from, int size);
+extern int __copy_from_user(unsigned long to, unsigned long from, int size);
+
+#define copy_to_user(to,from,n) ({ \
+unsigned long __copy_to = (unsigned long) (to); \
+unsigned long __copy_size = (unsigned long) (n); \
+unsigned long __copy_res; \
+if(__copy_size && __access_ok(__copy_to, __copy_size)) { \
+__copy_res = __copy_to_user(__copy_to, (unsigned long) (from), __copy_size); \
+if(__copy_res) __copy_res = __copy_size - __copy_res; \
+} else __copy_res = __copy_size; \
+__copy_res; })
+
+#define copy_from_user(to,from,n) ({ \
+unsigned long __copy_from = (unsigned long) (from); \
+unsigned long __copy_size = (unsigned long) (n); \
+unsigned long __copy_res; \
+if(__copy_size && __access_ok(__copy_from, __copy_size)) { \
+__copy_res = __copy_from_user((unsigned long) (to), __copy_from, __copy_size); \
+if(__copy_res) __copy_res = __copy_size - __copy_res; \
+} else __copy_res = __copy_size; \
+__copy_res; })
+
+extern int __clear_user(unsigned long addr, int size);
+
+#define clear_user(addr,n) ({ \
+unsigned long __clear_addr = (unsigned long) (addr); \
+int __clear_size = (int) (n); \
+int __clear_res; \
+if(__clear_size && __access_ok(__clear_addr, __clear_size)) { \
+__clear_res = __clear_user(__clear_addr, __clear_size); \
+if(__clear_res) __clear_res = __clear_size - __clear_res; \
+} else __clear_res = __clear_size; \
+__clear_res; })
+
+extern int __strncpy_from_user(unsigned long dest, unsigned long src, int count);
+
+#define strncpy_from_user(dest,src,count) ({ \
+unsigned long __sfu_src = (unsigned long) (src); \
+int __sfu_count = (int) (count); \
+long __sfu_res = -EFAULT; \
+if(__access_ok(__sfu_src, __sfu_count)) { \
+__sfu_res = __strncpy_from_user((unsigned long) (dest), __sfu_src, __sfu_count); \
+} __sfu_res; })
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_UACCESS_H */
diff --git a/include/asm-sparc/ultra.h b/include/asm-sparc/ultra.h
new file mode 100644
index 000000000..fdc6c7f48
--- /dev/null
+++ b/include/asm-sparc/ultra.h
@@ -0,0 +1,52 @@
+/* $Id: ultra.h,v 1.2 1995/11/25 02:33:10 davem Exp $
+ * ultra.h: Definitions and defines for the TI V9 UltraSparc.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_ULTRA_H
+#define _SPARC_ULTRA_H
+
+/* Spitfire MMU control register:
+ *
+ * ----------------------------------------------------------
+ * | | IMPL | VERS | | MID | |
+ * ----------------------------------------------------------
+ * 64 31-28 27-24 23-22 21-17 16 0
+ *
+ * IMPL: Implementation of this Spitfire.
+ * VERS: Version of this Spitfire.
+ * MID: Module ID of this processor.
+ */
+
+#define SPITFIRE_MIDMASK 0x00000000003e0000
+
+/* Spitfire Load Store Unit control register:
+ *
+ * ---------------------------------------------------------------------
+ * | RSV | PWR | PWW | VWR | VWW | RSV | PMASK | DME | IME | DCE | ICE |
+ * ---------------------------------------------------------------------
+ * 63-25 24 23 22 21 20 19-4 3 2 1 0
+ *
+ * PWR: Physical Watchpoint Read enable: 0=off 1=on
+ * PWW: Physical Watchpoint Write enable: 0=off 1=on
+ * VWR: Virtual Watchpoint Read enable: 0=off 1=on
+ * VWW: Virtual Watchpoint Write enable: 0=off 1=on
+ * PMASK: Parity MASK ???
+ * DME: Data MMU Enable: 0=off 1=on
+ * IME: Instruction MMU Enable: 0=off 1=on
+ * DCE: Data Cache Enable: 0=off 1=on
+ * ICE: Instruction Cache Enable: 0=off 1=on
+ */
+
+#define SPITFIRE_LSU_PWR 0x01000000
+#define SPITFIRE_LSU_PWW 0x00800000
+#define SPITFIRE_LSU_VWR 0x00400000
+#define SPITFIRE_LSU_VWW 0x00200000
+#define SPITFIRE_LSU_PMASK 0x000ffff0
+#define SPITFIRE_LSU_DME 0x00000008
+#define SPITFIRE_LSU_IME 0x00000004
+#define SPITFIRE_LSU_DCE 0x00000002
+#define SPITFIRE_LSU_ICE 0x00000001
+
+#endif /* !(_SPARC_ULTRA_H) */
diff --git a/include/asm-sparc/unaligned.h b/include/asm-sparc/unaligned.h
new file mode 100644
index 000000000..470b8fe59
--- /dev/null
+++ b/include/asm-sparc/unaligned.h
@@ -0,0 +1,19 @@
+#ifndef _ASM_SPARC_UNALIGNED_H_
+#define _ASM_SPARC_UNALIGNED_H_
+
+/* Sparc can't handle unaligned accesses. */
+
+#include <asm/string.h>
+
+
+/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
+
+#define get_unaligned(ptr) \
+ ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
+
+#define put_unaligned(val, ptr) \
+ ({ __typeof__(*(ptr)) __tmp = (val); \
+ memmove((ptr), &__tmp, sizeof(*(ptr))); \
+ (void)0; })
+
+#endif /* _ASM_SPARC_UNALIGNED_H */
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index 3b0551461..468097d6f 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -1,3 +1,4 @@
+/* $Id: unistd.h,v 1.24 1996/08/29 09:49:06 davem Exp $ */
#ifndef _SPARC_UNISTD_H
#define _SPARC_UNISTD_H
@@ -8,19 +9,282 @@
* think of right now to force the arguments into fixed registers
* before the trap into the system call with gcc 'asm' statements.
*
- * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * SunOS compatibility based upon preliminary work which is:
+ *
+ * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
*/
-/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+#define __NR_setup 0 /* Used only by init, to get system going. */
+#define __NR_exit 1 /* Common */
+#define __NR_fork 2 /* Common */
+#define __NR_read 3 /* Common */
+#define __NR_write 4 /* Common */
+#define __NR_open 5 /* Common */
+#define __NR_close 6 /* Common */
+#define __NR_wait4 7 /* Common */
+#define __NR_creat 8 /* Common */
+#define __NR_link 9 /* Common */
+#define __NR_unlink 10 /* Common */
+#define __NR_execv 11 /* SunOS Specific */
+#define __NR_chdir 12 /* Common */
+/* #define __NR_ni_syscall 13 ENOSYS under SunOS */
+#define __NR_mknod 14 /* Common */
+#define __NR_chmod 15 /* Common */
+#define __NR_chown 16 /* Common */
+#define __NR_brk 17 /* Common */
+/* #define __NR_ni_syscall 18 ENOSYS under SunOS */
+#define __NR_lseek 19 /* Common */
+#define __NR_getpid 20 /* Common */
+/* #define __NR_ni_syscall 21 ENOSYS under SunOS */
+/* #define __NR_ni_syscall 22 ENOSYS under SunOS */
+#define __NR_setuid 23 /* Implemented via setreuid in SunOS */
+#define __NR_getuid 24 /* Common */
+/* #define __NR_ni_syscall 25 ENOSYS under SunOS */
+#define __NR_ptrace 26 /* Common */
+#define __NR_alarm 27 /* Implemented via setitimer in SunOS */
+/* #define __NR_ni_syscall 28 ENOSYS under SunOS */
+#define __NR_pause 29 /* Is sigblock(0)->sigpause() in SunOS */
+#define __NR_utime 30 /* Implemented via utimes() under SunOS */
+#define __NR_stty 31 /* Implemented via ioctl() under SunOS */
+#define __NR_gtty 32 /* Implemented via ioctl() under SunOS */
+#define __NR_access 33 /* Common */
+#define __NR_nice 34 /* Implemented via get/setpriority() in SunOS */
+#define __NR_ftime 35 /* Implemented via gettimeofday() in SunOS */
+#define __NR_sync 36 /* Common */
+#define __NR_kill 37 /* Common */
+#define __NR_stat 38 /* Common */
+/* #define __NR_ni_syscall 39 ENOSYS under SunOS */
+#define __NR_lstat 40 /* Common */
+#define __NR_dup 41 /* Common */
+#define __NR_pipe 42 /* Common */
+#define __NR_times 43 /* Implemented via getrusage() in SunOS */
+#define __NR_profil 44 /* Common */
+/* #define __NR_ni_syscall 45 ENOSYS under SunOS */
+#define __NR_setgid 46 /* Implemented via setregid() in SunOS */
+#define __NR_getgid 47 /* Common */
+#define __NR_signal 48 /* Implemented via sigvec() in SunOS */
+#define __NR_geteuid 49 /* SunOS calls getuid() */
+#define __NR_getegid 50 /* SunOS calls getgid() */
+#define __NR_acct 51 /* Common */
+/* #define __NR_ni_syscall 52 ENOSYS under SunOS */
+#define __NR_mctl 53 /* SunOS specific */
+#define __NR_ioctl 54 /* Common */
+#define __NR_reboot 55 /* Common */
+/* #define __NR_ni_syscall 56 ENOSYS under SunOS */
+#define __NR_symlink 57 /* Common */
+#define __NR_readlink 58 /* Common */
+#define __NR_execve 59 /* Common */
+#define __NR_umask 60 /* Common */
+#define __NR_chroot 61 /* Common */
+#define __NR_fstat 62 /* Common */
+/* #define __NR_ni_syscall 63 ENOSYS under SunOS */
+#define __NR_getpagesize 64 /* Common */
+#define __NR_msync 65 /* Common in newer 1.3.x revs... */
+/* #define __NR_ni_syscall 66 ENOSYS under SunOS */
+/* #define __NR_ni_syscall 67 ENOSYS under SunOS */
+/* #define __NR_ni_syscall 68 ENOSYS under SunOS */
+#define __NR_sbrk 69 /* SunOS Specific */
+#define __NR_sstk 70 /* SunOS Specific */
+#define __NR_mmap 71 /* Common */
+#define __NR_vadvise 72 /* SunOS Specific */
+#define __NR_munmap 73 /* Common */
+#define __NR_mprotect 74 /* Common */
+#define __NR_madvise 75 /* SunOS Specific */
+#define __NR_vhangup 76 /* Common */
+/* #define __NR_ni_syscall 77 ENOSYS under SunOS */
+#define __NR_mincore 78 /* SunOS Specific */
+#define __NR_getgroups 79 /* Common */
+#define __NR_setgroups 80 /* Common */
+#define __NR_getpgrp 81 /* Common */
+#define __NR_setpgrp 82 /* setpgid, same difference... */
+#define __NR_setitimer 83 /* Common */
+/* #define __NR_ni_syscall 84 ENOSYS under SunOS */
+#define __NR_swapon 85 /* Common */
+#define __NR_getitimer 86 /* Common */
+#define __NR_gethostname 87 /* SunOS Specific */
+#define __NR_sethostname 88 /* Common */
+#define __NR_getdtablesize 89 /* SunOS Specific */
+#define __NR_dup2 90 /* Common */
+#define __NR_getdopt 91 /* SunOS Specific */
+#define __NR_fcntl 92 /* Common */
+#define __NR_select 93 /* Common */
+#define __NR_setdopt 94 /* SunOS Specific */
+#define __NR_fsync 95 /* Common */
+#define __NR_setpriority 96 /* Common */
+#define __NR_socket 97 /* SunOS Specific */
+#define __NR_connect 98 /* SunOS Specific */
+#define __NR_accept 99 /* SunOS Specific */
+#define __NR_getpriority 100 /* Common */
+#define __NR_send 101 /* SunOS Specific */
+#define __NR_recv 102 /* SunOS Specific */
+/* #define __NR_ni_syscall 103 ENOSYS under SunOS */
+#define __NR_bind 104 /* SunOS Specific */
+#define __NR_setsockopt 105 /* SunOS Specific */
+#define __NR_listen 106 /* SunOS Specific */
+/* #define __NR_ni_syscall 107 ENOSYS under SunOS */
+#define __NR_sigvec 108 /* SunOS Specific */
+#define __NR_sigblock 109 /* SunOS Specific */
+#define __NR_sigsetmask 110 /* SunOS Specific */
+#define __NR_sigpause 111 /* SunOS Specific */
+#define __NR_sigstack 112 /* SunOS Specific */
+#define __NR_recvmsg 113 /* SunOS Specific */
+#define __NR_sendmsg 114 /* SunOS Specific */
+#define __NR_vtrace 115 /* SunOS Specific */
+#define __NR_gettimeofday 116 /* Common */
+#define __NR_getrusage 117 /* Common */
+#define __NR_getsockopt 118 /* SunOS Specific */
+/* #define __NR_ni_syscall 119 ENOSYS under SunOS */
+#define __NR_readv 120 /* Common */
+#define __NR_writev 121 /* Common */
+#define __NR_settimeofday 122 /* Common */
+#define __NR_fchown 123 /* Common */
+#define __NR_fchmod 124 /* Common */
+#define __NR_recvfrom 125 /* SunOS Specific */
+#define __NR_setreuid 126 /* Common */
+#define __NR_setregid 127 /* Common */
+#define __NR_rename 128 /* Common */
+#define __NR_truncate 129 /* Common */
+#define __NR_ftruncate 130 /* Common */
+#define __NR_flock 131 /* Common */
+/* #define __NR_ni_syscall 132 ENOSYS under SunOS */
+#define __NR_sendto 133 /* SunOS Specific */
+#define __NR_shutdown 134 /* SunOS Specific */
+#define __NR_socketpair 135 /* SunOS Specific */
+#define __NR_mkdir 136 /* Common */
+#define __NR_rmdir 137 /* Common */
+#define __NR_utimes 138 /* SunOS Specific */
+/* #define __NR_ni_syscall 139 ENOSYS under SunOS */
+#define __NR_adjtime 140 /* SunOS Specific */
+#define __NR_getpeername 141 /* SunOS Specific */
+#define __NR_gethostid 142 /* SunOS Specific */
+/* #define __NR_ni_syscall 143 ENOSYS under SunOS */
+#define __NR_getrlimit 144 /* Common */
+#define __NR_setrlimit 145 /* Common */
+#define __NR_killpg 146 /* SunOS Specific */
+/* #define __NR_ni_syscall 147 ENOSYS under SunOS */
+/* #define __NR_ni_syscall 148 ENOSYS under SunOS */
+/* #define __NR_ni_syscall 149 ENOSYS under SunOS */
+#define __NR_getsockname 150 /* SunOS Specific */
+#define __NR_getmsg 151 /* SunOS Specific */
+#define __NR_putmsg 152 /* SunOS Specific */
+#define __NR_poll 153 /* SunOS Specific */
+/* #define __NR_ni_syscall 154 ENOSYS under SunOS */
+#define __NR_nfssvc 155 /* SunOS Specific */
+#define __NR_getdirentries 156 /* SunOS Specific */
+#define __NR_statfs 157 /* Common */
+#define __NR_fstatfs 158 /* Common */
+#define __NR_umount 159 /* Common */
+#define __NR_async_daemon 160 /* SunOS Specific */
+#define __NR_getfh 161 /* SunOS Specific */
+#define __NR_getdomainname 162 /* SunOS Specific */
+#define __NR_setdomainname 163 /* Common */
+/* #define __NR_ni_syscall 164 ENOSYS under SunOS */
+#define __NR_quotactl 165 /* Common */
+#define __NR_exportfs 166 /* SunOS Specific */
+#define __NR_mount 167 /* Common */
+#define __NR_ustat 168 /* Common */
+#define __NR_semsys 169 /* SunOS Specific */
+#define __NR_msgsys 170 /* SunOS Specific */
+#define __NR_shmsys 171 /* SunOS Specific */
+#define __NR_auditsys 172 /* SunOS Specific */
+#define __NR_rfssys 173 /* SunOS Specific */
+#define __NR_getdents 174 /* Common */
+#define __NR_setsid 175 /* Common */
+#define __NR_fchdir 176 /* Common */
+#define __NR_fchroot 177 /* SunOS Specific */
+#define __NR_vpixsys 178 /* SunOS Specific */
+#define __NR_aioread 179 /* SunOS Specific */
+#define __NR_aiowrite 180 /* SunOS Specific */
+#define __NR_aiowait 181 /* SunOS Specific */
+#define __NR_aiocancel 182 /* SunOS Specific */
+#define __NR_sigpending 183 /* Common */
+/* #define __NR_ni_syscall 184 ENOSYS under SunOS */
+#define __NR_setpgid 185 /* Common */
+#define __NR_pathconf 186 /* SunOS Specific */
+#define __NR_fpathconf 187 /* SunOS Specific */
+#define __NR_sysconf 188 /* SunOS Specific */
+#define __NR_uname 189 /* Linux Specific */
+#define __NR_init_module 190 /* Linux Specific */
+#define __NR_personality 191 /* Linux Specific */
+#define __NR_prof 192 /* Linux Specific */
+#define __NR_break 193 /* Linux Specific */
+#define __NR_lock 194 /* Linux Specific */
+#define __NR_mpx 195 /* Linux Specific */
+#define __NR_ulimit 196 /* Linux Specific */
+#define __NR_getppid 197 /* Linux Specific */
+#define __NR_sigaction 198 /* Linux Specific */
+#define __NR_sgetmask 199 /* Linux Specific */
+#define __NR_ssetmask 200 /* Linux Specific */
+#define __NR_sigsuspend 201 /* Linux Specific */
+#define __NR_oldlstat 202 /* Linux Specific */
+#define __NR_uselib 203 /* Linux Specific */
+#define __NR_readdir 204 /* Linux Specific */
+#define __NR_ioperm 205 /* Linux Specific - i386 specific, unused */
+#define __NR_socketcall 206 /* Linux Specific */
+#define __NR_syslog 207 /* Linux Specific */
+#define __NR_olduname 208 /* Linux Specific */
+#define __NR_iopl 209 /* Linux Specific - i386 specific, unused */
+#define __NR_idle 210 /* Linux Specific */
+#define __NR_vm86 211 /* Linux Specific - i386 specific, unused */
+#define __NR_waitpid 212 /* Linux Specific */
+#define __NR_swapoff 213 /* Linux Specific */
+#define __NR_sysinfo 214 /* Linux Specific */
+#define __NR_ipc 215 /* Linux Specific */
+#define __NR_sigreturn 216 /* Linux Specific */
+#define __NR_clone 217 /* Linux Specific */
+#define __NR_modify_ldt 218 /* Linux Specific - i386 specific, unused */
+#define __NR_adjtimex 219 /* Linux Specific */
+#define __NR_sigprocmask 220 /* Linux Specific */
+#define __NR_create_module 221 /* Linux Specific */
+#define __NR_delete_module 222 /* Linux Specific */
+#define __NR_get_kernel_syms 223 /* Linux Specific */
+#define __NR_getpgid 224 /* Linux Specific */
+#define __NR_bdflush 225 /* Linux Specific */
+#define __NR_sysfs 226 /* Linux Specific */
+#define __NR_afs_syscall 227 /* Linux Specific */
+#define __NR_setfsuid 228 /* Linux Specific */
+#define __NR_setfsgid 229 /* Linux Specific */
+#define __NR__newselect 230 /* Linux Specific */
+#define __NR_time 231 /* Linux Specific */
+#define __NR_oldstat 232 /* Linux Specific */
+#define __NR_stime 233 /* Linux Specific */
+#define __NR_oldfstat 234 /* Linux Specific */
+#define __NR_phys 235 /* Linux Specific */
+#define __NR__llseek 236 /* Linux Specific */
+#define __NR_mlock 237
+#define __NR_munlock 238
+#define __NR_mlockall 239
+#define __NR_munlockall 240
+#define __NR_sched_setparam 241
+#define __NR_sched_getparam 242
+#define __NR_sched_setscheduler 243
+#define __NR_sched_getscheduler 244
+#define __NR_sched_yield 245
+#define __NR_sched_get_priority_max 246
+#define __NR_sched_get_priority_min 247
+#define __NR_sched_rr_get_interval 248
+#define __NR_nanosleep 249
+#define __NR_mremap 250
+#define __NR__sysctl 251
+#define __NR_getsid 252
+#define __NR_fdatasync 253
+#define __NR_nfsctl 254
+
#define _syscall0(type,name) \
type name(void) \
{ \
long __res; \
-__asm__ volatile ("or %%g0, %0, %%o0\n\t" \
- "t 0xa\n\t" \
- : "=r" (__res) \
- : "0" (__NR_##name) \
- : "o0"); \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+ "t 0x10\n\t" \
+ "bcc 1f\n\t" \
+ "or %%g0, %%o0, %0\n\t" \
+ "sub %%g0, %%o0, %0\n\t" \
+ "1:\n\t" \
+ : "=r" (__res)\
+ : "0" (__NR_##name) \
+ : "g1", "o0"); \
if (__res >= 0) \
return (type) __res; \
errno = -__res; \
@@ -31,12 +295,16 @@ return -1; \
type name(type1 arg1) \
{ \
long __res; \
-__asm__ volatile ("or %%g0, %0, %%o0\n\t" \
- "or %%g0, %1, %%o1\n\t" \
- "t 0xa\n\t" \
- : "=r" (__res), "=r" ((long)(arg1)) \
- : "0" (__NR_##name),"1" ((long)(arg1)) \
- : "o0", "o1"); \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+ "or %%g0, %1, %%o0\n\t" \
+ "t 0x10\n\t" \
+ "bcc 1f\n\t" \
+ "or %%g0, %%o0, %0\n\t" \
+ "sub %%g0, %%o0, %0\n\t" \
+ "1:\n\t" \
+ : "=r" (__res), "=r" ((long)(arg1)) \
+ : "0" (__NR_##name),"1" ((long)(arg1)) \
+ : "g1", "o0"); \
if (__res >= 0) \
return (type) __res; \
errno = -__res; \
@@ -47,13 +315,17 @@ return -1; \
type name(type1 arg1,type2 arg2) \
{ \
long __res; \
-__asm__ volatile ("or %%g0, %0, %%o0\n\t" \
- "or %%g0, %1, %%o1\n\t" \
- "or %%g0, %2, %%o2\n\t" \
- "t 0xa\n\t" \
- : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(args)) \
- : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)) \
- : "o0", "o1", "o2"); \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+ "or %%g0, %1, %%o0\n\t" \
+ "or %%g0, %2, %%o1\n\t" \
+ "t 0x10\n\t" \
+ "bcc 1f\n\t" \
+ "or %%g0, %%o0, %0\n\t" \
+ "sub %%g0, %%o0, %0\n\t" \
+ "1:\n\t" \
+ : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)) \
+ : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)) \
+ : "g1", "o0", "o1"); \
if (__res >= 0) \
return (type) __res; \
errno = -__res; \
@@ -64,19 +336,23 @@ return -1; \
type name(type1 arg1,type2 arg2,type3 arg3) \
{ \
long __res; \
-__asm__ volatile ("or %%g0, %0, %%o0\n\t" \
- "or %%g0, %1, %%o1\n\t" \
- "or %%g0, %2, %%o2\n\t" \
- "or %%g0, %3, %%o3\n\t" \
- "t 0xa\n\t" \
- : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
- "=r" ((long)(arg3)) \
- : "0" (__NR_##name), "1" ((long)(arg1)), "2" ((long)(arg2)), \
- "3" ((long)(arg3)) \
- : "o0", "o1", "o2", "o3"); \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+ "or %%g0, %1, %%o0\n\t" \
+ "or %%g0, %2, %%o1\n\t" \
+ "or %%g0, %3, %%o2\n\t" \
+ "t 0x10\n\t" \
+ "bcc 1f\n\t" \
+ "or %%g0, %%o0, %0\n\t" \
+ "sub %%g0, %%o0, %0\n\t" \
+ "1:\n\t" \
+ : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
+ "=r" ((long)(arg3)) \
+ : "0" (__NR_##name), "1" ((long)(arg1)), "2" ((long)(arg2)), \
+ "3" ((long)(arg3)) \
+ : "g1", "o0", "o1", "o2"); \
if (__res>=0) \
return (type) __res; \
-errno=-__res; \
+errno = -__res; \
return -1; \
}
@@ -84,20 +360,24 @@ return -1; \
type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
{ \
long __res; \
-__asm__ volatile ("or %%g0, %0, %%o0\n\t" \
- "or %%g0, %1, %%o1\n\t" \
- "or %%g0, %2, %%o2\n\t" \
- "or %%g0, %3, %%o3\n\t" \
- "or %%g0, %4, %%o4\n\t" \
- "t 0xa\n\t" \
- : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
- "=r" ((long)(arg3)), "=r" ((long)(arg4)) \
- : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \
- "3" ((long)(arg3)),"4" ((long)(arg4)) \
- : "o0", "o1", "o2", "o3", "o4"); \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+ "or %%g0, %1, %%o0\n\t" \
+ "or %%g0, %2, %%o1\n\t" \
+ "or %%g0, %3, %%o2\n\t" \
+ "or %%g0, %4, %%o3\n\t" \
+ "t 0x10\n\t" \
+ "bcc 1f\n\t" \
+ "or %%g0, %%o0, %0\n\t" \
+ "sub %%g0,%%o0, %0\n\t" \
+ "1:\n\t" \
+ : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
+ "=r" ((long)(arg3)), "=r" ((long)(arg4)) \
+ : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \
+ "3" ((long)(arg3)),"4" ((long)(arg4)) \
+ : "g1", "o0", "o1", "o2", "o3"); \
if (__res>=0) \
return (type) __res; \
-errno=-__res; \
+errno = -__res; \
return -1; \
}
@@ -105,25 +385,29 @@ return -1; \
type5,arg5) \
type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
{ \
-long __res; \
-__asm__ volatile ("or %%g0, %0, %%o0\n\t" \
- "or %%g0, %1, %%o1\n\t" \
- "or %%g0, %2, %%o2\n\t" \
- "or %%g0, %3, %%o3\n\t" \
- "or %%g0, %4, %%o4\n\t" \
- "or %%g0, %5, %%o5\n\t" \
- "t 0xa\n\t" \
- : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
- "=r" ((long)(arg3)), "=r" ((long)(arg4)), "=r" ((long)(arg5)) \
- : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \
- "3" ((long)(arg3)),"4" ((long)(arg4)),"5" ((long)(arg5)) \
- : "o0", "o1", "o2", "o3", "o4", "o5"); \
+ long __res; \
+\
+__asm__ __volatile__ ("or %%g0, %1, %%o0\n\t" \
+ "or %%g0, %2, %%o1\n\t" \
+ "or %%g0, %3, %%o2\n\t" \
+ "or %%g0, %4, %%o3\n\t" \
+ "or %%g0, %5, %%o4\n\t" \
+ "or %%g0, %6, %%g1\n\t" \
+ "t 0x10\n\t" \
+ "bcc 1f\n\t" \
+ "or %%g0, %%o0, %0\n\t" \
+ "sub %%g0, %%o0, %0\n\t" \
+ "1:\n\t" \
+ : "=r" (__res) \
+ : "r" ((long)(arg1)),"r" ((long)(arg2)), \
+ "r" ((long)(arg3)),"r" ((long)(arg4)),"r" ((long)(arg5)), \
+ "i" (__NR_##name) \
+ : "g1", "o0", "o1", "o2", "o3", "o4"); \
if (__res>=0) \
return (type) __res; \
-errno=-__res; \
+errno = -__res; \
return -1; \
}
-
#ifdef __KERNEL_SYSCALLS__
/*
@@ -139,25 +423,70 @@ return -1; \
* some others too.
*/
#define __NR__exit __NR_exit
-static inline _syscall0(int,idle)
-static inline _syscall0(int,fork)
-static inline _syscall0(int,pause)
-static inline _syscall0(int,setup)
-static inline _syscall0(int,sync)
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static __inline__ _syscall0(int,idle)
+static __inline__ _syscall0(int,fork)
+static __inline__ _syscall2(int,clone,unsigned long,flags,char *,ksp)
+static __inline__ _syscall0(int,pause)
+static __inline__ _syscall0(int,setup)
+static __inline__ _syscall0(int,sync)
+static __inline__ _syscall0(pid_t,setsid)
+static __inline__ _syscall3(int,write,int,fd,__const__ char *,buf,off_t,count)
+static __inline__ _syscall1(int,dup,int,fd)
+static __inline__ _syscall3(int,execve,__const__ char *,file,char **,argv,char **,envp)
+static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode)
+static __inline__ _syscall1(int,close,int,fd)
+static __inline__ _syscall1(int,_exit,int,exitcode)
+static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static inline pid_t wait(int * wait_stat)
+static __inline__ pid_t wait(int * wait_stat)
{
return waitpid(-1,wait_stat,0);
}
-#endif
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+ * who haven't done an "execve()") should use this: it will work within
+ * a system call from a "real" process, but the process memory space will
+ * not be free'd until both the parent and the child have exited.
+ */
+static __inline__ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+ long retval;
+
+ __asm__ __volatile("mov %4, %%g2\n\t" /* Set aside fn ptr... */
+ "mov %5, %%g3\n\t" /* and arg. */
+ "mov %1, %%g1\n\t"
+ "mov %2, %%o0\n\t" /* Clone flags. */
+ "mov 0, %%o1\n\t" /* usp arg == 0 */
+ "t 0x10\n\t" /* Linux/Sparc clone(). */
+ "cmp %%o1, 0\n\t"
+ "be 1f\n\t" /* The parent, just return. */
+ " nop\n\t" /* Delay slot. */
+ "jmpl %%g2, %%o7\n\t" /* Call the function. */
+ " mov %%g3, %%o0\n\t" /* Get back the arg in delay. */
+ "mov %3, %%g1\n\t"
+ "t 0x10\n\t" /* Linux/Sparc exit(). */
+ /* Notreached by child. */
+ "1: mov %%o0, %0\n\t" :
+ "=r" (retval) :
+ "i" (__NR_clone), "r" (flags | CLONE_VM),
+ "i" (__NR_exit), "r" (fn), "r" (arg) :
+ "g1", "g2", "g3", "o0", "o1", "memory");
+ return retval;
+}
+
+#endif /* __KERNEL_SYSCALLS__ */
+
+/* sysconf options, for SunOS compatibility */
+#define _SC_ARG_MAX 1
+#define _SC_CHILD_MAX 2
+#define _SC_CLK_TCK 3
+#define _SC_NGROUPS_MAX 4
+#define _SC_OPEN_MAX 5
+#define _SC_JOB_CONTROL 6
+#define _SC_SAVED_IDS 7
+#define _SC_VERSION 8
#endif /* _SPARC_UNISTD_H */
diff --git a/include/asm-sparc/user.h b/include/asm-sparc/user.h
new file mode 100644
index 000000000..7306b0d10
--- /dev/null
+++ b/include/asm-sparc/user.h
@@ -0,0 +1,60 @@
+/* $Id: user.h,v 1.4 1996/07/24 23:17:14 miguel Exp $
+ * asm-sparc/user.h: Core file definitions for the Sparc.
+ *
+ * Keep in sync with reg.h. Actually, we could get rid of this
+ * one, since we won't a.out core dump that much anyways - miguel.
+ * Copyright (C) 1995 (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_USER_H
+#define _SPARC_USER_H
+
+#include <asm/a.out.h>
+struct sunos_regs {
+ unsigned long psr, pc, npc, y;
+ unsigned long regs[15];
+};
+
+struct sunos_fpqueue {
+ unsigned long *addr;
+ unsigned long inst;
+};
+
+struct sunos_fp {
+ union {
+ unsigned long regs[32];
+ double reg_dbls[16];
+ } fregs;
+ unsigned long fsr;
+ unsigned long flags;
+ unsigned long extra;
+ unsigned long fpq_count;
+ struct sunos_fpqueue fpq[16];
+};
+
+struct sunos_fpu {
+ struct sunos_fp fpstatus;
+};
+
+/* The SunOS core file header layout. */
+struct user {
+ unsigned long magic;
+ unsigned long len;
+ struct sunos_regs regs;
+ struct exec uexec;
+ int signal;
+ size_t u_tsize; /* all of these in bytes! */
+ size_t u_dsize;
+ size_t u_ssize;
+ char u_comm[17];
+ struct sunos_fpu fpu;
+ unsigned long sigcode; /* Special sigcontext subcode, if any */
+};
+
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_DATA_START_ADDR (u.start_data)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+#define SUNOS_CORE_MAGIC 0x080456
+
+#endif /* !(_SPARC_USER_H) */
diff --git a/include/asm-sparc/vac-ops.h b/include/asm-sparc/vac-ops.h
index 18755e048..d963a7fa3 100644
--- a/include/asm-sparc/vac-ops.h
+++ b/include/asm-sparc/vac-ops.h
@@ -1,89 +1,125 @@
+/* $Id: vac-ops.h,v 1.12 1996/07/08 15:12:30 ecd Exp $ */
#ifndef _SPARC_VAC_OPS_H
#define _SPARC_VAC_OPS_H
/* vac-ops.h: Inline assembly routines to do operations on the Sparc
- VAC (virtual address cache).
-
- Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu)
-*/
-
-extern unsigned long *trapbase;
-extern char end, etext, msgbuf;
-
-extern void flush_vac_context(void);
-extern void flush_vac_segment(unsigned int foo_segment);
-extern void flush_vac_page(unsigned int foo_addr);
-
-extern int vac_do_hw_vac_flushes, vac_size, vac_linesize;
-extern int vac_entries_per_context, vac_entries_per_segment;
-extern int vac_entries_per_page;
-
-/* enable_vac() enables the virtual address cache. It returns 0 on
- success, 1 on failure.
-*/
-
-extern __inline__ int enable_vac(void)
-{
- int success=0;
-
- __asm__ __volatile__("lduba [%1] 2, %0\n\t"
- "or %0, 0x10, %0\n\t"
- "stba %0, [%1] 2\n\t"
- "or %%g0, %%g0, %0" :
- "=r" (success) :
- "r" ((unsigned int) 0x40000000),
- "0" (success));
- return success;
-}
-
-/* disable_vac() disables the virtual address cache. It returns 0 on
- success, 1 on failure.
-*/
-
-extern __inline__ int disable_vac(void)
+ * VAC (virtual address cache) for the sun4c.
+ *
+ * Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <asm/sysen.h>
+#include <asm/contregs.h>
+#include <asm/asi.h>
+
+/* The SUN4C models have a virtually addressed write-through
+ * cache.
+ *
+ * The cache tags are directly accessible through an ASI and
+ * each have the form:
+ *
+ * ------------------------------------------------------------
+ * | MBZ | CONTEXT | WRITE | PRIV | VALID | MBZ | TagID | MBZ |
+ * ------------------------------------------------------------
+ * 31 25 24 22 21 20 19 18 16 15 2 1 0
+ *
+ * MBZ: These bits are either unused and/or reserved and should
+ * be written as zeroes.
+ *
+ * CONTEXT: Records the context to which this cache line belongs.
+ *
+ * WRITE: A copy of the writable bit from the mmu pte access bits.
+ *
+ * PRIV: A copy of the privileged bit from the pte access bits.
+ *
+ * VALID: If set, this line is valid, else invalid.
+ *
+ * TagID: Fourteen bits of tag ID.
+ *
+ * Every virtual address is seen by the cache like this:
+ *
+ * ----------------------------------------
+ * | RESV | TagID | LINE | BYTE-in-LINE |
+ * ----------------------------------------
+ * 31 30 29 16 15 4 3 0
+ *
+ * RESV: Unused/reserved.
+ *
+ * TagID: Used to match the Tag-ID in that vac tags.
+ *
+ * LINE: Which line within the cache
+ *
+ * BYTE-in-LINE: Which byte within the cache line.
+ */
+
+/* Sun4c VAC Tags */
+#define S4CVACTAG_CID 0x01c00000
+#define S4CVACTAG_W 0x00200000
+#define S4CVACTAG_P 0x00100000
+#define S4CVACTAG_V 0x00080000
+#define S4CVACTAG_TID 0x0000fffc
+
+/* Sun4c VAC Virtual Address */
+#define S4CVACVA_TID 0x3fff0000
+#define S4CVACVA_LINE 0x0000fff0
+#define S4CVACVA_BIL 0x0000000f
+
+/* The indexing of cache lines creates a problem. Because the line
+ * field of a virtual address extends past the page offset within
+ * the virtual address it is possible to have what are called
+ * 'bad aliases' which will create inconsistencies. So we must make
+ * sure that within a context that if a physical page is mapped
+ * more than once, that 'extra' line bits are the same. If this is
+ * not the case, and thus is a 'bad alias' we must turn off the
+ * cacheable bit in the pte's of all such pages.
+ */
+#define S4CVAC_BADBITS 0x0000f000
+
+/* The following is true if vaddr1 and vaddr2 would cause
+ * a 'bad alias'.
+ */
+#define S4CVAC_BADALIAS(vaddr1, vaddr2) \
+ ((((unsigned long) (vaddr1)) ^ ((unsigned long) (vaddr2))) & \
+ (S4CVAC_BADBITS))
+
+/* The following structure describes the characteristics of a sun4c
+ * VAC as probed from the prom during boot time.
+ */
+struct sun4c_vac_props {
+ unsigned int num_bytes; /* Size of the cache */
+ unsigned int num_lines; /* Number of cache lines */
+ unsigned int do_hwflushes; /* Hardware flushing available? */
+ unsigned int linesize; /* Size of each line in bytes */
+ unsigned int log2lsize; /* log2(linesize) */
+ unsigned int on; /* VAC is enabled */
+};
+
+extern struct sun4c_vac_props sun4c_vacinfo;
+
+extern void sun4c_flush_all(void);
+
+/* sun4c_enable_vac() enables the sun4c virtual address cache. */
+extern __inline__ void sun4c_enable_vac(void)
{
- int success=0;
-
- __asm__ __volatile__("lduba [%1] 0x2, %0\n\t"
- "xor %0, 0x10, %0\n\t"
- "stba %0, [%1] 0x2\n\t"
- "or %%g0, %%g0, %0" :
- "=r" (success) :
- "r" (0x40000000),
- "0" (success));
- return success;
+ __asm__ __volatile__("lduba [%0] %1, %%g1\n\t"
+ "or %%g1, %2, %%g1\n\t"
+ "stba %%g1, [%0] %1\n\t" : :
+ "r" ((unsigned int) AC_SENABLE),
+ "i" (ASI_CONTROL), "i" (SENABLE_CACHE) :
+ "g1");
+ sun4c_vacinfo.on = 1;
}
-/* Various one-shot VAC entry flushes on the Sparc */
-
-extern __inline__ void hw_flush_vac_context_entry(char* addr)
+/* sun4c_disable_vac() disables the virtual address cache. */
+extern __inline__ void sun4c_disable_vac(void)
{
- __asm__ __volatile__("sta %%g0, [%0] 0x7" : : "r" (addr));
+ __asm__ __volatile__("lduba [%0] %1, %%g1\n\t"
+ "andn %%g1, %2, %%g1\n\t"
+ "stba %%g1, [%0] %1\n\t" : :
+ "r" ((unsigned int) AC_SENABLE),
+ "i" (ASI_CONTROL), "i" (SENABLE_CACHE) :
+ "g1");
+ sun4c_vacinfo.on = 0;
}
-extern __inline__ void sw_flush_vac_context_entry(char* addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] 0xe" : : "r" (addr));
-}
-
-extern __inline__ void hw_flush_vac_segment_entry(char* addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] 0x5" : : "r" (addr));
-}
-
-extern __inline__ void sw_flush_vac_segment_entry(char* addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] 0xc" : : "r" (addr));
-}
-
-extern __inline__ void hw_flush_vac_page_entry(unsigned long* addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] 0x6" : : "r" (addr));
-}
-
-extern __inline__ void sw_flush_vac_page_entry(unsigned long* addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] 0xd" : : "r" (addr));
-}
-
#endif /* !(_SPARC_VAC_OPS_H) */
diff --git a/include/asm-sparc/vaddrs.h b/include/asm-sparc/vaddrs.h
index 7df443103..30e927b1b 100644
--- a/include/asm-sparc/vaddrs.h
+++ b/include/asm-sparc/vaddrs.h
@@ -1,6 +1,9 @@
+/* $Id: vaddrs.h,v 1.21 1996/10/07 03:03:02 davem Exp $ */
#ifndef _SPARC_VADDRS_H
#define _SPARC_VADDRS_H
+#include <asm/head.h>
+
/* asm-sparc/vaddrs.h: Here will be define the virtual addresses at
* which important I/O addresses will be mapped.
* For instance the timer register virtual address
@@ -9,8 +12,54 @@
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
-#define TIMER_VADDR 0x3000 /* Next page after where the interrupt enable
- * register gets mapped at boot.
- */
+/* I can see only one reason why we should have statically defined
+ * mappings for devices and is the speedup improvements of not loading
+ * a pointer and then the value in the assembly code
+ */
+#define IOBASE_VADDR 0xfe000000 /* Base for mapping pages */
+#define IOBASE_LEN 0x00300000 /* Length of the IO area */
+#define IOBASE_END 0xfe300000
+#define DVMA_VADDR 0xfff00000 /* Base area of the DVMA on suns */
+#define DVMA_LEN 0x00040000 /* Size of the DVMA address space */
+#define DVMA_END 0xfff40000
+
+/* IOMMU Mapping area, must be on a 16MB boundary! Note this
+ * doesn't count the DVMA areas, the prom lives between the
+ * iommu mapping area (for scsi transfer buffers) and the
+ * dvma upper range (for lance packet ring buffers).
+ */
+#define IOMMU_VADDR 0xff000000
+#define IOMMU_LEN 0x00c00000
+#define IOMMU_END 0xffc00000 /* KADB debugger vm starts here */
+
+/* On the sun4/4c we don't need an IOMMU area, but we need a place
+ * to reliably map locked down kernel data. This includes the
+ * task_struct and kernel stack pages of each process plus the
+ * scsi buffers during dvma IO transfers, also the floppy buffers
+ * during pseudo dma which runs with traps off (no faults allowed).
+ * Some quick calculations yield:
+ * NR_TASKS <512> * (3 * PAGE_SIZE) == 0x600000
+ * Subtract this from 0xc00000 and you get 0x927C0 of vm left
+ * over to map SCSI dvma + floppy pseudo-dma buffers. So be
+ * careful if you change NR_TASKS or else there won't be enough
+ * room for it all.
+ */
+#define SUN4C_LOCK_VADDR 0xff000000
+#define SUN4C_LOCK_LEN 0x00c00000
+#define SUN4C_LOCK_END 0xffc00000
+
+/* On sun4m machines we need per-cpu virtual areas */
+#define PERCPU_VADDR 0xffc00000 /* Base for per-cpu virtual mappings */
+#define PERCPU_ENTSIZE 0x00100000
+#define PERCPU_LEN ((PERCPU_ENTSIZE*NCPUS))
+
+/* per-cpu offsets */
+#define PERCPU_TBR_OFFSET 0x00000 /* %tbr, mainly used for identification. */
+#define PERCPU_KSTACK_OFFSET 0x01000 /* Beginning of kernel stack for this cpu */
+#define PERCPU_MBOX_OFFSET 0x03000 /* Prom SMP Mailbox */
+#define PERCPU_CPUID_OFFSET 0x04000 /* Per-cpu ID number. */
+#define PERCPU_ISALIVE_OFFSET 0x04004 /* Has CPU been initted yet? */
+#define PERCPU_ISIDLING_OFFSET 0x04008 /* Is CPU in idle loop spinning? */
#endif /* !(_SPARC_VADDRS_H) */
+
diff --git a/include/asm-sparc/version.h b/include/asm-sparc/version.h
deleted file mode 100644
index 0c238e9cf..000000000
--- a/include/asm-sparc/version.h
+++ /dev/null
@@ -1 +0,0 @@
-#define WHO_COMPILED_ME "someone@somewhere.domain"
diff --git a/include/asm-sparc/viking.h b/include/asm-sparc/viking.h
new file mode 100644
index 000000000..dc4adc393
--- /dev/null
+++ b/include/asm-sparc/viking.h
@@ -0,0 +1,198 @@
+/* $Id: viking.h,v 1.16 1996/08/29 09:49:10 davem Exp $
+ * viking.h: Defines specific to the GNU/Viking MBUS module.
+ * This is SRMMU stuff.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_VIKING_H
+#define _SPARC_VIKING_H
+
+#include <asm/asi.h>
+#include <asm/mxcc.h>
+
+/* Bits in the SRMMU control register for GNU/Viking modules.
+ *
+ * -----------------------------------------------------------
+ * |impl-vers| RSV |TC|AC|SP|BM|PC|MBM|SB|IC|DC|PSO|RSV|NF|ME|
+ * -----------------------------------------------------------
+ * 31 24 23-17 16 15 14 13 12 11 10 9 8 7 6-2 1 0
+ *
+ * TC: Tablewalk Cacheable -- 0 = Twalks are not cacheable in E-cache
+ * 1 = Twalks are cacheable in E-cache
+ *
+ * GNU/Viking will only cache tablewalks in the E-cache (mxcc) if present
+ * and never caches them internally (or so states the docs). Therefore
+ * for machines lacking an E-cache (ie. in MBUS mode) this bit must
+ * remain cleared.
+ *
+ * AC: Alternate Cacheable -- 0 = Passthru physical accesses not cacheable
+ * 1 = Passthru physical accesses cacheable
+ *
+ * This indicates whether accesses are cacheable when no cachable bit
+ * is present in the pte when the processor is in boot-mode or the
+ * access does not need pte's for translation (ie. pass-thru ASI's).
+ * "Cachable" is only referring to E-cache (if present) and not the
+ * on chip split I/D caches of the GNU/Viking.
+ *
+ * SP: SnooP Enable -- 0 = bus snooping off, 1 = bus snooping on
+ *
+ * This enables snooping on the GNU/Viking bus. This must be on
+ * for the hardware cache consistency mechanisms of the GNU/Viking
+ * to work at all. On non-mxcc GNU/Viking modules the split I/D
+ * caches will snoop regardless of whether they are enabled, this
+ * takes care of the case where the I or D or both caches are turned
+ * off yet still contain valid data. Note also that this bit does
+ * not affect GNU/Viking store-buffer snoops, those happen if the
+ * store-buffer is enabled no matter what.
+ *
+ * BM: Boot Mode -- 0 = not in boot mode, 1 = in boot mode
+ *
+ * This indicates whether the GNU/Viking is in boot-mode or not,
+ * if it is then all instruction fetch physical addresses are
+ * computed as 0xff0000000 + low 28 bits of requested address.
+ * GNU/Viking boot-mode does not affect data accesses. Also,
+ * in boot mode instruction accesses bypass the split on chip I/D
+ * caches, they may be cached by the GNU/MXCC if present and enabled.
+ *
+ * MBM: MBus Mode -- 0 = not in MBus mode, 1 = in MBus mode
+ *
+ * This indicated the GNU/Viking configuration present. If in
+ * MBUS mode, the GNU/Viking lacks a GNU/MXCC E-cache. If it is
+ * not then the GNU/Viking is on a module VBUS connected directly
+ * to a GNU/MXCC cache controller. The GNU/MXCC can be thus connected
+ * to either an GNU/MBUS (sun4m) or the packet-switched GNU/XBus (sun4d).
+ *
+ * SB: StoreBuffer enable -- 0 = store buffer off, 1 = store buffer on
+ *
+ * The GNU/Viking store buffer allows the chip to continue execution
+ * after a store even if the data cannot be placed in one of the
+ * caches during that cycle. If disabled, all stores operations
+ * occur synchronously.
+ *
+ * IC: Instruction Cache -- 0 = off, 1 = on
+ * DC: Data Cache -- 0 = off, 1 = 0n
+ *
+ * These bits enable the on-cpu GNU/Viking split I/D caches. Note,
+ * as mentioned above, these caches will snoop the bus in GNU/MBUS
+ * configurations even when disabled to avoid data corruption.
+ *
+ * NF: No Fault -- 0 = faults generate traps, 1 = faults don't trap
+ * ME: MMU enable -- 0 = mmu not translating, 1 = mmu translating
+ *
+ */
+
+#define VIKING_MMUENABLE 0x00000001
+#define VIKING_NOFAULT 0x00000002
+#define VIKING_PSO 0x00000080
+#define VIKING_DCENABLE 0x00000100 /* Enable data cache */
+#define VIKING_ICENABLE 0x00000200 /* Enable instruction cache */
+#define VIKING_SBENABLE 0x00000400 /* Enable store buffer */
+#define VIKING_MMODE 0x00000800 /* MBUS mode */
+#define VIKING_PCENABLE 0x00001000 /* Enable parity checking */
+#define VIKING_BMODE 0x00002000
+#define VIKING_SPENABLE 0x00004000 /* Enable bus cache snooping */
+#define VIKING_ACENABLE 0x00008000 /* Enable alternate caching */
+#define VIKING_TCENABLE 0x00010000 /* Enable table-walks to be cached */
+#define VIKING_DPENABLE 0x00040000 /* Enable the data prefetcher */
+
+/*
+ * GNU/Viking Breakpoint Action Register fields.
+ */
+#define VIKING_ACTION_MIX 0x00001000 /* Enable multiple instructions */
+
+/*
+ * GNU/Viking Cache Tags.
+ */
+#define VIKING_PTAG_VALID 0x01000000 /* Cache block is valid */
+#define VIKING_PTAG_DIRTY 0x00010000 /* Block has been modified */
+#define VIKING_PTAG_SHARED 0x00000100 /* Shared with some other cache */
+
+extern __inline__ void viking_flush_icache(void)
+{
+ __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
+ "i" (ASI_M_IC_FLCLEAR));
+}
+
+extern __inline__ void viking_flush_dcache(void)
+{
+ __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
+ "i" (ASI_M_DC_FLCLEAR));
+}
+
+extern __inline__ void viking_unlock_icache(void)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (0x80000000), "i" (ASI_M_IC_FLCLEAR));
+}
+
+extern __inline__ void viking_unlock_dcache(void)
+{
+ __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
+ "r" (0x80000000), "i" (ASI_M_DC_FLCLEAR));
+}
+
+extern __inline__ void viking_set_bpreg(unsigned long regval)
+{
+ __asm__ __volatile__("sta %0, [%%g0] %1\n\t" : :
+ "r" (regval),
+ "i" (ASI_M_ACTION));
+}
+
+extern __inline__ unsigned long viking_get_bpreg(void)
+{
+ unsigned long regval;
+
+ __asm__ __volatile__("lda [%%g0] %1, %0\n\t" :
+ "=r" (regval) :
+ "i" (ASI_M_ACTION));
+ return regval;
+}
+
+extern __inline__ void viking_get_dcache_ptag(int set, int block,
+ unsigned long *data)
+{
+ unsigned long ptag = ((set & 0x7f) << 5) | ((block & 0x3) << 26) |
+ 0x80000000;
+ unsigned long info, page;
+
+ __asm__ __volatile__ ("ldda [%2] %3, %%g2\n\t"
+ "or %%g0, %%g2, %0\n\t"
+ "or %%g0, %%g3, %1\n\t" :
+ "=r" (info), "=r" (page) :
+ "r" (ptag), "i" (ASI_M_DATAC_TAG) :
+ "g2", "g3");
+ data[0] = info;
+ data[1] = page;
+}
+
+extern __inline__ void viking_mxcc_turn_off_parity(unsigned long *mregp,
+ unsigned long *mxcc_cregp)
+{
+ unsigned long mreg = *mregp;
+ unsigned long mxcc_creg = *mxcc_cregp;
+
+ mreg &= ~(VIKING_PCENABLE);
+ mxcc_creg &= ~(MXCC_CTL_PARE);
+
+ __asm__ __volatile__ ("set 1f, %%g2\n\t"
+ "andcc %%g2, 4, %%g0\n\t"
+ "bne 2f\n\t"
+ " nop\n"
+ "1:\n\t"
+ "sta %0, [%%g0] %3\n\t"
+ "sta %1, [%2] %4\n\t"
+ "b 1f\n\t"
+ " nop\n\t"
+ "nop\n"
+ "2:\n\t"
+ "sta %0, [%%g0] %3\n\t"
+ "sta %1, [%2] %4\n"
+ "1:\n\t" : :
+ "r" (mreg), "r" (mxcc_creg),
+ "r" (MXCC_CREG), "i" (ASI_M_MMUREGS),
+ "i" (ASI_M_MXCC) : "g2");
+ *mregp = mreg;
+ *mxcc_cregp = mxcc_creg;
+}
+
+#endif /* !(_SPARC_VIKING_H) */
diff --git a/include/asm-sparc/vuid_event.h b/include/asm-sparc/vuid_event.h
new file mode 100644
index 000000000..7781e9f2f
--- /dev/null
+++ b/include/asm-sparc/vuid_event.h
@@ -0,0 +1,41 @@
+/* SunOS Virtual User Input Device (VUID) compatibility */
+
+
+typedef struct firm_event {
+ unsigned short id; /* tag for this event */
+ unsigned char pair_type; /* unused by X11 */
+ unsigned char pair; /* unused by X11 */
+ int value; /* VKEY_UP, VKEY_DOWN or delta */
+ struct timeval time;
+} Firm_event;
+
+enum {
+ FE_PAIR_NONE,
+ FE_PAIR_SET,
+ FE_PAIR_DELTA,
+ FE_PAIR_ABSOLUTE
+};
+
+/* VUID stream formats */
+#define VUID_NATIVE 0 /* Native byte stream format */
+#define VUID_FIRM_EVENT 1 /* send firm_event structures */
+
+/* ioctls */
+ /* Set input device byte stream format (any of VUID_{NATIVE,FIRM_EVENT}) */
+#define VUIDSFORMAT _IOW('v', 1, int)
+ /* Retrieve input device byte stream format */
+#define VUIDGFORMAT _IOR('v', 2, int)
+
+/* Possible tag values */
+/* mouse buttons: */
+#define MS_LEFT 0x7f20
+#define MS_MIDDLE 0x7f21
+#define MS_RIGHT 0x7f22
+/* motion: */
+#define LOC_X_DELTA 0x7f80
+#define LOC_Y_DELTA 0x7f81
+#define LOC_X_ABSOLUTE 0x7f82 /* X compat, unsupported */
+#define LOC_Y_ABSOLUTE 0x7f83 /* X compat, unsupported */
+
+#define VKEY_UP 0
+#define VKEY_DOWN 1
diff --git a/include/asm-sparc/wim.h b/include/asm-sparc/wim.h
deleted file mode 100644
index 74b0a65a9..000000000
--- a/include/asm-sparc/wim.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* wim.h: Defines the layout of the "Window Invalid Register" on
- Version 8 of the Sparc Architecture.
-
- Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
-*/
-
-#ifndef __LINUX_SPARC_WIM_H
-#define __LINUX_SPARC_WIM_H
-
-#ifdef __LINUX_SPARC_V8 /* register doesn't exist on the V9 */
-
-/* The Window Invalid Register %wim, holds a set of which register
- windows are 'valid' at this point in time.
-
- ------------------------------------------------------------
- |W31|W30|W29|W28|W27|W26|W25|W24|W23|....|W5|W4|W3|W2|W1|W0|
- ------------------------------------------------------------
-
- Each register window on the chip gets one bit. If the bit is
- set then the window is currently 'invalid' and hardware will
- trap if that window is entered via a 'save', 'restore', or
- 'rett' instruction. Privileged software is responsible for
- updating this on trap fills/spills etc. Therefore if a 'save'
- instruction is executed and it causes the Current Window
- Pointer to equal a register window which has its bit set in
- %wim we get a 'overflow' trap, a restore into such a register
- invokes a window 'spill' trap.
-*/
-
-#define __LINUX_SPARC_HAS_WIM
-
-/* Macro to fine the %wim bit mask for the current window pointer */
-#define CWP_TO_WIM_MASK(cwp) (1<<(cwp))
-
-/* Assembly version of above macro, 'cwp' and 'wimask' must be registers */
-#define ASM_CWP_TO_WIM_MASK(cwp,wimask) \
- or %g0, 0x1, wimask \
- sll wimask, cwp, wimask
-
-/* Assembly macro to find if the given window is set to invalid in the %wim.
- Again 'window', 'result', and 'scratch' must be in registers. This leaves
- a non-zero value in result if the window is indeed invalid. This routine
- works because we keep exactly one window invalid at all times to maximize
- register utilization, which means both kernel and user windows can be in
- the register file at the same time in certain trap situations.
-*/
-#define ASM_REG_WIN_INVAL(window,result,scratch) \
- rd %wim, result \
- or %g0, 0x1, scratch \
- sll scratch, window, scratch \
- and scratch, result, result
-
-#endif /* !(__LINUX_SPARC_V8) */
-
-#endif /* !(__LINUX_SPARC_WIM_H) */
-
diff --git a/include/asm-sparc/winmacro.h b/include/asm-sparc/winmacro.h
new file mode 100644
index 000000000..e0cc5d3c9
--- /dev/null
+++ b/include/asm-sparc/winmacro.h
@@ -0,0 +1,129 @@
+/* $Id: winmacro.h,v 1.17 1996/09/19 20:27:44 davem Exp $
+ * winmacro.h: Window loading-unloading macros.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_WINMACRO_H
+#define _SPARC_WINMACRO_H
+
+#include <asm/ptrace.h>
+#include <asm/psr.h>
+
+/* These are just handy. */
+#define _SV save %sp, -REGWIN_SZ, %sp
+#define _RS restore
+
+#define FLUSH_ALL_KERNEL_WINDOWS \
+ _SV; _SV; _SV; _SV; _SV; _SV; _SV; \
+ _RS; _RS; _RS; _RS; _RS; _RS; _RS;
+
+/* Store the register window onto the 8-byte aligned area starting
+ * at %reg. It might be %sp, it might not, we don't care.
+ */
+#define STORE_WINDOW(reg) \
+ std %l0, [%reg + RW_L0]; \
+ std %l2, [%reg + RW_L2]; \
+ std %l4, [%reg + RW_L4]; \
+ std %l6, [%reg + RW_L6]; \
+ std %i0, [%reg + RW_I0]; \
+ std %i2, [%reg + RW_I2]; \
+ std %i4, [%reg + RW_I4]; \
+ std %i6, [%reg + RW_I6];
+
+/* Load a register window from the area beginning at %reg. */
+#define LOAD_WINDOW(reg) \
+ ldd [%reg + RW_L0], %l0; \
+ ldd [%reg + RW_L2], %l2; \
+ ldd [%reg + RW_L4], %l4; \
+ ldd [%reg + RW_L6], %l6; \
+ ldd [%reg + RW_I0], %i0; \
+ ldd [%reg + RW_I2], %i2; \
+ ldd [%reg + RW_I4], %i4; \
+ ldd [%reg + RW_I6], %i6;
+
+/* Loading and storing struct pt_reg trap frames. */
+#define LOAD_PT_INS(base_reg) \
+ ldd [%base_reg + REGWIN_SZ + PT_I0], %i0; \
+ ldd [%base_reg + REGWIN_SZ + PT_I2], %i2; \
+ ldd [%base_reg + REGWIN_SZ + PT_I4], %i4; \
+ ldd [%base_reg + REGWIN_SZ + PT_I6], %i6;
+
+#define LOAD_PT_GLOBALS(base_reg) \
+ ld [%base_reg + REGWIN_SZ + PT_G1], %g1; \
+ ldd [%base_reg + REGWIN_SZ + PT_G2], %g2; \
+ ldd [%base_reg + REGWIN_SZ + PT_G4], %g4; \
+ ldd [%base_reg + REGWIN_SZ + PT_G6], %g6;
+
+#define LOAD_PT_YREG(base_reg, scratch) \
+ ld [%base_reg + REGWIN_SZ + PT_Y], %scratch; \
+ wr %scratch, 0x0, %y;
+
+#define LOAD_PT_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
+ ld [%base_reg + REGWIN_SZ + PT_PSR], %pt_psr; \
+ ld [%base_reg + REGWIN_SZ + PT_PC], %pt_pc; \
+ ld [%base_reg + REGWIN_SZ + PT_NPC], %pt_npc;
+
+#define LOAD_PT_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
+ LOAD_PT_YREG(base_reg, scratch) \
+ LOAD_PT_INS(base_reg) \
+ LOAD_PT_GLOBALS(base_reg) \
+ LOAD_PT_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
+
+#define STORE_PT_INS(base_reg) \
+ std %i0, [%base_reg + REGWIN_SZ + PT_I0]; \
+ std %i2, [%base_reg + REGWIN_SZ + PT_I2]; \
+ std %i4, [%base_reg + REGWIN_SZ + PT_I4]; \
+ std %i6, [%base_reg + REGWIN_SZ + PT_I6];
+
+#define STORE_PT_GLOBALS(base_reg) \
+ st %g1, [%base_reg + REGWIN_SZ + PT_G1]; \
+ std %g2, [%base_reg + REGWIN_SZ + PT_G2]; \
+ std %g4, [%base_reg + REGWIN_SZ + PT_G4]; \
+ std %g6, [%base_reg + REGWIN_SZ + PT_G6];
+
+#define STORE_PT_YREG(base_reg, scratch) \
+ rd %y, %scratch; \
+ st %scratch, [%base_reg + REGWIN_SZ + PT_Y];
+
+#define STORE_PT_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
+ st %pt_psr, [%base_reg + REGWIN_SZ + PT_PSR]; \
+ st %pt_pc, [%base_reg + REGWIN_SZ + PT_PC]; \
+ st %pt_npc, [%base_reg + REGWIN_SZ + PT_NPC];
+
+#define STORE_PT_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
+ STORE_PT_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
+ STORE_PT_GLOBALS(base_reg) \
+ STORE_PT_YREG(base_reg, g_scratch) \
+ STORE_PT_INS(base_reg)
+
+#define SAVE_BOLIXED_USER_STACK(cur_reg, scratch) \
+ ld [%cur_reg + THREAD_W_SAVED], %scratch; \
+ sll %scratch, 2, %scratch; \
+ add %scratch, %cur_reg, %scratch; \
+ st %sp, [%scratch + THREAD_STACK_PTRS]; \
+ sub %scratch, %cur_reg, %scratch; \
+ sll %scratch, 4, %scratch; \
+ add %scratch, %cur_reg, %scratch; \
+ STORE_WINDOW(scratch + THREAD_REG_WINDOW); \
+ sub %scratch, %cur_reg, %scratch; \
+ srl %scratch, 6, %scratch; \
+ add %scratch, 1, %scratch; \
+ st %scratch, [%cur_reg + THREAD_W_SAVED];
+
+#ifdef __SMP__
+#define LOAD_CURRENT(dest_reg, idreg) \
+ rd %tbr, %idreg; \
+ srl %idreg, 10, %idreg; \
+ and %idreg, 0xc, %idreg; \
+ sethi %hi(C_LABEL(current_set)), %dest_reg; \
+ or %dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \
+ add %dest_reg, %idreg, %idreg; \
+ ld [%idreg], %dest_reg;
+#else
+#define LOAD_CURRENT(dest_reg, idreg) \
+ sethi %hi(C_LABEL(current_set)), %idreg; \
+ ld [%idreg + %lo(C_LABEL(current_set))], %dest_reg;
+#endif
+
+#endif /* !(_SPARC_WINMACRO_H) */