diff options
Diffstat (limited to 'include/asm-mips')
52 files changed, 3866 insertions, 1749 deletions
diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h index afb189d63..20dd39cb6 100644 --- a/include/asm-mips/asm.h +++ b/include/asm-mips/asm.h @@ -5,7 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 1996 by Ralf Baechle + * Copyright (C) 1995, 1996, 1997 by Ralf Baechle * * Some useful macros for MIPS assembler code * @@ -131,23 +131,6 @@ symbol = value .text /* - * Return from exception - */ -#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) -#define ERET rfe -#endif -#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS5) -#define ERET \ - eret; \ - nop; \ - nop; \ - nop; \ - nop; \ - nop -#endif - -/* * MIPS IV pref instruction. * Use with .set noreorder only! * diff --git a/include/asm-mips/asmmacro.h b/include/asm-mips/asmmacro.h new file mode 100644 index 000000000..e48f759ca --- /dev/null +++ b/include/asm-mips/asmmacro.h @@ -0,0 +1,115 @@ +/* $Id: asmmacro.h,v 1.4 1996/06/29 12:41:13 dm Exp $ + * asmmacro.h: Assembler macros to make things easier to read. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ + +#ifndef __MIPS_ASMMACRO_H +#define __MIPS_ASMMACRO_H + +#include <asm/offset.h> + +#define FPU_SAVE_16ODD(thread) \ + swc1 $f1, (THREAD_FPU + 0x08)(thread); \ + swc1 $f3, (THREAD_FPU + 0x18)(thread); \ + swc1 $f5, (THREAD_FPU + 0x28)(thread); \ + swc1 $f7, (THREAD_FPU + 0x38)(thread); \ + swc1 $f9, (THREAD_FPU + 0x48)(thread); \ + swc1 $f11, (THREAD_FPU + 0x58)(thread); \ + swc1 $f13, (THREAD_FPU + 0x68)(thread); \ + swc1 $f15, (THREAD_FPU + 0x78)(thread); \ + swc1 $f17, (THREAD_FPU + 0x88)(thread); \ + swc1 $f19, (THREAD_FPU + 0x98)(thread); \ + swc1 $f21, (THREAD_FPU + 0xa8)(thread); \ + swc1 $f23, (THREAD_FPU + 0xb8)(thread); \ + swc1 $f25, (THREAD_FPU + 0xc8)(thread); \ + swc1 $f27, (THREAD_FPU + 0xd8)(thread); \ + swc1 $f29, (THREAD_FPU + 0xe8)(thread); \ + swc1 $f31, (THREAD_FPU + 0xf8)(thread); + + +#define FPU_RESTORE_16ODD(thread) \ + lwc1 $f1, (THREAD_FPU + 0x08)(thread); \ + lwc1 $f3, (THREAD_FPU + 0x18)(thread); \ + lwc1 $f5, (THREAD_FPU + 0x28)(thread); \ + lwc1 $f7, (THREAD_FPU + 0x38)(thread); \ + lwc1 $f9, (THREAD_FPU + 0x48)(thread); \ + lwc1 $f11, (THREAD_FPU + 0x58)(thread); \ + lwc1 $f13, (THREAD_FPU + 0x68)(thread); \ + lwc1 $f15, (THREAD_FPU + 0x78)(thread); \ + lwc1 $f17, (THREAD_FPU + 0x88)(thread); \ + lwc1 $f19, (THREAD_FPU + 0x98)(thread); \ + lwc1 $f21, (THREAD_FPU + 0xa8)(thread); \ + lwc1 $f23, (THREAD_FPU + 0xb8)(thread); \ + lwc1 $f25, (THREAD_FPU + 0xc8)(thread); \ + lwc1 $f27, (THREAD_FPU + 0xd8)(thread); \ + lwc1 $f29, (THREAD_FPU + 0xe8)(thread); \ + lwc1 $f31, (THREAD_FPU + 0xf8)(thread); + +#define FPU_SAVE_16EVEN(thread, tmp) \ + cfc1 tmp, fcr31; \ + swc1 $f2, (THREAD_FPU + 0x010)(thread); \ + swc1 $f4, (THREAD_FPU + 0x020)(thread); \ + swc1 $f6, (THREAD_FPU + 0x030)(thread); \ + swc1 $f8, (THREAD_FPU + 0x040)(thread); \ + swc1 $f10, (THREAD_FPU + 0x050)(thread); \ + swc1 $f12, (THREAD_FPU + 0x060)(thread); \ + swc1 $f14, (THREAD_FPU + 0x070)(thread); \ + swc1 $f16, (THREAD_FPU + 0x080)(thread); \ + swc1 $f18, (THREAD_FPU + 0x090)(thread); \ + swc1 $f20, (THREAD_FPU + 0x0a0)(thread); \ + swc1 $f22, (THREAD_FPU + 0x0b0)(thread); \ + swc1 $f24, (THREAD_FPU + 0x0c0)(thread); \ + swc1 $f26, (THREAD_FPU + 0x0d0)(thread); \ + swc1 $f28, (THREAD_FPU + 0x0e0)(thread); \ + swc1 $f30, (THREAD_FPU + 0x0f0)(thread); \ + sw tmp, (THREAD_FPU + 0x100)(thread); + + +#define FPU_RESTORE_16EVEN(thread, tmp) \ + lw tmp, (THREAD_FPU + 0x100)(thread); \ + lwc1 $f2, (THREAD_FPU + 0x010)(thread); \ + lwc1 $f4, (THREAD_FPU + 0x020)(thread); \ + lwc1 $f6, (THREAD_FPU + 0x030)(thread); \ + lwc1 $f8, (THREAD_FPU + 0x040)(thread); \ + lwc1 $f10, (THREAD_FPU + 0x050)(thread); \ + lwc1 $f12, (THREAD_FPU + 0x060)(thread); \ + lwc1 $f14, (THREAD_FPU + 0x070)(thread); \ + lwc1 $f16, (THREAD_FPU + 0x080)(thread); \ + lwc1 $f18, (THREAD_FPU + 0x090)(thread); \ + lwc1 $f20, (THREAD_FPU + 0x0a0)(thread); \ + lwc1 $f22, (THREAD_FPU + 0x0b0)(thread); \ + lwc1 $f24, (THREAD_FPU + 0x0c0)(thread); \ + lwc1 $f26, (THREAD_FPU + 0x0d0)(thread); \ + lwc1 $f28, (THREAD_FPU + 0x0e0)(thread); \ + lwc1 $f30, (THREAD_FPU + 0x0f0)(thread); \ + ctc1 tmp, fcr31; + +#define CPU_SAVE_NONSCRATCH(thread) \ + sw s0, THREAD_REG16(thread); \ + sw s1, THREAD_REG17(thread); \ + sw s2, THREAD_REG18(thread); \ + sw s3, THREAD_REG19(thread); \ + sw s4, THREAD_REG20(thread); \ + sw s5, THREAD_REG21(thread); \ + sw s6, THREAD_REG22(thread); \ + sw s7, THREAD_REG23(thread); \ + sw gp, THREAD_REG28(thread); \ + sw sp, THREAD_REG29(thread); \ + sw fp, THREAD_REG30(thread); + +#define CPU_RESTORE_NONSCRATCH(thread) \ + lw s0, THREAD_REG16(thread); \ + lw s1, THREAD_REG17(thread); \ + lw s2, THREAD_REG18(thread); \ + lw s3, THREAD_REG19(thread); \ + lw s4, THREAD_REG20(thread); \ + lw s5, THREAD_REG21(thread); \ + lw s6, THREAD_REG22(thread); \ + lw s7, THREAD_REG23(thread); \ + lw gp, THREAD_REG28(thread); \ + lw sp, THREAD_REG29(thread); \ + lw fp, THREAD_REG30(thread); \ + lw ra, THREAD_REG31(thread); + +#endif /* !(__MIPS_ASMMACRO_H) */ diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 4a7f8ab89..53de94227 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h @@ -10,7 +10,25 @@ #ifndef __ASM_MIPS_BITOPS_H #define __ASM_MIPS_BITOPS_H +#ifdef __KERNEL__ + #include <asm/sgidefs.h> +#include <asm/system.h> + +/* + * Only disable interrupt for kernel mode stuff to keep usermode stuff + * that dares to use kernel include files alive. + */ +#define __flags unsigned long flags +#define __cli() cli() +#define __save_flags(x) save_flags(x) +#define __restore_flags(x) restore_flags(x) +#else +#define __flags +#define __cli() +#define __save_flags(x) +#define __restore_flags(x) +#endif /* __KERNEL__ */ /* * Note that the bit operations are defined on arrays of 32 bit sized @@ -21,7 +39,9 @@ extern __inline__ int set_bit(int nr, void *addr); extern __inline__ int clear_bit(int nr, void *addr); extern __inline__ int change_bit(int nr, void *addr); extern __inline__ int test_bit(int nr, const void *addr); +#ifndef __MIPSEB__ extern __inline__ int find_first_zero_bit (void *addr, unsigned size); +#endif extern __inline__ int find_next_zero_bit (void * addr, int size, int offset); extern __inline__ unsigned long ffz(unsigned long word); @@ -46,8 +66,7 @@ extern __inline__ int set_bit(int nr, void *addr) do { mw = load_linked(addr); retval = (mask & mw) != 0; - } - while (!store_conditional(addr, mw|mask)); + } while (!store_conditional(addr, mw|mask)); return retval; } @@ -76,37 +95,13 @@ extern __inline__ int change_bit(int nr, void *addr) do { mw = load_linked(addr); retval = (mask & mw) != 0; - } - while (!store_conditional(addr, mw ^ mask)); + } while (!store_conditional(addr, mw ^ mask)); return retval; } #else /* MIPS I */ -#ifdef __KERNEL__ -/* - * These functions are only used for MIPS ISA 1 CPUs. Since I don't - * believe that someone ever will run Linux/SMP on such a beast I don't - * worry about making them SMP proof. - */ -#include <asm/system.h> - -/* - * Only disable interrupt for kernel mode stuff to keep usermode stuff - * that dares to use kernel include files alive. - */ -#define __flags unsigned long flags -#define __cli() cli() -#define __save_flags(x) save_flags(x) -#define __restore_flags(x) restore_flags(x) -#else -#define __flags -#define __cli() -#define __save_flags(x) -#define __restore_flags(x) -#endif /* __KERNEL__ */ - extern __inline__ int set_bit(int nr, void * addr) { int mask, retval; @@ -170,6 +165,10 @@ extern __inline__ int test_bit(int nr, const void *addr) return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0; } +#ifndef __MIPSEB__ + +/* Little endian versions. */ + extern __inline__ int find_first_zero_bit (void *addr, unsigned size) { unsigned long dummy; @@ -259,6 +258,8 @@ extern __inline__ int find_next_zero_bit (void * addr, int size, int offset) return offset + set + res; } +#endif /* !(__MIPSEB__) */ + /* * ffz = Find First Zero in word. Undefined if no zero exists, * so code should check against ~0UL first.. @@ -287,17 +288,167 @@ extern __inline__ unsigned long ffz(unsigned long word) return __res; } -#ifdef __KERNEL__ #ifdef __MIPSEB__ -#error "Aieee... fix these sources for big endian machines" -#endif /* __MIPSEB__ */ +/* For now I steal the Sparc C versions, no need for speed, just need to + * get it working. + */ +/* find_next_zero_bit() finds the first zero bit in a bit string of length + * 'size' bits, starting the search at bit 'offset'. This is largely based + * on Linus's ALPHA routines, which are pretty portable BTW. + */ -#define ext2_set_bit set_bit -#define ext2_clear_bit clear_bit -#define ext2_test_bit test_bit -#define ext2_find_first_zero_bit find_first_zero_bit -#define ext2_find_next_zero_bit find_next_zero_bit +extern __inline__ int find_next_zero_bit(void *addr, int size, int offset) +{ + unsigned long *p = ((unsigned long *) addr) + (offset >> 5); + unsigned long result = offset & ~31UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if (offset) { + tmp = *(p++); + tmp |= ~0UL >> (32-offset); + if (size < 32) + goto found_first; + if (~tmp) + goto found_middle; + size -= 32; + result += 32; + } + while (size & ~31UL) { + if (~(tmp = *(p++))) + goto found_middle; + result += 32; + size -= 32; + } + if (!size) + return result; + tmp = *p; -#endif /* __KERNEL__ */ +found_first: + tmp |= ~0UL << size; +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) + +#endif /* (__MIPSEB__) */ + +/* Now for the ext2 filesystem bit operations and helper routines. */ + +#ifdef __MIPSEB__ +extern __inline__ int ext2_set_bit(int nr,void * addr) +{ + int mask, retval, flags; + unsigned char *ADDR = (unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + save_flags(flags); cli(); + retval = (mask & *ADDR) != 0; + *ADDR |= mask; + restore_flags(flags); + return retval; +} + +extern __inline__ int ext2_clear_bit(int nr, void * addr) +{ + int mask, retval, flags; + unsigned char *ADDR = (unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + save_flags(flags); cli(); + retval = (mask & *ADDR) != 0; + *ADDR &= ~mask; + restore_flags(flags); + return retval; +} + +extern __inline__ int ext2_test_bit(int nr, const void * addr) +{ + int mask; + const unsigned char *ADDR = (const unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + return ((mask & *ADDR) != 0); +} + +#define ext2_find_first_zero_bit(addr, size) \ + ext2_find_next_zero_bit((addr), (size), 0) + +static __inline__ unsigned long __swab32(unsigned long val) +{ + return ((val>>24)|((val>>8)&0xff00)|((val<<8)&0xff0000)|(val<<24)); +} + +extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) +{ + unsigned long *p = ((unsigned long *) addr) + (offset >> 5); + unsigned long result = offset & ~31UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if(offset) { + /* 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) + goto found_first; + if(~tmp) + goto found_middle; + size -= 32; + result += 32; + } + while(size & ~31UL) { + if(~(tmp = *(p++))) + goto found_middle; + result += 32; + size -= 32; + } + if(!size) + return result; + tmp = *p; + +found_first: + /* tmp 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)); +found_middle: + return result + ffz(__swab32(tmp)); +} +#else /* !(__MIPSEB__) */ + +/* Native ext2 byte ordering, just collapse using defines. */ +#define ext2_set_bit(nr, addr) set_bit((nr), (addr)) +#define ext2_clear_bit(nr, addr) 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 #endif /* __ASM_MIPS_BITOPS_H */ diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index a7e712b96..7388b34d0 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -11,16 +11,41 @@ #ifndef __ASM_MIPS_BOOTINFO_H #define __ASM_MIPS_BOOTINFO_H +/* XXX */ +#include <linux/config.h> + +#if 0 +/* + * Valid machtype values + * FIXME: note that we really need a hierarchy for this stuff, as there are + * several models of DECStation (for example). PMA + */ +#define MACH_UNKNOWN 0 /* whatever... */ +#define MACH_DESKSTATION_RPC44 1 /* Deskstation rPC44 */ +#define MACH_DESKSTATION_TYNE 2 /* Deskstation Tyne */ +#define MACH_ACER_PICA_61 3 /* Acer PICA-61 (PICA1) */ +#define MACH_MIPS_MAGNUM_4000 4 /* Mips Magnum 4000 "RC4030" */ +#define MACH_OLIVETTI_M700 4 /* almost a clone ... */ +#define MACH_DECSTATION 5 /* DECStation 5000/2x for now */ +#define MACH_SNI_RM200_PCI 6 /* RM200/RM300/RM400 PCI series */ +#define MACH_SGI_INDY 7 /* R4?K and R5K Indy workstaions */ +#define MACH_LAST 7 + +#define MACH_NAMES {"unknown", "Deskstation rPC44", "Deskstation Tyne", \ + "Acer PICA 61", "Mips Magnum 4000", "DECStation", "RM200 PCI", \ + "SGI INDY" } +#endif + /* - * Valid machgroup values + * Values for machgroup */ -#define MACH_GROUP_UNKNOWN 0 /* whatever... */ -#define MACH_GROUP_JAZZ 1 /* Acer Pica 61, Mips Magnum 4000, Olivetti */ - /* M700-10 */ -#define MACH_GROUP_DEC 2 /* Digital */ -#define MACH_GROUP_ARC 3 /* Deskstation Tyne, rpc44, possibly other */ -#define MACH_GROUP_SNI_RM 4 /* Siemens Nixdorf RM series */ +#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_ACN 5 +#define MACH_GROUP_SGI 6 /* Silicon Graphics workstations and servers */ #define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", "SNI", "ACN" } @@ -58,20 +83,25 @@ #define GROUP_ARC_NAMES { "Deskstation rPC44", "Deskstation Tyne" } /* - * Valid machtype for group SNI_RM + * 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 SNI_RM + * Valid machtype for group ACN */ -#define MACH_ACN_MIPS_BOARD 0 /* ACN MIPS single board */ +#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 workstaions */ + +/* * Valid cputype values */ #define CPU_UNKNOWN 0 @@ -101,7 +131,7 @@ #define CPU_R5000 24 #define CPU_R5000A 25 #define CPU_R4640 26 -#define CPU_LAST 26 +#define CPU_LAST 27 #define CPU_NAMES { "unknown", "R2000", "R3000", "R3000A", "R3041", "R3051", \ "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC", \ @@ -123,12 +153,11 @@ struct drive_info_struct { /* 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; +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; /* @@ -136,8 +165,6 @@ typedef struct mips_arc_DisplayInfo /* video adapter information */ * * Add new tags only at the end of the enum; *never* remove any tags * or you'll break compatibility! - * Which compatibility ? compatibility consideration lead to - * MS-DOG :) -Stoned */ enum bi_tag { /* @@ -191,8 +218,7 @@ enum bi_tag { /* * Boot flags for the kernel */ - tag_mount_root_rdonly, /* No longer used; use "ro" command - line argument instead. */ + tag_mount_root_rdonly, tag_drive_info, /* @@ -216,7 +242,6 @@ enum bi_tag { * tag to pass a complete struct screen_info */ tag_screen_info - }; /* struct defining a tag */ @@ -242,7 +267,9 @@ typedef struct { #define DRVINFOSIZE (sizeof(struct drive_info_struct)) #define CMDLINESIZE (sizeof(char[CL_SIZE]) -/* For tag readers aka the kernel */ +/* + * For tag readers aka the kernel + */ tag *bi_TagFind(enum bi_tag type); void bi_EarlySnarf(void); @@ -252,11 +279,22 @@ int bi_TagAdd(enum bi_tag type, unsigned long size, void *data); int bi_TagAddList(tag_def* taglist); void bi_TagWalk(void); + +#ifdef CONFIG_SGI + +/* screen info will dissapear... soon */ +#define DEFAULT_SCREEN_INFO {0, 0, {0, 0, }, 0, 0, 158, 0, 0, 0, 62, 0, 16} + +#else + /* default values for screen_info variable */ #define DEFAULT_SCREEN_INFO {0, 0, {0, }, 52, 3, 80, 4626, 3, 9, 50} /* default values for drive info */ #define DEFAULT_DRIVE_INFO { {0,}} +#endif + + /* * These are the kernel variables initialized from * the tag. And they have to be initialized to dummy/default diff --git a/include/asm-mips/branch.h b/include/asm-mips/branch.h index abca807ec..08dda213e 100644 --- a/include/asm-mips/branch.h +++ b/include/asm-mips/branch.h @@ -5,7 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996 by Ralf Baechle + * Copyright (C) 1996, 1997 by Ralf Baechle */ #include <asm/ptrace.h> diff --git a/include/asm-mips/byteorder.h b/include/asm-mips/byteorder.h index bf4c54a1f..92e3b8863 100644 --- a/include/asm-mips/byteorder.h +++ b/include/asm-mips/byteorder.h @@ -5,7 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 1996 by Ralf Baechle + * Copyright (C) 1995, 1996, 1997 by Ralf Baechle */ #ifndef __ASM_MIPS_BYTEORDER_H #define __ASM_MIPS_BYTEORDER_H diff --git a/include/asm-mips/cache.h b/include/asm-mips/cacheops.h index 7add64caa..66b0b361f 100644 --- a/include/asm-mips/cache.h +++ b/include/asm-mips/cacheops.h @@ -1,14 +1,14 @@ /* - * Defines related to MIPS caches. + * Cache operations for the cache instruction. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * (C) Copyright 1996 by Ralf Baechle + * (C) Copyright 1996, 1997 by Ralf Baechle */ -#ifndef __ASM_MIPS_CACHE -#define __ASM_MIPS_CACHE +#ifndef __ASM_MIPS_CACHEOPS_H +#define __ASM_MIPS_CACHEOPS_H /* * Cache Operations @@ -44,24 +44,4 @@ #define Hit_Set_Virtual_SI 0x1e #define Hit_Set_Virtual_SD 0x1f -/* - * Flags for internal cacheflush call - * FIXME: CF_DMA is not implemented yet. - */ -#define CF_ICACHE (1<<0) /* flush instruction cache */ -#define CF_DCACHE (1<<1) /* writeback and flush data cache */ -#define CF_BCACHE (CF_ICACHE|CF_DCACHE) /* writeback and flush data cache */ -#define CF_VIRTUAL (1<<2) /* operate only on virtual caches */ -#define CF_PHYSICAL (1<<4) /* operate only on physical caches */ -#define CF_ALL (CF_VIRTUAL|CF_PHYSICAL)/* work on all cache types */ -#define CF_DMA (1<<5) /* Do DMA cache maintenance */ - -#ifndef __LANGUAGE_ASSEMBLY__ - -#include <linux/linkage.h> - -extern void (*mips_cache_init)(void); -extern asmlinkage void (*cacheflush)(unsigned long addr, unsigned long nbytes, unsigned int flags); - -#endif /* !__LANGUAGE_ASSEMBLY__ */ -#endif /* __ASM_MIPS_CACHE */ +#endif /* __ASM_MIPS_CACHEOPS_H */ diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h index 08dd07707..f6423ecce 100644 --- a/include/asm-mips/checksum.h +++ b/include/asm-mips/checksum.h @@ -148,7 +148,13 @@ static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, nor %0,$0,%0 .set at" : "=r" (sum) - : "0" (daddr), "r"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum) + : "0" (daddr), "r"(saddr), +#ifdef __MIPSEL__ + "r" ((ntohs(len)<<16)+proto*256), +#else + "r" (((proto)<<16)+len), +#endif + "r"(sum) : "$1"); return (unsigned short)sum; @@ -185,7 +191,7 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, unsigned short proto, unsigned int sum) { - __asm__(" + __asm__(" .set noreorder .set noat addu %0,%5 # proto (long in network byte order) @@ -234,13 +240,12 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, addu %0,%1 sltu $1,%0,$1 .set noat - .set noreorder - " - : "=r" (sum), + .set noreorder" + : "=r" (sum), "=r" (proto) - : "r" (saddr), + : "r" (saddr), "r" (daddr), - "0" (htonl((__u32) (len))), + "0" (htonl((__u32) (len))), "1" (htonl(proto)), "r"(sum) : "$1"); diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h new file mode 100644 index 000000000..b93af21c8 --- /dev/null +++ b/include/asm-mips/cpu.h @@ -0,0 +1,36 @@ +/* $Id: cpu.h,v 1.1 1996/06/23 09:38:33 dm Exp $ + * cpu.h: Values of the PRId register used to match up + * various MIPS cpu types. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#ifndef _MIPS_CPU_H +#define _MIPS_CPU_H + +/* + * Assigned values for the product ID register. In order to detect a + * certain CPU type exactly eventually additional registers may need to + * be examined. + */ +#define PRID_IMP_R2000 0x0100 +#define PRID_IMP_R3000 0x0200 +#define PRID_IMP_R6000 0x0300 +#define PRID_IMP_R4000 0x0400 +#define PRID_IMP_R6000A 0x0600 +#define PRID_IMP_R10000 0x0900 +#define PRID_IMP_R4300 0x0b00 +#define PRID_IMP_R8000 0x1000 +#define PRID_IMP_R4600 0x2000 +#define PRID_IMP_R4700 0x2100 +#define PRID_IMP_R4640 0x2200 +#define PRID_IMP_R4650 0x2200 +#define PRID_IMP_R5000 0x2300 +#define PRID_IMP_SONIC 0x2400 +#define PRID_IMP_UNKNOWN 0xff00 + +#define PRID_REV_R4400 0x0040 +#define PRID_REV_R3000A 0x0030 +#define PRID_REV_R3000 0x0020 +#define PRID_REV_R2000A 0x0010 + +#endif /* !(_MIPS_CPU_H) */ diff --git a/include/asm-mips/dec/decstation.h b/include/asm-mips/dec/decstation.h deleted file mode 100644 index cae4302d2..000000000 --- a/include/asm-mips/dec/decstation.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * General info common to all DECstation systems - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions - * are by curteousy of Chris Fraser. - * - * This file is under construction - you were warned! - */ - -#ifndef __ASM_DEC_DECSTATION_H -#define __ASM_DEC_DECSTATION_H - -/* - * REX functions -- these are for the new TURBOchannel style ROMs - */ -#define REX_PROM_MAGIC 0x30464354 /* passed in a2 */ - -#define REX_GETBITMAP 0x84 /* get mem bitmap */ -#define REX_GETCHAR 0x24 /* getch() */ -#define REX_PUTCHAR 0x13 /* putch() */ -#define REX_HALT 0x9c /* halt the system */ -#define REX_PRINTF 0x30 /* printf() */ -#define REX_PUTS 0x2c /* puts() */ -#define REX_SLOTADDR 0x6c /* slotaddr */ -#define REX_GETENV 0x64 /* get env. variable */ -#define REX_GETSYSID 0x80 /* get system id */ -#define REX_OPEN 0x54 /* open() */ -#define REX_READ 0x58 /* read() */ - - - -#ifndef __LANGUAGE_ASSEMBLY__ - -/* - * A structure to allow calling of the various DEC boot prom routines. - * FIXME: Don't know how well different DECStation boot prom revisions - * are accomodated. - */ -struct dec_prom { - void (*dec_prom_printf)(char *format, ...); - char *(*dec_prom_getenv)(char *name); - unsigned long (*dec_prom_getbitmap)(void); - unsigned long (*dec_prom_getsysid)(void); - char *(*dec_prom_gets)(char *s); - void (*dec_prom_halt)(const unsigned int); -}; - -#endif - -#endif /* __ASM_DEC_DECSTATION_H */ diff --git a/include/asm-mips/dec/kn02.h b/include/asm-mips/dec/kn02.h deleted file mode 100644 index 61df7b512..000000000 --- a/include/asm-mips/dec/kn02.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Hardware info about DEC DECstation 5000/2xx systems (otherwise known - * as 3max or kn02. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions - * are by curteousy of Chris Fraser. - * - * This file is under construction - you were warned! - */ -#include <asm/segment.h> -#ifndef __ASM_MIPS_PMAX_H -#define __ASM_MIPS_PMAX_H - -/* - * The addresses below are virtual address. The mappings are - * created on startup via wired entries in the tlb. - */ - -#define PMAX_LOCAL_IO_SPACE 0xe0000000 - -/* - * Motherboard regs (kseg1 addresses) - */ -#define PMAX_SSR_ADDR KSEG1ADDR(0x1ff00000) /* system control & status reg */ - -/* - * SSR defines - */ -#define PMAX_SSR_LEDMASK 0x0000001000 /* diagnostic LED */ - -#ifndef __LANGUAGE_ASSEMBLY__ - -extern __inline__ void pmax_set_led(unsigned int bits) -{ - volatile unsigned int *led_register = (unsigned int *) PMAX_SSR_ADDR; - - *led_register = bits & PMAX_SSR_LEDMASK; -} - -#endif - -/* - * Some port addresses... - * FIXME: these addresses are incomplete and need tidying up! - */ -#define PMAX_RTC_BASE (KSEG1ADDR(0x1fe80000 + 0x200000)) /* ASIC + SL8 */ - -#endif /* __ASM_MIPS_PMAX_H */ diff --git a/include/asm-mips/dec/maxine.h b/include/asm-mips/dec/maxine.h deleted file mode 100644 index 3f908d5fb..000000000 --- a/include/asm-mips/dec/maxine.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Hardware info about DEC Personal DECStation systems (otherwise known - * as maxine (internal DEC codename). - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions - * are by curteousy of Chris Fraser. - * - * This file is under construction - you were warned! - */ - -#ifndef __ASM_DEC_MAXINE_H -#define __ASM_DEC_MAXINE_H - -/* - * The addresses below are virtual address. The mappings are - * created on startup via wired entries in the tlb. - */ - -#define PMAX_LOCAL_IO_SPACE 0xe0000000 - -/* - * Motherboard regs (kseg1 addresses) - */ -#define PMAX_SSR_ADDR KSEG1ADDR(0x1c040100) /* system support reg */ - -/* - * SSR defines - */ -#define PMAX_SSR_LEDMASK 0x00000001 /* power LED */ - -#ifndef __LANGUAGE_ASSEMBLY__ - -extern __inline__ void pmax_set_led(unsigned int bits) -{ - volatile unsigned int *led_register = (unsigned int *) PMAX_SSR_ADDR; - - *led_register = bits & PMAX_SSR_LEDMASK; -} - -#endif - -/* - * Some port addresses... - * FIXME: these addresses are incomplete and need tidying up! - */ -#define PMAX_RTC_BASE (KSEG1ADDR(0x1c000000 + 0x200000)) /* ASIC + SL8 */ - -#endif /* __ASM_DEC_MAXINE_H */ diff --git a/include/asm-mips/deskstation.h b/include/asm-mips/deskstation.h new file mode 100644 index 000000000..52b8cdf43 --- /dev/null +++ b/include/asm-mips/deskstation.h @@ -0,0 +1,15 @@ +/* + * SNI specific 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) 1997 by Ralf Baechle + */ +#ifndef __ASM_MIPS_DESKSTATION_H +#define __ASM_MIPS_DESKSTATION_H + +#define RPC44_PORT_BASE 0xe2000000 + +#endif /* __ASM_MIPS_DESKSTATION_H */ diff --git a/include/asm-mips/dma.h b/include/asm-mips/dma.h index c3fd31d58..320022c76 100644 --- a/include/asm-mips/dma.h +++ b/include/asm-mips/dma.h @@ -12,7 +12,8 @@ #ifndef __ASM_MIPS_DMA_H #define __ASM_MIPS_DMA_H -#include <asm/io.h> /* need byte IO */ +#include <linux/config.h> +#include <asm/io.h> /* need byte IO */ #ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER @@ -79,7 +80,11 @@ * Deskstations or Acer PICA but not the much more versatile DMA logic used * for the local devices on Acer PICA or Magnums. */ +#ifndef CONFIG_SGI #define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000) +#else +#define MAX_DMA_ADDRESS (~0UL) +#endif /* 8237 DMA controllers */ #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h index 527352711..97e670510 100644 --- a/include/asm-mips/elf.h +++ b/include/asm-mips/elf.h @@ -1,12 +1,9 @@ #ifndef __ASM_MIPS_ELF_H #define __ASM_MIPS_ELF_H -/* - * ELF register definitions - * This is "make it compile" stuff! - */ -#define ELF_NGREG 32 -#define ELF_NFPREG 32 +/* ELF register definitions */ +#define ELF_NGREG 45 +#define ELF_NFPREG 33 typedef unsigned long elf_greg_t; typedef elf_greg_t elf_gregset_t[ELF_NGREG]; @@ -16,32 +13,31 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; /* * This is used to ensure we don't load something for the wrong architecture. - * Using EM_MIPS is actually wrong - this one is reserved for big endian - * machines only but there is no EM_ constant for little endian ... */ #define elf_check_arch(x) ((x) == EM_MIPS || (x) == EM_MIPS_RS4_BE) /* * These are used to set parameters in the core dumps. + * FIXME(eric) I don't know what the correct endianness to use is. */ #define ELF_CLASS ELFCLASS32 #ifdef __MIPSEB__ -#define ELF_DATA ELFDATA2MSB; +#define ELF_DATA ELFDATA2MSB; #elif __MIPSEL__ -#define ELF_DATA ELFDATA2LSB; +#define ELF_DATA ELFDATA2LSB; #endif #define ELF_ARCH EM_MIPS - /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program - starts %edx contains a pointer to a function which might be - registered using `atexit'. This provides a mean for the - dynamic linker to call DT_FINI functions for shared libraries - that have been loaded before the code runs. - - A value of 0 tells we have no such handler. */ -#define ELF_PLAT_INIT(_r) _r->regs[2] = 0 - #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE 4096 +#define ELF_CORE_COPY_REGS(_dest,_regs) \ + memcpy((char *) &_dest, (char *) _regs, \ + sizeof(struct pt_regs)); + +/* See comments in asm-alpha/elf.h, this is the same thing + * on the MIPS. + */ +#define ELF_PLAT_INIT(_r) _r->regs[2] = 0; + #endif /* __ASM_MIPS_ELF_H */ diff --git a/include/asm-mips/errno.h b/include/asm-mips/errno.h index dc4072a94..70b1effd9 100644 --- a/include/asm-mips/errno.h +++ b/include/asm-mips/errno.h @@ -65,14 +65,7 @@ #define ENOANO 53 /* No anode */ #define EBADRQC 54 /* Invalid request code */ #define EBADSLT 55 /* Invalid slot */ -#if 0 #define EDEADLOCK 56 /* File locking deadlock error */ -#else -/* - * This needs to be fixed - DEADLOCK should be 45. - */ -#define EDEADLOCK EDEADLK /* File locking deadlock error */ -#endif #define EBFONT 59 /* Bad font file format */ #define ENOSTR 60 /* Device not a stream */ #define ENODATA 61 /* No data available */ diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h index e6bc9ae3c..b09ca61a4 100644 --- a/include/asm-mips/irq.h +++ b/include/asm-mips/irq.h @@ -15,7 +15,7 @@ /* * Actually this is a lie but we hide the local device's interrupts ... */ -#define NR_IRQS 16 +#define NR_IRQS 64 #define TIMER_IRQ 0 diff --git a/include/asm-mips/jazz.h b/include/asm-mips/jazz.h index 9a3dbccf0..2f6e4b225 100644 --- a/include/asm-mips/jazz.h +++ b/include/asm-mips/jazz.h @@ -307,8 +307,8 @@ extern inline unsigned int r4030_write_reg32(unsigned addr, unsigned val) #endif /* !LANGUAGE_ASSEMBLY__ */ -#define JAZZ_FDC_BASE 0xe0003000 - -#define JAZZ_RTC_BASE 0xe0004000 +#define JAZZ_FDC_BASE 0xe0003000 +#define JAZZ_RTC_BASE 0xe0004000 +#define JAZZ_PORT_BASE 0xe2000000 #endif /* __ASM_MIPS_JAZZ_H */ diff --git a/include/asm-mips/keyboard.h b/include/asm-mips/keyboard.h index 3c5c7ce65..a99289d00 100644 --- a/include/asm-mips/keyboard.h +++ b/include/asm-mips/keyboard.h @@ -9,6 +9,7 @@ #define __ASM_MIPS_KEYBOARD_H #include <linux/config.h> +#include <linux/delay.h> /* * The default IO slowdown is doing 'inb()'s from 0x61, which should be @@ -19,13 +20,30 @@ #define REALLY_SLOW_IO #define SLOW_IO_BY_JUMPING #include <asm/io.h> + +#ifdef CONFIG_SGI +#include <asm/segment.h> +#include <asm/sgihpc.h> +#endif #include <asm/bootinfo.h> #include <asm/jazz.h> -/* - * Not true for Jazz machines, we cheat a bit for 'em. - */ +#ifdef CONFIG_SGI +#define KEYBOARD_IRQ 20 +#else +/* Not true for Jazz machines, we cheat a bit for 'em. */ #define KEYBOARD_IRQ 1 +#endif + +#ifdef CONFIG_SGI +#define DISABLE_KBD_DURING_INTERRUPTS 1 +#else +#define DISABLE_KBD_DURING_INTERRUPTS 0 +#endif + +#ifndef CONFIG_SGI +#define KBD_REPORT_ERR +#endif static int initialize_kbd(void); @@ -34,13 +52,21 @@ int (*kbd_inb)(unsigned short port); void (*kbd_outb_p)(unsigned char data, unsigned short port); void (*kbd_outb)(unsigned char data, unsigned short port); -#ifdef CONFIG_MIPS_JAZZ +#if defined(CONFIG_MIPS_JAZZ) || defined(CONFIG_SGI) /* * We want the full initialization for the keyboard controller. */ -#define INIT_KBD +/* XXX Define both and ... */ +#ifdef CONFIG_MIPS_JAZZ +#define INIT_KBD /* full initialization for the keyboard controller. */ static volatile keyboard_hardware *kh = (void *) JAZZ_KEYBOARD_ADDRESS; +#endif + +#ifdef CONFIG_SGI +#define INIT_KBD /* full initialization for the keyboard controller. */ +volatile struct hpc_keyb *kh = (struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64); +#endif static int jazz_kbd_inb_p(unsigned short port) @@ -51,7 +77,9 @@ jazz_kbd_inb_p(unsigned short port) result = kh->data; else /* Must be KBD_STATUS_REG */ result = kh->command; +#ifndef CONFIG_SGI inb(0x80); +#endif return result; } @@ -76,7 +104,9 @@ jazz_kbd_outb_p(unsigned char data, unsigned short port) kh->data = data; else if(port == KBD_CNTL_REG) kh->command = data; +#ifndef CONFIG_SGI inb(0x80); +#endif } static void diff --git a/include/asm-mips/mipsconfig.h b/include/asm-mips/mipsconfig.h index 01316c11b..bb9907bc1 100644 --- a/include/asm-mips/mipsconfig.h +++ b/include/asm-mips/mipsconfig.h @@ -5,12 +5,8 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle - * - * This file contains constant definitions and some MIPS specific debug and - * other compile time switches. + * Copyright (C) 1994, 1995, 1996, 1997 by Ralf Baechle */ - #ifndef __ASM_MIPS_MIPSCONFIG_H #define __ASM_MIPS_MIPSCONFIG_H @@ -18,10 +14,6 @@ * This is the virtual address to which all ports are being mapped. * Must be a value that can be load with a lui instruction. */ -#define PORT_BASE_SNI 0xb4000000 -#define PORT_BASE_RPC44 0xe2000000 -#define PORT_BASE_TYNE 0xe2000000 -#define PORT_BASE_JAZZ 0xe2000000 #ifndef PORT_BASE #if !defined (__LANGUAGE_ASSEMBLY__) extern unsigned long port_base; @@ -29,23 +21,10 @@ extern unsigned long port_base; #define PORT_BASE port_base #endif -/* - * Pagetables are 4MB mapped at 0xe4000000 - * Must be a value that can be loaded with a single instruction. - * The xtlb exception handler assumes that bit 30 and 31 of TLBMAP - * are the same. This is true for all KSEG2 and KSEG3 addresses and - * will therefore not a problem. - */ -#define TLBMAP 0xe4000000 +/* Pgdir is 1 page mapped at 0xff800000. */ +#define TLBMAP 0xff800000 -/* - * The virtual address where we'll map the pagetables - * For a base address of 0xe3000000 this is 0xe338c000 - * For a base address of 0xe4000000 this is 0xe4390000 - * FIXME: Gas computes the following expression with signed - * shift and therefore false -#define TLB_ROOT (TLBMAP + (TLBMAP >> (12-2))) - */ -#define TLB_ROOT 0xe4390000 +/* The virtual address where we'll map the pgdir. */ +#define TLB_ROOT 0xff000000 #endif /* __ASM_MIPS_MIPSCONFIG_H */ diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 12666127e..bf2340305 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -25,23 +25,6 @@ #endif /* - * Assigned values for the product ID register. In order to detect a - * certain CPU type exactly eventually additional registers may need to - * be examined. - */ -#define PRID_R3000A 0x02 -#define PRID_R4000 0x04 -#define PRID_R4400 0x04 -#define PRID_R4300 0x0b -#define PRID_R4600 0x20 -#define PRID_R4700 0x21 -#define PRID_R4640 0x22 -#define PRID_R4650 0x22 -#define PRID_R5000 0x23 -#define PRID_SONIC 0x24 -#define PRID_R10000 0x09 - -/* * Coprocessor 0 register names */ #define CP0_INDEX $0 @@ -125,6 +108,9 @@ : "=r" (__res)); \ __res;}) +/* + * For now use this only with interrupts disabled! + */ #define read_64bit_cp0_register(source) \ ({ int __res; \ __asm__ __volatile__( \ @@ -233,52 +219,51 @@ BUILD_SET_CP0(cause,CP0_CAUSE) /* * Bitfields in the R4xx0 cp0 status register */ -#define ST0_IE (1 << 0) -#define ST0_EXL (1 << 1) -#define ST0_ERL (1 << 2) -#define ST0_KSU (3 << 3) -# define KSU_USER (2 << 3) -# define KSU_SUPERVISOR (1 << 3) -# define KSU_KERNEL (0 << 3) -#define ST0_UX (1 << 5) -#define ST0_SX (1 << 6) -#define ST0_KX (1 << 7) +#define ST0_IE 0x00000001 +#define ST0_EXL 0x00000002 +#define ST0_ERL 0x00000004 +#define ST0_KSU 0x00000018 +# define KSU_USER 0x00000010 +# define KSU_SUPERVISOR 0x00000008 +# define KSU_KERNEL 0x00000000 +#define ST0_UX 0x00000020 +#define ST0_SX 0x00000040 +#define ST0_KX 0x00000080 /* * Bitfields in the R[23]000 cp0 status register. */ -#define ST0_IEC (1 << 0) -#define ST0_KUC (1 << 1) -#define ST0_IEP (1 << 2) -#define ST0_KUP (1 << 3) -#define ST0_IEO (1 << 4) -#define ST0_KUO (1 << 5) +#define ST0_KUC 0x00000001 +#define ST0_IEP 0x00000002 +#define ST0_KUP 0x00000004 +#define ST0_IEO 0x00000008 +#define ST0_KUO 0x00000010 /* bits 6 & 7 are reserved on R[23]000 */ /* * Bits specific to the R4640/R4650 */ -#define ST0_UM <1 << 4) -#define ST0_IL (1 << 23) -#define ST0_DL (1 << 24) +#define ST0_UM <1 << 4) +#define ST0_IL (1 << 23) +#define ST0_DL (1 << 24) /* * Status register bits available in all MIPS CPUs. */ -#define ST0_IM (255 << 8) -#define ST0_DE (1 << 16) -#define ST0_CE (1 << 17) -#define ST0_CH (1 << 18) -#define ST0_SR (1 << 20) -#define ST0_BEV (1 << 22) -#define ST0_RE (1 << 25) -#define ST0_FR (1 << 26) -#define ST0_CU (15 << 28) -#define ST0_CU0 (1 << 28) -#define ST0_CU1 (1 << 29) -#define ST0_CU2 (1 << 30) -#define ST0_CU3 (1 << 31) -#define ST0_XX (1 << 31) /* MIPS IV naming */ +#define ST0_IM 0x0000ff00 +#define ST0_DE 0x00010000 +#define ST0_CE 0x00020000 +#define ST0_CH 0x00040000 +#define ST0_SR 0x00100000 +#define ST0_BEV 0x00400000 +#define ST0_RE 0x02000000 +#define ST0_FR 0x04000000 +#define ST0_CU 0xf0000000 +#define ST0_CU0 0x10000000 +#define ST0_CU1 0x20000000 +#define ST0_CU2 0x40000000 +#define ST0_CU3 0x80000000 +#define ST0_XX 0x80000000 /* MIPS IV naming */ /* * Bitfields and bit numbers in the coprocessor 0 cause register. @@ -313,9 +298,9 @@ BUILD_SET_CP0(cause,CP0_CAUSE) /* * Bits in the coprozessor 0 config register. */ -#define CONFIG_DB (1<<4) -#define CONFIG_IB (1<<5) -#define CONFIG_SC (1<<17) +#define CONFIG_DB (1 << 4) +#define CONFIG_IB (1 << 5) +#define CONFIG_SC (1 << 17) /* * R10000 performance counter definitions. diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h index 5a61279da..d905d8f11 100644 --- a/include/asm-mips/mmu_context.h +++ b/include/asm-mips/mmu_context.h @@ -10,13 +10,38 @@ #ifndef __ASM_MIPS_MMU_CONTEXT_H #define __ASM_MIPS_MMU_CONTEXT_H -/* - * Get a new mmu context. For MIPS we use resume() to change the - * PID (R3000)/ASID (R4000). Well, we will ... - */ -extern __inline__ void -get_mmu_context(struct task_struct *p) +#define MAX_ASID 255 + +extern unsigned long asid_cache; + +#define ASID_VERSION_SHIFT 16 +#define ASID_VERSION_MASK ((~0UL) << ASID_VERSION_SHIFT) +#define ASID_FIRST_VERSION (1UL << ASID_VERSION_SHIFT) + +extern inline void get_new_mmu_context(struct mm_struct *mm, unsigned long asid) { + /* check if it's legal.. */ + if ((asid & ~ASID_VERSION_MASK) > MAX_ASID) { + /* start a new version, invalidate all old asid's */ + flush_tlb_all(); + asid = (asid & ASID_VERSION_MASK) + ASID_FIRST_VERSION; + if (!asid) + asid = ASID_FIRST_VERSION; + } + asid_cache = asid + 1; + mm->context = asid; /* full version + asid */ +} + +extern inline void get_mmu_context(struct task_struct *p) +{ + struct mm_struct *mm = p->mm; + + if (mm) { + unsigned long asid = asid_cache; + /* Check if our ASID is of an older version and thus invalid */ + if ((mm->context ^ asid) & ASID_VERSION_MASK) + get_new_mmu_context(mm, asid); + } } #endif /* __ASM_MIPS_MMU_CONTEXT_H */ diff --git a/include/asm-mips/offset.h b/include/asm-mips/offset.h new file mode 100644 index 000000000..c5e6f37fa --- /dev/null +++ b/include/asm-mips/offset.h @@ -0,0 +1,89 @@ +/* DO NOT TOUCH, AUTOGENERATED BY OFFSET.C */ + +#ifndef _MIPS_OFFSET_H +#define _MIPS_OFFSET_H + +/* MIPS pt_regs offsets. */ +#define PT_R0 24 +#define PT_R1 28 +#define PT_R2 32 +#define PT_R3 36 +#define PT_R4 40 +#define PT_R5 44 +#define PT_R6 48 +#define PT_R7 52 +#define PT_R8 56 +#define PT_R9 60 +#define PT_R10 64 +#define PT_R11 68 +#define PT_R12 72 +#define PT_R13 76 +#define PT_R14 80 +#define PT_R15 84 +#define PT_R16 88 +#define PT_R17 92 +#define PT_R18 96 +#define PT_R19 100 +#define PT_R20 104 +#define PT_R21 108 +#define PT_R22 112 +#define PT_R23 116 +#define PT_R24 120 +#define PT_R25 124 +#define PT_R26 128 +#define PT_R27 132 +#define PT_R28 136 +#define PT_R29 140 +#define PT_R30 144 +#define PT_R31 148 +#define PT_LO 152 +#define PT_HI 156 +#define PT_OR2 160 +#define PT_OR7 164 +#define PT_EPC 168 +#define PT_BVADDR 172 +#define PT_STATUS 176 +#define PT_CAUSE 180 +#define PT_SIZE 184 + +/* MIPS task_struct offsets. */ +#define TASK_STATE 0 +#define TASK_PRIORITY 8 +#define TASK_SIGNAL 12 +#define TASK_BLOCKED 16 +#define TASK_FLAGS 20 +#define TASK_SAVED_KSTACK 84 +#define TASK_KSTACK_PG 88 +#define TASK_MM 912 + +/* MIPS specific thread_struct offsets. */ +#define THREAD_REG16 544 +#define THREAD_REG17 548 +#define THREAD_REG18 552 +#define THREAD_REG19 556 +#define THREAD_REG20 560 +#define THREAD_REG21 564 +#define THREAD_REG22 568 +#define THREAD_REG23 572 +#define THREAD_REG28 576 +#define THREAD_REG29 580 +#define THREAD_REG30 584 +#define THREAD_REG31 588 +#define THREAD_STATUS 592 +#define THREAD_FPU 600 +#define THREAD_BVADDR 864 +#define THREAD_ECODE 868 +#define THREAD_TRAPNO 872 +#define THREAD_KSP 876 +#define THREAD_PGDIR 880 +#define THREAD_MFLAGS 884 +#define THREAD_CURDS 888 +#define THREAD_TRAMP 892 +#define THREAD_OLDCTX 896 + +/* Linux mm_struct offsets. */ +#define MM_COUNT 0 +#define MM_PGD 4 +#define MM_CONTEXT 8 + +#endif /* !(_MIPS_OFFSET_H) */ diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index 6339c0373..ba42d3baa 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h @@ -19,11 +19,11 @@ #define STRICT_MM_TYPECHECKS +#ifndef __LANGUAGE_ASSEMBLY__ + extern void (*clear_page)(unsigned long page); extern void (*copy_page)(unsigned long to, unsigned long from); -#ifndef __LANGUAGE_ASSEMBLY__ - #ifdef STRICT_MM_TYPECHECKS /* * These are used to make use of C type-checking.. @@ -69,46 +69,16 @@ typedef unsigned long pgprot_t; /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -/* This handles the memory map */ -#if 0 /* - * Kernel with 64 bit address space. - * We handle pages at XKPHYS + 0x1800000000000000 (cachable, noncoherent) - * Pagetables are at XKPHYS + 0x1000000000000000 (uncached) - */ -#define PAGE_OFFSET 0x9800000000000000UL -#define PT_OFFSET 0x9000000000000000UL -#define MAP_MASK 0x07ffffffffffffffUL -#else /* !defined (__mips64) */ -/* - * Kernel with 32 bit address space. - * We handle pages at KSEG0 (cachable, noncoherent) - * Pagetables are at KSEG1 (uncached) + * This handles the memory map. + * We handle pages at KSEG0 for kernels with 32 bit address space. */ #define PAGE_OFFSET 0x80000000UL -#define PT_OFFSET 0xa0000000UL +#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) #define MAP_MASK 0x1fffffffUL -#endif /* !defined (__mips64) */ - -/* - * __pa breaks when applied to a pagetable pointer on >= R4000. - */ -#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) -#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) - #define MAP_NR(addr) ((((unsigned long)(addr)) & MAP_MASK) >> PAGE_SHIFT) -#ifndef __LANGUAGE_ASSEMBLY__ - -extern unsigned long page_colour_mask; - -extern inline unsigned long -page_colour(unsigned long page) -{ - return page & page_colour_mask; -} - -#endif /* defined (__LANGUAGE_ASSEMBLY__) */ #endif /* defined (__KERNEL__) */ #endif /* __ASM_MIPS_PAGE_H */ diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index 2744d5c24..2192a39d5 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h @@ -1,12 +1,3 @@ -/* - * Linux/MIPS pagetables - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1995, 1996 by Ralf Baechle - */ #ifndef __ASM_MIPS_PGTABLE_H #define __ASM_MIPS_PGTABLE_H @@ -16,100 +7,44 @@ #ifndef __LANGUAGE_ASSEMBLY__ #include <linux/linkage.h> -#include <asm/cache.h> - -extern inline void -flush_cache_all(void) -{ - cacheflush(0, ~0UL, CF_DCACHE|CF_VIRTUAL); -} - -extern inline void -flush_cache_mm(struct mm_struct *mm) -{ - cacheflush(0, ~0UL, CF_BCACHE|CF_VIRTUAL); -} +#include <asm/cachectl.h> -extern inline void -flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) -{ - cacheflush(start, end - start, CF_DCACHE|CF_VIRTUAL); -} - -extern inline void -flush_cache_page(struct vm_area_struct * vma, unsigned long vmaddr) -{ - unsigned int flags; - - flags = (vma->vm_flags & VM_EXEC) ? CF_BCACHE|CF_VIRTUAL - : CF_DCACHE|CF_VIRTUAL; - cacheflush(vmaddr, PAGE_SIZE, flags); -} - -extern inline void -flush_page_to_ram(unsigned long page) -{ - cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_VIRTUAL); -} - -/* - * The Linux memory management assumes a three-level page table setup. In - * 32 bit mode we use that, but "fold" the mid level into the top-level page - * table, so that we physically have the same two-level page table as the - * i386 mmu expects. The 64 bit version uses a three level setup. +/* Cache flushing: * - * This file contains the functions and defines necessary to modify and use - * the MIPS page table tree. Note the frequent conversion between addresses - * in KSEG0 and KSEG1. - * - * This is required due to the cache aliasing problem of the R4xx0 series. - * Sometimes doing uncached accesses also to improve the cache performance - * slightly. The R10000 caching mode "uncached accelerated" will help even - * further. + * - 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(mm, start, end) flushes a range of pages + * - flush_page_to_ram(page) write back kernel page to ram */ - -/* - * TLB invalidation: +extern void (*flush_cache_all)(void); +extern void (*flush_cache_mm)(struct mm_struct *mm); +extern void (*flush_cache_range)(struct mm_struct *mm, 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)(unsigned long page); + +/* TLB flushing: * - * - flush_tlb() flushes the current mm struct TLB entries * - flush_tlb_all() flushes all processes TLB entries * - flush_tlb_mm(mm) flushes the specified mm context TLB entries * - flush_tlb_page(mm, vmaddr) flushes a single page * - flush_tlb_range(mm, start, end) flushes a range of pages - * - * FIXME: MIPS has full control of all TLB activity in the CPU. Though - * we just stick with complete flushing of TLBs for now. - * Currently this code only supports only R4000 and newer. Support - * for R3000 is in the works. The R6000 uses a 2x8 entry TLB slice - * and the R6000A an 16 entry TLB slice which is quite different - * from the memory management concepts of the other R-series CPUs. - * Only a few machines with this CPU still exist and I don't have one - * so chances for complete R6000 support are relativly low. */ -extern asmlinkage void tlbflush(void); -extern asmlinkage void tlbflush_page(unsigned long addr); -#define flush_tlb() tlbflush() -#define flush_tlb_all() flush_tlb() - -static inline void flush_tlb_mm(struct mm_struct *mm) -{ - if (mm == current->mm) - flush_tlb(); -} - -static inline void flush_tlb_page(struct vm_area_struct *vma, - unsigned long addr) -{ - if (vma->vm_mm == current->mm) - tlbflush_page(addr); -} +extern void (*flush_tlb_all)(void); +extern void (*flush_tlb_mm)(struct mm_struct *mm); +extern void (*flush_tlb_range)(struct mm_struct *mm, unsigned long start, + unsigned long end); +extern void (*flush_tlb_page)(struct vm_area_struct *vma, unsigned long page); + +/* Basically we have the same two-level (which is the logical three level + * Linux page table layout folded) page tables as the i386. Some day + * when we have proper page coloring support we can have a 1% quicker + * tlb refill handling mechanism, but for now it is a bit slower but + * works even with the cache aliasing problem the R4k and above have. + */ -static inline void flush_tlb_range(struct mm_struct *mm, - unsigned long start, unsigned long end) -{ - if (mm == current->mm) - flush_tlb(); -} #endif /* !defined (__LANGUAGE_ASSEMBLY__) */ /* PMD_SHIFT determines the size of the area a second-level page table can map */ @@ -122,8 +57,7 @@ static inline void flush_tlb_range(struct mm_struct *mm, #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. */ #define PTRS_PER_PTE 1024 @@ -133,22 +67,32 @@ static inline void flush_tlb_range(struct mm_struct *mm, #define VMALLOC_START KSEG2 #define VMALLOC_VMADDR(x) ((unsigned long)(x)) -/* - * Note that we shift the lower 32bits of each EntryLo[01] entry +/* 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. - * Since the Mips has chosen some quite misleading names for the - * valid and dirty bits they're defined here but only their synonyms - * will be used. + * + * 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_UNUSED1 (1<<5) +#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 */ @@ -167,16 +111,15 @@ static inline void flush_tlb_range(struct mm_struct *mm, #define __READABLE (_PAGE_READ|_PAGE_SILENT_READ|_PAGE_ACCESSED) #define __WRITEABLE (_PAGE_WRITE|_PAGE_SILENT_WRITE|_PAGE_MODIFIED) -#define _PAGE_TABLE (_PAGE_PRESENT | __READABLE | __WRITEABLE | \ - _PAGE_DIRTY | _CACHE_UNCACHED) -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _CACHE_MASK) +#define _PAGE_CHG_MASK (PAGE_MASK | __READABLE | __WRITEABLE | _CACHE_MASK) -#define PAGE_NONE __pgprot(_PAGE_PRESENT | __READABLE | _CACHE_UNCACHED) -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | __READABLE | _PAGE_WRITE | \ +#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ + _CACHE_CACHABLE_NONCOHERENT) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ _PAGE_ACCESSED | _CACHE_CACHABLE_NONCOHERENT) -#define PAGE_COPY __pgprot(_PAGE_PRESENT | __READABLE | \ +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_READ | \ _CACHE_CACHABLE_NONCOHERENT) -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | __READABLE | \ +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_READ | \ _CACHE_CACHABLE_NONCOHERENT) #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ _CACHE_CACHABLE_NONCOHERENT) @@ -206,9 +149,6 @@ static inline void flush_tlb_range(struct mm_struct *mm, #if !defined (__LANGUAGE_ASSEMBLY__) -/* zero page used for uninitialized stuff */ -extern unsigned long empty_zero_page[1024]; - /* * BAD_PAGETABLE is used when we need a bogus page-table, while * BAD_PAGE is used for a bogus page. @@ -217,10 +157,12 @@ extern unsigned long empty_zero_page[1024]; * for zero-mapped memory areas etc.. */ extern pte_t __bad_page(void); -extern pte_t * __bad_pagetable(void); +extern pte_t *__bad_pagetable(void); extern unsigned long __zero_page(void); +extern unsigned long empty_zero_page[1024]; + #define BAD_PAGETABLE __bad_pagetable() #define BAD_PAGE __bad_page() #define ZERO_PAGE ((unsigned long)empty_zero_page) @@ -234,78 +176,78 @@ extern unsigned long __zero_page(void); /* * sizeof(void*) == (1 << SIZEOF_PTR_LOG2) */ -#ifdef 0 /* __mips64 */ -#define SIZEOF_PTR_LOG2 3 -#else #define SIZEOF_PTR_LOG2 2 -#endif /* 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 void (*load_pgd)(unsigned long pg_dir); /* to set the page-dir */ -#define SET_PAGE_DIR(tsk,pgdir) \ -do { \ - (tsk)->tss.pg_dir = ((unsigned long) (pgdir)) - PT_OFFSET; \ - if ((tsk) == current) \ - load_pgd((tsk)->tss.pg_dir); \ -} while (0) +#define SET_PAGE_DIR(tsk,pgdir) (tsk)->tss.pg_dir = ((unsigned long) (pgdir)) extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)]; /* - * Convert a page address to a page table pointer and vice versa. - * Due to the wiered virtual caches in the r-series we might run into - * problems with cache aliasing. We solve this problem by accessing - * the pagetables uncached. - */ -#define page_to_ptp(x) ((__typeof__(x))(((unsigned long) (x)) + (PT_OFFSET - PAGE_OFFSET))) -#define ptp_to_page(x) ((__typeof__(x))(((unsigned long) (x)) - (PT_OFFSET - PAGE_OFFSET))) - -/* * 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 pte_page(pte_t pte) -{ return PAGE_OFFSET + (pte_val(pte) & PAGE_MASK); } +{ + return PAGE_OFFSET + (pte_val(pte) & PAGE_MASK); +} extern inline unsigned long pmd_page(pmd_t pmd) -{ return PAGE_OFFSET + (pmd_val(pmd) & PAGE_MASK); } +{ + return pmd_val(pmd); +} extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) -{ pmd_val(*pmdp) = _PAGE_TABLE | ((unsigned long) ptep - PT_OFFSET); } +{ + 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; } +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; } -/* - * Certain architectures need to do special things when pte's +/* 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) { - *ptep = pteval; + *ptep = pteval; } extern inline void pte_clear(pte_t *ptep) { - pte_t pte; - - pte_val(pte) = 0; - set_pte(ptep, pte); + set_pte(ptep, __pte(0)); } /* * Empty pgd/pmd entries point to the invalid_pte_table. */ -extern inline int pmd_none(pmd_t pmd) { return (pmd_val(pmd) & PAGE_MASK) == ((unsigned long) invalid_pte_table - PAGE_OFFSET); } -extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE; } -extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_PRESENT; } -extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = ((unsigned long) invalid_pte_table - PAGE_OFFSET) | _PAGE_TABLE; } +extern 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)); +} + +extern inline int pmd_present(pmd_t pmd) +{ + return pmd_val(pmd); +} + +extern inline void pmd_clear(pmd_t *pmdp) +{ + pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); +} /* * The "pgd_xxx()" functions here are trivial for a folded two-level @@ -315,33 +257,41 @@ extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = ((unsigned long) i 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) { } +extern inline void pgd_clear(pgd_t *pgdp) { } /* * 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_exec(pte_t pte) { return pte_val(pte) & _PAGE_READ; } -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; } +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; } extern 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) { - pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ); return pte; + pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ); + return pte; } -extern inline pte_t pte_exprotect(pte_t pte) + +extern inline pte_t pte_mkclean(pte_t pte) { - pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ); return pte; + pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE); + return pte; } -extern 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) { pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ|_PAGE_SILENT_WRITE); return pte; } + +extern inline pte_t pte_mkold(pte_t pte) +{ + pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ|_PAGE_SILENT_WRITE); + return pte; +} + extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; @@ -349,6 +299,7 @@ extern inline pte_t pte_mkwrite(pte_t pte) pte_val(pte) |= _PAGE_SILENT_WRITE; return pte; } + extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_READ; @@ -356,13 +307,7 @@ extern inline pte_t pte_mkread(pte_t pte) pte_val(pte) |= _PAGE_SILENT_READ; return pte; } -extern inline pte_t pte_mkexec(pte_t pte) -{ - pte_val(pte) |= _PAGE_READ; - if (pte_val(pte) & _PAGE_ACCESSED) - pte_val(pte) |= _PAGE_SILENT_READ; - return pte; -} + extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_MODIFIED; @@ -370,13 +315,14 @@ extern inline pte_t pte_mkdirty(pte_t pte) pte_val(pte) |= _PAGE_SILENT_WRITE; return pte; } + extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; - if (pte_val(pte) & _PAGE_READ) - { + if (pte_val(pte) & _PAGE_READ) { pte_val(pte) |= _PAGE_SILENT_READ; - if ((pte_val(pte) & (_PAGE_WRITE|_PAGE_MODIFIED)) == (_PAGE_WRITE|_PAGE_MODIFIED)) + if ((pte_val(pte) & (_PAGE_WRITE|_PAGE_MODIFIED)) == + (_PAGE_WRITE|_PAGE_MODIFIED)) pte_val(pte) |= _PAGE_SILENT_WRITE; } return pte; @@ -387,30 +333,36 @@ extern inline pte_t pte_mkyoung(pte_t pte) * and a page entry and page directory to the page they refer to. */ extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot) -{ pte_t pte; pte_val(pte) = (page - PAGE_OFFSET) | pgprot_val(pgprot); return pte; } +{ + return __pte(((page & PAGE_MASK) - PAGE_OFFSET) | pgprot_val(pgprot)); +} extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) -{ pte_t pte; pte_val(pte) = physpage | pgprot_val(pgprot); return pte; } +{ + return __pte((physpage - PAGE_OFFSET) | pgprot_val(pgprot)); +} extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } +{ + return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); +} /* to find an entry in a page-table-directory */ -extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) +extern inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address) { return mm->pgd + (address >> PGDIR_SHIFT); } /* Find an entry in the second-level page table.. */ -extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) +extern 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) +extern inline pte_t *pte_offset(pmd_t * dir, unsigned long address) { - return (pte_t *) (page_to_ptp(pmd_page(*dir))) + + return (pte_t *) (pmd_page(*dir)) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); } @@ -419,121 +371,93 @@ extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) * used to allocate a kernel page table - this turns on ASN bits * if any. */ -extern inline void pte_free_kernel(pte_t * pte) +extern inline void pte_free_kernel(pte_t *pte) { - unsigned long page = (unsigned long) pte; - - if(!page) - return; - /* - * Flush complete cache - we don't know the virtual address. - */ - cacheflush(0, ~0, CF_DCACHE|CF_VIRTUAL); - free_page(ptp_to_page(page)); + free_page((unsigned long) pte); } -extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) +extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address) { address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); if (pmd_none(*pmd)) { - unsigned long page = get_free_page(GFP_KERNEL); + pte_t *page = (pte_t *) get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (page) { - cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_VIRTUAL); - sync_mem(); - page = page_to_ptp(page); - pmd_set(pmd, (pte_t *)page); - return (pte_t *)page + address; + pmd_set(pmd, page); + return page + address; } pmd_set(pmd, (pte_t *) BAD_PAGETABLE); return NULL; } - free_page(page); + free_page((unsigned long) page); } if (pmd_bad(*pmd)) { printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd)); pmd_set(pmd, (pte_t *) BAD_PAGETABLE); return NULL; } - return (pte_t *) page_to_ptp(pmd_page(*pmd)) + address; + return (pte_t *) pmd_page(*pmd) + address; } /* * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. */ -extern inline void pmd_free_kernel(pmd_t * pmd) +extern inline void pmd_free_kernel(pmd_t *pmd) { + pmd_val(*pmd) = ((unsigned long) invalid_pte_table); } -extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address) +extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address) { return (pmd_t *) pgd; } -extern inline void pte_free(pte_t * pte) +extern inline void pte_free(pte_t *pte) { - unsigned long page = (unsigned long) pte; - - if(!page) - return; - /* - * Flush complete cache - we don't know the virtual address. - */ - cacheflush(0, ~0UL, CF_DCACHE|CF_VIRTUAL); - free_page(ptp_to_page(page)); + free_page((unsigned long) pte); } -extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) +extern inline pte_t *pte_alloc(pmd_t *pmd, unsigned long address) { address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); if (pmd_none(*pmd)) { - unsigned long page = get_free_page(GFP_KERNEL); + pte_t *page = (pte_t *) get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (page) { - cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_VIRTUAL); - sync_mem(); - page = page_to_ptp(page); - pmd_set(pmd, (pte_t *)page); - return (pte_t *)page + address; + pmd_set(pmd, page); + return page + address; } pmd_set(pmd, (pte_t *) BAD_PAGETABLE); return NULL; } - free_page(page); + free_page((unsigned long) page); } if (pmd_bad(*pmd)) { printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); pmd_set(pmd, (pte_t *) BAD_PAGETABLE); return NULL; } - return (pte_t *) page_to_ptp(pmd_page(*pmd)) + address; + return (pte_t *) pmd_page(*pmd) + address; } /* * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. */ -extern inline void pmd_free(pmd_t * pmd) +extern inline void pmd_free(pmd_t *pmd) { + pmd_val(*pmd) = ((unsigned long) invalid_pte_table); } -extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address) +extern inline pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address) { return (pmd_t *) pgd; } -extern inline void pgd_free(pgd_t * pgd) +extern inline void pgd_free(pgd_t *pgd) { - unsigned long page = (unsigned long) pgd; - - if(!page) - return; - /* - * Flush complete cache - we don't know the virtual address. - */ - cacheflush(0, ~0UL, CF_DCACHE|CF_VIRTUAL); - free_page(ptp_to_page(page)); + free_page((unsigned long) pgd); } /* @@ -541,48 +465,313 @@ extern inline void pgd_free(pgd_t * pgd) */ extern void (*pgd_init)(unsigned long page); -extern inline pgd_t * pgd_alloc(void) +extern inline pgd_t *pgd_alloc(void) { unsigned long page; if(!(page = __get_free_page(GFP_KERNEL))) return NULL; + pgd_init(page); - return (pgd_t *) page_to_ptp(page); + return (pgd_t *) page; } extern pgd_t swapper_pg_dir[1024]; -extern inline void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) +extern void (*update_mmu_cache)(struct vm_area_struct *vma, + unsigned long address, pte_t pte); + +/* + * Kernel with 32 bit address space + */ +#define SWP_TYPE(entry) (((entry) >> 8) & 0x7f) +#define SWP_OFFSET(entry) ((entry) >> 15) +#define SWP_ENTRY(type,offset) (((type) << 8) | ((offset) << 15)) + +/* TLB operations. */ +extern inline void tlb_probe(void) { - tlbflush_page(address); - /* - * FIXME: We should also reload a new entry into the TLB to - * avoid unnecessary exceptions. - */ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbp\n\t" + ".set reorder"); } -#if 0 /* defined(__mips64) */ +extern inline void tlb_read(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbr\n\t" + ".set reorder"); +} -/* - * For true 64 bit kernel - */ -#define SWP_TYPE(entry) (((entry) >> 32) & 0xff) -#define SWP_OFFSET(entry) ((entry) >> 40) -#define SWP_ENTRY(type,offset) pte_val(mk_swap_pte((type),(offset))) +extern inline void tlb_write_indexed(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwi\n\t" + ".set reorder"); +} -#else +extern inline void tlb_write_random(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwr\n\t" + ".set reorder"); +} -/* - * Kernel with 32 bit address space - */ -#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f) -#define SWP_OFFSET(entry) ((entry) >> 8) -#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8)) +/* Dealing with various CP0 mmu/cache related registers. */ + +/* CP0_PAGEMASK register */ +extern inline unsigned long get_pagemask(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mfc0 %0, $5\n\t" + ".set mips2\n\t" + ".set reorder" + : "=r" (val)); + return val; +} + +extern inline void set_pagemask(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mtc0 %0, $5\n\t" + ".set mips2\n\t" + ".set reorder" + : : "r" (val)); +} + +/* CP0_ENTRYLO0 and CP0_ENTRYLO1 registers */ +extern inline unsigned long get_entrylo0(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mfc0 %0, $2\n\t" + ".set mips2\n\t" + ".set reorder" + : "=r" (val)); + return val; +} + +extern inline void set_entrylo0(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mtc0 %0, $2\n\t" + ".set mips2\n\t" + ".set reorder" + : : "r" (val)); +} + +extern inline unsigned long get_entrylo1(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mfc0 %0, $3\n\t" + ".set mips2\n\t" + ".set reorder" : "=r" (val)); + + return val; +} + +extern inline void set_entrylo1(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mtc0 %0, $3\n\t" + ".set mips2\n\t" + ".set reorder" + : : "r" (val)); +} + +/* CP0_ENTRYHI register */ +extern inline unsigned long get_entryhi(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mfc0 %0, $10\n\t" + ".set mips2\n\t" + ".set reorder" + : "=r" (val)); + + return val; +} -#endif +extern inline void set_entryhi(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mtc0 %0, $10\n\t" + ".set mips2\n\t" + ".set reorder" + : : "r" (val)); +} + +/* CP0_INDEX register */ +extern inline unsigned long get_index(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mfc0 %0, $0\n\t" + ".set mips2\n\t" + ".set reorder" + : "=r" (val)); + return val; +} + +extern inline void set_index(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mtc0 %0, $0\n\t" + ".set mips2\n\t" + ".set reorder\n\t" + : : "r" (val)); +} + +/* CP0_WIRED register */ +extern inline unsigned long get_wired(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mfc0 %0, $6\n\t" + ".set mips2\n\t" + ".set reorder\n\t" + : "=r" (val)); + return val; +} + +extern inline void set_wired(unsigned long val) +{ + __asm__ __volatile__( + "\n\t.set noreorder\n\t" + ".set mips3\n\t" + "mtc0 %0, $6\n\t" + ".set mips2\n\t" + ".set reorder" + : : "r" (val)); +} + +/* CP0_TAGLO and CP0_TAGHI registers */ +extern inline unsigned long get_taglo(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mfc0 %0, $28\n\t" + ".set mips2\n\t" + ".set reorder" + : "=r" (val)); + return val; +} + +extern inline void set_taglo(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mtc0 %0, $28\n\t" + ".set mips2\n\t" + ".set reorder" + : : "r" (val)); +} + +extern inline unsigned long get_taghi(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mfc0 %0, $29\n\t" + ".set mips2\n\t" + ".set reorder" + : "=r" (val)); + return val; +} + +extern inline void set_taghi(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mtc0 %0, $29\n\t" + ".set mips2\n\t" + ".set reorder" + : : "r" (val)); +} + +/* CP0_CONTEXT register */ +extern inline unsigned long get_context(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mfc0 %0, $4\n\t" + ".set mips2\n\t" + ".set reorder" + : "=r" (val)); + + return val; +} + +extern inline void set_context(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "mtc0 %0, $4\n\t" + ".set mips2\n\t" + ".set reorder" + : : "r" (val)); +} + +/* Kernel stack allocation/freeing. */ +extern inline unsigned long alloc_kernel_stack(void) +{ + unsigned long stack; + stack = __get_free_pages(GFP_KERNEL, 1, 0); + memset((void *)stack, 0, (size_t) KERNEL_STACK_SIZE); + + return stack; +} + +extern inline void free_kernel_stack(unsigned long stack) +{ + free_pages(stack, 1); +} #endif /* !defined (__LANGUAGE_ASSEMBLY__) */ diff --git a/include/asm-mips/pica.h b/include/asm-mips/pica.h new file mode 100644 index 000000000..a1056f845 --- /dev/null +++ b/include/asm-mips/pica.h @@ -0,0 +1,181 @@ +/* + * Hardware info about Acer PICA 61 and similar + * + * 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 Andreas Busse and Ralf Baechle + */ +#ifndef __ASM_MIPS_PICA_H +#define __ASM_MIPS_PICA_H + +/* + * The addresses below are virtual address. The mappings are + * created on startup via wired entries in the tlb. The Mips + * Magnum R3000 and R4000 machines are similar in many aspects, + * but many hardware register are accessible at 0xb9000000 in + * instead of 0xe0000000. + */ + +/* + * Revision numbers in PICA_ASIC_REVISION + * + * 0xf0000000 - Rev1 + * 0xf0000001 - Rev2 + * 0xf0000002 - Rev3 + */ +#define PICA_ASIC_REVISION 0xe0000008 + +/* + * The segments of the seven segment LED are mapped + * to the control bits as follows: + * + * (7) + * --------- + * | | + * (2) | | (6) + * | (1) | + * --------- + * | | + * (3) | | (5) + * | (4) | + * --------- . (0) + */ +#define PICA_LED 0xe000f000 + +/* + * Some characters for the LED control registers + * The original Mips machines seem to have a LED display + * with integrated decoder while the Acer machines can + * control each of the seven segments and the dot independently. + * It only a toy, anyway... + */ +#define LED_DOT 0x01 +#define LED_SPACE 0x00 +#define LED_0 0xfc +#define LED_1 0x60 +#define LED_2 0xda +#define LED_3 0xf2 +#define LED_4 0x66 +#define LED_5 0xb6 +#define LED_6 0xbe +#define LED_7 0xe0 +#define LED_8 0xfe +#define LED_9 0xf6 +#define LED_A 0xee +#define LED_b 0x3e +#define LED_C 0x9c +#define LED_d 0x7a +#define LED_E 0x9e +#define LED_F 0x8e + +#ifndef __LANGUAGE_ASSEMBLY__ + +extern __inline__ void pica_set_led(unsigned int bits) +{ + volatile unsigned int *led_register = (unsigned int *) PICA_LED; + + *led_register = bits; +} + +#endif + +/* + * i8042 keyboard controller for PICA chipset. + * This address is just a guess and seems to differ + * from the other mips machines... + */ +#define PICA_KEYBOARD_ADDRESS 0xe0005000 +#define PICA_KEYBOARD_DATA 0xe0005000 +#define PICA_KEYBOARD_COMMAND 0xe0005001 + +#ifndef __LANGUAGE_ASSEMBLY__ + +typedef struct { + unsigned char data; + unsigned char command; +} pica_keyboard_hardware; + +typedef struct { + unsigned char pad0[3]; + unsigned char data; + unsigned char pad1[3]; + unsigned char command; +} mips_keyboard_hardware; + +/* + * For now + */ +#define keyboard_hardware pica_keyboard_hardware + +#endif + +/* + * i8042 keyboard controller for most other Mips machines. + */ +#define MIPS_KEYBOARD_ADDRESS 0xb9005000 +#define MIPS_KEYBOARD_DATA 0xb9005003 +#define MIPS_KEYBOARD_COMMAND 0xb9005007 + +#ifndef __LANGUAGE_ASSEMBLY__ + +#endif + +/* + * PICA timer registers and interrupt no. + * Note that the hardware timer interrupt is actually on + * cpu level 6, but to keep compatibility with PC stuff + * it is remapped to vector 0. See arch/mips/kernel/entry.S. + */ +#define PICA_TIMER_INTERVAL 0xe0000228 +#define PICA_TIMER_REGISTER 0xe0000230 + +/* + * DRAM configuration register + */ +#ifndef __LANGUAGE_ASSEMBLY__ +#ifdef __MIPSEL__ +typedef struct { + unsigned int bank2 : 3; + unsigned int bank1 : 3; + unsigned int mem_bus_width : 1; + unsigned int reserved2 : 1; + unsigned int page_mode : 1; + unsigned int reserved1 : 23; +} dram_configuration; +#else /* defined (__MIPSEB__) */ +typedef struct { + unsigned int reserved1 : 23; + unsigned int page_mode : 1; + unsigned int reserved2 : 1; + unsigned int mem_bus_width : 1; + unsigned int bank1 : 3; + unsigned int bank2 : 3; +} dram_configuration; +#endif +#endif /* __LANGUAGE_ASSEMBLY__ */ + +#define PICA_DRAM_CONFIG 0xe00fffe0 + +/* + * PICA interrupt control registers + */ +#define PICA_IO_IRQ_SOURCE 0xe0100000 +#define PICA_IO_IRQ_ENABLE 0xe0100002 + +/* + * Pica interrupt enable bits + */ +#define PIE_PARALLEL (1<<0) +#define PIE_FLOPPY (1<<1) +#define PIE_SOUND (1<<2) +#define PIE_VIDEO (1<<3) +#define PIE_ETHERNET (1<<4) +#define PIE_SCSI (1<<5) +#define PIE_KEYBOARD (1<<6) +#define PIE_MOUSE (1<<7) +#define PIE_SERIAL1 (1<<8) +#define PIE_SERIAL2 (1<<9) + +#endif /* __ASM_MIPS_PICA_H */ diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index be6d26a61..1d308a439 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -1,16 +1,15 @@ /* * include/asm-mips/processor.h * - * Copyright (C) 1994, 1995 by Waldorf Electronics - * Copyright (C) 1995, 1996 by Ralf Baechle + * Copyright (C) 1994 Waldorf Electronics + * written by Ralf Baechle * Modified further for R[236]000 compatibility by Paul M. Antoine */ #ifndef __ASM_MIPS_PROCESSOR_H #define __ASM_MIPS_PROCESSOR_H -#include <asm/sgidefs.h> - #if !defined (__LANGUAGE_ASSEMBLY__) +#include <asm/cachectl.h> #include <asm/mipsregs.h> #include <asm/reg.h> #include <asm/system.h> @@ -25,18 +24,25 @@ extern unsigned long event; /* * Bus types (default is ISA, but people can check others with these..) - * There are no Microchannel MIPS machines. + * 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. */ extern int EISA_bus; #define MCA_bus 0 +#define MCA_bus__is_a_macro /* for versions in ksyms.c */ + +/* + * MIPS has no problems with write protection + */ +#define wp_works_ok 1 +#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ /* * User space process size: 2GB. This is hardcoded into a few places, * so don't change it unless you know what you are doing. TASK_SIZE - * for a 64 bit kernel is expandable to 8192PB, of which the current MIPS + * for a 64 bit kernel expandable to 8192EB, of which the current MIPS * implementations will "only" be able to use 1TB ... */ #define TASK_SIZE (0x80000000UL) @@ -58,7 +64,7 @@ struct mips_fpu_hard_struct { */ struct mips_fpu_soft_struct { long dummy; - }; +}; union mips_fpu_union { struct mips_fpu_hard_struct hard; @@ -73,63 +79,33 @@ union mips_fpu_union { * If you change thread_struct remember to change the #defines below too! */ struct thread_struct { - /* - * saved main processor registers - */ - __register_t reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23; - __register_t reg28, reg29, reg30, reg31; - /* - * saved cp0 stuff - */ - unsigned int cp0_status; - /* - * saved fpu/fpu emulator stuff - */ - union mips_fpu_union fpu; - /* - * Other stuff associated with the thread - */ - long cp0_badvaddr; + /* Saved main processor registers. */ + unsigned long reg16 __attribute__ ((aligned (8))); + unsigned long reg17, reg18, reg19, reg20, reg21, reg22, reg23; + unsigned long reg28, reg29, reg30, reg31; + + /* Saved cp0 stuff. */ + unsigned long cp0_status; + + /* Saved fpu/fpu emulator stuff. */ + union mips_fpu_union fpu __attribute__ ((aligned (8))); + + /* Other stuff associated with the thread. */ + unsigned long cp0_badvaddr; unsigned long error_code; unsigned long trap_no; - long ksp; /* Top of kernel stack */ - long pg_dir; /* L1 page table pointer */ + unsigned long ksp; /* Top of kernel stack */ + unsigned long pg_dir; /* used in tlb refill */ #define MF_FIXADE 1 /* Fix address errors in software */ #define MF_LOGADE 2 /* Log address errors to syslog */ unsigned long mflags; - unsigned long segment; + int current_ds; + unsigned long irix_trampoline; /* Wheee... */ + unsigned long irix_oldctx; }; #endif /* !defined (__LANGUAGE_ASSEMBLY__) */ -/* - * If you change the #defines remember to change thread_struct above too! - */ -#define TOFF_REG16 0 -#define TOFF_REG17 (TOFF_REG16+SZREG) -#define TOFF_REG18 (TOFF_REG17+SZREG) -#define TOFF_REG19 (TOFF_REG18+SZREG) -#define TOFF_REG20 (TOFF_REG19+SZREG) -#define TOFF_REG21 (TOFF_REG20+SZREG) -#define TOFF_REG22 (TOFF_REG21+SZREG) -#define TOFF_REG23 (TOFF_REG22+SZREG) -#define TOFF_REG28 (TOFF_REG23+SZREG) -#define TOFF_REG29 (TOFF_REG28+SZREG) -#define TOFF_REG30 (TOFF_REG29+SZREG) -#define TOFF_REG31 (TOFF_REG30+SZREG) -#define TOFF_CP0_STATUS (TOFF_REG31+SZREG) -/* - * Pad for 8 byte boundary! - */ -#define TOFF_FPU (((TOFF_CP0_STATUS+SZREG)+(8-1))&~(8-1)) -#define TOFF_CP0_BADVADDR (TOFF_FPU+264) -#define TOFF_ERROR_CODE (TOFF_CP0_BADVADDR+4) -#define TOFF_TRAP_NO (TOFF_ERROR_CODE+4) -#define TOFF_KSP (TOFF_TRAP_NO+4) -#define TOFF_PG_DIR (TOFF_KSP+4) -#define TOFF_MFLAGS (TOFF_PG_DIR+4) -#define TOFF_EX (TOFF_PG_MFLAGS+4) - #define INIT_MMAP { &init_mm, KSEG0, KSEG1, PAGE_SHARED, \ VM_READ | VM_WRITE | VM_EXEC } @@ -151,46 +127,39 @@ struct thread_struct { * Other stuff associated with the process \ */ \ 0, 0, 0, sizeof(init_kernel_stack) + (unsigned long)init_kernel_stack - 8, \ - (unsigned long) swapper_pg_dir - PT_OFFSET, \ + (unsigned long) swapper_pg_dir, \ /* \ * For now the default is to fix address errors \ */ \ - MF_FIXADE, \ - KERNEL_DS \ + MF_FIXADE, 0, 0, 0 \ } -/* - * Paul, please check if 4kb stack are sufficient for the R3000. With 4kb - * I never had a stack overflows on 32 bit R4000 kernels but the almost - * completly 64bit R4000 kernels from 1.3.63 on need more stack even in - * trivial situations. - */ +#ifdef __KERNEL__ + #define KERNEL_STACK_SIZE 8192 #if !defined (__LANGUAGE_ASSEMBLY__) -extern unsigned long alloc_kernel_stack(void); -extern void free_kernel_stack(unsigned long stack); - /* * Return saved PC of a blocked thread. */ -extern unsigned long (*thread_saved_pc)(struct thread_struct *t); +extern inline unsigned long thread_saved_pc(struct thread_struct *t) +{ + return ((struct pt_regs *)(long)t->reg29)->cp0_epc; +} /* * Do necessary setup to start up a newly executed thread. */ extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp); +#endif /* !defined (__LANGUAGE_ASSEMBLY__) */ + /* * Does the process account for user or for system time? */ -#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) -#define USES_USER_TIME(regs) (!((regs)->cp0_status & 0x4)) -#endif -#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS5) #define USES_USER_TIME(regs) (!((regs)->cp0_status & 0x18)) -#endif + +#endif /* __KERNEL__ */ /* * Return_address is a replacement for __builtin_return_address(count) @@ -215,6 +184,5 @@ extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long */ #define return_address() NULL #endif -#endif /* !defined (__LANGUAGE_ASSEMBLY__) */ #endif /* __ASM_MIPS_PROCESSOR_H */ diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h index ade150d90..ebe4cf888 100644 --- a/include/asm-mips/ptrace.h +++ b/include/asm-mips/ptrace.h @@ -13,89 +13,52 @@ #ifndef __ASM_MIPS_PTRACE_H #define __ASM_MIPS_PTRACE_H -#include <asm/sgidefs.h> -#include <asm/register.h> - -/* - * General purpose registers. - */ -#define GPR_BASE 0 -#define NGP_REGS 32 - -/* - * Floating point registers. - */ -#define FPR_BASE (GPR_BASE + NGP_REGS) -#define NFP_REGS 32 - -/* - * Signal handlers - */ -#define SIG_BASE (FPR_BASE + NFP_REGS) -#define NSIG_HNDLRS 32 - -/* - * Special registers. - */ -#define SPEC_BASE (SIG_BASE + NSIG_HNDLRS) -#define NSPEC_REGS 7 -#define PC SPEC_BASE -#define CAUSE (PC + 1) -#define BADVADDR (CAUSE + 1) -#define MMHI (BADVADDR + 1) -#define MMLO (MMHI + 1) -#define FPC_CSR (MMLO + 1) -#define FPC_EIR (FPC_CSR + 1) -#define NPTRC_REGS (FPC_EIR + 1) +#include <linux/types.h> +#ifndef __ASSEMBLY__ /* * This struct defines the way the registers are stored on the stack during a - * system call/exception. As usual the registers zero/k0/k1 aren't being saved. + * system call/exception. As usual the registers k0/k1 aren't being saved. */ struct pt_regs { - /* - * Pad bytes for argument save space on the stack - * 20/40 Bytes for 32/64 bit code - */ - __register_t pad0[6]; /* extra word for alignment */ + /* Pad bytes for argument save space on the stack. */ + unsigned long pad0[6]; - /* - * Saved main processor registers - */ - __register_t regs[32]; + /* Saved main processor registers. */ + unsigned long regs[32]; - /* - * Other saved registers - */ - __register_t lo; - __register_t hi; - __register_t orig_reg2; - __register_t orig_reg7; + /* Other saved registers. */ + unsigned long lo; + unsigned long hi; + unsigned long orig_reg2; + unsigned long orig_reg7; /* * saved cp0 registers */ - __register_t cp0_epc; - __register_t cp0_badvaddr; - unsigned int cp0_status; - unsigned int cp0_cause; + unsigned long cp0_epc; + unsigned long cp0_badvaddr; + unsigned long cp0_status; + unsigned long cp0_cause; }; +#endif /* !(__ASSEMBLY__) */ + +#include <asm/offset.h> + #ifdef __KERNEL__ +#ifndef __ASSEMBLY__ /* * Does the process account for user or for system time? */ -#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) -#define user_mode(regs) (!((regs)->cp0_status & 0x8)) -#endif -#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS5) #define user_mode(regs) ((regs)->cp0_status & 0x10) -#endif #define instruction_pointer(regs) ((regs)->cp0_epc) -extern void show_regs(struct pt_regs *); + +extern void (*show_regs)(struct pt_regs *); +#endif /* !(__ASSEMBLY__) */ + #endif #endif /* __ASM_MIPS_PTRACE_H */ diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h new file mode 100644 index 000000000..07b0ceff2 --- /dev/null +++ b/include/asm-mips/r4kcache.h @@ -0,0 +1,1025 @@ +/* $Id: r4kcache.h,v 1.3 1996/07/22 22:32:59 dm Exp $ + * r4kcache.h: Inline assembly cache operations. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#ifndef _MIPS_R4KCACHE_H +#define _MIPS_R4KCACHE_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 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)); +} + +extern inline void blast_dcache16(void) +{ + unsigned long start = KSEG0; + unsigned long end = (start + dcache_size); + + while(start < end) { + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x010(%0) + cache %1, 0x020(%0); cache %1, 0x030(%0) + cache %1, 0x040(%0); cache %1, 0x050(%0) + cache %1, 0x060(%0); cache %1, 0x070(%0) + cache %1, 0x080(%0); cache %1, 0x090(%0) + cache %1, 0x0a0(%0); cache %1, 0x0b0(%0) + cache %1, 0x0c0(%0); cache %1, 0x0d0(%0) + cache %1, 0x0e0(%0); cache %1, 0x0f0(%0) + cache %1, 0x100(%0); cache %1, 0x110(%0) + cache %1, 0x120(%0); cache %1, 0x130(%0) + cache %1, 0x140(%0); cache %1, 0x150(%0) + cache %1, 0x160(%0); cache %1, 0x170(%0) + cache %1, 0x180(%0); cache %1, 0x190(%0) + cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) + cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) + cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) + .set mips0 + .set reorder" + : + : "r" (start), + "i" (Index_Writeback_Inv_D)); + start += 0x200; + } +} + +extern inline void blast_dcache16_page(unsigned long page) +{ + unsigned long start = page; + unsigned long end = (start + PAGE_SIZE); + + while(start < end) { + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x010(%0) + cache %1, 0x020(%0); cache %1, 0x030(%0) + cache %1, 0x040(%0); cache %1, 0x050(%0) + cache %1, 0x060(%0); cache %1, 0x070(%0) + cache %1, 0x080(%0); cache %1, 0x090(%0) + cache %1, 0x0a0(%0); cache %1, 0x0b0(%0) + cache %1, 0x0c0(%0); cache %1, 0x0d0(%0) + cache %1, 0x0e0(%0); cache %1, 0x0f0(%0) + cache %1, 0x100(%0); cache %1, 0x110(%0) + cache %1, 0x120(%0); cache %1, 0x130(%0) + cache %1, 0x140(%0); cache %1, 0x150(%0) + cache %1, 0x160(%0); cache %1, 0x170(%0) + cache %1, 0x180(%0); cache %1, 0x190(%0) + cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) + cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) + cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) + cache %1, 0x200(%0); cache %1, 0x210(%0) + cache %1, 0x220(%0); cache %1, 0x230(%0) + cache %1, 0x240(%0); cache %1, 0x250(%0) + cache %1, 0x260(%0); cache %1, 0x270(%0) + cache %1, 0x280(%0); cache %1, 0x290(%0) + cache %1, 0x2a0(%0); cache %1, 0x2b0(%0) + cache %1, 0x2c0(%0); cache %1, 0x2d0(%0) + cache %1, 0x2e0(%0); cache %1, 0x2f0(%0) + cache %1, 0x300(%0); cache %1, 0x310(%0) + cache %1, 0x320(%0); cache %1, 0x330(%0) + cache %1, 0x340(%0); cache %1, 0x350(%0) + cache %1, 0x360(%0); cache %1, 0x370(%0) + cache %1, 0x380(%0); cache %1, 0x390(%0) + cache %1, 0x3a0(%0); cache %1, 0x3b0(%0) + cache %1, 0x3c0(%0); cache %1, 0x3d0(%0) + cache %1, 0x3e0(%0); cache %1, 0x3f0(%0) + cache %1, 0x400(%0); cache %1, 0x410(%0) + cache %1, 0x420(%0); cache %1, 0x430(%0) + cache %1, 0x440(%0); cache %1, 0x450(%0) + cache %1, 0x460(%0); cache %1, 0x470(%0) + cache %1, 0x480(%0); cache %1, 0x490(%0) + cache %1, 0x4a0(%0); cache %1, 0x4b0(%0) + cache %1, 0x4c0(%0); cache %1, 0x4d0(%0) + cache %1, 0x4e0(%0); cache %1, 0x4f0(%0) + cache %1, 0x500(%0); cache %1, 0x510(%0) + cache %1, 0x520(%0); cache %1, 0x530(%0) + cache %1, 0x540(%0); cache %1, 0x550(%0) + cache %1, 0x560(%0); cache %1, 0x570(%0) + cache %1, 0x580(%0); cache %1, 0x590(%0) + cache %1, 0x5a0(%0); cache %1, 0x5b0(%0) + cache %1, 0x5c0(%0); cache %1, 0x5d0(%0) + cache %1, 0x5e0(%0); cache %1, 0x5f0(%0) + cache %1, 0x600(%0); cache %1, 0x610(%0) + cache %1, 0x620(%0); cache %1, 0x630(%0) + cache %1, 0x640(%0); cache %1, 0x650(%0) + cache %1, 0x660(%0); cache %1, 0x670(%0) + cache %1, 0x680(%0); cache %1, 0x690(%0) + cache %1, 0x6a0(%0); cache %1, 0x6b0(%0) + cache %1, 0x6c0(%0); cache %1, 0x6d0(%0) + cache %1, 0x6e0(%0); cache %1, 0x6f0(%0) + cache %1, 0x700(%0); cache %1, 0x710(%0) + cache %1, 0x720(%0); cache %1, 0x730(%0) + cache %1, 0x740(%0); cache %1, 0x750(%0) + cache %1, 0x760(%0); cache %1, 0x770(%0) + cache %1, 0x780(%0); cache %1, 0x790(%0) + cache %1, 0x7a0(%0); cache %1, 0x7b0(%0) + cache %1, 0x7c0(%0); cache %1, 0x7d0(%0) + cache %1, 0x7e0(%0); cache %1, 0x7f0(%0) + .set mips0 + .set reorder" + : + : "r" (start), + "i" (Hit_Writeback_Inv_D)); + start += 0x800; + } +} + +extern inline void blast_dcache16_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = (start + PAGE_SIZE); + + while(start < end) { + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x010(%0) + cache %1, 0x020(%0); cache %1, 0x030(%0) + cache %1, 0x040(%0); cache %1, 0x050(%0) + cache %1, 0x060(%0); cache %1, 0x070(%0) + cache %1, 0x080(%0); cache %1, 0x090(%0) + cache %1, 0x0a0(%0); cache %1, 0x0b0(%0) + cache %1, 0x0c0(%0); cache %1, 0x0d0(%0) + cache %1, 0x0e0(%0); cache %1, 0x0f0(%0) + cache %1, 0x100(%0); cache %1, 0x110(%0) + cache %1, 0x120(%0); cache %1, 0x130(%0) + cache %1, 0x140(%0); cache %1, 0x150(%0) + cache %1, 0x160(%0); cache %1, 0x170(%0) + cache %1, 0x180(%0); cache %1, 0x190(%0) + cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) + cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) + cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) + cache %1, 0x200(%0); cache %1, 0x210(%0) + cache %1, 0x220(%0); cache %1, 0x230(%0) + cache %1, 0x240(%0); cache %1, 0x250(%0) + cache %1, 0x260(%0); cache %1, 0x270(%0) + cache %1, 0x280(%0); cache %1, 0x290(%0) + cache %1, 0x2a0(%0); cache %1, 0x2b0(%0) + cache %1, 0x2c0(%0); cache %1, 0x2d0(%0) + cache %1, 0x2e0(%0); cache %1, 0x2f0(%0) + cache %1, 0x300(%0); cache %1, 0x310(%0) + cache %1, 0x320(%0); cache %1, 0x330(%0) + cache %1, 0x340(%0); cache %1, 0x350(%0) + cache %1, 0x360(%0); cache %1, 0x370(%0) + cache %1, 0x380(%0); cache %1, 0x390(%0) + cache %1, 0x3a0(%0); cache %1, 0x3b0(%0) + cache %1, 0x3c0(%0); cache %1, 0x3d0(%0) + cache %1, 0x3e0(%0); cache %1, 0x3f0(%0) + cache %1, 0x400(%0); cache %1, 0x410(%0) + cache %1, 0x420(%0); cache %1, 0x430(%0) + cache %1, 0x440(%0); cache %1, 0x450(%0) + cache %1, 0x460(%0); cache %1, 0x470(%0) + cache %1, 0x480(%0); cache %1, 0x490(%0) + cache %1, 0x4a0(%0); cache %1, 0x4b0(%0) + cache %1, 0x4c0(%0); cache %1, 0x4d0(%0) + cache %1, 0x4e0(%0); cache %1, 0x4f0(%0) + cache %1, 0x500(%0); cache %1, 0x510(%0) + cache %1, 0x520(%0); cache %1, 0x530(%0) + cache %1, 0x540(%0); cache %1, 0x550(%0) + cache %1, 0x560(%0); cache %1, 0x570(%0) + cache %1, 0x580(%0); cache %1, 0x590(%0) + cache %1, 0x5a0(%0); cache %1, 0x5b0(%0) + cache %1, 0x5c0(%0); cache %1, 0x5d0(%0) + cache %1, 0x5e0(%0); cache %1, 0x5f0(%0) + cache %1, 0x600(%0); cache %1, 0x610(%0) + cache %1, 0x620(%0); cache %1, 0x630(%0) + cache %1, 0x640(%0); cache %1, 0x650(%0) + cache %1, 0x660(%0); cache %1, 0x670(%0) + cache %1, 0x680(%0); cache %1, 0x690(%0) + cache %1, 0x6a0(%0); cache %1, 0x6b0(%0) + cache %1, 0x6c0(%0); cache %1, 0x6d0(%0) + cache %1, 0x6e0(%0); cache %1, 0x6f0(%0) + cache %1, 0x700(%0); cache %1, 0x710(%0) + cache %1, 0x720(%0); cache %1, 0x730(%0) + cache %1, 0x740(%0); cache %1, 0x750(%0) + cache %1, 0x760(%0); cache %1, 0x770(%0) + cache %1, 0x780(%0); cache %1, 0x790(%0) + cache %1, 0x7a0(%0); cache %1, 0x7b0(%0) + cache %1, 0x7c0(%0); cache %1, 0x7d0(%0) + cache %1, 0x7e0(%0); cache %1, 0x7f0(%0) + .set mips0 + .set reorder" + : + : "r" (start), + "i" (Index_Writeback_Inv_D)); + start += 0x800; + } +} + +extern inline void blast_dcache32(void) +{ + unsigned long start = KSEG0; + unsigned long end = (start + dcache_size); + + while(start < end) { + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x020(%0) + cache %1, 0x040(%0); cache %1, 0x060(%0) + cache %1, 0x080(%0); cache %1, 0x0a0(%0) + cache %1, 0x0c0(%0); cache %1, 0x0e0(%0) + cache %1, 0x100(%0); cache %1, 0x120(%0) + cache %1, 0x140(%0); cache %1, 0x160(%0) + cache %1, 0x180(%0); cache %1, 0x1a0(%0) + cache %1, 0x1c0(%0); cache %1, 0x1e0(%0) + cache %1, 0x200(%0); cache %1, 0x220(%0) + cache %1, 0x240(%0); cache %1, 0x260(%0) + cache %1, 0x280(%0); cache %1, 0x2a0(%0) + cache %1, 0x2c0(%0); cache %1, 0x2e0(%0) + cache %1, 0x300(%0); cache %1, 0x320(%0) + cache %1, 0x340(%0); cache %1, 0x360(%0) + cache %1, 0x380(%0); cache %1, 0x3a0(%0) + cache %1, 0x3c0(%0); cache %1, 0x3e0(%0) + cache %1, 0x400(%0); cache %1, 0x420(%0) + cache %1, 0x440(%0); cache %1, 0x460(%0) + cache %1, 0x480(%0); cache %1, 0x4a0(%0) + cache %1, 0x4c0(%0); cache %1, 0x4e0(%0) + cache %1, 0x500(%0); cache %1, 0x520(%0) + cache %1, 0x540(%0); cache %1, 0x560(%0) + cache %1, 0x580(%0); cache %1, 0x5a0(%0) + cache %1, 0x5c0(%0); cache %1, 0x5e0(%0) + cache %1, 0x600(%0); cache %1, 0x620(%0) + cache %1, 0x640(%0); cache %1, 0x660(%0) + cache %1, 0x680(%0); cache %1, 0x6a0(%0) + cache %1, 0x6c0(%0); cache %1, 0x6e0(%0) + cache %1, 0x700(%0); cache %1, 0x720(%0) + cache %1, 0x740(%0); cache %1, 0x760(%0) + cache %1, 0x780(%0); cache %1, 0x7a0(%0) + cache %1, 0x7c0(%0); cache %1, 0x7e0(%0) + .set mips0 + .set reorder" + : + : "r" (start), + "i" (Index_Writeback_Inv_D)); + start += 0x400; + } +} + +extern inline void blast_dcache32_page(unsigned long page) +{ + unsigned long start = page; + unsigned long end = (start + PAGE_SIZE); + + while(start < end) { + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x020(%0) + cache %1, 0x040(%0); cache %1, 0x060(%0) + cache %1, 0x080(%0); cache %1, 0x0a0(%0) + cache %1, 0x0c0(%0); cache %1, 0x0e0(%0) + cache %1, 0x100(%0); cache %1, 0x120(%0) + cache %1, 0x140(%0); cache %1, 0x160(%0) + cache %1, 0x180(%0); cache %1, 0x1a0(%0) + cache %1, 0x1c0(%0); cache %1, 0x1e0(%0) + cache %1, 0x200(%0); cache %1, 0x220(%0) + cache %1, 0x240(%0); cache %1, 0x260(%0) + cache %1, 0x280(%0); cache %1, 0x2a0(%0) + cache %1, 0x2c0(%0); cache %1, 0x2e0(%0) + cache %1, 0x300(%0); cache %1, 0x320(%0) + cache %1, 0x340(%0); cache %1, 0x360(%0) + cache %1, 0x380(%0); cache %1, 0x3a0(%0) + cache %1, 0x3c0(%0); cache %1, 0x3e0(%0) + cache %1, 0x400(%0); cache %1, 0x420(%0) + cache %1, 0x440(%0); cache %1, 0x460(%0) + cache %1, 0x480(%0); cache %1, 0x4a0(%0) + cache %1, 0x4c0(%0); cache %1, 0x4e0(%0) + cache %1, 0x500(%0); cache %1, 0x520(%0) + cache %1, 0x540(%0); cache %1, 0x560(%0) + cache %1, 0x580(%0); cache %1, 0x5a0(%0) + cache %1, 0x5c0(%0); cache %1, 0x5e0(%0) + cache %1, 0x600(%0); cache %1, 0x620(%0) + cache %1, 0x640(%0); cache %1, 0x660(%0) + cache %1, 0x680(%0); cache %1, 0x6a0(%0) + cache %1, 0x6c0(%0); cache %1, 0x6e0(%0) + cache %1, 0x700(%0); cache %1, 0x720(%0) + cache %1, 0x740(%0); cache %1, 0x760(%0) + cache %1, 0x780(%0); cache %1, 0x7a0(%0) + cache %1, 0x7c0(%0); cache %1, 0x7e0(%0) + .set mips0 + .set reorder" + : + : "r" (start), + "i" (Hit_Writeback_Inv_D)); + start += 0x800; + } +} + +extern inline void blast_dcache32_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = (start + PAGE_SIZE); + + while(start < end) { + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x020(%0) + cache %1, 0x040(%0); cache %1, 0x060(%0) + cache %1, 0x080(%0); cache %1, 0x0a0(%0) + cache %1, 0x0c0(%0); cache %1, 0x0e0(%0) + cache %1, 0x100(%0); cache %1, 0x120(%0) + cache %1, 0x140(%0); cache %1, 0x160(%0) + cache %1, 0x180(%0); cache %1, 0x1a0(%0) + cache %1, 0x1c0(%0); cache %1, 0x1e0(%0) + cache %1, 0x200(%0); cache %1, 0x220(%0) + cache %1, 0x240(%0); cache %1, 0x260(%0) + cache %1, 0x280(%0); cache %1, 0x2a0(%0) + cache %1, 0x2c0(%0); cache %1, 0x2e0(%0) + cache %1, 0x300(%0); cache %1, 0x320(%0) + cache %1, 0x340(%0); cache %1, 0x360(%0) + cache %1, 0x380(%0); cache %1, 0x3a0(%0) + cache %1, 0x3c0(%0); cache %1, 0x3e0(%0) + cache %1, 0x400(%0); cache %1, 0x420(%0) + cache %1, 0x440(%0); cache %1, 0x460(%0) + cache %1, 0x480(%0); cache %1, 0x4a0(%0) + cache %1, 0x4c0(%0); cache %1, 0x4e0(%0) + cache %1, 0x500(%0); cache %1, 0x520(%0) + cache %1, 0x540(%0); cache %1, 0x560(%0) + cache %1, 0x580(%0); cache %1, 0x5a0(%0) + cache %1, 0x5c0(%0); cache %1, 0x5e0(%0) + cache %1, 0x600(%0); cache %1, 0x620(%0) + cache %1, 0x640(%0); cache %1, 0x660(%0) + cache %1, 0x680(%0); cache %1, 0x6a0(%0) + cache %1, 0x6c0(%0); cache %1, 0x6e0(%0) + cache %1, 0x700(%0); cache %1, 0x720(%0) + cache %1, 0x740(%0); cache %1, 0x760(%0) + cache %1, 0x780(%0); cache %1, 0x7a0(%0) + cache %1, 0x7c0(%0); cache %1, 0x7e0(%0) + .set mips0 + .set reorder" + : + : "r" (start), + "i" (Index_Invalidate_I)); + start += 0x800; + } +} + +extern inline void blast_icache16(void) +{ + unsigned long start = KSEG0; + unsigned long end = (start + icache_size); + + while(start < end) { + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x010(%0) + cache %1, 0x020(%0); cache %1, 0x030(%0) + cache %1, 0x040(%0); cache %1, 0x050(%0) + cache %1, 0x060(%0); cache %1, 0x070(%0) + cache %1, 0x080(%0); cache %1, 0x090(%0) + cache %1, 0x0a0(%0); cache %1, 0x0b0(%0) + cache %1, 0x0c0(%0); cache %1, 0x0d0(%0) + cache %1, 0x0e0(%0); cache %1, 0x0f0(%0) + cache %1, 0x100(%0); cache %1, 0x110(%0) + cache %1, 0x120(%0); cache %1, 0x130(%0) + cache %1, 0x140(%0); cache %1, 0x150(%0) + cache %1, 0x160(%0); cache %1, 0x170(%0) + cache %1, 0x180(%0); cache %1, 0x190(%0) + cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) + cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) + cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) + .set mips0 + .set reorder" + : + : "r" (start), + "i" (Index_Invalidate_I)); + start += 0x200; + } +} + +extern inline void blast_icache16_page(unsigned long page) +{ + unsigned long start = page; + unsigned long end = (start + PAGE_SIZE); + + while(start < end) { + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x010(%0) + cache %1, 0x020(%0); cache %1, 0x030(%0) + cache %1, 0x040(%0); cache %1, 0x050(%0) + cache %1, 0x060(%0); cache %1, 0x070(%0) + cache %1, 0x080(%0); cache %1, 0x090(%0) + cache %1, 0x0a0(%0); cache %1, 0x0b0(%0) + cache %1, 0x0c0(%0); cache %1, 0x0d0(%0) + cache %1, 0x0e0(%0); cache %1, 0x0f0(%0) + cache %1, 0x100(%0); cache %1, 0x110(%0) + cache %1, 0x120(%0); cache %1, 0x130(%0) + cache %1, 0x140(%0); cache %1, 0x150(%0) + cache %1, 0x160(%0); cache %1, 0x170(%0) + cache %1, 0x180(%0); cache %1, 0x190(%0) + cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) + cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) + cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) + cache %1, 0x200(%0); cache %1, 0x210(%0) + cache %1, 0x220(%0); cache %1, 0x230(%0) + cache %1, 0x240(%0); cache %1, 0x250(%0) + cache %1, 0x260(%0); cache %1, 0x270(%0) + cache %1, 0x280(%0); cache %1, 0x290(%0) + cache %1, 0x2a0(%0); cache %1, 0x2b0(%0) + cache %1, 0x2c0(%0); cache %1, 0x2d0(%0) + cache %1, 0x2e0(%0); cache %1, 0x2f0(%0) + cache %1, 0x300(%0); cache %1, 0x310(%0) + cache %1, 0x320(%0); cache %1, 0x330(%0) + cache %1, 0x340(%0); cache %1, 0x350(%0) + cache %1, 0x360(%0); cache %1, 0x370(%0) + cache %1, 0x380(%0); cache %1, 0x390(%0) + cache %1, 0x3a0(%0); cache %1, 0x3b0(%0) + cache %1, 0x3c0(%0); cache %1, 0x3d0(%0) + cache %1, 0x3e0(%0); cache %1, 0x3f0(%0) + cache %1, 0x400(%0); cache %1, 0x410(%0) + cache %1, 0x420(%0); cache %1, 0x430(%0) + cache %1, 0x440(%0); cache %1, 0x450(%0) + cache %1, 0x460(%0); cache %1, 0x470(%0) + cache %1, 0x480(%0); cache %1, 0x490(%0) + cache %1, 0x4a0(%0); cache %1, 0x4b0(%0) + cache %1, 0x4c0(%0); cache %1, 0x4d0(%0) + cache %1, 0x4e0(%0); cache %1, 0x4f0(%0) + cache %1, 0x500(%0); cache %1, 0x510(%0) + cache %1, 0x520(%0); cache %1, 0x530(%0) + cache %1, 0x540(%0); cache %1, 0x550(%0) + cache %1, 0x560(%0); cache %1, 0x570(%0) + cache %1, 0x580(%0); cache %1, 0x590(%0) + cache %1, 0x5a0(%0); cache %1, 0x5b0(%0) + cache %1, 0x5c0(%0); cache %1, 0x5d0(%0) + cache %1, 0x5e0(%0); cache %1, 0x5f0(%0) + cache %1, 0x600(%0); cache %1, 0x610(%0) + cache %1, 0x620(%0); cache %1, 0x630(%0) + cache %1, 0x640(%0); cache %1, 0x650(%0) + cache %1, 0x660(%0); cache %1, 0x670(%0) + cache %1, 0x680(%0); cache %1, 0x690(%0) + cache %1, 0x6a0(%0); cache %1, 0x6b0(%0) + cache %1, 0x6c0(%0); cache %1, 0x6d0(%0) + cache %1, 0x6e0(%0); cache %1, 0x6f0(%0) + cache %1, 0x700(%0); cache %1, 0x710(%0) + cache %1, 0x720(%0); cache %1, 0x730(%0) + cache %1, 0x740(%0); cache %1, 0x750(%0) + cache %1, 0x760(%0); cache %1, 0x770(%0) + cache %1, 0x780(%0); cache %1, 0x790(%0) + cache %1, 0x7a0(%0); cache %1, 0x7b0(%0) + cache %1, 0x7c0(%0); cache %1, 0x7d0(%0) + cache %1, 0x7e0(%0); cache %1, 0x7f0(%0) + .set mips0 + .set reorder" + : + : "r" (start), + "i" (Hit_Invalidate_I)); + start += 0x800; + } +} + +extern inline void blast_icache16_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = (start + PAGE_SIZE); + + while(start < end) { + __asm__ __volatile__(" +.set noreorder +.set mips3 +cache 0, 0x000(%0); cache 0, 0x010(%0); cache 0, 0x020(%0); cache 0, 0x030(%0) +cache 0, 0x040(%0); cache 0, 0x050(%0); cache 0, 0x060(%0); cache 0, 0x070(%0) +cache 0, 0x080(%0); cache 0, 0x090(%0); cache 0, 0x0a0(%0); cache 0, 0x0b0(%0) +cache 0, 0x0c0(%0); cache 0, 0x0d0(%0); cache 0, 0x0e0(%0); cache 0, 0x0f0(%0) +cache 0, 0x100(%0); cache 0, 0x110(%0); cache 0, 0x120(%0); cache 0, 0x130(%0) +cache 0, 0x140(%0); cache 0, 0x150(%0); cache 0, 0x160(%0); cache 0, 0x170(%0) +cache 0, 0x180(%0); cache 0, 0x190(%0); cache 0, 0x1a0(%0); cache 0, 0x1b0(%0) +cache 0, 0x1c0(%0); cache 0, 0x1d0(%0); cache 0, 0x1e0(%0); cache 0, 0x1f0(%0) +cache 0, 0x200(%0); cache 0, 0x210(%0); cache 0, 0x220(%0); cache 0, 0x230(%0) +cache 0, 0x240(%0); cache 0, 0x250(%0); cache 0, 0x260(%0); cache 0, 0x270(%0) +cache 0, 0x280(%0); cache 0, 0x290(%0); cache 0, 0x2a0(%0); cache 0, 0x2b0(%0) +cache 0, 0x2c0(%0); cache 0, 0x2d0(%0); cache 0, 0x2e0(%0); cache 0, 0x2f0(%0) +cache 0, 0x300(%0); cache 0, 0x310(%0); cache 0, 0x320(%0); cache 0, 0x330(%0) +cache 0, 0x340(%0); cache 0, 0x350(%0); cache 0, 0x360(%0); cache 0, 0x370(%0) +cache 0, 0x380(%0); cache 0, 0x390(%0); cache 0, 0x3a0(%0); cache 0, 0x3b0(%0) +cache 0, 0x3c0(%0); cache 0, 0x3d0(%0); cache 0, 0x3e0(%0); cache 0, 0x3f0(%0) +cache 0, 0x400(%0); cache 0, 0x410(%0); cache 0, 0x420(%0); cache 0, 0x430(%0) +cache 0, 0x440(%0); cache 0, 0x450(%0); cache 0, 0x460(%0); cache 0, 0x470(%0) +cache 0, 0x480(%0); cache 0, 0x490(%0); cache 0, 0x4a0(%0); cache 0, 0x4b0(%0) +cache 0, 0x4c0(%0); cache 0, 0x4d0(%0); cache 0, 0x4e0(%0); cache 0, 0x4f0(%0) +cache 0, 0x500(%0); cache 0, 0x510(%0); cache 0, 0x520(%0); cache 0, 0x530(%0) +cache 0, 0x540(%0); cache 0, 0x550(%0); cache 0, 0x560(%0); cache 0, 0x570(%0) +cache 0, 0x580(%0); cache 0, 0x590(%0); cache 0, 0x5a0(%0); cache 0, 0x5b0(%0) +cache 0, 0x5c0(%0); cache 0, 0x5d0(%0); cache 0, 0x5e0(%0); cache 0, 0x5f0(%0) +cache 0, 0x600(%0); cache 0, 0x610(%0); cache 0, 0x620(%0); cache 0, 0x630(%0) +cache 0, 0x640(%0); cache 0, 0x650(%0); cache 0, 0x660(%0); cache 0, 0x670(%0) +cache 0, 0x680(%0); cache 0, 0x690(%0); cache 0, 0x6a0(%0); cache 0, 0x6b0(%0) +cache 0, 0x6c0(%0); cache 0, 0x6d0(%0); cache 0, 0x6e0(%0); cache 0, 0x6f0(%0) +cache 0, 0x700(%0); cache 0, 0x710(%0); cache 0, 0x720(%0); cache 0, 0x730(%0) +cache 0, 0x740(%0); cache 0, 0x750(%0); cache 0, 0x760(%0); cache 0, 0x770(%0) +cache 0, 0x780(%0); cache 0, 0x790(%0); cache 0, 0x7a0(%0); cache 0, 0x7b0(%0) +cache 0, 0x7c0(%0); cache 0, 0x7d0(%0); cache 0, 0x7e0(%0); cache 0, 0x7f0(%0) +.set mips0 +.set reorder + " : : "r" (start)); + start += 0x800; + } +} + +extern inline void blast_icache32(void) +{ + unsigned long start = KSEG0; + unsigned long end = (start + icache_size); + + while(start < end) { + __asm__ __volatile__(" +.set noreorder +.set mips3 +cache 0, 0x000(%0); cache 0, 0x020(%0); cache 0, 0x040(%0); cache 0, 0x060(%0); +cache 0, 0x080(%0); cache 0, 0x0a0(%0); cache 0, 0x0c0(%0); cache 0, 0x0e0(%0); +cache 0, 0x100(%0); cache 0, 0x120(%0); cache 0, 0x140(%0); cache 0, 0x160(%0); +cache 0, 0x180(%0); cache 0, 0x1a0(%0); cache 0, 0x1c0(%0); cache 0, 0x1e0(%0); +cache 0, 0x200(%0); cache 0, 0x220(%0); cache 0, 0x240(%0); cache 0, 0x260(%0); +cache 0, 0x280(%0); cache 0, 0x2a0(%0); cache 0, 0x2c0(%0); cache 0, 0x2e0(%0); +cache 0, 0x300(%0); cache 0, 0x320(%0); cache 0, 0x340(%0); cache 0, 0x360(%0); +cache 0, 0x380(%0); cache 0, 0x3a0(%0); cache 0, 0x3c0(%0); cache 0, 0x3e0(%0); +.set mips0 +.set reorder + " : : "r" (start)); + start += 0x400; + } +} + +extern inline void blast_icache32_page(unsigned long page) +{ + unsigned long start = page; + unsigned long end = (start + PAGE_SIZE); + + while(start < end) { + __asm__ __volatile__(" +.set noreorder +.set mips3 +cache 16, 0x000(%0); cache 16, 0x020(%0); cache 16, 0x040(%0); cache 16, 0x060(%0); +cache 16, 0x080(%0); cache 16, 0x0a0(%0); cache 16, 0x0c0(%0); cache 16, 0x0e0(%0); +cache 16, 0x100(%0); cache 16, 0x120(%0); cache 16, 0x140(%0); cache 16, 0x160(%0); +cache 16, 0x180(%0); cache 16, 0x1a0(%0); cache 16, 0x1c0(%0); cache 16, 0x1e0(%0); +cache 16, 0x200(%0); cache 16, 0x220(%0); cache 16, 0x240(%0); cache 16, 0x260(%0); +cache 16, 0x280(%0); cache 16, 0x2a0(%0); cache 16, 0x2c0(%0); cache 16, 0x2e0(%0); +cache 16, 0x300(%0); cache 16, 0x320(%0); cache 16, 0x340(%0); cache 16, 0x360(%0); +cache 16, 0x380(%0); cache 16, 0x3a0(%0); cache 16, 0x3c0(%0); cache 16, 0x3e0(%0); +cache 16, 0x400(%0); cache 16, 0x420(%0); cache 16, 0x440(%0); cache 16, 0x460(%0); +cache 16, 0x480(%0); cache 16, 0x4a0(%0); cache 16, 0x4c0(%0); cache 16, 0x4e0(%0); +cache 16, 0x500(%0); cache 16, 0x520(%0); cache 16, 0x540(%0); cache 16, 0x560(%0); +cache 16, 0x580(%0); cache 16, 0x5a0(%0); cache 16, 0x5c0(%0); cache 16, 0x5e0(%0); +cache 16, 0x600(%0); cache 16, 0x620(%0); cache 16, 0x640(%0); cache 16, 0x660(%0); +cache 16, 0x680(%0); cache 16, 0x6a0(%0); cache 16, 0x6c0(%0); cache 16, 0x6e0(%0); +cache 16, 0x700(%0); cache 16, 0x720(%0); cache 16, 0x740(%0); cache 16, 0x760(%0); +cache 16, 0x780(%0); cache 16, 0x7a0(%0); cache 16, 0x7c0(%0); cache 16, 0x7e0(%0); +.set mips0 +.set reorder + " : : "r" (start)); + start += 0x800; + } +} + +extern inline void blast_icache32_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = (start + PAGE_SIZE); + + while(start < end) { + __asm__ __volatile__(" +.set noreorder +.set mips3 +cache 0, 0x000(%0); cache 0, 0x020(%0); cache 0, 0x040(%0); cache 0, 0x060(%0); +cache 0, 0x080(%0); cache 0, 0x0a0(%0); cache 0, 0x0c0(%0); cache 0, 0x0e0(%0); +cache 0, 0x100(%0); cache 0, 0x120(%0); cache 0, 0x140(%0); cache 0, 0x160(%0); +cache 0, 0x180(%0); cache 0, 0x1a0(%0); cache 0, 0x1c0(%0); cache 0, 0x1e0(%0); +cache 0, 0x200(%0); cache 0, 0x220(%0); cache 0, 0x240(%0); cache 0, 0x260(%0); +cache 0, 0x280(%0); cache 0, 0x2a0(%0); cache 0, 0x2c0(%0); cache 0, 0x2e0(%0); +cache 0, 0x300(%0); cache 0, 0x320(%0); cache 0, 0x340(%0); cache 0, 0x360(%0); +cache 0, 0x380(%0); cache 0, 0x3a0(%0); cache 0, 0x3c0(%0); cache 0, 0x3e0(%0); +cache 0, 0x400(%0); cache 0, 0x420(%0); cache 0, 0x440(%0); cache 0, 0x460(%0); +cache 0, 0x480(%0); cache 0, 0x4a0(%0); cache 0, 0x4c0(%0); cache 0, 0x4e0(%0); +cache 0, 0x500(%0); cache 0, 0x520(%0); cache 0, 0x540(%0); cache 0, 0x560(%0); +cache 0, 0x580(%0); cache 0, 0x5a0(%0); cache 0, 0x5c0(%0); cache 0, 0x5e0(%0); +cache 0, 0x600(%0); cache 0, 0x620(%0); cache 0, 0x640(%0); cache 0, 0x660(%0); +cache 0, 0x680(%0); cache 0, 0x6a0(%0); cache 0, 0x6c0(%0); cache 0, 0x6e0(%0); +cache 0, 0x700(%0); cache 0, 0x720(%0); cache 0, 0x740(%0); cache 0, 0x760(%0); +cache 0, 0x780(%0); cache 0, 0x7a0(%0); cache 0, 0x7c0(%0); cache 0, 0x7e0(%0); +.set mips0 +.set reorder + " : : "r" (start)); + start += 0x800; + } +} + +extern inline void blast_scache16(void) +{ + unsigned long start = KSEG0; + unsigned long end = KSEG0 + scache_size; + + while(start < end) { + __asm__ __volatile__(" +.set noreorder +.set mips3 +cache 3, 0x000(%0); cache 3, 0x010(%0); cache 3, 0x020(%0); cache 3, 0x030(%0) +cache 3, 0x040(%0); cache 3, 0x050(%0); cache 3, 0x060(%0); cache 3, 0x070(%0) +cache 3, 0x080(%0); cache 3, 0x090(%0); cache 3, 0x0a0(%0); cache 3, 0x0b0(%0) +cache 3, 0x0c0(%0); cache 3, 0x0d0(%0); cache 3, 0x0e0(%0); cache 3, 0x0f0(%0) +cache 3, 0x100(%0); cache 3, 0x110(%0); cache 3, 0x120(%0); cache 3, 0x130(%0) +cache 3, 0x140(%0); cache 3, 0x150(%0); cache 3, 0x160(%0); cache 3, 0x170(%0) +cache 3, 0x180(%0); cache 3, 0x190(%0); cache 3, 0x1a0(%0); cache 3, 0x1b0(%0) +cache 3, 0x1c0(%0); cache 3, 0x1d0(%0); cache 3, 0x1e0(%0); cache 3, 0x1f0(%0) +.set mips0 +.set reorder + " : : "r" (start)); + start += 0x200; + } +} + +extern inline void blast_scache16_page(unsigned long page) +{ + unsigned long start = page; + unsigned long end = page + PAGE_SIZE; + + while(start < end) { + __asm__ __volatile__(" +.set noreorder +.set mips3 +cache 23, 0x000(%0); cache 23, 0x010(%0); cache 23, 0x020(%0); cache 23, 0x030(%0) +cache 23, 0x040(%0); cache 23, 0x050(%0); cache 23, 0x060(%0); cache 23, 0x070(%0) +cache 23, 0x080(%0); cache 23, 0x090(%0); cache 23, 0x0a0(%0); cache 23, 0x0b0(%0) +cache 23, 0x0c0(%0); cache 23, 0x0d0(%0); cache 23, 0x0e0(%0); cache 23, 0x0f0(%0) +cache 23, 0x100(%0); cache 23, 0x110(%0); cache 23, 0x120(%0); cache 23, 0x130(%0) +cache 23, 0x140(%0); cache 23, 0x150(%0); cache 23, 0x160(%0); cache 23, 0x170(%0) +cache 23, 0x180(%0); cache 23, 0x190(%0); cache 23, 0x1a0(%0); cache 23, 0x1b0(%0) +cache 23, 0x1c0(%0); cache 23, 0x1d0(%0); cache 23, 0x1e0(%0); cache 23, 0x1f0(%0) +.set mips0 +.set reorder + " : : "r" (start)); + start += 0x200; + } +} + +extern inline void blast_scache16_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = page + PAGE_SIZE; + + while(start < end) { + __asm__ __volatile__(" +.set noreorder +.set mips3 +cache 3, 0x000(%0); cache 3, 0x010(%0); cache 3, 0x020(%0); cache 3, 0x030(%0) +cache 3, 0x040(%0); cache 3, 0x050(%0); cache 3, 0x060(%0); cache 3, 0x070(%0) +cache 3, 0x080(%0); cache 3, 0x090(%0); cache 3, 0x0a0(%0); cache 3, 0x0b0(%0) +cache 3, 0x0c0(%0); cache 3, 0x0d0(%0); cache 3, 0x0e0(%0); cache 3, 0x0f0(%0) +cache 3, 0x100(%0); cache 3, 0x110(%0); cache 3, 0x120(%0); cache 3, 0x130(%0) +cache 3, 0x140(%0); cache 3, 0x150(%0); cache 3, 0x160(%0); cache 3, 0x170(%0) +cache 3, 0x180(%0); cache 3, 0x190(%0); cache 3, 0x1a0(%0); cache 3, 0x1b0(%0) +cache 3, 0x1c0(%0); cache 3, 0x1d0(%0); cache 3, 0x1e0(%0); cache 3, 0x1f0(%0) +.set mips0 +.set reorder + " : : "r" (start)); + start += 0x200; + } +} + +extern inline void blast_scache32(void) +{ + unsigned long start = KSEG0; + unsigned long end = KSEG0 + scache_size; + + while(start < end) { + __asm__ __volatile__(" +.set noreorder +.set mips3 +cache 3, 0x000(%0); cache 3, 0x020(%0); cache 3, 0x040(%0); cache 3, 0x060(%0); +cache 3, 0x080(%0); cache 3, 0x0a0(%0); cache 3, 0x0c0(%0); cache 3, 0x0e0(%0); +cache 3, 0x100(%0); cache 3, 0x120(%0); cache 3, 0x140(%0); cache 3, 0x160(%0); +cache 3, 0x180(%0); cache 3, 0x1a0(%0); cache 3, 0x1c0(%0); cache 3, 0x1e0(%0); +cache 3, 0x200(%0); cache 3, 0x220(%0); cache 3, 0x240(%0); cache 3, 0x260(%0); +cache 3, 0x280(%0); cache 3, 0x2a0(%0); cache 3, 0x2c0(%0); cache 3, 0x2e0(%0); +cache 3, 0x300(%0); cache 3, 0x320(%0); cache 3, 0x340(%0); cache 3, 0x360(%0); +cache 3, 0x380(%0); cache 3, 0x3a0(%0); cache 3, 0x3c0(%0); cache 3, 0x3e0(%0); +.set mips0 +.set reorder + " : : "r" (start)); + start += 0x400; + } +} + +extern inline void blast_scache32_page(unsigned long page) +{ + unsigned long start = page; + unsigned long end = page + PAGE_SIZE; + + while(start < end) { + __asm__ __volatile__(" +.set noreorder +.set mips3 +cache 23, 0x000(%0); cache 23, 0x020(%0); cache 23, 0x040(%0); cache 23, 0x060(%0); +cache 23, 0x080(%0); cache 23, 0x0a0(%0); cache 23, 0x0c0(%0); cache 23, 0x0e0(%0); +cache 23, 0x100(%0); cache 23, 0x120(%0); cache 23, 0x140(%0); cache 23, 0x160(%0); +cache 23, 0x180(%0); cache 23, 0x1a0(%0); cache 23, 0x1c0(%0); cache 23, 0x1e0(%0); +cache 23, 0x200(%0); cache 23, 0x220(%0); cache 23, 0x240(%0); cache 23, 0x260(%0); +cache 23, 0x280(%0); cache 23, 0x2a0(%0); cache 23, 0x2c0(%0); cache 23, 0x2e0(%0); +cache 23, 0x300(%0); cache 23, 0x320(%0); cache 23, 0x340(%0); cache 23, 0x360(%0); +cache 23, 0x380(%0); cache 23, 0x3a0(%0); cache 23, 0x3c0(%0); cache 23, 0x3e0(%0); +.set mips0 +.set reorder + " : : "r" (start)); + start += 0x400; + } +} + +extern inline void blast_scache32_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = page + PAGE_SIZE; + + while(start < end) { + __asm__ __volatile__(" +.set noreorder +.set mips3 +cache 3, 0x000(%0); cache 3, 0x020(%0); cache 3, 0x040(%0); cache 3, 0x060(%0); +cache 3, 0x080(%0); cache 3, 0x0a0(%0); cache 3, 0x0c0(%0); cache 3, 0x0e0(%0); +cache 3, 0x100(%0); cache 3, 0x120(%0); cache 3, 0x140(%0); cache 3, 0x160(%0); +cache 3, 0x180(%0); cache 3, 0x1a0(%0); cache 3, 0x1c0(%0); cache 3, 0x1e0(%0); +cache 3, 0x200(%0); cache 3, 0x220(%0); cache 3, 0x240(%0); cache 3, 0x260(%0); +cache 3, 0x280(%0); cache 3, 0x2a0(%0); cache 3, 0x2c0(%0); cache 3, 0x2e0(%0); +cache 3, 0x300(%0); cache 3, 0x320(%0); cache 3, 0x340(%0); cache 3, 0x360(%0); +cache 3, 0x380(%0); cache 3, 0x3a0(%0); cache 3, 0x3c0(%0); cache 3, 0x3e0(%0); +.set mips0 +.set reorder + " : : "r" (start)); + start += 0x400; + } +} + +extern inline void blast_scache64(void) +{ + unsigned long start = KSEG0; + unsigned long end = KSEG0 + scache_size; + + while(start < end) { + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x040(%0) + cache %1, 0x080(%0); cache %1, 0x0c0(%0) + cache %1, 0x100(%0); cache %1, 0x140(%0) + cache %1, 0x180(%0); cache %1, 0x1c0(%0) + cache %1, 0x200(%0); cache %1, 0x240(%0) + cache %1, 0x280(%0); cache %1, 0x2c0(%0) + cache %1, 0x300(%0); cache %1, 0x340(%0) + cache %1, 0x380(%0); cache %1, 0x3c0(%0) + cache %1, 0x400(%0); cache %1, 0x440(%0) + cache %1, 0x480(%0); cache %1, 0x4c0(%0) + cache %1, 0x500(%0); cache %1, 0x540(%0) + cache %1, 0x580(%0); cache %1, 0x5c0(%0) + cache %1, 0x600(%0); cache %1, 0x640(%0) + cache %1, 0x680(%0); cache %1, 0x6c0(%0) + cache %1, 0x700(%0); cache %1, 0x740(%0) + cache %1, 0x780(%0); cache %1, 0x7c0(%0) + .set mips0 + .set reorder" + : + : "r" (start), + "i" (Index_Writeback_Inv_SD)); + start += 0x800; + } +} + +extern inline void blast_scache64_page(unsigned long page) +{ + unsigned long start = page; + unsigned long end = page + PAGE_SIZE; + + while(start < end) { + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x040(%0) + cache %1, 0x080(%0); cache %1, 0x0c0(%0) + cache %1, 0x100(%0); cache %1, 0x140(%0) + cache %1, 0x180(%0); cache %1, 0x1c0(%0) + cache %1, 0x200(%0); cache %1, 0x240(%0) + cache %1, 0x280(%0); cache %1, 0x2c0(%0) + cache %1, 0x300(%0); cache %1, 0x340(%0) + cache %1, 0x380(%0); cache %1, 0x3c0(%0) + cache %1, 0x400(%0); cache %1, 0x440(%0) + cache %1, 0x480(%0); cache %1, 0x4c0(%0) + cache %1, 0x500(%0); cache %1, 0x540(%0) + cache %1, 0x580(%0); cache %1, 0x5c0(%0) + cache %1, 0x600(%0); cache %1, 0x640(%0) + cache %1, 0x680(%0); cache %1, 0x6c0(%0) + cache %1, 0x700(%0); cache %1, 0x740(%0) + cache %1, 0x780(%0); cache %1, 0x7c0(%0) + .set mips0 + .set reorder" + : + : "r" (start), + "i" (Hit_Writeback_Inv_D)); + start += 0x800; + } +} + +extern inline void blast_scache64_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = page + PAGE_SIZE; + + while(start < end) { + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x040(%0) + cache %1, 0x080(%0); cache %1, 0x0c0(%0) + cache %1, 0x100(%0); cache %1, 0x140(%0) + cache %1, 0x180(%0); cache %1, 0x1c0(%0) + cache %1, 0x200(%0); cache %1, 0x240(%0) + cache %1, 0x280(%0); cache %1, 0x2c0(%0) + cache %1, 0x300(%0); cache %1, 0x340(%0) + cache %1, 0x380(%0); cache %1, 0x3c0(%0) + cache %1, 0x400(%0); cache %1, 0x440(%0) + cache %1, 0x480(%0); cache %1, 0x4c0(%0) + cache %1, 0x500(%0); cache %1, 0x540(%0) + cache %1, 0x580(%0); cache %1, 0x5c0(%0) + cache %1, 0x600(%0); cache %1, 0x640(%0) + cache %1, 0x680(%0); cache %1, 0x6c0(%0) + cache %1, 0x700(%0); cache %1, 0x740(%0) + cache %1, 0x780(%0); cache %1, 0x7c0(%0) + .set mips0 + .set reorder" + : + : "r" (start), + "i" (Index_Writeback_Inv_SD)); + start += 0x800; + } +} + +extern inline void blast_scache128(void) +{ + unsigned long start = KSEG0; + unsigned long end = KSEG0 + scache_size; + + while(start < end) { + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x080(%0) + cache %1, 0x100(%0); cache %1, 0x180(%0) + cache %1, 0x200(%0); cache %1, 0x280(%0) + cache %1, 0x300(%0); cache %1, 0x380(%0) + cache %1, 0x400(%0); cache %1, 0x480(%0) + cache %1, 0x500(%0); cache %1, 0x580(%0) + cache %1, 0x600(%0); cache %1, 0x680(%0) + cache %1, 0x700(%0); cache %1, 0x780(%0) + cache %1, 0x800(%0); cache %1, 0x880(%0) + cache %1, 0x900(%0); cache %1, 0x980(%0) + cache %1, 0xa00(%0); cache %1, 0xa80(%0) + cache %1, 0xb00(%0); cache %1, 0xb80(%0) + cache %1, 0xc00(%0); cache %1, 0xc80(%0) + cache %1, 0xd00(%0); cache %1, 0xd80(%0) + cache %1, 0xe00(%0); cache %1, 0xe80(%0) + cache %1, 0xf00(%0); cache %1, 0xf80(%0) + .set mips0 + .set reorder" + : + : "r" (start), + "i" (Index_Writeback_Inv_SD)); + start += 0x1000; + } +} + +extern inline void blast_scache128_page(unsigned long page) +{ + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x080(%0) + cache %1, 0x100(%0); cache %1, 0x180(%0) + cache %1, 0x200(%0); cache %1, 0x280(%0) + cache %1, 0x300(%0); cache %1, 0x380(%0) + cache %1, 0x400(%0); cache %1, 0x480(%0) + cache %1, 0x500(%0); cache %1, 0x580(%0) + cache %1, 0x600(%0); cache %1, 0x680(%0) + cache %1, 0x700(%0); cache %1, 0x780(%0) + cache %1, 0x800(%0); cache %1, 0x880(%0) + cache %1, 0x900(%0); cache %1, 0x980(%0) + cache %1, 0xa00(%0); cache %1, 0xa80(%0) + cache %1, 0xb00(%0); cache %1, 0xb80(%0) + cache %1, 0xc00(%0); cache %1, 0xc80(%0) + cache %1, 0xd00(%0); cache %1, 0xd80(%0) + cache %1, 0xe00(%0); cache %1, 0xe80(%0) + cache %1, 0xf00(%0); cache %1, 0xf80(%0) + .set mips0 + .set reorder" + : + : "r" (page), + "i" (Hit_Writeback_Inv_D)); +} + +extern inline void blast_scache128_page_indexed(unsigned long page) +{ + __asm__ __volatile__(" + .set noreorder + .set mips3 + cache %1, 0x000(%0); cache %1, 0x080(%0) + cache %1, 0x100(%0); cache %1, 0x180(%0) + cache %1, 0x200(%0); cache %1, 0x280(%0) + cache %1, 0x300(%0); cache %1, 0x380(%0) + cache %1, 0x400(%0); cache %1, 0x480(%0) + cache %1, 0x500(%0); cache %1, 0x580(%0) + cache %1, 0x600(%0); cache %1, 0x680(%0) + cache %1, 0x700(%0); cache %1, 0x780(%0) + cache %1, 0x800(%0); cache %1, 0x880(%0) + cache %1, 0x900(%0); cache %1, 0x980(%0) + cache %1, 0xa00(%0); cache %1, 0xa80(%0) + cache %1, 0xb00(%0); cache %1, 0xb80(%0) + cache %1, 0xc00(%0); cache %1, 0xc80(%0) + cache %1, 0xd00(%0); cache %1, 0xd80(%0) + cache %1, 0xe00(%0); cache %1, 0xe80(%0) + cache %1, 0xf00(%0); cache %1, 0xf80(%0) + .set mips0 + .set reorder" + : + : "r" (page), + "i" (Index_Writeback_Inv_SD)); +} + +#endif /* !(_MIPS_R4KCACHE_H) */ diff --git a/include/asm-mips/reg.h b/include/asm-mips/reg.h index 196a1a133..5fd97c23c 100644 --- a/include/asm-mips/reg.h +++ b/include/asm-mips/reg.h @@ -1,5 +1,6 @@ /* - * Makefile for MIPS Linux main source directory + * Various register offset definitions for debuggers, core file + * examiners and whatnot. * * 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 @@ -15,67 +16,53 @@ * if the order here is changed, it needs to be updated in * include/asm-mips/stackframe.h */ -#define EF_REG1 5 -#define EF_REG2 6 -#define EF_REG3 7 -#define EF_REG4 8 -#define EF_REG5 9 -#define EF_REG6 10 -#define EF_REG7 11 -#define EF_REG8 12 -#define EF_REG9 13 -#define EF_REG10 14 -#define EF_REG11 15 -#define EF_REG12 16 -#define EF_REG13 17 -#define EF_REG14 18 -#define EF_REG15 19 -#define EF_REG16 20 -#define EF_REG17 21 -#define EF_REG18 22 -#define EF_REG19 23 -#define EF_REG20 24 -#define EF_REG21 25 -#define EF_REG22 26 -#define EF_REG23 27 -#define EF_REG24 28 -#define EF_REG25 29 +#define EF_REG0 6 +#define EF_REG1 7 +#define EF_REG2 8 +#define EF_REG3 9 +#define EF_REG4 10 +#define EF_REG5 11 +#define EF_REG6 12 +#define EF_REG7 13 +#define EF_REG8 14 +#define EF_REG9 15 +#define EF_REG10 16 +#define EF_REG11 17 +#define EF_REG12 18 +#define EF_REG13 19 +#define EF_REG14 20 +#define EF_REG15 21 +#define EF_REG16 22 +#define EF_REG17 23 +#define EF_REG18 24 +#define EF_REG19 25 +#define EF_REG20 26 +#define EF_REG21 27 +#define EF_REG22 28 +#define EF_REG23 29 +#define EF_REG24 30 +#define EF_REG25 31 /* * k0/k1 unsaved */ -#define EF_REG28 30 -#define EF_REG29 31 -#define EF_REG30 32 -#define EF_REG31 33 +#define EF_REG28 34 +#define EF_REG29 35 +#define EF_REG30 36 +#define EF_REG31 37 /* * Saved special registers */ -#define EF_LO 34 -#define EF_HI 35 -#define EF_ORIG_REG2 36 +#define EF_LO 38 +#define EF_HI 39 +#define EF_ORIG_REG2 40 +#define EF_ORIG_REG7 41 -#if 0 -/* - * saved cp0 registers - */ -#define EF_CP0_EPC 37 -#define EF_CP0_STATUS 36 -#define EF_CP0_CAUSE 38 -#endif - -#ifdef __mips64 -#define EF_SIZE 304 -#else -#define EF_SIZE 160 -#endif +#define EF_CP0_EPC 42 +#define EF_CP0_BADVADDR 43 +#define EF_CP0_STATUS 44 +#define EF_CP0_CAUSE 45 -#if 0 -/* - * Map register number into core file offset. - */ -#define CORE_REG(reg, ubase) \ - (((unsigned long *)((unsigned long)(ubase)))[reg]) -#endif +#define EF_SIZE 180 #endif /* __ASM_MIPS_REG_H */ diff --git a/include/asm-mips/register.h b/include/asm-mips/register.h deleted file mode 100644 index 9a19187e0..000000000 --- a/include/asm-mips/register.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1996 by Ralf Baechle - */ -#ifndef __ASM_MIPS_REGISTER_H -#define __ASM_MIPS_REGISTER_H - -/* - * Types to represent a register - */ -#ifdef __mips64 -/* - * The R4000 port makes use of the 64 bit wide registers - */ -#ifndef __LANGUAGE_ASSEMBLY__ -typedef long long __register_t; -typedef unsigned long long __uregister_t; -#endif - -#else - -/* - * Good 'ole R3000 has only 32 bit wide registers - */ -#ifndef __LANGUAGE_ASSEMBLY__ -typedef long __register_t; -typedef unsigned long __uregister_t; -#endif -#endif - -#endif /* __ASM_MIPS_REGISTER_H */ diff --git a/include/asm-mips/segment.h b/include/asm-mips/segment.h index c6a684e8d..0453d97da 100644 --- a/include/asm-mips/segment.h +++ b/include/asm-mips/segment.h @@ -1,6 +1,6 @@ -#ifndef __MIPS_SEGMENT_H -#define __MIPS_SEGMENT_H +#ifndef __ALPHA_SEGMENT_H +#define __ALPHA_SEGMENT_H /* Only here because we have some old header files that expect it.. */ -#endif /* __MIPS_SEGMENT_H */ +#endif diff --git a/include/asm-mips/sgi.h b/include/asm-mips/sgi.h new file mode 100644 index 000000000..b49623eaf --- /dev/null +++ b/include/asm-mips/sgi.h @@ -0,0 +1,42 @@ +/* $Id: sgi.h,v 1.3 1996/06/25 07:18:24 dm Exp $ + * sgi.h: Definitions specific to SGI machines. + * + * Copyright (C) 1996 David S. Miller (dm@sgi.com) + */ +#ifndef _MIPS_SGI_H +#define _MIPS_SGI_H + +/* UP=UniProcessor MP=MultiProcessor(capable) */ +enum sgi_mach { + ip4, /* R2k UP */ + ip5, /* R2k MP */ + ip6, /* R3k UP */ + ip7, /* R3k MP */ + ip9, /* R3k UP */ + ip12, /* R3kA UP, Indigo */ + ip15, /* R3kA MP */ + ip17, /* R4K UP */ + ip19, /* R4K MP */ + ip20, /* R4K UP, Indigo */ + ip21, /* TFP MP */ + ip22, /* R4x00 UP, Indigo2 */ + ip25, /* R10k MP */ + ip26, /* TFP UP, Indigo2 */ + ip28, /* R10k UP, Indigo2 */ + ip30, + ip32, +}; + +extern enum sgi_mach sgimach; +extern void sgi_sysinit(void); + +/* Many I/O space registers are byte sized and are contained within + * one byte per word, specifically the MSB, this macro helps out. + */ +#ifdef __MIPSEL__ +#define SGI_MSB(regaddr) (regaddr) +#else +#define SGI_MSB(regaddr) ((regaddr) | 0x3) +#endif + +#endif /* !(_MIPS_SGI_H) */ diff --git a/include/asm-mips/sgialib.h b/include/asm-mips/sgialib.h new file mode 100644 index 000000000..45ac539d4 --- /dev/null +++ b/include/asm-mips/sgialib.h @@ -0,0 +1,118 @@ +/* $Id: sgialib.h,v 1.7 1996/06/08 06:05:15 dm Exp $ + * sgialib.h: SGI ARCS firmware interface library for the Linux kernel. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ + +#ifndef _MIPS_SGIALIB_H +#define _MIPS_SGIALIB_H + +#include <asm/sgiarcs.h> + +extern struct linux_promblock *sgi_pblock; +extern struct linux_romvec *romvec; +extern int prom_argc; +extern char **prom_argv, **prom_envp; + +/* Init the PROM library and it's internal data structures. Called + * at boot time from head.S before start_kernel is invoked. + */ +extern int prom_init(int argc, char **argv, char **envp); + +/* Simple char-by-char console I/O. */ +extern void prom_putchar(char c); +extern char prom_getchar(void); + +/* Generic printf() using ARCS console I/O. */ +extern void prom_printf(char *fmt, ...); + +/* Memory descriptor management. */ +#define PROM_MAX_PMEMBLOCKS 32 +struct prom_pmemblock { + unsigned long base; /* Within KSEG0. */ + unsigned int size; /* In bytes. */ +}; + +/* Get next memory descriptor after CURR, returns first descriptor + * in chain is CURR is NULL. + */ +extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr); +#define PROM_NULL_MDESC ((struct linux_mdesc *) 0) + +/* Called by prom_init to setup the physical memory pmemblock + * array. + */ +extern void prom_meminit(void); +extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem); + +/* Returns pointer to PROM physical memory block array. */ +extern struct prom_pmemblock *prom_getpblock_array(void); + +/* PROM device tree library routines. */ +#define PROM_NULL_COMPONENT ((pcomponent *) 0) + +/* Get sibling component of THIS. */ +extern pcomponent *prom_getsibling(pcomponent *this); + +/* Get child component of THIS. */ +extern pcomponent *prom_getchild(pcomponent *this); + +/* Get parent component of CHILD. */ +extern pcomponent *prom_getparent(pcomponent *child); + +/* Copy component opaque data of component THIS into BUFFER + * if component THIS has opaque data. Returns success or + * failure status. + */ +extern long prom_getcdata(void *buffer, pcomponent *this); + +/* Other misc. component routines. */ +extern pcomponent *prom_childadd(pcomponent *this, pcomponent *tmp, void *data); +extern long prom_delcomponent(pcomponent *this); +extern pcomponent *prom_componentbypath(char *path); + +/* This is called at prom_init time to setup the tags which the + * MIPS kernel setup code wants to diddle with. + */ +extern void prom_setup_archtags(void); + +/* Environemt variable routines. */ +extern char *prom_getenv(char *name); +extern long prom_setenv(char *name, char *value); + +/* ARCS command line acquisition and parsing. */ +extern char *prom_getcmdline(void); +extern void prom_init_cmdline(void); + +/* Acquiring info about the current time, etc. */ +extern struct linux_tinfo *prom_gettinfo(void); +extern unsigned long prom_getrtime(void); + +/* File operations. */ +extern long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt); +extern long prom_open(char *name, enum linux_omode md, unsigned long *fd); +extern long prom_close(unsigned long fd); +extern long prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt); +extern long prom_getrstatus(unsigned long fd); +extern long prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt); +extern long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm); +extern long prom_mount(char *name, enum linux_mountops op); +extern long prom_getfinfo(unsigned long fd, struct linux_finfo *buf); +extern long prom_setfinfo(unsigned long fd, unsigned long flags, unsigned long msk); + +/* Running stand-along programs. */ +extern long prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr); +extern long prom_invoke(unsigned long pc, unsigned long sp, long argc, char **argv, char **envp); +extern long prom_exec(char *name, long argc, char **argv, char **envp); + +/* Misc. routines. */ +extern void prom_halt(void); +extern void prom_powerdown(void); +extern void prom_restart(void); +extern void prom_reboot(void); +extern void prom_imode(void); +extern long prom_cfgsave(void); +extern struct linux_sysid *prom_getsysid(void); +extern void prom_cacheflush(void); + +#endif /* !(_MIPS_SGIALIB_H) */ diff --git a/include/asm-mips/sgiarcs.h b/include/asm-mips/sgiarcs.h new file mode 100644 index 000000000..2e820feca --- /dev/null +++ b/include/asm-mips/sgiarcs.h @@ -0,0 +1,351 @@ +/* $Id: sgiarcs.h,v 1.4 1996/06/08 04:48:43 dm Exp $ + * SGI ARCS firmware interface defines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ + +#ifndef _MIPS_SGIARCS_H +#define _MIPS_SGIARCS_H + +/* Various ARCS error codes. */ +#define PROM_ESUCCESS 0x00 +#define PROM_E2BIG 0x01 +#define PROM_EACCESS 0x02 +#define PROM_EAGAIN 0x03 +#define PROM_EBADF 0x04 +#define PROM_EBUSY 0x05 +#define PROM_EFAULT 0x06 +#define PROM_EINVAL 0x07 +#define PROM_EIO 0x08 +#define PROM_EISDIR 0x09 +#define PROM_EMFILE 0x0a +#define PROM_EMLINK 0x0b +#define PROM_ENAMETOOLONG 0x0c +#define PROM_ENODEV 0x0d +#define PROM_ENOENT 0x0e +#define PROM_ENOEXEC 0x0f +#define PROM_ENOMEM 0x10 +#define PROM_ENOSPC 0x11 +#define PROM_ENOTDIR 0x12 +#define PROM_ENOTTY 0x13 +#define PROM_ENXIO 0x14 +#define PROM_EROFS 0x15 +/* SGI ARCS specific errno's. */ +#define PROM_EADDRNOTAVAIL 0x1f +#define PROM_ETIMEDOUT 0x20 +#define PROM_ECONNABORTED 0x21 +#define PROM_ENOCONNECT 0x22 + +/* Device classes, types, and identifiers for prom + * device inventory queries. + */ +enum linux_devclass { + system, processor, cache, adapter, controller, peripheral, memory +}; + +enum linux_devtypes { + /* Generic stuff. */ + Arc, Cpu, Fpu, + + /* Primary insn and data caches. */ + picache, pdcache, + + /* Secondary insn, data, and combined caches. */ + sicache, sdcache, sccache, + + memdev, eisa_adapter, tc_adapter, scsi_adapter, dti_adapter, + multifunc_adapter, dsk_controller, tp_controller, cdrom_controller, + worm_controller, serial_controller, net_controller, disp_controller, + parallel_controller, ptr_controller, kbd_controller, audio_controller, + misc_controller, disk_peripheral, flpy_peripheral, tp_peripheral, + modem_peripheral, monitor_peripheral, printer_peripheral, + ptr_peripheral, kbd_peripheral, term_peripheral, line_peripheral, + net_peripheral, misc_peripheral, anon +}; + +enum linux_identifier { + bogus, ronly, removable, consin, consout, input, output +}; + +/* A prom device tree component. */ +struct linux_component { + enum linux_devclass class; /* node class */ + enum linux_devtypes type; /* node type */ + enum linux_identifier iflags; /* node flags */ + unsigned short vers; /* node version */ + unsigned short rev; /* node revision */ + unsigned long key; /* completely magic */ + unsigned long amask; /* XXX affinity mask??? */ + unsigned long cdsize; /* size of configuration data */ + unsigned long ilen; /* length of string identifier */ + char *iname; /* string identifier */ +}; +typedef struct linux_component pcomponent; + +struct linux_sysid { + char vend[8], prod[8]; +}; + +/* ARCS prom memory descriptors. */ +enum linux_memtypes { + eblock, /* exception block */ + rvpage, /* ARCS romvec page */ + fcontig, /* Contiguous and free */ + free, /* Generic free memory */ + bmem, /* Borken memory, don't use */ + prog, /* A loaded program resides here */ + atmp, /* ARCS temporary storage area, wish Sparc OpenBoot told this */ + aperm, /* ARCS permanent storage... */ +}; + +struct linux_mdesc { + enum linux_memtypes type; + unsigned long base; + unsigned long pages; +}; + +/* Time of day descriptor. */ +struct linux_tinfo { + unsigned short yr; + unsigned short mnth; + unsigned short day; + unsigned short hr; + unsigned short min; + unsigned short sec; + unsigned short msec; +}; + +/* ARCS virtual dirents. */ +struct linux_vdirent { + unsigned long namelen; + unsigned char attr; + char fname[32]; /* XXX imperical, should be a define */ +}; + +/* Other stuff for files. */ +enum linux_omode { + rdonly, wronly, rdwr, wronly_creat, rdwr_creat, + wronly_ssede, rdwr_ssede, dirent, dirent_creat +}; + +enum linux_seekmode { + absolute, relative +}; + +enum linux_mountops { + media_load, media_unload +}; + +/* This prom has a bolixed design. */ +struct linux_bigint { +#ifdef __MIPSEL__ + unsigned long lo; + long hi; +#else /* !(__MIPSEL__) */ + long hi; + unsigned long lo; +#endif +}; + +struct linux_finfo { + struct linux_bigint begin; + struct linux_bigint end; + struct linux_bigint cur; + enum linux_devtypes dtype; + unsigned long namelen; + unsigned char attr; + char name[32]; /* XXX imperical, should be define */ +}; + +struct linux_romvec { + /* Load an executable image. */ + long (*load)(char *file, unsigned long end, + unsigned long *start_pc, + unsigned long *end_addr); + + /* Invoke a standalong image. */ + long (*invoke)(unsigned long startpc, unsigned long sp, + long argc, char **argv, char **envp); + + /* Load and begin execution of a standalong image. */ + long (*exec)(char *file, long argc, char **argv, char **envp); + + void (*halt)(void); /* Halt the machine. */ + void (*pdown)(void); /* Power down the machine. */ + void (*restart)(void); /* XXX soft reset??? */ + void (*reboot)(void); /* Reboot the machine. */ + void (*imode)(void); /* Enter PROM interactive mode. */ + int _unused1; /* padding */ + + /* PROM device tree interface. */ + pcomponent *(*next_component)(pcomponent *this); + pcomponent *(*child_component)(pcomponent *this); + pcomponent *(*parent_component)(pcomponent *this); + long (*component_data)(void *opaque_data, pcomponent *this); + pcomponent *(*child_add)(pcomponent *this, + pcomponent *tmp, + void *opaque_data); + long (*comp_del)(pcomponent *this); + pcomponent *(*component_by_path)(char *file); + + /* Misc. stuff. */ + long (*cfg_save)(void); + struct linux_sysid *(*get_sysid)(void); + + /* Probing for memory. */ + struct linux_mdesc *(*get_mdesc)(struct linux_mdesc *curr); + long _unused2; /* padding */ + + struct linux_tinfo *(*get_tinfo)(void); + unsigned long (*get_rtime)(void); + + /* File type operations. */ + long (*get_vdirent)(unsigned long fd, struct linux_vdirent *entry, + unsigned long num, unsigned long *count); + long (*open)(char *file, enum linux_omode mode, unsigned long *fd); + long (*close)(unsigned long fd); + long (*read)(unsigned long fd, void *buffer, unsigned long num, + unsigned long *count); + long (*get_rstatus)(unsigned long fd); + long (*write)(unsigned long fd, void *buffer, unsigned long num, + unsigned long *count); + long (*seek)(unsigned long fd, struct linux_bigint *offset, + enum linux_seekmode smode); + long (*mount)(char *file, enum linux_mountops op); + + /* Dealing with firmware environment variables. */ + char *(*get_evar)(char *name); + long (*set_evar)(char *name, char *value); + + long (*get_finfo)(unsigned long fd, struct linux_finfo *buf); + long (*set_finfo)(unsigned long fd, unsigned long flags, + unsigned long mask); + + /* Miscellaneous. */ + void (*cache_flush)(void); +}; + +/* The SGI ARCS parameter block is in a fixed location for standalone + * programs to access PROM facilities easily. + */ +struct linux_promblock { + long magic; /* magic cookie */ +#define PROMBLOCK_MAGIC 0x53435241 + + unsigned long len; /* length of parm block */ + unsigned short ver; /* ARCS firmware version */ + unsigned short rev; /* ARCS firmware revision */ + long *rs_block; /* Restart block. */ + long *dbg_block; /* Debug block. */ + long *gevect; /* XXX General vector??? */ + long *utlbvect; /* XXX UTLB vector??? */ + unsigned long rveclen; /* Size of romvec struct. */ + struct linux_romvec *romvec; /* Function interface. */ + unsigned long pveclen; /* Length of private vector. */ + long *pvector; /* Private vector. */ + long adap_cnt; /* Adapter count. */ + long adap_typ0; /* First adapter type. */ + long adap_vcnt0; /* Adapter 0 vector count. */ + long *adap_vector; /* Adapter 0 vector ptr. */ + long adap_typ1; /* Second adapter type. */ + long adap_vcnt1; /* Adapter 1 vector count. */ + long *adap_vector1; /* Adapter 1 vector ptr. */ + /* More adapter vectors go here... */ +}; + +#define PROMBLOCK ((struct linux_promblock *)0xA0001000UL) +#define ROMVECTOR ((PROMBLOCK)->romvec) + +/* Cache layout parameter block. */ +union linux_cache_key { + struct param { +#ifdef __MIPSEL__ + unsigned short size; + unsigned char lsize; + unsigned char bsize; +#else /* !(__MIPSEL__) */ + unsigned char bsize; + unsigned char lsize; + unsigned short size; +#endif + } info; + unsigned long allinfo; +}; + +/* Configuration data. */ +struct linux_cdata { + char *name; + int mlen; + enum linux_devtypes type; +}; + +/* Common SGI ARCS firmware file descriptors. */ +#define SGIPROM_STDIN 0 +#define SGIPROM_STDOUT 1 + +/* Common SGI ARCS firmware file types. */ +#define SGIPROM_ROFILE 0x01 /* read-only file */ +#define SGIPROM_HFILE 0x02 /* hidden file */ +#define SGIPROM_SFILE 0x04 /* System file */ +#define SGIPROM_AFILE 0x08 /* Archive file */ +#define SGIPROM_DFILE 0x10 /* Directory file */ +#define SGIPROM_DELFILE 0x20 /* Deleted file */ + +/* SGI ARCS boot record information. */ +struct sgi_partition { + unsigned char flag; +#define SGIPART_UNUSED 0x00 +#define SGIPART_ACTIVE 0x80 + + unsigned char shead, ssect, scyl; /* unused */ + unsigned char systype; /* OS type, Irix or NT */ + unsigned char ehead, esect, ecyl; /* unused */ + unsigned char rsect0, rsect1, rsect2, rsect3; + unsigned char tsect0, tsect1, tsect2, tsect3; +}; + +#define SGIBBLOCK_MAGIC 0xaa55 +#define SGIBBLOCK_MAXPART 0x0004 + +struct sgi_bootblock { + unsigned char _unused[446]; + struct sgi_partition partitions[SGIBBLOCK_MAXPART]; + unsigned short magic; +}; + +/* BIOS parameter block. */ +struct sgi_bparm_block { + unsigned short bytes_sect; /* bytes per sector */ + unsigned char sect_clust; /* sectors per cluster */ + unsigned short sect_resv; /* reserved sectors */ + unsigned char nfats; /* # of allocation tables */ + unsigned short nroot_dirents; /* # of root directory entries */ + unsigned short sect_volume; /* sectors in volume */ + unsigned char media_type; /* media descriptor */ + unsigned short sect_fat; /* sectors per allocation table */ + unsigned short sect_track; /* sectors per track */ + unsigned short nheads; /* # of heads */ + unsigned short nhsects; /* # of hidden sectors */ +}; + +struct sgi_bsector { + unsigned char jmpinfo[3]; + unsigned char manuf_name[8]; + struct sgi_bparm_block info; +}; + +/* Debugging block used with SGI symmon symbolic debugger. */ +#define SMB_DEBUG_MAGIC 0xfeeddead +struct linux_smonblock { + unsigned long magic; + void (*handler)(void); /* Breakpoint routine. */ + unsigned long dtable_base; /* Base addr of dbg table. */ + int (*printf)(const char *fmt, ...); + unsigned long btable_base; /* Breakpoint table. */ + unsigned long mpflushreqs; /* SMP cache flush request list. */ + unsigned long ntab; /* Name table. */ + unsigned long stab; /* Symbol table. */ + int smax; /* Max # of symbols. */ +}; + +#endif /* !(_MIPS_SGIARCS_H) */ diff --git a/include/asm-mips/sgihpc.h b/include/asm-mips/sgihpc.h new file mode 100644 index 000000000..e3c28b495 --- /dev/null +++ b/include/asm-mips/sgihpc.h @@ -0,0 +1,340 @@ +/* $Id: sgihpc.h,v 1.7 1996/06/16 07:22:30 dm Exp $ + * sgihpc.h: Various HPC I/O controller defines. The HPC is basically + * the approximate functional equivalent of the Sun SYSIO + * on SGI INDY machines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#ifndef _MIPS_SGIHPC_H +#define _MIPS_SGIHPC_H + +#include <asm/page.h> + +extern int sgi_has_ioc2; /* to know if we have older ioc1 or ioc2. */ +extern int sgi_guiness; /* GUINESS or FULLHOUSE machine. */ +extern int sgi_boardid; /* Board revision. */ + +/* An HPC dma descriptor. */ +struct hpc_dma_desc { + unsigned long pbuf; /* physical address of data buffer */ + unsigned long cntinfo; /* counter and info bits */ +#define HPCDMA_EOX 0x80000000 /* last desc in chain for tx */ +#define HPCDMA_EOR 0x80000000 /* last desc in chain for rx */ +#define HPCDMA_EOXP 0x40000000 /* end of packet for tx */ +#define HPCDMA_EORP 0x40000000 /* end of packet for rx */ +#define HPCDMA_XIE 0x20000000 /* irq generated when at end of this desc */ +#define HPCDMA_XIU 0x01000000 /* Tx buffer in use by CPU. */ +#define HPCDMA_EIPC 0x00ff0000 /* SEEQ ethernet special xternal bytecount */ +#define HPCDMA_ETXD 0x00008000 /* set to one by HPC when packet tx'd */ +#define HPCDMA_OWN 0x00004000 /* Denotes ring buffer ownership on rx */ +#define HPCDMA_BCNT 0x00003fff /* size in bytes of this dma buffer */ + + unsigned long pnext; /* paddr of next hpc_dma_desc if any */ +}; + +typedef volatile unsigned long hpcreg; + +/* HPC1 stuff. */ + +/* HPC3 stuff. */ + +/* The set of regs for each HPC3 pbus dma channel. */ +struct hpc3_pbus_dmacregs { + hpcreg pbdma_bptr; /* pbus dma channel buffer ptr */ + hpcreg pbdma_dptr; /* pbus dma channel desc ptr */ + char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ + hpcreg pbdma_ctrl; /* pbus dma channel control reg */ +#define HPC3_PDMACTRL_SEL 0x00000002 /* little endian transfer */ +#define HPC3_PDMACTRL_RCV 0x00000004 /* direction is receive */ +#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */ +#define HPC3_PDMACTRL_ACT 0x00000010 /* start dma transfer */ +#define HPC3_PDMACTRL_LD 0x00000020 /* load enable for ACT */ +#define HPC3_PDMACTRL_RT 0x00000040 /* Use realtime GIO bus servicing */ +#define HPC3_PDMACTRL_HW 0x0000ff00 /* DMA High-water mark */ +#define HPC3_PDMACTRL_FB 0x003f0000 /* Ptr to beginning of fifo */ +#define HPC3_PDMACTRL_FE 0x3f000000 /* Ptr to end of fifo */ + + char _unused2[PAGE_SIZE - (sizeof(hpcreg))]; /* padding */ +}; + +/* The HPC3 scsi registers, this does not include external ones. */ +struct hpc3_scsiregs { + hpcreg cbptr; /* current dma buffer ptr, diagnostic use only */ + hpcreg ndptr; /* next dma descriptor ptr */ + char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ + hpcreg bcd; /* byte count info */ +#define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */ +#define HPC3_SBCD_XIE 0x00004000 /* Send IRQ when done with cur buf */ +#define HPC3_SBCD_EOX 0x00008000 /* Indicates this is last buf in chain */ + + hpcreg ctrl; /* control register */ +#define HPC3_SCTRL_IRQ 0x01 /* IRQ asserted, either dma done or parity */ +#define HPC3_SCTRL_ENDIAN 0x02 /* DMA endian mode, 0=big 1=little */ +#define HPC3_SCTRL_DIR 0x04 /* DMA direction, 1=dev2mem 0=mem2dev */ +#define HPC3_SCTRL_FLUSH 0x08 /* Tells HPC3 to flush scsi fifos */ +#define HPC3_SCTRL_ACTIVE 0x10 /* SCSI DMA channel is active */ +#define HPC3_SCTRL_AMASK 0x20 /* DMA active inhibits PIO */ +#define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */ +#define HPC3_SCTRL_PERR 0x80 /* Bad parity on HPC3 iface to scsi controller */ + + hpcreg gfptr; /* current GIO fifo ptr */ + hpcreg dfptr; /* current device fifo ptr */ + hpcreg dconfig; /* DMA configuration register */ +#define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */ +#define HPC3_SDCFG_D1 0x00006 /* Cycles to spend in D1 state */ +#define HPC3_SDCFG_D2 0x00038 /* Cycles to spend in D2 state */ +#define HPC3_SDCFG_D3 0x001c0 /* Cycles to spend in D3 state */ +#define HPC3_SDCFG_HWAT 0x00e00 /* DMA high water mark */ +#define HPC3_SDCFG_HW 0x01000 /* Enable 16-bit halfword DMA accesses to scsi */ +#define HPC3_SDCFG_SWAP 0x02000 /* Byte swap all DMA accesses */ +#define HPC3_SDCFG_EPAR 0x04000 /* Enable parity checking for DMA */ +#define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */ +#define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */ + + hpcreg pconfig; /* PIO configuration register */ +#define HPC3_SPCFG_P3 0x0003 /* Cycles to spend in P3 state */ +#define HPC3_SPCFG_P2W 0x001c /* Cycles to spend in P2 state for writes */ +#define HPC3_SPCFG_P2R 0x01e0 /* Cycles to spend in P2 state for reads */ +#define HPC3_SPCFG_P1 0x0e00 /* Cycles to spend in P1 state */ +#define HPC3_SPCFG_HW 0x1000 /* Enable 16-bit halfword PIO accesses to scsi */ +#define HPC3_SPCFG_SWAP 0x2000 /* Byte swap all PIO accesses */ +#define HPC3_SPCFG_EPAR 0x4000 /* Enable parity checking for PIO */ +#define HPC3_SPCFG_FUJI 0x8000 /* Fujitsu scsi controller mode for faster dma/pio */ + + char _unused2[PAGE_SIZE - (6 * sizeof(hpcreg))]; /* padding */ +}; + +/* SEEQ ethernet HPC3 registers, only one seeq per HPC3. */ +struct hpc3_ethregs { + /* Receiver registers. */ + hpcreg rx_cbptr; /* current dma buffer ptr, diagnostic use only */ + hpcreg rx_ndptr; /* next dma descriptor ptr */ + char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ + hpcreg rx_bcd; /* byte count info */ +#define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */ +#define HPC3_ERXBCD_XIE 0x20000000 /* HPC3 interrupts cpu at end of this buf */ +#define HPC3_ERXBCD_EOX 0x80000000 /* flags this as end of descriptor chain */ + + hpcreg rx_ctrl; /* control register */ +#define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */ +#define HPC3_ERXCTRL_STAT6 0x00000040 /* Rdonly irq status */ +#define HPC3_ERXCTRL_STAT7 0x00000080 /* Rdonlt old/new status bit from Seeq */ +#define HPC3_ERXCTRL_ENDIAN 0x00000100 /* Endian for dma channel, little=1 big=0 */ +#define HPC3_ERXCTRL_ACTIVE 0x00000200 /* Tells if DMA transfer is in progress */ +#define HPC3_ERXCTRL_AMASK 0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */ +#define HPC3_ERXCTRL_RBO 0x00000800 /* Receive buffer overflow if set to 1 */ + + hpcreg rx_gfptr; /* current GIO fifo ptr */ + hpcreg rx_dfptr; /* current device fifo ptr */ + hpcreg _unused2; /* padding */ + hpcreg rx_reset; /* reset register */ +#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */ +#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */ +#define HPC3_ERXRST_LBACK 0x4 /* Enable diagnostic loopback mode of Seeq8003 */ + + hpcreg rx_dconfig; /* DMA configuration register */ +#define HPC3_ERXDCFG_D1 0x0000f /* Cycles to spend in D1 state for PIO */ +#define HPC3_ERXDCFG_D2 0x000f0 /* Cycles to spend in D2 state for PIO */ +#define HPC3_ERXDCFG_D3 0x00f00 /* Cycles to spend in D3 state for PIO */ +#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */ +#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */ +#define HPC3_ERXDCFG_FEOP 0x04000 /* Bad packet marker timeout enable */ +#define HPC3_ERXDCFG_FIRQ 0x08000 /* Another bad packet timeout enable */ +#define HPC3_ERXDCFG_PTO 0x30000 /* Programmed timeout value for above two */ + + hpcreg rx_pconfig; /* PIO configuration register */ +#define HPC3_ERXPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */ +#define HPC3_ERXPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */ +#define HPC3_ERXPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */ +#define HPC3_ERXPCFG_TST 0x1000 /* Diagnistic ram test feature bit */ + + char _unused3[PAGE_SIZE - (8 * sizeof(hpcreg))]; /* padding */ + + /* Transmitter registers. */ + hpcreg tx_cbptr; /* current dma buffer ptr, diagnostic use only */ + hpcreg tx_ndptr; /* next dma descriptor ptr */ + char _unused4[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ + hpcreg tx_bcd; /* byte count info */ +#define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */ +#define HPC3_ETXBCD_ESAMP 0x10000000 /* if set, too late to add descriptor */ +#define HPC3_ETXBCD_XIE 0x20000000 /* Interrupt cpu at end of cur desc */ +#define HPC3_ETXBCD_EOP 0x40000000 /* Last byte of cur buf is end of packet */ +#define HPC3_ETXBCD_EOX 0x80000000 /* This buf is the end of desc chain */ + + hpcreg tx_ctrl; /* control register */ +#define HPC3_ETXCTRL_STAT30 0x0000000f /* Rdonly copy of seeq tx stat reg */ +#define HPC3_ETXCTRL_STAT4 0x00000010 /* Indicate late collision occurred */ +#define HPC3_ETXCTRL_STAT75 0x000000e0 /* Rdonly irq status from seeq */ +#define HPC3_ETXCTRL_ENDIAN 0x00000100 /* Dma channel endian mode, 1=little 0=big */ +#define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */ +#define HPC3_ETXCTRL_AMASK 0x00000400 /* Indicates ACTIVE inhibits PIO's */ + + hpcreg tx_gfptr; /* current GIO fifo ptr */ + hpcreg tx_dfptr; /* current device fifo ptr */ + char _unused5[PAGE_SIZE - (4 * sizeof(hpcreg))]; /* padding */ +}; + +struct hpc3_regs { + /* First regs for the PBUS 8 dma channels. */ + struct hpc3_pbus_dmacregs pbdma0, pbdma1, pbdma2, pbdma3; + struct hpc3_pbus_dmacregs pbdma4, pbdma5, pbdma6, pbdma7; + + /* Now the HPC scsi registers, we get two scsi reg sets. */ + struct hpc3_scsiregs scsi_chan0, scsi_chan1; + + /* The SEEQ hpc3 ethernet dma/control registers. */ + struct hpc3_ethregs ethregs; + + /* Here are where the hpc3 fifo's can be directly accessed + * via PIO accesses. Under normal operation we never stick + * our grubby paws in here so it's just padding. + */ + char _unused1[PAGE_SIZE * 16]; + + /* HPC3 irq status regs. Due to a peculiar bug you need to + * look at two different register addresses to get at all of + * the status bits. The first reg can only reliably report + * bits 4:0 of the status, and the second reg can only + * reliably report bits 9:5 of the hpc3 irq status. I told + * you it was a peculiar bug. ;-) + */ + hpcreg istat0; /* Irq status, only bits <4:0> reliable. */ +#define HPC3_ISTAT_PBIMASK 0x0ff /* irq bits for pbus devs 0 --> 7 */ +#define HPC3_ISTAT_SC0MASK 0x100 /* irq bit for scsi channel 0 */ +#define HPC3_ISTAT_SC1MASK 0x200 /* irq bit for scsi channel 1 */ + + hpcreg gio64_misc; /* GIO64 misc control bits. */ +#define HPC3_GIOMISC_ERTIME 0x1 /* Enable external timer real time. */ +#define HPC3_GIOMISC_DENDIAN 0x2 /* dma descriptor endian, 1=lit 0=big */ + + hpcreg eeprom_data; /* EEPROM data reg. */ +#define HPC3_EEPROM_EPROT 0x01 /* Protect register enable */ +#define HPC3_EEPROM_CSEL 0x02 /* Chip select */ +#define HPC3_EEPROM_ECLK 0x04 /* EEPROM clock */ +#define HPC3_EEPROM_DATO 0x08 /* Data out */ +#define HPC3_EEPROM_DATI 0x10 /* Data in */ + + hpcreg istat1; /* Irq status, only bits <9:5> reliable. */ + hpcreg gio64_estat; /* GIO64 error interrupt status reg. */ +#define HPC3_GIOESTAT_BLMASK 0x000ff /* Bus lane where bad parity occurred */ +#define HPC3_GIOESTAT_CTYPE 0x00100 /* Bus cycle type, 0=PIO 1=DMA */ +#define HPC3_GIOESTAT_PIDMSK 0x3f700 /* DMA channel parity identifier */ + + /* Now direct PIO per-HPC3 peripheral access to external regs. */ + char _unused2[0x13ff0]; /* Trust me... */ + hpcreg scsi0_ext[256]; /* SCSI channel 0 external regs */ + char _unused3[0x07c00]; /* Trust me... */ + hpcreg scsi1_ext[256]; /* SCSI channel 1 external regs */ + char _unused4[0x07c00]; /* It'll only hurt a little... */ + + /* Per-peripheral device external registers and dma/pio control. */ + hpcreg pbus_extregs[256][10]; /* 2nd indice indexes controller */ + hpcreg pbus_dmacfgs[128][10]; /* 2nd indice indexes controller */ +#define HPC3_PIODCFG_D3R 0x00000001 /* Cycles to spend in D3 for reads */ +#define HPC3_PIODCFG_D4R 0x0000001e /* Cycles to spend in D4 for reads */ +#define HPC3_PIODCFG_D5R 0x000001e0 /* Cycles to spend in D5 for reads */ +#define HPC3_PIODCFG_D3W 0x00000200 /* Cycles to spend in D3 for writes */ +#define HPC3_PIODCFG_D4W 0x00003c00 /* Cycles to spend in D4 for writes */ +#define HPC3_PIODCFG_D5W 0x0003c000 /* Cycles to spend in D5 for writes */ +#define HPC3_PIODCFG_HWORD 0x00040000 /* Enable 16-bit dma access mode */ +#define HPC3_PIODCFG_EHI 0x00080000 /* Places halfwords on high 16 bits of bus */ +#define HPC3_PIODCFG_RTIME 0x00200000 /* Make this device real time on GIO bus */ +#define HPC3_PIODCFG_BURST 0x07c00000 /* 5 bit burst count for DMA device */ +#define HPC3_PIODCFG_DRQLV 0x08000000 /* Use live pbus_dreq unsynchronized signal */ + + hpcreg pbus_piocfgs[64][10]; /* 2nd indice indexes controller */ +#define HPC3_PIOPCFG_RP2 0x00001 /* Cycles to spend in P2 state for reads */ +#define HPC3_PIOPCFG_RP3 0x0001e /* Cycles to spend in P3 state for reads */ +#define HPC3_PIOPCFG_RP4 0x001e0 /* Cycles to spend in P4 state for reads */ +#define HPC3_PIOPCFG_WP2 0x00200 /* Cycles to spend in P2 state for writes */ +#define HPC3_PIOPCFG_WP3 0x03c00 /* Cycles to spend in P3 state for writes */ +#define HPC3_PIOPCFG_WP4 0x3c000 /* Cycles to spend in P4 state for writes */ +#define HPC3_PIOPCFG_HW 0x40000 /* Enable 16-bit PIO accesses */ +#define HPC3_PIOPCFG_EHI 0x80000 /* Place even address bits in bits <15:8> */ + + /* PBUS PROM control regs. */ + hpcreg pbus_promwe; /* PROM write enable register */ +#define HPC3_PROM_WENAB 0x1 /* Enable writes to the PROM */ + + char _unused5[0x800 - sizeof(hpcreg)]; + hpcreg pbus_promswap; /* Chip select swap reg */ +#define HPC3_PROM_SWAP 0x1 /* invert GIO addr bit to select prom0 or prom1 */ + + char _unused6[0x800 - sizeof(hpcreg)]; + hpcreg pbus_gout; /* PROM general purpose output reg */ +#define HPC3_PROM_STAT 0x1 /* General purpose status bit in gout */ + + char _unused7[0x1000 - sizeof(hpcreg)]; + hpcreg pbus_promram[16384]; /* 64k of PROM battery backed ram */ +}; + +/* It is possible to have two HPC3's within the address space on + * one machine, though only having one is more likely on an INDY. + * Controller 0 lives at physical address 0x1fb80000 and the controller + * 1 if present lives at address 0x1fb00000. + */ +extern struct hpc3_regs *hpc3c0, *hpc3c1; +#define HPC3_CHIP0_PBASE 0x1fb80000 /* physical */ +#define HPC3_CHIP1_PBASE 0x1fb00000 /* physical */ + +/* Control and misc status information, these live in pbus channel 6. */ +struct hpc3_miscregs { + hpcreg pdata, pctrl, pstat, pdmactrl, pistat, pimask; + hpcreg ptimer1, ptimer2, ptimer3, ptimer4; + hpcreg _unused1[2]; + hpcreg ser1cmd, ser1data; + hpcreg ser0cmd, ser0data; + hpcreg kbdmouse0, kbdmouse1; + hpcreg gcsel, genctrl, panel; + hpcreg _unused2; + hpcreg sysid; + hpcreg _unused3; + hpcreg read, _unused4; + hpcreg dselect; +#define HPC3_DSELECT_SCLK10MHZ 0x00 /* use 10MHZ serial clock */ +#define HPC3_DSELECT_ISDNB 0x01 /* enable isdn B */ +#define HPC3_DSELECT_ISDNA 0x02 /* enable isdn A */ +#define HPC3_DSELECT_LPR 0x04 /* use parallel DMA */ +#define HPC3_DSELECT_SCLK667MHZ 0x10 /* use 6.67MHZ serial clock */ +#define HPC3_DSELECT_SCLKEXT 0x20 /* use external serial clock */ + + hpcreg _unused5; + hpcreg write1; +#define HPC3_WRITE1_PRESET 0x01 /* 0=LPR_RESET, 1=NORMAL */ +#define HPC3_WRITE1_KMRESET 0x02 /* 0=KBDMOUSE_RESET, 1=NORMAL */ +#define HPC3_WRITE1_ERESET 0x04 /* 0=EISA_RESET, 1=NORMAL */ +#define HPC3_WRITE1_GRESET 0x08 /* 0=MAGIC_GIO_RESET, 1=NORMAL */ +#define HPC3_WRITE1_LC0OFF 0x10 /* turn led off (guiness=red, else green) */ +#define HPC3_WRITE1_LC1OFF 0x20 /* turn led off (guiness=green, else amber) */ + + hpcreg _unused6; + hpcreg write2; +#define HPC3_WRITE2_NTHRESH 0x01 /* use 4.5db threshhold */ +#define HPC3_WRITE2_TPSPEED 0x02 /* use 100ohm TP speed */ +#define HPC3_WRITE2_EPSEL 0x04 /* force cable mode: 1=AUI 0=TP */ +#define HPC3_WRITE2_EASEL 0x08 /* 1=autoselect 0=manual cable selection */ +#define HPC3_WRITE2_U1AMODE 0x10 /* 1=PC 0=MAC UART mode */ +#define HPC3_WRITE2_U0AMODE 0x20 /* 1=PC 0=MAC UART mode */ +#define HPC3_WRITE2_MLO 0x40 /* 1=4.75V 0=+5V */ +#define HPC3_WRITE2_MHI 0x80 /* 1=5.25V 0=+5V */ +}; +extern struct hpc3_miscregs *hpc3mregs; +#define HPC3_MREGS_PBASE 0x1fbd9800 /* physical */ + +struct hpc_keyb { +#ifdef __MIPSEB__ + unsigned char _unused0[3]; + volatile unsigned char data; + unsigned char _unused1[3]; + volatile unsigned char command; +#else + volatile unsigned char data; + unsigned char _unused0[3]; + volatile unsigned char command; + unsigned char _unused1[3]; +#endif +}; + +extern void sgihpc_init(void); + +#endif /* !(_MIPS_SGIHPC_H) */ diff --git a/include/asm-mips/sgimc.h b/include/asm-mips/sgimc.h new file mode 100644 index 000000000..70bec8b1e --- /dev/null +++ b/include/asm-mips/sgimc.h @@ -0,0 +1,223 @@ +/* $Id: sgimc.h,v 1.4 1996/06/25 07:18:24 dm Exp $ + * sgimc.h: Definitions for memory controller hardware found on + * SGI IP20, IP22, IP26, and IP28 machines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ + +#ifndef _MIPS_SGIMC_H +#define _MIPS_SGIMC_H + +struct sgimc_misc_ctrl { + unsigned long _unused1; + volatile unsigned long cpuctrl0; /* CPU control register 0, readwrite */ +#define SGIMC_CCTRL0_REFS 0x0000000f /* REFS mask */ +#define SGIMC_CCTRL0_EREFRESH 0x00000010 /* Memory refresh enable */ +#define SGIMC_CCTRL0_EPERRGIO 0x00000020 /* GIO parity error enable */ +#define SGIMC_CCTRL0_EPERRMEM 0x00000040 /* Main mem parity error enable */ +#define SGIMC_CCTRL0_EPERRCPU 0x00000080 /* CPU bus parity error enable */ +#define SGIMC_CCTRL0_WDOG 0x00000100 /* Watchdog timer enable */ +#define SGIMC_CCTRL0_SYSINIT 0x00000200 /* System init bit */ +#define SGIMC_CCTRL0_GFXRESET 0x00000400 /* Graphics interface reset */ +#define SGIMC_CCTRL0_EISALOCK 0x00000800 /* Lock CPU from memory for EISA */ +#define SGIMC_CCTRL0_EPERRSCMD 0x00001000 /* SysCMD bus parity error enable */ +#define SGIMC_CCTRL0_IENAB 0x00002000 /* Allow interrupts from MC */ +#define SGIMC_CCTRL0_ESNOOP 0x00004000 /* Snooping I/O enable */ +#define SGIMC_CCTRL0_EPROMWR 0x00008000 /* Prom writes from cpu enable */ +#define SGIMC_CCTRL0_WRESETPMEM 0x00010000 /* Perform warm reset, preserves mem */ +#define SGIMC_CCTRL0_LENDIAN 0x00020000 /* Put MC in little-endian mode */ +#define SGIMC_CCTRL0_WRESETDMEM 0x00040000 /* Warm reset, destroys mem contents */ +#define SGIMC_CCTRL0_CMEMBADPAR 0x02000000 /* Generate bad perr from cpu to mem */ +#define SGIMC_CCTRL0_R4KNOCHKPARR 0x04000000 /* Don't chk parity on mem data reads */ +#define SGIMC_CCTRL0_GIOBTOB 0x08000000 /* Allow GIO back to back writes */ + + unsigned long _unused2; + volatile unsigned long cpuctrl1; /* CPU control register 1, readwrite */ +#define SGIMC_CCTRL1_EGIOTIMEO 0x00000010 /* GIO bus timeout enable */ +#define SGIMC_CCTRL1_FIXEDEHPC 0x00001000 /* Fixed HPC endianness */ +#define SGIMC_CCTRL1_LITTLEHPC 0x00002000 /* Little endian HPC */ +#define SGIMC_CCTRL1_FIXEDEEXP0 0x00004000 /* Fixed EXP0 endianness */ +#define SGIMC_CCTRL1_LITTLEEXP0 0x00008000 /* Little endian EXP0 */ +#define SGIMC_CCTRL1_FIXEDEEXP1 0x00010000 /* Fixed EXP1 endianness */ +#define SGIMC_CCTRL1_LITTLEEXP1 0x00020000 /* Little endian EXP1 */ + + unsigned long _unused3; + volatile unsigned long watchdogt; /* Watchdog reg rdonly, write clears */ + + unsigned long _unused4; + volatile unsigned long systemid; /* MC system ID register, readonly */ +#define SGIMC_SYSID_MASKREV 0x0000000f /* Revision of MC controller */ +#define SGIMC_SYSID_EPRESENT 0x00000010 /* Indicates presence of EISA bus */ + + unsigned long _unused5[3]; + volatile unsigned long divider; /* Divider reg for RPSS */ + + unsigned long _unused6; + volatile unsigned char eeprom; /* EEPROM byte reg for r4k */ +#define SGIMC_EEPROM_PRE 0x00000001 /* eeprom chip PRE pin assertion */ +#define SGIMC_EEPROM_CSEL 0x00000002 /* Active high, eeprom chip select */ +#define SGIMC_EEPROM_SECLOCK 0x00000004 /* EEPROM serial clock */ +#define SGIMC_EEPROM_SDATAO 0x00000008 /* Serial EEPROM data-out */ +#define SGIMC_EEPROM_SDATAI 0x00000010 /* Serial EEPROM data-in */ + + unsigned char _unused7[3]; + unsigned long _unused8[3]; + volatile unsigned short rcntpre; /* Preload refresh counter */ + + unsigned short _unused9; + unsigned long _unused9a; + volatile unsigned short rcounter; /* Readonly refresh counter */ + + unsigned short _unused10; + unsigned long _unused11[13]; + volatile unsigned long gioparm; /* Parameter word for GIO64 */ +#define SGIMC_GIOPARM_HPC64 0x00000001 /* HPC talks to GIO using 64-bits */ +#define SGIMC_GIOPARM_GFX64 0x00000002 /* GFX talks to GIO using 64-bits */ +#define SGIMC_GIOPARM_EXP064 0x00000004 /* EXP(slot0) talks using 64-bits */ +#define SGIMC_GIOPARM_EXP164 0x00000008 /* EXP(slot1) talks using 64-bits */ +#define SGIMC_GIOPARM_EISA64 0x00000010 /* EISA bus talks 64-bits to GIO */ +#define SGIMC_GIOPARM_HPC264 0x00000020 /* 2nd HPX talks 64-bits to GIO */ +#define SGIMC_GIOPARM_RTIMEGFX 0x00000040 /* GFX device has realtime attr */ +#define SGIMC_GIOPARM_RTIMEEXP0 0x00000080 /* EXP(slot0) has realtime attr */ +#define SGIMC_GIOPARM_RTIMEEXP1 0x00000100 /* EXP(slot1) has realtime attr */ +#define SGIMC_GIOPARM_MASTEREISA 0x00000200 /* EISA bus can act as bus master */ +#define SGIMC_GIOPARM_ONEBUS 0x00000400 /* Exists one GIO64 pipelined bus */ +#define SGIMC_GIOPARM_MASTERGFX 0x00000800 /* GFX can act as a bus master */ +#define SGIMC_GIOPARM_MASTEREXP0 0x00001000 /* EXP(slot0) can bus master */ +#define SGIMC_GIOPARM_MASTEREXP1 0x00002000 /* EXP(slot1) can bus master */ +#define SGIMC_GIOPARM_PLINEEXP0 0x00004000 /* EXP(slot0) has pipeline attr */ +#define SGIMC_GIOPARM_PLINEEXP1 0x00008000 /* EXP(slot1) has pipeline attr */ + + unsigned long _unused13; + volatile unsigned short cputp; /* CPU bus arb time period */ + + unsigned short _unused14; + unsigned long _unused15[3]; + volatile unsigned short lbursttp; /* Time period for long bursts */ + + unsigned short _unused16; + unsigned long _unused17[9]; + volatile unsigned long mconfig0; /* Memory config register zero */ + unsigned long _unused18; + volatile unsigned long mconfig1; /* Memory config register one */ + + /* These defines apply to both mconfig registers above. */ +#define SGIMC_MCONFIG_FOURMB 0x00000000 /* Physical ram = 4megs */ +#define SGIMC_MCONFIG_EIGHTMB 0x00000100 /* Physical ram = 8megs */ +#define SGIMC_MCONFIG_SXTEENMB 0x00000300 /* Physical ram = 16megs */ +#define SGIMC_MCONFIG_TTWOMB 0x00000700 /* Physical ram = 32megs */ +#define SGIMC_MCONFIG_SFOURMB 0x00000f00 /* Physical ram = 64megs */ +#define SGIMC_MCONFIG_OTEIGHTMB 0x00001f00 /* Physical ram = 128megs */ +#define SGIMC_MCONFIG_RMASK 0x00001f00 /* Ram config bitmask */ + + unsigned long _unused19; + volatile unsigned long cmacc; /* Mem access config for CPU */ + unsigned long _unused20; + volatile unsigned long gmacc; /* Mem access config for GIO */ + + /* This define applies to both cmacc and gmacc registers above. */ +#define SGIMC_MACC_ALIASBIG 0x20000000 /* 512MB home for alias */ + + /* Error address/status regs from GIO and CPU perspectives. */ + unsigned long _unused21; + volatile unsigned long cerr; /* Error address reg for CPU */ + unsigned long _unused22; + volatile unsigned long cstat; /* Status reg for CPU */ + unsigned long _unused23; + volatile unsigned long gerr; /* Error address reg for GIO */ + unsigned long _unused24; + volatile unsigned long gstat; /* Status reg for GIO */ + + /* Special hard bus locking registers. */ + unsigned long _unused25; + volatile unsigned char syssembit; /* Uni-bit system semaphore */ + unsigned char _unused26[3]; + unsigned long _unused27; + volatile unsigned char mlock; /* Global GIO memory access lock */ + unsigned char _unused28[3]; + unsigned long _unused29; + volatile unsigned char elock; /* Locks EISA from GIO accesses */ + + /* GIO dma control registers. */ + unsigned char _unused30[3]; + unsigned long _unused31[14]; + volatile unsigned long gio_dma_trans;/* DMA mask to translation GIO addrs */ + unsigned long _unused32; + volatile unsigned long gio_dma_sbits;/* DMA GIO addr substitution bits */ + unsigned long _unused33; + volatile unsigned long dma_intr_cause; /* DMA IRQ cause indicator bits */ + unsigned long _unused34; + volatile unsigned long dma_ctrl; /* Main DMA control reg */ + + /* DMA TLB entry 0 */ + unsigned long _unused35; + volatile unsigned long dtlb_hi0; + unsigned long _unused36; + volatile unsigned long dtlb_lo0; + + /* DMA TLB entry 1 */ + unsigned long _unused37; + volatile unsigned long dtlb_hi1; + unsigned long _unused38; + volatile unsigned long dtlb_lo1; + + /* DMA TLB entry 2 */ + unsigned long _unused39; + volatile unsigned long dtlb_hi2; + unsigned long _unused40; + volatile unsigned long dtlb_lo2; + + /* DMA TLB entry 3 */ + unsigned long _unused41; + volatile unsigned long dtlb_hi3; + unsigned long _unused42; + volatile unsigned long dtlb_lo3; +}; + +/* MC misc control registers live at physical 0x1fa00000. */ +extern struct sgimc_misc_ctrl *mcmisc_regs; +extern unsigned long *rpsscounter; /* Chirps at 100ns */ + +struct sgimc_dma_ctrl { + unsigned long _unused1; + volatile unsigned long maddronly; /* Address DMA goes at */ + unsigned long _unused2; + volatile unsigned long maddrpdeflts; /* Same as above, plus set defaults */ + unsigned long _unused3; + volatile unsigned long dmasz; /* DMA count */ + unsigned long _unused4; + volatile unsigned long ssize; /* DMA stride size */ + unsigned long _unused5; + volatile unsigned long gmaddronly; /* Set GIO DMA but do not start trans */ + unsigned long _unused6; + volatile unsigned long dmaddnpgo; /* Set GIO DMA addr + start transfer */ + unsigned long _unused7; + volatile unsigned long dmamode; /* DMA mode config bit settings */ + unsigned long _unused8; + volatile unsigned long dmacount; /* Zoom and byte count for DMA */ + unsigned long _unused9; + volatile unsigned long dmastart; /* Pedal to the metal. */ + unsigned long _unused10; + volatile unsigned long dmarunning; /* DMA op is in progress */ + unsigned long _unused11; + + /* Set dma addr, defaults, and kick it */ + volatile unsigned long maddr_defl_go; /* go go go! -lm */ +}; + +/* MC controller dma regs live at physical 0x1fa02000. */ +extern struct sgimc_dma_ctrl *dmactrlregs; + +/* Base location of the two ram banks found in IP2[0268] machines. */ +#define SGIMC_SEG0_BADDR 0x08000000 +#define SGIMC_SEG1_BADDR 0x20000000 + +/* Maximum size of the above banks are per machine. */ +extern unsigned long sgimc_seg0_size, sgimc_seg1_size; +#define SGIMC_SEG0_SIZE_ALL 0x10000000 /* 256MB */ +#define SGIMC_SEG1_SIZE_IP20_IP22 0x08000000 /* 128MB */ +#define SGIMC_SEG1_SIZE_IP26_IP28 0x20000000 /* 512MB */ + +extern void sgimc_init(void); + +#endif /* !(_MIPS_SGIMC_H) */ diff --git a/include/asm-mips/sgint23.h b/include/asm-mips/sgint23.h new file mode 100644 index 000000000..31319f829 --- /dev/null +++ b/include/asm-mips/sgint23.h @@ -0,0 +1,179 @@ +/* $Id: sgint23.h,v 1.5 1996/06/12 00:44:01 dm Exp $ + * sgint23.h: Defines for the SGI INT2 and INT3 chipsets. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#ifndef _MIPS_SGINT23_H +#define _MIPS_SGINT23_H + +/* These are the virtual IRQ numbers, we divide all IRQ's into + * 'spaces', the 'space' determines where and how to enable/disable + * that particular IRQ on an SGI machine. Add new 'spaces' as new + * IRQ hardware is supported. + */ +#define SGINT_LOCAL0 0 /* INDY has 8 local0 irq levels */ +#define SGINT_LOCAL1 8 /* INDY has 8 local1 irq levels */ +#define SGINT_LOCAL2 16 /* INDY has 8 local2 vectored irq levels */ +#define SGINT_LOCAL3 24 /* INDY has 8 local3 vectored irq levels */ +#define SGINT_GIO 32 /* INDY has 9 GIO irq levels */ +#define SGINT_HPCDMA 41 /* INDY has 11 HPCDMA irq _sources_ */ +#define SGINT_END 52 /* End of 'spaces' */ + +/* INT2 occupies HPC PBUS slot 4, INT3 uses slot 6. */ +#define SGI_INT2_BASE 0x1fb80100 /* physical */ +#define SGI_INT3_BASE 0x1fbd9880 /* physical */ + +struct sgi_ioc_ints { +#ifdef __MIPSEB__ + unsigned char _unused0[3]; + volatile unsigned char istat0; /* Interrupt status zero */ +#else + volatile unsigned char istat0; /* Interrupt status zero */ + unsigned char _unused0[3]; +#endif +#define ISTAT0_FFULL 0x01 +#define ISTAT0_SCSI0 0x02 +#define ISTAT0_SCSI1 0x04 +#define ISTAT0_ENET 0x08 +#define ISTAT0_GFXDMA 0x10 +#define ISTAT0_LPR 0x20 +#define ISTAT0_HPC2 0x40 +#define ISTAT0_LIO2 0x80 + +#ifdef __MIPSEB__ + unsigned char _unused1[3]; + volatile unsigned char imask0; /* Interrupt mask zero */ + unsigned char _unused2[3]; + volatile unsigned char istat1; /* Interrupt status one */ +#else + volatile unsigned char imask0; /* Interrupt mask zero */ + unsigned char _unused1[3]; + volatile unsigned char istat1; /* Interrupt status one */ + unsigned char _unused2[3]; +#endif +#define ISTAT1_ISDNI 0x01 +#define ISTAT1_PWR 0x02 +#define ISTAT1_ISDNH 0x04 +#define ISTAT1_LIO3 0x08 +#define ISTAT1_HPC3 0x10 +#define ISTAT1_AFAIL 0x20 +#define ISTAT1_VIDEO 0x40 +#define ISTAT1_GIO2 0x80 + +#ifdef __MIPSEB__ + unsigned char _unused3[3]; + volatile unsigned char imask1; /* Interrupt mask one */ + unsigned char _unused4[3]; + volatile unsigned char vmeistat; /* VME interrupt status */ + unsigned char _unused5[3]; + volatile unsigned char cmeimask0; /* VME interrupt mask zero */ + unsigned char _unused6[3]; + volatile unsigned char cmeimask1; /* VME interrupt mask one */ + unsigned char _unused7[3]; + volatile unsigned char cmepol; /* VME polarity */ +#else + volatile unsigned char imask1; /* Interrupt mask one */ + unsigned char _unused3[3]; + volatile unsigned char vmeistat; /* VME interrupt status */ + unsigned char _unused4[3]; + volatile unsigned char cmeimask0; /* VME interrupt mask zero */ + unsigned char _unused5[3]; + volatile unsigned char cmeimask1; /* VME interrupt mask one */ + unsigned char _unused6[3]; + volatile unsigned char cmepol; /* VME polarity */ + unsigned char _unused7[3]; +#endif +}; + +struct sgi_ioc_timers { +#ifdef __MIPSEB__ + unsigned char _unused0[3]; + volatile unsigned char tcnt0; /* counter 0 */ + unsigned char _unused1[3]; + volatile unsigned char tcnt1; /* counter 1 */ + unsigned char _unused2[3]; + volatile unsigned char tcnt2; /* counter 2 */ + unsigned char _unused3[3]; + volatile unsigned char tcword; /* control word */ +#else + volatile unsigned char tcnt0; /* counter 0 */ + unsigned char _unused0[3]; + volatile unsigned char tcnt1; /* counter 1 */ + unsigned char _unused1[3]; + volatile unsigned char tcnt2; /* counter 2 */ + unsigned char _unused2[3]; + volatile unsigned char tcword; /* control word */ + unsigned char _unused3[3]; +#endif +}; + +/* Timer control word bits. */ +#define SGINT_TCWORD_BCD 0x01 /* Use BCD mode for counters */ +#define SGINT_TCWORD_MMASK 0x0e /* Mode bitmask. */ +#define SGINT_TCWORD_MITC 0x00 /* IRQ on terminal count (doesn't work) */ +#define SGINT_TCWORD_MOS 0x02 /* One-shot IRQ mode. */ +#define SGINT_TCWORD_MRGEN 0x04 /* Normal rate generation */ +#define SGINT_TCWORD_MSWGEN 0x06 /* Square wave generator mode */ +#define SGINT_TCWORD_MSWST 0x08 /* Software strobe */ +#define SGINT_TCWORD_MHWST 0x0a /* Hardware strobe */ +#define SGINT_TCWORD_CMASK 0x30 /* Command mask */ +#define SGINT_TCWORD_CLAT 0x00 /* Latch command */ +#define SGINT_TCWORD_CLSB 0x10 /* LSB read/write */ +#define SGINT_TCWORD_CMSB 0x20 /* MSB read/write */ +#define SGINT_TCWORD_CALL 0x30 /* Full counter read/write */ +#define SGINT_TCWORD_CNT0 0x00 /* Select counter zero */ +#define SGINT_TCWORD_CNT1 0x40 /* Select counter one */ +#define SGINT_TCWORD_CNT2 0x80 /* Select counter two */ +#define SGINT_TCWORD_CRBCK 0xc0 /* Readback command */ + +#define SGINT_TCSAMP_COUNTER 0x164 + +struct sgi_int2_regs { + struct sgi_ioc_ints ints; + + volatile unsigned long ledbits; /* LED control bits */ +#define INT2_LED_TXCLK 0x01 /* GPI to TXCLK enable */ +#define INT2_LED_SERSLCT0 0x02 /* serial port0: 0=apple 1=pc */ +#define INT2_LED_SERSLCT1 0x04 /* serial port1: 0=apple 1=pc */ +#define INT2_LED_CHEAPER 0x08 /* 0=cheapernet 1=ethernet */ +#define INT2_LED_POWEROFF 0x10 /* Power-off request, active high */ + +#ifdef __MIPSEB__ + unsigned char _unused0[3]; + volatile unsigned char tclear; /* Timer clear strobe address */ +#else + volatile unsigned char tclear; /* Timer clear strobe address */ + unsigned char _unused0[3]; +#endif +#define INT2_TCLEAR_T0CLR 0x1 /* Clear timer0 IRQ */ +#define INT2_TCLEAR_T1CLR 0x2 /* Clear timer1 IRQ */ + + unsigned long _unused[3]; + struct sgi_ioc_timers timers; +}; + +struct sgi_int3_regs { + struct sgi_ioc_ints ints; + +#ifdef __MIPSEB__ + unsigned char _unused0[3]; + volatile unsigned char tclear; /* Timer clear strobe address */ +#else + volatile unsigned char tclear; /* Timer clear strobe address */ + unsigned char _unused0[3]; +#endif + volatile unsigned long estatus; /* Error status reg */ + unsigned long _unused1[2]; + struct sgi_ioc_timers timers; +}; + +extern struct sgi_int2_regs *sgi_i2regs; +extern struct sgi_int3_regs *sgi_i3regs; +extern struct sgi_ioc_ints *ioc_icontrol; +extern struct sgi_ioc_timers *ioc_timers; +extern volatile unsigned char *ioc_tclear; + +extern void sgint_init(void); +extern void indy_timer_init(void); + +#endif /* !(_MIPS_SGINT23_H) */ diff --git a/include/asm-mips/shmparam.h b/include/asm-mips/shmparam.h index 9c5a38a40..b2441c81a 100644 --- a/include/asm-mips/shmparam.h +++ b/include/asm-mips/shmparam.h @@ -39,7 +39,7 @@ #define SHMALL /* max shm system wide (pages) */ \ (1<<(_SHM_IDX_BITS+_SHM_ID_BITS)) /* - * This constant is very large but the ABI in its wisdom says ... + * This constant is very large but the ABI in it's wisdom says ... */ #define SHMLBA 0x40000 /* attach addr a multiple of this */ #define SHMSEG SHMMNI /* max shared segs per process */ diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h index 135d83df6..a1f7613f4 100644 --- a/include/asm-mips/sigcontext.h +++ b/include/asm-mips/sigcontext.h @@ -18,6 +18,7 @@ #endif #if defined(__LANGUAGE_C__) || \ + defined(_LANGUAGE_C) || \ defined(__LANGUAGE_C_PLUS_PLUS__) || \ defined(__LANGUAGE_OBJECTIVE_C__) diff --git a/include/asm-mips/slots.h b/include/asm-mips/slots.h deleted file mode 100644 index 387802333..000000000 --- a/include/asm-mips/slots.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * include/asm-mips/slots.h - * - * Copyright (C) 1994 by Waldorf Electronics - * Written by Ralf Baechle - */ -#ifndef __ASM_MIPS_SLOTS_H -#define __ASM_MIPS_SLOTS_H - -#include <linux/config.h> - -/* - * SLOTSPACE is the address to which the physical address 0 - * of the Slotspace is mapped by the chipset in the main CPU's - * address space. - */ -#ifdef CONFIG_DESKSTATION_RPC44 -#define SLOTSPACE 0xa0000000 -#else -#define SLOTSPACE 0xe1000000 -#endif - -#endif /* __ASM_MIPS_SLOTS_H */ diff --git a/include/asm-mips/sni.h b/include/asm-mips/sni.h new file mode 100644 index 000000000..304506aee --- /dev/null +++ b/include/asm-mips/sni.h @@ -0,0 +1,15 @@ +/* + * SNI specific 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) 1997 by Ralf Baechle + */ +#ifndef __ASM_MIPS_SNI_H +#define __ASM_MIPS_SNI_H + +#define SNI_PORT_BASE 0xb4000000 + +#endif /* __ASM_MIPS_SNI_H */ diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index 3cdbb61ef..4a110338a 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h @@ -1,351 +1,114 @@ /* - * Makefile for MIPS Linux main source directory + * include/asm-mips/stackframe.h * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Paul M. Antoine. - * Additional R3000 support by Didier Frick <dfrick@dial.eunet.ch> - * for ACN S.A, Copyright (C) 1996 by ACN S.A + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Paul M. Antoine. */ #ifndef __ASM_MIPS_STACKFRAME_H #define __ASM_MIPS_STACKFRAME_H -#include <asm/sgidefs.h> #include <asm/asm.h> - -/* - * Stack layout for all exceptions: - * - * ptrace needs to have all regs on the stack. If the order here is changed, - * it needs to be updated in include/asm-mips/ptrace.h - * - * The first PTRSIZE*6 bytes are argument save space for C subroutines. - * zero doesn't get saved; it's just a placeholder. - */ -#define FR_REG0 (SZREG*6) -#define FR_REG1 ((FR_REG0) + SZREG) -#define FR_REG2 ((FR_REG1) + SZREG) -#define FR_REG3 ((FR_REG2) + SZREG) -#define FR_REG4 ((FR_REG3) + SZREG) -#define FR_REG5 ((FR_REG4) + SZREG) -#define FR_REG6 ((FR_REG5) + SZREG) -#define FR_REG7 ((FR_REG6) + SZREG) -#define FR_REG8 ((FR_REG7) + SZREG) -#define FR_REG9 ((FR_REG8) + SZREG) -#define FR_REG10 ((FR_REG9) + SZREG) -#define FR_REG11 ((FR_REG10) + SZREG) -#define FR_REG12 ((FR_REG11) + SZREG) -#define FR_REG13 ((FR_REG12) + SZREG) -#define FR_REG14 ((FR_REG13) + SZREG) -#define FR_REG15 ((FR_REG14) + SZREG) -#define FR_REG16 ((FR_REG15) + SZREG) -#define FR_REG17 ((FR_REG16) + SZREG) -#define FR_REG18 ((FR_REG17) + SZREG) -#define FR_REG19 ((FR_REG18) + SZREG) -#define FR_REG20 ((FR_REG19) + SZREG) -#define FR_REG21 ((FR_REG20) + SZREG) -#define FR_REG22 ((FR_REG21) + SZREG) -#define FR_REG23 ((FR_REG22) + SZREG) -#define FR_REG24 ((FR_REG23) + SZREG) -#define FR_REG25 ((FR_REG24) + SZREG) - -/* - * $26 (k0) and $27 (k1) not saved - just placeholders - */ -#define FR_REG26 ((FR_REG25) + SZREG) -#define FR_REG27 ((FR_REG26) + SZREG) - -#define FR_REG28 ((FR_REG27) + SZREG) -#define FR_REG29 ((FR_REG28) + SZREG) -#define FR_REG30 ((FR_REG29) + SZREG) -#define FR_REG31 ((FR_REG30) + SZREG) - -/* - * Saved special registers - */ -#define FR_LO ((FR_REG31) + SZREG) -#define FR_HI ((FR_LO) + SZREG) -#define FR_ORIG_REG2 ((FR_HI) + SZREG) -#define FR_ORIG_REG7 ((FR_ORIG_REG2) + SZREG) - -/* - * Saved cp0 registers follow - */ -#define FR_EPC ((FR_ORIG_REG7) + SZREG) -#define FR_BADVADDR ((FR_EPC) + SZREG) -#define FR_STATUS ((FR_BADVADDR) + SZREG) -#define FR_CAUSE ((FR_STATUS) + 4) - -/* - * Size of stack frame, word/double word alignment - */ -#define FR_SIZE (((FR_CAUSE + 4) + ALSZ) & ALMASK) - -/* - * Load the global pointer. Only for ELF executables global pointer - * optimization is possible, so we only load the global pointer for - * ELF kernels. - */ -#if 0 -#define LOAD_GP la gp,_gp -#else -#define LOAD_GP -#endif - -#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) - -#define SAVE_ALL \ - mfc0 k0,CP0_STATUS; \ - li k1,ST0_CU0; \ - and k0,k1; \ - bnez k0,8f; \ - move k1,sp; \ - nop; \ - /* \ - * Called from user mode, new stack \ - */ \ - lw k1,kernelsp; \ -8: move k0,sp; \ - subu sp,k1,FR_SIZE; \ - sw k0,FR_REG29(sp); \ - sw $3,FR_REG3(sp); \ - mfc0 $3,CP0_STATUS; \ - nop; \ - sw $3,FR_STATUS(sp); \ - li k1,ST0_CU0; \ - or k1,$3; \ - mtc0 k1,CP0_STATUS; \ - nop; \ - mfc0 $3,CP0_ENTRYHI; \ - nop; \ - sw $3,FR_ENTRYHI(sp); \ - mfc0 $3,CP0_CAUSE; \ - nop; \ - sw $3,FR_CAUSE(sp); \ - mfc0 $3,CP0_EPC; \ - nop; \ - sw $3,FR_EPC(sp); \ - mfc0 $3,CP0_BADVADDR; \ - nop; \ - sw $3,FR_BADVADDR(sp); \ - mfhi $3; \ - sw $3,FR_HI(sp); \ - mflo $3; \ - sw $3,FR_LO(sp); \ - sw $1,FR_REG1(sp); \ - sw $2,FR_REG2(sp); \ - sw $4,FR_REG4(sp); \ - sw $5,FR_REG5(sp); \ - sw $6,FR_REG6(sp); \ - sw $7,FR_REG7(sp); \ - sw $8,FR_REG8(sp); \ - sw $9,FR_REG9(sp); \ - sw $10,FR_REG10(sp); \ - sw $11,FR_REG11(sp); \ - sw $12,FR_REG12(sp); \ - sw $13,FR_REG13(sp); \ - sw $14,FR_REG14(sp); \ - sw $15,FR_REG15(sp); \ - sw $16,FR_REG16(sp); \ - sw $17,FR_REG17(sp); \ - sw $18,FR_REG18(sp); \ - sw $19,FR_REG19(sp); \ - sw $20,FR_REG20(sp); \ - sw $21,FR_REG21(sp); \ - sw $22,FR_REG22(sp); \ - sw $23,FR_REG23(sp); \ - sw $24,FR_REG24(sp); \ - sw $25,FR_REG25(sp); \ - sw $28,FR_REG28(sp); \ - sw $30,FR_REG30(sp); \ - sw $31,FR_REG31(sp); \ - LOAD_GP +#include <asm/offset.h> + +#define SAVE_ALL \ + mfc0 k0, CP0_STATUS; \ + sll k0, 3; /* extract cu0 bit */ \ + bltz k0, 8f; \ + move k1, sp; \ + /* Called from user mode, new stack. */ \ + lui k1, %hi(kernelsp); \ + lw k1, %lo(kernelsp)(k1); \ +8: \ + move k0, sp; \ + subu sp, k1, PT_SIZE; \ + sw k0, PT_R29(sp); \ + sw $2, PT_R2(sp); \ + sw $1, PT_R1(sp); \ + sw $2, PT_OR2(sp); \ + sw $0, PT_R0(sp); \ + mfc0 v0, CP0_STATUS; \ + sw $3, PT_R3(sp); \ + sw v0, PT_STATUS(sp); \ + sw $4, PT_R4(sp); \ + mfc0 v0, CP0_CAUSE; \ + sw $5, PT_R5(sp); \ + sw v0, PT_CAUSE(sp); \ + sw $6, PT_R6(sp); \ + mfc0 v0, CP0_EPC; \ + sw $7, PT_R7(sp); \ + sw v0, PT_EPC(sp); \ + sw $7, PT_OR7(sp); \ + sw $8, PT_R8(sp); \ + mfhi v0; \ + sw $9, PT_R9(sp); \ + sw v0, PT_HI(sp); \ + sw $10,PT_R10(sp); \ + mflo v0; \ + sw $11, PT_R11(sp); \ + sw v0, PT_LO(sp); \ + sw $12, PT_R12(sp); \ + sw $13, PT_R13(sp); \ + sw $14, PT_R14(sp); \ + sw $15, PT_R15(sp); \ + 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 $24, PT_R24(sp); \ + sw $25, PT_R25(sp); \ + sw $28, PT_R28(sp); \ + sw $30, PT_R30(sp); \ + sw $31, PT_R31(sp); /* * Note that we restore the IE flags from stack. This means * that a modified IE mask will be nullified. */ -/* - * FIXME: Don't need to clear these bits on R[236]000's?? - * - mfc0 t0,CP0_STATUS; \ - ori t0,0x1f; \ - xori t0,0x1f; \ - mtc0 t0,CP0_STATUS; \ - */ -#define RESTORE_ALL \ - lw v1,FR_LO(sp); \ - lw v0,FR_HI(sp); \ - mtlo v1; \ - lw v1,FR_EPC(sp); \ - mthi v0; \ - mtc0 v1,CP0_EPC; \ - lw $31,FR_REG31(sp); \ - lw $30,FR_REG30(sp); \ - lw $28,FR_REG28(sp); \ - lw $25,FR_REG25(sp); \ - lw $24,FR_REG24(sp); \ - lw $23,FR_REG23(sp); \ - lw $22,FR_REG22(sp); \ - lw $21,FR_REG21(sp); \ - lw $20,FR_REG20(sp); \ - lw $19,FR_REG19(sp); \ - lw $18,FR_REG18(sp); \ - lw $17,FR_REG17(sp); \ - lw $16,FR_REG16(sp); \ - lw $15,FR_REG15(sp); \ - lw $14,FR_REG14(sp); \ - lw $13,FR_REG13(sp); \ - lw $12,FR_REG12(sp); \ - lw $11,FR_REG11(sp); \ - lw $10,FR_REG10(sp); \ - lw $9,FR_REG9(sp); \ - lw $8,FR_REG8(sp); \ - lw $7,FR_REG7(sp); \ - lw $6,FR_REG6(sp); \ - lw $5,FR_REG5(sp); \ - lw $4,FR_REG4(sp); \ - lw $3,FR_REG3(sp); \ - lw $2,FR_REG2(sp); \ - lw $1,FR_REG1(sp); \ - lw k1,FR_STATUS(sp); \ - lw sp,FR_REG29(sp); \ - ori k1,3; \ - xori k1,3; \ - mtc0 k1,CP0_STATUS; \ - nop - -/* - * We disable interrupts when restoring the status register because: - * 1) the ret_from_syscall routine uses k0/k1 to preserve values around - * the RESTORE_ALL - * 2) the rfe instruction will restore the IE and KU flags to their - * previous value. - */ - -#define CLI \ - mfc0 t1,$12; \ - li t0,ST0_CU0|1; \ - or t1,t1,t0; \ - xori t1,1; \ - mtc0 t1,$12; \ - nop; \ - nop - -#define STI \ - mfc0 t1,$12; \ - li t0,ST0_CU0|1; \ - or t1,t1,t0; \ - mtc0 t1,$12; \ - nop; \ - nop - -#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) */ - -#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS5) - -#define SAVE_ALL \ - mfc0 k0,CP0_STATUS; \ - sll k0,3; /* extract cu0 bit */ \ - bltz k0,8f; \ - move k1,sp; \ - /* \ - * Called from user mode, new stack \ - */ \ - lw k1,kernelsp; \ -8: move k0,sp; \ - subu sp,k1,FR_SIZE; \ - sd k0,FR_REG29(sp); \ - sd $3,FR_REG3(sp); \ - mfc0 $3,CP0_STATUS; \ - sw $3,FR_STATUS(sp); \ - mfc0 $3,CP0_CAUSE; \ - sw $3,FR_CAUSE(sp); \ - dmfc0 $3,CP0_EPC; \ - sd $3,FR_EPC(sp); \ - mfhi $3; \ - sd $3,FR_HI(sp); \ - mflo $3; \ - sd $3,FR_LO(sp); \ - sd $1,FR_REG1(sp); \ - sd $2,FR_REG2(sp); \ - sd $4,FR_REG4(sp); \ - sd $5,FR_REG5(sp); \ - sd $6,FR_REG6(sp); \ - sd $7,FR_REG7(sp); \ - sd $8,FR_REG8(sp); \ - sd $9,FR_REG9(sp); \ - sd $10,FR_REG10(sp); \ - sd $11,FR_REG11(sp); \ - sd $12,FR_REG12(sp); \ - sd $13,FR_REG13(sp); \ - sd $14,FR_REG14(sp); \ - sd $15,FR_REG15(sp); \ - sd $16,FR_REG16(sp); \ - sd $17,FR_REG17(sp); \ - sd $18,FR_REG18(sp); \ - sd $19,FR_REG19(sp); \ - sd $20,FR_REG20(sp); \ - sd $21,FR_REG21(sp); \ - sd $22,FR_REG22(sp); \ - sd $23,FR_REG23(sp); \ - sd $24,FR_REG24(sp); \ - sd $25,FR_REG25(sp); \ - sd $28,FR_REG28(sp); \ - sd $30,FR_REG30(sp); \ - sd $31,FR_REG31(sp); \ - LOAD_GP - -/* - * Note that we restore the IE flags from stack. This means - * that a modified IE mask will be nullified. - */ -#define RESTORE_ALL \ - mfc0 t0,CP0_STATUS; \ - ori t0,0x1f; \ - xori t0,0x1f; \ - mtc0 t0,CP0_STATUS; \ - \ - lw v0,FR_STATUS(sp); \ - ld v1,FR_LO(sp); \ - mtc0 v0,CP0_STATUS; \ - mtlo v1; \ - ld v0,FR_HI(sp); \ - ld v1,FR_EPC(sp); \ - mthi v0; \ - dmtc0 v1,CP0_EPC; \ - ld $31,FR_REG31(sp); \ - ld $30,FR_REG30(sp); \ - ld $28,FR_REG28(sp); \ - ld $25,FR_REG25(sp); \ - ld $24,FR_REG24(sp); \ - ld $23,FR_REG23(sp); \ - ld $22,FR_REG22(sp); \ - ld $21,FR_REG21(sp); \ - ld $20,FR_REG20(sp); \ - ld $19,FR_REG19(sp); \ - ld $18,FR_REG18(sp); \ - ld $17,FR_REG17(sp); \ - ld $16,FR_REG16(sp); \ - ld $15,FR_REG15(sp); \ - ld $14,FR_REG14(sp); \ - ld $13,FR_REG13(sp); \ - ld $12,FR_REG12(sp); \ - ld $11,FR_REG11(sp); \ - ld $10,FR_REG10(sp); \ - ld $9,FR_REG9(sp); \ - ld $8,FR_REG8(sp); \ - ld $7,FR_REG7(sp); \ - ld $6,FR_REG6(sp); \ - ld $5,FR_REG5(sp); \ - ld $4,FR_REG4(sp); \ - ld $3,FR_REG3(sp); \ - ld $2,FR_REG2(sp); \ - ld $1,FR_REG1(sp); \ - ld sp,FR_REG29(sp) /* Deallocate stack */ \ +#define RESTORE_ALL \ + mfc0 t0, CP0_STATUS; \ + ori t0, 0x1f; \ + xori t0, 0x1f; \ + mtc0 t0, CP0_STATUS; \ + lw v0, PT_STATUS(sp); \ + lw v1, PT_LO(sp); \ + mtc0 v0, CP0_STATUS; \ + mtlo v1; \ + lw v0, PT_HI(sp); \ + lw v1, PT_EPC(sp); \ + mthi v0; \ + mtc0 v1, CP0_EPC; \ + lw $31, PT_R31(sp); \ + lw $30, PT_R30(sp); \ + lw $28, PT_R28(sp); \ + lw $25, PT_R25(sp); \ + lw $24, PT_R24(sp); \ + lw $23, PT_R23(sp); \ + lw $22, PT_R22(sp); \ + lw $21, PT_R21(sp); \ + lw $20, PT_R20(sp); \ + lw $19, PT_R19(sp); \ + lw $18, PT_R18(sp); \ + lw $17, PT_R17(sp); \ + lw $16, PT_R16(sp); \ + lw $15, PT_R15(sp); \ + lw $14, PT_R14(sp); \ + lw $13, PT_R13(sp); \ + lw $12, PT_R12(sp); \ + lw $11, PT_R11(sp); \ + lw $10, PT_R10(sp); \ + lw $9, PT_R9(sp); \ + lw $8, PT_R8(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); \ + lw $1, PT_R1(sp); \ + lw sp, PT_R29(sp); /* * Move to kernel mode and disable interrupts. @@ -373,6 +136,4 @@ xori t0,0x1e; \ mtc0 t0,CP0_STATUS -#endif /* _MIPS_ISA >= MIPS3 */ - #endif /* __ASM_MIPS_STACKFRAME_H */ diff --git a/include/asm-mips/string.h b/include/asm-mips/string.h index 1773abd81..2fb241775 100644 --- a/include/asm-mips/string.h +++ b/include/asm-mips/string.h @@ -10,11 +10,6 @@ #ifndef __ASM_MIPS_STRING_H #define __ASM_MIPS_STRING_H -#ifdef __KERNEL__ - -#include <linux/linkage.h> -#include <asm/sgidefs.h> - #define __HAVE_ARCH_STRCPY extern __inline__ char *strcpy(char *__dest, __const__ char *__src) { @@ -122,318 +117,16 @@ extern __inline__ int strncmp(__const__ char *__cs, __const__ char *__ct, size_t } #define __HAVE_ARCH_MEMSET -/* - * Ok, this definately looks braindead. I tried several other variants - * some of which GCC wasn't able to optimize or which made GCC consume - * extreme amounts of memory. - * This code attempts never to generate address errors which require - * expensive software emulation. For this purpose GCC's __alignof__ - * seems to be perfect. Unfortunately GCC 2.7.2 complains about - * __alignof__(*p) when p is a pointer to void. For now I ignore these - * warnings. - */ - -extern void __generic_memset_b(void *__s, int __c, size_t __count); -extern void __generic_memset_dw(void *__s, unsigned long long __c, - size_t __count); - -/* - * The constant c handling looks wired but it combines minimal code - * size with fast execution. - */ -#define __generic_memset(s, c, count, const_c) \ -({if(const_c) { \ - unsigned long long __dwc; \ -\ - __dwc = c & 0xff; \ - __dwc = (__dwc << 8) | __dwc; \ - __dwc = (__dwc << 16) | __dwc; \ - __dwc = (__dwc << 32) | __dwc; \ - __generic_memset_dw(s, __dwc, count); \ - } \ -else \ - __generic_memset_b(s, c, count); \ -}) - -extern __inline__ void __const_count_memset1(void *__s, int __c, size_t __count, - int __const_c) -{ - switch(__count) { - case 0: return; - case 1: *(0+(char *)__s) = __c; - return; - case 2: *(0+(char *)__s) = __c; - *(1+(char *)__s) = __c; - return; - case 3: *(0+(char *)__s) = __c; - *(1+(char *)__s) = __c; - *(2+(char *)__s) = __c; - return; - case 4: *(0+(char *)__s) = __c; - *(1+(char *)__s) = __c; - *(2+(char *)__s) = __c; - *(3+(char *)__s) = __c; - return; - case 5: *(0+(char *)__s) = __c; - *(1+(char *)__s) = __c; - *(2+(char *)__s) = __c; - *(3+(char *)__s) = __c; - *(4+(char *)__s) = __c; - return; - case 6: *(0+(char *)__s) = __c; - *(1+(char *)__s) = __c; - *(2+(char *)__s) = __c; - *(3+(char *)__s) = __c; - *(4+(char *)__s) = __c; - *(5+(char *)__s) = __c; - return; - case 7: *(0+(char *)__s) = __c; - *(1+(char *)__s) = __c; - *(2+(char *)__s) = __c; - *(3+(char *)__s) = __c; - *(4+(char *)__s) = __c; - *(5+(char *)__s) = __c; - *(6+(char *)__s) = __c; - return; - case 8: *(0+(char *)__s) = __c; - *(1+(char *)__s) = __c; - *(2+(char *)__s) = __c; - *(3+(char *)__s) = __c; - *(4+(char *)__s) = __c; - *(5+(char *)__s) = __c; - *(6+(char *)__s) = __c; - *(7+(char *)__s) = __c; - return; - } - __generic_memset(__s, __c, __count, __const_c); - return; -} - -extern __inline__ void __const_count_memset2(void *__s, int __c, size_t __count, - int __const_c) -{ - switch(__count) { - case 0: return; - case 2: *(0+(short *)__s) = 0x0101 * __c; - return; - case 4: *(0+(short *)__s) = 0x0101 * __c; - *(1+(short *)__s) = 0x0101 * __c; - return; - case 6: *(0+(short *)__s) = 0x0101 * __c; - *(1+(short *)__s) = 0x0101 * __c; - *(2+(short *)__s) = 0x0101 * __c; - return; - case 8: *(0+(short *)__s) = 0x0101 * __c; - *(1+(short *)__s) = 0x0101 * __c; - *(2+(short *)__s) = 0x0101 * __c; - *(3+(short *)__s) = 0x0101 * __c; - return; - case 10:*(0+(short *)__s) = 0x0101 * __c; - *(1+(short *)__s) = 0x0101 * __c; - *(2+(short *)__s) = 0x0101 * __c; - *(3+(short *)__s) = 0x0101 * __c; - *(4+(short *)__s) = 0x0101 * __c; - return; - case 12:*(0+(short *)__s) = 0x0101 * __c; - *(1+(short *)__s) = 0x0101 * __c; - *(2+(short *)__s) = 0x0101 * __c; - *(3+(short *)__s) = 0x0101 * __c; - *(4+(short *)__s) = 0x0101 * __c; - *(5+(short *)__s) = 0x0101 * __c; - return; - case 14:*(0+(short *)__s) = 0x0101 * __c; - *(1+(short *)__s) = 0x0101 * __c; - *(2+(short *)__s) = 0x0101 * __c; - *(3+(short *)__s) = 0x0101 * __c; - *(4+(short *)__s) = 0x0101 * __c; - *(5+(short *)__s) = 0x0101 * __c; - *(6+(short *)__s) = 0x0101 * __c; - return; - case 16:*(0+(short *)__s) = 0x0101 * __c; - *(1+(short *)__s) = 0x0101 * __c; - *(2+(short *)__s) = 0x0101 * __c; - *(3+(short *)__s) = 0x0101 * __c; - *(4+(short *)__s) = 0x0101 * __c; - *(5+(short *)__s) = 0x0101 * __c; - *(6+(short *)__s) = 0x0101 * __c; - *(7+(short *)__s) = 0x0101 * __c; - return; - } - __generic_memset(__s, __c, __count, __const_c); - return; -} - -extern __inline__ void __const_count_memset4(void *__s, int __c, size_t __count, - int __const_c) -{ - switch(__count) { - case 0: return; - case 4: *(0+(int *)__s) = 0x01010101 * __c; - return; - case 8: *(0+(int *)__s) = 0x01010101 * __c; - *(1+(int *)__s) = 0x01010101 * __c; - return; - case 12:*(0+(int *)__s) = 0x01010101 * __c; - *(1+(int *)__s) = 0x01010101 * __c; - *(2+(int *)__s) = 0x01010101 * __c; - return; - case 16:*(0+(int *)__s) = 0x01010101 * __c; - *(1+(int *)__s) = 0x01010101 * __c; - *(2+(int *)__s) = 0x01010101 * __c; - *(3+(int *)__s) = 0x01010101 * __c; - return; - case 20:*(0+(int *)__s) = 0x01010101 * __c; - *(1+(int *)__s) = 0x01010101 * __c; - *(2+(int *)__s) = 0x01010101 * __c; - *(3+(int *)__s) = 0x01010101 * __c; - *(4+(int *)__s) = 0x01010101 * __c; - return; - case 24:*(0+(int *)__s) = 0x01010101 * __c; - *(1+(int *)__s) = 0x01010101 * __c; - *(2+(int *)__s) = 0x01010101 * __c; - *(3+(int *)__s) = 0x01010101 * __c; - *(4+(int *)__s) = 0x01010101 * __c; - *(5+(int *)__s) = 0x01010101 * __c; - return; - case 28:*(0+(int *)__s) = 0x01010101 * __c; - *(1+(int *)__s) = 0x01010101 * __c; - *(2+(int *)__s) = 0x01010101 * __c; - *(3+(int *)__s) = 0x01010101 * __c; - *(4+(int *)__s) = 0x01010101 * __c; - *(5+(int *)__s) = 0x01010101 * __c; - *(6+(int *)__s) = 0x01010101 * __c; - return; - case 32:*(0+(int *)__s) = 0x01010101 * __c; - *(1+(int *)__s) = 0x01010101 * __c; - *(2+(int *)__s) = 0x01010101 * __c; - *(3+(int *)__s) = 0x01010101 * __c; - *(4+(int *)__s) = 0x01010101 * __c; - *(5+(int *)__s) = 0x01010101 * __c; - *(6+(int *)__s) = 0x01010101 * __c; - *(7+(int *)__s) = 0x01010101 * __c; - return; - } - __generic_memset(__s, __c, __count, __const_c); - return; -} - -extern __inline__ void __const_count_memset8(void *__s, int __c, size_t __count, - int __const_c) -{ - unsigned long long __dwc; - - __dwc = __c & 0xff; - __dwc = (__dwc << 8) | __dwc; - __dwc = (__dwc << 16) | __dwc; - __dwc = (__dwc << 32) | __dwc; - switch(__count) { - case 0: return; - case 8: *(0+(long long *)__s) = __dwc; - return; - case 16:*(0+(long long *)__s) = __dwc; - *(1+(long long *)__s) = __dwc; - return; - case 24:*(0+(long long *)__s) = __dwc; - *(1+(long long *)__s) = __dwc; - *(2+(long long *)__s) = __dwc; - return; - case 32:*(0+(long long *)__s) = __dwc; - *(1+(long long *)__s) = __dwc; - *(2+(long long *)__s) = __dwc; - *(3+(long long *)__s) = __dwc; - return; - case 40:*(0+(long long *)__s) = __dwc; - *(1+(long long *)__s) = __dwc; - *(2+(long long *)__s) = __dwc; - *(3+(long long *)__s) = __dwc; - *(4+(long long *)__s) = __dwc; - return; - case 48:*(0+(long long *)__s) = __dwc; - *(1+(long long *)__s) = __dwc; - *(2+(long long *)__s) = __dwc; - *(3+(long long *)__s) = __dwc; - *(4+(long long *)__s) = __dwc; - *(5+(long long *)__s) = __dwc; - return; - case 56:*(0+(long long *)__s) = __dwc; - *(1+(long long *)__s) = __dwc; - *(2+(long long *)__s) = __dwc; - *(3+(long long *)__s) = __dwc; - *(4+(long long *)__s) = __dwc; - *(5+(long long *)__s) = __dwc; - *(6+(long long *)__s) = __dwc; - return; - case 64:*(0+(long long *)__s) = __dwc; - *(1+(long long *)__s) = __dwc; - *(2+(long long *)__s) = __dwc; - *(3+(long long *)__s) = __dwc; - *(4+(long long *)__s) = __dwc; - *(5+(long long *)__s) = __dwc; - *(6+(long long *)__s) = __dwc; - *(7+(long long *)__s) = __dwc; - return; - } - __generic_memset(__s, __c, __count, __const_c); - return; -} - -extern __inline__ void * __const_count_memset(void *__s, int __c, - size_t __count, int __align, - int __const_c) -{ - switch(__align) { - /* - * We only want this for the 64 bit CPUs; this gets - * too bloated on 32 bit. - */ - case 1: __const_count_memset1(__s, __c, __count, __const_c); - return __s; - case 2: __const_count_memset2(__s, __c, __count, __const_c); - return __s; - case 4: __const_count_memset4(__s, __c, __count, __const_c); - return __s; -#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS5) - case 8: __const_count_memset8(__s, __c, __count, __const_c); - return __s; -#endif - } - __generic_memset(__s, __c, __count, __const_c); - return __s; -} - -#define memset(s, c, count) \ -(__builtin_constant_p(count) ? \ - __const_count_memset((s),(c),(count),__alignof__(*(s)), \ - __builtin_constant_p(c)) : \ - __generic_memset((s),(c),(count),__builtin_constant_p(c))) +extern void *memset(void *__s, char __c, size_t __count); #define __HAVE_ARCH_MEMCPY -extern void __memcpy(void *__to, __const__ void *__from, size_t __n); -extern __inline__ void *memcpy(void *__to, __const__ void *__from, size_t __n) -{ - __memcpy(__to, __from, __n); - - return __to; -} +extern void *memcpy(void *__to, __const__ void *__from, size_t __n); #define __HAVE_ARCH_MEMMOVE -extern void __memmove(void *__dest, __const__ void *__src, size_t __n); -extern __inline__ void *memmove(void *__dest, __const__ void *__src, size_t __n) -{ - __memmove(__dest, __src, __n); - - return __dest; -} +extern void *memmove(void *__dest, __const__ void *__src, size_t __n); #define __HAVE_ARCH_BCOPY -extern __inline__ char *bcopy(__const__ char *__src, char *__dest, size_t __count) -{ - __memmove(__dest, __src, __count); - - return __dest; -} +extern char * bcopy(const char * src, char * dest, int count); #define __HAVE_ARCH_MEMSCAN extern __inline__ void *memscan(void *__addr, int __c, size_t __size) @@ -442,15 +135,19 @@ extern __inline__ void *memscan(void *__addr, int __c, size_t __size) if (!__size) return __addr; - __asm__(".set\tnoat\n" + __asm__(".set\tnoreorder\n\t" + ".set\tnoat\n" "1:\tlbu\t$1,(%0)\n\t" - ".set\tnoreorder\n\t" +#if _MIPS_ISA == _MIPS_ISA_MIPS1 + "nop\n\t" +#endif "beq\t$1,%3,2f\n\t" - "addiu\t%0,1\t\t\t# delay slot\n\t" - ".set\treorder\n\t" - ".set\tat\n\t" + "addiu\t%0,1\n\t" "bne\t%0,%2,1b\n\t" - "2:\n" + "nop\n\t" + ".set\tat\n\t" + ".set\treorder\n" + "2:" : "=r" (__addr) : "0" (__addr), "1" (__end), "r" (__c) : "$1"); @@ -458,6 +155,4 @@ extern __inline__ void *memscan(void *__addr, int __c, size_t __size) return __addr; } -#endif /* __KERNEL__ */ - #endif /* __ASM_MIPS_STRING_H */ diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 5489dd87a..4bb2bf1c7 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -5,18 +5,15 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle, Paul M. Antoine + * Copyright (C) 1994, 1995 by Ralf Baechle + * Modified further for R[236]000 by Paul M. Antoine, 1996 */ #ifndef __ASM_MIPS_SYSTEM_H #define __ASM_MIPS_SYSTEM_H -#include <linux/linkage.h> #include <asm/sgidefs.h> +#include <linux/kernel.h> -/* - * sti/cli/save_flags use a memory clobber to make shure GCC doesn't - * move memory references around calls to these functions. - */ extern __inline__ void sti(void) { @@ -24,20 +21,22 @@ sti(void) ".set\tnoreorder\n\t" ".set\tnoat\n\t" "mfc0\t$1,$12\n\t" - "ori\t$1,1\n\t" + "ori\t$1,0x1f\n\t" + "xori\t$1,0x1e\n\t" "mtc0\t$1,$12\n\t" ".set\tat\n\t" ".set\treorder" : /* no outputs */ : /* no inputs */ - : "$1","memory"); + : "$1", "memory"); } /* - * For cli() we have to make shure that the new c0_status value has - * really arrived in the status register at the end of the inline - * function using worst case scheduling. The worst case is the R4000 - * which needs three nops. + * For cli() we have to insert nops to make shure 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 cli(void) @@ -56,7 +55,7 @@ cli(void) ".set\treorder" : /* no outputs */ : /* no inputs */ - : "$1","memory"); + : "$1", "memory"); } #define save_flags(x) \ @@ -83,8 +82,6 @@ restore_flags(int flags) : "memory"); } -#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) #define sync_mem() \ __asm__ __volatile__( \ ".set\tnoreorder\n\t" \ @@ -93,37 +90,24 @@ __asm__ __volatile__( \ : /* no output */ \ : /* no input */ \ : "memory") -#else -/* - * FIXME: Don't really know what to do here for the R[236]000's. - * Should probably bfc0 until write buffer is empty? - PMA - * Not shure if wb flushing is really required but sounds reasonable. - * The code below does this for R2000/R3000. - Ralf - */ -#define sync_mem() \ -__asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - "nop;nop;nop;nop;\n" \ - "1:\tbc0f\t1b\n\t" \ - "nop\n\t" \ - ".set\treorder" \ - : /* no output */ \ - : /* no input */ \ - : "memory") -#endif +#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. */ -struct task_struct; -asmlinkage void resume(struct task_struct *tsk, int offset); +extern asmlinkage void (*resume)(void *tsk); +#endif /* !defined (__LANGUAGE_ASSEMBLY__) */ /* * FIXME: resume() assumes current == prev */ -#define switch_to(prev,next) \ - resume(next, ((int)(&((struct task_struct *)0)->tss))); +#define switch_to(prev,next) \ +do { \ + prev->tss.current_ds = active_ds; \ + active_ds = next->tss.current_ds; \ + resume(next); \ +} while(0) /* * The 8 and 16 bit variants have to disable interrupts temporarily. diff --git a/include/asm-mips/termbits.h b/include/asm-mips/termbits.h index 336915bce..7c981e6f7 100644 --- a/include/asm-mips/termbits.h +++ b/include/asm-mips/termbits.h @@ -38,15 +38,10 @@ struct termios { #define VQUIT 1 /* Quit character [ISIG]. */ #define VERASE 2 /* Erase character [ICANON]. */ #define VKILL 3 /* Kill-line character [ICANON]. */ -#define VEOF 4 /* End-of-file character [ICANON]. */ -#define VMIN VEOF /* Minimum number of bytes read at once [!ICANON]. */ -#define VEOL 5 /* End-of-line character [ICANON]. */ -#define VTIME VEOL /* Time-out value (tenths of a second) [!ICANON]. */ -#if defined (__USE_BSD) || defined (__KERNEL__) +#define VMIN 4 /* Minimum number of bytes read at once [!ICANON]. */ +#define VTIME 5 /* Time-out value (tenths of a second) [!ICANON]. */ #define VEOL2 6 /* Second EOL character [ICANON]. */ -/* The next two are guesses ... */ #define VSWTC 7 /* ??? */ -#endif #define VSWTCH VSWTC #define VSTART 8 /* Start (X-ON) character [IXON, IXOFF]. */ #define VSTOP 9 /* Stop (X-OFF) character [IXON, IXOFF]. */ @@ -55,21 +50,14 @@ struct termios { /* * VDSUSP is not supported */ -#if defined (__USE_BSD) || defined (__KERNEL__) #define VDSUSP 11 /* Delayed suspend character [ISIG]. */ #endif -#endif -#if defined (__USE_BSD) || defined (__KERNEL__) #define VREPRINT 12 /* Reprint-line character [ICANON]. */ -#endif -#if defined (__USE_BSD) || defined (__KERNEL__) #define VDISCARD 13 /* Discard character [IEXTEN]. */ #define VWERASE 14 /* Word-erase character [ICANON]. */ #define VLNEXT 15 /* Literal-next character [IEXTEN]. */ -#endif -/* - * 17 - 19 are reserved - */ +#define VEOF 16 /* End-of-file character [ICANON]. */ +#define VEOL 17 /* End-of-line character [ICANON]. */ /* c_iflag bits */ #define IGNBRK 0000001 /* Ignore break condition. */ @@ -210,8 +198,8 @@ struct termios { #define TCIOFLUSH 2 /* Discard all pending data. */ /* tcsetattr uses these */ -#define TCSANOW 0x540e /* Same as TCSETS; change immediately. */ -#define TCSADRAIN 0x540f /* Same as TCSETSW; change when pending output is written. */ -#define TCSAFLUSH 0x5410 /* Same as TCSETSF; flush pending input before changing. */ +#define TCSANOW TCSETS /* Change immediately. */ +#define TCSADRAIN TCSETSW /* Change when pending output is written. */ +#define TCSAFLUSH TCSETSF /* Flush pending input before changing. */ #endif /* __ASM_MIPS_TERMBITS_H */ diff --git a/include/asm-mips/termios.h b/include/asm-mips/termios.h index 57fcbeef7..e62a60eab 100644 --- a/include/asm-mips/termios.h +++ b/include/asm-mips/termios.h @@ -61,11 +61,12 @@ struct termio { #ifdef __KERNEL__ /* * intr=^C quit=^\ erase=del kill=^U - * eof=^D eol=time=\0 eol2=\0 swtc=\0 + * vmin=\1 vtime=\0 eol2=\0 swtc=\0 * start=^Q stop=^S susp=^Z vdsusp= * reprint=^R discard=^U werase=^W lnext=^V + * eof=^D eol=\0 */ -#define INIT_C_CC "\003\034\177\025\004\0\0\0\021\023\032\0\022\017\027\026" +#define INIT_C_CC "\003\034\177\025\1\0\0\0\021\023\032\0\022\017\027\026\004\0" #endif /* modem lines */ diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h index 48a205077..d71cb3fca 100644 --- a/include/asm-mips/uaccess.h +++ b/include/asm-mips/uaccess.h @@ -30,8 +30,10 @@ #define VERIFY_READ 0 #define VERIFY_WRITE 1 -#define get_fs() (current->tss.segment) -#define set_fs(x) (current->tss.segment=(x)) +extern int active_ds; + +#define get_fs() active_ds +#define set_fs(x) (active_ds=(x)) static inline unsigned long get_ds(void) { diff --git a/include/asm-mips/unaligned.h b/include/asm-mips/unaligned.h index 95eb47f55..ff7803316 100644 --- a/include/asm-mips/unaligned.h +++ b/include/asm-mips/unaligned.h @@ -10,52 +10,12 @@ #ifndef __ASM_MIPS_UNALIGNED_H #define __ASM_MIPS_UNALIGNED_H -#if 0 -/* - * The following macros are the portable and efficient versions of - * get_unaligned()/put_unaligned(). They work but due to some lackings in the - * MIPS machine description of GCC generate only good code only for accessing - * word sized data. We only use get_unaligned() for accessing unaligned ints - * and then GCC makes full score anyway ... - */ -#define get_unaligned(ptr) \ - ({ \ - struct __unal { \ - __typeof__(*(ptr)) __x __attribute__((packed)); \ - }; \ - \ - ((struct __unal *)(ptr))->__x; \ - }) - -#define put_unaligned(ptr,val) \ - ({ \ - struct __unal { \ - __typeof__(*(ptr)) __x __attribute__((packed)); \ - }; \ - \ - ((struct __unal *)(ptr))->__x = (val); \ - }) -#else - -/* - * The main single-value unaligned transfer routines. - */ -#define get_unaligned(ptr) \ - ((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr)))) -#define put_unaligned(x,ptr) \ - __put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr))) - -/* - * This is a silly but good way to make sure that - * the get/put functions are indeed always optimized, - * and that we use the correct sizes. - */ -extern void bad_unaligned_access_length(void); +#include <asm/string.h> /* - * Load unaligned doubleword. + * Load quad unaligned. */ -extern __inline__ unsigned long __uld(const unsigned long long * __addr) +extern __inline__ unsigned long ldq_u(unsigned long long * __addr) { unsigned long long __res; @@ -67,9 +27,9 @@ extern __inline__ unsigned long __uld(const unsigned long long * __addr) } /* - * Load unaligned word. + * Load long unaligned. */ -extern __inline__ unsigned long __ulw(const unsigned int * __addr) +extern __inline__ unsigned long ldl_u(unsigned int * __addr) { unsigned long __res; @@ -81,9 +41,9 @@ extern __inline__ unsigned long __ulw(const unsigned int * __addr) } /* - * Load unaligned halfword. + * Load word unaligned. */ -extern __inline__ unsigned long __ulh(const unsigned short * __addr) +extern __inline__ unsigned long ldw_u(unsigned short * __addr) { unsigned long __res; @@ -95,9 +55,9 @@ extern __inline__ unsigned long __ulh(const unsigned short * __addr) } /* - * Store unaligned doubleword. + * Store quad ununaligned. */ -extern __inline__ void __usd(unsigned long __val, unsigned long long * __addr) +extern __inline__ void stq_u(unsigned long __val, unsigned long long * __addr) { __asm__ __volatile__( "usd\t%0,(%1)" @@ -107,9 +67,9 @@ extern __inline__ void __usd(unsigned long __val, unsigned long long * __addr) } /* - * Store unaligned word. + * Store long ununaligned. */ -extern __inline__ void __usw(unsigned long __val, unsigned int * __addr) +extern __inline__ void stl_u(unsigned long __val, unsigned int * __addr) { __asm__ __volatile__( "usw\t%0,(%1)" @@ -119,9 +79,9 @@ extern __inline__ void __usw(unsigned long __val, unsigned int * __addr) } /* - * Store unaligned halfword. + * Store word ununaligned. */ -extern __inline__ void __ush(unsigned long __val, unsigned short * __addr) +extern __inline__ void stw_u(unsigned long __val, unsigned short * __addr) { __asm__ __volatile__( "ush\t%0,(%1)" @@ -130,47 +90,12 @@ extern __inline__ void __ush(unsigned long __val, unsigned short * __addr) "r" (__addr)); } -extern inline unsigned long __get_unaligned(const void *ptr, size_t size) -{ - unsigned long val; - switch (size) { - case 1: - val = *(const unsigned char *)ptr; - break; - case 2: - val = __ulh((const unsigned short *)ptr); - break; - case 4: - val = __ulw((const unsigned int *)ptr); - break; - case 8: - val = __uld((const unsigned long long *)ptr); - break; - default: - bad_unaligned_access_length(); - } - return val; -} +#define get_unaligned(ptr) \ + ({ __typeof__(*(ptr)) __tmp; memcpy(&__tmp, (ptr), sizeof(*(ptr))); __tmp; }) -extern inline void __put_unaligned(unsigned long val, void *ptr, size_t size) -{ - switch (size) { - case 1: - *(unsigned char *)ptr = (val); - break; - case 2: - __ush(val, (unsigned short *)ptr); - break; - case 4: - __usw(val, (unsigned int *)ptr); - break; - case 8: - __usd(val, (unsigned long long *)ptr); - break; - default: - bad_unaligned_access_length(); - } -} -#endif +#define put_unaligned(val, ptr) \ + ({ __typeof__(*(ptr)) __tmp = (val); \ + memcpy((ptr), &__tmp, sizeof(*(ptr))); \ + (void)0; }) #endif /* __ASM_MIPS_UNALIGNED_H */ diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 8db0d3cee..c62dad56b 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -5,7 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 1996 by Ralf Baechle + * Copyright (C) 1995, 1996, 1997 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 @@ -15,9 +15,8 @@ /* * The syscalls 0 - 3999 are reserved for a down to the root syscall - * compatibility with RISC/os and IRIX. None of these syscalls has yet been - * implemented. We'll see how to deal with the various "real" BSD variants - * like Ultrix, NetBSD ... + * compatibility with RISC/os and IRIX. We'll see how to deal with the + * various "real" BSD variants like Ultrix, NetBSD ... */ /* diff --git a/include/asm-mips/user.h b/include/asm-mips/user.h index 64069dd60..e3747e88c 100644 --- a/include/asm-mips/user.h +++ b/include/asm-mips/user.h @@ -9,8 +9,8 @@ /* * Core file format: The core file is written in such a way that gdb * can understand it and provide useful information to the user (under - * linux we use the `trad-core' bfd, NOT the osf-core). The file contents - * are as follows: + * linux we use the `trad-core' bfd, NOT the irix-core). The file + * contents are as follows: * * upage: 1 page consisting of a user struct that tells gdb * what is present in the file. Directly after this is a @@ -30,7 +30,7 @@ * to write an integer number of pages. */ struct user { - unsigned long regs[EF_SIZE/8+32]; /* integer and fp regs */ + unsigned long regs[EF_SIZE/4+64]; /* integer and fp regs */ size_t u_tsize; /* text size (pages) */ size_t u_dsize; /* data size (pages) */ size_t u_ssize; /* stack size (pages) */ diff --git a/include/asm-mips/vector.h b/include/asm-mips/vector.h index 23c5b8385..e3183b1de 100644 --- a/include/asm-mips/vector.h +++ b/include/asm-mips/vector.h @@ -5,7 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 1996 by Ralf Baechle + * Copyright (C) 1995, 1996, 1997 by Ralf Baechle */ #ifndef __ASM_MIPS_VECTOR_H #define __ASM_MIPS_VECTOR_H |