1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (C) 2010 Imagination Technologies Ltd.
5 * This file contains code that can be accessed from userspace and can
6 * access certain kernel data structures without the overhead of a system
10 #include <asm/metag_regs.h>
11 #include <asm/user_gateway.h>
16 * These are segment of kernel provided user code reachable from user space
17 * at a fixed address in kernel memory. This is used to provide user space
18 * with some operations which require kernel help because of unimplemented
19 * native feature and/or instructions in some Meta CPUs. The idea is for
20 * this code to be executed directly in user mode for best efficiency but
21 * which is too intimate with the kernel counter part to be left to user
22 * libraries. The kernel reserves the right to change this code as needed
23 * without warning. Only the entry points and their results are guaranteed
26 * Each segment is 64-byte aligned. This mechanism should be used only for
27 * for things that are really small and justified, and not be abused freely.
30 .global ___user_gateway_start
31 ___user_gateway_start:
35 * Description: Get the TLS pointer for this process.
37 .global ___kuser_get_tls
38 .type ___kuser_get_tls,function
40 MOVT D1Ar1,#HI(USER_GATEWAY_PAGE + USER_GATEWAY_TLS)
41 ADD D1Ar1,D1Ar1,#LO(USER_GATEWAY_PAGE + USER_GATEWAY_TLS)
43 AND D1Ar3,D1Ar3,#(TXENABLE_THREAD_BITS)
44 LSR D1Ar3,D1Ar3,#(TXENABLE_THREAD_S - 2)
45 GETD D0Re0,[D1Ar1+D1Ar3]
46 ___kuser_get_tls_end: /* Beyond this point the read will complete */
48 .size ___kuser_get_tls,.-___kuser_get_tls
49 .global ___kuser_get_tls_end
53 * Description: Replace the value at 'ptr' with 'newval' if the current
54 * value is 'oldval'. Return zero if we succeeded,
57 * Reference prototype:
59 * int __kuser_cmpxchg(int oldval, int newval, unsigned long *ptr)
63 .global ___kuser_cmpxchg
64 .type ___kuser_cmpxchg,function
68 * We must use LNKGET/LNKSET with an SMP kernel because the other method
69 * does not provide atomicity across multiple CPUs.
71 0: LNKGETD D0Re0,[D1Ar3]
73 LNKSETDZ [D1Ar3],D0Ar2
76 ANDT D0Re0,D0Re0,#HI(0x3f000000)
77 CMPT D0Re0,#HI(0x02000000)
79 #ifdef CONFIG_METAG_LNKGET_AROUND_CACHE
83 XORZ D0Re0,D0Re0,D0Re0
89 ___kuser_cmpxchg_end: /* Beyond this point the write will complete */
91 XORZ D0Re0,D0Re0,D0Re0
93 #endif /* CONFIG_SMP */
94 .size ___kuser_cmpxchg,.-___kuser_cmpxchg
95 .global ___kuser_cmpxchg_end
97 .global ___user_gateway_end