···11+/*22+ * linux/arch/unicore32/include/asm/assembler.h33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ *1212+ * Do not include any C declarations in this file - it is included by1313+ * assembler source.1414+ */1515+#ifndef __ASSEMBLY__1616+#error "Only include this from assembly code"1717+#endif1818+1919+#include <asm/ptrace.h>2020+2121+/*2222+ * Little Endian independent macros for shifting bytes within registers.2323+ */2424+#define pull >>2525+#define push <<2626+#define get_byte_0 << #02727+#define get_byte_1 >> #82828+#define get_byte_2 >> #162929+#define get_byte_3 >> #243030+#define put_byte_0 << #03131+#define put_byte_1 << #83232+#define put_byte_2 << #163333+#define put_byte_3 << #243434+3535+#define cadd cmpadd3636+#define cand cmpand3737+#define csub cmpsub3838+#define cxor cmpxor3939+4040+/*4141+ * Enable and disable interrupts4242+ */4343+ .macro disable_irq, temp4444+ mov \temp, asr4545+ andn \temp, \temp, #0xFF4646+ or \temp, \temp, #PSR_I_BIT | PRIV_MODE4747+ mov.a asr, \temp4848+ .endm4949+5050+ .macro enable_irq, temp5151+ mov \temp, asr5252+ andn \temp, \temp, #0xFF5353+ or \temp, \temp, #PRIV_MODE5454+ mov.a asr, \temp5555+ .endm5656+5757+#define USER(x...) \5858+9999: x; \5959+ .pushsection __ex_table, "a"; \6060+ .align 3; \6161+ .long 9999b, 9001f; \6262+ .popsection6363+6464+ .macro notcond, cond, nexti = .+86565+ .ifc \cond, eq6666+ bne \nexti6767+ .else; .ifc \cond, ne6868+ beq \nexti6969+ .else; .ifc \cond, ea7070+ bub \nexti7171+ .else; .ifc \cond, ub7272+ bea \nexti7373+ .else; .ifc \cond, fs7474+ bns \nexti7575+ .else; .ifc \cond, ns7676+ bfs \nexti7777+ .else; .ifc \cond, fv7878+ bnv \nexti7979+ .else; .ifc \cond, nv8080+ bfv \nexti8181+ .else; .ifc \cond, ua8282+ beb \nexti8383+ .else; .ifc \cond, eb8484+ bua \nexti8585+ .else; .ifc \cond, eg8686+ bsl \nexti8787+ .else; .ifc \cond, sl8888+ beg \nexti8989+ .else; .ifc \cond, sg9090+ bel \nexti9191+ .else; .ifc \cond, el9292+ bsg \nexti9393+ .else; .ifnc \cond, al9494+ .error "Unknown cond in notcond macro argument"9595+ .endif; .endif; .endif; .endif; .endif; .endif; .endif9696+ .endif; .endif; .endif; .endif; .endif; .endif; .endif9797+ .endif9898+ .endm9999+100100+ .macro usracc, instr, reg, ptr, inc, cond, rept, abort101101+ .rept \rept102102+ notcond \cond, .+8103103+9999 :104104+ .if \inc == 1105105+ \instr\()b.u \reg, [\ptr], #\inc106106+ .elseif \inc == 4107107+ \instr\()w.u \reg, [\ptr], #\inc108108+ .else109109+ .error "Unsupported inc macro argument"110110+ .endif111111+112112+ .pushsection __ex_table, "a"113113+ .align 3114114+ .long 9999b, \abort115115+ .popsection116116+ .endr117117+ .endm118118+119119+ .macro strusr, reg, ptr, inc, cond = al, rept = 1, abort = 9001f120120+ usracc st, \reg, \ptr, \inc, \cond, \rept, \abort121121+ .endm122122+123123+ .macro ldrusr, reg, ptr, inc, cond = al, rept = 1, abort = 9001f124124+ usracc ld, \reg, \ptr, \inc, \cond, \rept, \abort125125+ .endm126126+127127+ .macro nop8128128+ .rept 8129129+ nop130130+ .endr131131+ .endm
+47
arch/unicore32/include/asm/bitops.h
···11+/*22+ * linux/arch/unicore32/include/asm/bitops.h33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+1313+#ifndef __UNICORE_BITOPS_H__1414+#define __UNICORE_BITOPS_H__1515+1616+#define find_next_bit __uc32_find_next_bit1717+#define find_next_zero_bit __uc32_find_next_zero_bit1818+1919+#define find_first_bit __uc32_find_first_bit2020+#define find_first_zero_bit __uc32_find_first_zero_bit2121+2222+#define _ASM_GENERIC_BITOPS_FLS_H_2323+#define _ASM_GENERIC_BITOPS___FLS_H_2424+#define _ASM_GENERIC_BITOPS_FFS_H_2525+#define _ASM_GENERIC_BITOPS___FFS_H_2626+/*2727+ * On UNICORE, those functions can be implemented around2828+ * the cntlz instruction for much better code efficiency.2929+ */3030+3131+static inline int fls(int x)3232+{3333+ int ret;3434+3535+ asm("cntlz\t%0, %1" : "=r" (ret) : "r" (x) : "cc");3636+ ret = 32 - ret;3737+3838+ return ret;3939+}4040+4141+#define __fls(x) (fls(x) - 1)4242+#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })4343+#define __ffs(x) (ffs(x) - 1)4444+4545+#include <asm-generic/bitops.h>4646+4747+#endif /* __UNICORE_BITOPS_H__ */
+41
arch/unicore32/include/asm/checksum.h
···11+/*22+ * linux/arch/unicore32/include/asm/checksum.h33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ *1212+ * IP checksum routines1313+ */1414+#ifndef __UNICORE_CHECKSUM_H__1515+#define __UNICORE_CHECKSUM_H__1616+1717+/*1818+ * computes the checksum of the TCP/UDP pseudo-header1919+ * returns a 16-bit checksum, already complemented2020+ */2121+2222+static inline __wsum2323+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,2424+ unsigned short proto, __wsum sum)2525+{2626+ __asm__(2727+ "add.a %0, %1, %2\n"2828+ "addc.a %0, %0, %3\n"2929+ "addc.a %0, %0, %4 << #8\n"3030+ "addc.a %0, %0, %5\n"3131+ "addc %0, %0, #0\n"3232+ : "=&r"(sum)3333+ : "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto))3434+ : "cc");3535+ return sum;3636+}3737+#define csum_tcpudp_nofold csum_tcpudp_nofold3838+3939+#include <asm-generic/checksum.h>4040+4141+#endif
+52
arch/unicore32/include/asm/delay.h
···11+/*22+ * linux/arch/unicore32/include/asm/delay.h33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ *1212+ * Delay routines, using a pre-computed "loops_per_second" value.1313+ */1414+#ifndef __UNICORE_DELAY_H__1515+#define __UNICORE_DELAY_H__1616+1717+#include <asm/param.h> /* HZ */1818+1919+extern void __delay(int loops);2020+2121+/*2222+ * This function intentionally does not exist; if you see references to2323+ * it, it means that you're calling udelay() with an out of range value.2424+ *2525+ * With currently imposed limits, this means that we support a max delay2626+ * of 2000us. Further limits: HZ<=1000 and bogomips<=33552727+ */2828+extern void __bad_udelay(void);2929+3030+/*3131+ * division by multiplication: you don't have to worry about3232+ * loss of precision.3333+ *3434+ * Use only for very small delays ( < 1 msec). Should probably use a3535+ * lookup table, really, as the multiplications take much too long with3636+ * short delays. This is a "reasonable" implementation, though (and the3737+ * first constant multiplications gets optimized away if the delay is3838+ * a constant)3939+ */4040+extern void __udelay(unsigned long usecs);4141+extern void __const_udelay(unsigned long);4242+4343+#define MAX_UDELAY_MS 24444+4545+#define udelay(n) \4646+ (__builtin_constant_p(n) ? \4747+ ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \4848+ __const_udelay((n) * ((2199023U*HZ)>>11))) : \4949+ __udelay(n))5050+5151+#endif /* __UNICORE_DELAY_H__ */5252+
+143
arch/unicore32/include/asm/futex.h
···11+/*22+ * linux/arch/unicore32/include/asm/futex.h33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+1313+#ifndef __UNICORE_FUTEX_H__1414+#define __UNICORE_FUTEX_H__1515+1616+#ifdef __KERNEL__1717+1818+#include <linux/futex.h>1919+#include <linux/preempt.h>2020+#include <linux/uaccess.h>2121+#include <linux/errno.h>2222+2323+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \2424+ __asm__ __volatile__( \2525+ "1: ldw.u %1, [%2]\n" \2626+ " " insn "\n" \2727+ "2: stw.u %0, [%2]\n" \2828+ " mov %0, #0\n" \2929+ "3:\n" \3030+ " .pushsection __ex_table,\"a\"\n" \3131+ " .align 3\n" \3232+ " .long 1b, 4f, 2b, 4f\n" \3333+ " .popsection\n" \3434+ " .pushsection .fixup,\"ax\"\n" \3535+ "4: mov %0, %4\n" \3636+ " b 3b\n" \3737+ " .popsection" \3838+ : "=&r" (ret), "=&r" (oldval) \3939+ : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \4040+ : "cc", "memory")4141+4242+static inline int4343+futex_atomic_op_inuser(int encoded_op, int __user *uaddr)4444+{4545+ int op = (encoded_op >> 28) & 7;4646+ int cmp = (encoded_op >> 24) & 15;4747+ int oparg = (encoded_op << 8) >> 20;4848+ int cmparg = (encoded_op << 20) >> 20;4949+ int oldval = 0, ret;5050+5151+ if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))5252+ oparg = 1 << oparg;5353+5454+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))5555+ return -EFAULT;5656+5757+ pagefault_disable(); /* implies preempt_disable() */5858+5959+ switch (op) {6060+ case FUTEX_OP_SET:6161+ __futex_atomic_op("mov %0, %3", ret, oldval, uaddr, oparg);6262+ break;6363+ case FUTEX_OP_ADD:6464+ __futex_atomic_op("add %0, %1, %3", ret, oldval, uaddr, oparg);6565+ break;6666+ case FUTEX_OP_OR:6767+ __futex_atomic_op("or %0, %1, %3", ret, oldval, uaddr, oparg);6868+ break;6969+ case FUTEX_OP_ANDN:7070+ __futex_atomic_op("and %0, %1, %3",7171+ ret, oldval, uaddr, ~oparg);7272+ break;7373+ case FUTEX_OP_XOR:7474+ __futex_atomic_op("xor %0, %1, %3", ret, oldval, uaddr, oparg);7575+ break;7676+ default:7777+ ret = -ENOSYS;7878+ }7979+8080+ pagefault_enable(); /* subsumes preempt_enable() */8181+8282+ if (!ret) {8383+ switch (cmp) {8484+ case FUTEX_OP_CMP_EQ:8585+ ret = (oldval == cmparg);8686+ break;8787+ case FUTEX_OP_CMP_NE:8888+ ret = (oldval != cmparg);8989+ break;9090+ case FUTEX_OP_CMP_LT:9191+ ret = (oldval < cmparg);9292+ break;9393+ case FUTEX_OP_CMP_GE:9494+ ret = (oldval >= cmparg);9595+ break;9696+ case FUTEX_OP_CMP_LE:9797+ ret = (oldval <= cmparg);9898+ break;9999+ case FUTEX_OP_CMP_GT:100100+ ret = (oldval > cmparg);101101+ break;102102+ default:103103+ ret = -ENOSYS;104104+ }105105+ }106106+ return ret;107107+}108108+109109+static inline int110110+futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)111111+{112112+ int val;113113+114114+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))115115+ return -EFAULT;116116+117117+ pagefault_disable(); /* implies preempt_disable() */118118+119119+ __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"120120+ "1: ldw.u %0, [%3]\n"121121+ " cmpxor.a %0, %1\n"122122+ " bne 3f\n"123123+ "2: stw.u %2, [%3]\n"124124+ "3:\n"125125+ " .pushsection __ex_table,\"a\"\n"126126+ " .align 3\n"127127+ " .long 1b, 4f, 2b, 4f\n"128128+ " .popsection\n"129129+ " .pushsection .fixup,\"ax\"\n"130130+ "4: mov %0, %4\n"131131+ " b 3b\n"132132+ " .popsection"133133+ : "=&r" (val)134134+ : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)135135+ : "cc", "memory");136136+137137+ pagefault_enable(); /* subsumes preempt_enable() */138138+139139+ return val;140140+}141141+142142+#endif /* __KERNEL__ */143143+#endif /* __UNICORE_FUTEX_H__ */
+52
arch/unicore32/include/asm/io.h
···11+/*22+ * linux/arch/unicore32/include/asm/io.h33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+#ifndef __UNICORE_IO_H__1313+#define __UNICORE_IO_H__1414+1515+#ifdef __KERNEL__1616+1717+#include <asm/byteorder.h>1818+#include <asm/memory.h>1919+#include <asm/system.h>2020+2121+#include <asm-generic/io.h>2222+2323+/*2424+ * __uc32_ioremap and __uc32_ioremap_cached takes CPU physical address.2525+ */2626+extern void __iomem *__uc32_ioremap(unsigned long, size_t);2727+extern void __iomem *__uc32_ioremap_cached(unsigned long, size_t);2828+extern void __uc32_iounmap(volatile void __iomem *addr);2929+3030+/*3131+ * ioremap and friends.3232+ *3333+ * ioremap takes a PCI memory address, as specified in3434+ * Documentation/IO-mapping.txt.3535+ *3636+ */3737+#define ioremap(cookie, size) __uc32_ioremap(cookie, size)3838+#define ioremap_cached(cookie, size) __uc32_ioremap_cached(cookie, size)3939+#define iounmap(cookie) __uc32_iounmap(cookie)4040+4141+extern void __iomem *ioport_map(unsigned long port, unsigned int nr);4242+extern void ioport_unmap(void __iomem *addr);4343+4444+/*4545+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem4646+ * access4747+ */4848+#undef xlate_dev_mem_ptr4949+#define xlate_dev_mem_ptr(p) __va(p)5050+5151+#endif /* __KERNEL__ */5252+#endif /* __UNICORE_IO_H__ */
+20
arch/unicore32/include/asm/mutex.h
···11+/*22+ * linux/arch/unicore32/include/asm/mutex.h33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ *1212+ * UniCore optimized mutex locking primitives1313+ *1414+ * Please look into asm-generic/mutex-xchg.h for a formal definition.1515+ */1616+#ifndef __UNICORE_MUTEX_H__1717+#define __UNICORE_MUTEX_H__1818+1919+# include <asm-generic/mutex-xchg.h>2020+#endif
···11+/*22+ * linux/arch/unicore32/lib/delay.S33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+#include <linux/linkage.h>1313+#include <asm/assembler.h>1414+#include <asm/param.h>1515+ .text1616+1717+.LC0: .word loops_per_jiffy1818+.LC1: .word (2199023*HZ)>>111919+2020+/*2121+ * r0 <= 20002222+ * lpj <= 0x01ffffff (max. 3355 bogomips)2323+ * HZ <= 10002424+ */2525+2626+ENTRY(__udelay)2727+ ldw r2, .LC12828+ mul r0, r2, r02929+ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff063030+ ldw r2, .LC03131+ ldw r2, [r2] @ max = 0x01ffffff3232+ mov r0, r0 >> #14 @ max = 0x0001ffff3333+ mov r2, r2 >> #10 @ max = 0x00007fff3434+ mul r0, r2, r0 @ max = 2^32-13535+ mov.a r0, r0 >> #63636+ cmoveq pc, lr3737+3838+/*3939+ * loops = r0 * HZ * loops_per_jiffy / 10000004040+ *4141+ * Oh, if only we had a cycle counter...4242+ */4343+4444+@ Delay routine4545+ENTRY(__delay)4646+ sub.a r0, r0, #24747+ bua __delay4848+ mov pc, lr4949+ENDPROC(__udelay)5050+ENDPROC(__const_udelay)5151+ENDPROC(__delay)
+98
arch/unicore32/lib/findbit.S
···11+/*22+ * linux/arch/unicore32/lib/findbit.S33+ *44+ * Code specific to PKUnity SoC and UniCore ISA55+ *66+ * Copyright (C) 2001-2010 GUAN Xue-tao77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+#include <linux/linkage.h>1313+#include <asm/assembler.h>1414+ .text1515+1616+/*1717+ * Purpose : Find a 'zero' bit1818+ * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);1919+ */2020+__uc32_find_first_zero_bit:2121+ cxor.a r1, #02222+ beq 3f2323+ mov r2, #02424+1: ldb r3, [r0+], r2 >> #32525+ xor.a r3, r3, #0xff @ invert bits2626+ bne .L_found @ any now set - found zero bit2727+ add r2, r2, #8 @ next bit pointer2828+2: csub.a r2, r1 @ any more?2929+ bub 1b3030+3: mov r0, r1 @ no free bits3131+ mov pc, lr3232+3333+/*3434+ * Purpose : Find next 'zero' bit3535+ * Prototype: int find_next_zero_bit3636+ * (void *addr, unsigned int maxbit, int offset)3737+ */3838+ENTRY(__uc32_find_next_zero_bit)3939+ cxor.a r1, #04040+ beq 3b4141+ and.a ip, r2, #74242+ beq 1b @ If new byte, goto old routine4343+ ldb r3, [r0+], r2 >> #34444+ xor r3, r3, #0xff @ now looking for a 1 bit4545+ mov.a r3, r3 >> ip @ shift off unused bits4646+ bne .L_found4747+ or r2, r2, #7 @ if zero, then no bits here4848+ add r2, r2, #1 @ align bit pointer4949+ b 2b @ loop for next bit5050+ENDPROC(__uc32_find_next_zero_bit)5151+5252+/*5353+ * Purpose : Find a 'one' bit5454+ * Prototype: int find_first_bit5555+ * (const unsigned long *addr, unsigned int maxbit);5656+ */5757+__uc32_find_first_bit:5858+ cxor.a r1, #05959+ beq 3f6060+ mov r2, #06161+1: ldb r3, [r0+], r2 >> #36262+ mov.a r3, r36363+ bne .L_found @ any now set - found zero bit6464+ add r2, r2, #8 @ next bit pointer6565+2: csub.a r2, r1 @ any more?6666+ bub 1b6767+3: mov r0, r1 @ no free bits6868+ mov pc, lr6969+7070+/*7171+ * Purpose : Find next 'one' bit7272+ * Prototype: int find_next_zero_bit7373+ * (void *addr, unsigned int maxbit, int offset)7474+ */7575+ENTRY(__uc32_find_next_bit)7676+ cxor.a r1, #07777+ beq 3b7878+ and.a ip, r2, #77979+ beq 1b @ If new byte, goto old routine8080+ ldb r3, [r0+], r2 >> #38181+ mov.a r3, r3 >> ip @ shift off unused bits8282+ bne .L_found8383+ or r2, r2, #7 @ if zero, then no bits here8484+ add r2, r2, #1 @ align bit pointer8585+ b 2b @ loop for next bit8686+ENDPROC(__uc32_find_next_bit)8787+8888+/*8989+ * One or more bits in the LSB of r3 are assumed to be set.9090+ */9191+.L_found:9292+ rsub r1, r3, #09393+ and r3, r3, r19494+ cntlz r3, r39595+ rsub r3, r3, #319696+ add r0, r2, r39797+ mov pc, lr9898+