diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1994-12-01 08:00:00 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1994-12-01 08:00:00 +0000 |
commit | 90ecc248e200fee448001248dde0ca540dd3ef64 (patch) | |
tree | a3fe89494ce63b4835f0f9cf5c45e74cde88252b /include | |
parent | 1513ff9b7899ab588401c89db0e99903dbf5f886 (diff) |
Import of Linux/MIPS 1.1.68
Diffstat (limited to 'include')
50 files changed, 2861 insertions, 707 deletions
diff --git a/include/asm-generic/bitops.h b/include/asm-generic/bitops.h index 130619840..7b0350da1 100644 --- a/include/asm-generic/bitops.h +++ b/include/asm-generic/bitops.h @@ -1,5 +1,5 @@ -#ifndef _ASM_GENERIC_BITOPS_H_ -#define _ASM_GENERIC_BITOPS_H_ +#ifndef _ASM_GENERIC_BITOPS_H +#define _ASM_GENERIC_BITOPS_H /* * For the benefit of those who are trying to port Linux to another @@ -16,38 +16,56 @@ * C language equivalents written by Theodore Ts'o, 9/26/92 */ -extern __inline__ int set_bit(int nr,int * addr) +#ifdef __USE_GENERIC_set_bit +extern __inline__ int set_bit(int nr, void * addr) { int mask, retval; + int *a = addr; - addr += nr >> 5; + a += nr >> 5; mask = 1 << (nr & 0x1f); cli(); - retval = (mask & *addr) != 0; - *addr |= mask; + retval = (mask & *a) != 0; + *a |= mask; sti(); return retval; } +#endif -extern __inline__ int clear_bit(int nr, int * addr) +#ifdef __USE_GENERIC_clear_bit +extern __inline__ int clear_bit(int nr, void * addr) { int mask, retval; + int *a = addr; - addr += nr >> 5; + a += nr >> 5; mask = 1 << (nr & 0x1f); cli(); - retval = (mask & *addr) != 0; - *addr &= ~mask; + retval = (mask & *a) != 0; + *a &= ~mask; sti(); return retval; } +#endif -extern __inline__ int test_bit(int nr, int * addr) +#ifdef __USE_GENERIC_test_bit +extern __inline__ int test_bit(int nr, void * addr) { int mask; + int *a = addr; - addr += nr >> 5; + a += nr >> 5; mask = 1 << (nr & 0x1f); - return ((mask & *addr) != 0); + return ((mask & *a) != 0); } +#endif + +#ifdef __USE_GENERIC_find_first_zero_bit +#error "Generic find_first_zero_bit() not written yet." +#endif + +#ifdef __USE_GENERIC_find_next_zero_bit +#error "Generic find_next_zero_bit() not written yet." +#endif + #endif /* _ASM_GENERIC_BITOPS_H */ diff --git a/include/asm-generic/string.h b/include/asm-generic/string.h index 03fd6321f..c9cf8b483 100644 --- a/include/asm-generic/string.h +++ b/include/asm-generic/string.h @@ -154,24 +154,26 @@ extern inline char * strpbrk(const char * cs,const char * ct) #endif #ifdef __USE_PORTABLE_strtok + +extern char * ___strtok; + extern inline char * strtok(char * s,const char * ct) { char *sbegin, *send; - static char *ssave = NULL; - sbegin = s ? s : ssave; + sbegin = s ? s : ___strtok; if (!sbegin) { return NULL; } sbegin += strspn(sbegin,ct); if (*sbegin == '\0') { - ssave = NULL; + ___strtok = NULL; return( NULL ); } send = strpbrk( sbegin, ct); if (send && *send != '\0') *send++ = '\0'; - ssave = send; + ___strtok = send; return (sbegin); } #endif diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h index ee339bd64..36b0bedc0 100644 --- a/include/asm-i386/bitops.h +++ b/include/asm-i386/bitops.h @@ -132,4 +132,18 @@ extern inline unsigned long ffz(unsigned long word) return word; } +/* + * ffoz = Find First One in word and set to Zero. Undefined if no one exists, + * so code should check against 0UL first.. + */ +extern inline unsigned long ffzc(unsigned long word) +{ + __asm__("bsf %2,%1\n\t" + "btrl %1,%0" + : "=m" (current->signal),"=r" (signr) + : "1" (signr)); + + return word; +} + #endif /* _I386_BITOPS_H */ diff --git a/include/asm-i386/head.h b/include/asm-i386/head.h new file mode 100644 index 000000000..c77f02bdf --- /dev/null +++ b/include/asm-i386/head.h @@ -0,0 +1,20 @@ +#ifndef _ASM_I386_HEAD_H +#define _ASM_I386_HEAD_H + +typedef struct desc_struct { + unsigned long a,b; +} desc_table[256]; + +extern unsigned long swapper_pg_dir[1024]; +extern desc_table idt,gdt; + +#define GDT_NUL 0 +#define GDT_CODE 1 +#define GDT_DATA 2 +#define GDT_TMP 3 + +#define LDT_NUL 0 +#define LDT_CODE 1 +#define LDT_DATA 2 + +#endif diff --git a/include/asm-i386/in.h b/include/asm-i386/in.h new file mode 100644 index 000000000..91b2f4d04 --- /dev/null +++ b/include/asm-i386/in.h @@ -0,0 +1,64 @@ +#ifndef _ASM_I386_IN_H +#define _ASM_I386_IN_H + +static __inline__ unsigned long int +__ntohl(unsigned long int x) +{ + __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ + "rorl $16,%0\n\t" /* swap words */ + "xchgb %b0,%h0" /* swap higher bytes */ + :"=q" (x) + : "0" (x)); + return x; +} + +static __inline__ unsigned long int +__constant_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) +{ + __asm__("xchgb %b0,%h0" /* swap bytes */ + : "=q" (x) + : "0" (x)); + return x; +} + +static __inline__ unsigned short int +__constant_ntohs(unsigned short int x) +{ + return (((x & 0x00ff) << 8) | + ((x & 0xff00) >> 8)); +} + +#define __htonl(x) __ntohl(x) +#define __htons(x) __ntohs(x) +#define __constant_htonl(x) __constant_ntohl(x) +#define __constant_htons(x) __constant_ntohs(x) + +#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_I386_IN_H */ diff --git a/include/asm-i386/interrupt.h b/include/asm-i386/interrupt.h new file mode 100644 index 000000000..30ccb5b15 --- /dev/null +++ b/include/asm-i386/interrupt.h @@ -0,0 +1,19 @@ +#ifndef _ASM_I386_INTERRUPT_H +#define _ASM_I386_INTERRUPT_H + +extern inline void mark_bh(int nr) +{ + __asm__ __volatile__("orl %1,%0":"=m" (bh_active):"ir" (1<<nr)); +} + +extern inline void disable_bh(int nr) +{ + __asm__ __volatile__("andl %1,%0":"=m" (bh_mask):"ir" (~(1<<nr))); +} + +extern inline void enable_bh(int nr) +{ + __asm__ __volatile__("orl %1,%0":"=m" (bh_mask):"ir" (1<<nr)); +} + +#endif /* _ASM_I386_INTERRUPT_H */ diff --git a/include/asm-i386/mm.h b/include/asm-i386/mm.h new file mode 100644 index 000000000..56df7bf23 --- /dev/null +++ b/include/asm-i386/mm.h @@ -0,0 +1,73 @@ +#ifndef _ASM_I386_MM_H +#define _ASM_I386_MM_H + +#if defined (__KERNEL__) + +#define PAGE_PRESENT 0x001 +#define PAGE_RW 0x002 +#define PAGE_USER 0x004 +#define PAGE_PWT 0x008 /* 486 only - not used currently */ +#define PAGE_PCD 0x010 /* 486 only - not used currently */ +#define PAGE_ACCESSED 0x020 +#define PAGE_DIRTY 0x040 +#define PAGE_COW 0x200 /* implemented in software (one of the AVL bits) */ + +#define PAGE_PRIVATE (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED | PAGE_COW) +#define PAGE_SHARED (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED) +#define PAGE_COPY (PAGE_PRESENT | PAGE_USER | PAGE_ACCESSED | PAGE_COW) +#define PAGE_READONLY (PAGE_PRESENT | PAGE_USER | PAGE_ACCESSED) +#define PAGE_TABLE (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED) + +#define invalidate() \ +__asm__ __volatile__("movl %%cr3,%%eax\n\tmovl %%eax,%%cr3": : :"ax") + +extern inline long find_in_swap_cache (unsigned long addr) +{ + unsigned long entry; + +#ifdef SWAP_CACHE_INFO + swap_cache_find_total++; +#endif + __asm__ __volatile__("xchgl %0,%1" + :"=m" (swap_cache[addr >> PAGE_SHIFT]), + "=r" (entry) + :"0" (swap_cache[addr >> PAGE_SHIFT]), + "1" (0)); +#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 + __asm__ __volatile__("xchgl %0,%1" + :"=m" (swap_cache[addr >> PAGE_SHIFT]), + "=r" (entry) + :"0" (swap_cache[addr >> PAGE_SHIFT]), + "1" (0)); + 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 low_start_mem, + unsigned long start_mem, unsigned long end_mem); + +#endif /* __KERNEL__ */ + +#endif /* _ASM_I386_MM_H */ diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h new file mode 100644 index 000000000..294acc7bd --- /dev/null +++ b/include/asm-i386/ptrace.h @@ -0,0 +1,61 @@ +#ifndef _ASM_I386_PTRACE_H +#define _ASM_I386_PTRACE_H + +/* + * linux/include/asm-i386/ptrace.h */ + * + * machine dependend structs and defines to help the user use + * the ptrace system call. + */ + +/* use ptrace (3 or 6, pid, PT_EXCL, data); to read or write + the processes registers. */ + +#define EBX 0 +#define ECX 1 +#define EDX 2 +#define ESI 3 +#define EDI 4 +#define EBP 5 +#define EAX 6 +#define DS 7 +#define ES 8 +#define FS 9 +#define GS 10 +#define ORIG_EAX 11 +#define EIP 12 +#define CS 13 +#define EFL 14 +#define UESP 15 +#define SS 16 + + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long eax; + unsigned short ds, __dsu; + unsigned short es, __esu; + unsigned short fs, __fsu; + unsigned short gs, __gsu; + long orig_eax; + long eip; + unsigned short cs, __csu; + long eflags; + long esp; + unsigned short ss, __ssu; +}; + +/* + * This function computes the interrupt number from the stack frame + */ +#define pt_regs2irq(p) ((int) -(((struct pt_regs *)p)->orig_eax+2)) + +#endif /* _ASM_I386_PTRACE_H */ diff --git a/include/asm-i386/sched.h b/include/asm-i386/sched.h new file mode 100644 index 000000000..1371d0226 --- /dev/null +++ b/include/asm-i386/sched.h @@ -0,0 +1,331 @@ +#ifndef _ASM_I386_SCHED_H +#define _ASM_I386_SCHED_H + +/* + * System setup and hardware bug flags.. + */ +extern int x86; +extern int ignore_irq13; +extern int wp_works_ok; /* doesn't work on a 386 */ +extern int hlt_works_ok; /* problems on some 486Dx4's and old 386's */ + +extern unsigned long intr_count; +extern unsigned long event; + +#define start_bh_atomic() \ +__asm__ __volatile__("incl _intr_count") + +#define end_bh_atomic() \ +__asm__ __volatile__("decl _intr_count") + +/* + * 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: 3GB. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + */ +#define TASK_SIZE 0xc0000000 + +/* + * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. + */ +#define IO_BITMAP_SIZE 32 + +#include <linux/vm86.h> + +struct i387_hard_struct { + long cwd; + long swd; + long twd; + long fip; + long fcs; + long foo; + long fos; + long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ +}; + +struct i387_soft_struct { + long cwd; + long swd; + long twd; + long fip; + long fcs; + long foo; + long fos; + long top; + struct fpu_reg regs[8]; /* 8*16 bytes for each FP-reg = 128 bytes */ + unsigned char lookahead; + struct info *info; + unsigned long entry_eip; +}; + +union i387_union { + struct i387_hard_struct hard; + struct i387_soft_struct soft; +}; + +struct tss_struct { + unsigned short back_link,__blh; + unsigned long esp0; + unsigned short ss0,__ss0h; + unsigned long esp1; + unsigned short ss1,__ss1h; + unsigned long esp2; + unsigned short ss2,__ss2h; + unsigned long cr3; + unsigned long eip; + unsigned long eflags; + unsigned long eax,ecx,edx,ebx; + unsigned long esp; + unsigned long ebp; + unsigned long esi; + unsigned long edi; + unsigned short es, __esh; + unsigned short cs, __csh; + unsigned short ss, __ssh; + unsigned short ds, __dsh; + unsigned short fs, __fsh; + unsigned short gs, __gsh; + unsigned short ldt, __ldth; + unsigned short trace, bitmap; + unsigned long io_bitmap[IO_BITMAP_SIZE+1]; + unsigned long tr; + unsigned long cr2, trap_no, error_code; + union i387_union i387; +}; + +#define INIT_TSS { \ + 0,0, \ + sizeof(init_kernel_stack) + (long) &init_kernel_stack, \ + KERNEL_DS, 0, \ + 0,0,0,0,0,0, \ + (long) &swapper_pg_dir, \ + 0,0,0,0,0,0,0,0,0,0, \ + USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0, \ + _LDT(0),0, \ + 0, 0x8000, \ + {~0, }, /* ioperm */ \ + _TSS(0), 0, 0,0, \ + { { 0, }, } /* 387 state */ \ +} + +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__ + +/* + * Entry into gdt where to find first TSS. GDT layout: + * 0 - nul + * 1 - kernel code segment + * 2 - kernel data segment + * 3 - user code segment + * 4 - user data segment + * ... + * 8 - TSS #0 + * 9 - LDT #0 + * 10 - TSS #1 + * 11 - LDT #1 + */ +#define FIRST_TSS_ENTRY 8 +#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1) +#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3)) +#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3)) +#define load_TR(n) __asm__("ltr %%ax": /* no output */ :"a" (_TSS(n))) +#define load_ldt(n) __asm__("lldt %%ax": /* no output */ :"a" (_LDT(n))) +#define store_TR(n) \ +__asm__("str %%ax\n\t" \ + "subl %2,%%eax\n\t" \ + "shrl $4,%%eax" \ + :"=a" (n) \ + :"0" (0),"i" (FIRST_TSS_ENTRY<<3)) +/* + * 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__("cli\n\t" \ + "xchgl %%ecx,_current\n\t" \ + "ljmp %0\n\t" \ + "sti\n\t" \ + "cmpl %%ecx,_last_task_used_math\n\t" \ + "jne 1f\n\t" \ + "clts\n" \ + "1:" \ + : /* no output */ \ + :"m" (*(((char *)&tsk->tss.tr)-4)), \ + "c" (tsk) \ + :"cx") + +#define _set_base(addr,base) \ +__asm__("movw %%dx,%0\n\t" \ + "rorl $16,%%edx\n\t" \ + "movb %%dl,%1\n\t" \ + "movb %%dh,%2" \ + : /* no output */ \ + :"m" (*((addr)+2)), \ + "m" (*((addr)+4)), \ + "m" (*((addr)+7)), \ + "d" (base) \ + :"dx") + +#define _set_limit(addr,limit) \ +__asm__("movw %%dx,%0\n\t" \ + "rorl $16,%%edx\n\t" \ + "movb %1,%%dh\n\t" \ + "andb $0xf0,%%dh\n\t" \ + "orb %%dh,%%dl\n\t" \ + "movb %%dl,%1" \ + : /* no output */ \ + :"m" (*(addr)), \ + "m" (*((addr)+6)), \ + "d" (limit) \ + :"dx") + +#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base ) +#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 ) + +static inline unsigned long _get_base(char * addr) +{ + unsigned long __base; + __asm__("movb %3,%%dh\n\t" + "movb %2,%%dl\n\t" + "shll $16,%%edx\n\t" + "movw %1,%%dx" + :"=&d" (__base) + :"m" (*((addr)+2)), + "m" (*((addr)+4)), + "m" (*((addr)+7))); + return __base; +} + +#define get_base(ldt) _get_base( ((char *)&(ldt)) ) + +static inline unsigned long get_limit(unsigned long segment) +{ + unsigned long __limit; + __asm__("lsll %1,%0" + :"=r" (__limit):"r" (segment)); + return __limit+1; +} + +/* + * This is the ldt that every process will get unless we need + * something other than this. + */ +extern struct desc_struct default_ldt; + +/* This special macro can be used to load a debugging register */ + +#define loaddebug(register) \ + __asm__("movl %0,%%edx\n\t" \ + "movl %%edx,%%db" #register "\n\t" \ + : /* no output */ \ + :"m" (current->debugreg[register]) \ + :"dx"); + +/* + * Does the process account for user or for system time? + */ +#define USES_USER_TIME(regs) ((VM_MASK & (regs)->eflags) || (3 & regs->cs)) + +#endif /* __KERNEL__ */ + +#endif diff --git a/include/asm-i386/signal.h b/include/asm-i386/signal.h new file mode 100644 index 000000000..5982091a3 --- /dev/null +++ b/include/asm-i386/signal.h @@ -0,0 +1,33 @@ +#ifndef _ASM_I386_SIGNAL_H +#define _ASM_I386_SIGNAL_H + +#ifdef __KERNEL__ + +struct sigcontext_struct { + unsigned short gs, __gsh; + unsigned short fs, __fsh; + unsigned short es, __esh; + unsigned short ds, __dsh; + unsigned long edi; + unsigned long esi; + unsigned long ebp; + unsigned long esp; + unsigned long ebx; + unsigned long edx; + unsigned long ecx; + unsigned long eax; + unsigned long trapno; + unsigned long err; + unsigned long eip; + unsigned short cs, __csh; + unsigned long eflags; + unsigned long esp_at_signal; + unsigned short ss, __ssh; + unsigned long i387; + unsigned long oldmask; + unsigned long cr2; +}; + +#endif + +#endif /* _ASM_I386_SIGNAL_H */ diff --git a/include/asm-i386/slots.h b/include/asm-i386/slots.h new file mode 100644 index 000000000..21139c59c --- /dev/null +++ b/include/asm-i386/slots.h @@ -0,0 +1,17 @@ +/* + * include/asm-i386/slots.h + * + * Written by Ralf Baechle + * Copyright (C) 1994 by Waldorf GMBH + */ +#ifndef _ASM_I386_SLOTS_H +#define _ASM_I386_SLOTS_H + +/* + * SLOTSPACE is the address to which the physical address 0 + * of the Slotspace is mapped by the chipset in the main CPU's + * address space. + */ +#define SLOTSPACE 0x0 + +#endif /* _ASM_I386_SLOTS_H */ diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h index 04c8b96b6..23af2e513 100644 --- a/include/asm-i386/system.h +++ b/include/asm-i386/system.h @@ -44,6 +44,16 @@ extern inline int tas(char * m) return res; } +/* + * atomic exchange + */ +#define atomic_exchange(m,r) \ + __asm__ __volatile__( \ + "xchgl %0,%2" \ + : "=r" ((r)) \ + : "0" ((r)), "m" (*(m)) \ + : "memory"); + #define save_flags(x) \ __asm__ __volatile__("pushfl ; popl %0":"=r" (x): /* no input */ :"memory") diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 9665c7f01..a2fd7972b 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h @@ -7,14 +7,167 @@ * * Copyright (c) 1994 by Ralf Baechle */ +#ifndef _ASM_MIPS_BITOPS_H +#define _ASM_MIPS_BITOPS_H -#ifndef _ASM_MIPS_BITOPS_H_ -#define _ASM_MIPS_BITOPS_H_ +#include <asm/mipsregs.h> + +extern inline int set_bit(int nr, void *addr) +{ + int mask, retval, mw; + + addr += nr >> 5; + mask = 1 << (nr & 0x1f); + do { + mw = load_linked(addr); + retval = (mask & mw) != 0; + } + while (!store_conditional(addr, mw|mask)); + + return retval; +} + +extern inline int clear_bit(int nr, void *addr) +{ + int mask, retval, mw; + + addr += nr >> 5; + mask = 1 << (nr & 0x1f); + do { + mw = load_linked(addr); + retval = (mask & mw) != 0; + } + while (!store_conditional(addr, mw & ~mask)); + + return retval; +} + +extern inline int change_bit(int nr, void *addr) +{ + int mask, retval, mw; + + addr += nr >> 5; + mask = 1 << (nr & 0x1f); + do { + mw = load_linked(addr); + retval = (mask & mw) != 0; + } + while (!store_conditional(addr, mw ^ mask)); + + return retval; +} + +extern inline int test_bit(int nr, void *addr) +{ + int mask; + int *a; + + a = addr; + addr += nr >> 5; + mask = 1 << (nr & 0x1f); + 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) +{ + int res; + + if (!size) + return 0; + + __asm__(".set\tnoreorder\n\t" + ".set\tnoat\n" + "1:\tsubu\t$1,%2,%0\n\t" + "blez\t$1,2f\n\t" + "lw\t$1,(%4)\n\t" + "addiu\t%4,%4,4\n\t" + "beql\t%1,$1,1b\n\t" + "addiu\t%0,%0,32\n\t" + "li\t%1,1\n" + "1:\tand\t%4,$1,%1\n\t" + "beq\t$0,%4,2f\n\t" + "sll\t%1,%1,1\n\t" + "bne\t$0,%1,1b\n\t" + "add\t%0,%0,1\n\t" + ".set\tat\n\t" + ".set\treorder\n" + "2:" + : "=d" (res) + : "d" ((unsigned int) 0xffffffff), + "d" (size), + "0" ((signed int) 0), + "d" (addr) + : "$1"); + + return res; +} + +static 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; + + if (bit) { + /* + * Look for zero in first byte + */ + __asm__(".set\tnoreorder\n\t" + ".set\tnoat\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" + "addiu\t%0,%0,1\n\t" + ".set\tat\n\t" + ".set\treorder\n" + : "=r" (set) + : "r" (*p >> bit), + "r" (1), + "0" (0)); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No zero yet, search remaining full bytes for a zero + */ + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} /* - * On MIPS inline assembler bitfunctions are as effective - * as the standard C counterparts. + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. */ -#include <asm-generic/bitops.h> +extern inline unsigned long ffz(unsigned long word) +{ + unsigned int __res; + unsigned int mask = 1; + + __asm__ __volatile__ ( + ".set\tnoreorder\n\t" + ".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" + ".set\tat\n\t" + ".set\treorder\n" + "2:\n\t" + : "=r" (__res), "=r" (word), "=r" (mask) + : "1" (~(word)), + "2" (mask), + "0" (0) + : "$1"); + + 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 new file mode 100644 index 000000000..4ff415bf1 --- /dev/null +++ b/include/asm-mips/bootinfo.h @@ -0,0 +1,63 @@ +/* + * bootinfo.h -- Definition of the Linux/68K boot information structure + * + * Written by Ralf Baechle, + * Copyright (C) 1994 by Waldorf GMBH + * + * Based on Linux/68k linux/include/linux/bootstrap.h + * Copyright (C) 1992 by Greg Harp + * + * This file is subject to the terms and conditions of the GNU General Public + * 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 + +/* + * Valid values for machtype field + */ +#define MACH_DESKSTATION_TYNE 1 /* Deskstation Tyne */ + +/* + * Type of CPU + */ +#define CPU_R4600 1 + +#define CL_SIZE (80) + +struct bootinfo { + unsigned long + machtype; /* machine type */ + + unsigned long + cputype; /* system CPU & FPU */ + + /* + * Installed RAM + */ + unsigned int memlower; + unsigned int memupper; + + /* + * Cache Information + */ + unsigned int sec_cache; + unsigned int dma_cache; + + unsigned long + ramdisk_size; /* ramdisk size in 1024 byte blocks */ + + unsigned long + ramdisk_addr; /* address of the ram disk in mem */ + + char + command_line[CL_SIZE]; /* kernel command line parameters */ + +}; + +extern struct bootinfo + boot_info; + +#endif /* ASM_MIPS_BOOTINFO_H */ diff --git a/include/asm-mips/cachectl.h b/include/asm-mips/cachectl.h new file mode 100644 index 000000000..167727c97 --- /dev/null +++ b/include/asm-mips/cachectl.h @@ -0,0 +1,32 @@ +/* + * include/asm-mips/cachectl.h + * + * 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 + +/* + * cachectl.h -- defines for MIPS cache control system calls + */ + +/* + * Options for cacheflush system call + */ +#define ICACHE (1<<0) /* flush instruction cache */ +#define DCACHE (1<<1) /* writeback and flush data cache */ +#define BCACHE (ICACHE|DCACHE) /* flush both caches */ + +#define CACHELINES 512 /* number of cachelines */ + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +extern int sys_cacheflush(void *addr, int nbytes, int cache); + +#endif +#endif +#endif /* _ASM_MIPS_CACHECTL */ diff --git a/include/asm-mips/delay.h b/include/asm-mips/delay.h index 09fd0c470..5aa85e165 100644 --- a/include/asm-mips/delay.h +++ b/include/asm-mips/delay.h @@ -1,13 +1,17 @@ -#ifndef _MIPS_DELAY_H -#define _MIPS_DELAY_H +#ifndef _ASM_MIPS_DELAY_H +#define _ASM_MIPS_DELAY_H extern __inline__ void __delay(int loops) { - __asm__(".align 3\n" - "1:\tbeq\t$0,%0,1b\n\t" - "addiu\t%0,%0,-1\n\t" - : - :"d" (loops)); + __asm__ __volatile__ ( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "1:\tbne\t$0,%0,1b\n\t" + "subu\t%0,%0,1\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (loops) + :"0" (loops)); } /* @@ -24,10 +28,9 @@ extern __inline__ void udelay(unsigned long usecs) { usecs *= 0x000010c6; /* 2**32 / 1000000 */ __asm__("mul\t%0,%0,%1" - :"=d" (usecs) - :"0" (usecs),"d" (loops_per_sec) - :"ax"); + :"=r" (usecs) + :"0" (usecs),"r" (loops_per_sec)); __delay(usecs); } -#endif /* defined(_MIPS_DELAY_H) */ +#endif /* defined (_ASM_MIPS_DELAY_H) */ diff --git a/include/asm-mips/dma.h b/include/asm-mips/dma.h new file mode 100644 index 000000000..7540aedec --- /dev/null +++ b/include/asm-mips/dma.h @@ -0,0 +1,271 @@ +/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $ + * linux/include/asm/dma.h: Defines for using and allocating dma channels. + * Written by Hennus Bergman, 1992. + * High DMA channel support & info by Hannu Savolainen + * and John Boyd, Nov. 1992. + */ + +#ifndef _ASM_MIPS_DMA_H +#define _ASM_MIPS_DMA_H + +#include <asm/io.h> /* need byte IO */ + + +#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER +#define dma_outb outb_p +#else +#define dma_outb outb +#endif + +#define dma_inb inb + +/* + * NOTES about DMA transfers: + * + * controller 1: channels 0-3, byte operations, ports 00-1F + * controller 2: channels 4-7, word operations, ports C0-DF + * + * - ALL registers are 8 bits only, regardless of transfer size + * - channel 4 is not used - cascades 1 into 2. + * - channels 0-3 are byte - addresses/counts are for physical bytes + * - channels 5-7 are word - addresses/counts are for physical words + * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries + * - transfer count loaded to registers is 1 less than actual count + * - controller 2 offsets are all even (2x offsets for controller 1) + * - page registers for 5-7 don't use data bit 0, represent 128K pages + * - page registers for 0-3 use bit 0, represent 64K pages + * + * DMA transfers are limited to the lower 16MB of _physical_ memory. + * Note that addresses loaded into registers must be _physical_ addresses, + * not logical addresses (which may differ if paging is active). + * + * Address mapping for channels 0-3: + * + * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * P7 ... P0 A7 ... A0 A7 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Address mapping for channels 5-7: + * + * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) + * | ... | \ \ ... \ \ \ ... \ \ + * | ... | \ \ ... \ \ \ ... \ (not used) + * | ... | \ \ ... \ \ \ ... \ + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses + * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at + * the hardware level, so odd-byte transfers aren't possible). + * + * Transfer count (_not # bytes_) is limited to 64K, represented as actual + * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, + * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * + */ + +#define MAX_DMA_CHANNELS 8 + +/* The maximum address that we can perform a DMA transfer to on this platform */ +#define MAX_DMA_ADDRESS 0xffffff + +/* 8237 DMA controllers */ +#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ +#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ + +/* DMA controller registers */ +#define DMA1_CMD_REG 0x08 /* command register (w) */ +#define DMA1_STAT_REG 0x08 /* status register (r) */ +#define DMA1_REQ_REG 0x09 /* request register (w) */ +#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ +#define DMA1_MODE_REG 0x0B /* mode register (w) */ +#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ +#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ +#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ +#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ +#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ + +#define DMA2_CMD_REG 0xD0 /* command register (w) */ +#define DMA2_STAT_REG 0xD0 /* status register (r) */ +#define DMA2_REQ_REG 0xD2 /* request register (w) */ +#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ +#define DMA2_MODE_REG 0xD6 /* mode register (w) */ +#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ +#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ +#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ +#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ +#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ + +#define DMA_ADDR_0 0x00 /* DMA address registers */ +#define DMA_ADDR_1 0x02 +#define DMA_ADDR_2 0x04 +#define DMA_ADDR_3 0x06 +#define DMA_ADDR_4 0xC0 +#define DMA_ADDR_5 0xC4 +#define DMA_ADDR_6 0xC8 +#define DMA_ADDR_7 0xCC + +#define DMA_CNT_0 0x01 /* DMA count registers */ +#define DMA_CNT_1 0x03 +#define DMA_CNT_2 0x05 +#define DMA_CNT_3 0x07 +#define DMA_CNT_4 0xC2 +#define DMA_CNT_5 0xC6 +#define DMA_CNT_6 0xCA +#define DMA_CNT_7 0xCE + +#define DMA_PAGE_0 0x87 /* DMA page registers */ +#define DMA_PAGE_1 0x83 +#define DMA_PAGE_2 0x81 +#define DMA_PAGE_3 0x82 +#define DMA_PAGE_5 0x8B +#define DMA_PAGE_6 0x89 +#define DMA_PAGE_7 0x8A + +#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ +#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ +#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ + +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr, DMA1_MASK_REG); + else + dma_outb(dmanr & 3, DMA2_MASK_REG); +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr | 4, DMA1_MASK_REG); + else + dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(0, DMA1_CLEAR_FF_REG); + else + dma_outb(0, DMA2_CLEAR_FF_REG); +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + if (dmanr<=3) + dma_outb(mode | dmanr, DMA1_MODE_REG); + else + dma_outb(mode | (dmanr&3), DMA2_MODE_REG); +} + +/* Set only the page register bits of the transfer address. + * This is used for successive transfers when we know the contents of + * the lower 16 bits of the DMA current address register, but a 64k boundary + * may have been crossed. + */ +static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) +{ + switch(dmanr) { + case 0: + dma_outb(pagenr, DMA_PAGE_0); + break; + case 1: + dma_outb(pagenr, DMA_PAGE_1); + break; + case 2: + dma_outb(pagenr, DMA_PAGE_2); + break; + case 3: + dma_outb(pagenr, DMA_PAGE_3); + break; + case 5: + dma_outb(pagenr & 0xfe, DMA_PAGE_5); + break; + case 6: + dma_outb(pagenr & 0xfe, DMA_PAGE_6); + break; + case 7: + dma_outb(pagenr & 0xfe, DMA_PAGE_7); + break; + } +} + + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + set_dma_page(dmanr, a>>16); + if (dmanr <= 3) { + dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + } else { + dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + } +} + + +/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for + * a specific DMA channel. + * You must ensure the parameters are valid. + * NOTE: from a manual: "the number of transfers is one more + * than the initial word count"! This is taken into account. + * Assumes dma flip-flop is clear. + * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + count--; + if (dmanr <= 3) { + dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + } else { + dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + } +} + + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE + : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; + + /* using short to get 16-bit wrap around */ + unsigned short count; + + count = 1 + dma_inb(io_port); + count += dma_inb(io_port) << 8; + + return (dmanr<=3)? count : (count<<1); +} + + +/* These are in kernel/dma.c: */ +extern int request_dma(unsigned int dmanr, char * deviceID); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + + +#endif /* _ASM_MIPS_DMA_H */ diff --git a/include/asm-mips/head.h b/include/asm-mips/head.h new file mode 100644 index 000000000..e0e01ec52 --- /dev/null +++ b/include/asm-mips/head.h @@ -0,0 +1,9 @@ +#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 new file mode 100644 index 000000000..18074abb9 --- /dev/null +++ b/include/asm-mips/in.h @@ -0,0 +1,34 @@ +#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 new file mode 100644 index 000000000..6450b1698 --- /dev/null +++ b/include/asm-mips/interrupt.h @@ -0,0 +1,40 @@ +#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 new file mode 100644 index 000000000..16dbd1b46 --- /dev/null +++ b/include/asm-mips/io.h @@ -0,0 +1,240 @@ +#ifndef _ASM_IO_H +#define _ASM_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. + * + * Ralf + * + * This file contains the definitions for the x86 IO instructions + * inb/inw/inl/outb/outw/outl and the "string versions" of the same + * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing" + * versions of the single-IO instructions (inb_p/inw_p/..). + * + * This file is not meant to be obfuscating: it's just complicated + * to (a) handle it all in a way that makes gcc able to optimize it + * as well as possible and (b) trying to avoid writing the same thing + * over and over again with slight variations and possibly making a + * mistake somewhere. + */ + +/* + * Thanks to James van Artsdalen for a better timing-fix than + * the two short jumps: using outb's to a nonexistent port seems + * to guarantee better timings even on fast machines. + * + * On the other hand, I'd like to be sure of a non-existent port: + * I feel a bit unsafe about using 0x80 (should be safe, though) + * + * Linus + */ + +#define __SLOW_DOWN_IO \ + __asm__ __volatile__( \ + "sb\t$0,0x80(%0)" \ + : : "d" (PORT_BASE)); + +#ifdef REALLY_SLOW_IO +#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; } +#else +#define SLOW_DOWN_IO __SLOW_DOWN_IO +#endif + +/* + * Talk about misusing macros.. + */ + +#define __OUT1(s) \ +extern inline void __out##s(unsigned int value, unsigned int port) { + +#define __OUT2(m) \ +__asm__ __volatile__ ("s" #m "\t%0,%1(%2)" + +#define __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)); \ + SLOW_DOWN_IO; } \ +__OUT1(s##c_p) __OUT2(m) : : "d" (value), "i" (port), "d" (PORT_BASE)); \ + SLOW_DOWN_IO; } + +#define __IN1(s) \ +extern inline unsigned int __in##s(unsigned int port) { unsigned int _v; + +#define __IN2(m) \ +__asm__ __volatile__ ("l" #m "u\t%0,%1(%2)\n\t" + +#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; } + +#define __INS1(s) \ +extern inline void __ins##s(unsigned int port, void * addr, unsigned long count) { + +#define __INS2(m) \ +__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" \ + "s" #m "\t$1,(%0)\n\t" \ + "bne\t$0,%1,1b\n\t" \ + "addiu\t%0,%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) \ + : "$1");} \ +__INS1(s##c) __INS2(m) \ + : "=d" (addr), "=d" (count) \ + : "0" (addr), "1" (count), "i" (port), "d" (PORT_BASE), "I" (i) \ + : "$1");} + +#define __OUTS1(s) \ +extern inline void __outs##s(unsigned int port, const void * addr, unsigned long count) { + +#define __OUTS2(m) \ +__asm__ __volatile__ ( \ + ".set\tnoreorder\n\t" \ + ".set\tnoat\n" \ + "1:\tl" #m "u\t$1,(%0)\n\t" \ + "subu\t%1,%1,1\n\t" \ + "s" #m "\t$1,%4(%5)\n\t" \ + "bne\t$0,%1,1b\n\t" \ + "addiu\t%0,%0,%6\n\t" \ + ".set\tat\n\t" \ + ".set\treorder" + +#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) \ + : "$1");} \ +__OUTS1(s##c) __OUTS2(m) \ + : "=d" (addr), "=d" (count) \ + : "0" (addr), "1" (count), "i" (port), "d" (PORT_BASE), "I" (i) \ + : "$1");} + +__IN(b,b) +__IN(h,w) +__IN(w,l) + +__OUT(b,b) +__OUT(h,w) +__OUT(w,l) + +__INS(b,b,1) +__INS(h,w,2) +__INS(w,l,4) + +__OUTS(b,b,1) +__OUTS(h,w,2) +__OUTS(w,l,4) + +/* + * Note that due to the way __builtin_constant_p() works, you + * - can't use it inside a inline function (it will never be true) + * - you don't have to worry about side effects within the __builtin.. + */ +#define outb(val,port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outbc((val),(port)) : \ + __outb((val),(port))) + +#define inb(port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inbc(port) : \ + __inb(port)) + +#define outb_p(val,port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outbc_p((val),(port)) : \ + __outb_p((val),(port))) + +#define inb_p(port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inbc_p(port) : \ + __inb_p(port)) + +#define outw(val,port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outwc((val),(port)) : \ + __outw((val),(port))) + +#define inw(port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inwc(port) : \ + __inw(port)) + +#define outw_p(val,port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outwc_p((val),(port)) : \ + __outw_p((val),(port))) + +#define inw_p(port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inwc_p(port) : \ + __inw_p(port)) + +#define outl(val,port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outlc((val),(port)) : \ + __outl((val),(port))) + +#define inl(port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inlc(port) : \ + __inl(port)) + +#define outl_p(val,port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outlc_p((val),(port)) : \ + __outl_p((val),(port))) + +#define inl_p(port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inlc_p(port) : \ + __inl_p(port)) + + +#define outsb(port,addr,count) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outsbc((port),(addr),(count)) : \ + __outsb ((port),(addr),(count))) + +#define insb(port,addr,count) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __insbc((port),(addr),(count)) : \ + __insb((port),(addr),(count))) + +#define outsw(port,addr,count) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outswc((port),(addr),(count)) : \ + __outsw ((port),(addr),(count))) + +#define insw(port,addr,count) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inswc((port),(addr),(count)) : \ + __insw((port),(addr),(count))) + +#define outsl(port,addr,count) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outslc((port),(addr),(count)) : \ + __outsl ((port),(addr),(count))) + +#define insl(port,addr,count) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inslc((port),(addr),(count)) : \ + __insl((port),(addr),(count))) + +#endif diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h new file mode 100644 index 000000000..a6d10c29e --- /dev/null +++ b/include/asm-mips/irq.h @@ -0,0 +1,18 @@ +/* + * include/asm-mips/irq.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 + * written by Ralf Baechle + * + */ +#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 */ diff --git a/include/asm-mips/mipsconfig.h b/include/asm-mips/mipsconfig.h new file mode 100644 index 000000000..4194df998 --- /dev/null +++ b/include/asm-mips/mipsconfig.h @@ -0,0 +1,29 @@ +/* + * linux/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 + * written by Ralf Baechle + * + */ +#ifndef _ASM_MIPS_MIPS_CONFIG_H +#define _ASM_MIPS_MIPS_CONFIG_H + +/* + * This is the virtual adress to which all ports are being mapped. + */ +#define PORT_BASE 0xe0000000 +#define PORT_BASE_HIGH 0xe000 + +#define NUMBER_OF_TLB_ENTRIES 48 + +/* + * Absolute address of the kernelstack is 0x80000280 + */ +#define KERNEL_SP_HIGH 0x8000 +#define KERNEL_SP_LOW 0x0280 + +#endif /* _ASM_MIPS_MIPS_CONFIG_H */ diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 2fd47473e..b9b96e73d 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -24,6 +24,19 @@ #endif /* + * 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 + */ +#if !defined (__R4000__) +#define FILL_LDS nop +#else +#define FILL_LDS +#endif + +/* * Coprocessor 0 register names */ #define CP0_INDEX $0 @@ -53,15 +66,15 @@ #define CP0_ERROREPC $30 /* - * Values for pagemask register + * Values for PageMask register */ -#define PM_4K 0x000000000 -#define PM_16K 0x000060000 -#define PM_64K 0x0001e0000 -#define PM_256K 0x0007e0000 -#define PM_1M 0x001fe0000 -#define PM_4M 0x007fe0000 -#define PM_16M 0x01ffe0000 +#define PM_4K 0x00000000 +#define PM_16K 0x00006000 +#define PM_64K 0x0001e000 +#define PM_256K 0x0007e000 +#define PM_1M 0x001fe000 +#define PM_4M 0x007fe000 +#define PM_16M 0x01ffe000 /* * Values used for computation of new tlb entries @@ -80,4 +93,86 @@ #define VPN(addr,pagesizeshift) ((addr) & ~((1 << (pagesizeshift))-1)) #define PFN(addr,pagesizeshift) (((addr) & ((1 << (pagesizeshift))-1)) << 6) +/* + * Macros to access the system control copprocessor + */ +#define read_32bit_cp0_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + "mfc0\t%0,"STR(source) \ + : "=r" (__res)); \ + __res;}) + +#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"); + + +#define write_32bit_cp0_register(register,value) \ + __asm__ __volatile__( \ + "mtc0\t%0,"STR(register) \ + : : "r" (value)); + +/* + * Inline code for use of the ll and sc instructions + * + * FIXME: This code code will break on R[23]00 CPUs + * 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 store_conditional(value,addr) \ +({ \ + 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 + */ +#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_ */ diff --git a/include/asm-mips/mm.h b/include/asm-mips/mm.h new file mode 100644 index 000000000..84a09e1c8 --- /dev/null +++ b/include/asm-mips/mm.h @@ -0,0 +1,94 @@ +#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 new file mode 100644 index 000000000..0176c0251 --- /dev/null +++ b/include/asm-mips/page.h @@ -0,0 +1,90 @@ +#ifndef _ASM_MIPS_LINUX_PAGE_H +#define _ASM_MIPS_LINUX_PAGE_H + +/* + * For now... + */ +#define invalidate() + + /* 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) + +#ifdef __KERNEL__ + + /* 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__) +/* + * Do it the 64bit way... + */ +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"); +} +#else +/* + * Use 32 bit Diesel fuel... + */ +extern __inline__ void __copy_page(void *from, void *to, int bytes) +{ + __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"); +} +#endif + +#endif /* __KERNEL__ */ + +#endif /* _ASM_MIPS_LINUX_PAGE_H */ diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h new file mode 100644 index 000000000..97b08ce74 --- /dev/null +++ b/include/asm-mips/ptrace.h @@ -0,0 +1,110 @@ +/* + * linux/include/asm-mips/ptrace.h + * + * machine dependend structs and defines to help the user use + * the ptrace system call. + */ +#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 - + * 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. + */ + +#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 + +/* + * k0 and k1 not saved + */ +#define IN_REG28 25 +#define IN_REG29 26 +#define IN_REG30 27 +#define IN_REG31 28 + +/* + * Saved special registers + */ +#define FR_LO ((IN_REG31) + 1) +#define FR_HI ((IN_LO) + 1) + +/* + * 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) + +/* + * Some goodies... + */ +#define IN_INTERRUPT ((IN_CP0_ERROREPC) + 1) +#define IN_ORIG_REG2 ((IN_INTERRUPT) + 1) + +/* + * 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 { + /* + * 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; + /* + * Some goodies... + */ + unsigned long interrupt; + long orig_reg2; +}; + +/* + * This function computes the interrupt number from the stack frame + */ +#define pt_regs2irq(p) ((int) ((struct pt_regs *)p)->interrupt) + +#endif /* _ASM_MIPS_PTRACE_H */ diff --git a/include/asm-mips/regdef.h b/include/asm-mips/regdef.h new file mode 100644 index 000000000..1fbe8f19f --- /dev/null +++ b/include/asm-mips/regdef.h @@ -0,0 +1,50 @@ +/* + * include/asm-mips/regdefs.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 Ralf Baechle + */ + +#ifndef _ASM_MIPS_REGSDEFS_H_ +#define _ASM_MIPS_REGSDEFS_H_ + +/* + * Symbolic register names + */ +#define zero $0 /* wired zero */ +#define AT $1 /* assembler temp (uprcase, because ".set at") */ +#define v0 $2 /* return value */ +#define v1 $3 +#define a0 $4 /* argument registers */ +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t0 $8 /* caller saved */ +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define s0 $16 /* callee saved */ +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 /* caller saved */ +#define t9 $25 +#define k0 $26 /* kernel scratch */ +#define k1 $27 +#define gp $28 /* global pointer */ +#define sp $29 /* stack pointer */ +#define fp $30 /* frame pointer */ +#define ra $31 /* return address */ + +#endif /* _ASM_MIPS_REGSDEFS_H_ */ diff --git a/include/asm-mips/sched.h b/include/asm-mips/sched.h new file mode 100644 index 000000000..661675a37 --- /dev/null +++ b/include/asm-mips/sched.h @@ -0,0 +1,240 @@ +#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 8b29ad0b2..511c499c8 100644 --- a/include/asm-mips/segment.h +++ b/include/asm-mips/segment.h @@ -12,11 +12,19 @@ #ifndef _ASM_MIPS_SEGMENT_H_ #define _ASM_MIPS_SEGMENT_H_ +#define KERNEL_CS 0x80000000 +#define KERNEL_DS KERNEL_CS + +#define USER_CS 0x00000000 +#define USER_DS USER_CS + +#ifndef __ASSEMBLY__ + static inline unsigned char get_user_byte(const char * addr) { - register unsigned char _v; + unsigned char _v; - __asm__ ("lbu\t%0,%1":"=r" (_v):"r" (*addr)); + __asm__ ("lbu\t%0,(%1)":"=r" (_v):"r" (*addr)); return _v; } @@ -27,7 +35,7 @@ static inline unsigned short get_user_word(const short *addr) { unsigned short _v; - __asm__ ("lhu\t%0,%1":"=r" (_v):"r" (*addr)); + __asm__ ("lhu\t%0,(%1)":"=r" (_v):"r" (*addr)); return _v; } @@ -38,7 +46,7 @@ static inline unsigned long get_user_long(const int *addr) { unsigned long _v; - __asm__ ("lwu\t%0,%1":"=r" (_v):"r" (*addr)); \ + __asm__ ("lwu\t%0,(%1)":"=r" (_v):"r" (*addr)); \ return _v; } @@ -48,7 +56,7 @@ static inline unsigned long get_user_dlong(const int *addr) { unsigned long _v; - __asm__ ("ld\t%0,%1":"=r" (_v):"r" (*addr)); \ + __asm__ ("ld\t%0,(%1)":"=r" (_v):"r" (*addr)); \ return _v; } @@ -56,28 +64,28 @@ static inline unsigned long get_user_dlong(const int *addr) static inline void put_user_byte(char val,char *addr) { -__asm__ ("sb\t%0,%1": /* no outputs */ :"r" (val),"r" (*addr)); +__asm__ ("sb\t%0,(%1)": /* no outputs */ :"r" (val),"r" (*addr)); } #define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr)) static inline void put_user_word(short val,short * addr) { -__asm__ ("sh\t%0,%1": /* no outputs */ :"r" (val),"r" (*addr)); +__asm__ ("sh\t%0,(%1)": /* no outputs */ :"r" (val),"r" (*addr)); } #define put_fs_word(x,addr) put_user_word((x),(short *)(addr)) static inline void put_user_long(unsigned long val,int * addr) { -__asm__ ("sw\t%0,%1": /* no outputs */ :"r" (val),"r" (*addr)); +__asm__ ("sw\t%0,(%1)": /* no outputs */ :"r" (val),"r" (*addr)); } #define put_fs_long(x,addr) put_user_long((x),(int *)(addr)) static inline void put_user_dlong(unsigned long val,int * addr) { -__asm__ ("sd\t%0,%1": /* no outputs */ :"r" (val),"r" (*addr)); +__asm__ ("sd\t%0,(%1)": /* no outputs */ :"r" (val),"r" (*addr)); } #define put_fs_dlong(x,addr) put_user_dlong((x),(int *)(addr)) @@ -214,4 +222,6 @@ static inline void set_fs(unsigned long val) segment_fs = val; } +#endif + #endif /* _ASM_MIPS_SEGMENT_H_ */ diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h new file mode 100644 index 000000000..6c66d6271 --- /dev/null +++ b/include/asm-mips/signal.h @@ -0,0 +1,28 @@ +#ifndef _ASM_MIPS_SIGNAL_H +#define _ASM_MIPS_SIGNAL_H + +#ifdef __KERNEL__ + +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; + /* + * Old userstack pointer ($29) + */ + unsigned long sc_sp; + + unsigned long oldmask; +}; + +#endif + +#endif /* _ASM_MIPS_SIGNAL_H */ diff --git a/include/asm-mips/slots.h b/include/asm-mips/slots.h new file mode 100644 index 000000000..fa5ae9fcb --- /dev/null +++ b/include/asm-mips/slots.h @@ -0,0 +1,17 @@ +/* + * include/asm-mips/slots.h + * + * Written by Ralf Baechle + * Copyright (C) 1994 by Waldorf GMBH + */ +#ifndef _ASM_MIPS_SLOTS_H +#define _ASM_MIPS_SLOTS_H + +/* + * SLOTSPACE is the address to which the physical address 0 + * of the Slotspace is mapped by the chipset in the main CPU's + * address space. + */ +#define SLOTSPACE 0xe1000000 + +#endif /* _ASM_MIPS_SLOTS_H */ diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h new file mode 100644 index 000000000..0c3c4699c --- /dev/null +++ b/include/asm-mips/stackframe.h @@ -0,0 +1,176 @@ +/* + * include/asm-mips/stackframe.h + * + * Copyright (C) 1994 Waldorf GMBH + * written by Ralf Baechle + */ + +#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. + */ +#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 + +/* + * $26 (k0) and $27 (k1) not saved + */ +#define FR_REG28 100 +#define FR_REG29 104 +#define FR_REG30 108 +#define FR_REG31 112 + +/* + * Saved special registers + */ +#define FR_LO ((FR_REG31) + 4) +#define FR_HI ((FR_LO) + 4) + +/* + * Saved cp0 registers follow + */ +#define FR_STATUS ((FR_HI) + 4) +#define FR_EPC ((FR_STATUS) + 4) +#define FR_ERROREPC ((FR_EPC) + 4) + +/* + * Some goodies... + */ +#define FR_INTERRUPT ((FR_ERROREPC) + 4) +#define FR_ORIG_REG2 ((FR_INTERRUPT) + 4) + +/* + * Size of stack frame + */ +#define FR_SIZE ((FR_ORIG_REG2) + 4) + +#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); \ + 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); \ + lw sp,FR_REG29(sp); /* Deallocate stack */ \ + eret + +#endif /* _ASM_MIPS_STACKFRAME_H_ */ diff --git a/include/asm-mips/string.h b/include/asm-mips/string.h index 06d4f2ce5..0116fd026 100644 --- a/include/asm-mips/string.h +++ b/include/asm-mips/string.h @@ -11,6 +11,8 @@ #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) @@ -77,7 +79,8 @@ extern inline int strcmp(const char * cs,const char * ct) "bne\t$1,%2,2f\n\t" "addiu\t%1,%1,1\n\t" "bne\t$0,%2,1b\n\t" - "lbu\t%2,(%0)\n" + "lbu\t%2,(%0)\n\t" + STR(FILL_LDS) "\n\t" "move\t%2,$1\n" "2:\tsub\t%2,%2,$1\n" "3:\t.set\tat\n\t" @@ -206,4 +209,24 @@ extern inline void * memmove(void * dest,const void * src, size_t n) #define __USE_PORTABLE_memcmp +static inline char * memscan(void * addr, unsigned char c, int size) +{ + if (!size) + return addr; + __asm__(".set\tnoreorder\n\t" + ".set\tnoat\n" + "1:\tbeq\t$0,%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" + ".set\tat\n\t" + ".set\treorder\n" + "2:" + : "=d" (addr), "=d" (size) + : "0" (addr), "1" (size), "d" (c) + : "$1"); + + return addr; +} #endif /* _ASM_MIPS_STRING_H_ */ diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 5e0dbfe3c..3a3029b31 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -11,8 +11,9 @@ #ifndef _ASM_MIPS_SYSTEM_H_ #define _ASM_MIPS_SYSTEM_H_ +#include <linux/types.h> #include <asm/segment.h> -#include <mips/mipsregs.h> +#include <asm/mipsregs.h> /* * move_to_user_mode() doesn't switch to user mode on the mips, since @@ -25,46 +26,64 @@ #define move_to_user_mode() #define sti() \ -__asm__ __volatile__( \ +__asm__ __volatile__( \ + ".set\tnoat\n\t" \ "mfc0\t$1,"STR(CP0_STATUS)"\n\t" \ - "ori\t$1,$1,1\n\t" \ + "ori\t$1,$1,0x1f\n\t" \ + "xori\t$1,$1,0x1e\n\t" \ "mtc0\t$1,"STR(CP0_STATUS)"\n\t" \ - : /* no outputs */ \ - : /* no inputs */ \ - : "$1","memory") + ".set\tat" \ + : /* no outputs */ \ + : /* no inputs */ \ + : "$1") #define cli() \ -__asm__ __volatile__( \ +__asm__ __volatile__( \ + ".set\tnoat\n\t" \ "mfc0\t$1,"STR(CP0_STATUS)"\n\t" \ - "srl\t$1,$1,1\n\t" \ - "sll\t$1,$1,1\n\t" \ + "ori\t$1,$1,1\n\t" \ + "xori\t$1,$1,1\n\t" \ "mtc0\t$1,"STR(CP0_STATUS)"\n\t" \ - : /* no outputs */ \ - : /* no inputs */ \ - : "$1","memory") + ".set\tat" \ + : /* no outputs */ \ + : /* no inputs */ \ + : "$1") #define nop() __asm__ __volatile__ ("nop") -#define save_flags(x) \ -__asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n\t" \ - "mfc0\t%0,$12\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ - : "=r" (x) \ - : /* no inputs */ \ - : "memory") +extern ulong IRQ_vectors[256]; +extern ulong exception_handlers[256]; -#define restore_flags(x) \ -__asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n\t" \ - "mtc0\t%0,$12\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ - : /* no output */ \ - : "r" (x) \ - : "memory") +#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__( \ + "mfc0\t%0,$12\n\t" \ + : "=r" (x)) \ + +#define restore_flags(x) \ +__asm__ __volatile__( \ + "mtc0\t%0,$12\n\t" \ + : /* no output */ \ + : "r" (x)); \ #endif /* _ASM_MIPS_SYSTEM_H_ */ diff --git a/include/asm-mips/types.h b/include/asm-mips/types.h new file mode 100644 index 000000000..236996dd5 --- /dev/null +++ b/include/asm-mips/types.h @@ -0,0 +1,39 @@ +#ifndef _ASM_MIPS_TYPES_H +#define _ASM_MIPS_TYPES_H + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed long s32; +typedef unsigned long u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#endif /* __KERNEL__ */ + +/* + * These definitions double the definitions from <gnu/types.h>. + */ +#undef __FDELT +#define __FDELT(d) ((d) / __NFDBITS) +#undef __FDMASK +#define __FDMASK(d) (1 << ((d) % __NFDBITS)) +#undef __FD_SET +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) +#undef __FD_CLR +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) +#undef __FD_ISSET +#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 /* _ASM_MIPS_TYPES_H */ diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 46ce46ff0..0776f3fdb 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -5,7 +5,7 @@ #define _syscall0(type,name) \ type name(void) \ { \ -register long __res; \ +register long __res __asm__ ("$2"); \ __asm__ volatile (".set\tnoat\n\t" \ "li\t$1,%1\n\t" \ ".set\tat\n\t" \ @@ -22,7 +22,7 @@ return -1; \ #define _syscall1(type,name,atype,a) \ type name(atype a) \ { \ -register long __res; \ +register long __res __asm__ ("$2"); \ __asm__ volatile ("move\t$2,%2\n\t" \ ".set\tnoat\n\t" \ "li\t$1,%1\n\t" \ @@ -40,7 +40,7 @@ return -1; \ #define _syscall2(type,name,atype,a,btype,b) \ type name(atype a,btype b) \ { \ -register long __res; \ +register long __res __asm__ ("$2"); \ __asm__ volatile ("move\t$2,%2\n\t" \ "move\t$3,%3\n\t" \ ".set\tnoat\n\t" \ @@ -60,7 +60,7 @@ return -1; \ #define _syscall3(type,name,atype,a,btype,b,ctype,c) \ type name (atype a, btype b, ctype c) \ { \ -register long __res; \ +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" \ @@ -82,7 +82,7 @@ return -1; \ #define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ type name (atype a, btype b, ctype c, dtype d) \ { \ -register long __res; \ +register long __res __asm__ ("$2"); \ __asm__ volatile (".set\tnoat\n\t" \ "move\t$2,%2\n\t" \ "move\t$3,%3\n\t" \ @@ -107,7 +107,7 @@ return -1; \ #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ type name (atype a,btype b,ctype c,dtype d,etype e) \ { \ -register long __res; \ +register long __res __asm__ ("$2"); \ __asm__ volatile (".set\tnoat\n\t" \ "move\t$2,%2\n\t" \ "move\t$3,%3\n\t" \ diff --git a/include/linux/head.h b/include/linux/head.h index 8911a6819..ea79de8e9 100644 --- a/include/linux/head.h +++ b/include/linux/head.h @@ -1,20 +1,9 @@ #ifndef _LINUX_HEAD_H #define _LINUX_HEAD_H -typedef struct desc_struct { - unsigned long a,b; -} desc_table[256]; - -extern unsigned long swapper_pg_dir[1024]; -extern desc_table idt,gdt; - -#define GDT_NUL 0 -#define GDT_CODE 1 -#define GDT_DATA 2 -#define GDT_TMP 3 - -#define LDT_NUL 0 -#define LDT_CODE 1 -#define LDT_DATA 2 +/* + * Include machine dependend stuff + */ +#include <asm/head.h> #endif diff --git a/include/linux/in.h b/include/linux/in.h index 1c268f216..bb26749a9 100644 --- a/include/linux/in.h +++ b/include/linux/in.h @@ -121,64 +121,9 @@ extern unsigned short int ntohs(unsigned short int); extern unsigned long int htonl(unsigned long int); extern unsigned short int htons(unsigned short int); -static __inline__ unsigned long int -__ntohl(unsigned long int x) -{ - __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ - "rorl $16,%0\n\t" /* swap words */ - "xchgb %b0,%h0" /* swap higher bytes */ - :"=q" (x) - : "0" (x)); - return x; -} - -static __inline__ unsigned long int -__constant_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) -{ - __asm__("xchgb %b0,%h0" /* swap bytes */ - : "=q" (x) - : "0" (x)); - return x; -} - -static __inline__ unsigned short int -__constant_ntohs(unsigned short int x) -{ - return (((x & 0x00ff) << 8) | - ((x & 0xff00) >> 8)); -} - -#define __htonl(x) __ntohl(x) -#define __htons(x) __ntohs(x) -#define __constant_htonl(x) __constant_ntohl(x) -#define __constant_htons(x) __constant_ntohs(x) - -#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 +/* + * include machine dependencies + */ +#include <asm/in.h> #endif /* _LINUX_IN_H */ diff --git a/include/linux/inet.h b/include/linux/inet.h index d8511a7ce..fbddc4e1f 100644 --- a/include/linux/inet.h +++ b/include/linux/inet.h @@ -42,11 +42,11 @@ #ifndef _LINUX_INET_H #define _LINUX_INET_H -#if defined(__i386__) +#if defined (__i386__) || defined (__MIPSEL__) #define NET16(x) ((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00)) -#elif defined(__mc68000__) +#elif #if defined (__mc680x0__) || defined (__MIPSEB__) #define NET16(x) (x) -#elif defined(__alpha__) +#elif defined (__alpha__) #define NET16(x) ((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00)) #else #error change this to match your machine diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 2ccaec523..6ef2710e8 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -24,19 +24,9 @@ enum { KEYBOARD_BH }; -extern inline void mark_bh(int nr) -{ - __asm__ __volatile__("orl %1,%0":"=m" (bh_active):"ir" (1<<nr)); -} - -extern inline void disable_bh(int nr) -{ - __asm__ __volatile__("andl %1,%0":"=m" (bh_mask):"ir" (~(1<<nr))); -} - -extern inline void enable_bh(int nr) -{ - __asm__ __volatile__("orl %1,%0":"=m" (bh_mask):"ir" (1<<nr)); -} +/* + * Include machine depended stuff + */ +#include <asm/interrupt.h> #endif diff --git a/include/linux/ip.h b/include/linux/ip.h index 1d3789638..75a40a2c9 100644 --- a/include/linux/ip.h +++ b/include/linux/ip.h @@ -32,19 +32,19 @@ struct timestamp { u8 len; u8 ptr; union { -#if defined(__i386__) - u8 flags:4, - overflow:4; -#elif defined(__mc68000__) - u8 overflow:4, +#if defined(__i386__) || defined(__MIPSEL__) + u8 flags:4, + overflow:4; +#elif defined(__mc68000__) || defined(__MIPSEB__) + unsigned char overflow:4, flags:4; #elif defined(__alpha__) - u8 flags:4, - overflow:4; + u8 flags:4, + overflow:4; #else #error "Adjust this structure to match your CPU" #endif - u8 full_char; + u8 full_char; } x; u32 data[9]; }; @@ -73,13 +73,13 @@ struct options { struct iphdr { -#if defined(__i386__) +#if defined(__i386__) || defined(__MIPSEL__) u8 ihl:4, version:4; -#elif defined (__mc68000__) +#elif defined (__mc68000__) || defined(__MIPSEB__) u8 version:4, ihl:4; -#elif defined (__alpha__) +#elif defined(__alpha__) u8 ihl:4, version:4; #else diff --git a/include/linux/mm.h b/include/linux/mm.h index e2128f033..d1f1b3a98 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -6,6 +6,7 @@ #include <linux/sched.h> #include <linux/errno.h> #include <linux/kernel.h> +#include <linux/string.h> #define VERIFY_READ 0 #define VERIFY_WRITE 1 @@ -142,10 +143,8 @@ extern inline unsigned long get_free_page(int priority) page = __get_free_page(priority); if (page) - __asm__ __volatile__("rep ; stosl" - : /* no outputs */ \ - :"a" (0),"c" (1024),"D" (page) - :"di","cx"); + memset((void *)page, 0, 4096); + return page; } @@ -172,8 +171,6 @@ extern void do_no_page(struct vm_area_struct * vma, unsigned long address, unsigned long error_code); extern unsigned long paging_init(unsigned long start_mem, unsigned long end_mem); -extern void mem_init(unsigned long low_start_mem, - unsigned long start_mem, unsigned long end_mem); extern void show_mem(void); extern void oom(struct task_struct * task); extern void si_meminfo(struct sysinfo * val); @@ -212,21 +209,6 @@ extern unsigned long high_memory; extern unsigned short * mem_map; -#define PAGE_PRESENT 0x001 -#define PAGE_RW 0x002 -#define PAGE_USER 0x004 -#define PAGE_PWT 0x008 /* 486 only - not used currently */ -#define PAGE_PCD 0x010 /* 486 only - not used currently */ -#define PAGE_ACCESSED 0x020 -#define PAGE_DIRTY 0x040 -#define PAGE_COW 0x200 /* implemented in software (one of the AVL bits) */ - -#define PAGE_PRIVATE (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED | PAGE_COW) -#define PAGE_SHARED (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED) -#define PAGE_COPY (PAGE_PRESENT | PAGE_USER | PAGE_ACCESSED | PAGE_COW) -#define PAGE_READONLY (PAGE_PRESENT | PAGE_USER | PAGE_ACCESSED) -#define PAGE_TABLE (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED) - #define GFP_BUFFER 0x00 #define GFP_ATOMIC 0x01 #define GFP_USER 0x02 @@ -268,46 +250,10 @@ extern inline unsigned long in_swap_cache(unsigned long addr) return swap_cache[addr >> PAGE_SHIFT]; } -extern inline long find_in_swap_cache (unsigned long addr) -{ - unsigned long entry; - -#ifdef SWAP_CACHE_INFO - swap_cache_find_total++; -#endif - __asm__ __volatile__("xchgl %0,%1" - :"=m" (swap_cache[addr >> PAGE_SHIFT]), - "=r" (entry) - :"0" (swap_cache[addr >> PAGE_SHIFT]), - "1" (0)); -#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 - __asm__ __volatile__("xchgl %0,%1" - :"=m" (swap_cache[addr >> PAGE_SHIFT]), - "=r" (entry) - :"0" (swap_cache[addr >> PAGE_SHIFT]), - "1" (0)); - if (entry) { -#ifdef SWAP_CACHE_INFO - swap_cache_del_success++; -#endif - swap_free(entry); - return 1; - } - return 0; -} +/* + * Include machine dependend stuff + */ +#include <asm/mm.h> #endif /* __KERNEL__ */ diff --git a/include/linux/ncp.h b/include/linux/ncp.h new file mode 100644 index 000000000..bd6daf29d --- /dev/null +++ b/include/linux/ncp.h @@ -0,0 +1,106 @@ +#ifndef _LINUX_NCP_H_ +#define _LINUX_NCP_H_ + +#define NCP_OPEN 0x1111 +#define NCP_CLOSE 0x5555 +#define NCP_REQUEST 0x2222 +#define NCP_REPLY 0x3333 + +struct ncp_request +{ + unsigned short p_type __attribute__ ((packed)); + unsigned char seq __attribute__ ((packed)); + unsigned char c_low __attribute__ ((packed)); + unsigned char task __attribute__ ((packed)); + unsigned char c_high __attribute__ ((packed)); + unsigned char func __attribute__ ((packed)); +}; + +struct ncp_request_sf +{ + unsigned short p_type __attribute__ ((packed)); + unsigned char seq __attribute__ ((packed)); + unsigned char c_low __attribute__ ((packed)); + unsigned char task __attribute__ ((packed)); + unsigned char c_high __attribute__ ((packed)); + unsigned char func __attribute__ ((packed)); + unsigned short s_len __attribute__ ((packed)); + unsigned char s_func __attribute__ ((packed)); +}; + +struct ncp_reply +{ + unsigned short p_type __attribute__ ((packed)); + unsigned char seq __attribute__ ((packed)); + unsigned char c_low __attribute__ ((packed)); + unsigned char task __attribute__ ((packed)); + unsigned char c_high __attribute__ ((packed)); + unsigned char f_stat __attribute__ ((packed)); + unsigned char c_stat __attribute__ ((packed)); +}; + +#define OTYPE_USER 0x0001 +#define OTYPE_GROUP 0x0002 +#define OTYPE_PQUEUE 0x0003 +#define OTYPE_FSERVER 0x0004 +#define OTYPE_JSERVER 0x0005 +#define OTYPE_PSERVER 0x0007 +#define OTYPE_UNKNOWN_1 0x002E +#define OTYPE_ADV_PSERVER 0x0047 +#define OTYPE_AFSERVER 0x0107 +#define OTYPE_UNKNOWN_2 0x0143 +#define OTYPE_UNKNOWN_3 0x01F5 +#define OTYPE_UNKNOWN_4 0x023F + +#define LIMIT_OBJNAME 47 + +struct bind_obj +{ + unsigned long id __attribute__ ((packed)); + unsigned short type __attribute__ ((packed)); + char name[LIMIT_OBJNAME+1] __attribute__ ((packed)); +}; + +struct get_bind_obj +{ + unsigned short type __attribute__ ((packed)); + unsigned char n_len __attribute__ ((packed)); + char name[0] __attribute__ ((packed)); +}; + +struct scan_bind_obj +{ + unsigned long id __attribute__ ((packed)); + unsigned short type __attribute__ ((packed)); + unsigned char n_len __attribute__ ((packed)); + char name[0] __attribute__ ((packed)); +}; + +struct login_req +{ + unsigned char password[8] __attribute__ ((packed)); + unsigned short type __attribute__ ((packed)); + unsigned char n_len __attribute__ ((packed)); + char name[0] __attribute__ ((packed)); +}; + +struct ncp_time +{ + unsigned char year __attribute__ ((packed)); + unsigned char month __attribute__ ((packed)); + unsigned char day __attribute__ ((packed)); + unsigned char hours __attribute__ ((packed)); + unsigned char mins __attribute__ ((packed)); + unsigned char secs __attribute__ ((packed)); + unsigned char c_secs __attribute__ ((packed)); +}; + +struct login_info +{ + unsigned long id __attribute__ ((packed)); + unsigned short un1 __attribute__ ((packed)); + char name[LIMIT_OBJNAME+1] __attribute__ ((packed)); + struct ncp_time time __attribute__ ((packed)); +}; +#endif + diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 6718860e0..c98e66a68 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -1,9 +1,11 @@ #ifndef _LINUX_PTRACE_H #define _LINUX_PTRACE_H -/* ptrace.h */ -/* structs and defines to help the user use the ptrace system call. */ -/* has the defines to get at the registers. */ +/* + * linux/include/linux/ptrace.h + * + * structs and defines to help the user use the ptrace system call. + */ #define PTRACE_TRACEME 0 #define PTRACE_PEEKTEXT 1 @@ -21,49 +23,9 @@ #define PTRACE_SYSCALL 24 -/* use ptrace (3 or 6, pid, PT_EXCL, data); to read or write - the processes registers. */ - -#define EBX 0 -#define ECX 1 -#define EDX 2 -#define ESI 3 -#define EDI 4 -#define EBP 5 -#define EAX 6 -#define DS 7 -#define ES 8 -#define FS 9 -#define GS 10 -#define ORIG_EAX 11 -#define EIP 12 -#define CS 13 -#define EFL 14 -#define UESP 15 -#define SS 16 - - -/* this struct defines the way the registers are stored on the - stack during a system call. */ - -struct pt_regs { - long ebx; - long ecx; - long edx; - long esi; - long edi; - long ebp; - long eax; - unsigned short ds, __dsu; - unsigned short es, __esu; - unsigned short fs, __fsu; - unsigned short gs, __gsu; - long orig_eax; - long eip; - unsigned short cs, __csu; - long eflags; - long esp; - unsigned short ss, __ssu; -}; +/* + * include machine dependend stuff + */ +#include <asm/ptrace.h> #endif diff --git a/include/linux/sched.h b/include/linux/sched.h index 3a38d57eb..76519a8b9 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -15,26 +15,6 @@ * System setup and hardware bug flags.. */ extern int hard_math; -extern int x86; -extern int ignore_irq13; -extern int wp_works_ok; /* doesn't work on a 386 */ -extern int hlt_works_ok; /* problems on some 486Dx4's and old 386's */ - -extern unsigned long intr_count; -extern unsigned long event; - -#define start_bh_atomic() \ -__asm__ __volatile__("incl _intr_count") - -#define end_bh_atomic() \ -__asm__ __volatile__("decl _intr_count") - -/* - * 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 #include <linux/binfmts.h> #include <linux/personality.h> @@ -42,17 +22,6 @@ extern int EISA_bus; #include <asm/system.h> /* - * User space process size: 3GB. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. - */ -#define TASK_SIZE 0xc0000000 - -/* - * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. - */ -#define IO_BITMAP_SIZE 32 - -/* * These are the constant used to fake the fixed-point load-average * counting. Some notes: * - 11 bit fractions expand to 22 bits by the multiplies: this gives @@ -62,22 +31,22 @@ extern int EISA_bus; * the EXP_n values would be 1981, 2034 and 2043 if still using only * 11 bit fractions. */ -extern unsigned long avenrun[]; /* Load averages */ +extern unsigned long avenrun[]; /* Load averages */ -#define FSHIFT 11 /* nr of bits of precision */ -#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */ -#define LOAD_FREQ (5*HZ) /* 5 sec intervals */ -#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */ -#define EXP_5 2014 /* 1/exp(5sec/5min) */ -#define EXP_15 2037 /* 1/exp(5sec/15min) */ +#define FSHIFT 11 /* nr of bits of precision */ +#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */ +#define LOAD_FREQ (5*HZ) /* 5 sec intervals */ +#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */ +#define EXP_5 2014 /* 1/exp(5sec/5min) */ +#define EXP_15 2037 /* 1/exp(5sec/15min) */ #define CALC_LOAD(load,exp,n) \ load *= exp; \ load += n*(FIXED_1-exp); \ load >>= FSHIFT; -#define CT_TO_SECS(x) ((x) / HZ) -#define CT_TO_USECS(x) (((x) % HZ) * 1000000/HZ) +#define CT_TO_SECS(x) ((x) / HZ) +#define CT_TO_USECS(x) (((x) % HZ) * 1000000/HZ) #define FIRST_TASK task[0] #define LAST_TASK task[NR_TASKS-1] @@ -89,16 +58,16 @@ extern unsigned long avenrun[]; /* Load averages */ #include <linux/time.h> #include <linux/param.h> #include <linux/resource.h> -#include <linux/vm86.h> +/* #include <linux/vm86.h> */ #include <linux/math_emu.h> #include <linux/ptrace.h> -#define TASK_RUNNING 0 -#define TASK_INTERRUPTIBLE 1 -#define TASK_UNINTERRUPTIBLE 2 -#define TASK_ZOMBIE 3 -#define TASK_STOPPED 4 -#define TASK_SWAPPING 5 +#define TASK_RUNNING 0 +#define TASK_INTERRUPTIBLE 1 +#define TASK_UNINTERRUPTIBLE 2 +#define TASK_ZOMBIE 3 +#define TASK_STOPPED 4 +#define TASK_SWAPPING 5 #ifndef NULL #define NULL ((void *) 0) @@ -114,82 +83,6 @@ asmlinkage void schedule(void); #endif /* __KERNEL__ */ -struct i387_hard_struct { - long cwd; - long swd; - long twd; - long fip; - long fcs; - long foo; - long fos; - long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ -}; - -struct i387_soft_struct { - long cwd; - long swd; - long twd; - long fip; - long fcs; - long foo; - long fos; - long top; - struct fpu_reg regs[8]; /* 8*16 bytes for each FP-reg = 128 bytes */ - unsigned char lookahead; - struct info *info; - unsigned long entry_eip; -}; - -union i387_union { - struct i387_hard_struct hard; - struct i387_soft_struct soft; -}; - -struct tss_struct { - unsigned short back_link,__blh; - unsigned long esp0; - unsigned short ss0,__ss0h; - unsigned long esp1; - unsigned short ss1,__ss1h; - unsigned long esp2; - unsigned short ss2,__ss2h; - unsigned long cr3; - unsigned long eip; - unsigned long eflags; - unsigned long eax,ecx,edx,ebx; - unsigned long esp; - unsigned long ebp; - unsigned long esi; - unsigned long edi; - unsigned short es, __esh; - unsigned short cs, __csh; - unsigned short ss, __ssh; - unsigned short ds, __dsh; - unsigned short fs, __fsh; - unsigned short gs, __gsh; - unsigned short ldt, __ldth; - unsigned short trace, bitmap; - unsigned long io_bitmap[IO_BITMAP_SIZE+1]; - unsigned long tr; - unsigned long cr2, trap_no, error_code; - union i387_union i387; -}; - -#define INIT_TSS { \ - 0,0, \ - sizeof(init_kernel_stack) + (long) &init_kernel_stack, \ - KERNEL_DS, 0, \ - 0,0,0,0,0,0, \ - (long) &swapper_pg_dir, \ - 0,0,0,0,0,0,0,0,0,0, \ - USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0, \ - _LDT(0),0, \ - 0, 0x8000, \ - {~0, }, /* ioperm */ \ - _TSS(0), 0, 0,0, \ - { { 0, }, } /* 387 state */ \ -} - struct files_struct { int count; fd_set close_on_exec; @@ -223,9 +116,10 @@ struct mm_struct { unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; int swappable:1; unsigned long swap_address; - unsigned long old_maj_flt; /* old value of maj_flt */ - unsigned long dec_flt; /* page fault count of the last time */ - unsigned long swap_cnt; /* number of pages to swap on next pass */ + unsigned long old_maj_flt; /* old value of maj_flt */ + unsigned long dec_flt; /* page fault count of the last time */ + unsigned long swap_cnt; /* number of pages to swap on next pass +*/ struct vm_area_struct * mmap; }; @@ -242,113 +136,22 @@ struct mm_struct { /* swap */ 0, 0, 0, 0, \ &init_mmap } -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]; -}; - /* * Per process flags */ -#define PF_ALIGNWARN 0x00000001 /* Print alignment warning msgs */ +#define PF_ALIGNWARN 0x00000001 /* Print alignment warning msgs */ /* Not implemented yet, only for 486*/ -#define PF_PTRACED 0x00000010 /* set if ptrace (0) has been called. */ -#define PF_TRACESYS 0x00000020 /* tracing system calls */ +#define PF_PTRACED 0x00000010 /* set if ptrace (0) has been called. */ +#define PF_TRACESYS 0x00000020 /* tracing system calls */ /* * cloning flags: */ #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */ -#define COPYVM 0x00000100 /* set if VM copy desired (like normal fork()) */ -#define COPYFD 0x00000200 /* set if fd's should be copied, not shared (NI) */ - -/* - * 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 } \ -} +#define COPYVM 0x00000100 /* set if VM copy desired (like normal f +ork()) */ +#define COPYFD 0x00000200 /* set if fd's should be copied, not sha +red (NI) */ #ifdef __KERNEL__ @@ -373,98 +176,31 @@ extern void notify_parent(struct task_struct * tsk); extern int send_sig(unsigned long sig,struct task_struct * p,int priv); extern int in_group_p(gid_t grp); -extern int request_irq(unsigned int irq,void (*handler)(int), unsigned long flags, const char *device); +extern int request_irq(unsigned int irq,void (*handler)(int), + unsigned long flags, const char *device); extern void free_irq(unsigned int irq); /* - * Entry into gdt where to find first TSS. GDT layout: - * 0 - nul - * 1 - kernel code segment - * 2 - kernel data segment - * 3 - user code segment - * 4 - user data segment - * ... - * 8 - TSS #0 - * 9 - LDT #0 - * 10 - TSS #1 - * 11 - LDT #1 - */ -#define FIRST_TSS_ENTRY 8 -#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1) -#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3)) -#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3)) -#define load_TR(n) __asm__("ltr %%ax": /* no output */ :"a" (_TSS(n))) -#define load_ldt(n) __asm__("lldt %%ax": /* no output */ :"a" (_LDT(n))) -#define store_TR(n) \ -__asm__("str %%ax\n\t" \ - "subl %2,%%eax\n\t" \ - "shrl $4,%%eax" \ - :"=a" (n) \ - :"0" (0),"i" (FIRST_TSS_ENTRY<<3)) -/* - * 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__("cli\n\t" \ - "xchgl %%ecx,_current\n\t" \ - "ljmp %0\n\t" \ - "sti\n\t" \ - "cmpl %%ecx,_last_task_used_math\n\t" \ - "jne 1f\n\t" \ - "clts\n" \ - "1:" \ - : /* no output */ \ - :"m" (*(((char *)&tsk->tss.tr)-4)), \ - "c" (tsk) \ - :"cx") - -#define _set_base(addr,base) \ -__asm__("movw %%dx,%0\n\t" \ - "rorl $16,%%edx\n\t" \ - "movb %%dl,%1\n\t" \ - "movb %%dh,%2" \ - : /* no output */ \ - :"m" (*((addr)+2)), \ - "m" (*((addr)+4)), \ - "m" (*((addr)+7)), \ - "d" (base) \ - :"dx") - -#define _set_limit(addr,limit) \ -__asm__("movw %%dx,%0\n\t" \ - "rorl $16,%%edx\n\t" \ - "movb %1,%%dh\n\t" \ - "andb $0xf0,%%dh\n\t" \ - "orb %%dh,%%dl\n\t" \ - "movb %%dl,%1" \ - : /* no output */ \ - :"m" (*(addr)), \ - "m" (*((addr)+6)), \ - "d" (limit) \ - :"dx") - -#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base ) -#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 ) - -/* * The wait-queues are circular lists, and you have to be *very* sure * to keep them correct. Use only these two functions to add/remove * entries in the queues. */ -extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wait) +extern inline void add_wait_queue(struct wait_queue ** p, + struct wait_queue * wait) { - unsigned long flags; + unsigned long flags; -#ifdef DEBUG +#if defined (DEBUG) && defined (__mips__) + /* + * FIXME: I don't work for MIPS yet + */ if (wait->next) { unsigned long pc; __asm__ __volatile__("call 1f\n" "1:\tpopl %0":"=r" (pc)); - printk("add_wait_queue (%08x): wait->next = %08x\n",pc,(unsigned long) wait->next); - } + printk("add_wait_queue (%08x): wait->next = %08x\n",pc, + (unsigned long) wait->next); + } #endif save_flags(flags); cli(); @@ -478,27 +214,37 @@ extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wa restore_flags(flags); } -extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait) +extern inline void remove_wait_queue(struct wait_queue ** p, + struct wait_queue *wait) { unsigned long flags; struct wait_queue * tmp; -#ifdef DEBUG +#if defined (DEBUG) && !defined(__mips__) + /* + * FIXME: I don't work for MIPS yet + */ unsigned long ok = 0; #endif save_flags(flags); cli(); if ((*p == wait) && -#ifdef DEBUG +#if defined (DEBUG) && !defined(__mips__) + /* + * FIXME: I don't work for MIPS yet + */ (ok = 1) && #endif ((*p = wait->next) == wait)) { *p = NULL; - } else { + } else { tmp = wait; while (tmp->next != wait) { tmp = tmp->next; -#ifdef DEBUG +#if defined (DEBUG) && !defined(__mips__) + /* + * FIXME: I don't work for MIPS yet + */ if (tmp == *p) ok = 1; #endif @@ -507,17 +253,22 @@ extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * } wait->next = NULL; restore_flags(flags); -#ifdef DEBUG +#if defined (DEBUG) && !defined(__mips__) + /* + * FIXME: I don't work for MIPS yet + */ if (!ok) { printk("removed wait_queue not on list.\n"); - printk("list = %08x, queue = %08x\n",(unsigned long) p, (unsigned long) wait); + printk("list = %08x, queue = %08x\n",(unsigned long) p, (unsigne +d long) wait); __asm__("call 1f\n1:\tpopl %0":"=r" (ok)); printk("eip = %08x\n",ok); } #endif } -extern inline void select_wait(struct wait_queue ** wait_address, select_table * p) +extern inline void select_wait(struct wait_queue ** wait_address, + select_table *p) { struct select_table_entry * entry; @@ -525,7 +276,7 @@ extern inline void select_wait(struct wait_queue ** wait_address, select_table * return; if (p->nr >= __MAX_SELECT_TABLE_ENTRIES) return; - entry = p->entry + p->nr; + entry = p->entry + p->nr; entry->wait_address = wait_address; entry->wait.task = current; entry->wait.next = NULL; @@ -549,30 +300,6 @@ extern inline void up(struct semaphore * sem) { sem->count++; wake_up(&sem->wait); -} - -static inline unsigned long _get_base(char * addr) -{ - unsigned long __base; - __asm__("movb %3,%%dh\n\t" - "movb %2,%%dl\n\t" - "shll $16,%%edx\n\t" - "movw %1,%%dx" - :"=&d" (__base) - :"m" (*((addr)+2)), - "m" (*((addr)+4)), - "m" (*((addr)+7))); - return __base; -} - -#define get_base(ldt) _get_base( ((char *)&(ldt)) ) - -static inline unsigned long get_limit(unsigned long segment) -{ - unsigned long __limit; - __asm__("lsll %1,%0" - :"=r" (__limit):"r" (segment)); - return __limit+1; } #define REMOVE_LINKS(p) do { unsigned long flags; \ @@ -604,21 +331,11 @@ static inline unsigned long get_limit(unsigned long segment) #define for_each_task(p) \ for (p = &init_task ; (p = p->next_task) != &init_task ; ) +#endif /* __KERNEL__ */ + /* - * This is the ldt that every process will get unless we need - * something other than this. + * Include machine dependent stuff */ -extern struct desc_struct default_ldt; - -/* This special macro can be used to load a debugging register */ - -#define loaddebug(register) \ - __asm__("movl %0,%%edx\n\t" \ - "movl %%edx,%%db" #register "\n\t" \ - : /* no output */ \ - :"m" (current->debugreg[register]) \ - :"dx"); - -#endif /* __KERNEL__ */ +#include <asm/sched.h> #endif diff --git a/include/linux/signal.h b/include/linux/signal.h index ed625098f..4527fae69 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -76,33 +76,9 @@ struct sigaction { void (*sa_restorer)(void); }; -#ifdef __KERNEL__ - -struct sigcontext_struct { - unsigned short gs, __gsh; - unsigned short fs, __fsh; - unsigned short es, __esh; - unsigned short ds, __dsh; - unsigned long edi; - unsigned long esi; - unsigned long ebp; - unsigned long esp; - unsigned long ebx; - unsigned long edx; - unsigned long ecx; - unsigned long eax; - unsigned long trapno; - unsigned long err; - unsigned long eip; - unsigned short cs, __csh; - unsigned long eflags; - unsigned long esp_at_signal; - unsigned short ss, __ssh; - unsigned long i387; - unsigned long oldmask; - unsigned long cr2; -}; - -#endif +/* + * Include machine dependencies + */ +#include <asm/signal.h> #endif diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 4acc22cae..36fe49b53 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -17,7 +17,6 @@ #ifndef _LINUX_TCP_H #define _LINUX_TCP_H -#include <asm/types.h> #define HEADER_SIZE 64 /* maximum header size */ @@ -27,7 +26,7 @@ struct tcphdr { u16 dest; u32 seq; u32 ack_seq; -#if defined(__i386__) +#if defined(__i386__) || defined(__MIPSEL__) u16 res1:4, doff:4, fin:1, @@ -37,7 +36,7 @@ struct tcphdr { ack:1, urg:1, res2:2; -#elif defined(__mc68000__) +#elif defined(__mc68000__) || defined(__MIPSEB__) u16 res2:2, urg:1, ack:1, diff --git a/include/linux/tqueue.h b/include/linux/tqueue.h index d264495e3..45b4403a0 100644 --- a/include/linux/tqueue.h +++ b/include/linux/tqueue.h @@ -144,8 +144,7 @@ _INLINE_ void run_task_queue(task_queue *list) while(1) { p = &tq_last; - __asm__ __volatile__("xchgl %0,%2" : "=r" (p) : - "0" (p), "m" (*list) : "memory"); + atomic_exchange(*list,p); if(p == &tq_last) break; diff --git a/include/linux/types.h b/include/linux/types.h index bc068f3b3..8d04cf810 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -94,30 +94,10 @@ typedef struct fd_set { #undef __FD_SETSIZE #define __FD_SETSIZE (__FDSET_LONGS*__NFDBITS) -#undef __FD_SET -#define __FD_SET(fd,fdsetp) \ - __asm__ __volatile__("btsl %1,%0": \ - "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd))) - -#undef __FD_CLR -#define __FD_CLR(fd,fdsetp) \ - __asm__ __volatile__("btrl %1,%0": \ - "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd))) - -#undef __FD_ISSET -#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \ - unsigned char __result; \ - __asm__ __volatile__("btl %1,%2 ; setb %0" \ - :"=q" (__result) :"r" ((int) (fd)), \ - "m" (*(fd_set *) (fdsetp))); \ - __result; })) - -#undef __FD_ZERO -#define __FD_ZERO(fdsetp) \ - __asm__ __volatile__("cld ; rep ; stosl" \ - :"=m" (*(fd_set *) (fdsetp)) \ - :"a" (0), "c" (__FDSET_LONGS), \ - "D" ((fd_set *) (fdsetp)) :"cx","di") +/* + * Include machine dependent assembler stuff + */ +#include <asm/types.h> struct ustat { daddr_t f_tfree; |