Skip to content
Snippets Groups Projects
Unverified Commit bb6fb6df authored by James Hogan's avatar James Hogan
Browse files

metag: Remove arch/metag/


The earliest Meta architecture port of Linux I have a record of was an
import of a Meta port of Linux v2.4.1 in February 2004, which was worked
on significantly over the next few years by Graham Whaley, Will Newton,
Matt Fleming, myself and others.

Eventually the port was merged into mainline in v3.9 in March 2013, not
long after Imagination Technologies bought MIPS Technologies and shifted
its CPU focus over to the MIPS architecture.

As a result, though the port was maintained for a while, kept on life
support for a while longer, and useful for testing a few specific
drivers for which I don't have ready access to the equivalent MIPS
hardware, it is now essentially dead with no users.

It is also stuck using an out-of-tree toolchain based on GCC 4.2.4 which
is no longer maintained, now struggles to build modern kernels due to
toolchain bugs, and doesn't itself build with a modern GCC. The latest
buildroot port is still using an old uClibc snapshot which is no longer
served, and the latest uClibc doesn't build with GCC 4.2.4.

So lets call it a day and drop the Meta architecture port from the
kernel. RIP Meta.

Signed-off-by: default avatarJames Hogan <jhogan@kernel.org>
Link: https://lkml.kernel.org/r/95906b76-6ce1-3f84-eaba-c29b4ae952eb@roeck-us.net


