diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2015-08-05 17:04:01 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2015-08-05 17:04:01 -0300 |
commit | 57f0f512b273f60d52568b8c6b77e17f5636edc0 (patch) | |
tree | 5e910f0e82173f4ef4f51111366a3f1299037a7b /arch/mn10300/include/asm |
Initial import
Diffstat (limited to 'arch/mn10300/include/asm')
90 files changed, 7824 insertions, 0 deletions
diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild new file mode 100644 index 000000000..f892d9de4 --- /dev/null +++ b/arch/mn10300/include/asm/Kbuild @@ -0,0 +1,11 @@ + +generic-y += barrier.h +generic-y += clkdev.h +generic-y += cputime.h +generic-y += exec.h +generic-y += irq_work.h +generic-y += mcs_spinlock.h +generic-y += preempt.h +generic-y += scatterlist.h +generic-y += sections.h +generic-y += trace_clock.h diff --git a/arch/mn10300/include/asm/asm-offsets.h b/arch/mn10300/include/asm/asm-offsets.h new file mode 100644 index 000000000..d370ee36a --- /dev/null +++ b/arch/mn10300/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include <generated/asm-offsets.h> diff --git a/arch/mn10300/include/asm/atomic.h b/arch/mn10300/include/asm/atomic.h new file mode 100644 index 000000000..5be655e83 --- /dev/null +++ b/arch/mn10300/include/asm/atomic.h @@ -0,0 +1,199 @@ +/* MN10300 Atomic counter operations + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_ATOMIC_H +#define _ASM_ATOMIC_H + +#include <asm/irqflags.h> +#include <asm/cmpxchg.h> +#include <asm/barrier.h> + +#ifndef CONFIG_SMP +#include <asm-generic/atomic.h> +#else + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +#define ATOMIC_INIT(i) { (i) } + +#ifdef __KERNEL__ + +/** + * atomic_read - read atomic variable + * @v: pointer of type atomic_t + * + * Atomically reads the value of @v. Note that the guaranteed + */ +#define atomic_read(v) (ACCESS_ONCE((v)->counter)) + +/** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value + * + * Atomically sets the value of @v to @i. Note that the guaranteed + */ +#define atomic_set(v, i) (((v)->counter) = (i)) + +#define ATOMIC_OP(op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + int retval, status; \ + \ + asm volatile( \ + "1: mov %4,(_AAR,%3) \n" \ + " mov (_ADR,%3),%1 \n" \ + " " #op " %5,%1 \n" \ + " mov %1,(_ADR,%3) \n" \ + " mov (_ADR,%3),%0 \n" /* flush */ \ + " mov (_ASR,%3),%0 \n" \ + " or %0,%0 \n" \ + " bne 1b \n" \ + : "=&r"(status), "=&r"(retval), "=m"(v->counter) \ + : "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i) \ + : "memory", "cc"); \ +} + +#define ATOMIC_OP_RETURN(op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + int retval, status; \ + \ + asm volatile( \ + "1: mov %4,(_AAR,%3) \n" \ + " mov (_ADR,%3),%1 \n" \ + " " #op " %5,%1 \n" \ + " mov %1,(_ADR,%3) \n" \ + " mov (_ADR,%3),%0 \n" /* flush */ \ + " mov (_ASR,%3),%0 \n" \ + " or %0,%0 \n" \ + " bne 1b \n" \ + : "=&r"(status), "=&r"(retval), "=m"(v->counter) \ + : "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i) \ + : "memory", "cc"); \ + return retval; \ +} + +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) + +ATOMIC_OPS(add) +ATOMIC_OPS(sub) + +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP + +static inline int atomic_add_negative(int i, atomic_t *v) +{ + return atomic_add_return(i, v) < 0; +} + +static inline void atomic_inc(atomic_t *v) +{ + atomic_add_return(1, v); +} + +static inline void atomic_dec(atomic_t *v) +{ + atomic_sub_return(1, v); +} + +#define atomic_dec_return(v) atomic_sub_return(1, (v)) +#define atomic_inc_return(v) atomic_add_return(1, (v)) + +#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) +#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) + +#define __atomic_add_unless(v, a, u) \ +({ \ + int c, old; \ + c = atomic_read(v); \ + while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ + c = old; \ + c; \ +}) + +#define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v))) +#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new))) + +/** + * atomic_clear_mask - Atomically clear bits in memory + * @mask: Mask of the bits to be cleared + * @v: pointer to word in memory + * + * Atomically clears the bits set in mask from the memory word specified. + */ +static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) +{ +#ifdef CONFIG_SMP + int status; + + asm volatile( + "1: mov %3,(_AAR,%2) \n" + " mov (_ADR,%2),%0 \n" + " and %4,%0 \n" + " mov %0,(_ADR,%2) \n" + " mov (_ADR,%2),%0 \n" /* flush */ + " mov (_ASR,%2),%0 \n" + " or %0,%0 \n" + " bne 1b \n" + : "=&r"(status), "=m"(*addr) + : "a"(ATOMIC_OPS_BASE_ADDR), "r"(addr), "r"(~mask) + : "memory", "cc"); +#else + unsigned long flags; + + mask = ~mask; + flags = arch_local_cli_save(); + *addr &= mask; + arch_local_irq_restore(flags); +#endif +} + +/** + * atomic_set_mask - Atomically set bits in memory + * @mask: Mask of the bits to be set + * @v: pointer to word in memory + * + * Atomically sets the bits set in mask from the memory word specified. + */ +static inline void atomic_set_mask(unsigned long mask, unsigned long *addr) +{ +#ifdef CONFIG_SMP + int status; + + asm volatile( + "1: mov %3,(_AAR,%2) \n" + " mov (_ADR,%2),%0 \n" + " or %4,%0 \n" + " mov %0,(_ADR,%2) \n" + " mov (_ADR,%2),%0 \n" /* flush */ + " mov (_ASR,%2),%0 \n" + " or %0,%0 \n" + " bne 1b \n" + : "=&r"(status), "=m"(*addr) + : "a"(ATOMIC_OPS_BASE_ADDR), "r"(addr), "r"(mask) + : "memory", "cc"); +#else + unsigned long flags; + + flags = arch_local_cli_save(); + *addr |= mask; + arch_local_irq_restore(flags); +#endif +} + +#endif /* __KERNEL__ */ +#endif /* CONFIG_SMP */ +#endif /* _ASM_ATOMIC_H */ diff --git a/arch/mn10300/include/asm/bitops.h b/arch/mn10300/include/asm/bitops.h new file mode 100644 index 000000000..fe6f8e2c3 --- /dev/null +++ b/arch/mn10300/include/asm/bitops.h @@ -0,0 +1,232 @@ +/* MN10300 bit operations + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + * + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ +#ifndef __ASM_BITOPS_H +#define __ASM_BITOPS_H + +#include <asm/cpu-regs.h> +#include <asm/barrier.h> + +/* + * set bit + */ +#define __set_bit(nr, addr) \ +({ \ + volatile unsigned char *_a = (unsigned char *)(addr); \ + const unsigned shift = (nr) & 7; \ + _a += (nr) >> 3; \ + \ + asm volatile("bset %2,(%1) # set_bit reg" \ + : "=m"(*_a) \ + : "a"(_a), "d"(1 << shift), "m"(*_a) \ + : "memory", "cc"); \ +}) + +#define set_bit(nr, addr) __set_bit((nr), (addr)) + +/* + * clear bit + */ +#define ___clear_bit(nr, addr) \ +({ \ + volatile unsigned char *_a = (unsigned char *)(addr); \ + const unsigned shift = (nr) & 7; \ + _a += (nr) >> 3; \ + \ + asm volatile("bclr %2,(%1) # clear_bit reg" \ + : "=m"(*_a) \ + : "a"(_a), "d"(1 << shift), "m"(*_a) \ + : "memory", "cc"); \ +}) + +#define clear_bit(nr, addr) ___clear_bit((nr), (addr)) + + +static inline void __clear_bit(unsigned long nr, volatile void *addr) +{ + unsigned int *a = (unsigned int *) addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + *a &= ~mask; +} + +/* + * test bit + */ +static inline int test_bit(unsigned long nr, const volatile void *addr) +{ + return 1UL & (((const volatile unsigned int *) addr)[nr >> 5] >> (nr & 31)); +} + +/* + * change bit + */ +static inline void __change_bit(unsigned long nr, volatile void *addr) +{ + int mask; + unsigned int *a = (unsigned int *) addr; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + *a ^= mask; +} + +extern void change_bit(unsigned long nr, volatile void *addr); + +/* + * test and set bit + */ +#define __test_and_set_bit(nr,addr) \ +({ \ + volatile unsigned char *_a = (unsigned char *)(addr); \ + const unsigned shift = (nr) & 7; \ + unsigned epsw; \ + _a += (nr) >> 3; \ + \ + asm volatile("bset %3,(%2) # test_set_bit reg\n" \ + "mov epsw,%1" \ + : "=m"(*_a), "=d"(epsw) \ + : "a"(_a), "d"(1 << shift), "m"(*_a) \ + : "memory", "cc"); \ + \ + !(epsw & EPSW_FLAG_Z); \ +}) + +#define test_and_set_bit(nr, addr) __test_and_set_bit((nr), (addr)) + +/* + * test and clear bit + */ +#define __test_and_clear_bit(nr, addr) \ +({ \ + volatile unsigned char *_a = (unsigned char *)(addr); \ + const unsigned shift = (nr) & 7; \ + unsigned epsw; \ + _a += (nr) >> 3; \ + \ + asm volatile("bclr %3,(%2) # test_clear_bit reg\n" \ + "mov epsw,%1" \ + : "=m"(*_a), "=d"(epsw) \ + : "a"(_a), "d"(1 << shift), "m"(*_a) \ + : "memory", "cc"); \ + \ + !(epsw & EPSW_FLAG_Z); \ +}) + +#define test_and_clear_bit(nr, addr) __test_and_clear_bit((nr), (addr)) + +/* + * test and change bit + */ +static inline int __test_and_change_bit(unsigned long nr, volatile void *addr) +{ + int mask, retval; + unsigned int *a = (unsigned int *)addr; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + retval = (mask & *a) != 0; + *a ^= mask; + + return retval; +} + +extern int test_and_change_bit(unsigned long nr, volatile void *addr); + +#include <asm-generic/bitops/lock.h> + +#ifdef __KERNEL__ + +/** + * __ffs - find first bit set + * @x: the word to search + * + * - return 31..0 to indicate bit 31..0 most least significant bit set + * - if no bits are set in x, the result is undefined + */ +static inline __attribute__((const)) +unsigned long __ffs(unsigned long x) +{ + int bit; + asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(x & -x) : "cc"); + return bit; +} + +/* + * special slimline version of fls() for calculating ilog2_u32() + * - note: no protection against n == 0 + */ +static inline __attribute__((const)) +int __ilog2_u32(u32 n) +{ + int bit; + asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(n) : "cc"); + return bit; +} + +/** + * fls - find last bit set + * @x: the word to search + * + * This is defined the same way as ffs: + * - return 32..1 to indicate bit 31..0 most significant bit set + * - return 0 to indicate no bits set + */ +static inline __attribute__((const)) +int fls(int x) +{ + return (x != 0) ? __ilog2_u32(x) + 1 : 0; +} + +/** + * __fls - find last (most-significant) set bit in a long word + * @word: the word to search + * + * Undefined if no set bit exists, so code should check against 0 first. + */ +static inline unsigned long __fls(unsigned long word) +{ + return __ilog2_u32(word); +} + +/** + * ffs - find first bit set + * @x: the word to search + * + * - return 32..1 to indicate bit 31..0 most least significant bit set + * - return 0 to indicate no bits set + */ +static inline __attribute__((const)) +int ffs(int x) +{ + /* Note: (x & -x) gives us a mask that is the least significant + * (rightmost) 1-bit of the value in x. + */ + return fls(x & -x); +} + +#include <asm-generic/bitops/ffz.h> +#include <asm-generic/bitops/fls64.h> +#include <asm-generic/bitops/find.h> +#include <asm-generic/bitops/sched.h> +#include <asm-generic/bitops/hweight.h> +#include <asm-generic/bitops/ext2-atomic-setbit.h> +#include <asm-generic/bitops/le.h> + +#endif /* __KERNEL__ */ +#endif /* __ASM_BITOPS_H */ diff --git a/arch/mn10300/include/asm/bug.h b/arch/mn10300/include/asm/bug.h new file mode 100644 index 000000000..aa6a38886 --- /dev/null +++ b/arch/mn10300/include/asm/bug.h @@ -0,0 +1,37 @@ +/* MN10300 Kernel bug reporting + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_BUG_H +#define _ASM_BUG_H + +#ifdef CONFIG_BUG + +/* + * Tell the user there is some problem. + */ +#define BUG() \ +do { \ + asm volatile( \ + " syscall 15 \n" \ + "0: \n" \ + " .section __bug_table,\"a\" \n" \ + " .long 0b,%0,%1 \n" \ + " .previous \n" \ + : \ + : "i"(__FILE__), "i"(__LINE__) \ + ); \ +} while (1) + +#define HAVE_ARCH_BUG +#endif /* CONFIG_BUG */ + +#include <asm-generic/bug.h> + +#endif /* _ASM_BUG_H */ diff --git a/arch/mn10300/include/asm/bugs.h b/arch/mn10300/include/asm/bugs.h new file mode 100644 index 000000000..31c8bc592 --- /dev/null +++ b/arch/mn10300/include/asm/bugs.h @@ -0,0 +1,20 @@ +/* MN10300 Checks for architecture-dependent bugs + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_BUGS_H +#define _ASM_BUGS_H + +#include <asm/processor.h> + +static inline void __init check_bugs(void) +{ +} + +#endif /* _ASM_BUGS_H */ diff --git a/arch/mn10300/include/asm/busctl-regs.h b/arch/mn10300/include/asm/busctl-regs.h new file mode 100644 index 000000000..1632aef73 --- /dev/null +++ b/arch/mn10300/include/asm/busctl-regs.h @@ -0,0 +1,151 @@ +/* AM33v2 on-board bus controller registers + * + * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_BUSCTL_REGS_H +#define _ASM_BUSCTL_REGS_H + +#include <asm/cpu-regs.h> + +#ifdef __KERNEL__ + +/* bus controller registers */ +#define BCCR __SYSREG(0xc0002000, u32) /* bus controller control reg */ +#define BCCR_B0AD 0x00000003 /* block 0 (80000000-83ffffff) bus allocation */ +#define BCCR_B1AD 0x0000000c /* block 1 (84000000-87ffffff) bus allocation */ +#define BCCR_B2AD 0x00000030 /* block 2 (88000000-8bffffff) bus allocation */ +#define BCCR_B3AD 0x000000c0 /* block 3 (8c000000-8fffffff) bus allocation */ +#define BCCR_B4AD 0x00000300 /* block 4 (90000000-93ffffff) bus allocation */ +#define BCCR_B5AD 0x00000c00 /* block 5 (94000000-97ffffff) bus allocation */ +#define BCCR_B6AD 0x00003000 /* block 6 (98000000-9bffffff) bus allocation */ +#define BCCR_B7AD 0x0000c000 /* block 7 (9c000000-9fffffff) bus allocation */ +#define BCCR_BxAD_EXBUS 0x0 /* - direct to system bus controller */ +#define BCCR_BxAD_OPEXBUS 0x1 /* - direct to memory bus controller */ +#define BCCR_BxAD_OCMBUS 0x2 /* - direct to on chip memory */ +#define BCCR_API 0x00070000 /* bus arbitration priority */ +#define BCCR_API_DMACICD 0x00000000 /* - DMA > CI > CD */ +#define BCCR_API_DMACDCI 0x00010000 /* - DMA > CD > CI */ +#define BCCR_API_CICDDMA 0x00020000 /* - CI > CD > DMA */ +#define BCCR_API_CDCIDMA 0x00030000 /* - CD > CI > DMA */ +#define BCCR_API_ROUNDROBIN 0x00040000 /* - round robin */ +#define BCCR_BEPRI_DMACICD 0x00c00000 /* bus error address priority */ +#define BCCR_BEPRI_DMACDCI 0x00000000 /* - DMA > CI > CD */ +#define BCCR_BEPRI_CICDDMA 0x00400000 /* - DMA > CD > CI */ +#define BCCR_BEPRI_CDCIDMA 0x00800000 /* - CI > CD > DMA */ +#define BCCR_BEPRI 0x00c00000 /* - CD > CI > DMA */ +#define BCCR_TMON 0x03000000 /* timeout value settings */ +#define BCCR_TMON_16IOCLK 0x00000000 /* - 16 IOCLK cycles */ +#define BCCR_TMON_256IOCLK 0x01000000 /* - 256 IOCLK cycles */ +#define BCCR_TMON_4096IOCLK 0x02000000 /* - 4096 IOCLK cycles */ +#define BCCR_TMON_65536IOCLK 0x03000000 /* - 65536 IOCLK cycles */ +#define BCCR_TMOE 0x10000000 /* timeout detection enable */ + +#define BCBERR __SYSREG(0xc0002010, u32) /* bus error source reg */ +#define BCBERR_BESB 0x0000001f /* erroneous access destination space */ +#define BCBERR_BESB_MON 0x00000001 /* - monitor space */ +#define BCBERR_BESB_IO 0x00000002 /* - IO bus */ +#define BCBERR_BESB_EX 0x00000004 /* - EX bus */ +#define BCBERR_BESB_OPEX 0x00000008 /* - OpEX bus */ +#define BCBERR_BESB_OCM 0x00000010 /* - on chip memory */ +#define BCBERR_BERW 0x00000100 /* type of access */ +#define BCBERR_BERW_WRITE 0x00000000 /* - write */ +#define BCBERR_BERW_READ 0x00000100 /* - read */ +#define BCBERR_BESD 0x00000200 /* error detector */ +#define BCBERR_BESD_BCU 0x00000000 /* - BCU detected error */ +#define BCBERR_BESD_SLAVE_BUS 0x00000200 /* - slave bus detected error */ +#define BCBERR_BEBST 0x00000400 /* type of access */ +#define BCBERR_BEBST_SINGLE 0x00000000 /* - single */ +#define BCBERR_BEBST_BURST 0x00000400 /* - burst */ +#define BCBERR_BEME 0x00000800 /* multiple bus error flag */ +#define BCBERR_BEMR 0x00007000 /* master bus that caused the error */ +#define BCBERR_BEMR_NOERROR 0x00000000 /* - no error */ +#define BCBERR_BEMR_CI 0x00001000 /* - CPU instruction fetch bus caused error */ +#define BCBERR_BEMR_CD 0x00002000 /* - CPU data bus caused error */ +#define BCBERR_BEMR_DMA 0x00004000 /* - DMA bus caused error */ + +#define BCBEAR __SYSREGC(0xc0002020, u32) /* bus error address reg */ + +/* system bus controller registers */ +#define SBBASE(X) __SYSREG(0xd8c00100 + (X) * 0x10, u32) /* SBC base addr regs */ +#define SBBASE_BE 0x00000001 /* bank enable */ +#define SBBASE_BAM 0x0000fffe /* bank address mask [31:17] */ +#define SBBASE_BBA 0xfffe0000 /* bank base address [31:17] */ + +#define SBCNTRL0(X) __SYSREG(0xd8c00200 + (X) * 0x10, u32) /* SBC bank ctrl0 regs */ +#define SBCNTRL0_WEH 0x00000f00 /* write enable hold */ +#define SBCNTRL0_REH 0x0000f000 /* read enable hold */ +#define SBCNTRL0_RWH 0x000f0000 /* SRW signal hold */ +#define SBCNTRL0_CSH 0x00f00000 /* chip select hold */ +#define SBCNTRL0_DAH 0x0f000000 /* data hold */ +#define SBCNTRL0_ADH 0xf0000000 /* address hold */ + +#define SBCNTRL1(X) __SYSREG(0xd8c00204 + (X) * 0x10, u32) /* SBC bank ctrl1 regs */ +#define SBCNTRL1_WED 0x00000f00 /* write enable delay */ +#define SBCNTRL1_RED 0x0000f000 /* read enable delay */ +#define SBCNTRL1_RWD 0x000f0000 /* SRW signal delay */ +#define SBCNTRL1_ASW 0x00f00000 /* address strobe width */ +#define SBCNTRL1_CSD 0x0f000000 /* chip select delay */ +#define SBCNTRL1_ASD 0xf0000000 /* address strobe delay */ + +#define SBCNTRL2(X) __SYSREG(0xd8c00208 + (X) * 0x10, u32) /* SBC bank ctrl2 regs */ +#define SBCNTRL2_WC 0x000000ff /* wait count */ +#define SBCNTRL2_BWC 0x00000f00 /* burst wait count */ +#define SBCNTRL2_WM 0x01000000 /* wait mode setting */ +#define SBCNTRL2_WM_FIXEDWAIT 0x00000000 /* - fixed wait access */ +#define SBCNTRL2_WM_HANDSHAKE 0x01000000 /* - handshake access */ +#define SBCNTRL2_BM 0x02000000 /* bus synchronisation mode */ +#define SBCNTRL2_BM_SYNC 0x00000000 /* - synchronous mode */ +#define SBCNTRL2_BM_ASYNC 0x02000000 /* - asynchronous mode */ +#define SBCNTRL2_BW 0x04000000 /* bus width */ +#define SBCNTRL2_BW_32 0x00000000 /* - 32 bits */ +#define SBCNTRL2_BW_16 0x04000000 /* - 16 bits */ +#define SBCNTRL2_RWINV 0x08000000 /* R/W signal invert polarity */ +#define SBCNTRL2_RWINV_NORM 0x00000000 /* - normal (read high) */ +#define SBCNTRL2_RWINV_INV 0x08000000 /* - inverted (read low) */ +#define SBCNTRL2_BT 0x70000000 /* bus type setting */ +#define SBCNTRL2_BT_SRAM 0x00000000 /* - SRAM interface */ +#define SBCNTRL2_BT_ADMUX 0x00000000 /* - addr/data multiplexed interface */ +#define SBCNTRL2_BT_BROM 0x00000000 /* - burst ROM interface */ +#define SBCNTRL2_BTSE 0x80000000 /* burst enable */ + +/* memory bus controller */ +#define SDBASE(X) __SYSREG(0xda000008 + (X) * 0x4, u32) /* MBC base addr regs */ +#define SDBASE_CE 0x00000001 /* chip enable */ +#define SDBASE_CBAM 0x0000fff0 /* chip base address mask [31:20] */ +#define SDBASE_CBAM_SHIFT 16 +#define SDBASE_CBA 0xfff00000 /* chip base address [31:20] */ + +#define SDRAMBUS __SYSREG(0xda000000, u32) /* bus mode control reg */ +#define SDRAMBUS_REFEN 0x00000004 /* refresh enable */ +#define SDRAMBUS_TRC 0x00000018 /* refresh command delay time */ +#define SDRAMBUS_BSTPT 0x00000020 /* burst stop command enable */ +#define SDRAMBUS_PONSEQ 0x00000040 /* power on sequence */ +#define SDRAMBUS_SELFREQ 0x00000080 /* self-refresh mode request */ +#define SDRAMBUS_SELFON 0x00000100 /* self-refresh mode on */ +#define SDRAMBUS_SIZE 0x00030000 /* SDRAM size */ +#define SDRAMBUS_SIZE_64Mbit 0x00010000 /* 64Mbit SDRAM (x16) */ +#define SDRAMBUS_SIZE_128Mbit 0x00020000 /* 128Mbit SDRAM (x16) */ +#define SDRAMBUS_SIZE_256Mbit 0x00030000 /* 256Mbit SDRAM (x16) */ +#define SDRAMBUS_TRASWAIT 0x000c0000 /* row address precharge command cycle number */ +#define SDRAMBUS_REFNUM 0x00300000 /* refresh command number */ +#define SDRAMBUS_BSTWAIT 0x00c00000 /* burst stop command cycle */ +#define SDRAMBUS_SETWAIT 0x03000000 /* mode register setting command cycle */ +#define SDRAMBUS_PREWAIT 0x0c000000 /* precharge command cycle */ +#define SDRAMBUS_RASLATE 0x30000000 /* RAS latency */ +#define SDRAMBUS_CASLATE 0xc0000000 /* CAS latency */ + +#define SDREFCNT __SYSREG(0xda000004, u32) /* refresh period reg */ +#define SDREFCNT_PERI 0x00000fff /* refresh period */ + +#define SDSHDW __SYSREG(0xda000010, u32) /* test reg */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_BUSCTL_REGS_H */ diff --git a/arch/mn10300/include/asm/cache.h b/arch/mn10300/include/asm/cache.h new file mode 100644 index 000000000..f29cde2cf --- /dev/null +++ b/arch/mn10300/include/asm/cache.h @@ -0,0 +1,60 @@ +/* MN10300 cache management registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_CACHE_H +#define _ASM_CACHE_H + +#include <asm/cpu-regs.h> +#include <proc/cache.h> + +#ifndef __ASSEMBLY__ +#define L1_CACHE_DISPARITY (L1_CACHE_NENTRIES * L1_CACHE_BYTES) +#else +#define L1_CACHE_DISPARITY L1_CACHE_NENTRIES * L1_CACHE_BYTES +#endif + +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES + +/* data cache purge registers + * - read from the register to unconditionally purge that cache line + * - write address & 0xffffff00 to conditionally purge that cache line + * - clear LSB to request invalidation as well + */ +#define DCACHE_PURGE(WAY, ENTRY) \ + __SYSREG(0xc8400000 + (WAY) * L1_CACHE_WAYDISP + \ + (ENTRY) * L1_CACHE_BYTES, u32) + +#define DCACHE_PURGE_WAY0(ENTRY) \ + __SYSREG(0xc8400000 + 0 * L1_CACHE_WAYDISP + (ENTRY) * L1_CACHE_BYTES, u32) +#define DCACHE_PURGE_WAY1(ENTRY) \ + __SYSREG(0xc8400000 + 1 * L1_CACHE_WAYDISP + (ENTRY) * L1_CACHE_BYTES, u32) +#define DCACHE_PURGE_WAY2(ENTRY) \ + __SYSREG(0xc8400000 + 2 * L1_CACHE_WAYDISP + (ENTRY) * L1_CACHE_BYTES, u32) +#define DCACHE_PURGE_WAY3(ENTRY) \ + __SYSREG(0xc8400000 + 3 * L1_CACHE_WAYDISP + (ENTRY) * L1_CACHE_BYTES, u32) + +/* instruction cache access registers */ +#define ICACHE_DATA(WAY, ENTRY, OFF) \ + __SYSREG(0xc8000000 + (WAY) * L1_CACHE_WAYDISP + \ + (ENTRY) * L1_CACHE_BYTES + (OFF) * 4, u32) +#define ICACHE_TAG(WAY, ENTRY) \ + __SYSREG(0xc8100000 + (WAY) * L1_CACHE_WAYDISP + \ + (ENTRY) * L1_CACHE_BYTES, u32) + +/* data cache access registers */ +#define DCACHE_DATA(WAY, ENTRY, OFF) \ + __SYSREG(0xc8200000 + (WAY) * L1_CACHE_WAYDISP + \ + (ENTRY) * L1_CACHE_BYTES + (OFF) * 4, u32) +#define DCACHE_TAG(WAY, ENTRY) \ + __SYSREG(0xc8300000 + (WAY) * L1_CACHE_WAYDISP + \ + (ENTRY) * L1_CACHE_BYTES, u32) + +#endif /* _ASM_CACHE_H */ diff --git a/arch/mn10300/include/asm/cacheflush.h b/arch/mn10300/include/asm/cacheflush.h new file mode 100644 index 000000000..6d6df8399 --- /dev/null +++ b/arch/mn10300/include/asm/cacheflush.h @@ -0,0 +1,164 @@ +/* MN10300 Cache flushing + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_CACHEFLUSH_H +#define _ASM_CACHEFLUSH_H + +#ifndef __ASSEMBLY__ + +/* Keep includes the same across arches. */ +#include <linux/mm.h> + +/* + * Primitive routines + */ +#ifdef CONFIG_MN10300_CACHE_ENABLED +extern void mn10300_local_icache_inv(void); +extern void mn10300_local_icache_inv_page(unsigned long start); +extern void mn10300_local_icache_inv_range(unsigned long start, unsigned long end); +extern void mn10300_local_icache_inv_range2(unsigned long start, unsigned long size); +extern void mn10300_local_dcache_inv(void); +extern void mn10300_local_dcache_inv_page(unsigned long start); +extern void mn10300_local_dcache_inv_range(unsigned long start, unsigned long end); +extern void mn10300_local_dcache_inv_range2(unsigned long start, unsigned long size); +extern void mn10300_icache_inv(void); +extern void mn10300_icache_inv_page(unsigned long start); +extern void mn10300_icache_inv_range(unsigned long start, unsigned long end); +extern void mn10300_icache_inv_range2(unsigned long start, unsigned long size); +extern void mn10300_dcache_inv(void); +extern void mn10300_dcache_inv_page(unsigned long start); +extern void mn10300_dcache_inv_range(unsigned long start, unsigned long end); +extern void mn10300_dcache_inv_range2(unsigned long start, unsigned long size); +#ifdef CONFIG_MN10300_CACHE_WBACK +extern void mn10300_local_dcache_flush(void); +extern void mn10300_local_dcache_flush_page(unsigned long start); +extern void mn10300_local_dcache_flush_range(unsigned long start, unsigned long end); +extern void mn10300_local_dcache_flush_range2(unsigned long start, unsigned long size); +extern void mn10300_local_dcache_flush_inv(void); +extern void mn10300_local_dcache_flush_inv_page(unsigned long start); +extern void mn10300_local_dcache_flush_inv_range(unsigned long start, unsigned long end); +extern void mn10300_local_dcache_flush_inv_range2(unsigned long start, unsigned long size); +extern void mn10300_dcache_flush(void); +extern void mn10300_dcache_flush_page(unsigned long start); +extern void mn10300_dcache_flush_range(unsigned long start, unsigned long end); +extern void mn10300_dcache_flush_range2(unsigned long start, unsigned long size); +extern void mn10300_dcache_flush_inv(void); +extern void mn10300_dcache_flush_inv_page(unsigned long start); +extern void mn10300_dcache_flush_inv_range(unsigned long start, unsigned long end); +extern void mn10300_dcache_flush_inv_range2(unsigned long start, unsigned long size); +#else +#define mn10300_local_dcache_flush() do {} while (0) +#define mn10300_local_dcache_flush_page(start) do {} while (0) +#define mn10300_local_dcache_flush_range(start, end) do {} while (0) +#define mn10300_local_dcache_flush_range2(start, size) do {} while (0) +#define mn10300_local_dcache_flush_inv() \ + mn10300_local_dcache_inv() +#define mn10300_local_dcache_flush_inv_page(start) \ + mn10300_local_dcache_inv_page(start) +#define mn10300_local_dcache_flush_inv_range(start, end) \ + mn10300_local_dcache_inv_range(start, end) +#define mn10300_local_dcache_flush_inv_range2(start, size) \ + mn10300_local_dcache_inv_range2(start, size) +#define mn10300_dcache_flush() do {} while (0) +#define mn10300_dcache_flush_page(start) do {} while (0) +#define mn10300_dcache_flush_range(start, end) do {} while (0) +#define mn10300_dcache_flush_range2(start, size) do {} while (0) +#define mn10300_dcache_flush_inv() mn10300_dcache_inv() +#define mn10300_dcache_flush_inv_page(start) \ + mn10300_dcache_inv_page((start)) +#define mn10300_dcache_flush_inv_range(start, end) \ + mn10300_dcache_inv_range((start), (end)) +#define mn10300_dcache_flush_inv_range2(start, size) \ + mn10300_dcache_inv_range2((start), (size)) +#endif /* CONFIG_MN10300_CACHE_WBACK */ +#else +#define mn10300_local_icache_inv() do {} while (0) +#define mn10300_local_icache_inv_page(start) do {} while (0) +#define mn10300_local_icache_inv_range(start, end) do {} while (0) +#define mn10300_local_icache_inv_range2(start, size) do {} while (0) +#define mn10300_local_dcache_inv() do {} while (0) +#define mn10300_local_dcache_inv_page(start) do {} while (0) +#define mn10300_local_dcache_inv_range(start, end) do {} while (0) +#define mn10300_local_dcache_inv_range2(start, size) do {} while (0) +#define mn10300_local_dcache_flush() do {} while (0) +#define mn10300_local_dcache_flush_inv_page(start) do {} while (0) +#define mn10300_local_dcache_flush_inv() do {} while (0) +#define mn10300_local_dcache_flush_inv_range(start, end)do {} while (0) +#define mn10300_local_dcache_flush_inv_range2(start, size) do {} while (0) +#define mn10300_local_dcache_flush_page(start) do {} while (0) +#define mn10300_local_dcache_flush_range(start, end) do {} while (0) +#define mn10300_local_dcache_flush_range2(start, size) do {} while (0) +#define mn10300_icache_inv() do {} while (0) +#define mn10300_icache_inv_page(start) do {} while (0) +#define mn10300_icache_inv_range(start, end) do {} while (0) +#define mn10300_icache_inv_range2(start, size) do {} while (0) +#define mn10300_dcache_inv() do {} while (0) +#define mn10300_dcache_inv_page(start) do {} while (0) +#define mn10300_dcache_inv_range(start, end) do {} while (0) +#define mn10300_dcache_inv_range2(start, size) do {} while (0) +#define mn10300_dcache_flush() do {} while (0) +#define mn10300_dcache_flush_inv_page(start) do {} while (0) +#define mn10300_dcache_flush_inv() do {} while (0) +#define mn10300_dcache_flush_inv_range(start, end) do {} while (0) +#define mn10300_dcache_flush_inv_range2(start, size) do {} while (0) +#define mn10300_dcache_flush_page(start) do {} while (0) +#define mn10300_dcache_flush_range(start, end) do {} while (0) +#define mn10300_dcache_flush_range2(start, size) do {} while (0) +#endif /* CONFIG_MN10300_CACHE_ENABLED */ + +/* + * Virtually-indexed cache management (our cache is physically indexed) + */ +#define flush_cache_all() do {} while (0) +#define flush_cache_mm(mm) do {} while (0) +#define flush_cache_dup_mm(mm) do {} while (0) +#define flush_cache_range(mm, start, end) do {} while (0) +#define flush_cache_page(vma, vmaddr, pfn) do {} while (0) +#define flush_cache_vmap(start, end) do {} while (0) +#define flush_cache_vunmap(start, end) do {} while (0) +#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 +#define flush_dcache_page(page) do {} while (0) +#define flush_dcache_mmap_lock(mapping) do {} while (0) +#define flush_dcache_mmap_unlock(mapping) do {} while (0) + +/* + * Physically-indexed cache management + */ +#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) +extern void flush_icache_page(struct vm_area_struct *vma, struct page *page); +extern void flush_icache_range(unsigned long start, unsigned long end); +#elif defined(CONFIG_MN10300_CACHE_INV_ICACHE) +static inline void flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + mn10300_icache_inv_page(page_to_phys(page)); +} +extern void flush_icache_range(unsigned long start, unsigned long end); +#else +#define flush_icache_range(start, end) do {} while (0) +#define flush_icache_page(vma, pg) do {} while (0) +#endif + + +#define flush_icache_user_range(vma, pg, adr, len) \ + flush_icache_range(adr, adr + len) + +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ + do { \ + memcpy(dst, src, len); \ + flush_icache_page(vma, page); \ + } while (0) + +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + memcpy(dst, src, len) + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_CACHEFLUSH_H */ diff --git a/arch/mn10300/include/asm/checksum.h b/arch/mn10300/include/asm/checksum.h new file mode 100644 index 000000000..9fb2a8d88 --- /dev/null +++ b/arch/mn10300/include/asm/checksum.h @@ -0,0 +1,86 @@ +/* MN10300 Optimised checksumming code + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_CHECKSUM_H +#define _ASM_CHECKSUM_H + +extern __wsum csum_partial(const void *buff, int len, __wsum sum); +extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, + int len, __wsum sum); +extern __wsum csum_partial_copy_from_user(const void *src, void *dst, + int len, __wsum sum, + int *err_ptr); +extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl); +extern __wsum csum_partial(const void *buff, int len, __wsum sum); +extern __sum16 ip_compute_csum(const void *buff, int len); + +#define csum_partial_copy_fromuser csum_partial_copy +extern __wsum csum_partial_copy(const void *src, void *dst, int len, + __wsum sum); + +static inline __sum16 csum_fold(__wsum sum) +{ + asm( + " add %1,%0 \n" + " addc 0xffff,%0 \n" + : "=r" (sum) + : "r" (sum << 16), "0" (sum & 0xffff0000) + : "cc" + ); + return (~sum) >> 16; +} + +static inline __wsum csum_tcpudp_nofold(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ + __wsum tmp; + + tmp = (__wsum) ntohs(len) << 16; + tmp += (__wsum) proto << 8; + + asm( + " add %1,%0 \n" + " addc %2,%0 \n" + " addc %3,%0 \n" + " addc 0,%0 \n" + : "=r" (sum) + : "r" (daddr), "r"(saddr), "r"(tmp), "0"(sum) + : "cc" + ); + return sum; +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 csum_tcpudp_magic(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); +} + +#undef _HAVE_ARCH_IPV6_CSUM + +/* + * Copy and checksum to user + */ +#define HAVE_CSUM_COPY_USER +extern __wsum csum_and_copy_to_user(const void *src, void *dst, int len, + __wsum sum, int *err_ptr); + + +#endif /* _ASM_CHECKSUM_H */ diff --git a/arch/mn10300/include/asm/cmpxchg.h b/arch/mn10300/include/asm/cmpxchg.h new file mode 100644 index 000000000..97a4aaf38 --- /dev/null +++ b/arch/mn10300/include/asm/cmpxchg.h @@ -0,0 +1,115 @@ +/* MN10300 Atomic xchg/cmpxchg operations + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_CMPXCHG_H +#define _ASM_CMPXCHG_H + +#include <asm/irqflags.h> + +#ifdef CONFIG_SMP +#ifdef CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT +static inline +unsigned long __xchg(volatile unsigned long *m, unsigned long val) +{ + unsigned long status; + unsigned long oldval; + + asm volatile( + "1: mov %4,(_AAR,%3) \n" + " mov (_ADR,%3),%1 \n" + " mov %5,(_ADR,%3) \n" + " mov (_ADR,%3),%0 \n" /* flush */ + " mov (_ASR,%3),%0 \n" + " or %0,%0 \n" + " bne 1b \n" + : "=&r"(status), "=&r"(oldval), "=m"(*m) + : "a"(ATOMIC_OPS_BASE_ADDR), "r"(m), "r"(val) + : "memory", "cc"); + + return oldval; +} + +static inline unsigned long __cmpxchg(volatile unsigned long *m, + unsigned long old, unsigned long new) +{ + unsigned long status; + unsigned long oldval; + + asm volatile( + "1: mov %4,(_AAR,%3) \n" + " mov (_ADR,%3),%1 \n" + " cmp %5,%1 \n" + " bne 2f \n" + " mov %6,(_ADR,%3) \n" + "2: mov (_ADR,%3),%0 \n" /* flush */ + " mov (_ASR,%3),%0 \n" + " or %0,%0 \n" + " bne 1b \n" + : "=&r"(status), "=&r"(oldval), "=m"(*m) + : "a"(ATOMIC_OPS_BASE_ADDR), "r"(m), + "r"(old), "r"(new) + : "memory", "cc"); + + return oldval; +} +#else /* CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT */ +#error "No SMP atomic operation support!" +#endif /* CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT */ + +#else /* CONFIG_SMP */ + +/* + * Emulate xchg for non-SMP MN10300 + */ +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((struct __xchg_dummy *)(x)) + +static inline +unsigned long __xchg(volatile unsigned long *m, unsigned long val) +{ + unsigned long oldval; + unsigned long flags; + + flags = arch_local_cli_save(); + oldval = *m; + *m = val; + arch_local_irq_restore(flags); + return oldval; +} + +/* + * Emulate cmpxchg for non-SMP MN10300 + */ +static inline unsigned long __cmpxchg(volatile unsigned long *m, + unsigned long old, unsigned long new) +{ + unsigned long oldval; + unsigned long flags; + + flags = arch_local_cli_save(); + oldval = *m; + if (oldval == old) + *m = new; + arch_local_irq_restore(flags); + return oldval; +} + +#endif /* CONFIG_SMP */ + +#define xchg(ptr, v) \ + ((__typeof__(*(ptr))) __xchg((unsigned long *)(ptr), \ + (unsigned long)(v))) + +#define cmpxchg(ptr, o, n) \ + ((__typeof__(*(ptr))) __cmpxchg((unsigned long *)(ptr), \ + (unsigned long)(o), \ + (unsigned long)(n))) + +#endif /* _ASM_CMPXCHG_H */ diff --git a/arch/mn10300/include/asm/cpu-regs.h b/arch/mn10300/include/asm/cpu-regs.h new file mode 100644 index 000000000..c54effae2 --- /dev/null +++ b/arch/mn10300/include/asm/cpu-regs.h @@ -0,0 +1,353 @@ +/* MN10300 Core system registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_CPU_REGS_H +#define _ASM_CPU_REGS_H + +#ifndef __ASSEMBLY__ +#include <linux/types.h> +#endif + +/* we tell the compiler to pretend to be AM33 so that it doesn't try and use + * the FP regs, but tell the assembler that we're actually allowed AM33v2 + * instructions */ +#ifndef __ASSEMBLY__ +asm(" .am33_2\n"); +#else +.am33_2 +#endif + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ +#define __SYSREG(ADDR, TYPE) (*(volatile TYPE *)(ADDR)) +#define __SYSREGC(ADDR, TYPE) (*(const volatile TYPE *)(ADDR)) +#else +#define __SYSREG(ADDR, TYPE) ADDR +#define __SYSREGC(ADDR, TYPE) ADDR +#endif + +/* CPU registers */ +#define EPSW_FLAG_Z 0x00000001 /* zero flag */ +#define EPSW_FLAG_N 0x00000002 /* negative flag */ +#define EPSW_FLAG_C 0x00000004 /* carry flag */ +#define EPSW_FLAG_V 0x00000008 /* overflow flag */ +#define EPSW_IM 0x00000700 /* interrupt mode */ +#define EPSW_IM_0 0x00000000 /* interrupt mode 0 */ +#define EPSW_IM_1 0x00000100 /* interrupt mode 1 */ +#define EPSW_IM_2 0x00000200 /* interrupt mode 2 */ +#define EPSW_IM_3 0x00000300 /* interrupt mode 3 */ +#define EPSW_IM_4 0x00000400 /* interrupt mode 4 */ +#define EPSW_IM_5 0x00000500 /* interrupt mode 5 */ +#define EPSW_IM_6 0x00000600 /* interrupt mode 6 */ +#define EPSW_IM_7 0x00000700 /* interrupt mode 7 */ +#define EPSW_IE 0x00000800 /* interrupt enable */ +#define EPSW_S 0x00003000 /* software auxiliary bits */ +#define EPSW_T 0x00008000 /* trace enable */ +#define EPSW_nSL 0x00010000 /* not supervisor level */ +#define EPSW_NMID 0x00020000 /* nonmaskable interrupt disable */ +#define EPSW_nAR 0x00040000 /* register bank control */ +#define EPSW_ML 0x00080000 /* monitor level */ +#define EPSW_FE 0x00100000 /* FPU enable */ +#define EPSW_IM_SHIFT 8 /* EPSW_IM_SHIFT determines the interrupt mode */ + +#define NUM2EPSW_IM(num) ((num) << EPSW_IM_SHIFT) + +/* FPU registers */ +#define FPCR_EF_I 0x00000001 /* inexact result FPU exception flag */ +#define FPCR_EF_U 0x00000002 /* underflow FPU exception flag */ +#define FPCR_EF_O 0x00000004 /* overflow FPU exception flag */ +#define FPCR_EF_Z 0x00000008 /* zero divide FPU exception flag */ +#define FPCR_EF_V 0x00000010 /* invalid operand FPU exception flag */ +#define FPCR_EE_I 0x00000020 /* inexact result FPU exception enable */ +#define FPCR_EE_U 0x00000040 /* underflow FPU exception enable */ +#define FPCR_EE_O 0x00000080 /* overflow FPU exception enable */ +#define FPCR_EE_Z 0x00000100 /* zero divide FPU exception enable */ +#define FPCR_EE_V 0x00000200 /* invalid operand FPU exception enable */ +#define FPCR_EC_I 0x00000400 /* inexact result FPU exception cause */ +#define FPCR_EC_U 0x00000800 /* underflow FPU exception cause */ +#define FPCR_EC_O 0x00001000 /* overflow FPU exception cause */ +#define FPCR_EC_Z 0x00002000 /* zero divide FPU exception cause */ +#define FPCR_EC_V 0x00004000 /* invalid operand FPU exception cause */ +#define FPCR_RM 0x00030000 /* rounding mode */ +#define FPCR_RM_NEAREST 0x00000000 /* - round to nearest value */ +#define FPCR_FCC_U 0x00040000 /* FPU unordered condition code */ +#define FPCR_FCC_E 0x00080000 /* FPU equal condition code */ +#define FPCR_FCC_G 0x00100000 /* FPU greater than condition code */ +#define FPCR_FCC_L 0x00200000 /* FPU less than condition code */ +#define FPCR_INIT 0x00000000 /* no exceptions, rounding to nearest */ + +/* CPU control registers */ +#define CPUP __SYSREG(0xc0000020, u16) /* CPU pipeline register */ +#define CPUP_DWBD 0x0020 /* write buffer disable flag */ +#define CPUP_IPFD 0x0040 /* instruction prefetch disable flag */ +#define CPUP_EXM 0x0080 /* exception operation mode */ +#define CPUP_EXM_AM33V1 0x0000 /* - AM33 v1 exception mode */ +#define CPUP_EXM_AM33V2 0x0080 /* - AM33 v2 exception mode */ + +#define CPUM __SYSREG(0xc0000040, u16) /* CPU mode register */ +#define CPUM_SLEEP 0x0004 /* set to enter sleep state */ +#define CPUM_HALT 0x0008 /* set to enter halt state */ +#define CPUM_STOP 0x0010 /* set to enter stop state */ + +#define CPUREV __SYSREGC(0xc0000050, u32) /* CPU revision register */ +#define CPUREV_TYPE 0x0000000f /* CPU type */ +#define CPUREV_TYPE_S 0 +#define CPUREV_TYPE_AM33_1 0x00000000 /* - AM33-1 core, AM33/1.00 arch */ +#define CPUREV_TYPE_AM33_2 0x00000001 /* - AM33-2 core, AM33/2.00 arch */ +#define CPUREV_TYPE_AM34_1 0x00000002 /* - AM34-1 core, AM33/2.00 arch */ +#define CPUREV_TYPE_AM33_3 0x00000003 /* - AM33-3 core, AM33/2.00 arch */ +#define CPUREV_TYPE_AM34_2 0x00000004 /* - AM34-2 core, AM33/3.00 arch */ +#define CPUREV_REVISION 0x000000f0 /* CPU revision */ +#define CPUREV_REVISION_S 4 +#define CPUREV_ICWAY 0x00000f00 /* number of instruction cache ways */ +#define CPUREV_ICWAY_S 8 +#define CPUREV_ICSIZE 0x0000f000 /* instruction cache way size */ +#define CPUREV_ICSIZE_S 12 +#define CPUREV_DCWAY 0x000f0000 /* number of data cache ways */ +#define CPUREV_DCWAY_S 16 +#define CPUREV_DCSIZE 0x00f00000 /* data cache way size */ +#define CPUREV_DCSIZE_S 20 +#define CPUREV_FPUTYPE 0x0f000000 /* FPU core type */ +#define CPUREV_FPUTYPE_NONE 0x00000000 /* - no FPU core implemented */ +#define CPUREV_OCDCTG 0xf0000000 /* on-chip debug function category */ + +#define DCR __SYSREG(0xc0000030, u16) /* Debug control register */ + +/* interrupt/exception control registers */ +#define IVAR0 __SYSREG(0xc0000000, u16) /* interrupt vector 0 */ +#define IVAR1 __SYSREG(0xc0000004, u16) /* interrupt vector 1 */ +#define IVAR2 __SYSREG(0xc0000008, u16) /* interrupt vector 2 */ +#define IVAR3 __SYSREG(0xc000000c, u16) /* interrupt vector 3 */ +#define IVAR4 __SYSREG(0xc0000010, u16) /* interrupt vector 4 */ +#define IVAR5 __SYSREG(0xc0000014, u16) /* interrupt vector 5 */ +#define IVAR6 __SYSREG(0xc0000018, u16) /* interrupt vector 6 */ + +#define TBR __SYSREG(0xc0000024, u32) /* Trap table base */ +#define TBR_TB 0xff000000 /* table base address bits 31-24 */ +#define TBR_INT_CODE 0x00ffffff /* interrupt code */ + +#define DEAR __SYSREG(0xc0000038, u32) /* Data access exception address */ + +#define sISR __SYSREG(0xc0000044, u32) /* Supervisor interrupt status */ +#define sISR_IRQICE 0x00000001 /* ICE interrupt */ +#define sISR_ISTEP 0x00000002 /* single step interrupt */ +#define sISR_MISSA 0x00000004 /* memory access address misalignment fault */ +#define sISR_UNIMP 0x00000008 /* unimplemented instruction execution fault */ +#define sISR_PIEXE 0x00000010 /* program interrupt */ +#define sISR_MEMERR 0x00000020 /* illegal memory access fault */ +#define sISR_IBREAK 0x00000040 /* instraction break interrupt */ +#define sISR_DBSRL 0x00000080 /* debug serial interrupt */ +#define sISR_PERIDB 0x00000100 /* peripheral debug interrupt */ +#define sISR_EXUNIMP 0x00000200 /* unimplemented ex-instruction execution fault */ +#define sISR_OBREAK 0x00000400 /* operand break interrupt */ +#define sISR_PRIV 0x00000800 /* privileged instruction execution fault */ +#define sISR_BUSERR 0x00001000 /* bus error fault */ +#define sISR_DBLFT 0x00002000 /* double fault */ +#define sISR_DBG 0x00008000 /* debug reserved interrupt */ +#define sISR_ITMISS 0x00010000 /* instruction TLB miss */ +#define sISR_DTMISS 0x00020000 /* data TLB miss */ +#define sISR_ITEX 0x00040000 /* instruction TLB access exception */ +#define sISR_DTEX 0x00080000 /* data TLB access exception */ +#define sISR_ILGIA 0x00100000 /* illegal instruction access exception */ +#define sISR_ILGDA 0x00200000 /* illegal data access exception */ +#define sISR_IOIA 0x00400000 /* internal I/O space instruction access excep */ +#define sISR_PRIVA 0x00800000 /* privileged space instruction access excep */ +#define sISR_PRIDA 0x01000000 /* privileged space data access excep */ +#define sISR_DISA 0x02000000 /* data space instruction access excep */ +#define sISR_SYSC 0x04000000 /* system call instruction excep */ +#define sISR_FPUD 0x08000000 /* FPU disabled excep */ +#define sISR_FPUUI 0x10000000 /* FPU unimplemented instruction excep */ +#define sISR_FPUOP 0x20000000 /* FPU operation excep */ +#define sISR_NE 0x80000000 /* multiple synchronous exceptions excep */ + +/* cache control registers */ +#define CHCTR __SYSREG(0xc0000070, u16) /* cache control */ +#define CHCTR_ICEN 0x0001 /* instruction cache enable */ +#define CHCTR_DCEN 0x0002 /* data cache enable */ +#define CHCTR_ICBUSY 0x0004 /* instruction cache busy */ +#define CHCTR_DCBUSY 0x0008 /* data cache busy */ +#define CHCTR_ICINV 0x0010 /* instruction cache invalidate */ +#define CHCTR_DCINV 0x0020 /* data cache invalidate */ +#define CHCTR_DCWTMD 0x0040 /* data cache writing mode */ +#define CHCTR_DCWTMD_WRBACK 0x0000 /* - write back mode */ +#define CHCTR_DCWTMD_WRTHROUGH 0x0040 /* - write through mode */ +#define CHCTR_DCALMD 0x0080 /* data cache allocation mode */ +#define CHCTR_ICWMD 0x0f00 /* instruction cache way mode */ +#define CHCTR_DCWMD 0xf000 /* data cache way mode */ + +#ifdef CONFIG_AM34_2 +#define ICIVCR __SYSREG(0xc0000c00, u32) /* icache area invalidate control */ +#define ICIVCR_ICIVBSY 0x00000008 /* icache area invalidate busy */ +#define ICIVCR_ICI 0x00000001 /* icache area invalidate */ + +#define ICIVMR __SYSREG(0xc0000c04, u32) /* icache area invalidate mask */ + +#define DCPGCR __SYSREG(0xc0000c10, u32) /* data cache area purge control */ +#define DCPGCR_DCPGBSY 0x00000008 /* data cache area purge busy */ +#define DCPGCR_DCP 0x00000002 /* data cache area purge */ +#define DCPGCR_DCI 0x00000001 /* data cache area invalidate */ + +#define DCPGMR __SYSREG(0xc0000c14, u32) /* data cache area purge mask */ +#endif /* CONFIG_AM34_2 */ + +/* MMU control registers */ +#define MMUCTR __SYSREG(0xc0000090, u32) /* MMU control register */ +#define MMUCTR_IRP 0x0000003f /* instruction TLB replace pointer */ +#define MMUCTR_ITE 0x00000040 /* instruction TLB enable */ +#define MMUCTR_IIV 0x00000080 /* instruction TLB invalidate */ +#define MMUCTR_ITL 0x00000700 /* instruction TLB lock pointer */ +#define MMUCTR_ITL_NOLOCK 0x00000000 /* - no lock */ +#define MMUCTR_ITL_LOCK0 0x00000100 /* - entry 0 locked */ +#define MMUCTR_ITL_LOCK0_1 0x00000200 /* - entry 0-1 locked */ +#define MMUCTR_ITL_LOCK0_3 0x00000300 /* - entry 0-3 locked */ +#define MMUCTR_ITL_LOCK0_7 0x00000400 /* - entry 0-7 locked */ +#define MMUCTR_ITL_LOCK0_15 0x00000500 /* - entry 0-15 locked */ +#define MMUCTR_CE 0x00008000 /* cacheable bit enable */ +#define MMUCTR_DRP 0x003f0000 /* data TLB replace pointer */ +#define MMUCTR_DTE 0x00400000 /* data TLB enable */ +#define MMUCTR_DIV 0x00800000 /* data TLB invalidate */ +#define MMUCTR_DTL 0x07000000 /* data TLB lock pointer */ +#define MMUCTR_DTL_NOLOCK 0x00000000 /* - no lock */ +#define MMUCTR_DTL_LOCK0 0x01000000 /* - entry 0 locked */ +#define MMUCTR_DTL_LOCK0_1 0x02000000 /* - entry 0-1 locked */ +#define MMUCTR_DTL_LOCK0_3 0x03000000 /* - entry 0-3 locked */ +#define MMUCTR_DTL_LOCK0_7 0x04000000 /* - entry 0-7 locked */ +#define MMUCTR_DTL_LOCK0_15 0x05000000 /* - entry 0-15 locked */ +#ifdef CONFIG_AM34_2 +#define MMUCTR_WTE 0x80000000 /* write-through cache TLB entry bit enable */ +#endif + +#define PIDR __SYSREG(0xc0000094, u16) /* PID register */ +#define PIDR_PID 0x00ff /* process identifier */ + +#define PTBR __SYSREG(0xc0000098, unsigned long) /* Page table base register */ + +#define IPTEL __SYSREG(0xc00000a0, u32) /* instruction TLB entry */ +#define DPTEL __SYSREG(0xc00000b0, u32) /* data TLB entry */ +#define xPTEL_V 0x00000001 /* TLB entry valid */ +#define xPTEL_UNUSED1 0x00000002 /* unused bit */ +#define xPTEL_UNUSED2 0x00000004 /* unused bit */ +#define xPTEL_C 0x00000008 /* cached if set */ +#define xPTEL_PV 0x00000010 /* page valid */ +#define xPTEL_D 0x00000020 /* dirty */ +#define xPTEL_PR 0x000001c0 /* page protection */ +#define xPTEL_PR_ROK 0x00000000 /* - R/O kernel */ +#define xPTEL_PR_RWK 0x00000100 /* - R/W kernel */ +#define xPTEL_PR_ROK_ROU 0x00000080 /* - R/O kernel and R/O user */ +#define xPTEL_PR_RWK_ROU 0x00000180 /* - R/W kernel and R/O user */ +#define xPTEL_PR_RWK_RWU 0x000001c0 /* - R/W kernel and R/W user */ +#define xPTEL_G 0x00000200 /* global (use PID if 0) */ +#define xPTEL_PS 0x00000c00 /* page size */ +#define xPTEL_PS_4Kb 0x00000000 /* - 4Kb page */ +#define xPTEL_PS_128Kb 0x00000400 /* - 128Kb page */ +#define xPTEL_PS_1Kb 0x00000800 /* - 1Kb page */ +#define xPTEL_PS_4Mb 0x00000c00 /* - 4Mb page */ +#define xPTEL_PPN 0xfffff006 /* physical page number */ + +#define IPTEU __SYSREG(0xc00000a4, u32) /* instruction TLB virtual addr */ +#define DPTEU __SYSREG(0xc00000b4, u32) /* data TLB virtual addr */ +#define xPTEU_VPN 0xfffffc00 /* virtual page number */ +#define xPTEU_PID 0x000000ff /* process identifier to which applicable */ + +#define IPTEL2 __SYSREG(0xc00000a8, u32) /* instruction TLB entry */ +#define DPTEL2 __SYSREG(0xc00000b8, u32) /* data TLB entry */ +#define xPTEL2_V 0x00000001 /* TLB entry valid */ +#define xPTEL2_C 0x00000002 /* cacheable */ +#define xPTEL2_PV 0x00000004 /* page valid */ +#define xPTEL2_D 0x00000008 /* dirty */ +#define xPTEL2_PR 0x00000070 /* page protection */ +#define xPTEL2_PR_ROK 0x00000000 /* - R/O kernel */ +#define xPTEL2_PR_RWK 0x00000040 /* - R/W kernel */ +#define xPTEL2_PR_ROK_ROU 0x00000020 /* - R/O kernel and R/O user */ +#define xPTEL2_PR_RWK_ROU 0x00000060 /* - R/W kernel and R/O user */ +#define xPTEL2_PR_RWK_RWU 0x00000070 /* - R/W kernel and R/W user */ +#define xPTEL2_G 0x00000080 /* global (use PID if 0) */ +#define xPTEL2_PS 0x00000300 /* page size */ +#define xPTEL2_PS_4Kb 0x00000000 /* - 4Kb page */ +#define xPTEL2_PS_128Kb 0x00000100 /* - 128Kb page */ +#define xPTEL2_PS_1Kb 0x00000200 /* - 1Kb page */ +#define xPTEL2_PS_4Mb 0x00000300 /* - 4Mb page */ +#define xPTEL2_CWT 0x00000400 /* cacheable write-through */ +#define xPTEL2_UNUSED1 0x00000800 /* unused bit (broadcast mask) */ +#define xPTEL2_PPN 0xfffff000 /* physical page number */ + +#define xPTEL2_V_BIT 0 /* bit numbers corresponding to above masks */ +#define xPTEL2_C_BIT 1 +#define xPTEL2_PV_BIT 2 +#define xPTEL2_D_BIT 3 +#define xPTEL2_G_BIT 7 +#define xPTEL2_UNUSED1_BIT 11 + +#define MMUFCR __SYSREGC(0xc000009c, u32) /* MMU exception cause */ +#define MMUFCR_IFC __SYSREGC(0xc000009c, u16) /* MMU instruction excep cause */ +#define MMUFCR_DFC __SYSREGC(0xc000009e, u16) /* MMU data exception cause */ +#define MMUFCR_xFC_TLBMISS 0x0001 /* TLB miss flag */ +#define MMUFCR_xFC_INITWR 0x0002 /* initial write excep flag */ +#define MMUFCR_xFC_PGINVAL 0x0004 /* page invalid excep flag */ +#define MMUFCR_xFC_PROTVIOL 0x0008 /* protection violation excep flag */ +#define MMUFCR_xFC_ACCESS 0x0010 /* access level flag */ +#define MMUFCR_xFC_ACCESS_USR 0x0000 /* - user mode */ +#define MMUFCR_xFC_ACCESS_SR 0x0010 /* - supervisor mode */ +#define MMUFCR_xFC_TYPE 0x0020 /* access type flag */ +#define MMUFCR_xFC_TYPE_READ 0x0000 /* - read */ +#define MMUFCR_xFC_TYPE_WRITE 0x0020 /* - write */ +#define MMUFCR_xFC_PR 0x01c0 /* page protection flag */ +#define MMUFCR_xFC_PR_ROK 0x0000 /* - R/O kernel */ +#define MMUFCR_xFC_PR_RWK 0x0100 /* - R/W kernel */ +#define MMUFCR_xFC_PR_ROK_ROU 0x0080 /* - R/O kernel and R/O user */ +#define MMUFCR_xFC_PR_RWK_ROU 0x0180 /* - R/W kernel and R/O user */ +#define MMUFCR_xFC_PR_RWK_RWU 0x01c0 /* - R/W kernel and R/W user */ +#define MMUFCR_xFC_ILLADDR 0x0200 /* illegal address excep flag */ + +#ifdef CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT +/* atomic operation registers */ +#define AAR __SYSREG(0xc0000a00, u32) /* cacheable address */ +#define AAR2 __SYSREG(0xc0000a04, u32) /* uncacheable address */ +#define ADR __SYSREG(0xc0000a08, u32) /* data */ +#define ASR __SYSREG(0xc0000a0c, u32) /* status */ +#define AARU __SYSREG(0xd400aa00, u32) /* user address */ +#define ADRU __SYSREG(0xd400aa08, u32) /* user data */ +#define ASRU __SYSREG(0xd400aa0c, u32) /* user status */ + +#define ASR_RW 0x00000008 /* read */ +#define ASR_BW 0x00000004 /* bus error */ +#define ASR_IW 0x00000002 /* interrupt */ +#define ASR_LW 0x00000001 /* bus lock */ + +#define ASRU_RW ASR_RW /* read */ +#define ASRU_BW ASR_BW /* bus error */ +#define ASRU_IW ASR_IW /* interrupt */ +#define ASRU_LW ASR_LW /* bus lock */ + +/* in inline ASM, we stick the base pointer in to a reg and use offsets from + * it */ +#define ATOMIC_OPS_BASE_ADDR 0xc0000a00 +#ifndef __ASSEMBLY__ +asm( + "_AAR = 0\n" + "_AAR2 = 4\n" + "_ADR = 8\n" + "_ASR = 12\n"); +#else +#define _AAR 0 +#define _AAR2 4 +#define _ADR 8 +#define _ASR 12 +#endif + +/* physical page address for userspace atomic operations registers */ +#define USER_ATOMIC_OPS_PAGE_ADDR 0xd400a000 + +#endif /* CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_CPU_REGS_H */ diff --git a/arch/mn10300/include/asm/current.h b/arch/mn10300/include/asm/current.h new file mode 100644 index 000000000..ca6027d83 --- /dev/null +++ b/arch/mn10300/include/asm/current.h @@ -0,0 +1,37 @@ +/* MN10300 Current task structure accessor + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_CURRENT_H +#define _ASM_CURRENT_H + +#include <linux/thread_info.h> + +/* + * dedicate E2 to keeping the current task pointer + */ +#ifdef CONFIG_MN10300_CURRENT_IN_E2 + +register struct task_struct *const current asm("e2") __attribute__((used)); + +#define get_current() current + +extern struct task_struct *__current; + +#else +static inline __attribute__((const)) +struct task_struct *get_current(void) +{ + return current_thread_info()->task; +} + +#define current get_current() +#endif + +#endif /* _ASM_CURRENT_H */ diff --git a/arch/mn10300/include/asm/debugger.h b/arch/mn10300/include/asm/debugger.h new file mode 100644 index 000000000..e1d3b0836 --- /dev/null +++ b/arch/mn10300/include/asm/debugger.h @@ -0,0 +1,43 @@ +/* Kernel debugger for MN10300 + * + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_DEBUGGER_H +#define _ASM_DEBUGGER_H + +#if defined(CONFIG_KERNEL_DEBUGGER) + +extern int debugger_intercept(enum exception_code, int, int, struct pt_regs *); +extern int at_debugger_breakpoint(struct pt_regs *); + +#ifndef CONFIG_MN10300_DEBUGGER_CACHE_NO_FLUSH +extern void debugger_local_cache_flushinv(void); +extern void debugger_local_cache_flushinv_one(u8 *); +#else +static inline void debugger_local_cache_flushinv(void) {} +static inline void debugger_local_cache_flushinv_one(u8 *addr) {} +#endif + +#else /* CONFIG_KERNEL_DEBUGGER */ + +static inline int debugger_intercept(enum exception_code excep, + int signo, int si_code, + struct pt_regs *regs) +{ + return 0; +} + +static inline int at_debugger_breakpoint(struct pt_regs *regs) +{ + return 0; +} + +#endif /* CONFIG_KERNEL_DEBUGGER */ +#endif /* _ASM_DEBUGGER_H */ diff --git a/arch/mn10300/include/asm/delay.h b/arch/mn10300/include/asm/delay.h new file mode 100644 index 000000000..34517b359 --- /dev/null +++ b/arch/mn10300/include/asm/delay.h @@ -0,0 +1,19 @@ +/* MN10300 Uninterruptible delay routines + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_DELAY_H +#define _ASM_DELAY_H + +extern void __udelay(unsigned long usecs); +extern void __delay(unsigned long loops); + +#define udelay(n) __udelay(n) + +#endif /* _ASM_DELAY_H */ diff --git a/arch/mn10300/include/asm/device.h b/arch/mn10300/include/asm/device.h new file mode 100644 index 000000000..f0a4c2564 --- /dev/null +++ b/arch/mn10300/include/asm/device.h @@ -0,0 +1 @@ +#include <asm-generic/device.h> diff --git a/arch/mn10300/include/asm/div64.h b/arch/mn10300/include/asm/div64.h new file mode 100644 index 000000000..503efab2a --- /dev/null +++ b/arch/mn10300/include/asm/div64.h @@ -0,0 +1,115 @@ +/* MN10300 64-bit division + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_DIV64 +#define _ASM_DIV64 + +#include <linux/types.h> + +extern void ____unhandled_size_in_do_div___(void); + +/* + * Beginning with gcc 4.6, the MDR register is represented explicitly. We + * must, therefore, at least explicitly clobber the register when we make + * changes to it. The following assembly fragments *could* be rearranged in + * order to leave the moves to/from the MDR register to the compiler, but the + * gains would be minimal at best. + */ +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) +# define CLOBBER_MDR_CC "mdr", "cc" +#else +# define CLOBBER_MDR_CC "cc" +#endif + +/* + * divide n by base, leaving the result in n and returning the remainder + * - we can do this quite efficiently on the MN10300 by cascading the divides + * through the MDR register + */ +#define do_div(n, base) \ +({ \ + unsigned __rem = 0; \ + if (sizeof(n) <= 4) { \ + asm("mov %1,mdr \n" \ + "divu %2,%0 \n" \ + "mov mdr,%1 \n" \ + : "+r"(n), "=d"(__rem) \ + : "r"(base), "1"(__rem) \ + : CLOBBER_MDR_CC \ + ); \ + } else if (sizeof(n) <= 8) { \ + union { \ + unsigned long long l; \ + u32 w[2]; \ + } __quot; \ + __quot.l = n; \ + asm("mov %0,mdr \n" /* MDR = 0 */ \ + "divu %3,%1 \n" \ + /* __quot.MSL = __div.MSL / base, */ \ + /* MDR = MDR:__div.MSL % base */ \ + "divu %3,%2 \n" \ + /* __quot.LSL = MDR:__div.LSL / base, */ \ + /* MDR = MDR:__div.LSL % base */ \ + "mov mdr,%0 \n" \ + : "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0]) \ + : "r"(base), "0"(__rem), "1"(__quot.w[1]), \ + "2"(__quot.w[0]) \ + : CLOBBER_MDR_CC \ + ); \ + n = __quot.l; \ + } else { \ + ____unhandled_size_in_do_div___(); \ + } \ + __rem; \ +}) + +/* + * do an unsigned 32-bit multiply and divide with intermediate 64-bit product + * so as not to lose accuracy + * - we use the MDR register to hold the MSW of the product + */ +static inline __attribute__((const)) +unsigned __muldiv64u(unsigned val, unsigned mult, unsigned div) +{ + unsigned result; + + asm("mulu %2,%0 \n" /* MDR:val = val*mult */ + "divu %3,%0 \n" /* val = MDR:val/div; + * MDR = MDR:val%div */ + : "=r"(result) + : "0"(val), "ir"(mult), "r"(div) + : CLOBBER_MDR_CC + ); + + return result; +} + +/* + * do a signed 32-bit multiply and divide with intermediate 64-bit product so + * as not to lose accuracy + * - we use the MDR register to hold the MSW of the product + */ +static inline __attribute__((const)) +signed __muldiv64s(signed val, signed mult, signed div) +{ + signed result; + + asm("mul %2,%0 \n" /* MDR:val = val*mult */ + "div %3,%0 \n" /* val = MDR:val/div; + * MDR = MDR:val%div */ + : "=r"(result) + : "0"(val), "ir"(mult), "r"(div) + : CLOBBER_MDR_CC + ); + + return result; +} + +#endif /* _ASM_DIV64 */ diff --git a/arch/mn10300/include/asm/dma-mapping.h b/arch/mn10300/include/asm/dma-mapping.h new file mode 100644 index 000000000..a18abfc55 --- /dev/null +++ b/arch/mn10300/include/asm/dma-mapping.h @@ -0,0 +1,186 @@ +/* DMA mapping routines for the MN10300 arch + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_DMA_MAPPING_H +#define _ASM_DMA_MAPPING_H + +#include <linux/mm.h> +#include <linux/scatterlist.h> + +#include <asm/cache.h> +#include <asm/io.h> + +/* + * See Documentation/DMA-API.txt for the description of how the + * following DMA API should work. + */ + +extern void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, int flag); + +extern void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle); + +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f)) +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent((d), (s), (v), (h)) + +static inline +dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + mn10300_dcache_flush_inv(); + return virt_to_bus(ptr); +} + +static inline +void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +static inline +int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents, + enum dma_data_direction direction) +{ + struct scatterlist *sg; + int i; + + BUG_ON(!valid_dma_direction(direction)); + WARN_ON(nents == 0 || sglist[0].length == 0); + + for_each_sg(sglist, sg, nents, i) { + BUG_ON(!sg_page(sg)); + + sg->dma_address = sg_phys(sg); + } + + mn10300_dcache_flush_inv(); + return nents; +} + +static inline +void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, + enum dma_data_direction direction) +{ + BUG_ON(!valid_dma_direction(direction)); +} + +static inline +dma_addr_t dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + return page_to_bus(page) + offset; +} + +static inline +void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +static inline +void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) +{ +} + +static inline +void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) +{ + mn10300_dcache_flush_inv(); +} + +static inline +void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ +} + +static inline void +dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + mn10300_dcache_flush_inv(); +} + + +static inline +void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, + int nelems, enum dma_data_direction direction) +{ +} + +static inline +void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, + int nelems, enum dma_data_direction direction) +{ + mn10300_dcache_flush_inv(); +} + +static inline +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return 0; +} + +static inline +int dma_supported(struct device *dev, u64 mask) +{ + /* + * we fall back to GFP_DMA when the mask isn't all 1s, so we can't + * guarantee allocations that must be within a tighter range than + * GFP_DMA + */ + if (mask < 0x00ffffff) + return 0; + return 1; +} + +static inline +int dma_set_mask(struct device *dev, u64 mask) +{ + if (!dev->dma_mask || !dma_supported(dev, mask)) + return -EIO; + + *dev->dma_mask = mask; + return 0; +} + +static inline +void dma_cache_sync(void *vaddr, size_t size, + enum dma_data_direction direction) +{ + mn10300_dcache_flush_inv(); +} + +/* Not supported for now */ +static inline int dma_mmap_coherent(struct device *dev, + struct vm_area_struct *vma, void *cpu_addr, + dma_addr_t dma_addr, size_t size) +{ + return -EINVAL; +} + +static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt, + void *cpu_addr, dma_addr_t dma_addr, + size_t size) +{ + return -EINVAL; +} + +#endif diff --git a/arch/mn10300/include/asm/dma.h b/arch/mn10300/include/asm/dma.h new file mode 100644 index 000000000..10b77d462 --- /dev/null +++ b/arch/mn10300/include/asm/dma.h @@ -0,0 +1,117 @@ +/* MN10300 ISA DMA handlers and definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_DMA_H +#define _ASM_DMA_H + +#include <linux/spinlock.h> +#include <asm/io.h> +#include <linux/delay.h> + +#undef MAX_DMA_CHANNELS /* switch off linux/kernel/dma.c */ +#define MAX_DMA_ADDRESS 0xbfffffff + +extern spinlock_t dma_spin_lock; + +static inline unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static inline void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + +/* enable/disable a specific DMA channel */ +static inline void enable_dma(unsigned int dmanr) +{ +} + +static inline void disable_dma(unsigned int dmanr) +{ +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while holding the DMA lock ! --- + */ +static inline void clear_dma_ff(unsigned int dmanr) +{ +} + +/* set mode (above) for a specific DMA channel */ +static inline void set_dma_mode(unsigned int dmanr, char mode) +{ +} + +/* Set only the page register bits of the transfer address. + * This is used for successive transfers when we know the contents of + * the lower 16 bits of the DMA current address register, but a 64k boundary + * may have been crossed. + */ +static inline void set_dma_page(unsigned int dmanr, char pagenr) +{ +} + + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +static inline void set_dma_addr(unsigned int dmanr, unsigned int a) +{ +} + + +/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for + * a specific DMA channel. + * You must ensure the parameters are valid. + * NOTE: from a manual: "the number of transfers is one more + * than the initial word count"! This is taken into account. + * Assumes dma flip-flop is clear. + * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. + */ +static inline void set_dma_count(unsigned int dmanr, unsigned int count) +{ +} + + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +static inline int get_dma_residue(unsigned int dmanr) +{ + return 0; +} + + +/* These are in kernel/dma.c: */ +extern int request_dma(unsigned int dmanr, const char *device_id); +extern void free_dma(unsigned int dmanr); + +/* From PCI */ + +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) +#endif + +#endif /* _ASM_DMA_H */ diff --git a/arch/mn10300/include/asm/dmactl-regs.h b/arch/mn10300/include/asm/dmactl-regs.h new file mode 100644 index 000000000..80337b339 --- /dev/null +++ b/arch/mn10300/include/asm/dmactl-regs.h @@ -0,0 +1,16 @@ +/* MN10300 on-board DMA controller registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_DMACTL_REGS_H +#define _ASM_DMACTL_REGS_H + +#include <proc/dmactl-regs.h> + +#endif /* _ASM_DMACTL_REGS_H */ diff --git a/arch/mn10300/include/asm/elf.h b/arch/mn10300/include/asm/elf.h new file mode 100644 index 000000000..f592d7a9f --- /dev/null +++ b/arch/mn10300/include/asm/elf.h @@ -0,0 +1,153 @@ +/* MN10300 ELF constant and register definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_ELF_H +#define _ASM_ELF_H + +#include <linux/utsname.h> +#include <asm/ptrace.h> +#include <asm/user.h> + +/* + * AM33 relocations + */ +#define R_MN10300_NONE 0 /* No reloc. */ +#define R_MN10300_32 1 /* Direct 32 bit. */ +#define R_MN10300_16 2 /* Direct 16 bit. */ +#define R_MN10300_8 3 /* Direct 8 bit. */ +#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ +#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ +#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ +#define R_MN10300_24 9 /* Direct 24 bit. */ +#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ +#define R_MN10300_SYM_DIFF 33 /* Adjustment when relaxing. */ +#define R_MN10300_ALIGN 34 /* Alignment requirement. */ + +/* + * AM33/AM34 HW Capabilities + */ +#define HWCAP_MN10300_ATOMIC_OP_UNIT 1 /* Has AM34 Atomic Operations */ + + +/* + * ELF register definitions.. + */ +typedef unsigned long elf_greg_t; + +#define ELF_NGREG ((sizeof(struct pt_regs) / sizeof(elf_greg_t)) - 1) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +#define ELF_NFPREG 32 +typedef float elf_fpreg_t; + +typedef struct { + elf_fpreg_t fpregs[ELF_NFPREG]; + u_int32_t fpcr; +} elf_fpregset_t; + +/* + * This is used to ensure we don't load something for the wrong architecture + */ +#define elf_check_arch(x) \ + (((x)->e_machine == EM_CYGNUS_MN10300) || \ + ((x)->e_machine == EM_MN10300)) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2LSB +#define ELF_ARCH EM_MN10300 + +/* + * ELF process initialiser + */ +#define ELF_PLAT_INIT(_r, load_addr) \ +do { \ + struct pt_regs *_ur = current->thread.uregs; \ + _ur->a3 = 0; _ur->a2 = 0; _ur->d3 = 0; _ur->d2 = 0; \ + _ur->mcvf = 0; _ur->mcrl = 0; _ur->mcrh = 0; _ur->mdrq = 0; \ + _ur->e1 = 0; _ur->e0 = 0; _ur->e7 = 0; _ur->e6 = 0; \ + _ur->e5 = 0; _ur->e4 = 0; _ur->e3 = 0; _ur->e2 = 0; \ + _ur->lar = 0; _ur->lir = 0; _ur->mdr = 0; \ + _ur->a1 = 0; _ur->a0 = 0; _ur->d1 = 0; _ur->d0 = 0; \ +} while (0) + +#define CORE_DUMP_USE_REGSET +#define ELF_EXEC_PAGESIZE 4096 + +/* + * This is the location that an ET_DYN program is loaded if exec'ed. Typical + * use of this is to invoke "./ld.so someprog" to test out a new version of + * the loader. We need to make sure that it is out of the way of the program + * that it will "exec", and that there is sufficient room for the brk. + * - must clear the VMALLOC area + */ +#define ELF_ET_DYN_BASE 0x04000000 + +/* + * regs is struct pt_regs, pr_reg is elf_gregset_t (which is + * now struct user_regs, they are different) + * - ELF_CORE_COPY_REGS has been guessed, and may be wrong + */ +#define ELF_CORE_COPY_REGS(pr_reg, regs) \ +do { \ + pr_reg[0] = regs->a3; \ + pr_reg[1] = regs->a2; \ + pr_reg[2] = regs->d3; \ + pr_reg[3] = regs->d2; \ + pr_reg[4] = regs->mcvf; \ + pr_reg[5] = regs->mcrl; \ + pr_reg[6] = regs->mcrh; \ + pr_reg[7] = regs->mdrq; \ + pr_reg[8] = regs->e1; \ + pr_reg[9] = regs->e0; \ + pr_reg[10] = regs->e7; \ + pr_reg[11] = regs->e6; \ + pr_reg[12] = regs->e5; \ + pr_reg[13] = regs->e4; \ + pr_reg[14] = regs->e3; \ + pr_reg[15] = regs->e2; \ + pr_reg[16] = regs->sp; \ + pr_reg[17] = regs->lar; \ + pr_reg[18] = regs->lir; \ + pr_reg[19] = regs->mdr; \ + pr_reg[20] = regs->a1; \ + pr_reg[21] = regs->a0; \ + pr_reg[22] = regs->d1; \ + pr_reg[23] = regs->d0; \ + pr_reg[24] = regs->orig_d0; \ + pr_reg[25] = regs->epsw; \ + pr_reg[26] = regs->pc; \ +} while (0); + +/* + * This yields a mask that user programs can use to figure out what + * instruction set this CPU supports. This could be done in user space, + * but it's not easy, and we've already done it here. + */ +#ifdef CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT +#define ELF_HWCAP (HWCAP_MN10300_ATOMIC_OP_UNIT) +#else +#define ELF_HWCAP (0) +#endif + +/* + * This yields a string that ld.so will use to load implementation + * specific libraries for optimization. This is more specific in + * intent than poking at uname or /proc/cpuinfo. + * + * For the moment, we have only optimizations for the Intel generations, + * but that could change... + */ +#define ELF_PLATFORM (NULL) + +#endif /* _ASM_ELF_H */ diff --git a/arch/mn10300/include/asm/emergency-restart.h b/arch/mn10300/include/asm/emergency-restart.h new file mode 100644 index 000000000..3711bd9d5 --- /dev/null +++ b/arch/mn10300/include/asm/emergency-restart.h @@ -0,0 +1 @@ +#include <asm-generic/emergency-restart.h> diff --git a/arch/mn10300/include/asm/exceptions.h b/arch/mn10300/include/asm/exceptions.h new file mode 100644 index 000000000..95a4d42c3 --- /dev/null +++ b/arch/mn10300/include/asm/exceptions.h @@ -0,0 +1,121 @@ +/* MN10300 Microcontroller core exceptions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_EXCEPTIONS_H +#define _ASM_EXCEPTIONS_H + +#include <linux/linkage.h> + +/* + * define the breakpoint instruction opcode to use + * - note that the JTAG unit steals 0xFF, so you can't use JTAG and GDBSTUB at + * the same time. + */ +#define GDBSTUB_BKPT 0xFF + +#ifndef __ASSEMBLY__ + +/* + * enumeration of exception codes (as extracted from TBR MSW) + */ +enum exception_code { + EXCEP_RESET = 0x000000, /* reset */ + + /* MMU exceptions */ + EXCEP_ITLBMISS = 0x000100, /* instruction TLB miss */ + EXCEP_DTLBMISS = 0x000108, /* data TLB miss */ + EXCEP_IAERROR = 0x000110, /* instruction address */ + EXCEP_DAERROR = 0x000118, /* data address */ + + /* system exceptions */ + EXCEP_TRAP = 0x000128, /* program interrupt (PI instruction) */ + EXCEP_ISTEP = 0x000130, /* single step */ + EXCEP_IBREAK = 0x000150, /* instruction breakpoint */ + EXCEP_OBREAK = 0x000158, /* operand breakpoint */ + EXCEP_PRIVINS = 0x000160, /* privileged instruction execution */ + EXCEP_UNIMPINS = 0x000168, /* unimplemented instruction execution */ + EXCEP_UNIMPEXINS = 0x000170, /* unimplemented extended instruction execution */ + EXCEP_MEMERR = 0x000178, /* illegal memory access */ + EXCEP_MISALIGN = 0x000180, /* misalignment */ + EXCEP_BUSERROR = 0x000188, /* bus error */ + EXCEP_ILLINSACC = 0x000190, /* illegal instruction access */ + EXCEP_ILLDATACC = 0x000198, /* illegal data access */ + EXCEP_IOINSACC = 0x0001a0, /* I/O space instruction access */ + EXCEP_PRIVINSACC = 0x0001a8, /* privileged space instruction access */ + EXCEP_PRIVDATACC = 0x0001b0, /* privileged space data access */ + EXCEP_DATINSACC = 0x0001b8, /* data space instruction access */ + EXCEP_DOUBLE_FAULT = 0x000200, /* double fault */ + + /* FPU exceptions */ + EXCEP_FPU_DISABLED = 0x0001c0, /* FPU disabled */ + EXCEP_FPU_UNIMPINS = 0x0001c8, /* FPU unimplemented operation */ + EXCEP_FPU_OPERATION = 0x0001d0, /* FPU operation */ + + /* interrupts */ + EXCEP_WDT = 0x000240, /* watchdog timer overflow */ + EXCEP_NMI = 0x000248, /* non-maskable interrupt */ + EXCEP_IRQ_LEVEL0 = 0x000280, /* level 0 maskable interrupt */ + EXCEP_IRQ_LEVEL1 = 0x000288, /* level 1 maskable interrupt */ + EXCEP_IRQ_LEVEL2 = 0x000290, /* level 2 maskable interrupt */ + EXCEP_IRQ_LEVEL3 = 0x000298, /* level 3 maskable interrupt */ + EXCEP_IRQ_LEVEL4 = 0x0002a0, /* level 4 maskable interrupt */ + EXCEP_IRQ_LEVEL5 = 0x0002a8, /* level 5 maskable interrupt */ + EXCEP_IRQ_LEVEL6 = 0x0002b0, /* level 6 maskable interrupt */ + + /* system calls */ + EXCEP_SYSCALL0 = 0x000300, /* system call 0 */ + EXCEP_SYSCALL1 = 0x000308, /* system call 1 */ + EXCEP_SYSCALL2 = 0x000310, /* system call 2 */ + EXCEP_SYSCALL3 = 0x000318, /* system call 3 */ + EXCEP_SYSCALL4 = 0x000320, /* system call 4 */ + EXCEP_SYSCALL5 = 0x000328, /* system call 5 */ + EXCEP_SYSCALL6 = 0x000330, /* system call 6 */ + EXCEP_SYSCALL7 = 0x000338, /* system call 7 */ + EXCEP_SYSCALL8 = 0x000340, /* system call 8 */ + EXCEP_SYSCALL9 = 0x000348, /* system call 9 */ + EXCEP_SYSCALL10 = 0x000350, /* system call 10 */ + EXCEP_SYSCALL11 = 0x000358, /* system call 11 */ + EXCEP_SYSCALL12 = 0x000360, /* system call 12 */ + EXCEP_SYSCALL13 = 0x000368, /* system call 13 */ + EXCEP_SYSCALL14 = 0x000370, /* system call 14 */ + EXCEP_SYSCALL15 = 0x000378, /* system call 15 */ +}; + +extern void __set_intr_stub(enum exception_code code, void *handler); +extern void set_intr_stub(enum exception_code code, void *handler); + +struct pt_regs; + +extern asmlinkage void __common_exception(void); +extern asmlinkage void itlb_miss(void); +extern asmlinkage void dtlb_miss(void); +extern asmlinkage void itlb_aerror(void); +extern asmlinkage void dtlb_aerror(void); +extern asmlinkage void raw_bus_error(void); +extern asmlinkage void double_fault(void); +extern asmlinkage int system_call(struct pt_regs *); +extern asmlinkage void nmi(struct pt_regs *, enum exception_code); +extern asmlinkage void uninitialised_exception(struct pt_regs *, + enum exception_code); +extern asmlinkage void irq_handler(void); +extern asmlinkage void profile_handler(void); +extern asmlinkage void nmi_handler(void); +extern asmlinkage void misalignment(struct pt_regs *, enum exception_code); + +extern void die(const char *, struct pt_regs *, enum exception_code) + __noreturn; + +extern int die_if_no_fixup(const char *, struct pt_regs *, enum exception_code); + +#define NUM2EXCEP_IRQ_LEVEL(num) (EXCEP_IRQ_LEVEL0 + (num) * 8) + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_EXCEPTIONS_H */ diff --git a/arch/mn10300/include/asm/fb.h b/arch/mn10300/include/asm/fb.h new file mode 100644 index 000000000..697b24a91 --- /dev/null +++ b/arch/mn10300/include/asm/fb.h @@ -0,0 +1,23 @@ +/* MN10300 Frame buffer stuff + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_FB_H +#define _ASM_FB_H + +#include <linux/fb.h> + +#define fb_pgprotect(...) do {} while (0) + +static inline int fb_is_primary_device(struct fb_info *info) +{ + return 0; +} + +#endif /* _ASM_FB_H */ diff --git a/arch/mn10300/include/asm/fpu.h b/arch/mn10300/include/asm/fpu.h new file mode 100644 index 000000000..738ff7265 --- /dev/null +++ b/arch/mn10300/include/asm/fpu.h @@ -0,0 +1,134 @@ +/* MN10300 FPU definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * Derived from include/asm-i386/i387.h: Copyright (C) 1994 Linus Torvalds + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_FPU_H +#define _ASM_FPU_H + +#ifndef __ASSEMBLY__ + +#include <linux/sched.h> +#include <asm/exceptions.h> +#include <asm/sigcontext.h> + +#ifdef __KERNEL__ + +extern asmlinkage void fpu_disabled(void); + +#ifdef CONFIG_FPU + +#ifdef CONFIG_LAZY_SAVE_FPU +/* the task that currently owns the FPU state */ +extern struct task_struct *fpu_state_owner; +#endif + +#if (THREAD_USING_FPU & ~0xff) +#error THREAD_USING_FPU must be smaller than 0x100. +#endif + +static inline void set_using_fpu(struct task_struct *tsk) +{ + asm volatile( + "bset %0,(0,%1)" + : + : "i"(THREAD_USING_FPU), "a"(&tsk->thread.fpu_flags) + : "memory", "cc"); +} + +static inline void clear_using_fpu(struct task_struct *tsk) +{ + asm volatile( + "bclr %0,(0,%1)" + : + : "i"(THREAD_USING_FPU), "a"(&tsk->thread.fpu_flags) + : "memory", "cc"); +} + +#define is_using_fpu(tsk) ((tsk)->thread.fpu_flags & THREAD_USING_FPU) + +extern asmlinkage void fpu_kill_state(struct task_struct *); +extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code); +extern asmlinkage void fpu_init_state(void); +extern asmlinkage void fpu_save(struct fpu_state_struct *); +extern int fpu_setup_sigcontext(struct fpucontext *buf); +extern int fpu_restore_sigcontext(struct fpucontext *buf); + +static inline void unlazy_fpu(struct task_struct *tsk) +{ + preempt_disable(); +#ifndef CONFIG_LAZY_SAVE_FPU + if (tsk->thread.fpu_flags & THREAD_HAS_FPU) { + fpu_save(&tsk->thread.fpu_state); + tsk->thread.fpu_flags &= ~THREAD_HAS_FPU; + tsk->thread.uregs->epsw &= ~EPSW_FE; + } +#else + if (fpu_state_owner == tsk) + fpu_save(&tsk->thread.fpu_state); +#endif + preempt_enable(); +} + +static inline void exit_fpu(void) +{ +#ifdef CONFIG_LAZY_SAVE_FPU + struct task_struct *tsk = current; + + preempt_disable(); + if (fpu_state_owner == tsk) + fpu_state_owner = NULL; + preempt_enable(); +#endif +} + +static inline void flush_fpu(void) +{ + struct task_struct *tsk = current; + + preempt_disable(); +#ifndef CONFIG_LAZY_SAVE_FPU + if (tsk->thread.fpu_flags & THREAD_HAS_FPU) { + tsk->thread.fpu_flags &= ~THREAD_HAS_FPU; + tsk->thread.uregs->epsw &= ~EPSW_FE; + } +#else + if (fpu_state_owner == tsk) { + fpu_state_owner = NULL; + tsk->thread.uregs->epsw &= ~EPSW_FE; + } +#endif + preempt_enable(); + clear_using_fpu(tsk); +} + +#else /* CONFIG_FPU */ + +extern asmlinkage +void unexpected_fpu_exception(struct pt_regs *, enum exception_code); +#define fpu_exception unexpected_fpu_exception + +struct task_struct; +struct fpu_state_struct; +static inline bool is_using_fpu(struct task_struct *tsk) { return false; } +static inline void set_using_fpu(struct task_struct *tsk) {} +static inline void clear_using_fpu(struct task_struct *tsk) {} +static inline void fpu_init_state(void) {} +static inline void fpu_save(struct fpu_state_struct *s) {} +static inline void fpu_kill_state(struct task_struct *tsk) {} +static inline void unlazy_fpu(struct task_struct *tsk) {} +static inline void exit_fpu(void) {} +static inline void flush_fpu(void) {} +static inline int fpu_setup_sigcontext(struct fpucontext *buf) { return 0; } +static inline int fpu_restore_sigcontext(struct fpucontext *buf) { return 0; } +#endif /* CONFIG_FPU */ + +#endif /* __KERNEL__ */ +#endif /* !__ASSEMBLY__ */ +#endif /* _ASM_FPU_H */ diff --git a/arch/mn10300/include/asm/frame.inc b/arch/mn10300/include/asm/frame.inc new file mode 100644 index 000000000..1c3eb4fda --- /dev/null +++ b/arch/mn10300/include/asm/frame.inc @@ -0,0 +1,97 @@ +/* MN10300 Microcontroller core system register definitions -*- asm -*- + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_FRAME_INC +#define _ASM_FRAME_INC + +#ifndef __ASSEMBLY__ +#error not for use in C files +#endif + +#ifndef __ASM_OFFSETS_H__ +#include <asm/asm-offsets.h> +#endif +#include <asm/thread_info.h> + +#define pi break + +#define fp a3 + +############################################################################### +# +# build a stack frame from the registers +# - the caller has subtracted 4 from SP before coming here +# +############################################################################### +.macro SAVE_ALL + add -4,sp # next exception frame ptr save area + movm [other],(sp) + mov usp,a1 + mov a1,(sp) # USP in MOVM[other] dummy slot + movm [d2,d3,a2,a3,exreg0,exreg1,exother],(sp) + mov sp,fp # FRAME pointer in A3 + add -12,sp # allow for calls to be made + + # push the exception frame onto the front of the list + GET_THREAD_INFO a1 + mov (TI_frame,a1),a0 + mov a0,(REG_NEXT,fp) + mov fp,(TI_frame,a1) + + # disable the FPU inside the kernel + and ~EPSW_FE,epsw + + # we may be holding current in E2 +#ifdef CONFIG_MN10300_CURRENT_IN_E2 + mov (__current),e2 +#endif +.endm + +############################################################################### +# +# restore the registers from a stack frame +# +############################################################################### +.macro RESTORE_ALL + # peel back the stack to the calling frame + # - we need that when returning from interrupts to kernel mode + GET_THREAD_INFO a0 + mov (TI_frame,a0),fp + mov fp,sp + mov (REG_NEXT,fp),d0 + mov d0,(TI_frame,a0) # userspace has regs->next == 0 + +#ifndef CONFIG_MN10300_USING_JTAG + mov (REG_EPSW,fp),d0 + btst EPSW_T,d0 + beq 99f + + or EPSW_NMID,epsw + movhu (DCR),d1 + or 0x0001, d1 + movhu d1,(DCR) + +99: +#endif + movm (sp),[d2,d3,a2,a3,exreg0,exreg1,exother] + + # must restore usp even if returning to kernel space, + # when CONFIG_PREEMPT is enabled. + mov (sp),a1 # USP in MOVM[other] dummy slot + mov a1,usp + + movm (sp),[other] + add 8,sp + rti + +.endm + + +#endif /* _ASM_FRAME_INC */ diff --git a/arch/mn10300/include/asm/ftrace.h b/arch/mn10300/include/asm/ftrace.h new file mode 100644 index 000000000..40a8c178f --- /dev/null +++ b/arch/mn10300/include/asm/ftrace.h @@ -0,0 +1 @@ +/* empty */ diff --git a/arch/mn10300/include/asm/futex.h b/arch/mn10300/include/asm/futex.h new file mode 100644 index 000000000..0b745828f --- /dev/null +++ b/arch/mn10300/include/asm/futex.h @@ -0,0 +1 @@ +#include <asm-generic/futex.h> diff --git a/arch/mn10300/include/asm/gdb-stub.h b/arch/mn10300/include/asm/gdb-stub.h new file mode 100644 index 000000000..f5495ad82 --- /dev/null +++ b/arch/mn10300/include/asm/gdb-stub.h @@ -0,0 +1,182 @@ +/* MN10300 Kernel GDB stub definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * - Derived from asm-mips/gdb-stub.h (c) 1995 Andreas Busse + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_GDB_STUB_H +#define _ASM_GDB_STUB_H + +#include <asm/exceptions.h> + +/* + * register ID numbers in GDB remote protocol + */ + +#define GDB_REGID_PC 9 +#define GDB_REGID_FP 7 +#define GDB_REGID_SP 8 + +/* + * virtual stack layout for the GDB exception handler + */ +#define NUMREGS 64 + +#define GDB_FR_D0 (0 * 4) +#define GDB_FR_D1 (1 * 4) +#define GDB_FR_D2 (2 * 4) +#define GDB_FR_D3 (3 * 4) +#define GDB_FR_A0 (4 * 4) +#define GDB_FR_A1 (5 * 4) +#define GDB_FR_A2 (6 * 4) +#define GDB_FR_A3 (7 * 4) + +#define GDB_FR_SP (8 * 4) +#define GDB_FR_PC (9 * 4) +#define GDB_FR_MDR (10 * 4) +#define GDB_FR_EPSW (11 * 4) +#define GDB_FR_LIR (12 * 4) +#define GDB_FR_LAR (13 * 4) +#define GDB_FR_MDRQ (14 * 4) + +#define GDB_FR_E0 (15 * 4) +#define GDB_FR_E1 (16 * 4) +#define GDB_FR_E2 (17 * 4) +#define GDB_FR_E3 (18 * 4) +#define GDB_FR_E4 (19 * 4) +#define GDB_FR_E5 (20 * 4) +#define GDB_FR_E6 (21 * 4) +#define GDB_FR_E7 (22 * 4) + +#define GDB_FR_SSP (23 * 4) +#define GDB_FR_MSP (24 * 4) +#define GDB_FR_USP (25 * 4) +#define GDB_FR_MCRH (26 * 4) +#define GDB_FR_MCRL (27 * 4) +#define GDB_FR_MCVF (28 * 4) + +#define GDB_FR_FPCR (29 * 4) +#define GDB_FR_DUMMY0 (30 * 4) +#define GDB_FR_DUMMY1 (31 * 4) + +#define GDB_FR_FS0 (32 * 4) + +#define GDB_FR_SIZE (NUMREGS * 4) + +#ifndef __ASSEMBLY__ + +/* + * This is the same as above, but for the high-level + * part of the GDB stub. + */ + +struct gdb_regs { + /* saved main processor registers */ + u32 d0, d1, d2, d3, a0, a1, a2, a3; + u32 sp, pc, mdr, epsw, lir, lar, mdrq; + u32 e0, e1, e2, e3, e4, e5, e6, e7; + u32 ssp, msp, usp, mcrh, mcrl, mcvf; + + /* saved floating point registers */ + u32 fpcr, _dummy0, _dummy1; + u32 fs0, fs1, fs2, fs3, fs4, fs5, fs6, fs7; + u32 fs8, fs9, fs10, fs11, fs12, fs13, fs14, fs15; + u32 fs16, fs17, fs18, fs19, fs20, fs21, fs22, fs23; + u32 fs24, fs25, fs26, fs27, fs28, fs29, fs30, fs31; +}; + +/* + * Prototypes + */ +extern void show_registers_only(struct pt_regs *regs); + +extern asmlinkage void gdbstub_init(void); +extern asmlinkage void gdbstub_exit(int status); +extern asmlinkage void gdbstub_io_init(void); +extern asmlinkage void gdbstub_io_set_baud(unsigned baud); +extern asmlinkage int gdbstub_io_rx_char(unsigned char *_ch, int nonblock); +extern asmlinkage void gdbstub_io_tx_char(unsigned char ch); +extern asmlinkage void gdbstub_io_tx_flush(void); + +extern asmlinkage void gdbstub_io_rx_handler(void); +extern asmlinkage void gdbstub_rx_irq(struct pt_regs *, enum exception_code); +extern asmlinkage int gdbstub_intercept(struct pt_regs *, enum exception_code); +extern asmlinkage void gdbstub_exception(struct pt_regs *, enum exception_code); +extern asmlinkage void __gdbstub_bug_trap(void); +extern asmlinkage void __gdbstub_pause(void); + +#ifdef CONFIG_MN10300_CACHE_ENABLED +extern asmlinkage void gdbstub_purge_cache(void); +#else +#define gdbstub_purge_cache() do {} while (0) +#endif + +/* Used to prevent crashes in memory access */ +extern asmlinkage int gdbstub_read_byte(const u8 *, u8 *); +extern asmlinkage int gdbstub_read_word(const u8 *, u8 *); +extern asmlinkage int gdbstub_read_dword(const u8 *, u8 *); +extern asmlinkage int gdbstub_write_byte(u32, u8 *); +extern asmlinkage int gdbstub_write_word(u32, u8 *); +extern asmlinkage int gdbstub_write_dword(u32, u8 *); + +extern asmlinkage void gdbstub_read_byte_guard(void); +extern asmlinkage void gdbstub_read_byte_cont(void); +extern asmlinkage void gdbstub_read_word_guard(void); +extern asmlinkage void gdbstub_read_word_cont(void); +extern asmlinkage void gdbstub_read_dword_guard(void); +extern asmlinkage void gdbstub_read_dword_cont(void); +extern asmlinkage void gdbstub_write_byte_guard(void); +extern asmlinkage void gdbstub_write_byte_cont(void); +extern asmlinkage void gdbstub_write_word_guard(void); +extern asmlinkage void gdbstub_write_word_cont(void); +extern asmlinkage void gdbstub_write_dword_guard(void); +extern asmlinkage void gdbstub_write_dword_cont(void); + +extern u8 gdbstub_rx_buffer[PAGE_SIZE]; +extern u32 gdbstub_rx_inp; +extern u32 gdbstub_rx_outp; +extern u8 gdbstub_rx_overflow; +extern u8 gdbstub_busy; +extern u8 gdbstub_rx_unget; + +#ifdef CONFIG_GDBSTUB_DEBUGGING +extern void gdbstub_printk(const char *fmt, ...) + __attribute__((format(printf, 1, 2))); +#else +static inline __attribute__((format(printf, 1, 2))) +void gdbstub_printk(const char *fmt, ...) +{ +} +#endif + +#ifdef CONFIG_GDBSTUB_DEBUG_ENTRY +#define gdbstub_entry(FMT, ...) gdbstub_printk(FMT, ##__VA_ARGS__) +#else +#define gdbstub_entry(FMT, ...) no_printk(FMT, ##__VA_ARGS__) +#endif + +#ifdef CONFIG_GDBSTUB_DEBUG_PROTOCOL +#define gdbstub_proto(FMT, ...) gdbstub_printk(FMT, ##__VA_ARGS__) +#else +#define gdbstub_proto(FMT, ...) no_printk(FMT, ##__VA_ARGS__) +#endif + +#ifdef CONFIG_GDBSTUB_DEBUG_IO +#define gdbstub_io(FMT, ...) gdbstub_printk(FMT, ##__VA_ARGS__) +#else +#define gdbstub_io(FMT, ...) no_printk(FMT, ##__VA_ARGS__) +#endif + +#ifdef CONFIG_GDBSTUB_DEBUG_BREAKPOINT +#define gdbstub_bkpt(FMT, ...) gdbstub_printk(FMT, ##__VA_ARGS__) +#else +#define gdbstub_bkpt(FMT, ...) no_printk(FMT, ##__VA_ARGS__) +#endif + +#endif /* !__ASSEMBLY__ */ +#endif /* _ASM_GDB_STUB_H */ diff --git a/arch/mn10300/include/asm/hardirq.h b/arch/mn10300/include/asm/hardirq.h new file mode 100644 index 000000000..0000d650b --- /dev/null +++ b/arch/mn10300/include/asm/hardirq.h @@ -0,0 +1,49 @@ +/* MN10300 Hardware IRQ statistics and management + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Modified by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_HARDIRQ_H +#define _ASM_HARDIRQ_H + +#include <linux/threads.h> +#include <linux/irq.h> +#include <asm/exceptions.h> + +/* assembly code in softirq.h is sensitive to the offsets of these fields */ +typedef struct { + unsigned int __softirq_pending; +#ifdef CONFIG_MN10300_WD_TIMER + unsigned int __nmi_count; /* arch dependent */ + unsigned int __irq_count; /* arch dependent */ +#endif +} ____cacheline_aligned irq_cpustat_t; + +#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ + +extern void ack_bad_irq(int irq); + +/* + * manipulate stubs in the MN10300 CPU Trap/Interrupt Vector table + * - these should jump to __common_exception in entry.S unless there's a good + * reason to do otherwise (see trap_preinit() in traps.c) + */ +typedef void (*intr_stub_fnx)(struct pt_regs *regs, + enum exception_code intcode); + +/* + * manipulate pointers in the Exception table (see entry.S) + * - these are indexed by decoding the lower 24 bits of the TBR register + * - note that the MN103E010 doesn't always trap through the correct vector, + * but does always set the TBR correctly + */ +extern asmlinkage void set_excp_vector(enum exception_code code, + intr_stub_fnx handler); + +#endif /* _ASM_HARDIRQ_H */ diff --git a/arch/mn10300/include/asm/highmem.h b/arch/mn10300/include/asm/highmem.h new file mode 100644 index 000000000..2fbbe4d92 --- /dev/null +++ b/arch/mn10300/include/asm/highmem.h @@ -0,0 +1,128 @@ +/* MN10300 Virtual kernel memory mappings for high memory + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * - Derived from include/asm-i386/highmem.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_HIGHMEM_H +#define _ASM_HIGHMEM_H + +#ifdef __KERNEL__ + +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/highmem.h> +#include <asm/kmap_types.h> +#include <asm/pgtable.h> + +/* undef for production */ +#undef HIGHMEM_DEBUG + +/* declarations for highmem.c */ +extern unsigned long highstart_pfn, highend_pfn; + +extern pte_t *kmap_pte; +extern pgprot_t kmap_prot; +extern pte_t *pkmap_page_table; + +extern void __init kmap_init(void); + +/* + * Right now we initialize only a single pte table. It can be extended + * easily, subsequent pte tables have to be allocated in one physical + * chunk of RAM. + */ +#define PKMAP_BASE 0xfe000000UL +#define LAST_PKMAP 1024 +#define LAST_PKMAP_MASK (LAST_PKMAP - 1) +#define PKMAP_NR(virt) ((virt - PKMAP_BASE) >> PAGE_SHIFT) +#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) + +extern unsigned long kmap_high(struct page *page); +extern void kunmap_high(struct page *page); + +static inline unsigned long kmap(struct page *page) +{ + if (in_interrupt()) + BUG(); + if (page < highmem_start_page) + return page_address(page); + return kmap_high(page); +} + +static inline void kunmap(struct page *page) +{ + if (in_interrupt()) + BUG(); + if (page < highmem_start_page) + return; + kunmap_high(page); +} + +/* + * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap + * gives a more generic (and caching) interface. But kmap_atomic can + * be used in IRQ contexts, so in some (very limited) cases we need + * it. + */ +static inline void *kmap_atomic(struct page *page) +{ + unsigned long vaddr; + int idx, type; + + pagefault_disable(); + if (page < highmem_start_page) + return page_address(page); + + type = kmap_atomic_idx_push(); + idx = type + KM_TYPE_NR * smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +#if HIGHMEM_DEBUG + if (!pte_none(*(kmap_pte - idx))) + BUG(); +#endif + set_pte(kmap_pte - idx, mk_pte(page, kmap_prot)); + local_flush_tlb_one(vaddr); + + return (void *)vaddr; +} + +static inline void __kunmap_atomic(unsigned long vaddr) +{ + int type; + + if (vaddr < FIXADDR_START) { /* FIXME */ + pagefault_enable(); + return; + } + + type = kmap_atomic_idx(); + +#if HIGHMEM_DEBUG + { + unsigned int idx; + idx = type + KM_TYPE_NR * smp_processor_id(); + + if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)) + BUG(); + + /* + * force other mappings to Oops if they'll try to access + * this pte without first remap it + */ + pte_clear(kmap_pte - idx); + local_flush_tlb_one(vaddr); + } +#endif + + kmap_atomic_idx_pop(); + pagefault_enable(); +} +#endif /* __KERNEL__ */ + +#endif /* _ASM_HIGHMEM_H */ diff --git a/arch/mn10300/include/asm/hw_irq.h b/arch/mn10300/include/asm/hw_irq.h new file mode 100644 index 000000000..706199010 --- /dev/null +++ b/arch/mn10300/include/asm/hw_irq.h @@ -0,0 +1,14 @@ +/* MN10300 Hardware interrupt definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_HW_IRQ_H +#define _ASM_HW_IRQ_H + +#endif /* _ASM_HW_IRQ_H */ diff --git a/arch/mn10300/include/asm/intctl-regs.h b/arch/mn10300/include/asm/intctl-regs.h new file mode 100644 index 000000000..d65bbeebe --- /dev/null +++ b/arch/mn10300/include/asm/intctl-regs.h @@ -0,0 +1,71 @@ +/* MN10300 On-board interrupt controller registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_INTCTL_REGS_H +#define _ASM_INTCTL_REGS_H + +#include <asm/cpu-regs.h> + +#ifdef __KERNEL__ + +/* + * Interrupt controller registers + * - Registers 64-191 are at addresses offset from the main array + */ +#define GxICR(X) \ + __SYSREG(0xd4000000 + (X) * 4 + \ + (((X) >= 64) && ((X) < 192)) * 0xf00, u16) + +#define GxICR_u8(X) \ + __SYSREG(0xd4000000 + (X) * 4 + \ + (((X) >= 64) && ((X) < 192)) * 0xf00, u8) + +#include <proc/intctl-regs.h> + +#define XIRQ_TRIGGER_LOWLEVEL 0 +#define XIRQ_TRIGGER_HILEVEL 1 +#define XIRQ_TRIGGER_NEGEDGE 2 +#define XIRQ_TRIGGER_POSEDGE 3 + +/* non-maskable interrupt control */ +#define NMIIRQ 0 +#define NMICR GxICR(NMIIRQ) /* NMI control register */ +#define NMICR_NMIF 0x0001 /* NMI pin interrupt flag */ +#define NMICR_WDIF 0x0002 /* watchdog timer overflow flag */ +#define NMICR_ABUSERR 0x0008 /* async bus error flag */ + +/* maskable interrupt control */ +#define GxICR_DETECT 0x0001 /* interrupt detect flag */ +#define GxICR_REQUEST 0x0010 /* interrupt request flag */ +#define GxICR_ENABLE 0x0100 /* interrupt enable flag */ +#define GxICR_LEVEL 0x7000 /* interrupt priority level */ +#define GxICR_LEVEL_0 0x0000 /* - level 0 */ +#define GxICR_LEVEL_1 0x1000 /* - level 1 */ +#define GxICR_LEVEL_2 0x2000 /* - level 2 */ +#define GxICR_LEVEL_3 0x3000 /* - level 3 */ +#define GxICR_LEVEL_4 0x4000 /* - level 4 */ +#define GxICR_LEVEL_5 0x5000 /* - level 5 */ +#define GxICR_LEVEL_6 0x6000 /* - level 6 */ +#define GxICR_LEVEL_SHIFT 12 +#define GxICR_NMI 0x8000 /* nmi request flag */ + +#define NUM2GxICR_LEVEL(num) ((num) << GxICR_LEVEL_SHIFT) + +#ifndef __ASSEMBLY__ +extern void set_intr_level(int irq, u16 level); +extern void mn10300_set_lateack_irq_type(int irq); +#endif + +/* external interrupts */ +#define XIRQxICR(X) GxICR((X)) /* external interrupt control regs */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_INTCTL_REGS_H */ diff --git a/arch/mn10300/include/asm/io.h b/arch/mn10300/include/asm/io.h new file mode 100644 index 000000000..cc4a2ba9e --- /dev/null +++ b/arch/mn10300/include/asm/io.h @@ -0,0 +1,323 @@ +/* MN10300 I/O port emulation and memory-mapped I/O + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_IO_H +#define _ASM_IO_H + +#include <asm/page.h> /* I/O is all done through memory accesses */ +#include <asm/cpu-regs.h> +#include <asm/cacheflush.h> +#include <asm-generic/pci_iomap.h> + +#define mmiowb() do {} while (0) + +/*****************************************************************************/ +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the x86 architecture, we just read/write the + * memory location directly. + */ +static inline u8 readb(const volatile void __iomem *addr) +{ + return *(const volatile u8 *) addr; +} + +static inline u16 readw(const volatile void __iomem *addr) +{ + return *(const volatile u16 *) addr; +} + +static inline u32 readl(const volatile void __iomem *addr) +{ + return *(const volatile u32 *) addr; +} + +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl + +#define readb_relaxed readb +#define readw_relaxed readw +#define readl_relaxed readl + +static inline void writeb(u8 b, volatile void __iomem *addr) +{ + *(volatile u8 *) addr = b; +} + +static inline void writew(u16 b, volatile void __iomem *addr) +{ + *(volatile u16 *) addr = b; +} + +static inline void writel(u32 b, volatile void __iomem *addr) +{ + *(volatile u32 *) addr = b; +} + +#define __raw_writeb writeb +#define __raw_writew writew +#define __raw_writel writel + +#define writeb_relaxed writeb +#define writew_relaxed writew +#define writel_relaxed writel + +/*****************************************************************************/ +/* + * traditional input/output functions + */ +static inline u8 inb_local(unsigned long addr) +{ + return readb((volatile void __iomem *) addr); +} + +static inline void outb_local(u8 b, unsigned long addr) +{ + return writeb(b, (volatile void __iomem *) addr); +} + +static inline u8 inb(unsigned long addr) +{ + return readb((volatile void __iomem *) addr); +} + +static inline u16 inw(unsigned long addr) +{ + return readw((volatile void __iomem *) addr); +} + +static inline u32 inl(unsigned long addr) +{ + return readl((volatile void __iomem *) addr); +} + +static inline void outb(u8 b, unsigned long addr) +{ + return writeb(b, (volatile void __iomem *) addr); +} + +static inline void outw(u16 b, unsigned long addr) +{ + return writew(b, (volatile void __iomem *) addr); +} + +static inline void outl(u32 b, unsigned long addr) +{ + return writel(b, (volatile void __iomem *) addr); +} + +#define inb_p(addr) inb(addr) +#define inw_p(addr) inw(addr) +#define inl_p(addr) inl(addr) +#define outb_p(x, addr) outb((x), (addr)) +#define outw_p(x, addr) outw((x), (addr)) +#define outl_p(x, addr) outl((x), (addr)) + +static inline void insb(unsigned long addr, void *buffer, int count) +{ + if (count) { + u8 *buf = buffer; + do { + u8 x = inb(addr); + *buf++ = x; + } while (--count); + } +} + +static inline void insw(unsigned long addr, void *buffer, int count) +{ + if (count) { + u16 *buf = buffer; + do { + u16 x = inw(addr); + *buf++ = x; + } while (--count); + } +} + +static inline void insl(unsigned long addr, void *buffer, int count) +{ + if (count) { + u32 *buf = buffer; + do { + u32 x = inl(addr); + *buf++ = x; + } while (--count); + } +} + +static inline void outsb(unsigned long addr, const void *buffer, int count) +{ + if (count) { + const u8 *buf = buffer; + do { + outb(*buf++, addr); + } while (--count); + } +} + +static inline void outsw(unsigned long addr, const void *buffer, int count) +{ + if (count) { + const u16 *buf = buffer; + do { + outw(*buf++, addr); + } while (--count); + } +} + +extern void __outsl(unsigned long addr, const void *buffer, int count); +static inline void outsl(unsigned long addr, const void *buffer, int count) +{ + if ((unsigned long) buffer & 0x3) + return __outsl(addr, buffer, count); + + if (count) { + const u32 *buf = buffer; + do { + outl(*buf++, addr); + } while (--count); + } +} + +#define ioread8(addr) readb(addr) +#define ioread16(addr) readw(addr) +#define ioread32(addr) readl(addr) + +#define iowrite8(v, addr) writeb((v), (addr)) +#define iowrite16(v, addr) writew((v), (addr)) +#define iowrite32(v, addr) writel((v), (addr)) + +#define ioread16be(addr) be16_to_cpu(readw(addr)) +#define ioread32be(addr) be32_to_cpu(readl(addr)) +#define iowrite16be(v, addr) writew(cpu_to_be16(v), (addr)) +#define iowrite32be(v, addr) writel(cpu_to_be32(v), (addr)) + +#define ioread8_rep(p, dst, count) \ + insb((unsigned long) (p), (dst), (count)) +#define ioread16_rep(p, dst, count) \ + insw((unsigned long) (p), (dst), (count)) +#define ioread32_rep(p, dst, count) \ + insl((unsigned long) (p), (dst), (count)) + +#define iowrite8_rep(p, src, count) \ + outsb((unsigned long) (p), (src), (count)) +#define iowrite16_rep(p, src, count) \ + outsw((unsigned long) (p), (src), (count)) +#define iowrite32_rep(p, src, count) \ + outsl((unsigned long) (p), (src), (count)) + +#define readsb(p, dst, count) \ + insb((unsigned long) (p), (dst), (count)) +#define readsw(p, dst, count) \ + insw((unsigned long) (p), (dst), (count)) +#define readsl(p, dst, count) \ + insl((unsigned long) (p), (dst), (count)) + +#define writesb(p, src, count) \ + outsb((unsigned long) (p), (src), (count)) +#define writesw(p, src, count) \ + outsw((unsigned long) (p), (src), (count)) +#define writesl(p, src, count) \ + outsl((unsigned long) (p), (src), (count)) + +#define IO_SPACE_LIMIT 0xffffffff + +#ifdef __KERNEL__ + +#include <linux/vmalloc.h> +#define __io_virt(x) ((void *) (x)) + +/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ +struct pci_dev; +static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p) +{ +} + +/* + * Change virtual addresses to physical addresses and vv. + * These are pretty trivial + */ +static inline unsigned long virt_to_phys(volatile void *address) +{ + return __pa(address); +} + +static inline void *phys_to_virt(unsigned long address) +{ + return __va(address); +} + +/* + * Change "struct page" to physical address. + */ +static inline void __iomem *__ioremap(unsigned long offset, unsigned long size, + unsigned long flags) +{ + return (void __iomem *) offset; +} + +static inline void __iomem *ioremap(unsigned long offset, unsigned long size) +{ + return (void __iomem *)(offset & ~0x20000000); +} + +/* + * This one maps high address device memory and turns off caching for that + * area. it's useful if some control registers are in such an area and write + * combining or read caching is not desirable: + */ +static inline void __iomem *ioremap_nocache(unsigned long offset, unsigned long size) +{ + return (void __iomem *) (offset | 0x20000000); +} + +#define ioremap_wc ioremap_nocache + +static inline void iounmap(void __iomem *addr) +{ +} + +static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) +{ + return (void __iomem *) port; +} + +static inline void ioport_unmap(void __iomem *p) +{ +} + +#define xlate_dev_kmem_ptr(p) ((void *) (p)) +#define xlate_dev_mem_ptr(p) ((void *) (p)) + +/* + * PCI bus iomem addresses must be in the region 0x80000000-0x9fffffff + */ +static inline unsigned long virt_to_bus(volatile void *address) +{ + return ((unsigned long) address) & ~0x20000000; +} + +static inline void *bus_to_virt(unsigned long address) +{ + return (void *) address; +} + +#define page_to_bus page_to_phys + +#define memset_io(a, b, c) memset(__io_virt(a), (b), (c)) +#define memcpy_fromio(a, b, c) memcpy((a), __io_virt(b), (c)) +#define memcpy_toio(a, b, c) memcpy(__io_virt(a), (b), (c)) + +#endif /* __KERNEL__ */ + +#endif /* _ASM_IO_H */ diff --git a/arch/mn10300/include/asm/irq.h b/arch/mn10300/include/asm/irq.h new file mode 100644 index 000000000..1a73fb3f6 --- /dev/null +++ b/arch/mn10300/include/asm/irq.h @@ -0,0 +1,40 @@ +/* MN10300 Hardware interrupt definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Modified by David Howells (dhowells@redhat.com) + * - Derived from include/asm-i386/irq.h: + * - (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_IRQ_H +#define _ASM_IRQ_H + +#include <asm/intctl-regs.h> +#include <asm/reset-regs.h> +#include <proc/irq.h> + +/* this number is used when no interrupt has been assigned */ +#define NO_IRQ INT_MAX + +/* + * hardware irq numbers + * - the ASB2364 has an FPGA with an IRQ multiplexer on it + */ +#ifdef CONFIG_MN10300_UNIT_ASB2364 +#include <unit/irq.h> +#else +#define NR_CPU_IRQS GxICR_NUM_IRQS +#define NR_IRQS NR_CPU_IRQS +#endif + +/* external hardware irq numbers */ +#define NR_XIRQS GxICR_NUM_XIRQS + +#define irq_canonicalize(IRQ) (IRQ) + +#endif /* _ASM_IRQ_H */ diff --git a/arch/mn10300/include/asm/irq_regs.h b/arch/mn10300/include/asm/irq_regs.h new file mode 100644 index 000000000..97d0cb5af --- /dev/null +++ b/arch/mn10300/include/asm/irq_regs.h @@ -0,0 +1,28 @@ +/* MN10300 IRQ registers pointer definition + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_IRQ_REGS_H +#define _ASM_IRQ_REGS_H + +/* + * Per-cpu current frame pointer - the location of the last exception frame on + * the stack + */ +#define ARCH_HAS_OWN_IRQ_REGS + +#ifndef __ASSEMBLY__ +static inline __attribute__((const)) +struct pt_regs *get_irq_regs(void) +{ + return current_frame(); +} +#endif + +#endif /* _ASM_IRQ_REGS_H */ diff --git a/arch/mn10300/include/asm/irqflags.h b/arch/mn10300/include/asm/irqflags.h new file mode 100644 index 000000000..8730c0a3c --- /dev/null +++ b/arch/mn10300/include/asm/irqflags.h @@ -0,0 +1,215 @@ +/* MN10300 IRQ flag handling + * + * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_IRQFLAGS_H +#define _ASM_IRQFLAGS_H + +#include <asm/cpu-regs.h> +/* linux/smp.h <- linux/irqflags.h needs asm/smp.h first */ +#include <asm/smp.h> + +/* + * interrupt control + * - "disabled": run in IM1/2 + * - level 0 - kernel debugger + * - level 1 - virtual serial DMA (if present) + * - level 5 - normal interrupt priority + * - level 6 - timer interrupt + * - "enabled": run in IM7 + */ +#define MN10300_CLI_LEVEL (CONFIG_LINUX_CLI_LEVEL << EPSW_IM_SHIFT) + +#ifndef __ASSEMBLY__ + +static inline unsigned long arch_local_save_flags(void) +{ + unsigned long flags; + + asm volatile("mov epsw,%0" : "=d"(flags)); + return flags; +} + +static inline void arch_local_irq_disable(void) +{ + asm volatile( + " and %0,epsw \n" + " or %1,epsw \n" + " nop \n" + " nop \n" + " nop \n" + : + : "i"(~EPSW_IM), "i"(EPSW_IE | MN10300_CLI_LEVEL) + : "memory"); +} + +static inline unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + + flags = arch_local_save_flags(); + arch_local_irq_disable(); + return flags; +} + +/* + * we make sure arch_irq_enable() doesn't cause priority inversion + */ +extern unsigned long __mn10300_irq_enabled_epsw[]; + +static inline void arch_local_irq_enable(void) +{ + unsigned long tmp; + int cpu = raw_smp_processor_id(); + + asm volatile( + " mov epsw,%0 \n" + " and %1,%0 \n" + " or %2,%0 \n" + " mov %0,epsw \n" + : "=&d"(tmp) + : "i"(~EPSW_IM), "r"(__mn10300_irq_enabled_epsw[cpu]) + : "memory", "cc"); +} + +static inline void arch_local_irq_restore(unsigned long flags) +{ + asm volatile( + " mov %0,epsw \n" + " nop \n" + " nop \n" + " nop \n" + : + : "d"(flags) + : "memory", "cc"); +} + +static inline bool arch_irqs_disabled_flags(unsigned long flags) +{ + return (flags & (EPSW_IE | EPSW_IM)) != (EPSW_IE | EPSW_IM_7); +} + +static inline bool arch_irqs_disabled(void) +{ + return arch_irqs_disabled_flags(arch_local_save_flags()); +} + +/* + * Hook to save power by halting the CPU + * - called from the idle loop + * - must reenable interrupts (which takes three instruction cycles to complete) + */ +static inline void arch_safe_halt(void) +{ +#ifdef CONFIG_SMP + arch_local_irq_enable(); +#else + asm volatile( + " or %0,epsw \n" + " nop \n" + " nop \n" + " bset %2,(%1) \n" + : + : "i"(EPSW_IE|EPSW_IM), "n"(&CPUM), "i"(CPUM_SLEEP) + : "cc"); +#endif +} + +#define __sleep_cpu() \ +do { \ + asm volatile( \ + " bset %1,(%0)\n" \ + "1: btst %1,(%0)\n" \ + " bne 1b\n" \ + : \ + : "i"(&CPUM), "i"(CPUM_SLEEP) \ + : "cc" \ + ); \ +} while (0) + +static inline void arch_local_cli(void) +{ + asm volatile( + " and %0,epsw \n" + " nop \n" + " nop \n" + " nop \n" + : + : "i"(~EPSW_IE) + : "memory" + ); +} + +static inline unsigned long arch_local_cli_save(void) +{ + unsigned long flags = arch_local_save_flags(); + arch_local_cli(); + return flags; +} + +static inline void arch_local_sti(void) +{ + asm volatile( + " or %0,epsw \n" + : + : "i"(EPSW_IE) + : "memory"); +} + +static inline void arch_local_change_intr_mask_level(unsigned long level) +{ + asm volatile( + " and %0,epsw \n" + " or %1,epsw \n" + : + : "i"(~EPSW_IM), "i"(EPSW_IE | level) + : "cc", "memory"); +} + +#else /* !__ASSEMBLY__ */ + +#define LOCAL_SAVE_FLAGS(reg) \ + mov epsw,reg + +#define LOCAL_IRQ_DISABLE \ + and ~EPSW_IM,epsw; \ + or EPSW_IE|MN10300_CLI_LEVEL,epsw; \ + nop; \ + nop; \ + nop + +#define LOCAL_IRQ_ENABLE \ + or EPSW_IE|EPSW_IM_7,epsw + +#define LOCAL_IRQ_RESTORE(reg) \ + mov reg,epsw + +#define LOCAL_CLI_SAVE(reg) \ + mov epsw,reg; \ + and ~EPSW_IE,epsw; \ + nop; \ + nop; \ + nop + +#define LOCAL_CLI \ + and ~EPSW_IE,epsw; \ + nop; \ + nop; \ + nop + +#define LOCAL_STI \ + or EPSW_IE,epsw + +#define LOCAL_CHANGE_INTR_MASK_LEVEL(level) \ + and ~EPSW_IM,epsw; \ + or EPSW_IE|(level),epsw + +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_IRQFLAGS_H */ diff --git a/arch/mn10300/include/asm/kdebug.h b/arch/mn10300/include/asm/kdebug.h new file mode 100644 index 000000000..0f47e1121 --- /dev/null +++ b/arch/mn10300/include/asm/kdebug.h @@ -0,0 +1,22 @@ +/* MN10300 In-kernel death knells + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_KDEBUG_H +#define _ASM_KDEBUG_H + +/* Grossly misnamed. */ +enum die_val { + DIE_OOPS = 1, + DIE_BREAKPOINT, + DIE_GPF, +}; + +#endif /* _ASM_KDEBUG_H */ diff --git a/arch/mn10300/include/asm/kgdb.h b/arch/mn10300/include/asm/kgdb.h new file mode 100644 index 000000000..eb245f18a --- /dev/null +++ b/arch/mn10300/include/asm/kgdb.h @@ -0,0 +1,81 @@ +/* Kernel debugger for MN10300 + * + * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_KGDB_H +#define _ASM_KGDB_H + +/* + * BUFMAX defines the maximum number of characters in inbound/outbound + * buffers at least NUMREGBYTES*2 are needed for register packets + * Longer buffer is needed to list all threads + */ +#define BUFMAX 1024 + +/* + * Note that this register image is in a different order than the register + * image that Linux produces at interrupt time. + */ +enum regnames { + GDB_FR_D0 = 0, + GDB_FR_D1 = 1, + GDB_FR_D2 = 2, + GDB_FR_D3 = 3, + GDB_FR_A0 = 4, + GDB_FR_A1 = 5, + GDB_FR_A2 = 6, + GDB_FR_A3 = 7, + + GDB_FR_SP = 8, + GDB_FR_PC = 9, + GDB_FR_MDR = 10, + GDB_FR_EPSW = 11, + GDB_FR_LIR = 12, + GDB_FR_LAR = 13, + GDB_FR_MDRQ = 14, + + GDB_FR_E0 = 15, + GDB_FR_E1 = 16, + GDB_FR_E2 = 17, + GDB_FR_E3 = 18, + GDB_FR_E4 = 19, + GDB_FR_E5 = 20, + GDB_FR_E6 = 21, + GDB_FR_E7 = 22, + + GDB_FR_SSP = 23, + GDB_FR_MSP = 24, + GDB_FR_USP = 25, + GDB_FR_MCRH = 26, + GDB_FR_MCRL = 27, + GDB_FR_MCVF = 28, + + GDB_FR_FPCR = 29, + GDB_FR_DUMMY0 = 30, + GDB_FR_DUMMY1 = 31, + + GDB_FR_FS0 = 32, + + GDB_FR_SIZE = 64, +}; + +#define GDB_ORIG_D0 41 +#define NUMREGBYTES (GDB_FR_SIZE*4) + +static inline void arch_kgdb_breakpoint(void) +{ + asm(".globl __arch_kgdb_breakpoint; __arch_kgdb_breakpoint: break"); +} +extern u8 __arch_kgdb_breakpoint; + +#define BREAK_INSTR_SIZE 1 +#define CACHE_FLUSH_IS_SAFE 1 + +#endif /* _ASM_KGDB_H */ diff --git a/arch/mn10300/include/asm/kmap_types.h b/arch/mn10300/include/asm/kmap_types.h new file mode 100644 index 000000000..76d093b58 --- /dev/null +++ b/arch/mn10300/include/asm/kmap_types.h @@ -0,0 +1,6 @@ +#ifndef _ASM_KMAP_TYPES_H +#define _ASM_KMAP_TYPES_H + +#include <asm-generic/kmap_types.h> + +#endif /* _ASM_KMAP_TYPES_H */ diff --git a/arch/mn10300/include/asm/kprobes.h b/arch/mn10300/include/asm/kprobes.h new file mode 100644 index 000000000..c800b5901 --- /dev/null +++ b/arch/mn10300/include/asm/kprobes.h @@ -0,0 +1,50 @@ +/* MN10300 Kernel Probes support + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by Mark Salter (msalter@redhat.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public Licence as published by + * the Free Software Foundation; either version 2 of the Licence, or + * (at your option) any later version. + * + * This program 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 Licence for more details. + * + * You should have received a copy of the GNU General Public Licence + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ +#ifndef _ASM_KPROBES_H +#define _ASM_KPROBES_H + +#include <linux/types.h> +#include <linux/ptrace.h> + +struct kprobe; + +typedef unsigned char kprobe_opcode_t; +#define BREAKPOINT_INSTRUCTION 0xff +#define MAX_INSN_SIZE 8 +#define MAX_STACK_SIZE 128 + +/* Architecture specific copy of original instruction */ +struct arch_specific_insn { + /* copy of original instruction + */ + kprobe_opcode_t insn[MAX_INSN_SIZE]; +}; + +extern const int kretprobe_blacklist_size; + +extern int kprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data); + +#define flush_insn_slot(p) do {} while (0) + +extern void arch_remove_kprobe(struct kprobe *p); + +#endif /* _ASM_KPROBES_H */ diff --git a/arch/mn10300/include/asm/linkage.h b/arch/mn10300/include/asm/linkage.h new file mode 100644 index 000000000..dda3002a5 --- /dev/null +++ b/arch/mn10300/include/asm/linkage.h @@ -0,0 +1,20 @@ +/* MN10300 Linkage and calling-convention overrides + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_LINKAGE_H +#define _ASM_LINKAGE_H + +/* don't override anything */ +#define asmlinkage + +#define __ALIGN .align 4,0xcb +#define __ALIGN_STR ".align 4,0xcb" + +#endif diff --git a/arch/mn10300/include/asm/local.h b/arch/mn10300/include/asm/local.h new file mode 100644 index 000000000..c11c530f7 --- /dev/null +++ b/arch/mn10300/include/asm/local.h @@ -0,0 +1 @@ +#include <asm-generic/local.h> diff --git a/arch/mn10300/include/asm/local64.h b/arch/mn10300/include/asm/local64.h new file mode 100644 index 000000000..36c93b5cc --- /dev/null +++ b/arch/mn10300/include/asm/local64.h @@ -0,0 +1 @@ +#include <asm-generic/local64.h> diff --git a/arch/mn10300/include/asm/mc146818rtc.h b/arch/mn10300/include/asm/mc146818rtc.h new file mode 100644 index 000000000..df6bc6e0e --- /dev/null +++ b/arch/mn10300/include/asm/mc146818rtc.h @@ -0,0 +1 @@ +#include <asm/rtc-regs.h> diff --git a/arch/mn10300/include/asm/mmu.h b/arch/mn10300/include/asm/mmu.h new file mode 100644 index 000000000..2d2d097e7 --- /dev/null +++ b/arch/mn10300/include/asm/mmu.h @@ -0,0 +1,19 @@ +/* MN10300 Memory management context + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * - Derived from include/asm-frv/mmu.h + */ + +#ifndef _ASM_MMU_H +#define _ASM_MMU_H + +/* + * MMU context + */ +typedef struct { + unsigned long tlbpid[NR_CPUS]; /* TLB PID for this process on + * each CPU */ +} mm_context_t; + +#endif /* _ASM_MMU_H */ diff --git a/arch/mn10300/include/asm/mmu_context.h b/arch/mn10300/include/asm/mmu_context.h new file mode 100644 index 000000000..75dbe696f --- /dev/null +++ b/arch/mn10300/include/asm/mmu_context.h @@ -0,0 +1,161 @@ +/* MN10300 MMU context management + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Modified by David Howells (dhowells@redhat.com) + * - Derived from include/asm-m32r/mmu_context.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + * + * + * This implements an algorithm to provide TLB PID mappings to provide + * selective access to the TLB for processes, thus reducing the number of TLB + * flushes required. + * + * Note, however, that the M32R algorithm is technically broken as it does not + * handle version wrap-around, and could, theoretically, have a problem with a + * very long lived program that sleeps long enough for the version number to + * wrap all the way around so that its TLB mappings appear valid once again. + */ +#ifndef _ASM_MMU_CONTEXT_H +#define _ASM_MMU_CONTEXT_H + +#include <linux/atomic.h> +#include <asm/pgalloc.h> +#include <asm/tlbflush.h> +#include <asm-generic/mm_hooks.h> + +#define MMU_CONTEXT_TLBPID_NR 256 +#define MMU_CONTEXT_TLBPID_MASK 0x000000ffUL +#define MMU_CONTEXT_VERSION_MASK 0xffffff00UL +#define MMU_CONTEXT_FIRST_VERSION 0x00000100UL +#define MMU_NO_CONTEXT 0x00000000UL +#define MMU_CONTEXT_TLBPID_LOCK_NR 0 + +#define enter_lazy_tlb(mm, tsk) do {} while (0) + +static inline void cpu_ran_vm(int cpu, struct mm_struct *mm) +{ +#ifdef CONFIG_SMP + cpumask_set_cpu(cpu, mm_cpumask(mm)); +#endif +} + +static inline bool cpu_maybe_ran_vm(int cpu, struct mm_struct *mm) +{ +#ifdef CONFIG_SMP + return cpumask_test_and_set_cpu(cpu, mm_cpumask(mm)); +#else + return true; +#endif +} + +#ifdef CONFIG_MN10300_TLB_USE_PIDR +extern unsigned long mmu_context_cache[NR_CPUS]; +#define mm_context(mm) (mm->context.tlbpid[smp_processor_id()]) + +/** + * allocate_mmu_context - Allocate storage for the arch-specific MMU data + * @mm: The userspace VM context being set up + */ +static inline unsigned long allocate_mmu_context(struct mm_struct *mm) +{ + unsigned long *pmc = &mmu_context_cache[smp_processor_id()]; + unsigned long mc = ++(*pmc); + + if (!(mc & MMU_CONTEXT_TLBPID_MASK)) { + /* we exhausted the TLB PIDs of this version on this CPU, so we + * flush this CPU's TLB in its entirety and start new cycle */ + local_flush_tlb_all(); + + /* fix the TLB version if needed (we avoid version #0 so as to + * distinguish MMU_NO_CONTEXT) */ + if (!mc) + *pmc = mc = MMU_CONTEXT_FIRST_VERSION; + } + mm_context(mm) = mc; + return mc; +} + +/* + * get an MMU context if one is needed + */ +static inline unsigned long get_mmu_context(struct mm_struct *mm) +{ + unsigned long mc = MMU_NO_CONTEXT, cache; + + if (mm) { + cache = mmu_context_cache[smp_processor_id()]; + mc = mm_context(mm); + + /* if we have an old version of the context, replace it */ + if ((mc ^ cache) & MMU_CONTEXT_VERSION_MASK) + mc = allocate_mmu_context(mm); + } + return mc; +} + +/* + * initialise the context related info for a new mm_struct instance + */ +static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) +{ + int num_cpus = NR_CPUS, i; + + for (i = 0; i < num_cpus; i++) + mm->context.tlbpid[i] = MMU_NO_CONTEXT; + return 0; +} + +/* + * after we have set current->mm to a new value, this activates the context for + * the new mm so we see the new mappings. + */ +static inline void activate_context(struct mm_struct *mm) +{ + PIDR = get_mmu_context(mm) & MMU_CONTEXT_TLBPID_MASK; +} +#else /* CONFIG_MN10300_TLB_USE_PIDR */ + +#define init_new_context(tsk, mm) (0) +#define activate_context(mm) local_flush_tlb() + +#endif /* CONFIG_MN10300_TLB_USE_PIDR */ + +/** + * destroy_context - Destroy mm context information + * @mm: The MM being destroyed. + * + * Destroy context related info for an mm_struct that is about to be put to + * rest + */ +#define destroy_context(mm) do {} while (0) + +/** + * switch_mm - Change between userspace virtual memory contexts + * @prev: The outgoing MM context. + * @next: The incoming MM context. + * @tsk: The incoming task. + */ +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ + int cpu = smp_processor_id(); + + if (prev != next) { +#ifdef CONFIG_SMP + per_cpu(cpu_tlbstate, cpu).active_mm = next; +#endif + cpu_ran_vm(cpu, next); + PTBR = (unsigned long) next->pgd; + activate_context(next); + } +} + +#define deactivate_mm(tsk, mm) do {} while (0) +#define activate_mm(prev, next) switch_mm((prev), (next), NULL) + +#endif /* _ASM_MMU_CONTEXT_H */ diff --git a/arch/mn10300/include/asm/module.h b/arch/mn10300/include/asm/module.h new file mode 100644 index 000000000..6571103b0 --- /dev/null +++ b/arch/mn10300/include/asm/module.h @@ -0,0 +1,22 @@ +/* MN10300 Arch-specific module definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by Mark Salter (msalter@redhat.com) + * Derived from include/asm-i386/module.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_MODULE_H +#define _ASM_MODULE_H + +#include <asm-generic/module.h> + +/* + * Include the MN10300 architecture version. + */ +#define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " " + +#endif /* _ASM_MODULE_H */ diff --git a/arch/mn10300/include/asm/mutex.h b/arch/mn10300/include/asm/mutex.h new file mode 100644 index 000000000..84f5490c6 --- /dev/null +++ b/arch/mn10300/include/asm/mutex.h @@ -0,0 +1,16 @@ +/* MN10300 Mutex fastpath + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + * + * + * TODO: implement optimized primitives instead, or leave the generic + * implementation in place, or pick the atomic_xchg() based generic + * implementation. (see asm-generic/mutex-xchg.h for details) + */ +#include <asm-generic/mutex-null.h> diff --git a/arch/mn10300/include/asm/nmi.h b/arch/mn10300/include/asm/nmi.h new file mode 100644 index 000000000..f3671cbbc --- /dev/null +++ b/arch/mn10300/include/asm/nmi.h @@ -0,0 +1,14 @@ +/* MN10300 NMI handling + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_NMI_H +#define _ASM_NMI_H + +#endif /* _ASM_NMI_H */ diff --git a/arch/mn10300/include/asm/page.h b/arch/mn10300/include/asm/page.h new file mode 100644 index 000000000..8288e1241 --- /dev/null +++ b/arch/mn10300/include/asm/page.h @@ -0,0 +1,128 @@ +/* MN10300 Page table definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PAGE_H +#define _ASM_PAGE_H + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 + +#ifndef __ASSEMBLY__ +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE - 1)) +#else +#define PAGE_SIZE +(1 << PAGE_SHIFT) /* unary plus marks an + * immediate val not an addr */ +#define PAGE_MASK +(~(PAGE_SIZE - 1)) +#endif + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) +#define copy_page(to, from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) + +#define clear_user_page(addr, vaddr, page) clear_page(addr) +#define copy_user_page(vto, vfrom, vaddr, to) copy_page(vto, vfrom) + +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct page *pgtable_t; + +#define PTE_MASK PAGE_MASK +#define HPAGE_SHIFT 22 + +#ifdef CONFIG_HUGETLB_PAGE +#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) +#define HPAGE_MASK (~(HPAGE_SIZE - 1)) +#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) +#endif + +#define pte_val(x) ((x).pte) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) }) +#define __pgd(x) ((pgd_t) { (x) }) +#define __pgprot(x) ((pgprot_t) { (x) }) + +#include <asm-generic/pgtable-nopmd.h> + +#endif /* !__ASSEMBLY__ */ + +/* + * This handles the memory map.. We could make this a config + * option, but too many people screw it up, and too few need + * it. + * + * A __PAGE_OFFSET of 0xC0000000 means that the kernel has + * a virtual address space of one gigabyte, which limits the + * amount of physical memory you can use to about 950MB. + */ + +#ifndef __ASSEMBLY__ + +/* Pure 2^n version of get_order */ +static inline int get_order(unsigned long size) __attribute__((const)); +static inline int get_order(unsigned long size) +{ + int order; + + size = (size - 1) >> (PAGE_SHIFT - 1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +#endif /* __ASSEMBLY__ */ + +#include <asm/page_offset.h> + +#define __PAGE_OFFSET (PAGE_OFFSET_RAW) +#define PAGE_OFFSET ((unsigned long) __PAGE_OFFSET) + +/* + * main RAM and kernel working space are coincident at 0x90000000, but to make + * life more interesting, there's also an uncached virtual shadow at 0xb0000000 + * - these mappings are fixed in the MMU + */ +#define __pfn_disp (CONFIG_KERNEL_RAM_BASE_ADDRESS >> PAGE_SHIFT) + +#define __pa(x) ((unsigned long)(x)) +#define __va(x) ((void *)(unsigned long)(x)) +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) +#define pfn_to_page(pfn) (mem_map + ((pfn) - __pfn_disp)) +#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + __pfn_disp) + +#define pfn_valid(pfn) \ +({ \ + unsigned long __pfn = (pfn) - __pfn_disp; \ + __pfn < max_mapnr; \ +}) + +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) +#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) + +#define VM_DATA_DEFAULT_FLAGS \ + (VM_READ | VM_WRITE | \ + ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#endif /* __KERNEL__ */ + +#endif /* _ASM_PAGE_H */ diff --git a/arch/mn10300/include/asm/page_offset.h b/arch/mn10300/include/asm/page_offset.h new file mode 100644 index 000000000..8eb5b16ad --- /dev/null +++ b/arch/mn10300/include/asm/page_offset.h @@ -0,0 +1,11 @@ +/* MN10300 Kernel base address + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ +#ifndef _ASM_PAGE_OFFSET_H +#define _ASM_PAGE_OFFSET_H + +#define PAGE_OFFSET_RAW CONFIG_KERNEL_RAM_BASE_ADDRESS + +#endif diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h new file mode 100644 index 000000000..5f70af25c --- /dev/null +++ b/arch/mn10300/include/asm/pci.h @@ -0,0 +1,106 @@ +/* MN10300 PCI definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PCI_H +#define _ASM_PCI_H + +#ifdef __KERNEL__ +#include <linux/mm.h> /* for struct page */ + +#if 0 +#define __pcbdebug(FMT, ADDR, ...) \ + printk(KERN_DEBUG "PCIBRIDGE[%08x]: "FMT"\n", \ + (u32)(ADDR), ##__VA_ARGS__) + +#define __pcidebug(FMT, BUS, DEVFN, WHERE,...) \ +do { \ + printk(KERN_DEBUG "PCI[%02x:%02x.%x + %02x]: "FMT"\n", \ + (BUS)->number, \ + PCI_SLOT(DEVFN), \ + PCI_FUNC(DEVFN), \ + (u32)(WHERE), ##__VA_ARGS__); \ +} while (0) + +#else +#define __pcbdebug(FMT, ADDR, ...) do {} while (0) +#define __pcidebug(FMT, BUS, DEVFN, WHERE, ...) do {} while (0) +#endif + +/* Can be used to override the logic in pci_scan_bus for skipping + * already-configured bus numbers - to be used for buggy BIOSes or + * architectures with incomplete PCI setup by the loader */ + +#ifdef CONFIG_PCI +#define pcibios_assign_all_busses() 1 +extern void unit_pci_init(void); +#else +#define pcibios_assign_all_busses() 0 +#endif + +#define PCIBIOS_MIN_IO 0xBE000004 +#define PCIBIOS_MIN_MEM 0xB8000000 + +void pcibios_set_master(struct pci_dev *dev); + +/* Dynamic DMA mapping stuff. + * i386 has everything mapped statically. + */ + +#include <linux/types.h> +#include <linux/slab.h> +#include <asm/scatterlist.h> +#include <linux/string.h> +#include <asm/io.h> + +struct pci_dev; + +/* The PCI address space does equal the physical memory + * address space. The networking and block device layers use + * this boolean for bounce buffer decisions. + */ +#define PCI_DMA_BUS_IS_PHYS (1) + +/* Return the index of the PCI controller for device. */ +static inline int pci_controller_num(struct pci_dev *dev) +{ + return 0; +} + +#define HAVE_PCI_MMAP +extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, + int write_combine); + +#endif /* __KERNEL__ */ + +/* implement the pci_ DMA API in terms of the generic device dma_ one */ +#include <asm-generic/pci-dma-compat.h> + +static inline struct resource * +pcibios_select_root(struct pci_dev *pdev, struct resource *res) +{ + struct resource *root = NULL; + + if (res->flags & IORESOURCE_IO) + root = &ioport_resource; + if (res->flags & IORESOURCE_MEM) + root = &iomem_resource; + + return root; +} + +static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) +{ + return channel ? 15 : 14; +} + +#include <asm-generic/pci_iomap.h> + +#endif /* _ASM_PCI_H */ diff --git a/arch/mn10300/include/asm/percpu.h b/arch/mn10300/include/asm/percpu.h new file mode 100644 index 000000000..06a959d67 --- /dev/null +++ b/arch/mn10300/include/asm/percpu.h @@ -0,0 +1 @@ +#include <asm-generic/percpu.h> diff --git a/arch/mn10300/include/asm/pgalloc.h b/arch/mn10300/include/asm/pgalloc.h new file mode 100644 index 000000000..0f25d5fa8 --- /dev/null +++ b/arch/mn10300/include/asm/pgalloc.h @@ -0,0 +1,56 @@ +/* MN10300 Page and page table/directory allocation + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PGALLOC_H +#define _ASM_PGALLOC_H + +#include <asm/page.h> +#include <linux/threads.h> +#include <linux/mm.h> /* for struct page */ + +struct mm_struct; +struct page; + +/* attach a page table to a PMD entry */ +#define pmd_populate_kernel(mm, pmd, pte) \ + set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE)) + +static inline +void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte) +{ + set_pmd(pmd, __pmd((page_to_pfn(pte) << PAGE_SHIFT) | _PAGE_TABLE)); +} +#define pmd_pgtable(pmd) pmd_page(pmd) + +/* + * Allocate and free page tables. + */ + +extern pgd_t *pgd_alloc(struct mm_struct *); +extern void pgd_free(struct mm_struct *, pgd_t *); + +extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); +extern struct page *pte_alloc_one(struct mm_struct *, unsigned long); + +static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) +{ + free_page((unsigned long) pte); +} + +static inline void pte_free(struct mm_struct *mm, struct page *pte) +{ + pgtable_page_dtor(pte); + __free_page(pte); +} + + +#define __pte_free_tlb(tlb, pte, addr) tlb_remove_page((tlb), (pte)) + +#endif /* _ASM_PGALLOC_H */ diff --git a/arch/mn10300/include/asm/pgtable.h b/arch/mn10300/include/asm/pgtable.h new file mode 100644 index 000000000..96d3f9deb --- /dev/null +++ b/arch/mn10300/include/asm/pgtable.h @@ -0,0 +1,494 @@ +/* MN10300 Page table manipulators and constants + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + * + * + * The Linux memory management assumes a three-level page table setup. On + * the i386, we use that, but "fold" the mid level into the top-level page + * table, so that we physically have the same two-level page table as the + * i386 mmu expects. + * + * This file contains the functions and defines necessary to modify and use + * the i386 page table tree for the purposes of the MN10300 TLB handler + * functions. + */ +#ifndef _ASM_PGTABLE_H +#define _ASM_PGTABLE_H + +#include <asm/cpu-regs.h> + +#ifndef __ASSEMBLY__ +#include <asm/processor.h> +#include <asm/cache.h> +#include <linux/threads.h> + +#include <asm/bitops.h> + +#include <linux/slab.h> +#include <linux/list.h> +#include <linux/spinlock.h> + +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) +extern unsigned long empty_zero_page[1024]; +extern spinlock_t pgd_lock; +extern struct page *pgd_list; + +extern void pmd_ctor(void *, struct kmem_cache *, unsigned long); +extern void pgtable_cache_init(void); +extern void paging_init(void); + +#endif /* !__ASSEMBLY__ */ + +/* + * The Linux mn10300 paging architecture only implements both the traditional + * 2-level page tables + */ +#define PGDIR_SHIFT 22 +#define PTRS_PER_PGD 1024 +#define PTRS_PER_PUD 1 /* we don't really have any PUD physically */ +#define __PAGETABLE_PUD_FOLDED +#define PTRS_PER_PMD 1 /* we don't really have any PMD physically */ +#define __PAGETABLE_PMD_FOLDED +#define PTRS_PER_PTE 1024 + +#define PGD_SIZE PAGE_SIZE +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE - 1)) + +#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) +#define FIRST_USER_ADDRESS 0UL + +#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT) +#define KERNEL_PGD_PTRS (PTRS_PER_PGD - USER_PGD_PTRS) + +#define TWOLEVEL_PGDIR_SHIFT 22 +#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT) +#define BOOT_KERNEL_PGD_PTRS (1024 - BOOT_USER_PGD_PTRS) + +#ifndef __ASSEMBLY__ +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; +#endif + +/* + * Unfortunately, due to the way the MMU works on the MN10300, the vmalloc VM + * area has to be in the lower half of the virtual address range (the upper + * half is not translated through the TLB). + * + * So in this case, the vmalloc area goes at the bottom of the address map + * (leaving a hole at the very bottom to catch addressing errors), and + * userspace starts immediately above. + * + * The vmalloc() routines also leaves a hole of 4kB between each vmalloced + * area to catch addressing errors. + */ +#ifndef __ASSEMBLY__ +#define VMALLOC_OFFSET (8UL * 1024 * 1024) +#define VMALLOC_START (0x70000000UL) +#define VMALLOC_END (0x7C000000UL) +#else +#define VMALLOC_OFFSET (8 * 1024 * 1024) +#define VMALLOC_START (0x70000000) +#define VMALLOC_END (0x7C000000) +#endif + +#ifndef __ASSEMBLY__ +extern pte_t kernel_vmalloc_ptes[(VMALLOC_END - VMALLOC_START) / PAGE_SIZE]; +#endif + +/* IPTEL2/DPTEL2 bit assignments */ +#define _PAGE_BIT_VALID xPTEL2_V_BIT +#define _PAGE_BIT_CACHE xPTEL2_C_BIT +#define _PAGE_BIT_PRESENT xPTEL2_PV_BIT +#define _PAGE_BIT_DIRTY xPTEL2_D_BIT +#define _PAGE_BIT_GLOBAL xPTEL2_G_BIT +#define _PAGE_BIT_ACCESSED xPTEL2_UNUSED1_BIT /* mustn't be loaded into IPTEL2/DPTEL2 */ + +#define _PAGE_VALID xPTEL2_V +#define _PAGE_CACHE xPTEL2_C +#define _PAGE_PRESENT xPTEL2_PV +#define _PAGE_DIRTY xPTEL2_D +#define _PAGE_PROT xPTEL2_PR +#define _PAGE_PROT_RKNU xPTEL2_PR_ROK +#define _PAGE_PROT_WKNU xPTEL2_PR_RWK +#define _PAGE_PROT_RKRU xPTEL2_PR_ROK_ROU +#define _PAGE_PROT_WKRU xPTEL2_PR_RWK_ROU +#define _PAGE_PROT_WKWU xPTEL2_PR_RWK_RWU +#define _PAGE_GLOBAL xPTEL2_G +#define _PAGE_PS_MASK xPTEL2_PS +#define _PAGE_PS_4Kb xPTEL2_PS_4Kb +#define _PAGE_PS_128Kb xPTEL2_PS_128Kb +#define _PAGE_PS_1Kb xPTEL2_PS_1Kb +#define _PAGE_PS_4Mb xPTEL2_PS_4Mb +#define _PAGE_PSE xPTEL2_PS_4Mb /* 4MB page */ +#define _PAGE_CACHE_WT xPTEL2_CWT +#define _PAGE_ACCESSED xPTEL2_UNUSED1 +#define _PAGE_NX 0 /* no-execute bit */ + +/* If _PAGE_VALID is clear, we use these: */ +#define _PAGE_PROTNONE 0x000 /* If not present */ + +#define __PAGE_PROT_UWAUX 0x010 +#define __PAGE_PROT_USER 0x020 +#define __PAGE_PROT_WRITE 0x040 + +#define _PAGE_PRESENTV (_PAGE_PRESENT|_PAGE_VALID) + +#ifndef __ASSEMBLY__ + +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) + +#define _PAGE_TABLE (_PAGE_PRESENTV | _PAGE_PROT_WKNU | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) + +#define __PAGE_NONE (_PAGE_PRESENTV | _PAGE_PROT_RKNU | _PAGE_ACCESSED | _PAGE_CACHE) +#define __PAGE_SHARED (_PAGE_PRESENTV | _PAGE_PROT_WKWU | _PAGE_ACCESSED | _PAGE_CACHE) +#define __PAGE_COPY (_PAGE_PRESENTV | _PAGE_PROT_RKRU | _PAGE_ACCESSED | _PAGE_CACHE) +#define __PAGE_READONLY (_PAGE_PRESENTV | _PAGE_PROT_RKRU | _PAGE_ACCESSED | _PAGE_CACHE) + +#define PAGE_NONE __pgprot(__PAGE_NONE | _PAGE_NX) +#define PAGE_SHARED_NOEXEC __pgprot(__PAGE_SHARED | _PAGE_NX) +#define PAGE_COPY_NOEXEC __pgprot(__PAGE_COPY | _PAGE_NX) +#define PAGE_READONLY_NOEXEC __pgprot(__PAGE_READONLY | _PAGE_NX) +#define PAGE_SHARED_EXEC __pgprot(__PAGE_SHARED) +#define PAGE_COPY_EXEC __pgprot(__PAGE_COPY) +#define PAGE_READONLY_EXEC __pgprot(__PAGE_READONLY) +#define PAGE_COPY PAGE_COPY_NOEXEC +#define PAGE_READONLY PAGE_READONLY_NOEXEC +#define PAGE_SHARED PAGE_SHARED_EXEC + +#define __PAGE_KERNEL_BASE (_PAGE_PRESENTV | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL) + +#define __PAGE_KERNEL (__PAGE_KERNEL_BASE | _PAGE_PROT_WKNU | _PAGE_CACHE | _PAGE_NX) +#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL_BASE | _PAGE_PROT_WKNU | _PAGE_NX) +#define __PAGE_KERNEL_EXEC (__PAGE_KERNEL & ~_PAGE_NX) +#define __PAGE_KERNEL_RO (__PAGE_KERNEL_BASE | _PAGE_PROT_RKNU | _PAGE_CACHE | _PAGE_NX) +#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) +#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) + +#define PAGE_KERNEL __pgprot(__PAGE_KERNEL) +#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) +#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) +#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) +#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) +#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) + +#define __PAGE_USERIO (__PAGE_KERNEL_BASE | _PAGE_PROT_WKWU | _PAGE_NX) +#define PAGE_USERIO __pgprot(__PAGE_USERIO) + +/* + * Whilst the MN10300 can do page protection for execute (given separate data + * and insn TLBs), we are not supporting it at the moment. Write permission, + * however, always implies read permission (but not execute permission). + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY_NOEXEC +#define __P010 PAGE_COPY_NOEXEC +#define __P011 PAGE_COPY_NOEXEC +#define __P100 PAGE_READONLY_EXEC +#define __P101 PAGE_READONLY_EXEC +#define __P110 PAGE_COPY_EXEC +#define __P111 PAGE_COPY_EXEC + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY_NOEXEC +#define __S010 PAGE_SHARED_NOEXEC +#define __S011 PAGE_SHARED_NOEXEC +#define __S100 PAGE_READONLY_EXEC +#define __S101 PAGE_READONLY_EXEC +#define __S110 PAGE_SHARED_EXEC +#define __S111 PAGE_SHARED_EXEC + +/* + * Define this to warn about kernel memory accesses that are + * done without a 'verify_area(VERIFY_WRITE,..)' + */ +#undef TEST_VERIFY_AREA + +#define pte_present(x) (pte_val(x) & _PAGE_VALID) +#define pte_clear(mm, addr, xp) \ +do { \ + set_pte_at((mm), (addr), (xp), __pte(0)); \ +} while (0) + +#define pmd_none(x) (!pmd_val(x)) +#define pmd_present(x) (!pmd_none(x)) +#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) +#define pmd_bad(x) 0 + + +#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT)) + +#ifndef __ASSEMBLY__ + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +static inline int pte_user(pte_t pte) { return pte_val(pte) & __PAGE_PROT_USER; } +static inline int pte_read(pte_t pte) { return pte_val(pte) & __PAGE_PROT_USER; } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_write(pte_t pte) { return pte_val(pte) & __PAGE_PROT_WRITE; } +static inline int pte_special(pte_t pte){ return 0; } + +static inline pte_t pte_rdprotect(pte_t pte) +{ + pte_val(pte) &= ~(__PAGE_PROT_USER|__PAGE_PROT_UWAUX); return pte; +} +static inline pte_t pte_exprotect(pte_t pte) +{ + pte_val(pte) |= _PAGE_NX; return pte; +} + +static inline pte_t pte_wrprotect(pte_t pte) +{ + pte_val(pte) &= ~(__PAGE_PROT_WRITE|__PAGE_PROT_UWAUX); return pte; +} + +static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } +static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) &= ~_PAGE_NX; return pte; } + +static inline pte_t pte_mkread(pte_t pte) +{ + pte_val(pte) |= __PAGE_PROT_USER; + if (pte_write(pte)) + pte_val(pte) |= __PAGE_PROT_UWAUX; + return pte; +} +static inline pte_t pte_mkwrite(pte_t pte) +{ + pte_val(pte) |= __PAGE_PROT_WRITE; + if (pte_val(pte) & __PAGE_PROT_USER) + pte_val(pte) |= __PAGE_PROT_UWAUX; + return pte; +} + +static inline pte_t pte_mkspecial(pte_t pte) { return pte; } + +#define pte_ERROR(e) \ + printk(KERN_ERR "%s:%d: bad pte %08lx.\n", \ + __FILE__, __LINE__, pte_val(e)) +#define pgd_ERROR(e) \ + printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", \ + __FILE__, __LINE__, pgd_val(e)) + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +#define pgd_clear(xp) do { } while (0) + +/* + * Certain architectures need to do special things when PTEs + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#define set_pte(pteptr, pteval) (*(pteptr) = pteval) +#define set_pte_at(mm, addr, ptep, pteval) set_pte((ptep), (pteval)) +#define set_pte_atomic(pteptr, pteval) set_pte((pteptr), (pteval)) + +/* + * (pmds are folded into pgds so this doesn't get actually called, + * but the define is needed for a generic inline function.) + */ +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) + +#define ptep_get_and_clear(mm, addr, ptep) \ + __pte(xchg(&(ptep)->pte, 0)) +#define pte_same(a, b) (pte_val(a) == pte_val(b)) +#define pte_page(x) pfn_to_page(pte_pfn(x)) +#define pte_none(x) (!pte_val(x)) +#define pte_pfn(x) ((unsigned long) (pte_val(x) >> PAGE_SHIFT)) +#define __pfn_addr(pfn) ((pfn) << PAGE_SHIFT) +#define pfn_pte(pfn, prot) __pte(__pfn_addr(pfn) | pgprot_val(prot)) +#define pfn_pmd(pfn, prot) __pmd(__pfn_addr(pfn) | pgprot_val(prot)) + +/* + * All present user pages are user-executable: + */ +static inline int pte_exec(pte_t pte) +{ + return pte_user(pte); +} + +/* + * All present pages are kernel-executable: + */ +static inline int pte_exec_kernel(pte_t pte) +{ + return 1; +} + +/* Encode and de-code a swap entry */ +#define __swp_type(x) (((x).val >> 1) & 0x3f) +#define __swp_offset(x) ((x).val >> 7) +#define __swp_entry(type, offset) \ + ((swp_entry_t) { ((type) << 1) | ((offset) << 7) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) __pte((x).val) + +static inline +int ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr, + pte_t *ptep) +{ + if (!pte_dirty(*ptep)) + return 0; + return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte); +} + +static inline +int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, + pte_t *ptep) +{ + if (!pte_young(*ptep)) + return 0; + return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte); +} + +static inline +void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + pte_val(*ptep) &= ~(__PAGE_PROT_WRITE|__PAGE_PROT_UWAUX); +} + +static inline void ptep_mkdirty(pte_t *ptep) +{ + set_bit(_PAGE_BIT_DIRTY, &ptep->pte); +} + +/* + * Macro to mark a page protection value as "uncacheable". On processors which + * do not support it, this is a no-op. + */ +#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) & ~_PAGE_CACHE) + +/* + * Macro to mark a page protection value as "Write-Through". + * On processors which do not support it, this is a no-op. + */ +#define pgprot_through(prot) __pgprot(pgprot_val(prot) | _PAGE_CACHE_WT) + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ + +#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) +#define mk_pte_huge(entry) \ + ((entry).pte |= _PAGE_PRESENT | _PAGE_PSE | _PAGE_VALID) + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte_val(pte) &= _PAGE_CHG_MASK; + pte_val(pte) |= pgprot_val(newprot); + return pte; +} + +#define page_pte(page) page_pte_prot((page), __pgprot(0)) + +#define pmd_page_kernel(pmd) \ + ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) + +#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT) + +#define pmd_large(pmd) \ + ((pmd_val(pmd) & (_PAGE_PSE | _PAGE_PRESENT)) == \ + (_PAGE_PSE | _PAGE_PRESENT)) + +/* + * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD] + * + * this macro returns the index of the entry in the pgd page which would + * control the given virtual address + */ +#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) + +/* + * pgd_offset() returns a (pgd_t *) + * pgd_index() is used get the offset into the pgd page's array of pgd_t's; + */ +#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) + +/* + * a shortcut which implies the use of the kernel's pgd, instead + * of a process's + */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* + * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD] + * + * this macro returns the index of the entry in the pmd page which would + * control the given virtual address + */ +#define pmd_index(address) \ + (((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) + +/* + * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE] + * + * this macro returns the index of the entry in the pte page which would + * control the given virtual address + */ +#define pte_index(address) \ + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) + +#define pte_offset_kernel(dir, address) \ + ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(address)) + +/* + * Make a given kernel text page executable/non-executable. + * Returns the previous executability setting of that page (which + * is used to restore the previous state). Used by the SMP bootup code. + * NOTE: this is an __init function for security reasons. + */ +static inline int set_kernel_exec(unsigned long vaddr, int enable) +{ + return 0; +} + +#define pte_offset_map(dir, address) \ + ((pte_t *) page_address(pmd_page(*(dir))) + pte_index(address)) +#define pte_unmap(pte) do {} while (0) + +/* + * The MN10300 has external MMU info in the form of a TLB: this is adapted from + * the kernel page tables containing the necessary information by tlb-mn10300.S + */ +extern void update_mmu_cache(struct vm_area_struct *vma, + unsigned long address, pte_t *ptep); + +#endif /* !__ASSEMBLY__ */ + +#define kern_addr_valid(addr) (1) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR +#define __HAVE_ARCH_PTEP_SET_WRPROTECT +#define __HAVE_ARCH_PTEP_MKDIRTY +#define __HAVE_ARCH_PTE_SAME +#include <asm-generic/pgtable.h> + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_PGTABLE_H */ diff --git a/arch/mn10300/include/asm/pio-regs.h b/arch/mn10300/include/asm/pio-regs.h new file mode 100644 index 000000000..96bc8182d --- /dev/null +++ b/arch/mn10300/include/asm/pio-regs.h @@ -0,0 +1,233 @@ +/* MN10300 On-board I/O port module registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PIO_REGS_H +#define _ASM_PIO_REGS_H + +#include <asm/cpu-regs.h> +#include <asm/intctl-regs.h> + +#ifdef __KERNEL__ + +/* I/O port 0 */ +#define P0MD __SYSREG(0xdb000000, u16) /* mode reg */ +#define P0MD_0 0x0003 /* mask */ +#define P0MD_0_IN 0x0000 /* input mode */ +#define P0MD_0_OUT 0x0001 /* output mode */ +#define P0MD_0_TM0IO 0x0002 /* timer 0 I/O mode */ +#define P0MD_0_EYECLK 0x0003 /* test signal output (clock) */ +#define P0MD_1 0x000c +#define P0MD_1_IN 0x0000 +#define P0MD_1_OUT 0x0004 +#define P0MD_1_TM1IO 0x0008 /* timer 1 I/O mode */ +#define P0MD_1_EYED 0x000c /* test signal output (data) */ +#define P0MD_2 0x0030 +#define P0MD_2_IN 0x0000 +#define P0MD_2_OUT 0x0010 +#define P0MD_2_TM2IO 0x0020 /* timer 2 I/O mode */ +#define P0MD_3 0x00c0 +#define P0MD_3_IN 0x0000 +#define P0MD_3_OUT 0x0040 +#define P0MD_3_TM3IO 0x0080 /* timer 3 I/O mode */ +#define P0MD_4 0x0300 +#define P0MD_4_IN 0x0000 +#define P0MD_4_OUT 0x0100 +#define P0MD_4_TM4IO 0x0200 /* timer 4 I/O mode */ +#define P0MD_4_XCTS 0x0300 /* XCTS input for serial port 2 */ +#define P0MD_5 0x0c00 +#define P0MD_5_IN 0x0000 +#define P0MD_5_OUT 0x0400 +#define P0MD_5_TM5IO 0x0800 /* timer 5 I/O mode */ +#define P0MD_6 0x3000 +#define P0MD_6_IN 0x0000 +#define P0MD_6_OUT 0x1000 +#define P0MD_6_TM6IOA 0x2000 /* timer 6 I/O mode A */ +#define P0MD_7 0xc000 +#define P0MD_7_IN 0x0000 +#define P0MD_7_OUT 0x4000 +#define P0MD_7_TM6IOB 0x8000 /* timer 6 I/O mode B */ + +#define P0IN __SYSREG(0xdb000004, u8) /* in reg */ +#define P0OUT __SYSREG(0xdb000008, u8) /* out reg */ + +#define P0TMIO __SYSREG(0xdb00000c, u8) /* TM pin I/O control reg */ +#define P0TMIO_TM0_IN 0x00 +#define P0TMIO_TM0_OUT 0x01 +#define P0TMIO_TM1_IN 0x00 +#define P0TMIO_TM1_OUT 0x02 +#define P0TMIO_TM2_IN 0x00 +#define P0TMIO_TM2_OUT 0x04 +#define P0TMIO_TM3_IN 0x00 +#define P0TMIO_TM3_OUT 0x08 +#define P0TMIO_TM4_IN 0x00 +#define P0TMIO_TM4_OUT 0x10 +#define P0TMIO_TM5_IN 0x00 +#define P0TMIO_TM5_OUT 0x20 +#define P0TMIO_TM6A_IN 0x00 +#define P0TMIO_TM6A_OUT 0x40 +#define P0TMIO_TM6B_IN 0x00 +#define P0TMIO_TM6B_OUT 0x80 + +/* I/O port 1 */ +#define P1MD __SYSREG(0xdb000100, u16) /* mode reg */ +#define P1MD_0 0x0003 /* mask */ +#define P1MD_0_IN 0x0000 /* input mode */ +#define P1MD_0_OUT 0x0001 /* output mode */ +#define P1MD_0_TM7IO 0x0002 /* timer 7 I/O mode */ +#define P1MD_0_ADTRG 0x0003 /* A/D converter trigger mode */ +#define P1MD_1 0x000c +#define P1MD_1_IN 0x0000 +#define P1MD_1_OUT 0x0004 +#define P1MD_1_TM8IO 0x0008 /* timer 8 I/O mode */ +#define P1MD_1_XDMR0 0x000c /* DMA request input 0 mode */ +#define P1MD_2 0x0030 +#define P1MD_2_IN 0x0000 +#define P1MD_2_OUT 0x0010 +#define P1MD_2_TM9IO 0x0020 /* timer 9 I/O mode */ +#define P1MD_2_XDMR1 0x0030 /* DMA request input 1 mode */ +#define P1MD_3 0x00c0 +#define P1MD_3_IN 0x0000 +#define P1MD_3_OUT 0x0040 +#define P1MD_3_TM10IO 0x0080 /* timer 10 I/O mode */ +#define P1MD_3_FRQS0 0x00c0 /* CPU clock multiplier setting input 0 mode */ +#define P1MD_4 0x0300 +#define P1MD_4_IN 0x0000 +#define P1MD_4_OUT 0x0100 +#define P1MD_4_TM11IO 0x0200 /* timer 11 I/O mode */ +#define P1MD_4_FRQS1 0x0300 /* CPU clock multiplier setting input 1 mode */ + +#define P1IN __SYSREG(0xdb000104, u8) /* in reg */ +#define P1OUT __SYSREG(0xdb000108, u8) /* out reg */ +#define P1TMIO __SYSREG(0xdb00010c, u8) /* TM pin I/O control reg */ +#define P1TMIO_TM11_IN 0x00 +#define P1TMIO_TM11_OUT 0x01 +#define P1TMIO_TM10_IN 0x00 +#define P1TMIO_TM10_OUT 0x02 +#define P1TMIO_TM9_IN 0x00 +#define P1TMIO_TM9_OUT 0x04 +#define P1TMIO_TM8_IN 0x00 +#define P1TMIO_TM8_OUT 0x08 +#define P1TMIO_TM7_IN 0x00 +#define P1TMIO_TM7_OUT 0x10 + +/* I/O port 2 */ +#define P2MD __SYSREG(0xdb000200, u16) /* mode reg */ +#define P2MD_0 0x0003 /* mask */ +#define P2MD_0_IN 0x0000 /* input mode */ +#define P2MD_0_OUT 0x0001 /* output mode */ +#define P2MD_0_BOOTBW 0x0003 /* boot bus width selector mode */ +#define P2MD_1 0x000c +#define P2MD_1_IN 0x0000 +#define P2MD_1_OUT 0x0004 +#define P2MD_1_BOOTSEL 0x000c /* boot device selector mode */ +#define P2MD_2 0x0030 +#define P2MD_2_IN 0x0000 +#define P2MD_2_OUT 0x0010 +#define P2MD_3 0x00c0 +#define P2MD_3_IN 0x0000 +#define P2MD_3_OUT 0x0040 +#define P2MD_3_CKIO 0x00c0 /* mode */ +#define P2MD_4 0x0300 +#define P2MD_4_IN 0x0000 +#define P2MD_4_OUT 0x0100 +#define P2MD_4_CMOD 0x0300 /* mode */ + +#define P2IN __SYSREG(0xdb000204, u8) /* in reg */ +#define P2OUT __SYSREG(0xdb000208, u8) /* out reg */ +#define P2TMIO __SYSREG(0xdb00020c, u8) /* TM pin I/O control reg */ + +/* I/O port 3 */ +#define P3MD __SYSREG(0xdb000300, u16) /* mode reg */ +#define P3MD_0 0x0003 /* mask */ +#define P3MD_0_IN 0x0000 /* input mode */ +#define P3MD_0_OUT 0x0001 /* output mode */ +#define P3MD_0_AFRXD 0x0002 /* AFR interface mode */ +#define P3MD_1 0x000c +#define P3MD_1_IN 0x0000 +#define P3MD_1_OUT 0x0004 +#define P3MD_1_AFTXD 0x0008 /* AFR interface mode */ +#define P3MD_2 0x0030 +#define P3MD_2_IN 0x0000 +#define P3MD_2_OUT 0x0010 +#define P3MD_2_AFSCLK 0x0020 /* AFR interface mode */ +#define P3MD_3 0x00c0 +#define P3MD_3_IN 0x0000 +#define P3MD_3_OUT 0x0040 +#define P3MD_3_AFFS 0x0080 /* AFR interface mode */ +#define P3MD_4 0x0300 +#define P3MD_4_IN 0x0000 +#define P3MD_4_OUT 0x0100 +#define P3MD_4_AFEHC 0x0200 /* AFR interface mode */ + +#define P3IN __SYSREG(0xdb000304, u8) /* in reg */ +#define P3OUT __SYSREG(0xdb000308, u8) /* out reg */ + +/* I/O port 4 */ +#define P4MD __SYSREG(0xdb000400, u16) /* mode reg */ +#define P4MD_0 0x0003 /* mask */ +#define P4MD_0_IN 0x0000 /* input mode */ +#define P4MD_0_OUT 0x0001 /* output mode */ +#define P4MD_0_SCL0 0x0002 /* I2C/serial mode */ +#define P4MD_1 0x000c +#define P4MD_1_IN 0x0000 +#define P4MD_1_OUT 0x0004 +#define P4MD_1_SDA0 0x0008 +#define P4MD_2 0x0030 +#define P4MD_2_IN 0x0000 +#define P4MD_2_OUT 0x0010 +#define P4MD_2_SCL1 0x0020 +#define P4MD_3 0x00c0 +#define P4MD_3_IN 0x0000 +#define P4MD_3_OUT 0x0040 +#define P4MD_3_SDA1 0x0080 +#define P4MD_4 0x0300 +#define P4MD_4_IN 0x0000 +#define P4MD_4_OUT 0x0100 +#define P4MD_4_SBO0 0x0200 +#define P4MD_5 0x0c00 +#define P4MD_5_IN 0x0000 +#define P4MD_5_OUT 0x0400 +#define P4MD_5_SBO1 0x0800 +#define P4MD_6 0x3000 +#define P4MD_6_IN 0x0000 +#define P4MD_6_OUT 0x1000 +#define P4MD_6_SBT0 0x2000 +#define P4MD_7 0xc000 +#define P4MD_7_IN 0x0000 +#define P4MD_7_OUT 0x4000 +#define P4MD_7_SBT1 0x8000 + +#define P4IN __SYSREG(0xdb000404, u8) /* in reg */ +#define P4OUT __SYSREG(0xdb000408, u8) /* out reg */ + +/* I/O port 5 */ +#define P5MD __SYSREG(0xdb000500, u16) /* mode reg */ +#define P5MD_0 0x0003 /* mask */ +#define P5MD_0_IN 0x0000 /* input mode */ +#define P5MD_0_OUT 0x0001 /* output mode */ +#define P5MD_0_IRTXD 0x0002 /* IrDA mode */ +#define P5MD_0_SOUT 0x0004 /* serial mode */ +#define P5MD_1 0x000c +#define P5MD_1_IN 0x0000 +#define P5MD_1_OUT 0x0004 +#define P5MD_1_IRRXDS 0x0008 /* IrDA mode */ +#define P5MD_1_SIN 0x000c /* serial mode */ +#define P5MD_2 0x0030 +#define P5MD_2_IN 0x0000 +#define P5MD_2_OUT 0x0010 +#define P5MD_2_IRRXDF 0x0020 /* IrDA mode */ + +#define P5IN __SYSREG(0xdb000504, u8) /* in reg */ +#define P5OUT __SYSREG(0xdb000508, u8) /* out reg */ + + +#endif /* __KERNEL__ */ + +#endif /* _ASM_PIO_REGS_H */ diff --git a/arch/mn10300/include/asm/processor.h b/arch/mn10300/include/asm/processor.h new file mode 100644 index 000000000..769d5ed8e --- /dev/null +++ b/arch/mn10300/include/asm/processor.h @@ -0,0 +1,178 @@ +/* MN10300 Processor specifics + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_PROCESSOR_H +#define _ASM_PROCESSOR_H + +#include <linux/threads.h> +#include <linux/thread_info.h> +#include <asm/page.h> +#include <asm/ptrace.h> +#include <asm/cpu-regs.h> +#include <asm/uaccess.h> +#include <asm/current.h> + +/* Forward declaration, a strange C thing */ +struct task_struct; +struct mm_struct; + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() \ +({ \ + void *__pc; \ + asm("mov pc,%0" : "=a"(__pc)); \ + __pc; \ +}) + +extern void get_mem_info(unsigned long *mem_base, unsigned long *mem_size); + +extern void show_registers(struct pt_regs *regs); + +/* + * CPU type and hardware bug flags. Kept separately for each CPU. + * Members of this structure are referenced in head.S, so think twice + * before touching them. [mj] + */ + +struct mn10300_cpuinfo { + int type; + unsigned long loops_per_jiffy; + char hard_math; +}; + +extern struct mn10300_cpuinfo boot_cpu_data; + +#ifdef CONFIG_SMP +#if CONFIG_NR_CPUS < 2 || CONFIG_NR_CPUS > 8 +# error Sorry, NR_CPUS should be 2 to 8 +#endif +extern struct mn10300_cpuinfo cpu_data[]; +#define current_cpu_data cpu_data[smp_processor_id()] +#else /* CONFIG_SMP */ +#define cpu_data &boot_cpu_data +#define current_cpu_data boot_cpu_data +#endif /* CONFIG_SMP */ + +extern void identify_cpu(struct mn10300_cpuinfo *); +extern void print_cpu_info(struct mn10300_cpuinfo *); +extern void dodgy_tsc(void); + +#define cpu_relax() barrier() +#define cpu_relax_lowlatency() cpu_relax() + +/* + * User space process size: 1.75GB (default). + */ +#define TASK_SIZE 0x70000000 + +/* + * Where to put the userspace stack by default + */ +#define STACK_TOP 0x70000000 +#define STACK_TOP_MAX STACK_TOP + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE 0x30000000 + +struct fpu_state_struct { + unsigned long fs[32]; /* fpu registers */ + unsigned long fpcr; /* fpu control register */ +}; + +struct thread_struct { + struct pt_regs *uregs; /* userspace register frame */ + unsigned long pc; /* kernel PC */ + unsigned long sp; /* kernel SP */ + unsigned long a3; /* kernel FP */ + unsigned long wchan; + unsigned long usp; + unsigned long fpu_flags; +#define THREAD_USING_FPU 0x00000001 /* T if this task is using the FPU */ +#define THREAD_HAS_FPU 0x00000002 /* T if this task owns the FPU right now */ + struct fpu_state_struct fpu_state; +}; + +#define INIT_THREAD \ +{ \ + .uregs = init_uregs, \ + .pc = 0, \ + .sp = 0, \ + .a3 = 0, \ + .wchan = 0, \ +} + +#define INIT_MMAP \ +{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, \ + NULL, NULL } + +/* + * do necessary setup to start up a newly executed thread + */ +static inline void start_thread(struct pt_regs *regs, + unsigned long new_pc, unsigned long new_sp) +{ + regs->epsw = EPSW_nSL | EPSW_IE | EPSW_IM; + regs->pc = new_pc; + regs->sp = new_sp; +} + + +/* Free all resources held by a thread. */ +extern void release_thread(struct task_struct *); + +/* + * Return saved PC of a blocked thread. + */ +extern unsigned long thread_saved_pc(struct task_struct *tsk); + +unsigned long get_wchan(struct task_struct *p); + +#define task_pt_regs(task) ((task)->thread.uregs) +#define KSTK_EIP(task) (task_pt_regs(task)->pc) +#define KSTK_ESP(task) (task_pt_regs(task)->sp) + +#define KSTK_TOP(info) \ +({ \ + (unsigned long)(info) + THREAD_SIZE; \ +}) + +#define ARCH_HAS_PREFETCH +#define ARCH_HAS_PREFETCHW + +static inline void prefetch(const void *x) +{ +#ifdef CONFIG_MN10300_CACHE_ENABLED +#ifdef CONFIG_MN10300_PROC_MN103E010 + asm volatile ("nop; nop; dcpf (%0)" : : "r"(x)); +#else + asm volatile ("dcpf (%0)" : : "r"(x)); +#endif +#endif +} + +static inline void prefetchw(const void *x) +{ +#ifdef CONFIG_MN10300_CACHE_ENABLED +#ifdef CONFIG_MN10300_PROC_MN103E010 + asm volatile ("nop; nop; dcpf (%0)" : : "r"(x)); +#else + asm volatile ("dcpf (%0)" : : "r"(x)); +#endif +#endif +} + +#endif /* _ASM_PROCESSOR_H */ diff --git a/arch/mn10300/include/asm/ptrace.h b/arch/mn10300/include/asm/ptrace.h new file mode 100644 index 000000000..838a38300 --- /dev/null +++ b/arch/mn10300/include/asm/ptrace.h @@ -0,0 +1,26 @@ +/* MN10300 Exception frame layout and ptrace constants + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PTRACE_H +#define _ASM_PTRACE_H + +#include <uapi/asm/ptrace.h> + + +#define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL) +#define instruction_pointer(regs) ((regs)->pc) +#define user_stack_pointer(regs) ((regs)->sp) +#define current_pt_regs() current_frame() + +#define arch_has_single_step() (1) + +#define profile_pc(regs) ((regs)->pc) + +#endif /* _ASM_PTRACE_H */ diff --git a/arch/mn10300/include/asm/reset-regs.h b/arch/mn10300/include/asm/reset-regs.h new file mode 100644 index 000000000..8ca2a42d3 --- /dev/null +++ b/arch/mn10300/include/asm/reset-regs.h @@ -0,0 +1,60 @@ +/* MN10300 Reset controller and watchdog timer definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_RESET_REGS_H +#define _ASM_RESET_REGS_H + +#include <asm/cpu-regs.h> +#include <asm/exceptions.h> + +#ifdef __KERNEL__ + +/* + * watchdog timer registers + */ +#define WDBC __SYSREGC(0xc0001000, u8) /* watchdog binary counter reg */ + +#define WDCTR __SYSREG(0xc0001002, u8) /* watchdog timer control reg */ +#define WDCTR_WDCK 0x07 /* clock source selection */ +#define WDCTR_WDCK_256th 0x00 /* - OSCI/256 */ +#define WDCTR_WDCK_1024th 0x01 /* - OSCI/1024 */ +#define WDCTR_WDCK_2048th 0x02 /* - OSCI/2048 */ +#define WDCTR_WDCK_16384th 0x03 /* - OSCI/16384 */ +#define WDCTR_WDCK_65536th 0x04 /* - OSCI/65536 */ +#define WDCTR_WDRST 0x40 /* binary counter reset */ +#define WDCTR_WDCNE 0x80 /* watchdog timer enable */ + +#define RSTCTR __SYSREG(0xc0001004, u8) /* reset control reg */ +#define RSTCTR_CHIPRST 0x01 /* chip reset */ +#define RSTCTR_DBFRST 0x02 /* double fault reset flag */ +#define RSTCTR_WDTRST 0x04 /* watchdog timer reset flag */ +#define RSTCTR_WDREN 0x08 /* watchdog timer reset enable */ + +#ifndef __ASSEMBLY__ + +static inline void mn10300_proc_hard_reset(void) +{ + RSTCTR &= ~RSTCTR_CHIPRST; + RSTCTR |= RSTCTR_CHIPRST; +} + +extern unsigned int watchdog_alert_counter[]; + +extern void watchdog_go(void); +extern asmlinkage void watchdog_handler(void); +extern asmlinkage +void watchdog_interrupt(struct pt_regs *, enum exception_code); + +#endif + +#endif /* __KERNEL__ */ + +#endif /* _ASM_RESET_REGS_H */ diff --git a/arch/mn10300/include/asm/rtc-regs.h b/arch/mn10300/include/asm/rtc-regs.h new file mode 100644 index 000000000..c42deefae --- /dev/null +++ b/arch/mn10300/include/asm/rtc-regs.h @@ -0,0 +1,86 @@ +/* MN10300 on-chip Real-Time Clock registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_RTC_REGS_H +#define _ASM_RTC_REGS_H + +#include <asm/intctl-regs.h> + +#ifdef __KERNEL__ + +#define RTSCR __SYSREG(0xd8600000, u8) /* RTC seconds count reg */ +#define RTSAR __SYSREG(0xd8600001, u8) /* RTC seconds alarm reg */ +#define RTMCR __SYSREG(0xd8600002, u8) /* RTC minutes count reg */ +#define RTMAR __SYSREG(0xd8600003, u8) /* RTC minutes alarm reg */ +#define RTHCR __SYSREG(0xd8600004, u8) /* RTC hours count reg */ +#define RTHAR __SYSREG(0xd8600005, u8) /* RTC hours alarm reg */ +#define RTDWCR __SYSREG(0xd8600006, u8) /* RTC day of the week count reg */ +#define RTDMCR __SYSREG(0xd8600007, u8) /* RTC days count reg */ +#define RTMTCR __SYSREG(0xd8600008, u8) /* RTC months count reg */ +#define RTYCR __SYSREG(0xd8600009, u8) /* RTC years count reg */ + +#define RTCRA __SYSREG(0xd860000a, u8)/* RTC control reg A */ +#define RTCRA_RS 0x0f /* periodic timer interrupt cycle setting */ +#define RTCRA_RS_NONE 0x00 /* - off */ +#define RTCRA_RS_3_90625ms 0x01 /* - 3.90625ms (1/256s) */ +#define RTCRA_RS_7_8125ms 0x02 /* - 7.8125ms (1/128s) */ +#define RTCRA_RS_122_070us 0x03 /* - 122.070us (1/8192s) */ +#define RTCRA_RS_244_141us 0x04 /* - 244.141us (1/4096s) */ +#define RTCRA_RS_488_281us 0x05 /* - 488.281us (1/2048s) */ +#define RTCRA_RS_976_5625us 0x06 /* - 976.5625us (1/1024s) */ +#define RTCRA_RS_1_953125ms 0x07 /* - 1.953125ms (1/512s) */ +#define RTCRA_RS_3_90624ms 0x08 /* - 3.90624ms (1/256s) */ +#define RTCRA_RS_7_8125ms_b 0x09 /* - 7.8125ms (1/128s) */ +#define RTCRA_RS_15_625ms 0x0a /* - 15.625ms (1/64s) */ +#define RTCRA_RS_31_25ms 0x0b /* - 31.25ms (1/32s) */ +#define RTCRA_RS_62_5ms 0x0c /* - 62.5ms (1/16s) */ +#define RTCRA_RS_125ms 0x0d /* - 125ms (1/8s) */ +#define RTCRA_RS_250ms 0x0e /* - 250ms (1/4s) */ +#define RTCRA_RS_500ms 0x0f /* - 500ms (1/2s) */ +#define RTCRA_DVR 0x40 /* divider reset */ +#define RTCRA_UIP 0x80 /* clock update flag */ + +#define RTCRB __SYSREG(0xd860000b, u8) /* RTC control reg B */ +#define RTCRB_DSE 0x01 /* daylight savings time enable */ +#define RTCRB_TM 0x02 /* time format */ +#define RTCRB_TM_12HR 0x00 /* - 12 hour format */ +#define RTCRB_TM_24HR 0x02 /* - 24 hour format */ +#define RTCRB_DM 0x04 /* numeric value format */ +#define RTCRB_DM_BCD 0x00 /* - BCD */ +#define RTCRB_DM_BINARY 0x04 /* - binary */ +#define RTCRB_UIE 0x10 /* update interrupt disable */ +#define RTCRB_AIE 0x20 /* alarm interrupt disable */ +#define RTCRB_PIE 0x40 /* periodic interrupt disable */ +#define RTCRB_SET 0x80 /* clock update enable */ + +#define RTSRC __SYSREG(0xd860000c, u8) /* RTC status reg C */ +#define RTSRC_UF 0x10 /* update end interrupt flag */ +#define RTSRC_AF 0x20 /* alarm interrupt flag */ +#define RTSRC_PF 0x40 /* periodic interrupt flag */ +#define RTSRC_IRQF 0x80 /* interrupt flag */ + +#define RTIRQ 32 +#define RTICR GxICR(RTIRQ) + +/* + * MC146818 RTC compatibility defs for the MN10300 on-chip RTC + */ +#define RTC_PORT(x) 0xd8600000 +#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ + +#define CMOS_READ(addr) __SYSREG(0xd8600000 + (addr), u8) +#define CMOS_WRITE(val, addr) \ + do { __SYSREG(0xd8600000 + (addr), u8) = val; } while (0) + +#define RTC_IRQ RTIRQ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_RTC_REGS_H */ diff --git a/arch/mn10300/include/asm/rtc.h b/arch/mn10300/include/asm/rtc.h new file mode 100644 index 000000000..6c14bb1d0 --- /dev/null +++ b/arch/mn10300/include/asm/rtc.h @@ -0,0 +1,30 @@ +/* MN10300 Real time clock definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_RTC_H +#define _ASM_RTC_H + +#ifdef CONFIG_MN10300_RTC + +#include <linux/init.h> + +extern void __init calibrate_clock(void); + +#else /* !CONFIG_MN10300_RTC */ + +static inline void calibrate_clock(void) +{ +} + +#endif /* !CONFIG_MN10300_RTC */ + +#include <asm-generic/rtc.h> + +#endif /* _ASM_RTC_H */ diff --git a/arch/mn10300/include/asm/rwlock.h b/arch/mn10300/include/asm/rwlock.h new file mode 100644 index 000000000..6d594d4a0 --- /dev/null +++ b/arch/mn10300/include/asm/rwlock.h @@ -0,0 +1,125 @@ +/* + * Helpers used by both rw spinlocks and rw semaphores. + * + * Based in part on code from semaphore.h and + * spinlock.h Copyright 1996 Linus Torvalds. + * + * Copyright 1999 Red Hat, Inc. + * + * Written by Benjamin LaHaise. + * + * Modified by Matsushita Electric Industrial Co., Ltd. + * Modifications: + * 13-Nov-2006 MEI Temporarily delete lock functions for SMP support. + * + * This program 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 of the License, or (at your option) + * any later version. + */ +#ifndef _ASM_RWLOCK_H +#define _ASM_RWLOCK_H + +#define RW_LOCK_BIAS 0x01000000 + +#ifndef CONFIG_SMP + +typedef struct { unsigned long a[100]; } __dummy_lock_t; +#define __dummy_lock(lock) (*(__dummy_lock_t *)(lock)) + +#define RW_LOCK_BIAS_STR "0x01000000" + +#define __build_read_lock_ptr(rw, helper) \ + do { \ + asm volatile( \ + " mov (%0),d3 \n" \ + " sub 1,d3 \n" \ + " mov d3,(%0) \n" \ + " blt 1f \n" \ + " bra 2f \n" \ + "1: jmp 3f \n" \ + "2: \n" \ + " .section .text.lock,\"ax\" \n" \ + "3: call "helper"[],0 \n" \ + " jmp 2b \n" \ + " .previous" \ + : \ + : "d" (rw) \ + : "memory", "d3", "cc"); \ + } while (0) + +#define __build_read_lock_const(rw, helper) \ + do { \ + asm volatile( \ + " mov (%0),d3 \n" \ + " sub 1,d3 \n" \ + " mov d3,(%0) \n" \ + " blt 1f \n" \ + " bra 2f \n" \ + "1: jmp 3f \n" \ + "2: \n" \ + " .section .text.lock,\"ax\" \n" \ + "3: call "helper"[],0 \n" \ + " jmp 2b \n" \ + " .previous" \ + : \ + : "d" (rw) \ + : "memory", "d3", "cc"); \ + } while (0) + +#define __build_read_lock(rw, helper) \ + do { \ + if (__builtin_constant_p(rw)) \ + __build_read_lock_const(rw, helper); \ + else \ + __build_read_lock_ptr(rw, helper); \ + } while (0) + +#define __build_write_lock_ptr(rw, helper) \ + do { \ + asm volatile( \ + " mov (%0),d3 \n" \ + " sub 1,d3 \n" \ + " mov d3,(%0) \n" \ + " blt 1f \n" \ + " bra 2f \n" \ + "1: jmp 3f \n" \ + "2: \n" \ + " .section .text.lock,\"ax\" \n" \ + "3: call "helper"[],0 \n" \ + " jmp 2b \n" \ + " .previous" \ + : \ + : "d" (rw) \ + : "memory", "d3", "cc"); \ + } while (0) + +#define __build_write_lock_const(rw, helper) \ + do { \ + asm volatile( \ + " mov (%0),d3 \n" \ + " sub 1,d3 \n" \ + " mov d3,(%0) \n" \ + " blt 1f \n" \ + " bra 2f \n" \ + "1: jmp 3f \n" \ + "2: \n" \ + " .section .text.lock,\"ax\" \n" \ + "3: call "helper"[],0 \n" \ + " jmp 2b \n" \ + " .previous" \ + : \ + : "d" (rw) \ + : "memory", "d3", "cc"); \ + } while (0) + +#define __build_write_lock(rw, helper) \ + do { \ + if (__builtin_constant_p(rw)) \ + __build_write_lock_const(rw, helper); \ + else \ + __build_write_lock_ptr(rw, helper); \ + } while (0) + +#endif /* CONFIG_SMP */ +#endif /* _ASM_RWLOCK_H */ diff --git a/arch/mn10300/include/asm/serial-regs.h b/arch/mn10300/include/asm/serial-regs.h new file mode 100644 index 000000000..8320cda32 --- /dev/null +++ b/arch/mn10300/include/asm/serial-regs.h @@ -0,0 +1,191 @@ +/* MN10300 on-board serial port module registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_SERIAL_REGS_H +#define _ASM_SERIAL_REGS_H + +#include <asm/cpu-regs.h> +#include <asm/intctl-regs.h> + +#ifdef __KERNEL__ + +/* serial port 0 */ +#define SC0CTR __SYSREG(0xd4002000, u16) /* control reg */ +#define SC01CTR_CK 0x0007 /* clock source select */ +#define SC01CTR_CK_IOCLK_8 0x0001 /* - 1/8 IOCLK */ +#define SC01CTR_CK_IOCLK_32 0x0002 /* - 1/32 IOCLK */ +#define SC01CTR_CK_EXTERN_8 0x0006 /* - 1/8 external closk */ +#define SC01CTR_CK_EXTERN 0x0007 /* - external closk */ +#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3) +#define SC0CTR_CK_TM8UFLOW_8 0x0000 /* - 1/8 timer 8 underflow (serial port 0 only) */ +#define SC0CTR_CK_TM2UFLOW_2 0x0003 /* - 1/2 timer 2 underflow (serial port 0 only) */ +#define SC0CTR_CK_TM0UFLOW_8 0x0004 /* - 1/8 timer 0 underflow (serial port 0 only) */ +#define SC0CTR_CK_TM2UFLOW_8 0x0005 /* - 1/8 timer 2 underflow (serial port 0 only) */ +#define SC1CTR_CK_TM9UFLOW_8 0x0000 /* - 1/8 timer 9 underflow (serial port 1 only) */ +#define SC1CTR_CK_TM3UFLOW_2 0x0003 /* - 1/2 timer 3 underflow (serial port 1 only) */ +#define SC1CTR_CK_TM1UFLOW_8 0x0004 /* - 1/8 timer 1 underflow (serial port 1 only) */ +#define SC1CTR_CK_TM3UFLOW_8 0x0005 /* - 1/8 timer 3 underflow (serial port 1 only) */ +#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */ +#define SC0CTR_CK_TM8UFLOW_8 0x0000 /* - 1/8 timer 8 underflow (serial port 0 only) */ +#define SC0CTR_CK_TM0UFLOW_8 0x0004 /* - 1/8 timer 0 underflow (serial port 0 only) */ +#define SC0CTR_CK_TM2UFLOW_8 0x0005 /* - 1/8 timer 2 underflow (serial port 0 only) */ +#define SC1CTR_CK_TM12UFLOW_8 0x0000 /* - 1/8 timer 12 underflow (serial port 1 only) */ +#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */ +#define SC01CTR_STB 0x0008 /* stop bit select */ +#define SC01CTR_STB_1BIT 0x0000 /* - 1 stop bit */ +#define SC01CTR_STB_2BIT 0x0008 /* - 2 stop bits */ +#define SC01CTR_PB 0x0070 /* parity bit select */ +#define SC01CTR_PB_NONE 0x0000 /* - no parity */ +#define SC01CTR_PB_FIXED0 0x0040 /* - fixed at 0 */ +#define SC01CTR_PB_FIXED1 0x0050 /* - fixed at 1 */ +#define SC01CTR_PB_EVEN 0x0060 /* - even parity */ +#define SC01CTR_PB_ODD 0x0070 /* - odd parity */ +#define SC01CTR_CLN 0x0080 /* character length */ +#define SC01CTR_CLN_7BIT 0x0000 /* - 7 bit chars */ +#define SC01CTR_CLN_8BIT 0x0080 /* - 8 bit chars */ +#define SC01CTR_TOE 0x0100 /* T input output enable */ +#define SC01CTR_OD 0x0200 /* bit order select */ +#define SC01CTR_OD_LSBFIRST 0x0000 /* - LSB first */ +#define SC01CTR_OD_MSBFIRST 0x0200 /* - MSB first */ +#define SC01CTR_MD 0x0c00 /* mode select */ +#define SC01CTR_MD_STST_SYNC 0x0000 /* - start-stop synchronous */ +#define SC01CTR_MD_CLOCK_SYNC1 0x0400 /* - clock synchronous 1 */ +#define SC01CTR_MD_I2C 0x0800 /* - I2C mode */ +#define SC01CTR_MD_CLOCK_SYNC2 0x0c00 /* - clock synchronous 2 */ +#define SC01CTR_IIC 0x1000 /* I2C mode select */ +#define SC01CTR_BKE 0x2000 /* break transmit enable */ +#define SC01CTR_RXE 0x4000 /* receive enable */ +#define SC01CTR_TXE 0x8000 /* transmit enable */ + +#define SC0ICR __SYSREG(0xd4002004, u8) /* interrupt control reg */ +#define SC01ICR_DMD 0x80 /* output data mode */ +#define SC01ICR_TD 0x20 /* transmit DMA trigger cause */ +#define SC01ICR_TI 0x10 /* transmit interrupt cause */ +#define SC01ICR_RES 0x04 /* receive error select */ +#define SC01ICR_RI 0x01 /* receive interrupt cause */ + +#define SC0TXB __SYSREG(0xd4002008, u8) /* transmit buffer reg */ +#define SC0RXB __SYSREG(0xd4002009, u8) /* receive buffer reg */ + +#define SC0STR __SYSREG(0xd400200c, u16) /* status reg */ +#define SC01STR_OEF 0x0001 /* overrun error found */ +#define SC01STR_PEF 0x0002 /* parity error found */ +#define SC01STR_FEF 0x0004 /* framing error found */ +#define SC01STR_RBF 0x0010 /* receive buffer status */ +#define SC01STR_TBF 0x0020 /* transmit buffer status */ +#define SC01STR_RXF 0x0040 /* receive status */ +#define SC01STR_TXF 0x0080 /* transmit status */ +#define SC01STR_STF 0x0100 /* I2C start sequence found */ +#define SC01STR_SPF 0x0200 /* I2C stop sequence found */ + +#define SC0RXIRQ 20 /* timer 0 Receive IRQ */ +#define SC0TXIRQ 21 /* timer 0 Transmit IRQ */ + +#define SC0RXICR GxICR(SC0RXIRQ) /* serial 0 receive intr ctrl reg */ +#define SC0TXICR GxICR(SC0TXIRQ) /* serial 0 transmit intr ctrl reg */ + +/* serial port 1 */ +#define SC1CTR __SYSREG(0xd4002010, u16) /* serial port 1 control */ +#define SC1ICR __SYSREG(0xd4002014, u8) /* interrupt control reg */ +#define SC1TXB __SYSREG(0xd4002018, u8) /* transmit buffer reg */ +#define SC1RXB __SYSREG(0xd4002019, u8) /* receive buffer reg */ +#define SC1STR __SYSREG(0xd400201c, u16) /* status reg */ + +#define SC1RXIRQ 22 /* timer 1 Receive IRQ */ +#define SC1TXIRQ 23 /* timer 1 Transmit IRQ */ + +#define SC1RXICR GxICR(SC1RXIRQ) /* serial 1 receive intr ctrl reg */ +#define SC1TXICR GxICR(SC1TXIRQ) /* serial 1 transmit intr ctrl reg */ + +/* serial port 2 */ +#define SC2CTR __SYSREG(0xd4002020, u16) /* control reg */ +#ifdef CONFIG_AM33_2 +#define SC2CTR_CK 0x0003 /* clock source select */ +#define SC2CTR_CK_TM10UFLOW 0x0000 /* - timer 10 underflow */ +#define SC2CTR_CK_TM2UFLOW 0x0001 /* - timer 2 underflow */ +#define SC2CTR_CK_EXTERN 0x0002 /* - external closk */ +#define SC2CTR_CK_TM3UFLOW 0x0003 /* - timer 3 underflow */ +#else /* CONFIG_AM33_2 */ +#define SC2CTR_CK 0x0007 /* clock source select */ +#define SC2CTR_CK_TM9UFLOW_8 0x0000 /* - 1/8 timer 9 underflow */ +#define SC2CTR_CK_IOCLK_8 0x0001 /* - 1/8 IOCLK */ +#define SC2CTR_CK_IOCLK_32 0x0002 /* - 1/32 IOCLK */ +#define SC2CTR_CK_TM3UFLOW_2 0x0003 /* - 1/2 timer 3 underflow */ +#define SC2CTR_CK_TM1UFLOW_8 0x0004 /* - 1/8 timer 1 underflow */ +#define SC2CTR_CK_TM3UFLOW_8 0x0005 /* - 1/8 timer 3 underflow */ +#define SC2CTR_CK_EXTERN_8 0x0006 /* - 1/8 external closk */ +#define SC2CTR_CK_EXTERN 0x0007 /* - external closk */ +#endif /* CONFIG_AM33_2 */ +#define SC2CTR_STB 0x0008 /* stop bit select */ +#define SC2CTR_STB_1BIT 0x0000 /* - 1 stop bit */ +#define SC2CTR_STB_2BIT 0x0008 /* - 2 stop bits */ +#define SC2CTR_PB 0x0070 /* parity bit select */ +#define SC2CTR_PB_NONE 0x0000 /* - no parity */ +#define SC2CTR_PB_FIXED0 0x0040 /* - fixed at 0 */ +#define SC2CTR_PB_FIXED1 0x0050 /* - fixed at 1 */ +#define SC2CTR_PB_EVEN 0x0060 /* - even parity */ +#define SC2CTR_PB_ODD 0x0070 /* - odd parity */ +#define SC2CTR_CLN 0x0080 /* character length */ +#define SC2CTR_CLN_7BIT 0x0000 /* - 7 bit chars */ +#define SC2CTR_CLN_8BIT 0x0080 /* - 8 bit chars */ +#define SC2CTR_TWE 0x0100 /* transmit wait enable (enable XCTS control) */ +#define SC2CTR_OD 0x0200 /* bit order select */ +#define SC2CTR_OD_LSBFIRST 0x0000 /* - LSB first */ +#define SC2CTR_OD_MSBFIRST 0x0200 /* - MSB first */ +#define SC2CTR_TWS 0x1000 /* transmit wait select */ +#define SC2CTR_TWS_XCTS_HIGH 0x0000 /* - interrupt TX when XCTS high */ +#define SC2CTR_TWS_XCTS_LOW 0x1000 /* - interrupt TX when XCTS low */ +#define SC2CTR_BKE 0x2000 /* break transmit enable */ +#define SC2CTR_RXE 0x4000 /* receive enable */ +#define SC2CTR_TXE 0x8000 /* transmit enable */ + +#define SC2ICR __SYSREG(0xd4002024, u8) /* interrupt control reg */ +#define SC2ICR_TD 0x20 /* transmit DMA trigger cause */ +#define SC2ICR_TI 0x10 /* transmit interrupt cause */ +#define SC2ICR_RES 0x04 /* receive error select */ +#define SC2ICR_RI 0x01 /* receive interrupt cause */ + +#define SC2TXB __SYSREG(0xd4002028, u8) /* transmit buffer reg */ +#define SC2RXB __SYSREG(0xd4002029, u8) /* receive buffer reg */ + +#ifdef CONFIG_AM33_2 +#define SC2STR __SYSREG(0xd400202c, u8) /* status reg */ +#else /* CONFIG_AM33_2 */ +#define SC2STR __SYSREG(0xd400202c, u16) /* status reg */ +#endif /* CONFIG_AM33_2 */ +#define SC2STR_OEF 0x0001 /* overrun error found */ +#define SC2STR_PEF 0x0002 /* parity error found */ +#define SC2STR_FEF 0x0004 /* framing error found */ +#define SC2STR_CTS 0x0008 /* XCTS input pin status (0 means high) */ +#define SC2STR_RBF 0x0010 /* receive buffer status */ +#define SC2STR_TBF 0x0020 /* transmit buffer status */ +#define SC2STR_RXF 0x0040 /* receive status */ +#define SC2STR_TXF 0x0080 /* transmit status */ + +#ifdef CONFIG_AM33_2 +#define SC2TIM __SYSREG(0xd400202d, u8) /* status reg */ +#endif + +#ifdef CONFIG_AM33_2 +#define SC2RXIRQ 24 /* serial 2 Receive IRQ */ +#define SC2TXIRQ 25 /* serial 2 Transmit IRQ */ +#else /* CONFIG_AM33_2 */ +#define SC2RXIRQ 68 /* serial 2 Receive IRQ */ +#define SC2TXIRQ 69 /* serial 2 Transmit IRQ */ +#endif /* CONFIG_AM33_2 */ + +#define SC2RXICR GxICR(SC2RXIRQ) /* serial 2 receive intr ctrl reg */ +#define SC2TXICR GxICR(SC2TXIRQ) /* serial 2 transmit intr ctrl reg */ + + +#endif /* __KERNEL__ */ + +#endif /* _ASM_SERIAL_REGS_H */ diff --git a/arch/mn10300/include/asm/serial.h b/arch/mn10300/include/asm/serial.h new file mode 100644 index 000000000..23a799293 --- /dev/null +++ b/arch/mn10300/include/asm/serial.h @@ -0,0 +1,36 @@ +/* Standard UART definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_SERIAL_H +#define _ASM_SERIAL_H + +/* Standard COM flags (except for COM4, because of the 8514 problem) */ +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) +#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF +#endif + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define FOURPORT_FLAGS ASYNC_FOURPORT +#define ACCENT_FLAGS 0 +#define BOCA_FLAGS 0 +#define HUB6_FLAGS 0 +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE +#endif + +#include <unit/serial.h> + +#endif /* _ASM_SERIAL_H */ diff --git a/arch/mn10300/include/asm/setup.h b/arch/mn10300/include/asm/setup.h new file mode 100644 index 000000000..fb024555d --- /dev/null +++ b/arch/mn10300/include/asm/setup.h @@ -0,0 +1,18 @@ +/* MN10300 Setup declarations + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SETUP_H +#define _ASM_SETUP_H + +#include <uapi/asm/setup.h> + +extern void __init unit_setup(void); +extern void __init unit_init_IRQ(void); +#endif /* _ASM_SETUP_H */ diff --git a/arch/mn10300/include/asm/shmparam.h b/arch/mn10300/include/asm/shmparam.h new file mode 100644 index 000000000..ab666ed1a --- /dev/null +++ b/arch/mn10300/include/asm/shmparam.h @@ -0,0 +1,6 @@ +#ifndef _ASM_SHMPARAM_H +#define _ASM_SHMPARAM_H + +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ + +#endif /* _ASM_SHMPARAM_H */ diff --git a/arch/mn10300/include/asm/signal.h b/arch/mn10300/include/asm/signal.h new file mode 100644 index 000000000..214ff5e9f --- /dev/null +++ b/arch/mn10300/include/asm/signal.h @@ -0,0 +1,33 @@ +/* MN10300 Signal definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SIGNAL_H +#define _ASM_SIGNAL_H + +#include <uapi/asm/signal.h> + +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#define __ARCH_HAS_SA_RESTORER + +#include <asm/sigcontext.h> + +#endif /* _ASM_SIGNAL_H */ diff --git a/arch/mn10300/include/asm/smp.h b/arch/mn10300/include/asm/smp.h new file mode 100644 index 000000000..56c42417d --- /dev/null +++ b/arch/mn10300/include/asm/smp.h @@ -0,0 +1,109 @@ +/* MN10300 SMP support + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * Modified by Matsushita Electric Industrial Co., Ltd. + * Modifications: + * 13-Nov-2006 MEI Define IPI-IRQ number and add inline/macro function + * for SMP support. + * 22-Jan-2007 MEI Add the define related to SMP_BOOT_IRQ. + * 23-Feb-2007 MEI Add the define related to SMP icahce invalidate. + * 23-Jun-2008 MEI Delete INTC_IPI. + * 22-Jul-2008 MEI Add smp_nmi_call_function and related defines. + * 04-Aug-2008 MEI Delete USE_DOIRQ_CACHE_IPI. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SMP_H +#define _ASM_SMP_H + +#ifndef __ASSEMBLY__ +#include <linux/threads.h> +#include <linux/cpumask.h> +#include <linux/thread_info.h> +#endif + +#ifdef CONFIG_SMP +#include <proc/smp-regs.h> + +#define RESCHEDULE_IPI 63 +#define CALL_FUNC_SINGLE_IPI 192 +#define LOCAL_TIMER_IPI 193 +#define FLUSH_CACHE_IPI 194 +#define CALL_FUNCTION_NMI_IPI 195 +#define DEBUGGER_NMI_IPI 196 + +#define SMP_BOOT_IRQ 195 + +#define RESCHEDULE_GxICR_LV GxICR_LEVEL_6 +#define CALL_FUNCTION_GxICR_LV GxICR_LEVEL_4 +#define LOCAL_TIMER_GxICR_LV GxICR_LEVEL_4 +#define FLUSH_CACHE_GxICR_LV GxICR_LEVEL_0 +#define SMP_BOOT_GxICR_LV GxICR_LEVEL_0 +#define DEBUGGER_GxICR_LV CONFIG_DEBUGGER_IRQ_LEVEL + +#define TIME_OUT_COUNT_BOOT_IPI 100 +#define DELAY_TIME_BOOT_IPI 75000 + + +#ifndef __ASSEMBLY__ + +/** + * raw_smp_processor_id - Determine the raw CPU ID of the CPU running it + * + * What we really want to do is to use the CPUID hardware CPU register to get + * this information, but accesses to that aren't cached, and run at system bus + * speed, not CPU speed. A copy of this value is, however, stored in the + * thread_info struct, and that can be cached. + * + * An alternate way of dealing with this could be to use the EPSW.S bits to + * cache this information for systems with up to four CPUs. + */ +#define arch_smp_processor_id() (CPUID) +#if 0 +#define raw_smp_processor_id() (arch_smp_processor_id()) +#else +#define raw_smp_processor_id() (current_thread_info()->cpu) +#endif + +static inline int cpu_logical_map(int cpu) +{ + return cpu; +} + +static inline int cpu_number_map(int cpu) +{ + return cpu; +} + + +extern cpumask_t cpu_boot_map; + +extern void smp_init_cpus(void); +extern void smp_cache_interrupt(void); +extern void send_IPI_allbutself(int irq); +extern int smp_nmi_call_function(void (*func)(void *), void *info, int wait); + +extern void arch_send_call_function_single_ipi(int cpu); +extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); + +#ifdef CONFIG_HOTPLUG_CPU +extern int __cpu_disable(void); +extern void __cpu_die(unsigned int cpu); +#endif /* CONFIG_HOTPLUG_CPU */ + +#endif /* __ASSEMBLY__ */ +#else /* CONFIG_SMP */ +#ifndef __ASSEMBLY__ + +static inline void smp_init_cpus(void) {} +#define raw_smp_processor_id() 0 + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_SMP */ + +#endif /* _ASM_SMP_H */ diff --git a/arch/mn10300/include/asm/smsc911x.h b/arch/mn10300/include/asm/smsc911x.h new file mode 100644 index 000000000..2fcd10803 --- /dev/null +++ b/arch/mn10300/include/asm/smsc911x.h @@ -0,0 +1 @@ +#include <unit/smsc911x.h> diff --git a/arch/mn10300/include/asm/spinlock.h b/arch/mn10300/include/asm/spinlock.h new file mode 100644 index 000000000..1ae580f38 --- /dev/null +++ b/arch/mn10300/include/asm/spinlock.h @@ -0,0 +1,193 @@ +/* MN10300 spinlock support + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SPINLOCK_H +#define _ASM_SPINLOCK_H + +#include <linux/atomic.h> +#include <asm/rwlock.h> +#include <asm/page.h> + +/* + * Simple spin lock operations. There are two variants, one clears IRQ's + * on the local processor, one does not. + * + * We make no fairness assumptions. They have a cost. + */ + +#define arch_spin_is_locked(x) (*(volatile signed char *)(&(x)->slock) != 0) +#define arch_spin_unlock_wait(x) do { barrier(); } while (arch_spin_is_locked(x)) + +static inline void arch_spin_unlock(arch_spinlock_t *lock) +{ + asm volatile( + " bclr 1,(0,%0) \n" + : + : "a"(&lock->slock) + : "memory", "cc"); +} + +static inline int arch_spin_trylock(arch_spinlock_t *lock) +{ + int ret; + + asm volatile( + " mov 1,%0 \n" + " bset %0,(%1) \n" + " bne 1f \n" + " clr %0 \n" + "1: xor 1,%0 \n" + : "=d"(ret) + : "a"(&lock->slock) + : "memory", "cc"); + + return ret; +} + +static inline void arch_spin_lock(arch_spinlock_t *lock) +{ + asm volatile( + "1: bset 1,(0,%0) \n" + " bne 1b \n" + : + : "a"(&lock->slock) + : "memory", "cc"); +} + +static inline void arch_spin_lock_flags(arch_spinlock_t *lock, + unsigned long flags) +{ + int temp; + + asm volatile( + "1: bset 1,(0,%2) \n" + " beq 3f \n" + " mov %1,epsw \n" + "2: mov (0,%2),%0 \n" + " or %0,%0 \n" + " bne 2b \n" + " mov %3,%0 \n" + " mov %0,epsw \n" + " nop \n" + " nop \n" + " bra 1b\n" + "3: \n" + : "=&d" (temp) + : "d" (flags), "a"(&lock->slock), "i"(EPSW_IE | MN10300_CLI_LEVEL) + : "memory", "cc"); +} + +#ifdef __KERNEL__ + +/* + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + */ + +/** + * read_can_lock - would read_trylock() succeed? + * @lock: the rwlock in question. + */ +#define arch_read_can_lock(x) ((int)(x)->lock > 0) + +/** + * write_can_lock - would write_trylock() succeed? + * @lock: the rwlock in question. + */ +#define arch_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS) + +/* + * On mn10300, we implement read-write locks as a 32-bit counter + * with the high bit (sign) being the "contended" bit. + */ +static inline void arch_read_lock(arch_rwlock_t *rw) +{ +#if 0 //def CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT + __build_read_lock(rw, "__read_lock_failed"); +#else + { + atomic_t *count = (atomic_t *)rw; + while (atomic_dec_return(count) < 0) + atomic_inc(count); + } +#endif +} + +static inline void arch_write_lock(arch_rwlock_t *rw) +{ +#if 0 //def CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT + __build_write_lock(rw, "__write_lock_failed"); +#else + { + atomic_t *count = (atomic_t *)rw; + while (!atomic_sub_and_test(RW_LOCK_BIAS, count)) + atomic_add(RW_LOCK_BIAS, count); + } +#endif +} + +static inline void arch_read_unlock(arch_rwlock_t *rw) +{ +#if 0 //def CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT + __build_read_unlock(rw); +#else + { + atomic_t *count = (atomic_t *)rw; + atomic_inc(count); + } +#endif +} + +static inline void arch_write_unlock(arch_rwlock_t *rw) +{ +#if 0 //def CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT + __build_write_unlock(rw); +#else + { + atomic_t *count = (atomic_t *)rw; + atomic_add(RW_LOCK_BIAS, count); + } +#endif +} + +static inline int arch_read_trylock(arch_rwlock_t *lock) +{ + atomic_t *count = (atomic_t *)lock; + atomic_dec(count); + if (atomic_read(count) >= 0) + return 1; + atomic_inc(count); + return 0; +} + +static inline int arch_write_trylock(arch_rwlock_t *lock) +{ + atomic_t *count = (atomic_t *)lock; + if (atomic_sub_and_test(RW_LOCK_BIAS, count)) + return 1; + atomic_add(RW_LOCK_BIAS, count); + return 0; +} + +#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) +#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) + +#define _raw_spin_relax(lock) cpu_relax() +#define _raw_read_relax(lock) cpu_relax() +#define _raw_write_relax(lock) cpu_relax() + +#endif /* __KERNEL__ */ +#endif /* _ASM_SPINLOCK_H */ diff --git a/arch/mn10300/include/asm/spinlock_types.h b/arch/mn10300/include/asm/spinlock_types.h new file mode 100644 index 000000000..653dc519b --- /dev/null +++ b/arch/mn10300/include/asm/spinlock_types.h @@ -0,0 +1,20 @@ +#ifndef _ASM_SPINLOCK_TYPES_H +#define _ASM_SPINLOCK_TYPES_H + +#ifndef __LINUX_SPINLOCK_TYPES_H +# error "please don't include this file directly" +#endif + +typedef struct arch_spinlock { + unsigned int slock; +} arch_spinlock_t; + +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } + +typedef struct { + unsigned int lock; +} arch_rwlock_t; + +#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } + +#endif /* _ASM_SPINLOCK_TYPES_H */ diff --git a/arch/mn10300/include/asm/string.h b/arch/mn10300/include/asm/string.h new file mode 100644 index 000000000..47dbd4346 --- /dev/null +++ b/arch/mn10300/include/asm/string.h @@ -0,0 +1,32 @@ +/* MN10300 Optimised string functions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Modified by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_STRING_H +#define _ASM_STRING_H + +#define __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMCPY +#define __HAVE_ARCH_MEMMOVE + +extern void *memset(void *dest, int ch, size_t count); +extern void *memcpy(void *dest, const void *src, size_t count); +extern void *memmove(void *dest, const void *src, size_t count); + + +extern void __struct_cpy_bug(void); +#define struct_cpy(x, y) \ +({ \ + if (sizeof(*(x)) != sizeof(*(y))) \ + __struct_cpy_bug; \ + memcpy(x, y, sizeof(*(x))); \ +}) + +#endif /* _ASM_STRING_H */ diff --git a/arch/mn10300/include/asm/switch_to.h b/arch/mn10300/include/asm/switch_to.h new file mode 100644 index 000000000..393d31173 --- /dev/null +++ b/arch/mn10300/include/asm/switch_to.h @@ -0,0 +1,49 @@ +/* MN10300 task switching definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SWITCH_TO_H +#define _ASM_SWITCH_TO_H + +#include <asm/barrier.h> + +struct task_struct; +struct thread_struct; + +#if !defined(CONFIG_LAZY_SAVE_FPU) +struct fpu_state_struct; +extern asmlinkage void fpu_save(struct fpu_state_struct *); +#define switch_fpu(prev, next) \ + do { \ + if ((prev)->thread.fpu_flags & THREAD_HAS_FPU) { \ + (prev)->thread.fpu_flags &= ~THREAD_HAS_FPU; \ + (prev)->thread.uregs->epsw &= ~EPSW_FE; \ + fpu_save(&(prev)->thread.fpu_state); \ + } \ + } while (0) +#else +#define switch_fpu(prev, next) do {} while (0) +#endif + +/* context switching is now performed out-of-line in switch_to.S */ +extern asmlinkage +struct task_struct *__switch_to(struct thread_struct *prev, + struct thread_struct *next, + struct task_struct *prev_task); + +#define switch_to(prev, next, last) \ +do { \ + switch_fpu(prev, next); \ + current->thread.wchan = (u_long) __builtin_return_address(0); \ + (last) = __switch_to(&(prev)->thread, &(next)->thread, (prev)); \ + mb(); \ + current->thread.wchan = 0; \ +} while (0) + +#endif /* _ASM_SWITCH_TO_H */ diff --git a/arch/mn10300/include/asm/syscall.h b/arch/mn10300/include/asm/syscall.h new file mode 100644 index 000000000..b44b0bb75 --- /dev/null +++ b/arch/mn10300/include/asm/syscall.h @@ -0,0 +1,117 @@ +/* Access to user system call parameters and results + * + * See asm-generic/syscall.h for function descriptions. + * + * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_SYSCALL_H +#define _ASM_SYSCALL_H + +#include <linux/sched.h> +#include <linux/err.h> + +extern const unsigned long sys_call_table[]; + +static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) +{ + return regs->orig_d0; +} + +static inline void syscall_rollback(struct task_struct *task, + struct pt_regs *regs) +{ + regs->d0 = regs->orig_d0; +} + +static inline long syscall_get_error(struct task_struct *task, + struct pt_regs *regs) +{ + unsigned long error = regs->d0; + return IS_ERR_VALUE(error) ? error : 0; +} + +static inline long syscall_get_return_value(struct task_struct *task, + struct pt_regs *regs) +{ + return regs->d0; +} + +static inline void syscall_set_return_value(struct task_struct *task, + struct pt_regs *regs, + int error, long val) +{ + regs->d0 = (long) error ?: val; +} + +static inline void syscall_get_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned int i, unsigned int n, + unsigned long *args) +{ + switch (i) { + case 0: + if (!n--) break; + *args++ = regs->a0; + case 1: + if (!n--) break; + *args++ = regs->d1; + case 2: + if (!n--) break; + *args++ = regs->a3; + case 3: + if (!n--) break; + *args++ = regs->a2; + case 4: + if (!n--) break; + *args++ = regs->d3; + case 5: + if (!n--) break; + *args++ = regs->d2; + case 6: + if (!n--) break; + default: + BUG(); + break; + } +} + +static inline void syscall_set_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned int i, unsigned int n, + const unsigned long *args) +{ + switch (i) { + case 0: + if (!n--) break; + regs->a0 = *args++; + case 1: + if (!n--) break; + regs->d1 = *args++; + case 2: + if (!n--) break; + regs->a3 = *args++; + case 3: + if (!n--) break; + regs->a2 = *args++; + case 4: + if (!n--) break; + regs->d3 = *args++; + case 5: + if (!n--) break; + regs->d2 = *args++; + case 6: + if (!n--) break; + default: + BUG(); + break; + } +} + +#endif /* _ASM_SYSCALL_H */ diff --git a/arch/mn10300/include/asm/termios.h b/arch/mn10300/include/asm/termios.h new file mode 100644 index 000000000..c2e29c75d --- /dev/null +++ b/arch/mn10300/include/asm/termios.h @@ -0,0 +1,13 @@ +#ifndef _ASM_TERMIOS_H +#define _ASM_TERMIOS_H + +#include <uapi/asm/termios.h> + +/* intr=^C quit=^| erase=del kill=^U + eof=^D vtime=\0 vmin=\1 sxtc=\0 + start=^Q stop=^S susp=^Z eol=\0 + reprint=^R discard=^U werase=^W lnext=^V + eol2=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" +#endif /* _ASM_TERMIOS_H */ diff --git a/arch/mn10300/include/asm/thread_info.h b/arch/mn10300/include/asm/thread_info.h new file mode 100644 index 000000000..4861a78c7 --- /dev/null +++ b/arch/mn10300/include/asm/thread_info.h @@ -0,0 +1,162 @@ +/* MN10300 Low-level thread information + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_THREAD_INFO_H +#define _ASM_THREAD_INFO_H + +#ifdef __KERNEL__ + +#include <asm/page.h> + +#ifdef CONFIG_4KSTACKS +#define THREAD_SIZE (4096) +#define THREAD_SIZE_ORDER (0) +#else +#define THREAD_SIZE (8192) +#define THREAD_SIZE_ORDER (1) +#endif + +#define STACK_WARN (THREAD_SIZE / 8) + +/* + * low level task data that entry.S needs immediate access to + * - this struct should fit entirely inside of one cache line + * - this struct shares the supervisor stack pages + * - if the contents of this structure are changed, the assembly constants + * must also be changed + */ +#ifndef __ASSEMBLY__ +typedef struct { + unsigned long seg; +} mm_segment_t; + +struct thread_info { + struct task_struct *task; /* main task structure */ + struct pt_regs *frame; /* current exception frame */ + unsigned long flags; /* low level flags */ + __u32 cpu; /* current CPU */ + __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ + + mm_segment_t addr_limit; /* thread address space: + 0-0xBFFFFFFF for user-thead + 0-0xFFFFFFFF for kernel-thread + */ + + __u8 supervisor_stack[0]; +}; + +#define thread_info_to_uregs(ti) \ + ((struct pt_regs *) \ + ((unsigned long)ti + THREAD_SIZE - sizeof(struct pt_regs))) + +#else /* !__ASSEMBLY__ */ + +#ifndef __ASM_OFFSETS_H__ +#include <asm/asm-offsets.h> +#endif + +#endif + +/* + * macros/functions for gaining access to the thread information structure + */ +#ifndef __ASSEMBLY__ + +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .flags = 0, \ + .cpu = 0, \ + .preempt_count = INIT_PREEMPT_COUNT, \ + .addr_limit = KERNEL_DS, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) +#define init_uregs \ + ((struct pt_regs *) \ + ((unsigned long) init_stack + THREAD_SIZE - sizeof(struct pt_regs))) + +extern struct thread_info *__current_ti; + +/* how to get the thread information struct from C */ +static inline __attribute__((const)) +struct thread_info *current_thread_info(void) +{ + struct thread_info *ti; + asm("mov sp,%0\n" + "and %1,%0\n" + : "=d" (ti) + : "i" (~(THREAD_SIZE - 1)) + : "cc"); + return ti; +} + +static inline __attribute__((const)) +struct pt_regs *current_frame(void) +{ + return current_thread_info()->frame; +} + +/* how to get the current stack pointer from C */ +static inline unsigned long current_stack_pointer(void) +{ + unsigned long sp; + asm("mov sp,%0; ":"=r" (sp)); + return sp; +} + +#ifndef CONFIG_KGDB +void arch_release_thread_info(struct thread_info *ti); +#endif +#define get_thread_info(ti) get_task_struct((ti)->task) +#define put_thread_info(ti) put_task_struct((ti)->task) + +#else /* !__ASSEMBLY__ */ + +#ifndef __VMLINUX_LDS__ +/* how to get the thread information struct from ASM */ +.macro GET_THREAD_INFO reg + mov sp,\reg + and -THREAD_SIZE,\reg +.endm +#endif +#endif + +/* + * thread information flags + * - these are process state flags that various assembly files may need to + * access + * - pending work-to-be-done flags are in LSW + * - other flags in MSW + */ +#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ +#define TIF_SIGPENDING 2 /* signal pending */ +#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */ +#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ +#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ +#define TIF_MEMDIE 17 /* is terminating due to OOM killer */ + +#define _TIF_SYSCALL_TRACE +(1 << TIF_SYSCALL_TRACE) +#define _TIF_NOTIFY_RESUME +(1 << TIF_NOTIFY_RESUME) +#define _TIF_SIGPENDING +(1 << TIF_SIGPENDING) +#define _TIF_NEED_RESCHED +(1 << TIF_NEED_RESCHED) +#define _TIF_SINGLESTEP +(1 << TIF_SINGLESTEP) +#define _TIF_POLLING_NRFLAG +(1 << TIF_POLLING_NRFLAG) + +#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ +#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_THREAD_INFO_H */ diff --git a/arch/mn10300/include/asm/timer-regs.h b/arch/mn10300/include/asm/timer-regs.h new file mode 100644 index 000000000..c634977ca --- /dev/null +++ b/arch/mn10300/include/asm/timer-regs.h @@ -0,0 +1,452 @@ +/* AM33v2 on-board timer module registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_TIMER_REGS_H +#define _ASM_TIMER_REGS_H + +#include <asm/cpu-regs.h> +#include <asm/intctl-regs.h> + +#ifdef __KERNEL__ + +/* + * Timer prescalar control + */ +#define TMPSCNT __SYSREG(0xd4003071, u8) /* timer prescaler control */ +#define TMPSCNT_ENABLE 0x80 /* timer prescaler enable */ +#define TMPSCNT_DISABLE 0x00 /* timer prescaler disable */ + +/* + * 8-bit timers + */ +#define TM0MD __SYSREG(0xd4003000, u8) /* timer 0 mode register */ +#define TM0MD_SRC 0x07 /* timer source */ +#define TM0MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM0MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM0MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM0MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM0MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#if defined(CONFIG_AM33_2) +#define TM0MD_SRC_TM2IO 0x03 /* - TM2IO pin input */ +#define TM0MD_SRC_TM0IO 0x07 /* - TM0IO pin input */ +#endif /* CONFIG_AM33_2 */ +#define TM0MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM0MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM1MD __SYSREG(0xd4003001, u8) /* timer 1 mode register */ +#define TM1MD_SRC 0x07 /* timer source */ +#define TM1MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM1MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM1MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM1MD_SRC_TM0CASCADE 0x03 /* - cascade with timer 0 */ +#define TM1MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM1MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#if defined(CONFIG_AM33_2) +#define TM1MD_SRC_TM1IO 0x07 /* - TM1IO pin input */ +#endif /* CONFIG_AM33_2 */ +#define TM1MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM1MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM2MD __SYSREG(0xd4003002, u8) /* timer 2 mode register */ +#define TM2MD_SRC 0x07 /* timer source */ +#define TM2MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM2MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM2MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM2MD_SRC_TM1CASCADE 0x03 /* - cascade with timer 1 */ +#define TM2MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM2MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#if defined(CONFIG_AM33_2) +#define TM2MD_SRC_TM2IO 0x07 /* - TM2IO pin input */ +#endif /* CONFIG_AM33_2 */ +#define TM2MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM2MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM3MD __SYSREG(0xd4003003, u8) /* timer 3 mode register */ +#define TM3MD_SRC 0x07 /* timer source */ +#define TM3MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM3MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM3MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM3MD_SRC_TM2CASCADE 0x03 /* - cascade with timer 2 */ +#define TM3MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM3MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM3MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#if defined(CONFIG_AM33_2) +#define TM3MD_SRC_TM3IO 0x07 /* - TM3IO pin input */ +#endif /* CONFIG_AM33_2 */ +#define TM3MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM3MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM01MD __SYSREG(0xd4003000, u16) /* timer 0:1 mode register */ + +#define TM0BR __SYSREG(0xd4003010, u8) /* timer 0 base register */ +#define TM1BR __SYSREG(0xd4003011, u8) /* timer 1 base register */ +#define TM2BR __SYSREG(0xd4003012, u8) /* timer 2 base register */ +#define TM3BR __SYSREG(0xd4003013, u8) /* timer 3 base register */ +#define TM01BR __SYSREG(0xd4003010, u16) /* timer 0:1 base register */ + +#define TM0BC __SYSREGC(0xd4003020, u8) /* timer 0 binary counter */ +#define TM1BC __SYSREGC(0xd4003021, u8) /* timer 1 binary counter */ +#define TM2BC __SYSREGC(0xd4003022, u8) /* timer 2 binary counter */ +#define TM3BC __SYSREGC(0xd4003023, u8) /* timer 3 binary counter */ +#define TM01BC __SYSREGC(0xd4003020, u16) /* timer 0:1 binary counter */ + +#define TM0IRQ 2 /* timer 0 IRQ */ +#define TM1IRQ 3 /* timer 1 IRQ */ +#define TM2IRQ 4 /* timer 2 IRQ */ +#define TM3IRQ 5 /* timer 3 IRQ */ + +#define TM0ICR GxICR(TM0IRQ) /* timer 0 uflow intr ctrl reg */ +#define TM1ICR GxICR(TM1IRQ) /* timer 1 uflow intr ctrl reg */ +#define TM2ICR GxICR(TM2IRQ) /* timer 2 uflow intr ctrl reg */ +#define TM3ICR GxICR(TM3IRQ) /* timer 3 uflow intr ctrl reg */ + +/* + * 16-bit timers 4,5 & 7-15 + */ +#define TM4MD __SYSREG(0xd4003080, u8) /* timer 4 mode register */ +#define TM4MD_SRC 0x07 /* timer source */ +#define TM4MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM4MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM4MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM4MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM4MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM4MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#if defined(CONFIG_AM33_2) +#define TM4MD_SRC_TM4IO 0x07 /* - TM4IO pin input */ +#endif /* CONFIG_AM33_2 */ +#define TM4MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM4MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM5MD __SYSREG(0xd4003082, u8) /* timer 5 mode register */ +#define TM5MD_SRC 0x07 /* timer source */ +#define TM5MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM5MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM5MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM5MD_SRC_TM4CASCADE 0x03 /* - cascade with timer 4 */ +#define TM5MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM5MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM5MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#if defined(CONFIG_AM33_2) +#define TM5MD_SRC_TM5IO 0x07 /* - TM5IO pin input */ +#else /* !CONFIG_AM33_2 */ +#define TM5MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */ +#endif /* CONFIG_AM33_2 */ +#define TM5MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM5MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM7MD __SYSREG(0xd4003086, u8) /* timer 7 mode register */ +#define TM7MD_SRC 0x07 /* timer source */ +#define TM7MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM7MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM7MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM7MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM7MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM7MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#if defined(CONFIG_AM33_2) +#define TM7MD_SRC_TM7IO 0x07 /* - TM7IO pin input */ +#endif /* CONFIG_AM33_2 */ +#define TM7MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM7MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM8MD __SYSREG(0xd4003088, u8) /* timer 8 mode register */ +#define TM8MD_SRC 0x07 /* timer source */ +#define TM8MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM8MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM8MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM8MD_SRC_TM7CASCADE 0x03 /* - cascade with timer 7 */ +#define TM8MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM8MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM8MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#if defined(CONFIG_AM33_2) +#define TM8MD_SRC_TM8IO 0x07 /* - TM8IO pin input */ +#else /* !CONFIG_AM33_2 */ +#define TM8MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */ +#endif /* CONFIG_AM33_2 */ +#define TM8MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM8MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM9MD __SYSREG(0xd400308a, u8) /* timer 9 mode register */ +#define TM9MD_SRC 0x07 /* timer source */ +#define TM9MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM9MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM9MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM9MD_SRC_TM8CASCADE 0x03 /* - cascade with timer 8 */ +#define TM9MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM9MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM9MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#if defined(CONFIG_AM33_2) +#define TM9MD_SRC_TM9IO 0x07 /* - TM9IO pin input */ +#else /* !CONFIG_AM33_2 */ +#define TM9MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */ +#endif /* CONFIG_AM33_2 */ +#define TM9MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM9MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM10MD __SYSREG(0xd400308c, u8) /* timer 10 mode register */ +#define TM10MD_SRC 0x07 /* timer source */ +#define TM10MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM10MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM10MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM10MD_SRC_TM9CASCADE 0x03 /* - cascade with timer 9 */ +#define TM10MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM10MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM10MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#if defined(CONFIG_AM33_2) +#define TM10MD_SRC_TM10IO 0x07 /* - TM10IO pin input */ +#else /* !CONFIG_AM33_2 */ +#define TM10MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */ +#endif /* CONFIG_AM33_2 */ +#define TM10MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM10MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM11MD __SYSREG(0xd400308e, u8) /* timer 11 mode register */ +#define TM11MD_SRC 0x07 /* timer source */ +#define TM11MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM11MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM11MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM11MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM11MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM11MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#if defined(CONFIG_AM33_2) +#define TM11MD_SRC_TM11IO 0x07 /* - TM11IO pin input */ +#else /* !CONFIG_AM33_2 */ +#define TM11MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */ +#endif /* CONFIG_AM33_2 */ +#define TM11MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM11MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#if defined(CONFIG_AM34_2) +#define TM12MD __SYSREG(0xd4003180, u8) /* timer 11 mode register */ +#define TM12MD_SRC 0x07 /* timer source */ +#define TM12MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM12MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM12MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM12MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM12MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM12MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM12MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */ +#define TM12MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM12MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM13MD __SYSREG(0xd4003182, u8) /* timer 11 mode register */ +#define TM13MD_SRC 0x07 /* timer source */ +#define TM13MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM13MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM13MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM13MD_SRC_TM12CASCADE 0x03 /* - cascade with timer 12 */ +#define TM13MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM13MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM13MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM13MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */ +#define TM13MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM13MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM14MD __SYSREG(0xd4003184, u8) /* timer 11 mode register */ +#define TM14MD_SRC 0x07 /* timer source */ +#define TM14MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM14MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM14MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM14MD_SRC_TM13CASCADE 0x03 /* - cascade with timer 13 */ +#define TM14MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM14MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM14MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM14MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */ +#define TM14MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM14MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM15MD __SYSREG(0xd4003186, u8) /* timer 11 mode register */ +#define TM15MD_SRC 0x07 /* timer source */ +#define TM15MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM15MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM15MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM15MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM15MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM15MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM15MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */ +#define TM15MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM15MD_COUNT_ENABLE 0x80 /* timer count enable */ +#endif /* CONFIG_AM34_2 */ + + +#define TM4BR __SYSREG(0xd4003090, u16) /* timer 4 base register */ +#define TM5BR __SYSREG(0xd4003092, u16) /* timer 5 base register */ +#define TM45BR __SYSREG(0xd4003090, u32) /* timer 4:5 base register */ +#define TM7BR __SYSREG(0xd4003096, u16) /* timer 7 base register */ +#define TM8BR __SYSREG(0xd4003098, u16) /* timer 8 base register */ +#define TM9BR __SYSREG(0xd400309a, u16) /* timer 9 base register */ +#define TM89BR __SYSREG(0xd4003098, u32) /* timer 8:9 base register */ +#define TM10BR __SYSREG(0xd400309c, u16) /* timer 10 base register */ +#define TM11BR __SYSREG(0xd400309e, u16) /* timer 11 base register */ +#if defined(CONFIG_AM34_2) +#define TM12BR __SYSREG(0xd4003190, u16) /* timer 12 base register */ +#define TM13BR __SYSREG(0xd4003192, u16) /* timer 13 base register */ +#define TM14BR __SYSREG(0xd4003194, u16) /* timer 14 base register */ +#define TM15BR __SYSREG(0xd4003196, u16) /* timer 15 base register */ +#endif /* CONFIG_AM34_2 */ + +#define TM4BC __SYSREG(0xd40030a0, u16) /* timer 4 binary counter */ +#define TM5BC __SYSREG(0xd40030a2, u16) /* timer 5 binary counter */ +#define TM45BC __SYSREG(0xd40030a0, u32) /* timer 4:5 binary counter */ +#define TM7BC __SYSREG(0xd40030a6, u16) /* timer 7 binary counter */ +#define TM8BC __SYSREG(0xd40030a8, u16) /* timer 8 binary counter */ +#define TM9BC __SYSREG(0xd40030aa, u16) /* timer 9 binary counter */ +#define TM89BC __SYSREG(0xd40030a8, u32) /* timer 8:9 binary counter */ +#define TM10BC __SYSREG(0xd40030ac, u16) /* timer 10 binary counter */ +#define TM11BC __SYSREG(0xd40030ae, u16) /* timer 11 binary counter */ +#if defined(CONFIG_AM34_2) +#define TM12BC __SYSREG(0xd40031a0, u16) /* timer 12 binary counter */ +#define TM13BC __SYSREG(0xd40031a2, u16) /* timer 13 binary counter */ +#define TM14BC __SYSREG(0xd40031a4, u16) /* timer 14 binary counter */ +#define TM15BC __SYSREG(0xd40031a6, u16) /* timer 15 binary counter */ +#endif /* CONFIG_AM34_2 */ + +#define TM4IRQ 6 /* timer 4 IRQ */ +#define TM5IRQ 7 /* timer 5 IRQ */ +#define TM7IRQ 11 /* timer 7 IRQ */ +#define TM8IRQ 12 /* timer 8 IRQ */ +#define TM9IRQ 13 /* timer 9 IRQ */ +#define TM10IRQ 14 /* timer 10 IRQ */ +#define TM11IRQ 15 /* timer 11 IRQ */ +#if defined(CONFIG_AM34_2) +#define TM12IRQ 64 /* timer 12 IRQ */ +#define TM13IRQ 65 /* timer 13 IRQ */ +#define TM14IRQ 66 /* timer 14 IRQ */ +#define TM15IRQ 67 /* timer 15 IRQ */ +#endif /* CONFIG_AM34_2 */ + +#define TM4ICR GxICR(TM4IRQ) /* timer 4 uflow intr ctrl reg */ +#define TM5ICR GxICR(TM5IRQ) /* timer 5 uflow intr ctrl reg */ +#define TM7ICR GxICR(TM7IRQ) /* timer 7 uflow intr ctrl reg */ +#define TM8ICR GxICR(TM8IRQ) /* timer 8 uflow intr ctrl reg */ +#define TM9ICR GxICR(TM9IRQ) /* timer 9 uflow intr ctrl reg */ +#define TM10ICR GxICR(TM10IRQ) /* timer 10 uflow intr ctrl reg */ +#define TM11ICR GxICR(TM11IRQ) /* timer 11 uflow intr ctrl reg */ +#if defined(CONFIG_AM34_2) +#define TM12ICR GxICR(TM12IRQ) /* timer 12 uflow intr ctrl reg */ +#define TM13ICR GxICR(TM13IRQ) /* timer 13 uflow intr ctrl reg */ +#define TM14ICR GxICR(TM14IRQ) /* timer 14 uflow intr ctrl reg */ +#define TM15ICR GxICR(TM15IRQ) /* timer 15 uflow intr ctrl reg */ +#endif /* CONFIG_AM34_2 */ + +/* + * 16-bit timer 6 + */ +#define TM6MD __SYSREG(0xd4003084, u16) /* timer6 mode register */ +#define TM6MD_SRC 0x0007 /* timer source */ +#define TM6MD_SRC_IOCLK 0x0000 /* - IOCLK */ +#define TM6MD_SRC_IOCLK_8 0x0001 /* - 1/8 IOCLK */ +#define TM6MD_SRC_IOCLK_32 0x0002 /* - 1/32 IOCLK */ +#define TM6MD_SRC_TM0UFLOW 0x0004 /* - timer 0 underflow */ +#define TM6MD_SRC_TM1UFLOW 0x0005 /* - timer 1 underflow */ +#define TM6MD_SRC_TM2UFLOW 0x0006 /* - timer 2 underflow */ +#if defined(CONFIG_AM33_2) +/* #define TM6MD_SRC_TM6IOB_BOTH 0x0006 */ /* - TM6IOB pin input (both edges) */ +#define TM6MD_SRC_TM6IOB_SINGLE 0x0007 /* - TM6IOB pin input (single edge) */ +#endif /* CONFIG_AM33_2 */ +#define TM6MD_ONESHOT_ENABLE 0x0040 /* oneshot count */ +#define TM6MD_CLR_ENABLE 0x0010 /* clear count enable */ +#if defined(CONFIG_AM33_2) +#define TM6MD_TRIG_ENABLE 0x0080 /* TM6IOB pin trigger enable */ +#define TM6MD_PWM 0x3800 /* PWM output mode */ +#define TM6MD_PWM_DIS 0x0000 /* - disabled */ +#define TM6MD_PWM_10BIT 0x1000 /* - 10 bits mode */ +#define TM6MD_PWM_11BIT 0x1800 /* - 11 bits mode */ +#define TM6MD_PWM_12BIT 0x3000 /* - 12 bits mode */ +#define TM6MD_PWM_14BIT 0x3800 /* - 14 bits mode */ +#endif /* CONFIG_AM33_2 */ + +#define TM6MD_INIT_COUNTER 0x4000 /* initialize TMnBC to zero */ +#define TM6MD_COUNT_ENABLE 0x8000 /* timer count enable */ + +#define TM6MDA __SYSREG(0xd40030b4, u8) /* timer6 cmp/cap A mode reg */ +#define TM6MDA_MODE_CMP_SINGLE 0x00 /* - compare, single buffer mode */ +#define TM6MDA_MODE_CMP_DOUBLE 0x40 /* - compare, double buffer mode */ +#if defined(CONFIG_AM33_2) +#define TM6MDA_OUT 0x07 /* output select */ +#define TM6MDA_OUT_SETA_RESETB 0x00 /* - set at match A, reset at match B */ +#define TM6MDA_OUT_SETA_RESETOV 0x01 /* - set at match A, reset at overflow */ +#define TM6MDA_OUT_SETA 0x02 /* - set at match A */ +#define TM6MDA_OUT_RESETA 0x03 /* - reset at match A */ +#define TM6MDA_OUT_TOGGLE 0x04 /* - toggle on match A */ +#define TM6MDA_MODE 0xc0 /* compare A register mode */ +#define TM6MDA_MODE_CAP_S_EDGE 0x80 /* - capture, single edge mode */ +#define TM6MDA_MODE_CAP_D_EDGE 0xc0 /* - capture, double edge mode */ +#define TM6MDA_EDGE 0x20 /* compare A edge select */ +#define TM6MDA_EDGE_FALLING 0x00 /* capture on falling edge */ +#define TM6MDA_EDGE_RISING 0x20 /* capture on rising edge */ +#define TM6MDA_CAPTURE_ENABLE 0x10 /* capture enable */ +#else /* !CONFIG_AM33_2 */ +#define TM6MDA_MODE 0x40 /* compare A register mode */ +#endif /* CONFIG_AM33_2 */ + +#define TM6MDB __SYSREG(0xd40030b5, u8) /* timer6 cmp/cap B mode reg */ +#define TM6MDB_MODE_CMP_SINGLE 0x00 /* - compare, single buffer mode */ +#define TM6MDB_MODE_CMP_DOUBLE 0x40 /* - compare, double buffer mode */ +#if defined(CONFIG_AM33_2) +#define TM6MDB_OUT 0x07 /* output select */ +#define TM6MDB_OUT_SETB_RESETA 0x00 /* - set at match B, reset at match A */ +#define TM6MDB_OUT_SETB_RESETOV 0x01 /* - set at match B */ +#define TM6MDB_OUT_RESETB 0x03 /* - reset at match B */ +#define TM6MDB_OUT_TOGGLE 0x04 /* - toggle on match B */ +#define TM6MDB_MODE 0xc0 /* compare B register mode */ +#define TM6MDB_MODE_CAP_S_EDGE 0x80 /* - capture, single edge mode */ +#define TM6MDB_MODE_CAP_D_EDGE 0xc0 /* - capture, double edge mode */ +#define TM6MDB_EDGE 0x20 /* compare B edge select */ +#define TM6MDB_EDGE_FALLING 0x00 /* capture on falling edge */ +#define TM6MDB_EDGE_RISING 0x20 /* capture on rising edge */ +#define TM6MDB_CAPTURE_ENABLE 0x10 /* capture enable */ +#else /* !CONFIG_AM33_2 */ +#define TM6MDB_MODE 0x40 /* compare B register mode */ +#endif /* CONFIG_AM33_2 */ + +#define TM6CA __SYSREG(0xd40030c4, u16) /* timer6 cmp/capture reg A */ +#define TM6CB __SYSREG(0xd40030d4, u16) /* timer6 cmp/capture reg B */ +#define TM6BC __SYSREG(0xd40030a4, u16) /* timer6 binary counter */ + +#define TM6IRQ 6 /* timer 6 IRQ */ +#define TM6AIRQ 9 /* timer 6A IRQ */ +#define TM6BIRQ 10 /* timer 6B IRQ */ + +#define TM6ICR GxICR(TM6IRQ) /* timer 6 uflow intr ctrl reg */ +#define TM6AICR GxICR(TM6AIRQ) /* timer 6A intr control reg */ +#define TM6BICR GxICR(TM6BIRQ) /* timer 6B intr control reg */ + +#if defined(CONFIG_AM34_2) +/* + * MTM: OS Tick-Timer + */ +#define TMTMD __SYSREG(0xd4004100, u8) /* Tick Timer mode register */ +#define TMTMD_TMTLDE 0x40 /* initialize TMTBC = TMTBR */ +#define TMTMD_TMTCNE 0x80 /* timer count enable */ + +#define TMTBR __SYSREG(0xd4004110, u32) /* Tick Timer mode reg */ +#define TMTBC __SYSREG(0xd4004120, u32) /* Tick Timer mode reg */ + +/* + * MTM: OS Timestamp-Timer + */ +#define TMSMD __SYSREG(0xd4004140, u8) /* Tick Timer mode register */ +#define TMSMD_TMSLDE 0x40 /* initialize TMSBC = TMSBR */ +#define TMSMD_TMSCNE 0x80 /* timer count enable */ + +#define TMSBR __SYSREG(0xd4004150, u32) /* Tick Timer mode register */ +#define TMSBC __SYSREG(0xd4004160, u32) /* Tick Timer mode register */ + +#define TMTIRQ 119 /* OS Tick timer IRQ */ +#define TMSIRQ 120 /* Timestamp timer IRQ */ + +#define TMTICR GxICR(TMTIRQ) /* OS Tick timer uflow intr ctrl reg */ +#define TMSICR GxICR(TMSIRQ) /* Timestamp timer uflow intr ctrl reg */ +#endif /* CONFIG_AM34_2 */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_TIMER_REGS_H */ diff --git a/arch/mn10300/include/asm/timex.h b/arch/mn10300/include/asm/timex.h new file mode 100644 index 000000000..f8e66425c --- /dev/null +++ b/arch/mn10300/include/asm/timex.h @@ -0,0 +1,34 @@ +/* MN10300 Architecture time management specifications + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_TIMEX_H +#define _ASM_TIMEX_H + +#include <unit/timex.h> + +#define TICK_SIZE (tick_nsec / 1000) + +#define CLOCK_TICK_RATE MN10300_JCCLK /* Underlying HZ */ + +#ifdef __KERNEL__ + +extern cycles_t cacheflush_time; + +static inline cycles_t get_cycles(void) +{ + return read_timestamp_counter(); +} + +extern int init_clockevents(void); +extern int init_clocksource(void); + +#endif /* __KERNEL__ */ + +#endif /* _ASM_TIMEX_H */ diff --git a/arch/mn10300/include/asm/tlb.h b/arch/mn10300/include/asm/tlb.h new file mode 100644 index 000000000..65d232b96 --- /dev/null +++ b/arch/mn10300/include/asm/tlb.h @@ -0,0 +1,34 @@ +/* MN10300 TLB definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_TLB_H +#define _ASM_TLB_H + +#include <asm/tlbflush.h> + +extern void check_pgt_cache(void); + +/* + * we don't need any special per-pte or per-vma handling... + */ +#define tlb_start_vma(tlb, vma) do { } while (0) +#define tlb_end_vma(tlb, vma) do { } while (0) +#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) + +/* + * .. because we flush the whole mm when it fills up + */ +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) + +/* for now, just use the generic stuff */ +#include <asm-generic/tlb.h> + +#endif /* _ASM_TLB_H */ diff --git a/arch/mn10300/include/asm/tlbflush.h b/arch/mn10300/include/asm/tlbflush.h new file mode 100644 index 000000000..efddd6e1a --- /dev/null +++ b/arch/mn10300/include/asm/tlbflush.h @@ -0,0 +1,154 @@ +/* MN10300 TLB flushing functions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_TLBFLUSH_H +#define _ASM_TLBFLUSH_H + +#include <linux/mm.h> +#include <asm/processor.h> + +struct tlb_state { + struct mm_struct *active_mm; + int state; +}; +DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate); + +/** + * local_flush_tlb - Flush the current MM's entries from the local CPU's TLBs + */ +static inline void local_flush_tlb(void) +{ + int w; + asm volatile( + " mov %1,%0 \n" + " or %2,%0 \n" + " mov %0,%1 \n" + : "=d"(w) + : "m"(MMUCTR), "i"(MMUCTR_IIV|MMUCTR_DIV) + : "cc", "memory"); +} + +/** + * local_flush_tlb_all - Flush all entries from the local CPU's TLBs + */ +static inline void local_flush_tlb_all(void) +{ + local_flush_tlb(); +} + +/** + * local_flush_tlb_one - Flush one entry from the local CPU's TLBs + */ +static inline void local_flush_tlb_one(unsigned long addr) +{ + local_flush_tlb(); +} + +/** + * local_flush_tlb_page - Flush a page's entry from the local CPU's TLBs + * @mm: The MM to flush for + * @addr: The address of the target page in RAM (not its page struct) + */ +static inline +void local_flush_tlb_page(struct mm_struct *mm, unsigned long addr) +{ + unsigned long pteu, flags, cnx; + + addr &= PAGE_MASK; + + local_irq_save(flags); + + cnx = 1; +#ifdef CONFIG_MN10300_TLB_USE_PIDR + cnx = mm->context.tlbpid[smp_processor_id()]; +#endif + if (cnx) { + pteu = addr; +#ifdef CONFIG_MN10300_TLB_USE_PIDR + pteu |= cnx & xPTEU_PID; +#endif + IPTEU = pteu; + DPTEU = pteu; + if (IPTEL & xPTEL_V) + IPTEL = 0; + if (DPTEL & xPTEL_V) + DPTEL = 0; + } + local_irq_restore(flags); +} + +/* + * TLB flushing: + * + * - flush_tlb() flushes the current mm struct TLBs + * - flush_tlb_all() flushes all processes TLBs + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_range(mm, start, end) flushes a range of pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables + */ +#ifdef CONFIG_SMP + +#include <asm/smp.h> + +extern void flush_tlb_all(void); +extern void flush_tlb_current_task(void); +extern void flush_tlb_mm(struct mm_struct *); +extern void flush_tlb_page(struct vm_area_struct *, unsigned long); + +#define flush_tlb() flush_tlb_current_task() + +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + flush_tlb_mm(vma->vm_mm); +} + +#else /* CONFIG_SMP */ + +static inline void flush_tlb_all(void) +{ + preempt_disable(); + local_flush_tlb_all(); + preempt_enable(); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + preempt_disable(); + local_flush_tlb_all(); + preempt_enable(); +} + +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + preempt_disable(); + local_flush_tlb_all(); + preempt_enable(); +} + +#define flush_tlb_page(vma, addr) local_flush_tlb_page((vma)->vm_mm, addr) +#define flush_tlb() flush_tlb_all() + +#endif /* CONFIG_SMP */ + +static inline void flush_tlb_kernel_range(unsigned long start, + unsigned long end) +{ + flush_tlb_all(); +} + +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + +#endif /* _ASM_TLBFLUSH_H */ diff --git a/arch/mn10300/include/asm/topology.h b/arch/mn10300/include/asm/topology.h new file mode 100644 index 000000000..5428f333a --- /dev/null +++ b/arch/mn10300/include/asm/topology.h @@ -0,0 +1 @@ +#include <asm-generic/topology.h> diff --git a/arch/mn10300/include/asm/types.h b/arch/mn10300/include/asm/types.h new file mode 100644 index 000000000..3d6e48311 --- /dev/null +++ b/arch/mn10300/include/asm/types.h @@ -0,0 +1,22 @@ +/* MN10300 Basic type definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_TYPES_H +#define _ASM_TYPES_H + +#include <uapi/asm/types.h> + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ + +#define BITS_PER_LONG 32 + +#endif /* _ASM_TYPES_H */ diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h new file mode 100644 index 000000000..537278746 --- /dev/null +++ b/arch/mn10300/include/asm/uaccess.h @@ -0,0 +1,495 @@ +/* MN10300 userspace access functions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_UACCESS_H +#define _ASM_UACCESS_H + +/* + * User space memory access functions + */ +#include <linux/thread_info.h> +#include <linux/kernel.h> +#include <asm/page.h> +#include <asm/errno.h> + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* + * The fs value determines whether argument validity checking should be + * performed or not. If get_fs() == USER_DS, checking is performed, with + * get_fs() == KERNEL_DS, checking is bypassed. + * + * For historical reasons, these macros are grossly misnamed. + */ +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) + +#define KERNEL_XDS MAKE_MM_SEG(0xBFFFFFFF) +#define KERNEL_DS MAKE_MM_SEG(0x9FFFFFFF) +#define USER_DS MAKE_MM_SEG(TASK_SIZE) + +#define get_ds() (KERNEL_DS) +#define get_fs() (current_thread_info()->addr_limit) +#define set_fs(x) (current_thread_info()->addr_limit = (x)) +#define __kernel_ds_p() (current_thread_info()->addr_limit.seg == 0x9FFFFFFF) + +#define segment_eq(a, b) ((a).seg == (b).seg) + +#define __addr_ok(addr) \ + ((unsigned long)(addr) < (current_thread_info()->addr_limit.seg)) + +/* + * check that a range of addresses falls within the current address limit + */ +static inline int ___range_ok(unsigned long addr, unsigned int size) +{ + int flag = 1, tmp; + + asm(" add %3,%1 \n" /* set C-flag if addr + size > 4Gb */ + " bcs 0f \n" + " cmp %4,%1 \n" /* jump if addr+size>limit (error) */ + " bhi 0f \n" + " clr %0 \n" /* mark okay */ + "0: \n" + : "=r"(flag), "=&r"(tmp) + : "1"(addr), "ir"(size), + "r"(current_thread_info()->addr_limit.seg), "0"(flag) + : "cc" + ); + + return flag; +} + +#define __range_ok(addr, size) ___range_ok((unsigned long)(addr), (u32)(size)) + +#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0) +#define __access_ok(addr, size) (__range_ok((addr), (size)) == 0) + +static inline int verify_area(int type, const void *addr, unsigned long size) +{ + return access_ok(type, addr, size) ? 0 : -EFAULT; +} + + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +/* Returns 0 if exception not found and fixup otherwise. */ +extern int fixup_exception(struct pt_regs *regs); + +#define put_user(x, ptr) __put_user_check((x), (ptr), sizeof(*(ptr))) +#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr))) + +/* + * The "__xxx" versions do not do address space checking, useful when + * doing multiple accesses to the same area (the user has to do the + * checks by hand with "access_ok()") + */ +#define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr))) +#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr))) + +/* + * The "xxx_ret" versions return constant specified in third argument, if + * something bad happens. These macros can be optimized for the + * case of just returning from the function xxx_ret is used. + */ + +#define put_user_ret(x, ptr, ret) \ + ({ if (put_user((x), (ptr))) return (ret); }) +#define get_user_ret(x, ptr, ret) \ + ({ if (get_user((x), (ptr))) return (ret); }) +#define __put_user_ret(x, ptr, ret) \ + ({ if (__put_user((x), (ptr))) return (ret); }) +#define __get_user_ret(x, ptr, ret) \ + ({ if (__get_user((x), (ptr))) return (ret); }) + +struct __large_struct { unsigned long buf[100]; }; +#define __m(x) (*(struct __large_struct *)(x)) + +#define __get_user_nocheck(x, ptr, size) \ +({ \ + unsigned long __gu_addr; \ + int __gu_err; \ + __gu_addr = (unsigned long) (ptr); \ + switch (size) { \ + case 1: { \ + unsigned char __gu_val; \ + __get_user_asm("bu"); \ + (x) = *(__force __typeof__(*(ptr))*) &__gu_val; \ + break; \ + } \ + case 2: { \ + unsigned short __gu_val; \ + __get_user_asm("hu"); \ + (x) = *(__force __typeof__(*(ptr))*) &__gu_val; \ + break; \ + } \ + case 4: { \ + unsigned int __gu_val; \ + __get_user_asm(""); \ + (x) = *(__force __typeof__(*(ptr))*) &__gu_val; \ + break; \ + } \ + default: \ + __get_user_unknown(); \ + break; \ + } \ + __gu_err; \ +}) + +#define __get_user_check(x, ptr, size) \ +({ \ + const __typeof__(*(ptr))* __guc_ptr = (ptr); \ + int _e; \ + if (likely(__access_ok((unsigned long) __guc_ptr, (size)))) \ + _e = __get_user_nocheck((x), __guc_ptr, (size)); \ + else { \ + _e = -EFAULT; \ + (x) = (__typeof__(x))0; \ + } \ + _e; \ +}) + +#define __get_user_asm(INSN) \ +({ \ + asm volatile( \ + "1:\n" \ + " mov"INSN" %2,%1\n" \ + " mov 0,%0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + "3:\n\t" \ + " mov %3,%0\n" \ + " jmp 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "=&r" (__gu_err), "=&r" (__gu_val) \ + : "m" (__m(__gu_addr)), "i" (-EFAULT)); \ +}) + +extern int __get_user_unknown(void); + +#define __put_user_nocheck(x, ptr, size) \ +({ \ + union { \ + __typeof__(*(ptr)) val; \ + u32 bits[2]; \ + } __pu_val; \ + unsigned long __pu_addr; \ + int __pu_err; \ + __pu_val.val = (x); \ + __pu_addr = (unsigned long) (ptr); \ + switch (size) { \ + case 1: __put_user_asm("bu"); break; \ + case 2: __put_user_asm("hu"); break; \ + case 4: __put_user_asm("" ); break; \ + case 8: __put_user_asm8(); break; \ + default: __pu_err = __put_user_unknown(); break; \ + } \ + __pu_err; \ +}) + +#define __put_user_check(x, ptr, size) \ +({ \ + union { \ + __typeof__(*(ptr)) val; \ + u32 bits[2]; \ + } __pu_val; \ + unsigned long __pu_addr; \ + int __pu_err; \ + __pu_val.val = (x); \ + __pu_addr = (unsigned long) (ptr); \ + if (likely(__access_ok(__pu_addr, size))) { \ + switch (size) { \ + case 1: __put_user_asm("bu"); break; \ + case 2: __put_user_asm("hu"); break; \ + case 4: __put_user_asm("" ); break; \ + case 8: __put_user_asm8(); break; \ + default: __pu_err = __put_user_unknown(); break; \ + } \ + } \ + else { \ + __pu_err = -EFAULT; \ + } \ + __pu_err; \ +}) + +#define __put_user_asm(INSN) \ +({ \ + asm volatile( \ + "1:\n" \ + " mov"INSN" %1,%2\n" \ + " mov 0,%0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + "3:\n" \ + " mov %3,%0\n" \ + " jmp 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "=&r" (__pu_err) \ + : "r" (__pu_val.val), "m" (__m(__pu_addr)), \ + "i" (-EFAULT) \ + ); \ +}) + +#define __put_user_asm8() \ +({ \ + asm volatile( \ + "1: mov %1,%3 \n" \ + "2: mov %2,%4 \n" \ + " mov 0,%0 \n" \ + "3: \n" \ + " .section .fixup,\"ax\" \n" \ + "4: \n" \ + " mov %5,%0 \n" \ + " jmp 3b \n" \ + " .previous \n" \ + " .section __ex_table,\"a\"\n" \ + " .balign 4 \n" \ + " .long 1b, 4b \n" \ + " .long 2b, 4b \n" \ + " .previous \n" \ + : "=&r" (__pu_err) \ + : "r" (__pu_val.bits[0]), "r" (__pu_val.bits[1]), \ + "m" (__m(__pu_addr)), "m" (__m(__pu_addr+4)), \ + "i" (-EFAULT) \ + ); \ +}) + +extern int __put_user_unknown(void); + + +/* + * Copy To/From Userspace + */ +/* Generic arbitrary sized copy. */ +#define __copy_user(to, from, size) \ +do { \ + if (size) { \ + void *__to = to; \ + const void *__from = from; \ + int w; \ + asm volatile( \ + "0: movbu (%0),%3;\n" \ + "1: movbu %3,(%1);\n" \ + " inc %0;\n" \ + " inc %1;\n" \ + " add -1,%2;\n" \ + " bne 0b;\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + "3: jmp 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,3b\n" \ + " .previous\n" \ + : "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\ + : "0"(__from), "1"(__to), "2"(size) \ + : "cc", "memory"); \ + } \ +} while (0) + +#define __copy_user_zeroing(to, from, size) \ +do { \ + if (size) { \ + void *__to = to; \ + const void *__from = from; \ + int w; \ + asm volatile( \ + "0: movbu (%0),%3;\n" \ + "1: movbu %3,(%1);\n" \ + " inc %0;\n" \ + " inc %1;\n" \ + " add -1,%2;\n" \ + " bne 0b;\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + "3:\n" \ + " mov %2,%0\n" \ + " clr %3\n" \ + "4: movbu %3,(%1);\n" \ + " inc %1;\n" \ + " add -1,%2;\n" \ + " bne 4b;\n" \ + " mov %0,%2\n" \ + " jmp 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,3b\n" \ + " .previous\n" \ + : "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\ + : "0"(__from), "1"(__to), "2"(size) \ + : "cc", "memory"); \ + } \ +} while (0) + +/* We let the __ versions of copy_from/to_user inline, because they're often + * used in fast paths and have only a small space overhead. + */ +static inline +unsigned long __generic_copy_from_user_nocheck(void *to, const void *from, + unsigned long n) +{ + __copy_user_zeroing(to, from, n); + return n; +} + +static inline +unsigned long __generic_copy_to_user_nocheck(void *to, const void *from, + unsigned long n) +{ + __copy_user(to, from, n); + return n; +} + + +#if 0 +#error "don't use - these macros don't increment to & from pointers" +/* Optimize just a little bit when we know the size of the move. */ +#define __constant_copy_user(to, from, size) \ +do { \ + asm volatile( \ + " mov %0,a0;\n" \ + "0: movbu (%1),d3;\n" \ + "1: movbu d3,(%2);\n" \ + " add -1,a0;\n" \ + " bne 0b;\n" \ + "2:;" \ + ".section .fixup,\"ax\"\n" \ + "3: jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,3b\n" \ + ".previous" \ + : \ + : "d"(size), "d"(to), "d"(from) \ + : "d3", "a0"); \ +} while (0) + +/* Optimize just a little bit when we know the size of the move. */ +#define __constant_copy_user_zeroing(to, from, size) \ +do { \ + asm volatile( \ + " mov %0,a0;\n" \ + "0: movbu (%1),d3;\n" \ + "1: movbu d3,(%2);\n" \ + " add -1,a0;\n" \ + " bne 0b;\n" \ + "2:;" \ + ".section .fixup,\"ax\"\n" \ + "3: jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,3b\n" \ + ".previous" \ + : \ + : "d"(size), "d"(to), "d"(from) \ + : "d3", "a0"); \ +} while (0) + +static inline +unsigned long __constant_copy_to_user(void *to, const void *from, + unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + __constant_copy_user(to, from, n); + return n; +} + +static inline +unsigned long __constant_copy_from_user(void *to, const void *from, + unsigned long n) +{ + if (access_ok(VERIFY_READ, from, n)) + __constant_copy_user_zeroing(to, from, n); + return n; +} + +static inline +unsigned long __constant_copy_to_user_nocheck(void *to, const void *from, + unsigned long n) +{ + __constant_copy_user(to, from, n); + return n; +} + +static inline +unsigned long __constant_copy_from_user_nocheck(void *to, const void *from, + unsigned long n) +{ + __constant_copy_user_zeroing(to, from, n); + return n; +} +#endif + +extern unsigned long __generic_copy_to_user(void __user *, const void *, + unsigned long); +extern unsigned long __generic_copy_from_user(void *, const void __user *, + unsigned long); + +#define __copy_to_user_inatomic(to, from, n) \ + __generic_copy_to_user_nocheck((to), (from), (n)) +#define __copy_from_user_inatomic(to, from, n) \ + __generic_copy_from_user_nocheck((to), (from), (n)) + +#define __copy_to_user(to, from, n) \ +({ \ + might_fault(); \ + __copy_to_user_inatomic((to), (from), (n)); \ +}) + +#define __copy_from_user(to, from, n) \ +({ \ + might_fault(); \ + __copy_from_user_inatomic((to), (from), (n)); \ +}) + + +#define copy_to_user(to, from, n) __generic_copy_to_user((to), (from), (n)) +#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n)) + +extern long strncpy_from_user(char *dst, const char __user *src, long count); +extern long __strncpy_from_user(char *dst, const char __user *src, long count); +extern long strnlen_user(const char __user *str, long n); +#define strlen_user(str) strnlen_user(str, ~0UL >> 1) +extern unsigned long clear_user(void __user *mem, unsigned long len); +extern unsigned long __clear_user(void __user *mem, unsigned long len); + +#endif /* _ASM_UACCESS_H */ diff --git a/arch/mn10300/include/asm/ucontext.h b/arch/mn10300/include/asm/ucontext.h new file mode 100644 index 000000000..fcab5c1d8 --- /dev/null +++ b/arch/mn10300/include/asm/ucontext.h @@ -0,0 +1,22 @@ +/* MN10300 User context + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_UCONTEXT_H +#define _ASM_UCONTEXT_H + +struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +#endif /* _ASM_UCONTEXT_H */ diff --git a/arch/mn10300/include/asm/unaligned.h b/arch/mn10300/include/asm/unaligned.h new file mode 100644 index 000000000..0df671318 --- /dev/null +++ b/arch/mn10300/include/asm/unaligned.h @@ -0,0 +1,20 @@ +/* MN10300 Unaligned memory access handling + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_MN10300_UNALIGNED_H +#define _ASM_MN10300_UNALIGNED_H + +#include <linux/unaligned/access_ok.h> +#include <linux/unaligned/generic.h> + +#define get_unaligned __get_unaligned_le +#define put_unaligned __put_unaligned_le + +#endif /* _ASM_MN10300_UNALIGNED_H */ diff --git a/arch/mn10300/include/asm/unistd.h b/arch/mn10300/include/asm/unistd.h new file mode 100644 index 000000000..0522468f4 --- /dev/null +++ b/arch/mn10300/include/asm/unistd.h @@ -0,0 +1,47 @@ +/* MN10300 System call number list + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_UNISTD_H +#define _ASM_UNISTD_H + +#include <uapi/asm/unistd.h> + + +#define NR_syscalls 340 + +/* + * specify the deprecated syscalls we want to support on this arch + */ +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_OLD_STAT +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_IPC +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_SIGNAL +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_WAITPID +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_SYS_OLD_SELECT +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_FORK +#define __ARCH_WANT_SYS_VFORK +#define __ARCH_WANT_SYS_CLONE + +#endif /* _ASM_UNISTD_H */ diff --git a/arch/mn10300/include/asm/user.h b/arch/mn10300/include/asm/user.h new file mode 100644 index 000000000..e1193908b --- /dev/null +++ b/arch/mn10300/include/asm/user.h @@ -0,0 +1,53 @@ +/* MN10300 User process data + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_USER_H +#define _ASM_USER_H + +#include <asm/page.h> +#include <linux/ptrace.h> + +#ifndef __ASSEMBLY__ +/* + * When the kernel dumps core, it starts by dumping the user struct - this will + * be used by gdb to figure out where the data and stack segments are within + * the file, and what virtual addresses to use. + */ +struct user { + /* We start with the registers, to mimic the way that "memory" is + * returned from the ptrace(3,...) function. + */ + struct pt_regs regs; /* Where the registers are actually stored */ + + /* The rest of this junk is to help gdb figure out what goes where */ + unsigned long int u_tsize; /* Text segment size (pages). */ + unsigned long int u_dsize; /* Data segment size (pages). */ + unsigned long int u_ssize; /* Stack segment size (pages). */ + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack area. + This is actually the bottom of the stack, + the top of the stack is always found in the + esp register. */ + long int signal; /* Signal that caused the core dump. */ + int reserved; /* No longer used */ + struct user_pt_regs *u_ar0; /* Used by gdb to help find the values for */ + + /* the registers */ + unsigned long magic; /* To uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ +}; +#endif + +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR +(u.start_code) +#define HOST_STACK_END_ADDR +(u.start_stack + u.u_ssize * NBPG) + +#endif /* _ASM_USER_H */ diff --git a/arch/mn10300/include/asm/vga.h b/arch/mn10300/include/asm/vga.h new file mode 100644 index 000000000..0163e50a3 --- /dev/null +++ b/arch/mn10300/include/asm/vga.h @@ -0,0 +1,17 @@ +/* MN10300 VGA register definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_VGA_H +#define _ASM_VGA_H + + + +#endif /* _ASM_VGA_H */ diff --git a/arch/mn10300/include/asm/xor.h b/arch/mn10300/include/asm/xor.h new file mode 100644 index 000000000..c82eb12a5 --- /dev/null +++ b/arch/mn10300/include/asm/xor.h @@ -0,0 +1 @@ +#include <asm-generic/xor.h> |