From 5f97f7f9400de47ae837170bb274e90ad3934386 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 25 Sep 2006 23:32:13 -0700 Subject: [PATCH] avr32 architecture This adds support for the Atmel AVR32 architecture as well as the AT32AP7000 CPU and the AT32STK1000 development board. AVR32 is a new high-performance 32-bit RISC microprocessor core, designed for cost-sensitive embedded applications, with particular emphasis on low power consumption and high code density. The AVR32 architecture is not binary compatible with earlier 8-bit AVR architectures. The AVR32 architecture, including the instruction set, is described by the AVR32 Architecture Manual, available from http://www.atmel.com/dyn/resources/prod_documents/doc32000.pdf The Atmel AT32AP7000 is the first CPU implementing the AVR32 architecture. It features a 7-stage pipeline, 16KB instruction and data caches and a full Memory Management Unit. It also comes with a large set of integrated peripherals, many of which are shared with the AT91 ARM-based controllers from Atmel. Full data sheet is available from http://www.atmel.com/dyn/resources/prod_documents/doc32003.pdf while the CPU core implementation including caches and MMU is documented by the AVR32 AP Technical Reference, available from http://www.atmel.com/dyn/resources/prod_documents/doc32001.pdf Information about the AT32STK1000 development board can be found at http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3918 including a BSP CD image with an earlier version of this patch, development tools (binaries and source/patches) and a root filesystem image suitable for booting from SD card. Alternatively, there's a preliminary "getting started" guide available at http://avr32linux.org/twiki/bin/view/Main/GettingStarted which provides links to the sources and patches you will need in order to set up a cross-compiling environment for avr32-linux. This patch, as well as the other patches included with the BSP and the toolchain patches, is actively supported by Atmel Corporation. [dmccr@us.ibm.com: Fix more pxx_page macro locations] [bunk@stusta.de: fix `make defconfig'] Signed-off-by: Haavard Skinnemoen Signed-off-by: Adrian Bunk Signed-off-by: Dave McCracken Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-avr32/system.h | 155 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 include/asm-avr32/system.h (limited to 'include/asm-avr32/system.h') diff --git a/include/asm-avr32/system.h b/include/asm-avr32/system.h new file mode 100644 index 00000000000..ac596058697 --- /dev/null +++ b/include/asm-avr32/system.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_AVR32_SYSTEM_H +#define __ASM_AVR32_SYSTEM_H + +#include +#include + +#include +#include + +#define xchg(ptr,x) \ + ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) + +#define nop() asm volatile("nop") + +#define mb() asm volatile("" : : : "memory") +#define rmb() mb() +#define wmb() asm volatile("sync 0" : : : "memory") +#define read_barrier_depends() do { } while(0) +#define set_mb(var, value) do { var = value; mb(); } while(0) + +/* + * Help PathFinder and other Nexus-compliant debuggers keep track of + * the current PID by emitting an Ownership Trace Message each time we + * switch task. + */ +#ifdef CONFIG_OWNERSHIP_TRACE +#include +#define finish_arch_switch(prev) \ + do { \ + __mtdr(DBGREG_PID, prev->pid); \ + __mtdr(DBGREG_PID, current->pid); \ + } while(0) +#endif + +/* + * switch_to(prev, next, last) should switch from task `prev' to task + * `next'. `prev' will never be the same as `next'. + * + * We just delegate everything to the __switch_to assembly function, + * which is implemented in arch/avr32/kernel/switch_to.S + * + * mb() tells GCC not to cache `current' across this call. + */ +struct cpu_context; +struct task_struct; +extern struct task_struct *__switch_to(struct task_struct *, + struct cpu_context *, + struct cpu_context *); +#define switch_to(prev, next, last) \ + do { \ + last = __switch_to(prev, &prev->thread.cpu_context + 1, \ + &next->thread.cpu_context); \ + } while (0) + +#ifdef CONFIG_SMP +# error "The AVR32 port does not support SMP" +#else +# define smp_mb() barrier() +# define smp_rmb() barrier() +# define smp_wmb() barrier() +# define smp_read_barrier_depends() do { } while(0) +#endif + +#include + +extern void __xchg_called_with_bad_pointer(void); + +#ifdef __CHECKER__ +extern unsigned long __builtin_xchg(void *ptr, unsigned long x); +#endif + +#define xchg_u32(val, m) __builtin_xchg((void *)m, val) + +static inline unsigned long __xchg(unsigned long x, + volatile void *ptr, + int size) +{ + switch(size) { + case 4: + return xchg_u32(x, ptr); + default: + __xchg_called_with_bad_pointer(); + return x; + } +} + +static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old, + unsigned long new) +{ + __u32 ret; + + asm volatile( + "1: ssrf 5\n" + " ld.w %[ret], %[m]\n" + " cp.w %[ret], %[old]\n" + " brne 2f\n" + " stcond %[m], %[new]\n" + " brne 1b\n" + "2:\n" + : [ret] "=&r"(ret), [m] "=m"(*m) + : "m"(m), [old] "ir"(old), [new] "r"(new) + : "memory", "cc"); + return ret; +} + +extern unsigned long __cmpxchg_u64_unsupported_on_32bit_kernels( + volatile int * m, unsigned long old, unsigned long new); +#define __cmpxchg_u64 __cmpxchg_u64_unsupported_on_32bit_kernels + +/* This function doesn't exist, so you'll get a linker error + if something tries to do an invalid cmpxchg(). */ +extern void __cmpxchg_called_with_bad_pointer(void); + +#define __HAVE_ARCH_CMPXCHG 1 + +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, + unsigned long new, int size) +{ + switch (size) { + case 4: + return __cmpxchg_u32(ptr, old, new); + case 8: + return __cmpxchg_u64(ptr, old, new); + } + + __cmpxchg_called_with_bad_pointer(); + return old; +} + +#define cmpxchg(ptr, old, new) \ + ((typeof(*(ptr)))__cmpxchg((ptr), (unsigned long)(old), \ + (unsigned long)(new), \ + sizeof(*(ptr)))) + +struct pt_regs; +extern void __die(const char *, struct pt_regs *, unsigned long, + const char *, const char *, unsigned long); +extern void __die_if_kernel(const char *, struct pt_regs *, unsigned long, + const char *, const char *, unsigned long); + +#define die(msg, regs, err) \ + __die(msg, regs, err, __FILE__ ":", __FUNCTION__, __LINE__) +#define die_if_kernel(msg, regs, err) \ + __die_if_kernel(msg, regs, err, __FILE__ ":", __FUNCTION__, __LINE__) + +#define arch_align_stack(x) (x) + +#endif /* __ASM_AVR32_SYSTEM_H */ -- cgit v1.2.3