Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu: (22 commits) m68knommu: Use generic show_interrupts() coldfire_qspi compile fix m68k: merge the mmu and non-mmu versions of sys_m68k.c m68knommu: use asm-generic/bitops/ext2-atomic.h m68knommu: Remove obsolete #include <linux/sys.h> m68k: merge mmu and non-mmu versions of asm-offsets.c m68k: merge non-mmu and mmu versions of m68k_ksyms.c m68knommu: remove un-needed exporting of COLDFIRE symbols m68knommu: move EXPORT of kernel_thread to function definition m68knommu: move EXPORT of local checksumming functions to definitions m68knommu: move EXPORT of dump_fpu to function definition m68knommu: clean up mm/init_no.c m68k: merge the mmu and non-mmu mm/Makefile m68k: mv kmap_mm.c to kmap.c m68knommu: remove stubs for __ioremap() and iounmap() m68knommu: remove unused kernel_set_cachemode() m68k: let Makefile sort out compiling mmu and non-mmu lib/checksum.c m68k: remove duplicate memcpy() implementation m68k: remove duplicate memset() implementation m68k: remove duplicate memmove() implementation ...
This commit is contained in:
commit
9f22aae046
|
@ -5,6 +5,7 @@ config M68K
|
|||
select HAVE_AOUT if MMU
|
||||
select GENERIC_ATOMIC64 if MMU
|
||||
select HAVE_GENERIC_HARDIRQS if !MMU
|
||||
select GENERIC_IRQ_SHOW if !MMU
|
||||
|
||||
config RWSEM_GENERIC_SPINLOCK
|
||||
bool
|
||||
|
|
|
@ -246,23 +246,7 @@ static inline int __test_and_clear_bit_le(int nr, volatile void *addr)
|
|||
return retval;
|
||||
}
|
||||
|
||||
#define ext2_set_bit_atomic(lock, nr, addr) \
|
||||
({ \
|
||||
int ret; \
|
||||
spin_lock(lock); \
|
||||
ret = __test_and_set_bit_le((nr), (addr)); \
|
||||
spin_unlock(lock); \
|
||||
ret; \
|
||||
})
|
||||
|
||||
#define ext2_clear_bit_atomic(lock, nr, addr) \
|
||||
({ \
|
||||
int ret; \
|
||||
spin_lock(lock); \
|
||||
ret = __test_and_clear_bit_le((nr), (addr)); \
|
||||
spin_unlock(lock); \
|
||||
ret; \
|
||||
})
|
||||
#include <asm-generic/bitops/ext2-atomic.h>
|
||||
|
||||
static inline int test_bit_le(int nr, const volatile void *addr)
|
||||
{
|
||||
|
|
|
@ -144,8 +144,10 @@ static inline void io_insl(unsigned int addr, void *buf, int len)
|
|||
#define IOMAP_NOCACHE_NONSER 2
|
||||
#define IOMAP_WRITETHROUGH 3
|
||||
|
||||
extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
|
||||
|
||||
static inline void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
|
||||
{
|
||||
return (void *) physaddr;
|
||||
}
|
||||
static inline void *ioremap(unsigned long physaddr, unsigned long size)
|
||||
{
|
||||
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
|
||||
|
@ -163,7 +165,7 @@ static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size
|
|||
return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
|
||||
}
|
||||
|
||||
extern void iounmap(void *addr);
|
||||
#define iounmap(addr) do { } while(0)
|
||||
|
||||
/*
|
||||
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
|
||||
|
|
|
@ -1,5 +1,105 @@
|
|||
#ifdef CONFIG_MMU
|
||||
#include "asm-offsets_mm.c"
|
||||
/*
|
||||
* This program is used to generate definitions needed by
|
||||
* assembly language modules.
|
||||
*
|
||||
* We use the technique used in the OSF Mach kernel code:
|
||||
* generate asm statements containing #defines,
|
||||
* compile this file to assembler, and then extract the
|
||||
* #defines from the assembly-language output.
|
||||
*/
|
||||
|
||||
#define ASM_OFFSETS_C
|
||||
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/kbuild.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/amigahw.h>
|
||||
#include <linux/font.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* offsets into the task struct */
|
||||
DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
|
||||
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
|
||||
DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
|
||||
DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info));
|
||||
|
||||
/* offsets into the thread struct */
|
||||
DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
|
||||
DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
|
||||
DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
|
||||
DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));
|
||||
DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
|
||||
DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
|
||||
DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
|
||||
DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
|
||||
DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
|
||||
|
||||
/* offsets into the thread_info struct */
|
||||
DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
|
||||
DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
|
||||
|
||||
/* offsets into the pt_regs */
|
||||
DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
|
||||
DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
|
||||
DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
|
||||
DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
|
||||
DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
|
||||
DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
|
||||
DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
|
||||
DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
|
||||
DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
|
||||
DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
|
||||
DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
|
||||
DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
|
||||
|
||||
/* bitfields are a bit difficult */
|
||||
#ifdef CONFIG_COLDFIRE
|
||||
DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2);
|
||||
#else
|
||||
#include "asm-offsets_no.c"
|
||||
DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
|
||||
#endif
|
||||
|
||||
/* offsets into the irq_cpustat_t struct */
|
||||
DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
|
||||
|
||||
/* signal defines */
|
||||
DEFINE(LSIGSEGV, SIGSEGV);
|
||||
DEFINE(LSEGV_MAPERR, SEGV_MAPERR);
|
||||
DEFINE(LSIGTRAP, SIGTRAP);
|
||||
DEFINE(LTRAP_TRACE, TRAP_TRACE);
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
/* offsets into the bi_record struct */
|
||||
DEFINE(BIR_TAG, offsetof(struct bi_record, tag));
|
||||
DEFINE(BIR_SIZE, offsetof(struct bi_record, size));
|
||||
DEFINE(BIR_DATA, offsetof(struct bi_record, data));
|
||||
|
||||
/* offsets into font_desc (drivers/video/console/font.h) */
|
||||
DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx));
|
||||
DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name));
|
||||
DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width));
|
||||
DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height));
|
||||
DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data));
|
||||
DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref));
|
||||
|
||||
/* offsets into the custom struct */
|
||||
DEFINE(CUSTOMBASE, &amiga_custom);
|
||||
DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar));
|
||||
DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr));
|
||||
DEFINE(C_INTENA, offsetof(struct CUSTOM, intena));
|
||||
DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq));
|
||||
DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr));
|
||||
DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat));
|
||||
DEFINE(C_SERPER, offsetof(struct CUSTOM, serper));
|
||||
DEFINE(CIAABASE, &ciaa);
|
||||
DEFINE(CIABBASE, &ciab);
|
||||
DEFINE(C_PRA, offsetof(struct CIA, pra));
|
||||
DEFINE(ZTWOBASE, zTwoBase);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* This program is used to generate definitions needed by
|
||||
* assembly language modules.
|
||||
*
|
||||
* We use the technique used in the OSF Mach kernel code:
|
||||
* generate asm statements containing #defines,
|
||||
* compile this file to assembler, and then extract the
|
||||
* #defines from the assembly-language output.
|
||||
*/
|
||||
|
||||
#define ASM_OFFSETS_C
|
||||
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/kbuild.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/amigahw.h>
|
||||
#include <linux/font.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* offsets into the task struct */
|
||||
DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
|
||||
DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
|
||||
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
|
||||
#ifdef CONFIG_MMU
|
||||
DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info));
|
||||
#endif
|
||||
|
||||
/* offsets into the thread struct */
|
||||
DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
|
||||
DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
|
||||
DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
|
||||
DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));
|
||||
DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
|
||||
DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
|
||||
DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
|
||||
DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
|
||||
DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
|
||||
|
||||
/* offsets into the thread_info struct */
|
||||
DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
|
||||
DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
|
||||
|
||||
/* offsets into the pt_regs */
|
||||
DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
|
||||
DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
|
||||
DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
|
||||
DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
|
||||
DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
|
||||
DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
|
||||
DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
|
||||
DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
|
||||
DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
|
||||
DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
|
||||
DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
|
||||
DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
|
||||
/* bitfields are a bit difficult */
|
||||
DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
|
||||
|
||||
/* offsets into the irq_cpustat_t struct */
|
||||
DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
|
||||
|
||||
/* offsets into the bi_record struct */
|
||||
DEFINE(BIR_TAG, offsetof(struct bi_record, tag));
|
||||
DEFINE(BIR_SIZE, offsetof(struct bi_record, size));
|
||||
DEFINE(BIR_DATA, offsetof(struct bi_record, data));
|
||||
|
||||
/* offsets into font_desc (drivers/video/console/font.h) */
|
||||
DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx));
|
||||
DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name));
|
||||
DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width));
|
||||
DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height));
|
||||
DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data));
|
||||
DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref));
|
||||
|
||||
/* signal defines */
|
||||
DEFINE(LSIGSEGV, SIGSEGV);
|
||||
DEFINE(LSEGV_MAPERR, SEGV_MAPERR);
|
||||
DEFINE(LSIGTRAP, SIGTRAP);
|
||||
DEFINE(LTRAP_TRACE, TRAP_TRACE);
|
||||
|
||||
/* offsets into the custom struct */
|
||||
DEFINE(CUSTOMBASE, &amiga_custom);
|
||||
DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar));
|
||||
DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr));
|
||||
DEFINE(C_INTENA, offsetof(struct CUSTOM, intena));
|
||||
DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq));
|
||||
DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr));
|
||||
DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat));
|
||||
DEFINE(C_SERPER, offsetof(struct CUSTOM, serper));
|
||||
DEFINE(CIAABASE, &ciaa);
|
||||
DEFINE(CIABBASE, &ciab);
|
||||
DEFINE(C_PRA, offsetof(struct CIA, pra));
|
||||
DEFINE(ZTWOBASE, zTwoBase);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* This program is used to generate definitions needed by
|
||||
* assembly language modules.
|
||||
*
|
||||
* We use the technique used in the OSF Mach kernel code:
|
||||
* generate asm statements containing #defines,
|
||||
* compile this file to assembler, and then extract the
|
||||
* #defines from the assembly-language output.
|
||||
*/
|
||||
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/kbuild.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* offsets into the task struct */
|
||||
DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
|
||||
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
|
||||
|
||||
/* offsets into the irq_cpustat_t struct */
|
||||
DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
|
||||
|
||||
/* offsets into the thread struct */
|
||||
DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
|
||||
DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
|
||||
DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
|
||||
DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));
|
||||
DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
|
||||
DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
|
||||
DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
|
||||
DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
|
||||
DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
|
||||
|
||||
/* offsets into the pt_regs */
|
||||
DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
|
||||
DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
|
||||
DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
|
||||
DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
|
||||
DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
|
||||
DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
|
||||
DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
|
||||
DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
|
||||
DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
|
||||
DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
|
||||
DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
|
||||
DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
|
||||
|
||||
#ifdef CONFIG_COLDFIRE
|
||||
/* bitfields are a bit difficult */
|
||||
DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2);
|
||||
#else
|
||||
/* bitfields are a bit difficult */
|
||||
DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
|
||||
#endif
|
||||
|
||||
/* signal defines */
|
||||
DEFINE(SIGSEGV, SIGSEGV);
|
||||
DEFINE(SEGV_MAPERR, SEGV_MAPERR);
|
||||
DEFINE(SIGTRAP, SIGTRAP);
|
||||
DEFINE(TRAP_TRACE, TRAP_TRACE);
|
||||
|
||||
DEFINE(PT_PTRACED, PT_PTRACED);
|
||||
|
||||
/* Offsets in thread_info structure */
|
||||
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
|
||||
DEFINE(TI_PREEMPTCOUNT, offsetof(struct thread_info, preempt_count));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -24,7 +24,6 @@
|
|||
* linux 2.4 support David McCullough <davidm@snapgear.com>
|
||||
*/
|
||||
|
||||
#include <linux/sys.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/setup.h>
|
||||
|
|
|
@ -28,31 +28,3 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
|
|||
|
||||
set_irq_regs(oldregs);
|
||||
}
|
||||
|
||||
int show_interrupts(struct seq_file *p, void *v)
|
||||
{
|
||||
struct irqaction *ap;
|
||||
int irq = *((loff_t *) v);
|
||||
|
||||
if (irq == 0)
|
||||
seq_puts(p, " CPU0\n");
|
||||
|
||||
if (irq < NR_IRQS) {
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
|
||||
ap = desc->action;
|
||||
if (ap) {
|
||||
seq_printf(p, "%3d: ", irq);
|
||||
seq_printf(p, "%10u ", kstat_irqs(irq));
|
||||
seq_printf(p, "%14s ", irq_desc_get_chip(desc)->name);
|
||||
|
||||
seq_printf(p, "%s", ap->name);
|
||||
for (ap = ap->next; ap; ap = ap->next)
|
||||
seq_printf(p, ", %s", ap->name);
|
||||
seq_putc(p, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,33 @@
|
|||
#ifdef CONFIG_MMU
|
||||
#include "m68k_ksyms_mm.c"
|
||||
#else
|
||||
#include "m68k_ksyms_no.c"
|
||||
#include <linux/module.h>
|
||||
|
||||
asmlinkage long long __ashldi3 (long long, int);
|
||||
asmlinkage long long __ashrdi3 (long long, int);
|
||||
asmlinkage long long __lshrdi3 (long long, int);
|
||||
asmlinkage long long __muldi3 (long long, long long);
|
||||
|
||||
/* The following are special because they're not called
|
||||
explicitly (the C compiler generates them). Fortunately,
|
||||
their interface isn't gonna change any time soon now, so
|
||||
it's OK to leave it out of version control. */
|
||||
EXPORT_SYMBOL(__ashldi3);
|
||||
EXPORT_SYMBOL(__ashrdi3);
|
||||
EXPORT_SYMBOL(__lshrdi3);
|
||||
EXPORT_SYMBOL(__muldi3);
|
||||
|
||||
#if !defined(__mc68020__) && !defined(__mc68030__) && \
|
||||
!defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcpu32__)
|
||||
/*
|
||||
* Simpler 68k and ColdFire parts also need a few other gcc functions.
|
||||
*/
|
||||
extern long long __divsi3(long long, long long);
|
||||
extern long long __modsi3(long long, long long);
|
||||
extern long long __mulsi3(long long, long long);
|
||||
extern long long __udivsi3(long long, long long);
|
||||
extern long long __umodsi3(long long, long long);
|
||||
|
||||
EXPORT_SYMBOL(__divsi3);
|
||||
EXPORT_SYMBOL(__modsi3);
|
||||
EXPORT_SYMBOL(__mulsi3);
|
||||
EXPORT_SYMBOL(__udivsi3);
|
||||
EXPORT_SYMBOL(__umodsi3);
|
||||
#endif
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
#include <linux/module.h>
|
||||
|
||||
asmlinkage long long __ashldi3 (long long, int);
|
||||
asmlinkage long long __ashrdi3 (long long, int);
|
||||
asmlinkage long long __lshrdi3 (long long, int);
|
||||
asmlinkage long long __muldi3 (long long, long long);
|
||||
|
||||
/* The following are special because they're not called
|
||||
explicitly (the C compiler generates them). Fortunately,
|
||||
their interface isn't gonna change any time soon now, so
|
||||
it's OK to leave it out of version control. */
|
||||
EXPORT_SYMBOL(__ashldi3);
|
||||
EXPORT_SYMBOL(__ashrdi3);
|
||||
EXPORT_SYMBOL(__lshrdi3);
|
||||
EXPORT_SYMBOL(__muldi3);
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/elfcore.h>
|
||||
#include <linux/in6.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/checksum.h>
|
||||
#include <asm/current.h>
|
||||
|
||||
extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
|
||||
|
||||
/* platform dependent support */
|
||||
|
||||
EXPORT_SYMBOL(__ioremap);
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
EXPORT_SYMBOL(dump_fpu);
|
||||
|
||||
EXPORT_SYMBOL(ip_fast_csum);
|
||||
|
||||
EXPORT_SYMBOL(kernel_thread);
|
||||
|
||||
/* Networking helper routines. */
|
||||
EXPORT_SYMBOL(csum_partial_copy_nocheck);
|
||||
|
||||
/* The following are special because they're not called
|
||||
explicitly (the C compiler generates them). Fortunately,
|
||||
their interface isn't gonna change any time soon now, so
|
||||
it's OK to leave it out of version control. */
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
EXPORT_SYMBOL(memset);
|
||||
|
||||
/*
|
||||
* libgcc functions - functions that are used internally by the
|
||||
* compiler... (prototypes are not correct though, but that
|
||||
* doesn't really matter since they're not versioned).
|
||||
*/
|
||||
extern void __ashldi3(void);
|
||||
extern void __ashrdi3(void);
|
||||
extern void __divsi3(void);
|
||||
extern void __lshrdi3(void);
|
||||
extern void __modsi3(void);
|
||||
extern void __muldi3(void);
|
||||
extern void __mulsi3(void);
|
||||
extern void __udivsi3(void);
|
||||
extern void __umodsi3(void);
|
||||
|
||||
/* gcc lib functions */
|
||||
EXPORT_SYMBOL(__ashldi3);
|
||||
EXPORT_SYMBOL(__ashrdi3);
|
||||
EXPORT_SYMBOL(__divsi3);
|
||||
EXPORT_SYMBOL(__lshrdi3);
|
||||
EXPORT_SYMBOL(__modsi3);
|
||||
EXPORT_SYMBOL(__muldi3);
|
||||
EXPORT_SYMBOL(__mulsi3);
|
||||
EXPORT_SYMBOL(__udivsi3);
|
||||
EXPORT_SYMBOL(__umodsi3);
|
||||
|
||||
#ifdef CONFIG_COLDFIRE
|
||||
extern unsigned int *dma_device_address;
|
||||
extern unsigned long dma_base_addr, _ramend;
|
||||
EXPORT_SYMBOL(dma_base_addr);
|
||||
EXPORT_SYMBOL(dma_device_address);
|
||||
EXPORT_SYMBOL(_ramend);
|
||||
|
||||
extern asmlinkage void trap(void);
|
||||
extern void *_ramvec;
|
||||
EXPORT_SYMBOL(trap);
|
||||
EXPORT_SYMBOL(_ramvec);
|
||||
#endif /* CONFIG_COLDFIRE */
|
|
@ -151,6 +151,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
|||
set_fs(fs);
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_thread);
|
||||
|
||||
void flush_thread(void)
|
||||
{
|
||||
|
@ -283,6 +284,7 @@ int dump_fpu(struct pt_regs *regs, struct user_m68kfp_struct *fpu)
|
|||
#endif
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(dump_fpu);
|
||||
|
||||
/*
|
||||
* Generic dumping code. Used for panic and debug.
|
||||
|
|
|
@ -1,5 +1,580 @@
|
|||
/*
|
||||
* linux/arch/m68k/kernel/sys_m68k.c
|
||||
*
|
||||
* This file contains various random system calls that
|
||||
* have a non-standard calling sequence on the Linux/m68k
|
||||
* platform.
|
||||
*/
|
||||
|
||||
#include <linux/capability.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/sem.h>
|
||||
#include <linux/msg.h>
|
||||
#include <linux/shm.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/ipc.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/cachectl.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
#include "sys_m68k_mm.c"
|
||||
|
||||
#include <asm/tlb.h>
|
||||
|
||||
asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
|
||||
unsigned long error_code);
|
||||
|
||||
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
|
||||
unsigned long prot, unsigned long flags,
|
||||
unsigned long fd, unsigned long pgoff)
|
||||
{
|
||||
/*
|
||||
* This is wrong for sun3 - there PAGE_SIZE is 8Kb,
|
||||
* so we need to shift the argument down by 1; m68k mmap64(3)
|
||||
* (in libc) expects the last argument of mmap2 in 4Kb units.
|
||||
*/
|
||||
return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
|
||||
}
|
||||
|
||||
/* Convert virtual (user) address VADDR to physical address PADDR */
|
||||
#define virt_to_phys_040(vaddr) \
|
||||
({ \
|
||||
unsigned long _mmusr, _paddr; \
|
||||
\
|
||||
__asm__ __volatile__ (".chip 68040\n\t" \
|
||||
"ptestr (%1)\n\t" \
|
||||
"movec %%mmusr,%0\n\t" \
|
||||
".chip 68k" \
|
||||
: "=r" (_mmusr) \
|
||||
: "a" (vaddr)); \
|
||||
_paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0; \
|
||||
_paddr; \
|
||||
})
|
||||
|
||||
static inline int
|
||||
cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len)
|
||||
{
|
||||
unsigned long paddr, i;
|
||||
|
||||
switch (scope)
|
||||
{
|
||||
case FLUSH_SCOPE_ALL:
|
||||
switch (cache)
|
||||
{
|
||||
case FLUSH_CACHE_DATA:
|
||||
/* This nop is needed for some broken versions of the 68040. */
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpusha %dc\n\t"
|
||||
".chip 68k");
|
||||
break;
|
||||
case FLUSH_CACHE_INSN:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpusha %ic\n\t"
|
||||
".chip 68k");
|
||||
break;
|
||||
default:
|
||||
case FLUSH_CACHE_BOTH:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpusha %bc\n\t"
|
||||
".chip 68k");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLUSH_SCOPE_LINE:
|
||||
/* Find the physical address of the first mapped page in the
|
||||
address range. */
|
||||
if ((paddr = virt_to_phys_040(addr))) {
|
||||
paddr += addr & ~(PAGE_MASK | 15);
|
||||
len = (len + (addr & 15) + 15) >> 4;
|
||||
} else {
|
||||
unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
|
||||
|
||||
if (len <= tmp)
|
||||
return 0;
|
||||
addr += tmp;
|
||||
len -= tmp;
|
||||
tmp = PAGE_SIZE;
|
||||
for (;;)
|
||||
{
|
||||
if ((paddr = virt_to_phys_040(addr)))
|
||||
break;
|
||||
if (len <= tmp)
|
||||
return 0;
|
||||
addr += tmp;
|
||||
len -= tmp;
|
||||
}
|
||||
len = (len + 15) >> 4;
|
||||
}
|
||||
i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
|
||||
while (len--)
|
||||
{
|
||||
switch (cache)
|
||||
{
|
||||
case FLUSH_CACHE_DATA:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpushl %%dc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
case FLUSH_CACHE_INSN:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpushl %%ic,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
default:
|
||||
case FLUSH_CACHE_BOTH:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpushl %%bc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
}
|
||||
if (!--i && len)
|
||||
{
|
||||
/*
|
||||
* No need to page align here since it is done by
|
||||
* virt_to_phys_040().
|
||||
*/
|
||||
addr += PAGE_SIZE;
|
||||
i = PAGE_SIZE / 16;
|
||||
/* Recompute physical address when crossing a page
|
||||
boundary. */
|
||||
for (;;)
|
||||
{
|
||||
if ((paddr = virt_to_phys_040(addr)))
|
||||
break;
|
||||
if (len <= i)
|
||||
return 0;
|
||||
len -= i;
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
paddr += 16;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case FLUSH_SCOPE_PAGE:
|
||||
len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
|
||||
for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
|
||||
{
|
||||
if (!(paddr = virt_to_phys_040(addr)))
|
||||
continue;
|
||||
switch (cache)
|
||||
{
|
||||
case FLUSH_CACHE_DATA:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpushp %%dc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
case FLUSH_CACHE_INSN:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpushp %%ic,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
default:
|
||||
case FLUSH_CACHE_BOTH:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpushp %%bc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define virt_to_phys_060(vaddr) \
|
||||
({ \
|
||||
unsigned long paddr; \
|
||||
__asm__ __volatile__ (".chip 68060\n\t" \
|
||||
"plpar (%0)\n\t" \
|
||||
".chip 68k" \
|
||||
: "=a" (paddr) \
|
||||
: "0" (vaddr)); \
|
||||
(paddr); /* XXX */ \
|
||||
})
|
||||
|
||||
static inline int
|
||||
cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)
|
||||
{
|
||||
unsigned long paddr, i;
|
||||
|
||||
/*
|
||||
* 68060 manual says:
|
||||
* cpush %dc : flush DC, remains valid (with our %cacr setup)
|
||||
* cpush %ic : invalidate IC
|
||||
* cpush %bc : flush DC + invalidate IC
|
||||
*/
|
||||
switch (scope)
|
||||
{
|
||||
case FLUSH_SCOPE_ALL:
|
||||
switch (cache)
|
||||
{
|
||||
case FLUSH_CACHE_DATA:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpusha %dc\n\t"
|
||||
".chip 68k");
|
||||
break;
|
||||
case FLUSH_CACHE_INSN:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpusha %ic\n\t"
|
||||
".chip 68k");
|
||||
break;
|
||||
default:
|
||||
case FLUSH_CACHE_BOTH:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpusha %bc\n\t"
|
||||
".chip 68k");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLUSH_SCOPE_LINE:
|
||||
/* Find the physical address of the first mapped page in the
|
||||
address range. */
|
||||
len += addr & 15;
|
||||
addr &= -16;
|
||||
if (!(paddr = virt_to_phys_060(addr))) {
|
||||
unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
|
||||
|
||||
if (len <= tmp)
|
||||
return 0;
|
||||
addr += tmp;
|
||||
len -= tmp;
|
||||
tmp = PAGE_SIZE;
|
||||
for (;;)
|
||||
{
|
||||
if ((paddr = virt_to_phys_060(addr)))
|
||||
break;
|
||||
if (len <= tmp)
|
||||
return 0;
|
||||
addr += tmp;
|
||||
len -= tmp;
|
||||
}
|
||||
}
|
||||
len = (len + 15) >> 4;
|
||||
i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
|
||||
while (len--)
|
||||
{
|
||||
switch (cache)
|
||||
{
|
||||
case FLUSH_CACHE_DATA:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpushl %%dc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
case FLUSH_CACHE_INSN:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpushl %%ic,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
default:
|
||||
case FLUSH_CACHE_BOTH:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpushl %%bc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
}
|
||||
if (!--i && len)
|
||||
{
|
||||
|
||||
/*
|
||||
* We just want to jump to the first cache line
|
||||
* in the next page.
|
||||
*/
|
||||
addr += PAGE_SIZE;
|
||||
addr &= PAGE_MASK;
|
||||
|
||||
i = PAGE_SIZE / 16;
|
||||
/* Recompute physical address when crossing a page
|
||||
boundary. */
|
||||
for (;;)
|
||||
{
|
||||
if ((paddr = virt_to_phys_060(addr)))
|
||||
break;
|
||||
if (len <= i)
|
||||
return 0;
|
||||
len -= i;
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
paddr += 16;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case FLUSH_SCOPE_PAGE:
|
||||
len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
|
||||
addr &= PAGE_MASK; /* Workaround for bug in some
|
||||
revisions of the 68060 */
|
||||
for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
|
||||
{
|
||||
if (!(paddr = virt_to_phys_060(addr)))
|
||||
continue;
|
||||
switch (cache)
|
||||
{
|
||||
case FLUSH_CACHE_DATA:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpushp %%dc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
case FLUSH_CACHE_INSN:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpushp %%ic,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
default:
|
||||
case FLUSH_CACHE_BOTH:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpushp %%bc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sys_cacheflush -- flush (part of) the processor cache. */
|
||||
asmlinkage int
|
||||
sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
|
||||
{
|
||||
struct vm_area_struct *vma;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||
|
||||
cache & ~FLUSH_CACHE_BOTH)
|
||||
goto out;
|
||||
|
||||
if (scope == FLUSH_SCOPE_ALL) {
|
||||
/* Only the superuser may explicitly flush the whole cache. */
|
||||
ret = -EPERM;
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
goto out;
|
||||
} else {
|
||||
/*
|
||||
* Verify that the specified address region actually belongs
|
||||
* to this process.
|
||||
*/
|
||||
vma = find_vma (current->mm, addr);
|
||||
ret = -EINVAL;
|
||||
/* Check for overflow. */
|
||||
if (addr + len < addr)
|
||||
goto out;
|
||||
if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (CPU_IS_020_OR_030) {
|
||||
if (scope == FLUSH_SCOPE_LINE && len < 256) {
|
||||
unsigned long cacr;
|
||||
__asm__ ("movec %%cacr, %0" : "=r" (cacr));
|
||||
if (cache & FLUSH_CACHE_INSN)
|
||||
cacr |= 4;
|
||||
if (cache & FLUSH_CACHE_DATA)
|
||||
cacr |= 0x400;
|
||||
len >>= 2;
|
||||
while (len--) {
|
||||
__asm__ __volatile__ ("movec %1, %%caar\n\t"
|
||||
"movec %0, %%cacr"
|
||||
: /* no outputs */
|
||||
: "r" (cacr), "r" (addr));
|
||||
addr += 4;
|
||||
}
|
||||
} else {
|
||||
/* Flush the whole cache, even if page granularity requested. */
|
||||
unsigned long cacr;
|
||||
__asm__ ("movec %%cacr, %0" : "=r" (cacr));
|
||||
if (cache & FLUSH_CACHE_INSN)
|
||||
cacr |= 8;
|
||||
if (cache & FLUSH_CACHE_DATA)
|
||||
cacr |= 0x800;
|
||||
__asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr));
|
||||
}
|
||||
ret = 0;
|
||||
goto out;
|
||||
} else {
|
||||
/*
|
||||
* 040 or 060: don't blindly trust 'scope', someone could
|
||||
* try to flush a few megs of memory.
|
||||
*/
|
||||
|
||||
if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE)
|
||||
scope=FLUSH_SCOPE_PAGE;
|
||||
if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL)
|
||||
scope=FLUSH_SCOPE_ALL;
|
||||
if (CPU_IS_040) {
|
||||
ret = cache_flush_040 (addr, scope, cache, len);
|
||||
} else if (CPU_IS_060) {
|
||||
ret = cache_flush_060 (addr, scope, cache, len);
|
||||
}
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This syscall gets its arguments in A0 (mem), D2 (oldval) and
|
||||
D1 (newval). */
|
||||
asmlinkage int
|
||||
sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
|
||||
unsigned long __user * mem)
|
||||
{
|
||||
/* This was borrowed from ARM's implementation. */
|
||||
for (;;) {
|
||||
struct mm_struct *mm = current->mm;
|
||||
pgd_t *pgd;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
spinlock_t *ptl;
|
||||
unsigned long mem_value;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
pgd = pgd_offset(mm, (unsigned long)mem);
|
||||
if (!pgd_present(*pgd))
|
||||
goto bad_access;
|
||||
pmd = pmd_offset(pgd, (unsigned long)mem);
|
||||
if (!pmd_present(*pmd))
|
||||
goto bad_access;
|
||||
pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl);
|
||||
if (!pte_present(*pte) || !pte_dirty(*pte)
|
||||
|| !pte_write(*pte)) {
|
||||
pte_unmap_unlock(pte, ptl);
|
||||
goto bad_access;
|
||||
}
|
||||
|
||||
mem_value = *mem;
|
||||
if (mem_value == oldval)
|
||||
*mem = newval;
|
||||
|
||||
pte_unmap_unlock(pte, ptl);
|
||||
up_read(&mm->mmap_sem);
|
||||
return mem_value;
|
||||
|
||||
bad_access:
|
||||
up_read(&mm->mmap_sem);
|
||||
/* This is not necessarily a bad access, we can get here if
|
||||
a memory we're trying to write to should be copied-on-write.
|
||||
Make the kernel do the necessary page stuff, then re-iterate.
|
||||
Simulate a write access fault to do that. */
|
||||
{
|
||||
/* The first argument of the function corresponds to
|
||||
D1, which is the first field of struct pt_regs. */
|
||||
struct pt_regs *fp = (struct pt_regs *)&newval;
|
||||
|
||||
/* '3' is an RMW flag. */
|
||||
if (do_page_fault(fp, (unsigned long)mem, 3))
|
||||
/* If the do_page_fault() failed, we don't
|
||||
have anything meaningful to return.
|
||||
There should be a SIGSEGV pending for
|
||||
the process. */
|
||||
return 0xdeadbeef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#include "sys_m68k_no.c"
|
||||
#endif
|
||||
|
||||
/* sys_cacheflush -- flush (part of) the processor cache. */
|
||||
asmlinkage int
|
||||
sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
|
||||
{
|
||||
flush_cache_all();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This syscall gets its arguments in A0 (mem), D2 (oldval) and
|
||||
D1 (newval). */
|
||||
asmlinkage int
|
||||
sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
|
||||
unsigned long __user * mem)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
unsigned long mem_value;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
|
||||
mem_value = *mem;
|
||||
if (mem_value == oldval)
|
||||
*mem = newval;
|
||||
|
||||
up_read(&mm->mmap_sem);
|
||||
return mem_value;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
asmlinkage int sys_getpagesize(void)
|
||||
{
|
||||
return PAGE_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a system call from kernel instead of calling sys_execve so we
|
||||
* end up with proper pt_regs.
|
||||
*/
|
||||
int kernel_execve(const char *filename,
|
||||
const char *const argv[],
|
||||
const char *const envp[])
|
||||
{
|
||||
register long __res asm ("%d0") = __NR_execve;
|
||||
register long __a asm ("%d1") = (long)(filename);
|
||||
register long __b asm ("%d2") = (long)(argv);
|
||||
register long __c asm ("%d3") = (long)(envp);
|
||||
asm volatile ("trap #0" : "+d" (__res)
|
||||
: "d" (__a), "d" (__b), "d" (__c));
|
||||
return __res;
|
||||
}
|
||||
|
||||
asmlinkage unsigned long sys_get_thread_area(void)
|
||||
{
|
||||
return current_thread_info()->tp_value;
|
||||
}
|
||||
|
||||
asmlinkage int sys_set_thread_area(unsigned long tp)
|
||||
{
|
||||
current_thread_info()->tp_value = tp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
asmlinkage int sys_atomic_barrier(void)
|
||||
{
|
||||
/* no code needed for uniprocs */
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,546 +0,0 @@
|
|||
/*
|
||||
* linux/arch/m68k/kernel/sys_m68k.c
|
||||
*
|
||||
* This file contains various random system calls that
|
||||
* have a non-standard calling sequence on the Linux/m68k
|
||||
* platform.
|
||||
*/
|
||||
|
||||
#include <linux/capability.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/sem.h>
|
||||
#include <linux/msg.h>
|
||||
#include <linux/shm.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/ipc.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/cachectl.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <linux/elf.h>
|
||||
#include <asm/tlb.h>
|
||||
|
||||
asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
|
||||
unsigned long error_code);
|
||||
|
||||
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
|
||||
unsigned long prot, unsigned long flags,
|
||||
unsigned long fd, unsigned long pgoff)
|
||||
{
|
||||
/*
|
||||
* This is wrong for sun3 - there PAGE_SIZE is 8Kb,
|
||||
* so we need to shift the argument down by 1; m68k mmap64(3)
|
||||
* (in libc) expects the last argument of mmap2 in 4Kb units.
|
||||
*/
|
||||
return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
|
||||
}
|
||||
|
||||
/* Convert virtual (user) address VADDR to physical address PADDR */
|
||||
#define virt_to_phys_040(vaddr) \
|
||||
({ \
|
||||
unsigned long _mmusr, _paddr; \
|
||||
\
|
||||
__asm__ __volatile__ (".chip 68040\n\t" \
|
||||
"ptestr (%1)\n\t" \
|
||||
"movec %%mmusr,%0\n\t" \
|
||||
".chip 68k" \
|
||||
: "=r" (_mmusr) \
|
||||
: "a" (vaddr)); \
|
||||
_paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0; \
|
||||
_paddr; \
|
||||
})
|
||||
|
||||
static inline int
|
||||
cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len)
|
||||
{
|
||||
unsigned long paddr, i;
|
||||
|
||||
switch (scope)
|
||||
{
|
||||
case FLUSH_SCOPE_ALL:
|
||||
switch (cache)
|
||||
{
|
||||
case FLUSH_CACHE_DATA:
|
||||
/* This nop is needed for some broken versions of the 68040. */
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpusha %dc\n\t"
|
||||
".chip 68k");
|
||||
break;
|
||||
case FLUSH_CACHE_INSN:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpusha %ic\n\t"
|
||||
".chip 68k");
|
||||
break;
|
||||
default:
|
||||
case FLUSH_CACHE_BOTH:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpusha %bc\n\t"
|
||||
".chip 68k");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLUSH_SCOPE_LINE:
|
||||
/* Find the physical address of the first mapped page in the
|
||||
address range. */
|
||||
if ((paddr = virt_to_phys_040(addr))) {
|
||||
paddr += addr & ~(PAGE_MASK | 15);
|
||||
len = (len + (addr & 15) + 15) >> 4;
|
||||
} else {
|
||||
unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
|
||||
|
||||
if (len <= tmp)
|
||||
return 0;
|
||||
addr += tmp;
|
||||
len -= tmp;
|
||||
tmp = PAGE_SIZE;
|
||||
for (;;)
|
||||
{
|
||||
if ((paddr = virt_to_phys_040(addr)))
|
||||
break;
|
||||
if (len <= tmp)
|
||||
return 0;
|
||||
addr += tmp;
|
||||
len -= tmp;
|
||||
}
|
||||
len = (len + 15) >> 4;
|
||||
}
|
||||
i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
|
||||
while (len--)
|
||||
{
|
||||
switch (cache)
|
||||
{
|
||||
case FLUSH_CACHE_DATA:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpushl %%dc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
case FLUSH_CACHE_INSN:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpushl %%ic,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
default:
|
||||
case FLUSH_CACHE_BOTH:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpushl %%bc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
}
|
||||
if (!--i && len)
|
||||
{
|
||||
/*
|
||||
* No need to page align here since it is done by
|
||||
* virt_to_phys_040().
|
||||
*/
|
||||
addr += PAGE_SIZE;
|
||||
i = PAGE_SIZE / 16;
|
||||
/* Recompute physical address when crossing a page
|
||||
boundary. */
|
||||
for (;;)
|
||||
{
|
||||
if ((paddr = virt_to_phys_040(addr)))
|
||||
break;
|
||||
if (len <= i)
|
||||
return 0;
|
||||
len -= i;
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
paddr += 16;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case FLUSH_SCOPE_PAGE:
|
||||
len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
|
||||
for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
|
||||
{
|
||||
if (!(paddr = virt_to_phys_040(addr)))
|
||||
continue;
|
||||
switch (cache)
|
||||
{
|
||||
case FLUSH_CACHE_DATA:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpushp %%dc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
case FLUSH_CACHE_INSN:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpushp %%ic,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
default:
|
||||
case FLUSH_CACHE_BOTH:
|
||||
__asm__ __volatile__ ("nop\n\t"
|
||||
".chip 68040\n\t"
|
||||
"cpushp %%bc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define virt_to_phys_060(vaddr) \
|
||||
({ \
|
||||
unsigned long paddr; \
|
||||
__asm__ __volatile__ (".chip 68060\n\t" \
|
||||
"plpar (%0)\n\t" \
|
||||
".chip 68k" \
|
||||
: "=a" (paddr) \
|
||||
: "0" (vaddr)); \
|
||||
(paddr); /* XXX */ \
|
||||
})
|
||||
|
||||
static inline int
|
||||
cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)
|
||||
{
|
||||
unsigned long paddr, i;
|
||||
|
||||
/*
|
||||
* 68060 manual says:
|
||||
* cpush %dc : flush DC, remains valid (with our %cacr setup)
|
||||
* cpush %ic : invalidate IC
|
||||
* cpush %bc : flush DC + invalidate IC
|
||||
*/
|
||||
switch (scope)
|
||||
{
|
||||
case FLUSH_SCOPE_ALL:
|
||||
switch (cache)
|
||||
{
|
||||
case FLUSH_CACHE_DATA:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpusha %dc\n\t"
|
||||
".chip 68k");
|
||||
break;
|
||||
case FLUSH_CACHE_INSN:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpusha %ic\n\t"
|
||||
".chip 68k");
|
||||
break;
|
||||
default:
|
||||
case FLUSH_CACHE_BOTH:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpusha %bc\n\t"
|
||||
".chip 68k");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLUSH_SCOPE_LINE:
|
||||
/* Find the physical address of the first mapped page in the
|
||||
address range. */
|
||||
len += addr & 15;
|
||||
addr &= -16;
|
||||
if (!(paddr = virt_to_phys_060(addr))) {
|
||||
unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
|
||||
|
||||
if (len <= tmp)
|
||||
return 0;
|
||||
addr += tmp;
|
||||
len -= tmp;
|
||||
tmp = PAGE_SIZE;
|
||||
for (;;)
|
||||
{
|
||||
if ((paddr = virt_to_phys_060(addr)))
|
||||
break;
|
||||
if (len <= tmp)
|
||||
return 0;
|
||||
addr += tmp;
|
||||
len -= tmp;
|
||||
}
|
||||
}
|
||||
len = (len + 15) >> 4;
|
||||
i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
|
||||
while (len--)
|
||||
{
|
||||
switch (cache)
|
||||
{
|
||||
case FLUSH_CACHE_DATA:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpushl %%dc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
case FLUSH_CACHE_INSN:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpushl %%ic,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
default:
|
||||
case FLUSH_CACHE_BOTH:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpushl %%bc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
}
|
||||
if (!--i && len)
|
||||
{
|
||||
|
||||
/*
|
||||
* We just want to jump to the first cache line
|
||||
* in the next page.
|
||||
*/
|
||||
addr += PAGE_SIZE;
|
||||
addr &= PAGE_MASK;
|
||||
|
||||
i = PAGE_SIZE / 16;
|
||||
/* Recompute physical address when crossing a page
|
||||
boundary. */
|
||||
for (;;)
|
||||
{
|
||||
if ((paddr = virt_to_phys_060(addr)))
|
||||
break;
|
||||
if (len <= i)
|
||||
return 0;
|
||||
len -= i;
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
paddr += 16;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case FLUSH_SCOPE_PAGE:
|
||||
len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
|
||||
addr &= PAGE_MASK; /* Workaround for bug in some
|
||||
revisions of the 68060 */
|
||||
for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
|
||||
{
|
||||
if (!(paddr = virt_to_phys_060(addr)))
|
||||
continue;
|
||||
switch (cache)
|
||||
{
|
||||
case FLUSH_CACHE_DATA:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpushp %%dc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
case FLUSH_CACHE_INSN:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpushp %%ic,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
default:
|
||||
case FLUSH_CACHE_BOTH:
|
||||
__asm__ __volatile__ (".chip 68060\n\t"
|
||||
"cpushp %%bc,(%0)\n\t"
|
||||
".chip 68k"
|
||||
: : "a" (paddr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sys_cacheflush -- flush (part of) the processor cache. */
|
||||
asmlinkage int
|
||||
sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
|
||||
{
|
||||
struct vm_area_struct *vma;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||
|
||||
cache & ~FLUSH_CACHE_BOTH)
|
||||
goto out;
|
||||
|
||||
if (scope == FLUSH_SCOPE_ALL) {
|
||||
/* Only the superuser may explicitly flush the whole cache. */
|
||||
ret = -EPERM;
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
goto out;
|
||||
} else {
|
||||
/*
|
||||
* Verify that the specified address region actually belongs
|
||||
* to this process.
|
||||
*/
|
||||
vma = find_vma (current->mm, addr);
|
||||
ret = -EINVAL;
|
||||
/* Check for overflow. */
|
||||
if (addr + len < addr)
|
||||
goto out;
|
||||
if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (CPU_IS_020_OR_030) {
|
||||
if (scope == FLUSH_SCOPE_LINE && len < 256) {
|
||||
unsigned long cacr;
|
||||
__asm__ ("movec %%cacr, %0" : "=r" (cacr));
|
||||
if (cache & FLUSH_CACHE_INSN)
|
||||
cacr |= 4;
|
||||
if (cache & FLUSH_CACHE_DATA)
|
||||
cacr |= 0x400;
|
||||
len >>= 2;
|
||||
while (len--) {
|
||||
__asm__ __volatile__ ("movec %1, %%caar\n\t"
|
||||
"movec %0, %%cacr"
|
||||
: /* no outputs */
|
||||
: "r" (cacr), "r" (addr));
|
||||
addr += 4;
|
||||
}
|
||||
} else {
|
||||
/* Flush the whole cache, even if page granularity requested. */
|
||||
unsigned long cacr;
|
||||
__asm__ ("movec %%cacr, %0" : "=r" (cacr));
|
||||
if (cache & FLUSH_CACHE_INSN)
|
||||
cacr |= 8;
|
||||
if (cache & FLUSH_CACHE_DATA)
|
||||
cacr |= 0x800;
|
||||
__asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr));
|
||||
}
|
||||
ret = 0;
|
||||
goto out;
|
||||
} else {
|
||||
/*
|
||||
* 040 or 060: don't blindly trust 'scope', someone could
|
||||
* try to flush a few megs of memory.
|
||||
*/
|
||||
|
||||
if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE)
|
||||
scope=FLUSH_SCOPE_PAGE;
|
||||
if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL)
|
||||
scope=FLUSH_SCOPE_ALL;
|
||||
if (CPU_IS_040) {
|
||||
ret = cache_flush_040 (addr, scope, cache, len);
|
||||
} else if (CPU_IS_060) {
|
||||
ret = cache_flush_060 (addr, scope, cache, len);
|
||||
}
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage int sys_getpagesize(void)
|
||||
{
|
||||
return PAGE_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a system call from kernel instead of calling sys_execve so we
|
||||
* end up with proper pt_regs.
|
||||
*/
|
||||
int kernel_execve(const char *filename,
|
||||
const char *const argv[],
|
||||
const char *const envp[])
|
||||
{
|
||||
register long __res asm ("%d0") = __NR_execve;
|
||||
register long __a asm ("%d1") = (long)(filename);
|
||||
register long __b asm ("%d2") = (long)(argv);
|
||||
register long __c asm ("%d3") = (long)(envp);
|
||||
asm volatile ("trap #0" : "+d" (__res)
|
||||
: "d" (__a), "d" (__b), "d" (__c));
|
||||
return __res;
|
||||
}
|
||||
|
||||
asmlinkage unsigned long sys_get_thread_area(void)
|
||||
{
|
||||
return current_thread_info()->tp_value;
|
||||
}
|
||||
|
||||
asmlinkage int sys_set_thread_area(unsigned long tp)
|
||||
{
|
||||
current_thread_info()->tp_value = tp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This syscall gets its arguments in A0 (mem), D2 (oldval) and
|
||||
D1 (newval). */
|
||||
asmlinkage int
|
||||
sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
|
||||
unsigned long __user * mem)
|
||||
{
|
||||
/* This was borrowed from ARM's implementation. */
|
||||
for (;;) {
|
||||
struct mm_struct *mm = current->mm;
|
||||
pgd_t *pgd;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
spinlock_t *ptl;
|
||||
unsigned long mem_value;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
pgd = pgd_offset(mm, (unsigned long)mem);
|
||||
if (!pgd_present(*pgd))
|
||||
goto bad_access;
|
||||
pmd = pmd_offset(pgd, (unsigned long)mem);
|
||||
if (!pmd_present(*pmd))
|
||||
goto bad_access;
|
||||
pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl);
|
||||
if (!pte_present(*pte) || !pte_dirty(*pte)
|
||||
|| !pte_write(*pte)) {
|
||||
pte_unmap_unlock(pte, ptl);
|
||||
goto bad_access;
|
||||
}
|
||||
|
||||
mem_value = *mem;
|
||||
if (mem_value == oldval)
|
||||
*mem = newval;
|
||||
|
||||
pte_unmap_unlock(pte, ptl);
|
||||
up_read(&mm->mmap_sem);
|
||||
return mem_value;
|
||||
|
||||
bad_access:
|
||||
up_read(&mm->mmap_sem);
|
||||
/* This is not necessarily a bad access, we can get here if
|
||||
a memory we're trying to write to should be copied-on-write.
|
||||
Make the kernel do the necessary page stuff, then re-iterate.
|
||||
Simulate a write access fault to do that. */
|
||||
{
|
||||
/* The first argument of the function corresponds to
|
||||
D1, which is the first field of struct pt_regs. */
|
||||
struct pt_regs *fp = (struct pt_regs *)&newval;
|
||||
|
||||
/* '3' is an RMW flag. */
|
||||
if (do_page_fault(fp, (unsigned long)mem, 3))
|
||||
/* If the do_page_fault() failed, we don't
|
||||
have anything meaningful to return.
|
||||
There should be a SIGSEGV pending for
|
||||
the process. */
|
||||
return 0xdeadbeef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage int sys_atomic_barrier(void)
|
||||
{
|
||||
/* no code needed for uniprocs */
|
||||
return 0;
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* linux/arch/m68knommu/kernel/sys_m68k.c
|
||||
*
|
||||
* This file contains various random system calls that
|
||||
* have a non-standard calling sequence on the Linux/m68k
|
||||
* platform.
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/sem.h>
|
||||
#include <linux/msg.h>
|
||||
#include <linux/shm.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/ipc.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/cachectl.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/unistd.h>
|
||||
|
||||
/* sys_cacheflush -- flush (part of) the processor cache. */
|
||||
asmlinkage int
|
||||
sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
|
||||
{
|
||||
flush_cache_all();
|
||||
return(0);
|
||||
}
|
||||
|
||||
asmlinkage int sys_getpagesize(void)
|
||||
{
|
||||
return PAGE_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a system call from kernel instead of calling sys_execve so we
|
||||
* end up with proper pt_regs.
|
||||
*/
|
||||
int kernel_execve(const char *filename,
|
||||
const char *const argv[],
|
||||
const char *const envp[])
|
||||
{
|
||||
register long __res asm ("%d0") = __NR_execve;
|
||||
register long __a asm ("%d1") = (long)(filename);
|
||||
register long __b asm ("%d2") = (long)(argv);
|
||||
register long __c asm ("%d3") = (long)(envp);
|
||||
asm volatile ("trap #0" : "+d" (__res)
|
||||
: "d" (__a), "d" (__b), "d" (__c));
|
||||
return __res;
|
||||
}
|
||||
|
||||
asmlinkage unsigned long sys_get_thread_area(void)
|
||||
{
|
||||
return current_thread_info()->tp_value;
|
||||
}
|
||||
|
||||
asmlinkage int sys_set_thread_area(unsigned long tp)
|
||||
{
|
||||
current_thread_info()->tp_value = tp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This syscall gets its arguments in A0 (mem), D2 (oldval) and
|
||||
D1 (newval). */
|
||||
asmlinkage int
|
||||
sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
|
||||
unsigned long __user * mem)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
unsigned long mem_value;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
|
||||
mem_value = *mem;
|
||||
if (mem_value == oldval)
|
||||
*mem = newval;
|
||||
|
||||
up_read(&mm->mmap_sem);
|
||||
return mem_value;
|
||||
}
|
||||
|
||||
asmlinkage int sys_atomic_barrier(void)
|
||||
{
|
||||
/* no code needed for uniprocs */
|
||||
return 0;
|
||||
}
|
|
@ -11,7 +11,6 @@
|
|||
* Linux/m68k support by Hamish Macdonald
|
||||
*/
|
||||
|
||||
#include <linux/sys.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#ifndef CONFIG_MMU
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
|
||||
#
|
||||
# Makefile for m68k-specific library files..
|
||||
#
|
||||
|
||||
lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
|
||||
memcpy.o memset.o memmove.o
|
||||
|
||||
ifdef CONFIG_MMU
|
||||
include arch/m68k/lib/Makefile_mm
|
||||
lib-y += string.o uaccess.o checksum_mm.o
|
||||
else
|
||||
include arch/m68k/lib/Makefile_no
|
||||
lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o delay.o checksum_no.o
|
||||
endif
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#
|
||||
# Makefile for m68k-specific library files..
|
||||
#
|
||||
|
||||
lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
|
||||
checksum.o string.o uaccess.o
|
|
@ -1,7 +0,0 @@
|
|||
#
|
||||
# Makefile for m68knommu specific library files..
|
||||
#
|
||||
|
||||
lib-y := ashldi3.o ashrdi3.o lshrdi3.o \
|
||||
muldi3.o mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \
|
||||
checksum.o memcpy.o memmove.o memset.o delay.o
|
|
@ -1,5 +0,0 @@
|
|||
#ifdef CONFIG_MMU
|
||||
#include "checksum_mm.c"
|
||||
#else
|
||||
#include "checksum_no.c"
|
||||
#endif
|
|
@ -101,6 +101,7 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
|
|||
{
|
||||
return (__force __sum16)~do_csum(iph,ihl*4);
|
||||
}
|
||||
EXPORT_SYMBOL(ip_fast_csum);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -140,6 +141,7 @@ csum_partial_copy_from_user(const void __user *src, void *dst,
|
|||
memcpy(dst, (__force const void *)src, len);
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
EXPORT_SYMBOL(csum_partial_copy_from_user);
|
||||
|
||||
/*
|
||||
* copy from ds while checksumming, otherwise like csum_partial
|
||||
|
@ -151,3 +153,4 @@ csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
|
|||
memcpy(dst, src, len);
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
EXPORT_SYMBOL(csum_partial_copy_nocheck);
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
void *memcpy(void *to, const void *from, size_t n)
|
||||
{
|
||||
#ifdef CONFIG_COLDFIRE
|
||||
void *xto = to;
|
||||
size_t temp;
|
||||
size_t temp, temp1;
|
||||
|
||||
if (!n)
|
||||
return xto;
|
||||
if ((long) to & 1)
|
||||
{
|
||||
if ((long)to & 1) {
|
||||
char *cto = to;
|
||||
const char *cfrom = from;
|
||||
*cto++ = *cfrom++;
|
||||
|
@ -18,8 +22,7 @@ void * memcpy(void * to, const void * from, size_t n)
|
|||
from = cfrom;
|
||||
n--;
|
||||
}
|
||||
if (n > 2 && (long) to & 2)
|
||||
{
|
||||
if (n > 2 && (long)to & 2) {
|
||||
short *sto = to;
|
||||
const short *sfrom = from;
|
||||
*sto++ = *sfrom++;
|
||||
|
@ -28,35 +31,50 @@ void * memcpy(void * to, const void * from, size_t n)
|
|||
n -= 2;
|
||||
}
|
||||
temp = n >> 2;
|
||||
if (temp)
|
||||
{
|
||||
if (temp) {
|
||||
long *lto = to;
|
||||
const long *lfrom = from;
|
||||
#if defined(__mc68020__) || defined(__mc68030__) || \
|
||||
defined(__mc68040__) || defined(__mc68060__) || defined(__mcpu32__)
|
||||
asm volatile (
|
||||
" movel %2,%3\n"
|
||||
" andw #7,%3\n"
|
||||
" lsrl #3,%2\n"
|
||||
" negw %3\n"
|
||||
" jmp %%pc@(1f,%3:w:2)\n"
|
||||
"4: movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
"1: dbra %2,4b\n"
|
||||
" clrw %2\n"
|
||||
" subql #1,%2\n"
|
||||
" jpl 4b"
|
||||
: "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1)
|
||||
: "0" (lfrom), "1" (lto), "2" (temp));
|
||||
#else
|
||||
for (; temp; temp--)
|
||||
*lto++ = *lfrom++;
|
||||
#endif
|
||||
to = lto;
|
||||
from = lfrom;
|
||||
}
|
||||
if (n & 2)
|
||||
{
|
||||
if (n & 2) {
|
||||
short *sto = to;
|
||||
const short *sfrom = from;
|
||||
*sto++ = *sfrom++;
|
||||
to = sto;
|
||||
from = sfrom;
|
||||
}
|
||||
if (n & 1)
|
||||
{
|
||||
if (n & 1) {
|
||||
char *cto = to;
|
||||
const char *cfrom = from;
|
||||
*cto = *cfrom;
|
||||
}
|
||||
return xto;
|
||||
#else
|
||||
const char *c_from = from;
|
||||
char *c_to = to;
|
||||
while (n-- > 0)
|
||||
*c_to++ = *c_from++;
|
||||
return((void *) to);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
* for more details.
|
||||
*/
|
||||
|
||||
#define __IN_STRING_C
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
#include <linux/types.h>
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
void *memset(void *s, int c, size_t count)
|
||||
{
|
||||
|
@ -10,38 +17,59 @@ void * memset(void * s, int c, size_t count)
|
|||
c &= 0xff;
|
||||
c |= c << 8;
|
||||
c |= c << 16;
|
||||
if ((long) s & 1)
|
||||
{
|
||||
if ((long)s & 1) {
|
||||
char *cs = s;
|
||||
*cs++ = c;
|
||||
s = cs;
|
||||
count--;
|
||||
}
|
||||
if (count > 2 && (long) s & 2)
|
||||
{
|
||||
if (count > 2 && (long)s & 2) {
|
||||
short *ss = s;
|
||||
*ss++ = c;
|
||||
s = ss;
|
||||
count -= 2;
|
||||
}
|
||||
temp = count >> 2;
|
||||
if (temp)
|
||||
{
|
||||
if (temp) {
|
||||
long *ls = s;
|
||||
#if defined(__mc68020__) || defined(__mc68030__) || \
|
||||
defined(__mc68040__) || defined(__mc68060__) || defined(__mcpu32__)
|
||||
size_t temp1;
|
||||
asm volatile (
|
||||
" movel %1,%2\n"
|
||||
" andw #7,%2\n"
|
||||
" lsrl #3,%1\n"
|
||||
" negw %2\n"
|
||||
" jmp %%pc@(2f,%2:w:2)\n"
|
||||
"1: movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
"2: dbra %1,1b\n"
|
||||
" clrw %1\n"
|
||||
" subql #1,%1\n"
|
||||
" jpl 1b"
|
||||
: "=a" (ls), "=d" (temp), "=&d" (temp1)
|
||||
: "d" (c), "0" (ls), "1" (temp));
|
||||
#else
|
||||
for (; temp; temp--)
|
||||
*ls++ = c;
|
||||
#endif
|
||||
s = ls;
|
||||
}
|
||||
if (count & 2)
|
||||
{
|
||||
if (count & 2) {
|
||||
short *ss = s;
|
||||
*ss++ = c;
|
||||
s = ss;
|
||||
}
|
||||
if (count & 1)
|
||||
{
|
||||
if (count & 1) {
|
||||
char *cs = s;
|
||||
*cs = c;
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
EXPORT_SYMBOL(memset);
|
||||
|
|
|
@ -1,5 +1,98 @@
|
|||
#ifdef CONFIG_MMU
|
||||
#include "muldi3_mm.c"
|
||||
/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and
|
||||
gcc-2.7.2.3/longlong.h which is: */
|
||||
/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if defined(__mc68020__) || defined(__mc68030__) || \
|
||||
defined(__mc68040__) || defined(__mc68060__) || defined(__mcpu32__)
|
||||
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
__asm__ ("mulu%.l %3,%1:%0" \
|
||||
: "=d" ((USItype)(w0)), \
|
||||
"=d" ((USItype)(w1)) \
|
||||
: "%0" ((USItype)(u)), \
|
||||
"dmi" ((USItype)(v)))
|
||||
|
||||
#else
|
||||
#include "muldi3_no.c"
|
||||
|
||||
#define SI_TYPE_SIZE 32
|
||||
#define __BITS4 (SI_TYPE_SIZE / 4)
|
||||
#define __ll_B (1L << (SI_TYPE_SIZE / 2))
|
||||
#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
|
||||
#define __ll_highpart(t) ((USItype) (t) / __ll_B)
|
||||
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
do { \
|
||||
USItype __x0, __x1, __x2, __x3; \
|
||||
USItype __ul, __vl, __uh, __vh; \
|
||||
\
|
||||
__ul = __ll_lowpart (u); \
|
||||
__uh = __ll_highpart (u); \
|
||||
__vl = __ll_lowpart (v); \
|
||||
__vh = __ll_highpart (v); \
|
||||
\
|
||||
__x0 = (USItype) __ul * __vl; \
|
||||
__x1 = (USItype) __ul * __vh; \
|
||||
__x2 = (USItype) __uh * __vl; \
|
||||
__x3 = (USItype) __uh * __vh; \
|
||||
\
|
||||
__x1 += __ll_highpart (__x0);/* this can't give carry */ \
|
||||
__x1 += __x2; /* but this indeed can */ \
|
||||
if (__x1 < __x2) /* did we get it? */ \
|
||||
__x3 += __ll_B; /* yes, add it in the proper pos. */ \
|
||||
\
|
||||
(w1) = __x3 + __ll_highpart (__x1); \
|
||||
(w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define __umulsidi3(u, v) \
|
||||
({DIunion __w; \
|
||||
umul_ppmm (__w.s.high, __w.s.low, u, v); \
|
||||
__w.ll; })
|
||||
|
||||
typedef int SItype __attribute__ ((mode (SI)));
|
||||
typedef unsigned int USItype __attribute__ ((mode (SI)));
|
||||
typedef int DItype __attribute__ ((mode (DI)));
|
||||
typedef int word_type __attribute__ ((mode (__word__)));
|
||||
|
||||
struct DIstruct {SItype high, low;};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct DIstruct s;
|
||||
DItype ll;
|
||||
} DIunion;
|
||||
|
||||
DItype
|
||||
__muldi3 (DItype u, DItype v)
|
||||
{
|
||||
DIunion w;
|
||||
DIunion uu, vv;
|
||||
|
||||
uu.ll = u,
|
||||
vv.ll = v;
|
||||
|
||||
w.ll = __umulsidi3 (uu.s.low, vv.s.low);
|
||||
w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
|
||||
+ (USItype) uu.s.high * (USItype) vv.s.low);
|
||||
|
||||
return w.ll;
|
||||
}
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and
|
||||
gcc-2.7.2.3/longlong.h which is: */
|
||||
/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define BITS_PER_UNIT 8
|
||||
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
__asm__ ("mulu%.l %3,%1:%0" \
|
||||
: "=d" ((USItype)(w0)), \
|
||||
"=d" ((USItype)(w1)) \
|
||||
: "%0" ((USItype)(u)), \
|
||||
"dmi" ((USItype)(v)))
|
||||
|
||||
#define __umulsidi3(u, v) \
|
||||
({DIunion __w; \
|
||||
umul_ppmm (__w.s.high, __w.s.low, u, v); \
|
||||
__w.ll; })
|
||||
|
||||
typedef int SItype __attribute__ ((mode (SI)));
|
||||
typedef unsigned int USItype __attribute__ ((mode (SI)));
|
||||
typedef int DItype __attribute__ ((mode (DI)));
|
||||
typedef int word_type __attribute__ ((mode (__word__)));
|
||||
|
||||
struct DIstruct {SItype high, low;};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct DIstruct s;
|
||||
DItype ll;
|
||||
} DIunion;
|
||||
|
||||
DItype
|
||||
__muldi3 (DItype u, DItype v)
|
||||
{
|
||||
DIunion w;
|
||||
DIunion uu, vv;
|
||||
|
||||
uu.ll = u,
|
||||
vv.ll = v;
|
||||
|
||||
w.ll = __umulsidi3 (uu.s.low, vv.s.low);
|
||||
w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
|
||||
+ (USItype) uu.s.high * (USItype) vv.s.low);
|
||||
|
||||
return w.ll;
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and
|
||||
gcc-2.7.2.3/longlong.h which is: */
|
||||
/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define BITS_PER_UNIT 8
|
||||
#define SI_TYPE_SIZE 32
|
||||
|
||||
#define __BITS4 (SI_TYPE_SIZE / 4)
|
||||
#define __ll_B (1L << (SI_TYPE_SIZE / 2))
|
||||
#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
|
||||
#define __ll_highpart(t) ((USItype) (t) / __ll_B)
|
||||
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
do { \
|
||||
USItype __x0, __x1, __x2, __x3; \
|
||||
USItype __ul, __vl, __uh, __vh; \
|
||||
\
|
||||
__ul = __ll_lowpart (u); \
|
||||
__uh = __ll_highpart (u); \
|
||||
__vl = __ll_lowpart (v); \
|
||||
__vh = __ll_highpart (v); \
|
||||
\
|
||||
__x0 = (USItype) __ul * __vl; \
|
||||
__x1 = (USItype) __ul * __vh; \
|
||||
__x2 = (USItype) __uh * __vl; \
|
||||
__x3 = (USItype) __uh * __vh; \
|
||||
\
|
||||
__x1 += __ll_highpart (__x0);/* this can't give carry */ \
|
||||
__x1 += __x2; /* but this indeed can */ \
|
||||
if (__x1 < __x2) /* did we get it? */ \
|
||||
__x3 += __ll_B; /* yes, add it in the proper pos. */ \
|
||||
\
|
||||
(w1) = __x3 + __ll_highpart (__x1); \
|
||||
(w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
|
||||
} while (0)
|
||||
|
||||
#define __umulsidi3(u, v) \
|
||||
({DIunion __w; \
|
||||
umul_ppmm (__w.s.high, __w.s.low, u, v); \
|
||||
__w.ll; })
|
||||
|
||||
typedef int SItype __attribute__ ((mode (SI)));
|
||||
typedef unsigned int USItype __attribute__ ((mode (SI)));
|
||||
typedef int DItype __attribute__ ((mode (DI)));
|
||||
typedef int word_type __attribute__ ((mode (__word__)));
|
||||
|
||||
struct DIstruct {SItype high, low;};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct DIstruct s;
|
||||
DItype ll;
|
||||
} DIunion;
|
||||
|
||||
DItype
|
||||
__muldi3 (DItype u, DItype v)
|
||||
{
|
||||
DIunion w;
|
||||
DIunion uu, vv;
|
||||
|
||||
uu.ll = u,
|
||||
vv.ll = v;
|
||||
|
||||
w.ll = __umulsidi3 (uu.s.low, vv.s.low);
|
||||
w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
|
||||
+ (USItype) uu.s.high * (USItype) vv.s.low);
|
||||
|
||||
return w.ll;
|
||||
}
|
|
@ -20,226 +20,3 @@ char *strcat(char *dest, const char *src)
|
|||
return __kernel_strcpy(dest + __kernel_strlen(dest), src);
|
||||
}
|
||||
EXPORT_SYMBOL(strcat);
|
||||
|
||||
void *memset(void *s, int c, size_t count)
|
||||
{
|
||||
void *xs = s;
|
||||
size_t temp, temp1;
|
||||
|
||||
if (!count)
|
||||
return xs;
|
||||
c &= 0xff;
|
||||
c |= c << 8;
|
||||
c |= c << 16;
|
||||
if ((long)s & 1) {
|
||||
char *cs = s;
|
||||
*cs++ = c;
|
||||
s = cs;
|
||||
count--;
|
||||
}
|
||||
if (count > 2 && (long)s & 2) {
|
||||
short *ss = s;
|
||||
*ss++ = c;
|
||||
s = ss;
|
||||
count -= 2;
|
||||
}
|
||||
temp = count >> 2;
|
||||
if (temp) {
|
||||
long *ls = s;
|
||||
|
||||
asm volatile (
|
||||
" movel %1,%2\n"
|
||||
" andw #7,%2\n"
|
||||
" lsrl #3,%1\n"
|
||||
" negw %2\n"
|
||||
" jmp %%pc@(2f,%2:w:2)\n"
|
||||
"1: movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
" movel %3,%0@+\n"
|
||||
"2: dbra %1,1b\n"
|
||||
" clrw %1\n"
|
||||
" subql #1,%1\n"
|
||||
" jpl 1b"
|
||||
: "=a" (ls), "=d" (temp), "=&d" (temp1)
|
||||
: "d" (c), "0" (ls), "1" (temp));
|
||||
s = ls;
|
||||
}
|
||||
if (count & 2) {
|
||||
short *ss = s;
|
||||
*ss++ = c;
|
||||
s = ss;
|
||||
}
|
||||
if (count & 1) {
|
||||
char *cs = s;
|
||||
*cs = c;
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
EXPORT_SYMBOL(memset);
|
||||
|
||||
void *memcpy(void *to, const void *from, size_t n)
|
||||
{
|
||||
void *xto = to;
|
||||
size_t temp, temp1;
|
||||
|
||||
if (!n)
|
||||
return xto;
|
||||
if ((long)to & 1) {
|
||||
char *cto = to;
|
||||
const char *cfrom = from;
|
||||
*cto++ = *cfrom++;
|
||||
to = cto;
|
||||
from = cfrom;
|
||||
n--;
|
||||
}
|
||||
if (n > 2 && (long)to & 2) {
|
||||
short *sto = to;
|
||||
const short *sfrom = from;
|
||||
*sto++ = *sfrom++;
|
||||
to = sto;
|
||||
from = sfrom;
|
||||
n -= 2;
|
||||
}
|
||||
temp = n >> 2;
|
||||
if (temp) {
|
||||
long *lto = to;
|
||||
const long *lfrom = from;
|
||||
|
||||
asm volatile (
|
||||
" movel %2,%3\n"
|
||||
" andw #7,%3\n"
|
||||
" lsrl #3,%2\n"
|
||||
" negw %3\n"
|
||||
" jmp %%pc@(1f,%3:w:2)\n"
|
||||
"4: movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
" movel %0@+,%1@+\n"
|
||||
"1: dbra %2,4b\n"
|
||||
" clrw %2\n"
|
||||
" subql #1,%2\n"
|
||||
" jpl 4b"
|
||||
: "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1)
|
||||
: "0" (lfrom), "1" (lto), "2" (temp));
|
||||
to = lto;
|
||||
from = lfrom;
|
||||
}
|
||||
if (n & 2) {
|
||||
short *sto = to;
|
||||
const short *sfrom = from;
|
||||
*sto++ = *sfrom++;
|
||||
to = sto;
|
||||
from = sfrom;
|
||||
}
|
||||
if (n & 1) {
|
||||
char *cto = to;
|
||||
const char *cfrom = from;
|
||||
*cto = *cfrom;
|
||||
}
|
||||
return xto;
|
||||
}
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t n)
|
||||
{
|
||||
void *xdest = dest;
|
||||
size_t temp;
|
||||
|
||||
if (!n)
|
||||
return xdest;
|
||||
|
||||
if (dest < src) {
|
||||
if ((long)dest & 1) {
|
||||
char *cdest = dest;
|
||||
const char *csrc = src;
|
||||
*cdest++ = *csrc++;
|
||||
dest = cdest;
|
||||
src = csrc;
|
||||
n--;
|
||||
}
|
||||
if (n > 2 && (long)dest & 2) {
|
||||
short *sdest = dest;
|
||||
const short *ssrc = src;
|
||||
*sdest++ = *ssrc++;
|
||||
dest = sdest;
|
||||
src = ssrc;
|
||||
n -= 2;
|
||||
}
|
||||
temp = n >> 2;
|
||||
if (temp) {
|
||||
long *ldest = dest;
|
||||
const long *lsrc = src;
|
||||
temp--;
|
||||
do
|
||||
*ldest++ = *lsrc++;
|
||||
while (temp--);
|
||||
dest = ldest;
|
||||
src = lsrc;
|
||||
}
|
||||
if (n & 2) {
|
||||
short *sdest = dest;
|
||||
const short *ssrc = src;
|
||||
*sdest++ = *ssrc++;
|
||||
dest = sdest;
|
||||
src = ssrc;
|
||||
}
|
||||
if (n & 1) {
|
||||
char *cdest = dest;
|
||||
const char *csrc = src;
|
||||
*cdest = *csrc;
|
||||
}
|
||||
} else {
|
||||
dest = (char *)dest + n;
|
||||
src = (const char *)src + n;
|
||||
if ((long)dest & 1) {
|
||||
char *cdest = dest;
|
||||
const char *csrc = src;
|
||||
*--cdest = *--csrc;
|
||||
dest = cdest;
|
||||
src = csrc;
|
||||
n--;
|
||||
}
|
||||
if (n > 2 && (long)dest & 2) {
|
||||
short *sdest = dest;
|
||||
const short *ssrc = src;
|
||||
*--sdest = *--ssrc;
|
||||
dest = sdest;
|
||||
src = ssrc;
|
||||
n -= 2;
|
||||
}
|
||||
temp = n >> 2;
|
||||
if (temp) {
|
||||
long *ldest = dest;
|
||||
const long *lsrc = src;
|
||||
temp--;
|
||||
do
|
||||
*--ldest = *--lsrc;
|
||||
while (temp--);
|
||||
dest = ldest;
|
||||
src = lsrc;
|
||||
}
|
||||
if (n & 2) {
|
||||
short *sdest = dest;
|
||||
const short *ssrc = src;
|
||||
*--sdest = *--ssrc;
|
||||
dest = sdest;
|
||||
src = ssrc;
|
||||
}
|
||||
if (n & 1) {
|
||||
char *cdest = dest;
|
||||
const char *csrc = src;
|
||||
*--cdest = *--csrc;
|
||||
}
|
||||
}
|
||||
return xdest;
|
||||
}
|
||||
EXPORT_SYMBOL(memmove);
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
ifdef CONFIG_MMU
|
||||
include arch/m68k/mm/Makefile_mm
|
||||
else
|
||||
include arch/m68k/mm/Makefile_no
|
||||
endif
|
||||
#
|
||||
# Makefile for the linux m68k-specific parts of the memory manager.
|
||||
#
|
||||
|
||||
obj-y := init.o
|
||||
|
||||
obj-$(CONFIG_MMU) += cache.o fault.o hwtest.o
|
||||
obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o
|
||||
obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
#
|
||||
# Makefile for the linux m68k-specific parts of the memory manager.
|
||||
#
|
||||
|
||||
obj-y := cache.o init.o fault.o hwtest.o
|
||||
|
||||
obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o
|
||||
obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o
|
|
@ -1,5 +0,0 @@
|
|||
#
|
||||
# Makefile for the linux m68knommu specific parts of the memory manager.
|
||||
#
|
||||
|
||||
obj-y += init.o kmap.o
|
|
@ -38,28 +38,10 @@
|
|||
#include <asm/system.h>
|
||||
#include <asm/machdep.h>
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
extern void die_if_kernel(char *,struct pt_regs *,long);
|
||||
extern void free_initmem(void);
|
||||
|
||||
/*
|
||||
* BAD_PAGE is the page that is used for page faults when linux
|
||||
* is out-of-memory. Older versions of linux just did a
|
||||
* do_exit(), but using this instead means there is less risk
|
||||
* for a process dying in kernel mode, possibly leaving a inode
|
||||
* unused etc..
|
||||
*
|
||||
* BAD_PAGETABLE is the accompanying page-table: it is initialized
|
||||
* to point to BAD_PAGE entries.
|
||||
*
|
||||
* ZERO_PAGE is a special page that is used for zero-initialized
|
||||
* data and COW.
|
||||
*/
|
||||
static unsigned long empty_bad_page_table;
|
||||
|
||||
static unsigned long empty_bad_page;
|
||||
|
||||
unsigned long empty_zero_page;
|
||||
|
||||
extern unsigned long memory_start;
|
||||
|
@ -77,22 +59,9 @@ void __init paging_init(void)
|
|||
* Make sure start_mem is page aligned, otherwise bootmem and
|
||||
* page_alloc get different views of the world.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
unsigned long start_mem = PAGE_ALIGN(memory_start);
|
||||
#endif
|
||||
unsigned long end_mem = memory_end & PAGE_MASK;
|
||||
unsigned long zones_size[MAX_NR_ZONES] = {0, };
|
||||
|
||||
#ifdef DEBUG
|
||||
printk (KERN_DEBUG "start_mem is %#lx\nvirtual_end is %#lx\n",
|
||||
start_mem, end_mem);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize the bad page table and bad page to point
|
||||
* to a couple of allocated pages.
|
||||
*/
|
||||
empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
|
||||
empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
|
||||
empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
|
||||
memset((void *)empty_zero_page, 0, PAGE_SIZE);
|
||||
|
||||
|
@ -101,20 +70,9 @@ void __init paging_init(void)
|
|||
*/
|
||||
set_fs (USER_DS);
|
||||
|
||||
#ifdef DEBUG
|
||||
printk (KERN_DEBUG "before free_area_init\n");
|
||||
|
||||
printk (KERN_DEBUG "free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
|
||||
start_mem, end_mem);
|
||||
#endif
|
||||
|
||||
{
|
||||
unsigned long zones_size[MAX_NR_ZONES] = {0, };
|
||||
|
||||
zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
|
||||
free_area_init(zones_size);
|
||||
}
|
||||
}
|
||||
|
||||
void __init mem_init(void)
|
||||
{
|
||||
|
@ -166,8 +124,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
free_initmem()
|
||||
void free_initmem(void)
|
||||
{
|
||||
#ifdef CONFIG_RAMKERNEL
|
||||
unsigned long addr;
|
||||
|
|
|
@ -1,5 +1,367 @@
|
|||
#ifdef CONFIG_MMU
|
||||
#include "kmap_mm.c"
|
||||
/*
|
||||
* linux/arch/m68k/mm/kmap.c
|
||||
*
|
||||
* Copyright (C) 1997 Roman Hodek
|
||||
*
|
||||
* 10/01/99 cleaned up the code and changing to the same interface
|
||||
* used by other architectures /Roman Zippel
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#define PTRTREESIZE (256*1024)
|
||||
|
||||
/*
|
||||
* For 040/060 we can use the virtual memory area like other architectures,
|
||||
* but for 020/030 we want to use early termination page descriptor and we
|
||||
* can't mix this with normal page descriptors, so we have to copy that code
|
||||
* (mm/vmalloc.c) and return appriorate aligned addresses.
|
||||
*/
|
||||
|
||||
#ifdef CPU_M68040_OR_M68060_ONLY
|
||||
|
||||
#define IO_SIZE PAGE_SIZE
|
||||
|
||||
static inline struct vm_struct *get_io_area(unsigned long size)
|
||||
{
|
||||
return get_vm_area(size, VM_IOREMAP);
|
||||
}
|
||||
|
||||
|
||||
static inline void free_io_area(void *addr)
|
||||
{
|
||||
vfree((void *)(PAGE_MASK & (unsigned long)addr));
|
||||
}
|
||||
|
||||
#else
|
||||
#include "kmap_no.c"
|
||||
|
||||
#define IO_SIZE (256*1024)
|
||||
|
||||
static struct vm_struct *iolist;
|
||||
|
||||
static struct vm_struct *get_io_area(unsigned long size)
|
||||
{
|
||||
unsigned long addr;
|
||||
struct vm_struct **p, *tmp, *area;
|
||||
|
||||
area = kmalloc(sizeof(*area), GFP_KERNEL);
|
||||
if (!area)
|
||||
return NULL;
|
||||
addr = KMAP_START;
|
||||
for (p = &iolist; (tmp = *p) ; p = &tmp->next) {
|
||||
if (size + addr < (unsigned long)tmp->addr)
|
||||
break;
|
||||
if (addr > KMAP_END-size) {
|
||||
kfree(area);
|
||||
return NULL;
|
||||
}
|
||||
addr = tmp->size + (unsigned long)tmp->addr;
|
||||
}
|
||||
area->addr = (void *)addr;
|
||||
area->size = size + IO_SIZE;
|
||||
area->next = *p;
|
||||
*p = area;
|
||||
return area;
|
||||
}
|
||||
|
||||
static inline void free_io_area(void *addr)
|
||||
{
|
||||
struct vm_struct **p, *tmp;
|
||||
|
||||
if (!addr)
|
||||
return;
|
||||
addr = (void *)((unsigned long)addr & -IO_SIZE);
|
||||
for (p = &iolist ; (tmp = *p) ; p = &tmp->next) {
|
||||
if (tmp->addr == addr) {
|
||||
*p = tmp->next;
|
||||
__iounmap(tmp->addr, tmp->size);
|
||||
kfree(tmp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Map some physical address range into the kernel address space.
|
||||
*/
|
||||
/* Rewritten by Andreas Schwab to remove all races. */
|
||||
|
||||
void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
|
||||
{
|
||||
struct vm_struct *area;
|
||||
unsigned long virtaddr, retaddr;
|
||||
long offset;
|
||||
pgd_t *pgd_dir;
|
||||
pmd_t *pmd_dir;
|
||||
pte_t *pte_dir;
|
||||
|
||||
/*
|
||||
* Don't allow mappings that wrap..
|
||||
*/
|
||||
if (!size || physaddr > (unsigned long)(-size))
|
||||
return NULL;
|
||||
|
||||
#ifdef CONFIG_AMIGA
|
||||
if (MACH_IS_AMIGA) {
|
||||
if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000)
|
||||
&& (cacheflag == IOMAP_NOCACHE_SER))
|
||||
return (void __iomem *)physaddr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag);
|
||||
#endif
|
||||
/*
|
||||
* Mappings have to be aligned
|
||||
*/
|
||||
offset = physaddr & (IO_SIZE - 1);
|
||||
physaddr &= -IO_SIZE;
|
||||
size = (size + offset + IO_SIZE - 1) & -IO_SIZE;
|
||||
|
||||
/*
|
||||
* Ok, go for it..
|
||||
*/
|
||||
area = get_io_area(size);
|
||||
if (!area)
|
||||
return NULL;
|
||||
|
||||
virtaddr = (unsigned long)area->addr;
|
||||
retaddr = virtaddr + offset;
|
||||
#ifdef DEBUG
|
||||
printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* add cache and table flags to physical address
|
||||
*/
|
||||
if (CPU_IS_040_OR_060) {
|
||||
physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 |
|
||||
_PAGE_ACCESSED | _PAGE_DIRTY);
|
||||
switch (cacheflag) {
|
||||
case IOMAP_FULL_CACHING:
|
||||
physaddr |= _PAGE_CACHE040;
|
||||
break;
|
||||
case IOMAP_NOCACHE_SER:
|
||||
default:
|
||||
physaddr |= _PAGE_NOCACHE_S;
|
||||
break;
|
||||
case IOMAP_NOCACHE_NONSER:
|
||||
physaddr |= _PAGE_NOCACHE;
|
||||
break;
|
||||
case IOMAP_WRITETHROUGH:
|
||||
physaddr |= _PAGE_CACHE040W;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
|
||||
switch (cacheflag) {
|
||||
case IOMAP_NOCACHE_SER:
|
||||
case IOMAP_NOCACHE_NONSER:
|
||||
default:
|
||||
physaddr |= _PAGE_NOCACHE030;
|
||||
break;
|
||||
case IOMAP_FULL_CACHING:
|
||||
case IOMAP_WRITETHROUGH:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while ((long)size > 0) {
|
||||
#ifdef DEBUG
|
||||
if (!(virtaddr & (PTRTREESIZE-1)))
|
||||
printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr);
|
||||
#endif
|
||||
pgd_dir = pgd_offset_k(virtaddr);
|
||||
pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr);
|
||||
if (!pmd_dir) {
|
||||
printk("ioremap: no mem for pmd_dir\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (CPU_IS_020_OR_030) {
|
||||
pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr;
|
||||
physaddr += PTRTREESIZE;
|
||||
virtaddr += PTRTREESIZE;
|
||||
size -= PTRTREESIZE;
|
||||
} else {
|
||||
pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);
|
||||
if (!pte_dir) {
|
||||
printk("ioremap: no mem for pte_dir\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pte_val(*pte_dir) = physaddr;
|
||||
virtaddr += PAGE_SIZE;
|
||||
physaddr += PAGE_SIZE;
|
||||
size -= PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printk("\n");
|
||||
#endif
|
||||
flush_tlb_all();
|
||||
|
||||
return (void __iomem *)retaddr;
|
||||
}
|
||||
EXPORT_SYMBOL(__ioremap);
|
||||
|
||||
/*
|
||||
* Unmap a ioremap()ed region again
|
||||
*/
|
||||
void iounmap(void __iomem *addr)
|
||||
{
|
||||
#ifdef CONFIG_AMIGA
|
||||
if ((!MACH_IS_AMIGA) ||
|
||||
(((unsigned long)addr < 0x40000000) ||
|
||||
((unsigned long)addr > 0x60000000)))
|
||||
free_io_area((__force void *)addr);
|
||||
#else
|
||||
free_io_area((__force void *)addr);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
|
||||
/*
|
||||
* __iounmap unmaps nearly everything, so be careful
|
||||
* it doesn't free currently pointer/page tables anymore but it
|
||||
* wans't used anyway and might be added later.
|
||||
*/
|
||||
void __iounmap(void *addr, unsigned long size)
|
||||
{
|
||||
unsigned long virtaddr = (unsigned long)addr;
|
||||
pgd_t *pgd_dir;
|
||||
pmd_t *pmd_dir;
|
||||
pte_t *pte_dir;
|
||||
|
||||
while ((long)size > 0) {
|
||||
pgd_dir = pgd_offset_k(virtaddr);
|
||||
if (pgd_bad(*pgd_dir)) {
|
||||
printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
|
||||
pgd_clear(pgd_dir);
|
||||
return;
|
||||
}
|
||||
pmd_dir = pmd_offset(pgd_dir, virtaddr);
|
||||
|
||||
if (CPU_IS_020_OR_030) {
|
||||
int pmd_off = (virtaddr/PTRTREESIZE) & 15;
|
||||
int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK;
|
||||
|
||||
if (pmd_type == _PAGE_PRESENT) {
|
||||
pmd_dir->pmd[pmd_off] = 0;
|
||||
virtaddr += PTRTREESIZE;
|
||||
size -= PTRTREESIZE;
|
||||
continue;
|
||||
} else if (pmd_type == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pmd_bad(*pmd_dir)) {
|
||||
printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir));
|
||||
pmd_clear(pmd_dir);
|
||||
return;
|
||||
}
|
||||
pte_dir = pte_offset_kernel(pmd_dir, virtaddr);
|
||||
|
||||
pte_val(*pte_dir) = 0;
|
||||
virtaddr += PAGE_SIZE;
|
||||
size -= PAGE_SIZE;
|
||||
}
|
||||
|
||||
flush_tlb_all();
|
||||
}
|
||||
|
||||
/*
|
||||
* Set new cache mode for some kernel address space.
|
||||
* The caller must push data for that range itself, if such data may already
|
||||
* be in the cache.
|
||||
*/
|
||||
void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
|
||||
{
|
||||
unsigned long virtaddr = (unsigned long)addr;
|
||||
pgd_t *pgd_dir;
|
||||
pmd_t *pmd_dir;
|
||||
pte_t *pte_dir;
|
||||
|
||||
if (CPU_IS_040_OR_060) {
|
||||
switch (cmode) {
|
||||
case IOMAP_FULL_CACHING:
|
||||
cmode = _PAGE_CACHE040;
|
||||
break;
|
||||
case IOMAP_NOCACHE_SER:
|
||||
default:
|
||||
cmode = _PAGE_NOCACHE_S;
|
||||
break;
|
||||
case IOMAP_NOCACHE_NONSER:
|
||||
cmode = _PAGE_NOCACHE;
|
||||
break;
|
||||
case IOMAP_WRITETHROUGH:
|
||||
cmode = _PAGE_CACHE040W;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (cmode) {
|
||||
case IOMAP_NOCACHE_SER:
|
||||
case IOMAP_NOCACHE_NONSER:
|
||||
default:
|
||||
cmode = _PAGE_NOCACHE030;
|
||||
break;
|
||||
case IOMAP_FULL_CACHING:
|
||||
case IOMAP_WRITETHROUGH:
|
||||
cmode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while ((long)size > 0) {
|
||||
pgd_dir = pgd_offset_k(virtaddr);
|
||||
if (pgd_bad(*pgd_dir)) {
|
||||
printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
|
||||
pgd_clear(pgd_dir);
|
||||
return;
|
||||
}
|
||||
pmd_dir = pmd_offset(pgd_dir, virtaddr);
|
||||
|
||||
if (CPU_IS_020_OR_030) {
|
||||
int pmd_off = (virtaddr/PTRTREESIZE) & 15;
|
||||
|
||||
if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {
|
||||
pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] &
|
||||
_CACHEMASK040) | cmode;
|
||||
virtaddr += PTRTREESIZE;
|
||||
size -= PTRTREESIZE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (pmd_bad(*pmd_dir)) {
|
||||
printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir));
|
||||
pmd_clear(pmd_dir);
|
||||
return;
|
||||
}
|
||||
pte_dir = pte_offset_kernel(pmd_dir, virtaddr);
|
||||
|
||||
pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode;
|
||||
virtaddr += PAGE_SIZE;
|
||||
size -= PAGE_SIZE;
|
||||
}
|
||||
|
||||
flush_tlb_all();
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_set_cachemode);
|
||||
|
|
|
@ -1,367 +0,0 @@
|
|||
/*
|
||||
* linux/arch/m68k/mm/kmap.c
|
||||
*
|
||||
* Copyright (C) 1997 Roman Hodek
|
||||
*
|
||||
* 10/01/99 cleaned up the code and changing to the same interface
|
||||
* used by other architectures /Roman Zippel
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#define PTRTREESIZE (256*1024)
|
||||
|
||||
/*
|
||||
* For 040/060 we can use the virtual memory area like other architectures,
|
||||
* but for 020/030 we want to use early termination page descriptor and we
|
||||
* can't mix this with normal page descriptors, so we have to copy that code
|
||||
* (mm/vmalloc.c) and return appriorate aligned addresses.
|
||||
*/
|
||||
|
||||
#ifdef CPU_M68040_OR_M68060_ONLY
|
||||
|
||||
#define IO_SIZE PAGE_SIZE
|
||||
|
||||
static inline struct vm_struct *get_io_area(unsigned long size)
|
||||
{
|
||||
return get_vm_area(size, VM_IOREMAP);
|
||||
}
|
||||
|
||||
|
||||
static inline void free_io_area(void *addr)
|
||||
{
|
||||
vfree((void *)(PAGE_MASK & (unsigned long)addr));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define IO_SIZE (256*1024)
|
||||
|
||||
static struct vm_struct *iolist;
|
||||
|
||||
static struct vm_struct *get_io_area(unsigned long size)
|
||||
{
|
||||
unsigned long addr;
|
||||
struct vm_struct **p, *tmp, *area;
|
||||
|
||||
area = kmalloc(sizeof(*area), GFP_KERNEL);
|
||||
if (!area)
|
||||
return NULL;
|
||||
addr = KMAP_START;
|
||||
for (p = &iolist; (tmp = *p) ; p = &tmp->next) {
|
||||
if (size + addr < (unsigned long)tmp->addr)
|
||||
break;
|
||||
if (addr > KMAP_END-size) {
|
||||
kfree(area);
|
||||
return NULL;
|
||||
}
|
||||
addr = tmp->size + (unsigned long)tmp->addr;
|
||||
}
|
||||
area->addr = (void *)addr;
|
||||
area->size = size + IO_SIZE;
|
||||
area->next = *p;
|
||||
*p = area;
|
||||
return area;
|
||||
}
|
||||
|
||||
static inline void free_io_area(void *addr)
|
||||
{
|
||||
struct vm_struct **p, *tmp;
|
||||
|
||||
if (!addr)
|
||||
return;
|
||||
addr = (void *)((unsigned long)addr & -IO_SIZE);
|
||||
for (p = &iolist ; (tmp = *p) ; p = &tmp->next) {
|
||||
if (tmp->addr == addr) {
|
||||
*p = tmp->next;
|
||||
__iounmap(tmp->addr, tmp->size);
|
||||
kfree(tmp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Map some physical address range into the kernel address space.
|
||||
*/
|
||||
/* Rewritten by Andreas Schwab to remove all races. */
|
||||
|
||||
void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
|
||||
{
|
||||
struct vm_struct *area;
|
||||
unsigned long virtaddr, retaddr;
|
||||
long offset;
|
||||
pgd_t *pgd_dir;
|
||||
pmd_t *pmd_dir;
|
||||
pte_t *pte_dir;
|
||||
|
||||
/*
|
||||
* Don't allow mappings that wrap..
|
||||
*/
|
||||
if (!size || physaddr > (unsigned long)(-size))
|
||||
return NULL;
|
||||
|
||||
#ifdef CONFIG_AMIGA
|
||||
if (MACH_IS_AMIGA) {
|
||||
if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000)
|
||||
&& (cacheflag == IOMAP_NOCACHE_SER))
|
||||
return (void __iomem *)physaddr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag);
|
||||
#endif
|
||||
/*
|
||||
* Mappings have to be aligned
|
||||
*/
|
||||
offset = physaddr & (IO_SIZE - 1);
|
||||
physaddr &= -IO_SIZE;
|
||||
size = (size + offset + IO_SIZE - 1) & -IO_SIZE;
|
||||
|
||||
/*
|
||||
* Ok, go for it..
|
||||
*/
|
||||
area = get_io_area(size);
|
||||
if (!area)
|
||||
return NULL;
|
||||
|
||||
virtaddr = (unsigned long)area->addr;
|
||||
retaddr = virtaddr + offset;
|
||||
#ifdef DEBUG
|
||||
printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* add cache and table flags to physical address
|
||||
*/
|
||||
if (CPU_IS_040_OR_060) {
|
||||
physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 |
|
||||
_PAGE_ACCESSED | _PAGE_DIRTY);
|
||||
switch (cacheflag) {
|
||||
case IOMAP_FULL_CACHING:
|
||||
physaddr |= _PAGE_CACHE040;
|
||||
break;
|
||||
case IOMAP_NOCACHE_SER:
|
||||
default:
|
||||
physaddr |= _PAGE_NOCACHE_S;
|
||||
break;
|
||||
case IOMAP_NOCACHE_NONSER:
|
||||
physaddr |= _PAGE_NOCACHE;
|
||||
break;
|
||||
case IOMAP_WRITETHROUGH:
|
||||
physaddr |= _PAGE_CACHE040W;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
|
||||
switch (cacheflag) {
|
||||
case IOMAP_NOCACHE_SER:
|
||||
case IOMAP_NOCACHE_NONSER:
|
||||
default:
|
||||
physaddr |= _PAGE_NOCACHE030;
|
||||
break;
|
||||
case IOMAP_FULL_CACHING:
|
||||
case IOMAP_WRITETHROUGH:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while ((long)size > 0) {
|
||||
#ifdef DEBUG
|
||||
if (!(virtaddr & (PTRTREESIZE-1)))
|
||||
printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr);
|
||||
#endif
|
||||
pgd_dir = pgd_offset_k(virtaddr);
|
||||
pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr);
|
||||
if (!pmd_dir) {
|
||||
printk("ioremap: no mem for pmd_dir\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (CPU_IS_020_OR_030) {
|
||||
pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr;
|
||||
physaddr += PTRTREESIZE;
|
||||
virtaddr += PTRTREESIZE;
|
||||
size -= PTRTREESIZE;
|
||||
} else {
|
||||
pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);
|
||||
if (!pte_dir) {
|
||||
printk("ioremap: no mem for pte_dir\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pte_val(*pte_dir) = physaddr;
|
||||
virtaddr += PAGE_SIZE;
|
||||
physaddr += PAGE_SIZE;
|
||||
size -= PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printk("\n");
|
||||
#endif
|
||||
flush_tlb_all();
|
||||
|
||||
return (void __iomem *)retaddr;
|
||||
}
|
||||
EXPORT_SYMBOL(__ioremap);
|
||||
|
||||
/*
|
||||
* Unmap a ioremap()ed region again
|
||||
*/
|
||||
void iounmap(void __iomem *addr)
|
||||
{
|
||||
#ifdef CONFIG_AMIGA
|
||||
if ((!MACH_IS_AMIGA) ||
|
||||
(((unsigned long)addr < 0x40000000) ||
|
||||
((unsigned long)addr > 0x60000000)))
|
||||
free_io_area((__force void *)addr);
|
||||
#else
|
||||
free_io_area((__force void *)addr);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
|
||||
/*
|
||||
* __iounmap unmaps nearly everything, so be careful
|
||||
* it doesn't free currently pointer/page tables anymore but it
|
||||
* wans't used anyway and might be added later.
|
||||
*/
|
||||
void __iounmap(void *addr, unsigned long size)
|
||||
{
|
||||
unsigned long virtaddr = (unsigned long)addr;
|
||||
pgd_t *pgd_dir;
|
||||
pmd_t *pmd_dir;
|
||||
pte_t *pte_dir;
|
||||
|
||||
while ((long)size > 0) {
|
||||
pgd_dir = pgd_offset_k(virtaddr);
|
||||
if (pgd_bad(*pgd_dir)) {
|
||||
printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
|
||||
pgd_clear(pgd_dir);
|
||||
return;
|
||||
}
|
||||
pmd_dir = pmd_offset(pgd_dir, virtaddr);
|
||||
|
||||
if (CPU_IS_020_OR_030) {
|
||||
int pmd_off = (virtaddr/PTRTREESIZE) & 15;
|
||||
int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK;
|
||||
|
||||
if (pmd_type == _PAGE_PRESENT) {
|
||||
pmd_dir->pmd[pmd_off] = 0;
|
||||
virtaddr += PTRTREESIZE;
|
||||
size -= PTRTREESIZE;
|
||||
continue;
|
||||
} else if (pmd_type == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pmd_bad(*pmd_dir)) {
|
||||
printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir));
|
||||
pmd_clear(pmd_dir);
|
||||
return;
|
||||
}
|
||||
pte_dir = pte_offset_kernel(pmd_dir, virtaddr);
|
||||
|
||||
pte_val(*pte_dir) = 0;
|
||||
virtaddr += PAGE_SIZE;
|
||||
size -= PAGE_SIZE;
|
||||
}
|
||||
|
||||
flush_tlb_all();
|
||||
}
|
||||
|
||||
/*
|
||||
* Set new cache mode for some kernel address space.
|
||||
* The caller must push data for that range itself, if such data may already
|
||||
* be in the cache.
|
||||
*/
|
||||
void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
|
||||
{
|
||||
unsigned long virtaddr = (unsigned long)addr;
|
||||
pgd_t *pgd_dir;
|
||||
pmd_t *pmd_dir;
|
||||
pte_t *pte_dir;
|
||||
|
||||
if (CPU_IS_040_OR_060) {
|
||||
switch (cmode) {
|
||||
case IOMAP_FULL_CACHING:
|
||||
cmode = _PAGE_CACHE040;
|
||||
break;
|
||||
case IOMAP_NOCACHE_SER:
|
||||
default:
|
||||
cmode = _PAGE_NOCACHE_S;
|
||||
break;
|
||||
case IOMAP_NOCACHE_NONSER:
|
||||
cmode = _PAGE_NOCACHE;
|
||||
break;
|
||||
case IOMAP_WRITETHROUGH:
|
||||
cmode = _PAGE_CACHE040W;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (cmode) {
|
||||
case IOMAP_NOCACHE_SER:
|
||||
case IOMAP_NOCACHE_NONSER:
|
||||
default:
|
||||
cmode = _PAGE_NOCACHE030;
|
||||
break;
|
||||
case IOMAP_FULL_CACHING:
|
||||
case IOMAP_WRITETHROUGH:
|
||||
cmode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while ((long)size > 0) {
|
||||
pgd_dir = pgd_offset_k(virtaddr);
|
||||
if (pgd_bad(*pgd_dir)) {
|
||||
printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
|
||||
pgd_clear(pgd_dir);
|
||||
return;
|
||||
}
|
||||
pmd_dir = pmd_offset(pgd_dir, virtaddr);
|
||||
|
||||
if (CPU_IS_020_OR_030) {
|
||||
int pmd_off = (virtaddr/PTRTREESIZE) & 15;
|
||||
|
||||
if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {
|
||||
pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] &
|
||||
_CACHEMASK040) | cmode;
|
||||
virtaddr += PTRTREESIZE;
|
||||
size -= PTRTREESIZE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (pmd_bad(*pmd_dir)) {
|
||||
printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir));
|
||||
pmd_clear(pmd_dir);
|
||||
return;
|
||||
}
|
||||
pte_dir = pte_offset_kernel(pmd_dir, virtaddr);
|
||||
|
||||
pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode;
|
||||
virtaddr += PAGE_SIZE;
|
||||
size -= PAGE_SIZE;
|
||||
}
|
||||
|
||||
flush_tlb_all();
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_set_cachemode);
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* linux/arch/m68knommu/mm/kmap.c
|
||||
*
|
||||
* Copyright (C) 2000 Lineo, <davidm@snapgear.com>
|
||||
* Copyright (C) 2000-2002 David McCullough <davidm@snapgear.com>
|
||||
*/
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
/*
|
||||
* Map some physical address range into the kernel address space.
|
||||
*/
|
||||
void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
|
||||
{
|
||||
return (void *)physaddr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unmap a ioremap()ed region again.
|
||||
*/
|
||||
void iounmap(void *addr)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Set new cache mode for some kernel address space.
|
||||
* The caller must push data for that range itself, if such data may already
|
||||
* be in the cache.
|
||||
*/
|
||||
void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
|
||||
{
|
||||
}
|
|
@ -10,7 +10,6 @@
|
|||
* Linux/m68k support by Hamish Macdonald
|
||||
*/
|
||||
|
||||
#include <linux/sys.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/unistd.h>
|
||||
|
@ -80,7 +79,7 @@ ENTRY(system_call)
|
|||
movel %sp,%d1 /* get thread_info pointer */
|
||||
andl #-THREAD_SIZE,%d1
|
||||
movel %d1,%a2
|
||||
btst #(TIF_SYSCALL_TRACE%8),%a2@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
|
||||
btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
|
||||
jne do_trace
|
||||
cmpl #NR_syscalls,%d0
|
||||
jcc badsys
|
||||
|
@ -107,12 +106,12 @@ Luser_return:
|
|||
andl #-THREAD_SIZE,%d1
|
||||
movel %d1,%a2
|
||||
1:
|
||||
move %a2@(TI_FLAGS),%d1 /* thread_info->flags */
|
||||
move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */
|
||||
jne Lwork_to_do
|
||||
RESTORE_ALL
|
||||
|
||||
Lwork_to_do:
|
||||
movel %a2@(TI_FLAGS),%d1 /* thread_info->flags */
|
||||
movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */
|
||||
btst #TIF_NEED_RESCHED,%d1
|
||||
jne reschedule
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
* M68360 Port by SED Systems, and Lineo.
|
||||
*/
|
||||
|
||||
#include <linux/sys.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/unistd.h>
|
||||
|
@ -76,7 +75,7 @@ ENTRY(system_call)
|
|||
movel %sp,%d1 /* get thread_info pointer */
|
||||
andl #-THREAD_SIZE,%d1
|
||||
movel %d1,%a2
|
||||
btst #(TIF_SYSCALL_TRACE%8),%a2@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
|
||||
btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
|
||||
jne do_trace
|
||||
cmpl #NR_syscalls,%d0
|
||||
jcc badsys
|
||||
|
@ -103,12 +102,12 @@ Luser_return:
|
|||
andl #-THREAD_SIZE,%d1
|
||||
movel %d1,%a2
|
||||
1:
|
||||
move %a2@(TI_FLAGS),%d1 /* thread_info->flags */
|
||||
move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */
|
||||
jne Lwork_to_do
|
||||
RESTORE_ALL
|
||||
|
||||
Lwork_to_do:
|
||||
movel %a2@(TI_FLAGS),%d1 /* thread_info->flags */
|
||||
movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */
|
||||
btst #TIF_NEED_RESCHED,%d1
|
||||
jne reschedule
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
|
@ -33,7 +34,9 @@ unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
|
|||
MCFDMA_BASE3,
|
||||
#endif
|
||||
};
|
||||
EXPORT_SYMBOL(dma_base_addr);
|
||||
|
||||
unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
|
||||
EXPORT_SYMBOL(dma_device_address);
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
* Bug, speed and maintainability fixes by Philippe De Muyter <phdm@macqel.be>
|
||||
*/
|
||||
|
||||
#include <linux/sys.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
@ -78,7 +77,7 @@ ENTRY(system_call)
|
|||
movel %d2,%a0
|
||||
movel %a0@,%a1 /* save top of frame */
|
||||
movel %sp,%a1@(TASK_THREAD+THREAD_ESP0)
|
||||
btst #(TIF_SYSCALL_TRACE%8),%a0@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
|
||||
btst #(TIF_SYSCALL_TRACE%8),%a0@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
|
||||
bnes 1f
|
||||
|
||||
movel %d3,%a0
|
||||
|
@ -113,11 +112,11 @@ ret_from_exception:
|
|||
movel %sp,%d1 /* get thread_info pointer */
|
||||
andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
|
||||
movel %d1,%a0
|
||||
movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */
|
||||
movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */
|
||||
andl #(1<<TIF_NEED_RESCHED),%d1
|
||||
jeq Lkernel_return
|
||||
|
||||
movel %a0@(TI_PREEMPTCOUNT),%d1
|
||||
movel %a0@(TINFO_PREEMPT),%d1
|
||||
cmpl #0,%d1
|
||||
jne Lkernel_return
|
||||
|
||||
|
@ -137,14 +136,14 @@ Luser_return:
|
|||
movel %sp,%d1 /* get thread_info pointer */
|
||||
andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
|
||||
movel %d1,%a0
|
||||
movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */
|
||||
movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */
|
||||
jne Lwork_to_do /* still work to do */
|
||||
|
||||
Lreturn:
|
||||
RESTORE_USER
|
||||
|
||||
Lwork_to_do:
|
||||
movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */
|
||||
movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */
|
||||
move #0x2000,%sr /* enable intrs again */
|
||||
btst #TIF_NEED_RESCHED,%d1
|
||||
jne reschedule
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <linux/sys.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <linux/spi/spi.h>
|
||||
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
#define DRIVER_NAME "mcfqspi"
|
||||
|
|
Loading…
Reference in New Issue