diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1995-11-14 08:00:00 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1995-11-14 08:00:00 +0000 |
commit | e7c2a72e2680827d6a733931273a93461c0d8d1b (patch) | |
tree | c9abeda78ef7504062bb2e816bcf3e3c9d680112 /include/asm-mips | |
parent | ec6044459060a8c9ce7f64405c465d141898548c (diff) |
Import of Linux/MIPS 1.3.0
Diffstat (limited to 'include/asm-mips')
41 files changed, 3841 insertions, 1265 deletions
diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h new file mode 100644 index 000000000..12c9785d8 --- /dev/null +++ b/include/asm-mips/asm.h @@ -0,0 +1,241 @@ +/* + * include/asm-mips/asm.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 by Ralf Baechle + * + * Some usefull macros for MIPS assembler code + * + * Some of the routines below contain useless nops that will be optimized + * away by gas in -O mode. These nops are however required to fill delay + * slots in noreorder mode. + */ +#ifndef __ASM_ASM_H +#define __ASM_ASM_H + +#include <linux/autoconf.h> +#include <asm/regdef.h> + +#ifndef CAT +#ifdef __STDC__ +#define __CAT(str1,str2) str1##str2 +#else +#define __CAT(str1,str2) str1/**/str2 +#endif +#define CAT(str1,str2) __CAT(str1,str2) +#endif + +/* + * Macros to handle different pointer sizes for 32/64-bit code + */ +#if __mips == 3 +#define PTR .quad +#define PTRSIZE 8 +#define PTRLOG 3 +#define lp ld +#else +#define PTR .word +#define PTRSIZE 4 +#define PTRLOG 2 +#define lp lw +#endif + +/* + * ELF specific declarations + */ +#ifdef __ELF__ +#define TYPE(symbol,_type) \ + .type symbol,@_type +#define SIZE(symbol,_size) \ + .size symbol,_size +#else +#define TYPE(symbol,type) +#define SIZE(symbol,size) +#endif + +/* + * PIC specific declarations + * Not used for the kernel but here seems to be the right place. + */ +#ifdef __PIC__ +#define CPRESTORE(register) \ + .cprestore register +#define CPADD(register) \ + .cpadd register +#define CPLOAD(register) \ + .cpload register +#else +#define CPRESTORE(register) +#define CPADD(register) +#define CPLOAD(register) +#endif + +/* + * LEAF - declare leaf routine + */ +#define LEAF(symbol) \ + .globl symbol; \ + .align 2; \ + TYPE(symbol,function); \ + .ent symbol,0; \ +symbol: .frame sp,0,ra + +/* + * NESTED - declare nested routine entry point + */ +#define NESTED(symbol, framesize, rpc) \ + .globl symbol; \ + .align 2; \ + TYPE(symbol,function); \ + .ent symbol,0; \ +symbol: .frame sp, framesize, rpc + +/* + * END - mark end of function + */ +#define END(function) \ + .end function; \ + SIZE(function,.-function) + +/* + * EXPORT - export definition of symbol + */ +#define EXPORT(symbol) \ + .globl symbol; \ +symbol: + +/* + * ABS - export absolute symbol + */ +#define ABS(symbol,value) \ + .globl symbol; \ +symbol = value + +#define PANIC(msg) \ + la a0,8f; \ + jal panic; \ + nop; \ +9: b 9b; \ + nop; \ + TEXT(msg) + +/* + * Print formated string + */ +#define PRINT(string) \ + la a0,8f; \ + jal printk; \ + nop; \ + TEXT(string) + +#define TEXT(msg) \ + .data; \ +8: .asciiz msg; \ + .text + +/* + * Build text tables + */ +#define TTABLE(string) \ + .text; \ + .word 1f; \ + .data; \ +1: .asciz string; \ + .text; + +/* + * Move to kernel mode and disable interrupts + * Set cp0 enable bit as sign that we're running on the kernel stack + * Use with .set noat! + */ +#define CLI \ + mfc0 AT,CP0_STATUS; \ + li t0,ST0_CU0|0x1f; \ + or AT,t0; \ + xori AT,0x1f; \ + mtc0 AT,CP0_STATUS; \ + +/* + * Move to kernel mode and enable interrupts + * Set cp0 enable bit as sign that we're running on the kernel stack + * Use with .set noat! + */ +#define STI \ + mfc0 AT,CP0_STATUS; \ + li t0,ST0_CU0|0x1f; \ + or AT,t0; \ + xori AT,0x1e; \ + mtc0 AT,CP0_STATUS; \ + +/* + * Special nop to fill load delay slots + */ +#ifndef __R4000__ +#define NOP nop +#else +#define NOP +#endif + +/* + * Return from exception + */ +#if defined (CONFIG_CPU_R3000) +#define ERET rfe +#elif defined (CONFIG_CPU_R4X00) || defined (CONFIG_CPU_R4600) +#define ERET \ + .set mips3; \ + eret; \ + .set mips0 +#else +#error "Implement ERET macro!" +#endif + +/* + * R8000/R10000 (MIPS ISA IV) pref instruction. + * Use with .set noreorder only! + */ +#if defined (CONFIG_CPU_R8000) || defined(CONFIG_CPU_R10000) +#define PREF(hint,addr) \ + pref hint,addr +#define PREFX(hint,addr) \ + prefx hint,addr +#else +#define PREF +#define PREFX +#endif + +/* + * R8000/R10000 (MIPS ISA IV) movn/movz instructions and + * equivalents for old CPUs. Use with .set noreorder only! + */ +#if defined (CONFIG_CPU_R8000) || defined (CONFIG_CPU_R10000) +#define MOVN(rd,rs,rt) \ + movn rd,rs,rt +#define MOVZ(rd,rs,rt) \ + movz rd,rs,rt +#elif defined (CONFIG_CPU_R4000) || defined (CONFIG_CPU_R6000) +#define MOVN(rd,rs,rt) \ + bnezl rt,9f \ + move rd,rs \ +9: +#define MOVZ(rd,rs,rt) \ + beqzl rt,9f \ + movz rd,rt \ +9: +#else /* R2000, R3000 */ +#define MOVN(rd,rs,rt) \ + beqz rt,9f \ + nop \ + move rd,rs \ +9: +#define MOVZ(rd,rs,rt) \ + bneqz rt,9f \ + nop \ + movz rd,rt \ +9: +#endif + +#endif /* __ASM_ASM_H */ diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index a2fd7972b..255ec9ee2 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h @@ -5,18 +5,23 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 1994 by Ralf Baechle + * Copyright (c) 1994, 1995 Ralf Baechle */ -#ifndef _ASM_MIPS_BITOPS_H -#define _ASM_MIPS_BITOPS_H +#ifndef __ASM_MIPS_BITOPS_H +#define __ASM_MIPS_BITOPS_H + +#ifdef __R4000__ #include <asm/mipsregs.h> -extern inline int set_bit(int nr, void *addr) +/* + * The following functions will only work for the R4000! + */ +extern __inline__ int set_bit(int nr, void *addr) { int mask, retval, mw; - addr += nr >> 5; + addr += ((nr >> 3) & ~3); mask = 1 << (nr & 0x1f); do { mw = load_linked(addr); @@ -27,11 +32,11 @@ extern inline int set_bit(int nr, void *addr) return retval; } -extern inline int clear_bit(int nr, void *addr) +extern __inline__ int clear_bit(int nr, void *addr) { int mask, retval, mw; - addr += nr >> 5; + addr += ((nr >> 3) & ~3); mask = 1 << (nr & 0x1f); do { mw = load_linked(addr); @@ -42,11 +47,11 @@ extern inline int clear_bit(int nr, void *addr) return retval; } -extern inline int change_bit(int nr, void *addr) +extern __inline__ int change_bit(int nr, void *addr) { int mask, retval, mw; - addr += nr >> 5; + addr += ((nr >> 3) & ~3); mask = 1 << (nr & 0x1f); do { mw = load_linked(addr); @@ -57,10 +62,83 @@ extern inline int change_bit(int nr, void *addr) return retval; } -extern inline int test_bit(int nr, void *addr) +#else /* !defined(__R4000__) */ + +#include <asm/system.h> + +#ifdef __KERNEL__ +/* + * Only disable interrupt for kernelmode stuff to keep some + * usermode stuff alive + */ +#define __flags unsigned long flags +#define __cli() cli() +#define __save_flags(x) save_flags(x) +#define __restore_flags(x) restore_flags(x) +#endif /* __KERNEL__ */ + +extern __inline__ int set_bit(int nr, void * addr) +{ + int mask, retval; + int *a = addr; + __flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + __save_flags(flags); + __cli(); + retval = (mask & *a) != 0; + *a |= mask; + __restore_flags(flags); + + return retval; +} + +extern __inline__ int clear_bit(int nr, void * addr) +{ + int mask, retval; + int *a = addr; + __flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + __save_flags(flags); + __cli(); + retval = (mask & *a) != 0; + *a &= ~mask; + __restore_flags(flags); + + return retval; +} + +extern __inline__ int change_bit(int nr, void * addr) +{ + int mask, retval; + int *a = addr; + __flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + __save_flags(flags); + __cli(); + retval = (mask & *a) != 0; + *a ^= mask; + __restore_flags(flags); + + return retval; +} + +#undef __flags +#undef __cli() +#undef __save_flags(x) +#undef __restore_flags(x) + +#endif /* !defined(__R4000__) */ + +extern __inline__ int test_bit(int nr, void *addr) { int mask; - int *a; + unsigned long *a; a = addr; addr += nr >> 5; @@ -68,11 +146,7 @@ extern inline int test_bit(int nr, void *addr) return ((mask & *a) != 0); } - -/* - * The above written is not true for the bitfield functions. - */ -static inline int find_first_zero_bit (void *addr, unsigned size) +extern __inline__ int find_first_zero_bit (void *addr, unsigned size) { int res; @@ -96,17 +170,17 @@ static inline int find_first_zero_bit (void *addr, unsigned size) ".set\tat\n\t" ".set\treorder\n" "2:" - : "=d" (res) - : "d" ((unsigned int) 0xffffffff), - "d" (size), + : "=r" (res) + : "r" ((unsigned int) 0xffffffff), + "r" (size), "0" ((signed int) 0), - "d" (addr) + "r" (addr) : "$1"); return res; } -static inline int find_next_zero_bit (void * addr, int size, int offset) +extern __inline__ int find_next_zero_bit (void * addr, int size, int offset) { unsigned long * p = ((unsigned long *) addr) + (offset >> 5); int set = 0, bit = offset & 31, res; @@ -127,7 +201,8 @@ static inline int find_next_zero_bit (void * addr, int size, int offset) : "=r" (set) : "r" (*p >> bit), "r" (1), - "0" (0)); + "0" (0) + : "$1"); if (set < (32 - bit)) return set + offset; set = 32 - bit; @@ -144,7 +219,7 @@ static inline int find_next_zero_bit (void * addr, int size, int offset) * ffz = Find First Zero in word. Undefined if no zero exists, * so code should check against ~0UL first.. */ -extern inline unsigned long ffz(unsigned long word) +extern __inline__ unsigned long ffz(unsigned long word) { unsigned int __res; unsigned int mask = 1; @@ -154,10 +229,10 @@ extern inline unsigned long ffz(unsigned long word) ".set\tnoat\n\t" "li\t%2,1\n" "1:\tand\t$1,%2,%1\n\t" - "beq\t$0,$1,2f\n\t" - "sll\t%2,%2,1\n\t" - "bne\t$0,%2,1b\n\t" - "add\t%0,%0,1\n\t" + "beqz\t$1,2f\n\t" + "sll\t%2,1\n\t" + "bnez\t%2,1b\n\t" + "addiu\t%0,1\n\t" ".set\tat\n\t" ".set\treorder\n" "2:\n\t" @@ -170,4 +245,4 @@ extern inline unsigned long ffz(unsigned long word) return __res; } -#endif /* _ASM_MIPS_BITOPS_H */ +#endif /* __ASM_MIPS_BITOPS_H */ diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 4ff415bf1..594b45b5d 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -1,8 +1,8 @@ /* - * bootinfo.h -- Definition of the Linux/68K boot information structure + * bootinfo.h -- Definition of the Linux/MIPS boot information structure * - * Written by Ralf Baechle, - * Copyright (C) 1994 by Waldorf GMBH + * Copyright (C) 1994 by Waldorf Electronics + * Written by Ralf Baechle and Andreas Busse * * Based on Linux/68k linux/include/linux/bootstrap.h * Copyright (C) 1992 by Greg Harp @@ -11,53 +11,238 @@ * License. See the file README.legal in the main directory of this archive * for more details. */ - -#ifndef ASM_MIPS_BOOTINFO_H -#define ASM_MIPS_BOOTINFO_H +#ifndef __ASM_MIPS_BOOTINFO_H +#define __ASM_MIPS_BOOTINFO_H /* - * Valid values for machtype field + * Valid machtype values */ -#define MACH_DESKSTATION_TYNE 1 /* Deskstation Tyne */ +#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 5 /* Olivetti M700 */ /* - * Type of CPU + * Valid cputype values */ -#define CPU_R4600 1 +#define CPU_UNKNOWN 0 +#define CPU_R2000 1 +#define CPU_R3000 2 +#define CPU_R3000A 3 +#define CPU_R3041 4 +#define CPU_R3051 5 +#define CPU_R3052 6 +#define CPU_R3081 7 +#define CPU_R3081E 8 +#define CPU_R4000PC 9 +#define CPU_R4000SC 10 +#define CPU_R4000MC 11 +#define CPU_R4200 12 +#define CPU_R4400PC 13 +#define CPU_R4400SC 14 +#define CPU_R4400MC 15 +#define CPU_R4600 16 +#define CPU_R6000 17 +#define CPU_R6000A 18 +#define CPU_R8000 19 +#define CPU_R10000 20 +#define CPU_LAST 20 + +#define CPU_NAMES { "UNKNOWN", "R2000", "R3000", "R3000A", "R3041", "R3051", \ + "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC", \ + "R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000", \ + "R6000A", "R8000", "R10000" } #define CL_SIZE (80) +#ifndef __LANGUAGE_ASSEMBLY__ + +/* + * Some machine parameters passed by MILO. Note that bootinfo + * *must* be in the data segment since the kernel clears the + * bss segment directly after startup. + */ + +struct drive_info_struct { + char dummy[32]; + }; + struct bootinfo { - unsigned long - machtype; /* machine type */ + /* + * machine type + */ + unsigned long machtype; + + /* + * system CPU & FPU + */ + unsigned long cputype; + + /* + * Installed RAM + */ + unsigned long memlower; + unsigned long memupper; + + /* + * Cache Sizes (0xffffffff = unknown) + */ + unsigned long icache_size; + unsigned long icache_linesize; + unsigned long dcache_size; + unsigned long dcache_linesize; + unsigned long scache_size; + unsigned long scache_linesize; + + /* + * TLB Info + */ + unsigned long tlb_entries; + + /* + * DMA buffer size (Deskstation only) + */ + unsigned long dma_cache_size; + unsigned long dma_cache_base; + + /* + * Ramdisk Info + */ + unsigned long ramdisk_size; /* ramdisk size in 1024 byte blocks */ + unsigned long ramdisk_base; /* address of the ram disk in mem */ + + /* + * Boot flags for the kernel + */ + unsigned long mount_root_rdonly; + struct drive_info_struct drive_info; + + /* + * Video ram info (not in tty.h) + */ + unsigned long vram_base; /* video ram base address */ + + char command_line[CL_SIZE]; /* kernel command line parameters */ + +}; - unsigned long - cputype; /* system CPU & FPU */ +#if 0 +/* + * New style bootinfo + * + * Add new tags only at the end of the enum; *never* remove any tags + * or you'll break compatibility! + */ +enum bi_tag { + /* + * not a real tag + */ + dummy, + + /* + * machine type + */ + machtype, - /* - * Installed RAM - */ - unsigned int memlower; - unsigned int memupper; + /* + * system CPU & FPU + */ + cputype, - /* - * Cache Information - */ - unsigned int sec_cache; - unsigned int dma_cache; + /* + * Installed RAM + */ + memlower, + memupper, - unsigned long - ramdisk_size; /* ramdisk size in 1024 byte blocks */ + /* + * Cache Sizes (0xffffffff = unknown) + */ + icache_size, + icache_linesize, + dcache_size, + dcache_linesize, + scache_size, + scache_linesize, - unsigned long - ramdisk_addr; /* address of the ram disk in mem */ + /* + * TLB Info + */ + tlb_entries, - char - command_line[CL_SIZE]; /* kernel command line parameters */ + /* + * DMA buffer size (Deskstation only) + */ + dma_cache_size, + dma_cache_base, + /* + * Ramdisk Info + */ + ramdisk_size, /* ramdisk size in 1024 byte blocks */ + ramdisk_base, /* address of the ram disk in mem */ + + /* + * Boot flags for the kernel + */ + mount_root_rdonly, + drive_info, + + /* + * Video ram info (not in tty.h) + */ + vram_base, /* video ram base address */ + + command_line /* kernel command line parameters */ + }; -extern struct bootinfo - boot_info; +typedef struct { + bi_tag tag; + unsigned long size; +} tag; +#endif + +extern struct bootinfo boot_info; + +/* + * Defaults, may be overwritten by milo. We initialize + * them to make sure that both boot_info and screen_info + * are in the .data segment since the .bss segment is + * cleared during startup. + */ +#define BOOT_INFO { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, {{0,}}, 0, "" } +#define SCREEN_INFO {0, 0, {0, }, 52, 3, 80, 4626, 3, 9, 50} + +#else /* !__LANGUAGE_ASSEMBLY__ */ + +/* + * Same structure, but as offsets for usage within assembler source. + * Don't mess with struct bootinfo without changing offsets too! + */ + +#define OFFSET_BOOTINFO_MACHTYPE 0 +#define OFFSET_BOOTINFO_CPUTYPE 4 +#define OFFSET_BOOTINFO_MEMLOWER 8 +#define OFFSET_BOOTINFO_MEMUPPER 12 +#define OFFSET_BOOTINFO_ICACHE_SIZE 16 +#define OFFSET_BOOTINFO_ICACHE_LINESIZE 20 +#define OFFSET_BOOTINFO_DCACHE_SIZE 24 +#define OFFSET_BOOTINFO_DCACHE_LINESIZE 28 +#define OFFSET_BOOTINFO_SCACHE_SIZE 32 +#define OFFSET_BOOTINFO_SCACHE_LINESIZE 36 +#define OFFSET_BOOTINFO_TLB_ENTRIES 40 +#define OFFSET_BOOTINFO_DMA_CACHE_SIZE 44 +#define OFFSET_BOOTINFO_DMA_CACHE_BASE 48 +#define OFFSET_BOOTINFO_RAMDISK_SIZE 52 +#define OFFSET_BOOTINFO_RAMDISK_BASE 56 +#define OFFSET_BOOTINFO_MOUNT_RD_ONLY 60 +#define OFFSET_BOOTINFO_DRIVE_INFO 64 +#define OFFSET_BOOTINFO_VRAM_BASE 96 +#define OFFSET_BOOTINFO_COMMAND_LINE 100 + +#endif /* __LANGUAGE_ASSEMBLY__ */ -#endif /* ASM_MIPS_BOOTINFO_H */ +#endif /* __ASM_MIPS_BOOTINFO_H */ diff --git a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h new file mode 100644 index 000000000..41ca73366 --- /dev/null +++ b/include/asm-mips/bugs.h @@ -0,0 +1,36 @@ +/* + * include/asm-mips/bugs.h + * + * Copyright (C) 1995 Waldorf Electronics + * written by Ralf Baechle + */ +#include <asm/bootinfo.h> + +/* + * This is included by init/main.c to check for architecture-dependent bugs. + * + * Needs: + * void check_bugs(void); + */ + +extern struct bootinfo boot_info; + +static void check_wait(void) +{ + printk("Checking for 'wait' instruction... "); + switch(boot_info.cputype) { + case CPU_R4200: + case CPU_R4600: + wait_available = 1; + printk(" available.\n"); + break; + default: + printk(" unavailable.\n"); + break; + } +} + +static void check_bugs(void) +{ + check_wait(); +} diff --git a/include/asm-mips/byteorder.h b/include/asm-mips/byteorder.h new file mode 100644 index 000000000..45abf2350 --- /dev/null +++ b/include/asm-mips/byteorder.h @@ -0,0 +1,94 @@ +#ifndef __ASM_MIPS_BYTEORDER_H +#define __ASM_MIPS_BYTEORDER_H + +/* + * FIXME: Add big endian support + */ +#undef ntohl +#undef ntohs +#undef htonl +#undef htons + +#ifdef __MIPSEL__ +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif + +#ifndef LITTLE_ENDIAN_BITFIELD +#define LITTLE_ENDIAN_BITFIELD +#endif +#elif __MIPSEB__ +#define BIG_ENDIAN 4321 +#define BIG_ENDIAN_BITFIELD +#else +#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?" +#endif + +extern unsigned long int ntohl(unsigned long int); +extern unsigned short int ntohs(unsigned short int); +extern unsigned long int htonl(unsigned long int); +extern unsigned short int htons(unsigned short int); + +extern unsigned long int __ntohl(unsigned long int); +extern unsigned short int __ntohs(unsigned short int); +extern unsigned long int __constant_ntohl(unsigned long int); +extern unsigned short int __constant_ntohs(unsigned short int); + +/* + * The constant and non-constant versions here are the same. + * Maybe I'll come up with an mips-optimized routine for the + * non-constant ones (the constant ones don't need it: gcc + * will optimize it to the correct constant) + */ + +extern __inline__ unsigned long int +__ntohl(unsigned long int x) +{ + return (((x & 0x000000ffU) << 24) | + ((x & 0x0000ff00U) << 8) | + ((x & 0x00ff0000U) >> 8) | + ((x & 0xff000000U) >> 24)); +} + +#define __constant_ntohl(x) \ + ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \ + (((unsigned long int)(x) & 0x0000ff00U) << 8) | \ + (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \ + (((unsigned long int)(x) & 0xff000000U) >> 24))) + +extern __inline__ unsigned short int +__ntohs(unsigned short int x) +{ + return (((x & 0x00ff) << 8) | + ((x & 0xff00) >> 8)); +} + +#define __constant_ntohs(x) \ + ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \ + (((unsigned short int)(x) & 0xff00) >> 8))) \ + +#define __htonl(x) __ntohl(x) +#define __htons(x) __ntohs(x) +#define __constant_htonl(x) __constant_ntohl(x) +#define __constant_htons(x) __constant_ntohs(x) + +#ifdef __OPTIMIZE__ +# define ntohl(x) \ +(__builtin_constant_p((long)(x)) ? \ + __constant_ntohl((x)) : \ + __ntohl((x))) +# define ntohs(x) \ +(__builtin_constant_p((short)(x)) ? \ + __constant_ntohs((x)) : \ + __ntohs((x))) +# define htonl(x) \ +(__builtin_constant_p((long)(x)) ? \ + __constant_htonl((x)) : \ + __htonl((x))) +# define htons(x) \ +(__builtin_constant_p((short)(x)) ? \ + __constant_htons((x)) : \ + __htons((x))) +#endif + +#endif /* __ASM_MIPS_BYTEORDER_H */ diff --git a/include/asm-mips/cachectl.h b/include/asm-mips/cachectl.h index 167727c97..68105fb69 100644 --- a/include/asm-mips/cachectl.h +++ b/include/asm-mips/cachectl.h @@ -3,11 +3,9 @@ * * Written by Ralf Baechle, * Copyright (C) 1994 by Waldorf GMBH - * - * Defines for Risc/OS compatible cacheflush systemcall */ -#ifndef _ASM_MIPS_CACHECTL -#define _ASM_MIPS_CACHECTL +#ifndef __ASM_MIPS_CACHECTL +#define __ASM_MIPS_CACHECTL /* * cachectl.h -- defines for MIPS cache control system calls @@ -20,13 +18,20 @@ #define DCACHE (1<<1) /* writeback and flush data cache */ #define BCACHE (ICACHE|DCACHE) /* flush both caches */ -#define CACHELINES 512 /* number of cachelines */ +#define CACHELINES 512 /* number of cachelines (kludgy) */ + +/* + * Cache Operations - for use by assembler code + */ +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 +#define Index_Load_Tag_D 0x05 #ifdef __KERNEL__ -#ifndef __ASSEMBLY__ +#ifndef __LANGUAGE_ASSEMBLY__ extern int sys_cacheflush(void *addr, int nbytes, int cache); #endif #endif -#endif /* _ASM_MIPS_CACHECTL */ +#endif /* __ASM_MIPS_CACHECTL */ diff --git a/include/asm-mips/delay.h b/include/asm-mips/delay.h index 5aa85e165..b35498dc1 100644 --- a/include/asm-mips/delay.h +++ b/include/asm-mips/delay.h @@ -1,5 +1,5 @@ -#ifndef _ASM_MIPS_DELAY_H -#define _ASM_MIPS_DELAY_H +#ifndef __ASM_MIPS_DELAY_H +#define __ASM_MIPS_DELAY_H extern __inline__ void __delay(int loops) { @@ -27,10 +27,20 @@ extern __inline__ void __delay(int loops) extern __inline__ void udelay(unsigned long usecs) { usecs *= 0x000010c6; /* 2**32 / 1000000 */ - __asm__("mul\t%0,%0,%1" + __asm__("multu\t%0,%1\n\t" + "mfhi\t%0" :"=r" (usecs) :"0" (usecs),"r" (loops_per_sec)); __delay(usecs); } -#endif /* defined (_ASM_MIPS_DELAY_H) */ +/* + * The different variants for 32/64 bit are pure paranoia. The typical + * range of numbers that apprears for MIPS machines avoids overflows. + */ +extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c) +{ + return (a*b)/c; +} + +#endif /* __ASM_MIPS_DELAY_H */ diff --git a/include/asm-mips/dma.h b/include/asm-mips/dma.h index 7540aedec..14f1f0dae 100644 --- a/include/asm-mips/dma.h +++ b/include/asm-mips/dma.h @@ -3,10 +3,14 @@ * Written by Hennus Bergman, 1992. * High DMA channel support & info by Hannu Savolainen * and John Boyd, Nov. 1992. + * + * NOTE: all this is true *only* for ISA/EISA expansions on Mips boards + * and can only be used for expansion cards. Onboard DMA controller, such + * as the R4030 on Jazz boards behave totally different! */ -#ifndef _ASM_MIPS_DMA_H -#define _ASM_MIPS_DMA_H +#ifndef __ASM_MIPS_DMA_H +#define __ASM_MIPS_DMA_H #include <asm/io.h> /* need byte IO */ @@ -70,7 +74,10 @@ #define MAX_DMA_CHANNELS 8 /* The maximum address that we can perform a DMA transfer to on this platform */ -#define MAX_DMA_ADDRESS 0xffffff +#define MAX_DMA_ADDRESS 0x1000000 + +/* The maximum address that we can perform a DMA transfer to on this platform */ +#define MAX_DMA_ADDRESS 0x1000000 /* 8237 DMA controllers */ #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ @@ -264,8 +271,8 @@ static __inline__ int get_dma_residue(unsigned int dmanr) /* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, char * deviceID); /* reserve a DMA channel */ +extern int request_dma(unsigned int dmanr, char * device_id); /* reserve a DMA channel */ extern void free_dma(unsigned int dmanr); /* release it again */ -#endif /* _ASM_MIPS_DMA_H */ +#endif /* __ASM_MIPS_DMA_H */ diff --git a/include/asm-mips/errno.h b/include/asm-mips/errno.h new file mode 100644 index 000000000..f31e2b19f --- /dev/null +++ b/include/asm-mips/errno.h @@ -0,0 +1,143 @@ +/* + * include/asm-mips/errno.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 by Ralf Baechle + */ +#ifndef __ASM_MIPS_ERRNO_H +#define __ASM_MIPS_ERRNO_H + +/* + * These error numbers are intended to be MIPS ABI compatible + */ +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define ENOMSG 35 /* No message of desired type */ +#define EIDRM 36 /* Identifier removed */ +#define ECHRNG 37 /* Channel number out of range */ +#define EL2NSYNC 38 /* Level 2 not synchronized */ +#define EL3HLT 39 /* Level 3 halted */ +#define EL3RST 40 /* Level 3 reset */ +#define ELNRNG 41 /* Link number out of range */ +#define EUNATCH 42 /* Protocol driver not attached */ +#define ENOCSI 43 /* No CSI structure available */ +#define EL2HLT 44 /* Level 2 halted */ +#define EDEADLK 45 /* Resource deadlock would occur */ +#define ENOLCK 46 /* No record locks available */ +#define EBADE 50 /* Invalid exchange */ +#define EBADR 51 /* Invalid request descriptor */ +#define EXFULL 52 /* Exchange full */ +#define ENOANO 53 /* No anode */ +#define EBADRQC 54 /* Invalid request code */ +#define EBADSLT 55 /* Invalid slot */ +#define EDEADLOCK 56 /* File locking deadlock error */ +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EDOTDOT 73 /* RFS specific error */ +#define EMULTIHOP 74 /* Multihop attempted */ +#define EBADMSG 77 /* Not a data message */ +#define ENAMETOOLONG 78 /* File name too long */ +#define EOVERFLOW 79 /* Value too large for defined data type */ +#define ENOTUNIQ 80 /* Name not unique on network */ +#define EBADFD 81 /* File descriptor in bad state */ +#define EREMCHG 82 /* Remote address changed */ +#define ELIBACC 83 /* Can not access a needed shared library */ +#define ELIBBAD 84 /* Accessing a corrupted shared library */ +#define ELIBSCN 85 /* .lib section in a.out corrupted */ +#define ELIBMAX 86 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 87 /* Cannot exec a shared library directly */ +#define EILSEQ 88 /* Illegal byte sequence */ +#define ENOSYS 89 /* Function not implemented */ +#define ELOOP 90 /* Too many symbolic links encountered */ +#define ERESTART 91 /* Interrupted system call should be restarted */ +#define ESTRPIPE 92 /* Streams pipe error */ +#define ENOTEMPTY 93 /* Directory not empty */ +#define EUSERS 94 /* Too many users */ +#define ENOTSOCK 95 /* Socket operation on non-socket */ +#define EDESTADDRREQ 96 /* Destination address required */ +#define EMSGSIZE 97 /* Message too long */ +#define EPROTOTYPE 98 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 99 /* Protocol not available */ +#define EPROTONOSUPPORT 120 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 121 /* Socket type not supported */ +#define EOPNOTSUPP 122 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 123 /* Protocol family not supported */ +#define EAFNOSUPPORT 124 /* Address family not supported by protocol */ +#define EADDRINUSE 125 /* Address already in use */ +#define EADDRNOTAVAIL 126 /* Cannot assign requested address */ +#define ENETDOWN 127 /* Network is down */ +#define ENETUNREACH 128 /* Network is unreachable */ +#define ENETRESET 129 /* Network dropped connection because of reset */ +#define ECONNABORTED 130 /* Software caused connection abort */ +#define ECONNRESET 131 /* Connection reset by peer */ +#define ENOBUFS 132 /* No buffer space available */ +#define EISCONN 133 /* Transport endpoint is already connected */ +#define ENOTCONN 134 /* Transport endpoint is not connected */ +#define EUCLEAN 135 /* Structure needs cleaning */ +#define ENOTNAM 137 /* Not a XENIX named type file */ +#define ENAVAIL 138 /* No XENIX semaphores available */ +#define EISNAM 139 /* Is a named type file */ +#define EREMOTEIO 140 /* Remote I/O error */ +#define EINIT 141 /* Reserved */ +#define EREMDEV 142 /* Error 142 */ +#define ESHUTDOWN 143 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 144 /* Too many references: cannot splice */ +#define ETIMEDOUT 145 /* Connection timed out */ +#define ECONNREFUSED 146 /* Connection refused */ +#define EHOSTDOWN 147 /* Host is down */ +#define EHOSTUNREACH 148 /* No route to host */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define EALREADY 149 /* Operation already in progress */ +#define EINPROGRESS 150 /* Operation now in progress */ +#define ESTALE 151 /* Stale NFS file handle */ +#define ECANCELED 158 /* AIO operation canceled */ +#define EDQUOT 1133 /* Quota exceeded */ +#define ENFSREMOTE 1134 /* ??? */ + +#endif /* __ASM_MIPS_ERRNO_H */ diff --git a/include/asm-mips/fcntl.h b/include/asm-mips/fcntl.h new file mode 100644 index 000000000..2a41e3da9 --- /dev/null +++ b/include/asm-mips/fcntl.h @@ -0,0 +1,67 @@ +#ifndef _I386_FCNTL_H +#define _I386_FCNTL_H + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_ACCMODE 0x0003 +#define O_RDONLY 0x0000 +#define O_WRONLY 0x0001 +#define O_RDWR 0x0002 +#define O_APPEND 0x0008 +#define O_SYNC 0x0010 +#define O_NONBLOCK 0x0080 +#define O_CREAT 0x0100 /* not fcntl */ +#define O_TRUNC 0x0200 /* not fcntl */ +#define O_EXCL 0x0400 /* not fcntl */ +#define O_NOCTTY 0x0800 /* not fcntl */ +#define FASYNC 0x1000 /* fcntl, for BSD compatibility */ + +#define O_NDELAY O_NONBLOCK + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get f_flags */ +#define F_SETFD 2 /* set f_flags */ +#define F_GETFL 3 /* more flags (cloexec) */ +#define F_SETFL 4 +#define F_GETLK 14 +#define F_SETLK 6 +#define F_SETLKW 7 + +#define F_SETOWN 24 /* for sockets. */ +#define F_GETOWN 23 /* for sockets. */ + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 + +/* for old implementation of bsd flock () */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent XXXXXXXXXXXXXXXXXX + blocking */ +#define LOCK_UN 8 /* remove lock */ + +#ifdef __KERNEL__ +#define F_POSIX 1 +#define F_FLOCK 2 +#endif /* __KERNEL__ */ + +typedef struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + long l_sysid; /* XXXXXXXXXXXXXXXXXXXXXXXXX */ + pid_t l_pid; + long pad[4]; /* ZZZZZZZZZZZZZZZZZZZZZZZZZZ */ +} flock_t; + +#endif diff --git a/include/asm-mips/gdb-stub.h b/include/asm-mips/gdb-stub.h new file mode 100644 index 000000000..d85ce077f --- /dev/null +++ b/include/asm-mips/gdb-stub.h @@ -0,0 +1,211 @@ +/* + * include/asm-mips/gdb-stub.h + * + * Copyright (C) 1995 Andreas Busse + */ + +#ifndef __ASM_MIPS_GDB_STUB_H +#define __ASM_MIPS_GDB_STUB_H + + +/* + * important register numbers + */ + +#define REG_EPC 37 +#define REG_FP 72 +#define REG_SP 29 + +/* + * Stack layout for the GDB exception handler + * Derived from the stack layout described in asm-mips/stackframe.h + * + * The first PTRSIZE*5 bytes are argument save space for C subroutines. + */ +#define NUMREGS 90 + +#define GDB_FR_REG0 (PTRSIZE*5) /* 0 */ +#define GDB_FR_REG1 ((GDB_FR_REG0) + 4) /* 1 */ +#define GDB_FR_REG2 ((GDB_FR_REG1) + 4) /* 2 */ +#define GDB_FR_REG3 ((GDB_FR_REG2) + 4) /* 3 */ +#define GDB_FR_REG4 ((GDB_FR_REG3) + 4) /* 4 */ +#define GDB_FR_REG5 ((GDB_FR_REG4) + 4) /* 5 */ +#define GDB_FR_REG6 ((GDB_FR_REG5) + 4) /* 6 */ +#define GDB_FR_REG7 ((GDB_FR_REG6) + 4) /* 7 */ +#define GDB_FR_REG8 ((GDB_FR_REG7) + 4) /* 8 */ +#define GDB_FR_REG9 ((GDB_FR_REG8) + 4) /* 9 */ +#define GDB_FR_REG10 ((GDB_FR_REG9) + 4) /* 10 */ +#define GDB_FR_REG11 ((GDB_FR_REG10) + 4) /* 11 */ +#define GDB_FR_REG12 ((GDB_FR_REG11) + 4) /* 12 */ +#define GDB_FR_REG13 ((GDB_FR_REG12) + 4) /* 13 */ +#define GDB_FR_REG14 ((GDB_FR_REG13) + 4) /* 14 */ +#define GDB_FR_REG15 ((GDB_FR_REG14) + 4) /* 15 */ +#define GDB_FR_REG16 ((GDB_FR_REG15) + 4) /* 16 */ +#define GDB_FR_REG17 ((GDB_FR_REG16) + 4) /* 17 */ +#define GDB_FR_REG18 ((GDB_FR_REG17) + 4) /* 18 */ +#define GDB_FR_REG19 ((GDB_FR_REG18) + 4) /* 19 */ +#define GDB_FR_REG20 ((GDB_FR_REG19) + 4) /* 20 */ +#define GDB_FR_REG21 ((GDB_FR_REG20) + 4) /* 21 */ +#define GDB_FR_REG22 ((GDB_FR_REG21) + 4) /* 22 */ +#define GDB_FR_REG23 ((GDB_FR_REG22) + 4) /* 23 */ +#define GDB_FR_REG24 ((GDB_FR_REG23) + 4) /* 24 */ +#define GDB_FR_REG25 ((GDB_FR_REG24) + 4) /* 25 */ +#define GDB_FR_REG26 ((GDB_FR_REG25) + 4) /* 26 */ +#define GDB_FR_REG27 ((GDB_FR_REG26) + 4) /* 27 */ +#define GDB_FR_REG28 ((GDB_FR_REG27) + 4) /* 28 */ +#define GDB_FR_REG29 ((GDB_FR_REG28) + 4) /* 29 */ +#define GDB_FR_REG30 ((GDB_FR_REG29) + 4) /* 30 */ +#define GDB_FR_REG31 ((GDB_FR_REG30) + 4) /* 31 */ + +/* + * Saved special registers + */ +#define GDB_FR_STATUS ((GDB_FR_REG31) + 4) /* 32 */ +#define GDB_FR_LO ((GDB_FR_STATUS) + 4) /* 33 */ +#define GDB_FR_HI ((GDB_FR_LO) + 4) /* 34 */ +#define GDB_FR_BADVADDR ((GDB_FR_HI) + 4) /* 35 */ +#define GDB_FR_CAUSE ((GDB_FR_BADVADDR) + 4) /* 36 */ +#define GDB_FR_EPC ((GDB_FR_CAUSE) + 4) /* 37 */ + +/* + * Saved floating point registers + */ +#define GDB_FR_FPR0 ((GDB_FR_EPC) + 4) /* 38 */ +#define GDB_FR_FPR1 ((GDB_FR_FPR0) + 4) /* 39 */ +#define GDB_FR_FPR2 ((GDB_FR_FPR1) + 4) /* 40 */ +#define GDB_FR_FPR3 ((GDB_FR_FPR2) + 4) /* 41 */ +#define GDB_FR_FPR4 ((GDB_FR_FPR3) + 4) /* 42 */ +#define GDB_FR_FPR5 ((GDB_FR_FPR4) + 4) /* 43 */ +#define GDB_FR_FPR6 ((GDB_FR_FPR5) + 4) /* 44 */ +#define GDB_FR_FPR7 ((GDB_FR_FPR6) + 4) /* 45 */ +#define GDB_FR_FPR8 ((GDB_FR_FPR7) + 4) /* 46 */ +#define GDB_FR_FPR9 ((GDB_FR_FPR8) + 4) /* 47 */ +#define GDB_FR_FPR10 ((GDB_FR_FPR9) + 4) /* 48 */ +#define GDB_FR_FPR11 ((GDB_FR_FPR10) + 4) /* 49 */ +#define GDB_FR_FPR12 ((GDB_FR_FPR11) + 4) /* 50 */ +#define GDB_FR_FPR13 ((GDB_FR_FPR12) + 4) /* 51 */ +#define GDB_FR_FPR14 ((GDB_FR_FPR13) + 4) /* 52 */ +#define GDB_FR_FPR15 ((GDB_FR_FPR14) + 4) /* 53 */ +#define GDB_FR_FPR16 ((GDB_FR_FPR15) + 4) /* 54 */ +#define GDB_FR_FPR17 ((GDB_FR_FPR16) + 4) /* 55 */ +#define GDB_FR_FPR18 ((GDB_FR_FPR17) + 4) /* 56 */ +#define GDB_FR_FPR19 ((GDB_FR_FPR18) + 4) /* 57 */ +#define GDB_FR_FPR20 ((GDB_FR_FPR19) + 4) /* 58 */ +#define GDB_FR_FPR21 ((GDB_FR_FPR20) + 4) /* 59 */ +#define GDB_FR_FPR22 ((GDB_FR_FPR21) + 4) /* 60 */ +#define GDB_FR_FPR23 ((GDB_FR_FPR22) + 4) /* 61 */ +#define GDB_FR_FPR24 ((GDB_FR_FPR23) + 4) /* 62 */ +#define GDB_FR_FPR25 ((GDB_FR_FPR24) + 4) /* 63 */ +#define GDB_FR_FPR26 ((GDB_FR_FPR25) + 4) /* 64 */ +#define GDB_FR_FPR27 ((GDB_FR_FPR26) + 4) /* 65 */ +#define GDB_FR_FPR28 ((GDB_FR_FPR27) + 4) /* 66 */ +#define GDB_FR_FPR29 ((GDB_FR_FPR28) + 4) /* 67 */ +#define GDB_FR_FPR30 ((GDB_FR_FPR29) + 4) /* 68 */ +#define GDB_FR_FPR31 ((GDB_FR_FPR30) + 4) /* 69 */ + +#define GDB_FR_FSR ((GDB_FR_FPR31) + 4) /* 70 */ +#define GDB_FR_FIR ((GDB_FR_FSR) + 4) /* 71 */ +#define GDB_FR_FRP ((GDB_FR_FIR) + 4) /* 72 */ + +#define GDB_FR_DUMMY ((GDB_FR_FRP) + 4) /* 73, unused ??? */ + +/* + * Again, CP0 registers + */ +#define GDB_FR_CP0_INDEX ((GDB_FR_DUMMY) + 4) /* 74 */ +#define GDB_FR_CP0_RANDOM ((GDB_FR_CP0_INDEX) + 4) /* 75 */ +#define GDB_FR_CP0_ENTRYLO0 ((GDB_FR_CP0_RANDOM) + 4) /* 76 */ +#define GDB_FR_CP0_ENTRYLO1 ((GDB_FR_CP0_ENTRYLO0) + 4) /* 77 */ +#define GDB_FR_CP0_REG4 ((GDB_FR_CP0_ENTRYLO1) + 4) /* 78 */ +#define GDB_FR_CP0_PAGEMASK ((GDB_FR_CP0_REG4) + 4) /* 79 */ +#define GDB_FR_CP0_WIRED ((GDB_FR_CP0_PAGEMASK) + 4) /* 80 */ +#define GDB_FR_CP0_REG7 ((GDB_FR_CP0_WIRED) + 4) /* 81 */ +#define GDB_FR_CP0_REG8 ((GDB_FR_CP0_REG7) + 4) /* 82 */ +#define GDB_FR_CP0_REG9 ((GDB_FR_CP0_REG8) + 4) /* 83 */ +#define GDB_FR_CP0_ENTRYHI ((GDB_FR_CP0_REG9) + 4) /* 84 */ +#define GDB_FR_CP0_REG11 ((GDB_FR_CP0_ENTRYHI) + 4) /* 85 */ +#define GDB_FR_CP0_REG12 ((GDB_FR_CP0_REG11) + 4) /* 86 */ +#define GDB_FR_CP0_REG13 ((GDB_FR_CP0_REG12) + 4) /* 87 */ +#define GDB_FR_CP0_REG14 ((GDB_FR_CP0_REG13) + 4) /* 88 */ +#define GDB_FR_CP0_PRID ((GDB_FR_CP0_REG14) + 4) /* 89 */ + +#define GDB_FR_SIZE ((((GDB_FR_CP0_PRID) + 4) + (PTRSIZE-1)) & ~(PTRSIZE-1)) + +#ifndef __LANGUAGE_ASSEMBLY__ + +/* + * This is the same as above, but for the high-level + * part of the GDB stub. + */ + +struct gdb_regs { + /* + * Pad bytes for argument save space on the stack + * 20/40 Bytes for 32/64 bit code + */ + unsigned long pad0[5]; + + /* + * saved main processor registers + */ + long reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; + long reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15; + long reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23; + long reg24, reg25, reg26, reg27, reg28, reg29, reg30, reg31; + + /* + * Saved special registers + */ + long cp0_status; + long lo; + long hi; + long cp0_badvaddr; + long cp0_cause; + long cp0_epc; + + /* + * Saved floating point registers + */ + long fpr0, fpr1, fpr2, fpr3, fpr4, fpr5, fpr6, fpr7; + long fpr8, fpr9, fpr10, fpr11, fpr12, fpr13, fpr14, fpr15; + long fpr16, fpr17, fpr18, fpr19, fpr20, fpr21, fpr22, fpr23; + long fpr24, fpr25, fpr26, fpr27, fpr28, fpr29, fpr30, fpr31; + + long cp1_fsr; + long cp1_fir; + + /* + * Frame pointer + */ + long frame_ptr; + long dummy; /* unused */ + + /* + * saved cp0 registers + */ + long cp0_index; + long cp0_random; + long cp0_entrylo0; + long cp0_entrylo1; + long cp0_reg4; + long cp0_pagemask; + long cp0_wired; + long cp0_reg7; + long cp0_reg8; + long cp0_reg9; + long cp0_entryhi; + long cp0_reg11; + long cp0_reg12; + long cp0_reg13; + long cp0_reg14; + long cp0_prid; +}; + +/* + * Prototypes + */ + +void set_debug_traps(void); + +#endif /* __LANGUAGE_ASSEMBLY */ +#endif /* __ASM_MIPS_GDB_STUB_H */ diff --git a/include/asm-mips/head.h b/include/asm-mips/head.h deleted file mode 100644 index e0e01ec52..000000000 --- a/include/asm-mips/head.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _ASM_MIPS_HEAD_H -#define _ASM_MIPS_HEAD_H - -#include <linux/types.h> - -extern unsigned long swapper_pg_dir[1024]; -extern ulong IRQ_vectors[]; - -#endif diff --git a/include/asm-mips/in.h b/include/asm-mips/in.h deleted file mode 100644 index 18074abb9..000000000 --- a/include/asm-mips/in.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _ASM_I386_IN_H -#define _ASM_I386_IN_H - -static __inline__ unsigned long int -__ntohl(unsigned long int x) -{ - return (((x & 0x000000ffU) << 24) | - ((x & 0x0000ff00U) << 8) | - ((x & 0x00ff0000U) >> 8) | - ((x & 0xff000000U) >> 24)); -} - -static __inline__ unsigned short int -__ntohs(unsigned short int x) -{ - return (((x & 0x00ff) << 8) | - ((x & 0xff00) >> 8)); -} - -#define __htonl(x) __ntohl(x) -#define __htons(x) __ntohs(x) - -#ifdef __OPTIMIZE__ -# define ntohl(x) \ -(__ntohl((x))) -# define ntohs(x) \ -(__ntohs((x))) -# define htonl(x) \ -(__htonl((x))) -# define htons(x) \ -(__htons((x))) -#endif - -#endif /* _ASM_I386_IN_H */ diff --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h deleted file mode 100644 index 6450b1698..000000000 --- a/include/asm-mips/interrupt.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _ASM_MIPS_INTERRUPT_H -#define _ASM_MIPS_INTERRUPT_H - -extern inline void mark_bh(int nr) -{ - __asm__ __volatile__( - "1:\tll\t$8,(%0)\n\t" - "or\t$8,$8,%1\n\t" - "sc\t$8,(%0)\n\t" - "beq\t$0,$8,1b\n\t" - : "=m" (bh_active) - : "r" (1<<nr) - : "$8","memory"); -} - -extern inline void disable_bh(int nr) -{ - __asm__ __volatile__( - "1:\tll\t$8,(%0)\n\t" - "and\t$8,$8,%1\n\t" - "sc\t$8,(%0)\n\t" - "beq\t$0,$8,1b\n\t" - : "=m" (bh_mask) - : "r" (1<<nr) - : "$8","memory"); -} - -extern inline void enable_bh(int nr) -{ - __asm__ __volatile__( - "1:\tll\t$8,(%0)\n\t" - "or\t$8,$8,%1\n\t" - "sc\t$8,(%0)\n\t" - "beq\t$0,$8,1b\n\t" - : "=m" (bh_mask) - : "r" (1<<nr) - : "$8","memory"); -} - -#endif /* _ASM_MIPS_INTERRUPT_H */ diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index 16dbd1b46..94f099066 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -1,13 +1,13 @@ -#ifndef _ASM_IO_H -#define _ASM_IO_H +#ifndef __ASM_MIPS_IO_H +#define __ASM_MIPS_IO_H -#include <asm/mipsregs.h> #include <asm/mipsconfig.h> /* * This file contains the definitions for the MIPS counterpart of the * x86 in/out instructions. This heap of macros and C results in much - * better code than the approach of doing it in plain C. + * better code than the approach of doing it in plain C, though that's + * probably not needed. * * Ralf * @@ -37,7 +37,7 @@ #define __SLOW_DOWN_IO \ __asm__ __volatile__( \ "sb\t$0,0x80(%0)" \ - : : "d" (PORT_BASE)); + : : "r" (PORT_BASE)); #ifdef REALLY_SLOW_IO #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; } @@ -56,24 +56,27 @@ extern inline void __out##s(unsigned int value, unsigned int port) { __asm__ __volatile__ ("s" #m "\t%0,%1(%2)" #define __OUT(m,s) \ -__OUT1(s) __OUT2(m) : : "d" (value), "i" (0), "d" (PORT_BASE+port)); } \ -__OUT1(s##c) __OUT2(m) : : "d" (value), "i" (port), "d" (PORT_BASE)); } \ -__OUT1(s##_p) __OUT2(m) : : "d" (value), "i" (0), "d" (PORT_BASE+port)); \ +__OUT1(s) __OUT2(m) : : "r" (value), "i" (0), "r" (PORT_BASE+port)); } \ +__OUT1(s##c) __OUT2(m) : : "r" (value), "i" (port), "r" (PORT_BASE)); } \ +__OUT1(s##_p) __OUT2(m) : : "r" (value), "i" (0), "r" (PORT_BASE+port)); \ SLOW_DOWN_IO; } \ -__OUT1(s##c_p) __OUT2(m) : : "d" (value), "i" (port), "d" (PORT_BASE)); \ +__OUT1(s##c_p) __OUT2(m) : : "r" (value), "i" (port), "r" (PORT_BASE)); \ SLOW_DOWN_IO; } #define __IN1(s) \ extern inline unsigned int __in##s(unsigned int port) { unsigned int _v; +/* + * Useless nops will be removed by the assembler + */ #define __IN2(m) \ -__asm__ __volatile__ ("l" #m "u\t%0,%1(%2)\n\t" +__asm__ __volatile__ ("l" #m "u\t%0,%1(%2)\n\tnop" #define __IN(m,s) \ -__IN1(s) __IN2(m) STR(FILL_LDS) : "=d" (_v) : "i" (0), "d" (PORT_BASE+port)); return _v; } \ -__IN1(s##c) __IN2(m) STR(FILL_LDS) : "=d" (_v) : "i" (port), "d" (PORT_BASE)); return _v; } \ -__IN1(s##_p) __IN2(m) : "=d" (_v) : "i" (0), "d" (PORT_BASE+port)); SLOW_DOWN_IO; return _v; } \ -__IN1(s##c_p) __IN2(m) : "=d" (_v) : "i" (port), "d" (PORT_BASE)); SLOW_DOWN_IO; return _v; } +__IN1(s) __IN2(m) : "=r" (_v) : "i" (0), "r" (PORT_BASE+port)); return _v; } \ +__IN1(s##c) __IN2(m) : "=r" (_v) : "i" (port), "r" (PORT_BASE)); return _v; } \ +__IN1(s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (PORT_BASE+port)); SLOW_DOWN_IO; return _v; } \ +__IN1(s##c_p) __IN2(m) : "=r" (_v) : "i" (port), "r" (PORT_BASE)); SLOW_DOWN_IO; return _v; } #define __INS1(s) \ extern inline void __ins##s(unsigned int port, void * addr, unsigned long count) { @@ -83,21 +86,21 @@ __asm__ __volatile__ ( \ ".set\tnoreorder\n\t" \ ".set\tnoat\n" \ "1:\tl" #m "u\t$1,%4(%5)\n\t" \ - "subu\t%1,%1,1\n\t" \ + "subu\t%1,1\n\t" \ "s" #m "\t$1,(%0)\n\t" \ "bne\t$0,%1,1b\n\t" \ - "addiu\t%0,%0,%6\n\t" \ + "addiu\t%0,%6\n\t" \ ".set\tat\n\t" \ ".set\treorder" #define __INS(m,s,i) \ __INS1(s) __INS2(m) \ - : "=d" (addr), "=d" (count) \ - : "0" (addr), "1" (count), "i" (0), "d" (PORT_BASE+port), "I" (i) \ + : "=r" (addr), "=r" (count) \ + : "0" (addr), "1" (count), "i" (0), "r" (PORT_BASE+port), "I" (i) \ : "$1");} \ __INS1(s##c) __INS2(m) \ - : "=d" (addr), "=d" (count) \ - : "0" (addr), "1" (count), "i" (port), "d" (PORT_BASE), "I" (i) \ + : "=r" (addr), "=r" (count) \ + : "0" (addr), "1" (count), "i" (port), "r" (PORT_BASE), "I" (i) \ : "$1");} #define __OUTS1(s) \ @@ -117,12 +120,12 @@ __asm__ __volatile__ ( \ #define __OUTS(m,s,i) \ __OUTS1(s) __OUTS2(m) \ - : "=d" (addr), "=d" (count) \ - : "0" (addr), "1" (count), "i" (0), "d" (PORT_BASE+port), "I" (i) \ + : "=r" (addr), "=r" (count) \ + : "0" (addr), "1" (count), "i" (0), "r" (PORT_BASE+port), "I" (i) \ : "$1");} \ __OUTS1(s##c) __OUTS2(m) \ - : "=d" (addr), "=d" (count) \ - : "0" (addr), "1" (count), "i" (port), "d" (PORT_BASE), "I" (i) \ + : "=r" (addr), "=r" (count) \ + : "0" (addr), "1" (count), "i" (port), "r" (PORT_BASE), "I" (i) \ : "$1");} __IN(b,b) @@ -237,4 +240,4 @@ __OUTS(w,l,4) __inslc((port),(addr),(count)) : \ __insl((port),(addr),(count))) -#endif +#endif /* __ASM_MIPS_IO_H */ diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h index a6d10c29e..4c5191fef 100644 --- a/include/asm-mips/irq.h +++ b/include/asm-mips/irq.h @@ -9,10 +9,10 @@ * written by Ralf Baechle * */ -#ifndef _ASM_MIPS_IRQ_H -#define _ASM_MIPS_IRQ_H +#ifndef __ASM_MIPS_IRQ_H +#define __ASM_MIPS_IRQ_H extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); -#endif /* _ASM_MIPS_IRQ_H */ +#endif /* __ASM_MIPS_IRQ_H */ diff --git a/include/asm-mips/jazz.h b/include/asm-mips/jazz.h new file mode 100644 index 000000000..2e6a3cc2d --- /dev/null +++ b/include/asm-mips/jazz.h @@ -0,0 +1,314 @@ +/* + * Hardware info about Mips JAZZ and similar 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 by Andreas Busse and Ralf Baechle + * + * This file is a mess. It really needs some reorganisation! + */ + +#ifndef __ASM_MIPS_JAZZ_H +#define __ASM_MIPS_JAZZ_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. + */ + +#define JAZZ_LOCAL_IO_SPACE 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 independend. + * It's 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 JAZZ and PICA chipsets. + * This address is just a guess and seems to differ from + * other mips machines such as RC3xxx... + */ +#define JAZZ_KEYBOARD_ADDRESS 0xe0005000 +#define JAZZ_KEYBOARD_DATA 0xe0005000 +#define JAZZ_KEYBOARD_COMMAND 0xe0005001 + +#ifndef __LANGUAGE_ASSEMBLY__ + +typedef struct { + unsigned char data; + unsigned char command; +} jazz_keyboard_hardware; + +typedef struct { + unsigned char pad0[3]; + unsigned char data; + unsigned char pad1[3]; + unsigned char command; +} mips_keyboard_hardware; + +/* + * For now. Needs to be changed for RC3xxx support. See below. + */ +#define keyboard_hardware jazz_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 + +/* + * Serial and parallel ports (WD 16C552) on the Mips JAZZ + */ + +#define JAZZ_SERIAL1_BASE (unsigned int)0xe0006000 +#define JAZZ_SERIAL2_BASE (unsigned int)0xe0007000 +#define JAZZ_PARALLEL_BASE (unsigned int)0xe0008000 + +/* + * Dummy Device Address. Used in jazzdma.c + */ + +#define JAZZ_DUMMY_DEVICE 0xe000d000 + +/* + * JAZZ 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 JAZZ_TIMER_INTERVAL 0xe0000228 +#define JAZZ_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 + +/* + * JAZZ interrupt control registers + */ +#define JAZZ_IO_IRQ_SOURCE 0xe0100000 +#define JAZZ_IO_IRQ_ENABLE 0xe0100002 + +/* + * JAZZ interrupt enable bits + */ +#define JAZZ_IE_PARALLEL (1 << 0) +#define JAZZ_IE_FLOPPY (1 << 1) +#define JAZZ_IE_SOUND (1 << 2) +#define JAZZ_IE_VIDEO (1 << 3) +#define JAZZ_IE_ETHERNET (1 << 4) +#define JAZZ_IE_SCSI (1 << 5) +#define JAZZ_IE_KEYBOARD (1 << 6) +#define JAZZ_IE_MOUSE (1 << 7) +#define JAZZ_IE_SERIAL1 (1 << 8) +#define JAZZ_IE_SERIAL2 (1 << 9) + +/* + * JAZZ Interrupt Level definitions + */ + +#define JAZZ_TIMER_IRQ 0 +#define JAZZ_KEYBOARD_IRQ 1 +#define JAZZ_ETHERNET_IRQ 2 /* 15 */ +#define JAZZ_SERIAL1_IRQ 3 +#define JAZZ_SERIAL2_IRQ 4 +#define JAZZ_PARALLEL_IRQ 5 +#define JAZZ_FLOPPY_IRQ 6 /* needs to be consistent with floppy driver! */ + + +/* + * JAZZ DMA Channels + * Note: Channels 4...7 are not used with respect to the Acer PICA-61 + * chipset which does not provide these DMA channels. + */ + +#define JAZZ_SCSI_DMA 0 /* SCSI */ +#define JAZZ_FLOPPY_DMA 1 /* FLOPPY */ +#define JAZZ_AUDIOL_DMA 2 /* AUDIO L */ +#define JAZZ_AUDIOR_DMA 3 /* AUDIO R */ + +/* + * JAZZ R4030 MCT_ADR chip (DMA controller) + * Note: Virtual Addresses ! + */ + +#define JAZZ_R4030_CONFIG 0xE0000000 /* R4030 config register */ +#define JAZZ_R4030_REVISION 0xE0000008 /* same as PICA_ASIC_REVISION */ +#define JAZZ_R4030_INV_ADDR 0xE0000010 /* Invalid Address register */ + +#define JAZZ_R4030_TRSTBL_BASE 0xE0000018 /* Translation Table Base */ +#define JAZZ_R4030_TRSTBL_LIM 0xE0000020 /* Translation Table Limit */ +#define JAZZ_R4030_TRSTBL_INV 0xE0000028 /* Translation Table Invalidate */ + +#define JAZZ_R4030_CACHE_MTNC 0xE0000030 /* Cache Maintenance */ +#define JAZZ_R4030_R_FAIL_ADDR 0xE0000038 /* Remote Failed Address */ +#define JAZZ_R4030_M_FAIL_ADDR 0xE0000040 /* Memory Failed Adresss */ + +#define JAZZ_R4030_CACHE_PTAG 0xE0000048 /* I/O Cache Physical Tag */ +#define JAZZ_R4030_CACHE_LTAG 0xE0000050 /* I/O Cache Logical Tag */ +#define JAZZ_R4030_CACHE_BMASK 0xE0000058 /* I/O Cache Byte Mask */ +#define JAZZ_R4030_CACHE_BWIN 0xE0000060 /* I/O Cache Buffer Window */ + +/* + * Remote Speed Registers. + * + * 0: free, 1: Ethernet, 2: SCSI, 3: Floppy, + * 4: RTC, 5: Kb./Mouse 6: serial 1, 7: serial 2, + * 8: parallel, 9: NVRAM, 10: CPU, 11: PROM, + * 12: reserved, 13: free, 14: 7seg LED, 15: ??? + */ + +#define JAZZ_R4030_REM_SPEED 0xE0000070 /* 16 Remote Speed Registers */ + /* 0xE0000070,78,80... 0xE00000E8 */ +#define JAZZ_R4030_IRQ_ENABLE 0xE00000E8 /* Internal Interrupt Enable */ + +#define JAZZ_R4030_IRQ_SOURCE 0xE0000200 /* Interrupt Source Reg */ +#define JAZZ_R4030_I386_ERROR 0xE0000208 /* i386/EISA Bus Error */ + + +/* + * Access the R4030 DMA and I/O Controller + */ + +#ifndef __LANGUAGE_ASSEMBLY__ + +extern inline unsigned short r4030_read_reg16(unsigned addr) { + unsigned short ret = *((volatile unsigned short *)addr); + __asm__ __volatile__( + ".set\tnoreorder\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\treorder"); + return ret; +} + +extern inline unsigned int r4030_read_reg32(unsigned addr) { + unsigned int ret = *((volatile unsigned int *)addr); + __asm__ __volatile__( + ".set\tnoreorder\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\treorder"); + return ret; +} + +extern inline void r4030_write_reg16(unsigned addr, unsigned val) { + *((volatile unsigned short *)addr) = val; + __asm__ __volatile__( + ".set\tnoreorder\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\treorder"); +} + +extern inline unsigned int r4030_write_reg32(unsigned addr, unsigned val) { + *((volatile unsigned int *)addr) = val; + __asm__ __volatile__( + ".set\tnoreorder\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\treorder"); +} + +#endif /* !LANGUAGE_ASSEMBLY__ */ + + +#endif /* __ASM_MIPS_JAZZ_H */ diff --git a/include/asm-mips/jazzdma.h b/include/asm-mips/jazzdma.h new file mode 100644 index 000000000..292a16177 --- /dev/null +++ b/include/asm-mips/jazzdma.h @@ -0,0 +1,100 @@ +/* + * Helpfile for jazzdma.c -- Mips Jazz R4030 DMA controller support + */ + +#ifndef __ASM_JAZZDMA_H +#define __ASM_JAZZDMA_H + +/* + * Prototypes and macros + */ + +unsigned long vdma_init(unsigned long memory_start, unsigned long memory_end); +unsigned long vdma_alloc(unsigned long paddr, unsigned long size); +int vdma_free(unsigned long laddr); +int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size); +unsigned long vdma_phys2log(unsigned long paddr); +unsigned long vdma_log2phys(unsigned long laddr); +void vdma_stats(void); /* for debugging only */ + +void vdma_enable(int channel); +void vdma_disable(int channel); +void vdma_set_mode(int channel, int mode); +void vdma_set_addr(int channel, long addr); +void vdma_set_count(int channel, int count); +int vdma_get_residue(int channel); + +/* + * some definitions used by the driver functions + */ + +#define VDMA_PAGESIZE 4096 +#define VDMA_PGTBL_ENTRIES 4096 +#define VDMA_PGTBL_SIZE (sizeof(VDMA_PGTBL_ENTRY) * VDMA_PGTBL_ENTRIES) +#define VDMA_PAGE_EMPTY 0 + +/* + * Macros to get page no. and offset of a given address + * Note that VDMA_PAGE() works for physical addresses only + */ +#define VDMA_PAGE(a) ((unsigned int)(a) >> 12) +#define VDMA_OFFSET(a) ((unsigned int)(a) & (VDMA_PAGESIZE-1)) + +/* + * error code returned by vdma_alloc() + * (See also arch/mips/kernel/jazzdma.c) + */ + +#define VDMA_ERROR 0xffffffff + +/* + * VDMA pagetable entry description + */ + +typedef volatile struct VDMA_PGTBL_ENTRY +{ + unsigned int frame; /* physical frame no. */ + unsigned int owner; /* owner of this entry (0=free) */ +} VDMA_PGTBL_ENTRY; + + +/* + * DMA channel control registers + * in the R4030 MCT_ADR chip + */ + +#define JAZZ_R4030_CHNL_MODE 0xE0000100 /* 8 DMA Channel Mode Registers, */ + /* 0xE0000100,120,140... */ +#define JAZZ_R4030_CHNL_ENABLE 0xE0000108 /* 8 DMA Channel Enable Regs, */ + /* 0xE0000108,128,148... */ +#define JAZZ_R4030_CHNL_COUNT 0xE0000110 /* 8 DMA Channel Byte Cnt Regs, */ + /* 0xE0000110,130,150... */ +#define JAZZ_R4030_CHNL_ADDR 0xE0000118 /* 8 DMA Channel Address Regs, */ + /* 0xE0000118,138,158... */ + +/* channel enable register bits */ + +#define R4030_CHNL_ENABLE (1<<0) +#define R4030_CHNL_WRITE (1<<1) +#define R4030_TC_INTR (1<<8) +#define R4030_MEM_INTR (1<<9) +#define R4030_ADDR_INTR (1<<10) + +/* channel mode register bits */ + +#define R4030_MODE_ATIME_40 (0) /* device access time on remote bus */ +#define R4030_MODE_ATIME_80 (1) +#define R4030_MODE_ATIME_120 (2) +#define R4030_MODE_ATIME_160 (3) +#define R4030_MODE_ATIME_200 (4) +#define R4030_MODE_ATIME_240 (5) +#define R4030_MODE_ATIME_280 (6) +#define R4030_MODE_ATIME_320 (7) +#define R4030_MODE_WIDTH_8 (1<<3) /* device data bus width */ +#define R4030_MODE_WIDTH_16 (2<<3) +#define R4030_MODE_WIDTH_32 (3<<3) +#define R4030_MODE_INTR_EN (1<<5) +#define R4030_MODE_BURST (1<<6) /* Rev. 2 only */ +#define R4030_MODE_FAST_ACK (1<<7) /* Rev. 2 only */ + +#endif /* __ASM_JAZZDMA_H */ diff --git a/include/asm-mips/mipsconfig.h b/include/asm-mips/mipsconfig.h index 4194df998..1648f7c7e 100644 --- a/include/asm-mips/mipsconfig.h +++ b/include/asm-mips/mipsconfig.h @@ -1,29 +1,49 @@ /* - * linux/include/asm-mips/mipsconfig.h + * include/asm-mips/mipsconfig.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 by Waldorf GMBH + * Copyright (C) 1994, 1995 by Waldorf Electronics * written by Ralf Baechle - * */ -#ifndef _ASM_MIPS_MIPS_CONFIG_H -#define _ASM_MIPS_MIPS_CONFIG_H +#ifndef __ASM_MIPS_MIPSCONFIG_H +#define __ASM_MIPS_MIPSCONFIG_H /* - * This is the virtual adress to which all ports are being mapped. + * 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 0xe0000000 -#define PORT_BASE_HIGH 0xe000 +#ifndef PORT_BASE +#define PORT_BASE 0xe2000000 +#endif -#define NUMBER_OF_TLB_ENTRIES 48 +/* + * Pagetables are 4MB mapped at 0xe4000000 + * Must be a value that can be loaded with a single instruction. + */ +#define TLBMAP 0xe4000000 + +/* + * 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 + +/* + * Use this to activate extra TLB error checking + */ +#define CONFIG_DEBUG_TLB /* - * Absolute address of the kernelstack is 0x80000280 + * Use this to activate extra TLB profiling code + * (currently not implemented) */ -#define KERNEL_SP_HIGH 0x8000 -#define KERNEL_SP_LOW 0x0280 +#undef CONFIG_PROFILE_TLB -#endif /* _ASM_MIPS_MIPS_CONFIG_H */ +#endif /* __ASM_MIPS_MIPSCONFIG_H */ diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index b9b96e73d..466c8b12b 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -5,11 +5,11 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994 by Ralf Baechle + * Copyright (C) 1994, 1995 by Ralf Baechle */ -#ifndef _ASM_MIPS_MIPSREGS_H_ -#define _ASM_MIPS_MIPSREGS_H_ +#ifndef __ASM_MIPS_MIPSREGS_H +#define __ASM_MIPS_MIPSREGS_H /* * The following macros are especially useful for __asm__ @@ -25,10 +25,8 @@ /* * On the R2000/3000 load instructions are not interlocked - - * we therefore sometimes need to fill load delay slots with nop - * which are not needed for >=R4000. - * - * FIXME: Don't know about R6000 + * we therefore sometimes need to fill load delay slots with a nop + * which would be useless for ISA >= 2. */ #if !defined (__R4000__) #define FILL_LDS nop @@ -59,6 +57,9 @@ #define CP0_WATCHLO $18 #define CP0_WATCHHI $19 #define CP0_XCONTEXT $20 +#define CP0_FRAMEMASK $21 +#define CP0_DIAGNOSTIC $22 +#define CP0_PERFORMANCE $25 #define CP0_ECC $26 #define CP0_CACHEERR $27 #define CP0_TAGLO $28 @@ -66,6 +67,13 @@ #define CP0_ERROREPC $30 /* + * Coprocessor 1 (FPU) register names + */ + +#define CP1_REVISION $0 +#define CP1_STATUS $31 + +/* * Values for PageMask register */ #define PM_4K 0x00000000 @@ -88,91 +96,173 @@ #define PL_16M 24 /* - * Compute a vpn/pfn entry for EntryHi register + * Macros to access the system control coprocessor */ -#define VPN(addr,pagesizeshift) ((addr) & ~((1 << (pagesizeshift))-1)) -#define PFN(addr,pagesizeshift) (((addr) & ((1 << (pagesizeshift))-1)) << 6) +#define read_32bit_cp0_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + "mfc0\t%0,"STR(source) \ + : "=r" (__res)); \ + __res;}) +#define read_64bit_cp0_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmfc0\t%0,"STR(source)"\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + __res;}) + +#define write_32bit_cp0_register(register,value) \ + __asm__ __volatile__( \ + "mtc0\t%0,"STR(register) \ + : : "r" (value)); + +#define write_64bit_cp0_register(register,value) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmtc0\t%0,"STR(register)"\n\t" \ + ".set\tmips0" \ + : : "r" (value)) /* - * Macros to access the system control copprocessor + * R4x00 interrupt enable / cause bits */ -#define read_32bit_cp0_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - "mfc0\t%0,"STR(source) \ - : "=r" (__res)); \ - __res;}) +#define IE_SW0 (1<< 8) +#define IE_SW1 (1<< 9) +#define IE_IRQ0 (1<<10) +#define IE_IRQ1 (1<<11) +#define IE_IRQ2 (1<<12) +#define IE_IRQ3 (1<<13) +#define IE_IRQ4 (1<<14) +#define IE_IRQ5 (1<<15) -#define read_64bit_cp0_register(target,source) \ - __asm__ __volatile__( \ - ".set\tnoat\n\t" \ - "dmfc0\t$1,"STR(source)"\n\t" \ - "sd\t$1,(%0)\n\t" \ - ".set\tat" \ - : \ - : "r" (target) \ - : "$1","memory"); +/* + * R4x00 interrupt cause bits + */ +#define C_SW0 (1<< 8) +#define C_SW1 (1<< 9) +#define C_IRQ0 (1<<10) +#define C_IRQ1 (1<<11) +#define C_IRQ2 (1<<12) +#define C_IRQ3 (1<<13) +#define C_IRQ4 (1<<14) +#define C_IRQ5 (1<<15) + +#ifndef __LANGUAGE_ASSEMBLY__ +/* + * Manipulate the status register. + * Mostly used to access the interrupt bits. + */ +#define BUILD_SET_CP0(name,register) \ +extern __inline__ unsigned int \ +set_cp0_##name(unsigned int change, unsigned int new) \ +{ \ + unsigned int res; \ + \ + res = read_32bit_cp0_register(register); \ + res &= ~change; \ + res |= (new & change); \ + if(change) \ + write_32bit_cp0_register(register, res); \ + \ + return res; \ +} +BUILD_SET_CP0(status,CP0_STATUS) +BUILD_SET_CP0(cause,CP0_CAUSE) -#define write_32bit_cp0_register(register,value) \ - __asm__ __volatile__( \ - "mtc0\t%0,"STR(register) \ - : : "r" (value)); +#endif /* defined (__LANGUAGE_ASSEMBLY__) */ /* * Inline code for use of the ll and sc instructions * - * FIXME: This code code will break on R[23]00 CPUs + * FIXME: This instruction is only available on MIPS ISA >=3. * Since these operations are only being used for atomic operations * the easiest workaround for the R[23]00 is to disable interrupts. */ -#define load_linked(addr) \ -({ \ - unsigned int __res; \ - \ - __asm__ __volatile__( \ - "ll\t%0,(%1)" \ - : "=r" (__res) \ - : "r" ((unsigned int) (addr))); \ - \ - __res; \ +#define load_linked(addr) \ +({ \ + unsigned int __res; \ + \ + __asm__ __volatile__( \ + "ll\t%0,(%1)" \ + : "=r" (__res) \ + : "r" ((unsigned int) (addr))); \ + \ + __res; \ }) -#define store_conditional(value,addr) \ -({ \ - int __res; \ - \ - __asm__ __volatile__( \ - "sc\t%0,(%2)" \ - : "=r" (__res) \ - : "0" (value), "r" (addr)); \ - \ - __res; \ +#define store_conditional(addr,value) \ +({ \ + int __res; \ + \ + __asm__ __volatile__( \ + "sc\t%0,(%2)" \ + : "=r" (__res) \ + : "0" (value), "r" (addr)); \ + \ + __res; \ }) /* * Bitfields in the cp0 status register * - * Refer to MIPS R4600 manual, page 5-4 for explanation + * Refer to the MIPS R4xx0 manuals, chapter 5 for explanation. + * FIXME: This doesn't cover all R4xx0 processors. */ -#define ST0_IE (1 << 1) -#define ST0_EXL (1 << 2) -#define ST0_ERL (3 << 3) -#define ST0_UX (1 << 5) -#define ST0_SX (1 << 6) -#define ST0_KX (1 << 7) -#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) - -#endif /* _ASM_MIPS_MIPSREGS_H_ */ +#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_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) + +/* + * Bitfields and bit numbers in the coprocessor 0 cause register. + * + * Refer to to your MIPS R4xx0 manual, chapter 5 for explanation. + */ +#define CAUSEB_EXCCODE 2 +#define CAUSEF_EXCCODE (31 << 2) +#define CAUSEB_IP 8 +#define CAUSEF_IP (255 << 8) +#define CAUSEB_IP0 8 +#define CAUSEF_IP0 (1 << 8) +#define CAUSEB_IP1 9 +#define CAUSEF_IP1 (1 << 9) +#define CAUSEB_IP2 10 +#define CAUSEF_IP2 (1 << 10) +#define CAUSEB_IP3 11 +#define CAUSEF_IP3 (1 << 11) +#define CAUSEB_IP4 12 +#define CAUSEF_IP4 (1 << 12) +#define CAUSEB_IP5 13 +#define CAUSEF_IP5 (1 << 13) +#define CAUSEB_IP6 14 +#define CAUSEF_IP6 (1 << 14) +#define CAUSEB_IP7 15 +#define CAUSEF_IP7 (1 << 15) +#define CAUSEB_CE 28 +#define CAUSEF_CE (3 << 28) +#define CAUSEB_BD 31 +#define CAUSEF_BD (1 << 31) + +#endif /* __ASM_MIPS_MIPSREGS_H */ diff --git a/include/asm-mips/mm.h b/include/asm-mips/mm.h deleted file mode 100644 index 84a09e1c8..000000000 --- a/include/asm-mips/mm.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef _ASM_MIPS_MM_H_ -#define _ASM_MIPS_MM_H_ - -#if defined (__KERNEL__) - -/* - * Note that we shift the lower 32bits of each EntryLo[01] entry - * 6 bit to the left. That way we can convert the PFN into the - * physical address by a single and operation and gain 6 aditional - * bits for storing information which isn't present in a normal - * MIPS page table. - * I've also changed the naming of some bits so that they conform - * the i386 naming as much as possible. - */ -#define PAGE_COW (1<<0) /* implemented in software */ -#define PAGE_ACCESSED (1<<1) /* implemented in software */ -#define PAGE_DIRTY (1<<2) /* implemented in software */ -#define PAGE_USER (1<<3) /* implemented in software */ -#define PAGE_UNUSED2 (1<<4) /* for use by software */ -#define PAGE_UNUSED3 (1<<5) /* for use by software */ -#define PAGE_GLOBAL (1<<6) -#define PAGE_VALID (1<<7) -/* - * In the hardware the PAGE_WP bit is represented by the dirty bit - */ -#define PAGE_RW (1<<8) -#define CACHE_CACHABLE_NO_WA (0<<9) -#define CACHE_CACHABLE_WA (1<<9) -#define CACHE_UNCACHED (2<<9) -#define CACHE_CACHABLE_NONCOHERENT (3<<9) -#define CACHE_CACHABLE_CE (4<<9) -#define CACHE_CACHABLE_COW (5<<9) -#define CACHE_CACHABLE_CUW (6<<9) -#define CACHE_MASK (7<<9) - -#define PAGE_PRIVATE (PAGE_VALID | PAGE_ACCESSED | PAGE_DIRTY | \ - PAGE_RW | PAGE_COW) -#define PAGE_SHARED (PAGE_VALID | PAGE_ACCESSED | PAGE_DIRTY | PAGE_RW) -#define PAGE_COPY (PAGE_VALID | PAGE_ACCESSED | PAGE_COW) -#define PAGE_READONLY (PAGE_VALID | PAGE_ACCESSED) -#define PAGE_TABLE (PAGE_VALID | PAGE_ACCESSED | PAGE_DIRTY | PAGE_RW) - -/* - * Predicate for testing - */ -#define IS_PAGE_USER(p) (((unsigned long)(p)) & PAGE_USER) - -extern inline long find_in_swap_cache (unsigned long addr) -{ - unsigned long entry; - -#ifdef SWAP_CACHE_INFO - swap_cache_find_total++; -#endif - cli(); - entry = swap_cache[addr >> PAGE_SHIFT]; - swap_cache[addr >> PAGE_SHIFT] = 0; - sti(); -#ifdef SWAP_CACHE_INFO - if (entry) - swap_cache_find_success++; -#endif - return entry; -} - -extern inline int delete_from_swap_cache(unsigned long addr) -{ - unsigned long entry; - -#ifdef SWAP_CACHE_INFO - swap_cache_del_total++; -#endif - cli(); - entry = swap_cache[addr >> PAGE_SHIFT]; - swap_cache[addr >> PAGE_SHIFT] = 0; - sti(); - if (entry) { -#ifdef SWAP_CACHE_INFO - swap_cache_del_success++; -#endif - swap_free(entry); - return 1; - } - return 0; -} - -/* - * memory.c & swap.c - */ -extern void mem_init(unsigned long start_mem, unsigned long end_mem); - -#endif /* defined (__KERNEL__) */ - -#endif /* _ASM_MIPS_MM_H_ */ diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index 0176c0251..4ea742d84 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h @@ -1,90 +1,126 @@ -#ifndef _ASM_MIPS_LINUX_PAGE_H -#define _ASM_MIPS_LINUX_PAGE_H +#ifndef __ASM_MIPS_PAGE_H +#define __ASM_MIPS_PAGE_H +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ + +#define CONFIG_STRICT_MM_TYPECHECKS + +#ifndef __LANGUAGE_ASSEMBLY__ + +#include <asm/cachectl.h> + +#ifdef CONFIG_STRICT_MM_TYPECHECKS /* - * For now... + * These are used to make use of C type-checking.. */ -#define invalidate() +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; - /* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT 12 -#define PGDIR_SHIFT 22 -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((x).pmd) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) -#ifdef __KERNEL__ +#define __pte(x) ((pte_t) { (x) } ) +#define __pme(x) ((pme_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) - /* number of bits that fit into a memory pointer */ -#define BITS_PER_PTR (8*sizeof(unsigned long)) - /* to mask away the intra-page address bits */ -#define PAGE_MASK (~(PAGE_SIZE-1)) - /* to mask away the intra-page address bits */ -#define PGDIR_MASK (~(PGDIR_SIZE-1)) - /* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - /* to align the pointer to a pointer address */ -#define PTR_MASK (~(sizeof(void*)-1)) - - /* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */ - /* 64-bit machines, beware! SRB. */ -#define SIZEOF_PTR_LOG2 2 - - /* to find an entry in a page-table-directory */ -#define PAGE_DIR_OFFSET(base,address) ((unsigned long*)((base)+\ - ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)*2&PTR_MASK&~PAGE_MASK))) - /* to find an entry in a page-table */ -#define PAGE_PTR(address) \ - ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) - /* the no. of pointers that fit on a page */ -#define PTRS_PER_PAGE (PAGE_SIZE/sizeof(void*)) - -#define copy_page(from,to) \ - __copy_page((void *)(from),(void *)(to), PAGE_SIZE) - -#if defined (__R4000__) +#else /* !defined (CONFIG_STRICT_MM_TYPECHECKS) */ /* - * Do it the 64bit way... + * .. while these make it easier on the compiler */ -extern __inline__ void __copy_page(void *from, void *to, int bytes) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tld\t$1,(%0)\n\t" - "addiu\t%0,%0,8\n\t" - "sd\t$1,(%1)\n\t" - "subu\t%2,%2,8\n\t" - "bne\t$0,%2,1b\n\t" - "addiu\t%1,%1,8\n\t" - ".set\tat\n\t" - ".set\treorder\n\t" - : "=r" (from), "=r" (to), "=r" (bytes) - : "r" (from), "r" (to), "r" (bytes) - : "$1"); -} +typedef unsigned long pte_t; +typedef unsigned long pmd_t; +typedef unsigned long pgd_t; +typedef unsigned long pgprot_t; + +#define pte_val(x) (x) +#define pmd_val(x) (x) +#define pgd_val(x) (x) +#define pgprot_val(x) (x) + +#define __pte(x) (x) +#define __pmd(x) (x) +#define __pgd(x) (x) +#define __pgprot(x) (x) + +#endif /* !defined (CONFIG_STRICT_MM_TYPECHECKS) */ + +#include <linux/linkage.h> + +extern asmlinkage void tlbflush(void); +#define invalidate() ({sys_cacheflush(0, ~0, BCACHE);tlbflush();}) + +#if __mips == 3 +typedef unsigned int mem_map_t; +#else +typedef unsigned short mem_map_t; +#endif + +#endif /* __LANGUAGE_ASSEMBLY__ */ + +/* 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 __mips == 3 +/* + * 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 +#define MAP_PAGE_RESERVED (1<<31) #else /* - * Use 32 bit Diesel fuel... + * We handle pages at KSEG0 (cachable, noncoherent) + * Pagetables are at KSEG1 (uncached) */ -extern __inline__ void __copy_page(void *from, void *to, int bytes) +#define PAGE_OFFSET 0x80000000 +#define PT_OFFSET 0xa0000000 +#define MAP_MASK 0x1fffffff +#define MAP_PAGE_RESERVED (1<<15) +#endif + +#define MAP_NR(addr) ((((unsigned long)(addr)) & MAP_MASK) >> PAGE_SHIFT) + +#ifndef __LANGUAGE_ASSEMBLY__ + +#define copy_page(from,to) __copy_page((unsigned long)from, (unsigned long)to) + +extern unsigned long page_colour_mask; + +extern inline unsigned long +page_colour(unsigned long page) { - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tlw\t$1,(%0)\n\t" - "addiu\t%0,%0,4\n\t" - "sw\t$1,(%1)\n\t" - "subu\t%2,%2,4\n\t" - "bne\t$0,%2,1b\n\t" - "addiu\t%1,%1,4\n\t" - ".set\tat\n\t" - ".set\treorder\n\t" - : "=r" (from), "=r" (to), "=r" (bytes) - : "r" (from), "r" (to), "r" (bytes) - : "$1"); + return page & page_colour_mask; } + +#if 0 +extern inline void __copy_page(unsigned long from, unsigned long to) +{ +printk("__copy_page(%08lx, %08lx)\n", from, to); + sys_cacheflush(0, ~0, DCACHE); + sync_mem(); + from += (PT_OFFSET - PAGE_OFFSET); + to += (PT_OFFSET - PAGE_OFFSET); + memcpy((void *) to, (void *) from, PAGE_SIZE); + sys_cacheflush(0, ~0, ICACHE); +} +#else +extern void __copy_page(unsigned long from, unsigned long to); #endif -#endif /* __KERNEL__ */ +#endif /* defined (__LANGUAGE_ASSEMBLY__) */ +#endif /* defined (__KERNEL__) */ -#endif /* _ASM_MIPS_LINUX_PAGE_H */ +#endif /* __ASM_MIPS_PAGE_H */ diff --git a/include/asm-mips/param.h b/include/asm-mips/param.h new file mode 100644 index 000000000..09000b46a --- /dev/null +++ b/include/asm-mips/param.h @@ -0,0 +1,20 @@ +#ifndef __ASM_MIPS_PARAM_H +#define __ASM_MIPS_PARAM_H + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NGROUPS +#define NGROUPS 32 +#endif + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* __ASM_MIPS_PARAM_H */ diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h new file mode 100644 index 000000000..e2fb67cbe --- /dev/null +++ b/include/asm-mips/pgtable.h @@ -0,0 +1,524 @@ +#ifndef __ASM_MIPS_PGTABLE_H +#define __ASM_MIPS_PGTABLE_H + +#include <asm/cachectl.h> + +/* + * 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. + * + * This file contains the functions and defines necessary to modify and use + * the MIPS page table tree. + */ + +/* PMD_SHIFT determines the size of the area a second-level page table can map */ +#define PMD_SHIFT 22 +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#define PGDIR_SHIFT 22 +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* + * entries per page directory level: we use two-level, so + * we don't really have any PMD directory physically. + */ +#define PTRS_PER_PTE 1024 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 1024 + +#define VMALLOC_START KSEG2 +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) + +/* + * 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 choosen some quite missleading names for the + * valid and dirty bits they're defined here but only their synonyms + * will be used. + */ +#define _PAGE_PRESENT (1<<0) /* implemented in software */ +#define _PAGE_COW (1<<1) /* implemented in software */ +#define _PAGE_READ (1<<2) /* implemented in software */ +#define _PAGE_WRITE (1<<3) /* implemented in software */ +#define _PAGE_ACCESSED (1<<4) /* implemented in software */ +#define _PAGE_MODIFIED (1<<5) /* implemented in software */ +#define _PAGE_GLOBAL (1<<6) +#define _PAGE_VALID (1<<7) +#define _PAGE_SILENT_READ (1<<7) /* synonym */ +#define _PAGE_DIRTY (1<<8) /* The MIPS dirty bit */ +#define _PAGE_SILENT_WRITE (1<<8) +#define _CACHE_CACHABLE_NO_WA (0<<9) /* R4600 only */ +#define _CACHE_CACHABLE_WA (1<<9) /* R4600 only */ +#define _CACHE_UNCACHED (2<<9) /* R4[0246]00 */ +#define _CACHE_CACHABLE_NONCOHERENT (3<<9) /* R4[0246]00 */ +#define _CACHE_CACHABLE_CE (4<<9) /* R4[04]00 only */ +#define _CACHE_CACHABLE_COW (5<<9) /* R4[04]00 only */ +#define _CACHE_CACHABLE_CUW (6<<9) /* R4[04]00 only */ +#define _CACHE_CACHABLE_ACCELERATED (7<<9) /* R10000 only */ +#define _CACHE_MASK (7<<9) + +#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_NONE __pgprot(_PAGE_PRESENT | __READABLE | _CACHE_UNCACHED) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | __READABLE | _PAGE_WRITE | \ + _PAGE_ACCESSED | _CACHE_CACHABLE_NONCOHERENT) +#define PAGE_COPY __pgprot(_PAGE_PRESENT | __READABLE | _PAGE_COW | \ + _CACHE_CACHABLE_NONCOHERENT) +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | __READABLE | \ + _CACHE_CACHABLE_NONCOHERENT) +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ + _CACHE_CACHABLE_NONCOHERENT) + +/* + * MIPS can't do page protection for execute, and considers that the same like + * read. Also, write permissions imply read permissions. This is the closest + * we can get by reasonable means.. + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + +#if !defined (__LANGUAGE_ASSEMBLY__) + +/* page table for 0-4MB for everybody */ +extern unsigned long pg0[1024]; + +/* + * BAD_PAGETABLE is used when we need a bogus page-table, while + * BAD_PAGE is used for a bogus page. + * + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +extern pte_t __bad_page(void); +extern pte_t * __bad_pagetable(void); + +extern unsigned long __zero_page(void); + +#define BAD_PAGETABLE __bad_pagetable() +#define BAD_PAGE __bad_page() +#define ZERO_PAGE __zero_page() + +/* number of bits that fit into a memory pointer */ +#define BITS_PER_PTR (8*sizeof(unsigned long)) + +/* to align the pointer to a pointer address */ +#define PTR_MASK (~(sizeof(void*)-1)) + +/* + * sizeof(void*)==1<<SIZEOF_PTR_LOG2 + */ +#if __mips == 3 +#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) + +/* to set the page-dir */ +#define SET_PAGE_DIR(tsk,pgdir) \ +do { \ + (tsk)->tss.pg_dir = ((unsigned long) (pgdir)) - PT_OFFSET; \ + if ((tsk) == current) \ + invalidate(); \ +} while (0) + +extern unsigned long high_memory; +extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)]; + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +extern inline unsigned long pte_page(pte_t pte) +{ 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); } + +extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) +{ pmd_val(*pmdp) = _PAGE_TABLE | ((unsigned long) ptep - PT_OFFSET); } + +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_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] != 1; } +extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } +extern inline void pte_reuse(pte_t * ptep) +{ + if (!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED)) + mem_map[MAP_NR(ptep)]++; +} + +/* + * 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 || + pmd_page(pmd) > high_memory || + pmd_page(pmd) < PAGE_OFFSET; +} +extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_PRESENT; } +extern inline int pmd_inuse(pmd_t *pmdp) { return 0; } +extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = ((unsigned long) invalid_pte_table - PAGE_OFFSET); } +extern inline void pmd_reuse(pmd_t * pmdp) { } + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +extern inline int pgd_none(pgd_t pgd) { return 0; } +extern inline int pgd_bad(pgd_t pgd) { return 0; } +extern inline int pgd_present(pgd_t pgd) { return 1; } +extern inline int pgd_inuse(pgd_t * pgdp) { return mem_map[MAP_NR(pgdp)] != 1; } +extern inline void pgd_clear(pgd_t * pgdp) { } +extern inline void pgd_reuse(pgd_t * pgdp) +{ + if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED)) + mem_map[MAP_NR(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_cow(pte_t pte) { return pte_val(pte) & _PAGE_COW; } + +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; +} +extern inline pte_t pte_exprotect(pte_t pte) +{ + pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ); 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_uncow(pte_t pte) { pte_val(pte) &= ~_PAGE_COW; return pte; } +extern inline pte_t pte_mkwrite(pte_t pte) +{ + pte_val(pte) |= _PAGE_WRITE; + if (pte_val(pte) & _PAGE_MODIFIED) + pte_val(pte) |= _PAGE_SILENT_WRITE; + return pte; +} +extern inline pte_t pte_mkread(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_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; + if (pte_val(pte) & _PAGE_WRITE) + 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) + { + pte_val(pte) |= _PAGE_SILENT_READ; + if ((pte_val(pte) & (_PAGE_WRITE|_PAGE_MODIFIED)) == (_PAGE_WRITE|_PAGE_MODIFIED)) + pte_val(pte) |= _PAGE_SILENT_WRITE; + } + return pte; +} +extern inline pte_t pte_mkcow(pte_t pte) +{ + pte_val(pte) |= _PAGE_COW; + return pte; +} + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +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; } + +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; } + +/* to find an entry in a page-table-directory */ +extern inline pgd_t * pgd_offset(struct task_struct * tsk, unsigned long address) +{ + return (pgd_t *) (tsk->tss.pg_dir + PT_OFFSET) + + (address >> PGDIR_SHIFT); +} + +/* Find an entry in the second-level page table.. */ +extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) +{ + return (pmd_t *) dir; +} + +/* Find an entry in the third-level page table.. */ +extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) +{ + return (pte_t *) (pmd_page(*dir) + (PT_OFFSET - PAGE_OFFSET)) + + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); +} + +/* + * Allocate and free page tables. The xxx_kernel() versions are + * used to allocate a kernel page table - this turns on ASN bits + * if any, and marks the page tables reserved. + */ +extern inline void pte_free_kernel(pte_t * pte) +{ + unsigned long page = (unsigned long) pte; + + mem_map[MAP_NR(pte)] = 1; + if(!page) + return; + page -= (PT_OFFSET - PAGE_OFFSET); + free_page(page); +} + +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); + if (pmd_none(*pmd)) { + if (page) { + mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED; + sys_cacheflush((void *)page, PAGE_SIZE, DCACHE); + sync_mem(); + page += (PT_OFFSET - PAGE_OFFSET); + memset((void *) page, 0, PAGE_SIZE); + pmd_set(pmd, (pte_t *)page); + return ((pte_t *)page) + address; + } + pmd_set(pmd, (pte_t *) BAD_PAGETABLE); + return NULL; + } + free_page(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 *) (pmd_page(*pmd) + (PT_OFFSET - PAGE_OFFSET)) + 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 pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address) +{ + return (pmd_t *) pgd; +} + +extern inline void pte_free(pte_t * pte) +{ + unsigned long page = (unsigned long) pte; + + if(!page) + return; + page -= (PT_OFFSET - PAGE_OFFSET); + free_page(page); +} + +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); + if (pmd_none(*pmd)) { + if (page) { + sys_cacheflush((void *)page, PAGE_SIZE, DCACHE); + sync_mem(); + page += (PT_OFFSET - PAGE_OFFSET); + memset((void *) page, 0, PAGE_SIZE); + pmd_set(pmd, (pte_t *)page); + return ((pte_t *)page) + address; + } + pmd_set(pmd, (pte_t *) BAD_PAGETABLE); + return NULL; + } + free_page(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 *) (pmd_page(*pmd) + (PT_OFFSET - PAGE_OFFSET)) + 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 pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address) +{ + return (pmd_t *) pgd; +} + +extern inline void pgd_free(pgd_t * pgd) +{ + unsigned long page = (unsigned long) pgd; + + if(!page) + return; + page -= (PT_OFFSET - PAGE_OFFSET); + free_page(page); +} + +/* + * Initialize new page directory with pointers to invalid ptes + */ +extern inline void pgd_init(unsigned long page) +{ + unsigned long dummy1, dummy2; + + page += (PT_OFFSET - PAGE_OFFSET); +#ifdef __R4000__ + /* + * Ich will Spass - ich geb Gas ich geb Gas... + */ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "dsll32\t$1,%2,0\n\t" + "dsrl32\t%2,$1,0\n\t" + "or\t%2,$1\n" + "1:\tsd\t%2,(%0)\n\t" + "subu\t%1,1\n\t" + "bnez\t%1,1b\n\t" + "addiu\t%0,8\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), + "=r" (dummy2) + :"r" (((unsigned long) invalid_pte_table - PAGE_OFFSET) | + _PAGE_TABLE), + "0" (page), + "1" (PAGE_SIZE/(sizeof(pmd_t)*2)) + :"$1"); +#else + __asm__ __volatile__( + ".set\tnoreorder\n" + "1:\tsw\t%2,(%0)\n\t" + "subu\t%1,1\n\t" + "bnez\t%1,1b\n\t" + "addiu\t%0,4\n\t" + ".set\treorder" + :"=r" (dummy1), + "=r" (dummy2) + :"r" (((unsigned long) invalid_pte_table - PAGE_OFFSET) | + _PAGE_TABLE), + "0" (page), + "1" (PAGE_SIZE/sizeof(pmd_t))); +#endif +} + +extern inline pgd_t * pgd_alloc(void) +{ + unsigned long page; + + if(!(page = __get_free_page(GFP_KERNEL))) + return NULL; + + sys_cacheflush((void *)page, PAGE_SIZE, DCACHE); + sync_mem(); + pgd_init(page); + + return (pgd_t *) (page + (PT_OFFSET - PAGE_OFFSET)); +} + +extern pgd_t swapper_pg_dir[1024]; + +/* + * MIPS doesn't need any external MMU info: the kernel page + * tables contain all the necessary information. + */ +extern inline void update_mmu_cache(struct vm_area_struct * vma, + unsigned long address, pte_t pte) +{ +} + +#if __mips >= 3 + +#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))) + +#else + +#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f) +#define SWP_OFFSET(entry) ((entry) >> 8) +#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8)) + +#endif + +#endif /* !defined (__LANGUAGE_ASSEMBLY__) */ + +#endif /* __ASM_MIPS_PGTABLE_H */ diff --git a/include/asm-mips/pica.h b/include/asm-mips/pica.h new file mode 100644 index 000000000..799dcf4a0 --- /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 independend. + * 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 new file mode 100644 index 000000000..8e3e00267 --- /dev/null +++ b/include/asm-mips/processor.h @@ -0,0 +1,198 @@ +/* + * include/asm-mips/processor.h + * + * Copyright (C) 1994 Waldorf Electronics + * written by Ralf Baechle + */ + +#ifndef __ASM_MIPS_PROCESSOR_H +#define __ASM_MIPS_PROCESSOR_H + +#if !defined (__LANGUAGE_ASSEMBLY__) +#include <asm/cachectl.h> +#include <asm/system.h> + +/* + * System setup and hardware bug flags.. + */ +extern char wait_available; /* only available on R4[26]00 */ + +extern unsigned long intr_count; +extern unsigned long event; + +/* + * Bus types (default is ISA, but people can check others with these..) + * MCA_bus hardcoded to 0 for now. + * + * This needs to be extended since MIPS systems are being delivered with + * numerous different types of bus systems. + */ +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. + */ +#define TASK_SIZE (0x80000000UL) + +/* + * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. + */ +#define IO_BITMAP_SIZE 32 + +#define NUM_FPU_REGS 32 + +struct mips_fpu_hard_struct { + double fp_regs[NUM_FPU_REGS]; + unsigned int control; +}; + +/* + * FIXME: no fpu emulator yet (but who cares anyway?) + */ +struct mips_fpu_soft_struct { + long dummy; + }; + +union mips_fpu_union { + struct mips_fpu_hard_struct hard; + struct mips_fpu_soft_struct soft; +}; + +#define INIT_FPU { \ + {{0,},} \ +} + +/* + * If you change thread_struct remember to change the #defines below too! + */ +struct thread_struct { + /* + * saved main processor registers + */ + unsigned long reg16, 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; + /* + * Other stuff associated with the process + */ + unsigned long cp0_badvaddr; + unsigned long error_code; + unsigned long trap_no; + unsigned long ksp; /* Top of kernel stack */ + unsigned long pg_dir; /* L1 page table pointer */ +}; + +#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+4) +#define TOFF_REG18 (TOFF_REG17+4) +#define TOFF_REG19 (TOFF_REG18+4) +#define TOFF_REG20 (TOFF_REG19+4) +#define TOFF_REG21 (TOFF_REG20+4) +#define TOFF_REG22 (TOFF_REG21+4) +#define TOFF_REG23 (TOFF_REG22+4) +#define TOFF_REG28 (TOFF_REG23+4) +#define TOFF_REG29 (TOFF_REG28+4) +#define TOFF_REG30 (TOFF_REG29+4) +#define TOFF_REG31 (TOFF_REG30+4) +#define TOFF_CP0_STATUS (TOFF_REG31+4) +/* + * Pad for 8 byte boundary! + */ +#define TOFF_FPU (((TOFF_CP0_STATUS+4)+(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) + +#if !defined (__LANGUAGE_ASSEMBLY__) + +#define INIT_MMAP { &init_task, 0, 0x40000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } + +#define INIT_TSS { \ + /* \ + * saved main processor registers \ + */ \ + 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, \ + /* \ + * saved cp0 stuff \ + */ \ + 0, \ + /* \ + * saved fpu/fpu emulator stuff \ + */ \ + INIT_FPU, \ + /* \ + * 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 \ +} + +/* + * Do necessary setup to start up a newly executed thread. + */ +static __inline__ +void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) +{ + sys_cacheflush(0, ~0, BCACHE); + sync_mem(); + regs->cp0_epc = pc; + /* + * New thread looses kernel priviledges + */ + regs->cp0_status = (regs->cp0_status & ~ST0_KSU) | KSU_USER; + regs->reg29 = sp; +} + +#ifdef __KERNEL__ + +/* + * 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. + */ +asmlinkage void resume(struct task_struct *tsk, int offset); + +#define switch_to(n) \ + resume(n, ((int)(&((struct task_struct *)0)->tss))) + +/* + * Does the process account for user or for system time? + */ +#if defined (__R4000__) + +#define USES_USER_TIME(regs) (!((regs)->cp0_status & 0x18)) + +#else /* !defined (__R4000__) */ + +#define USES_USER_TIME(regs) (!((regs)->cp0_status & 0x4)) + +#endif /* !defined (__R4000__) */ + +#endif /* __KERNEL__ */ + +#endif /* !defined (__LANGUAGE_ASSEMBLY__) */ + +#endif /* __ASM_MIPS_PROCESSOR_H */ diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h index 97b08ce74..18cdb8387 100644 --- a/include/asm-mips/ptrace.h +++ b/include/asm-mips/ptrace.h @@ -1,110 +1,132 @@ /* * linux/include/asm-mips/ptrace.h * - * machine dependend structs and defines to help the user use + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 1995 by Waldorf GMBH + * written by Ralf Baechle + * + * Machine dependent structs and defines to help the user use * the ptrace system call. */ -#ifndef _ASM_MIPS_PTRACE_H -#define _ASM_MIPS_PTRACE_H +#ifndef __ASM_MIPS_PTRACE_H +#define __ASM_MIPS_PTRACE_H /* - * use ptrace (3 or 6, pid, PT_EXCL, data); to read or write - * the processes registers. - * - * This defines/structures corrospond to the register layout on stack - + * This defines/structures correspond to the register layout on stack - * if the order here is changed, it needs to be updated in - * arch/mips/fork.c:copy_process, asm/mips/signal.c:do_signal, - * asm-mips/ptrace.c, include/asm-mips/ptrace.h. + * include/asm-mips/stackframe.h */ - -#define IN_REG1 0 -#define IN_REG2 1 -#define IN_REG3 2 -#define IN_REG4 3 -#define IN_REG5 4 -#define IN_REG6 5 -#define IN_REG7 6 -#define IN_REG8 7 -#define IN_REG9 8 -#define IN_REG10 9 -#define IN_REG11 10 -#define IN_REG12 11 -#define IN_REG13 12 -#define IN_REG14 13 -#define IN_REG15 14 -#define IN_REG16 15 -#define IN_REG17 16 -#define IN_REG18 17 -#define IN_REG19 18 -#define IN_REG20 19 -#define IN_REG21 20 -#define IN_REG22 21 -#define IN_REG23 22 -#define IN_REG24 23 -#define IN_REG25 24 - +#define IN_REG1 5 +#define IN_REG2 6 +#define IN_REG3 7 +#define IN_REG4 8 +#define IN_REG5 9 +#define IN_REG6 10 +#define IN_REG7 11 +#define IN_REG8 12 +#define IN_REG9 13 +#define IN_REG10 14 +#define IN_REG11 15 +#define IN_REG12 16 +#define IN_REG13 17 +#define IN_REG14 18 +#define IN_REG15 19 +#define IN_REG16 20 +#define IN_REG17 21 +#define IN_REG18 22 +#define IN_REG19 23 +#define IN_REG20 24 +#define IN_REG21 25 +#define IN_REG22 26 +#define IN_REG23 27 +#define IN_REG24 28 +#define IN_REG25 29 /* - * k0 and k1 not saved + * k0/k1 unsaved */ -#define IN_REG28 25 -#define IN_REG29 26 -#define IN_REG30 27 -#define IN_REG31 28 +#define IN_REG28 30 +#define IN_REG29 31 +#define IN_REG30 32 +#define IN_REG31 33 /* * Saved special registers */ -#define FR_LO ((IN_REG31) + 1) -#define FR_HI ((IN_LO) + 1) +#define IN_LO 34 +#define IN_HI 35 /* - * Saved cp0 registers + * saved cp0 registers */ -#define IN_CP0_STATUS ((IN_LO) + 1) -#define IN_CP0_EPC ((IN_CP0_STATUS) + 1) -#define IN_CP0_ERROREPC ((IN_CP0_EPC) + 1) +#define IN_CP0_STATUS 36 +#define IN_CP0_EPC 37 +#define IN_CP0_CAUSE 38 /* - * Some goodies... + * Some goodies */ -#define IN_INTERRUPT ((IN_CP0_ERROREPC) + 1) -#define IN_ORIG_REG2 ((IN_INTERRUPT) + 1) +#define IN_INTERRUPT 39 +#define IN_ORIG_REG2 40 /* - * this struct defines the way the registers are stored on the - * stack during a system call/exception. As usual the registers - * k0/k1 aren't being saved. + * This struct defines the way the registers are stored on the stack during a + * system call/exception. As usual the registers k0/k1 aren't being saved. */ - struct pt_regs { /* + * Pad bytes for argument save space on the stack + * 20/40 Bytes for 32/64 bit code + */ + unsigned long pad0[5]; + + /* * saved main processor registers */ long reg1, reg2, reg3, reg4, reg5, reg6, reg7; long reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15; long reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23; long reg24, reg25, reg28, reg29, reg30, reg31; + /* * Saved special registers */ long lo; long hi; + /* * saved cp0 registers */ unsigned long cp0_status; unsigned long cp0_epc; - unsigned long cp0_errorepc; + unsigned long cp0_cause; + /* * Some goodies... */ unsigned long interrupt; long orig_reg2; + long pad1; }; +#ifdef __KERNEL__ + /* - * This function computes the interrupt number from the stack frame + * Does the process account for user or for system time? */ -#define pt_regs2irq(p) ((int) ((struct pt_regs *)p)->interrupt) +#if defined (__R4000__) + +#define user_mode(regs) ((regs)->cp0_status & 0x10) + +#else /* !defined (__R4000__) */ + +#define user_mode(regs) (!((regs)->cp0_status & 0x8)) + +#endif /* !defined (__R4000__) */ + +extern void show_regs(struct pt_regs *); +#endif -#endif /* _ASM_MIPS_PTRACE_H */ +#endif /* __ASM_MIPS_PTRACE_H */ diff --git a/include/asm-mips/regdef.h b/include/asm-mips/regdef.h index 1fbe8f19f..ec455790e 100644 --- a/include/asm-mips/regdef.h +++ b/include/asm-mips/regdef.h @@ -5,17 +5,17 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994 by Ralf Baechle + * Copyright (C) 1994, 1995 by Ralf Baechle */ -#ifndef _ASM_MIPS_REGSDEFS_H_ -#define _ASM_MIPS_REGSDEFS_H_ +#ifndef __ASM_MIPS_REGDEF_H +#define __ASM_MIPS_REGDEF_H /* * Symbolic register names */ #define zero $0 /* wired zero */ -#define AT $1 /* assembler temp (uprcase, because ".set at") */ +#define AT $1 /* assembler temp - uppercase because of ".set at" */ #define v0 $2 /* return value */ #define v1 $3 #define a0 $4 /* argument registers */ @@ -47,4 +47,4 @@ #define fp $30 /* frame pointer */ #define ra $31 /* return address */ -#endif /* _ASM_MIPS_REGSDEFS_H_ */ +#endif /* __ASM_MIPS_REGDEF_H */ diff --git a/include/asm-mips/resource.h b/include/asm-mips/resource.h new file mode 100644 index 000000000..001f92435 --- /dev/null +++ b/include/asm-mips/resource.h @@ -0,0 +1,25 @@ +#ifndef __ASM_MIPS_RESOURCE_H +#define __ASM_MIPS_RESOURCE_H + +/* + * Resource limits + */ + +#define RLIMIT_CPU 0 /* CPU time in ms */ +#define RLIMIT_FSIZE 1 /* Maximum filesize */ +#define RLIMIT_DATA 2 /* max data size */ +#define RLIMIT_STACK 3 /* max stack size */ +#define RLIMIT_CORE 4 /* max core file size */ +#define RLIMIT_NOFILE 5 /* max number of open files */ +#define RLIMIT_VMEM 6 /* mapped memory */ +#define RLIMIT_AS RLIMIT_VMEM +#define RLIMIT_RSS 7 /* max resident set size */ +#define RLIMIT_NPROC 8 /* max number of processes */ + +#ifdef notdef +#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space*/ +#endif + +#define RLIM_NLIMITS 9 + +#endif /* __ASM_MIPS_RESOURCE_H */ diff --git a/include/asm-mips/sched.h b/include/asm-mips/sched.h deleted file mode 100644 index 661675a37..000000000 --- a/include/asm-mips/sched.h +++ /dev/null @@ -1,240 +0,0 @@ -#ifndef _ASM_MIPS_SCHED_H -#define _ASM_MIPS_SCHED_H - -#include <asm/system.h> - -/* - * System setup and hardware bug flags.. - */ -extern int hard_math; -extern int wp_works_ok; /* doesn't work on a 386 */ - -extern unsigned long intr_count; -extern unsigned long event; - -#define start_bh_atomic() \ -{int flags; save_flags(flags); cli(); intr_count++; restore_flags(flags)} - -#define end_bh_atomic() \ -{int flags; save_flags(flags); cli(); intr_count--; restore_flags(flags)} - -/* - * Bus types (default is ISA, but people can check others with these..) - * MCA_bus hardcoded to 0 for now. - */ -extern int EISA_bus; -#define MCA_bus 0 - -/* - * User space process size: 2GB. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. - */ -#define TASK_SIZE 0x80000000 - -#define NUM_FPA_REGS 32 - -struct mips_fpa_hard_struct { - float fp_regs[NUM_FPA_REGS]; - unsigned int control; -}; - -struct mips_fpa_soft_struct { - /* - * FIXME: no fpa emulator yet, but who cares? - */ - long dummy; - }; - -union mips_fpa_union { - struct mips_fpa_hard_struct hard; - struct mips_fpa_soft_struct soft; -}; - -#define INIT_FPA { \ - 0, \ -} - -struct tss_struct { - /* - * saved main processor registers - */ - unsigned long reg1, reg2, reg3, reg4, reg5, reg6, reg7; - unsigned long reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15; - unsigned long reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23; - unsigned long reg24, reg25, reg26, reg29, reg30, reg31; - /* - * saved cp0 registers - */ - unsigned int cp0_status; - unsigned long cp0_epc; - unsigned long cp0_errorepc; - unsigned long cp0_context; - /* - * saved fpa/fpa emulator stuff - */ - union mips_fpa_union fpa; - /* - * Other stuff associated with the process - */ - unsigned long cp0_badvaddr; - unsigned long errorcode; - unsigned long trap_no; - unsigned long fs; /* "Segment" pointer */ - unsigned long ksp; /* Kernel stack pointer */ - unsigned long pg_dir; /* L1 page table pointer */ -}; - -#define INIT_TSS { \ - /* \ - * saved main processor registers \ - */ \ - 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, \ - /* \ - * saved cp0 registers \ - */ \ - 0, 0, 0, 0, \ - /* \ - * saved fpa/fpa emulator stuff \ - */ \ - INIT_FPA, \ - /* \ - * Other stuff associated with the process\ - */ \ - 0, 0, 0, KERNEL_DS, 0, 0 \ -} - -struct task_struct { - /* - * these are hardcoded - don't touch - */ - volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ - long counter; - long priority; - unsigned long signal; - unsigned long blocked; /* bitmap of masked signals */ - unsigned long flags; /* per process flags, defined below */ - int errno; - int debugreg[8]; /* Hardware debugging registers */ - struct exec_domain *exec_domain; - /* - * various fields - */ - struct linux_binfmt *binfmt; - struct task_struct *next_task, *prev_task; - struct sigaction sigaction[32]; - unsigned long saved_kernel_stack; - unsigned long kernel_stack_page; - int exit_code, exit_signal; - unsigned long personality; - int dumpable:1; - int did_exec:1; - int pid,pgrp,session,leader; - int groups[NGROUPS]; - /* - * pointers to (original) parent process, youngest child, younger - * sibling, older sibling, respectively. (p->father can be replaced - * with p->p_pptr->pid) - */ - struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr; - struct wait_queue *wait_chldexit; /* for wait4() */ - unsigned short uid,euid,suid,fsuid; - unsigned short gid,egid,sgid,fsgid; - unsigned long timeout; - unsigned long it_real_value, it_prof_value, it_virt_value; - unsigned long it_real_incr, it_prof_incr, it_virt_incr; - long utime, stime, cutime, cstime, start_time; - struct rlimit rlim[RLIM_NLIMITS]; - unsigned short used_math; - char comm[16]; - /* - * virtual 86 mode stuff - */ - struct vm86_struct * vm86_info; - unsigned long screen_bitmap; - unsigned long v86flags, v86mask, v86mode; - /* - * file system info - */ - int link_count; - struct tty_struct *tty; /* NULL if no tty */ - /* - * ipc stuff - */ - struct sem_undo *semundo; - /* - * ldt for this task - used by Wine. If NULL, default_ldt is used - */ - struct desc_struct *ldt; - /* - * tss for this task - */ - struct tss_struct tss; - /* - * filesystem information - */ - struct fs_struct fs[1]; - /* - * open file information - */ - struct files_struct files[1]; - /* - * memory management info - */ - struct mm_struct mm[1]; -}; - -/* - * INIT_TASK is used to set up the first task table, touch at - * your own risk!. Base=0, limit=0x1fffff (=2MB) - */ -#define INIT_TASK \ -/* state etc */ { 0,15,15,0,0,0,0, \ -/* debugregs */ { 0, }, \ -/* exec domain */&default_exec_domain, \ -/* binfmt */ NULL, \ -/* schedlink */ &init_task,&init_task, \ -/* signals */ {{ 0, },}, \ -/* stack */ 0,(unsigned long) &init_kernel_stack, \ -/* ec,brk... */ 0,0,0,0,0, \ -/* pid etc.. */ 0,0,0,0, \ -/* suppl grps*/ {NOGROUP,}, \ -/* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \ -/* uid etc */ 0,0,0,0,0,0,0,0, \ -/* timeout */ 0,0,0,0,0,0,0,0,0,0,0,0, \ -/* rlimits */ { {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ - {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ - { 0, LONG_MAX}, {LONG_MAX, LONG_MAX}}, \ -/* math */ 0, \ -/* comm */ "swapper", \ -/* vm86_info */ NULL, 0, 0, 0, 0, \ -/* fs info */ 0,NULL, \ -/* ipc */ NULL, \ -/* ldt */ NULL, \ -/* tss */ INIT_TSS, \ -/* fs */ { INIT_FS }, \ -/* files */ { INIT_FILES }, \ -/* mm */ { INIT_MM } \ -} - -#ifdef __KERNEL__ - -/* - * 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. - * This also clears the TS-flag if the task we switched to has used - * tha math co-processor latest. - */ -#define switch_to(tsk) \ - __asm__(""::); /* fix me */ - -/* - * Does the process account for user or for system time? - */ -#define USES_USER_TIME(regs) (!((regs)->cp0_status & 0x18)) - -#endif /* __KERNEL__ */ - -#endif /* _ASM_MIPS_SCHED_H */ diff --git a/include/asm-mips/segment.h b/include/asm-mips/segment.h index 511c499c8..73c0de45f 100644 --- a/include/asm-mips/segment.h +++ b/include/asm-mips/segment.h @@ -5,223 +5,193 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994 by Ralf Baechle + * Copyright (C) 1994, 1995 by Ralf Baechle * */ +#ifndef __ASM_MIPS_SEGMENT_H +#define __ASM_MIPS_SEGMENT_H -#ifndef _ASM_MIPS_SEGMENT_H_ -#define _ASM_MIPS_SEGMENT_H_ - -#define KERNEL_CS 0x80000000 -#define KERNEL_DS KERNEL_CS +#ifndef __LANGUAGE_ASSEMBLY__ +/* + * Uh, these should become the main single-value transfer routines.. + * They automatically use the right size if we just have the right + * pointer type.. + */ +#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))) +#define get_user(ptr) __get_user((ptr),sizeof(*(ptr))) -#define USER_CS 0x00000000 -#define USER_DS USER_CS +/* + * This is a silly but good way to make sure that + * the __put_user function is indeed always optimized, + * and that we use the correct sizes.. + */ +extern int bad_user_access_length(void); -#ifndef __ASSEMBLY__ +/* I should make this use unaligned transfers etc.. */ +static inline void __put_user(unsigned long x, void * y, int size) +{ + switch (size) { + case 1: + *(char *) y = x; + break; + case 2: + *(short *) y = x; + break; + case 4: + *(int *) y = x; + break; + case 8: + *(long *) y = x; + break; + default: + bad_user_access_length(); + } +} -static inline unsigned char get_user_byte(const char * addr) +/* I should make this use unaligned transfers etc.. */ +static inline unsigned long __get_user(void * y, int size) { - unsigned char _v; + switch (size) { + case 1: + return *(unsigned char *) y; + case 2: + return *(unsigned short *) y; + case 4: + return *(unsigned int *) y; + case 8: + return *(unsigned long *) y; + default: + return bad_user_access_length(); + } +} +#endif /* __LANGUAGE_ASSEMBLY__ */ - __asm__ ("lbu\t%0,(%1)":"=r" (_v):"r" (*addr)); +/* + * Memory segments (32bit kernel mode addresses) + */ +#define KUSEG 0x00000000 +#define KSEG0 0x80000000 +#define KSEG1 0xa0000000 +#define KSEG2 0xc0000000 +#define KSEG3 0xe0000000 - return _v; -} +/* + * Returns the kernel segment base of a given address + */ +#define KSEGX(a) (a & 0xe0000000) -#define get_fs_byte(addr) get_user_byte((char *)(addr)) +/* + * Returns the physical address of a KSEG0/KSEG1 address + */ -static inline unsigned short get_user_word(const short *addr) -{ - unsigned short _v; +#define PHYSADDR(a) ((unsigned long)a & 0x1fffffff) - __asm__ ("lhu\t%0,(%1)":"=r" (_v):"r" (*addr)); +/* + * Map an address to a certain kernel segment + */ - return _v; -} +#define KSEG0ADDR(a) (((unsigned long)a & 0x1fffffff) | KSEG0) +#define KSEG1ADDR(a) (((unsigned long)a & 0x1fffffff) | KSEG1) +#define KSEG2ADDR(a) (((unsigned long)a & 0x1fffffff) | KSEG2) +#define KSEG3ADDR(a) (((unsigned long)a & 0x1fffffff) | KSEG3) -#define get_fs_word(addr) get_user_word((short *)(addr)) -static inline unsigned long get_user_long(const int *addr) +/* + * Memory segments (64bit kernel mode addresses) + */ +#define XKUSEG 0x0000 0000 0000 0000 +#define XKSSEG 0x4000 0000 0000 0000 +#define XKPHYS 0x8000 0000 0000 0000 +#define XKSEG 0xc000 0000 0000 0000 +#define CKSEG0 0xffff ffff 8000 0000 +#define CKSEG1 0xffff ffff a000 0000 +#define CKSSEG 0xffff ffff c000 0000 +#define CKSEG3 0xffff ffff e000 0000 + +#ifndef __LANGUAGE_ASSEMBLY__ +/* + * These are deprecated + */ + +#define get_fs_byte(addr) get_user_byte((char *)(addr)) +static inline unsigned char get_user_byte(const char *addr) { - unsigned long _v; + return *addr; +} - __asm__ ("lwu\t%0,(%1)":"=r" (_v):"r" (*addr)); \ - return _v; +/* + * Beware: the xxx_fs_word functions work on 16bit words! + */ +#define get_fs_word(addr) get_user_word((short *)(addr)) +static inline unsigned short get_user_word(const short *addr) +{ + return *addr; } #define get_fs_long(addr) get_user_long((int *)(addr)) - -static inline unsigned long get_user_dlong(const int *addr) +static inline unsigned long get_user_long(const int *addr) { - unsigned long _v; - - __asm__ ("ld\t%0,(%1)":"=r" (_v):"r" (*addr)); \ - return _v; + return *addr; } -#define get_fs_dlong(addr) get_user_dlong((int *)(addr)) - -static inline void put_user_byte(char val,char *addr) +#define get_fs_dlong(addr) get_user_dlong((long long *)(addr)) +static inline unsigned long get_user_dlong(const long long *addr) { -__asm__ ("sb\t%0,(%1)": /* no outputs */ :"r" (val),"r" (*addr)); + return *addr; } #define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr)) - -static inline void put_user_word(short val,short * addr) +static inline void put_user_byte(char val,char *addr) { -__asm__ ("sh\t%0,(%1)": /* no outputs */ :"r" (val),"r" (*addr)); + *addr = val; } #define put_fs_word(x,addr) put_user_word((x),(short *)(addr)) - -static inline void put_user_long(unsigned long val,int * addr) +static inline void put_user_word(short val,short * addr) { -__asm__ ("sw\t%0,(%1)": /* no outputs */ :"r" (val),"r" (*addr)); + *addr = val; } #define put_fs_long(x,addr) put_user_long((x),(int *)(addr)) - -static inline void put_user_dlong(unsigned long val,int * addr) +static inline void put_user_long(unsigned long val,int * addr) { -__asm__ ("sd\t%0,(%1)": /* no outputs */ :"r" (val),"r" (*addr)); + *addr = val; } #define put_fs_dlong(x,addr) put_user_dlong((x),(int *)(addr)) - -/* - * These following two variables are defined in mips/head.S. - */ -extern unsigned long segment_fs; - -static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n) -{ - __asm__( - ".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tlbu\t$1,(%2)\n\t" - "addiu\t%2,%2,1\n\t" - "sb\t$1,(%1)\n\t" - "addiu\t%0,%0,-1\n\t" - "bne\t$0,%0,1b\n\t" - "addiu\t%1,%1,1\n\t" - ".set\tat\n\t" - ".set\treorder" - : /* no outputs */ - :"d" (n),"d" (((long) to)| segment_fs),"d" ((long) from) - :"$1"); -} - -static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n) -{ - /* - * Use put_user_byte to avoid trouble with alignment. - */ - switch (n) { - case 0: - return; - case 1: - put_user_byte(*(const char *) from, (char *) to); - return; - case 2: - put_user_byte(*(const char *) from, (char *) to); - put_user_byte(*(1+(const char *) from), 1+(char *) to); - return; - case 3: - put_user_byte(*((const char *) from), (char *) to); - put_user_byte(*(1+(const char *) from), 1+(char *) to); - put_user_byte(*(2+(const char *) from), 2+(char *) to); - return; - case 4: - put_user_byte(*((const char *) from), (char *) to); - put_user_byte(*(1+(const char *) from), 1+(char *) to); - put_user_byte(*(2+(const char *) from), 2+(char *) to); - put_user_byte(*(3+(const char *) from), 3+(char *) to); - return; - } - - __generic_memcpy_tofs(to, from, n); - - return; -} - -static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n) +static inline void put_user_dlong(unsigned long val,long long * addr) { - __asm__( - ".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tlbu\t$1,(%2)\n\t" - "addiu\t%2,%2,1\n\t" - "sb\t$1,(%1)\n\t" - "addiu\t%0,%0,-1\n\t" - "bne\t$0,%0,1b\n\t" - "addiu\t%1,%1,1\n\t" - ".set\tat\n\t" - ".set\treorder" - : /* no outputs */ - :"d" (n),"d" ((long) to),"d" (((long) from | segment_fs)) - :"$1","memory"); + *addr = val; } -static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n) -{ - /* - * Use put_user_byte to avoid trouble with alignment. - */ - switch (n) { - case 0: - return; - case 1: - *(char *)to = get_user_byte((const char *) from); - return; - case 2: - *(char *) to = get_user_byte((const char *) from); - *(char *) to = get_user_byte(1+(const char *) from); - return; - case 3: - *(char *) to = get_user_byte((const char *) from); - *(char *) to = get_user_byte(1+(const char *) from); - *(char *) to = get_user_byte(2+(const char *) from); - return; - case 4: - *(char *) to = get_user_byte((const char *) from); - *(char *) to = get_user_byte(1+(const char *) from); - *(char *) to = get_user_byte(2+(const char *) from); - *(char *) to = get_user_byte(3+(const char *) from); - return; - } +#define memcpy_fromfs(to, from, n) memcpy((to),(from),(n)) - - __generic_memcpy_fromfs(to, from, n); - return; -} +#define memcpy_tofs(to, from, n) memcpy((to),(from),(n)) -#define memcpy_fromfs(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy_fromfs((to),(from),(n)) : \ - __generic_memcpy_fromfs((to),(from),(n))) +/* + * For segmented architectures, these are used to specify which segment + * to use for the above functions. + * + * MIPS is not segmented, so these are just dummies. + */ -#define memcpy_tofs(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy_tofs((to),(from),(n)) : \ - __generic_memcpy_tofs((to),(from),(n))) +#define KERNEL_DS 0 +#define USER_DS 1 static inline unsigned long get_fs(void) { - return segment_fs; + return 0; } static inline unsigned long get_ds(void) { - return KERNEL_DS; + return 0; } static inline void set_fs(unsigned long val) { - segment_fs = val; } -#endif +#endif /* !__LANGUAGE_ASSEMBLY__ */ -#endif /* _ASM_MIPS_SEGMENT_H_ */ +#endif /* __ASM_MIPS_SEGMENT_H */ diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h index 6c66d6271..998d95c14 100644 --- a/include/asm-mips/signal.h +++ b/include/asm-mips/signal.h @@ -1,28 +1,124 @@ -#ifndef _ASM_MIPS_SIGNAL_H -#define _ASM_MIPS_SIGNAL_H +#ifndef __ASM_MIPS_SIGNAL_H +#define __ASM_MIPS_SIGNAL_H -#ifdef __KERNEL__ +#if 0 +/* The Linux/i386 definition */ +typedef unsigned long sigset_t; /* at least 32 bits */ +#endif -struct sigcontext_struct { - /* - * In opposite to the SVr4 implentation in Risc/OS the - * sc_ra points to an address suitable to "jr ra" to. - * Registers that are callee saved by convention aren't - * being saved on entry of a signal handler. - */ - unsigned long sc_at; - unsigned long sc_v0, sc_v1; - unsigned long sc_a0, sc_a1, sc_a2, sc_a3; - unsigned long sc_t0, sc_t1, sc_t2, sc_t3, sc_t4; - unsigned long sc_t5, sc_t6, sc_t7, sc_t8, sc_t9; +#if 1 +/* For now ... */ +#include <asm/types.h> +typedef __u64 sigset_t; +#else +/* This is what we should really use ... */ +typedef struct { + unsigned int sigbits[4]; +} sigset_t; +#endif + +#define _NSIG 65 +#define NSIG _NSIG + +/* + * For 1.3.0 Linux/MIPS changed the signal numbers to be compatible the ABI. + */ +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGIOT 6 +#define SIGABRT SIGIOT +#define SIGEMT 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGBUS 10 +#define SIGSEGV 11 +#define SIGSYS 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGUSR1 16 +#define SIGUSR2 17 +#define SIGCHLD 18 +#define SIGCLD SIGCHLD +#define SIGPWR 19 +#define SIGWINCH 20 +#define SIGURG 21 +#define SIGIO 22 +#define SIGPOLL SIGIO +#define SIGSTOP 23 +#define SIGTSTP 24 +#define SIGCONT 25 +#define SIGTTIN 26 +#define SIGTTOU 27 +#define SIGVTALRM 28 +#define SIGPROF 29 +#define SIGXCPU 30 +#define SIGXFSZ 31 + +/* + * sa_flags values: SA_STACK is not currently supported, but will allow the + * usage of signal stacks by using the (now obsolete) sa_restorer field in + * the sigaction structure as a stack pointer. This is now possible due to + * the changes in signal handling. LBT 010493. + * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the + * SA_RESTART flag to get restarting signals (which were the default long ago) + */ +#define SA_STACK 0x1 +#define SA_ONSTACK SA_STACK +#define SA_RESTART 0x4 +#define SA_NOCLDSTOP 0x20000 +/* Non ABI signals */ +#define SA_INTERRUPT 0x01000000 +#define SA_NOMASK 0x02000000 +#define SA_ONESHOT 0x04000000 + +#define SIG_BLOCK 1 /* for blocking signals */ +#define SIG_UNBLOCK 2 /* for unblocking signals */ +#define SIG_SETMASK 3 /* for setting the signal mask */ + +/* Type of a signal handler. */ +typedef void (*__sighandler_t)(int); + +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ + +struct sigaction { + unsigned int sa_flags; + __sighandler_t sa_handler; + sigset_t sa_mask; + void (*sa_restorer)(void); +#if __mips <= 3 /* - * Old userstack pointer ($29) + * For 32 bit code we have to pad struct sigaction to get + * constant size for the ABI */ - unsigned long sc_sp; + int pad0[2]; /* reserved */ +#endif +}; + +#ifdef __KERNEL__ + +/* + * This struct isn't in the ABI, so we continue to use the old + * pre 1.3 definition. Needs to be changed for 64 bit kernels, + * but it's 4am ... + */ +struct sigcontext_struct { + unsigned long sc_at, sc_v0, sc_v1, sc_a0, sc_a1, sc_a2, sc_a3; + unsigned long sc_t0, sc_t1, sc_t2, sc_t3, sc_t4, sc_t5, sc_t6, sc_t7; + unsigned long sc_s0, sc_s1, sc_s2, sc_s3, sc_s4, sc_s5, sc_s6, sc_s7; + unsigned long sc_t8, sc_t9, sc_gp, sc_sp, sc_fp, sc_ra; + + unsigned long sc_epc; + unsigned long sc_cause; unsigned long oldmask; }; #endif -#endif /* _ASM_MIPS_SIGNAL_H */ +#endif /* __ASM_MIPS_SIGNAL_H */ diff --git a/include/asm-mips/slots.h b/include/asm-mips/slots.h index fa5ae9fcb..4b9eb358c 100644 --- a/include/asm-mips/slots.h +++ b/include/asm-mips/slots.h @@ -1,11 +1,11 @@ /* * include/asm-mips/slots.h * + * Copyright (C) 1994 by Waldorf Electronics * Written by Ralf Baechle - * Copyright (C) 1994 by Waldorf GMBH */ -#ifndef _ASM_MIPS_SLOTS_H -#define _ASM_MIPS_SLOTS_H +#ifndef __ASM_MIPS_SLOTS_H +#define __ASM_MIPS_SLOTS_H /* * SLOTSPACE is the address to which the physical address 0 @@ -14,4 +14,4 @@ */ #define SLOTSPACE 0xe1000000 -#endif /* _ASM_MIPS_SLOTS_H */ +#endif /* __ASM_MIPS_SLOTS_H */ diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index 0c3c4699c..b3b69f3c6 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h @@ -1,59 +1,54 @@ /* * include/asm-mips/stackframe.h * - * Copyright (C) 1994 Waldorf GMBH + * Copyright (C) 1994, 1995 Waldorf Electronics * written by Ralf Baechle */ -#ifndef _ASM_MIPS_STACKFRAME_H_ -#define _ASM_MIPS_STACKFRAME_H_ +#ifndef __ASM_MIPS_STACKFRAME_H +#define __ASM_MIPS_STACKFRAME_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 asm/mips/fork.c:copy_process, asm/mips/signal.c:do_signal, - * asm-mips/ptrace.c, include/asm-mips/ptrace.h - * and asm-mips/ptrace - */ - -/* - * Offsets into the Interrupt stackframe. + * 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*5 bytes are argument save space for C subroutines. */ -#define FR_REG1 0 -#define FR_REG2 4 -#define FR_REG3 8 -#define FR_REG4 12 -#define FR_REG5 16 -#define FR_REG6 20 -#define FR_REG7 24 -#define FR_REG8 28 -#define FR_REG9 32 -#define FR_REG10 36 -#define FR_REG11 40 -#define FR_REG12 44 -#define FR_REG13 48 -#define FR_REG14 52 -#define FR_REG15 56 -#define FR_REG16 60 -#define FR_REG17 64 -#define FR_REG18 68 -#define FR_REG19 72 -#define FR_REG20 76 -#define FR_REG21 80 -#define FR_REG22 84 -#define FR_REG23 88 -#define FR_REG24 92 -#define FR_REG25 96 +#define FR_REG1 (PTRSIZE*5) +#define FR_REG2 ((FR_REG1) + 4) +#define FR_REG3 ((FR_REG2) + 4) +#define FR_REG4 ((FR_REG3) + 4) +#define FR_REG5 ((FR_REG4) + 4) +#define FR_REG6 ((FR_REG5) + 4) +#define FR_REG7 ((FR_REG6) + 4) +#define FR_REG8 ((FR_REG7) + 4) +#define FR_REG9 ((FR_REG8) + 4) +#define FR_REG10 ((FR_REG9) + 4) +#define FR_REG11 ((FR_REG10) + 4) +#define FR_REG12 ((FR_REG11) + 4) +#define FR_REG13 ((FR_REG12) + 4) +#define FR_REG14 ((FR_REG13) + 4) +#define FR_REG15 ((FR_REG14) + 4) +#define FR_REG16 ((FR_REG15) + 4) +#define FR_REG17 ((FR_REG16) + 4) +#define FR_REG18 ((FR_REG17) + 4) +#define FR_REG19 ((FR_REG18) + 4) +#define FR_REG20 ((FR_REG19) + 4) +#define FR_REG21 ((FR_REG20) + 4) +#define FR_REG22 ((FR_REG21) + 4) +#define FR_REG23 ((FR_REG22) + 4) +#define FR_REG24 ((FR_REG23) + 4) +#define FR_REG25 ((FR_REG24) + 4) /* * $26 (k0) and $27 (k1) not saved */ -#define FR_REG28 100 -#define FR_REG29 104 -#define FR_REG30 108 -#define FR_REG31 112 +#define FR_REG28 ((FR_REG25) + 4) +#define FR_REG29 ((FR_REG28) + 4) +#define FR_REG30 ((FR_REG29) + 4) +#define FR_REG31 ((FR_REG30) + 4) /* * Saved special registers @@ -66,111 +61,129 @@ */ #define FR_STATUS ((FR_HI) + 4) #define FR_EPC ((FR_STATUS) + 4) -#define FR_ERROREPC ((FR_EPC) + 4) +#define FR_CAUSE ((FR_EPC) + 4) /* * Some goodies... */ -#define FR_INTERRUPT ((FR_ERROREPC) + 4) +#define FR_INTERRUPT ((FR_CAUSE) + 4) #define FR_ORIG_REG2 ((FR_INTERRUPT) + 4) +#define FR_PAD1 ((FR_ORIG_REG2) + 4) /* - * Size of stack frame + * Size of stack frame, word/double word alignment */ -#define FR_SIZE ((FR_ORIG_REG2) + 4) +#define FR_SIZE ((((FR_PAD1) + 4) + (PTRSIZE-1)) & ~(PTRSIZE-1)) + +#ifdef __R4000__ -#define SAVE_ALL \ - mfc0 k0,CP0_STATUS; \ - andi k0,k0,0x18; /* extract KSU bits */ \ - beq zero,k0,1f; \ - move k1,sp; \ - /* \ - * Called from user mode, new stack \ - */ \ - lw k1,_kernelsp; \ -1: move k0,sp; \ - subu sp,k1,FR_SIZE; \ - sw k0,FR_REG29(sp); \ - sw $2,FR_REG2(sp); \ - sw $2,FR_ORIG_REG2(sp); \ - mfc0 v0,CP0_STATUS; \ - sw v0,FR_STATUS(sp); \ - mfc0 v0,CP0_EPC; \ - sw v0,FR_EPC(sp); \ - mfc0 v0,CP0_ERROREPC; \ - sw v0,FR_ERROREPC(sp); \ - mfhi v0; \ - sw v0,FR_HI(sp); \ - mflo v0; \ - sw v0,FR_LO(sp); \ - sw $1,FR_REG1(sp); \ - sw $3,FR_REG3(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); \ +#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,FR_SIZE; \ + sw k0,FR_REG29(sp); \ + sw $2,FR_REG2(sp); \ + sw $2,FR_ORIG_REG2(sp); \ + mfc0 v0,CP0_STATUS; \ + sw v0,FR_STATUS(sp); \ + mfc0 v0,CP0_CAUSE; \ + sw v0,FR_CAUSE(sp); \ + mfc0 v0,CP0_EPC; \ + sw v0,FR_EPC(sp); \ + mfhi v0; \ + sw v0,FR_HI(sp); \ + mflo v0; \ + sw v0,FR_LO(sp); \ + sw $1,FR_REG1(sp); \ + sw $3,FR_REG3(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) -#define RESTORE_ALL \ - lw v0,FR_ERROREPC(sp); \ - lw v1,FR_EPC(sp); \ - mtc0 v0,CP0_ERROREPC; \ - lw v0,FR_HI(sp); \ - mtc0 v1,CP0_EPC; \ - lw v1,FR_LO(sp); \ - mthi v0; \ - lw v0,FR_STATUS(sp); \ - mtlo v1; \ - mtc0 v0,CP0_STATUS; \ - 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); \ +/* + * Note that we restore the IE flags from stack. This means + * that a modified IE mask will be nullified. + */ +#define RESTORE_ALL \ + .set mips3; \ + mfc0 t0,CP0_STATUS; \ + ori t0,0x1f; \ + xori t0,0x1f; \ + mtc0 t0,CP0_STATUS; \ + \ + lw v0,FR_STATUS(sp); \ + lw v1,FR_LO(sp); \ + mtc0 v0,CP0_STATUS; \ + mtlo v1; \ + lw v0,FR_HI(sp); \ + 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 sp,FR_REG29(sp); /* Deallocate stack */ \ - eret + .set mips0 + +#else /* !defined (__R4000__) */ + +#error "Implement SAVE_ALL and RESTORE_ALL!" + +#endif /* !defined (__R4000__) */ -#endif /* _ASM_MIPS_STACKFRAME_H_ */ +#endif /* __ASM_MIPS_STACKFRAME_H */ diff --git a/include/asm-mips/stat.h b/include/asm-mips/stat.h new file mode 100644 index 000000000..ffae5bbcf --- /dev/null +++ b/include/asm-mips/stat.h @@ -0,0 +1,55 @@ +#ifndef __ASM_MIPS_STAT_H +#define __ASM_MIPS_STAT_H + +#include <asm/types.h> + +struct old_stat { + unsigned int st_dev; + unsigned int st_ino; + unsigned int st_mode; + unsigned int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned int st_rdev; + long st_size; + unsigned int st_atime, st_res1; + unsigned int st_mtime, st_res2; + unsigned int st_ctime, st_res3; + unsigned int st_blkize; + int st_blocks; + unsigned int st_flags; + unsigned int st_gen; +}; + +struct new_stat { + dev_t st_dev; + long st_pad1[3]; /* Reserved for network id */ + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + long st_pad2[2]; + off_t st_size; + long st_pad3; + /* + * Actually this should be timestruc_t st_atime, st_mtime and st_ctime + * but we don't have it under Linux. + */ + time_t st_atime; + long reserved0; + time_t st_mtime; + long reserved1; + time_t st_ctime; + long reserved2; + long st_blksize; + long st_blocks; + char st_fstype[16]; /* Filesystem type name */ + long st_pad4[8]; + /* Linux specific fields */ + unsigned int st_flags; + unsigned int st_gen; +}; + +#endif /* __ASM_MIPS_STAT_H */ diff --git a/include/asm-mips/statfs.h b/include/asm-mips/statfs.h new file mode 100644 index 000000000..3cae73206 --- /dev/null +++ b/include/asm-mips/statfs.h @@ -0,0 +1,25 @@ +#ifndef __ASM_MIPS_STATFS_H +#define __ASM_MIPS_STATFS_H + +typedef struct { + long val[2]; +} fsid_t; + +struct statfs { + long f_type; +#define f_fstyp f_type + long f_bsize; + long f_frsize; /* Fragment size - unsupported */ + long f_blocks; + long f_bfree; + long f_files; + long f_ffree; + + /* Linux specials */ + long f_bavail; + fsid_t f_fsid; + long f_namelen; + long f_spare[6]; +}; + +#endif /* __ASM_MIPS_STATFS_H */ diff --git a/include/asm-mips/string.h b/include/asm-mips/string.h index 0116fd026..1142eaf30 100644 --- a/include/asm-mips/string.h +++ b/include/asm-mips/string.h @@ -5,17 +5,13 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 1994 by Ralf Baechle + * Copyright (c) 1994, 1995 Waldorf Electronics + * written by Ralf Baechle */ +#ifndef __ASM_MIPS_STRING_H +#define __ASM_MIPS_STRING_H -#ifndef _ASM_MIPS_STRING_H_ -#define _ASM_MIPS_STRING_H_ - -#include <asm/mipsregs.h> - -#define __USE_PORTABLE_STRINGS_H_ - -extern inline char * strcpy(char * dest,const char *src) +extern __inline__ char * strcpy(char * dest, const char *src) { char *xdest = dest; @@ -23,20 +19,20 @@ extern inline char * strcpy(char * dest,const char *src) ".set\tnoreorder\n\t" ".set\tnoat\n" "1:\tlbu\t$1,(%1)\n\t" - "addiu\t%1,%1,1\n\t" + "addiu\t%1,1\n\t" "sb\t$1,(%0)\n\t" - "bne\t$0,$1,1b\n\t" - "addiu\t%0,%0,1\n\t" + "bnez\t$1,1b\n\t" + "addiu\t%0,1\n\t" ".set\tat\n\t" ".set\treorder" - : "=d" (dest), "=d" (src) + : "=r" (dest), "=r" (src) : "0" (dest), "1" (src) : "$1","memory"); return xdest; } -extern inline char * strncpy(char *dest, const char *src, size_t n) +extern __inline__ char * strncpy(char *dest, const char *src, size_t n) { char *xdest = dest; @@ -47,26 +43,23 @@ extern inline char * strncpy(char *dest, const char *src, size_t n) ".set\tnoreorder\n\t" ".set\tnoat\n" "1:\tlbu\t$1,(%1)\n\t" - "addiu\t%2,%2,-1\n\t" + "subu\t%2,%2,1\n\t" "sb\t$1,(%0)\n\t" - "beq\t$0,$1,2f\n\t" + "beqz\t$1,2f\n\t" "addiu\t%0,%0,1\n\t" - "bne\t$0,%2,1b\n\t" + "bnez\t%2,1b\n\t" "addiu\t%1,%1,1\n" "2:\n\t" ".set\tat\n\t" ".set\treorder\n\t" - : "=d" (dest), "=d" (src), "=d" (n) + : "=r" (dest), "=r" (src), "=r" (n) : "0" (dest), "1" (src), "2" (n) : "$1","memory"); return dest; } -#define __USE_PORTABLE_strcat -#define __USE_PORTABLE_strncat - -extern inline int strcmp(const char * cs,const char * ct) +extern __inline__ int strcmp(const char * cs, const char * ct) { int __res; @@ -75,16 +68,18 @@ extern inline int strcmp(const char * cs,const char * ct) ".set\tnoat\n\t" "lbu\t%2,(%0)\n" "1:\tlbu\t$1,(%1)\n\t" - "addiu\t%0,%0,1\n\t" + "addiu\t%0,1\n\t" "bne\t$1,%2,2f\n\t" - "addiu\t%1,%1,1\n\t" - "bne\t$0,%2,1b\n\t" + "addiu\t%1,1\n\t" + "bnez\t%2,1b\n\t" "lbu\t%2,(%0)\n\t" - STR(FILL_LDS) "\n\t" +#ifndef __R4000__ + "nop\n\t" +#endif "move\t%2,$1\n" - "2:\tsub\t%2,%2,$1\n" + "2:\tsubu\t%2,$1\n" "3:\t.set\tat\n\t" - ".set\treorder\n\t" + ".set\treorder" : "=d" (cs), "=d" (ct), "=d" (__res) : "0" (cs), "1" (ct) : "$1"); @@ -92,7 +87,7 @@ extern inline int strcmp(const char * cs,const char * ct) return __res; } -extern inline int strncmp(const char * cs,const char * ct,size_t count) +extern __inline__ int strncmp(const char * cs, const char * ct, size_t count) { char __res; @@ -100,15 +95,15 @@ extern inline int strncmp(const char * cs,const char * ct,size_t count) ".set\tnoreorder\n\t" ".set\tnoat\n" "1:\tlbu\t%3,(%0)\n\t" - "beq\t$0,%2,2f\n\t" + "beqz\t%2,2f\n\t" "lbu\t$1,(%1)\n\t" - "addiu\t%2,%2,-1\n\t" + "subu\t%2,1\n\t" "bne\t$1,%3,3f\n\t" - "addiu\t%0,%0,1\n\t" - "bne\t$0,%3,1b\n\t" - "addiu\t%1,%1,1\n" + "addiu\t%0,1\n\t" + "bnez\t%3,1b\n\t" + "addiu\t%1,1\n" "2:\tmove\t%3,$1\n" - "3:\tsub\t%3,%3,$1\n\t" + "3:\tsubu\t%3,$1\n\t" ".set\tat\n\t" ".set\treorder" : "=d" (cs), "=d" (ct), "=d" (count), "=d" (__res) @@ -118,13 +113,7 @@ extern inline int strncmp(const char * cs,const char * ct,size_t count) return __res; } -#define __USE_PORTABLE_strchr -#define __USE_PORTABLE_strlen -#define __USE_PORTABLE_strspn -#define __USE_PORTABLE_strpbrk -#define __USE_PORTABLE_strtok - -extern inline void * memset(void * s,char c,size_t count) +extern __inline__ void * memset(void * s, int c, size_t count) { void *xs = s; @@ -133,18 +122,17 @@ extern inline void * memset(void * s,char c,size_t count) __asm__ __volatile__( ".set\tnoreorder\n" "1:\tsb\t%3,(%0)\n\t" - "addiu\t%1,%1,-1\n\t" - "bne\t$0,%1,1b\n\t" - "addiu\t%3,%3,1\n\t" + "bne\t%0,%1,1b\n\t" + "addiu\t%0,%0,1\n\t" ".set\treorder" - : "=d" (s), "=d" (count) - : "0" (s), "d" (c), "1" (count) + : "=r" (s), "=r" (count) + : "0" (s), "r" (c), "1" (s + count - 1) : "memory"); return xs; } -extern inline void * memcpy(void * to, const void * from, size_t n) +extern __inline__ void * memcpy(void * to, const void * from, size_t n) { void *xto = to; @@ -154,20 +142,20 @@ extern inline void * memcpy(void * to, const void * from, size_t n) ".set\tnoreorder\n\t" ".set\tnoat\n" "1:\tlbu\t$1,(%1)\n\t" - "addiu\t%1,%1,1\n\t" + "addiu\t%1,1\n\t" "sb\t$1,(%0)\n\t" - "addiu\t%2,%2,-1\n\t" - "bne\t$0,%2,1b\n\t" - "addiu\t%0,%0,1\n\t" + "subu\t%2,1\n\t" + "bnez\t%2,1b\n\t" + "addiu\t%0,1\n\t" ".set\tat\n\t" ".set\treorder" - : "=d" (to), "=d" (from), "=d" (n) + : "=r" (to), "=r" (from), "=r" (n) : "0" (to), "1" (from), "2" (n) : "$1","memory" ); return xto; } -extern inline void * memmove(void * dest,const void * src, size_t n) +extern __inline__ void * memmove(void * dest,const void * src, size_t n) { void *xdest = dest; @@ -179,14 +167,14 @@ extern inline void * memmove(void * dest,const void * src, size_t n) ".set\tnoreorder\n\t" ".set\tnoat\n" "1:\tlbu\t$1,(%1)\n\t" - "addiu\t%1,%1,1\n\t" + "addiu\t%1,1\n\t" "sb\t$1,(%0)\n\t" - "addiu\t%2,%2,-1\n\t" - "bne\t$0,%2,1b\n\t" - "addiu\t%0,%0,1\n\t" + "subu\t%2,1\n\t" + "bnez\t%2,1b\n\t" + "addiu\t%0,1\n\t" ".set\tat\n\t" ".set\treorder" - : "=d" (dest), "=d" (src), "=d" (n) + : "=r" (dest), "=r" (src), "=r" (n) : "0" (dest), "1" (src), "2" (n) : "$1","memory" ); else @@ -194,39 +182,38 @@ extern inline void * memmove(void * dest,const void * src, size_t n) ".set\tnoreorder\n\t" ".set\tnoat\n" "1:\tlbu\t$1,-1(%1)\n\t" - "addiu\t%1,%1,-1\n\t" + "subu\t%1,1\n\t" "sb\t$1,-1(%0)\n\t" - "addiu\t%2,%2,-1\n\t" - "bne\t$0,%2,1b\n\t" - "addiu\t%0,%0,-1\n\t" + "subu\t%2,1\n\t" + "bnez\t%2,1b\n\t" + "subu\t%0,1\n\t" ".set\tat\n\t" ".set\treorder" - : "=d" (dest), "=d" (src), "=d" (n) + : "=r" (dest), "=r" (src), "=r" (n) : "0" (dest+n), "1" (src+n), "2" (n) : "$1","memory" ); return xdest; } -#define __USE_PORTABLE_memcmp - -static inline char * memscan(void * addr, unsigned char c, int size) +extern __inline__ void * memscan(void * addr, int c, size_t size) { if (!size) return addr; __asm__(".set\tnoreorder\n\t" ".set\tnoat\n" - "1:\tbeq\t$0,%1,2f\n\t" + "1:\tbeqz\t%1,2f\n\t" "lbu\t$1,(%0)\n\t" - "subu\t%1,%1,1\n\t" - "bne\t$0,%1,1b\n\t" - "addiu\t%0,%0,1\n\t" + "subu\t%1,1\n\t" + "bnez\t%1,1b\n\t" + "addiu\t%0,1\n\t" ".set\tat\n\t" ".set\treorder\n" "2:" - : "=d" (addr), "=d" (size) - : "0" (addr), "1" (size), "d" (c) + : "=r" (addr), "=r" (size) + : "0" (addr), "1" (size), "r" (c) : "$1"); return addr; } -#endif /* _ASM_MIPS_STRING_H_ */ + +#endif /* __ASM_MIPS_STRING_H */ diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 3a3029b31..ef8c51b21 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -5,85 +5,191 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994 by Ralf Baechle + * Copyright (C) 1994, 1995 by Ralf Baechle */ +#ifndef __ASM_MIPS_SYSTEM_H +#define __ASM_MIPS_SYSTEM_H -#ifndef _ASM_MIPS_SYSTEM_H_ -#define _ASM_MIPS_SYSTEM_H_ +#if defined (__R4000__) +#define sti() \ +__asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ + ".set\tnoat\n\t" \ + "mfc0\t$1,$12\n\t" \ + "ori\t$1,0x1f\n\t" \ + "xori\t$1,0x1e\n\t" \ + "mtc0\t$1,$12\n\t" \ + ".set\tat\n\t" \ + ".set\treorder" \ + : /* no outputs */ \ + : /* no inputs */ \ + : "$1") -#include <linux/types.h> -#include <asm/segment.h> -#include <asm/mipsregs.h> +#define cli() \ +__asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ + ".set\tnoat\n\t" \ + "mfc0\t$1,$12\n\t" \ + "ori\t$1,1\n\t" \ + "xori\t$1,1\n\t" \ + "mtc0\t$1,$12\n\t" \ + "nop\n\t" \ + "nop\n\t" \ + "nop\n\t" \ + ".set\tat\n\t" \ + ".set\treorder" \ + : /* no outputs */ \ + : /* no inputs */ \ + : "$1") +#else /* !defined (__R4000__) */ /* - * move_to_user_mode() doesn't switch to user mode on the mips, since - * that would run us into problems: The kernel is located at virtual - * address 0x80000000. If we now would switch over to user mode, we - * we would immediately get an address error exception. - * Anyway - we don't have problems with a task running in kernel mode, - * as long it's code is foolproof. + * Untested goodies for the R3000 based DECstation et al. */ -#define move_to_user_mode() - -#define sti() \ +#define sti() \ __asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ ".set\tnoat\n\t" \ - "mfc0\t$1,"STR(CP0_STATUS)"\n\t" \ - "ori\t$1,$1,0x1f\n\t" \ - "xori\t$1,$1,0x1e\n\t" \ - "mtc0\t$1,"STR(CP0_STATUS)"\n\t" \ - ".set\tat" \ + "mfc0\t$1,$12\n\t" \ + "ori\t$1,0x01\n\t" \ + "mtc0\t$1,$12\n\t" \ + ".set\tat\n\t" \ + ".set\treorder" \ : /* no outputs */ \ : /* no inputs */ \ : "$1") -#define cli() \ +#define cli() \ __asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ ".set\tnoat\n\t" \ - "mfc0\t$1,"STR(CP0_STATUS)"\n\t" \ - "ori\t$1,$1,1\n\t" \ - "xori\t$1,$1,1\n\t" \ - "mtc0\t$1,"STR(CP0_STATUS)"\n\t" \ - ".set\tat" \ + "mfc0\t$1,$12\n\t" \ + "ori\t$1,1\n\t" \ + "xori\t$1,1\n\t" \ + "mtc0\t$1,$12\n\t" \ + ".set\tat\n\t" \ + ".set\treorder" \ : /* no outputs */ \ : /* no inputs */ \ : "$1") +#endif /* !defined (__R4000__) */ #define nop() __asm__ __volatile__ ("nop") -extern ulong IRQ_vectors[256]; -extern ulong exception_handlers[256]; - -#define set_intr_gate(n,addr) \ - IRQ_vectors[n] = (ulong) (addr) - -#define set_except_vector(n,addr) \ - exception_handlers[n] = (ulong) (addr) - -/* - * atomic exchange of one word - * - * Fixme: This works only on MIPS ISA >=3 - */ -#define atomic_exchange(m,r) \ - __asm__ __volatile__( \ - "1:\tll\t$8,(%2)\n\t" \ - "move\t$9,%0\n\t" \ - "sc\t$9,(%2)\n\t" \ - "beq\t$0,$9,1b\n\t" \ - : "=r" (r) \ - : "0" (r), "r" (&(m)) \ - : "$8","$9","memory"); - #define save_flags(x) \ __asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ "mfc0\t%0,$12\n\t" \ + ".set\treorder" \ : "=r" (x)) \ #define restore_flags(x) \ __asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ "mtc0\t%0,$12\n\t" \ + ".set\treorder" \ : /* no output */ \ - : "r" (x)); \ + : "r" (x)) \ + +#define sync_mem() \ +__asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ + "sync\n\t" \ + ".set\treorder") \ + +/* + * The 8 and 16 bit variants have to disable interrupts temporarily. + * Both are currently unused. + */ +extern inline unsigned long xchg_u8(char * m, unsigned long val) +{ + unsigned long flags, retval; + + save_flags(flags); + sti(); + retval = *m; + *m = val; + restore_flags(flags); + + return retval; +} + +extern inline unsigned long xchg_u16(short * m, unsigned long val) +{ + unsigned long flags, retval; + + save_flags(flags); + sti(); + retval = *m; + *m = val; + restore_flags(flags); + + return retval; +} + +/* + * For 32 and 64 bit operands we can take advantage of ll and sc. + * FIXME: This doesn't work for R3000 machines. + */ +extern inline unsigned long xchg_u32(int * m, unsigned long val) +{ + unsigned long dummy; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "ll\t%0,(%1)\n" + "1:\tmove\t$1,%2\n\t" + "sc\t$1,(%1)\n\t" + "beqzl\t$1,1b\n\t" + "ll\t%0,(%1)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (val), "=r" (m), "=r" (dummy) + : "1" (m), "2" (val)); + + return val; +} + +/* + * Only used for 64 bit kernel. + */ +extern inline unsigned long xchg_u64(long * m, unsigned long val) +{ + unsigned long dummy; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "lld\t%0,(%1)\n" + "1:\tmove\t$1,%2\n\t" + "scd\t$1,(%1)\n\t" + "beqzl\t$1,1b\n\t" + "ll\t%0,(%1)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (val), "=r" (m), "=r" (dummy) + : "1" (m), "2" (val)); + + return val; +} + +extern inline void * xchg_ptr(void * m, void * val) +{ +#if __mips == 3 + return (void *) xchg_u64(m, (unsigned long) val); +#else + return (void *) xchg_u32(m, (unsigned long) val); +#endif +} + +extern unsigned long IRQ_vectors[16]; +extern unsigned long exception_handlers[32]; + +#define set_int_vector(n,addr) \ + IRQ_vectors[n] = (unsigned long) (addr) + +#define set_except_vector(n,addr) \ + exception_handlers[n] = (unsigned long) (addr) -#endif /* _ASM_MIPS_SYSTEM_H_ */ +#endif /* __ASM_MIPS_SYSTEM_H */ diff --git a/include/asm-mips/types.h b/include/asm-mips/types.h index 236996dd5..da0310a02 100644 --- a/include/asm-mips/types.h +++ b/include/asm-mips/types.h @@ -1,25 +1,111 @@ -#ifndef _ASM_MIPS_TYPES_H -#define _ASM_MIPS_TYPES_H +/* + * include/asm-mips/types.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 by Waldorf GMBH + * written by Ralf Baechle + */ +#ifndef __ASM_MIPS_TYPES_H +#define __ASM_MIPS_TYPES_H + +#ifndef _SIZE_T +#define _SIZE_T +typedef __SIZE_TYPE__ size_t; +#endif + +#ifndef _SSIZE_T +#define _SSIZE_T +typedef __SSIZE_TYPE__ ssize_t; +#endif + +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef __PTRDIFF_TYPE__ ptrdiff_t; +#endif + +#ifndef _TIME_T +#define _TIME_T +typedef long time_t; +#endif + +#ifndef _CLOCK_T +#define _CLOCK_T +typedef long clock_t; +#endif + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if ((~0UL) == 0xffffffff) + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +#else + +typedef __signed__ long __s64; +typedef unsigned long __u64; + +#endif /* * These aren't exported outside the kernel to avoid name space clashes */ #ifdef __KERNEL__ -typedef signed char s8; +typedef __signed char s8; typedef unsigned char u8; -typedef signed short s16; +typedef __signed short s16; typedef unsigned short u16; -typedef signed long s32; -typedef unsigned long u32; +typedef __signed int s32; +typedef unsigned int u32; + +#if ((~0UL) == 0xffffffff) -typedef signed long long s64; +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long s64; typedef unsigned long long u64; +#endif + +#else + +typedef __signed__ long s64; +typedef unsigned long u64; + +#endif #endif /* __KERNEL__ */ +typedef __s32 pid_t; +typedef __s32 uid_t; +typedef __s32 gid_t; +typedef __u32 dev_t; +typedef __u32 ino_t; +typedef __u32 mode_t; +typedef __u32 umode_t; +typedef __u32 nlink_t; +typedef long daddr_t; +typedef long off_t; + +#if 0 /* * These definitions double the definitions from <gnu/types.h>. */ @@ -35,5 +121,6 @@ typedef unsigned long long u64; #define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) #undef __FD_ZERO #define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) +#endif -#endif /* _ASM_MIPS_TYPES_H */ +#endif /* __ASM_MIPS_TYPES_H */ diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 0776f3fdb..94878e595 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -1,18 +1,14 @@ -#ifndef _ASM_MIPS_UNISTD_H_ -#define _ASM_MIPS_UNISTD_H_ +#ifndef __ASM_MIPS_UNISTD_H +#define __ASM_MIPS_UNISTD_H /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ type name(void) \ { \ register long __res __asm__ ("$2"); \ -__asm__ volatile (".set\tnoat\n\t" \ - "li\t$1,%1\n\t" \ - ".set\tat\n\t" \ - "syscall\n\t" \ - : "=d" (__res) \ - : "i" (__NR_##name) \ - : "$1"); \ +__asm__ volatile ("syscall" \ + : "=r" (__res) \ + : "0" (__NR_##name)); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ @@ -23,14 +19,11 @@ return -1; \ type name(atype a) \ { \ register long __res __asm__ ("$2"); \ -__asm__ volatile ("move\t$2,%2\n\t" \ - ".set\tnoat\n\t" \ - "li\t$1,%1\n\t" \ - ".set\tat\n\t" \ +__asm__ volatile ("move\t$4,%2\n\t" \ "syscall" \ - : "=d" (__res) \ - : "i" (__NR_##name),"d" ((long)(a)) \ - : "$1","$2"); \ + : "=r" (__res) \ + : "0" (__NR_##name),"r" ((long)(a)) \ + : "$4"); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ @@ -41,16 +34,13 @@ return -1; \ type name(atype a,btype b) \ { \ register long __res __asm__ ("$2"); \ -__asm__ volatile ("move\t$2,%2\n\t" \ - "move\t$3,%3\n\t" \ - ".set\tnoat\n\t" \ - "li\t$1,%1\n\t" \ - ".set\tat\n\t" \ +__asm__ volatile ("move\t$4,%2\n\t" \ + "move\t$5,%3\n\t" \ "syscall" \ - : "=d" (__res) \ - : "i" (__NR_##name),"d" ((long)(a)), \ - "d" ((long)(b))); \ - : "$1","$2","$3"); \ + : "=r" (__res) \ + : "0" (__NR_##name),"r" ((long)(a)), \ + "r" ((long)(b))); \ + : "$4","$5"); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ @@ -61,18 +51,15 @@ return -1; \ type name (atype a, btype b, ctype c) \ { \ register long __res __asm__ ("$2"); \ -__asm__ volatile ("move\t$2,%2\n\t" \ - "move\t$3,%3\n\t" \ - "move\t$4,%4\n\t" \ - ".set\tnoat\n\t" \ - "li\t$1,%1\n\t" \ - ".set\tat\n\t" \ +__asm__ volatile ("move\t$4,%2\n\t" \ + "move\t$5,%3\n\t" \ + "move\t$6,%4\n\t" \ "syscall" \ - : "=d" (__res) \ - : "i" (__NR_##name),"d" ((long)(a)), \ - "d" ((long)(b)), \ - "d" ((long)(c)) \ - : "$1","$2","$3","$4"); \ + : "=r" (__res) \ + : "0" (__NR_##name),"r" ((long)(a)), \ + "r" ((long)(b)), \ + "r" ((long)(c)) \ + : "$4","$5","$6"); \ if (__res>=0) \ return (type) __res; \ errno=-__res; \ @@ -83,21 +70,17 @@ return -1; \ type name (atype a, btype b, ctype c, dtype d) \ { \ register long __res __asm__ ("$2"); \ -__asm__ volatile (".set\tnoat\n\t" \ - "move\t$2,%2\n\t" \ - "move\t$3,%3\n\t" \ - "move\t$4,%4\n\t" \ - "move\t$5,%5\n\t" \ - ".set\tnoat\n\t" \ - "li\t$1,%1\n\t" \ - ".set\tat\n\t" \ +__asm__ volatile ("move\t$4,%2\n\t" \ + "move\t$5,%3\n\t" \ + "move\t$6,%4\n\t" \ + "move\t$7,%5\n\t" \ "syscall" \ - : "=d" (__res) \ - : "i" (__NR_##name),"d" ((long)(a)), \ - "d" ((long)(b)), \ - "d" ((long)(c)), \ - "d" ((long)(d)) \ - : "$1","$2","$3","$4","$5"); \ + : "=r" (__res) \ + : "0" (__NR_##name),"r" ((long)(a)), \ + "r" ((long)(b)), \ + "r" ((long)(c)), \ + "r" ((long)(d)) \ + : "$4","$5","$6","$7"); \ if (__res>=0) \ return (type) __res; \ errno=-__res; \ @@ -108,27 +91,59 @@ return -1; \ type name (atype a,btype b,ctype c,dtype d,etype e) \ { \ register long __res __asm__ ("$2"); \ -__asm__ volatile (".set\tnoat\n\t" \ - "move\t$2,%2\n\t" \ - "move\t$3,%3\n\t" \ - "move\t$4,%4\n\t" \ - "move\t$5,%5\n\t" \ - "move\t$6,%6\n\t" \ - ".set\tnoat\n\t" \ - "li\t$1,%1\n\t" \ - ".set\tat\n\t" \ +__asm__ volatile ("move\t$4,%2\n\t" \ + "move\t$5,%3\n\t" \ + "move\t$6,%4\n\t" \ + "move\t$7,%5\n\t" \ + "move\t$3,%6\n\t" \ "syscall" \ - : "=d" (__res) \ - : "i" (__NR_##name),"d" ((long)(a)), \ - "d" ((long)(b)), \ - "d" ((long)(c)), \ - "d" ((long)(d)), \ - "d" ((long)(e)) \ - : "$1","$2","$3","$4","$5","$6"); \ + : "=r" (__res) \ + : "0" (__NR_##name),"r" ((long)(a)), \ + "r" ((long)(b)), \ + "r" ((long)(c)), \ + "r" ((long)(d)), \ + "r" ((long)(e)) \ + : "$3","$4","$5","$6","$7"); \ if (__res>=0) \ return (type) __res; \ errno=-__res; \ return -1; \ } -#endif /* _ASM_MIPS_UNISTD_H_ */ +#ifdef __KERNEL_SYSCALLS__ + +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ +#define __NR__exit __NR_exit +static inline _syscall0(int,idle) +static inline _syscall0(int,fork) +static inline _syscall0(int,pause) +static inline _syscall0(int,setup) +static inline _syscall0(int,sync) +static inline _syscall0(pid_t,setsid) +static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) +static inline _syscall1(int,dup,int,fd) +static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) +static inline _syscall3(int,open,const char *,file,int,flag,int,mode) +static inline _syscall1(int,close,int,fd) +static inline _syscall1(int,_exit,int,exitcode) +static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +static inline pid_t wait(int * wait_stat) +{ + return waitpid(-1,wait_stat,0); +} + +#endif + +#endif /* __ASM_MIPS_UNISTD_H */ diff --git a/include/asm-mips/vector.h b/include/asm-mips/vector.h new file mode 100644 index 000000000..bc0d85e3b --- /dev/null +++ b/include/asm-mips/vector.h @@ -0,0 +1,32 @@ +/* + * include/asm-mips/vector.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 by Ralf Baechle + */ + +/* + * This structure defines how to access various features of + * different machine types and how to access them. + * + * FIXME: More things need to be accessed via this vector. + */ +struct feature { + void (*handle_int)(void); +}; + +/* + * Similar to the above this is a structure that describes various + * CPU dependend features. + * + * FIXME: This vector isn't being used yet + */ +struct cpu { + int dummy; /* keep GCC from complaining */ +}; + +extern struct feature *feature; +extern struct cpu *cpu; |