Reviewed-by: default avatarGuenter Roeck <linux@roeck-us.net>
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: default avatarGraham Whaley <graham.whaley@gmail.com>
Cc: linux-metag@vger.kernel.org
parent 91ab883e
No related branches found
No related tags found
No related merge requests found
Showing
with 0 additions and 1222 deletions
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_METAG_BITOPS_H
#define __ASM_METAG_BITOPS_H
#include <linux/compiler.h>
#include <asm/barrier.h>
#include <asm/global_lock.h>
#ifdef CONFIG_SMP
/*
* These functions are the basis of our bit ops.
*/
static inline void set_bit(unsigned int bit, volatile unsigned long *p)
{
unsigned long flags;
unsigned long mask = 1UL << (bit & 31);
p += bit >> 5;
__global_lock1(flags);
fence();
*p |= mask;
__global_unlock1(flags);
}
static inline void clear_bit(unsigned int bit, volatile unsigned long *p)
{
unsigned long flags;
unsigned long mask = 1UL << (bit & 31);
p += bit >> 5;
__global_lock1(flags);
fence();
*p &= ~mask;
__global_unlock1(flags);
}
static inline void change_bit(unsigned int bit, volatile unsigned long *p)
{
unsigned long flags;
unsigned long mask = 1UL << (bit & 31);
p += bit >> 5;
__global_lock1(flags);
fence();
*p ^= mask;
__global_unlock1(flags);
}
static inline int test_and_set_bit(unsigned int bit, volatile unsigned long *p)
{
unsigned long flags;
unsigned long old;
unsigned long mask = 1UL << (bit & 31);
p += bit >> 5;
__global_lock1(flags);
old = *p;
if (!(old & mask)) {
fence();
*p = old | mask;
}
__global_unlock1(flags);
return (old & mask) != 0;
}
static inline int test_and_clear_bit(unsigned int bit,
volatile unsigned long *p)
{
unsigned long flags;
unsigned long old;
unsigned long mask = 1UL << (bit & 31);
p += bit >> 5;
__global_lock1(flags);
old = *p;
if (old & mask) {
fence();
*p = old & ~mask;
}
__global_unlock1(flags);
return (old & mask) != 0;
}
static inline int test_and_change_bit(unsigned int bit,
volatile unsigned long *p)
{
unsigned long flags;
unsigned long old;
unsigned long mask = 1UL << (bit & 31);
p += bit >> 5;
__global_lock1(flags);
fence();
old = *p;
*p = old ^ mask;
__global_unlock1(flags);
return (old & mask) != 0;
}
#else
#include <asm-generic/bitops/atomic.h>
#endif /* CONFIG_SMP */
#include <asm-generic/bitops/non-atomic.h>
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/__ffs.h>
#include <asm-generic/bitops/ffz.h>
#include <asm-generic/bitops/fls.h>
#include <asm-generic/bitops/__fls.h>
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/le.h>
#include <asm-generic/bitops/ext2-atomic.h>
#endif /* __ASM_METAG_BITOPS_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_METAG_BUG_H
#define _ASM_METAG_BUG_H
#include <asm-generic/bug.h>
struct pt_regs;
extern const char *trap_name(int trapno);
extern void __noreturn die(const char *str, struct pt_regs *regs, long err,
unsigned long addr);
#endif
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_METAG_CACHE_H
#define __ASM_METAG_CACHE_H
/* L1 cache line size (64 bytes) */
#define L1_CACHE_SHIFT 6
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
/* Meta requires large data items to be 8 byte aligned. */
#define ARCH_SLAB_MINALIGN 8
/*
* With an L2 cache, we may invalidate dirty lines, so we need to ensure DMA
* buffers have cache line alignment.
*/
#ifdef CONFIG_METAG_L2C
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
#else
#define ARCH_DMA_MINALIGN 8
#endif
#define __read_mostly __attribute__((__section__(".data..read_mostly")))
#endif
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _METAG_CACHEFLUSH_H
#define _METAG_CACHEFLUSH_H
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/io.h>
#include <asm/l2cache.h>
#include <asm/metag_isa.h>
#include <asm/metag_mem.h>
void metag_cache_probe(void);
void metag_data_cache_flush_all(const void *start);
void metag_code_cache_flush_all(const void *start);
/*
* Routines to flush physical cache lines that may be used to cache data or code
* normally accessed via the linear address range supplied. The region flushed
* must either lie in local or global address space determined by the top bit of
* the pStart address. If Bytes is >= 4K then the whole of the related cache
* state will be flushed rather than a limited range.
*/
void metag_data_cache_flush(const void *start, int bytes);
void metag_code_cache_flush(const void *start, int bytes);
#ifdef CONFIG_METAG_META12
/* Write through, virtually tagged, split I/D cache. */
static inline void __flush_cache_all(void)
{
metag_code_cache_flush_all((void *) PAGE_OFFSET);
metag_data_cache_flush_all((void *) PAGE_OFFSET);
}
#define flush_cache_all() __flush_cache_all()
/* flush the entire user address space referenced in this mm structure */
static inline void flush_cache_mm(struct mm_struct *mm)
{
if (mm == current->mm)
__flush_cache_all();
}
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
/* flush a range of addresses from this mm */
static inline void flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
flush_cache_mm(vma->vm_mm);
}
static inline void flush_cache_page(struct vm_area_struct *vma,
unsigned long vmaddr, unsigned long pfn)
{
flush_cache_mm(vma->vm_mm);
}
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
static inline void flush_dcache_page(struct page *page)
{
metag_data_cache_flush_all((void *) PAGE_OFFSET);
}
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
static inline void flush_icache_page(struct vm_area_struct *vma,
struct page *page)
{
metag_code_cache_flush(page_to_virt(page), PAGE_SIZE);
}
static inline void flush_cache_vmap(unsigned long start, unsigned long end)
{
metag_data_cache_flush_all((void *) PAGE_OFFSET);
}
static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
{
metag_data_cache_flush_all((void *) PAGE_OFFSET);
}
#else
/* Write through, physically tagged, split I/D cache. */
#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(vma, start, end) do { } while (0)
#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
#define flush_icache_page(vma, pg) 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 1
static inline void flush_dcache_page(struct page *page)
{
/* FIXME: We can do better than this. All we are trying to do is
* make the i-cache coherent, we should use the PG_arch_1 bit like
* e.g. powerpc.
*/
#ifdef CONFIG_SMP
metag_out32(1, SYSC_ICACHE_FLUSH);
#else
metag_code_cache_flush_all((void *) PAGE_OFFSET);
#endif
}
#endif
/* Push n pages at kernel virtual address and clear the icache */
static inline void flush_icache_range(unsigned long address,
unsigned long endaddr)
{
#ifdef CONFIG_SMP
metag_out32(1, SYSC_ICACHE_FLUSH);
#else
metag_code_cache_flush((void *) address, endaddr - address);
#endif
}
static inline void flush_cache_sigtramp(unsigned long addr, int size)
{
/*
* Flush the icache in case there was previously some code
* fetched from this address, perhaps a previous sigtramp.
*
* We don't need to flush the dcache, it's write through and
* we just wrote the sigtramp code through it.
*/
#ifdef CONFIG_SMP
metag_out32(1, SYSC_ICACHE_FLUSH);
#else
metag_code_cache_flush((void *) addr, size);
#endif
}
#ifdef CONFIG_METAG_L2C
/*
* Perform a single specific CACHEWD operation on an address, masking lower bits
* of address first.
*/
static inline void cachewd_line(void *addr, unsigned int data)
{
unsigned long masked = (unsigned long)addr & -0x40;
__builtin_meta2_cachewd((void *)masked, data);
}
/* Perform a certain CACHEW op on each cache line in a range */
static inline void cachew_region_op(void *start, unsigned long size,
unsigned int op)
{
unsigned long offset = (unsigned long)start & 0x3f;
int i;
if (offset) {
size += offset;
start -= offset;
}
i = (size - 1) >> 6;
do {
__builtin_meta2_cachewd(start, op);
start += 0x40;
} while (i--);
}
/* prevent write fence and flushbacks being reordered in L2 */
static inline void l2c_fence_flush(void *addr)
{
/*
* Synchronise by reading back and re-flushing.
* It is assumed this access will miss, as the caller should have just
* flushed the cache line.
*/
(void)(volatile u8 *)addr;
cachewd_line(addr, CACHEW_FLUSH_L1D_L2);
}
/* prevent write fence and writebacks being reordered in L2 */
static inline void l2c_fence(void *addr)
{
/*
* A write back has occurred, but not necessarily an invalidate, so the
* readback in l2c_fence_flush() would hit in the cache and have no
* effect. Therefore fully flush the line first.
*/
cachewd_line(addr, CACHEW_FLUSH_L1D_L2);
l2c_fence_flush(addr);
}
/* Used to keep memory consistent when doing DMA. */
static inline void flush_dcache_region(void *start, unsigned long size)
{
/* metag_data_cache_flush won't flush L2 cache lines if size >= 4096 */
if (meta_l2c_is_enabled()) {
cachew_region_op(start, size, CACHEW_FLUSH_L1D_L2);
if (meta_l2c_is_writeback())
l2c_fence_flush(start + size - 1);
} else {
metag_data_cache_flush(start, size);
}
}
/* Write back dirty lines to memory (or do nothing if no writeback caches) */
static inline void writeback_dcache_region(void *start, unsigned long size)
{
if (meta_l2c_is_enabled() && meta_l2c_is_writeback()) {
cachew_region_op(start, size, CACHEW_WRITEBACK_L1D_L2);
l2c_fence(start + size - 1);
}
}
/* Invalidate (may also write back if necessary) */
static inline void invalidate_dcache_region(void *start, unsigned long size)
{
if (meta_l2c_is_enabled())
cachew_region_op(start, size, CACHEW_INVALIDATE_L1D_L2);
else
metag_data_cache_flush(start, size);
}
#else
#define flush_dcache_region(s, l) metag_data_cache_flush((s), (l))
#define writeback_dcache_region(s, l) do {} while (0)
#define invalidate_dcache_region(s, l) flush_dcache_region((s), (l))
#endif
static inline void copy_to_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr,
void *dst, const void *src,
unsigned long len)
{
memcpy(dst, src, len);
flush_icache_range((unsigned long)dst, (unsigned long)dst + len);
}
static inline void copy_from_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr,
void *dst, const void *src,
unsigned long len)
{
memcpy(dst, src, len);
}
#endif /* _METAG_CACHEFLUSH_H */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Meta cache partition manipulation.
*
* Copyright 2010 Imagination Technologies Ltd.
*/
#ifndef _METAG_CACHEPART_H_
#define _METAG_CACHEPART_H_
/**
* get_dcache_size() - Get size of data cache.
*/
unsigned int get_dcache_size(void);
/**
* get_icache_size() - Get size of code cache.
*/
unsigned int get_icache_size(void);
/**
* get_global_dcache_size() - Get the thread's global dcache.
*
* Returns the size of the current thread's global dcache partition.
*/
unsigned int get_global_dcache_size(void);
/**
* get_global_icache_size() - Get the thread's global icache.
*
* Returns the size of the current thread's global icache partition.
*/
unsigned int get_global_icache_size(void);
/**
* check_for_dache_aliasing() - Ensure that the bootloader has configured the
* dache and icache properly to avoid aliasing
* @thread_id: Hardware thread ID
*
*/
void check_for_cache_aliasing(int thread_id);
#endif
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _METAG_CHECKSUM_H
#define _METAG_CHECKSUM_H
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
extern __wsum csum_partial(const void *buff, int len, __wsum sum);
/*
* the same as csum_partial, but copies from src while it
* checksums
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
extern __wsum csum_partial_copy(const void *src, void *dst, int len,
__wsum sum);
/*
* the same as csum_partial_copy, but copies from user space.
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
int len, __wsum sum, int *csum_err);
#define csum_partial_copy_nocheck(src, dst, len, sum) \
csum_partial_copy((src), (dst), (len), (sum))
/*
* Fold a partial checksum
*/
static inline __sum16 csum_fold(__wsum csum)
{
u32 sum = (__force u32)csum;
sum = (sum & 0xffff) + (sum >> 16);
sum = (sum & 0xffff) + (sum >> 16);
return (__force __sum16)~sum;
}
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
*/
extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
__u32 len, __u8 proto,
__wsum sum)
{
unsigned long len_proto = (proto + len) << 8;
asm ("ADDS %0, %0, %1\n"
"ADDCS %0, %0, #1\n"
"ADDS %0, %0, %2\n"
"ADDCS %0, %0, #1\n"
"ADDS %0, %0, %3\n"
"ADDCS %0, %0, #1\n"
: "=d" (sum)
: "d" (daddr), "d" (saddr), "d" (len_proto),
"0" (sum)
: "cc");
return sum;
}
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
extern __sum16 ip_compute_csum(const void *buff, int len);
#endif /* _METAG_CHECKSUM_H */
/*
* arch/metag/include/asm/clock.h
*
* Copyright (C) 2012 Imagination Technologies Ltd.
*
* 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 _METAG_CLOCK_H_
#define _METAG_CLOCK_H_
#include <asm/mach/arch.h>
/**
* struct meta_clock_desc - Meta Core clock callbacks.
* @get_core_freq: Get the frequency of the Meta core. If this is NULL, the
* core frequency will be determined like this:
* Meta 1: based on loops_per_jiffy.
* Meta 2: (EXPAND_TIMER_DIV + 1) MHz.
* If a "core" clock is provided by the device tree, it
* will override this function.
*/
struct meta_clock_desc {
unsigned long (*get_core_freq)(void);
};
extern struct meta_clock_desc _meta_clock;
/*
* Perform platform clock initialisation, reading clocks from device tree etc.
* Only accessible during boot.
*/
void init_metag_clocks(void);
/*
* Set up the default clock, ensuring all callbacks are valid - only accessible
* during boot.
*/
void setup_meta_clocks(struct meta_clock_desc *desc);
/**
* get_coreclock() - Get the frequency of the Meta core clock.
*
* Returns: The Meta core clock frequency in Hz.
*/
static inline unsigned long get_coreclock(void)
{
/*
* Use the current clock callback. If set correctly this will provide
* the most accurate frequency as it can be calculated directly from the
* PLL configuration. otherwise a default callback will have been set
* instead.
*/
return _meta_clock.get_core_freq();
}
#endif /* _METAG_CLOCK_H_ */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_METAG_CMPXCHG_H
#define __ASM_METAG_CMPXCHG_H
#include <asm/barrier.h>
#if defined(CONFIG_METAG_ATOMICITY_IRQSOFF)
#include <asm/cmpxchg_irq.h>
#elif defined(CONFIG_METAG_ATOMICITY_LOCK1)
#include <asm/cmpxchg_lock1.h>
#elif defined(CONFIG_METAG_ATOMICITY_LNKGET)
#include <asm/cmpxchg_lnkget.h>
#endif
extern void __xchg_called_with_bad_pointer(void);
#define __xchg(ptr, x, size) \
({ \
unsigned long __xchg__res; \
volatile void *__xchg_ptr = (ptr); \
switch (size) { \
case 4: \
__xchg__res = xchg_u32(__xchg_ptr, x); \
break; \
case 1: \
__xchg__res = xchg_u8(__xchg_ptr, x); \
break; \
default: \
__xchg_called_with_bad_pointer(); \
__xchg__res = x; \
break; \
} \
\
__xchg__res; \
})
#define xchg(ptr, x) \
((__typeof__(*(ptr)))__xchg((ptr), (unsigned long)(x), sizeof(*(ptr))))
/* 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);
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);
}
__cmpxchg_called_with_bad_pointer();
return old;
}
#define cmpxchg(ptr, o, n) \
({ \
__typeof__(*(ptr)) _o_ = (o); \
__typeof__(*(ptr)) _n_ = (n); \
(__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
(unsigned long)_n_, \
sizeof(*(ptr))); \
})
#endif /* __ASM_METAG_CMPXCHG_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_METAG_CMPXCHG_IRQ_H
#define __ASM_METAG_CMPXCHG_IRQ_H
#include <linux/irqflags.h>
static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
{
unsigned long flags, retval;
local_irq_save(flags);
retval = *m;
*m = val;
local_irq_restore(flags);
return retval;
}
static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
{
unsigned long flags, retval;
local_irq_save(flags);
retval = *m;
*m = val & 0xff;
local_irq_restore(flags);
return retval;
}
static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,
unsigned long new)
{
__u32 retval;
unsigned long flags;
local_irq_save(flags);
retval = *m;
if (retval == old)
*m = new;
local_irq_restore(flags); /* implies memory barrier */
return retval;
}
#endif /* __ASM_METAG_CMPXCHG_IRQ_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_METAG_CMPXCHG_LNKGET_H
#define __ASM_METAG_CMPXCHG_LNKGET_H
static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
{
int temp, old;
smp_mb();
asm volatile (
"1: LNKGETD %1, [%2]\n"
" LNKSETD [%2], %3\n"
" DEFR %0, TXSTAT\n"
" ANDT %0, %0, #HI(0x3f000000)\n"
" CMPT %0, #HI(0x02000000)\n"
" BNZ 1b\n"
#ifdef CONFIG_METAG_LNKGET_AROUND_CACHE
" DCACHE [%2], %0\n"
#endif
: "=&d" (temp), "=&d" (old)
: "da" (m), "da" (val)
: "cc"
);
smp_mb();
return old;
}
static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
{
int temp, old;
smp_mb();
asm volatile (
"1: LNKGETD %1, [%2]\n"
" LNKSETD [%2], %3\n"
" DEFR %0, TXSTAT\n"
" ANDT %0, %0, #HI(0x3f000000)\n"
" CMPT %0, #HI(0x02000000)\n"
" BNZ 1b\n"
#ifdef CONFIG_METAG_LNKGET_AROUND_CACHE
" DCACHE [%2], %0\n"
#endif
: "=&d" (temp), "=&d" (old)
: "da" (m), "da" (val & 0xff)
: "cc"
);
smp_mb();
return old;
}
static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,
unsigned long new)
{
__u32 retval, temp;
smp_mb();
asm volatile (
"1: LNKGETD %1, [%2]\n"
" CMP %1, %3\n"
" LNKSETDEQ [%2], %4\n"
" BNE 2f\n"
" DEFR %0, TXSTAT\n"
" ANDT %0, %0, #HI(0x3f000000)\n"
" CMPT %0, #HI(0x02000000)\n"
" BNZ 1b\n"
#ifdef CONFIG_METAG_LNKGET_AROUND_CACHE
" DCACHE [%2], %0\n"
#endif
"2:\n"
: "=&d" (temp), "=&d" (retval)
: "da" (m), "bd" (old), "da" (new)
: "cc"
);
smp_mb();
return retval;
}
#endif /* __ASM_METAG_CMPXCHG_LNKGET_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_METAG_CMPXCHG_LOCK1_H
#define __ASM_METAG_CMPXCHG_LOCK1_H
#include <asm/global_lock.h>
/* Use LOCK2 as these have to be atomic w.r.t. ordinary accesses. */
static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
{
unsigned long flags, retval;
__global_lock2(flags);
fence();
retval = *m;
*m = val;
__global_unlock2(flags);
return retval;
}
static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
{
unsigned long flags, retval;
__global_lock2(flags);
fence();
retval = *m;
*m = val & 0xff;
__global_unlock2(flags);
return retval;
}
static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,
unsigned long new)
{
__u32 retval;
unsigned long flags;
__global_lock2(flags);
retval = *m;
if (retval == old) {
fence();
*m = new;
}
__global_unlock2(flags);
return retval;
}
#endif /* __ASM_METAG_CMPXCHG_LOCK1_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_METAG_CORE_REG_H_
#define __ASM_METAG_CORE_REG_H_
#include <asm/metag_regs.h>
extern void core_reg_write(int unit, int reg, int thread, unsigned int val);
extern unsigned int core_reg_read(int unit, int reg, int thread);
/*
* These macros allow direct access from C to any register known to the
* assembler. Example candidates are TXTACTCYC, TXIDLECYC, and TXPRIVEXT.
*/
#define __core_reg_get(reg) ({ \
unsigned int __grvalue; \
asm volatile("MOV %0," #reg \
: "=r" (__grvalue)); \
__grvalue; \
})
#define __core_reg_set(reg, value) do { \
unsigned int __srvalue = (value); \
asm volatile("MOV " #reg ",%0" \
: \
: "r" (__srvalue)); \
} while (0)
#define __core_reg_swap(reg, value) do { \
unsigned int __srvalue = (value); \
asm volatile("SWAP " #reg ",%0" \
: "+r" (__srvalue)); \
(value) = __srvalue; \
} while (0)
#endif
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_METAG_CPU_H
#define _ASM_METAG_CPU_H
#include <linux/percpu.h>
struct cpuinfo_metag {
struct cpu cpu;
#ifdef CONFIG_SMP
unsigned long loops_per_jiffy;
#endif
};
DECLARE_PER_CPU(struct cpuinfo_metag, cpu_data);
#endif /* _ASM_METAG_CPU_H */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Meta DA JTAG debugger control.
*
* Copyright 2012 Imagination Technologies Ltd.
*/
#ifndef _METAG_DA_H_
#define _METAG_DA_H_
#ifdef CONFIG_METAG_DA
#include <linux/init.h>
#include <linux/types.h>
extern bool _metag_da_present;
/**
* metag_da_enabled() - Find whether a DA is currently enabled.
*
* Returns: true if a DA was detected, false if not.
*/
static inline bool metag_da_enabled(void)
{
return _metag_da_present;
}
/**
* metag_da_probe() - Try and detect a connected DA.
*
* This is used at start up to detect whether a DA is active.
*
* Returns: 0 on detection, -err otherwise.
*/
int __init metag_da_probe(void);
#else /* !CONFIG_METAG_DA */
#define metag_da_enabled() false
#define metag_da_probe() do {} while (0)
#endif
#endif /* _METAG_DA_H_ */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _METAG_DELAY_H
#define _METAG_DELAY_H
/*
* Copyright (C) 1993 Linus Torvalds
*
* Delay routines calling functions in arch/metag/lib/delay.c
*/
/* Undefined functions to get compile-time errors */
extern void __bad_udelay(void);
extern void __bad_ndelay(void);
extern void __udelay(unsigned long usecs);
extern void __ndelay(unsigned long nsecs);
extern void __const_udelay(unsigned long xloops);
extern void __delay(unsigned long loops);
/* 0x10c7 is 2**32 / 1000000 (rounded up) */
#define udelay(n) (__builtin_constant_p(n) ? \
((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
__udelay(n))
/* 0x5 is 2**32 / 1000000000 (rounded up) */
#define ndelay(n) (__builtin_constant_p(n) ? \
((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
__ndelay(n))
#endif /* _METAG_DELAY_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_DIV64_H__
#define __ASM_DIV64_H__
#include <asm-generic/div64.h>
extern u64 div_u64(u64 dividend, u64 divisor);
extern s64 div_s64(s64 dividend, s64 divisor);
#define div_u64 div_u64
#define div_s64 div_s64
#endif
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_METAG_DMA_MAPPING_H
#define _ASM_METAG_DMA_MAPPING_H
extern const struct dma_map_ops metag_dma_ops;
static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
{
return &metag_dma_ops;
}
#endif
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_METAG_ELF_H
#define __ASM_METAG_ELF_H
#define EM_METAG 174
/* Meta relocations */
#define R_METAG_HIADDR16 0
#define R_METAG_LOADDR16 1
#define R_METAG_ADDR32 2
#define R_METAG_NONE 3
#define R_METAG_RELBRANCH 4
#define R_METAG_GETSETOFF 5
/* Backward compatibility */
#define R_METAG_REG32OP1 6
#define R_METAG_REG32OP2 7
#define R_METAG_REG32OP3 8
#define R_METAG_REG16OP1 9
#define R_METAG_REG16OP2 10
#define R_METAG_REG16OP3 11
#define R_METAG_REG32OP4 12
#define R_METAG_HIOG 13
#define R_METAG_LOOG 14
/* GNU */
#define R_METAG_GNU_VTINHERIT 30
#define R_METAG_GNU_VTENTRY 31
/* PIC relocations */
#define R_METAG_HI16_GOTOFF 32
#define R_METAG_LO16_GOTOFF 33
#define R_METAG_GETSET_GOTOFF 34
#define R_METAG_GETSET_GOT 35
#define R_METAG_HI16_GOTPC 36
#define R_METAG_LO16_GOTPC 37
#define R_METAG_HI16_PLT 38
#define R_METAG_LO16_PLT 39
#define R_METAG_RELBRANCH_PLT 40
#define R_METAG_GOTOFF 41
#define R_METAG_PLT 42
#define R_METAG_COPY 43
#define R_METAG_JMP_SLOT 44
#define R_METAG_RELATIVE 45
#define R_METAG_GLOB_DAT 46
/*
* ELF register definitions.
*/
#include <asm/page.h>
#include <asm/processor.h>
#include <asm/ptrace.h>
#include <asm/user.h>
typedef unsigned long elf_greg_t;
#define ELF_NGREG (sizeof(struct user_gp_regs) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef unsigned long 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_METAG)
/*
* These are used to set parameters in the core dumps.
*/
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_METAG
#define ELF_PLAT_INIT(_r, load_addr) \
do { _r->ctx.AX[0].U0 = 0; } while (0)
#define USE_ELF_CORE_DUMP
#define CORE_DUMP_USE_REGSET
#define ELF_EXEC_PAGESIZE PAGE_SIZE
/* 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. */
#define ELF_ET_DYN_BASE 0x08000000UL
#define ELF_CORE_COPY_REGS(_dest, _regs) \
memcpy((char *)&_dest, (char *)_regs, sizeof(struct pt_regs));
/* This yields a mask that user programs can use to figure out what
instruction set this cpu supports. */
#define ELF_HWCAP (0)
/* 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. */
#define ELF_PLATFORM (NULL)
#define STACK_RND_MASK (0)
#ifdef CONFIG_METAG_USER_TCM
struct elf32_phdr;
struct file;
unsigned long __metag_elf_map(struct file *filep, unsigned long addr,
struct elf32_phdr *eppnt, int prot, int type,
unsigned long total_size);
static inline unsigned long metag_elf_map(struct file *filep,
unsigned long addr,
struct elf32_phdr *eppnt, int prot,
int type, unsigned long total_size)
{
return __metag_elf_map(filep, addr, eppnt, prot, type, total_size);
}
#define elf_map metag_elf_map
#endif
#endif
/*
* fixmap.h: compile-time virtual memory allocation
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1998 Ingo Molnar
*
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
*/
#ifndef _ASM_FIXMAP_H
#define _ASM_FIXMAP_H
#include <asm/pgtable.h>
#ifdef CONFIG_HIGHMEM
#include <linux/threads.h>
#include <asm/kmap_types.h>
#endif
/*
* Here we define all the compile-time 'special' virtual
* addresses. The point is to have a constant address at
* compile time, but to set the physical address only
* in the boot process. We allocate these special addresses
* from the end of the consistent memory region backwards.
* Also this lets us do fail-safe vmalloc(), we
* can guarantee that these special addresses and
* vmalloc()-ed addresses never overlap.
*
* these 'compile-time allocated' memory buffers are
* fixed-size 4k pages. (or larger if used with an increment
* higher than 1) use fixmap_set(idx,phys) to associate
* physical memory with fixmap indices.
*
* TLB entries of such buffers will not be flushed across
* task switches.
*/
enum fixed_addresses {
#define FIX_N_COLOURS 8
#ifdef CONFIG_HIGHMEM
/* reserved pte's for temporary kernel mappings */
FIX_KMAP_BEGIN,
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
#endif
__end_of_fixed_addresses
};
#define FIXADDR_TOP (CONSISTENT_START - PAGE_SIZE)
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK)
#include <asm-generic/fixmap.h>
#define kmap_get_fixmap_pte(vaddr) \
pte_offset_kernel( \
pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), \
(vaddr) \
)
/*
* Called from pgtable_init()
*/
extern void fixrange_init(unsigned long start, unsigned long end,
pgd_t *pgd_base);
#endif
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_METAG_FTRACE
#define _ASM_METAG_FTRACE
#ifdef CONFIG_FUNCTION_TRACER
#define MCOUNT_INSN_SIZE 8 /* sizeof mcount call */
#ifndef __ASSEMBLY__
extern void mcount_wrapper(void);
#define MCOUNT_ADDR ((unsigned long)(mcount_wrapper))
static inline unsigned long ftrace_call_adjust(unsigned long addr)
{
return addr;
}
struct dyn_arch_ftrace {
/* No extra data needed on metag */
};
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_FUNCTION_TRACER */
#endif /* _ASM_METAG_FTRACE */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment