diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-01-10 05:27:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-01-10 05:27:25 +0000 |
commit | c9c06167e7933d93a6e396174c68abf242294abb (patch) | |
tree | d9a8bb30663e9a3405a1ef37ffb62bc14b9f019f /include/asm-m68k | |
parent | f79e8cc3c34e4192a3e5ef4cc9c6542fdef703c0 (diff) |
Merge with Linux 2.4.0-test12.
Diffstat (limited to 'include/asm-m68k')
31 files changed, 1250 insertions, 616 deletions
diff --git a/include/asm-m68k/amigahw.h b/include/asm-m68k/amigahw.h index d63ceca32..3e5a2770c 100644 --- a/include/asm-m68k/amigahw.h +++ b/include/asm-m68k/amigahw.h @@ -16,6 +16,8 @@ #ifndef _M68K_AMIGAHW_H #define _M68K_AMIGAHW_H +#include <linux/ioport.h> + /* * Different Amiga models */ @@ -279,11 +281,27 @@ struct CIA { #define ciab ((*(volatile struct CIA *)(zTwoBase + CIAB_PHYSADDR))) #define CHIP_PHYSADDR (0x000000) -#define chipaddr ((unsigned long)(zTwoBase + CHIP_PHYSADDR)) + void amiga_chip_init (void); -void *amiga_chip_alloc (long size, const char *name); -void amiga_chip_free (void *); +void *amiga_chip_alloc(unsigned long size, const char *name); +void *amiga_chip_alloc_res(unsigned long size, struct resource *res); +void amiga_chip_free(void *ptr); unsigned long amiga_chip_avail( void ); /*MILAN*/ +extern volatile unsigned short amiga_audio_min_period; + +static inline void amifb_video_off(void) +{ + if (amiga_chipset == CS_ECS || amiga_chipset == CS_AGA) { + /* program Denise/Lisa for a higher maximum play rate */ + custom.htotal = 113; /* 31 kHz */ + custom.vtotal = 223; /* 70 Hz */ + custom.beamcon0 = 0x4390; /* HARDDIS, VAR{BEAM,VSY,HSY,CSY}EN */ + /* suspend the monitor */ + custom.hsstrt = custom.hsstop = 116; + custom.vsstrt = custom.vsstop = 226; + amiga_audio_min_period = 57; + } +} struct tod3000 { unsigned int :28, second2:4; /* lower digit */ diff --git a/include/asm-m68k/amigaints.h b/include/asm-m68k/amigaints.h index 35bc3e18e..2aff4cfbf 100644 --- a/include/asm-m68k/amigaints.h +++ b/include/asm-m68k/amigaints.h @@ -106,12 +106,8 @@ #define IF_DSKBLK 0x0002 /* diskblock DMA finished */ #define IF_TBE 0x0001 /* serial transmit buffer empty interrupt */ -struct irq_server { - unsigned short count, reentrance; -}; - extern void amiga_do_irq(int irq, struct pt_regs *fp); -extern void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server); +extern void amiga_do_irq_list(int irq, struct pt_regs *fp); extern unsigned short amiga_intena_vals[]; diff --git a/include/asm-m68k/amipcmcia.h b/include/asm-m68k/amipcmcia.h index 78ffce6aa..6f1ec1887 100644 --- a/include/asm-m68k/amipcmcia.h +++ b/include/asm-m68k/amipcmcia.h @@ -36,17 +36,17 @@ static inline u_char pcmcia_get_intreq(void) static inline void pcmcia_ack_int(u_char intreq) { - gayle.intreq = ((intreq & 0x2c) ^ 0x2c) | 0xc0; + gayle.intreq = 0xf8; } static inline void pcmcia_enable_irq(void) { - gayle.inten = GAYLE_IRQ_IDE|GAYLE_IRQ_IRQ; + gayle.inten |= GAYLE_IRQ_IRQ; } static inline void pcmcia_disable_irq(void) { - gayle.inten = GAYLE_IRQ_IDE; + gayle.inten &= ~GAYLE_IRQ_IRQ; } #define PCMCIA_INSERTED (gayle.cardstatus & GAYLE_CS_CCDET) diff --git a/include/asm-m68k/atari_stram.h b/include/asm-m68k/atari_stram.h index 31d620b67..7546d1396 100644 --- a/include/asm-m68k/atari_stram.h +++ b/include/asm-m68k/atari_stram.h @@ -6,12 +6,12 @@ */ /* public interface */ -void *atari_stram_alloc( long size, unsigned long *start_mem, - const char *owner ); -void atari_stram_free( void *); +void *atari_stram_alloc(long size, const char *owner); +void atari_stram_free(void *); /* functions called internally by other parts of the kernel */ -void atari_stram_init( void); -void atari_stram_reserve_pages( unsigned long start_mem ); +void atari_stram_init(void); +void atari_stram_reserve_pages(void *start_mem); +void atari_stram_mem_init_hook (void); #endif /*_M68K_ATARI_STRAM_H */ diff --git a/include/asm-m68k/atarihw.h b/include/asm-m68k/atarihw.h index 8937fc2d1..e27147ae8 100644 --- a/include/asm-m68k/atarihw.h +++ b/include/asm-m68k/atarihw.h @@ -123,7 +123,7 @@ extern struct atari_hw_present atari_hw_present; */ #include <linux/mm.h> -#include <asm/pgtable.h> +#include <asm/pgalloc.h> static inline void dma_cache_maintenance( unsigned long paddr, unsigned long len, diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h index ff1c8b9fa..7d91887d7 100644 --- a/include/asm-m68k/bitops.h +++ b/include/asm-m68k/bitops.h @@ -83,6 +83,12 @@ extern __inline__ int __generic_test_and_clear_bit(int nr, void * vaddr) return retval; } +/* + * clear_bit() doesn't provide any barrier for the compiler. + */ +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + #define clear_bit(nr,vaddr) \ (__builtin_constant_p(nr) ? \ __constant_clear_bit(nr, vaddr) : \ diff --git a/include/asm-m68k/entry.h b/include/asm-m68k/entry.h index 444d5ba35..d5eae1ee1 100644 --- a/include/asm-m68k/entry.h +++ b/include/asm-m68k/entry.h @@ -49,13 +49,13 @@ LFLUSH_I_AND_D = 0x00000808 LSIGTRAP = 5 -/* process bits for task_struct.flags */ -PF_TRACESYS_OFF = 3 -PF_TRACESYS_BIT = 5 -PF_PTRACED_OFF = 3 -PF_PTRACED_BIT = 4 -PF_DTRACE_OFF = 1 -PF_DTRACE_BIT = 5 +/* process bits for task_struct.ptrace */ +PT_TRACESYS_OFF = 3 +PT_TRACESYS_BIT = 1 +PT_PTRACED_OFF = 3 +PT_PTRACED_BIT = 0 +PT_DTRACE_OFF = 3 +PT_DTRACE_BIT = 2 #define SAVE_ALL_INT save_all_int #define SAVE_ALL_SYS save_all_sys diff --git a/include/asm-m68k/fcntl.h b/include/asm-m68k/fcntl.h index 9738061b7..c0b273f68 100644 --- a/include/asm-m68k/fcntl.h +++ b/include/asm-m68k/fcntl.h @@ -35,6 +35,10 @@ #define F_SETSIG 10 /* for sockets. */ #define F_GETSIG 11 /* for sockets. */ +#define F_GETLK64 12 /* using 'struct flock64' */ +#define F_SETLK64 13 +#define F_SETLKW64 14 + /* for F_[GET|SET]FL */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ @@ -70,5 +74,13 @@ struct flock { pid_t l_pid; }; +struct flock64 { + short l_type; + short l_whence; + loff_t l_start; + loff_t l_len; + pid_t l_pid; +}; + #define F_LINUX_SPECIFIC_BASE 1024 #endif /* _M68K_FCNTL_H */ diff --git a/include/asm-m68k/keyboard.h b/include/asm-m68k/keyboard.h index 555ef68ec..4129be701 100644 --- a/include/asm-m68k/keyboard.h +++ b/include/asm-m68k/keyboard.h @@ -8,12 +8,12 @@ * This file contains the m68k architecture specific keyboard definitions */ -#include <linux/config.h> /* CONFIG_MAGIC_SYSRQ */ #ifndef __M68K_KEYBOARD_H #define __M68K_KEYBOARD_H #ifdef __KERNEL__ +#include <linux/config.h> #include <asm/machdep.h> #ifdef CONFIG_Q40 @@ -39,17 +39,6 @@ static __inline__ int kbd_getkeycode(unsigned int scancode) return scancode > 127 ? -EINVAL : scancode; } -static __inline__ int kbd_translate(unsigned char scancode, - unsigned char *keycode, char raw_mode) -{ -#ifdef CONFIG_Q40 - if (MACH_IS_Q40) - return q40kbd_translate(scancode,keycode,raw_mode); -#endif - *keycode = scancode; - return 1; -} - static __inline__ char kbd_unexpected_up(unsigned char keycode) { #ifdef CONFIG_Q40 @@ -65,15 +54,16 @@ static __inline__ void kbd_leds(unsigned char leds) mach_kbd_leds(leds); } -#ifdef CONFIG_MAGIC_SYSRQ -#define kbd_is_sysrq(keycode) ((keycode) == mach_sysrq_key && \ - (up_flag || \ - (shift_state & mach_sysrq_shift_mask) == \ - mach_sysrq_shift_state)) -#define kbd_sysrq_xlate mach_sysrq_xlate -#endif +#define kbd_init_hw mach_keyb_init +#define kbd_translate mach_kbd_translate + +#define kbd_sysrq_xlate mach_sysrq_xlate + +/* resource allocation */ +#define kbd_request_region() +#define kbd_request_irq(handler) -#define kbd_init_hw mach_keyb_init +extern unsigned int SYSRQ_KEY; #endif /* __KERNEL__ */ diff --git a/include/asm-m68k/machdep.h b/include/asm-m68k/machdep.h index 864f09ecd..269d90b9d 100644 --- a/include/asm-m68k/machdep.h +++ b/include/asm-m68k/machdep.h @@ -13,6 +13,7 @@ extern void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)); extern int (*mach_keyb_init) (void); extern int (*mach_kbdrate) (struct kbd_repeat *); extern void (*mach_kbd_leds) (unsigned int); +extern int (*mach_kbd_translate)(unsigned char scancode, unsigned char *keycode, char raw_mode); /* machine dependent irq functions */ extern void (*mach_init_IRQ) (void); extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); diff --git a/include/asm-m68k/mman.h b/include/asm-m68k/mman.h index cbee6c998..8255e9d60 100644 --- a/include/asm-m68k/mman.h +++ b/include/asm-m68k/mman.h @@ -25,6 +25,12 @@ #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ +#define MADV_NORMAL 0x0 /* default page-in behavior */ +#define MADV_RANDOM 0x1 /* page-in minimum required */ +#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ +#define MADV_WILLNEED 0x3 /* pre-fault pages */ +#define MADV_DONTNEED 0x4 /* discard these pages */ + /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS #define MAP_FILE 0 diff --git a/include/asm-m68k/motorola_pgalloc.h b/include/asm-m68k/motorola_pgalloc.h new file mode 100644 index 000000000..9257aeb43 --- /dev/null +++ b/include/asm-m68k/motorola_pgalloc.h @@ -0,0 +1,260 @@ +#ifndef _MOTOROLA_PGALLOC_H +#define _MOTOROLA_PGALLOC_H + +extern struct pgtable_cache_struct { + unsigned long *pmd_cache; + unsigned long *pte_cache; +/* This counts in units of pointer tables, of which can be eight per page. */ + unsigned long pgtable_cache_sz; +} quicklists; + +#define pgd_quicklist ((unsigned long *)0) +#define pmd_quicklist (quicklists.pmd_cache) +#define pte_quicklist (quicklists.pte_cache) +/* This isn't accurate because of fragmentation of allocated pages for + pointer tables, but that should not be a problem. */ +#define pgtable_cache_size ((quicklists.pgtable_cache_sz+7)/8) + +extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset); +extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset); + +extern pmd_t *get_pointer_table(void); +extern int free_pointer_table(pmd_t *); + +extern inline pte_t *get_pte_fast(void) +{ + unsigned long *ret; + + ret = pte_quicklist; + if (ret) { + pte_quicklist = (unsigned long *)*ret; + ret[0] = 0; + quicklists.pgtable_cache_sz -= 8; + } + return (pte_t *)ret; +} + +extern inline void free_pte_fast(pte_t *pte) +{ + *(unsigned long *)pte = (unsigned long)pte_quicklist; + pte_quicklist = (unsigned long *)pte; + quicklists.pgtable_cache_sz += 8; +} + +extern inline void free_pte_slow(pte_t *pte) +{ + cache_page((unsigned long)pte); + free_page((unsigned long) pte); +} + +extern inline pmd_t *get_pmd_fast(void) +{ + unsigned long *ret; + + ret = pmd_quicklist; + if (ret) { + pmd_quicklist = (unsigned long *)*ret; + ret[0] = 0; + quicklists.pgtable_cache_sz--; + } + return (pmd_t *)ret; +} + +extern inline void free_pmd_fast(pmd_t *pmd) +{ + *(unsigned long *)pmd = (unsigned long)pmd_quicklist; + pmd_quicklist = (unsigned long *) pmd; + quicklists.pgtable_cache_sz++; +} + +extern inline int free_pmd_slow(pmd_t *pmd) +{ + return free_pointer_table(pmd); +} + +/* The pgd cache is folded into the pmd cache, so these are dummy routines. */ +extern inline pgd_t *get_pgd_fast(void) +{ + return (pgd_t *)0; +} + +extern inline void free_pgd_fast(pgd_t *pgd) +{ +} + +extern inline void free_pgd_slow(pgd_t *pgd) +{ +} + +extern void __bad_pte(pmd_t *pmd); +extern void __bad_pmd(pgd_t *pgd); + +extern inline void pte_free(pte_t *pte) +{ + free_pte_fast(pte); +} + +extern inline pte_t *pte_alloc(pmd_t *pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + if (pmd_none(*pmd)) { + pte_t *page = get_pte_fast(); + + if (!page) + return get_pte_slow(pmd, address); + pmd_set(pmd,page); + return page + address; + } + if (pmd_bad(*pmd)) { + __bad_pte(pmd); + return NULL; + } + return (pte_t *)__pmd_page(*pmd) + address; +} + +extern inline void pmd_free(pmd_t *pmd) +{ + free_pmd_fast(pmd); +} + +extern inline pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address) +{ + address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); + if (pgd_none(*pgd)) { + pmd_t *page = get_pmd_fast(); + + if (!page) + return get_pmd_slow(pgd, address); + pgd_set(pgd, page); + return page + address; + } + if (pgd_bad(*pgd)) { + __bad_pmd(pgd); + return NULL; + } + return (pmd_t *)__pgd_page(*pgd) + address; +} + +extern inline void pte_free_kernel(pte_t *pte) +{ + free_pte_fast(pte); +} + +extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address) +{ + return pte_alloc(pmd, address); +} + +extern inline void pmd_free_kernel(pmd_t *pmd) +{ + free_pmd_fast(pmd); +} + +extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address) +{ + return pmd_alloc(pgd, address); +} + +extern inline void pgd_free(pgd_t *pgd) +{ + free_pmd_fast((pmd_t *)pgd); +} + +extern inline pgd_t *pgd_alloc(void) +{ + pgd_t *pgd = (pgd_t *)get_pmd_fast(); + if (!pgd) + pgd = (pgd_t *)get_pointer_table(); + return pgd; +} + +extern int do_check_pgt_cache(int, int); + +extern inline void set_pgdir(unsigned long address, pgd_t entry) +{ +} + + +/* + * flush all user-space atc entries. + */ +static inline void __flush_tlb(void) +{ + if (CPU_IS_040_OR_060) + __asm__ __volatile__(".chip 68040\n\t" + "pflushan\n\t" + ".chip 68k"); + else + __asm__ __volatile__("pflush #0,#4"); +} + +static inline void __flush_tlb040_one(unsigned long addr) +{ + __asm__ __volatile__(".chip 68040\n\t" + "pflush (%0)\n\t" + ".chip 68k" + : : "a" (addr)); +} + +static inline void __flush_tlb_one(unsigned long addr) +{ + if (CPU_IS_040_OR_060) + __flush_tlb040_one(addr); + else + __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr)); +} + +#define flush_tlb() __flush_tlb() + +/* + * flush all atc entries (both kernel and user-space entries). + */ +static inline void flush_tlb_all(void) +{ + if (CPU_IS_040_OR_060) + __asm__ __volatile__(".chip 68040\n\t" + "pflusha\n\t" + ".chip 68k"); + else + __asm__ __volatile__("pflusha"); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mm == current->mm) + __flush_tlb(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) +{ + if (vma->vm_mm == current->mm) + __flush_tlb_one(addr); +} + +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + if (mm == current->mm) + __flush_tlb(); +} + +extern inline void flush_tlb_kernel_page(unsigned long addr) +{ + if (CPU_IS_040_OR_060) { + mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); + __asm__ __volatile__(".chip 68040\n\t" + "pflush (%0)\n\t" + ".chip 68k" + : : "a" (addr)); + set_fs(old_fs); + } else + __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr)); +} + +extern inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + +#endif /* _MOTOROLA_PGALLOC_H */ diff --git a/include/asm-m68k/motorola_pgtable.h b/include/asm-m68k/motorola_pgtable.h new file mode 100644 index 000000000..7fea2e4ff --- /dev/null +++ b/include/asm-m68k/motorola_pgtable.h @@ -0,0 +1,266 @@ +#ifndef _MOTOROLA_PGTABLE_H +#define _MOTOROLA_PGTABLE_H + +#include <linux/config.h> + +/* + * Definitions for MMU descriptors + */ +#define _PAGE_PRESENT 0x001 +#define _PAGE_SHORT 0x002 +#define _PAGE_RONLY 0x004 +#define _PAGE_ACCESSED 0x008 +#define _PAGE_DIRTY 0x010 +#define _PAGE_SUPER 0x080 /* 68040 supervisor only */ +#define _PAGE_FAKE_SUPER 0x200 /* fake supervisor only on 680[23]0 */ +#define _PAGE_GLOBAL040 0x400 /* 68040 global bit, used for kva descs */ +#define _PAGE_COW 0x800 /* implemented in software */ +#define _PAGE_NOCACHE030 0x040 /* 68030 no-cache mode */ +#define _PAGE_NOCACHE 0x060 /* 68040 cache mode, non-serialized */ +#define _PAGE_NOCACHE_S 0x040 /* 68040 no-cache mode, serialized */ +#define _PAGE_CACHE040 0x020 /* 68040 cache mode, cachable, copyback */ +#define _PAGE_CACHE040W 0x000 /* 68040 cache mode, cachable, write-through */ + +#define _DESCTYPE_MASK 0x003 + +#define _CACHEMASK040 (~0x060) +#define _TABLE_MASK (0xfffffe00) + +#define _PAGE_TABLE (_PAGE_SHORT) +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_NOCACHE) + +#ifndef __ASSEMBLY__ + +/* This is the cache mode to be used for pages containing page descriptors for + * processors >= '040. It is in pte_mknocache(), and the variable is defined + * and initialized in head.S */ +extern int m68k_pgtable_cachemode; + +/* This is the cache mode for normal pages, for supervisor access on + * processors >= '040. It is used in pte_mkcache(), and the variable is + * defined and initialized in head.S */ + +#if defined(CONFIG_060_WRITETHROUGH) +extern int m68k_supervisor_cachemode; +#else +#define m68k_supervisor_cachemode _PAGE_CACHE040 +#endif + +#if defined(CPU_M68040_OR_M68060_ONLY) +#define mm_cachebits _PAGE_CACHE040 +#elif defined(CPU_M68020_OR_M68030_ONLY) +#define mm_cachebits 0 +#else +extern unsigned long mm_cachebits; +#endif + +#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | mm_cachebits) + +/* Alternate definitions that are compile time constants, for + initializing protection_map. The cachebits are fixed later. */ +#define PAGE_NONE_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) +#define PAGE_SHARED_C __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) +#define PAGE_COPY_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) +#define PAGE_READONLY_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) + +/* + * The m68k can't do page protection for execute, and considers that the same are read. + * Also, write permissions imply read permissions. This is the closest we can get.. + */ +#define __P000 PAGE_NONE_C +#define __P001 PAGE_READONLY_C +#define __P010 PAGE_COPY_C +#define __P011 PAGE_COPY_C +#define __P100 PAGE_READONLY_C +#define __P101 PAGE_READONLY_C +#define __P110 PAGE_COPY_C +#define __P111 PAGE_COPY_C + +#define __S000 PAGE_NONE_C +#define __S001 PAGE_READONLY_C +#define __S010 PAGE_SHARED_C +#define __S011 PAGE_SHARED_C +#define __S100 PAGE_READONLY_C +#define __S101 PAGE_READONLY_C +#define __S110 PAGE_SHARED_C +#define __S111 PAGE_SHARED_C + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +#define __mk_pte(page, pgprot) \ +({ \ + pte_t __pte; \ + \ + pte_val(__pte) = __pa(page) + pgprot_val(pgprot); \ + __pte; \ +}) +#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot)) +#define mk_pte_phys(physpage, pgprot) \ +({ \ + pte_t __pte; \ + \ + pte_val(__pte) = (physpage) + pgprot_val(pgprot); \ + __pte; \ +}) + +extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } + +extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) +{ + unsigned long ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED; + unsigned long *ptr = pmdp->pmd; + short i = 16; + while (--i >= 0) { + *ptr++ = ptbl; + ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16); + } +} + +extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp) +{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp); } + +#define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK)) +#define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK)) +#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK)) + + +#define pte_none(pte) (!pte_val(pte)) +#define pte_present(pte) (pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER)) +#define pte_clear(ptep) ({ pte_val(*(ptep)) = 0; }) +#define pte_pagenr(pte) ((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT) + +#define pmd_none(pmd) (!pmd_val(pmd)) +#define pmd_bad(pmd) ((pmd_val(pmd) & _DESCTYPE_MASK) != _PAGE_TABLE) +#define pmd_present(pmd) (pmd_val(pmd) & _PAGE_TABLE) +#define pmd_clear(pmdp) ({ \ + unsigned long *__ptr = pmdp->pmd; \ + short __i = 16; \ + while (--__i >= 0) \ + *__ptr++ = 0; \ +}) + + +#define pgd_none(pgd) (!pgd_val(pgd)) +#define pgd_bad(pgd) ((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE) +#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_TABLE) +#define pgd_clear(pgdp) ({ pgd_val(*pgdp) = 0; }) +/* Permanent address of a page. */ +#define page_address(page) ({ if (!(page)->virtual) BUG(); (page)->virtual; }) +#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT)) +#define pte_page(pte) (mem_map+pte_pagenr(pte)) + +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +extern inline int pte_read(pte_t pte) { return 1; } +extern inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_RONLY); } +extern inline int pte_exec(pte_t pte) { return 1; } +extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } + +extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_RONLY; return pte; } +extern inline pte_t pte_rdprotect(pte_t pte) { return pte; } +extern inline pte_t pte_exprotect(pte_t pte) { return pte; } +extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } +extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } +extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_RONLY; return pte; } +extern inline pte_t pte_mkread(pte_t pte) { return pte; } +extern inline pte_t pte_mkexec(pte_t pte) { return pte; } +extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } +extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } +extern inline pte_t pte_mknocache(pte_t pte) +{ + pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_pgtable_cachemode; + return pte; +} +extern inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode; return pte; } + +#define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) + +#define pgd_index(address) ((address) >> PGDIR_SHIFT) + +/* to find an entry in a page-table-directory */ +extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) +{ + return mm->pgd + pgd_index(address); +} + +#define swapper_pg_dir kernel_pg_dir +extern pgd_t kernel_pg_dir[128]; + +extern inline pgd_t * pgd_offset_k(unsigned long address) +{ + return kernel_pg_dir + (address >> PGDIR_SHIFT); +} + + +/* Find an entry in the second-level page table.. */ +extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) +{ + return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1)); +} + +/* Find an entry in the third-level page table.. */ +extern inline pte_t * pte_offset(pmd_t * pmdp, unsigned long address) +{ + return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); +} + + +/* + * Allocate and free page tables. The xxx_kernel() versions are + * used to allocate a kernel page table - this turns on ASN bits + * if any. + */ + +/* Prior to calling these routines, the page should have been flushed + * from both the cache and ATC, or the CPU might not notice that the + * cache setting for the page has been changed. -jskov + */ +static inline void nocache_page (unsigned long vaddr) +{ + if (CPU_IS_040_OR_060) { + pgd_t *dir; + pmd_t *pmdp; + pte_t *ptep; + + dir = pgd_offset_k(vaddr); + pmdp = pmd_offset(dir,vaddr); + ptep = pte_offset(pmdp,vaddr); + *ptep = pte_mknocache(*ptep); + } +} + +static inline void cache_page (unsigned long vaddr) +{ + if (CPU_IS_040_OR_060) { + pgd_t *dir; + pmd_t *pmdp; + pte_t *ptep; + + dir = pgd_offset_k(vaddr); + pmdp = pmd_offset(dir,vaddr); + ptep = pte_offset(pmdp,vaddr); + *ptep = pte_mkcache(*ptep); + } +} + + +#endif /* !__ASSEMBLY__ */ +#endif /* _MOTOROLA_PGTABLE_H */ diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h index 80e5269a2..40915d41c 100644 --- a/include/asm-m68k/page.h +++ b/include/asm-m68k/page.h @@ -160,7 +160,7 @@ static inline void *__va(unsigned long x) #endif /* CONFIG_SUN3 */ #define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) -#define virt_to_page(kaddr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)) +#define virt_to_page(kaddr) (mem_map + (((unsigned long)(kaddr)-PAGE_OFFSET) >> PAGE_SHIFT)) #define VALID_PAGE(page) ((page - mem_map) < max_mapnr) #ifndef CONFIG_SUN3 diff --git a/include/asm-m68k/param.h b/include/asm-m68k/param.h index ffd640baa..7d37eb540 100644 --- a/include/asm-m68k/param.h +++ b/include/asm-m68k/param.h @@ -26,4 +26,8 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#ifdef __KERNEL__ +# define CLOCKS_PER_SEC HZ /* frequency at which times() counts */ +#endif + #endif /* _M68K_PARAM_H */ diff --git a/include/asm-m68k/parport.h b/include/asm-m68k/parport.h new file mode 100644 index 000000000..98a228ac7 --- /dev/null +++ b/include/asm-m68k/parport.h @@ -0,0 +1,23 @@ +/* + * parport.h: platform-specific PC-style parport initialisation + * + * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk> + * + * This file should only be included by drivers/parport/parport_pc.c. + * + * RZ: for use with Q40 and other ISA machines + */ + +#ifndef _ASM_M68K_PARPORT_H +#define _ASM_M68K_PARPORT_H 1 + +/* no dma, or IRQ autoprobing */ +static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); +static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) +{ + if (! (MACH_IS_Q40)) + return 0; /* count=0 */ + return parport_pc_find_isa_ports (PARPORT_IRQ_NONE, PARPORT_DMA_NONE); +} + +#endif /* !(_ASM_M68K_PARPORT_H) */ diff --git a/include/asm-m68k/pgalloc.h b/include/asm-m68k/pgalloc.h index 028b7c40e..9f307b343 100644 --- a/include/asm-m68k/pgalloc.h +++ b/include/asm-m68k/pgalloc.h @@ -1,183 +1,11 @@ -#ifndef _M68K_PGALLOC_H -#define _M68K_PGALLOC_H +#ifndef M68K_PGALLOC_H +#define M68K_PGALLOC_H + +#include <linux/config.h> #include <asm/setup.h> #include <asm/virtconvert.h> -extern struct pgtable_cache_struct { - unsigned long *pmd_cache; - unsigned long *pte_cache; -/* This counts in units of pointer tables, of which can be eight per page. */ - unsigned long pgtable_cache_sz; -} quicklists; - -#define pgd_quicklist ((unsigned long *)0) -#define pmd_quicklist (quicklists.pmd_cache) -#define pte_quicklist (quicklists.pte_cache) -/* This isn't accurate because of fragmentation of allocated pages for - pointer tables, but that should not be a problem. */ -#define pgtable_cache_size ((quicklists.pgtable_cache_sz+7)/8) - -extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset); -extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset); - -extern pmd_t *get_pointer_table(void); -extern int free_pointer_table(pmd_t *); - -extern inline pte_t *get_pte_fast(void) -{ - unsigned long *ret; - - ret = pte_quicklist; - if (ret) { - pte_quicklist = (unsigned long *)*ret; - ret[0] = 0; - quicklists.pgtable_cache_sz -= 8; - } - return (pte_t *)ret; -} - -extern inline void free_pte_fast(pte_t *pte) -{ - *(unsigned long *)pte = (unsigned long)pte_quicklist; - pte_quicklist = (unsigned long *)pte; - quicklists.pgtable_cache_sz += 8; -} - -extern inline void free_pte_slow(pte_t *pte) -{ - cache_page((unsigned long)pte); - free_page((unsigned long) pte); -} - -extern inline pmd_t *get_pmd_fast(void) -{ - unsigned long *ret; - - ret = pmd_quicklist; - if (ret) { - pmd_quicklist = (unsigned long *)*ret; - ret[0] = 0; - quicklists.pgtable_cache_sz--; - } - return (pmd_t *)ret; -} - -extern inline void free_pmd_fast(pmd_t *pmd) -{ - *(unsigned long *)pmd = (unsigned long)pmd_quicklist; - pmd_quicklist = (unsigned long *) pmd; - quicklists.pgtable_cache_sz++; -} - -extern inline int free_pmd_slow(pmd_t *pmd) -{ - return free_pointer_table(pmd); -} - -/* The pgd cache is folded into the pmd cache, so these are dummy routines. */ -extern inline pgd_t *get_pgd_fast(void) -{ - return (pgd_t *)0; -} - -extern inline void free_pgd_fast(pgd_t *pgd) -{ -} - -extern inline void free_pgd_slow(pgd_t *pgd) -{ -} - -extern void __bad_pte(pmd_t *pmd); -extern void __bad_pmd(pgd_t *pgd); - -extern inline void pte_free(pte_t *pte) -{ - free_pte_fast(pte); -} - -extern inline pte_t *pte_alloc(pmd_t *pmd, unsigned long address) -{ - address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); - if (pmd_none(*pmd)) { - pte_t *page = get_pte_fast(); - - if (!page) - return get_pte_slow(pmd, address); - pmd_set(pmd,page); - return page + address; - } - if (pmd_bad(*pmd)) { - __bad_pte(pmd); - return NULL; - } - return (pte_t *)__pmd_page(*pmd) + address; -} - -extern inline void pmd_free(pmd_t *pmd) -{ - free_pmd_fast(pmd); -} - -extern inline pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address) -{ - address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); - if (pgd_none(*pgd)) { - pmd_t *page = get_pmd_fast(); - - if (!page) - return get_pmd_slow(pgd, address); - pgd_set(pgd, page); - return page + address; - } - if (pgd_bad(*pgd)) { - __bad_pmd(pgd); - return NULL; - } - return (pmd_t *)__pgd_page(*pgd) + address; -} - -extern inline void pte_free_kernel(pte_t *pte) -{ - free_pte_fast(pte); -} - -extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address) -{ - return pte_alloc(pmd, address); -} - -extern inline void pmd_free_kernel(pmd_t *pmd) -{ - free_pmd_fast(pmd); -} - -extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address) -{ - return pmd_alloc(pgd, address); -} - -extern inline void pgd_free(pgd_t *pgd) -{ - free_pmd_fast((pmd_t *)pgd); -} - -extern inline pgd_t *pgd_alloc(void) -{ - pgd_t *pgd = (pgd_t *)get_pmd_fast(); - if (!pgd) - pgd = (pgd_t *)get_pointer_table(); - return pgd; -} - -extern int do_check_pgt_cache(int, int); - -extern inline void set_pgdir(unsigned long address, pgd_t entry) -{ -} - - /* * Cache handling functions */ @@ -325,82 +153,13 @@ extern inline void flush_icache_range (unsigned long address, } } +#define flush_icache_page(vma,pg) do { } while (0) -/* - * flush all user-space atc entries. - */ -static inline void __flush_tlb(void) -{ - if (CPU_IS_040_OR_060) - __asm__ __volatile__(".chip 68040\n\t" - "pflushan\n\t" - ".chip 68k"); - else - __asm__ __volatile__("pflush #0,#4"); -} - -static inline void __flush_tlb_one(unsigned long addr) -{ - if (CPU_IS_040_OR_060) { - __asm__ __volatile__(".chip 68040\n\t" - "pflush (%0)\n\t" - ".chip 68k" - : : "a" (addr)); - } else - __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr)); -} - -#define flush_tlb() __flush_tlb() - -/* - * flush all atc entries (both kernel and user-space entries). - */ -static inline void flush_tlb_all(void) -{ - if (CPU_IS_040_OR_060) - __asm__ __volatile__(".chip 68040\n\t" - "pflusha\n\t" - ".chip 68k"); - else - __asm__ __volatile__("pflusha"); -} - -static inline void flush_tlb_mm(struct mm_struct *mm) -{ - if (mm == current->mm) - __flush_tlb(); -} - -static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) -{ - if (vma->vm_mm == current->mm) - __flush_tlb_one(addr); -} - -static inline void flush_tlb_range(struct mm_struct *mm, - unsigned long start, unsigned long end) -{ - if (mm == current->mm) - __flush_tlb(); -} -extern inline void flush_tlb_kernel_page(unsigned long addr) -{ - if (CPU_IS_040_OR_060) { - mm_segment_t old_fs = get_fs(); - set_fs(KERNEL_DS); - __asm__ __volatile__(".chip 68040\n\t" - "pflush (%0)\n\t" - ".chip 68k" - : : "a" (addr)); - set_fs(old_fs); - } else - __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr)); -} - -extern inline void flush_tlb_pgtables(struct mm_struct *mm, - unsigned long start, unsigned long end) -{ -} +#ifdef CONFIG_SUN3 +#include <asm/sun3_pgalloc.h> +#else +#include <asm/motorola_pgalloc.h> +#endif -#endif /* _M68K_PGALLOC_H */ +#endif /* M68K_PGALLOC_H */ diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h index 655d604d2..71fd0ae75 100644 --- a/include/asm-m68k/pgtable.h +++ b/include/asm-m68k/pgtable.h @@ -26,12 +26,20 @@ /* PMD_SHIFT determines the size of the area a second-level page table can map */ +#ifdef CONFIG_SUN3 +#define PMD_SHIFT 17 +#else #define PMD_SHIFT 22 +#endif #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) /* PGDIR_SHIFT determines what a third-level page table entry can map */ +#ifdef CONFIG_SUN3 +#define PGDIR_SHIFT 17 +#else #define PGDIR_SHIFT 25 +#endif #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) @@ -39,16 +47,28 @@ * entries per page directory level: the m68k is configured as three-level, * so we do have PMD level physically. */ +#ifdef CONFIG_SUN3 +#define PTRS_PER_PTE 16 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 2048 +#else #define PTRS_PER_PTE 1024 #define PTRS_PER_PMD 8 #define PTRS_PER_PGD 128 +#endif #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) #define FIRST_USER_PGD_NR 0 /* Virtual address region for use by kernel_map() */ +#ifdef CONFIG_SUN3 +#define KMAP_START 0x0DC00000 +#define KMAP_END 0x0E000000 +#else #define KMAP_START 0xd0000000 #define KMAP_END 0xf0000000 +#endif +#ifndef CONFIG_SUN3 /* Just any arbitrary offset to the start of the vmalloc VM area: the * current 8MB value just means that there will be a 8MB "hole" after the * physical memory until the kernel virtual memory starts. That means that @@ -60,102 +80,12 @@ #define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) #define VMALLOC_VMADDR(x) ((unsigned long)(x)) #define VMALLOC_END KMAP_START - -#endif /* __ASSEMBLY__ */ - -/* - * Definitions for MMU descriptors - */ -#define _PAGE_PRESENT 0x001 -#define _PAGE_SHORT 0x002 -#define _PAGE_RONLY 0x004 -#define _PAGE_ACCESSED 0x008 -#define _PAGE_DIRTY 0x010 -#define _PAGE_SUPER 0x080 /* 68040 supervisor only */ -#define _PAGE_FAKE_SUPER 0x200 /* fake supervisor only on 680[23]0 */ -#define _PAGE_GLOBAL040 0x400 /* 68040 global bit, used for kva descs */ -#define _PAGE_COW 0x800 /* implemented in software */ -#define _PAGE_NOCACHE030 0x040 /* 68030 no-cache mode */ -#define _PAGE_NOCACHE 0x060 /* 68040 cache mode, non-serialized */ -#define _PAGE_NOCACHE_S 0x040 /* 68040 no-cache mode, serialized */ -#define _PAGE_CACHE040 0x020 /* 68040 cache mode, cachable, copyback */ -#define _PAGE_CACHE040W 0x000 /* 68040 cache mode, cachable, write-through */ - -/* Page protection values within PTE. */ -#define SUN3_PAGE_VALID (0x80000000) -#define SUN3_PAGE_WRITEABLE (0x40000000) -#define SUN3_PAGE_SYSTEM (0x20000000) -#define SUN3_PAGE_NOCACHE (0x10000000) -#define SUN3_PAGE_ACCESSED (0x02000000) -#define SUN3_PAGE_MODIFIED (0x01000000) - -#define _DESCTYPE_MASK 0x003 - -#define _CACHEMASK040 (~0x060) -#define _TABLE_MASK (0xfffffe00) - -#define _PAGE_TABLE (_PAGE_SHORT) -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_NOCACHE) - -#ifndef __ASSEMBLY__ - -/* This is the cache mode to be used for pages containing page descriptors for - * processors >= '040. It is in pte_mknocache(), and the variable is defined - * and initialized in head.S */ -extern int m68k_pgtable_cachemode; - -/* This is the cache mode for normal pages, for supervisor access on - * processors >= '040. It is used in pte_mkcache(), and the variable is - * defined and initialized in head.S */ - -#if defined(CONFIG_060_WRITETHROUGH) -extern int m68k_supervisor_cachemode; -#else -#define m68k_supervisor_cachemode _PAGE_CACHE040 -#endif - -#if defined(CPU_M68040_OR_M68060_ONLY) -#define mm_cachebits _PAGE_CACHE040 -#elif defined(CPU_M68020_OR_M68030_ONLY) -#define mm_cachebits 0 #else -extern unsigned long mm_cachebits; -#endif - -#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits) -#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) -#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | mm_cachebits) - -/* Alternate definitions that are compile time constants, for - initializing protection_map. The cachebits are fixed later. */ -#define PAGE_NONE_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) -#define PAGE_SHARED_C __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) -#define PAGE_COPY_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) -#define PAGE_READONLY_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) - -/* - * The m68k can't do page protection for execute, and considers that the same are read. - * Also, write permissions imply read permissions. This is the closest we can get.. - */ -#define __P000 PAGE_NONE_C -#define __P001 PAGE_READONLY_C -#define __P010 PAGE_COPY_C -#define __P011 PAGE_COPY_C -#define __P100 PAGE_READONLY_C -#define __P101 PAGE_READONLY_C -#define __P110 PAGE_COPY_C -#define __P111 PAGE_COPY_C - -#define __S000 PAGE_NONE_C -#define __S001 PAGE_READONLY_C -#define __S010 PAGE_SHARED_C -#define __S011 PAGE_SHARED_C -#define __S100 PAGE_READONLY_C -#define __S101 PAGE_READONLY_C -#define __S110 PAGE_SHARED_C -#define __S111 PAGE_SHARED_C +extern unsigned long vmalloc_end; +#define VMALLOC_START 0x0f800000 +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#define VMALLOC_END vmalloc_end +#endif /* CONFIG_SUN3 */ /* zero page used for uninitialized stuff */ extern unsigned long empty_zero_page; @@ -182,176 +112,7 @@ extern pte_t * __bad_pagetable(void); /* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */ /* 64-bit machines, beware! SRB. */ -#define SIZEOF_PTR_LOG2 2 - -/* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - */ -#define __mk_pte(page, pgprot) \ -({ \ - pte_t __pte; \ - \ - pte_val(__pte) = __pa((page) + pgprot_val(pgprot); \ - __pte; \ -}) -#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot)) -#define mk_pte_phys(physpage, pgprot) \ -({ \ - pte_t __pte; \ - \ - pte_val(__pte) = (physpage) + pgprot_val(pgprot); \ - __pte; \ -}) - -extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } - -extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) -{ - unsigned long ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED; - unsigned long *ptr = pmdp->pmd; - short i = 16; - while (--i >= 0) { - *ptr++ = ptbl; - ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16); - } -} - -extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp) -{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp); } - -#define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK)) -#define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK)) -#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK)) - -#define pte_none(pte) (!pte_val(pte)) -#define pte_present(pte) (pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER)) -#define pte_clear(ptep) ({ pte_val(*(ptep)) = 0; }) - -#define pmd_none(pmd) (!pmd_val(pmd)) -#define pmd_bad(pmd) ((pmd_val(pmd) & _DESCTYPE_MASK) != _PAGE_TABLE) -#define pmd_present(pmd) (pmd_val(pmd) & _PAGE_TABLE) -#define pmd_clear(pmdp) ({ \ - unsigned long *__ptr = pmdp->pmd; \ - short __i = 16; \ - while (--__i >= 0) \ - *__ptr++ = 0; \ -}) - -#define pgd_none(pgd) (!pgd_val(pgd)) -#define pgd_bad(pgd) ((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE) -#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_TABLE) -#define pgd_clear(pgdp) ({ pgd_val(*pgdp) = 0; }) - -/* Permanent address of a page. */ -#define page_address(page) ((page)->virtual) -#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT)) -#define pte_page(pte) (mem_map+((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)) - -#define pte_ERROR(e) \ - printk("%s:%d: bad pte %p(%08lx).\n", __FILE__, __LINE__, &(e), pte_val(e)) -#define pmd_ERROR(e) \ - printk("%s:%d: bad pmd %p(%08lx).\n", __FILE__, __LINE__, &(e), pmd_val(e)) -#define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), pgd_val(e)) - -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -extern inline int pte_read(pte_t pte) { return 1; } -extern inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_RONLY); } -extern inline int pte_exec(pte_t pte) { return 1; } -extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } -extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } - -extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_RONLY; return pte; } -extern inline pte_t pte_rdprotect(pte_t pte) { return pte; } -extern inline pte_t pte_exprotect(pte_t pte) { return pte; } -extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } -extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } -extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_RONLY; return pte; } -extern inline pte_t pte_mkread(pte_t pte) { return pte; } -extern inline pte_t pte_mkexec(pte_t pte) { return pte; } -extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } -extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } -extern inline pte_t pte_mknocache(pte_t pte) -{ - pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_pgtable_cachemode; - return pte; -} -extern inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode; return pte; } - -#define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) - -#define pgd_index(address) ((address) >> PGDIR_SHIFT) - -/* to find an entry in a page-table-directory */ -extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) -{ - return mm->pgd + pgd_index(address); -} - -#define swapper_pg_dir kernel_pg_dir -extern pgd_t kernel_pg_dir[128]; - -extern inline pgd_t * pgd_offset_k(unsigned long address) -{ - return kernel_pg_dir + (address >> PGDIR_SHIFT); -} - - -/* Find an entry in the second-level page table.. */ -extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) -{ - return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1)); -} - -/* Find an entry in the third-level page table.. */ -extern inline pte_t * pte_offset(pmd_t * pmdp, unsigned long address) -{ - return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); -} - -/* - * Allocate and free page tables. The xxx_kernel() versions are - * used to allocate a kernel page table - this turns on ASN bits - * if any. - */ - -/* Prior to calling these routines, the page should have been flushed - * from both the cache and ATC, or the CPU might not notice that the - * cache setting for the page has been changed. -jskov - */ -static inline void nocache_page (unsigned long vaddr) -{ - if (CPU_IS_040_OR_060) { - pgd_t *dir; - pmd_t *pmdp; - pte_t *ptep; - - dir = pgd_offset_k(vaddr); - pmdp = pmd_offset(dir,vaddr); - ptep = pte_offset(pmdp,vaddr); - *ptep = pte_mknocache(*ptep); - } -} - -static inline void cache_page (unsigned long vaddr) -{ - if (CPU_IS_040_OR_060) { - pgd_t *dir; - pmd_t *pmdp; - pte_t *ptep; - - dir = pgd_offset_k(vaddr); - pmdp = pmd_offset(dir,vaddr); - ptep = pte_offset(pmdp,vaddr); - *ptep = pte_mkcache(*ptep); - } -} - +#define SIZEOF_PTR_LOG2 2 /* * Check if the addr/len goes up to the end of a physical @@ -374,13 +135,24 @@ extern void kernel_set_cachemode(void *addr, unsigned long size, int cmode); /* * The m68k doesn't have any external MMU info: the kernel page - * tables contain all the necessary information. + * tables contain all the necessary information. The Sun3 does, but + * they are updated on demand. */ extern inline void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte) { } +#ifdef CONFIG_SUN3 +/* Macros to (de)construct the fake PTEs representing swap pages. */ +#define SWP_TYPE(x) ((x).val & 0x7F) +#define SWP_OFFSET(x) (((x).val) >> 7) +#define SWP_ENTRY(type,offset) ((swp_entry_t) { ((type) | ((offset) << 7)) }) +#define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define swp_entry_to_pte(x) ((pte_t) { (x).val }) + +#else + /* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */ #define SWP_TYPE(x) (((x).val >> 1) & 0xff) #define SWP_OFFSET(x) ((x).val >> 10) @@ -388,7 +160,9 @@ extern inline void update_mmu_cache(struct vm_area_struct * vma, #define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define swp_entry_to_pte(x) ((pte_t) { (x).val }) -#endif /* __ASSEMBLY__ */ +#endif CONFIG_SUN3 + +#endif /* !__ASSEMBLY__ */ /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ #define PageSkip(page) (0) @@ -396,6 +170,16 @@ extern inline void update_mmu_cache(struct vm_area_struct * vma, #define io_remap_page_range remap_page_range +/* MMU-specific headers */ + +#ifdef CONFIG_SUN3 +#include <asm/sun3_pgtable.h> +#else +#include <asm/motorola_pgtable.h> +#endif + +#ifndef __ASSEMBLY__ #include <asm-generic/pgtable.h> +#endif /* !__ASSEMBLY__ */ #endif /* _M68K_PGTABLE_H */ diff --git a/include/asm-m68k/processor.h b/include/asm-m68k/processor.h index 79d81adc2..1bba1277f 100644 --- a/include/asm-m68k/processor.h +++ b/include/asm-m68k/processor.h @@ -71,6 +71,8 @@ struct thread_struct { unsigned short fs; /* saved fs (sfc, dfc) */ unsigned long crp[2]; /* cpu root pointer */ unsigned long esp0; /* points to SR of stack frame */ + unsigned long faddr; /* info about last fault */ + int signo, code; unsigned long fp[8*3]; unsigned long fpcntl[3]; /* fp control regs */ unsigned char fpstate[FPSTATESIZE]; /* floating point state */ @@ -81,7 +83,6 @@ struct thread_struct { #define INIT_THREAD { \ sizeof(init_stack) + (unsigned long) init_stack, 0, \ PS_S, __KERNEL_DS, \ - {0, 0}, 0, {0,}, {0, 0, 0}, {0,}, \ } /* diff --git a/include/asm-m68k/q40_keyboard.h b/include/asm-m68k/q40_keyboard.h index 9083bc1ec..88993462d 100644 --- a/include/asm-m68k/q40_keyboard.h +++ b/include/asm-m68k/q40_keyboard.h @@ -23,7 +23,6 @@ extern int q40kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode); extern char q40kbd_unexpected_up(unsigned char keycode); extern void q40kbd_leds(unsigned char leds); -extern int q40kbd_is_sysrq(unsigned char keycode); extern void q40kbd_init_hw(void); extern unsigned char q40kbd_sysrq_xlate[128]; @@ -36,7 +35,6 @@ extern unsigned char q40kbd_sysrq_xlate[128]; #define kbd_unexpected_up q40kbd_unexpected_up #define kbd_leds q40kbd_leds #define kbd_init_hw q40kbd_init_hw -#define kbd_is_sysrq q40kbd_is_sysrq #define kbd_sysrq_xlate q40kbd_sysrq_xlate diff --git a/include/asm-m68k/q40_master.h b/include/asm-m68k/q40_master.h index b7e365b0f..dd34c1b93 100644 --- a/include/asm-m68k/q40_master.h +++ b/include/asm-m68k/q40_master.h @@ -3,13 +3,14 @@ * RTC stuff merged for compactnes.. */ -#if 1 +#ifndef _Q40_MASTER_H +#define _Q40_MASTER_H + +#include <asm/io.h> + + #define q40_master_addr 0xff000000 #define q40_rtc_addr 0xff021ffc -#else -extern unsigned long q40_master_addr; /* wherever it is mapped ... */ -extern unsigned long q40_rtc_addr; -#endif #define IIRQ_REG 0x0 /* internal IRQ reg */ #define EIRQ_REG 0x4 /* external ... */ @@ -22,7 +23,7 @@ extern unsigned long q40_rtc_addr; #define KEYBOARD_UNLOCK_REG 0x20 /* clear kb int */ #define SAMPLE_ENABLE_REG 0x14 /* generate SAMPLE ints */ -#define SAMPLE_RATE_REG 0x28 +#define SAMPLE_RATE_REG 0x2c #define SAMPLE_CLEAR_REG 0x28 #define SAMPLE_LOW 0x00 #define SAMPLE_HIGH 0x01 @@ -34,9 +35,13 @@ extern unsigned long q40_rtc_addr; #endif #define EXT_ENABLE_REG 0x10 /* ... rest of the ISA ints ... */ +#if 0 #define master_inb(_reg_) (*(((unsigned char *)q40_master_addr)+_reg_)) #define master_outb(_b_,_reg_) (*(((unsigned char *)q40_master_addr)+_reg_)=(_b_)) - +#else +#define master_inb(_reg_) native_inb((unsigned char *)q40_master_addr+_reg_) +#define master_outb(_b_,_reg_) native_outb(_b_,(unsigned char *)q40_master_addr+_reg_) +#endif /* define some Q40 specific ints */ #include "q40ints.h" @@ -55,21 +60,13 @@ extern unsigned long q40_rtc_addr; #define RTC_CTRL (*(unsigned char *)(Q40_RTC_BASE-28)) -#if 0 -struct RTC_STRUCT{ - unsigned char bcd_year; - unsigned char bcd_mth; - unsigned char bcd_dom; - unsigned char bcd_dayofweek; - unsigned char bcd_hr; - unsigned char bcd_min; - unsigned char bcd_sec; - unsigned char ctrl; -}; -typedef struct RTC_STRUCT *RtcPtr_t; -#endif - - /* some control bits */ #define RTC_READ 64 /* prepare for reading */ #define RTC_WRITE 128 + + +/* misc defs */ +#define DAC_LEFT ((unsigned char *)0xff008000) +#define DAC_RIGHT ((unsigned char *)0xff008004) + +#endif /* _Q40_MASTER_H */ diff --git a/include/asm-m68k/q40ints.h b/include/asm-m68k/q40ints.h index f5e29c982..8aaca406e 100644 --- a/include/asm-m68k/q40ints.h +++ b/include/asm-m68k/q40ints.h @@ -4,7 +4,7 @@ #define Q40_IRQ_MAX (34) -#define Q40_IRQ_TIMER (34) +#define Q40_IRQ_SAMPLE (34) #define Q40_IRQ_KEYBOARD (32) #define Q40_IRQ_FRAME (33) diff --git a/include/asm-m68k/siginfo.h b/include/asm-m68k/siginfo.h index 2a5782905..6b48063af 100644 --- a/include/asm-m68k/siginfo.h +++ b/include/asm-m68k/siginfo.h @@ -23,8 +23,9 @@ typedef struct siginfo { /* kill() */ struct { - pid_t _pid; /* sender's pid */ - uid_t _uid; /* sender's uid */ + __kernel_pid_t _pid; /* sender's pid */ + __kernel_uid_t _uid; /* backwards compatibility */ + __kernel_uid32_t _uid32; /* sender's uid */ } _kill; /* POSIX.1b timers */ @@ -35,18 +36,20 @@ typedef struct siginfo { /* POSIX.1b signals */ struct { - pid_t _pid; /* sender's pid */ - uid_t _uid; /* sender's uid */ + __kernel_pid_t _pid; /* sender's pid */ + __kernel_uid_t _uid; /* backwards compatibility */ sigval_t _sigval; + __kernel_uid32_t _uid32; /* sender's uid */ } _rt; /* SIGCHLD */ struct { - pid_t _pid; /* which child */ - uid_t _uid; /* sender's uid */ + __kernel_pid_t _pid; /* which child */ + __kernel_uid_t _uid; /* backwards compatibility */ int _status; /* exit code */ clock_t _utime; clock_t _stime; + __kernel_uid32_t _uid32; /* sender's uid */ } _sigchld; /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ @@ -62,11 +65,18 @@ typedef struct siginfo { } _sifields; } siginfo_t; +#define UID16_SIGINFO_COMPAT_NEEDED + /* * How these fields are to be accessed. */ #define si_pid _sifields._kill._pid +#ifdef __KERNEL__ +#define si_uid _sifields._kill._uid32 +#define si_uid16 _sifields._kill._uid +#else #define si_uid _sifields._kill._uid +#endif /* __KERNEL__ */ #define si_status _sifields._sigchld._status #define si_utime _sifields._sigchld._utime #define si_stime _sifields._sigchld._stime diff --git a/include/asm-m68k/softirq.h b/include/asm-m68k/softirq.h index 89a3e3971..3a346780b 100644 --- a/include/asm-m68k/softirq.h +++ b/include/asm-m68k/softirq.h @@ -7,14 +7,12 @@ #include <asm/atomic.h> -#define local_bh_disable() (local_bh_count(smp_processor_id())++) -#define local_bh_enable() (local_bh_count(smp_processor_id())--) +#define cpu_bh_disable(cpu) do { local_bh_count(cpu)++; barrier(); } while (0) +#define cpu_bh_enable(cpu) do { barrier(); local_bh_count(cpu)--; } while (0) -#define in_softirq() (local_bh_count != 0) +#define local_bh_disable() cpu_bh_disable(smp_processor_id()) +#define local_bh_enable() cpu_bh_enable(smp_processor_id()) -/* These are for the irq's testing the lock */ -#define softirq_trylock(cpu) (local_bh_count(cpu) ? 0 : (local_bh_count(cpu)=1)) -#define softirq_endlock(cpu) (local_bh_count(cpu) = 0) -#define synchronize_bh() barrier() +#define in_softirq() (local_bh_count(smp_processor_id()) != 0) #endif diff --git a/include/asm-m68k/spinlock.h b/include/asm-m68k/spinlock.h index fec148175..20f46e27b 100644 --- a/include/asm-m68k/spinlock.h +++ b/include/asm-m68k/spinlock.h @@ -1,6 +1,6 @@ #ifndef __M68K_SPINLOCK_H #define __M68K_SPINLOCK_H -#error "m68k doesn't do SMP" +#error "m68k doesn't do SMP yet" #endif diff --git a/include/asm-m68k/stat.h b/include/asm-m68k/stat.h index 1d5b008e0..81b225ef4 100644 --- a/include/asm-m68k/stat.h +++ b/include/asm-m68k/stat.h @@ -44,8 +44,10 @@ struct stat { struct stat64 { unsigned char __pad0[6]; unsigned short st_dev; + unsigned char __pad1[4]; - unsigned long long st_ino; +#define STAT64_HAS_BROKEN_ST_INO 1 + unsigned long __st_ino; unsigned int st_mode; unsigned int st_nlink; @@ -53,14 +55,15 @@ struct stat64 { unsigned long st_uid; unsigned long st_gid; + unsigned char __pad2[6]; unsigned short st_rdev; - unsigned char __pad3[10]; + unsigned char __pad3[4]; long long st_size; unsigned long st_blksize; - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ unsigned long __pad4; /* future possible st_blocks high bits */ + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ unsigned long st_atime; unsigned long __pad5; @@ -71,8 +74,7 @@ struct stat64 { unsigned long st_ctime; unsigned long __pad7; /* will be high 32 bits of ctime someday */ - unsigned long __unused1; - unsigned long __unused2; + unsigned long long st_ino; }; #endif /* _M68K_STAT_H */ diff --git a/include/asm-m68k/sun3_pgalloc.h b/include/asm-m68k/sun3_pgalloc.h new file mode 100644 index 000000000..32a810aa5 --- /dev/null +++ b/include/asm-m68k/sun3_pgalloc.h @@ -0,0 +1,274 @@ +/* sun3_pgalloc.h -- + * reorganization around 2.3.39, routines moved from sun3_pgtable.h + * + * moved 1/26/2000 Sam Creasey + */ + +#ifndef _SUN3_PGALLOC_H +#define _SUN3_PGALLOC_H + +/* Pagetable caches. */ +//todo: should implement for at least ptes. --m +#define pgd_quicklist ((unsigned long *) 0) +#define pmd_quicklist ((unsigned long *) 0) +#define pte_quicklist ((unsigned long *) 0) +#define pgtable_cache_size (0L) + +/* Allocation and deallocation of various flavours of pagetables. */ +extern inline int free_pmd_fast (pmd_t *pmdp) { return 0; } +extern inline int free_pmd_slow (pmd_t *pmdp) { return 0; } +extern inline pmd_t *get_pmd_fast (void) { return (pmd_t *) 0; } + +//todo: implement the following properly. +#define get_pte_fast() ((pte_t *) 0) +#define get_pte_slow pte_alloc +#define free_pte_fast(pte) +#define free_pte_slow pte_free + +/* FIXME - when we get this compiling */ +/* erm, now that it's compiling, what do we do with it? */ +#define _KERNPG_TABLE 0 + +extern inline void pte_free_kernel(pte_t * pte) +{ + free_page((unsigned long) pte); +} + +extern const char bad_pmd_string[]; + +extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + if (pmd_none(*pmd)) { + pte_t * page = (pte_t *) get_free_page(GFP_KERNEL); + if (pmd_none(*pmd)) { + if (page) { + pmd_val(*pmd) = _KERNPG_TABLE + __pa(page); + return page + address; + } + pmd_val(*pmd) = _KERNPG_TABLE + __pa((unsigned long)BAD_PAGETABLE); + return NULL; + } + free_page((unsigned long) page); + } + if (pmd_bad(*pmd)) { + printk(bad_pmd_string, pmd_val(*pmd)); + printk("at kernel pgd off %08x\n", (unsigned int)pmd); + pmd_val(*pmd) = _KERNPG_TABLE + __pa((unsigned long)BAD_PAGETABLE); + return NULL; + } + return (pte_t *) __pmd_page(*pmd) + address; +} + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +extern inline void pmd_free_kernel(pmd_t * pmd) +{ +// pmd_val(*pmd) = 0; +} + +extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address) +{ + return (pmd_t *) pgd; +} + +extern inline void pte_free(pte_t * pte) +{ + free_page((unsigned long) pte); +} + +extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) +{ + address = (address >> (PAGE_SHIFT-2)) & 4*(PTRS_PER_PTE - 1); + +repeat: + if (pmd_none(*pmd)) + goto getnew; + if (pmd_bad(*pmd)) + goto fix; + return (pte_t *) (__pmd_page(*pmd) + address); + +getnew: +{ + unsigned long page = __get_free_page(GFP_KERNEL); + if (!pmd_none(*pmd)) + goto freenew; + if (!page) + goto oom; + memset((void *)page, 0, PAGE_SIZE); +// pmd_val(*pmd) = SUN3_PMD_MAGIC + __pa(page); + pmd_val(*pmd) = __pa(page); + return (pte_t *) (page + address); +freenew: + free_page(page); + goto repeat; +} + +fix: + printk(bad_pmd_string, pmd_val(*pmd)); + printk("in normal pgd offset %08x\n", (unsigned int)pmd); +oom: +// pmd_val(*pmd) = SUN3_PMD_MAGIC + __pa(BAD_PAGETABLE); + pmd_val(*pmd) = __pa(BAD_PAGETABLE); + return NULL; +} + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +extern inline void pmd_free(pmd_t * pmd) +{ + pmd_val(*pmd) = 0; +} + +extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address) +{ + return (pmd_t *) pgd; +} + +extern inline void pgd_free(pgd_t * pgd) +{ + free_page((unsigned long) pgd); +} + +extern inline pgd_t * pgd_alloc(void) +{ + pgd_t *new_pgd; + + new_pgd = (pgd_t *)get_free_page(GFP_KERNEL); + memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE); + memset(new_pgd, 0, (PAGE_OFFSET >> PGDIR_SHIFT)); + return new_pgd; +} + +/* FIXME: the sun3 doesn't have a page table cache! + (but the motorola routine should just return 0) */ + +extern int do_check_pgt_cache(int, int); + +extern inline void set_pgdir(unsigned long address, pgd_t entry) +{ +} + +/* Reserved PMEGs. */ +extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM]; +extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM]; +extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM]; +extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM]; + +/* Flush all userspace mappings one by one... (why no flush command, + sun?) */ +static inline void flush_tlb_all(void) +{ + unsigned long addr; + unsigned char ctx, oldctx; + + oldctx = sun3_get_context(); + for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) { + for(ctx = 0; ctx < 8; ctx++) { + sun3_put_context(ctx); + sun3_put_segmap(addr, SUN3_INVALID_PMEG); + } + } + + sun3_put_context(oldctx); + /* erase all of the userspace pmeg maps, we've clobbered them + all anyway */ + for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) { + if(pmeg_alloc[addr] == 1) { + pmeg_alloc[addr] = 0; + pmeg_ctx[addr] = 0; + pmeg_vaddr[addr] = 0; + } + } + +} + +/* Clear user TLB entries within the context named in mm */ +static inline void flush_tlb_mm (struct mm_struct *mm) +{ + unsigned char oldctx; + unsigned char seg; + unsigned long i; + + oldctx = sun3_get_context(); + sun3_put_context(mm->context); + + for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) { + seg = sun3_get_segmap(i); + if(seg == SUN3_INVALID_PMEG) + continue; + + sun3_put_segmap(i, SUN3_INVALID_PMEG); + pmeg_alloc[seg] = 0; + pmeg_ctx[seg] = 0; + pmeg_vaddr[seg] = 0; + } + + sun3_put_context(oldctx); + +} + +/* Flush a single TLB page. In this case, we're limited to flushing a + single PMEG */ +static inline void flush_tlb_page (struct vm_area_struct *vma, + unsigned long addr) +{ + unsigned char oldctx; + unsigned char i; + + oldctx = sun3_get_context(); + sun3_put_context(vma->vm_mm->context); + addr &= ~SUN3_PMEG_MASK; + if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG) + { + pmeg_alloc[i] = 0; + pmeg_ctx[i] = 0; + pmeg_vaddr[i] = 0; + sun3_put_segmap (addr, SUN3_INVALID_PMEG); + } + sun3_put_context(oldctx); + +} +/* Flush a range of pages from TLB. */ + +static inline void flush_tlb_range (struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + unsigned char seg, oldctx; + + start &= ~SUN3_PMEG_MASK; + + oldctx = sun3_get_context(); + sun3_put_context(mm->context); + + while(start < end) + { + if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG) + goto next; + if(pmeg_ctx[seg] == mm->context) { + pmeg_alloc[seg] = 0; + pmeg_ctx[seg] = 0; + pmeg_vaddr[seg] = 0; + } + sun3_put_segmap(start, SUN3_INVALID_PMEG); + next: + start += SUN3_PMEG_SIZE; + } +} + +/* Flush kernel page from TLB. */ +static inline void flush_tlb_kernel_page (unsigned long addr) +{ + sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG); +} + +extern inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + +#endif /* SUN3_PGALLOC_H */ diff --git a/include/asm-m68k/sun3_pgtable.h b/include/asm-m68k/sun3_pgtable.h new file mode 100644 index 000000000..ce9e09a2c --- /dev/null +++ b/include/asm-m68k/sun3_pgtable.h @@ -0,0 +1,219 @@ +#ifndef _SUN3_PGTABLE_H +#define _SUN3_PGTABLE_H + +#include <asm/sun3mmu.h> + +#ifndef __ASSEMBLY__ +#include <asm/virtconvert.h> +#include <linux/linkage.h> + +/* + * This file contains all the things which change drastically for the sun3 + * pagetable stuff, to avoid making too much of a mess of the generic m68k + * `pgtable.h'; this should only be included from the generic file. --m + */ + +/* For virtual address to physical address conversion */ +#define VTOP(addr) __pa(addr) +#define PTOV(addr) __va(addr) + + +#endif /* !__ASSEMBLY__ */ + +/* These need to be defined for compatibility although the sun3 doesn't use them */ +#define _PAGE_NOCACHE030 0x040 +#define _CACHEMASK040 (~0x060) +#define _PAGE_NOCACHE_S 0x040 + +/* Page protection values within PTE. */ +#define SUN3_PAGE_VALID (0x80000000) +#define SUN3_PAGE_WRITEABLE (0x40000000) +#define SUN3_PAGE_SYSTEM (0x20000000) +#define SUN3_PAGE_NOCACHE (0x10000000) +#define SUN3_PAGE_ACCESSED (0x02000000) +#define SUN3_PAGE_MODIFIED (0x01000000) + + +/* Externally used page protection values. */ +#define _PAGE_PRESENT (SUN3_PAGE_VALID) +#define _PAGE_ACCESSED (SUN3_PAGE_ACCESSED) + +/* Compound page protection values. */ +//todo: work out which ones *should* have SUN3_PAGE_NOCACHE and fix... +// is it just PAGE_KERNEL and PAGE_SHARED? +#define PAGE_NONE __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_NOCACHE) +#define PAGE_SHARED __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_WRITEABLE \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_NOCACHE) +#define PAGE_COPY __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_NOCACHE) +#define PAGE_READONLY __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_NOCACHE) +#define PAGE_KERNEL __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_WRITEABLE \ + | SUN3_PAGE_SYSTEM \ + | SUN3_PAGE_NOCACHE \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_MODIFIED) +#define PAGE_INIT __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_WRITEABLE \ + | SUN3_PAGE_SYSTEM \ + | SUN3_PAGE_NOCACHE) + +/* + * Page protections for initialising protection_map. The sun3 has only two + * protection settings, valid (implying read and execute) and writeable. These + * are as close as we can get... + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + +/* Use these fake page-protections on PMDs. */ +#define SUN3_PMD_VALID (0x00000001) +#define SUN3_PMD_MASK (0x0000003F) +#define SUN3_PMD_MAGIC (0x0000002B) + +#ifndef __ASSEMBLY__ + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +#define __mk_pte(page, pgprot) \ +({ pte_t __pte; pte_val(__pte) = (__pa(page) >> PAGE_SHIFT) | pgprot_val(pgprot); __pte; }) +#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot)) +#define mk_pte_phys(physpage, pgprot) \ +({ pte_t __pte; pte_val(__pte) = ((physpage) >> PAGE_SHIFT) | pgprot_val(pgprot); __pte; }) +extern inline pte_t pte_modify (pte_t pte, pgprot_t newprot) +{ pte_val(pte) = (pte_val(pte) & SUN3_PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } + +#define pmd_set(pmdp,ptep) do {} while (0) + +extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp) +{ pgd_val(*pgdp) = virt_to_phys(pmdp); } + +#define __pte_page(pte) \ +((unsigned long) __va ((pte_val (pte) & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT)) +#define __pmd_page(pmd) \ +((unsigned long) __va (pmd_val (pmd) & PAGE_MASK)) + +extern inline int pte_none (pte_t pte) { return !pte_val (pte); } +extern inline int pte_present (pte_t pte) { return pte_val (pte) & SUN3_PAGE_VALID; } +extern inline void pte_clear (pte_t *ptep) { pte_val (*ptep) = 0; } + +/* FIXME: this is only a guess */ +#define pte_pagenr(pte) ((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT) +/* Permanent address of a page. */ +#define page_address(page) ({ if (!(page)->virtual) BUG(); (page)->virtual; }) +#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT)) +#define pte_page(pte) (mem_map+pte_pagenr(pte)) + + +extern inline int pmd_none2 (pmd_t *pmd) { return !pmd_val (*pmd); } +#define pmd_none(pmd) pmd_none2(&(pmd)) +//extern inline int pmd_bad (pmd_t pmd) { return (pmd_val (pmd) & SUN3_PMD_MASK) != SUN3_PMD_MAGIC; } +extern inline int pmd_bad2 (pmd_t *pmd) { return 0; } +#define pmd_bad(pmd) pmd_bad2(&(pmd)) +extern inline int pmd_present2 (pmd_t *pmd) { return pmd_val (*pmd) & SUN3_PMD_VALID; } +#define pmd_present(pmd) pmd_present2(&(pmd)) +extern inline void pmd_clear (pmd_t *pmdp) { pmd_val (*pmdp) = 0; } + +extern inline int pgd_none (pgd_t pgd) { return 0; } +extern inline int pgd_bad (pgd_t pgd) { return 0; } +extern inline int pgd_present (pgd_t pgd) { return 0; } +extern inline void pgd_clear (pgd_t *pgdp) {} + + +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not... + * [we have the full set here even if they don't change from m68k] + */ +extern inline int pte_read(pte_t pte) { return 1; } +extern inline int pte_write(pte_t pte) { return pte_val(pte) & SUN3_PAGE_WRITEABLE; } +extern inline int pte_exec(pte_t pte) { return 1; } +extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & SUN3_PAGE_MODIFIED; } +extern inline int pte_young(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESSED; } + +extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_WRITEABLE; return pte; } +extern inline pte_t pte_rdprotect(pte_t pte) { return pte; } +extern inline pte_t pte_exprotect(pte_t pte) { return pte; } +extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_MODIFIED; return pte; } +extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_ACCESSED; return pte; } +extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= SUN3_PAGE_WRITEABLE; return pte; } +extern inline pte_t pte_mkread(pte_t pte) { return pte; } +extern inline pte_t pte_mkexec(pte_t pte) { return pte; } +extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= SUN3_PAGE_MODIFIED; return pte; } +extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= SUN3_PAGE_ACCESSED; return pte; } +extern inline pte_t pte_mknocache(pte_t pte) { pte_val(pte) |= SUN3_PAGE_NOCACHE; return pte; } +// use this version when caches work... +//extern inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) &= SUN3_PAGE_NOCACHE; return pte; } +// until then, use: +extern inline pte_t pte_mkcache(pte_t pte) { return pte; } + +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; +extern pgd_t kernel_pg_dir[PTRS_PER_PGD]; + +/* Find an entry in a pagetable directory. */ +#define pgd_index(address) ((address) >> PGDIR_SHIFT) + +#define pgd_offset(mm, address) \ +((mm)->pgd + pgd_index(address)) + +/* Find an entry in a kernel pagetable directory. */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* Find an entry in the second-level pagetable. */ +extern inline pmd_t *pmd_offset (pgd_t *pgd, unsigned long address) +{ + return (pmd_t *) pgd; +} + +/* Find an entry in the third-level pagetable. */ +#define pte_offset(pmd, address) \ +((pte_t *) __pmd_page (*pmd) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1))) + +/* Disable caching for page at given kernel virtual address. */ +static inline void nocache_page (unsigned long vaddr) +{ + /* Don't think this is required on sun3. --m */ +} + +/* Enable caching for page at given kernel virtual address. */ +static inline void cache_page (unsigned long vaddr) +{ + /* Don't think this is required on sun3. --m */ +} + + + +#endif /* !__ASSEMBLY__ */ +#endif /* !_SUN3_PGTABLE_H */ diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h index a33bb7c14..3da1d58d7 100644 --- a/include/asm-m68k/system.h +++ b/include/asm-m68k/system.h @@ -3,6 +3,7 @@ #include <linux/config.h> /* get configuration macros */ #include <linux/linkage.h> +#include <linux/kernel.h> #include <asm/segment.h> #include <asm/entry.h> @@ -70,19 +71,23 @@ asmlinkage void resume(void); #define sti() __sti() #define save_flags(x) __save_flags(x) #define restore_flags(x) __restore_flags(x) - +#define save_and_cli(flags) do { save_flags(flags); cli(); } while(0) /* * Force strict CPU ordering. * Not really required on m68k... */ -#define nop() asm volatile ("nop"::) -#define mb() asm volatile ("" : : :"memory") -#define rmb() asm volatile ("" : : :"memory") -#define wmb() asm volatile ("" : : :"memory") +#define nop() do { asm volatile ("nop"); barrier(); } while (0) +#define mb() barrier() +#define rmb() barrier() +#define wmb() barrier() #define set_mb(var, value) do { xchg(&var, value); } while (0) #define set_wmb(var, value) do { var = value; wmb(); } while (0) +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() + #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) #define tas(ptr) (xchg((ptr),1)) diff --git a/include/asm-m68k/types.h b/include/asm-m68k/types.h index b0ece7bda..45d1588f2 100644 --- a/include/asm-m68k/types.h +++ b/include/asm-m68k/types.h @@ -49,6 +49,10 @@ typedef unsigned long long u64; #define BITS_PER_LONG 32 +/* DMA addresses are 32-bits wide */ + +typedef u32 dma_addr_t; + #endif /* __KERNEL__ */ #endif /* _M68K_TYPES_H */ diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h index 9b88477aa..4c43eb814 100644 --- a/include/asm-m68k/unistd.h +++ b/include/asm-m68k/unistd.h @@ -80,7 +80,7 @@ #define __NR_sigpending 73 #define __NR_sethostname 74 #define __NR_setrlimit 75 -#define __NR_old_getrlimit 76 +#define __NR_getrlimit 76 #define __NR_getrusage 77 #define __NR_gettimeofday 78 #define __NR_settimeofday 79 @@ -170,6 +170,7 @@ #define __NR_mremap 163 #define __NR_setresuid 164 #define __NR_getresuid 165 +#define __NR_getpagesize 166 #define __NR_query_module 167 #define __NR_poll 168 #define __NR_nfsservctl 169 @@ -194,7 +195,7 @@ #define __NR_getpmsg 188 /* some people actually want streams */ #define __NR_putpmsg 189 /* some people actually want streams */ #define __NR_vfork 190 -#define __NR_getrlimit 191 +#define __NR_ugetrlimit 191 #define __NR_mmap2 192 #define __NR_truncate64 193 #define __NR_ftruncate64 194 |