diff options
Diffstat (limited to 'include')
125 files changed, 6755 insertions, 4082 deletions
diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h index 0d1bf3246db0..797a71c0f1cf 100644 --- a/include/asm-mips/addrspace.h +++ b/include/asm-mips/addrspace.h @@ -4,67 +4,100 @@ * for more details. * * Copyright (C) 1996 by Ralf Baechle - * Copyright (C) 2000 by Maciej W. Rozycki + * Copyright (C) 2000, 2002 Maciej W. Rozycki * - * Defitions for the address spaces of the MIPS CPUs. + * Definitions for the address spaces of the MIPS CPUs. */ -#ifndef __ASM_MIPS_ADDRSPACE_H -#define __ASM_MIPS_ADDRSPACE_H +#ifndef __ASM_ADDRSPACE_H +#define __ASM_ADDRSPACE_H + +/* + * Configure language + */ +#ifdef __ASSEMBLY__ +#define _ATYPE_ +#define _ATYPE32_ +#define _ATYPE64_ +#else +#define _ATYPE_ __PTRDIFF_TYPE__ +#define _ATYPE32_ int +#define _ATYPE64_ long long +#endif + +/* + * 32-bit MIPS address spaces + */ +#ifdef __ASSEMBLY__ +#define _ACAST32_ +#define _ACAST64_ +#else +#define _ACAST32_ (_ATYPE_)(_ATYPE32_) /* widen if necessary */ +#define _ACAST64_ (_ATYPE64_) /* do _not_ narrow */ +#endif /* * Memory segments (32bit kernel mode addresses) */ -#define KUSEG 0x00000000 -#define KSEG0 0x80000000 -#define KSEG1 0xa0000000 -#define KSEG2 0xc0000000 -#define KSEG3 0xe0000000 +#define KUSEG 0x00000000 +#define KSEG0 0x80000000 +#define KSEG1 0xa0000000 +#define KSEG2 0xc0000000 +#define KSEG3 0xe0000000 -#define K0BASE KSEG0 +#define K0BASE KSEG0 /* * Returns the kernel segment base of a given address */ -#ifndef __ASSEMBLY__ -#define KSEGX(a) (((unsigned long)(a)) & 0xe0000000) -#else -#define KSEGX(a) ((a) & 0xe0000000) -#endif +#define KSEGX(a) ((_ACAST32_ (a)) & 0xe0000000) /* * Returns the physical address of a KSEG0/KSEG1 address */ -#ifndef __ASSEMBLY__ -#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff) -#else -#define PHYSADDR(a) ((a) & 0x1fffffff) -#endif +#define CPHYSADDR(a) ((_ACAST32_ (a)) & 0x1fffffff) + +#define PHYSADDR(a) CPHYSADDR(a) /* * Map an address to a certain kernel segment */ -#ifndef __ASSEMBLY__ -#define KSEG0ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG0)) -#define KSEG1ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG1)) -#define KSEG2ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG2)) -#define KSEG3ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG3)) -#else -#define KSEG0ADDR(a) (((a) & 0x1fffffff) | KSEG0) -#define KSEG1ADDR(a) (((a) & 0x1fffffff) | KSEG1) -#define KSEG2ADDR(a) (((a) & 0x1fffffff) | KSEG2) -#define KSEG3ADDR(a) (((a) & 0x1fffffff) | KSEG3) -#endif +#define KSEG0ADDR(a) (CPHYSADDR(a) | KSEG0) +#define KSEG1ADDR(a) (CPHYSADDR(a) | KSEG1) +#define KSEG2ADDR(a) (CPHYSADDR(a) | KSEG2) +#define KSEG3ADDR(a) (CPHYSADDR(a) | KSEG3) /* * Memory segments (64bit kernel mode addresses) */ -#define XKUSEG 0x0000000000000000 -#define XKSSEG 0x4000000000000000 -#define XKPHYS 0x8000000000000000 -#define XKSEG 0xc000000000000000 -#define CKSEG0 0xffffffff80000000 -#define CKSEG1 0xffffffffa0000000 -#define CKSSEG 0xffffffffc0000000 -#define CKSEG3 0xffffffffe0000000 +#define XKUSEG 0x0000000000000000 +#define XKSSEG 0x4000000000000000 +#define XKPHYS 0x8000000000000000 +#define XKSEG 0xc000000000000000 +#define CKSEG0 0xffffffff80000000 +#define CKSEG1 0xffffffffa0000000 +#define CKSSEG 0xffffffffc0000000 +#define CKSEG3 0xffffffffe0000000 + +/* + * Cache modes for XKPHYS address conversion macros + */ +#define K_CALG_COH_EXCL1_NOL2 0 +#define K_CALG_COH_SHRL1_NOL2 1 +#define K_CALG_UNCACHED 2 +#define K_CALG_NONCOHERENT 3 +#define K_CALG_COH_EXCL 4 +#define K_CALG_COH_SHAREABLE 5 +#define K_CALG_NOTUSED 6 +#define K_CALG_UNCACHED_ACCEL 7 + +#define TO_PHYS_MASK 0xfffffffffULL /* 36 bit */ + +/* + * 64-bit address conversions + */ +#define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED,(p)) +#define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE,(p)) +#define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK) +#define PHYS_TO_XKPHYS(cm,a) (0x8000000000000000 | ((cm)<<59) | (a)) -#endif /* __ASM_MIPS_ADDRSPACE_H */ +#endif /* __ASM_ADDRSPACE_H */ diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h index 22d773b17e0f..db92a744289e 100644 --- a/include/asm-mips/asm.h +++ b/include/asm-mips/asm.h @@ -1,11 +1,10 @@ /* - * include/asm-mips/asm.h - * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle + * Copyright (C) 2002 Maciej W. Rozycki * * Some useful macros for MIPS assembler code * @@ -16,6 +15,7 @@ #ifndef __ASM_ASM_H #define __ASM_ASM_H +#include <linux/config.h> #include <asm/sgidefs.h> #ifndef CAT @@ -28,16 +28,6 @@ #endif /* - * Macros to handle different pointer/register sizes for 32/64-bit code - * - * 64 bit address space isn't used yet, so we may use the R3000 32 bit - * defines for now. - */ -#define PTR .word -#define PTRSIZE 4 -#define PTRLOG 2 - -/* * PIC specific declarations * Not used for the kernel but here seems to be the right place. */ @@ -106,7 +96,7 @@ symbol = value #define PANIC(msg) \ .set push; \ .set reorder; \ - la a0,8f; \ + PTR_LA a0,8f; \ jal panic; \ 9: b 9b; \ .set pop; \ @@ -118,26 +108,26 @@ symbol = value #define PRINT(string) \ .set push; \ .set reorder; \ - la a0,8f; \ + PTR_LA a0,8f; \ jal printk; \ .set pop; \ TEXT(string) #define TEXT(msg) \ - .data; \ + .pushsection .data; \ 8: .asciiz msg; \ - .previous; + .popsection; /* * Build text tables */ #define TTABLE(string) \ - .text; \ + .pushsection .text; \ .word 1f; \ - .previous; \ - .data; \ -1: .asciz string; \ - .previous + .popsection \ + .pushsection .data; \ +1: .asciiz string; \ + .popsection /* * MIPS IV pref instruction. @@ -146,16 +136,26 @@ symbol = value * MIPS IV implementations are free to treat this as a nop. The R5000 * is one of them. So we should have an option not to use this instruction. */ -#if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS64) +#if CONFIG_CPU_HAS_PREFETCH + #define PREF(hint,addr) \ - pref hint,addr + .set push; \ + .set mips4; \ + pref hint,addr; \ + .set pop + #define PREFX(hint,addr) \ - prefx hint,addr -#else -#define PREF -#define PREFX -#endif + .set push; \ + .set mips4; \ + prefx hint,addr; \ + .set pop + +#else /* !CONFIG_CPU_HAS_PREFETCH */ + +#define PREF(hint,addr) +#define PREFX(hint,addr) + +#endif /* !CONFIG_CPU_HAS_PREFETCH */ /* * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. @@ -163,16 +163,16 @@ symbol = value #if (_MIPS_ISA == _MIPS_ISA_MIPS1) #define MOVN(rd,rs,rt) \ .set push; \ - .set noreorder; \ + .set reorder; \ beqz rt,9f; \ move rd,rs; \ .set pop; \ 9: #define MOVZ(rd,rs,rt) \ .set push; \ - .set noreorder; \ + .set reorder; \ bnez rt,9f; \ - move rd,rt; \ + move rd,rs; \ .set pop; \ 9: #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ @@ -181,24 +181,24 @@ symbol = value .set push; \ .set noreorder; \ bnezl rt,9f; \ - move rd,rs; \ + move rd,rs; \ .set pop; \ 9: #define MOVZ(rd,rs,rt) \ .set push; \ .set noreorder; \ beqzl rt,9f; \ - movz rd,rs; \ + move rd,rs; \ .set pop; \ 9: #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS64) + (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) #define MOVN(rd,rs,rt) \ movn rd,rs,rt #define MOVZ(rd,rs,rt) \ movz rd,rs,rt -#endif /* MIPS IV, MIPS V or MIPS64 */ +#endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */ /* * Stack alignment @@ -215,6 +215,10 @@ symbol = value #endif /* + * Macros to handle different pointer/register sizes for 32/64-bit code + */ + +/* * Size of a register */ #ifdef __mips64 @@ -229,59 +233,54 @@ symbol = value */ #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ (_MIPS_ISA == _MIPS_ISA_MIPS32) -#define REG_S sw -#define REG_L lw -#define PTR_SUBU subu -#define PTR_ADDU addu +#define REG_S sw +#define REG_L lw +#define REG_SUBU subu +#define REG_ADDU addu #endif #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64) -#define REG_S sd -#define REG_L ld -/* We still live in a 32 bit address space ... */ -#define PTR_SUBU subu -#define PTR_ADDU addu +#define REG_S sd +#define REG_L ld +#define REG_SUBU dsubu +#define REG_ADDU daddu #endif /* * How to add/sub/load/store/shift C int variables. */ #if (_MIPS_SZINT == 32) -#define INT_ADD add -#define INT_ADDI addi +#define INT_ADD add #define INT_ADDU addu +#define INT_ADDI addi #define INT_ADDIU addiu -#define INT_SUB add -#define INT_SUBI subi +#define INT_SUB sub #define INT_SUBU subu -#define INT_SUBIU subu #define INT_L lw #define INT_S sw -#define LONG_SLL sll -#define LONG_SLLV sllv -#define LONG_SRL srl -#define LONG_SRLV srlv -#define LONG_SRA sra -#define LONG_SRAV srav +#define INT_SLL sll +#define INT_SLLV sllv +#define INT_SRL srl +#define INT_SRLV srlv +#define INT_SRA sra +#define INT_SRAV srav #endif #if (_MIPS_SZINT == 64) -#define INT_ADD dadd -#define INT_ADDI daddi +#define INT_ADD dadd #define INT_ADDU daddu +#define INT_ADDI daddi #define INT_ADDIU daddiu -#define INT_SUB dadd -#define INT_SUBI dsubi +#define INT_SUB dsub #define INT_SUBU dsubu -#define INT_SUBIU dsubu #define INT_L ld #define INT_S sd -#define LONG_SLL dsll -#define LONG_SLLV dsllv -#define LONG_SRL dsrl -#define LONG_SRLV dsrlv -#define LONG_SRA dsra -#define LONG_SRAV dsrav +#define INT_SLL dsll +#define INT_SLLV dsllv +#define INT_SRL dsrl +#define INT_SRLV dsrlv +#define INT_SRA dsra +#define INT_SRAV dsrav #endif /* @@ -289,13 +288,11 @@ symbol = value */ #if (_MIPS_SZLONG == 32) #define LONG_ADD add -#define LONG_ADDI addi #define LONG_ADDU addu +#define LONG_ADDI addi #define LONG_ADDIU addiu -#define LONG_SUB add -#define LONG_SUBI subi +#define LONG_SUB sub #define LONG_SUBU subu -#define LONG_SUBIU subu #define LONG_L lw #define LONG_S sw #define LONG_SLL sll @@ -308,13 +305,11 @@ symbol = value #if (_MIPS_SZLONG == 64) #define LONG_ADD dadd -#define LONG_ADDI daddi #define LONG_ADDU daddu +#define LONG_ADDI daddi #define LONG_ADDIU daddiu -#define LONG_SUB dadd -#define LONG_SUBI dsubi +#define LONG_SUB dsub #define LONG_SUBU dsubu -#define LONG_SUBIU dsubu #define LONG_L ld #define LONG_S sd #define LONG_SLL dsll @@ -328,17 +323,16 @@ symbol = value /* * How to add/sub/load/store/shift pointers. */ -#if (_MIPS_SZLONG == 32) -#define PTR_ADD add -#define PTR_ADDI addi +#if (_MIPS_SZPTR == 32) +#define PTR_ADD add #define PTR_ADDU addu +#define PTR_ADDI addi #define PTR_ADDIU addiu -#define PTR_SUB add -#define PTR_SUBI subi +#define PTR_SUB sub #define PTR_SUBU subu -#define PTR_SUBIU subu #define PTR_L lw #define PTR_S sw +#define PTR_LA la #define PTR_SLL sll #define PTR_SLLV sllv #define PTR_SRL srl @@ -347,19 +341,22 @@ symbol = value #define PTR_SRAV srav #define PTR_SCALESHIFT 2 + +#define PTR .word +#define PTRSIZE 4 +#define PTRLOG 2 #endif -#if (_MIPS_SZLONG == 64) -#define PTR_ADD dadd -#define PTR_ADDI daddi +#if (_MIPS_SZPTR == 64) +#define PTR_ADD dadd #define PTR_ADDU daddu +#define PTR_ADDI daddi #define PTR_ADDIU daddiu -#define PTR_SUB dadd -#define PTR_SUBI dsubi +#define PTR_SUB dsub #define PTR_SUBU dsubu -#define PTR_SUBIU dsubu #define PTR_L ld #define PTR_S sd +#define PTR_LA dla #define PTR_SLL dsll #define PTR_SLLV dsllv #define PTR_SRL dsrl @@ -368,6 +365,10 @@ symbol = value #define PTR_SRAV dsrav #define PTR_SCALESHIFT 3 + +#define PTR .dword +#define PTRSIZE 8 +#define PTRLOG 3 #endif /* @@ -375,13 +376,15 @@ symbol = value */ #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ (_MIPS_ISA == _MIPS_ISA_MIPS32) -#define MFC0 mfc0 -#define MTC0 mtc0 +#define MFC0 mfc0 +#define MTC0 mtc0 #endif #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64) -#define MFC0 dmfc0 -#define MTC0 dmtc0 +#define MFC0 dmfc0 +#define MTC0 dmtc0 #endif +#define SSNOP sll zero,zero,1 + #endif /* __ASM_ASM_H */ diff --git a/include/asm-mips/asmmacro.h b/include/asm-mips/asmmacro.h index 7becc9bd1ae2..d4cc46162567 100644 --- a/include/asm-mips/asmmacro.h +++ b/include/asm-mips/asmmacro.h @@ -7,8 +7,22 @@ #ifndef _ASM_ASMMACRO_H #define _ASM_ASMMACRO_H +#include <linux/config.h> #include <asm/offset.h> +#ifdef CONFIG_CPU_SB1 +#define FPU_ENABLE_HAZARD \ + .set push; \ + .set noreorder; \ + .set mips2; \ + SSNOP; \ + bnezl $0, .+4; \ + SSNOP; \ + .set pop +#else +#define FPU_ENABLE_HAZARD +#endif + #define FPU_SAVE_DOUBLE(thread, tmp) \ cfc1 tmp, fcr31; \ sdc1 $f0, (THREAD_FPU + 0x000)(thread); \ @@ -29,41 +43,81 @@ sdc1 $f30, (THREAD_FPU + 0x0f0)(thread); \ sw tmp, (THREAD_FPU + 0x100)(thread) +#if defined (__MIPSEL__) #define FPU_SAVE_SINGLE(thread,tmp) \ cfc1 tmp, fcr31; \ swc1 $f0, (THREAD_FPU + 0x000)(thread); \ - swc1 $f1, (THREAD_FPU + 0x008)(thread); \ + swc1 $f1, (THREAD_FPU + 0x004)(thread); \ swc1 $f2, (THREAD_FPU + 0x010)(thread); \ - swc1 $f3, (THREAD_FPU + 0x018)(thread); \ + swc1 $f3, (THREAD_FPU + 0x014)(thread); \ swc1 $f4, (THREAD_FPU + 0x020)(thread); \ - swc1 $f5, (THREAD_FPU + 0x028)(thread); \ + swc1 $f5, (THREAD_FPU + 0x024)(thread); \ swc1 $f6, (THREAD_FPU + 0x030)(thread); \ - swc1 $f7, (THREAD_FPU + 0x038)(thread); \ + swc1 $f7, (THREAD_FPU + 0x034)(thread); \ swc1 $f8, (THREAD_FPU + 0x040)(thread); \ - swc1 $f9, (THREAD_FPU + 0x048)(thread); \ + swc1 $f9, (THREAD_FPU + 0x044)(thread); \ swc1 $f10, (THREAD_FPU + 0x050)(thread); \ - swc1 $f11, (THREAD_FPU + 0x058)(thread); \ + swc1 $f11, (THREAD_FPU + 0x054)(thread); \ swc1 $f12, (THREAD_FPU + 0x060)(thread); \ - swc1 $f13, (THREAD_FPU + 0x068)(thread); \ + swc1 $f13, (THREAD_FPU + 0x064)(thread); \ swc1 $f14, (THREAD_FPU + 0x070)(thread); \ - swc1 $f15, (THREAD_FPU + 0x078)(thread); \ + swc1 $f15, (THREAD_FPU + 0x074)(thread); \ swc1 $f16, (THREAD_FPU + 0x080)(thread); \ - swc1 $f17, (THREAD_FPU + 0x088)(thread); \ + swc1 $f17, (THREAD_FPU + 0x084)(thread); \ swc1 $f18, (THREAD_FPU + 0x090)(thread); \ - swc1 $f19, (THREAD_FPU + 0x098)(thread); \ + swc1 $f19, (THREAD_FPU + 0x094)(thread); \ swc1 $f20, (THREAD_FPU + 0x0a0)(thread); \ - swc1 $f21, (THREAD_FPU + 0x0a8)(thread); \ + swc1 $f21, (THREAD_FPU + 0x0a4)(thread); \ swc1 $f22, (THREAD_FPU + 0x0b0)(thread); \ - swc1 $f23, (THREAD_FPU + 0x0b8)(thread); \ + swc1 $f23, (THREAD_FPU + 0x0b4)(thread); \ swc1 $f24, (THREAD_FPU + 0x0c0)(thread); \ - swc1 $f25, (THREAD_FPU + 0x0c8)(thread); \ + swc1 $f25, (THREAD_FPU + 0x0c4)(thread); \ swc1 $f26, (THREAD_FPU + 0x0d0)(thread); \ - swc1 $f27, (THREAD_FPU + 0x0d8)(thread); \ + swc1 $f27, (THREAD_FPU + 0x0d4)(thread); \ swc1 $f28, (THREAD_FPU + 0x0e0)(thread); \ - swc1 $f29, (THREAD_FPU + 0x0e8)(thread); \ + swc1 $f29, (THREAD_FPU + 0x0e4)(thread); \ swc1 $f30, (THREAD_FPU + 0x0f0)(thread); \ - swc1 $f31, (THREAD_FPU + 0x0f8)(thread); \ + swc1 $f31, (THREAD_FPU + 0x0f4)(thread); \ + sw tmp, (THREAD_FPU + 0x100)(thread) +#elif defined (__MIPSEB__) +#define FPU_SAVE_SINGLE(thread,tmp) \ + cfc1 tmp, fcr31; \ + swc1 $f0, (THREAD_FPU + 0x004)(thread); \ + swc1 $f1, (THREAD_FPU + 0x000)(thread); \ + swc1 $f2, (THREAD_FPU + 0x014)(thread); \ + swc1 $f3, (THREAD_FPU + 0x010)(thread); \ + swc1 $f4, (THREAD_FPU + 0x024)(thread); \ + swc1 $f5, (THREAD_FPU + 0x020)(thread); \ + swc1 $f6, (THREAD_FPU + 0x034)(thread); \ + swc1 $f7, (THREAD_FPU + 0x030)(thread); \ + swc1 $f8, (THREAD_FPU + 0x044)(thread); \ + swc1 $f9, (THREAD_FPU + 0x040)(thread); \ + swc1 $f10, (THREAD_FPU + 0x054)(thread); \ + swc1 $f11, (THREAD_FPU + 0x050)(thread); \ + swc1 $f12, (THREAD_FPU + 0x064)(thread); \ + swc1 $f13, (THREAD_FPU + 0x060)(thread); \ + swc1 $f14, (THREAD_FPU + 0x074)(thread); \ + swc1 $f15, (THREAD_FPU + 0x070)(thread); \ + swc1 $f16, (THREAD_FPU + 0x084)(thread); \ + swc1 $f17, (THREAD_FPU + 0x080)(thread); \ + swc1 $f18, (THREAD_FPU + 0x094)(thread); \ + swc1 $f19, (THREAD_FPU + 0x090)(thread); \ + swc1 $f20, (THREAD_FPU + 0x0a4)(thread); \ + swc1 $f21, (THREAD_FPU + 0x0a0)(thread); \ + swc1 $f22, (THREAD_FPU + 0x0b4)(thread); \ + swc1 $f23, (THREAD_FPU + 0x0b0)(thread); \ + swc1 $f24, (THREAD_FPU + 0x0c4)(thread); \ + swc1 $f25, (THREAD_FPU + 0x0c0)(thread); \ + swc1 $f26, (THREAD_FPU + 0x0d4)(thread); \ + swc1 $f27, (THREAD_FPU + 0x0d0)(thread); \ + swc1 $f28, (THREAD_FPU + 0x0e4)(thread); \ + swc1 $f29, (THREAD_FPU + 0x0e0)(thread); \ + swc1 $f30, (THREAD_FPU + 0x0f4)(thread); \ + swc1 $f31, (THREAD_FPU + 0x0f0)(thread); \ sw tmp, (THREAD_FPU + 0x100)(thread) +#else +#error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???" +#endif #define FPU_RESTORE_DOUBLE(thread, tmp) \ lw tmp, (THREAD_FPU + 0x100)(thread); \ @@ -85,41 +139,81 @@ ldc1 $f30, (THREAD_FPU + 0x0f0)(thread); \ ctc1 tmp, fcr31 +#if defined (__MIPSEL__) #define FPU_RESTORE_SINGLE(thread,tmp) \ lw tmp, (THREAD_FPU + 0x100)(thread); \ lwc1 $f0, (THREAD_FPU + 0x000)(thread); \ - lwc1 $f1, (THREAD_FPU + 0x008)(thread); \ + lwc1 $f1, (THREAD_FPU + 0x004)(thread); \ lwc1 $f2, (THREAD_FPU + 0x010)(thread); \ - lwc1 $f3, (THREAD_FPU + 0x018)(thread); \ + lwc1 $f3, (THREAD_FPU + 0x014)(thread); \ lwc1 $f4, (THREAD_FPU + 0x020)(thread); \ - lwc1 $f5, (THREAD_FPU + 0x028)(thread); \ + lwc1 $f5, (THREAD_FPU + 0x024)(thread); \ lwc1 $f6, (THREAD_FPU + 0x030)(thread); \ - lwc1 $f7, (THREAD_FPU + 0x038)(thread); \ + lwc1 $f7, (THREAD_FPU + 0x034)(thread); \ lwc1 $f8, (THREAD_FPU + 0x040)(thread); \ - lwc1 $f9, (THREAD_FPU + 0x048)(thread); \ + lwc1 $f9, (THREAD_FPU + 0x044)(thread); \ lwc1 $f10, (THREAD_FPU + 0x050)(thread); \ - lwc1 $f11, (THREAD_FPU + 0x058)(thread); \ + lwc1 $f11, (THREAD_FPU + 0x054)(thread); \ lwc1 $f12, (THREAD_FPU + 0x060)(thread); \ - lwc1 $f13, (THREAD_FPU + 0x068)(thread); \ + lwc1 $f13, (THREAD_FPU + 0x064)(thread); \ lwc1 $f14, (THREAD_FPU + 0x070)(thread); \ - lwc1 $f15, (THREAD_FPU + 0x078)(thread); \ + lwc1 $f15, (THREAD_FPU + 0x074)(thread); \ lwc1 $f16, (THREAD_FPU + 0x080)(thread); \ - lwc1 $f17, (THREAD_FPU + 0x088)(thread); \ + lwc1 $f17, (THREAD_FPU + 0x084)(thread); \ lwc1 $f18, (THREAD_FPU + 0x090)(thread); \ - lwc1 $f19, (THREAD_FPU + 0x098)(thread); \ + lwc1 $f19, (THREAD_FPU + 0x094)(thread); \ lwc1 $f20, (THREAD_FPU + 0x0a0)(thread); \ - lwc1 $f21, (THREAD_FPU + 0x0a8)(thread); \ + lwc1 $f21, (THREAD_FPU + 0x0a4)(thread); \ lwc1 $f22, (THREAD_FPU + 0x0b0)(thread); \ - lwc1 $f23, (THREAD_FPU + 0x0b8)(thread); \ + lwc1 $f23, (THREAD_FPU + 0x0b4)(thread); \ lwc1 $f24, (THREAD_FPU + 0x0c0)(thread); \ - lwc1 $f25, (THREAD_FPU + 0x0c8)(thread); \ + lwc1 $f25, (THREAD_FPU + 0x0c4)(thread); \ lwc1 $f26, (THREAD_FPU + 0x0d0)(thread); \ - lwc1 $f27, (THREAD_FPU + 0x0d8)(thread); \ + lwc1 $f27, (THREAD_FPU + 0x0d4)(thread); \ lwc1 $f28, (THREAD_FPU + 0x0e0)(thread); \ - lwc1 $f29, (THREAD_FPU + 0x0e8)(thread); \ + lwc1 $f29, (THREAD_FPU + 0x0e4)(thread); \ lwc1 $f30, (THREAD_FPU + 0x0f0)(thread); \ - lwc1 $f31, (THREAD_FPU + 0x0f8)(thread); \ + lwc1 $f31, (THREAD_FPU + 0x0f4)(thread); \ + ctc1 tmp, fcr31 +#elif defined (__MIPSEB__) +#define FPU_RESTORE_SINGLE(thread,tmp) \ + lw tmp, (THREAD_FPU + 0x100)(thread); \ + lwc1 $f0, (THREAD_FPU + 0x004)(thread); \ + lwc1 $f1, (THREAD_FPU + 0x000)(thread); \ + lwc1 $f2, (THREAD_FPU + 0x014)(thread); \ + lwc1 $f3, (THREAD_FPU + 0x010)(thread); \ + lwc1 $f4, (THREAD_FPU + 0x024)(thread); \ + lwc1 $f5, (THREAD_FPU + 0x020)(thread); \ + lwc1 $f6, (THREAD_FPU + 0x034)(thread); \ + lwc1 $f7, (THREAD_FPU + 0x030)(thread); \ + lwc1 $f8, (THREAD_FPU + 0x044)(thread); \ + lwc1 $f9, (THREAD_FPU + 0x040)(thread); \ + lwc1 $f10, (THREAD_FPU + 0x054)(thread); \ + lwc1 $f11, (THREAD_FPU + 0x050)(thread); \ + lwc1 $f12, (THREAD_FPU + 0x064)(thread); \ + lwc1 $f13, (THREAD_FPU + 0x060)(thread); \ + lwc1 $f14, (THREAD_FPU + 0x074)(thread); \ + lwc1 $f15, (THREAD_FPU + 0x070)(thread); \ + lwc1 $f16, (THREAD_FPU + 0x084)(thread); \ + lwc1 $f17, (THREAD_FPU + 0x080)(thread); \ + lwc1 $f18, (THREAD_FPU + 0x094)(thread); \ + lwc1 $f19, (THREAD_FPU + 0x090)(thread); \ + lwc1 $f20, (THREAD_FPU + 0x0a4)(thread); \ + lwc1 $f21, (THREAD_FPU + 0x0a0)(thread); \ + lwc1 $f22, (THREAD_FPU + 0x0b4)(thread); \ + lwc1 $f23, (THREAD_FPU + 0x0b0)(thread); \ + lwc1 $f24, (THREAD_FPU + 0x0c4)(thread); \ + lwc1 $f25, (THREAD_FPU + 0x0c0)(thread); \ + lwc1 $f26, (THREAD_FPU + 0x0d4)(thread); \ + lwc1 $f27, (THREAD_FPU + 0x0d0)(thread); \ + lwc1 $f28, (THREAD_FPU + 0x0e4)(thread); \ + lwc1 $f29, (THREAD_FPU + 0x0e0)(thread); \ + lwc1 $f30, (THREAD_FPU + 0x0f4)(thread); \ + lwc1 $f31, (THREAD_FPU + 0x0f0)(thread); \ ctc1 tmp, fcr31 +#else +#error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???" +#endif #define CPU_SAVE_NONSCRATCH(thread) \ sw s0, THREAD_REG16(thread); \ diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h index bb017f91830a..9c8af4c017c1 100644 --- a/include/asm-mips/atomic.h +++ b/include/asm-mips/atomic.h @@ -57,12 +57,11 @@ typedef struct { volatile int counter; } atomic_t; */ extern __inline__ void atomic_add(int i, atomic_t * v) { - int flags; + unsigned long flags; - save_flags(flags); - cli(); + local_irq_save(flags); v->counter += i; - restore_flags(flags); + local_irq_restore(flags); } /* @@ -75,38 +74,37 @@ extern __inline__ void atomic_add(int i, atomic_t * v) */ extern __inline__ void atomic_sub(int i, atomic_t * v) { - int flags; + unsigned long flags; - save_flags(flags); - cli(); + local_irq_save(flags); v->counter -= i; - restore_flags(flags); + local_irq_restore(flags); } extern __inline__ int atomic_add_return(int i, atomic_t * v) { - int temp, flags; + unsigned long flags; + int temp; - save_flags(flags); - cli(); + local_irq_save(flags); temp = v->counter; temp += i; v->counter = temp; - restore_flags(flags); + local_irq_restore(flags); return temp; } extern __inline__ int atomic_sub_return(int i, atomic_t * v) { - int temp, flags; + unsigned long flags; + int temp; - save_flags(flags); - cli(); + local_irq_save(flags); temp = v->counter; temp -= i; v->counter = temp; - restore_flags(flags); + local_irq_restore(flags); return temp; } @@ -175,6 +173,7 @@ extern __inline__ int atomic_add_return(int i, atomic_t * v) " sc %0, %2 \n" " beqz %0, 1b \n" " addu %0, %1, %3 \n" + " sync \n" ".set pop \n" : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) @@ -195,6 +194,7 @@ extern __inline__ int atomic_sub_return(int i, atomic_t * v) " sc %0, %2 \n" " beqz %0, 1b \n" " subu %0, %1, %3 \n" + " sync \n" ".set pop \n" : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) @@ -228,7 +228,7 @@ extern __inline__ int atomic_sub_return(int i, atomic_t * v) * other cases. Note that the guaranteed * useful range of an atomic_t is only 24 bits. */ -#define atomic_inc_and_test(v) (atomic_inc_return(1, (v)) == 0) +#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) /* * atomic_dec_and_test - decrement by 1 and test @@ -268,15 +268,14 @@ extern __inline__ int atomic_sub_return(int i, atomic_t * v) * if the result is negative, or false when * result is greater than or equal to zero. Note that the guaranteed * useful range of an atomic_t is only 24 bits. - * - * Currently not implemented for MIPS. */ +#define atomic_add_negative(i,v) (atomic_add_return(i, (v)) < 0) /* Atomic operations are already serializing */ -#define smp_mb__before_atomic_dec() barrier() -#define smp_mb__after_atomic_dec() barrier() -#define smp_mb__before_atomic_inc() barrier() -#define smp_mb__after_atomic_inc() barrier() +#define smp_mb__before_atomic_dec() smp_mb() +#define smp_mb__after_atomic_dec() smp_mb() +#define smp_mb__before_atomic_inc() smp_mb() +#define smp_mb__after_atomic_inc() smp_mb() #endif /* defined(__KERNEL__) */ diff --git a/include/asm-mips/bcache.h b/include/asm-mips/bcache.h index e7c8071b003e..446102b34f4e 100644 --- a/include/asm-mips/bcache.h +++ b/include/asm-mips/bcache.h @@ -3,8 +3,8 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 1997, 1999, 2000 by Ralf Baechle - * Copyright (c) 2000 by Silicon Graphics, Inc. + * Copyright (c) 1997, 1999 by Ralf Baechle + * Copyright (c) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_BCACHE_H #define _ASM_BCACHE_H @@ -28,22 +28,22 @@ extern void sni_pcimt_sc_init(void); extern struct bcache_ops *bcops; -extern inline void bc_enable(void) +static inline void bc_enable(void) { bcops->bc_enable(); } -extern inline void bc_disable(void) +static inline void bc_disable(void) { bcops->bc_disable(); } -extern inline void bc_wback_inv(unsigned long page, unsigned long size) +static inline void bc_wback_inv(unsigned long page, unsigned long size) { bcops->bc_wback_inv(page, size); } -extern inline void bc_inv(unsigned long page, unsigned long size) +static inline void bc_inv(unsigned long page, unsigned long size) { bcops->bc_inv(page, size); } diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index d76387979544..7c9b6f51a9bb 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h @@ -9,42 +9,49 @@ #ifndef _ASM_BITOPS_H #define _ASM_BITOPS_H +#include <linux/config.h> +#include <linux/compiler.h> #include <linux/types.h> #include <asm/byteorder.h> /* sigh ... */ +#if (_MIPS_SZLONG == 32) +#define SZLONG_LOG 5 +#define SZLONG_MASK 31UL +#elif (_MIPS_SZLONG == 64) +#define SZLONG_LOG 6 +#define SZLONG_MASK 63UL +#endif + #ifdef __KERNEL__ #include <asm/sgidefs.h> #include <asm/system.h> -#include <linux/config.h> /* * clear_bit() doesn't provide any barrier for the compiler. */ -#define smp_mb__before_clear_bit() barrier() -#define smp_mb__after_clear_bit() barrier() +#define smp_mb__before_clear_bit() smp_mb() +#define smp_mb__after_clear_bit() smp_mb() /* * Only disable interrupt for kernel mode stuff to keep usermode stuff * that dares to use kernel include files alive. */ -#define __bi_flags unsigned long flags -#define __bi_cli() local_irq_disable() -#define __bi_save_flags(x) local_save_flags(x) -#define __bi_save_and_cli(x) local_irq_save(x) -#define __bi_restore_flags(x) local_irq_restore(x) +#define __bi_flags unsigned long flags +#define __bi_cli() local_irq_disable() +#define __bi_save_flags(x) local_save_flags(x) +#define __bi_local_irq_save(x) local_irq_save(x) +#define __bi_local_irq_restore(x) local_irq_restore(x) #else #define __bi_flags #define __bi_cli() #define __bi_save_flags(x) -#define __bi_save_and_cli(x) -#define __bi_restore_flags(x) +#define __bi_local_irq_save(x) +#define __bi_local_irq_restore(x) #endif /* __KERNEL__ */ #ifdef CONFIG_CPU_HAS_LLSC -#include <asm/mipsregs.h> - /* * These functions for MIPS ISA > 1 are interrupt and SMP proof and * interrupt friendly @@ -60,8 +67,7 @@ * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -extern __inline__ void -set_bit(int nr, volatile void *addr) +static __inline__ void set_bit(int nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 5); unsigned long temp; @@ -84,7 +90,7 @@ set_bit(int nr, volatile void *addr) * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -extern __inline__ void __set_bit(int nr, volatile void * addr) +static __inline__ void __set_bit(int nr, volatile unsigned long * addr) { unsigned long * m = ((unsigned long *) addr) + (nr >> 5); @@ -101,8 +107,7 @@ extern __inline__ void __set_bit(int nr, volatile void * addr) * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() * in order to ensure changes are visible on other processors. */ -extern __inline__ void -clear_bit(int nr, volatile void *addr) +static __inline__ void clear_bit(int nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 5); unsigned long temp; @@ -117,6 +122,22 @@ clear_bit(int nr, volatile void *addr) } /* + * __clear_bit - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * Unlike clear_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __inline__ void __clear_bit(int nr, volatile unsigned long * addr) +{ + unsigned long * m = ((unsigned long *) addr) + (nr >> 5); + + *m &= ~(1UL << (nr & 31)); +} + +/* * change_bit - Toggle a bit in memory * @nr: Bit to clear * @addr: Address to start counting from @@ -125,8 +146,7 @@ clear_bit(int nr, volatile void *addr) * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -extern __inline__ void -change_bit(int nr, volatile void *addr) +static __inline__ void change_bit(int nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 5); unsigned long temp; @@ -142,14 +162,14 @@ change_bit(int nr, volatile void *addr) /* * __change_bit - Toggle a bit in memory - * @nr: the bit to set + * @nr: the bit to change * @addr: the address to start counting from * * Unlike change_bit(), this function is non-atomic and may be reordered. * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -extern __inline__ void __change_bit(int nr, volatile void * addr) +static __inline__ void __change_bit(int nr, volatile unsigned long * addr) { unsigned long * m = ((unsigned long *) addr) + (nr >> 5); @@ -161,14 +181,14 @@ extern __inline__ void __change_bit(int nr, volatile void * addr) * @nr: Bit to set * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ int -test_and_set_bit(int nr, volatile void *addr) +static __inline__ int test_and_set_bit(int nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 5); - unsigned long temp, res; + unsigned long temp; + int res; __asm__ __volatile__( ".set\tnoreorder\t\t# test_and_set_bit\n" @@ -177,6 +197,9 @@ test_and_set_bit(int nr, volatile void *addr) "sc\t%2, %1\n\t" "beqz\t%2, 1b\n\t" " and\t%2, %0, %3\n\t" +#ifdef CONFIG_SMP + "sync\n\t" +#endif ".set\treorder" : "=&r" (temp), "=m" (*m), "=&r" (res) : "r" (1UL << (nr & 0x1f)), "m" (*m) @@ -190,14 +213,15 @@ test_and_set_bit(int nr, volatile void *addr) * @nr: Bit to set * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int __test_and_set_bit(int nr, volatile void * addr) +static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -209,14 +233,13 @@ extern __inline__ int __test_and_set_bit(int nr, volatile void * addr) /* * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ int -test_and_clear_bit(int nr, volatile void *addr) +static __inline__ int test_and_clear_bit(int nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 5); unsigned long temp, res; @@ -229,6 +252,9 @@ test_and_clear_bit(int nr, volatile void *addr) "sc\t%2, %1\n\t" "beqz\t%2, 1b\n\t" " and\t%2, %0, %3\n\t" +#ifdef CONFIG_SMP + "sync\n\t" +#endif ".set\treorder" : "=&r" (temp), "=m" (*m), "=&r" (res) : "r" (1UL << (nr & 0x1f)), "m" (*m) @@ -239,17 +265,18 @@ test_and_clear_bit(int nr, volatile void *addr) /* * __test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr) +static __inline__ int __test_and_clear_bit(int nr, + volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask, retval; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -261,14 +288,13 @@ extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr) /* * test_and_change_bit - Change a bit and return its new value - * @nr: Bit to set + * @nr: Bit to change * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ int -test_and_change_bit(int nr, volatile void *addr) +static __inline__ int test_and_change_bit(int nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 5); unsigned long temp, res; @@ -280,6 +306,9 @@ test_and_change_bit(int nr, volatile void *addr) "sc\t%2, %1\n\t" "beqz\t%2, 1b\n\t" " and\t%2, %0, %3\n\t" +#ifdef CONFIG_SMP + "sync\n\t" +#endif ".set\treorder" : "=&r" (temp), "=m" (*m), "=&r" (res) : "r" (1UL << (nr & 0x1f)), "m" (*m) @@ -290,17 +319,19 @@ test_and_change_bit(int nr, volatile void *addr) /* * __test_and_change_bit - Change a bit and return its old value - * @nr: Bit to set + * @nr: Bit to change * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int __test_and_change_bit(int nr, volatile void * addr) +static __inline__ int __test_and_change_bit(int nr, + volatile unsigned long *addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -322,17 +353,17 @@ extern __inline__ int __test_and_change_bit(int nr, volatile void * addr) * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -extern __inline__ void set_bit(int nr, volatile void * addr) +static __inline__ void set_bit(int nr, volatile unsigned long * addr) { - int mask; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; __bi_flags; a += nr >> 5; mask = 1 << (nr & 0x1f); - __bi_save_and_cli(flags); + __bi_local_irq_save(flags); *a |= mask; - __bi_restore_flags(flags); + __bi_local_irq_restore(flags); } /* @@ -344,10 +375,10 @@ extern __inline__ void set_bit(int nr, volatile void * addr) * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -extern __inline__ void __set_bit(int nr, volatile void * addr) +static __inline__ void __set_bit(int nr, volatile unsigned long * addr) { - int mask; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -364,51 +395,61 @@ extern __inline__ void __set_bit(int nr, volatile void * addr) * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() * in order to ensure changes are visible on other processors. */ -extern __inline__ void clear_bit(int nr, volatile void * addr) +static __inline__ void clear_bit(int nr, volatile unsigned long * addr) { - int mask; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; __bi_flags; a += nr >> 5; mask = 1 << (nr & 0x1f); - __bi_save_and_cli(flags); + __bi_local_irq_save(flags); + *a &= ~mask; + __bi_local_irq_restore(flags); +} + +static __inline__ void __clear_bit(int nr, volatile unsigned long * addr) +{ + volatile unsigned long *a = addr; + unsigned long mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); *a &= ~mask; - __bi_restore_flags(flags); } /* * change_bit - Toggle a bit in memory - * @nr: Bit to clear + * @nr: Bit to change * @addr: Address to start counting from * * change_bit() is atomic and may not be reordered. * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -extern __inline__ void change_bit(int nr, volatile void * addr) +static __inline__ void change_bit(int nr, volatile unsigned long * addr) { - int mask; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; __bi_flags; a += nr >> 5; mask = 1 << (nr & 0x1f); - __bi_save_and_cli(flags); + __bi_local_irq_save(flags); *a ^= mask; - __bi_restore_flags(flags); + __bi_local_irq_restore(flags); } /* * __change_bit - Toggle a bit in memory - * @nr: the bit to set + * @nr: the bit to change * @addr: the address to start counting from * * Unlike change_bit(), this function is non-atomic and may be reordered. * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -extern __inline__ void __change_bit(int nr, volatile void * addr) +static __inline__ void __change_bit(int nr, volatile unsigned long * addr) { unsigned long * m = ((unsigned long *) addr) + (nr >> 5); @@ -420,21 +461,22 @@ extern __inline__ void __change_bit(int nr, volatile void * addr) * @nr: Bit to set * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ int test_and_set_bit(int nr, volatile void * addr) +static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; __bi_flags; a += nr >> 5; mask = 1 << (nr & 0x1f); - __bi_save_and_cli(flags); + __bi_local_irq_save(flags); retval = (mask & *a) != 0; *a |= mask; - __bi_restore_flags(flags); + __bi_local_irq_restore(flags); return retval; } @@ -444,14 +486,15 @@ extern __inline__ int test_and_set_bit(int nr, volatile void * addr) * @nr: Bit to set * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int __test_and_set_bit(int nr, volatile void * addr) +static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -463,41 +506,44 @@ extern __inline__ int __test_and_set_bit(int nr, volatile void * addr) /* * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ int test_and_clear_bit(int nr, volatile void * addr) +static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; __bi_flags; a += nr >> 5; mask = 1 << (nr & 0x1f); - __bi_save_and_cli(flags); + __bi_local_irq_save(flags); retval = (mask & *a) != 0; *a &= ~mask; - __bi_restore_flags(flags); + __bi_local_irq_restore(flags); return retval; } /* * __test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr) +static __inline__ int __test_and_clear_bit(int nr, + volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -509,41 +555,43 @@ extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr) /* * test_and_change_bit - Change a bit and return its new value - * @nr: Bit to set + * @nr: Bit to change * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ int test_and_change_bit(int nr, volatile void * addr) +static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask, retval; __bi_flags; a += nr >> 5; mask = 1 << (nr & 0x1f); - __bi_save_and_cli(flags); + __bi_local_irq_save(flags); retval = (mask & *a) != 0; *a ^= mask; - __bi_restore_flags(flags); + __bi_local_irq_restore(flags); return retval; } /* * __test_and_change_bit - Change a bit and return its old value - * @nr: Bit to set + * @nr: Bit to change * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int __test_and_change_bit(int nr, volatile void * addr) +static __inline__ int __test_and_change_bit(int nr, + volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -556,7 +604,7 @@ extern __inline__ int __test_and_change_bit(int nr, volatile void * addr) #undef __bi_flags #undef __bi_cli #undef __bi_save_flags -#undef __bi_restore_flags +#undef __bi_local_irq_restore #endif /* MIPS I */ @@ -565,202 +613,80 @@ extern __inline__ int __test_and_change_bit(int nr, volatile void * addr) * @nr: bit number to test * @addr: Address to start counting from */ -extern __inline__ int test_bit(int nr, volatile void *addr) +static inline int test_bit(int nr, const volatile unsigned long *addr) { - return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0; + return 1UL & (((const volatile unsigned long *) addr)[nr >> SZLONG_LOG] >> (nr & SZLONG_MASK)); } -#ifndef __MIPSEB__ - -/* Little endian versions. */ - /* - * find_first_zero_bit - find the first zero bit in a memory region - * @addr: The address to start the search at - * @size: The maximum size to search + * ffz - find first zero in word. + * @word: The word to search * - * Returns the bit-number of the first zero bit, not the number of the byte - * containing a bit. + * Undefined if no zero exists, so code should check against ~0UL first. */ -extern __inline__ int find_first_zero_bit (void *addr, unsigned size) +static __inline__ unsigned long ffz(unsigned long word) { - unsigned long dummy; - int res; + int b = 0, s; - if (!size) - return 0; - - __asm__ (".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tsubu\t$1,%6,%0\n\t" - "blez\t$1,2f\n\t" - "lw\t$1,(%5)\n\t" - "addiu\t%5,4\n\t" -#if (_MIPS_ISA == _MIPS_ISA_MIPS2 ) || (_MIPS_ISA == _MIPS_ISA_MIPS3 ) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5 ) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) - "beql\t%1,$1,1b\n\t" - "addiu\t%0,32\n\t" -#else - "addiu\t%0,32\n\t" - "beq\t%1,$1,1b\n\t" - "nop\n\t" - "subu\t%0,32\n\t" -#endif -#ifdef __MIPSEB__ -#error "Fix this for big endian" -#endif /* __MIPSEB__ */ - "li\t%1,1\n" - "1:\tand\t%2,$1,%1\n\t" - "beqz\t%2,2f\n\t" - "sll\t%1,%1,1\n\t" - "bnez\t%1,1b\n\t" - "add\t%0,%0,1\n\t" - ".set\tat\n\t" - ".set\treorder\n" - "2:" - : "=r" (res), "=r" (dummy), "=r" (addr) - : "0" ((signed int) 0), "1" ((unsigned int) 0xffffffff), - "2" (addr), "r" (size) - : "$1"); - - return res; -} + word = ~word; + s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s; + s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s; + s = 4; if (word << 28 != 0) s = 0; b += s; word >>= s; + s = 2; if (word << 30 != 0) s = 0; b += s; word >>= s; + s = 1; if (word << 31 != 0) s = 0; b += s; -/* - * find_next_zero_bit - find the first zero bit in a memory region - * @addr: The address to base the search on - * @offset: The bitnumber to start searching at - * @size: The maximum size to search - */ -extern __inline__ int find_next_zero_bit (void * addr, int size, int offset) -{ - unsigned int *p = ((unsigned int *) addr) + (offset >> 5); - int set = 0, bit = offset & 31, res; - unsigned long dummy; - - if (bit) { - /* - * Look for zero in first byte - */ -#ifdef __MIPSEB__ -#error "Fix this for big endian byte order" -#endif - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tand\t$1,%4,%1\n\t" - "beqz\t$1,1f\n\t" - "sll\t%1,%1,1\n\t" - "bnez\t%1,1b\n\t" - "addiu\t%0,1\n\t" - ".set\tat\n\t" - ".set\treorder\n" - "1:" - : "=r" (set), "=r" (dummy) - : "0" (0), "1" (1 << bit), "r" (*p) - : "$1"); - if (set < (32 - bit)) - return set + offset; - set = 32 - bit; - p++; - } - /* - * No zero yet, search remaining full bytes for a zero - */ - res = find_first_zero_bit(p, size - 32 * (p - (unsigned int *) addr)); - return offset + set + res; + return b; } -#endif /* !(__MIPSEB__) */ - /* - * ffz - find first zero in word. + * __ffs - find first bit in word. * @word: The word to search * - * Undefined if no zero exists, so code should check against ~0UL first. + * Undefined if no bit exists, so code should check against 0 first. */ -extern __inline__ unsigned long ffz(unsigned long word) +static __inline__ unsigned long __ffs(unsigned long word) { - unsigned int __res; - unsigned int mask = 1; - - __asm__ ( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "move\t%0,$0\n" - "1:\tand\t$1,%2,%1\n\t" - "beqz\t$1,2f\n\t" - "sll\t%1,1\n\t" - "bnez\t%1,1b\n\t" - "addiu\t%0,1\n\t" - ".set\tat\n\t" - ".set\treorder\n" - "2:\n\t" - : "=&r" (__res), "=r" (mask) - : "r" (word), "1" (mask) - : "$1"); - - return __res; + return ffz(~word); } -#ifdef __KERNEL__ - -/** - * ffs - find first bit set - * @x: the word to search - * - * This is defined the same way as - * the libc and compiler builtin ffs routines, therefore - * differs in spirit from the above ffz (man ffs). - */ - -#define ffs(x) generic_ffs(x) - /* - * hweightN - returns the hamming weight of a N-bit word - * @x: the word to weigh - * - * The Hamming Weight of a number is the total number of bits set in it. + * fls: find last bit set. */ -#define hweight32(x) generic_hweight32(x) -#define hweight16(x) generic_hweight16(x) -#define hweight8(x) generic_hweight8(x) - -#endif /* __KERNEL__ */ +#define fls(x) generic_fls(x) -#ifdef __MIPSEB__ /* * find_next_zero_bit - find the first zero bit in a memory region * @addr: The address to base the search on * @offset: The bitnumber to start searching at * @size: The maximum size to search */ -extern __inline__ int find_next_zero_bit(void *addr, int size, int offset) +static inline unsigned long find_next_zero_bit(unsigned long *addr, + unsigned long size, unsigned long offset) { - unsigned long *p = ((unsigned long *) addr) + (offset >> 5); - unsigned long result = offset & ~31UL; + unsigned long *p = ((unsigned long *) addr) + (offset >> SZLONG_LOG); + unsigned long result = offset & ~SZLONG_MASK; unsigned long tmp; if (offset >= size) return size; size -= result; - offset &= 31UL; + offset &= SZLONG_MASK; if (offset) { tmp = *(p++); - tmp |= ~0UL >> (32-offset); - if (size < 32) + tmp |= ~0UL >> (_MIPS_SZLONG-offset); + if (size < _MIPS_SZLONG) goto found_first; if (~tmp) goto found_middle; - size -= 32; - result += 32; + size -= _MIPS_SZLONG; + result += _MIPS_SZLONG; } - while (size & ~31UL) { + while (size & ~SZLONG_MASK) { if (~(tmp = *(p++))) goto found_middle; - result += 32; - size -= 32; + result += _MIPS_SZLONG; + size -= _MIPS_SZLONG; } if (!size) return result; @@ -768,158 +694,241 @@ extern __inline__ int find_next_zero_bit(void *addr, int size, int offset) found_first: tmp |= ~0UL << size; + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. */ found_middle: return result + ffz(tmp); } -/* Linus sez that gcc can optimize the following correctly, we'll see if this - * holds on the Sparc as it does for the ALPHA. +#define find_first_zero_bit(addr, size) \ + find_next_zero_bit((addr), (size), 0) + +/* + * find_next_bit - find the next set bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search */ +static inline unsigned long find_next_bit(unsigned long *addr, + unsigned long size, unsigned long offset) +{ + unsigned long *p = addr + (offset >> SZLONG_LOG); + unsigned long result = offset & ~SZLONG_MASK; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= SZLONG_MASK; + if (offset) { + tmp = *(p++); + tmp &= ~0UL << offset; + if (size < _MIPS_SZLONG) + goto found_first; + if (tmp) + goto found_middle; + size -= _MIPS_SZLONG; + result += _MIPS_SZLONG; + } + while (size & ~SZLONG_MASK) { + if ((tmp = *(p++))) + goto found_middle; + result += _MIPS_SZLONG; + size -= _MIPS_SZLONG; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp &= ~0UL >> (_MIPS_SZLONG - size); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + __ffs(tmp); +} -#if 0 /* Fool kernel-doc since it doesn't do macros yet */ /* - * find_first_zero_bit - find the first zero bit in a memory region + * find_first_bit - find the first set bit in a memory region * @addr: The address to start the search at * @size: The maximum size to search * - * Returns the bit-number of the first zero bit, not the number of the byte + * Returns the bit-number of the first set bit, not the number of the byte * containing a bit. */ -extern int find_first_zero_bit (void *addr, unsigned size); -#endif +#define find_first_bit(addr, size) \ + find_next_bit((addr), (size), 0) -#define find_first_zero_bit(addr, size) \ - find_next_zero_bit((addr), (size), 0) +#ifdef __KERNEL__ + +/* + * Every architecture must define this function. It's the fastest + * way of searching a 168-bit bitmap where the first 128 bits are + * unlikely to be set. It's guaranteed that at least one of the 168 + * bits is cleared. + */ +static inline int sched_find_first_bit(unsigned long *b) +{ + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(b[1])) + return __ffs(b[1]) + 32; + if (unlikely(b[2])) + return __ffs(b[2]) + 64; + if (unlikely(b[3])) + return __ffs(b[3]) + 96; + if (b[4]) + return __ffs(b[4]) + 128; + return __ffs(b[5]) + 32 + 128; +} + +/* + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ -#endif /* (__MIPSEB__) */ +#define ffs(x) generic_ffs(x) -/* Now for the ext2 filesystem bit operations and helper routines. */ +/* + * hweightN - returns the hamming weight of a N-bit word + * @x: the word to weigh + * + * The Hamming Weight of a number is the total number of bits set in it. + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) -#ifdef __MIPSEB__ -extern __inline__ int ext2_set_bit(int nr, void * addr) +static inline int __test_and_set_le_bit(unsigned long nr, unsigned long *addr) { - int mask, retval, flags; unsigned char *ADDR = (unsigned char *) addr; + int mask, retval; ADDR += nr >> 3; mask = 1 << (nr & 0x07); - save_and_cli(flags); retval = (mask & *ADDR) != 0; *ADDR |= mask; - restore_flags(flags); + return retval; } -extern __inline__ int ext2_clear_bit(int nr, void * addr) +static inline int __test_and_clear_le_bit(unsigned long nr, unsigned long *addr) { - int mask, retval, flags; unsigned char *ADDR = (unsigned char *) addr; + int mask, retval; ADDR += nr >> 3; mask = 1 << (nr & 0x07); - save_and_cli(flags); retval = (mask & *ADDR) != 0; *ADDR &= ~mask; - restore_flags(flags); + return retval; } -#define ext2_set_bit_atomic(lock, nr, addr) \ - ({ \ - int ret; \ - spin_lock(lock); \ - ret = ext2_set_bit((nr), (addr)); \ - spin_unlock(lock); \ - ret; \ - }) - -#define ext2_clear_bit_atomic(lock, nr, addr) \ - ({ \ - int ret; \ - spin_lock(lock); \ - ret = ext2_clear_bit((nr), (addr)); \ - spin_unlock(lock); \ - ret; \ - }) - -extern __inline__ int ext2_test_bit(int nr, const void * addr) +static inline int test_le_bit(unsigned long nr, const unsigned long * addr) { - int mask; const unsigned char *ADDR = (const unsigned char *) addr; + int mask; ADDR += nr >> 3; mask = 1 << (nr & 0x07); + return ((mask & *ADDR) != 0); } -#define ext2_find_first_zero_bit(addr, size) \ - ext2_find_next_zero_bit((addr), (size), 0) +static inline unsigned long ext2_ffz(unsigned int word) +{ + int b = 0, s; + + word = ~word; + s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s; + s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s; + s = 4; if (word << 28 != 0) s = 0; b += s; word >>= s; + s = 2; if (word << 30 != 0) s = 0; b += s; word >>= s; + s = 1; if (word << 31 != 0) s = 0; b += s; -extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) + return b; +} + +static inline unsigned long find_next_zero_le_bit(unsigned long *addr, + unsigned long size, unsigned long offset) { - unsigned long *p = ((unsigned long *) addr) + (offset >> 5); - unsigned long result = offset & ~31UL; - unsigned long tmp; + unsigned int *p = ((unsigned int *) addr) + (offset >> 5); + unsigned int result = offset & ~31; + unsigned int tmp; if (offset >= size) return size; + size -= result; - offset &= 31UL; - if(offset) { - /* We hold the little endian value in tmp, but then the - * shift is illegal. So we could keep a big endian value - * in tmp, like this: - * - * tmp = __swab32(*(p++)); - * tmp |= ~0UL >> (32-offset); - * - * but this would decrease preformance, so we change the - * shift: - */ - tmp = *(p++); - tmp |= __swab32(~0UL >> (32-offset)); - if(size < 32) + offset &= 31; + if (offset) { + tmp = cpu_to_le32p(p++); + tmp |= ~0U >> (32-offset); /* bug or feature ? */ + if (size < 32) goto found_first; - if(~tmp) + if (tmp != ~0U) goto found_middle; size -= 32; result += 32; } - while(size & ~31UL) { - if(~(tmp = *(p++))) + while (size >= 32) { + if ((tmp = cpu_to_le32p(p++)) != ~0U) goto found_middle; result += 32; size -= 32; } - if(!size) + if (!size) return result; - tmp = *p; + tmp = cpu_to_le32p(p); found_first: - /* tmp is little endian, so we would have to swab the shift, - * see above. But then we have to swab tmp below for ffz, so - * we might as well do this here. - */ - return result + ffz(__swab32(tmp) | (~0UL << size)); + tmp |= ~0 << size; + if (tmp == ~0U) /* Are any bits zero? */ + return result + size; /* Nope. */ + found_middle: - return result + ffz(__swab32(tmp)); + return result + ext2_ffz(tmp); } -#else /* !(__MIPSEB__) */ -/* Native ext2 byte ordering, just collapse using defines. */ -#define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr)) -#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr), (addr)) -#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr), (addr)) -#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr), (addr)) -#define ext2_test_bit(nr, addr) test_bit((nr), (addr)) -#define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size)) -#define ext2_find_next_zero_bit(addr, size, offset) \ - find_next_zero_bit((addr), (size), (offset)) - -#endif /* !(__MIPSEB__) */ +#define find_first_zero_le_bit(addr, size) \ + find_next_zero_le_bit((addr), (size), 0) + +#define ext2_set_bit(nr,addr) \ + __test_and_set_le_bit((nr),(unsigned long*)addr) +#define ext2_clear_bit(nr, addr) \ + __test_and_clear_le_bit((nr),(unsigned long*)addr) + #define ext2_set_bit_atomic(lock, nr, addr) \ +({ \ + int ret; \ + spin_lock(lock); \ + ret = ext2_set_bit((nr), (addr)); \ + spin_unlock(lock); \ + ret; \ +}) + +#define ext2_clear_bit_atomic(lock, nr, addr) \ +({ \ + int ret; \ + spin_lock(lock); \ + ret = ext2_clear_bit((nr), (addr)); \ + spin_unlock(lock); \ + ret; \ +}) +#define ext2_test_bit(nr, addr) test_le_bit((nr),(unsigned long*)addr) +#define ext2_find_first_zero_bit(addr, size) \ + find_first_zero_le_bit((unsigned long*)addr, size) +#define ext2_find_next_zero_bit(addr, size, off) \ + find_next_zero_le_bit((unsigned long*)addr, size, off) /* * Bitmap functions for the minix filesystem. + * * FIXME: These assume that Minix uses the native byte/bitorder. * This limits the Minix filesystem's value for data exchange very much. */ @@ -929,4 +938,6 @@ found_middle: #define minix_test_bit(nr,addr) test_bit(nr,addr) #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) +#endif /* __KERNEL__ */ + #endif /* _ASM_BITOPS_H */ diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 552ddd93164b..16ebdd7d259c 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -9,40 +9,39 @@ #ifndef _ASM_BOOTINFO_H #define _ASM_BOOTINFO_H +#include <linux/types.h> + /* * Values for machgroup */ -#define MACH_GROUP_UNKNOWN 0 /* whatever... */ -#define MACH_GROUP_JAZZ 1 /* Jazz */ -#define MACH_GROUP_DEC 2 /* Digital Equipment */ +#define MACH_GROUP_UNKNOWN 0 /* whatever... */ +#define MACH_GROUP_JAZZ 1 /* Jazz */ +#define MACH_GROUP_DEC 2 /* Digital Equipment */ #define MACH_GROUP_ARC 3 /* Wreckstation Tyne, rPC44, possibly other */ -#define MACH_GROUP_SNI_RM 4 /* Siemens Nixdorf RM series */ +#define MACH_GROUP_SNI_RM 4 /* Siemens Nixdorf RM series */ #define MACH_GROUP_ACN 5 -#define MACH_GROUP_SGI 6 /* Silicon Graphics */ -#define MACH_GROUP_COBALT 7 /* Cobalt servers */ -#define MACH_GROUP_NEC_DDB 8 /* NEC DDB */ -#define MACH_GROUP_BAGET 9 /* Baget */ -#define MACH_GROUP_COSINE 10 /* CoSine Orion */ -#define MACH_GROUP_GALILEO 11 /* Galileo Eval Boards */ -#define MACH_GROUP_MOMENCO 12 /* Momentum Boards */ -#define MACH_GROUP_ITE 13 /* ITE Semi Eval Boards */ +#define MACH_GROUP_SGI 6 /* Silicon Graphics */ +#define MACH_GROUP_COBALT 7 /* Cobalt servers */ +#define MACH_GROUP_NEC_DDB 8 /* NEC DDB */ +#define MACH_GROUP_BAGET 9 /* Baget */ +#define MACH_GROUP_COSINE 10 /* CoSine Orion */ +#define MACH_GROUP_GALILEO 11 /* Galileo Eval Boards */ +#define MACH_GROUP_MOMENCO 12 /* Momentum Boards */ +#define MACH_GROUP_ITE 13 /* ITE Semi Eval Boards */ #define MACH_GROUP_PHILIPS 14 -#define MACH_GROUP_GLOBESPAN 15 /* Globespan PVR Referrence Board */ -#define MACH_GROUP_SIBYTE 16 /* Sibyte Eval Boards */ -#define MACH_GROUP_TOSHIBA 17 /* Toshiba Reference Systems TSBREF */ -#define MACH_GROUP_ALCHEMY 18 /* Alchemy Semi Eval Boards*/ - -#define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", "SNI", "ACN", \ - "SGI", "Cobalt", "NEC DDB", "Baget", "Cosine", "Galileo", "Momentum", \ - "ITE", "Philips", "Globepspan", "SiByte", "Toshiba", "Alchemy" } +#define MACH_GROUP_GLOBESPAN 15 /* Globespan PVR Referrence Board */ +#define MACH_GROUP_SIBYTE 16 /* Sibyte Eval Boards */ +#define MACH_GROUP_TOSHIBA 17 /* Toshiba Reference Systems TSBREF */ +#define MACH_GROUP_ALCHEMY 18 /* Alchemy Semi Eval Boards */ +#define MACH_GROUP_NEC_VR41XX 19 /* NEC Vr41xx based boards/gadgets */ +#define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ +#define MACH_GROUP_LASAT 21 /* * Valid machtype values for group unknown (low order halfword of mips_machtype) */ #define MACH_UNKNOWN 0 /* whatever... */ -#define GROUP_UNKNOWN_NAMES { "unknown" } - /* * Valid machtype values for group JAZZ */ @@ -50,26 +49,20 @@ #define MACH_MIPS_MAGNUM_4000 1 /* Mips Magnum 4000 "RC4030" */ #define MACH_OLIVETTI_M700 2 /* Olivetti M700-10 (-15 ??) */ -#define GROUP_JAZZ_NAMES { "Acer PICA 61", "Mips Magnum 4000", "Olivetti M700" } - /* - * Valid machtype for group DEC + * Valid machtype for group DEC */ #define MACH_DSUNKNOWN 0 #define MACH_DS23100 1 /* DECstation 2100 or 3100 */ -#define MACH_DS5100 2 /* DECstation 5100 */ +#define MACH_DS5100 2 /* DECsystem 5100 */ #define MACH_DS5000_200 3 /* DECstation 5000/200 */ #define MACH_DS5000_1XX 4 /* DECstation 5000/120, 125, 133, 150 */ #define MACH_DS5000_XX 5 /* DECstation 5000/20, 25, 33, 50 */ #define MACH_DS5000_2X0 6 /* DECstation 5000/240, 260 */ -#define MACH_DS5400 7 /* DECstation 5400 */ -#define MACH_DS5500 8 /* DECstation 5500 */ -#define MACH_DS5800 9 /* DECstation 5800 */ - -#define GROUP_DEC_NAMES { "unknown", "DECstation 2100/3100", "DECstation 5100", \ - "DECstation 5000/200", "DECstation 5000/1xx", "Personal DECstation 5000/xx", \ - "DECstation 5000/2x0", "DECstation 5400", "DECstation 5500", \ - "DECstation 5800" } +#define MACH_DS5400 7 /* DECsystem 5400 */ +#define MACH_DS5500 8 /* DECsystem 5500 */ +#define MACH_DS5800 9 /* DECsystem 5800 */ +#define MACH_DS5900 10 /* DECsystem 5900 */ /* * Valid machtype for group ARC @@ -77,46 +70,37 @@ #define MACH_DESKSTATION_RPC44 0 /* Deskstation rPC44 */ #define MACH_DESKSTATION_TYNE 1 /* Deskstation Tyne */ -#define GROUP_ARC_NAMES { "Deskstation rPC44", "Deskstation Tyne" } - /* * Valid machtype for group SNI_RM */ #define MACH_SNI_RM200_PCI 0 /* RM200/RM300/RM400 PCI series */ -#define GROUP_SNI_RM_NAMES { "RM200 PCI" } - /* * Valid machtype for group ACN */ #define MACH_ACN_MIPS_BOARD 0 /* ACN MIPS single board */ -#define GROUP_ACN_NAMES { "ACN" } - /* * Valid machtype for group SGI */ -#define MACH_SGI_INDY 0 /* R4?K and R5K Indy workstations */ -#define MACH_SGI_CHALLENGE_S 1 /* The Challenge S server */ -#define MACH_SGI_INDIGO2 2 /* The Indigo2 system */ - -#define GROUP_SGI_NAMES { "Indy", "Challenge S", "Indigo2" } +#define MACH_SGI_IP22 0 /* Indy, Indigo2, Challenge S */ +#define MACH_SGI_IP27 1 /* Origin 200, Origin 2000, Onyx 2 */ +#define MACH_SGI_IP28 2 /* Indigo2 Impact */ +#define MACH_SGI_IP32 3 /* O2 */ /* * Valid machtype for group COBALT */ -#define MACH_COBALT_27 0 /* Proto "27" hardware */ - -#define GROUP_COBALT_NAMES { "Microserver 27" } +#define MACH_COBALT_27 0 /* Proto "27" hardware */ /* * Valid machtype for group NEC DDB */ -#define MACH_NEC_DDB5074 0 /* NEC DDB Vrc-5074 */ -#define MACH_NEC_DDB5476 1 /* NEC DDB Vrc-5476 */ -#define MACH_NEC_DDB5477 2 /* NEC DDB Vrc-5477 */ - -#define GROUP_NEC_DDB_NAMES { "Vrc-5074", "Vrc-5476", "Vrc-5477"} +#define MACH_NEC_DDB5074 0 /* NEC DDB Vrc-5074 */ +#define MACH_NEC_DDB5476 1 /* NEC DDB Vrc-5476 */ +#define MACH_NEC_DDB5477 2 /* NEC DDB Vrc-5477 */ +#define MACH_NEC_ROCKHOPPER 3 /* Rockhopper base board */ +#define MACH_NEC_ROCKHOPPERII 4 /* Rockhopper II base board */ /* * Valid machtype for group BAGET @@ -124,44 +108,33 @@ #define MACH_BAGET201 0 /* BT23-201 */ #define MACH_BAGET202 1 /* BT23-202 */ -#define GROUP_BAGET_NAMES { "BT23-201", "BT23-202" } - /* * Cosine boards. */ #define MACH_COSINE_ORION 0 -#define GROUP_COSINE_NAMES { "Orion" } - /* * Valid machtype for group GALILEO */ #define MACH_EV96100 0 /* EV96100 */ #define MACH_EV64120A 1 /* EV64120A */ -#define GROUP_GALILEO_NAMES { "EV96100" , "EV64120A" } - /* * Valid machtype for group MOMENCO */ #define MACH_MOMENCO_OCELOT 0 +#define MACH_MOMENCO_OCELOT_G 1 +#define MACH_MOMENCO_OCELOT_C 2 -#define GROUP_MOMENCO_NAMES { "Ocelot" } - - /* * Valid machtype for group ITE */ #define MACH_QED_4N_S01B 0 /* ITE8172 based eval board */ - -#define GROUP_ITE_NAMES { "QED-4N-S01B" } /* the actual board name */ - + /* * Valid machtype for group Globespan */ -#define MACH_IVR 0 /* IVR eval board */ - -#define GROUP_GLOBESPAN_NAMES { "IVR" } /* the actual board name */ +#define MACH_IVR 0 /* IVR eval board */ /* * Valid machtype for group PHILIPS @@ -169,126 +142,63 @@ #define MACH_PHILIPS_NINO 0 /* Nino */ #define MACH_PHILIPS_VELO 1 /* Velo */ -#define GROUP_PHILIPS_NAMES { "Nino" , "Velo" } - /* * Valid machtype for group SIBYTE */ #define MACH_SWARM 0 -#define GROUP_SIBYTE_NAMES {"SWARM" } - /* * Valid machtypes for group Toshiba */ #define MACH_PALLAS 0 #define MACH_TOPAS 1 #define MACH_JMR 2 +#define MACH_TOSHIBA_JMR3927 3 /* JMR-TX3927 CPU/IO board */ +#define MACH_TOSHIBA_RBTX4927 4 +#define MACH_TOSHIBA_RBTX4937 5 +#define GROUP_TOSHIBA_NAMES { "Pallas", "TopasCE", "JMR", "JMR TX3927", \ + "RBTX4927", "RBTX4937" } -#define GROUP_TOSHIBA_NAMES { "Pallas", "TopasCE", "JMR" } +/* + * Valid machtype for group LASAT + */ +#define MACH_LASAT_100 0 /* Masquerade II/SP100/SP50/SP25 */ +#define MACH_LASAT_200 1 /* Masquerade PRO/SP200 */ /* * Valid machtype for group Alchemy */ -#define MACH_PB1000 0 /* Au1000-based eval board */ - -#define GROUP_ALCHEMY_NAMES { "PB1000" } /* the actual board name */ +#define MACH_PB1000 0 /* Au1000-based eval board */ +#define MACH_PB1100 1 /* Au1100-based eval board */ +#define MACH_PB1500 2 /* Au1500-based eval board */ +#define MACH_DB1000 3 /* Au1000-based eval board */ +#define MACH_DB1100 4 /* Au1100-based eval board */ +#define MACH_DB1500 5 /* Au1500-based eval board */ /* - * Valid cputype values + * Valid machtype for group NEC_VR41XX */ -#define CPU_UNKNOWN 0 -#define CPU_R2000 1 -#define CPU_R3000 2 -#define CPU_R3000A 3 -#define CPU_R3041 4 -#define CPU_R3051 5 -#define CPU_R3052 6 -#define CPU_R3081 7 -#define CPU_R3081E 8 -#define CPU_R4000PC 9 -#define CPU_R4000SC 10 -#define CPU_R4000MC 11 -#define CPU_R4200 12 -#define CPU_R4400PC 13 -#define CPU_R4400SC 14 -#define CPU_R4400MC 15 -#define CPU_R4600 16 -#define CPU_R6000 17 -#define CPU_R6000A 18 -#define CPU_R8000 19 -#define CPU_R10000 20 -#define CPU_R4300 21 -#define CPU_R4650 22 -#define CPU_R4700 23 -#define CPU_R5000 24 -#define CPU_R5000A 25 -#define CPU_R4640 26 -#define CPU_NEVADA 27 /* RM5230, RM5260 */ -#define CPU_RM7000 28 -#define CPU_R5432 29 -#define CPU_4KC 30 -#define CPU_5KC 31 -#define CPU_R4310 32 -#define CPU_SB1 33 -#define CPU_TX3912 34 -#define CPU_TX3922 35 -#define CPU_TX3927 36 -#define CPU_AU1000 37 -#define CPU_4KEC 38 -#define CPU_4KSC 39 -#define CPU_VR41XX 40 -#define CPU_LAST 40 +#define MACH_NEC_OSPREY 0 /* Osprey eval board */ +#define MACH_NEC_EAGLE 1 /* NEC Eagle/Hawk board */ +#define MACH_ZAO_CAPCELLA 2 /* ZAO Networks Capcella */ +#define MACH_VICTOR_MPC30X 3 /* Victor MP-C303/304 */ +#define MACH_IBM_WORKPAD 4 /* IBM WorkPad z50 */ +#define MACH_CASIO_E55 5 /* CASIO CASSIOPEIA E-10/15/55/65 */ +#define MACH_TANBAC_TB0226 6 /* TANBAC TB0226 (Mbase) */ +#define MACH_TANBAC_TB0229 7 /* TANBAC TB0229 (VR4131DIMM) */ +#define CL_SIZE (256) -#define CPU_NAMES { "unknown", "R2000", "R3000", "R3000A", "R3041", "R3051", \ - "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC", \ - "R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000", \ - "R6000A", "R8000", "R10000", "R4300", "R4650", "R4700", "R5000", \ - "R5000A", "R4640", "Nevada", "RM7000", "R5432", "MIPS 4Kc", \ - "MIPS 5Kc", "R4310", "SiByte SB1", "TX3912", "TX3922", "TX3927", \ - "Au1000", "MIPS 4KEc", "MIPS 4KSc", "NEC Vr41xx" } +const char *get_system_type(void); -#define COMMAND_LINE_SIZE 256 +extern unsigned long mips_machtype; +extern unsigned long mips_machgroup; #define BOOT_MEM_MAP_MAX 32 #define BOOT_MEM_RAM 1 #define BOOT_MEM_ROM_DATA 2 #define BOOT_MEM_RESERVED 3 -#ifndef __ASSEMBLY__ - -/* - * Some machine parameters passed by the bootloaders. - */ - -struct drive_info_struct { - char dummy[32]; -}; - -/* This is the same as in Milo but renamed for the sake of kernel's */ -/* namespace */ -typedef struct mips_arc_DisplayInfo { /* video adapter information */ - unsigned short cursor_x; - unsigned short cursor_y; - unsigned short columns; - unsigned short lines; -} mips_arc_DisplayInfo; - -/* default values for drive info */ -#define DEFAULT_DRIVE_INFO { {0,}} - -/* - * These are the kernel variables initialized from - * the tag. And they have to be initialized to dummy/default - * values in setup.c (or whereever suitable) so they are in - * .data section - */ -extern struct mips_cpu mips_cpu; -extern unsigned long mips_machtype; -extern unsigned long mips_machgroup; -extern unsigned long mips_tlb_entries; - /* * A memory map that's built upon what was determined * or specified on the command line. @@ -296,17 +206,14 @@ extern unsigned long mips_tlb_entries; struct boot_mem_map { int nr_map; struct { - unsigned long addr; /* start of memory segment */ - unsigned long size; /* size of memory segment */ + phys_t addr; /* start of memory segment */ + phys_t size; /* size of memory segment */ long type; /* type of memory segment */ } map[BOOT_MEM_MAP_MAX]; }; extern struct boot_mem_map boot_mem_map; -extern void add_memory_region(unsigned long start, unsigned long size, - long type); - -#endif /* !__ASSEMBLY__ */ +extern void add_memory_region(phys_t start, phys_t size, long type); #endif /* _ASM_BOOTINFO_H */ diff --git a/include/asm-mips/branch.h b/include/asm-mips/branch.h index d8882cfb1bf9..37c6857c8d4a 100644 --- a/include/asm-mips/branch.h +++ b/include/asm-mips/branch.h @@ -1,24 +1,31 @@ /* - * Branch and jump emulation. - * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 1997, 1998 by Ralf Baechle - * - * $Id: branch.h,v 1.2 1998/04/28 19:37:46 ralf Exp $ + * Copyright (C) 1996, 1997, 1998, 2001 by Ralf Baechle */ +#ifndef _ASM_BRANCH_H +#define _ASM_BRANCH_H + #include <asm/ptrace.h> -extern inline int delay_slot(struct pt_regs *regs) +static inline int delay_slot(struct pt_regs *regs) { return regs->cp0_cause & CAUSEF_BD; } +static inline unsigned long exception_epc(struct pt_regs *regs) +{ + if (!delay_slot(regs)) + return regs->cp0_epc; + + return regs->cp0_epc + 4; +} + extern int __compute_return_epc(struct pt_regs *regs); -extern inline int compute_return_epc(struct pt_regs *regs) +static inline int compute_return_epc(struct pt_regs *regs) { if (!delay_slot(regs)) { regs->cp0_epc += 4; @@ -27,3 +34,5 @@ extern inline int compute_return_epc(struct pt_regs *regs) return __compute_return_epc(regs); } + +#endif /* _ASM_BRANCH_H */ diff --git a/include/asm-mips/break.h b/include/asm-mips/break.h new file mode 100644 index 000000000000..c8d6ab34966c --- /dev/null +++ b/include/asm-mips/break.h @@ -0,0 +1,33 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 2003 by Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#ifndef __ASM_BREAK_H +#define __ASM_BREAK_H + +/* + * The following break codes are or were in use for specific purposes in + * other MIPS operating systems. Linux/MIPS doesn't use all of them. The + * unused ones are here as placeholders; we might encounter them in + * non-Linux/MIPS object files or make use of them in the future. + */ +#define BRK_USERBP 0 /* User bp (used by debuggers) */ +#define BRK_KERNELBP 1 /* Break in the kernel */ +#define BRK_ABORT 2 /* Sometimes used by abort(3) to SIGIOT */ +#define BRK_BD_TAKEN 3 /* For bd slot emulation - not implemented */ +#define BRK_BD_NOTTAKEN 4 /* For bd slot emulation - not implemented */ +#define BRK_SSTEPBP 5 /* User bp (used by debuggers) */ +#define BRK_OVERFLOW 6 /* Overflow check */ +#define BRK_DIVZERO 7 /* Divide by zero check */ +#define BRK_RANGE 8 /* Range error check */ +#define BRK_STACKOVERFLOW 9 /* For Ada stackchecking */ +#define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */ +#define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */ +#define BRK_MULOVF 1023 /* Multiply overflow */ +#define BRK_BUG 512 /* Used by BUG() */ + +#endif /* __ASM_BREAK_H */ diff --git a/include/asm-mips/bug.h b/include/asm-mips/bug.h index 76c923dcf903..d34c34f30282 100644 --- a/include/asm-mips/bug.h +++ b/include/asm-mips/bug.h @@ -1,15 +1,20 @@ -/* $Id$ */ #ifndef __ASM_BUG_H #define __ASM_BUG_H -#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0) +#include <asm/break.h> + +#define BUG() \ +do { \ + printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ + __asm__ __volatile__("break %0" : : "i" (BRK_BUG)); \ +} while (0) #define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) #define PAGE_BUG(page) do { BUG(); } while (0) #define WARN_ON(condition) do { \ if (unlikely((condition)!=0)) { \ printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ + dump_stack(); \ } \ } while (0) diff --git a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h index 17b94e2693cc..78fd2a3d6fb9 100644 --- a/include/asm-mips/bugs.h +++ b/include/asm-mips/bugs.h @@ -1,47 +1,12 @@ /* - * Copyright (C) 1995 Waldorf Electronics - * Copyright (C) 1997, 1999 Ralf Baechle - */ -#include <asm/bootinfo.h> -#include <asm/cpu.h> - -/* * This is included by init/main.c to check for architecture-dependent bugs. * * Needs: * void check_bugs(void); */ +#ifndef __ASM_BUGS_H +#define __ASM_BUGS_H +extern void check_bugs(void); -static inline void check_wait(void) -{ - printk("Checking for 'wait' instruction... "); - switch(mips_cpu.cputype) { - case CPU_R3081: - case CPU_R3081E: - cpu_wait = r3081_wait; - printk(" available.\n"); - break; - case CPU_R4200: - case CPU_R4300: - case CPU_R4600: - case CPU_R4640: - case CPU_R4650: - case CPU_R4700: - case CPU_R5000: - case CPU_NEVADA: - case CPU_RM7000: - cpu_wait = r4k_wait; - printk(" available.\n"); - break; - default: - printk(" unavailable.\n"); - break; - } -} - -static void __init -check_bugs(void) -{ - check_wait(); -} +#endif /* __ASM_BUGS_H */ diff --git a/include/asm-mips/byteorder.h b/include/asm-mips/byteorder.h index b9604cf202aa..445af5ec37eb 100644 --- a/include/asm-mips/byteorder.h +++ b/include/asm-mips/byteorder.h @@ -1,5 +1,4 @@ -/* $Id: byteorder.h,v 1.8 1998/11/02 09:29:32 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h index 05fc11d65ca9..4057cb45f744 100644 --- a/include/asm-mips/cache.h +++ b/include/asm-mips/cache.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1997, 98, 99, 2000 Ralf Baechle + * Copyright (C) 1997, 98, 99, 2000, 2003 Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_CACHE_H @@ -11,30 +11,15 @@ #include <linux/config.h> -#ifndef _LANGUAGE_ASSEMBLY -/* - * Descriptor for a cache - */ -struct cache_desc { - int linesz; - int sets; - int ways; - int flags; /* Details like write thru/back, coherent, etc. */ -}; -#endif - -/* - * Flag definitions - */ -#define MIPS_CACHE_NOT_PRESENT 0x00000001 - -#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_R6000) +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_R6000) || \ + defined(CONFIG_CPU_TX39XX) #define L1_CACHE_BYTES 16 +#define L1_CACHE_SHIFT_MAX 4 /* largest L1 which this arch supports */ #else #define L1_CACHE_BYTES 32 /* A guess */ +#define L1_CACHE_SHIFT_MAX 6 /* largest L1 which this arch supports */ #endif #define SMP_CACHE_BYTES L1_CACHE_BYTES -#define L1_CACHE_SHIFT_MAX 5 /* largest L1 which this arch supports */ #endif /* _ASM_CACHE_H */ diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h new file mode 100644 index 000000000000..6e586c25ff13 --- /dev/null +++ b/include/asm-mips/cacheflush.h @@ -0,0 +1,65 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02, 03 by Ralf Baechle + * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc. + */ +#ifndef __ASM_CACHEFLUSH_H +#define __ASM_CACHEFLUSH_H + +#include <linux/config.h> + +/* Keep includes the same across arches. */ +#include <linux/mm.h> + +/* Cache flushing: + * + * - flush_cache_all() flushes entire cache + * - flush_cache_mm(mm) flushes the specified mm context's cache lines + * - flush_cache_page(mm, vmaddr) flushes a single page + * - flush_cache_range(vma, start, end) flushes a range of pages + * - flush_icache_range(start, end) flush a range of instructions + * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache + * - flush_icache_page(vma, pg) flushes(invalidates) a page for icache + * + * MIPS specific flush operations: + * + * - flush_cache_sigtramp() flush signal trampoline + * - flush_icache_all() flush the entire instruction cache + * - flush_data_cache_page() flushes a page from the data cache + */ +extern void (*flush_cache_all)(void); +extern void (*__flush_cache_all)(void); +extern void (*flush_cache_mm)(struct mm_struct *mm); +extern void (*flush_cache_range)(struct vm_area_struct *vma, + unsigned long start, unsigned long end); +extern void (*flush_cache_page)(struct vm_area_struct *vma, + unsigned long page); +extern void flush_dcache_page(struct page *page); +extern void (*flush_icache_page)(struct vm_area_struct *vma, + struct page *page); +extern void (*flush_icache_range)(unsigned long start, unsigned long end); +#define flush_icache_user_range(vma, page, addr, len) \ + flush_icache_page(vma, page) + + +extern void (*flush_cache_sigtramp)(unsigned long addr); +extern void (*flush_icache_all)(void); +extern void (*flush_data_cache_page)(unsigned long addr); + +/* + * This flag is used to indicate that the page pointed to by a pte + * is dirty and requires cleaning before returning it to the user. + */ +#define PG_dcache_dirty PG_arch_1 + +#define Page_dcache_dirty(page) \ + test_bit(PG_dcache_dirty, &(page)->flags) +#define SetPageDcacheDirty(page) \ + set_bit(PG_dcache_dirty, &(page)->flags) +#define ClearPageDcacheDirty(page) \ + clear_bit(PG_dcache_dirty, &(page)->flags) + +#endif /* __ASM_CACHEFLUSH_H */ diff --git a/include/asm-mips/cacheops.h b/include/asm-mips/cacheops.h index 66b0b361f03e..91a2bed3669a 100644 --- a/include/asm-mips/cacheops.h +++ b/include/asm-mips/cacheops.h @@ -5,43 +5,77 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * (C) Copyright 1996, 1997 by Ralf Baechle + * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle + * (C) Copyright 1999 Silicon Graphics, Inc. */ -#ifndef __ASM_MIPS_CACHEOPS_H -#define __ASM_MIPS_CACHEOPS_H +#ifndef __ASM_CACHEOPS_H +#define __ASM_CACHEOPS_H /* - * Cache Operations + * Cache Operations available on all MIPS processors with R4000-style caches */ #define Index_Invalidate_I 0x00 #define Index_Writeback_Inv_D 0x01 -#define Index_Invalidate_SI 0x02 -#define Index_Writeback_Inv_SD 0x03 #define Index_Load_Tag_I 0x04 #define Index_Load_Tag_D 0x05 -#define Index_Load_Tag_SI 0x06 -#define Index_Load_Tag_SD 0x07 #define Index_Store_Tag_I 0x08 #define Index_Store_Tag_D 0x09 +#define Hit_Invalidate_I 0x10 +#define Hit_Invalidate_D 0x11 +#define Hit_Writeback_Inv_D 0x15 +#define Hit_Writeback_I 0x18 +#define Hit_Writeback_D 0x19 + +/* + * R4000-specific cacheops + */ +#define Create_Dirty_Excl_D 0x0d +#define Fill 0x14 + +/* + * R4000SC and R4400SC-specific cacheops + */ +#define Index_Invalidate_SI 0x02 +#define Index_Writeback_Inv_SD 0x03 +#define Index_Load_Tag_SI 0x06 +#define Index_Load_Tag_SD 0x07 #define Index_Store_Tag_SI 0x0A #define Index_Store_Tag_SD 0x0B -#define Create_Dirty_Excl_D 0x0d #define Create_Dirty_Excl_SD 0x0f -#define Hit_Invalidate_I 0x10 -#define Hit_Invalidate_D 0x11 #define Hit_Invalidate_SI 0x12 #define Hit_Invalidate_SD 0x13 -#define Fill 0x14 -#define Hit_Writeback_Inv_D 0x15 - /* 0x16 is unused */ #define Hit_Writeback_Inv_SD 0x17 -#define Hit_Writeback_I 0x18 -#define Hit_Writeback_D 0x19 - /* 0x1a is unused */ #define Hit_Writeback_SD 0x1b - /* 0x1c is unused */ - /* 0x1e is unused */ #define Hit_Set_Virtual_SI 0x1e #define Hit_Set_Virtual_SD 0x1f -#endif /* __ASM_MIPS_CACHEOPS_H */ +/* + * R5000-specific cacheops + */ +#define R5K_Page_Invalidate_S 0x17 + +/* + * RM7000-specific cacheops + */ +#define Page_Invalidate_T 0x16 + +/* + * R1000-specific cacheops + * + * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. + * Most of the _S cacheops are identical to the R4000SC _SD cacheops. + */ +#define Index_Writeback_Inv_S 0x03 +#define Index_Load_Tag_S 0x07 +#define Index_Store_Tag_S 0x0B +#define Hit_Invalidate_S 0x13 +#define Cache_Barrier 0x14 +#define Hit_Writeback_Inv_S 0x17 +#define Index_Load_Data_I 0x18 +#define Index_Load_Data_D 0x19 +#define Index_Load_Data_S 0x1b +#define Index_Store_Data_I 0x1c +#define Index_Store_Data_D 0x1d +#define Index_Store_Data_S 0x1f + +#endif /* __ASM_CACHEOPS_H */ diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h index 55932940b64b..756e6a6429c8 100644 --- a/include/asm-mips/checksum.h +++ b/include/asm-mips/checksum.h @@ -9,6 +9,7 @@ #define _ASM_CHECKSUM_H #include <asm/uaccess.h> +#include <linux/in6.h> /* * computes the checksum of a memory block at buff, length len, @@ -35,7 +36,7 @@ unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len, * Copy and checksum to user */ #define HAVE_CSUM_COPY_USER -extern inline unsigned int csum_and_copy_to_user (const char *src, char *dst, +static inline unsigned int csum_and_copy_to_user (const char *src, char *dst, int len, int sum, int *err_ptr) { @@ -71,12 +72,11 @@ static inline unsigned short int csum_fold(unsigned int sum) "xori\t%0,0xffff\n\t" ".set\tat" : "=r" (sum) - : "0" (sum) - : "$1"); + : "0" (sum)); - return sum; + return sum; } - + /* * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. @@ -124,8 +124,7 @@ static inline unsigned short ip_fast_csum(unsigned char *iph, "2:\t.set\tat\n\t" ".set\treorder" : "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (dummy) - : "1" (iph), "2" (ihl) - : "$1"); + : "1" (iph), "2" (ihl)); return csum_fold(sum); } @@ -161,8 +160,7 @@ static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, #else "r" (((proto)<<16)+len), #endif - "r" (sum) - : "$1"); + "r" (sum)); return sum; } @@ -194,10 +192,11 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len, unsigned short proto, - unsigned int sum) + unsigned int sum) { __asm__( - ".set\tnoreorder\t\t\t# csum_ipv6_magic\n\t" + ".set\tpush\t\t\t# csum_ipv6_magic\n\t" + ".set\tnoreorder\n\t" ".set\tnoat\n\t" "addu\t%0, %5\t\t\t# proto (long in network byte order)\n\t" "sltu\t$1, %0, %5\n\t" @@ -208,48 +207,48 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, "lw\t%1, 0(%2)\t\t\t# four words source address\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 4(%2)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 8(%2)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 12(%2)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 0(%3)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 4(%3)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 8(%3)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 12(%3)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" - ".set\tnoat\n\t" - ".set\tnoreorder" + "sltu\t$1, %0, %1\n\t" + + "addu\t%0, $1\t\t\t# Add final carry\n\t" + ".set\tpop" : "=r" (sum), "=r" (proto) : "r" (saddr), "r" (daddr), - "0" (htonl(len)), "1" (htonl(proto)), "r" (sum) - : "$1"); + "0" (htonl(len)), "1" (htonl(proto)), "r" (sum)); return csum_fold(sum); } diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index 8f4981b763bc..f2289ddc5432 100644 --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h @@ -7,10 +7,10 @@ #ifndef _ASM_CPU_H #define _ASM_CPU_H -#include <asm/cache.h> +#include <linux/cpu.h> -/* Assigned Company values for bits 23:16 of the PRId Register - (CP0 register 15, select 0). As of the MIPS32 and MIPS64 specs from +/* Assigned Company values for bits 23:16 of the PRId Register + (CP0 register 15, select 0). As of the MIPS32 and MIPS64 specs from MTI, the PRId register is defined in this (backwards compatible) way: @@ -21,16 +21,15 @@ I don't have docs for all the previous processors, but my impression is that bits 16-23 have been 0 for all MIPS processors before the MIPS32/64 - spec. + spec. */ #define PRID_COMP_LEGACY 0x000000 #define PRID_COMP_MIPS 0x010000 +#define PRID_COMP_BROADCOM 0x020000 #define PRID_COMP_ALCHEMY 0x030000 -/* - * Don't know who should be here...QED and Sandcraft, maybe? - */ #define PRID_COMP_SIBYTE 0x040000 +#define PRID_COMP_SANDCRAFT 0x050000 /* * Assigned values for the product ID register. In order to detect a @@ -38,7 +37,8 @@ * be examined. These are valid when 23:16 == PRID_COMP_LEGACY */ #define PRID_IMP_R2000 0x0100 -#define PRID_IMP_AU1000 0x0100 +#define PRID_IMP_AU1_REV1 0x0100 +#define PRID_IMP_AU1_REV2 0x0200 #define PRID_IMP_R3000 0x0200 /* Same as R2000A */ #define PRID_IMP_R6000 0x0300 /* Same as R3000A */ #define PRID_IMP_R4000 0x0400 @@ -54,13 +54,16 @@ #define PRID_IMP_R4640 0x2200 #define PRID_IMP_R4650 0x2200 /* Same as R4640 */ #define PRID_IMP_R5000 0x2300 +#define PRID_IMP_TX49 0x2d00 #define PRID_IMP_SONIC 0x2400 #define PRID_IMP_MAGIC 0x2500 #define PRID_IMP_RM7000 0x2700 #define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */ #define PRID_IMP_R5432 0x5400 +#define PRID_IMP_R5500 0x5500 #define PRID_IMP_4KC 0x8000 #define PRID_IMP_5KC 0x8100 +#define PRID_IMP_20KC 0x8200 #define PRID_IMP_4KEC 0x8400 #define PRID_IMP_4KSC 0x8600 @@ -74,10 +77,18 @@ #define PRID_IMP_SB1 0x0100 /* + * These are the PRID's for when 23:16 == PRID_COMP_SANDCRAFT + */ + +#define PRID_IMP_SR71000 0x0400 + +/* * Definitions for 7:0 on legacy processors */ +#define PRID_REV_TX4927 0x0022 +#define PRID_REV_TX4937 0x0030 #define PRID_REV_R4400 0x0040 #define PRID_REV_R3000A 0x0030 #define PRID_REV_R3000 0x0020 @@ -85,50 +96,116 @@ #define PRID_REV_TX3912 0x0010 #define PRID_REV_TX3922 0x0030 #define PRID_REV_TX3927 0x0040 +#define PRID_REV_VR4111 0x0050 +#define PRID_REV_VR4181 0x0050 /* Same as VR4111 */ +#define PRID_REV_VR4121 0x0060 +#define PRID_REV_VR4122 0x0070 +#define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */ +#define PRID_REV_VR4131 0x0080 -#ifndef _LANGUAGE_ASSEMBLY /* - * Capability and feature descriptor structure for MIPS CPU + * FPU implementation/revision register (CP1 control register 0). + * + * +---------------------------------+----------------+----------------+ + * | 0 | Implementation | Revision | + * +---------------------------------+----------------+----------------+ + * 31 16 15 8 7 0 */ -struct mips_cpu { - unsigned int processor_id; - unsigned int cputype; /* Old "mips_cputype" code */ - int isa_level; - int options; - int tlbsize; - struct cache_desc icache; /* Primary I-cache */ - struct cache_desc dcache; /* Primary D or combined I/D cache */ - struct cache_desc scache; /* Secondary cache */ - struct cache_desc tcache; /* Tertiary/split secondary cache */ -}; - -#endif + +#define FPIR_IMP_NONE 0x0000 + +#define CPU_UNKNOWN 0 +#define CPU_R2000 1 +#define CPU_R3000 2 +#define CPU_R3000A 3 +#define CPU_R3041 4 +#define CPU_R3051 5 +#define CPU_R3052 6 +#define CPU_R3081 7 +#define CPU_R3081E 8 +#define CPU_R4000PC 9 +#define CPU_R4000SC 10 +#define CPU_R4000MC 11 +#define CPU_R4200 12 +#define CPU_R4400PC 13 +#define CPU_R4400SC 14 +#define CPU_R4400MC 15 +#define CPU_R4600 16 +#define CPU_R6000 17 +#define CPU_R6000A 18 +#define CPU_R8000 19 +#define CPU_R10000 20 +#define CPU_R12000 21 +#define CPU_R4300 22 +#define CPU_R4650 23 +#define CPU_R4700 24 +#define CPU_R5000 25 +#define CPU_R5000A 26 +#define CPU_R4640 27 +#define CPU_NEVADA 28 +#define CPU_RM7000 29 +#define CPU_R5432 30 +#define CPU_4KC 31 +#define CPU_5KC 32 +#define CPU_R4310 33 +#define CPU_SB1 34 +#define CPU_TX3912 35 +#define CPU_TX3922 36 +#define CPU_TX3927 37 +#define CPU_AU1000 38 +#define CPU_4KEC 39 +#define CPU_4KSC 40 +#define CPU_VR41XX 41 +#define CPU_R5500 42 +#define CPU_TX49XX 43 +#define CPU_AU1500 44 +#define CPU_20KC 45 +#define CPU_VR4111 46 +#define CPU_VR4121 47 +#define CPU_VR4122 48 +#define CPU_VR4131 49 +#define CPU_VR4181 50 +#define CPU_VR4181A 51 +#define CPU_AU1100 52 +#define CPU_SR71000 53 +#define CPU_LAST 53 /* * ISA Level encodings + * */ #define MIPS_CPU_ISA_I 0x00000001 #define MIPS_CPU_ISA_II 0x00000002 -#define MIPS_CPU_ISA_III 0x00000003 -#define MIPS_CPU_ISA_IV 0x00000004 -#define MIPS_CPU_ISA_V 0x00000005 +#define MIPS_CPU_ISA_III 0x00008003 +#define MIPS_CPU_ISA_IV 0x00008004 +#define MIPS_CPU_ISA_V 0x00008005 #define MIPS_CPU_ISA_M32 0x00000020 -#define MIPS_CPU_ISA_M64 0x00000040 +#define MIPS_CPU_ISA_M64 0x00008040 + +/* + * Bit 15 encodes if an ISA level supports 64-bit operations. + */ +#define MIPS_CPU_ISA_64BIT 0x00008000 /* * CPU Option encodings */ -#define MIPS_CPU_TLB 0x00000001 /* CPU has TLB */ +#define MIPS_CPU_TLB 0x00000001 /* CPU has TLB */ /* Leave a spare bit for variant MMU types... */ -#define MIPS_CPU_4KEX 0x00000004 /* "R4K" exception model */ -#define MIPS_CPU_4KTLB 0x00000008 /* "R4K" TLB handler */ -#define MIPS_CPU_FPU 0x00000010 /* CPU has FPU */ -#define MIPS_CPU_32FPR 0x00000020 /* 32 dbl. prec. FP registers */ -#define MIPS_CPU_COUNTER 0x00000040 /* Cycle count/compare */ -#define MIPS_CPU_WATCH 0x00000080 /* watchpoint registers */ -#define MIPS_CPU_MIPS16 0x00000100 /* code compression */ -#define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */ -#define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */ +#define MIPS_CPU_4KEX 0x00000004 /* "R4K" exception model */ +#define MIPS_CPU_4KTLB 0x00000008 /* "R4K" TLB handler */ +#define MIPS_CPU_FPU 0x00000010 /* CPU has FPU */ +#define MIPS_CPU_32FPR 0x00000020 /* 32 dbl. prec. FP registers */ +#define MIPS_CPU_COUNTER 0x00000040 /* Cycle count/compare */ +#define MIPS_CPU_WATCH 0x00000080 /* watchpoint registers */ +#define MIPS_CPU_MIPS16 0x00000100 /* code compression */ +#define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */ +#define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */ #define MIPS_CPU_CACHE_CDEX 0x00000800 /* Create_Dirty_Exclusive CACHE op */ +#define MIPS_CPU_MCHECK 0x00001000 /* Machine check exception */ +#define MIPS_CPU_EJTAG 0x00002000 /* EJTAG exception */ +#define MIPS_CPU_NOFPUEX 0x00004000 /* no FPU exception */ +#define MIPS_CPU_LLSC 0x00008000 /* CPU has ll/sc instructions */ +#define MIPS_CPU_SUBSET_CACHES 0x00010000 /* P-cache subset enforced */ #endif /* _ASM_CPU_H */ diff --git a/include/asm-mips/current.h b/include/asm-mips/current.h index 2c776757e74a..559db66b9790 100644 --- a/include/asm-mips/current.h +++ b/include/asm-mips/current.h @@ -3,17 +3,21 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1998 Ralf Baechle + * Copyright (C) 1998, 2002 Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_CURRENT_H #define _ASM_CURRENT_H -#ifdef _LANGUAGE_C +#include <linux/thread_info.h> -/* MIPS rules... */ -register struct task_struct *current asm("$28"); +struct task_struct; -#endif /* _LANGUAGE_C */ +static inline struct task_struct * get_current(void) +{ + return current_thread_info()->task; +} + +#define current get_current() #endif /* _ASM_CURRENT_H */ diff --git a/include/asm-mips/db1x00.h b/include/asm-mips/db1x00.h new file mode 100644 index 000000000000..859614ae1edd --- /dev/null +++ b/include/asm-mips/db1x00.h @@ -0,0 +1,118 @@ +/* + * AMD Alchemy DB1x00 Reference Boards + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * + */ +#ifndef __ASM_DB1X00_H +#define __ASM_DB1X00_H + + +/* + * Overlay data structure of the Db1x00 board registers. + * Registers located at physical 1E0000xx, KSEG1 0xAE0000xx + */ +typedef volatile struct +{ + /*00*/ unsigned long whoami; + /*04*/ unsigned long status; + /*08*/ unsigned long switches; + /*0C*/ unsigned long resets; + /*10*/ unsigned long pcmcia; + /*14*/ unsigned long specific; + /*18*/ unsigned long leds; + /*1C*/ unsigned long swreset; + +} BCSR; + +/* + * Register/mask bit definitions for the BCSRs + */ +#define BCSR_WHOAMI_DCID 0x000F +#define BCSR_WHOAMI_CPLD 0x00F0 +#define BCSR_WHOAMI_BOARD 0x0F00 + +#define BCSR_STATUS_PC0VS 0x0003 +#define BCSR_STATUS_PC1VS 0x000C +#define BCSR_STATUS_PC0FI 0x0010 +#define BCSR_STATUS_PC1FI 0x0020 +#define BCSR_STATUS_FLASHBUSY 0x0100 +#define BCSR_STATUS_ROMBUSY 0x0400 +#define BCSR_STATUS_SWAPBOOT 0x2000 +#define BCSR_STATUS_FLASHDEN 0xC000 + +#define BCSR_SWITCHES_DIP 0x00FF +#define BCSR_SWITCHES_DIP_1 0x0080 +#define BCSR_SWITCHES_DIP_2 0x0040 +#define BCSR_SWITCHES_DIP_3 0x0020 +#define BCSR_SWITCHES_DIP_4 0x0010 +#define BCSR_SWITCHES_DIP_5 0x0008 +#define BCSR_SWITCHES_DIP_6 0x0004 +#define BCSR_SWITCHES_DIP_7 0x0002 +#define BCSR_SWITCHES_DIP_8 0x0001 +#define BCSR_SWITCHES_ROTARY 0x0F00 + +#define BCSR_RESETS_PHY0 0x0001 +#define BCSR_RESETS_PHY1 0x0002 +#define BCSR_RESETS_DC 0x0004 + +#define BCSR_PCMCIA_PC0VPP 0x0003 +#define BCSR_PCMCIA_PC0VCC 0x000C +#define BCSR_PCMCIA_PC0DRVEN 0x0010 +#define BCSR_PCMCIA_PC0RST 0x0080 +#define BCSR_PCMCIA_PC1VPP 0x0300 +#define BCSR_PCMCIA_PC1VCC 0x0C00 +#define BCSR_PCMCIA_PC1DRVEN 0x1000 +#define BCSR_PCMCIA_PC1RST 0x8000 + +#define BCSR_BOARD_PCIM66EN 0x0001 +#define BCSR_BOARD_PCIM33 0x0100 +#define BCSR_BOARD_GPIO200RST 0x0400 +#define BCSR_BOARD_PCICFG 0x1000 + +#define BCSR_LEDS_DECIMALS 0x0003 +#define BCSR_LEDS_LED0 0x0100 +#define BCSR_LEDS_LED1 0x0200 +#define BCSR_LEDS_LED2 0x0400 +#define BCSR_LEDS_LED3 0x0800 + +#define BCSR_SWRESET_RESET 0x0080 + +/* PCMCIA Db1x00 specific defines */ +#define PCMCIA_MAX_SOCK 1 +#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) + +/* VPP/VCC */ +#define SET_VCC_VPP(VCC, VPP, SLOT)\ + ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8)) + +/* MTD CONFIG OPTIONS */ +#if defined(CONFIG_MTD_DB1X00_BOOT) && defined(CONFIG_MTD_DB1X00_USER) +#define DB1X00_BOTH_BANKS +#elif defined(CONFIG_MTD_DB1X00_BOOT) && !defined(CONFIG_MTD_DB1X00_USER) +#define DB1X00_BOOT_ONLY +#elif !defined(CONFIG_MTD_DB1X00_BOOT) && defined(CONFIG_MTD_DB1X00_USER) +#define DB1X00_USER_ONLY +#endif + +#endif /* __ASM_DB1X00_H */ diff --git a/include/asm-mips/debug.h b/include/asm-mips/debug.h new file mode 100644 index 000000000000..e5466194cade --- /dev/null +++ b/include/asm-mips/debug.h @@ -0,0 +1,48 @@ +/* + * Debug macros for run-time debugging. Turned on/off with CONFIG_RUNTIME_DEBUG option. + * + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef _ASM_DEBUG_H +#define _ASM_DEBUG_H + +#include <linux/config.h> + +/* + * run-time macros for catching spurious errors. Eable CONFIG_RUNTIME_DEBUG in + * kernel hacking config menu to use them. + * + * Use them as run-time debugging aid. NEVER USE THEM AS ERROR HANDLING CODE!!! + */ + +#ifdef CONFIG_RUNTIME_DEBUG + +#include <linux/kernel.h> + +#define db_assert(x) if (!(x)) { \ + panic("assertion failed at %s:%d: %s\n", __FILE__, __LINE__, #x); } +#define db_warn(x) if (!(x)) { \ + printk(KERN_WARNING "warning at %s:%d: %s\n", __FILE__, __LINE__, #x); } +#define db_verify(x, y) db_assert(x y) +#define db_verify_warn(x, y) db_warn(x y) +#define db_run(x) do { x; } while (0) + +#else + +#define db_assert(x) +#define db_warn(x) +#define db_verify(x, y) x +#define db_verify_warn(x, y) x +#define db_run(x) + +#endif + +#endif /* _ASM_DEBUG_H */ diff --git a/include/asm-mips/delay.h b/include/asm-mips/delay.h index 50024e3481c1..751757079ee0 100644 --- a/include/asm-mips/delay.h +++ b/include/asm-mips/delay.h @@ -10,6 +10,7 @@ #define _ASM_DELAY_H #include <linux/config.h> +#include <linux/param.h> extern unsigned long loops_per_jiffy; @@ -26,7 +27,7 @@ __delay(unsigned long loops) } /* - * division by multiplication: you don't have to worry about + * Division by multiplication: you don't have to worry about * loss of precision. * * Use only for very small delays ( < 1 msec). Should probably use a @@ -39,7 +40,11 @@ extern __inline__ void __udelay(unsigned long usecs, unsigned long lpj) { unsigned long lo; - usecs *= 0x00068db8; /* 2**32 / (1000000 / HZ) */ + /* + * Excessive precission? Probably ... + */ + usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) + + 0x80000000ULL) >> 32); __asm__("multu\t%2,%3" :"=h" (usecs), "=l" (lo) :"r" (usecs),"r" (lpj)); diff --git a/include/asm-mips/div64.h b/include/asm-mips/div64.h index ce2a45d83897..6ef773a65ac5 100644 --- a/include/asm-mips/div64.h +++ b/include/asm-mips/div64.h @@ -1,6 +1,4 @@ /* - * include/asm-mips/div64.h - * * Copyright (C) 2000 Maciej W. Rozycki * * This file is subject to the terms and conditions of the GNU General Public @@ -10,105 +8,69 @@ #ifndef _ASM_DIV64_H #define _ASM_DIV64_H -#include <asm/sgidefs.h> - /* * No traps on overflows for any of these... */ -#if (_MIPS_ISA == _MIPS_ISA_MIPS1 ) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS32) - #define do_div64_32(res, high, low, base) ({ \ unsigned long __quot, __mod; \ - unsigned long __cf, __tmp, __i; \ + unsigned long __cf, __tmp, __tmp2, __i; \ \ __asm__(".set push\n\t" \ ".set noat\n\t" \ ".set noreorder\n\t" \ + "move %2, $0\n\t" \ + "move %3, $0\n\t" \ "b 1f\n\t" \ - " li %4,0x21\n" \ + " li %4, 0x21\n" \ "0:\n\t" \ - "sll $1,%0,0x1\n\t" \ - "srl %3,%0,0x1f\n\t" \ - "or %0,$1,$2\n\t" \ - "sll %1,%1,0x1\n\t" \ - "sll %2,%2,0x1\n" \ + "sll $1, %0, 0x1\n\t" \ + "srl %3, %0, 0x1f\n\t" \ + "or %0, $1, %5\n\t" \ + "sll %1, %1, 0x1\n\t" \ + "sll %2, %2, 0x1\n" \ "1:\n\t" \ - "bnez %3,2f\n\t" \ - "sltu $2,%0,%z5\n\t" \ - "bnez $2,3f\n\t" \ + "bnez %3, 2f\n\t" \ + " sltu %5, %0, %z6\n\t" \ + "bnez %5, 3f\n" \ "2:\n\t" \ - " addiu %4,%4,-1\n\t" \ - "subu %0,%0,%z5\n\t" \ - "addiu %2,%2,1\n" \ + " addiu %4, %4, -1\n\t" \ + "subu %0, %0, %z6\n\t" \ + "addiu %2, %2, 1\n" \ "3:\n\t" \ - "bnez %4,0b\n\t" \ - " srl $2,%1,0x1f\n\t" \ + "bnez %4, 0b\n\t" \ + " srl %5, %1, 0x1f\n\t" \ ".set pop" \ : "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \ - "=&r" (__i) \ - : "Jr" (base), "0" (high), "1" (low), "2" (0), "3" (0) \ - /* Aarrgh! Ran out of gcc's limit on constraints... */ \ - : "$1", "$2"); \ + "=&r" (__i), "=&r" (__tmp2) \ + : "Jr" (base), "0" (high), "1" (low)); \ \ (res) = __quot; \ __mod; }) #define do_div(n, base) ({ \ unsigned long long __quot; \ - unsigned long __upper, __low, __high, __mod; \ + unsigned long __mod; \ + unsigned long long __div; \ + unsigned long __upper, __low, __high, __base; \ + \ + __div = (n); \ + __base = (base); \ \ - __quot = (n); \ - __high = __quot >> 32; \ - __low = __quot; \ + __high = __div >> 32; \ + __low = __div; \ __upper = __high; \ \ if (__high) \ - __asm__("divu $0,%z2,%z3" \ + __asm__("divu $0, %z2, %z3" \ : "=h" (__upper), "=l" (__high) \ - : "Jr" (__high), "Jr" (base)); \ + : "Jr" (__high), "Jr" (__base)); \ \ - __mod = do_div64_32(__low, __upper, __low, base); \ + __mod = do_div64_32(__low, __upper, __low, __base); \ \ __quot = __high; \ __quot = __quot << 32 | __low; \ (n) = __quot; \ __mod; }) -#else - -#define do_div64_32(res, high, low, base) ({ \ - unsigned long __quot, __mod, __r0; \ - \ - __asm__("dsll32 %2,%z3,0\n\t" \ - "or %2,%2,%z4\n\t" \ - "ddivu $0,%2,%z5" \ - : "=h" (__mod), "=l" (__quot), "=&r" (__r0) \ - : "Jr" (high), "Jr" (low), "Jr" (base)); \ - \ - (res) = __quot; \ - __mod; }) - -#define do_div(n, base) ({ \ - unsigned long long __quot; \ - unsigned long __mod, __r0; \ - \ - __quot = (n); \ - \ - __asm__("dsll32 %2,%M3,0\n\t" \ - "or %2,%2,%L3\n\t" \ - "ddivu $0,%2,%z4\n\t" \ - "mflo %L1\n\t" \ - "dsra32 %M1,%L1,0\n\t" \ - "dsll32 %L1,%L1,0\n\t" \ - "dsra32 %L1,%L1,0" \ - : "=h" (__mod), "=r" (__quot), "=&r" (__r0) \ - : "r" (n), "Jr" (base)); \ - \ - (n) = __quot; \ - __mod; }) - -#endif - #endif /* _ASM_DIV64_H */ diff --git a/include/asm-mips/dma.h b/include/asm-mips/dma.h index 54e938ef42eb..eb21f821b946 100644 --- a/include/asm-mips/dma.h +++ b/include/asm-mips/dma.h @@ -1,4 +1,4 @@ -/* $Id: dma.h,v 1.6 1999/12/30 14:22:47 raiko Exp $ +/* * linux/include/asm/dma.h: Defines for using and allocating dma channels. * Written by Hennus Bergman, 1992. * High DMA channel support & info by Hannu Savolainen @@ -43,7 +43,7 @@ * - page registers for 5-7 don't use data bit 0, represent 128K pages * - page registers for 0-3 use bit 0, represent 64K pages * - * DMA transfers are limited to the lower 16MB of _physical_ memory. + * DMA transfers are limited to the lower 16MB of _physical_ memory. * Note that addresses loaded into registers must be _physical_ addresses, * not logical addresses (which may differ if paging is active). * @@ -53,7 +53,7 @@ * | ... | | ... | | ... | * | ... | | ... | | ... | * | ... | | ... | | ... | - * P7 ... P0 A7 ... A0 A7 ... A0 + * P7 ... P0 A7 ... A0 A7 ... A0 * | Page | Addr MSB | Addr LSB | (DMA registers) * * Address mapping for channels 5-7: @@ -62,7 +62,7 @@ * | ... | \ \ ... \ \ \ ... \ \ * | ... | \ \ ... \ \ \ ... \ (not used) * | ... | \ \ ... \ \ \ ... \ - * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 * | Page | Addr MSB | Addr LSB | (DMA registers) * * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses @@ -71,7 +71,7 @@ * * Transfer count (_not # bytes_) is limited to 64K, represented as actual * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, - * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * and up to 128K bytes may be transferred on channels 5-7 in one operation. * */ @@ -83,7 +83,13 @@ * Deskstations or Acer PICA but not the much more versatile DMA logic used * for the local devices on Acer PICA or Magnums. */ +#ifdef CONFIG_SGI_IP22 +/* Horrible hack to have a correct DMA window on IP22 */ +#include <asm/sgi/mc.h> +#define MAX_DMA_ADDRESS (PAGE_OFFSET + SGIMC_SEG0_BADDR + 0x01000000) +#else #define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000) +#endif /* 8237 DMA controllers */ #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ @@ -142,6 +148,7 @@ #define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ #define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ +#define DMA_AUTOINIT 0x10 extern spinlock_t dma_spin_lock; @@ -247,7 +254,7 @@ static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) } -/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for +/* Set transfer size (max 64k for DMA0..3, 128k for DMA5..7) for * a specific DMA channel. * You must ensure the parameters are valid. * NOTE: from a manual: "the number of transfers is one more @@ -286,7 +293,7 @@ static __inline__ int get_dma_residue(unsigned int dmanr) count = 1 + dma_inb(io_port); count += dma_inb(io_port) << 8; - + return (dmanr<=3)? count : (count<<1); } diff --git a/include/asm-mips/ds1286.h b/include/asm-mips/ds1286.h index 92686b110dc9..56af9b10d01b 100644 --- a/include/asm-mips/ds1286.h +++ b/include/asm-mips/ds1286.h @@ -1,5 +1,4 @@ -/* $Id: ds1286.h,v 1.1 1998/07/10 01:14:55 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h index 47807ff567e3..2d5e51c1df12 100644 --- a/include/asm-mips/elf.h +++ b/include/asm-mips/elf.h @@ -6,13 +6,32 @@ #ifndef __ASM_ELF_H #define __ASM_ELF_H +/* ELF header e_flags defines. */ +/* MIPS architecture level. */ +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */ +#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */ + +/* The ABI of a file. */ +#define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */ +#define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */ + #define PT_MIPS_REGINFO 0x70000000 +#define PT_MIPS_OPTIONS 0x70000001 /* Flags in the e_flags field of the header */ -#define EF_MIPS_NOREORDER 0x00000001 -#define EF_MIPS_PIC 0x00000002 -#define EF_MIPS_CPIC 0x00000004 -#define EF_MIPS_ARCH 0xf0000000 +#define EF_MIPS_NOREORDER 0x00000001 +#define EF_MIPS_PIC 0x00000002 +#define EF_MIPS_CPIC 0x00000004 +#define EF_MIPS_ABI2 0x00000020 +#define EF_MIPS_OPTIONS_FIRST 0x00000080 +#define EF_MIPS_32BITMODE 0x00000100 +#define EF_MIPS_ABI 0x0000f000 +#define EF_MIPS_ARCH 0xf0000000 #define DT_MIPS_RLD_VERSION 0x70000001 #define DT_MIPS_TIME_STAMP 0x70000002 @@ -102,8 +121,7 @@ typedef double elf_fpreg_t; typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; /* - * This is used to ensure we don't load something for the wrong architecture - * and also rejects IRIX binaries. + * This is used to ensure we don't load something for the wrong architecture. */ #define elf_check_arch(hdr) \ ({ \ @@ -112,7 +130,12 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; \ if (__h->e_machine != EM_MIPS) \ __res = 0; \ - if (__h->e_flags & EF_MIPS_ARCH) \ + if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ + __res = 0; \ + if ((__h->e_flags & EF_MIPS_ABI2) != 0) \ + __res = 0; \ + if (((__h->e_flags & EF_MIPS_ABI) != 0) && \ + ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \ __res = 0; \ \ __res; \ diff --git a/include/asm-mips/errno.h b/include/asm-mips/errno.h index bcb808005a31..35d47a882801 100644 --- a/include/asm-mips/errno.h +++ b/include/asm-mips/errno.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 1999, 2001 by Ralf Baechle + * Copyright (C) 1995, 1999, 2001, 2002 by Ralf Baechle */ #ifndef _ASM_ERRNO_H #define _ASM_ERRNO_H diff --git a/include/asm-mips/fcntl.h b/include/asm-mips/fcntl.h index f7a6ada7fffb..29003d919e0b 100644 --- a/include/asm-mips/fcntl.h +++ b/include/asm-mips/fcntl.h @@ -22,8 +22,8 @@ #define O_EXCL 0x0400 /* not fcntl */ #define O_NOCTTY 0x0800 /* not fcntl */ #define FASYNC 0x1000 /* fcntl, for BSD compatibility */ -#define O_LARGEFILE 0x2000 /* allow large file opens - currently ignored */ -#define O_DIRECT 0x8000 /* direct disk access hint - currently ignored */ +#define O_LARGEFILE 0x2000 /* allow large file opens */ +#define O_DIRECT 0x8000 /* direct disk access hint */ #define O_DIRECTORY 0x10000 /* must be a directory */ #define O_NOFOLLOW 0x20000 /* don't follow links */ @@ -65,7 +65,7 @@ /* 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 XXXXXXXXXXXXXXXXXX +#define LOCK_NB 4 /* or'd with one of the above to prevent blocking */ #define LOCK_UN 8 /* remove lock */ @@ -74,14 +74,21 @@ #define LOCK_WRITE 128 /* ... Which allows concurrent write operations */ #define LOCK_RW 192 /* ... Which allows concurrent read & write ops */ +/* + * The flavours of struct flock. "struct flock" is the ABI compliant + * variant. Finally struct flock64 is the LFS variant of struct flock. As + * a historic accident and inconsistence with the ABI definition it doesn't + * contain all the same fields as struct flock. + */ + typedef struct flock { - short l_type; - short l_whence; + short l_type; + short l_whence; __kernel_off_t l_start; __kernel_off_t l_len; - long l_sysid; /* ABI junk, unused on Linux */ + long l_sysid; __kernel_pid_t l_pid; - long pad[4]; /* ABI junk, unused on Linux */ + long pad[4]; } flock_t; typedef struct flock64 { diff --git a/include/asm-mips/fixmap.h b/include/asm-mips/fixmap.h new file mode 100644 index 000000000000..b86291d8ae80 --- /dev/null +++ b/include/asm-mips/fixmap.h @@ -0,0 +1,111 @@ +/* + * fixmap.h: compile-time virtual memory allocation + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1998 Ingo Molnar + * + * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 + */ + +#ifndef _ASM_FIXMAP_H +#define _ASM_FIXMAP_H + +#include <linux/config.h> +#include <linux/kernel.h> +#include <asm/page.h> +#ifdef CONFIG_HIGHMEM +#include <linux/threads.h> +#include <asm/kmap_types.h> +#endif + +/* + * Here we define all the compile-time 'special' virtual + * addresses. The point is to have a constant address at + * compile time, but to set the physical address only + * in the boot process. We allocate these special addresses + * from the end of virtual memory (0xfffff000) backwards. + * Also this lets us do fail-safe vmalloc(), we + * can guarantee that these special addresses and + * vmalloc()-ed addresses never overlap. + * + * these 'compile-time allocated' memory buffers are + * fixed-size 4k pages. (or larger if used with an increment + * highger than 1) use fixmap_set(idx,phys) to associate + * physical memory with fixmap indices. + * + * TLB entries of such buffers will not be flushed across + * task switches. + */ + +/* + * on UP currently we will have no trace of the fixmap mechanizm, + * no page table allocations, etc. This might change in the + * future, say framebuffers for the console driver(s) could be + * fix-mapped? + */ +enum fixed_addresses { +#ifdef CONFIG_HIGHMEM + FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ + FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, +#endif + __end_of_fixed_addresses +}; + +extern void __set_fixmap (enum fixed_addresses idx, + unsigned long phys, pgprot_t flags); + +#define set_fixmap(idx, phys) \ + __set_fixmap(idx, phys, PAGE_KERNEL) +/* + * Some hardware wants to get fixmapped without caching. + */ +#define set_fixmap_nocache(idx, phys) \ + __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) +/* + * used by vmalloc.c. + * + * Leave one empty page between vmalloc'ed areas and + * the start of the fixmap, and leave one page empty + * at the top of mem.. + */ +#define FIXADDR_TOP (0xffffe000UL) +#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) +#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) + +#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) +#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) + +extern void __this_fixmap_does_not_exist(void); + +/* + * 'index to address' translation. If anyone tries to use the idx + * directly without tranlation, we catch the bug with a NULL-deference + * kernel oops. Illegal ranges of incoming indices are caught too. + */ +static inline unsigned long fix_to_virt(const unsigned int idx) +{ + /* + * this branch gets completely eliminated after inlining, + * except when someone tries to use fixaddr indices in an + * illegal way. (such as mixing up address types or using + * out-of-range indices). + * + * If it doesn't get removed, the linker will complain + * loudly with a reasonably clear error message.. + */ + if (idx >= __end_of_fixed_addresses) + __this_fixmap_does_not_exist(); + + return __fix_to_virt(idx); +} + +static inline unsigned long virt_to_fix(const unsigned long vaddr) +{ + BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); + return __virt_to_fix(vaddr); +} + +#endif diff --git a/include/asm-mips/floppy.h b/include/asm-mips/floppy.h index 32b37c84eaa8..29b7c27b13a7 100644 --- a/include/asm-mips/floppy.h +++ b/include/asm-mips/floppy.h @@ -10,10 +10,6 @@ #ifndef _ASM_FLOPPY_H #define _ASM_FLOPPY_H -#include <asm/bootinfo.h> -#include <asm/jazz.h> -#include <asm/jazzdma.h> - struct fd_ops { unsigned char (*fd_inb)(unsigned int port); void (*fd_outb)(unsigned char value, unsigned int port); @@ -50,7 +46,7 @@ extern struct fd_ops *fd_ops; #define fd_clear_dma_ff() fd_ops->fd_clear_dma_ff(FLOPPY_DMA) #define fd_set_dma_mode(mode) fd_ops->fd_set_dma_mode(FLOPPY_DMA, mode) #define fd_set_dma_addr(addr) fd_ops->fd_set_dma_addr(FLOPPY_DMA, \ - virt_to_bus(addr)) + isa_virt_to_bus(addr)) #define fd_set_dma_count(count) fd_ops->fd_set_dma_count(FLOPPY_DMA,count) #define fd_get_dma_residue() fd_ops->fd_get_dma_residue(FLOPPY_DMA) @@ -63,7 +59,8 @@ extern struct fd_ops *fd_ops; #define fd_dma_mem_alloc(size) fd_ops->fd_dma_mem_alloc(size) #define fd_dma_mem_free(mem,size) fd_ops->fd_dma_mem_free(mem,size) #define fd_drive_type(n) fd_ops->fd_drive_type(n) -#define fd_cacheflush(addr,size) dma_cache_wback_inv(addr,size) +#define fd_cacheflush(addr,size) \ + dma_cache_wback_inv((unsigned long)(addr),(size)) #define MAX_BUFFER_SECTORS 24 diff --git a/include/asm-mips/fp.h b/include/asm-mips/fp.h deleted file mode 100644 index 30c17dc83e44..000000000000 --- a/include/asm-mips/fp.h +++ /dev/null @@ -1,34 +0,0 @@ -/* $Id: fp.h,v 1.1 1998/07/16 19:10:04 ralf Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1998 by Ralf Baechle - */ - -/* - * Activate and deactive the floatingpoint accelerator. - */ -#define enable_cp1() \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\tnoat\n\t" \ - ".set\treorder\n\t" \ - "mfc0\t$1,$12\n\t" \ - "or\t$1,%0\n\t" \ - "mtc0\t$1,$12\n\t" \ - ".set\tpop" \ - : : "r" (ST0_CU1)); - -#define disable_cp1() \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\tnoat\n\t" \ - ".set\treorder\n\t" \ - "mfc0\t$1,$12\n\t" \ - "or\t$1,%0\n\t" \ - "xor\t$1,%0\n\t" \ - "mtc0\t$1,$12\n\t" \ - ".set\tpop" \ - : : "r" (ST0_CU1)); diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h new file mode 100644 index 000000000000..87b5e51b1e52 --- /dev/null +++ b/include/asm-mips/fpu.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef _ASM_FPU_H +#define _ASM_FPU_H + +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/thread_info.h> + +#include <asm/mipsregs.h> +#include <asm/cpu.h> +#include <asm/bitops.h> +#include <asm/processor.h> +#include <asm/current.h> + +struct sigcontext; + +extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); +extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); + +extern void fpu_emulator_init_fpu(void); +extern void _init_fpu(void); +extern void _save_fp(struct task_struct *); +extern void _restore_fp(struct task_struct *); + +#if defined(CONFIG_CPU_SB1) +#define __enable_fpu_hazard() \ +do { \ + asm(".set push \n\t" \ + ".set mips64 \n\t" \ + ".set noreorder \n\t" \ + "ssnop \n\t" \ + "bnezl $0, .+4 \n\t" \ + "ssnop \n\t" \ + ".set pop"); \ +} while (0) +#else +#define __enable_fpu_hazard() \ +do { \ + asm("nop;nop;nop;nop"); /* max. hazard */ \ +} while (0) +#endif + +#define __enable_fpu() \ +do { \ + set_c0_status(ST0_CU1); \ + __enable_fpu_hazard(); \ +} while (0) + +#define __disable_fpu() \ +do { \ + clear_c0_status(ST0_CU1); \ + /* We don't care about the c0 hazard here */ \ +} while (0) + +#define enable_fpu() \ +do { \ + if (cpu_has_fpu) \ + __enable_fpu(); \ +} while (0) + +#define disable_fpu() \ +do { \ + if (cpu_has_fpu) \ + __disable_fpu(); \ +} while (0) + + +#define clear_fpu_owner() clear_thread_flag(TIF_USEDFPU) + +static inline int is_fpu_owner(void) +{ + return cpu_has_fpu && test_thread_flag(TIF_USEDFPU); +} + +static inline void own_fpu(void) +{ + if (cpu_has_fpu) { + __enable_fpu(); + KSTK_STATUS(current) |= ST0_CU1; + set_thread_flag(TIF_USEDFPU); + } +} + +static inline void loose_fpu(void) +{ + if (cpu_has_fpu) { + KSTK_STATUS(current) &= ~ST0_CU1; + clear_thread_flag(TIF_USEDFPU); + __disable_fpu(); + } +} + +static inline void init_fpu(void) +{ + if (cpu_has_fpu) { + _init_fpu(); + } else { + fpu_emulator_init_fpu(); + } +} + +static inline void save_fp(struct task_struct *tsk) +{ + if (cpu_has_fpu) + _save_fp(tsk); +} + +static inline void restore_fp(struct task_struct *tsk) +{ + if (cpu_has_fpu) + _restore_fp(tsk); +} + +static inline unsigned long long *get_fpu_regs(struct task_struct *tsk) +{ + if (cpu_has_fpu) { + if ((tsk == current) && is_fpu_owner()) + _save_fp(current); + return (unsigned long long *)&tsk->thread.fpu.hard.fp_regs[0]; + } else { + return (unsigned long long *)tsk->thread.fpu.soft.regs; + } +} + +#endif /* _ASM_FPU_H */ diff --git a/include/asm-mips/fpu_emulator.h b/include/asm-mips/fpu_emulator.h index 70800480b87e..46972ae2b95d 100644 --- a/include/asm-mips/fpu_emulator.h +++ b/include/asm-mips/fpu_emulator.h @@ -1,15 +1,4 @@ /* - * Definitiona for the Algorithmics FPU Emulator port into MIPS Linux - */ -/************************************************************************** - * - * include/asm-mips/fpu_emulator.h - * - * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -23,13 +12,16 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - *************************************************************************/ -/* * Further private data for which no space exists in mips_fpu_soft_struct. * This should be subsumed into the mips_fpu_soft_struct structure as * defined in processor.h as soon as the absurd wired absolute assembler * offsets become dynamic at compile time. + * + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. */ +#ifndef _ASM_FPU_EMULATOR_H +#define _ASM_FPU_EMULATOR_H struct mips_fpu_emulator_private { unsigned int eir; @@ -42,3 +34,5 @@ struct mips_fpu_emulator_private { unsigned int errors; } stats; }; + +#endif /* _ASM_FPU_EMULATOR_H */ diff --git a/include/asm-mips/gdb-stub.h b/include/asm-mips/gdb-stub.h index 0bf2aafb9c30..b326a5ab172d 100644 --- a/include/asm-mips/gdb-stub.h +++ b/include/asm-mips/gdb-stub.h @@ -1,5 +1,4 @@ -/* $Id: gdb-stub.h,v 1.3 1998/07/20 17:52:19 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -58,7 +57,7 @@ #define GDB_FR_REG29 ((GDB_FR_REG28) + 4) /* 29 */ #define GDB_FR_REG30 ((GDB_FR_REG29) + 4) /* 30 */ #define GDB_FR_REG31 ((GDB_FR_REG30) + 4) /* 31 */ - + /* * Saved special registers */ @@ -133,7 +132,7 @@ #define GDB_FR_SIZE ((((GDB_FR_CP0_PRID) + 4) + (PTRSIZE-1)) & ~(PTRSIZE-1)) -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ /* * This is the same as above, but for the high-level @@ -181,7 +180,7 @@ struct gdb_regs { */ long frame_ptr; long dummy; /* unused */ - + /* * saved cp0 registers */ @@ -209,5 +208,5 @@ struct gdb_regs { void set_debug_traps(void); -#endif /* _LANGUAGE_ASSEMBLY */ +#endif /* !__ASSEMBLY__ */ #endif /* __ASM_MIPS_GDB_STUB_H */ diff --git a/include/asm-mips/gfx.h b/include/asm-mips/gfx.h index 38b0ad5d0bdf..37235e41a6fd 100644 --- a/include/asm-mips/gfx.h +++ b/include/asm-mips/gfx.h @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -7,7 +6,7 @@ * This is the user-visible SGI GFX interface. * * This must be used verbatim into the GNU libc. It does not include - * any kernel-only bits on it. + * any kernel-only bits on it. * * miguel@nuclecu.unam.mx */ diff --git a/include/asm-mips/gt64120.h b/include/asm-mips/gt64120.h index 5d78b6126f40..9cf9edcdd54d 100644 --- a/include/asm-mips/gt64120.h +++ b/include/asm-mips/gt64120.h @@ -60,7 +60,7 @@ #define GT_PCI1M0REMAP_OFS 0x110 #define GT_PCI1M1REMAP_OFS 0x118 -#define GT_SCS0LD_OFS 0x400 +#define GT_SCS0LD_OFS 0x400 #define GT_SCS0HD_OFS 0x404 #define GT_SCS1LD_OFS 0x408 #define GT_SCS1HD_OFS 0x40c @@ -324,7 +324,7 @@ #define GT_PCI0_BARE_SWSCS32DIS_SHF 1 #define GT_PCI0_BARE_SWSCS32DIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS32DIS_SHF) #define GT_PCI0_BARE_SWSCS32DIS_BIT GT_PCI0_BARE_SWSCS32DIS_MSK - + #define GT_PCI0_BARE_SWSCS10DIS_SHF 2 #define GT_PCI0_BARE_SWSCS10DIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS10DIS_SHF) #define GT_PCI0_BARE_SWSCS10DIS_BIT GT_PCI0_BARE_SWSCS10DIS_MSK diff --git a/include/asm-mips/hardirq.h b/include/asm-mips/hardirq.h index e66f39b59207..530c7fc80eb4 100644 --- a/include/asm-mips/hardirq.h +++ b/include/asm-mips/hardirq.h @@ -13,12 +13,9 @@ #include <linux/config.h> #include <linux/threads.h> #include <linux/irq.h> -#include <linux/spinlock.h> typedef struct { unsigned int __softirq_pending; - unsigned int __local_irq_count; - unsigned int __local_bh_count; unsigned int __syscall_count; struct task_struct * __ksoftirqd_task; /* waitqueue is too large */ } ____cacheline_aligned irq_cpustat_t; @@ -26,72 +23,83 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ /* - * Are we in an interrupt context? Either doing bottom half - * or hardware interrupt processing? + * We put the hardirq and softirq counter into the preemption + * counter. The bitmask has the following meaning: + * + * - bits 0-7 are the preemption count (max preemption depth: 256) + * - bits 8-15 are the softirq count (max # of softirqs: 256) + * - bits 16-23 are the hardirq count (max # of hardirqs: 256) + * + * - ( bit 26 is the PREEMPT_ACTIVE flag. ) + * + * PREEMPT_MASK: 0x000000ff + * SOFTIRQ_MASK: 0x0000ff00 + * HARDIRQ_MASK: 0x00ff0000 */ -#define in_interrupt() ({ int __cpu = smp_processor_id(); \ - (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); }) -#define in_irq() (local_irq_count(smp_processor_id()) != 0) - -#ifndef CONFIG_SMP - -#define hardirq_trylock(cpu) (local_irq_count(cpu) == 0) -#define hardirq_endlock(cpu) do { } while (0) - -#define irq_enter(cpu, irq) (local_irq_count(cpu)++) -#define irq_exit(cpu, irq) (local_irq_count(cpu)--) - -#define synchronize_irq() barrier(); - -#else -#include <asm/atomic.h> -#include <linux/spinlock.h> -#include <asm/smp.h> +#define PREEMPT_BITS 8 +#define SOFTIRQ_BITS 8 +#define HARDIRQ_BITS 8 -extern int global_irq_holder; -extern spinlock_t global_irq_lock; +#define PREEMPT_SHIFT 0 +#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) +#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) -static inline int irqs_running (void) -{ - int i; +#define __MASK(x) ((1UL << (x))-1) - for (i = 0; i < smp_num_cpus; i++) - if (local_irq_count(i)) - return 1; - return 0; -} +#define PREEMPT_MASK (__MASK(PREEMPT_BITS) << PREEMPT_SHIFT) +#define HARDIRQ_MASK (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) +#define SOFTIRQ_MASK (__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) -static inline void release_irqlock(int cpu) -{ - /* if we didn't own the irq lock, just ignore.. */ - if (global_irq_holder == cpu) { - global_irq_holder = NO_PROC_ID; - spin_unlock(&global_irq_lock); - } -} +#define hardirq_count() (preempt_count() & HARDIRQ_MASK) +#define softirq_count() (preempt_count() & SOFTIRQ_MASK) +#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) -static inline int hardirq_trylock(int cpu) -{ - return !local_irq_count(cpu) && !spin_is_locked(&global_irq_lock); -} +#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) +#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) +#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) -#define hardirq_endlock(cpu) do { } while (0) +/* + * The hardirq mask has to be large enough to have + * space for potentially all IRQ sources in the system + * nesting on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif -static inline void irq_enter(int cpu, int irq) -{ - ++local_irq_count(cpu); +/* + * Are we doing bottom half or hardware interrupt processing? + * Are we in a softirq context? Interrupt context? + */ +#define in_irq() (hardirq_count()) +#define in_softirq() (softirq_count()) +#define in_interrupt() (irq_count()) - while (spin_is_locked(&global_irq_lock)) - barrier(); -} +#define hardirq_trylock() (!in_interrupt()) +#define hardirq_endlock() do { } while (0) -static inline void irq_exit(int cpu, int irq) -{ - --local_irq_count(cpu); -} +#define irq_enter() (preempt_count() += HARDIRQ_OFFSET) -extern void synchronize_irq(void); +#if CONFIG_PREEMPT +# define in_atomic() (preempt_count() != kernel_locked()) +# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) +#else +# define in_atomic() (preempt_count() != 0) +# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET +#endif +#define irq_exit() \ +do { \ + preempt_count() -= IRQ_EXIT_OFFSET; \ + if (!in_interrupt() && softirq_pending(smp_processor_id())) \ + do_softirq(); \ + preempt_enable_no_resched(); \ +} while (0) +#ifndef CONFIG_SMP +# define synchronize_irq(irq) barrier() +#else + extern void synchronize_irq(unsigned int irq); #endif /* CONFIG_SMP */ + #endif /* _ASM_HARDIRQ_H */ diff --git a/include/asm-mips/highmem.h b/include/asm-mips/highmem.h new file mode 100644 index 000000000000..36f5da14b1a1 --- /dev/null +++ b/include/asm-mips/highmem.h @@ -0,0 +1,59 @@ +/* + * highmem.h: virtual kernel memory mappings for high memory + * + * Used in CONFIG_HIGHMEM systems for memory pages which + * are not addressable by direct kernel virtual addresses. + * + * Copyright (C) 1999 Gerhard Wichert, Siemens AG + * Gerhard.Wichert@pdb.siemens.de + * + * + * Redesigned the x86 32-bit VM architecture to deal with + * up to 16 Terabyte physical memory. With current x86 CPUs + * we now support up to 64 Gigabytes physical RAM. + * + * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com> + */ +#ifndef _ASM_HIGHMEM_H +#define _ASM_HIGHMEM_H + +#ifdef __KERNEL__ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <asm/kmap_types.h> + +/* undef for production */ +#define HIGHMEM_DEBUG 1 + +/* declarations for highmem.c */ +extern unsigned long highstart_pfn, highend_pfn; + +extern pte_t *kmap_pte; +extern pgprot_t kmap_prot; +extern pte_t *pkmap_page_table; + +/* + * Right now we initialize only a single pte table. It can be extended + * easily, subsequent pte tables have to be allocated in one physical + * chunk of RAM. + */ +#define PKMAP_BASE (0xfe000000UL) +#define LAST_PKMAP 1024 +#define LAST_PKMAP_MASK (LAST_PKMAP-1) +#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) +#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) + +extern void * kmap_high(struct page *page); +extern void kunmap_high(struct page *page); + +extern void *kmap(struct page *page); +extern void kunmap(struct page *page); +extern void *kmap_atomic(struct page *page, enum km_type type); +extern void kunmap_atomic(void *kvaddr, enum km_type type); +extern struct page *kmap_atomic_to_page(void *ptr); + +#endif /* __KERNEL__ */ + +#endif /* _ASM_HIGHMEM_H */ diff --git a/include/asm-mips/hw_irq.h b/include/asm-mips/hw_irq.h index 8dfa57d9be94..8be338b9ac10 100644 --- a/include/asm-mips/hw_irq.h +++ b/include/asm-mips/hw_irq.h @@ -3,14 +3,27 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2000, 2001 by Ralf Baechle + * Copyright (C) 2000, 2001, 2002 by Ralf Baechle */ -#ifndef _ASM_HW_IRQ_H -#define _ASM_HW_IRQ_H +#ifndef __ASM_HW_IRQ_H +#define __ASM_HW_IRQ_H + +#include <linux/profile.h> +#include <asm/atomic.h> + +extern void mask_irq(unsigned int irq); +extern void unmask_irq(unsigned int irq); +extern void disable_8259A_irq(unsigned int irq); +extern void enable_8259A_irq(unsigned int irq); +extern int i8259A_irq_pending(unsigned int irq); +extern void make_8259A_irq(unsigned int irq); +extern void init_8259A(int aeoi); + +extern atomic_t irq_err_count; /* This may not be apropriate for all machines, we'll see ... */ static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { } -#endif /* _ASM_HW_IRQ_H */ +#endif /* __ASM_HW_IRQ_H */ diff --git a/include/asm-mips/i8259.h b/include/asm-mips/i8259.h new file mode 100644 index 000000000000..f58612ec7da7 --- /dev/null +++ b/include/asm-mips/i8259.h @@ -0,0 +1,23 @@ +/* + * include/asm-mips/i8259.h + * + * i8259A interrupt definitions. + * + * Copyright (C) 2003 Maciej W. Rozycki + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef __ASM_MIPS_I8259_H +#define __ASM_MIPS_I8259_H + +#include <linux/spinlock.h> + +#include <asm/io.h> +#include <asm/system.h> + +extern void init_i8259_irqs(void); + +#endif /* __ASM_MIPS_I8259_H */ diff --git a/include/asm-mips/ide.h b/include/asm-mips/ide.h index 33cd055aea35..f377adcfb1a3 100644 --- a/include/asm-mips/ide.h +++ b/include/asm-mips/ide.h @@ -14,6 +14,7 @@ #ifdef __KERNEL__ #include <linux/config.h> +#include <asm/byteorder.h> #include <asm/io.h> #ifndef MAX_HWIFS @@ -58,11 +59,16 @@ static __inline__ void ide_init_default_hwifs(void) for(index = 0; index < MAX_HWIFS; index++) { ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL); hw.irq = ide_default_irq(ide_default_io_base(index)); - ide_register_hw(&hw); + ide_register_hw(&hw, NULL); } #endif } +#define __ide_mm_insw ide_insw +#define __ide_mm_insl ide_insl +#define __ide_mm_outsw ide_outsw +#define __ide_mm_outsl ide_outsl + #endif /* __KERNEL__ */ #endif /* __ASM_IDE_H */ diff --git a/include/asm-mips/inventory.h b/include/asm-mips/inventory.h index 7ea13dc13c5f..4cd36fe98173 100644 --- a/include/asm-mips/inventory.h +++ b/include/asm-mips/inventory.h @@ -1,12 +1,9 @@ /* - * $Id:$ + * Miguel de Icaza */ -#ifndef __ASM_MIPS_INVENTORY_H -#define __ASM_MIPS_INVENTORY_H +#ifndef __ASM_INVENTORY_H +#define __ASM_INVENTORY_H -#include <linux/config.h> - -#ifdef CONFIG_BINFMT_IRIX typedef struct inventory_s { struct inventory_s *inv_next; int inv_class; @@ -19,10 +16,5 @@ typedef struct inventory_s { extern int inventory_items; void add_to_inventory (int class, int type, int controller, int unit, int state); int dump_inventory_to_user (void *userbuf, int size); -void init_inventory (void); -#else -#define add_to_inventory(c,t,o,u,s) -#define init_inventory() -#endif -#endif /* defined(CONFIG_BINFMT_IRIX) */ +#endif /* __ASM_INVENTORY_H */ diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index 28a2bc81e4cc..f1f748b9ac5f 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -12,9 +12,22 @@ #define _ASM_IO_H #include <linux/config.h> -#include <linux/pagemap.h> +#include <linux/types.h> + #include <asm/addrspace.h> +#include <asm/pgtable-bits.h> #include <asm/byteorder.h> +#include <asm/mipsregs.h> + +#ifdef CONFIG_SGI_IP27 +extern unsigned long bus_to_baddr[256]; + +#define bus_to_baddr(bus, addr) (bus_to_baddr[(bus)->number] + (addr)) +#define baddr_to_bus(bus, addr) ((addr) - bus_to_baddr[(bus)->number]) +#else +#define bus_to_baddr(bus, addr) (addr) +#define baddr_to_bus(bus, addr) (addr) +#endif /* * Slowdown I/O port space accesses for antique hardware. @@ -28,7 +41,13 @@ #if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__) #define __ioswab8(x) (x) +#ifdef CONFIG_SGI_IP22 +/* IP22 seems braindead enough to swap 16bits values in hardware, but + not 32bits. Go figure... Can't tell without documentation. */ +#define __ioswab16(x) (x) +#else #define __ioswab16(x) swab16(x) +#endif #define __ioswab32(x) swab32(x) #else @@ -40,27 +59,17 @@ #endif /* - * This file contains the definitions for the MIPS counterpart of the - * x86 in/out instructions. This heap of macros and C results in much - * better code than the approach of doing it in plain C. The macros - * result in code that is to fast for certain hardware. On the other - * side the performance of the string functions should be improved for - * sake of certain devices like EIDE disks that do highspeed polled I/O. - * - * Ralf - * - * This file contains the definitions for the x86 IO instructions - * inb/inw/inl/outb/outw/outl and the "string versions" of the same - * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing" - * versions of the single-IO instructions (inb_p/inw_p/..). + * <Bacchus> Historically I wrote this stuff the same way as Linus did + * because I was young and clueless. And now it's so jucky that I + * don't want to put my eyes on it again to get rid of it :-) * - * This file is not meant to be obfuscating: it's just complicated - * to (a) handle it all in a way that makes gcc able to optimize it - * as well as possible and (b) trying to avoid writing the same thing - * over and over again with slight variations and possibly making a - * mistake somewhere. + * I'll do it then, because this code offends both me and my compiler + * - particularly the bits of inline asm which end up doing crap like + * 'lb $2,$2($5)' -- dwmw2 */ +#define IO_SPACE_LIMIT 0xffff + /* * On MIPS I/O ports are memory mapped, so we access them using normal * load/store instructions. mips_io_port_base is the virtual address to @@ -69,7 +78,10 @@ * instruction, so the lower 16 bits must be zero. Should be true on * on any sane architecture; generic code does not use this assumption. */ -extern unsigned long mips_io_port_base; +extern const unsigned long mips_io_port_base; + +#define set_io_port_base(base) \ + do { * (unsigned long *) &mips_io_port_base = (base); } while (0) /* * Thanks to James van Artsdalen for a better timing-fix than @@ -99,49 +111,116 @@ extern unsigned long mips_io_port_base; #endif /* - * Change virtual addresses to physical addresses and vv. - * These are trivial on the 1:1 Linux/MIPS mapping + * virt_to_phys - map virtual addresses to physical + * @address: address to remap + * + * The returned physical address is the physical (CPU) mapping for + * the memory address given. It is only valid to use this function on + * addresses directly mapped or allocated via kmalloc. + * + * This function does not give bus mappings for DMA transfers. In + * almost all conceivable cases a device driver should not be using + * this function */ -extern inline unsigned long virt_to_phys(volatile void * address) +static inline unsigned long virt_to_phys(volatile void * address) { return PHYSADDR(address); } -extern inline void * phys_to_virt(unsigned long address) +/* + * phys_to_virt - map physical address to virtual + * @address: address to remap + * + * The returned virtual address is a current CPU mapping for + * the memory address given. It is only valid to use this function on + * addresses that have a kernel mapping + * + * This function does not handle bus mappings for DMA transfers. In + * almost all conceivable cases a device driver should not be using + * this function + */ +static inline void * phys_to_virt(unsigned long address) { return (void *)KSEG0ADDR(address); } /* - * IO bus memory addresses are also 1:1 with the physical address + * ISA I/O bus memory addresses are 1:1 with the physical address. */ -extern inline unsigned long virt_to_bus(volatile void * address) +static inline unsigned long isa_virt_to_bus(volatile void * address) { return PHYSADDR(address); } -extern inline void * bus_to_virt(unsigned long address) +static inline void * isa_bus_to_virt(unsigned long address) { return (void *)KSEG0ADDR(address); } +#define isa_page_to_bus page_to_phys + +/* + * However PCI ones are not necessarily 1:1 and therefore these interfaces + * are forbidden in portable PCI drivers. + * + * Allow them for x86 for legacy drivers, though. + */ +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + /* * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped * for the processor. */ extern unsigned long isa_slot_offset; -extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); +/* + * Change "struct page" to physical address. + */ +#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) -extern inline void *ioremap(unsigned long offset, unsigned long size) -{ - return __ioremap(offset, size, _CACHE_UNCACHED); -} +extern void * __ioremap(phys_t offset, phys_t size, unsigned long flags); -extern inline void *ioremap_nocache(unsigned long offset, unsigned long size) -{ - return __ioremap(offset, size, _CACHE_UNCACHED); -} + +/* + * ioremap - map bus memory into CPU space + * @offset: bus address of the memory + * @size: size of the resource to map + * + * ioremap performs a platform specific sequence of operations to + * make bus memory CPU accessible via the readb/readw/readl/writeb/ + * writew/writel functions and the other mmio helpers. The returned + * address is not guaranteed to be usable directly as a virtual + * address. + */ +#define ioremap(offset, size) \ + __ioremap((offset), (size), _CACHE_UNCACHED) + +/* + * ioremap_nocache - map bus memory into CPU space + * @offset: bus address of the memory + * @size: size of the resource to map + * + * ioremap_nocache performs a platform specific sequence of operations to + * make bus memory CPU accessible via the readb/readw/readl/writeb/ + * writew/writel functions and the other mmio helpers. The returned + * address is not guaranteed to be usable directly as a virtual + * address. + * + * This version of ioremap ensures that the memory is marked uncachable + * on the CPU as well as honouring existing caching rules from things like + * the PCI bus. Note that there are other caches and buffers on many + * busses. In paticular driver authors should read up on PCI writes + * + * It's useful if some control registers are in such an area and + * write combining or read caching is not desirable: + */ +#define ioremap_nocache(offset, size) \ + __ioremap((offset), (size), _CACHE_UNCACHED) +#define ioremap_cacheable_cow(offset, size) \ + __ioremap((offset), (size), _CACHE_CACHABLE_COW) +#define ioremap_uncached_accelerated(offset, size) \ + __ioremap((offset), (size), _CACHE_UNCACHED_ACCELERATED) extern void iounmap(void *addr); @@ -150,26 +229,26 @@ extern void iounmap(void *addr); * 24-31 on SNI. * XXX more SNI hacks. */ -#define readb(addr) (*(volatile unsigned char *)(addr)) -#define readw(addr) __ioswab16((*(volatile unsigned short *)(addr))) -#define readl(addr) __ioswab32((*(volatile unsigned int *)(addr))) -#define __raw_readb readb -#define __raw_readw readw -#define __raw_readl readl - -#define writeb(b,addr) (*(volatile unsigned char *)(addr)) = (b) -#define writew(b,addr) (*(volatile unsigned short *)(addr)) = (__ioswab16(b)) -#define writel(b,addr) (*(volatile unsigned int *)(addr)) = (__ioswab32(b)) -#define __raw_writeb writeb -#define __raw_writew writew -#define __raw_writel writel +#define readb(addr) (*(volatile unsigned char *)(addr)) +#define readw(addr) __ioswab16((*(volatile unsigned short *)(addr))) +#define readl(addr) __ioswab32((*(volatile unsigned int *)(addr))) + +#define __raw_readb(addr) (*(volatile unsigned char *)(addr)) +#define __raw_readw(addr) (*(volatile unsigned short *)(addr)) +#define __raw_readl(addr) (*(volatile unsigned int *)(addr)) + +#define writeb(b,addr) ((*(volatile unsigned char *)(addr)) = (__ioswab8(b))) +#define writew(b,addr) ((*(volatile unsigned short *)(addr)) = (__ioswab16(b))) +#define writel(b,addr) ((*(volatile unsigned int *)(addr)) = (__ioswab32(b))) + +#define __raw_writeb(b,addr) ((*(volatile unsigned char *)(addr)) = (b)) +#define __raw_writew(w,addr) ((*(volatile unsigned short *)(addr)) = (w)) +#define __raw_writel(l,addr) ((*(volatile unsigned int *)(addr)) = (l)) #define memset_io(a,b,c) memset((void *)(a),(b),(c)) #define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) #define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) -/* END SNI HACKS ... */ - /* * ISA space is 'always mapped' on currently supported MIPS systems, no need * to explicitly ioremap() it. The fact that the ISA IO space is mapped @@ -178,18 +257,17 @@ extern void iounmap(void *addr); * used as the IO-area pointer (it can be iounmapped as well, so the * analogy with PCI is quite large): */ -#define __ISA_IO_base ((char *)(PAGE_OFFSET)) - -#define isa_readb(a) readb(a) -#define isa_readw(a) readw(a) -#define isa_readl(a) readl(a) -#define isa_writeb(b,a) writeb(b,a) -#define isa_writew(w,a) writew(w,a) -#define isa_writel(l,a) writel(l,a) - -#define isa_memset_io(a,b,c) memset_io((a),(b),(c)) -#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),(b),(c)) -#define isa_memcpy_toio(a,b,c) memcpy_toio((a),(b),(c)) +#define __ISA_IO_base ((char *)(isa_slot_offset)) + +#define isa_readb(a) readb(__ISA_IO_base + (a)) +#define isa_readw(a) readw(__ISA_IO_base + (a)) +#define isa_readl(a) readl(__ISA_IO_base + (a)) +#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a)) +#define isa_writew(w,a) writew(w,__ISA_IO_base + (a)) +#define isa_writel(l,a) writel(l,__ISA_IO_base + (a)) +#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c)) +#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c)) /* * We don't have csum_partial_copy_fromio() yet, so we cheat here and @@ -198,6 +276,16 @@ extern void iounmap(void *addr); #define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len)) #define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(b),(c),(d)) +/* + * check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the mmio address io_addr. This + * address should have been obtained by ioremap. + * Returns 1 on a match. + */ static inline int check_signature(unsigned long io_addr, const unsigned char *signature, int length) { @@ -213,209 +301,160 @@ static inline int check_signature(unsigned long io_addr, out: return retval; } -#define isa_check_signature(io, s, l) check_signature(i,s,l) /* - * Talk about misusing macros.. + * isa_check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the ISA mmio address io_addr. + * Returns 1 on a match. + * + * This function is deprecated. New drivers should use ioremap and + * check_signature. */ +#define isa_check_signature(io, s, l) check_signature(i,s,l) -#define __OUT1(s) \ -extern inline void __out##s(unsigned int value, unsigned int port) { -#define __OUT2(m) \ -__asm__ __volatile__ ("s" #m "\t%0,%1(%2)" +#define outb(val,port) \ +do { \ + *(volatile u8 *)(mips_io_port_base + (port)) = __ioswab8(val); \ +} while(0) + +#define outw(val,port) \ +do { \ + *(volatile u16 *)(mips_io_port_base + (port)) = __ioswab16(val); \ +} while(0) + +#define outl(val,port) \ +do { \ + *(volatile u32 *)(mips_io_port_base + (port)) = __ioswab32(val);\ +} while(0) + +#define outb_p(val,port) \ +do { \ + *(volatile u8 *)(mips_io_port_base + (port)) = __ioswab8(val); \ + SLOW_DOWN_IO; \ +} while(0) + +#define outw_p(val,port) \ +do { \ + *(volatile u16 *)(mips_io_port_base + (port)) = __ioswab16(val);\ + SLOW_DOWN_IO; \ +} while(0) + +#define outl_p(val,port) \ +do { \ + *(volatile u32 *)(mips_io_port_base + (port)) = __ioswab32(val);\ + SLOW_DOWN_IO; \ +} while(0) + +#define inb(port) __inb(port) +#define inw(port) __inw(port) +#define inl(port) __inl(port) +#define inb_p(port) __inb_p(port) +#define inw_p(port) __inw_p(port) +#define inl_p(port) __inl_p(port) + +static inline unsigned char __inb(unsigned long port) +{ + return __ioswab8(*(volatile u8 *)(mips_io_port_base + port)); +} -#define __OUT(m,s,w) \ -__OUT1(s) __OUT2(m) : : "r" (__ioswab##w(value)), "i" (0), "r" (mips_io_port_base+port)); } \ -__OUT1(s##c) __OUT2(m) : : "r" (__ioswab##w(value)), "ir" (port), "r" (mips_io_port_base)); } \ -__OUT1(s##_p) __OUT2(m) : : "r" (__ioswab##w(value)), "i" (0), "r" (mips_io_port_base+port)); \ - SLOW_DOWN_IO; } \ -__OUT1(s##c_p) __OUT2(m) : : "r" (__ioswab##w(value)), "ir" (port), "r" (mips_io_port_base)); \ - SLOW_DOWN_IO; } +static inline unsigned short __inw(unsigned long port) +{ + return __ioswab16(*(volatile u16 *)(mips_io_port_base + port)); +} -#define __IN1(t,s) \ -extern __inline__ t __in##s(unsigned int port) { t _v; +static inline unsigned int __inl(unsigned long port) +{ + return __ioswab32(*(volatile u32 *)(mips_io_port_base + port)); +} -/* - * Required nops will be inserted by the assembler - */ -#define __IN2(m) \ -__asm__ __volatile__ ("l" #m "\t%0,%1(%2)" - -#define __IN(t,m,s,w) \ -__IN1(t,s) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); return __ioswab##w(_v); } \ -__IN1(t,s##c) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); return __ioswab##w(_v); } \ -__IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); SLOW_DOWN_IO; return __ioswab##w(_v); } \ -__IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return __ioswab##w(_v); } - -#define __INS1(s) \ -extern inline void __ins##s(unsigned int port, void * addr, unsigned long count) { - -#define __INS2(m) \ -if (count) \ -__asm__ __volatile__ ( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n" \ - "1:\tl" #m "\t$1,%4(%5)\n\t" \ - "subu\t%1,1\n\t" \ - "s" #m "\t$1,(%0)\n\t" \ - "bne\t$0,%1,1b\n\t" \ - "addiu\t%0,%6\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" - -#define __INS(m,s,i) \ -__INS1(s) __INS2(m) \ - : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "i" (0), \ - "r" (mips_io_port_base+port), "I" (i) \ - : "$1");} \ -__INS1(s##c) __INS2(m) \ - : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "ir" (port), \ - "r" (mips_io_port_base), "I" (i) \ - : "$1");} - -#define __OUTS1(s) \ -extern inline void __outs##s(unsigned int port, const void * addr, unsigned long count) { - -#define __OUTS2(m) \ -if (count) \ -__asm__ __volatile__ ( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n" \ - "1:\tl" #m "\t$1,(%0)\n\t" \ - "subu\t%1,1\n\t" \ - "s" #m "\t$1,%4(%5)\n\t" \ - "bne\t$0,%1,1b\n\t" \ - "addiu\t%0,%6\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" - -#define __OUTS(m,s,i) \ -__OUTS1(s) __OUTS2(m) \ - : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \ - : "$1");} \ -__OUTS1(s##c) __OUTS2(m) \ - : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \ - : "$1");} - -__IN(unsigned char,b,b,8) -__IN(unsigned short,h,w,16) -__IN(unsigned int,w,l,32) - -__OUT(b,b,8) -__OUT(h,w,16) -__OUT(w,l,32) - -__INS(b,b,1) -__INS(h,w,2) -__INS(w,l,4) - -__OUTS(b,b,1) -__OUTS(h,w,2) -__OUTS(w,l,4) +static inline unsigned char __inb_p(unsigned long port) +{ + u8 __val; + __val = *(volatile u8 *)(mips_io_port_base + port); + SLOW_DOWN_IO; -/* - * Note that due to the way __builtin_constant_p() works, you - * - can't use it inside an inline function (it will never be true) - * - you don't have to worry about side effects within the __builtin.. - */ -#define outb(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outbc((val),(port)) : \ - __outb((val),(port))) - -#define inb(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inbc(port) : \ - __inb(port)) - -#define outb_p(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outbc_p((val),(port)) : \ - __outb_p((val),(port))) - -#define inb_p(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inbc_p(port) : \ - __inb_p(port)) - -#define outw(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outwc((val),(port)) : \ - __outw((val),(port))) - -#define inw(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inwc(port) : \ - __inw(port)) - -#define outw_p(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outwc_p((val),(port)) : \ - __outw_p((val),(port))) - -#define inw_p(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inwc_p(port) : \ - __inw_p(port)) - -#define outl(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outlc((val),(port)) : \ - __outl((val),(port))) - -#define inl(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inlc(port) : \ - __inl(port)) - -#define outl_p(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outlc_p((val),(port)) : \ - __outl_p((val),(port))) - -#define inl_p(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inlc_p(port) : \ - __inl_p(port)) - - -#define outsb(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outsbc((port),(addr),(count)) : \ - __outsb ((port),(addr),(count))) - -#define insb(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __insbc((port),(addr),(count)) : \ - __insb((port),(addr),(count))) - -#define outsw(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outswc((port),(addr),(count)) : \ - __outsw ((port),(addr),(count))) - -#define insw(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inswc((port),(addr),(count)) : \ - __insw((port),(addr),(count))) - -#define outsl(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outslc((port),(addr),(count)) : \ - __outsl ((port),(addr),(count))) - -#define insl(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inslc((port),(addr),(count)) : \ - __insl((port),(addr),(count))) + return __ioswab8(__val); +} -#define IO_SPACE_LIMIT 0xffff +static inline unsigned short __inw_p(unsigned long port) +{ + u16 __val; + + __val = *(volatile u16 *)(mips_io_port_base + port); + SLOW_DOWN_IO; + + return __ioswab16(__val); +} + +static inline unsigned int __inl_p(unsigned long port) +{ + u32 __val; + + __val = *(volatile u32 *)(mips_io_port_base + port); + SLOW_DOWN_IO; + return __ioswab32(__val); +} + +#define outsb(port, addr, count) __outsb(port, addr, count) +#define insb(port, addr, count) __insb(port, addr, count) +#define outsw(port, addr, count) __outsw(port, addr, count) +#define insw(port, addr, count) __insw(port, addr, count) +#define outsl(port, addr, count) __outsl(port, addr, count) +#define insl(port, addr, count) __insl(port, addr, count) + +static inline void __outsb(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + outb(*(u8 *)addr, port); + addr++; + } +} + +static inline void __insb(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u8 *)addr = inb(port); + addr++; + } +} + +static inline void __outsw(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + outw(*(u16 *)addr, port); + addr += 2; + } +} + +static inline void __insw(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u16 *)addr = inw(port); + addr += 2; + } +} + +static inline void __outsl(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + outl(*(u32 *)addr, port); + addr += 4; + } +} + +static inline void __insl(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u32 *)addr = inl(port); + addr += 4; + } +} /* * The caches on some architectures aren't dma-coherent and have need to @@ -435,12 +474,25 @@ __OUTS(w,l,4) * be discarded. This operation is necessary before dma operations * to the memory. */ +#ifdef CONFIG_NONCOHERENT_IO + extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size); extern void (*_dma_cache_wback)(unsigned long start, unsigned long size); extern void (*_dma_cache_inv)(unsigned long start, unsigned long size); -#define dma_cache_wback_inv(start,size) _dma_cache_wback_inv(start,size) -#define dma_cache_wback(start,size) _dma_cache_wback(start,size) -#define dma_cache_inv(start,size) _dma_cache_inv(start,size) +#define dma_cache_wback_inv(start, size)_dma_cache_wback_inv(start,size) +#define dma_cache_wback(start, size) _dma_cache_wback(start,size) +#define dma_cache_inv(start, size) _dma_cache_inv(start,size) + +#else /* Sane hardware */ + +#define dma_cache_wback_inv(start,size) \ + do { (void) (start); (void) (size); } while (0) +#define dma_cache_wback(start,size) \ + do { (void) (start); (void) (size); } while (0) +#define dma_cache_inv(start,size) \ + do { (void) (start); (void) (size); } while (0) + +#endif /* CONFIG_NONCOHERENT_IO */ #endif /* _ASM_IO_H */ diff --git a/include/asm-mips/ioctls.h b/include/asm-mips/ioctls.h index 1fd384f2bc13..92f6c36aac4d 100644 --- a/include/asm-mips/ioctls.h +++ b/include/asm-mips/ioctls.h @@ -12,7 +12,7 @@ #include <asm/ioctl.h> #define TCGETA 0x5401 -#define TCSETA 0x5402 +#define TCSETA 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */ #define TCSETAW 0x5403 #define TCSETAF 0x5404 @@ -49,7 +49,7 @@ #define TIOCGETD 0x7400 #define FIOCLEX 0x6601 -#define FIONCLEX 0x6602 /* these numbers need to be adjusted. */ +#define FIONCLEX 0x6602 #define FIOASYNC 0x667d #define FIONBIO 0x667e #define FIOQSIZE 0x667f @@ -66,7 +66,7 @@ #define TIOCGETP 0x7408 #define TIOCSETP 0x7409 #define TIOCSETN 0x740a /* TIOCSETP wo flush */ - + /* #define TIOCSETA _IOW('t', 20, struct termios) set termios struct */ /* #define TIOCSETAW _IOW('t', 21, struct termios) drain output, set */ /* #define TIOCSETAF _IOW('t', 22, struct termios) drn out, fls in, set */ diff --git a/include/asm-mips/ipc.h b/include/asm-mips/ipc.h index 006d47307970..eaf4b8631435 100644 --- a/include/asm-mips/ipc.h +++ b/include/asm-mips/ipc.h @@ -1,7 +1,7 @@ #ifndef __ASM_MIPS_IPC_H #define __ASM_MIPS_IPC_H -/* +/* * These are used to wrap system calls on MIPS. * * See arch/mips/kernel/sysmips.c for ugly details.. @@ -15,6 +15,7 @@ struct ipc_kludge { #define SEMOP 1 #define SEMGET 2 #define SEMCTL 3 +#define SEMTIMEDOP 4 #define MSGSND 11 #define MSGRCV 12 #define MSGGET 13 diff --git a/include/asm-mips/ipcbuf.h b/include/asm-mips/ipcbuf.h index 4c898f677cb0..d47d08f264e7 100644 --- a/include/asm-mips/ipcbuf.h +++ b/include/asm-mips/ipcbuf.h @@ -1,7 +1,7 @@ #ifndef _ASM_IPCBUF_H #define _ASM_IPCBUF_H -/* +/* * The ipc64_perm structure for alpha architecture. * Note extra padding because this structure is passed back and forth * between kernel and user space. @@ -18,7 +18,7 @@ struct ipc64_perm __kernel_gid_t gid; __kernel_uid_t cuid; __kernel_gid_t cgid; - __kernel_mode_t mode; + __kernel_mode_t mode; unsigned short seq; unsigned short __pad1; unsigned long __unused1; diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h index bea209e24a50..4bb7750583d8 100644 --- a/include/asm-mips/irq.h +++ b/include/asm-mips/irq.h @@ -4,16 +4,17 @@ * for more details. * * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle - * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle + * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 2001 Kanoj Sarcar */ #ifndef _ASM_IRQ_H #define _ASM_IRQ_H #include <linux/config.h> +#include <linux/linkage.h> -#define NR_IRQS 64 /* Largest number of ints of all machines. */ - -#define TIMER_IRQ 0 +#define NR_IRQS 128 /* Largest number of ints of all machines. */ #ifdef CONFIG_I8259 static inline int irq_canonicalize(int irq) @@ -24,19 +25,16 @@ static inline int irq_canonicalize(int irq) #define irq_canonicalize(irq) (irq) /* Sane hardware, sane code ... */ #endif -struct irqaction; -extern int i8259_setup_irq(int irq, struct irqaction * new); extern void disable_irq(unsigned int); - -#ifndef CONFIG_NEW_IRQ -#define disable_irq_nosync disable_irq -#else extern void disable_irq_nosync(unsigned int); -#endif - extern void enable_irq(unsigned int); +struct pt_regs; +extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); + /* Machine specific interrupt initialization */ extern void (*irq_setup)(void); +extern void init_generic_irq(void); + #endif /* _ASM_IRQ_H */ diff --git a/include/asm-mips/irq_cpu.h b/include/asm-mips/irq_cpu.h new file mode 100644 index 000000000000..9baaca62a180 --- /dev/null +++ b/include/asm-mips/irq_cpu.h @@ -0,0 +1,18 @@ +/* + * include/asm-mips/irq_cpu.h + * + * MIPS CPU interrupt definitions. + * + * Copyright (C) 2002 Maciej W. Rozycki + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef __ASM_MIPS_IRQ_CPU_H +#define __ASM_MIPS_IRQ_CPU_H + +extern void mips_cpu_irq_init(int irq_base); + +#endif /* __ASM_MIPS_IRQ_CPU_H */ diff --git a/include/asm-mips/isadep.h b/include/asm-mips/isadep.h index b3453bb3ba34..7bb003511d9e 100644 --- a/include/asm-mips/isadep.h +++ b/include/asm-mips/isadep.h @@ -10,7 +10,7 @@ #ifndef __ASM_ISADEP_H #define __ASM_ISADEP_H -#if defined(CONFIG_CPU_R3000) +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) /* * R2000 or R3000 */ diff --git a/include/asm-mips/keyboard.h b/include/asm-mips/keyboard.h new file mode 100644 index 000000000000..b80dd875e71c --- /dev/null +++ b/include/asm-mips/keyboard.h @@ -0,0 +1,96 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994 - 1999 Ralf Baechle + */ +#ifndef _ASM_KEYBOARD_H +#define _ASM_KEYBOARD_H + +#ifdef __KERNEL__ + +#include <linux/config.h> +#include <linux/delay.h> +#include <linux/ioport.h> +#include <linux/kd.h> +#include <linux/pm.h> + +#define DISABLE_KBD_DURING_INTERRUPTS 0 + +#ifdef CONFIG_PC_KEYB + +extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int pckbd_getkeycode(unsigned int scancode); +extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char pckbd_unexpected_up(unsigned char keycode); +extern void pckbd_leds(unsigned char leds); +extern void pckbd_init_hw(void); +extern int pckbd_pm_resume(struct pm_dev *, pm_request_t, void *); +extern pm_callback pm_kbd_request_override; +extern unsigned char pckbd_sysrq_xlate[128]; +extern void kbd_forward_char (int ch); + +#define kbd_setkeycode pckbd_setkeycode +#define kbd_getkeycode pckbd_getkeycode +#define kbd_translate pckbd_translate +#define kbd_unexpected_up pckbd_unexpected_up +#define kbd_leds pckbd_leds +#define kbd_init_hw pckbd_init_hw +#define kbd_sysrq_xlate pckbd_sysrq_xlate + +#define SYSRQ_KEY 0x54 + +/* Some stoneage hardware needs delays after some operations. */ +#define kbd_pause() do { } while(0) + +struct kbd_ops { + /* Keyboard driver resource allocation */ + void (*kbd_request_region)(void); + int (*kbd_request_irq)(void (*handler)(int, void *, struct pt_regs *)); + + /* PSaux driver resource management */ + int (*aux_request_irq)(void (*handler)(int, void *, struct pt_regs *)); + void (*aux_free_irq)(void); + + /* Methods to access the keyboard processor's I/O registers */ + unsigned char (*kbd_read_input)(void); + void (*kbd_write_output)(unsigned char val); + void (*kbd_write_command)(unsigned char val); + unsigned char (*kbd_read_status)(void); +}; + +extern struct kbd_ops *kbd_ops; + +/* Do the actual calls via kbd_ops vector */ +#define kbd_request_region() kbd_ops->kbd_request_region() +#define kbd_request_irq(handler) kbd_ops->kbd_request_irq(handler) + +#define aux_request_irq(hand, dev_id) kbd_ops->aux_request_irq(hand) +#define aux_free_irq(dev_id) kbd_ops->aux_free_irq() + +#define kbd_read_input() kbd_ops->kbd_read_input() +#define kbd_write_output(val) kbd_ops->kbd_write_output(val) +#define kbd_write_command(val) kbd_ops->kbd_write_command(val) +#define kbd_read_status() kbd_ops->kbd_read_status() + +#else + +extern int kbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int kbd_getkeycode(unsigned int scancode); +extern int kbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char kbd_unexpected_up(unsigned char keycode); +extern void kbd_leds(unsigned char leds); +extern void kbd_init_hw(void); +extern unsigned char *kbd_sysrq_xlate; + +extern unsigned char kbd_sysrq_key; +#define SYSRQ_KEY kbd_sysrq_key + +#endif + +#endif /* __KERNEL */ + +#endif /* _ASM_KEYBOARD_H */ diff --git a/include/asm-mips/kmap_types.h b/include/asm-mips/kmap_types.h new file mode 100644 index 000000000000..a117c0ade4d0 --- /dev/null +++ b/include/asm-mips/kmap_types.h @@ -0,0 +1,32 @@ +#ifndef _ASM_KMAP_TYPES_H +#define _ASM_KMAP_TYPES_H + +#include <linux/config.h> + +#ifdef CONFIG_DEBUG_HIGHMEM +# define D(n) __KM_FENCE_##n , +#else +# define D(n) +#endif + +enum km_type { +D(0) KM_BOUNCE_READ, +D(1) KM_SKB_SUNRPC_DATA, +D(2) KM_SKB_DATA_SOFTIRQ, +D(3) KM_USER0, +D(4) KM_USER1, +D(5) KM_BIO_SRC_IRQ, +D(6) KM_BIO_DST_IRQ, +D(7) KM_PTE0, +D(8) KM_PTE1, +D(9) KM_PTE2, +D(10) KM_IRQ0, +D(11) KM_IRQ1, +D(12) KM_SOFTIRQ0, +D(13) KM_SOFTIRQ1, +D(14) KM_TYPE_NR +}; + +#undef D + +#endif diff --git a/include/asm-mips/mc146818rtc.h b/include/asm-mips/mc146818rtc.h index 6e23e432f335..cc6eeef7cbad 100644 --- a/include/asm-mips/mc146818rtc.h +++ b/include/asm-mips/mc146818rtc.h @@ -6,33 +6,15 @@ * Machine dependent access functions for RTC registers. * * Copyright (C) 1996, 1997, 1998, 2000 Ralf Baechle + * Copyright (C) 2002 Maciej W. Rozycki */ #ifndef _ASM_MC146818RTC_H #define _ASM_MC146818RTC_H #include <linux/config.h> -#include <asm/io.h> -#ifndef RTC_PORT -#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) -#define RTC_PORT(x) (0x14014800 + (x)) -#else -#define RTC_PORT(x) (0x70 + (x)) -#endif -#endif +#include <asm/io.h> -/* - * The yet supported machines all access the RTC index register via - * an ISA port access but the way to access the date register differs ... - */ -#define CMOS_READ(addr) ({ \ -rtc_ops->rtc_read_data(addr); \ -}) -#define CMOS_WRITE(val, addr) ({ \ -rtc_ops->rtc_write_data(val, addr); \ -}) -#define RTC_ALWAYS_BCD \ -rtc_ops->rtc_bcd_mode() /* * This structure defines how to access various features of @@ -47,15 +29,38 @@ struct rtc_ops { extern struct rtc_ops *rtc_ops; +/* + * Most supported machines access the RTC index register via an ISA + * port access but the way to access the date register differs ... + * The DECstation directly maps the RTC memory in the CPU's address + * space with the chipset generating necessary index write/data access + * cycles automagically. + */ +#define CMOS_READ(addr) ({ \ +rtc_ops->rtc_read_data(addr); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +rtc_ops->rtc_write_data(val, addr); \ +}) +#define RTC_ALWAYS_BCD \ +rtc_ops->rtc_bcd_mode() + + #ifdef CONFIG_DECSTATION -#define RTC_IRQ 0 -#elif defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) -#include <asm/it8172/it8172_int.h> -#define RTC_IRQ IT8172_RTC_IRQ + +#include <asm/dec/rtc-dec.h> + +#elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100) + +#define RTC_PORT(x) (0x0c000000 + (x)) +#define RTC_IOMAPPED 0 +#define RTC_IRQ 0 + #else -#define RTC_IRQ 8 -#endif -#define RTC_DEC_YEAR 0x3f /* Where we store the real year on DECs. */ +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_IRQ 8 + +#endif #endif /* _ASM_MC146818RTC_H */ diff --git a/include/asm-mips/mips32_cache.h b/include/asm-mips/mips32_cache.h deleted file mode 100644 index 2de18bd7cb71..000000000000 --- a/include/asm-mips/mips32_cache.h +++ /dev/null @@ -1,288 +0,0 @@ -/* - * mips32_cache.h - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Inline assembly cache operations. - * - * This file is the original r4cache.c file with modification that makes the - * cache handling more generic. - * - * FIXME: Handle split L2 caches. - * - */ -#ifndef _MIPS_R4KCACHE_H -#define _MIPS_R4KCACHE_H - -#include <asm/asm.h> -#include <asm/cacheops.h> - -extern inline void flush_icache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Invalidate_I)); -} - -extern inline void flush_dcache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Writeback_Inv_D)); -} - -extern inline void flush_scache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Writeback_Inv_SD)); -} - -extern inline void flush_icache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); -} - -extern inline void flush_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Writeback_Inv_D)); -} - -extern inline void invalidate_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_D)); -} - -extern inline void invalidate_scache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_SD)); -} - -extern inline void flush_scache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Writeback_Inv_SD)); -} - -/* - * The next two are for badland addresses like signal trampolines. - */ -extern inline void protected_flush_icache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n" - "1:\tcache %1,(%0)\n" - "2:\t.set mips0\n\t" - ".set reorder\n\t" - ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,2b\n\t" - ".previous" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); -} - -extern inline void protected_writeback_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n" - "1:\tcache %1,(%0)\n" - "2:\t.set mips0\n\t" - ".set reorder\n\t" - ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,2b\n\t" - ".previous" - : - : "r" (addr), - "i" (Hit_Writeback_D)); -} - -#define cache_unroll(base,op) \ - __asm__ __volatile__(" \ - .set noreorder; \ - .set mips3; \ - cache %1, (%0); \ - .set mips0; \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - - -extern inline void blast_dcache(void) -{ - unsigned long start = KSEG0; - unsigned long end = (start + dcache_size); - - while(start < end) { - cache_unroll(start,Index_Writeback_Inv_D); - start += dc_lsize; - } -} - -extern inline void blast_dcache_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache_unroll(start,Hit_Writeback_Inv_D); - start += dc_lsize; - } -} - -extern inline void blast_dcache_page_indexed(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache_unroll(start,Index_Writeback_Inv_D); - start += dc_lsize; - } -} - -extern inline void blast_icache(void) -{ - unsigned long start = KSEG0; - unsigned long end = (start + icache_size); - - while(start < end) { - cache_unroll(start,Index_Invalidate_I); - start += ic_lsize; - } -} - -extern inline void blast_icache_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache_unroll(start,Hit_Invalidate_I); - start += ic_lsize; - } -} - -extern inline void blast_icache_page_indexed(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache_unroll(start,Index_Invalidate_I); - start += ic_lsize; - } -} - -extern inline void blast_scache(void) -{ - unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; - - while(start < end) { - cache_unroll(start,Index_Writeback_Inv_SD); - start += sc_lsize; - } -} - -extern inline void blast_scache_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = page + PAGE_SIZE; - - while(start < end) { - cache_unroll(start,Hit_Writeback_Inv_SD); - start += sc_lsize; - } -} - -extern inline void blast_scache_page_indexed(unsigned long page) -{ - unsigned long start = page; - unsigned long end = page + PAGE_SIZE; - - while(start < end) { - cache_unroll(start,Index_Writeback_Inv_SD); - start += sc_lsize; - } -} - -#endif /* !(_MIPS_R4KCACHE_H) */ diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index ea791fc15eb7..6f266efe226c 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -8,10 +8,12 @@ * Modified for further R[236]000 support by Paul M. Antoine, 1996. * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2003 Maciej W. Rozycki */ #ifndef _ASM_MIPSREGS_H #define _ASM_MIPSREGS_H +#include <linux/config.h> #include <linux/linkage.h> /* @@ -26,6 +28,15 @@ #endif /* + * Configure language + */ +#ifdef __ASSEMBLY__ +#define _ULCAST_ +#else +#define _ULCAST_ (unsigned long) +#endif + +/* * Coprocessor 0 register names */ #define CP0_INDEX $0 @@ -52,12 +63,15 @@ #define CP0_XCONTEXT $20 #define CP0_FRAMEMASK $21 #define CP0_DIAGNOSTIC $22 +#define CP0_DEBUG $23 +#define CP0_DEPC $24 #define CP0_PERFORMANCE $25 #define CP0_ECC $26 #define CP0_CACHEERR $27 #define CP0_TAGLO $28 #define CP0_TAGHI $29 #define CP0_ERROREPC $30 +#define CP0_DESAVE $31 /* * R4640/R4650 cp0 register names. These registers are listed @@ -73,12 +87,18 @@ #define CP0_IWATCH $18 #define CP0_DWATCH $19 -/* +/* * Coprocessor 0 Set 1 register names */ #define CP0_S1_DERRADDR0 $26 #define CP0_S1_DERRADDR1 $27 #define CP0_S1_INTCONTROL $20 + +/* + * TX39 Series + */ +#define CP0_TX39_CACHE $7 + /* * Coprocessor 1 (FPU) register names */ @@ -108,7 +128,7 @@ * E the exception enable * S the sticky/flag bit */ -#define FPU_CSR_ALL_X 0x0003f000 +#define FPU_CSR_ALL_X 0x0003f000 #define FPU_CSR_UNI_X 0x00020000 #define FPU_CSR_INV_X 0x00010000 #define FPU_CSR_DIV_X 0x00008000 @@ -140,176 +160,66 @@ /* * Values for PageMask register */ -#include <linux/config.h> #ifdef CONFIG_CPU_VR41XX -#define PM_1K 0x00000000 -#define PM_4K 0x00001800 -#define PM_16K 0x00007800 -#define PM_64K 0x0001f800 -#define PM_256K 0x0007f800 -#else -#define PM_4K 0x00000000 -#define PM_16K 0x00006000 -#define PM_64K 0x0001e000 -#define PM_256K 0x0007e000 -#define PM_1M 0x001fe000 -#define PM_4M 0x007fe000 -#define PM_16M 0x01ffe000 -#endif -/* - * Values used for computation of new tlb entries - */ -#define PL_4K 12 -#define PL_16K 14 -#define PL_64K 16 -#define PL_256K 18 -#define PL_1M 20 -#define PL_4M 22 -#define PL_16M 24 +/* Why doesn't stupidity hurt ... */ -/* - * Macros to access the system control coprocessor - */ -#define read_32bit_cp0_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - "mfc0\t%0,"STR(source)"\n\t" \ - ".set\tpop" \ - : "=r" (__res)); \ - __res;}) - -#define read_32bit_cp0_set1_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - "cfc0\t%0,"STR(source)"\n\t" \ - ".set\tpop" \ - : "=r" (__res)); \ - __res;}) +#define PM_1K 0x00000000 +#define PM_4K 0x00001800 +#define PM_16K 0x00007800 +#define PM_64K 0x0001f800 +#define PM_256K 0x0007f800 -/* - * For now use this only with interrupts disabled! - */ -#define read_64bit_cp0_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tmips3\n\t" \ - "dmfc0\t%0,"STR(source)"\n\t" \ - ".set\tmips0" \ - : "=r" (__res)); \ - __res;}) +#else -#define write_32bit_cp0_register(register,value) \ - __asm__ __volatile__( \ - "mtc0\t%0,"STR(register)"\n\t" \ - "nop" \ - : : "r" (value)); +#define PM_4K 0x00000000 +#define PM_16K 0x00006000 +#define PM_64K 0x0001e000 +#define PM_256K 0x0007e000 +#define PM_1M 0x001fe000 +#define PM_4M 0x007fe000 +#define PM_16M 0x01ffe000 +#define PM_64M 0x07ffe000 +#define PM_256M 0x1fffe000 -#define write_32bit_cp0_set1_register(register,value) \ - __asm__ __volatile__( \ - "ctc0\t%0,"STR(register)"\n\t" \ - "nop" \ - : : "r" (value)); - -#define write_64bit_cp0_register(register,value) \ - __asm__ __volatile__( \ - ".set\tmips3\n\t" \ - "dmtc0\t%0,"STR(register)"\n\t" \ - ".set\tmips0" \ - : : "r" (value)) +#endif -/* - * This should be changed when we get a compiler that support the MIPS32 ISA. +/* + * Values used for computation of new tlb entries */ -#define read_mips32_cp0_config1() \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n\t" \ - ".word\t0x40018001\n\t" \ - "move\t%0,$1\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ - :"=r" (__res)); \ - __res;}) +#define PL_4K 12 +#define PL_16K 14 +#define PL_64K 16 +#define PL_256K 18 +#define PL_1M 20 +#define PL_4M 22 +#define PL_16M 24 +#define PL_64M 26 +#define PL_256M 28 /* * R4x00 interrupt enable / cause bits */ -#define IE_SW0 (1<< 8) -#define IE_SW1 (1<< 9) -#define IE_IRQ0 (1<<10) -#define IE_IRQ1 (1<<11) -#define IE_IRQ2 (1<<12) -#define IE_IRQ3 (1<<13) -#define IE_IRQ4 (1<<14) -#define IE_IRQ5 (1<<15) +#define IE_SW0 (_ULCAST_(1) << 8) +#define IE_SW1 (_ULCAST_(1) << 9) +#define IE_IRQ0 (_ULCAST_(1) << 10) +#define IE_IRQ1 (_ULCAST_(1) << 11) +#define IE_IRQ2 (_ULCAST_(1) << 12) +#define IE_IRQ3 (_ULCAST_(1) << 13) +#define IE_IRQ4 (_ULCAST_(1) << 14) +#define IE_IRQ5 (_ULCAST_(1) << 15) /* * R4x00 interrupt cause bits */ -#define C_SW0 (1<< 8) -#define C_SW1 (1<< 9) -#define C_IRQ0 (1<<10) -#define C_IRQ1 (1<<11) -#define C_IRQ2 (1<<12) -#define C_IRQ3 (1<<13) -#define C_IRQ4 (1<<14) -#define C_IRQ5 (1<<15) - -#ifndef _LANGUAGE_ASSEMBLY -/* - * Manipulate the status register. - * Mostly used to access the interrupt bits. - */ -#define __BUILD_SET_CP0(name,register) \ -extern __inline__ unsigned int \ -set_cp0_##name(unsigned int set) \ -{ \ - unsigned int res; \ - \ - res = read_32bit_cp0_register(register); \ - res |= set; \ - write_32bit_cp0_register(register, res); \ - \ - return res; \ -} \ - \ -extern __inline__ unsigned int \ -clear_cp0_##name(unsigned int clear) \ -{ \ - unsigned int res; \ - \ - res = read_32bit_cp0_register(register); \ - res &= ~clear; \ - write_32bit_cp0_register(register, res); \ - \ - return res; \ -} \ - \ -extern __inline__ unsigned int \ -change_cp0_##name(unsigned int change, unsigned int new) \ -{ \ - unsigned int res; \ - \ - res = read_32bit_cp0_register(register); \ - res &= ~change; \ - res |= (new & change); \ - if(change) \ - write_32bit_cp0_register(register, res); \ - \ - return res; \ -} - -__BUILD_SET_CP0(status,CP0_STATUS) -__BUILD_SET_CP0(cause,CP0_CAUSE) -__BUILD_SET_CP0(config,CP0_CONFIG) - -#endif /* defined (_LANGUAGE_ASSEMBLY) */ +#define C_SW0 (_ULCAST_(1) << 8) +#define C_SW1 (_ULCAST_(1) << 9) +#define C_IRQ0 (_ULCAST_(1) << 10) +#define C_IRQ1 (_ULCAST_(1) << 11) +#define C_IRQ2 (_ULCAST_(1) << 12) +#define C_IRQ3 (_ULCAST_(1) << 13) +#define C_IRQ4 (_ULCAST_(1) << 14) +#define C_IRQ5 (_ULCAST_(1) << 15) /* * Bitfields in the R4xx0 cp0 status register @@ -344,9 +254,9 @@ __BUILD_SET_CP0(config,CP0_CONFIG) /* * Bits specific to the R4640/R4650 */ -#define ST0_UM (1 << 4) -#define ST0_IL (1 << 23) -#define ST0_DL (1 << 24) +#define ST0_UM (_ULCAST_(1) << 4) +#define ST0_IL (_ULCAST_(1) << 23) +#define ST0_DL (_ULCAST_(1) << 24) /* * Bitfields in the TX39 family CP0 Configuration Register 3 @@ -386,39 +296,40 @@ __BUILD_SET_CP0(config,CP0_CONFIG) */ #define ST0_IM 0x0000ff00 #define STATUSB_IP0 8 -#define STATUSF_IP0 (1 << 8) +#define STATUSF_IP0 (_ULCAST_(1) << 8) #define STATUSB_IP1 9 -#define STATUSF_IP1 (1 << 9) +#define STATUSF_IP1 (_ULCAST_(1) << 9) #define STATUSB_IP2 10 -#define STATUSF_IP2 (1 << 10) +#define STATUSF_IP2 (_ULCAST_(1) << 10) #define STATUSB_IP3 11 -#define STATUSF_IP3 (1 << 11) +#define STATUSF_IP3 (_ULCAST_(1) << 11) #define STATUSB_IP4 12 -#define STATUSF_IP4 (1 << 12) +#define STATUSF_IP4 (_ULCAST_(1) << 12) #define STATUSB_IP5 13 -#define STATUSF_IP5 (1 << 13) +#define STATUSF_IP5 (_ULCAST_(1) << 13) #define STATUSB_IP6 14 -#define STATUSF_IP6 (1 << 14) +#define STATUSF_IP6 (_ULCAST_(1) << 14) #define STATUSB_IP7 15 -#define STATUSF_IP7 (1 << 15) +#define STATUSF_IP7 (_ULCAST_(1) << 15) #define STATUSB_IP8 0 -#define STATUSF_IP8 (1 << 0) +#define STATUSF_IP8 (_ULCAST_(1) << 0) #define STATUSB_IP9 1 -#define STATUSF_IP9 (1 << 1) +#define STATUSF_IP9 (_ULCAST_(1) << 1) #define STATUSB_IP10 2 -#define STATUSF_IP10 (1 << 2) +#define STATUSF_IP10 (_ULCAST_(1) << 2) #define STATUSB_IP11 3 -#define STATUSF_IP11 (1 << 3) +#define STATUSF_IP11 (_ULCAST_(1) << 3) #define STATUSB_IP12 4 -#define STATUSF_IP12 (1 << 4) +#define STATUSF_IP12 (_ULCAST_(1) << 4) #define STATUSB_IP13 5 -#define STATUSF_IP13 (1 << 5) +#define STATUSF_IP13 (_ULCAST_(1) << 5) #define STATUSB_IP14 6 -#define STATUSF_IP14 (1 << 6) +#define STATUSF_IP14 (_ULCAST_(1) << 6) #define STATUSB_IP15 7 -#define STATUSF_IP15 (1 << 7) +#define STATUSF_IP15 (_ULCAST_(1) << 7) #define ST0_CH 0x00040000 #define ST0_SR 0x00100000 +#define ST0_TS 0x00200000 #define ST0_BEV 0x00400000 #define ST0_RE 0x02000000 #define ST0_FR 0x04000000 @@ -435,35 +346,36 @@ __BUILD_SET_CP0(config,CP0_CONFIG) * Refer to your MIPS R4xx0 manual, chapter 5 for explanation. */ #define CAUSEB_EXCCODE 2 -#define CAUSEF_EXCCODE (31 << 2) +#define CAUSEF_EXCCODE (_ULCAST_(31) << 2) #define CAUSEB_IP 8 -#define CAUSEF_IP (255 << 8) +#define CAUSEF_IP (_ULCAST_(255) << 8) #define CAUSEB_IP0 8 -#define CAUSEF_IP0 (1 << 8) +#define CAUSEF_IP0 (_ULCAST_(1) << 8) #define CAUSEB_IP1 9 -#define CAUSEF_IP1 (1 << 9) +#define CAUSEF_IP1 (_ULCAST_(1) << 9) #define CAUSEB_IP2 10 -#define CAUSEF_IP2 (1 << 10) +#define CAUSEF_IP2 (_ULCAST_(1) << 10) #define CAUSEB_IP3 11 -#define CAUSEF_IP3 (1 << 11) +#define CAUSEF_IP3 (_ULCAST_(1) << 11) #define CAUSEB_IP4 12 -#define CAUSEF_IP4 (1 << 12) +#define CAUSEF_IP4 (_ULCAST_(1) << 12) #define CAUSEB_IP5 13 -#define CAUSEF_IP5 (1 << 13) +#define CAUSEF_IP5 (_ULCAST_(1) << 13) #define CAUSEB_IP6 14 -#define CAUSEF_IP6 (1 << 14) +#define CAUSEF_IP6 (_ULCAST_(1) << 14) #define CAUSEB_IP7 15 -#define CAUSEF_IP7 (1 << 15) +#define CAUSEF_IP7 (_ULCAST_(1) << 15) #define CAUSEB_IV 23 -#define CAUSEF_IV (1 << 23) +#define CAUSEF_IV (_ULCAST_(1) << 23) #define CAUSEB_CE 28 -#define CAUSEF_CE (3 << 28) +#define CAUSEF_CE (_ULCAST_(3) << 28) #define CAUSEB_BD 31 -#define CAUSEF_BD (1 << 31) +#define CAUSEF_BD (_ULCAST_(1) << 31) /* - * Bits in the coprozessor 0 config register. + * Bits in the coprocessor 0 config register. */ +/* Generic bits. */ #define CONF_CM_CACHABLE_NO_WA 0 #define CONF_CM_CACHABLE_WA 1 #define CONF_CM_UNCACHED 2 @@ -473,11 +385,72 @@ __BUILD_SET_CP0(config,CP0_CONFIG) #define CONF_CM_CACHABLE_CUW 6 #define CONF_CM_CACHABLE_ACCELERATED 7 #define CONF_CM_CMASK 7 -#define CONF_DB (1 << 4) -#define CONF_IB (1 << 5) -#define CONF_SC (1 << 17) -#define CONF_AC (1 << 23) -#define CONF_HALT (1 << 25) +#define CONF_BE (_ULCAST_(1) << 15) + +/* Bits common to various processors. */ +#define CONF_CU (_ULCAST_(1) << 3) +#define CONF_DB (_ULCAST_(1) << 4) +#define CONF_IB (_ULCAST_(1) << 5) +#define CONF_DC (_ULCAST_(7) << 6) +#define CONF_IC (_ULCAST_(7) << 9) +#define CONF_EB (_ULCAST_(1) << 13) +#define CONF_EM (_ULCAST_(1) << 14) +#define CONF_SM (_ULCAST_(1) << 16) +#define CONF_SC (_ULCAST_(1) << 17) +#define CONF_EW (_ULCAST_(3) << 18) +#define CONF_EP (_ULCAST_(15)<< 24) +#define CONF_EC (_ULCAST_(7) << 28) +#define CONF_CM (_ULCAST_(1) << 31) + +/* Bits specific to the R4xx0. */ +#define R4K_CONF_SW (_ULCAST_(1) << 20) +#define R4K_CONF_SS (_ULCAST_(1) << 21) +#define R4K_CONF_SB (_ULCAST_(3) << 22) + +/* Bits specific to the R5000. */ +#define R5K_CONF_SE (_ULCAST_(1) << 12) +#define R5K_CONF_SS (_ULCAST_(3) << 20) + +/* Bits specific to the R10000. */ +#define R10K_CONF_DN (_ULCAST_(3) << 3) +#define R10K_CONF_CT (_ULCAST_(1) << 5) +#define R10K_CONF_PE (_ULCAST_(1) << 6) +#define R10K_CONF_PM (_ULCAST_(3) << 7) +#define R10K_CONF_EC (_ULCAST_(15)<< 9) +#define R10K_CONF_SB (_ULCAST_(1) << 13) +#define R10K_CONF_SK (_ULCAST_(1) << 14) +#define R10K_CONF_SS (_ULCAST_(7) << 16) +#define R10K_CONF_SC (_ULCAST_(7) << 19) +#define R10K_CONF_DC (_ULCAST_(7) << 26) +#define R10K_CONF_IC (_ULCAST_(7) << 29) + +/* Bits specific to the VR41xx. */ +#define VR41_CONF_CS (_ULCAST_(1) << 12) +#define VR41_CONF_M16 (_ULCAST_(1) << 20) +#define VR41_CONF_AD (_ULCAST_(1) << 23) + +/* Bits specific to the R30xx. */ +#define R30XX_CONF_FDM (_ULCAST_(1) << 19) +#define R30XX_CONF_REV (_ULCAST_(1) << 22) +#define R30XX_CONF_AC (_ULCAST_(1) << 23) +#define R30XX_CONF_RF (_ULCAST_(1) << 24) +#define R30XX_CONF_HALT (_ULCAST_(1) << 25) +#define R30XX_CONF_FPINT (_ULCAST_(7) << 26) +#define R30XX_CONF_DBR (_ULCAST_(1) << 29) +#define R30XX_CONF_SB (_ULCAST_(1) << 30) +#define R30XX_CONF_LOCK (_ULCAST_(1) << 31) + +/* Bits specific to the TX49. */ +#define TX49_CONF_DC (_ULCAST_(1) << 16) +#define TX49_CONF_IC (_ULCAST_(1) << 17) /* conflict with CONF_SC */ +#define TX49_CONF_HALT (_ULCAST_(1) << 18) +#define TX49_CONF_CWFON (_ULCAST_(1) << 27) + +/* Bits specific to the MIPS32/64 PRA. */ +#define MIPS_CONF_MT (_ULCAST_(7) << 7) +#define MIPS_CONF_AR (_ULCAST_(7) << 10) +#define MIPS_CONF_AT (_ULCAST_(3) << 13) +#define MIPS_CONF_M (_ULCAST_(1) << 31) /* * R10000 performance counter definitions. @@ -535,4 +508,394 @@ __BUILD_SET_CP0(config,CP0_CONFIG) #define CEB_KERNEL 2 /* Count events in kernel mode EXL = ERL = 0 */ #define CEB_EXL 1 /* Count events with EXL = 1, ERL = 0 */ +#ifndef __ASSEMBLY__ + +/* + * Functions to access the r10k performance counter and control registers + */ +#define read_r10k_perf_cntr(counter) \ +({ unsigned int __res; \ + __asm__ __volatile__( \ + "mfpc\t%0, "STR(counter) \ + : "=r" (__res)); \ + __res;}) + +#define write_r10k_perf_cntr(counter,val) \ + __asm__ __volatile__( \ + "mtpc\t%0, "STR(counter) \ + : : "r" (val)); + +#define read_r10k_perf_cntl(counter) \ +({ unsigned int __res; \ + __asm__ __volatile__( \ + "mfps\t%0, "STR(counter) \ + : "=r" (__res)); \ + __res;}) + +#define write_r10k_perf_cntl(counter,val) \ + __asm__ __volatile__( \ + "mtps\t%0, "STR(counter) \ + : : "r" (val)); + +/* + * Macros to access the system control coprocessor + */ + +#define __read_32bit_c0_register(source, sel) \ +({ int __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __read_64bit_c0_register(source, sel) \ +({ unsigned long __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmfc0\t%0, " #source "\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_32bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mtc0\t%z0, " #register "\n\t" \ + : : "Jr" (value)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ +} while (0) + +#define __write_64bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmtc0\t%z0, " #register "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ +} while (0) + +#define __read_ulong_c0_register(reg, sel) \ + ((sizeof(unsigned long) == 4) ? \ + __read_32bit_c0_register(reg, sel) : \ + __read_64bit_c0_register(reg, sel)) + +#define __write_ulong_c0_register(reg, sel, val) \ +do { \ + if (sizeof(unsigned long) == 4) \ + __write_32bit_c0_register(reg, sel, val); \ + else \ + __write_64bit_c0_register(reg, sel, val); \ +} while (0) + +/* + * These versions are only needed for systems with more than 38 bits of + * physical address space running the 32-bit kernel. That's none atm :-) + */ +#define __read_64bit_c0_split(source, sel) \ +({ \ + unsigned long long val; \ + unsigned long flags; \ + \ + local_irq_save(flags); \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%M0, " #source "\n\t" \ + "dsll\t%L0, %M0, 32\n\t" \ + "dsrl\t%M0, %M0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + ".set\tmips0" \ + : "=r" (val)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%M0, " #source ", " #sel "\n\t" \ + "dsll\t%L0, %M0, 32\n\t" \ + "dsrl\t%M0, %M0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + ".set\tmips0" \ + : "=r" (val)); \ + local_irq_restore(flags); \ + \ + val; \ +}) + +#define __write_64bit_c0_split(source, sel, val) \ +do { \ + unsigned long flags; \ + \ + local_irq_save(flags); \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dsll\t%L0, %L0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + "dsll\t%M0, %M0, 32\n\t" \ + "or\t%L0, %L0, %M0\n\t" \ + "dmtc0\t%L0, " #source "\n\t" \ + ".set\tmips0" \ + : : "r" (val)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dsll\t%L0, %L0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + "dsll\t%M0, %M0, 32\n\t" \ + "or\t%L0, %L0, %M0\n\t" \ + "dmtc0\t%L0, " #source ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "r" (val)); \ + local_irq_restore(flags); \ +} while (0) + +#define read_c0_index() __read_32bit_c0_register($0, 0) +#define write_c0_index(val) __write_32bit_c0_register($0, 0, val) + +#define read_c0_entrylo0() __read_ulong_c0_register($2, 0) +#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) + +#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) +#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) + +#define read_c0_conf() __read_32bit_c0_register($3, 0) +#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) + +#define read_c0_context() __read_ulong_c0_register($4, 0) +#define write_c0_context(val) __write_ulong_c0_register($4, 0, val) + +#define read_c0_pagemask() __read_32bit_c0_register($5, 0) +#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) + +#define read_c0_wired() __read_32bit_c0_register($6, 0) +#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val) + +#define read_c0_info() __read_32bit_c0_register($7, 0) + +#define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */ +#define write_c0_cache(val) __write_32bit_c0_register($7, 0, val) + +#define read_c0_count() __read_32bit_c0_register($9, 0) +#define write_c0_count(val) __write_32bit_c0_register($9, 0, val) + +#define read_c0_entryhi() __read_ulong_c0_register($10, 0) +#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) + +#define read_c0_compare() __read_32bit_c0_register($11, 0) +#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) + +#define read_c0_status() __read_32bit_c0_register($12, 0) +#define write_c0_status(val) __write_32bit_c0_register($12, 0, val) + +#define read_c0_cause() __read_32bit_c0_register($13, 0) +#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) + +#define read_c0_prid() __read_32bit_c0_register($15, 0) + +#define read_c0_config() __read_32bit_c0_register($16, 0) +#define read_c0_config1() __read_32bit_c0_register($16, 1) +#define read_c0_config2() __read_32bit_c0_register($16, 2) +#define read_c0_config3() __read_32bit_c0_register($16, 3) +#define write_c0_config(val) __write_32bit_c0_register($16, 0, val) +#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val) +#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val) +#define write_c0_config3(val) __write_32bit_c0_register($16, 3, val) + +/* + * The WatchLo register. There may be upto 8 of them. + */ +#define read_c0_watchlo0() __read_ulong_c0_register($18, 0) +#define read_c0_watchlo1() __read_ulong_c0_register($18, 1) +#define read_c0_watchlo2() __read_ulong_c0_register($18, 2) +#define read_c0_watchlo3() __read_ulong_c0_register($18, 3) +#define read_c0_watchlo4() __read_ulong_c0_register($18, 4) +#define read_c0_watchlo5() __read_ulong_c0_register($18, 5) +#define read_c0_watchlo6() __read_ulong_c0_register($18, 6) +#define read_c0_watchlo7() __read_ulong_c0_register($18, 7) +#define write_c0_watchlo0(val) __write_ulong_c0_register($18, 0, val) +#define write_c0_watchlo1(val) __write_ulong_c0_register($18, 1, val) +#define write_c0_watchlo2(val) __write_ulong_c0_register($18, 2, val) +#define write_c0_watchlo3(val) __write_ulong_c0_register($18, 3, val) +#define write_c0_watchlo4(val) __write_ulong_c0_register($18, 4, val) +#define write_c0_watchlo5(val) __write_ulong_c0_register($18, 5, val) +#define write_c0_watchlo6(val) __write_ulong_c0_register($18, 6, val) +#define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val) + +/* + * The WatchHi register. There may be upto 8 of them. + */ +#define read_c0_watchhi0() __read_32bit_c0_register($19, 0) +#define read_c0_watchhi1() __read_32bit_c0_register($19, 1) +#define read_c0_watchhi2() __read_32bit_c0_register($19, 2) +#define read_c0_watchhi3() __read_32bit_c0_register($19, 3) +#define read_c0_watchhi4() __read_32bit_c0_register($19, 4) +#define read_c0_watchhi5() __read_32bit_c0_register($19, 5) +#define read_c0_watchhi6() __read_32bit_c0_register($19, 6) +#define read_c0_watchhi7() __read_32bit_c0_register($19, 7) + +#define write_c0_watchhi0(val) __write_32bit_c0_register($19, 0, val) +#define write_c0_watchhi1(val) __write_32bit_c0_register($19, 1, val) +#define write_c0_watchhi2(val) __write_32bit_c0_register($19, 2, val) +#define write_c0_watchhi3(val) __write_32bit_c0_register($19, 3, val) +#define write_c0_watchhi4(val) __write_32bit_c0_register($19, 4, val) +#define write_c0_watchhi5(val) __write_32bit_c0_register($19, 5, val) +#define write_c0_watchhi6(val) __write_32bit_c0_register($19, 6, val) +#define write_c0_watchhi7(val) __write_32bit_c0_register($19, 7, val) + +#define read_c0_xcontext() __read_ulong_c0_register($20, 0) +#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val) + +#define read_c0_intcontrol() __read_32bit_c0_register($20, 1) +#define write_c0_intcontrol(val) __write_32bit_c0_register($20, 1, val) + +#define read_c0_framemask() __read_32bit_c0_register($21, 0) +#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val) + +#define read_c0_debug() __read_32bit_c0_register($23, 0) +#define write_c0_debug(val) __write_32bit_c0_register($23, 0, val) + +#define read_c0_depc() __read_ulong_c0_register($24, 0) +#define write_c0_depc(val) __write_ulong_c0_register($24, 0, val) + +#define read_c0_ecc() __read_32bit_c0_register($26, 0) +#define write_c0_ecc(val) __write_32bit_c0_register($26, 0, val) + +#define read_c0_derraddr0() __read_ulong_c0_register($26, 1) +#define write_c0_derraddr0(val) __write_ulong_c0_register($26, 1, val) + +#define read_c0_cacheerr() __read_32bit_c0_register($27, 0) + +#define read_c0_derraddr1() __read_ulong_c0_register($27, 1) +#define write_c0_derraddr1(val) __write_ulong_c0_register($27, 1, val) + +#define read_c0_taglo() __read_32bit_c0_register($28, 0) +#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) + +#define read_c0_taghi() __read_32bit_c0_register($29, 0) +#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) + +#define read_c0_errorepc() __read_ulong_c0_register($30, 0) +#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val) + +/* + * Macros to access the floating point coprocessor control registers + */ +#define read_32bit_cp1_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + "cfc1\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) + +/* TLB operations. */ +static inline void tlb_probe(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbp\n\t" + ".set reorder"); +} + +static inline void tlb_read(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbr\n\t" + ".set reorder"); +} + +static inline void tlb_write_indexed(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwi\n\t" + ".set reorder"); +} + +static inline void tlb_write_random(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwr\n\t" + ".set reorder"); +} + +/* + * Manipulate bits in a c0 register. + */ +#define __BUILD_SET_C0(name,register) \ +static inline unsigned int \ +set_c0_##name(unsigned int set) \ +{ \ + unsigned int res; \ + \ + res = read_c0_##name(); \ + res |= set; \ + write_c0_##name(res); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +clear_c0_##name(unsigned int clear) \ +{ \ + unsigned int res; \ + \ + res = read_c0_##name(); \ + res &= ~clear; \ + write_c0_##name(res); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +change_c0_##name(unsigned int change, unsigned int new) \ +{ \ + unsigned int res; \ + \ + res = read_c0_##name(); \ + res &= ~change; \ + res |= (new & change); \ + write_c0_##name(res); \ + \ + return res; \ +} + +__BUILD_SET_C0(status,CP0_STATUS) +__BUILD_SET_C0(cause,CP0_CAUSE) +__BUILD_SET_C0(config,CP0_CONFIG) + +#endif /* !__ASSEMBLY__ */ + #endif /* _ASM_MIPSREGS_H */ diff --git a/include/asm-mips/mman.h b/include/asm-mips/mman.h index 64dd2c674aed..54b7fb1cb8f3 100644 --- a/include/asm-mips/mman.h +++ b/include/asm-mips/mman.h @@ -1,14 +1,12 @@ /* - * Linux/MIPS memory manager definitions - * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995 by Ralf Baechle + * Copyright (C) 1995, 1999, 2002 by Ralf Baechle */ -#ifndef __ASM_MIPS_MMAN_H -#define __ASM_MIPS_MMAN_H +#ifndef _ASM_MMAN_H +#define _ASM_MMAN_H /* * Protections are chosen from these bits, OR'd together. The @@ -16,10 +14,12 @@ * without PROT_READ. The only guarantees are that no writing will be * allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#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 0x00 /* page can not be accessed */ +#define PROT_READ 0x01 /* page can be read */ +#define PROT_WRITE 0x02 /* page can be written */ +#define PROT_EXEC 0x04 /* page can be executed */ +/* 0x08 reserved for PROT_EXEC_NOFLUSH */ +#define PROT_SEM 0x10 /* page may be used for atomic ops */ /* * Flags for mmap @@ -42,6 +42,8 @@ #define MAP_DENYWRITE 0x2000 /* ETXTBSY */ #define MAP_EXECUTABLE 0x4000 /* mark it as an executable */ #define MAP_LOCKED 0x8000 /* pages are locked */ +#define MAP_POPULATE 0x10000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x20000 /* do not block on IO */ /* * Flags for msync @@ -66,4 +68,4 @@ #define MAP_ANON MAP_ANONYMOUS #define MAP_FILE 0 -#endif /* __ASM_MIPS_MMAN_H */ +#endif /* _ASM_MMAN_H */ diff --git a/include/asm-mips/mmu.h b/include/asm-mips/mmu.h index ccd36d26615a..4063edd79623 100644 --- a/include/asm-mips/mmu.h +++ b/include/asm-mips/mmu.h @@ -1,7 +1,6 @@ -#ifndef __MMU_H -#define __MMU_H +#ifndef __ASM_MMU_H +#define __ASM_MMU_H -/* Default "unsigned long" context */ -typedef unsigned long mm_context_t; +typedef unsigned long mm_context_t[NR_CPUS]; -#endif +#endif /* __ASM_MMU_H */ diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h index 831ac14231f8..cf19cd768f95 100644 --- a/include/asm-mips/mmu_context.h +++ b/include/asm-mips/mmu_context.h @@ -12,14 +12,28 @@ #define _ASM_MMU_CONTEXT_H #include <linux/config.h> +#include <linux/errno.h> +#include <linux/sched.h> #include <linux/slab.h> -#include <asm/pgalloc.h> +#include <asm/cacheflush.h> +#include <asm/tlbflush.h> -/* Fuck. The f-word is here so you can grep for it :-) */ -extern unsigned long asid_cache; -extern pgd_t *current_pgd[]; +/* + * For the fast tlb miss handlers, we currently keep a per cpu array + * of pointers to the current pgd for each processor. Also, the proc. + * id is stuffed into the context register. This should be changed to + * use the processor id via current->processor, where current is stored + * in watchhi/lo. The context register should be used to contiguously + * map the page tables. + */ +#define TLBMISS_HANDLER_SETUP_PGD(pgd) \ + pgd_current[smp_processor_id()] = (unsigned long)(pgd) +#define TLBMISS_HANDLER_SETUP() \ + write_c0_context((unsigned long) smp_processor_id() << (23 + 3)); \ + TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) +extern unsigned long pgd_current[]; -#if defined(CONFIG_CPU_R3000) +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) #define ASID_INC 0x40 #define ASID_MASK 0xfc0 @@ -31,6 +45,10 @@ extern pgd_t *current_pgd[]; #endif +#define cpu_context(cpu, mm) ((mm)->context[cpu]) +#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK) +#define asid_cache(cpu) (cpu_data[cpu].asid_cache) + static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) { } @@ -42,60 +60,67 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, #define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1))) #define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1) -extern inline void -get_new_mmu_context(struct mm_struct *mm, unsigned long asid) +static inline void +get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) { + unsigned long asid = asid_cache(cpu); + if (! ((asid += ASID_INC) & ASID_MASK) ) { - flush_tlb_all(); /* start new asid cycle */ - if (!asid) /* fix version if needed */ +#ifdef CONFIG_VTAG_ICACHE + flush_icache_all(); +#endif + local_flush_tlb_all(); /* start new asid cycle */ + if (!asid) /* fix version if needed */ asid = ASID_FIRST_VERSION; } - mm->context = asid_cache = asid; + cpu_context(cpu, mm) = asid_cache(cpu) = asid; } /* * Initialize the context related info for a new mm_struct * instance. */ -extern inline int +static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { -#ifndef CONFIG_SMP - mm->context = 0; -#else - mm->context = (unsigned long)kmalloc(smp_num_cpus * - sizeof(unsigned long), GFP_KERNEL); - /* - * Init the "context" values so that a tlbpid allocation - * happens on the first switch. - */ - if (mm->context == 0) - return -ENOMEM; - memset((void *)mm->context, 0, smp_num_cpus * sizeof(unsigned long)); -#endif + int i; + + for (i = 0; i < num_online_cpus(); i++) + cpu_context(i, mm) = 0; + return 0; } -extern inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu) { - unsigned long asid = asid_cache; + unsigned long flags; + + local_irq_save(flags); /* Check if our ASID is of an older version and thus invalid */ - if ((next->context ^ asid) & ASID_VERSION_MASK) - get_new_mmu_context(next, asid); + if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK) + get_new_mmu_context(next, cpu); + + write_c0_entryhi(cpu_context(cpu, next)); + TLBMISS_HANDLER_SETUP_PGD(next->pgd); + + /* + * Mark current->active_mm as not "active" anymore. + * We don't want to mislead possible IPI tlb flush routines. + */ + clear_bit(cpu, &prev->cpu_vm_mask); + set_bit(cpu, &next->cpu_vm_mask); - current_pgd[cpu] = next->pgd; - set_entryhi(next->context); + local_irq_restore(flags); } /* * Destroy context related info for an mm_struct that is about * to be put to rest. */ -extern inline void destroy_context(struct mm_struct *mm) +static inline void destroy_context(struct mm_struct *mm) { - /* Nothing to do. */ } #define deactivate_mm(tsk,mm) do { } while (0) @@ -104,14 +129,47 @@ extern inline void destroy_context(struct mm_struct *mm) * After we have set current->mm to a new value, this activates * the context for the new mm so we see the new mappings. */ -extern inline void +static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { + unsigned long flags; + int cpu = smp_processor_id(); + + local_irq_save(flags); + /* Unconditionally get a new ASID. */ - get_new_mmu_context(next, asid_cache); + get_new_mmu_context(next, cpu); + + write_c0_entryhi(cpu_context(cpu, next)); + TLBMISS_HANDLER_SETUP_PGD(next->pgd); + + /* mark mmu ownership change */ + clear_bit(cpu, &prev->cpu_vm_mask); + set_bit(cpu, &next->cpu_vm_mask); + + local_irq_restore(flags); +} + +/* + * If mm is currently active_mm, we can't really drop it. Instead, + * we will get a new one for it. + */ +static inline void +drop_mmu_context(struct mm_struct *mm, unsigned cpu) +{ + unsigned long flags; + + local_irq_save(flags); + + if (test_bit(cpu, &mm->cpu_vm_mask)) { + get_new_mmu_context(mm, cpu); + write_c0_entryhi(cpu_asid(cpu, mm)); + } else { + /* will get a new context next time */ + cpu_context(cpu, mm) = 0; + } - current_pgd[smp_processor_id()] = next->pgd; - set_entryhi(next->context); + local_irq_restore(flags); } #endif /* _ASM_MMU_CONTEXT_H */ diff --git a/include/asm-mips/module.h b/include/asm-mips/module.h index 042dae3cbab4..39bcec8134e8 100644 --- a/include/asm-mips/module.h +++ b/include/asm-mips/module.h @@ -1,67 +1,14 @@ -#ifndef _ASM_MIPS_MODULE_H -#define _ASM_MIPS_MODULE_H -/* - * This file contains the mips architecture specific module code. - */ +#ifndef _ASM_MODULE_H +#define _ASM_MODULE_H -#include <linux/module.h> -#include <asm/uaccess.h> - -#define module_map(x) vmalloc(x) -#define module_unmap(x) vfree(x) -#define module_arch_init(x) mips_module_init(x) -#define arch_init_modules(x) mips_init_modules(x) - -/* - * This must match in size and layout the data created by - * modutils/obj/obj-mips.c - */ -struct archdata { +struct mod_arch_specific { + /* Data Bus Error exception tables */ const struct exception_table_entry *dbe_table_start; const struct exception_table_entry *dbe_table_end; }; -static inline int -mips_module_init(struct module *mod) -{ - struct archdata *archdata; - - if (!mod_member_present(mod, archdata_end)) - return 0; - - archdata = (struct archdata *)(mod->archdata_start); - if (!mod_archdata_member_present(mod, struct archdata, dbe_table_end)) - return 0; - - if (archdata->dbe_table_start > archdata->dbe_table_end || - (archdata->dbe_table_start && - !((unsigned long)archdata->dbe_table_start >= - ((unsigned long)mod + mod->size_of_struct) && - ((unsigned long)archdata->dbe_table_end < - (unsigned long)mod + mod->size))) || - (((unsigned long)archdata->dbe_table_start - - (unsigned long)archdata->dbe_table_end) % - sizeof(struct exception_table_entry))) { - printk(KERN_ERR - "module_arch_init: archdata->dbe_table_* invalid.\n"); - return 1; - } - - return 0; -} - -static inline void -mips_init_modules(struct module *mod) -{ - extern const struct exception_table_entry __start___dbe_table[]; - extern const struct exception_table_entry __stop___dbe_table[]; - static struct archdata archdata = { - dbe_table_start: __start___dbe_table, - dbe_table_end: __stop___dbe_table, - }; - - mod->archdata_start = (char *)&archdata; - mod->archdata_end = mod->archdata_start + sizeof(archdata); -} +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr -#endif /* _ASM_MIPS_MODULE_H */ +#endif /* _ASM_MODULE_H */ diff --git a/include/asm-mips/msgbuf.h b/include/asm-mips/msgbuf.h index 81d6e71452cd..1d4d90fb4a5e 100644 --- a/include/asm-mips/msgbuf.h +++ b/include/asm-mips/msgbuf.h @@ -1,7 +1,7 @@ #ifndef _ASM_MSGBUF_H #define _ASM_MSGBUF_H -/* +/* * The msqid64_ds structure for alpha architecture. * Note extra padding because this structure is passed back and forth * between kernel and user space. @@ -13,15 +13,18 @@ struct msqid64_ds { struct ipc64_perm msg_perm; __kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; __kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; __kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; unsigned long msg_cbytes; /* current number of bytes on queue */ unsigned long msg_qnum; /* number of messages in queue */ unsigned long msg_qbytes; /* max number of bytes on queue */ __kernel_pid_t msg_lspid; /* pid of last msgsnd */ __kernel_pid_t msg_lrpid; /* last receive pid */ - unsigned long __unused1; - unsigned long __unused2; + unsigned long __unused4; + unsigned long __unused5; }; #endif /* _ASM_MSGBUF_H */ diff --git a/include/asm-mips/mv64340.h b/include/asm-mips/mv64340.h new file mode 100644 index 000000000000..d7d89bf0f6dc --- /dev/null +++ b/include/asm-mips/mv64340.h @@ -0,0 +1,1037 @@ +/******************************************************************************* +* mv64340.h - MV-64340 Internal registers definition file. +* +* Copyright 2002 Momentum Computer, Inc. +* Copyright 2002 GALILEO TECHNOLOGY, LTD. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +*******************************************************************************/ + +#ifndef __MV64340_H__ +#define __MV64340_H__ + +#include <asm/mv64340_dep.h> + +/****************************************/ +/* Processor Address Space */ +/****************************************/ + +/* DDR SDRAM BAR and size registers */ + +#define MV64340_CS_0_BASE_ADDR 0x008 +#define MV64340_CS_0_SIZE 0x010 +#define MV64340_CS_1_BASE_ADDR 0x208 +#define MV64340_CS_1_SIZE 0x210 +#define MV64340_CS_2_BASE_ADDR 0x018 +#define MV64340_CS_2_SIZE 0x020 +#define MV64340_CS_3_BASE_ADDR 0x218 +#define MV64340_CS_3_SIZE 0x220 + +/* Devices BAR and size registers */ + +#define MV64340_DEV_CS0_BASE_ADDR 0x028 +#define MV64340_DEV_CS0_SIZE 0x030 +#define MV64340_DEV_CS1_BASE_ADDR 0x228 +#define MV64340_DEV_CS1_SIZE 0x230 +#define MV64340_DEV_CS2_BASE_ADDR 0x248 +#define MV64340_DEV_CS2_SIZE 0x250 +#define MV64340_DEV_CS3_BASE_ADDR 0x038 +#define MV64340_DEV_CS3_SIZE 0x040 +#define MV64340_BOOTCS_BASE_ADDR 0x238 +#define MV64340_BOOTCS_SIZE 0x240 + +/* PCI 0 BAR and size registers */ + +#define MV64340_PCI_0_IO_BASE_ADDR 0x048 +#define MV64340_PCI_0_IO_SIZE 0x050 +#define MV64340_PCI_0_MEMORY0_BASE_ADDR 0x058 +#define MV64340_PCI_0_MEMORY0_SIZE 0x060 +#define MV64340_PCI_0_MEMORY1_BASE_ADDR 0x080 +#define MV64340_PCI_0_MEMORY1_SIZE 0x088 +#define MV64340_PCI_0_MEMORY2_BASE_ADDR 0x258 +#define MV64340_PCI_0_MEMORY2_SIZE 0x260 +#define MV64340_PCI_0_MEMORY3_BASE_ADDR 0x280 +#define MV64340_PCI_0_MEMORY3_SIZE 0x288 + +/* PCI 1 BAR and size registers */ +#define MV64340_PCI_1_IO_BASE_ADDR 0x090 +#define MV64340_PCI_1_IO_SIZE 0x098 +#define MV64340_PCI_1_MEMORY0_BASE_ADDR 0x0a0 +#define MV64340_PCI_1_MEMORY0_SIZE 0x0a8 +#define MV64340_PCI_1_MEMORY1_BASE_ADDR 0x0b0 +#define MV64340_PCI_1_MEMORY1_SIZE 0x0b8 +#define MV64340_PCI_1_MEMORY2_BASE_ADDR 0x2a0 +#define MV64340_PCI_1_MEMORY2_SIZE 0x2a8 +#define MV64340_PCI_1_MEMORY3_BASE_ADDR 0x2b0 +#define MV64340_PCI_1_MEMORY3_SIZE 0x2b8 + +/* SRAM base address */ +#define MV64340_INTEGRATED_SRAM_BASE_ADDR 0x268 + +/* internal registers space base address */ +#define MV64340_INTERNAL_SPACE_BASE_ADDR 0x068 + +/* Enables the CS , DEV_CS , PCI 0 and PCI 1 + windows above */ +#define MV64340_BASE_ADDR_ENABLE 0x278 + +/****************************************/ +/* PCI remap registers */ +/****************************************/ + /* PCI 0 */ +#define MV64340_PCI_0_IO_ADDR_REMAP 0x0f0 +#define MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP 0x0f8 +#define MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP 0x320 +#define MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP 0x100 +#define MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP 0x328 +#define MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP 0x2f8 +#define MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP 0x330 +#define MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP 0x300 +#define MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP 0x338 + /* PCI 1 */ +#define MV64340_PCI_1_IO_ADDR_REMAP 0x108 +#define MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP 0x110 +#define MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP 0x340 +#define MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP 0x118 +#define MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP 0x348 +#define MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP 0x310 +#define MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP 0x350 +#define MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP 0x318 +#define MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP 0x358 + +#define MV64340_CPU_PCI_0_HEADERS_RETARGET_CONTROL 0x3b0 +#define MV64340_CPU_PCI_0_HEADERS_RETARGET_BASE 0x3b8 +#define MV64340_CPU_PCI_1_HEADERS_RETARGET_CONTROL 0x3c0 +#define MV64340_CPU_PCI_1_HEADERS_RETARGET_BASE 0x3c8 +#define MV64340_CPU_GE_HEADERS_RETARGET_CONTROL 0x3d0 +#define MV64340_CPU_GE_HEADERS_RETARGET_BASE 0x3d8 +#define MV64340_CPU_IDMA_HEADERS_RETARGET_CONTROL 0x3e0 +#define MV64340_CPU_IDMA_HEADERS_RETARGET_BASE 0x3e8 + +/****************************************/ +/* CPU Control Registers */ +/****************************************/ + +#define MV64340_CPU_CONFIG 0x000 +#define MV64340_CPU_MODE 0x120 +#define MV64340_CPU_MASTER_CONTROL 0x160 +#define MV64340_CPU_CROSS_BAR_CONTROL_LOW 0x150 +#define MV64340_CPU_CROSS_BAR_CONTROL_HIGH 0x158 +#define MV64340_CPU_CROSS_BAR_TIMEOUT 0x168 + +/****************************************/ +/* SMP RegisterS */ +/****************************************/ + +#define MV64340_SMP_WHO_AM_I 0x200 +#define MV64340_SMP_CPU0_DOORBELL 0x214 +#define MV64340_SMP_CPU0_DOORBELL_CLEAR 0x21C +#define MV64340_SMP_CPU1_DOORBELL 0x224 +#define MV64340_SMP_CPU1_DOORBELL_CLEAR 0x22C +#define MV64340_SMP_CPU0_DOORBELL_MASK 0x234 +#define MV64340_SMP_CPU1_DOORBELL_MASK 0x23C +#define MV64340_SMP_SEMAPHOR0 0x244 +#define MV64340_SMP_SEMAPHOR1 0x24c +#define MV64340_SMP_SEMAPHOR2 0x254 +#define MV64340_SMP_SEMAPHOR3 0x25c +#define MV64340_SMP_SEMAPHOR4 0x264 +#define MV64340_SMP_SEMAPHOR5 0x26c +#define MV64340_SMP_SEMAPHOR6 0x274 +#define MV64340_SMP_SEMAPHOR7 0x27c + +/****************************************/ +/* CPU Sync Barrier Register */ +/****************************************/ + +#define MV64340_CPU_0_SYNC_BARRIER_TRIGGER 0x0c0 +#define MV64340_CPU_0_SYNC_BARRIER_VIRTUAL 0x0c8 +#define MV64340_CPU_1_SYNC_BARRIER_TRIGGER 0x0d0 +#define MV64340_CPU_1_SYNC_BARRIER_VIRTUAL 0x0d8 + +/****************************************/ +/* CPU Access Protect */ +/****************************************/ + +#define MV64340_CPU_PROTECT_WINDOW_0_BASE_ADDR 0x180 +#define MV64340_CPU_PROTECT_WINDOW_0_SIZE 0x188 +#define MV64340_CPU_PROTECT_WINDOW_1_BASE_ADDR 0x190 +#define MV64340_CPU_PROTECT_WINDOW_1_SIZE 0x198 +#define MV64340_CPU_PROTECT_WINDOW_2_BASE_ADDR 0x1a0 +#define MV64340_CPU_PROTECT_WINDOW_2_SIZE 0x1a8 +#define MV64340_CPU_PROTECT_WINDOW_3_BASE_ADDR 0x1b0 +#define MV64340_CPU_PROTECT_WINDOW_3_SIZE 0x1b8 + + +/****************************************/ +/* CPU Error Report */ +/****************************************/ + +#define MV64340_CPU_ERROR_ADDR_LOW 0x070 +#define MV64340_CPU_ERROR_ADDR_HIGH 0x078 +#define MV64340_CPU_ERROR_DATA_LOW 0x128 +#define MV64340_CPU_ERROR_DATA_HIGH 0x130 +#define MV64340_CPU_ERROR_PARITY 0x138 +#define MV64340_CPU_ERROR_CAUSE 0x140 +#define MV64340_CPU_ERROR_MASK 0x148 + +/****************************************/ +/* CPU Interface Debug Registers */ +/****************************************/ + +#define MV64340_PUNIT_SLAVE_DEBUG_LOW 0x360 +#define MV64340_PUNIT_SLAVE_DEBUG_HIGH 0x368 +#define MV64340_PUNIT_MASTER_DEBUG_LOW 0x370 +#define MV64340_PUNIT_MASTER_DEBUG_HIGH 0x378 +#define MV64340_PUNIT_MMASK 0x3e4 + +/****************************************/ +/* Integrated SRAM Registers */ +/****************************************/ + +#define MV64340_SRAM_CONFIG 0x380 +#define MV64340_SRAM_TEST_MODE 0X3F4 +#define MV64340_SRAM_ERROR_CAUSE 0x388 +#define MV64340_SRAM_ERROR_ADDR 0x390 +#define MV64340_SRAM_ERROR_ADDR_HIGH 0X3F8 +#define MV64340_SRAM_ERROR_DATA_LOW 0x398 +#define MV64340_SRAM_ERROR_DATA_HIGH 0x3a0 +#define MV64340_SRAM_ERROR_DATA_PARITY 0x3a8 + +/****************************************/ +/* SDRAM Configuration */ +/****************************************/ + +#define MV64340_SDRAM_CONFIG 0x1400 +#define MV64340_D_UNIT_CONTROL_LOW 0x1404 +#define MV64340_D_UNIT_CONTROL_HIGH 0x1424 +#define MV64340_SDRAM_TIMING_CONTROL_LOW 0x1408 +#define MV64340_SDRAM_TIMING_CONTROL_HIGH 0x140c +#define MV64340_SDRAM_ADDR_CONTROL 0x1410 +#define MV64340_SDRAM_OPEN_PAGES_CONTROL 0x1414 +#define MV64340_SDRAM_OPERATION 0x1418 +#define MV64340_SDRAM_MODE 0x141c +#define MV64340_EXTENDED_DRAM_MODE 0x1420 +#define MV64340_SDRAM_CROSS_BAR_CONTROL_LOW 0x1430 +#define MV64340_SDRAM_CROSS_BAR_CONTROL_HIGH 0x1434 +#define MV64340_SDRAM_CROSS_BAR_TIMEOUT 0x1438 +#define MV64340_SDRAM_ADDR_CTRL_PADS_CALIBRATION 0x14c0 +#define MV64340_SDRAM_DATA_PADS_CALIBRATION 0x14c4 + +/****************************************/ +/* SDRAM Error Report */ +/****************************************/ + +#define MV64340_SDRAM_ERROR_DATA_LOW 0x1444 +#define MV64340_SDRAM_ERROR_DATA_HIGH 0x1440 +#define MV64340_SDRAM_ERROR_ADDR 0x1450 +#define MV64340_SDRAM_RECEIVED_ECC 0x1448 +#define MV64340_SDRAM_CALCULATED_ECC 0x144c +#define MV64340_SDRAM_ECC_CONTROL 0x1454 +#define MV64340_SDRAM_ECC_ERROR_COUNTER 0x1458 + +/******************************************/ +/* Controlled Delay Line (CDL) Registers */ +/******************************************/ + +#define MV64340_DFCDL_CONFIG0 0x1480 +#define MV64340_DFCDL_CONFIG1 0x1484 +#define MV64340_DLL_WRITE 0x1488 +#define MV64340_DLL_READ 0x148c +#define MV64340_SRAM_ADDR 0x1490 +#define MV64340_SRAM_DATA0 0x1494 +#define MV64340_SRAM_DATA1 0x1498 +#define MV64340_SRAM_DATA2 0x149c +#define MV64340_DFCL_PROBE 0x14a0 + +/******************************************/ +/* Debug Registers */ +/******************************************/ + +#define MV64340_DUNIT_DEBUG_LOW 0x1460 +#define MV64340_DUNIT_DEBUG_HIGH 0x1464 +#define MV64340_DUNIT_MMASK 0X1b40 + +/****************************************/ +/* Device Parameters */ +/****************************************/ + +#define MV64340_DEVICE_BANK0_PARAMETERS 0x45c +#define MV64340_DEVICE_BANK1_PARAMETERS 0x460 +#define MV64340_DEVICE_BANK2_PARAMETERS 0x464 +#define MV64340_DEVICE_BANK3_PARAMETERS 0x468 +#define MV64340_DEVICE_BOOT_BANK_PARAMETERS 0x46c +#define MV64340_DEVICE_INTERFACE_CONTROL 0x4c0 +#define MV64340_DEVICE_INTERFACE_CROSS_BAR_CONTROL_LOW 0x4c8 +#define MV64340_DEVICE_INTERFACE_CROSS_BAR_CONTROL_HIGH 0x4cc +#define MV64340_DEVICE_INTERFACE_CROSS_BAR_TIMEOUT 0x4c4 + +/****************************************/ +/* Device interrupt registers */ +/****************************************/ + +#define MV64340_DEVICE_INTERRUPT_CAUSE 0x4d0 +#define MV64340_DEVICE_INTERRUPT_MASK 0x4d4 +#define MV64340_DEVICE_ERROR_ADDR 0x4d8 +#define MV64340_DEVICE_ERROR_DATA 0x4dc +#define MV64340_DEVICE_ERROR_PARITY 0x4e0 + +/****************************************/ +/* Device debug registers */ +/****************************************/ + +#define MV64340_DEVICE_DEBUG_LOW 0x4e4 +#define MV64340_DEVICE_DEBUG_HIGH 0x4e8 +#define MV64340_RUNIT_MMASK 0x4f0 + +/****************************************/ +/* PCI Slave Address Decoding registers */ +/****************************************/ + +#define MV64340_PCI_0_CS_0_BANK_SIZE 0xc08 +#define MV64340_PCI_1_CS_0_BANK_SIZE 0xc88 +#define MV64340_PCI_0_CS_1_BANK_SIZE 0xd08 +#define MV64340_PCI_1_CS_1_BANK_SIZE 0xd88 +#define MV64340_PCI_0_CS_2_BANK_SIZE 0xc0c +#define MV64340_PCI_1_CS_2_BANK_SIZE 0xc8c +#define MV64340_PCI_0_CS_3_BANK_SIZE 0xd0c +#define MV64340_PCI_1_CS_3_BANK_SIZE 0xd8c +#define MV64340_PCI_0_DEVCS_0_BANK_SIZE 0xc10 +#define MV64340_PCI_1_DEVCS_0_BANK_SIZE 0xc90 +#define MV64340_PCI_0_DEVCS_1_BANK_SIZE 0xd10 +#define MV64340_PCI_1_DEVCS_1_BANK_SIZE 0xd90 +#define MV64340_PCI_0_DEVCS_2_BANK_SIZE 0xd18 +#define MV64340_PCI_1_DEVCS_2_BANK_SIZE 0xd98 +#define MV64340_PCI_0_DEVCS_3_BANK_SIZE 0xc14 +#define MV64340_PCI_1_DEVCS_3_BANK_SIZE 0xc94 +#define MV64340_PCI_0_DEVCS_BOOT_BANK_SIZE 0xd14 +#define MV64340_PCI_1_DEVCS_BOOT_BANK_SIZE 0xd94 +#define MV64340_PCI_0_P2P_MEM0_BAR_SIZE 0xd1c +#define MV64340_PCI_1_P2P_MEM0_BAR_SIZE 0xd9c +#define MV64340_PCI_0_P2P_MEM1_BAR_SIZE 0xd20 +#define MV64340_PCI_1_P2P_MEM1_BAR_SIZE 0xda0 +#define MV64340_PCI_0_P2P_I_O_BAR_SIZE 0xd24 +#define MV64340_PCI_1_P2P_I_O_BAR_SIZE 0xda4 +#define MV64340_PCI_0_CPU_BAR_SIZE 0xd28 +#define MV64340_PCI_1_CPU_BAR_SIZE 0xda8 +#define MV64340_PCI_0_INTERNAL_SRAM_BAR_SIZE 0xe00 +#define MV64340_PCI_1_INTERNAL_SRAM_BAR_SIZE 0xe80 +#define MV64340_PCI_0_EXPANSION_ROM_BAR_SIZE 0xd2c +#define MV64340_PCI_1_EXPANSION_ROM_BAR_SIZE 0xd9c +#define MV64340_PCI_0_BASE_ADDR_REG_ENABLE 0xc3c +#define MV64340_PCI_1_BASE_ADDR_REG_ENABLE 0xcbc +#define MV64340_PCI_0_CS_0_BASE_ADDR_REMAP 0xc48 +#define MV64340_PCI_1_CS_0_BASE_ADDR_REMAP 0xcc8 +#define MV64340_PCI_0_CS_1_BASE_ADDR_REMAP 0xd48 +#define MV64340_PCI_1_CS_1_BASE_ADDR_REMAP 0xdc8 +#define MV64340_PCI_0_CS_2_BASE_ADDR_REMAP 0xc4c +#define MV64340_PCI_1_CS_2_BASE_ADDR_REMAP 0xccc +#define MV64340_PCI_0_CS_3_BASE_ADDR_REMAP 0xd4c +#define MV64340_PCI_1_CS_3_BASE_ADDR_REMAP 0xdcc +#define MV64340_PCI_0_CS_0_BASE_HIGH_ADDR_REMAP 0xF04 +#define MV64340_PCI_1_CS_0_BASE_HIGH_ADDR_REMAP 0xF84 +#define MV64340_PCI_0_CS_1_BASE_HIGH_ADDR_REMAP 0xF08 +#define MV64340_PCI_1_CS_1_BASE_HIGH_ADDR_REMAP 0xF88 +#define MV64340_PCI_0_CS_2_BASE_HIGH_ADDR_REMAP 0xF0C +#define MV64340_PCI_1_CS_2_BASE_HIGH_ADDR_REMAP 0xF8C +#define MV64340_PCI_0_CS_3_BASE_HIGH_ADDR_REMAP 0xF10 +#define MV64340_PCI_1_CS_3_BASE_HIGH_ADDR_REMAP 0xF90 +#define MV64340_PCI_0_DEVCS_0_BASE_ADDR_REMAP 0xc50 +#define MV64340_PCI_1_DEVCS_0_BASE_ADDR_REMAP 0xcd0 +#define MV64340_PCI_0_DEVCS_1_BASE_ADDR_REMAP 0xd50 +#define MV64340_PCI_1_DEVCS_1_BASE_ADDR_REMAP 0xdd0 +#define MV64340_PCI_0_DEVCS_2_BASE_ADDR_REMAP 0xd58 +#define MV64340_PCI_1_DEVCS_2_BASE_ADDR_REMAP 0xdd8 +#define MV64340_PCI_0_DEVCS_3_BASE_ADDR_REMAP 0xc54 +#define MV64340_PCI_1_DEVCS_3_BASE_ADDR_REMAP 0xcd4 +#define MV64340_PCI_0_DEVCS_BOOTCS_BASE_ADDR_REMAP 0xd54 +#define MV64340_PCI_1_DEVCS_BOOTCS_BASE_ADDR_REMAP 0xdd4 +#define MV64340_PCI_0_P2P_MEM0_BASE_ADDR_REMAP_LOW 0xd5c +#define MV64340_PCI_1_P2P_MEM0_BASE_ADDR_REMAP_LOW 0xddc +#define MV64340_PCI_0_P2P_MEM0_BASE_ADDR_REMAP_HIGH 0xd60 +#define MV64340_PCI_1_P2P_MEM0_BASE_ADDR_REMAP_HIGH 0xde0 +#define MV64340_PCI_0_P2P_MEM1_BASE_ADDR_REMAP_LOW 0xd64 +#define MV64340_PCI_1_P2P_MEM1_BASE_ADDR_REMAP_LOW 0xde4 +#define MV64340_PCI_0_P2P_MEM1_BASE_ADDR_REMAP_HIGH 0xd68 +#define MV64340_PCI_1_P2P_MEM1_BASE_ADDR_REMAP_HIGH 0xde8 +#define MV64340_PCI_0_P2P_I_O_BASE_ADDR_REMAP 0xd6c +#define MV64340_PCI_1_P2P_I_O_BASE_ADDR_REMAP 0xdec +#define MV64340_PCI_0_CPU_BASE_ADDR_REMAP_LOW 0xd70 +#define MV64340_PCI_1_CPU_BASE_ADDR_REMAP_LOW 0xdf0 +#define MV64340_PCI_0_CPU_BASE_ADDR_REMAP_HIGH 0xd74 +#define MV64340_PCI_1_CPU_BASE_ADDR_REMAP_HIGH 0xdf4 +#define MV64340_PCI_0_INTEGRATED_SRAM_BASE_ADDR_REMAP 0xf00 +#define MV64340_PCI_1_INTEGRATED_SRAM_BASE_ADDR_REMAP 0xf80 +#define MV64340_PCI_0_EXPANSION_ROM_BASE_ADDR_REMAP 0xf38 +#define MV64340_PCI_1_EXPANSION_ROM_BASE_ADDR_REMAP 0xfb8 +#define MV64340_PCI_0_ADDR_DECODE_CONTROL 0xd3c +#define MV64340_PCI_1_ADDR_DECODE_CONTROL 0xdbc +#define MV64340_PCI_0_HEADERS_RETARGET_CONTROL 0xF40 +#define MV64340_PCI_1_HEADERS_RETARGET_CONTROL 0xFc0 +#define MV64340_PCI_0_HEADERS_RETARGET_BASE 0xF44 +#define MV64340_PCI_1_HEADERS_RETARGET_BASE 0xFc4 +#define MV64340_PCI_0_HEADERS_RETARGET_HIGH 0xF48 +#define MV64340_PCI_1_HEADERS_RETARGET_HIGH 0xFc8 + +/***********************************/ +/* PCI Control Register Map */ +/***********************************/ + +#define MV64340_PCI_0_DLL_STATUS_AND_COMMAND 0x1d20 +#define MV64340_PCI_1_DLL_STATUS_AND_COMMAND 0x1da0 +#define MV64340_PCI_0_MPP_PADS_DRIVE_CONTROL 0x1d1C +#define MV64340_PCI_1_MPP_PADS_DRIVE_CONTROL 0x1d9C +#define MV64340_PCI_0_COMMAND 0xc00 +#define MV64340_PCI_1_COMMAND 0xc80 +#define MV64340_PCI_0_MODE 0xd00 +#define MV64340_PCI_1_MODE 0xd80 +#define MV64340_PCI_0_RETRY 0xc04 +#define MV64340_PCI_1_RETRY 0xc84 +#define MV64340_PCI_0_READ_BUFFER_DISCARD_TIMER 0xd04 +#define MV64340_PCI_1_READ_BUFFER_DISCARD_TIMER 0xd84 +#define MV64340_PCI_0_MSI_TRIGGER_TIMER 0xc38 +#define MV64340_PCI_1_MSI_TRIGGER_TIMER 0xcb8 +#define MV64340_PCI_0_ARBITER_CONTROL 0x1d00 +#define MV64340_PCI_1_ARBITER_CONTROL 0x1d80 +#define MV64340_PCI_0_CROSS_BAR_CONTROL_LOW 0x1d08 +#define MV64340_PCI_1_CROSS_BAR_CONTROL_LOW 0x1d88 +#define MV64340_PCI_0_CROSS_BAR_CONTROL_HIGH 0x1d0c +#define MV64340_PCI_1_CROSS_BAR_CONTROL_HIGH 0x1d8c +#define MV64340_PCI_0_CROSS_BAR_TIMEOUT 0x1d04 +#define MV64340_PCI_1_CROSS_BAR_TIMEOUT 0x1d84 +#define MV64340_PCI_0_SYNC_BARRIER_TRIGGER_REG 0x1D18 +#define MV64340_PCI_1_SYNC_BARRIER_TRIGGER_REG 0x1D98 +#define MV64340_PCI_0_SYNC_BARRIER_VIRTUAL_REG 0x1d10 +#define MV64340_PCI_1_SYNC_BARRIER_VIRTUAL_REG 0x1d90 +#define MV64340_PCI_0_P2P_CONFIG 0x1d14 +#define MV64340_PCI_1_P2P_CONFIG 0x1d94 + +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_0_LOW 0x1e00 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_0_HIGH 0x1e04 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_0 0x1e08 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_1_LOW 0x1e10 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_1_HIGH 0x1e14 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_1 0x1e18 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_2_LOW 0x1e20 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_2_HIGH 0x1e24 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_2 0x1e28 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_3_LOW 0x1e30 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_3_HIGH 0x1e34 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_3 0x1e38 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_4_LOW 0x1e40 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_4_HIGH 0x1e44 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_4 0x1e48 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_5_LOW 0x1e50 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_5_HIGH 0x1e54 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_5 0x1e58 + +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_0_LOW 0x1e80 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_0_HIGH 0x1e84 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_0 0x1e88 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_1_LOW 0x1e90 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_1_HIGH 0x1e94 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_1 0x1e98 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_2_LOW 0x1ea0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_2_HIGH 0x1ea4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_2 0x1ea8 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_3_LOW 0x1eb0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_3_HIGH 0x1eb4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_3 0x1eb8 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_4_LOW 0x1ec0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_4_HIGH 0x1ec4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_4 0x1ec8 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_5_LOW 0x1ed0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_5_HIGH 0x1ed4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_5 0x1ed8 + +/****************************************/ +/* PCI Configuration Access Registers */ +/****************************************/ + +#define MV64340_PCI_0_CONFIG_ADDR 0xcf8 +#define MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG 0xcfc +#define MV64340_PCI_1_CONFIG_ADDR 0xc78 +#define MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG 0xc7c +#define MV64340_PCI_0_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG 0xc34 +#define MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG 0xcb4 + +/****************************************/ +/* PCI Error Report Registers */ +/****************************************/ + +#define MV64340_PCI_0_SERR_MASK 0xc28 +#define MV64340_PCI_1_SERR_MASK 0xca8 +#define MV64340_PCI_0_ERROR_ADDR_LOW 0x1d40 +#define MV64340_PCI_1_ERROR_ADDR_LOW 0x1dc0 +#define MV64340_PCI_0_ERROR_ADDR_HIGH 0x1d44 +#define MV64340_PCI_1_ERROR_ADDR_HIGH 0x1dc4 +#define MV64340_PCI_0_ERROR_ATTRIBUTE 0x1d48 +#define MV64340_PCI_1_ERROR_ATTRIBUTE 0x1dc8 +#define MV64340_PCI_0_ERROR_COMMAND 0x1d50 +#define MV64340_PCI_1_ERROR_COMMAND 0x1dd0 +#define MV64340_PCI_0_ERROR_CAUSE 0x1d58 +#define MV64340_PCI_1_ERROR_CAUSE 0x1dd8 +#define MV64340_PCI_0_ERROR_MASK 0x1d5c +#define MV64340_PCI_1_ERROR_MASK 0x1ddc + +/****************************************/ +/* PCI Debug Registers */ +/****************************************/ + +#define MV64340_PCI_0_MMASK 0X1D24 +#define MV64340_PCI_1_MMASK 0X1DA4 + +/*********************************************/ +/* PCI Configuration, Function 0, Registers */ +/*********************************************/ + +#define MV64340_PCI_DEVICE_AND_VENDOR_ID 0x000 +#define MV64340_PCI_STATUS_AND_COMMAND 0x004 +#define MV64340_PCI_CLASS_CODE_AND_REVISION_ID 0x008 +#define MV64340_PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 0x00C + +#define MV64340_PCI_SCS_0_BASE_ADDR_LOW 0x010 +#define MV64340_PCI_SCS_0_BASE_ADDR_HIGH 0x014 +#define MV64340_PCI_SCS_1_BASE_ADDR_LOW 0x018 +#define MV64340_PCI_SCS_1_BASE_ADDR_HIGH 0x01C +#define MV64340_PCI_INTERNAL_REG_MEM_MAPPED_BASE_ADDR_LOW 0x020 +#define MV64340_PCI_INTERNAL_REG_MEM_MAPPED_BASE_ADDR_HIGH 0x024 +#define MV64340_PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID 0x02c +#define MV64340_PCI_EXPANSION_ROM_BASE_ADDR_REG 0x030 +#define MV64340_PCI_CAPABILTY_LIST_POINTER 0x034 +#define MV64340_PCI_INTERRUPT_PIN_AND_LINE 0x03C + /* capability list */ +#define MV64340_PCI_POWER_MANAGEMENT_CAPABILITY 0x040 +#define MV64340_PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL 0x044 +#define MV64340_PCI_VPD_ADDR 0x048 +#define MV64340_PCI_VPD_DATA 0x04c +#define MV64340_PCI_MSI_MESSAGE_CONTROL 0x050 +#define MV64340_PCI_MSI_MESSAGE_ADDR 0x054 +#define MV64340_PCI_MSI_MESSAGE_UPPER_ADDR 0x058 +#define MV64340_PCI_MSI_MESSAGE_DATA 0x05c +#define MV64340_PCI_X_COMMAND 0x060 +#define MV64340_PCI_X_STATUS 0x064 +#define MV64340_PCI_COMPACT_PCI_HOT_SWAP 0x068 + +/***********************************************/ +/* PCI Configuration, Function 1, Registers */ +/***********************************************/ + +#define MV64340_PCI_SCS_2_BASE_ADDR_LOW 0x110 +#define MV64340_PCI_SCS_2_BASE_ADDR_HIGH 0x114 +#define MV64340_PCI_SCS_3_BASE_ADDR_LOW 0x118 +#define MV64340_PCI_SCS_3_BASE_ADDR_HIGH 0x11c +#define MV64340_PCI_INTERNAL_SRAM_BASE_ADDR_LOW 0x120 +#define MV64340_PCI_INTERNAL_SRAM_BASE_ADDR_HIGH 0x124 + +/***********************************************/ +/* PCI Configuration, Function 2, Registers */ +/***********************************************/ + +#define MV64340_PCI_DEVCS_0_BASE_ADDR_LOW 0x210 +#define MV64340_PCI_DEVCS_0_BASE_ADDR_HIGH 0x214 +#define MV64340_PCI_DEVCS_1_BASE_ADDR_LOW 0x218 +#define MV64340_PCI_DEVCS_1_BASE_ADDR_HIGH 0x21c +#define MV64340_PCI_DEVCS_2_BASE_ADDR_LOW 0x220 +#define MV64340_PCI_DEVCS_2_BASE_ADDR_HIGH 0x224 + +/***********************************************/ +/* PCI Configuration, Function 3, Registers */ +/***********************************************/ + +#define MV64340_PCI_DEVCS_3_BASE_ADDR_LOW 0x310 +#define MV64340_PCI_DEVCS_3_BASE_ADDR_HIGH 0x314 +#define MV64340_PCI_BOOT_CS_BASE_ADDR_LOW 0x318 +#define MV64340_PCI_BOOT_CS_BASE_ADDR_HIGH 0x31c +#define MV64340_PCI_CPU_BASE_ADDR_LOW 0x220 +#define MV64340_PCI_CPU_BASE_ADDR_HIGH 0x224 + +/***********************************************/ +/* PCI Configuration, Function 4, Registers */ +/***********************************************/ + +#define MV64340_PCI_P2P_MEM0_BASE_ADDR_LOW 0x410 +#define MV64340_PCI_P2P_MEM0_BASE_ADDR_HIGH 0x414 +#define MV64340_PCI_P2P_MEM1_BASE_ADDR_LOW 0x418 +#define MV64340_PCI_P2P_MEM1_BASE_ADDR_HIGH 0x41c +#define MV64340_PCI_P2P_I_O_BASE_ADDR 0x420 +#define MV64340_PCI_INTERNAL_REGS_I_O_MAPPED_BASE_ADDR 0x424 + +/****************************************/ +/* Messaging Unit Registers (I20) */ +/****************************************/ + +#define MV64340_I2O_INBOUND_MESSAGE_REG0_PCI_0_SIDE 0x010 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_PCI_0_SIDE 0x014 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_PCI_0_SIDE 0x018 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_PCI_0_SIDE 0x01C +#define MV64340_I2O_INBOUND_DOORBELL_REG_PCI_0_SIDE 0x020 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_PCI_0_SIDE 0x024 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_PCI_0_SIDE 0x028 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_PCI_0_SIDE 0x02C +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_PCI_0_SIDE 0x030 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_PCI_0_SIDE 0x034 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_0_SIDE 0x040 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_0_SIDE 0x044 +#define MV64340_I2O_QUEUE_CONTROL_REG_PCI_0_SIDE 0x050 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_PCI_0_SIDE 0x054 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_PCI_0_SIDE 0x060 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_PCI_0_SIDE 0x064 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_PCI_0_SIDE 0x068 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_PCI_0_SIDE 0x06C +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_PCI_0_SIDE 0x070 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_PCI_0_SIDE 0x074 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_PCI_0_SIDE 0x0F8 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_PCI_0_SIDE 0x0FC + +#define MV64340_I2O_INBOUND_MESSAGE_REG0_PCI_1_SIDE 0x090 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_PCI_1_SIDE 0x094 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_PCI_1_SIDE 0x098 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_PCI_1_SIDE 0x09C +#define MV64340_I2O_INBOUND_DOORBELL_REG_PCI_1_SIDE 0x0A0 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_PCI_1_SIDE 0x0A4 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_PCI_1_SIDE 0x0A8 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_PCI_1_SIDE 0x0AC +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_PCI_1_SIDE 0x0B0 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_PCI_1_SIDE 0x0B4 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_1_SIDE 0x0C0 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_1_SIDE 0x0C4 +#define MV64340_I2O_QUEUE_CONTROL_REG_PCI_1_SIDE 0x0D0 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_PCI_1_SIDE 0x0D4 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_PCI_1_SIDE 0x0E0 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_PCI_1_SIDE 0x0E4 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_PCI_1_SIDE 0x0E8 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_PCI_1_SIDE 0x0EC +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_PCI_1_SIDE 0x0F0 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_PCI_1_SIDE 0x0F4 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_PCI_1_SIDE 0x078 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_PCI_1_SIDE 0x07C + +#define MV64340_I2O_INBOUND_MESSAGE_REG0_CPU0_SIDE 0x1C10 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_CPU0_SIDE 0x1C14 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_CPU0_SIDE 0x1C18 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_CPU0_SIDE 0x1C1C +#define MV64340_I2O_INBOUND_DOORBELL_REG_CPU0_SIDE 0x1C20 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_CPU0_SIDE 0x1C24 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_CPU0_SIDE 0x1C28 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_CPU0_SIDE 0x1C2C +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_CPU0_SIDE 0x1C30 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_CPU0_SIDE 0x1C34 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_CPU0_SIDE 0x1C40 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_CPU0_SIDE 0x1C44 +#define MV64340_I2O_QUEUE_CONTROL_REG_CPU0_SIDE 0x1C50 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_CPU0_SIDE 0x1C54 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_CPU0_SIDE 0x1C60 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_CPU0_SIDE 0x1C64 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_CPU0_SIDE 0x1C68 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_CPU0_SIDE 0x1C6C +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_CPU0_SIDE 0x1C70 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_CPU0_SIDE 0x1C74 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_CPU0_SIDE 0x1CF8 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_CPU0_SIDE 0x1CFC +#define MV64340_I2O_INBOUND_MESSAGE_REG0_CPU1_SIDE 0x1C90 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_CPU1_SIDE 0x1C94 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_CPU1_SIDE 0x1C98 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_CPU1_SIDE 0x1C9C +#define MV64340_I2O_INBOUND_DOORBELL_REG_CPU1_SIDE 0x1CA0 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_CPU1_SIDE 0x1CA4 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_CPU1_SIDE 0x1CA8 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_CPU1_SIDE 0x1CAC +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_CPU1_SIDE 0x1CB0 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_CPU1_SIDE 0x1CB4 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_CPU1_SIDE 0x1CC0 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_CPU1_SIDE 0x1CC4 +#define MV64340_I2O_QUEUE_CONTROL_REG_CPU1_SIDE 0x1CD0 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_CPU1_SIDE 0x1CD4 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_CPU1_SIDE 0x1CE0 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_CPU1_SIDE 0x1CE4 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_CPU1_SIDE 0x1CE8 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_CPU1_SIDE 0x1CEC +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_CPU1_SIDE 0x1CF0 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_CPU1_SIDE 0x1CF4 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_CPU1_SIDE 0x1C78 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_CPU1_SIDE 0x1C7C + +/****************************************/ +/* Ethernet Unit Registers */ +/****************************************/ + +#define MV64340_ETH_PHY_ADDR_REG 0x2000 +#define MV64340_ETH_SMI_REG 0x2004 +#define MV64340_ETH_UNIT_DEFAULT_ADDR_REG 0x2008 +#define MV64340_ETH_UNIT_DEFAULTID_REG 0x200c +#define MV64340_ETH_UNIT_INTERRUPT_CAUSE_REG 0x2080 +#define MV64340_ETH_UNIT_INTERRUPT_MASK_REG 0x2084 +#define MV64340_ETH_UNIT_INTERNAL_USE_REG 0x24fc +#define MV64340_ETH_UNIT_ERROR_ADDR_REG 0x2094 +#define MV64340_ETH_BAR_0 0x2200 +#define MV64340_ETH_BAR_1 0x2208 +#define MV64340_ETH_BAR_2 0x2210 +#define MV64340_ETH_BAR_3 0x2218 +#define MV64340_ETH_BAR_4 0x2220 +#define MV64340_ETH_BAR_5 0x2228 +#define MV64340_ETH_SIZE_REG_0 0x2204 +#define MV64340_ETH_SIZE_REG_1 0x220c +#define MV64340_ETH_SIZE_REG_2 0x2214 +#define MV64340_ETH_SIZE_REG_3 0x221c +#define MV64340_ETH_SIZE_REG_4 0x2224 +#define MV64340_ETH_SIZE_REG_5 0x222c +#define MV64340_ETH_HEADERS_RETARGET_BASE_REG 0x2230 +#define MV64340_ETH_HEADERS_RETARGET_CONTROL_REG 0x2234 +#define MV64340_ETH_HIGH_ADDR_REMAP_REG_0 0x2280 +#define MV64340_ETH_HIGH_ADDR_REMAP_REG_1 0x2284 +#define MV64340_ETH_HIGH_ADDR_REMAP_REG_2 0x2288 +#define MV64340_ETH_HIGH_ADDR_REMAP_REG_3 0x228c +#define MV64340_ETH_BASE_ADDR_ENABLE_REG 0x2290 +#define MV64340_ETH_ACCESS_PROTECTION_REG(port) (0x2294 + (port<<2)) +#define MV64340_ETH_MIB_COUNTERS_BASE(port) (0x3000 + (port<<7)) +#define MV64340_ETH_PORT_CONFIG_REG(port) (0x2400 + (port<<10)) +#define MV64340_ETH_PORT_CONFIG_EXTEND_REG(port) (0x2404 + (port<<10)) +#define MV64340_ETH_MII_SERIAL_PARAMETRS_REG(port) (0x2408 + (port<<10)) +#define MV64340_ETH_GMII_SERIAL_PARAMETRS_REG(port) (0x240c + (port<<10)) +#define MV64340_ETH_VLAN_ETHERTYPE_REG(port) (0x2410 + (port<<10)) +#define MV64340_ETH_MAC_ADDR_LOW(port) (0x2414 + (port<<10)) +#define MV64340_ETH_MAC_ADDR_HIGH(port) (0x2418 + (port<<10)) +#define MV64340_ETH_SDMA_CONFIG_REG(port) (0x241c + (port<<10)) +#define MV64340_ETH_DSCP_0(port) (0x2420 + (port<<10)) +#define MV64340_ETH_DSCP_1(port) (0x2424 + (port<<10)) +#define MV64340_ETH_DSCP_2(port) (0x2428 + (port<<10)) +#define MV64340_ETH_DSCP_3(port) (0x242c + (port<<10)) +#define MV64340_ETH_DSCP_4(port) (0x2430 + (port<<10)) +#define MV64340_ETH_DSCP_5(port) (0x2434 + (port<<10)) +#define MV64340_ETH_DSCP_6(port) (0x2438 + (port<<10)) +#define MV64340_ETH_PORT_SERIAL_CONTROL_REG(port) (0x243c + (port<<10)) +#define MV64340_ETH_VLAN_PRIORITY_TAG_TO_PRIORITY(port) (0x2440 + (port<<10)) +#define MV64340_ETH_PORT_STATUS_REG(port) (0x2444 + (port<<10)) +#define MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(port) (0x2448 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_FIXED_PRIORITY(port) (0x244c + (port<<10)) +#define MV64340_ETH_PORT_TX_TOKEN_BUCKET_RATE_CONFIG(port) (0x2450 + (port<<10)) +#define MV64340_ETH_MAXIMUM_TRANSMIT_UNIT(port) (0x2458 + (port<<10)) +#define MV64340_ETH_PORT_MAXIMUM_TOKEN_BUCKET_SIZE(port) (0x245c + (port<<10)) +#define MV64340_ETH_INTERRUPT_CAUSE_REG(port) (0x2460 + (port<<10)) +#define MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port) (0x2464 + (port<<10)) +#define MV64340_ETH_INTERRUPT_MASK_REG(port) (0x2468 + (port<<10)) +#define MV64340_ETH_INTERRUPT_EXTEND_MASK_REG(port) (0x246c + (port<<10)) +#define MV64340_ETH_RX_FIFO_URGENT_THRESHOLD_REG(port) (0x2470 + (port<<10)) +#define MV64340_ETH_TX_FIFO_URGENT_THRESHOLD_REG(port) (0x2474 + (port<<10)) +#define MV64340_ETH_RX_MINIMAL_FRAME_SIZE_REG(port) (0x247c + (port<<10)) +#define MV64340_ETH_RX_DISCARDED_FRAMES_COUNTER(port) (0x2484 + (port<<10) +#define MV64340_ETH_PORT_DEBUG_0_REG(port) (0x248c + (port<<10)) +#define MV64340_ETH_PORT_DEBUG_1_REG(port) (0x2490 + (port<<10)) +#define MV64340_ETH_PORT_INTERNAL_ADDR_ERROR_REG(port) (0x2494 + (port<<10)) +#define MV64340_ETH_INTERNAL_USE_REG(port) (0x24fc + (port<<10)) +#define MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(port) (0x2680 + (port<<10)) +#define MV64340_ETH_CURRENT_SERVED_TX_DESC_PTR(port) (0x2684 + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port) (0x260c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_1(port) (0x261c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_2(port) (0x262c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_3(port) (0x263c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_4(port) (0x264c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_5(port) (0x265c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_6(port) (0x266c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_7(port) (0x267c + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(port) (0x26c0 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_1(port) (0x26c4 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_2(port) (0x26c8 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_3(port) (0x26cc + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_4(port) (0x26d0 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_5(port) (0x26d4 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_6(port) (0x26d8 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_7(port) (0x26dc + (port<<10)) +#define MV64340_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT(port) (0x2700 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_1_TOKEN_BUCKET_COUNT(port) (0x2710 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_2_TOKEN_BUCKET_COUNT(port) (0x2720 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_3_TOKEN_BUCKET_COUNT(port) (0x2730 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_4_TOKEN_BUCKET_COUNT(port) (0x2740 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_5_TOKEN_BUCKET_COUNT(port) (0x2750 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_6_TOKEN_BUCKET_COUNT(port) (0x2760 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_7_TOKEN_BUCKET_COUNT(port) (0x2770 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG(port) (0x2704 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_1_TOKEN_BUCKET_CONFIG(port) (0x2714 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_2_TOKEN_BUCKET_CONFIG(port) (0x2724 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_3_TOKEN_BUCKET_CONFIG(port) (0x2734 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_4_TOKEN_BUCKET_CONFIG(port) (0x2744 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_5_TOKEN_BUCKET_CONFIG(port) (0x2754 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_6_TOKEN_BUCKET_CONFIG(port) (0x2764 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_7_TOKEN_BUCKET_CONFIG(port) (0x2774 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_0_ARBITER_CONFIG(port) (0x2708 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_1_ARBITER_CONFIG(port) (0x2718 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_2_ARBITER_CONFIG(port) (0x2728 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_3_ARBITER_CONFIG(port) (0x2738 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_4_ARBITER_CONFIG(port) (0x2748 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_5_ARBITER_CONFIG(port) (0x2758 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_6_ARBITER_CONFIG(port) (0x2768 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_7_ARBITER_CONFIG(port) (0x2778 + (port<<10)) +#define MV64340_ETH_PORT_TX_TOKEN_BUCKET_COUNT(port) (0x2780 + (port<<10)) +#define MV64340_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port) (0x3400 + (port<<10)) +#define MV64340_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port) (0x3500 + (port<<10)) +#define MV64340_ETH_DA_FILTER_UNICAST_TABLE_BASE(port) (0x3600 + (port<<10)) + +/*******************************************/ +/* CUNIT Registers */ +/*******************************************/ + + /* Address Decoding Register Map */ + +#define MV64340_CUNIT_BASE_ADDR_REG0 0xf200 +#define MV64340_CUNIT_BASE_ADDR_REG1 0xf208 +#define MV64340_CUNIT_BASE_ADDR_REG2 0xf210 +#define MV64340_CUNIT_BASE_ADDR_REG3 0xf218 +#define MV64340_CUNIT_SIZE0 0xf204 +#define MV64340_CUNIT_SIZE1 0xf20c +#define MV64340_CUNIT_SIZE2 0xf214 +#define MV64340_CUNIT_SIZE3 0xf21c +#define MV64340_CUNIT_HIGH_ADDR_REMAP_REG0 0xf240 +#define MV64340_CUNIT_HIGH_ADDR_REMAP_REG1 0xf244 +#define MV64340_CUNIT_BASE_ADDR_ENABLE_REG 0xf250 +#define MV64340_MPSC0_ACCESS_PROTECTION_REG 0xf254 +#define MV64340_MPSC1_ACCESS_PROTECTION_REG 0xf258 +#define MV64340_CUNIT_INTERNAL_SPACE_BASE_ADDR_REG 0xf25C + + /* Error Report Registers */ + +#define MV64340_CUNIT_INTERRUPT_CAUSE_REG 0xf310 +#define MV64340_CUNIT_INTERRUPT_MASK_REG 0xf314 +#define MV64340_CUNIT_ERROR_ADDR 0xf318 + + /* Cunit Control Registers */ + +#define MV64340_CUNIT_ARBITER_CONTROL_REG 0xf300 +#define MV64340_CUNIT_CONFIG_REG 0xb40c +#define MV64340_CUNIT_CRROSBAR_TIMEOUT_REG 0xf304 + + /* Cunit Debug Registers */ + +#define MV64340_CUNIT_DEBUG_LOW 0xf340 +#define MV64340_CUNIT_DEBUG_HIGH 0xf344 +#define MV64340_CUNIT_MMASK 0xf380 + + /* MPSCs Clocks Routing Registers */ + +#define MV64340_MPSC_ROUTING_REG 0xb400 +#define MV64340_MPSC_RX_CLOCK_ROUTING_REG 0xb404 +#define MV64340_MPSC_TX_CLOCK_ROUTING_REG 0xb408 + + /* MPSCs Interrupts Registers */ + +#define MV64340_MPSC_CAUSE_REG(port) (0xb804 + (port<<3)) +#define MV64340_MPSC_MASK_REG(port) (0xb884 + (port<<3)) + +#define MV64340_MPSC_MAIN_CONFIG_LOW(port) (0x8000 + (port<<12)) +#define MV64340_MPSC_MAIN_CONFIG_HIGH(port) (0x8004 + (port<<12)) +#define MV64340_MPSC_PROTOCOL_CONFIG(port) (0x8008 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG1(port) (0x800c + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG2(port) (0x8010 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG3(port) (0x8014 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG4(port) (0x8018 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG5(port) (0x801c + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG6(port) (0x8020 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG7(port) (0x8024 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG8(port) (0x8028 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG9(port) (0x802c + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG10(port) (0x8030 + (port<<12)) + + /* MPSC0 Registers */ + + +/***************************************/ +/* SDMA Registers */ +/***************************************/ + +#define MV64340_SDMA_CONFIG_REG(channel) (0x4000 + (channel<<13)) +#define MV64340_SDMA_COMMAND_REG(channel) (0x4008 + (channel<<13)) +#define MV64340_SDMA_CURRENT_RX_DESCRIPTOR_POINTER(channel) (0x4810 + (channel<<13)) +#define MV64340_SDMA_CURRENT_TX_DESCRIPTOR_POINTER(channel) (0x4c10 + (channel<<13)) +#define MV64340_SDMA_FIRST_TX_DESCRIPTOR_POINTER(channel) (0x4c14 + (channel<<13)) + +#define MV64340_SDMA_CAUSE_REG 0xb800 +#define MV64340_SDMA_MASK_REG 0xb880 + +/* BRG Interrupts */ + +#define MV64340_BRG_CONFIG_REG(brg) (0xb200 + (brg<<3)) +#define MV64340_BRG_BAUDE_TUNING_REG(brg) (0xb208 + (brg<<3)) +#define MV64340_BRG_CAUSE_REG 0xb834 +#define MV64340_BRG_MASK_REG 0xb8b4 + +/****************************************/ +/* DMA Channel Control */ +/****************************************/ + +#define MV64340_DMA_CHANNEL0_CONTROL 0x840 +#define MV64340_DMA_CHANNEL0_CONTROL_HIGH 0x880 +#define MV64340_DMA_CHANNEL1_CONTROL 0x844 +#define MV64340_DMA_CHANNEL1_CONTROL_HIGH 0x884 +#define MV64340_DMA_CHANNEL2_CONTROL 0x848 +#define MV64340_DMA_CHANNEL2_CONTROL_HIGH 0x888 +#define MV64340_DMA_CHANNEL3_CONTROL 0x84C +#define MV64340_DMA_CHANNEL3_CONTROL_HIGH 0x88C + + +/****************************************/ +/* IDMA Registers */ +/****************************************/ + +#define MV64340_DMA_CHANNEL0_BYTE_COUNT 0x800 +#define MV64340_DMA_CHANNEL1_BYTE_COUNT 0x804 +#define MV64340_DMA_CHANNEL2_BYTE_COUNT 0x808 +#define MV64340_DMA_CHANNEL3_BYTE_COUNT 0x80C +#define MV64340_DMA_CHANNEL0_SOURCE_ADDR 0x810 +#define MV64340_DMA_CHANNEL1_SOURCE_ADDR 0x814 +#define MV64340_DMA_CHANNEL2_SOURCE_ADDR 0x818 +#define MV64340_DMA_CHANNEL3_SOURCE_ADDR 0x81c +#define MV64340_DMA_CHANNEL0_DESTINATION_ADDR 0x820 +#define MV64340_DMA_CHANNEL1_DESTINATION_ADDR 0x824 +#define MV64340_DMA_CHANNEL2_DESTINATION_ADDR 0x828 +#define MV64340_DMA_CHANNEL3_DESTINATION_ADDR 0x82C +#define MV64340_DMA_CHANNEL0_NEXT_DESCRIPTOR_POINTER 0x830 +#define MV64340_DMA_CHANNEL1_NEXT_DESCRIPTOR_POINTER 0x834 +#define MV64340_DMA_CHANNEL2_NEXT_DESCRIPTOR_POINTER 0x838 +#define MV64340_DMA_CHANNEL3_NEXT_DESCRIPTOR_POINTER 0x83C +#define MV64340_DMA_CHANNEL0_CURRENT_DESCRIPTOR_POINTER 0x870 +#define MV64340_DMA_CHANNEL1_CURRENT_DESCRIPTOR_POINTER 0x874 +#define MV64340_DMA_CHANNEL2_CURRENT_DESCRIPTOR_POINTER 0x878 +#define MV64340_DMA_CHANNEL3_CURRENT_DESCRIPTOR_POINTER 0x87C + + /* IDMA Address Decoding Base Address Registers */ + +#define MV64340_DMA_BASE_ADDR_REG0 0xa00 +#define MV64340_DMA_BASE_ADDR_REG1 0xa08 +#define MV64340_DMA_BASE_ADDR_REG2 0xa10 +#define MV64340_DMA_BASE_ADDR_REG3 0xa18 +#define MV64340_DMA_BASE_ADDR_REG4 0xa20 +#define MV64340_DMA_BASE_ADDR_REG5 0xa28 +#define MV64340_DMA_BASE_ADDR_REG6 0xa30 +#define MV64340_DMA_BASE_ADDR_REG7 0xa38 + + /* IDMA Address Decoding Size Address Register */ + +#define MV64340_DMA_SIZE_REG0 0xa04 +#define MV64340_DMA_SIZE_REG1 0xa0c +#define MV64340_DMA_SIZE_REG2 0xa14 +#define MV64340_DMA_SIZE_REG3 0xa1c +#define MV64340_DMA_SIZE_REG4 0xa24 +#define MV64340_DMA_SIZE_REG5 0xa2c +#define MV64340_DMA_SIZE_REG6 0xa34 +#define MV64340_DMA_SIZE_REG7 0xa3C + + /* IDMA Address Decoding High Address Remap and Access + Protection Registers */ + +#define MV64340_DMA_HIGH_ADDR_REMAP_REG0 0xa60 +#define MV64340_DMA_HIGH_ADDR_REMAP_REG1 0xa64 +#define MV64340_DMA_HIGH_ADDR_REMAP_REG2 0xa68 +#define MV64340_DMA_HIGH_ADDR_REMAP_REG3 0xa6C +#define MV64340_DMA_BASE_ADDR_ENABLE_REG 0xa80 +#define MV64340_DMA_CHANNEL0_ACCESS_PROTECTION_REG 0xa70 +#define MV64340_DMA_CHANNEL1_ACCESS_PROTECTION_REG 0xa74 +#define MV64340_DMA_CHANNEL2_ACCESS_PROTECTION_REG 0xa78 +#define MV64340_DMA_CHANNEL3_ACCESS_PROTECTION_REG 0xa7c +#define MV64340_DMA_ARBITER_CONTROL 0x860 +#define MV64340_DMA_CROSS_BAR_TIMEOUT 0x8d0 + + /* IDMA Headers Retarget Registers */ + +#define MV64340_DMA_HEADERS_RETARGET_CONTROL 0xa84 +#define MV64340_DMA_HEADERS_RETARGET_BASE 0xa88 + + /* IDMA Interrupt Register */ + +#define MV64340_DMA_INTERRUPT_CAUSE_REG 0x8c0 +#define MV64340_DMA_INTERRUPT_CAUSE_MASK 0x8c4 +#define MV64340_DMA_ERROR_ADDR 0x8c8 +#define MV64340_DMA_ERROR_SELECT 0x8cc + + /* IDMA Debug Register ( for internal use ) */ + +#define MV64340_DMA_DEBUG_LOW 0x8e0 +#define MV64340_DMA_DEBUG_HIGH 0x8e4 +#define MV64340_DMA_SPARE 0xA8C + +/****************************************/ +/* Timer_Counter */ +/****************************************/ + +#define MV64340_TIMER_COUNTER0 0x850 +#define MV64340_TIMER_COUNTER1 0x854 +#define MV64340_TIMER_COUNTER2 0x858 +#define MV64340_TIMER_COUNTER3 0x85C +#define MV64340_TIMER_COUNTER_0_3_CONTROL 0x864 +#define MV64340_TIMER_COUNTER_0_3_INTERRUPT_CAUSE 0x868 +#define MV64340_TIMER_COUNTER_0_3_INTERRUPT_MASK 0x86c + +/****************************************/ +/* Watchdog registers */ +/****************************************/ + +#define MV64340_WATCHDOG_CONFIG_REG 0xb410 +#define MV64340_WATCHDOG_VALUE_REG 0xb414 + +/****************************************/ +/* I2C Registers */ +/****************************************/ + +#define MV64340_I2C_SLAVE_ADDR 0xc000 +#define MV64340_I2C_EXTENDED_SLAVE_ADDR 0xc010 +#define MV64340_I2C_DATA 0xc004 +#define MV64340_I2C_CONTROL 0xc008 +#define MV64340_I2C_STATUS_BAUDE_RATE 0xc00C +#define MV64340_I2C_SOFT_RESET 0xc01c + +/****************************************/ +/* GPP Interface Registers */ +/****************************************/ + +#define MV64340_GPP_IO_CONTROL 0xf100 +#define MV64340_GPP_LEVEL_CONTROL 0xf110 +#define MV64340_GPP_VALUE 0xf104 +#define MV64340_GPP_INTERRUPT_CAUSE 0xf108 +#define MV64340_GPP_INTERRUPT_MASK0 0xf10c +#define MV64340_GPP_INTERRUPT_MASK1 0xf114 +#define MV64340_GPP_VALUE_SET 0xf118 +#define MV64340_GPP_VALUE_CLEAR 0xf11c + +/****************************************/ +/* Interrupt Controller Registers */ +/****************************************/ + +/****************************************/ +/* Interrupts */ +/****************************************/ + +#define MV64340_MAIN_INTERRUPT_CAUSE_LOW 0x004 +#define MV64340_MAIN_INTERRUPT_CAUSE_HIGH 0x00c +#define MV64340_CPU_INTERRUPT0_MASK_LOW 0x014 +#define MV64340_CPU_INTERRUPT0_MASK_HIGH 0x01c +#define MV64340_CPU_INTERRUPT0_SELECT_CAUSE 0x024 +#define MV64340_CPU_INTERRUPT1_MASK_LOW 0x034 +#define MV64340_CPU_INTERRUPT1_MASK_HIGH 0x03c +#define MV64340_CPU_INTERRUPT1_SELECT_CAUSE 0x044 +#define MV64340_INTERRUPT0_MASK_0_LOW 0x054 +#define MV64340_INTERRUPT0_MASK_0_HIGH 0x05c +#define MV64340_INTERRUPT0_SELECT_CAUSE 0x064 +#define MV64340_INTERRUPT1_MASK_0_LOW 0x074 +#define MV64340_INTERRUPT1_MASK_0_HIGH 0x07c +#define MV64340_INTERRUPT1_SELECT_CAUSE 0x084 + +/****************************************/ +/* MPP Interface Registers */ +/****************************************/ + +#define MV64340_MPP_CONTROL0 0xf000 +#define MV64340_MPP_CONTROL1 0xf004 +#define MV64340_MPP_CONTROL2 0xf008 +#define MV64340_MPP_CONTROL3 0xf00c + +/****************************************/ +/* Serial Initialization registers */ +/****************************************/ + +#define MV64340_SERIAL_INIT_LAST_DATA 0xf324 +#define MV64340_SERIAL_INIT_CONTROL 0xf328 +#define MV64340_SERIAL_INIT_STATUS 0xf32c + +#endif diff --git a/include/asm-mips/mv64340_dep.h b/include/asm-mips/mv64340_dep.h new file mode 100644 index 000000000000..f550fdfba7fa --- /dev/null +++ b/include/asm-mips/mv64340_dep.h @@ -0,0 +1,51 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm <mdharm@momenco.com> + * + * include/asm-mips/mv64340-dep.h + * Board-dependent definitions for MV-64340 chip. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __MV64340_DEP_H__ +#define __MV64340_DEP_H__ + +#include <asm/addrspace.h> /* for KSEG1ADDR() */ +#include <asm/byteorder.h> /* for cpu_to_le32() */ + +extern unsigned long mv64340_base; + +#define MV64340_BASE (mv64340_base) + +/* + * Because of an error/peculiarity in the Galileo chip, we need to swap the + * bytes when running bigendian. + */ + +#define MV_WRITE(ofs, data) \ + *(volatile u32 *)(MV64340_BASE+(ofs)) = cpu_to_le32(data) +#define MV_READ(ofs, data) \ + *(data) = le32_to_cpu(*(volatile u32 *)(MV64340_BASE+(ofs))) +#define MV_READ_DATA(ofs) \ + le32_to_cpu(*(volatile u32 *)(MV64340_BASE+(ofs))) + +#define MV_WRITE_16(ofs, data) \ + *(volatile u16 *)(MV64340_BASE+(ofs)) = cpu_to_le16(data) +#define MV_READ_16(ofs, data) \ + *(data) = le16_to_cpu(*(volatile u16 *)(MV64340_BASE+(ofs))) + +#define MV_WRITE_8(ofs, data) \ + *(volatile u8 *)(MV64340_BASE+(ofs)) = data +#define MV_READ_8(ofs, data) \ + *(data) = *(volatile u8 *)(MV64340_BASE+(ofs)) + +#define MV_SET_REG_BITS(ofs,bits) \ + (*((volatile u32 *)(MV64340_BASE+(ofs)))) |= ((u32)cpu_to_le32(bits)) +#define MV_RESET_REG_BITS(ofs,bits) \ + (*((volatile u32 *)(MV64340_BASE+(ofs)))) &= ~((u32)cpu_to_le32(bits)) + +#endif diff --git a/include/asm-mips/namei.h b/include/asm-mips/namei.h index 5361d07fdb37..dce62e3018c4 100644 --- a/include/asm-mips/namei.h +++ b/include/asm-mips/namei.h @@ -2,11 +2,9 @@ * linux/include/asm-mips/namei.h * * Included from linux/fs/namei.c - * - * $Id: namei.h,v 1.6 1999/01/04 16:09:23 ralf Exp $ */ -#ifndef __ASM_MIPS_NAMEI_H -#define __ASM_MIPS_NAMEI_H +#ifndef __ASM_NAMEI_H +#define __ASM_NAMEI_H #include <linux/config.h> @@ -28,4 +26,4 @@ static inline char *__emul_prefix(void) #endif /* !defined(CONFIG_BINFMT_IRIX) */ -#endif /* __ASM_MIPS_NAMEI_H */ +#endif /* __ASM_NAMEI_H */ diff --git a/include/asm-mips/ng1.h b/include/asm-mips/ng1.h index 7c7104415001..8c980fed63a9 100644 --- a/include/asm-mips/ng1.h +++ b/include/asm-mips/ng1.h @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff --git a/include/asm-mips/paccess.h b/include/asm-mips/paccess.h index 6f6f4a1d28b8..e67d89c9a238 100644 --- a/include/asm-mips/paccess.h +++ b/include/asm-mips/paccess.h @@ -1,5 +1,4 @@ -/* $Id: paccess.h,v 1.1 2000/04/07 12:55:57 raiko Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -16,6 +15,9 @@ #include <linux/errno.h> +extern asmlinkage void handle_ibe(void); +extern asmlinkage void handle_dbe(void); + #define put_dbe(x,ptr) __put_dbe((x),(ptr),sizeof(*(ptr))) #define get_dbe(x,ptr) __get_dbe((x),(ptr),sizeof(*(ptr))) @@ -95,4 +97,6 @@ __asm__ __volatile__( \ extern void __put_dbe_unknown(void); +extern unsigned long search_dbe_table(unsigned long addr); + #endif /* _ASM_PACCESS_H */ diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index 015ebf1f9aab..581975ea7b98 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h @@ -1,5 +1,4 @@ -/* $Id: page.h,v 1.9 2000/02/24 00:13:19 ralf Exp $ - * +/* * Definitions for page handling * * This file is subject to the terms and conditions of the GNU General Public @@ -8,8 +7,10 @@ * * Copyright (C) 1994 - 1999 by Ralf Baechle */ -#ifndef __ASM_PAGE_H -#define __ASM_PAGE_H +#ifndef _ASM_PAGE_H +#define _ASM_PAGE_H + +#include <linux/config.h> /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 12 @@ -18,27 +19,52 @@ #ifdef __KERNEL__ -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ extern void (*_clear_page)(void * page); extern void (*_copy_page)(void * to, void * from); -#define clear_page(page) _clear_page(page) -#define copy_page(to, from) _copy_page(to, from) +#define clear_page(addr) _clear_page((void *)(addr)) +#define copy_page(to, from) _copy_page((void *)(to), (void *)(from)) + +extern unsigned long shm_align_mask; + +static inline unsigned long pages_do_alias(unsigned long addr1, + unsigned long addr2) +{ + return (addr1 ^ addr2) & shm_align_mask; +} + +struct page; + +static inline void clear_user_page(void *addr, unsigned long vaddr, + struct page *page) +{ + extern void (*flush_data_cache_page)(unsigned long addr); -#define clear_user_page(addr, vaddr, page) \ - do { clear_page(addr); \ - flush_dcache_page(page); \ - } while (0) -#define copy_user_page(to, from, vaddr, page) \ - do { copy_page(to, from); \ - flush_dcache_page(page); \ - } while (0) + clear_page(addr); + if (pages_do_alias((unsigned long) addr, vaddr)) + flush_data_cache_page((unsigned long)addr); +} + +static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, + struct page *to) +{ + extern void (*flush_data_cache_page)(unsigned long addr); + + copy_page(vto, vfrom); + if (pages_do_alias((unsigned long)vto, vaddr)) + flush_data_cache_page((unsigned long)vto); +} /* * These are used to make use of C type-checking.. */ +#ifdef CONFIG_64BIT_PHYS_ADDR +typedef struct { unsigned long long pte; } pte_t; +#else typedef struct { unsigned long pte; } pte_t; +#endif typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; @@ -48,8 +74,10 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define pgd_val(x) ((x).pgd) #define pgprot_val(x) ((x).pgprot) +#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t))) + #define __pte(x) ((pte_t) { (x) } ) -#define __pme(x) ((pme_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) @@ -67,24 +95,40 @@ extern __inline__ int get_order(unsigned long size) return order; } -#endif /* _LANGUAGE_ASSEMBLY */ +#endif /* !__ASSEMBLY__ */ /* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) +#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) /* * This handles the memory map. * We handle pages at KSEG0 for kernels with 32 bit address space. */ -#define PAGE_OFFSET 0x80000000UL -#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) -#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) -#define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT)) -#define VALID_PAGE(page) ((page - mem_map) < max_mapnr) +#define PAGE_OFFSET 0x80000000UL +#define UNCAC_BASE 0xa0000000UL + +#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) + +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) +#define pfn_to_page(pfn) (mem_map + (pfn)) +#define page_to_pfn(page) ((unsigned long)((page) - mem_map)) +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) + +#define pfn_valid(pfn) ((pfn) < max_mapnr) +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE) +#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET) + +/* + * Memory above this physical address will be considered highmem. + */ +#define HIGHMEM_START 0x20000000UL + #endif /* defined (__KERNEL__) */ -#endif /* __ASM_PAGE_H */ +#endif /* _ASM_PAGE_H */ diff --git a/include/asm-mips/param.h b/include/asm-mips/param.h index d4e4c7d73316..854088bb18b4 100644 --- a/include/asm-mips/param.h +++ b/include/asm-mips/param.h @@ -1,15 +1,16 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright 1994 - 2000, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright 2000 Silicon Graphics, Inc. + */ #ifndef _ASM_PARAM_H #define _ASM_PARAM_H -#ifndef HZ - #ifdef __KERNEL__ -/* Safeguard against user stupidity */ -#ifdef _SYS_PARAM_H -#error Do not include <asm/param.h> with __KERNEL__ defined! -#endif - #include <linux/config.h> #ifdef CONFIG_DECSTATION @@ -19,38 +20,16 @@ */ # define LOG_2_HZ 7 # define HZ (1 << LOG_2_HZ) - /* - * Ye olde division-by-multiplication trick. - * This works only if 100 / HZ <= 1 - */ -# define QUOTIENT ((1UL << (32 - LOG_2_HZ)) * 100) -# define hz_to_std(a) \ - ({ unsigned int __res; \ - unsigned long __lo; \ - __asm__("multu\t%2,%3\n\t" \ - :"=h" (__res), "=l" (__lo) \ - :"r" (a),"r" (QUOTIENT)); \ - (__typeof__(a)) __res;}) - -#else /* Not a DECstation */ - -/* This is the internal value of HZ, that is the rate at which the jiffies - counter is increasing. This value is independent from the external value - and can be changed in order to suit the hardware and application - requirements. */ -# define HZ 100 -# define hz_to_std(a) (a) - -#endif /* Not a DECstation */ - -#else /* defined(__KERNEL__) */ +#else +# define HZ 1000 /* Internal kernel timer frequency */ +#endif +# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ +# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +#endif -/* This is the external value of HZ as seen by user programs. Don't change - unless you know what you're doing - changing breaks binary compatibility. */ +#ifndef HZ #define HZ 100 - -#endif /* defined(__KERNEL__) */ -#endif /* defined(HZ) */ +#endif #define EXEC_PAGESIZE 4096 @@ -64,8 +43,4 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ -#ifdef __KERNEL__ -# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */ -#endif - #endif /* _ASM_PARAM_H */ diff --git a/include/asm-mips/parport.h b/include/asm-mips/parport.h index 159e2345d9b2..a742e04e82de 100644 --- a/include/asm-mips/parport.h +++ b/include/asm-mips/parport.h @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk> * * This file should only be included by drivers/parport/parport_pc.c. diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h index 5cd89d7f84ea..30e68fa8b764 100644 --- a/include/asm-mips/pci.h +++ b/include/asm-mips/pci.h @@ -7,6 +7,7 @@ #define _ASM_PCI_H #include <linux/config.h> +#include <linux/mm.h> #ifdef __KERNEL__ @@ -23,12 +24,12 @@ extern unsigned int pcibios_assign_all_busses(void); #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 -extern inline void pcibios_set_master(struct pci_dev *dev) +static inline void pcibios_set_master(struct pci_dev *dev) { /* No special bus mastering setup handling */ } -extern inline void pcibios_penalize_isa_irq(int irq) +static inline void pcibios_penalize_isa_irq(int irq) { /* We don't do dynamic PCI IRQ allocation */ } @@ -38,14 +39,13 @@ extern inline void pcibios_penalize_isa_irq(int irq) * MIPS has everything mapped statically. */ -#include <linux/config.h> #include <linux/types.h> #include <linux/slab.h> #include <asm/scatterlist.h> #include <linux/string.h> #include <asm/io.h> -#if (defined(CONFIG_DDB5074) || defined(CONFIG_DDB5476)) +#if defined(CONFIG_DDB5074) || defined(CONFIG_DDB5476) #undef PCIBIOS_MIN_IO #undef PCIBIOS_MIN_MEM #define PCIBIOS_MIN_IO 0x0100000 @@ -55,6 +55,13 @@ extern inline void pcibios_penalize_isa_irq(int irq) struct pci_dev; /* + * The PCI address space does equal the physical memory address space. The + * networking and block device layers use this boolean for bounce buffer + * decisions. + */ +#define PCI_DMA_BUS_IS_PHYS (1) + +/* * Allocate and map kernel buffer using consistent mode DMA for a device. * hwdev should be valid struct pci_dev pointer for PCI devices, * NULL for PCI-like buses (ISA, EISA). @@ -77,6 +84,32 @@ extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); + +#ifdef CONFIG_MAPPED_PCI_IO + +extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, + int direction); +extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, + size_t size, int direction); +extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, + int direction); +extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents, int direction); +extern void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, + size_t size, int direction); +extern void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nelems, int direction); + +/* pci_unmap_{single,page} is not a nop, thus... */ +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME; +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME; +#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME) +#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL)) +#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) +#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) + +#else /* CONFIG_MAPPED_PCI_IO */ + /* * Map a single buffer of the indicated size for DMA in streaming mode. * The 32-bit bus address to use is returned. @@ -84,17 +117,17 @@ extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, * Once the device is given the dma address, the device owns this memory * until either pci_unmap_single or pci_dma_sync_single is performed. */ -extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, +static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) { + unsigned long addr = (unsigned long) ptr; + if (direction == PCI_DMA_NONE) BUG(); -#ifndef CONFIG_COHERENT_IO - dma_cache_wback_inv((unsigned long)ptr, size); -#endif + dma_cache_wback_inv(addr, size); - return virt_to_bus(ptr); + return bus_to_baddr(hwdev->bus, __pa(ptr)); } /* @@ -105,13 +138,18 @@ extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, * After this call, reads by the cpu to the buffer are guaranteed to see * whatever the device wrote there. */ -extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, +static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) { if (direction == PCI_DMA_NONE) BUG(); - /* Nothing to do */ + if (direction != PCI_DMA_TODEVICE) { + unsigned long addr; + + addr = baddr_to_bus(hwdev->bus, dma_addr) + PAGE_OFFSET; + dma_cache_wback_inv(addr, size); + } } /* pci_unmap_{page,single} is a nop so... */ @@ -123,6 +161,39 @@ extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) /* + * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical + * to pci_map_single, but takes a struct page instead of a virtual address + */ +static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, + unsigned long offset, size_t size, + int direction) +{ + unsigned long addr; + + if (direction == PCI_DMA_NONE) + BUG(); + + addr = (unsigned long) page_address(page) + offset; + dma_cache_wback_inv(addr, size); + + return bus_to_baddr(hwdev->bus, page_to_phys(page) + offset); +} + +static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address, + size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + + if (direction != PCI_DMA_TODEVICE) { + unsigned long addr; + + addr = baddr_to_bus(hwdev->bus, dma_address) + PAGE_OFFSET; + dma_cache_wback_inv(addr, size); + } +} + +/* * Map a set of buffers described by scatterlist in streaming * mode for DMA. This is the scather-gather version of the * above pci_map_single interface. Here the scatter gather list @@ -138,21 +209,23 @@ extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, * Device ownership issues as mentioned above for pci_map_single are * the same here. */ -extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, +static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { -#ifndef CONFIG_COHERENT_IO int i; -#endif if (direction == PCI_DMA_NONE) BUG(); -#ifndef CONFIG_COHERENT_IO - /* Make sure that gcc doesn't leave the empty loop body. */ - for (i = 0; i < nents; i++, sg++) - dma_cache_wback_inv((unsigned long)sg->address, sg->length); -#endif + for (i = 0; i < nents; i++, sg++) { + unsigned long addr; + + addr = (unsigned long) page_address(sg->page); + if (addr) + dma_cache_wback_inv(addr + sg->offset, sg->length); + sg->dma_address = (dma_addr_t) bus_to_baddr(hwdev->bus, + page_to_phys(sg->page) + sg->offset); + } return nents; } @@ -162,13 +235,27 @@ extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, * Again, cpu read rules concerning calls here are the same as for * pci_unmap_single() above. */ -extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, +static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { + int i; + if (direction == PCI_DMA_NONE) BUG(); - /* Nothing to do */ + if (direction == PCI_DMA_TODEVICE) + return; + + for (i = 0; i < nents; i++, sg++) { + unsigned long addr; + + if (!sg->page) + BUG(); + + addr = (unsigned long) page_address(sg->page); + if (addr) + dma_cache_wback_inv(addr + sg->offset, sg->length); + } } /* @@ -181,16 +268,17 @@ extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, * next point you give the PCI dma address back to the card, the * device again owns the buffer. */ -extern inline void pci_dma_sync_single(struct pci_dev *hwdev, +static inline void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) { + unsigned long addr; + if (direction == PCI_DMA_NONE) BUG(); -#ifndef CONFIG_COHERENT_IO - dma_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), size); -#endif + addr = baddr_to_bus(hwdev->bus, dma_handle) + PAGE_OFFSET; + dma_cache_wback_inv(addr, size); } /* @@ -200,11 +288,11 @@ extern inline void pci_dma_sync_single(struct pci_dev *hwdev, * The same as pci_dma_sync_single but for a scatter-gather list, * same rules and usage. */ -extern inline void pci_dma_sync_sg(struct pci_dev *hwdev, +static inline void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) { -#ifndef CONFIG_COHERENT_IO +#ifdef CONFIG_NONCOHERENT_IO int i; #endif @@ -212,30 +300,71 @@ extern inline void pci_dma_sync_sg(struct pci_dev *hwdev, BUG(); /* Make sure that gcc doesn't leave the empty loop body. */ -#ifndef CONFIG_COHERENT_IO +#ifdef CONFIG_NONCOHERENT_IO for (i = 0; i < nelems; i++, sg++) - dma_cache_wback_inv((unsigned long)sg->address, sg->length); + dma_cache_wback_inv((unsigned long)page_address(sg->page), + sg->length); #endif } +#endif /* CONFIG_MAPPED_PCI_IO */ -/* Return whether the given PCI device DMA address mask can +/* + * Return whether the given PCI device DMA address mask can * be supported properly. For example, if your device can * only drive the low 24-bits during PCI bus mastering, then * you would pass 0x00ffffff as the mask to this function. */ -extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) +static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) { /* * we fall back to GFP_DMA when the mask isn't all 1s, * so we can't guarantee allocations that must be * within a tighter range than GFP_DMA.. */ - if (mask < 0x1fffffff) +#ifdef CONFIG_ISA + if (mask < 0x00ffffff) return 0; +#endif return 1; } +/* This is always fine. */ +#define pci_dac_dma_supported(pci_dev, mask) (1) + +static inline dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev, + struct page *page, unsigned long offset, int direction) +{ + dma64_addr_t addr = page_to_phys(page) + offset; + + return (dma64_addr_t) bus_to_baddr(pdev->bus, addr); +} + +static inline struct page *pci_dac_dma_to_page(struct pci_dev *pdev, + dma64_addr_t dma_addr) +{ + unsigned long poff = baddr_to_bus(pdev->bus, dma_addr) >> PAGE_SHIFT; + + return mem_map + poff; +} + +static inline unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev, + dma64_addr_t dma_addr) +{ + return dma_addr & ~PAGE_MASK; +} + +static inline void pci_dac_dma_sync_single(struct pci_dev *pdev, + dma64_addr_t dma_addr, size_t len, int direction) +{ + unsigned long addr; + + if (direction == PCI_DMA_NONE) + BUG(); + + addr = baddr_to_bus(pdev->bus, dma_addr) + PAGE_OFFSET; + dma_cache_wback_inv(addr, len); +} /* * These macros should be used after a pci_map_sg call has been done @@ -244,7 +373,7 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) * returns, or alternatively stop on the first sg_dma_len(sg) which * is 0. */ -#define sg_dma_address(sg) (virt_to_bus((sg)->address)) +#define sg_dma_address(sg) ((sg)->dma_address) #define sg_dma_len(sg) ((sg)->length) #endif /* __KERNEL__ */ diff --git a/include/asm-mips/pci_channel.h b/include/asm-mips/pci_channel.h index 2e64ec5bf8f8..ce1ecaf2625b 100644 --- a/include/asm-mips/pci_channel.h +++ b/include/asm-mips/pci_channel.h @@ -23,7 +23,7 @@ struct pci_channel { int last_devfn; }; -/* +/* * each board defines an array of pci_channels, that ends with all NULL entry */ extern struct pci_channel mips_pci_channels[]; @@ -33,7 +33,7 @@ extern struct pci_channel mips_pci_channels[]; */ extern void pcibios_fixup_irqs(void); -/* +/* * board supplied pci fixup routines */ extern void pcibios_fixup_resources(struct pci_dev *dev); diff --git a/include/asm-mips/percpu.h b/include/asm-mips/percpu.h new file mode 100644 index 000000000000..844e763e9332 --- /dev/null +++ b/include/asm-mips/percpu.h @@ -0,0 +1,6 @@ +#ifndef __ASM_PERCPU_H +#define __ASM_PERCPU_H + +#include <asm-generic/percpu.h> + +#endif /* __ASM_PERCPU_H */ diff --git a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h index f71b90b1c8e1..447a294d3e6e 100644 --- a/include/asm-mips/pgalloc.h +++ b/include/asm-mips/pgalloc.h @@ -11,46 +11,32 @@ #include <linux/config.h> #include <linux/mm.h> +#include <linux/highmem.h> +#include <asm/fixmap.h> -/* TLB flushing: - * - * - flush_tlb_all() flushes all processes TLB entries - * - flush_tlb_mm(mm) flushes the specified mm context TLB entries - * - flush_tlb_page(vma, vmaddr) flushes a single page - * - flush_tlb_range(vma, start, end) flushes a range of pages - */ -extern void flush_tlb_all(void); -extern void flush_tlb_mm(struct mm_struct *mm); -extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end); -extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); - -extern inline void flush_tlb_pgtables(struct mm_struct *mm, - unsigned long start, unsigned long end) +static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, + pte_t *pte) { - /* Nothing to do on MIPS. */ + set_pmd(pmd, __pmd(__pa(pte))); } +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, + struct page *pte) +{ + set_pmd(pmd, __pmd(((unsigned long long)page_to_pfn(pte) << + (unsigned long long) PAGE_SHIFT))); +} -/* - * Allocate and free page tables. - */ - -#define pgd_quicklist (current_cpu_data.pgd_quick) -#define pmd_quicklist ((unsigned long *)0) -#define pte_quicklist (current_cpu_data.pte_quick) -#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz) - -#define pmd_populate(mm, pmd, pte) pmd_set(pmd, pte) +#define pgd_populate(mm, pmd, pte) BUG() /* * Initialize new page directory with pointers to invalid ptes */ extern void pgd_init(unsigned long page); -extern __inline__ pgd_t *get_pgd_slow(void) +static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL), *init; + pgd_t *ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGD_ORDER), *init; if (ret) { init = pgd_offset(&init_mm, 0); @@ -61,120 +47,59 @@ extern __inline__ pgd_t *get_pgd_slow(void) return ret; } -extern __inline__ pgd_t *get_pgd_fast(void) -{ - unsigned long *ret; - - if((ret = pgd_quicklist) != NULL) { - pgd_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } else - ret = (unsigned long *)get_pgd_slow(); - return (pgd_t *)ret; -} - -extern __inline__ void free_pgd_fast(pgd_t *pgd) -{ - *(unsigned long *)pgd = (unsigned long) pgd_quicklist; - pgd_quicklist = (unsigned long *) pgd; - pgtable_cache_size++; -} - -extern __inline__ void free_pgd_slow(pgd_t *pgd) -{ - free_page((unsigned long)pgd); -} - -extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted); - -extern __inline__ pte_t *get_pte_fast(void) -{ - unsigned long *ret; - - if((ret = (unsigned long *)pte_quicklist) != NULL) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } - return (pte_t *)ret; -} - -extern __inline__ void free_pte_fast(pte_t *pte) -{ - *(unsigned long *)pte = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pte; - pgtable_cache_size++; -} - -extern __inline__ void free_pte_slow(pte_t *pte) -{ - free_page((unsigned long)pte); -} - -/* We don't use pmd cache, so these are dummy routines */ -extern __inline__ pmd_t *get_pmd_fast(void) -{ - return (pmd_t *)0; -} - -extern __inline__ void free_pmd_fast(pmd_t *pmd) +static inline void pgd_free(pgd_t *pgd) { + free_pages((unsigned long)pgd, PGD_ORDER); } -extern __inline__ void free_pmd_slow(pmd_t *pmd) -{ -} - -extern void __bad_pte(pmd_t *pmd); - -static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, + unsigned long address) { pte_t *pte; pte = (pte_t *) __get_free_page(GFP_KERNEL|__GFP_REPEAT); if (pte) clear_page(pte); + return pte; } -static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address) +static inline struct page *pte_alloc_one(struct mm_struct *mm, + unsigned long address) { - unsigned long *ret; + struct page *pte; - if ((ret = (unsigned long *)pte_quicklist) != NULL) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } - return (pte_t *)ret; +#if CONFIG_HIGHPTE + pte = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT, 0); +#else + pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, 0); +#endif + if (pte) + clear_highpage(pte); + + return pte; } -extern __inline__ void pte_free_fast(pte_t *pte) +static inline void pte_free_kernel(pte_t *pte) { - *(unsigned long *)pte = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pte; - pgtable_cache_size++; + free_page((unsigned long)pte); } -extern __inline__ void pte_free_slow(pte_t *pte) +static inline void pte_free(struct page *pte) { - free_page((unsigned long)pte); + __free_page(pte); } -#define pte_free(pte) pte_free_slow(pte) -#define pgd_free(pgd) free_pgd_fast(pgd) -#define pgd_alloc(mm) get_pgd_fast() +#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) /* * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. */ -#define pmd_alloc_one_fast(mm, addr) ({ BUG(); ((pmd_t *)1); }) #define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(x) do { } while (0) -#define pgd_populate(mm, pmd, pte) BUG() +#define __pmd_free_tlb(tlb,x) do { } while (0) -extern int do_check_pgt_cache(int, int); +#define check_pgt_cache() do { } while (0) #endif /* _ASM_PGALLOC_H */ diff --git a/include/asm-mips/pgtable-bits.h b/include/asm-mips/pgtable-bits.h new file mode 100644 index 000000000000..fd79206b2fae --- /dev/null +++ b/include/asm-mips/pgtable-bits.h @@ -0,0 +1,102 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994 - 2002 by Ralf Baechle + * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc. + * Copyright (C) 2002 Maciej W. Rozycki + */ +#ifndef _ASM_PGTABLE_BITS_H +#define _ASM_PGTABLE_BITS_H + +#include <linux/config.h> + +/* + * Note that we shift the lower 32bits of each EntryLo[01] entry + * 6 bits to the left. That way we can convert the PFN into the + * physical address by a single 'and' operation and gain 6 additional + * bits for storing information which isn't present in a normal + * MIPS page table. + * + * Similar to the Alpha port, we need to keep track of the ref + * and mod bits in software. We have a software "yeah you can read + * from this page" bit, and a hardware one which actually lets the + * process read from the page. On the same token we have a software + * writable bit and the real hardware one which actually lets the + * process write to the page, this keeps a mod bit via the hardware + * dirty bit. + * + * Certain revisions of the R4000 and R5000 have a bug where if a + * certain sequence occurs in the last 3 instructions of an executable + * page, and the following page is not mapped, the cpu can do + * unpredictable things. The code (when it is written) to deal with + * this problem will be in the update_mmu_cache() code for the r4k. + */ +#define _PAGE_PRESENT (1<<0) /* implemented in software */ +#define _PAGE_READ (1<<1) /* implemented in software */ +#define _PAGE_WRITE (1<<2) /* implemented in software */ +#define _PAGE_ACCESSED (1<<3) /* implemented in software */ +#define _PAGE_MODIFIED (1<<4) /* implemented in software */ +#define _PAGE_FILE (1<<4) /* set:pagecache unset:swap */ + +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) + +#define _PAGE_GLOBAL (1<<8) +#define _PAGE_VALID (1<<9) +#define _PAGE_SILENT_READ (1<<9) /* synonym */ +#define _PAGE_DIRTY (1<<10) /* The MIPS dirty bit */ +#define _PAGE_SILENT_WRITE (1<<10) +#define _CACHE_UNCACHED (1<<11) +#define _CACHE_MASK (1<<11) +#define _CACHE_CACHABLE_NONCOHERENT 0 + +#else +#define _PAGE_R4KBUG (1<<5) /* workaround for r4k bug */ +#define _PAGE_GLOBAL (1<<6) +#define _PAGE_VALID (1<<7) +#define _PAGE_SILENT_READ (1<<7) /* synonym */ +#define _PAGE_DIRTY (1<<8) /* The MIPS dirty bit */ +#define _PAGE_SILENT_WRITE (1<<8) +#define _CACHE_MASK (7<<9) + +#if defined(CONFIG_CPU_SB1) + +/* No penalty for being coherent on the SB1, so just + use it for "noncoherent" spaces, too. Shouldn't hurt. */ + +#define _CACHE_UNCACHED (2<<9) +#define _CACHE_CACHABLE_COW (5<<9) +#define _CACHE_CACHABLE_NONCOHERENT (5<<9) +#define _CACHE_UNCACHED_ACCELERATED (7<<9) + +#else + +#define _CACHE_CACHABLE_NO_WA (0<<9) /* R4600 only */ +#define _CACHE_CACHABLE_WA (1<<9) /* R4600 only */ +#define _CACHE_UNCACHED (2<<9) /* R4[0246]00 */ +#define _CACHE_CACHABLE_NONCOHERENT (3<<9) /* R4[0246]00 */ +#define _CACHE_CACHABLE_CE (4<<9) /* R4[04]00MC only */ +#define _CACHE_CACHABLE_COW (5<<9) /* R4[04]00MC only */ +#define _CACHE_CACHABLE_CUW (6<<9) /* R4[04]00MC only */ +#define _CACHE_UNCACHED_ACCELERATED (7<<9) /* R10000 only */ + +#endif +#endif + +#define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED) +#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED) + +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK) + +#ifdef CONFIG_MIPS_UNCACHED +#define PAGE_CACHABLE_DEFAULT _CACHE_UNCACHED +#elif defined(CONFIG_NONCOHERENT_IO) +#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT +#else +#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW +#endif + +#define CONF_CM_DEFAULT (PAGE_CACHABLE_DEFAULT >> 9) + +#endif /* _ASM_PGTABLE_BITS_H */ diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index 0ba782b65479..6b6117f80d85 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h @@ -9,48 +9,13 @@ #ifndef _ASM_PGTABLE_H #define _ASM_PGTABLE_H +#include <linux/config.h> #include <asm/addrspace.h> #include <asm/page.h> -#ifndef _LANGUAGE_ASSEMBLY - #include <linux/linkage.h> #include <asm/cachectl.h> -#include <linux/config.h> - -/* Cache flushing: - * - * - flush_cache_all() flushes entire cache - * - flush_cache_mm(mm) flushes the specified mm context's cache lines - * - flush_cache_page(mm, vmaddr) flushes a single page - * - flush_cache_range(vma, start, end) flushes a range of pages - * - flush_icache_range(start, end) flush a range of instructions - */ -extern void (*_flush_cache_all)(void); -extern void (*___flush_cache_all)(void); -extern void (*_flush_cache_mm)(struct mm_struct *mm); -extern void (*_flush_cache_range)(struct vm_area_struct *vma, unsigned long start, - unsigned long end); -extern void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page); -extern void (*_flush_cache_sigtramp)(unsigned long addr); -extern void (*_flush_page_to_ram)(struct page * page); -extern void (*_flush_icache_range)(unsigned long start, unsigned long end); -extern void (*_flush_icache_page)(struct vm_area_struct *vma, - struct page *page); - -#define flush_cache_all() _flush_cache_all() -#define __flush_cache_all() ___flush_cache_all() -#define flush_cache_mm(mm) _flush_cache_mm(mm) -#define flush_cache_range(vma,start,end) _flush_cache_range(vma,start,end) -#define flush_cache_page(vma,page) _flush_cache_page(vma, page) -#define flush_cache_sigtramp(addr) _flush_cache_sigtramp(addr) -#define flush_dcache_page(page) _flush_page_to_ram(page) - -#define flush_icache_range(start, end) _flush_icache_range(start,end) -#define flush_icache_page(vma, page) _flush_icache_page(vma, page) -#define flush_icache_user_range(vma, page, addr, len) \ - _flush_icache_page((vma), (page)) - +#include <asm/fixmap.h> /* * - add_wired_entry() add a fixed TLB entry, and move wired register @@ -61,7 +26,7 @@ extern void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, /* * - add_temporary_entry() add a temporary TLB entry. We use TLB entries * starting at the top and working down. This is for populating the - * TLB before trap_init() puts the TLB miss handler in place. It + * TLB before trap_init() puts the TLB miss handler in place. It * should be used only for entries matching the actual page tables, * to prevent inconsistencies. */ @@ -76,114 +41,49 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, * works even with the cache aliasing problem the R4k and above have. */ -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ - /* PMD_SHIFT determines the size of the area a second-level page table can map */ +#ifdef CONFIG_64BIT_PHYS_ADDR +#define PMD_SHIFT 21 +#else #define PMD_SHIFT 22 +#endif #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 22 +#define PGDIR_SHIFT PMD_SHIFT #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -/* Entries per page directory level: we use two-level, so +/* + * Entries per page directory level: we use two-level, so * we don't really have any PMD directory physically. */ +#ifdef CONFIG_64BIT_PHYS_ADDR +#define PTRS_PER_PTE 512 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 2048 +#define PGD_ORDER 1 +#else #define PTRS_PER_PTE 1024 #define PTRS_PER_PMD 1 #define PTRS_PER_PGD 1024 -#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) +#define PGD_ORDER 0 +#endif + +#define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE) #define FIRST_USER_PGD_NR 0 #define VMALLOC_START KSEG2 #define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#define VMALLOC_END KSEG3 - -/* Note that we shift the lower 32bits of each EntryLo[01] entry - * 6 bits to the left. That way we can convert the PFN into the - * physical address by a single 'and' operation and gain 6 additional - * bits for storing information which isn't present in a normal - * MIPS page table. - * - * Similar to the Alpha port, we need to keep track of the ref - * and mod bits in software. We have a software "yeah you can read - * from this page" bit, and a hardware one which actually lets the - * process read from the page. On the same token we have a software - * writable bit and the real hardware one which actually lets the - * process write to the page, this keeps a mod bit via the hardware - * dirty bit. - * - * Certain revisions of the R4000 and R5000 have a bug where if a - * certain sequence occurs in the last 3 instructions of an executable - * page, and the following page is not mapped, the cpu can do - * unpredictable things. The code (when it is written) to deal with - * this problem will be in the update_mmu_cache() code for the r4k. - */ -#define _PAGE_PRESENT (1<<0) /* implemented in software */ -#define _PAGE_READ (1<<1) /* implemented in software */ -#define _PAGE_WRITE (1<<2) /* implemented in software */ -#define _PAGE_ACCESSED (1<<3) /* implemented in software */ -#define _PAGE_MODIFIED (1<<4) /* implemented in software */ - -#if defined(CONFIG_CPU_R3000) - -#define _PAGE_GLOBAL (1<<8) -#define _PAGE_VALID (1<<9) -#define _PAGE_SILENT_READ (1<<9) /* synonym */ -#define _PAGE_DIRTY (1<<10) /* The MIPS dirty bit */ -#define _PAGE_SILENT_WRITE (1<<10) -#define _CACHE_UNCACHED (1<<11) /* R4[0246]00 */ -#define _CACHE_MASK (1<<11) -#define _CACHE_CACHABLE_NONCOHERENT 0 +#if CONFIG_HIGHMEM +# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE) #else -#define _PAGE_R4KBUG (1<<5) /* workaround for r4k bug */ -#define _PAGE_GLOBAL (1<<6) -#define _PAGE_VALID (1<<7) -#define _PAGE_SILENT_READ (1<<7) /* synonym */ -#define _PAGE_DIRTY (1<<8) /* The MIPS dirty bit */ -#define _PAGE_SILENT_WRITE (1<<8) -#define _CACHE_MASK (7<<9) - -#if defined(CONFIG_CPU_SB1) - -/* No penalty for being coherent on the SB1, so just - use it for "noncoherent" spaces, too. Shouldn't hurt. */ - -#define _CACHE_UNCACHED (2<<9) -#define _CACHE_CACHABLE_COW (5<<9) -#define _CACHE_CACHABLE_NONCOHERENT (5<<9) - -#else - -#define _CACHE_CACHABLE_NO_WA (0<<9) /* R4600 only */ -#define _CACHE_CACHABLE_WA (1<<9) /* R4600 only */ -#define _CACHE_UNCACHED (2<<9) /* R4[0246]00 */ -#define _CACHE_CACHABLE_NONCOHERENT (3<<9) /* R4[0246]00 */ -#define _CACHE_CACHABLE_CE (4<<9) /* R4[04]00 only */ -#define _CACHE_CACHABLE_COW (5<<9) /* R4[04]00 only */ -#define _CACHE_CACHABLE_CUW (6<<9) /* R4[04]00 only */ -#define _CACHE_CACHABLE_ACCELERATED (7<<9) /* R10000 only */ - +# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) #endif -#endif - -#define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED) -#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED) -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK) - -#ifdef CONFIG_MIPS_UNCACHED -#define PAGE_CACHABLE_DEFAULT _CACHE_UNCACHED -#else -#ifdef CONFIG_CPU_SB1 -#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW -#else -#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT -#endif -#endif +#include <asm/pgtable-bits.h> #define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT) #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ @@ -193,11 +93,11 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_READ | \ PAGE_CACHABLE_DEFAULT) #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ - PAGE_CACHABLE_DEFAULT) + _PAGE_GLOBAL | PAGE_CACHABLE_DEFAULT) #define PAGE_USERIO __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ PAGE_CACHABLE_DEFAULT) -#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ - _CACHE_UNCACHED) +#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \ + __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED) /* * MIPS can't do page protection for execute, and considers that the same like @@ -222,14 +122,22 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, #define __S110 PAGE_SHARED #define __S111 PAGE_SHARED -#if !defined (_LANGUAGE_ASSEMBLY) - +#ifdef CONFIG_64BIT_PHYS_ADDR +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e)) +#else #define pte_ERROR(e) \ - printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e)) + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#endif #define pmd_ERROR(e) \ - printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e)) + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) #define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e)) + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + +/* + * ZERO_PAGE is a global shared page that is always zero; used + * for zero-mapped memory areas etc.. + */ extern unsigned long empty_zero_page; extern unsigned long zero_page_mask; @@ -237,21 +145,6 @@ extern unsigned long zero_page_mask; #define ZERO_PAGE(vaddr) \ (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask))) -/* number of bits that fit into a memory pointer */ -#define BITS_PER_PTR (8*sizeof(unsigned long)) - -/* to align the pointer to a pointer address */ -#define PTR_MASK (~(sizeof(void*)-1)) - -/* - * sizeof(void*) == (1 << SIZEOF_PTR_LOG2) - */ -#define SIZEOF_PTR_LOG2 2 - -/* 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 void load_pgd(unsigned long pg_dir); extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)]; @@ -260,60 +153,68 @@ extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_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 unsigned long pmd_page(pmd_t pmd) -{ - return pmd_val(pmd); -} +#define page_pte(page) page_pte_prot(page, __pgprot(0)) +#define pmd_phys(pmd) (pmd_val(pmd) - PAGE_OFFSET) +#define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT)) +#define pmd_page_kernel(pmd) pmd_val(pmd) -extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) -{ - pmd_val(*pmdp) = (((unsigned long) ptep) & PAGE_MASK); -} - -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_PRESENT; } +#define pte_none(pte) (!(pte_val(pte) & ~_PAGE_GLOBAL)) +#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) /* Certain architectures need to do special things when pte's * within a page table are directly modified. Thus, the following * hook is made available. */ -extern inline void set_pte(pte_t *ptep, pte_t pteval) +static inline void set_pte(pte_t *ptep, pte_t pteval) { *ptep = pteval; +#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) + if (pte_val(pteval) & _PAGE_GLOBAL) { + pte_t *buddy = ptep_buddy(ptep); + /* + * Make sure the buddy is global too (if it's !none, + * it better already be global) + */ + if (pte_none(*buddy)) + pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL; + } +#endif } -extern inline void pte_clear(pte_t *ptep) +static inline void pte_clear(pte_t *ptep) { - set_pte(ptep, __pte(0)); +#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) + /* Preserve global status for the pair */ + if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL) + set_pte(ptep, __pte(_PAGE_GLOBAL)); + else +#endif + set_pte(ptep, __pte(0)); } /* * (pmds are folded into pgds so this doesn't get actually called, * but the define is needed for a generic inline function.) */ -#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) -#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval) +#define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0) +#define set_pgd(pgdptr, pgdval) do { *(pgdptr) = (pgdval); } while(0) /* * Empty pgd/pmd entries point to the invalid_pte_table. */ -extern inline int pmd_none(pmd_t pmd) +static inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) == (unsigned long) invalid_pte_table; } -extern inline int pmd_bad(pmd_t pmd) -{ - return ((pmd_page(pmd) > (unsigned long) high_memory) || - (pmd_page(pmd) < PAGE_OFFSET)); -} +#define pmd_bad(pmd) (pmd_val(pmd) & ~PAGE_MASK) -extern inline int pmd_present(pmd_t pmd) +static inline int pmd_present(pmd_t pmd) { return (pmd_val(pmd) != (unsigned long) invalid_pte_table); } -extern inline void pmd_clear(pmd_t *pmdp) +static inline void pmd_clear(pmd_t *pmdp) { pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); } @@ -323,51 +224,79 @@ extern inline void pmd_clear(pmd_t *pmdp) * setup: the pgd is never bad, and a pmd always exists (as it's folded * into the pgd entry) */ -extern inline int pgd_none(pgd_t pgd) { return 0; } -extern inline int pgd_bad(pgd_t pgd) { return 0; } -extern inline int pgd_present(pgd_t pgd) { return 1; } -extern inline void pgd_clear(pgd_t *pgdp) { } +static inline int pgd_none(pgd_t pgd) { return 0; } +static inline int pgd_bad(pgd_t pgd) { return 0; } +static inline int pgd_present(pgd_t pgd) { return 1; } +static inline void pgd_clear(pgd_t *pgdp) { } + +#define pte_page(x) pfn_to_page(pte_pfn(x)) +#define pte_pfn(x) ((unsigned long)((x).pte >> PAGE_SHIFT)) +#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) + +#define PTE_FILE_MAX_BITS 27 + +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) + +/* + * Bits 0, 1, 2, 9 and 10 are taken, split up the 27 bits of offset + * into this range: + */ +#define pte_to_pgoff(_pte) \ + ((((_pte).pte >> 3) & 0x3f ) + (((_pte).pte >> 11) << 8 )) + +#define pgoff_to_pte(off) \ + ((pte_t) { (((off) & 0x3f) << 3) + (((off) >> 8) << 11) + _PAGE_FILE }) -#ifdef CONFIG_CPU_VR41XX -#define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> (PAGE_SHIFT + 2)))) #else -#define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT))) + +/* + * Bits 0, 1, 2, 7 and 8 are taken, split up the 27 bits of offset + * into this range: + */ +#define pte_to_pgoff(_pte) \ + ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) + +#define pgoff_to_pte(off) \ + ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) + #endif /* * 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_READ; } -extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } -extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } -extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_user(pte_t pte) { BUG(); return 0; } +static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_READ; } +static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } -extern inline pte_t pte_wrprotect(pte_t pte) +static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE); return pte; } -extern inline pte_t pte_rdprotect(pte_t pte) +static inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ); return pte; } -extern inline pte_t pte_mkclean(pte_t pte) +static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE); return pte; } -extern inline pte_t pte_mkold(pte_t pte) +static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ); return pte; } -extern inline pte_t pte_mkwrite(pte_t pte) +static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; if (pte_val(pte) & _PAGE_MODIFIED) @@ -375,7 +304,7 @@ extern inline pte_t pte_mkwrite(pte_t pte) return pte; } -extern inline pte_t pte_mkread(pte_t pte) +static inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_READ; if (pte_val(pte) & _PAGE_ACCESSED) @@ -383,7 +312,7 @@ extern inline pte_t pte_mkread(pte_t pte) return pte; } -extern inline pte_t pte_mkdirty(pte_t pte) +static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_MODIFIED; if (pte_val(pte) & _PAGE_WRITE) @@ -391,6 +320,14 @@ extern inline pte_t pte_mkdirty(pte_t pte) return pte; } +static inline pte_t pte_mkyoung(pte_t pte) +{ + pte_val(pte) |= _PAGE_ACCESSED; + if (pte_val(pte) & _PAGE_READ) + pte_val(pte) |= _PAGE_SILENT_READ; + return pte; +} + /* * Macro to make mark a page protection value as "uncacheable". Note * that "protection" is really a misnomer here as the protection value @@ -408,55 +345,20 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot) return __pgprot(prot); } -extern inline pte_t pte_mkyoung(pte_t pte) -{ - pte_val(pte) |= _PAGE_ACCESSED; - if (pte_val(pte) & _PAGE_READ) - pte_val(pte) |= _PAGE_SILENT_READ; - return pte; -} - /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -#ifdef CONFIG_CPU_VR41XX -#define mk_pte(page, pgprot) \ -({ \ - pte_t __pte; \ - \ - pte_val(__pte) = ((unsigned long)(page - mem_map) << (PAGE_SHIFT + 2)) | \ - pgprot_val(pgprot); \ - \ - __pte; \ -}) -#else -#define mk_pte(page, pgprot) \ -({ \ - pte_t __pte; \ - \ - pte_val(__pte) = ((unsigned long)(page - mem_map) << PAGE_SHIFT) | \ - pgprot_val(pgprot); \ - \ - __pte; \ -}) -#endif +#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) -extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) -{ -#ifdef CONFIG_CPU_VR41XX - return __pte((physpage << 2) | pgprot_val(pgprot)); -#else - return __pte(physpage | pgprot_val(pgprot)); -#endif -} - -extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); } -#define page_pte(page) page_pte_prot(page, __pgprot(0)) +#define __pgd_offset(address) pgd_index(address) +#define __pmd_offset(address) \ + (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) @@ -464,313 +366,86 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define pgd_index(address) ((address) >> PGDIR_SHIFT) /* to find an entry in a page-table-directory */ -extern inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address) -{ - return mm->pgd + pgd_index(address); -} +#define pgd_offset(mm,addr) ((mm)->pgd + pgd_index(addr)) /* Find an entry in the second-level page table.. */ -extern inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address) +static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address) { return (pmd_t *) dir; } -/* 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 int do_check_pgt_cache(int, int); +/* Find an entry in the third-level page table.. */ +#define __pte_offset(address) \ + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset(dir, address) \ + ((pte_t *) (pmd_page_kernel(*dir)) + __pte_offset(address)) +#define pte_offset_kernel(dir, address) \ + ((pte_t *) pmd_page_kernel(*(dir)) + __pte_offset(address)) + +#ifdef CONFIG_HIGHPTE +#define pte_offset_map(dir, address) \ + ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + __pte_offset(address)) +#define pte_offset_map_nested(dir, address) \ + ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + __pte_offset(address)) +#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) +#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1) +#else +#define pte_offset_map(dir, address) \ + ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) +#define pte_offset_map_nested(dir, address) \ + ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) +#define pte_unmap(pte) ((void)(pte)) +#define pte_unmap_nested(pte) ((void)(pte)) +#endif extern pgd_t swapper_pg_dir[1024]; extern void paging_init(void); -extern void update_mmu_cache(struct vm_area_struct *vma, - unsigned long address, pte_t pte); - -#define __swp_type(x) (((x).val >> 1) & 0x3f) -#define __swp_offset(x) ((x).val >> 8) -#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) }) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) - -#define kern_addr_valid(addr) (1) - -/* TLB operations. */ -extern inline void tlb_probe(void) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "tlbp\n\t" - ".set pop"); -} - -extern inline void tlb_read(void) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "tlbr\n\t" - ".set pop"); -} - -extern inline void tlb_write_indexed(void) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "tlbwi\n\t" - ".set pop"); -} - -extern inline void tlb_write_random(void) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "tlbwr\n\t" - ".set pop"); -} - -/* Dealing with various CP0 mmu/cache related registers. */ - -/* CP0_PAGEMASK register */ -extern inline unsigned long get_pagemask(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $5\n\t" - ".set pop" - : "=r" (val)); - return val; -} - -extern inline void set_pagemask(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $5\n\t" - ".set pop" - : : "Jr" (val)); -} - -/* CP0_ENTRYLO0 and CP0_ENTRYLO1 registers */ -extern inline unsigned long get_entrylo0(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $2\n\t" - ".set pop" - : "=r" (val)); - return val; -} - -extern inline void set_entrylo0(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $2\n\t" - ".set pop" - : : "Jr" (val)); -} - -extern inline unsigned long get_entrylo1(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $3\n\t" - ".set pop" : "=r" (val)); - - return val; -} - -extern inline void set_entrylo1(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $3\n\t" - ".set pop" - : : "Jr" (val)); -} - -/* CP0_ENTRYHI register */ -extern inline unsigned long get_entryhi(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $10\n\t" - ".set pop" - : "=r" (val)); - - return val; -} - -extern inline void set_entryhi(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $10\n\t" - ".set pop" - : : "Jr" (val)); -} - -/* CP0_INDEX register */ -extern inline unsigned long get_index(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $0\n\t" - ".set pop" - : "=r" (val)); - return val; -} - -extern inline void set_index(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $0\n\t" - ".set pop" - : : "Jr" (val)); -} - -/* CP0_WIRED register */ -extern inline unsigned long get_wired(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $6\n\t" - ".set pop" - : "=r" (val)); - return val; -} - -extern inline void set_wired(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $6\n\t" - ".set pop" - : : "Jr" (val)); -} - -extern inline unsigned long get_info(void) -{ - unsigned long val; - - __asm__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $7\n\t" - ".set pop" - : "=r" (val)); - return val; -} - -/* CP0_TAGLO and CP0_TAGHI registers */ -extern inline unsigned long get_taglo(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $28\n\t" - ".set pop" - : "=r" (val)); - return val; -} +extern void __update_tlb(struct vm_area_struct *vma, unsigned long address, + pte_t pte); +extern void __update_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte); -extern inline void set_taglo(unsigned long val) +static inline void update_mmu_cache(struct vm_area_struct *vma, + unsigned long address, pte_t pte) { - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $28\n\t" - ".set pop" - : : "Jr" (val)); + __update_tlb(vma, address, pte); + __update_cache(vma, address, pte); } -extern inline unsigned long get_taghi(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $29\n\t" - ".set pop" - : "=r" (val)); - return val; -} +/* Swap entries must have VALID and GLOBAL bits cleared. */ +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) -extern inline void set_taghi(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $29\n\t" - ".set pop" - : : "Jr" (val)); -} +#define __swp_type(x) (((x).val >> 1) & 0x7f) +#define __swp_offset(x) ((x).val >> 10) +#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 10) }) +#else -/* CP0_CONTEXT register */ -extern inline unsigned long get_context(void) -{ - unsigned long val; +#define __swp_type(x) (((x).val >> 1) & 0x1f) +#define __swp_offset(x) ((x).val >> 8) +#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) }) +#endif - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $4\n\t" - ".set pop" - : "=r" (val)); +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) - return val; -} -extern inline void set_context(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $4\n\t" - ".set pop" - : : "Jr" (val)); -} +/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ +#define kern_addr_valid(addr) (1) #include <asm-generic/pgtable.h> +#ifdef CONFIG_64BIT_PHYS_ADDR +typedef u64 pte_addr_t; +#else typedef pte_t *pte_addr_t; +#endif -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +/* + * We provide our own get_unmapped area to cope with the virtual aliasing + * constraints placed on us by the cache architecture. + */ +#define HAVE_ARCH_UNMAPPED_AREA #define io_remap_page_range remap_page_range diff --git a/include/asm-mips/pmc/ev64120.h b/include/asm-mips/pmc/ev64120.h deleted file mode 100644 index 74ad8c5105e3..000000000000 --- a/include/asm-mips/pmc/ev64120.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This is a direct copy of the ev96100.h file, with a global search and - * replace. The numbers are the same. - * - * The reason I'm duplicating this is so that the 64120/96100 - * defines won't be confusing in the source code. - */ -#ifndef _ASM_PMC_CP7000_H -#define _ASM_PMC_CP7000_H - -#include <asm/addrspace.h> - -/* - * GT64120 config space base address - */ -#define GT64120_BASE (KSEG1ADDR(0x14000000)) -#define MIPS_GT_BASE GT64120_BASE - -/* - * PCI Bus allocation - */ -#define GT_PCI_MEM_BASE 0x12000000 -#define GT_PCI_MEM_SIZE 0x02000000 -#define GT_PCI_IO_BASE 0x10000000 -#define GT_PCI_IO_SIZE 0x02000000 -#define GT_ISA_IO_BASE PCI_IO_BASE - -/* - * Duart I/O ports. - */ -#define EV64120_COM1_BASE_ADDR (0x1d000000 + 0x20) -#define EV64120_COM2_BASE_ADDR (0x1d000000 + 0x00) - - -/* - * EV64120 interrupt controller register base. - */ -#define EV64120_ICTRL_REGS_BASE (KSEG1ADDR(0x1f000000)) - -/* - * EV64120 UART register base. - */ -#define EV64120_UART0_REGS_BASE (KSEG1ADDR(EV64120_COM1_BASE_ADDR)) -#define EV64120_UART1_REGS_BASE (KSEG1ADDR(EV64120_COM2_BASE_ADDR)) -#define EV64120_BASE_BAUD ( 3686400 / 16 ) - - -/* - * Because of an error/peculiarity in the Galileo chip, we need to swap the - * bytes when running bigendian. - */ - -#define GT_WRITE(ofs, data) \ - *(volatile u32 *)(MIPS_GT_BASE+ofs) = cpu_to_le32(data) -#define GT_READ(ofs, data) \ - *data = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+ofs)) - - -#endif /* _ASM_PMC_CP7000_H */ diff --git a/include/asm-mips/pmc/ev64120int.h b/include/asm-mips/pmc/ev64120int.h deleted file mode 100644 index 463f6b39dcaf..000000000000 --- a/include/asm-mips/pmc/ev64120int.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _ASM_PMC_CP7000INT_H -#define _ASM_PMC_CP7000INT_H - -#define INT_CAUSE_MAIN 0 -#define INT_CAUSE_HIGH 1 - -#define MAX_CAUSE_REGS 4 -#define MAX_CAUSE_REG_WIDTH 32 - -void hook_irq_handler (int int_cause , int bit_num , void *isr_ptr); -int disable_galileo_irq (int int_cause , int bit_num); -int enable_galileo_irq (int int_cause , int bit_num); - -extern struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; - -/* - * PCI interrupts will come in on either the INTA or INTD interrups lines, - * which are mapped to the #2 and #5 interrupt pins of the MIPS. On our - * boards, they all either come in on IntD or they all come in on IntA, they - * aren't mixed. There can be numerous PCI interrupts, so we keep a list of the - * "requested" interrupt numbers and go through the list whenever we get an - * IntA/D. - * - * All PCI interrupts have numbers >= 20 by arbitrary convention. Any - * interrupt < 8 is an interrupt that is maskable on MIPS. - */ - -#define TIMER 4 -#define INTA 2 -#define INTD 5 - -#endif /* _ASM_PMC_CP7000INT_H */ diff --git a/include/asm-mips/poll.h b/include/asm-mips/poll.h index 12c1a5ec3889..a000f1f789e3 100644 --- a/include/asm-mips/poll.h +++ b/include/asm-mips/poll.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MIPS_POLL_H -#define __ASM_MIPS_POLL_H +#ifndef __ASM_POLL_H +#define __ASM_POLL_H #define POLLIN 0x0001 #define POLLPRI 0x0002 @@ -14,8 +14,9 @@ #define POLLWRNORM POLLOUT #define POLLWRBAND 0x0100 -/* XXX This one seems to be more-or-less nonstandard. */ +/* These seem to be more or less nonstandard ... */ #define POLLMSG 0x0400 +#define POLLREMOVE 0x1000 struct pollfd { int fd; @@ -23,4 +24,4 @@ struct pollfd { short revents; }; -#endif /* __ASM_MIPS_POLL_H */ +#endif /* __ASM_POLL_H */ diff --git a/include/asm-mips/posix_types.h b/include/asm-mips/posix_types.h index 21191a76c286..2c6ccfc714b1 100644 --- a/include/asm-mips/posix_types.h +++ b/include/asm-mips/posix_types.h @@ -1,5 +1,4 @@ -/* $Id: posix_types.h,v 1.6 2000/02/04 23:32:54 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -18,7 +17,7 @@ typedef unsigned int __kernel_dev_t; typedef unsigned long __kernel_ino_t; typedef unsigned int __kernel_mode_t; -typedef int __kernel_nlink_t; +typedef unsigned long __kernel_nlink_t; typedef long __kernel_off_t; typedef int __kernel_pid_t; typedef int __kernel_ipc_pid_t; @@ -30,6 +29,8 @@ typedef int __kernel_ptrdiff_t; typedef long __kernel_time_t; typedef long __kernel_suseconds_t; typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; typedef long __kernel_daddr_t; typedef char * __kernel_caddr_t; @@ -69,7 +70,7 @@ static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp) #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; diff --git a/include/asm-mips/prctl.h b/include/asm-mips/prctl.h index 941f96feace0..4aaaff670361 100644 --- a/include/asm-mips/prctl.h +++ b/include/asm-mips/prctl.h @@ -3,7 +3,6 @@ * * The IRIX kernel maps a page at PRDA_ADDRESS with the * contents of prda and fills it the bits on prda_sys. - * $Id$ */ #ifndef __PRCTL_H__ @@ -13,14 +12,14 @@ #define PRDA ((struct prda *) PRDA_ADDRESS) struct prda_sys { - pid_t t_pid; + pid_t t_pid; u32 t_hint; u32 t_dlactseq; u32 t_fpflags; u32 t_prid; /* processor type, $prid CP0 register */ u32 t_dlendseq; u64 t_unused1[5]; - pid_t t_rpid; + pid_t t_rpid; s32 t_resched; u32 t_unused[8]; u32 t_cpu; /* current/last cpu */ diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 5b06f8081a62..d7ac86362d79 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -4,7 +4,7 @@ * for more details. * * Copyright (C) 1994 Waldorf GMBH - * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001 Ralf Baechle + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle * Copyright (C) 1996 Paul M. Antoine * Copyright (C) 1999 Silicon Graphics, Inc. */ @@ -12,8 +12,9 @@ #define _ASM_PROCESSOR_H #include <linux/config.h> - +#include <linux/threads.h> #include <asm/isadep.h> +#include <asm/page.h> /* * Default implementation of macro that returns current @@ -21,59 +22,102 @@ */ #define current_text_addr() ({ __label__ _l; _l: &&_l;}) -#if !defined (_LANGUAGE_ASSEMBLY) +#ifndef __ASSEMBLY__ +#include <linux/cache.h> #include <linux/threads.h> + #include <asm/cachectl.h> #include <asm/mipsregs.h> #include <asm/reg.h> #include <asm/system.h> -struct mips_cpuinfo { - unsigned long udelay_val; - unsigned long *pgd_quick; - unsigned long *pte_quick; - unsigned long pgtable_cache_sz; +/* + * Descriptor for a cache + */ +struct cache_desc { + unsigned short linesz; + unsigned short ways; + unsigned int sets; + unsigned int waybit; /* Bits to select in a cache set */ + unsigned int flags; /* Flags describingcache properties */ }; /* - * System setup and hardware flags.. - * XXX: Should go into mips_cpuinfo. + * Flag definitions */ -extern void (*cpu_wait)(void); /* only available on R4[26]00 and R3081 */ -extern void r3081_wait(void); -extern void r4k_wait(void); -extern char cyclecounter_available; /* only available from R4000 upwards. */ +#define MIPS_CACHE_NOT_PRESENT 0x00000001 +#define MIPS_CACHE_VTAG 0x00000002 /* Virtually tagged cache */ +#define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */ +#define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */ -extern struct mips_cpuinfo boot_cpu_data; -extern unsigned int vced_count, vcei_count; +struct cpuinfo_mips { + unsigned long udelay_val; + unsigned long asid_cache; + + /* + * Capability and feature descriptor structure for MIPS CPU + */ + unsigned long options; + unsigned int processor_id; + unsigned int fpu_id; + unsigned int cputype; + int isa_level; + int tlbsize; + struct cache_desc icache; /* Primary I-cache */ + struct cache_desc dcache; /* Primary D or combined I/D cache */ + struct cache_desc scache; /* Secondary cache */ + struct cache_desc tcache; /* Tertiary/split secondary cache */ +} __attribute__((__aligned__(SMP_CACHE_BYTES))); -#ifdef CONFIG_SMP -extern struct mips_cpuinfo cpu_data[]; +/* + * Assumption: Options of CPU 0 are a superset of all processors. + * This is true for all known MIPS systems. + */ +#define cpu_has_tlb (cpu_data[0].options & MIPS_CPU_TLB) +#define cpu_has_4kex (cpu_data[0].options & MIPS_CPU_4KEX) +#define cpu_has_4ktlb (cpu_data[0].options & MIPS_CPU_4KTLB) +#define cpu_has_fpu (cpu_data[0].options & MIPS_CPU_FPU) +#define cpu_has_32fpr (cpu_data[0].options & MIPS_CPU_32FPR) +#define cpu_has_counter (cpu_data[0].options & MIPS_CPU_COUNTER) +#define cpu_has_watch (cpu_data[0].options & MIPS_CPU_WATCH) +#define cpu_has_mips16 (cpu_data[0].options & MIPS_CPU_MIPS16) +#define cpu_has_divec (cpu_data[0].options & MIPS_CPU_DIVEC) +#define cpu_has_vce (cpu_data[0].options & MIPS_CPU_VCE) +#define cpu_has_cache_cdex (cpu_data[0].options & MIPS_CPU_CACHE_CDEX) +#define cpu_has_mcheck (cpu_data[0].options & MIPS_CPU_MCHECK) +#define cpu_has_ejtag (cpu_data[0].options & MIPS_CPU_EJTAG) +#define cpu_has_nofpuex (cpu_data[0].options & MIPS_CPU_NOFPUEX) +#define cpu_has_llsc (cpu_data[0].options & MIPS_CPU_LLSC) +#define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG) +#define cpu_has_dc_aliases (cpu_data[0].dcache.flags & MIPS_CACHE_ALIASES) +#define cpu_has_ic_fills_f_dc (cpu_data[0].dcache.flags & MIPS_CACHE_IC_F_DC) +#define cpu_has_64bits (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT) +#define cpu_has_subset_pcaches (cpu_data[0].options & MIPS_CPU_SUBSET_CACHES) + +extern struct cpuinfo_mips cpu_data[]; #define current_cpu_data cpu_data[smp_processor_id()] -#else -#define cpu_data &boot_cpu_data -#define current_cpu_data boot_cpu_data -#endif + +extern void cpu_probe(void); +extern void cpu_report(void); /* - * Bus types (default is ISA, but people can check others with these..) - * MCA_bus hardcoded to 0 for now. - * - * This needs to be extended since MIPS systems are being delivered with - * numerous different types of bus systems. + * System setup and hardware flags.. */ -extern int EISA_bus; -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ +extern void (*cpu_wait)(void); + +extern unsigned int vced_count, vcei_count; /* - * MIPS has no problems with write protection + * Bus types (default is ISA, but people can check others with these..) */ -#define wp_works_ok 1 -#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ +#ifdef CONFIG_EISA +extern int EISA_bus; +#else +#define EISA_bus (0) +#endif -/* Lazy FPU handling on uni-processor */ -extern struct task_struct *last_task_used_math; +#define MCA_bus 0 +#define MCA_bus__is_a_macro /* for versions in ksyms.c */ /* * User space process size: 2GB. This is hardcoded into a few places, @@ -86,7 +130,7 @@ extern struct task_struct *last_task_used_math; /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) +#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) /* * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. @@ -148,27 +192,11 @@ struct thread_struct { #define MF_FIXADE 1 /* Fix address errors in software */ #define MF_LOGADE 2 /* Log address errors to syslog */ unsigned long mflags; - mm_segment_t current_ds; unsigned long irix_trampoline; /* Wheee... */ unsigned long irix_oldctx; - - /* - * These are really only needed if the full FPU emulator is configured. - * Would be made conditional on MIPS_FPU_EMULATOR if it weren't for the - * fact that having offset.h rebuilt differently for different config - * options would be asking for trouble. - * - * Saved EPC during delay-slot emulation (see math-emu/cp1emu.c) - */ - unsigned long dsemul_epc; - - /* - * Pointer to instruction used to induce address error - */ - unsigned long dsemul_aerpc; }; -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +#endif /* !__ASSEMBLY__ */ #define INIT_THREAD { \ /* \ @@ -191,19 +219,14 @@ struct thread_struct { /* \ * For now the default is to fix address errors \ */ \ - MF_FIXADE, { 0 }, 0, 0, \ - /* \ - * dsemul_epc and dsemul_aerpc should never be used uninitialized, \ - * but... \ - */ \ - 0 ,0 \ + MF_FIXADE, 0, 0 \ } #ifdef __KERNEL__ #define KERNEL_STACK_SIZE 8192 -#if !defined (_LANGUAGE_ASSEMBLY) +#ifndef __ASSEMBLY__ /* Free all resources held by a thread. */ #define release_thread(thread) do { } while(0) @@ -213,54 +236,25 @@ struct thread_struct { extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); -/* - * Return saved PC of a blocked thread. - */ -extern inline unsigned long thread_saved_pc(struct thread_struct *t) -{ - extern void ret_from_fork(void); - - /* New born processes are a special case */ - if (t->reg31 == (unsigned long) ret_from_fork) - return t->reg31; - - return ((unsigned long *)t->reg29)[10]; -} +extern unsigned long thread_saved_pc(struct thread_struct *t); /* * Do necessary setup to start up a newly executed thread. */ -#define start_thread(regs, new_pc, new_sp) do { \ - /* New thread loses kernel privileges. */ \ - regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU)) | KU_USER;\ - regs->cp0_epc = new_pc; \ - regs->regs[29] = new_sp; \ - current->thread.current_ds = USER_DS; \ -} while (0) +extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp); +struct task_struct; unsigned long get_wchan(struct task_struct *p); #define __PT_REG(reg) ((long)&((struct pt_regs *)0)->reg - sizeof(struct pt_regs)) -#define __KSTK_TOS(tsk) ((unsigned long)(tsk) + KERNEL_STACK_SIZE - 32) +#define __KSTK_TOS(tsk) ((unsigned long)(tsk->thread_info) + KERNEL_STACK_SIZE - 32) #define KSTK_EIP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(cp0_epc))) #define KSTK_ESP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(regs[29]))) - -/* Allocation and freeing of basic task resources. */ -/* - * NOTE! The task struct and the stack go together - */ -#define THREAD_SIZE (2*PAGE_SIZE) -#define alloc_task_struct() \ - ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) -#define free_task_struct(p) free_pages((unsigned long)(p),1) -#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count) - -#define init_task (init_task_union.task) -#define init_stack (init_task_union.stack) +#define KSTK_STATUS(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(cp0_status))) #define cpu_relax() barrier() -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +#endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ /* diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h index c52592cbbbe0..8e185b9fcd5b 100644 --- a/include/asm-mips/ptrace.h +++ b/include/asm-mips/ptrace.h @@ -12,7 +12,6 @@ #define _ASM_PTRACE_H #include <asm/isadep.h> -#include <linux/types.h> /* 0 - 31 are integer registers, 32 - 63 are fp registers. */ #define FPR_BASE 32 @@ -24,7 +23,7 @@ #define FPC_CSR 69 #define FPC_EIR 70 -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ /* * This struct defines the way the registers are stored on the stack during a * system call/exception. As usual the registers k0/k1 aren't being saved. @@ -49,7 +48,34 @@ struct pt_regs { unsigned long cp0_cause; }; -#endif /* !(_LANGUAGE_ASSEMBLY) */ +#define __str2(x) #x +#define __str(x) __str2(x) + +#define save_static_function(symbol) \ +__asm__ ( \ + ".text\n\t" \ + ".globl\t" #symbol "\n\t" \ + ".align\t2\n\t" \ + ".type\t" #symbol ", @function\n\t" \ + ".ent\t" #symbol ", 0\n" \ + #symbol":\n\t" \ + ".frame\t$29, 0, $31\n\t" \ + "sw\t$16,"__str(PT_R16)"($29)\t\t\t# save_static_function\n\t" \ + "sw\t$17,"__str(PT_R17)"($29)\n\t" \ + "sw\t$18,"__str(PT_R18)"($29)\n\t" \ + "sw\t$19,"__str(PT_R19)"($29)\n\t" \ + "sw\t$20,"__str(PT_R20)"($29)\n\t" \ + "sw\t$21,"__str(PT_R21)"($29)\n\t" \ + "sw\t$22,"__str(PT_R22)"($29)\n\t" \ + "sw\t$23,"__str(PT_R23)"($29)\n\t" \ + "sw\t$30,"__str(PT_R30)"($29)\n\t" \ + ".end\t" #symbol "\n\t" \ + ".size\t" #symbol",. - " #symbol) + +/* Used in declaration of save_static functions. */ +#define static_unused static __attribute__((unused)) + +#endif /* !__ASSEMBLY__ */ /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ /* #define PTRACE_GETREGS 12 */ @@ -61,13 +87,16 @@ struct pt_regs { #define PTRACE_OLDSETOPTIONS 21 -#ifdef _LANGUAGE_ASSEMBLY +#define PTRACE_GET_THREAD_AREA 25 +#define PTRACE_SET_THREAD_AREA 26 + +#ifdef __ASSEMBLY__ #include <asm/offset.h> #endif #ifdef __KERNEL__ -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ /* * Does the process account for user or for system time? */ @@ -76,7 +105,7 @@ struct pt_regs { #define instruction_pointer(regs) ((regs)->cp0_epc) extern void show_regs(struct pt_regs *); -#endif /* !(_LANGUAGE_ASSEMBLY) */ +#endif /* !__ASSEMBLY__ */ #endif diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h index 561be48b836b..b3814e2c262a 100644 --- a/include/asm-mips/r4kcache.h +++ b/include/asm-mips/r4kcache.h @@ -1,155 +1,114 @@ /* - * r4kcache.h: Inline assembly cache operations. + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: r4kcache.h,v 1.7 1997/12/18 13:00:45 ralf Exp $ + * Inline assembly cache operations. * - * FIXME: Handle split L2 caches. + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997 - 2002 Ralf Baechle (ralf@gnu.org) */ -#ifndef _MIPS_R4KCACHE_H -#define _MIPS_R4KCACHE_H +#ifndef __ASM_R4KCACHE_H +#define __ASM_R4KCACHE_H #include <asm/asm.h> #include <asm/cacheops.h> -extern inline void flush_icache_line_indexed(unsigned long addr) +#define cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " cache %0, %1 \n" \ + " .set mips0 \n" \ + " .set reorder" \ + : \ + : "i" (op), "m" (*(unsigned char *)(addr))) + +static inline void flush_icache_line_indexed(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Invalidate_I)); + cache_op(Index_Invalidate_I, addr); } -extern inline void flush_dcache_line_indexed(unsigned long addr) +static inline void flush_dcache_line_indexed(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Writeback_Inv_D)); + cache_op(Index_Writeback_Inv_D, addr); } -extern inline void flush_scache_line_indexed(unsigned long addr) +static inline void flush_scache_line_indexed(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Writeback_Inv_SD)); + cache_op(Index_Writeback_Inv_SD, addr); } -extern inline void flush_icache_line(unsigned long addr) +static inline void flush_icache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); + cache_op(Hit_Invalidate_I, addr); } -extern inline void flush_dcache_line(unsigned long addr) +static inline void flush_dcache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Writeback_Inv_D)); + cache_op(Hit_Writeback_Inv_D, addr); } -extern inline void invalidate_dcache_line(unsigned long addr) +static inline void invalidate_dcache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_D)); + cache_op(Hit_Invalidate_D, addr); } -extern inline void invalidate_scache_line(unsigned long addr) +static inline void invalidate_scache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_SD)); + cache_op(Hit_Invalidate_SD, addr); } -extern inline void flush_scache_line(unsigned long addr) +static inline void flush_scache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Writeback_Inv_SD)); + cache_op(Hit_Writeback_Inv_SD, addr); } /* * The next two are for badland addresses like signal trampolines. */ -extern inline void protected_flush_icache_line(unsigned long addr) +static inline void protected_flush_icache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n" - "1:\tcache %1,(%0)\n" + "1:\tcache %0,(%1)\n" "2:\t.set mips0\n\t" ".set reorder\n\t" ".section\t__ex_table,\"a\"\n\t" STR(PTR)"\t1b,2b\n\t" ".previous" : - : "r" (addr), - "i" (Hit_Invalidate_I)); + : "i" (Hit_Invalidate_I), "r" (addr)); } -extern inline void protected_writeback_dcache_line(unsigned long addr) +/* + * R10000 / R12000 hazard - these processors don't support the Hit_Writeback_D + * cacheop so we use Hit_Writeback_Inv_D which is supported by all R4000-style + * caches. We're talking about one cacheline unnecessarily getting invalidated + * here so the penaltiy isn't overly hard. + */ +static inline void protected_writeback_dcache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n" - "1:\tcache %1,(%0)\n" + "1:\tcache %0,(%1)\n" "2:\t.set mips0\n\t" ".set reorder\n\t" ".section\t__ex_table,\"a\"\n\t" STR(PTR)"\t1b,2b\n\t" ".previous" : - : "r" (addr), - "i" (Hit_Writeback_D)); + : "i" (Hit_Writeback_Inv_D), "r" (addr)); +} + +/* + * This one is RM7000-specific + */ +static inline void invalidate_tcache_page(unsigned long addr) +{ + cache_op(Page_Invalidate_T, addr); } #define cache16_unroll32(base,op) \ @@ -178,103 +137,121 @@ extern inline void protected_writeback_dcache_line(unsigned long addr) : "r" (base), \ "i" (op)); -extern inline void blast_dcache16(void) +static inline void blast_dcache16(void) { unsigned long start = KSEG0; - unsigned long end = (start + dcache_size); + unsigned long end = start + dcache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Writeback_Inv_D); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Writeback_Inv_D); } -extern inline void blast_dcache16_page(unsigned long page) +static inline void blast_dcache16_page(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; - while(start < end) { + while (start < end) { cache16_unroll32(start,Hit_Writeback_Inv_D); start += 0x200; } } -extern inline void blast_dcache16_page_indexed(unsigned long page) +static inline void blast_dcache16_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Writeback_Inv_D); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Writeback_Inv_D); } -extern inline void blast_icache16(void) +static inline void blast_icache16(void) { unsigned long start = KSEG0; - unsigned long end = (start + icache_size); + unsigned long end = start + icache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Invalidate_I); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_icache16_page(unsigned long page) +static inline void blast_icache16_page(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; - while(start < end) { + while (start < end) { cache16_unroll32(start,Hit_Invalidate_I); start += 0x200; } } -extern inline void blast_icache16_page_indexed(unsigned long page) +static inline void blast_icache16_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Invalidate_I); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_scache16(void) +static inline void blast_scache16(void) { unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; + unsigned long end = start + scache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Writeback_Inv_SD); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Writeback_Inv_SD); } -extern inline void blast_scache16_page(unsigned long page) +static inline void blast_scache16_page(unsigned long page) { unsigned long start = page; unsigned long end = page + PAGE_SIZE; - while(start < end) { + while (start < end) { cache16_unroll32(start,Hit_Writeback_Inv_SD); start += 0x200; } } -extern inline void blast_scache16_page_indexed(unsigned long page) +static inline void blast_scache16_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = page + PAGE_SIZE; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Writeback_Inv_SD); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Writeback_Inv_SD); } #define cache32_unroll32(base,op) \ @@ -303,121 +280,121 @@ extern inline void blast_scache16_page_indexed(unsigned long page) : "r" (base), \ "i" (op)); -extern inline void blast_dcache32(void) +static inline void blast_dcache32(void) { unsigned long start = KSEG0; - unsigned long end = (start + dcache_size); + unsigned long end = start + dcache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_D); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_D); } -/* - * Call this function only with interrupts disabled or R4600 V2.0 may blow - * up on you. - * - * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, - * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Excl_D will only - * operate correctly if the internal data cache refill buffer is empty. These - * CACHE instructions should be separated from any potential data cache miss - * by a load instruction to an uncached address to empty the response buffer." - * (Revision 2.0 device errata from IDT available on http://www.idt.com/ - * in .pdf format.) - */ -extern inline void blast_dcache32_page(unsigned long page) +static inline void blast_dcache32_page(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - /* - * Sigh ... workaround for R4600 v1.7 bug. Explanation see above. - */ - *(volatile unsigned long *)KSEG1; + unsigned long end = start + PAGE_SIZE; - __asm__ __volatile__("nop;nop;nop;nop"); - while(start < end) { + while (start < end) { cache32_unroll32(start,Hit_Writeback_Inv_D); start += 0x400; } } -extern inline void blast_dcache32_page_indexed(unsigned long page) +static inline void blast_dcache32_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_D); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_D); } -extern inline void blast_icache32(void) +static inline void blast_icache32(void) { unsigned long start = KSEG0; - unsigned long end = (start + icache_size); + unsigned long end = start + icache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Invalidate_I); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_icache32_page(unsigned long page) +static inline void blast_icache32_page(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; - while(start < end) { + while (start < end) { cache32_unroll32(start,Hit_Invalidate_I); start += 0x400; } } -extern inline void blast_icache32_page_indexed(unsigned long page) +static inline void blast_icache32_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Invalidate_I); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_scache32(void) +static inline void blast_scache32(void) { unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; + unsigned long end = start + scache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_SD); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_SD); } -extern inline void blast_scache32_page(unsigned long page) +static inline void blast_scache32_page(unsigned long page) { unsigned long start = page; unsigned long end = page + PAGE_SIZE; - while(start < end) { + while (start < end) { cache32_unroll32(start,Hit_Writeback_Inv_SD); start += 0x400; } } -extern inline void blast_scache32_page_indexed(unsigned long page) +static inline void blast_scache32_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = page + PAGE_SIZE; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_SD); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_SD); } #define cache64_unroll32(base,op) \ @@ -446,37 +423,82 @@ extern inline void blast_scache32_page_indexed(unsigned long page) : "r" (base), \ "i" (op)); -extern inline void blast_scache64(void) +static inline void blast_icache64(void) { unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; + unsigned long end = start + icache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x800) + cache64_unroll32(addr|ws,Index_Invalidate_I); +} + +static inline void blast_icache64_page(unsigned long page) +{ + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; - while(start < end) { - cache64_unroll32(start,Index_Writeback_Inv_SD); + while (start < end) { + cache64_unroll32(start,Hit_Invalidate_I); start += 0x800; } } -extern inline void blast_scache64_page(unsigned long page) +static inline void blast_icache64_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x800) + cache64_unroll32(addr|ws,Index_Invalidate_I); +} + +static inline void blast_scache64(void) +{ + unsigned long start = KSEG0; + unsigned long end = start + scache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x800) + cache64_unroll32(addr|ws,Index_Writeback_Inv_SD); +} + +static inline void blast_scache64_page(unsigned long page) { unsigned long start = page; unsigned long end = page + PAGE_SIZE; - while(start < end) { + while (start < end) { cache64_unroll32(start,Hit_Writeback_Inv_SD); start += 0x800; } } -extern inline void blast_scache64_page_indexed(unsigned long page) +static inline void blast_scache64_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = page + PAGE_SIZE; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; - while(start < end) { - cache64_unroll32(start,Index_Writeback_Inv_SD); - start += 0x800; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x800) + cache64_unroll32(addr|ws,Index_Writeback_Inv_SD); } #define cache128_unroll32(base,op) \ @@ -505,25 +527,43 @@ extern inline void blast_scache64_page_indexed(unsigned long page) : "r" (base), \ "i" (op)); -extern inline void blast_scache128(void) +static inline void blast_scache128(void) { unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; + unsigned long end = start + scache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; - while(start < end) { - cache128_unroll32(start,Index_Writeback_Inv_SD); - start += 0x1000; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x1000) + cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); } -extern inline void blast_scache128_page(unsigned long page) +static inline void blast_scache128_page(unsigned long page) { - cache128_unroll32(page,Hit_Writeback_Inv_SD); + unsigned long start = page; + unsigned long end = page + PAGE_SIZE; + + while (start < end) { + cache128_unroll32(start,Hit_Writeback_Inv_SD); + start += 0x1000; + } } -extern inline void blast_scache128_page_indexed(unsigned long page) +static inline void blast_scache128_page_indexed(unsigned long page) { - cache128_unroll32(page,Index_Writeback_Inv_SD); + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x1000) + cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); } -#endif /* !(_MIPS_R4KCACHE_H) */ +#endif /* __ASM_R4KCACHE_H */ diff --git a/include/asm-mips/reg.h b/include/asm-mips/reg.h index 35505b70f84b..36181de82a8b 100644 --- a/include/asm-mips/reg.h +++ b/include/asm-mips/reg.h @@ -59,7 +59,7 @@ #define EF_CP0_EPC 40 #define EF_CP0_BADVADDR 41 #define EF_CP0_STATUS 42 -#define EF_CP0_CAUSE 44 +#define EF_CP0_CAUSE 43 #define EF_SIZE 180 /* size in bytes */ diff --git a/include/asm-mips/riscos-syscall.h b/include/asm-mips/riscos-syscall.h index 8cb87df377bb..4d8eb15461eb 100644 --- a/include/asm-mips/riscos-syscall.h +++ b/include/asm-mips/riscos-syscall.h @@ -220,7 +220,7 @@ #define __NR_SVR4_reserved62 (__NR_SVR4 + 199) #define __NR_SVR4_reserved63 (__NR_SVR4 + 200) #define __NR_SVR4_aread (__NR_SVR4 + 201) -#define __NR_SVR4_awrite (__NR_SVR4 + 202) +#define __NR_SVR4_awrite (__NR_SVR4 + 202) #define __NR_SVR4_listio (__NR_SVR4 + 203) #define __NR_SVR4_mips_acancel (__NR_SVR4 + 204) #define __NR_SVR4_astatus (__NR_SVR4 + 205) diff --git a/include/asm-mips/rmap.h b/include/asm-mips/rmap.h index 2dc334a3b5f7..c9efd7b98749 100644 --- a/include/asm-mips/rmap.h +++ b/include/asm-mips/rmap.h @@ -1,7 +1,7 @@ -#ifndef _MIPS_RMAP_H -#define _MIPS_RMAP_H +#ifndef __ASM_RMAP_H +#define __ASM_RMAP_H /* nothing to see, move along */ #include <asm-generic/rmap.h> -#endif +#endif /* __ASM_RMAP_H */ diff --git a/include/asm-mips/rtc.h b/include/asm-mips/rtc.h new file mode 100644 index 000000000000..ffd02109a0e5 --- /dev/null +++ b/include/asm-mips/rtc.h @@ -0,0 +1,10 @@ +#ifndef _I386_RTC_H +#define _I386_RTC_H + +/* + * x86 uses the default access methods for the RTC. + */ + +#include <asm-generic/rtc.h> + +#endif diff --git a/include/asm-mips/scatterlist.h b/include/asm-mips/scatterlist.h index 861c2247f921..1693005bb6a4 100644 --- a/include/asm-mips/scatterlist.h +++ b/include/asm-mips/scatterlist.h @@ -1,21 +1,13 @@ -#ifndef __ASM_MIPS_SCATTERLIST_H -#define __ASM_MIPS_SCATTERLIST_H +#ifndef __ASM_SCATTERLIST_H +#define __ASM_SCATTERLIST_H struct scatterlist { - struct page *page; - unsigned int offset; - unsigned int length; - - __u32 dvma_address; + struct page * page; + unsigned int offset; + dma_addr_t dma_address; + unsigned int length; }; -struct mmu_sglist { - char *addr; - char *__dont_touch; - unsigned int len; - __u32 dvma_addr; -}; - -#define ISA_DMA_THRESHOLD (0x00ffffff) +#define ISA_DMA_THRESHOLD (0x00ffffffUL) -#endif /* __ASM_MIPS_SCATTERLIST_H */ +#endif /* __ASM_SCATTERLIST_H */ diff --git a/include/asm-mips/sections.h b/include/asm-mips/sections.h new file mode 100644 index 000000000000..c1da1c9437c2 --- /dev/null +++ b/include/asm-mips/sections.h @@ -0,0 +1,9 @@ +#ifndef __ASM_SECTIONS_H +#define __ASM_SECTIONS_H + +#include <asm-generic/sections.h> + +extern char _stext, _etext; +extern char _end; + +#endif /* __ASM_SECTIONS_H */ diff --git a/include/asm-mips/semaphore-helper.h b/include/asm-mips/semaphore-helper.h index 3650c32ad182..1151c37e1a16 100644 --- a/include/asm-mips/semaphore-helper.h +++ b/include/asm-mips/semaphore-helper.h @@ -3,14 +3,15 @@ * * Copyright (C) 1996 Linus Torvalds * Copyright (C) 1999 Andrea Arcangeli - * Copyright (C) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 1999, 2001, 2002 Ralf Baechle + * Copyright (C) 1999, 2001 Silicon Graphics, Inc. * Copyright (C) 2000 MIPS Technologies, Inc. */ #ifndef _ASM_SEMAPHORE_HELPER_H #define _ASM_SEMAPHORE_HELPER_H #include <linux/config.h> +#include <linux/errno.h> #define sem_read(a) ((a)->counter) #define sem_inc(a) (((a)->counter)++) @@ -25,20 +26,19 @@ static inline void wake_one_more(struct semaphore * sem) #ifdef CONFIG_CPU_HAS_LLSC -static inline int -waking_non_zero(struct semaphore *sem) +static inline int waking_non_zero(struct semaphore *sem) { int ret, tmp; __asm__ __volatile__( - "1:\tll\t%1, %2\n\t" + "1:\tll\t%1, %2\t\t\t# waking_non_zero\n\t" "blez\t%1, 2f\n\t" "subu\t%0, %1, 1\n\t" "sc\t%0, %2\n\t" - "beqz\t%0, 1b\n\t" + "beqz\t%0, 1b\n" "2:" - : "=r" (ret), "=r" (tmp), "=m" (sem->waking) - : "0"(0)); + : "=r" (ret), "=r" (tmp), "+m" (sem->waking) + : "0" (0)); return ret; } @@ -55,12 +55,12 @@ static inline int waking_non_zero(struct semaphore *sem) unsigned long flags; int ret = 0; - save_and_cli(flags); + local_irq_save(flags); if (sem_read(&sem->waking) > 0) { sem_dec(&sem->waking); ret = 1; } - restore_flags(flags); + local_irq_restore(flags); return ret; } #endif /* !CONFIG_CPU_HAS_LLSC */ @@ -74,22 +74,22 @@ static inline int waking_non_zero(struct semaphore *sem) * -EINTR interrupted * * We must undo the sem->count down_interruptible decrement - * simultaneously and atomicly with the sem->waking adjustment, + * simultaneously and atomically with the sem->waking adjustment, * otherwise we can race with wake_one_more. * - * This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words. + * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words. * - * This is crazy. Normally it stricly forbidden to use 64-bit operations + * This is crazy. Normally it's strictly forbidden to use 64-bit operations * in the 32-bit MIPS kernel. In this case it's however ok because if an * interrupt has destroyed the upper half of registers sc will fail. - * Note also that this will not work for MIPS32 CPUS! + * Note also that this will not work for MIPS32 CPUs! * * Pseudocode: * * If(sem->waking > 0) { * Decrement(sem->waking) * Return(SUCCESS) - * } else If(segnal_pending(tsk)) { + * } else If(signal_pending(tsk)) { * Increment(sem->count) * Return(-EINTR) * } else { @@ -103,7 +103,7 @@ waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk) long ret, tmp; __asm__ __volatile__( - ".set\tpush\n\t" + ".set\tpush\t\t\t# waking_non_zero_interruptible\n\t" ".set\tmips3\n\t" ".set\tnoat\n" "0:\tlld\t%1, %2\n\t" @@ -127,12 +127,11 @@ waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk) } /* - * waking_non_zero_trylock is unused. we do everything in + * waking_non_zero_trylock is unused. we do everything in * down_trylock and let non-ll/sc hosts bounce around. */ -static inline int -waking_non_zero_trylock(struct semaphore *sem) +static inline int waking_non_zero_trylock(struct semaphore *sem) { #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); @@ -149,7 +148,7 @@ static inline int waking_non_zero_interruptible(struct semaphore *sem, int ret = 0; unsigned long flags; - save_and_cli(flags); + local_irq_save(flags); if (sem_read(&sem->waking) > 0) { sem_dec(&sem->waking); ret = 1; @@ -157,7 +156,7 @@ static inline int waking_non_zero_interruptible(struct semaphore *sem, sem_inc(&sem->count); ret = -EINTR; } - restore_flags(flags); + local_irq_restore(flags); return ret; } @@ -166,14 +165,14 @@ static inline int waking_non_zero_trylock(struct semaphore *sem) int ret = 1; unsigned long flags; - save_and_cli(flags); + local_irq_save(flags); if (sem_read(&sem->waking) <= 0) sem_inc(&sem->count); else { sem_dec(&sem->waking); ret = 0; } - restore_flags(flags); + local_irq_restore(flags); return ret; } diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h index 3df320abd420..34fc00d60460 100644 --- a/include/asm-mips/semaphore.h +++ b/include/asm-mips/semaphore.h @@ -1,23 +1,21 @@ /* - * SMP- and interrupt-safe semaphores.. - * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * (C) Copyright 1996 Linus Torvalds - * (C) Copyright 1998, 99, 2000, 01 Ralf Baechle - * (C) Copyright 1999, 2000 Silicon Graphics, Inc. - * Copyright (C) 2000, 01 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 1996 Linus Torvalds + * Copyright (C) 1998, 99, 2000, 01 Ralf Baechle + * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc. + * Copyright (C) 2000, 01 MIPS Technologies, Inc. */ #ifndef _ASM_SEMAPHORE_H #define _ASM_SEMAPHORE_H +#include <linux/config.h> #include <asm/system.h> #include <asm/atomic.h> #include <linux/spinlock.h> #include <linux/wait.h> -#include <linux/config.h> #include <linux/rwsem.h> struct semaphore { @@ -94,6 +92,10 @@ static inline void down(struct semaphore * sem) __down(sem); } +/* + * Interruptible try to acquire a semaphore. If we obtained + * it, return zero. If we were interrupted, returns -EINTR + */ static inline int down_interruptible(struct semaphore * sem) { int ret = 0; @@ -108,6 +110,10 @@ static inline int down_interruptible(struct semaphore * sem) #ifndef CONFIG_CPU_HAS_LLDSCD +/* + * Non-blockingly attempt to down() a semaphore. + * Returns zero if we acquired it + */ static inline int down_trylock(struct semaphore * sem) { int ret = 0; @@ -122,8 +128,7 @@ static inline int down_trylock(struct semaphore * sem) * down_trylock returns 0 on success, 1 if we failed to get the lock. * * We must manipulate count and waking simultaneously and atomically. - * Here, we this by using ll/sc on the pair of 32-bit words. This - * won't work on MIPS32 platforms, however, and must be rewritten. + * Here, we do this by using lld/scd on the pair of 32-bit words. * * Pseudocode: * @@ -158,12 +163,12 @@ static inline int down_trylock(struct semaphore * sem) "sll\t%2, %1, 0\n\t" "blez\t%2, 1f\n\t" "daddiu\t%1, %1, -1\n\t" - "b\t2f\n\t" - "1:\tdaddu\t%1, %1, %3\n" + "b\t2f\n" + "1:\tdaddu\t%1, %1, %3\n\t" "li\t%0, 1\n" "2:\tscd\t%1, %4\n\t" "beqz\t%1, 0b\n\t" - ".set mips0" + ".set\tmips0" : "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub) : "m"(*sem) : "memory"); diff --git a/include/asm-mips/sembuf.h b/include/asm-mips/sembuf.h index 31892984e485..7281a4decaa0 100644 --- a/include/asm-mips/sembuf.h +++ b/include/asm-mips/sembuf.h @@ -1,7 +1,7 @@ #ifndef _ASM_SEMBUF_H #define _ASM_SEMBUF_H -/* +/* * The semid64_ds structure for the MIPS architecture. * Note extra padding because this structure is passed back and forth * between kernel and user space. diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h index 346b321e4cfc..66a9334c46c8 100644 --- a/include/asm-mips/serial.h +++ b/include/asm-mips/serial.h @@ -7,7 +7,6 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #include <linux/config.h> -#include <asm/bootinfo.h> #include <asm/jazz.h> /* @@ -65,9 +64,9 @@ #ifdef CONFIG_MIPS_JAZZ #define _JAZZ_SERIAL_INIT(int, base) \ - { baud_base: JAZZ_BASE_BAUD, irq: int, flags: STD_COM_FLAGS, \ - iomem_base: (u8 *) base, iomem_reg_shift: 0, \ - io_type: SERIAL_IO_MEM } + { .baud_base = JAZZ_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS, \ + .iomem_base = (u8 *) base, .iomem_reg_shift = 0, \ + .io_type = SERIAL_IO_MEM } #define JAZZ_SERIAL_PORT_DEFNS \ _JAZZ_SERIAL_INIT(JAZZ_SERIAL1_IRQ, JAZZ_SERIAL1_BASE), \ _JAZZ_SERIAL_INIT(JAZZ_SERIAL2_IRQ, JAZZ_SERIAL2_BASE), @@ -85,6 +84,26 @@ #define ATLAS_SERIAL_PORT_DEFNS #endif +#ifdef CONFIG_MIPS_SEAD +#include <asm/mips-boards/sead.h> +#include <asm/mips-boards/seadint.h> +#define SEAD_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, SEAD_BASE_BAUD, SEAD_UART0_REGS_BASE, SEADINT_UART0, STD_COM_FLAGS }, /* ttyS0 */ +#else +#define SEAD_SERIAL_PORT_DEFNS +#endif + +#ifdef CONFIG_MIPS_COBALT +#include <asm/cobalt/cobalt.h> +#define COBALT_BASE_BAUD (18432000 / 16) +#define COBALT_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, COBALT_BASE_BAUD, 0xc800000, COBALT_SERIAL_IRQ, STD_COM_FLAGS }, /* ttyS0 */ +#else +#define COBALT_SERIAL_PORT_DEFNS +#endif + /* * Both Galileo boards have the same UART mappings. */ @@ -92,12 +111,14 @@ #include <asm/galileo-boards/ev96100.h> #include <asm/galileo-boards/ev96100int.h> #define EV96100_SERIAL_PORT_DEFNS \ - { baud_base: EV96100_BASE_BAUD, port: EV96100_UART0_REGS_BASE, \ - irq: EV96100INT_UART_0, flags: STD_COM_FLAGS, type: 0x3, \ - iomem_base: EV96100_UART0_REGS_BASE }, \ - { baud_base: EV96100_BASE_BAUD, port: EV96100_UART1_REGS_BASE, \ - irq: EV96100INT_UART_0, flags: STD_COM_FLAGS, type: 0x3, \ - iomem_base: EV96100_UART1_REGS_BASE }, + { .baud_base = EV96100_BASE_BAUD, .irq = EV96100INT_UART_0, \ + .flags = STD_COM_FLAGS, \ + .iomem_base = EV96100_UART0_REGS_BASE, .iomem_reg_shift = 2, \ + .io_type = SERIAL_IO_MEM }, \ + { .baud_base = EV96100_BASE_BAUD, .irq = EV96100INT_UART_0, \ + .flags = STD_COM_FLAGS, \ + .iomem_base = EV96100_UART1_REGS_BASE, .iomem_reg_shift = 2, \ + .io_type = SERIAL_IO_MEM }, #else #define EV96100_SERIAL_PORT_DEFNS #endif @@ -107,16 +128,16 @@ #include <asm/it8172/it8172_int.h> #include <asm/it8712.h> #define ITE_SERIAL_PORT_DEFNS \ - { baud_base: BASE_BAUD, port: (IT8172_PCI_IO_BASE + IT_UART_BASE), \ - irq: IT8172_UART_IRQ, flags: STD_COM_FLAGS, type: 0x3 }, \ - { baud_base: (24000000/(16*13)), port: (IT8172_PCI_IO_BASE + IT8712_UART1_PORT), \ - irq: IT8172_SERIRQ_4, flags: STD_COM_FLAGS, type: 0x3 }, \ + { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \ + .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, \ + { .baud_base = (24000000/(16*13)), .port = (IT8172_PCI_IO_BASE + IT8712_UART1_PORT), \ + .irq = IT8172_SERIRQ_4, .flags = STD_COM_FLAGS, .type = 0x3 }, \ /* Smart Card Reader 0 */ \ - { baud_base: BASE_BAUD, port: (IT8172_PCI_IO_BASE + IT_SCR0_BASE), \ - irq: IT8172_SCR0_IRQ, flags: STD_COM_FLAGS, type: 0x3 }, \ + { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR0_BASE), \ + .irq = IT8172_SCR0_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, \ /* Smart Card Reader 1 */ \ - { baud_base: BASE_BAUD, port: (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ - irq: IT8172_SCR1_IRQ, flags: STD_COM_FLAGS, type: 0x3 }, + { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ + .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, #else #define ITE_SERIAL_PORT_DEFNS #endif @@ -125,28 +146,55 @@ #include <asm/it8172/it8172.h> #include <asm/it8172/it8172_int.h> #define IVR_SERIAL_PORT_DEFNS \ - { baud_base: BASE_BAUD, port: (IT8172_PCI_IO_BASE + IT_UART_BASE), \ - irq: IT8172_UART_IRQ, flags: STD_COM_FLAGS, type: 0x3 }, \ + { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \ + .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, \ /* Smart Card Reader 1 */ \ - { baud_base: BASE_BAUD, port: (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ - irq: IT8172_SCR1_IRQ, flags: STD_COM_FLAGS, type: 0x3 }, + { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ + .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, #else #define IVR_SERIAL_PORT_DEFNS #endif -#ifdef CONFIG_AU1000_UART +#ifdef CONFIG_LASAT +#include <asm/lasat/serial.h> +#define LASAT_SERIAL_PORT_DEFNS \ + { .baud_base = LASAT_BASE_BAUD, .irq = LASATINT_UART, \ + .flags = STD_COM_FLAGS, \ + .port = LASAT_UART_REGS_BASE, /* Only for display */ \ + .iomem_base = (u8 *)KSEG1ADDR(LASAT_UART_REGS_BASE), \ + .iomem_reg_shift = LASAT_UART_REGS_SHIFT, .io_type = SERIAL_IO_MEM }, +#else +#define LASAT_SERIAL_PORT_DEFNS +#endif + +#ifdef CONFIG_SERIAL_AU1X00 #include <asm/au1000.h> -#define AU1000_SERIAL_PORT_DEFNS \ - { baud_base: 0, port: UART0_ADDR, irq: AU1000_UART0_INT, \ - flags: STD_COM_FLAGS, type: 1 }, \ - { baud_base: 0, port: UART1_ADDR, irq: AU1000_UART1_INT, \ - flags: STD_COM_FLAGS, type: 1 }, \ - { baud_base: 0, port: UART2_ADDR, irq: AU1000_UART2_INT, \ - flags: STD_COM_FLAGS, type: 1 }, \ - { baud_base: 0, port: UART3_ADDR, irq: AU1000_UART3_INT, \ - flags: STD_COM_FLAGS, type: 1 }, +#define AU1X00_SERIAL_PORT_DEFNS \ + { .baud_base = 0, .iomem_base = (u8 *)UART0_ADDR, \ + .irq = AU1000_UART0_INT, .flags = STD_COM_FLAGS, \ + .iomem_reg_shift = 2, }, \ + { .baud_base = 0, .iomem_base = (u8 *)UART1_ADDR, \ + .irq = AU1000_UART1_INT, .flags = STD_COM_FLAGS, \ + .iomem_reg_shift = 2 }, \ + { .baud_base = 0, .iomem_base = (u8 *)UART2_ADDR, \ + .irq = AU1000_UART2_INT, .flags = STD_COM_FLAGS, \ + .iomem_reg_shift = 2}, \ + { .baud_base = 0, .iomem_base = (u8 *)UART3_ADDR, \ + .irq = AU1000_UART3_INT, .flags = STD_COM_FLAGS, \ + .iomem_reg_shift = 2}, +#else +#define AU1X00_SERIAL_PORT_DEFNS +#endif + +#ifdef CONFIG_TOSHIBA_JMR3927 +#include <asm/jmr3927/jmr3927.h> +#define TXX927_SERIAL_PORT_DEFNS \ + { .baud_base = JMR3927_BASE_BAUD, .port = UART0_ADDR, .irq = UART0_INT, \ + .flags = UART0_FLAGS, .type = 1 }, \ + { .baud_base = JMR3927_BASE_BAUD, .port = UART1_ADDR, .irq = UART1_INT, \ + .flags = UART1_FLAGS, .type = 1 }, #else -#define AU1000_SERIAL_PORT_DEFNS +#define TXX927_SERIAL_PORT_DEFNS #endif #ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT @@ -237,36 +285,85 @@ #define OCELOT_SERIAL1_BASE 0xe0001020 #define _OCELOT_SERIAL_INIT(int, base) \ - { baud_base: OCELOT_BASE_BAUD, irq: int, flags: STD_COM_FLAGS, \ - iomem_base: (u8 *) base, iomem_reg_shift: 2, \ - io_type: SERIAL_IO_MEM } + { .baud_base = OCELOT_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS, \ + .iomem_base = (u8 *) base, .iomem_reg_shift = 2, \ + .io_type = SERIAL_IO_MEM } #define MOMENCO_OCELOT_SERIAL_PORT_DEFNS \ _OCELOT_SERIAL_INIT(OCELOT_SERIAL1_IRQ, OCELOT_SERIAL1_BASE) #else #define MOMENCO_OCELOT_SERIAL_PORT_DEFNS #endif +#ifdef CONFIG_MOMENCO_OCELOT_G +/* Ordinary NS16552 duart with a 20MHz crystal. */ +#define OCELOT_G_BASE_BAUD ( 20000000 / 16 ) + +#define OCELOT_G_SERIAL1_IRQ 4 +#if 0 +#define OCELOT_G_SERIAL1_BASE 0xe0001020 +#else +#define OCELOT_G_SERIAL1_BASE 0xfd000020 +#endif + +#define _OCELOT_G_SERIAL_INIT(int, base) \ + { .baud_base = OCELOT_G_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS,\ + .iomem_base = (u8 *) base, .iomem_reg_shift = 2, \ + .io_type = SERIAL_IO_MEM } +#define MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS \ + _OCELOT_G_SERIAL_INIT(OCELOT_G_SERIAL1_IRQ, OCELOT_G_SERIAL1_BASE) +#else +#define MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS +#endif + +#ifdef CONFIG_MOMENCO_OCELOT_C +/* Ordinary NS16552 duart with a 20MHz crystal. */ +#define OCELOT_C_BASE_BAUD ( 20000000 / 16 ) + +#define OCELOT_C_SERIAL1_IRQ 80 +#define OCELOT_C_SERIAL1_BASE 0xfd000020 + +#define OCELOT_C_SERIAL2_IRQ 81 +#define OCELOT_C_SERIAL2_BASE 0xfd000000 + +#define _OCELOT_C_SERIAL_INIT(int, base) \ + { baud_base: OCELOT_C_BASE_BAUD, irq: int, flags: STD_COM_FLAGS,\ + iomem_base: (u8 *) base, iomem_reg_shift: 2, \ + io_type: SERIAL_IO_MEM } +#define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \ + _OCELOT_C_SERIAL_INIT(OCELOT_C_SERIAL1_IRQ, OCELOT_C_SERIAL1_BASE), \ + _OCELOT_C_SERIAL_INIT(OCELOT_C_SERIAL2_IRQ, OCELOT_C_SERIAL2_BASE) +#else +#define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS +#endif + #ifdef CONFIG_DDB5477 +#include <asm/ddb5xxx/ddb5477.h> #define DDB5477_SERIAL_PORT_DEFNS \ - { baud_base: BASE_BAUD, irq: 12, flags: STD_COM_FLAGS, \ - iomem_base: (u8*)0xbfa04200, iomem_reg_shift: 3, \ - io_type: SERIAL_IO_MEM},\ - { baud_base: BASE_BAUD, irq: 28, flags: STD_COM_FLAGS, \ - iomem_base: (u8*)0xbfa04240, iomem_reg_shift: 3, \ - io_type: SERIAL_IO_MEM}, + { .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART0, \ + .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04200, \ + .iomem_reg_shift = 3, .io_type = SERIAL_IO_MEM}, \ + { .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART1, \ + .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04240, \ + .iomem_reg_shift = 3, .io_type = SERIAL_IO_MEM}, #else #define DDB5477_SERIAL_PORT_DEFNS #endif -#define SERIAL_PORT_DFNS \ - IVR_SERIAL_PORT_DEFNS \ - ITE_SERIAL_PORT_DEFNS \ - ATLAS_SERIAL_PORT_DEFNS \ - EV96100_SERIAL_PORT_DEFNS \ - JAZZ_SERIAL_PORT_DEFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS \ - HUB6_SERIAL_PORT_DFNS \ - MOMENCO_OCELOT_SERIAL_PORT_DEFNS\ - AU1000_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ + IVR_SERIAL_PORT_DEFNS \ + ITE_SERIAL_PORT_DEFNS \ + ATLAS_SERIAL_PORT_DEFNS \ + SEAD_SERIAL_PORT_DEFNS \ + COBALT_SERIAL_PORT_DEFNS \ + LASAT_SERIAL_PORT_DEFNS \ + EV96100_SERIAL_PORT_DEFNS \ + JAZZ_SERIAL_PORT_DEFNS \ + STD_SERIAL_PORT_DEFNS \ + EXTRA_SERIAL_PORT_DEFNS \ + HUB6_SERIAL_PORT_DFNS \ + MOMENCO_OCELOT_SERIAL_PORT_DEFNS \ + MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS \ + MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \ + AU1X00_SERIAL_PORT_DEFNS \ + TXX927_SERIAL_PORT_DEFNS \ DDB5477_SERIAL_PORT_DEFNS diff --git a/include/asm-mips/shmbuf.h b/include/asm-mips/shmbuf.h index 37274d6d1e74..6d8e211eb738 100644 --- a/include/asm-mips/shmbuf.h +++ b/include/asm-mips/shmbuf.h @@ -1,7 +1,7 @@ #ifndef _ASM_SHMBUF_H #define _ASM_SHMBUF_H -/* +/* * The shmid64_ds structure for the MIPS architecture. * Note extra padding because this structure is passed back and forth * between kernel and user space. diff --git a/include/asm-mips/shmiq.h b/include/asm-mips/shmiq.h index 632d8aa5bf6a..80d3a5c98105 100644 --- a/include/asm-mips/shmiq.h +++ b/include/asm-mips/shmiq.h @@ -5,7 +5,7 @@ * * This also contains some streams and idev bits. * - * They may contain errors, please, refer to the source code of the Linux + * They may contain errors, please, refer to the source code of the Linux * kernel for a definitive answer on what we have implemented * * Miguel. @@ -91,7 +91,7 @@ struct shmqevent { * head is the user index into the events, user can modify this one. * tail is managed by the kernel. * flags is one of SHMIQ_OVERFLOW or SHMIQ_CORRUPTED - * if OVERFLOW is set it seems ioctl QUIOCSERVICED should be called + * if OVERFLOW is set it seems ioctl QUIOCSERVICED should be called * to notify the kernel. * events where the kernel sticks the events. */ @@ -186,14 +186,14 @@ typedef struct { unsigned hwMaxRes; int hwMinVal; int hwMaxVal; - + unsigned char possibleModes; #define IDEV_ABSOLUTE 0x0 #define IDEV_RELATIVE 0x1 #define IDEV_EITHER 0x2 - + unsigned char mode; /* One of: IDEV_ABSOLUTE, IDEV_RELATIVE */ - + unsigned short resolution; int minVal; int maxVal; diff --git a/include/asm-mips/shmparam.h b/include/asm-mips/shmparam.h index 966fcfe762c3..305a08b6b645 100644 --- a/include/asm-mips/shmparam.h +++ b/include/asm-mips/shmparam.h @@ -1,5 +1,4 @@ -/* $Id: shmparam.h,v 1.3 2000/01/28 19:46:32 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h index 748e3d5422b0..8ce99dc5e789 100644 --- a/include/asm-mips/sigcontext.h +++ b/include/asm-mips/sigcontext.h @@ -1,5 +1,4 @@ -/* $Id: sigcontext.h,v 1.5 1997/12/16 05:36:43 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -18,10 +17,11 @@ struct sigcontext { unsigned int sc_status; unsigned long long sc_pc; unsigned long long sc_regs[32]; - unsigned long long sc_fpregs[32]; /* Unused */ - unsigned int sc_ownedfp; - unsigned int sc_fpc_csr; /* Unused */ + unsigned long long sc_fpregs[32]; + unsigned int sc_ownedfp; /* Unused */ + unsigned int sc_fpc_csr; unsigned int sc_fpc_eir; /* Unused */ + unsigned int sc_used_math; unsigned int sc_ssflags; /* Unused */ unsigned long long sc_mdhi; unsigned long long sc_mdlo; diff --git a/include/asm-mips/siginfo.h b/include/asm-mips/siginfo.h index 3f45c60f5948..a9f27578857d 100644 --- a/include/asm-mips/siginfo.h +++ b/include/asm-mips/siginfo.h @@ -1,5 +1,4 @@ -/* $Id: siginfo.h,v 1.5 1999/08/18 23:37:49 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -13,7 +12,13 @@ #define HAVE_ARCH_SIGINFO_T #define HAVE_ARCH_SIGEVENT_T + +/* + * We duplicate the generic versions - <asm-generic/siginfo.h> is just borked + * by design ... + */ #define HAVE_ARCH_COPY_SIGINFO +struct siginfo; #include <asm-generic/siginfo.h> @@ -66,8 +71,11 @@ typedef struct siginfo { /* POSIX.1b timers */ struct { - unsigned int _timer1; - unsigned int _timer2; + timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ + char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; + sigval_t _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ } _timer; /* POSIX.1b signals */ @@ -93,8 +101,8 @@ typedef struct siginfo { /* * sigevent definitions - * - * It seems likely that SIGEV_THREAD will have to be handled from + * + * It seems likely that SIGEV_THREAD will have to be handled from * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the * thread manager then catches and does the appropriate nonsense. * However, everything is written out here so as to not get lost. @@ -109,21 +117,25 @@ typedef struct siginfo { /* XXX This one isn't yet IRIX / ABI compatible. */ typedef struct sigevent { - int sigev_notify; - sigval_t sigev_value; - int sigev_signo; + int sigev_notify; + sigval_t sigev_value; + int sigev_signo; union { - int _pad[SIGEV_PAD_SIZE]; + int _pad[SIGEV_PAD_SIZE]; + int _tid; struct { - void (*_function)(sigval_t); - void *_attribute; /* really pthread_attr_t */ + void (*_function)(sigval_t); + void *_attribute; /* really pthread_attr_t */ } _sigev_thread; } _sigev_un; } sigevent_t; #ifdef __KERNEL__ +/* + * Duplicated here because of <asm-generic/siginfo.h> braindamage ... + */ #include <linux/string.h> static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h index 6c5a3dfef907..7547fd224d5f 100644 --- a/include/asm-mips/signal.h +++ b/include/asm-mips/signal.h @@ -1,5 +1,4 @@ -/* $Id: signal.h,v 1.6 1999/08/18 23:37:49 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -10,6 +9,7 @@ #ifndef _ASM_SIGNAL_H #define _ASM_SIGNAL_H +#include <linux/config.h> #include <linux/types.h> #define _NSIG 128 @@ -89,7 +89,7 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */ #define SA_RESTORER 0x04000000 -/* +/* * sigaltstack controls */ #define SS_ONSTACK 1 @@ -131,12 +131,13 @@ struct sigaction { unsigned int sa_flags; __sighandler_t sa_handler; sigset_t sa_mask; - void (*sa_restorer)(void); - int sa_resv[1]; /* reserved */ }; struct k_sigaction { struct sigaction sa; +#ifdef CONFIG_BINFMT_IRIX + void (*sa_restorer)(void); +#endif }; /* IRIX compatible stack_t */ @@ -168,9 +169,10 @@ typedef struct sigaltstack { #define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */ #define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */ #define BRK_MULOVF 1023 /* Multiply overflow */ +#define BRK_BUG 512 /* Used by BUG() */ #define ptrace_signal_deliver(regs, cookie) do { } while (0) -#endif /* defined (__KERNEL__) */ +#endif /* __KERNEL__ */ #endif /* _ASM_SIGNAL_H */ diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h index 1bfcf41e09c2..c99411e8fbc5 100644 --- a/include/asm-mips/smp.h +++ b/include/asm-mips/smp.h @@ -1,37 +1,102 @@ -#ifndef __ASM_MIPS_SMP_H -#define __ASM_MIPS_SMP_H +/* + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file "COPYING" in the main directory of this + * archive for more details. + * + * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com) + * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc. + * Copyright (C) 2000, 2001, 2002 Ralf Baechle + * Copyright (C) 2000, 2001 Broadcom Corporation + */ +#ifndef __ASM_SMP_H +#define __ASM_SMP_H #include <linux/config.h> #ifdef CONFIG_SMP -#include <asm/spinlock.h> +#include <linux/bitops.h> +#include <linux/threads.h> #include <asm/atomic.h> -#include <asm/current.h> +#define smp_processor_id() (current_thread_info()->cpu) -/* Mappings are straight across. If we want - to add support for disabling cpus and such, - we'll have to do what the mips64 port does here */ -#define cpu_logical_map(cpu) (cpu) -#define cpu_number_map(cpu) (cpu) +/* Map from cpu id to sequential logical cpu number. This will only + not be idempotent when cpus failed to come on-line. */ +extern int __cpu_number_map[NR_CPUS]; +#define cpu_number_map(cpu) __cpu_number_map[cpu] -#define smp_processor_id() (current->processor) - - -/* I've no idea what the real meaning of this is */ -#define PROC_CHANGE_PENALTY 20 +/* The reverse map from sequential logical cpu number to cpu id. */ +extern int __cpu_logical_map[NR_CPUS]; +#define cpu_logical_map(cpu) __cpu_logical_map[cpu] #define NO_PROC_ID (-1) -struct smp_fn_call_struct { - spinlock_t lock; - atomic_t finished; - void (*fn)(void *); - void *data; +struct call_data_struct { + void (*func)(void *); + void *info; + atomic_t started; + atomic_t finished; + int wait; }; -extern struct smp_fn_call_struct smp_fn_call; +extern struct call_data_struct *call_data; + +#define SMP_RESCHEDULE_YOURSELF 0x1 /* XXX braindead */ +#define SMP_CALL_FUNCTION 0x2 + +#if (NR_CPUS <= _MIPS_SZLONG) + +typedef unsigned long cpumask_t; + +#define CPUMASK_CLRALL(p) (p) = 0 +#define CPUMASK_SETB(p, bit) (p) |= 1UL << (bit) +#define CPUMASK_CLRB(p, bit) (p) &= ~(1UL << (bit)) +#define CPUMASK_TSTB(p, bit) ((p) & (1UL << (bit))) + +#elif (NR_CPUS <= 128) + +/* + * The foll should work till 128 cpus. + */ +#define CPUMASK_SIZE (NR_CPUS/_MIPS_SZLONG) +#define CPUMASK_INDEX(bit) ((bit) >> 6) +#define CPUMASK_SHFT(bit) ((bit) & 0x3f) + +typedef struct { + unsigned long _bits[CPUMASK_SIZE]; +} cpumask_t; + +#define CPUMASK_CLRALL(p) (p)._bits[0] = 0, (p)._bits[1] = 0 +#define CPUMASK_SETB(p, bit) (p)._bits[CPUMASK_INDEX(bit)] |= \ + (1UL << CPUMASK_SHFT(bit)) +#define CPUMASK_CLRB(p, bit) (p)._bits[CPUMASK_INDEX(bit)] &= \ + ~(1UL << CPUMASK_SHFT(bit)) +#define CPUMASK_TSTB(p, bit) ((p)._bits[CPUMASK_INDEX(bit)] & \ + (1UL << CPUMASK_SHFT(bit))) + +#else +#error cpumask macros only defined for 128p kernels +#endif + +extern cpumask_t phys_cpu_present_map; +extern cpumask_t cpu_online_map; + +#define cpu_possible(cpu) (phys_cpu_present_map & (1<<(cpu))) +#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) + +extern inline unsigned int num_online_cpus(void) +{ + return hweight32(cpu_online_map); +} + +extern volatile unsigned long cpu_callout_map; +/* We don't mark CPUs online until __cpu_up(), so we need another measure */ +static inline int num_booting_cpus(void) +{ + return hweight32(cpu_callout_map); +} #endif /* CONFIG_SMP */ -#endif /* __ASM_MIPS_SMP_H */ + +#endif /* __ASM_SMP_H */ diff --git a/include/asm-mips/smplock.h b/include/asm-mips/smplock.h new file mode 100644 index 000000000000..861274910044 --- /dev/null +++ b/include/asm-mips/smplock.h @@ -0,0 +1,67 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Default SMP lock implementation + */ +#include <linux/config.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> + +extern spinlock_t kernel_flag; + +#ifdef CONFIG_SMP +#define kernel_locked() spin_is_locked(&kernel_flag) +#else +#ifdef CONFIG_PREEMPT +#define kernel_locked() preempt_count() +#else +#define kernel_locked() 1 +#endif +#endif + +/* + * Release global kernel lock and global interrupt lock + */ +#define release_kernel_lock(task) \ +do { \ + if (unlikely(task->lock_depth >= 0)) \ + spin_unlock(&kernel_flag); \ +} while (0) + +/* + * Re-acquire the kernel lock + */ +#define reacquire_kernel_lock(task) \ +do { \ + if (unlikely(task->lock_depth >= 0)) \ + spin_lock(&kernel_flag); \ +} while (0) + + +/* + * Getting the big kernel lock. + * + * This cannot happen asynchronously, + * so we only need to worry about other + * CPU's. + */ +static __inline__ void lock_kernel(void) +{ +#ifdef CONFIG_PREEMPT + if (current->lock_depth == -1) + spin_lock(&kernel_flag); + ++current->lock_depth; +#else + + if (!++current->lock_depth) + spin_lock(&kernel_flag); +#endif +} + +static __inline__ void unlock_kernel(void) +{ + if (--current->lock_depth < 0) + spin_unlock(&kernel_flag); +} diff --git a/include/asm-mips/softirq.h b/include/asm-mips/softirq.h new file mode 100644 index 000000000000..d944be956a25 --- /dev/null +++ b/include/asm-mips/softirq.h @@ -0,0 +1,20 @@ +#ifndef __ASM_SOFTIRQ_H +#define __ASM_SOFTIRQ_H + +#include <linux/preempt.h> +#include <asm/hardirq.h> + +#define local_bh_disable() \ + do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0) +#define __local_bh_enable() \ + do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0) + +#define local_bh_enable() \ +do { \ + __local_bh_enable(); \ + if (unlikely(!in_interrupt() && softirq_pending(smp_processor_id()))) \ + do_softirq(); \ + preempt_check_resched(); \ +} while (0) + +#endif /* __ASM_SOFTIRQ_H */ diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h index fb02686f7896..4a46e61ba379 100644 --- a/include/asm-mips/spinlock.h +++ b/include/asm-mips/spinlock.h @@ -31,7 +31,7 @@ typedef struct { * We make no fairness assumptions. They have a cost. */ -static inline void spin_lock(spinlock_t *lock) +static inline void _raw_spin_lock(spinlock_t *lock) { unsigned int tmp; @@ -44,24 +44,41 @@ static inline void spin_lock(spinlock_t *lock) "beqz\t%1, 1b\n\t" " sync\n\t" ".set\treorder" - : "=o" (lock->lock), "=&r" (tmp) - : "o" (lock->lock) + : "=m" (lock->lock), "=&r" (tmp) + : "m" (lock->lock) : "memory"); } -static inline void spin_unlock(spinlock_t *lock) +static inline void _raw_spin_unlock(spinlock_t *lock) { __asm__ __volatile__( ".set\tnoreorder\t\t\t# spin_unlock\n\t" "sync\n\t" "sw\t$0, %0\n\t" - ".set\treorder" - : "=o" (lock->lock) - : "o" (lock->lock) + ".set\treorder" + : "=m" (lock->lock) + : "m" (lock->lock) : "memory"); } -#define spin_trylock(lock) (!test_and_set_bit(0,(lock))) +static inline unsigned int _raw_spin_trylock(spinlock_t *lock) +{ + unsigned int temp, res; + + __asm__ __volatile__( + ".set\tnoreorder\t\t\t# spin_trylock\n\t" + "1:\tll\t%0, %3\n\t" + "ori\t%2, %0, 1\n\t" + "sc\t%2, %1\n\t" + "beqz\t%2, 1b\n\t" + " andi\t%2, %0, 1\n\t" + ".set\treorder" + : "=&r" (temp), "=m" (lock->lock), "=&r" (res) + : "m" (lock->lock) + : "memory"); + + return res == 0; +} /* * Read-write spinlocks, allowing multiple readers but only one writer. @@ -78,7 +95,11 @@ typedef struct { #define RW_LOCK_UNLOCKED (rwlock_t) { 0 } -static inline void read_lock(rwlock_t *rw) +#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0) + +#define rwlock_is_locked(x) ((x)->lock) + +static inline void _raw_read_lock(rwlock_t *rw) { unsigned int tmp; @@ -90,16 +111,16 @@ static inline void read_lock(rwlock_t *rw) "sc\t%1, %0\n\t" "beqz\t%1, 1b\n\t" " sync\n\t" - ".set\treorder" - : "=o" (rw->lock), "=&r" (tmp) - : "o" (rw->lock) + ".set\treorder" + : "=m" (rw->lock), "=&r" (tmp) + : "m" (rw->lock) : "memory"); } /* Note the use of sub, not subu which will make the kernel die with an overflow exception if we ever try to unlock an rwlock that is already unlocked or is being held by a writer. */ -static inline void read_unlock(rwlock_t *rw) +static inline void _raw_read_unlock(rwlock_t *rw) { unsigned int tmp; @@ -109,13 +130,14 @@ static inline void read_unlock(rwlock_t *rw) "sub\t%1, 1\n\t" "sc\t%1, %0\n\t" "beqz\t%1, 1b\n\t" - ".set\treorder" - : "=o" (rw->lock), "=&r" (tmp) - : "o" (rw->lock) + " sync\n\t" + ".set\treorder" + : "=m" (rw->lock), "=&r" (tmp) + : "m" (rw->lock) : "memory"); } -static inline void write_lock(rwlock_t *rw) +static inline void _raw_write_lock(rwlock_t *rw) { unsigned int tmp; @@ -127,21 +149,21 @@ static inline void write_lock(rwlock_t *rw) "sc\t%1, %0\n\t" "beqz\t%1, 1b\n\t" " sync\n\t" - ".set\treorder" - : "=o" (rw->lock), "=&r" (tmp) - : "o" (rw->lock) + ".set\treorder" + : "=m" (rw->lock), "=&r" (tmp) + : "m" (rw->lock) : "memory"); } -static inline void write_unlock(rwlock_t *rw) +static inline void _raw_write_unlock(rwlock_t *rw) { __asm__ __volatile__( ".set\tnoreorder\t\t\t# write_unlock\n\t" "sync\n\t" "sw\t$0, %0\n\t" - ".set\treorder" - : "=o" (rw->lock) - : "o" (rw->lock) + ".set\treorder" + : "=m" (rw->lock) + : "m" (rw->lock) : "memory"); } diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index d46cecef9afc..0d52478b38bb 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h @@ -9,282 +9,287 @@ #ifndef __ASM_STACKFRAME_H #define __ASM_STACKFRAME_H +#include <linux/config.h> #include <asm/addrspace.h> #include <asm/mipsregs.h> #include <asm/processor.h> #include <asm/asm.h> #include <asm/offset.h> -#include <linux/config.h> -#define SAVE_AT \ - .set push; \ - .set noat; \ - sw $1, PT_R1(sp); \ + .macro SAVE_AT + .set push + .set noat + sw $1, PT_R1(sp) .set pop + .endm -#define SAVE_TEMP \ - mfhi v1; \ - sw $8, PT_R8(sp); \ - sw $9, PT_R9(sp); \ - sw v1, PT_HI(sp); \ - mflo v1; \ - sw $10,PT_R10(sp); \ - sw $11, PT_R11(sp); \ - sw v1, PT_LO(sp); \ - sw $12, PT_R12(sp); \ - sw $13, PT_R13(sp); \ - sw $14, PT_R14(sp); \ - sw $15, PT_R15(sp); \ + .macro SAVE_TEMP + mfhi v1 + sw $8, PT_R8(sp) + sw $9, PT_R9(sp) + sw v1, PT_HI(sp) + mflo v1 + sw $10,PT_R10(sp) + sw $11, PT_R11(sp) + sw v1, PT_LO(sp) + sw $12, PT_R12(sp) + sw $13, PT_R13(sp) + sw $14, PT_R14(sp) + sw $15, PT_R15(sp) sw $24, PT_R24(sp) + .endm -#define SAVE_STATIC \ - sw $16, PT_R16(sp); \ - sw $17, PT_R17(sp); \ - sw $18, PT_R18(sp); \ - sw $19, PT_R19(sp); \ - sw $20, PT_R20(sp); \ - sw $21, PT_R21(sp); \ - sw $22, PT_R22(sp); \ - sw $23, PT_R23(sp); \ + .macro SAVE_STATIC + sw $16, PT_R16(sp) + sw $17, PT_R17(sp) + sw $18, PT_R18(sp) + sw $19, PT_R19(sp) + sw $20, PT_R20(sp) + sw $21, PT_R21(sp) + sw $22, PT_R22(sp) + sw $23, PT_R23(sp) sw $30, PT_R30(sp) - -#define __str2(x) #x -#define __str(x) __str2(x) - -#define save_static_function(symbol) \ -__asm__ ( \ - ".globl\t" #symbol "\n\t" \ - ".align\t2\n\t" \ - ".type\t" #symbol ", @function\n\t" \ - ".ent\t" #symbol ", 0\n" \ - #symbol":\n\t" \ - ".frame\t$29, 0, $31\n\t" \ - "sw\t$16,"__str(PT_R16)"($29)\t\t\t# save_static_function\n\t" \ - "sw\t$17,"__str(PT_R17)"($29)\n\t" \ - "sw\t$18,"__str(PT_R18)"($29)\n\t" \ - "sw\t$19,"__str(PT_R19)"($29)\n\t" \ - "sw\t$20,"__str(PT_R20)"($29)\n\t" \ - "sw\t$21,"__str(PT_R21)"($29)\n\t" \ - "sw\t$22,"__str(PT_R22)"($29)\n\t" \ - "sw\t$23,"__str(PT_R23)"($29)\n\t" \ - "sw\t$30,"__str(PT_R30)"($29)\n\t" \ - ".end\t" #symbol "\n\t" \ - ".size\t" #symbol",. - " #symbol) - -/* Used in declaration of save_static functions. */ -#define static_unused static __attribute__((unused)) - + .endm #ifdef CONFIG_SMP -# define GET_SAVED_SP \ - mfc0 k0, CP0_CONTEXT; \ - lui k1, %hi(kernelsp); \ - srl k0, k0, 23; \ - sll k0, k0, 2; \ - addu k1, k0; \ - lw k1, %lo(kernelsp)(k1); + .macro GET_SAVED_SP + mfc0 k0, CP0_CONTEXT + lui k1, %hi(kernelsp) + srl k0, k0, 23 + sll k0, k0, 2 + addu k1, k0 + lw k1, %lo(kernelsp)(k1) + .endm #else -# define GET_SAVED_SP \ - lui k1, %hi(kernelsp); \ - lw k1, %lo(kernelsp)(k1); + .macro GET_SAVED_SP + lui k1, %hi(kernelsp) + lw k1, %lo(kernelsp)(k1) + .endm #endif - -#define SAVE_SOME \ - .set push; \ - .set reorder; \ - mfc0 k0, CP0_STATUS; \ - sll k0, 3; /* extract cu0 bit */ \ - .set noreorder; \ - bltz k0, 8f; \ - move k1, sp; \ - .set reorder; \ - /* Called from user mode, new stack. */ \ - GET_SAVED_SP \ -8: \ - move k0, sp; \ - subu sp, k1, PT_SIZE; \ - sw k0, PT_R29(sp); \ - sw $3, PT_R3(sp); \ - sw $0, PT_R0(sp); \ - mfc0 v1, CP0_STATUS; \ - sw $2, PT_R2(sp); \ - sw v1, PT_STATUS(sp); \ - sw $4, PT_R4(sp); \ - mfc0 v1, CP0_CAUSE; \ - sw $5, PT_R5(sp); \ - sw v1, PT_CAUSE(sp); \ - sw $6, PT_R6(sp); \ - mfc0 v1, CP0_EPC; \ - sw $7, PT_R7(sp); \ - sw v1, PT_EPC(sp); \ - sw $25, PT_R25(sp); \ - sw $28, PT_R28(sp); \ - sw $31, PT_R31(sp); \ - ori $28, sp, 0x1fff; \ - xori $28, 0x1fff; \ + +#ifdef CONFIG_PREEMPT + .macro BUMP_LOCK_COUNT + lw t0, TI_PRE_COUNT($28) + addiu t0, t0, 1 + sw t0, TI_PRE_COUNT($28) + .endm +#else + .macro BUMP_LOCK_COUNT + .endm +#endif + + .macro SAVE_SOME + .set push + .set reorder + mfc0 k0, CP0_STATUS + sll k0, 3 /* extract cu0 bit */ + .set noreorder + bltz k0, 8f + move k1, sp + .set reorder + /* Called from user mode, new stack. */ + GET_SAVED_SP +8: + move k0, sp + subu sp, k1, PT_SIZE + sw k0, PT_R29(sp) + sw $3, PT_R3(sp) + sw $0, PT_R0(sp) + mfc0 v1, CP0_STATUS + sw $2, PT_R2(sp) + sw v1, PT_STATUS(sp) + sw $4, PT_R4(sp) + mfc0 v1, CP0_CAUSE + sw $5, PT_R5(sp) + sw v1, PT_CAUSE(sp) + sw $6, PT_R6(sp) + mfc0 v1, CP0_EPC + sw $7, PT_R7(sp) + sw v1, PT_EPC(sp) + sw $25, PT_R25(sp) + sw $28, PT_R28(sp) + sw $31, PT_R31(sp) + ori $28, sp, 0x1fff + xori $28, 0x1fff + BUMP_LOCK_COUNT .set pop + .endm -#define SAVE_ALL \ - SAVE_SOME; \ - SAVE_AT; \ - SAVE_TEMP; \ + .macro SAVE_ALL + SAVE_SOME + SAVE_AT + SAVE_TEMP SAVE_STATIC + .endm -#define RESTORE_AT \ - .set push; \ - .set noat; \ - lw $1, PT_R1(sp); \ - .set pop; + .macro RESTORE_AT + .set push + .set noat + lw $1, PT_R1(sp) + .set pop + .endm -#define RESTORE_TEMP \ - lw $24, PT_LO(sp); \ - lw $8, PT_R8(sp); \ - lw $9, PT_R9(sp); \ - mtlo $24; \ - lw $24, PT_HI(sp); \ - lw $10,PT_R10(sp); \ - lw $11, PT_R11(sp); \ - mthi $24; \ - lw $12, PT_R12(sp); \ - lw $13, PT_R13(sp); \ - lw $14, PT_R14(sp); \ - lw $15, PT_R15(sp); \ + .macro RESTORE_TEMP + lw $24, PT_LO(sp) + lw $8, PT_R8(sp) + lw $9, PT_R9(sp) + mtlo $24 + lw $24, PT_HI(sp) + lw $10,PT_R10(sp) + lw $11, PT_R11(sp) + mthi $24 + lw $12, PT_R12(sp) + lw $13, PT_R13(sp) + lw $14, PT_R14(sp) + lw $15, PT_R15(sp) lw $24, PT_R24(sp) + .endm -#define RESTORE_STATIC \ - lw $16, PT_R16(sp); \ - lw $17, PT_R17(sp); \ - lw $18, PT_R18(sp); \ - lw $19, PT_R19(sp); \ - lw $20, PT_R20(sp); \ - lw $21, PT_R21(sp); \ - lw $22, PT_R22(sp); \ - lw $23, PT_R23(sp); \ + .macro RESTORE_STATIC + lw $16, PT_R16(sp) + lw $17, PT_R17(sp) + lw $18, PT_R18(sp) + lw $19, PT_R19(sp) + lw $20, PT_R20(sp) + lw $21, PT_R21(sp) + lw $22, PT_R22(sp) + lw $23, PT_R23(sp) lw $30, PT_R30(sp) + .endm -#if defined(CONFIG_CPU_R3000) +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) -#define RESTORE_SOME \ - .set push; \ - .set reorder; \ - mfc0 t0, CP0_STATUS; \ - .set pop; \ - ori t0, 0x1f; \ - xori t0, 0x1f; \ - mtc0 t0, CP0_STATUS; \ - li v1, 0xff00; \ - and t0, v1; \ - lw v0, PT_STATUS(sp); \ - nor v1, $0, v1; \ - and v0, v1; \ - or v0, t0; \ - mtc0 v0, CP0_STATUS; \ - lw $31, PT_R31(sp); \ - lw $28, PT_R28(sp); \ - lw $25, PT_R25(sp); \ - lw $7, PT_R7(sp); \ - lw $6, PT_R6(sp); \ - lw $5, PT_R5(sp); \ - lw $4, PT_R4(sp); \ - lw $3, PT_R3(sp); \ + .macro RESTORE_SOME + .set push + .set reorder + mfc0 t0, CP0_STATUS + .set pop + ori t0, 0x1f + xori t0, 0x1f + mtc0 t0, CP0_STATUS + li v1, 0xff00 + and t0, v1 + lw v0, PT_STATUS(sp) + nor v1, $0, v1 + and v0, v1 + or v0, t0 + mtc0 v0, CP0_STATUS + lw $31, PT_R31(sp) + lw $28, PT_R28(sp) + lw $25, PT_R25(sp) + lw $7, PT_R7(sp) + lw $6, PT_R6(sp) + lw $5, PT_R5(sp) + lw $4, PT_R4(sp) + lw $3, PT_R3(sp) lw $2, PT_R2(sp) + .endm -#define RESTORE_SP_AND_RET \ - .set push; \ - .set noreorder; \ - lw k0, PT_EPC(sp); \ - lw sp, PT_R29(sp); \ - jr k0; \ - rfe; \ + .macro RESTORE_SP_AND_RET + .set push + .set noreorder + lw k0, PT_EPC(sp) + lw sp, PT_R29(sp) + jr k0 + rfe .set pop + .endm #else -#define RESTORE_SOME \ - .set push; \ - .set reorder; \ - mfc0 t0, CP0_STATUS; \ - .set pop; \ - ori t0, 0x1f; \ - xori t0, 0x1f; \ - mtc0 t0, CP0_STATUS; \ - li v1, 0xff00; \ - and t0, v1; \ - lw v0, PT_STATUS(sp); \ - nor v1, $0, v1; \ - and v0, v1; \ - or v0, t0; \ - mtc0 v0, CP0_STATUS; \ - lw v1, PT_EPC(sp); \ - mtc0 v1, CP0_EPC; \ - lw $31, PT_R31(sp); \ - lw $28, PT_R28(sp); \ - lw $25, PT_R25(sp); \ - lw $7, PT_R7(sp); \ - lw $6, PT_R6(sp); \ - lw $5, PT_R5(sp); \ - lw $4, PT_R4(sp); \ - lw $3, PT_R3(sp); \ + .macro RESTORE_SOME + .set push + .set reorder + mfc0 t0, CP0_STATUS + .set pop + ori t0, 0x1f + xori t0, 0x1f + mtc0 t0, CP0_STATUS + li v1, 0xff00 + and t0, v1 + lw v0, PT_STATUS(sp) + nor v1, $0, v1 + and v0, v1 + or v0, t0 + mtc0 v0, CP0_STATUS + lw v1, PT_EPC(sp) + mtc0 v1, CP0_EPC + lw $31, PT_R31(sp) + lw $28, PT_R28(sp) + lw $25, PT_R25(sp) + lw $7, PT_R7(sp) + lw $6, PT_R6(sp) + lw $5, PT_R5(sp) + lw $4, PT_R4(sp) + lw $3, PT_R3(sp) lw $2, PT_R2(sp) + .endm -#define RESTORE_SP_AND_RET \ - lw sp, PT_R29(sp); \ - .set mips3; \ - eret; \ + .macro RESTORE_SP_AND_RET + lw sp, PT_R29(sp) + .set mips3 + eret .set mips0 + .endm #endif -#define RESTORE_SP \ - lw sp, PT_R29(sp); \ + .macro RESTORE_SP + lw sp, PT_R29(sp) + .endm -#define RESTORE_ALL \ - RESTORE_SOME; \ - RESTORE_AT; \ - RESTORE_TEMP; \ - RESTORE_STATIC; \ + .macro RESTORE_ALL + RESTORE_SOME + RESTORE_AT + RESTORE_TEMP + RESTORE_STATIC RESTORE_SP + .endm -#define RESTORE_ALL_AND_RET \ - RESTORE_SOME; \ - RESTORE_AT; \ - RESTORE_TEMP; \ - RESTORE_STATIC; \ + .macro RESTORE_ALL_AND_RET + RESTORE_SOME + RESTORE_AT + RESTORE_TEMP + RESTORE_STATIC RESTORE_SP_AND_RET + .endm /* * Move to kernel mode and disable interrupts. * Set cp0 enable bit as sign that we're running on the kernel stack */ -#define CLI \ - mfc0 t0,CP0_STATUS; \ - li t1,ST0_CU0|0x1f; \ - or t0,t1; \ - xori t0,0x1f; \ + .macro CLI + mfc0 t0,CP0_STATUS + li t1,ST0_CU0|0x1f + or t0,t1 + xori t0,0x1f mtc0 t0,CP0_STATUS + .endm /* * Move to kernel mode and enable interrupts. * Set cp0 enable bit as sign that we're running on the kernel stack */ -#define STI \ - mfc0 t0,CP0_STATUS; \ - li t1,ST0_CU0|0x1f; \ - or t0,t1; \ - xori t0,0x1e; \ + .macro STI + mfc0 t0,CP0_STATUS + li t1,ST0_CU0|0x1f + or t0,t1 + xori t0,0x1e mtc0 t0,CP0_STATUS + .endm /* * Just move to kernel mode and leave interrupts as they are. * Set cp0 enable bit as sign that we're running on the kernel stack */ -#define KMODE \ - mfc0 t0,CP0_STATUS; \ - li t1,ST0_CU0|0x1e; \ - or t0,t1; \ - xori t0,0x1e; \ + .macro KMODE + mfc0 t0,CP0_STATUS + li t1,ST0_CU0|0x1e + or t0,t1 + xori t0,0x1e mtc0 t0,CP0_STATUS + .endm #endif /* __ASM_STACKFRAME_H */ diff --git a/include/asm-mips/stat.h b/include/asm-mips/stat.h index c1b837973545..693b886fcd60 100644 --- a/include/asm-mips/stat.h +++ b/include/asm-mips/stat.h @@ -3,23 +3,6 @@ #include <linux/types.h> -struct __old_kernel_stat { - unsigned int st_dev; - unsigned int st_ino; - unsigned int st_mode; - unsigned int st_nlink; - unsigned int st_uid; - unsigned int st_gid; - unsigned int st_rdev; - long st_size; - unsigned int st_atime, st_res1; - unsigned int st_mtime, st_res2; - unsigned int st_ctime, st_res3; - unsigned int st_blksize; - int st_blocks; - unsigned int st_unused0[2]; -}; - struct stat { dev_t st_dev; long st_pad1[3]; /* Reserved for network id */ @@ -75,13 +58,13 @@ struct stat64 { * but we don't have it under Linux. */ time_t st_atime; - unsigned long reserved0; /* Reserved for st_atime expansion */ + unsigned long st_atime_nsec; /* Reserved for st_atime expansion */ time_t st_mtime; - unsigned long reserved1; /* Reserved for st_mtime expansion */ + unsigned long st_mtime_nsec; /* Reserved for st_mtime expansion */ time_t st_ctime; - unsigned long reserved2; /* Reserved for st_ctime expansion */ + unsigned long st_ctime_nsec; /* Reserved for st_ctime expansion */ unsigned long st_blksize; unsigned long st_pad2; diff --git a/include/asm-mips/statfs.h b/include/asm-mips/statfs.h index 500f6f1b667b..fb56e50c2cfd 100644 --- a/include/asm-mips/statfs.h +++ b/include/asm-mips/statfs.h @@ -1,14 +1,12 @@ /* - * Definitions for the statfs(2) call. - * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995 by Ralf Baechle + * Copyright (C) 1995, 1999 by Ralf Baechle */ -#ifndef __ASM_MIPS_STATFS_H -#define __ASM_MIPS_STATFS_H +#ifndef _ASM_STATFS_H +#define _ASM_STATFS_H #include <linux/posix_types.h> @@ -37,4 +35,21 @@ struct statfs { long f_spare[6]; }; -#endif /* __ASM_MIPS_STATFS_H */ +/* + * Unlike the 32-bit version the 64-bit version has none of the ABI baggage. + */ +struct statfs64 { + __u32 f_type; + __u32 f_bsize; + __u64 f_blocks; + __u64 f_bfree; + __u64 f_bavail; + __u64 f_files; + __u64 f_ffree; + __kernel_fsid_t f_fsid; + __u32 f_namelen; + __u32 f_frsize; + __u32 f_spare[5]; +}; + +#endif /* _ASM_STATFS_H */ diff --git a/include/asm-mips/string.h b/include/asm-mips/string.h index f3f28a26ad82..f3074a3b7d05 100644 --- a/include/asm-mips/string.h +++ b/include/asm-mips/string.h @@ -28,7 +28,7 @@ extern __inline__ char *strcpy(char *__dest, __const__ char *__src) ".set\treorder" : "=r" (__dest), "=r" (__src) : "0" (__dest), "1" (__src) - : "$1","memory"); + : "memory"); return __xdest; } @@ -56,9 +56,9 @@ extern __inline__ char *strncpy(char *__dest, __const__ char *__src, size_t __n) ".set\treorder" : "=r" (__dest), "=r" (__src), "=r" (__n) : "0" (__dest), "1" (__src), "2" (__n) - : "$1","memory"); + : "memory"); - return __dest; + return __xdest; } #define __HAVE_ARCH_STRCMP @@ -84,8 +84,7 @@ extern __inline__ int strcmp(__const__ char *__cs, __const__ char *__ct) "3:\t.set\tat\n\t" ".set\treorder" : "=r" (__cs), "=r" (__ct), "=r" (__res) - : "0" (__cs), "1" (__ct) - : "$1"); + : "0" (__cs), "1" (__ct)); return __res; } @@ -110,14 +109,13 @@ strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count) "2:\n\t" #if defined(CONFIG_CPU_R3000) "nop\n\t" -#endif +#endif "move\t%3,$1\n" "3:\tsubu\t%3,$1\n\t" ".set\tat\n\t" ".set\treorder" : "=r" (__cs), "=r" (__ct), "=r" (__count), "=r" (__res) - : "0" (__cs), "1" (__ct), "2" (__count) - : "$1"); + : "0" (__cs), "1" (__ct), "2" (__count)); return __res; } @@ -138,18 +136,18 @@ extern void *memmove(void *__dest, __const__ void *__src, size_t __n); extern __inline__ void *memscan(void *__addr, int __c, size_t __size) { char *__end = (char *)__addr + __size; + unsigned char __uc = (unsigned char) __c; __asm__(".set\tpush\n\t" ".set\tnoat\n\t" ".set\treorder\n\t" "1:\tbeq\t%0,%1,2f\n\t" "addiu\t%0,1\n\t" - "lb\t$1,-1(%0)\n\t" + "lbu\t$1,-1(%0)\n\t" "bne\t$1,%z4,1b\n" "2:\t.set\tpop" : "=r" (__addr), "=r" (__end) - : "0" (__addr), "1" (__end), "Jr" (__c) - : "$1"); + : "0" (__addr), "1" (__end), "Jr" (__uc)); return __addr; } diff --git a/include/asm-mips/suspend.h b/include/asm-mips/suspend.h new file mode 100644 index 000000000000..2562f8f9be0e --- /dev/null +++ b/include/asm-mips/suspend.h @@ -0,0 +1,6 @@ +#ifndef __ASM_SUSPEND_H +#define __ASM_SUSPEND_H + +/* Somewhen... Maybe :-) */ + +#endif /* __ASM_SUSPEND_H */ diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 49dbea6f8c1f..94045c6d30a3 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -8,7 +8,7 @@ * Copyright (C) 1994 - 1999 by Ralf Baechle * * Changed set_except_vector declaration to allow return of previous - * vector address value - necessary for "borrowing" vectors. + * vector address value - necessary for "borrowing" vectors. * * Kevin D. Kissell, kevink@mips.org and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. @@ -18,153 +18,240 @@ #include <linux/config.h> #include <asm/sgidefs.h> -#include <asm/ptrace.h> + #include <linux/kernel.h> -extern __inline__ void -local_irq_enable(void) +#include <asm/addrspace.h> +#include <asm/ptrace.h> + +__asm__ ( + ".macro\tlocal_irq_enable\n\t" + ".set\tpush\n\t" + ".set\treorder\n\t" + ".set\tnoat\n\t" + "mfc0\t$1,$12\n\t" + "ori\t$1,0x1f\n\t" + "xori\t$1,0x1e\n\t" + "mtc0\t$1,$12\n\t" + ".set\tpop\n\t" + ".endm"); + +extern inline void local_irq_enable(void) { __asm__ __volatile__( - ".set\tpush\n\t" - ".set\treorder\n\t" - ".set\tnoat\n\t" - "mfc0\t$1,$12\n\t" - "ori\t$1,0x1f\n\t" - "xori\t$1,0x1e\n\t" - "mtc0\t$1,$12\n\t" - ".set\tpop\n\t" + "local_irq_enable" : /* no outputs */ : /* no inputs */ - : "$1", "memory"); + : "memory"); } /* - * For cli() we have to insert nops to make shure that the new value + * For cli() we have to insert nops to make sure that the new value * has actually arrived in the status register before the end of this * macro. * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs * no nops at all. */ -extern __inline__ void -local_irq_disable(void) +__asm__ ( + ".macro\tlocal_irq_disable\n\t" + ".set\tpush\n\t" + ".set\tnoat\n\t" + "mfc0\t$1,$12\n\t" + "ori\t$1,1\n\t" + "xori\t$1,1\n\t" + ".set\tnoreorder\n\t" + "mtc0\t$1,$12\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + ".set\tpop\n\t" + ".endm"); + +extern inline void local_irq_disable(void) { __asm__ __volatile__( - ".set\tpush\n\t" - ".set\treorder\n\t" - ".set\tnoat\n\t" - "mfc0\t$1,$12\n\t" - "ori\t$1,1\n\t" - "xori\t$1,1\n\t" - ".set\tnoreorder\n\t" - "mtc0\t$1,$12\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - ".set\tpop\n\t" + "local_irq_disable" : /* no outputs */ : /* no inputs */ - : "$1", "memory"); + : "memory"); } +__asm__ ( + ".macro\tlocal_save_flags flags\n\t" + ".set\tpush\n\t" + ".set\treorder\n\t" + "mfc0\t\\flags, $12\n\t" + ".set\tpop\n\t" + ".endm"); + #define local_save_flags(x) \ __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - "mfc0\t%0,$12\n\t" \ - ".set\tpop\n\t" \ + "local_save_flags %0" \ : "=r" (x)) +__asm__ ( + ".macro\tlocal_irq_save result\n\t" + ".set\tpush\n\t" + ".set\treorder\n\t" + ".set\tnoat\n\t" + "mfc0\t\\result, $12\n\t" + "ori\t$1, \\result, 1\n\t" + "xori\t$1, 1\n\t" + ".set\tnoreorder\n\t" + "mtc0\t$1, $12\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + ".set\tpop\n\t" + ".endm"); + #define local_irq_save(x) \ __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - ".set\tnoat\n\t" \ - "mfc0\t%0,$12\n\t" \ - "ori\t$1,%0,1\n\t" \ - "xori\t$1,1\n\t" \ - ".set\tnoreorder\n\t" \ - "mtc0\t$1,$12\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".set\tpop\n\t" \ + "local_irq_save\t%0" \ : "=r" (x) \ : /* no inputs */ \ - : "$1", "memory") + : "memory") + +__asm__(".macro\tlocal_irq_restore flags\n\t" + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "mfc0\t$1, $12\n\t" + "andi\t\\flags, 1\n\t" + "ori\t$1, 1\n\t" + "xori\t$1, 1\n\t" + "or\t\\flags, $1\n\t" + "mtc0\t\\flags, $12\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + ".set\tat\n\t" + ".set\treorder\n\t" + ".endm"); #define local_irq_restore(flags) \ do { \ unsigned long __tmp1; \ \ __asm__ __volatile__( \ - ".set\tnoreorder\t\t\t# local_irq_restore\n\t" \ - ".set\tnoat\n\t" \ - "mfc0\t$1, $12\n\t" \ - "andi\t%0, 1\n\t" \ - "ori\t$1, 1\n\t" \ - "xori\t$1, 1\n\t" \ - "or\t%0, $1\n\t" \ - "mtc0\t%0, $12\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ + "local_irq_restore\t%0" \ : "=r" (__tmp1) \ : "0" (flags) \ - : "$1", "memory"); \ + : "memory"); \ } while(0) -#ifdef CONFIG_SMP +#define irqs_disabled() \ +({ \ + unsigned long flags; \ + local_save_flags(flags); \ + !(flags & 1); \ +}) -extern void __global_sti(void); -extern void __global_cli(void); -extern unsigned long __global_save_flags(void); -extern void __global_restore_flags(unsigned long); -# define sti() __global_sti() -# define cli() __global_cli() -# define save_flags(x) do { x = __global_save_flags(); } while (0) -# define restore_flags(x) __global_restore_flags(x) -# define save_and_cli(x) do { save_flags(x); cli(); } while(0) +/* + * read_barrier_depends - Flush all pending reads that subsequents reads + * depend on. + * + * No data-dependent reads from memory-like regions are ever reordered + * over this barrier. All reads preceding this primitive are guaranteed + * to access memory (but not necessarily other CPUs' caches) before any + * reads following this primitive that depend on the data return by + * any of the preceding reads. This primitive is much lighter weight than + * rmb() on most CPUs, and is never heavier weight than is + * rmb(). + * + * These ordering constraints are respected by both the local CPU + * and the compiler. + * + * Ordering is not guaranteed by anything other than these primitives, + * not even by data dependencies. See the documentation for + * memory_barrier() for examples and URLs to more information. + * + * For example, the following code would force ordering (the initial + * value of "a" is zero, "b" is one, and "p" is "&a"): + * + * <programlisting> + * CPU 0 CPU 1 + * + * b = 2; + * memory_barrier(); + * p = &b; q = p; + * read_barrier_depends(); + * d = *q; + * </programlisting> + * + * because the read of "*q" depends on the read of "p" and these + * two reads are separated by a read_barrier_depends(). However, + * the following code, with the same initial values for "a" and "b": + * + * <programlisting> + * CPU 0 CPU 1 + * + * a = 2; + * memory_barrier(); + * b = 3; y = b; + * read_barrier_depends(); + * x = a; + * </programlisting> + * + * does not enforce ordering, since there is no data dependency between + * the read of "a" and the read of "b". Therefore, on some CPUs, such + * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() + * in cases like thiswhere there are no data dependencies. + */ -#else /* Single processor */ +#define read_barrier_depends() do { } while(0) -# define sti() local_irq_enable() -# define cli() local_irq_disable() -# define save_flags(x) local_save_flags(x) -# define save_and_cli(x) local_irq_save(x) -# define restore_flags(x) local_irq_restore(x) +#ifdef CONFIG_CPU_HAS_SYNC +#define __sync() \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + ".set mips2\n\t" \ + "sync\n\t" \ + ".set pop" \ + : /* no output */ \ + : /* no input */ \ + : "memory") +#else +#define __sync() do { } while(0) +#endif -#endif /* SMP */ +#define __fast_iob() \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "lw $0,%0\n\t" \ + "nop\n\t" \ + ".set pop" \ + : /* no output */ \ + : "m" (*(int *)KSEG1) \ + : "memory") + +#define fast_wmb() __sync() +#define fast_rmb() __sync() +#define fast_mb() __sync() +#define fast_iob() \ + do { \ + __sync(); \ + __fast_iob(); \ + } while (0) -/* - * These are probably defined overly paranoid ... - */ #ifdef CONFIG_CPU_HAS_WB #include <asm/wbflush.h> -#define rmb() do { } while(0) -#define wmb() wbflush() -#define mb() wbflush() -#define read_barrier_depends() do { } while(0) -#else /* CONFIG_CPU_HAS_WB */ - -#define mb() \ -__asm__ __volatile__( \ - "# prevent instructions being moved around\n\t" \ - ".set\tnoreorder\n\t" \ - "# 8 nops to fool the R4400 pipeline\n\t" \ - "nop;nop;nop;nop;nop;nop;nop;nop\n\t" \ - ".set\treorder" \ - : /* no output */ \ - : /* no input */ \ - : "memory") -#define rmb() mb() -#define wmb() mb() -#define read_barrier_depends() do { } while(0) +#define wmb() fast_wmb() +#define rmb() fast_rmb() +#define mb() wbflush(); +#define iob() wbflush(); + +#else /* !CONFIG_CPU_HAS_WB */ -#endif /* CONFIG_CPU_HAS_WB */ +#define wmb() fast_wmb() +#define rmb() fast_rmb() +#define mb() fast_mb() +#define iob() fast_iob() + +#endif /* !CONFIG_CPU_HAS_WB */ #ifdef CONFIG_SMP #define smp_mb() mb() @@ -184,18 +271,17 @@ do { var = value; mb(); } while (0) #define set_wmb(var, value) \ do { var = value; wmb(); } while (0) -#if !defined (_LANGUAGE_ASSEMBLY) /* * switch_to(n) should switch tasks to task nr n, first * checking that n isn't the current task, in which case it does nothing. */ -extern asmlinkage void *resume(void *last, void *next); -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +extern asmlinkage void *resume(void *last, void *next, void *next_ti); + +struct task_struct; -#define prepare_to_switch() do { } while(0) #define switch_to(prev,next,last) \ do { \ - (last) = resume(prev, next); \ + (last) = resume(prev, next, next->thread_info); \ } while(0) /* @@ -208,28 +294,28 @@ extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val) unsigned long dummy; __asm__ __volatile__( - ".set\tnoreorder\t\t\t# xchg_u32\n\t" - ".set\tnoat\n\t" + ".set\tpush\t\t\t\t# xchg_u32\n\t" + ".set\tnoreorder\n\t" + ".set\tnomacro\n\t" "ll\t%0, %3\n" - "1:\tmove\t$1, %2\n\t" - "sc\t$1, %1\n\t" - "beqzl\t$1, 1b\n\t" + "1:\tmove\t%2, %z4\n\t" + "sc\t%2, %1\n\t" + "beqzl\t%2, 1b\n\t" " ll\t%0, %3\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (val), "=o" (*m), "=r" (dummy) - : "o" (*m), "2" (val) + "sync\n\t" + ".set\tpop" + : "=&r" (val), "=m" (*m), "=&r" (dummy) + : "R" (*m), "Jr" (val) : "memory"); return val; #else unsigned long flags, retval; - save_flags(flags); - cli(); + local_irq_save(flags); retval = *m; *m = val; - restore_flags(flags); + local_irq_restore(flags); /* implies memory barrier */ return retval; #endif /* Processor-dependent optimization */ } @@ -248,15 +334,24 @@ __xchg(unsigned long x, volatile void * ptr, int size) } extern void *set_except_vector(int n, void *addr); +extern void per_cpu_trap_init(void); -extern void __die(const char *, struct pt_regs *, const char *where, - unsigned long line) __attribute__((noreturn)); -extern void __die_if_kernel(const char *, struct pt_regs *, const char *where, - unsigned long line); +extern void __die(const char *, struct pt_regs *, const char *file, + const char *func, unsigned long line) __attribute__((noreturn)); +extern void __die_if_kernel(const char *, struct pt_regs *, const char *file, + const char *func, unsigned long line); #define die(msg, regs) \ - __die(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__) + __die(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__) #define die_if_kernel(msg, regs) \ - __die_if_kernel(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__) + __die_if_kernel(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__) + +extern int serial_console; +extern int stop_a_enabled; + +static __inline__ int con_is_present(void) +{ + return serial_console ? 0 : 1; +} #endif /* _ASM_SYSTEM_H */ diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h new file mode 100644 index 000000000000..99ec130a7808 --- /dev/null +++ b/include/asm-mips/thread_info.h @@ -0,0 +1,103 @@ +/* thread_info.h: i386 low-level thread information + * + * Copyright (C) 2002 David Howells (dhowells@redhat.com) + * - Incorporating suggestions made by Linus Torvalds and Dave Miller + */ + +#ifndef _ASM_THREAD_INFO_H +#define _ASM_THREAD_INFO_H + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ + +#include <asm/processor.h> + +/* + * low level task data that entry.S needs immediate access to + * - this struct should fit entirely inside of one cache line + * - this struct shares the supervisor stack pages + * - if the contents of this structure are changed, the assembly constants + * must also be changed + */ +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + unsigned long flags; /* low level flags */ + __u32 cpu; /* current CPU */ + __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ + + mm_segment_t addr_limit; /* thread address space: + 0-0xBFFFFFFF for user-thead + 0-0xFFFFFFFF for kernel-thread + */ + struct restart_block restart_block; +}; + +#define PREEMPT_ACTIVE 0x4000000 + +/* + * macros/functions for gaining access to the thread information structure + * + * preempt_count needs to be 1 initially, until the scheduler is functional. + */ +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .preempt_count = 1, \ + .addr_limit = KERNEL_DS, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + +/* How to get the thread information struct from C. */ +register struct thread_info *__current_thread_info __asm__("$28"); +#define current_thread_info() __current_thread_info + +/* thread information allocation */ +#define THREAD_SIZE_ORDER (1) +#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define alloc_thread_info(tsk) ((struct thread_info *) \ + __get_free_pages(GFP_KERNEL,THREAD_SIZE_ORDER)) +#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_SIZE_ORDER) +#define get_thread_info(ti) get_task_struct((ti)->task) +#define put_thread_info(ti) put_task_struct((ti)->task) + +#endif /* !__ASSEMBLY__ */ + +/* + * thread information flags + * - these are process state flags that various assembly files may need to + * access + * - pending work-to-be-done flags are in LSW + * - other flags in MSW + */ +#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ +#define TIF_SIGPENDING 2 /* signal pending */ +#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ +#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ +#define TIF_SYSCALL_TRACE 31 /* syscall trace active */ + +#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) +#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) +#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) +#define _TIF_USEDFPU (1<<TIF_USEDFPU) +#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) + +#define _TIF_WORK_MASK 0x0000fffe /* work to do on + interrupt/exception return */ +#define _TIF_ALLWORK_MASK 0x8000fffe /* work to do on any return to + u-space */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_THREAD_INFO_H */ diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h index bf0cc3f84785..bc969bf65822 100644 --- a/include/asm-mips/time.h +++ b/include/asm-mips/time.h @@ -10,20 +10,17 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * + * Please refer to Documentation/mips/time.README. */ - -/* - * Please refer to Documentation/MIPS/time.README. - */ - #ifndef _ASM_TIME_H #define _ASM_TIME_H -#include <linux/ptrace.h> /* for struct pt_regs */ -#include <linux/linkage.h> /* for asmlinkage */ -#include <linux/rtc.h> /* for struct rtc_time */ +#include <linux/interrupt.h> +#include <linux/linkage.h> +#include <linux/ptrace.h> +#include <linux/rtc.h> -/* +/* * RTC ops. By default, they point a no-RTC functions. * rtc_get_time - mktime(year, mon, day, hour, min, sec) in seconds. * rtc_set_time - reverse the above translation and set time to RTC. @@ -39,7 +36,7 @@ extern int (*rtc_set_time)(unsigned long); extern void to_tm(unsigned long tim, struct rtc_time * tm); /* - * do_gettimeoffset(). By default, this func pointer points to + * do_gettimeoffset(). By default, this func pointer points to * do_null_gettimeoffset(), which leads to the same resolution as HZ. * Higher resolution versions are vailable, which gives ~1us resolution. */ @@ -53,7 +50,7 @@ extern unsigned long calibrate_div64_gettimeoffset(void); /* * high-level timer interrupt routines. */ -extern void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs); +extern irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs); /* * the corresponding low-level timer interrupt routine. diff --git a/include/asm-mips/timex.h b/include/asm-mips/timex.h index 599336a9a0c7..18254aa29713 100644 --- a/include/asm-mips/timex.h +++ b/include/asm-mips/timex.h @@ -1,5 +1,4 @@ -/* $Id: timex.h,v 1.1 1998/08/25 09:22:03 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -8,21 +7,22 @@ * * FIXME: For some of the supported machines this is dead wrong. */ -#ifndef __ASM_MIPS_TIMEX_H -#define __ASM_MIPS_TIMEX_H +#ifndef _ASM_TIMEX_H +#define _ASM_TIMEX_H + +#include <asm/mipsregs.h> -#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ +#define CLOCK_TICK_RATE 1193182 /* Underlying HZ */ #define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ #define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \ (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \ << (SHIFT_SCALE-SHIFT_HZ)) / HZ) -#ifdef __KERNEL__ /* * Standard way to access the cycle counter. * Currently only used on SMP for scheduling. * - * Only the low 32 bits are available as a continuously counting entity. + * Only the low 32 bits are available as a continuously counting entity. * But this only means we'll force a reschedule every 8 seconds or so, * which isn't an evil thing. * @@ -34,8 +34,7 @@ extern cycles_t cacheflush_time; static inline cycles_t get_cycles (void) { - return read_32bit_cp0_register(CP0_COUNT); + return read_c0_count(); } -#endif /* __KERNEL__ */ -#endif /* __ASM_MIPS_TIMEX_H */ +#endif /* _ASM_TIMEX_H */ diff --git a/include/asm-mips/tlb.h b/include/asm-mips/tlb.h index 69c0faa93194..9376fd6fffc9 100644 --- a/include/asm-mips/tlb.h +++ b/include/asm-mips/tlb.h @@ -1 +1,18 @@ +#ifndef __ASM_TLB_H +#define __ASM_TLB_H + +/* + * MIPS doesn't need any special per-pte or per-vma handling.. + */ +#define tlb_start_vma(tlb, vma) do { } while (0) +#define tlb_end_vma(tlb, vma) do { } while (0) +#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) + +/* + * .. because we flush the whole mm when it fills up. + */ +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) + #include <asm-generic/tlb.h> + +#endif /* __ASM_TLB_H */ diff --git a/include/asm-mips/tlbdebug.h b/include/asm-mips/tlbdebug.h new file mode 100644 index 000000000000..fff7a73e22d0 --- /dev/null +++ b/include/asm-mips/tlbdebug.h @@ -0,0 +1,20 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2002 by Ralf Baechle + */ +#ifndef __ASM_TLBDEBUG_H +#define __ASM_TLBDEBUG_H + +/* + * TLB debugging functions: + */ +extern void dump_tlb(int first, int last); +extern void dump_tlb_all(void); +extern void dump_tlb_wired(void); +extern void dump_tlb_addr(unsigned long addr); +extern void dump_tlb_nonwired(void); + +#endif /* __ASM_TLBDEBUG_H */ diff --git a/include/asm-mips/tlbflush.h b/include/asm-mips/tlbflush.h new file mode 100644 index 000000000000..9ce1779d413e --- /dev/null +++ b/include/asm-mips/tlbflush.h @@ -0,0 +1,55 @@ +#ifndef __ASM_TLBFLUSH_H +#define __ASM_TLBFLUSH_H + +#include <linux/config.h> +#include <linux/mm.h> + +/* + * TLB flushing: + * + * - flush_tlb_all() flushes all processes TLBs + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_range(vma, start, end) flushes a range of pages + * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables + */ +extern void local_flush_tlb_all(void); +extern void local_flush_tlb_mm(struct mm_struct *mm); +extern void local_flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end); +extern void local_flush_tlb_kernel_range(unsigned long start, + unsigned long end); +extern void local_flush_tlb_page(struct vm_area_struct *vma, + unsigned long page); +extern void local_flush_tlb_one(unsigned long vaddr); + +#ifdef CONFIG_SMP + +extern void flush_tlb_all(void); +extern void flush_tlb_mm(struct mm_struct *); +extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long, + unsigned long); +extern void flush_tlb_kernel_range(unsigned long, unsigned long); +extern void flush_tlb_page(struct vm_area_struct *, unsigned long); +extern void flush_tlb_one(unsigned long vaddr); + +#else /* CONFIG_SMP */ + +#define flush_tlb_all() local_flush_tlb_all() +#define flush_tlb_mm(mm) local_flush_tlb_mm(mm) +#define flush_tlb_range(vma,vmaddr,end) local_flush_tlb_range(vma, vmaddr, end) +#define flush_tlb_kernel_range(vmaddr,end) \ + local_flush_tlb_kernel_range(vmaddr, end) +#define flush_tlb_page(vma,page) local_flush_tlb_page(vma, page) +#define flush_tlb_one(vaddr) local_flush_tlb_one(vaddr) + +#endif /* CONFIG_SMP */ + +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* Nothing to do on MIPS. */ +} + +#endif /* __ASM_TLBFLUSH_H */ diff --git a/include/asm-mips/topology.h b/include/asm-mips/topology.h index cf224a32ba6d..592a9934af02 100644 --- a/include/asm-mips/topology.h +++ b/include/asm-mips/topology.h @@ -1,6 +1,6 @@ -#ifndef _ASM_MIPS_TOPOLOGY_H -#define _ASM_MIPS_TOPOLOGY_H +#ifndef __ASM_TOPOLOGY_H +#define __ASM_TOPOLOGY_H #include <asm-generic/topology.h> -#endif /* _ASM_MIPS_TOPOLOGY_H */ +#endif /* __ASM_TOPOLOGY_H */ diff --git a/include/asm-mips/traps.h b/include/asm-mips/traps.h new file mode 100644 index 000000000000..7f00e31e7c4f --- /dev/null +++ b/include/asm-mips/traps.h @@ -0,0 +1,26 @@ +/* + * include/asm-mips/traps.h + * + * Trap handling definitions. + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef __ASM_MIPS_TRAPS_H +#define __ASM_MIPS_TRAPS_H + +/* + * Possible status responses for a board_be_handler backend. + */ +#define MIPS_BE_DISCARD 0 /* return with no action */ +#define MIPS_BE_FIXUP 1 /* return to the fixup code */ +#define MIPS_BE_FATAL 2 /* treat as an unrecoverable error */ + +extern void (*board_be_init)(void); +extern int (*board_be_handler)(struct pt_regs *regs, int is_fixup); + +#endif /* __ASM_MIPS_TRAPS_H */ diff --git a/include/asm-mips/types.h b/include/asm-mips/types.h index d4796beca3f5..2f5d4ef94efa 100644 --- a/include/asm-mips/types.h +++ b/include/asm-mips/types.h @@ -1,5 +1,4 @@ -/* $Id: types.h,v 1.3 1999/08/18 23:37:50 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -10,6 +9,8 @@ #ifndef _ASM_TYPES_H #define _ASM_TYPES_H +#include <linux/config.h> + #ifndef __ASSEMBLY__ typedef unsigned short umode_t; @@ -34,12 +35,12 @@ typedef __signed__ long __s64; typedef unsigned long __u64; #else - + #if defined(__GNUC__) && !defined(__STRICT_ANSI__) typedef __signed__ long long __s64; typedef unsigned long long __u64; #endif - + #endif #endif /* __ASSEMBLY__ */ @@ -76,7 +77,23 @@ typedef unsigned long long u64; #endif -typedef unsigned long dma_addr_t; +#if defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR) +typedef u64 dma_addr_t; +#else +typedef u32 dma_addr_t; +#endif +typedef u64 dma64_addr_t; + +#ifdef CONFIG_64BIT_PHYS_ADDR +typedef unsigned long long phys_t; +#else +typedef unsigned long phys_t; +#endif + +#ifdef CONFIG_LBD +typedef u64 sector_t; +#define HAVE_SECTOR_T +#endif #endif /* __ASSEMBLY__ */ diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h index 06fe2da650c6..2a8833afe6dd 100644 --- a/include/asm-mips/uaccess.h +++ b/include/asm-mips/uaccess.h @@ -10,7 +10,7 @@ #define _ASM_UACCESS_H #include <linux/errno.h> -#include <linux/sched.h> +#include <linux/thread_info.h> #define STR(x) __STR(x) #define __STR(x) #x @@ -28,9 +28,9 @@ #define VERIFY_READ 0 #define VERIFY_WRITE 1 -#define get_fs() (current->thread.current_ds) #define get_ds() (KERNEL_DS) -#define set_fs(x) (current->thread.current_ds=(x)) +#define get_fs() (current_thread_info()->addr_limit) +#define set_fs(x) (current_thread_info()->addr_limit = (x)) #define segment_eq(a,b) ((a).seg == (b).seg) @@ -56,7 +56,7 @@ #define access_ok(type,addr,size) \ __access_ok(((unsigned long)(addr)),(size),__access_mask) -extern inline int verify_area(int type, const void * addr, unsigned long size) +static inline int verify_area(int type, const void * addr, unsigned long size) { return access_ok(type,addr,size) ? 0 : -EFAULT; } @@ -269,103 +269,99 @@ extern void __put_user_unknown(void); extern size_t __copy_user(void *__to, const void *__from, size_t __n); -#define __copy_to_user(to,from,n) ({ \ - void *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - __asm__ __volatile__( \ - "move\t$4, %1\n\t" \ - "move\t$5, %2\n\t" \ - "move\t$6, %3\n\t" \ - __MODULE_JAL(__copy_user) \ - "move\t%0, $6" \ - : "=r" (__cu_len) \ - : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \ - : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$15", \ - "$24", "$31","memory"); \ - __cu_len; \ +#define __invoke_copy_to_user(to,from,n) ({ \ + register void *__cu_to_r __asm__ ("$4"); \ + register const void *__cu_from_r __asm__ ("$5"); \ + register long __cu_len_r __asm__ ("$6"); \ + \ + __cu_to_r = (to); \ + __cu_from_r = (from); \ + __cu_len_r = (n); \ + __asm__ __volatile__( \ + __MODULE_JAL(__copy_user) \ + : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ + : \ + : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ + "memory"); \ + __cu_len_r; \ }) -#define __copy_from_user(to,from,n) ({ \ - void *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - __asm__ __volatile__( \ - "move\t$4, %1\n\t" \ - "move\t$5, %2\n\t" \ - "move\t$6, %3\n\t" \ - ".set\tnoreorder\n\t" \ - __MODULE_JAL(__copy_user) \ - ".set\tnoat\n\t" \ - "addu\t$1, %2, %3\n\t" \ - ".set\tat\n\t" \ - ".set\treorder\n\t" \ - "move\t%0, $6" \ - : "=r" (__cu_len) \ - : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \ - : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$15", \ - "$24", "$31","memory"); \ - __cu_len; \ +#define __copy_to_user(to,from,n) ({ \ + void *__cu_to; \ + const void *__cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, __cu_len); \ + __cu_len; \ }) -#define copy_to_user(to,from,n) ({ \ - void *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - if (access_ok(VERIFY_WRITE, __cu_to, __cu_len)) \ - __asm__ __volatile__( \ - "move\t$4, %1\n\t" \ - "move\t$5, %2\n\t" \ - "move\t$6, %3\n\t" \ - __MODULE_JAL(__copy_user) \ - "move\t%0, $6" \ - : "=r" (__cu_len) \ - : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \ - : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", \ - "$15", "$24", "$31","memory"); \ - __cu_len; \ +#define copy_to_user(to,from,n) ({ \ + void *__cu_to; \ + const void *__cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + if (access_ok(VERIFY_WRITE, __cu_to, __cu_len)) \ + __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, \ + __cu_len); \ + __cu_len; \ }) -#define copy_from_user(to,from,n) ({ \ - void *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - if (access_ok(VERIFY_READ, __cu_from, __cu_len)) \ - __asm__ __volatile__( \ - "move\t$4, %1\n\t" \ - "move\t$5, %2\n\t" \ - "move\t$6, %3\n\t" \ - ".set\tnoreorder\n\t" \ - __MODULE_JAL(__copy_user) \ - ".set\tnoat\n\t" \ - "addu\t$1, %2, %3\n\t" \ - ".set\tat\n\t" \ - ".set\treorder\n\t" \ - "move\t%0, $6" \ - : "=r" (__cu_len) \ - : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \ - : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", \ - "$15", "$24", "$31","memory"); \ - __cu_len; \ +#define __invoke_copy_from_user(to,from,n) ({ \ + register void *__cu_to_r __asm__ ("$4"); \ + register const void *__cu_from_r __asm__ ("$5"); \ + register long __cu_len_r __asm__ ("$6"); \ + \ + __cu_to_r = (to); \ + __cu_from_r = (from); \ + __cu_len_r = (n); \ + __asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ + __MODULE_JAL(__copy_user) \ + ".set\tnoat\n\t" \ + "addu\t$1, %1, %2\n\t" \ + ".set\tat\n\t" \ + ".set\treorder\n\t" \ + : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ + : \ + : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ + "memory"); \ + __cu_len_r; \ }) -extern inline __kernel_size_t +#define __copy_from_user(to,from,n) ({ \ + void *__cu_to; \ + const void *__cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \ + __cu_len); \ + __cu_len; \ +}) + +#define copy_from_user(to,from,n) ({ \ + void *__cu_to; \ + const void *__cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + if (access_ok(VERIFY_READ, __cu_from, __cu_len)) \ + __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \ + __cu_len); \ + __cu_len; \ +}) + +static inline __kernel_size_t __clear_user(void *addr, __kernel_size_t size) { __kernel_size_t res; @@ -394,7 +390,7 @@ __cl_size; }) * Returns: -EFAULT if exception before terminator, N if the entire * buffer filled, else strlen. */ -extern inline long +static inline long __strncpy_from_user(char *__to, const char *__from, long __len) { long res; @@ -412,7 +408,7 @@ __strncpy_from_user(char *__to, const char *__from, long __len) return res; } -extern inline long +static inline long strncpy_from_user(char *__to, const char *__from, long __len) { long res; @@ -431,7 +427,7 @@ strncpy_from_user(char *__to, const char *__from, long __len) } /* Returns: 0 if bad, string length+1 (memory size) of string if ok */ -extern inline long __strlen_user(const char *s) +static inline long __strlen_user(const char *s) { long res; @@ -446,7 +442,7 @@ extern inline long __strlen_user(const char *s) return res; } -extern inline long strlen_user(const char *s) +static inline long strlen_user(const char *s) { long res; @@ -462,7 +458,7 @@ extern inline long strlen_user(const char *s) } /* Returns: 0 if bad, string length+1 (memory size) of string if ok */ -extern inline long __strnlen_user(const char *s, long n) +static inline long __strnlen_user(const char *s, long n) { long res; @@ -478,7 +474,7 @@ extern inline long __strnlen_user(const char *s, long n) return res; } -extern inline long strnlen_user(const char *s, long n) +static inline long strnlen_user(const char *s, long n) { long res; @@ -500,13 +496,4 @@ struct exception_table_entry unsigned long nextinsn; }; -/* Returns 0 if exception not found and fixup.unit otherwise. */ -extern unsigned long search_exception_table(unsigned long addr); - -/* Returns the new pc */ -#define fixup_exception(map_reg, fixup_unit, pc) \ -({ \ - fixup_unit; \ -}) - #endif /* _ASM_UACCESS_H */ diff --git a/include/asm-mips/ucontext.h b/include/asm-mips/ucontext.h index db501bef0ec4..8a4b20e88b81 100644 --- a/include/asm-mips/ucontext.h +++ b/include/asm-mips/ucontext.h @@ -1,5 +1,4 @@ -/* $Id: ucontext.h,v 1.2 1999/09/27 16:01:40 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff --git a/include/asm-mips/umap.h b/include/asm-mips/umap.h deleted file mode 100644 index 940148ee2906..000000000000 --- a/include/asm-mips/umap.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __MIPS_UMAP_H -#define __MIPS_UMAP_H - -void remove_mapping (struct vm_area_struct *vma, struct task_struct *task, unsigned long start, -unsigned long end); - -#endif - diff --git a/include/asm-mips/unaligned.h b/include/asm-mips/unaligned.h index 2b0174925f22..3bd9d412f1d5 100644 --- a/include/asm-mips/unaligned.h +++ b/include/asm-mips/unaligned.h @@ -18,7 +18,7 @@ extern void __put_unaligned_bad_length(void); * This could have been implemented in plain C like IA64 but egcs 1.0.3a * inflates this to 23 instructions ... */ -extern inline unsigned long long __ldq_u(const unsigned long long * __addr) +static inline unsigned long long __ldq_u(const unsigned long long * __addr) { unsigned long long __res; @@ -33,7 +33,7 @@ extern inline unsigned long long __ldq_u(const unsigned long long * __addr) /* * Load word unaligned. */ -extern inline unsigned long __ldl_u(const unsigned int * __addr) +static inline unsigned long __ldl_u(const unsigned int * __addr) { unsigned long __res; @@ -47,7 +47,7 @@ extern inline unsigned long __ldl_u(const unsigned int * __addr) /* * Load halfword unaligned. */ -extern inline unsigned long __ldw_u(const unsigned short * __addr) +static inline unsigned long __ldw_u(const unsigned short * __addr) { unsigned long __res; @@ -61,7 +61,7 @@ extern inline unsigned long __ldw_u(const unsigned short * __addr) /* * Store doubleword ununaligned. */ -extern inline void __stq_u(unsigned long __val, unsigned long long * __addr) +static inline void __stq_u(unsigned long __val, unsigned long long * __addr) { __asm__("usw\t%1, %0\n\t" "usw\t%D1, 4+%0" @@ -72,7 +72,7 @@ extern inline void __stq_u(unsigned long __val, unsigned long long * __addr) /* * Store long ununaligned. */ -extern inline void __stl_u(unsigned long __val, unsigned int * __addr) +static inline void __stl_u(unsigned long __val, unsigned int * __addr) { __asm__("usw\t%1, %0" : "=m" (*__addr) @@ -82,7 +82,7 @@ extern inline void __stl_u(unsigned long __val, unsigned int * __addr) /* * Store word ununaligned. */ -extern inline void __stw_u(unsigned long __val, unsigned short * __addr) +static inline void __stw_u(unsigned long __val, unsigned short * __addr) { __asm__("ush\t%1, %0" : "=m" (*__addr) @@ -93,8 +93,8 @@ extern inline void __stw_u(unsigned long __val, unsigned short * __addr) * get_unaligned - get value from possibly mis-aligned location * @ptr: pointer to value * - * This macro should be used for accessing values larger in size than - * single bytes at locations that are expected to be improperly aligned, + * This macro should be used for accessing values larger in size than + * single bytes at locations that are expected to be improperly aligned, * e.g. retrieving a u16 value from a location not u16-aligned. * * Note that unaligned accesses can be very expensive on some architectures. @@ -129,8 +129,8 @@ extern inline void __stw_u(unsigned long __val, unsigned short * __addr) * @val: value to place * @ptr: pointer to location * - * This macro should be used for placing values larger in size than - * single bytes at locations that are expected to be improperly aligned, + * This macro should be used for placing values larger in size than + * single bytes at locations that are expected to be improperly aligned, * e.g. writing a u16 value to a location not u16-aligned. * * Note that unaligned accesses can be very expensive on some architectures. diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 293b93991430..cf324a06eaf1 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -4,9 +4,6 @@ * for more details. * * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle - * - * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto - * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A */ #ifndef _ASM_UNISTD_H #define _ASM_UNISTD_H @@ -30,7 +27,7 @@ #define __NR_chmod (__NR_Linux + 15) #define __NR_lchown (__NR_Linux + 16) #define __NR_break (__NR_Linux + 17) -#define __NR_oldstat (__NR_Linux + 18) +#define __NR_unused18 (__NR_Linux + 18) #define __NR_lseek (__NR_Linux + 19) #define __NR_getpid (__NR_Linux + 20) #define __NR_mount (__NR_Linux + 21) @@ -40,7 +37,7 @@ #define __NR_stime (__NR_Linux + 25) #define __NR_ptrace (__NR_Linux + 26) #define __NR_alarm (__NR_Linux + 27) -#define __NR_oldfstat (__NR_Linux + 28) +#define __NR_unused28 (__NR_Linux + 28) #define __NR_pause (__NR_Linux + 29) #define __NR_utime (__NR_Linux + 30) #define __NR_stty (__NR_Linux + 31) @@ -96,7 +93,7 @@ #define __NR_setgroups (__NR_Linux + 81) #define __NR_reserved82 (__NR_Linux + 82) #define __NR_symlink (__NR_Linux + 83) -#define __NR_oldlstat (__NR_Linux + 84) +#define __NR_unused84 (__NR_Linux + 84) #define __NR_readlink (__NR_Linux + 85) #define __NR_uselib (__NR_Linux + 86) #define __NR_swapon (__NR_Linux + 87) @@ -233,33 +230,70 @@ #define __NR_madvise (__NR_Linux + 218) #define __NR_getdents64 (__NR_Linux + 219) #define __NR_fcntl64 (__NR_Linux + 220) -#define __NR_gettid (__NR_Linux + 221) -#define __NR_tkill (__NR_Linux + 222) +#define __NR_reserved221 (__NR_Linux + 221) +#define __NR_gettid (__NR_Linux + 222) +#define __NR_readahead (__NR_Linux + 223) +#define __NR_setxattr (__NR_Linux + 224) +#define __NR_lsetxattr (__NR_Linux + 225) +#define __NR_fsetxattr (__NR_Linux + 226) +#define __NR_getxattr (__NR_Linux + 227) +#define __NR_lgetxattr (__NR_Linux + 228) +#define __NR_fgetxattr (__NR_Linux + 229) +#define __NR_listxattr (__NR_Linux + 230) +#define __NR_llistxattr (__NR_Linux + 231) +#define __NR_flistxattr (__NR_Linux + 232) +#define __NR_removexattr (__NR_Linux + 233) +#define __NR_lremovexattr (__NR_Linux + 234) +#define __NR_fremovexattr (__NR_Linux + 235) +#define __NR_tkill (__NR_Linux + 236) +#define __NR_sendfile64 (__NR_Linux + 237) +#define __NR_futex (__NR_Linux + 238) +#define __NR_sched_setaffinity (__NR_Linux + 239) +#define __NR_sched_getaffinity (__NR_Linux + 240) +#define __NR_io_setup (__NR_Linux + 241) +#define __NR_io_destroy (__NR_Linux + 242) +#define __NR_io_getevents (__NR_Linux + 243) +#define __NR_io_submit (__NR_Linux + 244) +#define __NR_io_cancel (__NR_Linux + 245) +#define __NR_exit_group (__NR_Linux + 246) +#define __NR_lookup_dcookie (__NR_Linux + 247) +#define __NR_epoll_create (__NR_Linux + 248) +#define __NR_epoll_ctl (__NR_Linux + 249) +#define __NR_epoll_wait (__NR_Linux + 250) +#define __NR_remap_file_pages (__NR_Linux + 251) +#define __NR_set_tid_address (__NR_Linux + 252) +#define __NR_restart_syscall (__NR_Linux + 253) +#define __NR_fadvise64 (__NR_Linux + 254) +#define __NR_statfs64 (__NR_Linux + 255) +#define __NR_fstatfs64 (__NR_Linux + 256) /* * Offset of the last Linux flavoured syscall */ -#define __NR_Linux_syscalls 220 +#define __NR_Linux_syscalls 256 -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ type name(void) \ { \ -long __res, __err; \ -__asm__ volatile ("li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name) \ - : "$2","$7","$8","$9","$10","$11","$12","$13","$14","$15", \ - "$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a3 asm("$7"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %2\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } /* @@ -269,189 +303,195 @@ return -1; \ #define _syscall1(type,name,atype,a) \ type name(atype a) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)) \ - : "$2","$4","$7","$8","$9","$10","$11","$12","$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a3 asm("$7"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %3\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "r" (__a0), "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall2(type,name,atype,a,btype,b) \ -type name(atype a,btype b) \ +type name(atype a, btype b) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "move\t$5,%4\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)) \ - : "$2","$4","$5","$7","$8","$9","$10","$11","$12","$13", \ - "$14","$15", "$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a3 asm("$7"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %4\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "r" (__a0), "r" (__a1), "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall3(type,name,atype,a,btype,b,ctype,c) \ -type name (atype a, btype b, ctype c) \ +type name(atype a, btype b, ctype c) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "move\t$5,%4\n\t" \ - "move\t$6,%5\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)) \ - : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \ - "$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ -type name (atype a, btype b, ctype c, dtype d) \ +type name(atype a, btype b, ctype c, dtype d) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "move\t$5,%4\n\t" \ - "move\t$6,%5\n\t" \ - "move\t$7,%6\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)) \ - : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \ - "$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } +/* + * Using those means your brain needs more than an oil change ;-) + */ + #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ -type name (atype a,btype b,ctype c,dtype d,etype e) \ +type name(atype a, btype b, ctype c, dtype d, etype e) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "move\t$5,%4\n\t" \ - "move\t$6,%5\n\t" \ - "lw\t$2,%7\n\t" \ - "move\t$7,%6\n\t" \ - "subu\t$29,24\n\t" \ - "sw\t$2,16($29)\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7\n\t" \ - "addiu\t$29,24" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)), \ - "m" ((long)(e)) \ - : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \ - "$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "lw\t$2, %6\n\t" \ + "subu\t$29, 32\n\t" \ + "sw\t$2, 16($29)\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "addiu\t$29, 32\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ + "m" ((unsigned long)e) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \ -type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \ +type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "move\t$5,%4\n\t" \ - "move\t$6,%5\n\t" \ - "lw\t$2,%7\n\t" \ - "lw\t$3,%8\n\t" \ - "move\t$7,%6\n\t" \ - "subu\t$29,24\n\t" \ - "sw\t$2,16($29)\n\t" \ - "sw\t$3,20($29)\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7\n\t" \ - "addiu\t$29,24" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)), \ - "m" ((long)(e)), \ - "m" ((long)(f)) \ - : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \ - "$12","$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "lw\t$2, %6\n\t" \ + "lw\t$8, %7\n\t" \ + "subu\t$29, 32\n\t" \ + "sw\t$2, 16($29)\n\t" \ + "sw\t$8, 20($29)\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "addiu\t$29, 32\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ + "m" ((unsigned long)e), "m" ((unsigned long)f) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall7(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f,gtype,g) \ -type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \ +type name(atype a, btype b, ctype c, dtype d, etype e, ftype f, gtype g) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "move\t$5,%4\n\t" \ - "move\t$6,%5\n\t" \ - "lw\t$2,%7\n\t" \ - "lw\t$3,%8\n\t" \ - "move\t$7,%6\n\t" \ - "subu\t$29,32\n\t" \ - "sw\t$2,16($29)\n\t" \ - "lw\t$2,%9\n\t" \ - "sw\t$3,20($29)\n\t" \ - "sw\t$2,24($29)\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7\n\t" \ - "addiu\t$29,32" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)), \ - "m" ((long)(e)), \ - "m" ((long)(f)), \ - "m" ((long)(g)) \ - : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \ - "$12","$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "lw\t$2, %6\n\t" \ + "lw\t$8, %7\n\t" \ + "lw\t$9, %8\n\t" \ + "subu\t$29, 32\n\t" \ + "sw\t$2, 16($29)\n\t" \ + "sw\t$8, 20($29)\n\t" \ + "sw\t$9, 24($29)\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "addiu\t$29, 32\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ + "m" ((unsigned long)e), "m" ((unsigned long)f), \ + "m" ((unsigned long)g), \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } + #ifdef __KERNEL_SYSCALLS__ /* @@ -478,8 +518,8 @@ 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) -#endif /* !defined (__KERNEL_SYSCALLS__) */ -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +#endif /* __KERNEL_SYSCALLS__ */ +#endif /* !__ASSEMBLY__ */ /* * "Conditional" syscalls @@ -487,6 +527,6 @@ static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) * What we want is __attribute__((weak,alias("sys_ni_syscall"))), * but it doesn't work on all toolchains, so we just do it by hand */ -#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall"); +#define cond_syscall(x) asm(".weak\t" #x "\n" #x "\t=\tsys_ni_syscall"); #endif /* _ASM_UNISTD_H */ diff --git a/include/asm-mips/user.h b/include/asm-mips/user.h index e3747e88cd19..3e55ed5466dd 100644 --- a/include/asm-mips/user.h +++ b/include/asm-mips/user.h @@ -1,8 +1,6 @@ #ifndef __ASM_MIPS_USER_H #define __ASM_MIPS_USER_H -#include <linux/ptrace.h> - #include <asm/page.h> #include <asm/reg.h> diff --git a/include/asm-mips/vga.h b/include/asm-mips/vga.h index a74df2d2d8b4..6b35cf054c79 100644 --- a/include/asm-mips/vga.h +++ b/include/asm-mips/vga.h @@ -3,18 +3,17 @@ * * (c) 1998 Martin Mares <mj@ucw.cz> */ - -#ifndef _LINUX_ASM_VGA_H_ -#define _LINUX_ASM_VGA_H_ +#ifndef _ASM_VGA_H +#define _ASM_VGA_H /* * On the PC, we can just recalculate addresses and then * access the videoram directly without any black magic. */ -#define VGA_MAP_MEM(x) ((unsigned long)0xb0000000 + (unsigned long)(x)) +#define VGA_MAP_MEM(x) (0xb0000000L + (unsigned long)(x)) -#define vga_readb(x) (*(x)) -#define vga_writeb(x,y) (*(y) = (x)) +#define vga_readb(x) (*(x)) +#define vga_writeb(x,y) (*(y) = (x)) -#endif +#endif /* _ASM_VGA_H */ diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h new file mode 100644 index 000000000000..a62c7d63240e --- /dev/null +++ b/include/asm-mips/war.h @@ -0,0 +1,132 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2002 by Ralf Baechle + */ +#ifndef _ASM_WAR_H +#define _ASM_WAR_H + +#include <linux/config.h> + +/* + * Pleassures of the R4600 V1.x. Cite from the IDT R4600 V1.7 errata: + * + * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, + * Hit_Invalidate_D and Create_Dirty_Excl_D should only be + * executed if there is no other dcache activity. If the dcache is + * accessed for another instruction immeidately preceding when these + * cache instructions are executing, it is possible that the dcache + * tag match outputs used by these cache instructions will be + * incorrect. These cache instructions should be preceded by at least + * four instructions that are not any kind of load or store + * instruction. + * + * This is not allowed: lw + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + * + * This is allowed: lw + * nop + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + * + * #define R4600_V1_HIT_CACHEOP_WAR 1 + */ + + +/* + * Writeback and invalidate the primary cache dcache before DMA. + * + * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, + * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only + * operate correctly if the internal data cache refill buffer is empty. These + * CACHE instructions should be separated from any potential data cache miss + * by a load instruction to an uncached address to empty the response buffer." + * (Revision 2.0 device errata from IDT available on http://www.idt.com/ + * in .pdf format.) + * + * #define R4600_V2_HIT_CACHEOP_WAR 1 + */ + +/* + * R4600 CPU modules for the Indy come with both V1.7 and V2.0 processors. + */ +#ifdef CONFIG_SGI_IP22 + +#define R4600_V1_HIT_CACHEOP_WAR 1 +#define R4600_V2_HIT_CACHEOP_WAR 1 + +#endif + +/* + * But the RM200C seems to have been shipped only with V2.0 R4600s + */ +#ifdef CONFIG_SNI_RM200_PCI + +#define R4600_V2_HIT_CACHEOP_WAR 1 + +#endif + +#ifdef CONFIG_CPU_R5432 + +/* + * When an interrupt happens on a CP0 register read instruction, CPU may + * lock up or read corrupted values of CP0 registers after it enters + * the exception handler. + * + * This workaround makes sure that we read a "safe" CP0 register as the + * first thing in the exception handler, which breaks one of the + * pre-conditions for this problem. + */ +#define R5432_CP0_INTERRUPT_WAR 1 + +#endif + +#if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \ + defined(CONFIG_SB1_PASS_2_WORKAROUNDS) + +/* + * Workaround for the Sibyte M3 errata the text of which can be found at + * + * http://sibyte.broadcom.com/hw/bcm1250/docs/pass2errata.txt + * + * This will enable the use of a special TLB refill handler which does a + * consistency check on the information in c0_badvaddr and c0_entryhi and + * will just return and take the exception again if the information was + * found to be inconsistent. + */ +#define BCM1250_M3_WAR 1 + +/* + * This is a DUART workaround related to glitches around register accesses + */ +#define SIBYTE_1956_WAR 1 + +#endif + +/* + * Workarounds default to off + */ +#ifndef R4600_V1_HIT_CACHEOP_WAR +#define R4600_V1_HIT_CACHEOP_WAR 0 +#endif +#ifndef R4600_V2_HIT_CACHEOP_WAR +#define R4600_V2_HIT_CACHEOP_WAR 0 +#endif +#ifndef R5432_CP0_INTERRUPT_WAR +#define R5432_CP0_INTERRUPT_WAR 0 +#endif +#ifndef BCM1250_M3_WAR +#define BCM1250_M3_WAR 0 +#endif +#ifndef SIBYTE_1956_WAR +#define SIBYTE_1956_WAR 0 +#endif + +#endif /* _ASM_WAR_H */ diff --git a/include/asm-mips/watch.h b/include/asm-mips/watch.h index 7945e0b2fef3..337d8af54261 100644 --- a/include/asm-mips/watch.h +++ b/include/asm-mips/watch.h @@ -18,20 +18,18 @@ enum wref_type { wr_load = 2 }; -extern char watch_available; - extern asmlinkage void __watch_set(unsigned long addr, enum wref_type ref); extern asmlinkage void __watch_clear(void); extern asmlinkage void __watch_reenable(void); #define watch_set(addr, ref) \ - if (watch_available) \ + if (cpu_has_watch) \ __watch_set(addr, ref) #define watch_clear() \ - if (watch_available) \ + if (cpu_has_watch) \ __watch_clear() #define watch_reenable() \ - if (watch_available) \ + if (cpu_has_watch) \ __watch_reenable() #endif /* __ASM_WATCH_H */ diff --git a/include/asm-mips/wbflush.h b/include/asm-mips/wbflush.h index 0d9c9a8683e0..8aac7ea7b6fa 100644 --- a/include/asm-mips/wbflush.h +++ b/include/asm-mips/wbflush.h @@ -6,31 +6,30 @@ * for more details. * * Copyright (c) 1998 Harald Koerfgen - * - * $Id: wbflush.h,v 1.2 1999/08/13 17:07:28 harald Exp $ + * Copyright (C) 2002 Maciej W. Rozycki */ #ifndef __ASM_MIPS_WBFLUSH_H #define __ASM_MIPS_WBFLUSH_H #include <linux/config.h> -#if defined(CONFIG_CPU_HAS_WB) -/* - * R2000 or R3000 - */ -extern void (*__wbflush) (void); +#ifdef CONFIG_CPU_HAS_WB + +extern void (*__wbflush)(void); +extern void wbflush_setup(void); -#define wbflush() __wbflush() +#define wbflush() \ + do { \ + __sync(); \ + __wbflush(); \ + } while (0) -#else -/* - * we don't need no stinkin' wbflush - */ +#else /* !CONFIG_CPU_HAS_WB */ -#define wbflush() do { } while(0) +#define wbflush_setup() do { } while (0) -#endif +#define wbflush() fast_iob() -extern void wbflush_setup(void); +#endif /* !CONFIG_CPU_HAS_WB */ #endif /* __ASM_MIPS_WBFLUSH_H */ |
