aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/unicore32/include/asm/byteorder.h24
-rw-r--r--arch/unicore32/include/asm/cpu-single.h45
-rw-r--r--arch/unicore32/include/asm/cputype.h33
-rw-r--r--arch/unicore32/include/asm/hwcap.h32
-rw-r--r--arch/unicore32/include/asm/processor.h92
-rw-r--r--arch/unicore32/include/asm/system.h161
-rw-r--r--arch/unicore32/include/asm/unistd.h18
-rw-r--r--arch/unicore32/kernel/sys.c126
-rw-r--r--arch/unicore32/mm/proc-macros.S145
-rw-r--r--arch/unicore32/mm/proc-ucv2.S134
10 files changed, 810 insertions, 0 deletions
diff --git a/arch/unicore32/include/asm/byteorder.h b/arch/unicore32/include/asm/byteorder.h
new file mode 100644
index 00000000000..ebe1b3fef3e
--- /dev/null
+++ b/arch/unicore32/include/asm/byteorder.h
@@ -0,0 +1,24 @@
1/*
2 * linux/arch/unicore32/include/asm/byteorder.h
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * UniCore ONLY support Little Endian mode, the data bus is connected such
13 * that byte accesses appear as:
14 * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31
15 * and word accesses (data or instruction) appear as:
16 * d0...d31
17 */
18#ifndef __UNICORE_BYTEORDER_H__
19#define __UNICORE_BYTEORDER_H__
20
21#include <linux/byteorder/little_endian.h>
22
23#endif
24
diff --git a/arch/unicore32/include/asm/cpu-single.h b/arch/unicore32/include/asm/cpu-single.h
new file mode 100644
index 00000000000..0f55d182343
--- /dev/null
+++ b/arch/unicore32/include/asm/cpu-single.h
@@ -0,0 +1,45 @@
1/*
2 * linux/arch/unicore32/include/asm/cpu-single.h
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef __UNICORE_CPU_SINGLE_H__
13#define __UNICORE_CPU_SINGLE_H__
14
15#include <asm/page.h>
16#include <asm/memory.h>
17
18#ifdef __KERNEL__
19#ifndef __ASSEMBLY__
20
21#define cpu_switch_mm(pgd, mm) cpu_do_switch_mm(virt_to_phys(pgd), mm)
22
23#define cpu_get_pgd() \
24 ({ \
25 unsigned long pg; \
26 __asm__("movc %0, p0.c2, #0" \
27 : "=r" (pg) : : "cc"); \
28 pg &= ~0x0fff; \
29 (pgd_t *)phys_to_virt(pg); \
30 })
31
32struct mm_struct;
33
34/* declare all the functions as extern */
35extern void cpu_proc_fin(void);
36extern int cpu_do_idle(void);
37extern void cpu_dcache_clean_area(void *, int);
38extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
39extern void cpu_set_pte(pte_t *ptep, pte_t pte);
40extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
41
42#endif /* __ASSEMBLY__ */
43#endif /* __KERNEL__ */
44
45#endif /* __UNICORE_CPU_SINGLE_H__ */
diff --git a/arch/unicore32/include/asm/cputype.h b/arch/unicore32/include/asm/cputype.h
new file mode 100644
index 00000000000..ec1a30f9807
--- /dev/null
+++ b/arch/unicore32/include/asm/cputype.h
@@ -0,0 +1,33 @@
1/*
2 * linux/arch/unicore32/include/asm/cputype.h
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef __UNICORE_CPUTYPE_H__
13#define __UNICORE_CPUTYPE_H__
14
15#include <linux/stringify.h>
16
17#define CPUID_CPUID 0
18#define CPUID_CACHETYPE 1
19
20#define read_cpuid(reg) \
21 ({ \
22 unsigned int __val; \
23 asm("movc %0, p0.c0, #" __stringify(reg) \
24 : "=r" (__val) \
25 : \
26 : "cc"); \
27 __val; \
28 })
29
30#define uc32_cpuid read_cpuid(CPUID_CPUID)
31#define uc32_cachetype read_cpuid(CPUID_CACHETYPE)
32
33#endif
diff --git a/arch/unicore32/include/asm/hwcap.h b/arch/unicore32/include/asm/hwcap.h
new file mode 100644
index 00000000000..97bd40fdd4a
--- /dev/null
+++ b/arch/unicore32/include/asm/hwcap.h
@@ -0,0 +1,32 @@
1/*
2 * linux/arch/unicore32/include/asm/hwcap.h
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef __UNICORE_HWCAP_H__
13#define __UNICORE_HWCAP_H__
14
15/*
16 * HWCAP flags
17 */
18#define HWCAP_MSP 1
19#define HWCAP_UNICORE16 2
20#define HWCAP_CMOV 4
21#define HWCAP_UNICORE_F64 8
22#define HWCAP_TLS 0x80
23
24#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
25/*
26 * This yields a mask that user programs can use to figure out what
27 * instruction set this cpu supports.
28 */
29#define ELF_HWCAP (HWCAP_CMOV | HWCAP_UNICORE_F64)
30#endif
31
32#endif
diff --git a/arch/unicore32/include/asm/processor.h b/arch/unicore32/include/asm/processor.h
new file mode 100644
index 00000000000..e11cb078657
--- /dev/null
+++ b/arch/unicore32/include/asm/processor.h
@@ -0,0 +1,92 @@
1/*
2 * linux/arch/unicore32/include/asm/processor.h
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __UNICORE_PROCESSOR_H__
14#define __UNICORE_PROCESSOR_H__
15
16/*
17 * Default implementation of macro that returns current
18 * instruction pointer ("program counter").
19 */
20#define current_text_addr() ({ __label__ _l; _l: &&_l; })
21
22#ifdef __KERNEL__
23
24#include <asm/ptrace.h>
25#include <asm/types.h>
26
27#ifdef __KERNEL__
28#define STACK_TOP TASK_SIZE
29#define STACK_TOP_MAX TASK_SIZE
30#endif
31
32struct debug_entry {
33 u32 address;
34 u32 insn;
35};
36
37struct debug_info {
38 int nsaved;
39 struct debug_entry bp[2];
40};
41
42struct thread_struct {
43 /* fault info */
44 unsigned long address;
45 unsigned long trap_no;
46 unsigned long error_code;
47 /* debugging */
48 struct debug_info debug;
49};
50
51#define INIT_THREAD { }
52
53#define start_thread(regs, pc, sp) \
54({ \
55 unsigned long *stack = (unsigned long *)sp; \
56 set_fs(USER_DS); \
57 memset(regs->uregs, 0, sizeof(regs->uregs)); \
58 regs->UCreg_asr = USER_MODE; \
59 regs->UCreg_pc = pc & ~1; /* pc */ \
60 regs->UCreg_sp = sp; /* sp */ \
61 regs->UCreg_02 = stack[2]; /* r2 (envp) */ \
62 regs->UCreg_01 = stack[1]; /* r1 (argv) */ \
63 regs->UCreg_00 = stack[0]; /* r0 (argc) */ \
64})
65
66/* Forward declaration, a strange C thing */
67struct task_struct;
68
69/* Free all resources held by a thread. */
70extern void release_thread(struct task_struct *);
71
72/* Prepare to copy thread state - unlazy all lazy status */
73#define prepare_to_copy(tsk) do { } while (0)
74
75unsigned long get_wchan(struct task_struct *p);
76
77#define cpu_relax() barrier()
78
79/*
80 * Create a new kernel thread
81 */
82extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
83
84#define task_pt_regs(p) \
85 ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
86
87#define KSTK_EIP(tsk) (task_pt_regs(tsk)->UCreg_pc)
88#define KSTK_ESP(tsk) (task_pt_regs(tsk)->UCreg_sp)
89
90#endif
91
92#endif /* __UNICORE_PROCESSOR_H__ */
diff --git a/arch/unicore32/include/asm/system.h b/arch/unicore32/include/asm/system.h
new file mode 100644
index 00000000000..246b71c17fd
--- /dev/null
+++ b/arch/unicore32/include/asm/system.h
@@ -0,0 +1,161 @@
1/*
2 * linux/arch/unicore32/include/asm/system.h
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef __UNICORE_SYSTEM_H__
13#define __UNICORE_SYSTEM_H__
14
15#ifdef __KERNEL__
16
17/*
18 * CR1 bits (CP#0 CR1)
19 */
20#define CR_M (1 << 0) /* MMU enable */
21#define CR_A (1 << 1) /* Alignment abort enable */
22#define CR_D (1 << 2) /* Dcache enable */
23#define CR_I (1 << 3) /* Icache enable */
24#define CR_B (1 << 4) /* Dcache write mechanism: write back */
25#define CR_T (1 << 5) /* Burst enable */
26#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */
27
28#ifndef __ASSEMBLY__
29
30#include <linux/linkage.h>
31#include <linux/irqflags.h>
32
33struct thread_info;
34struct task_struct;
35
36struct pt_regs;
37
38void die(const char *msg, struct pt_regs *regs, int err);
39
40struct siginfo;
41void uc32_notify_die(const char *str, struct pt_regs *regs,
42 struct siginfo *info, unsigned long err, unsigned long trap);
43
44void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
45 struct pt_regs *),
46 int sig, int code, const char *name);
47
48#define xchg(ptr, x) \
49 ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
50
51extern asmlinkage void __backtrace(void);
52extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
53
54struct mm_struct;
55extern void show_pte(struct mm_struct *mm, unsigned long addr);
56extern void __show_regs(struct pt_regs *);
57
58extern int cpu_architecture(void);
59extern void cpu_init(void);
60
61#define vectors_high() (cr_alignment & CR_V)
62
63#define isb() __asm__ __volatile__ ("" : : : "memory")
64#define dsb() __asm__ __volatile__ ("" : : : "memory")
65#define dmb() __asm__ __volatile__ ("" : : : "memory")
66
67#define mb() barrier()
68#define rmb() barrier()
69#define wmb() barrier()
70#define smp_mb() barrier()
71#define smp_rmb() barrier()
72#define smp_wmb() barrier()
73#define read_barrier_depends() do { } while (0)
74#define smp_read_barrier_depends() do { } while (0)
75
76#define set_mb(var, value) do { var = value; smp_mb(); } while (0)
77#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
78
79extern unsigned long cr_no_alignment; /* defined in entry-unicore.S */
80extern unsigned long cr_alignment; /* defined in entry-unicore.S */
81
82static inline unsigned int get_cr(void)
83{
84 unsigned int val;
85 asm("movc %0, p0.c1, #0" : "=r" (val) : : "cc");
86 return val;
87}
88
89static inline void set_cr(unsigned int val)
90{
91 asm volatile("movc p0.c1, %0, #0 @set CR"
92 : : "r" (val) : "cc");
93 isb();
94}
95
96extern void adjust_cr(unsigned long mask, unsigned long set);
97
98/*
99 * switch_to(prev, next) should switch from task `prev' to `next'
100 * `prev' will never be the same as `next'. schedule() itself
101 * contains the memory barrier to tell GCC not to cache `current'.
102 */
103extern struct task_struct *__switch_to(struct task_struct *,
104 struct thread_info *, struct thread_info *);
105extern void panic(const char *fmt, ...);
106
107#define switch_to(prev, next, last) \
108do { \
109 last = __switch_to(prev, \
110 task_thread_info(prev), task_thread_info(next)); \
111} while (0)
112
113static inline unsigned long
114__xchg(unsigned long x, volatile void *ptr, int size)
115{
116 unsigned long ret;
117
118 switch (size) {
119 case 1:
120 asm volatile("@ __xchg1\n"
121 " swapb %0, %1, [%2]"
122 : "=&r" (ret)
123 : "r" (x), "r" (ptr)
124 : "memory", "cc");
125 break;
126 case 4:
127 asm volatile("@ __xchg4\n"
128 " swapw %0, %1, [%2]"
129 : "=&r" (ret)
130 : "r" (x), "r" (ptr)
131 : "memory", "cc");
132 break;
133 default:
134 panic("xchg: bad data size: ptr 0x%p, size %d\n",
135 ptr, size);
136 }
137
138 return ret;
139}
140
141#include <asm-generic/cmpxchg-local.h>
142
143/*
144 * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
145 * them available.
146 */
147#define cmpxchg_local(ptr, o, n) \
148 ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), \
149 (unsigned long)(o), (unsigned long)(n), sizeof(*(ptr))))
150#define cmpxchg64_local(ptr, o, n) \
151 __cmpxchg64_local_generic((ptr), (o), (n))
152
153#include <asm-generic/cmpxchg.h>
154
155#endif /* __ASSEMBLY__ */
156
157#define arch_align_stack(x) (x)
158
159#endif /* __KERNEL__ */
160
161#endif
diff --git a/arch/unicore32/include/asm/unistd.h b/arch/unicore32/include/asm/unistd.h
new file mode 100644
index 00000000000..9b242801996
--- /dev/null
+++ b/arch/unicore32/include/asm/unistd.h
@@ -0,0 +1,18 @@
1/*
2 * linux/arch/unicore32/include/asm/unistd.h
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#if !defined(__UNICORE_UNISTD_H__) || defined(__SYSCALL)
13#define __UNICORE_UNISTD_H__
14
15/* Use the standard ABI for syscalls. */
16#include <asm-generic/unistd.h>
17
18#endif /* __UNICORE_UNISTD_H__ */
diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c
new file mode 100644
index 00000000000..3afe60a39ac
--- /dev/null
+++ b/arch/unicore32/kernel/sys.c
@@ -0,0 +1,126 @@
1/*
2 * linux/arch/unicore32/kernel/sys.c
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/module.h>
13#include <linux/errno.h>
14#include <linux/sched.h>
15#include <linux/slab.h>
16#include <linux/mm.h>
17#include <linux/sem.h>
18#include <linux/msg.h>
19#include <linux/shm.h>
20#include <linux/stat.h>
21#include <linux/syscalls.h>
22#include <linux/mman.h>
23#include <linux/fs.h>
24#include <linux/file.h>
25#include <linux/ipc.h>
26#include <linux/uaccess.h>
27
28#include <asm/syscalls.h>
29#include <asm/cacheflush.h>
30
31/* Clone a task - this clones the calling program thread.
32 * This is called indirectly via a small wrapper
33 */
34asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp,
35 void __user *parent_tid, void __user *child_tid,
36 struct pt_regs *regs)
37{
38 if (!newsp)
39 newsp = regs->UCreg_sp;
40
41 return do_fork(clone_flags, newsp, regs, 0,
42 parent_tid, child_tid);
43}
44
45/* sys_execve() executes a new program.
46 * This is called indirectly via a small wrapper
47 */
48asmlinkage long __sys_execve(const char __user *filename,
49 const char __user *const __user *argv,
50 const char __user *const __user *envp,
51 struct pt_regs *regs)
52{
53 int error;
54 char *fn;
55
56 fn = getname(filename);
57 error = PTR_ERR(fn);
58 if (IS_ERR(fn))
59 goto out;
60 error = do_execve(fn, argv, envp, regs);
61 putname(fn);
62out:
63 return error;
64}
65
66int kernel_execve(const char *filename,
67 const char *const argv[],
68 const char *const envp[])
69{
70 struct pt_regs regs;
71 int ret;
72
73 memset(&regs, 0, sizeof(struct pt_regs));
74 ret = do_execve(filename,
75 (const char __user *const __user *)argv,
76 (const char __user *const __user *)envp, &regs);
77 if (ret < 0)
78 goto out;
79
80 /*
81 * Save argc to the register structure for userspace.
82 */
83 regs.UCreg_00 = ret;
84
85 /*
86 * We were successful. We won't be returning to our caller, but
87 * instead to user space by manipulating the kernel stack.
88 */
89 asm("add r0, %0, %1\n\t"
90 "mov r1, %2\n\t"
91 "mov r2, %3\n\t"
92 "mov r22, #0\n\t" /* not a syscall */
93 "mov r23, %0\n\t" /* thread structure */
94 "b.l memmove\n\t" /* copy regs to top of stack */
95 "mov sp, r0\n\t" /* reposition stack pointer */
96 "b ret_to_user"
97 :
98 : "r" (current_thread_info()),
99 "Ir" (THREAD_START_SP - sizeof(regs)),
100 "r" (&regs),
101 "Ir" (sizeof(regs))
102 : "r0", "r1", "r2", "r3", "ip", "lr", "memory");
103
104 out:
105 return ret;
106}
107EXPORT_SYMBOL(kernel_execve);
108
109/* Note: used by the compat code even in 64-bit Linux. */
110SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
111 unsigned long, prot, unsigned long, flags,
112 unsigned long, fd, unsigned long, off_4k)
113{
114 return sys_mmap_pgoff(addr, len, prot, flags, fd,
115 off_4k);
116}
117
118/* Provide the actual syscall number to call mapping. */
119#undef __SYSCALL
120#define __SYSCALL(nr, call) [nr] = (call),
121
122/* Note that we don't include <linux/unistd.h> but <asm/unistd.h> */
123void *sys_call_table[__NR_syscalls] = {
124 [0 ... __NR_syscalls-1] = sys_ni_syscall,
125#include <asm/unistd.h>
126};
diff --git a/arch/unicore32/mm/proc-macros.S b/arch/unicore32/mm/proc-macros.S
new file mode 100644
index 00000000000..51560d68c89
--- /dev/null
+++ b/arch/unicore32/mm/proc-macros.S
@@ -0,0 +1,145 @@
1/*
2 * linux/arch/unicore32/mm/proc-macros.S
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * We need constants.h for:
13 * VMA_VM_MM
14 * VMA_VM_FLAGS
15 * VM_EXEC
16 */
17#include <generated/asm-offsets.h>
18#include <asm/thread_info.h>
19#include <asm/memory.h>
20
21/*
22 * the cache line sizes of the I and D cache are the same
23 */
24#define CACHE_LINESIZE 32
25
26/*
27 * This is the maximum size of an area which will be invalidated
28 * using the single invalidate entry instructions. Anything larger
29 * than this, and we go for the whole cache.
30 *
31 * This value should be chosen such that we choose the cheapest
32 * alternative.
33 */
34#ifdef CONFIG_CPU_UCV2
35#define MAX_AREA_SIZE 0x800 /* 64 cache line */
36#endif
37
38/*
39 * vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm)
40 */
41 .macro vma_vm_mm, rd, rn
42 ldw \rd, [\rn+], #VMA_VM_MM
43 .endm
44
45/*
46 * vma_vm_flags - get vma->vm_flags
47 */
48 .macro vma_vm_flags, rd, rn
49 ldw \rd, [\rn+], #VMA_VM_FLAGS
50 .endm
51
52 .macro tsk_mm, rd, rn
53 ldw \rd, [\rn+], #TI_TASK
54 ldw \rd, [\rd+], #TSK_ACTIVE_MM
55 .endm
56
57/*
58 * act_mm - get current->active_mm
59 */
60 .macro act_mm, rd
61 andn \rd, sp, #8128
62 andn \rd, \rd, #63
63 ldw \rd, [\rd+], #TI_TASK
64 ldw \rd, [\rd+], #TSK_ACTIVE_MM
65 .endm
66
67/*
68 * mmid - get context id from mm pointer (mm->context.id)
69 */
70 .macro mmid, rd, rn
71 ldw \rd, [\rn+], #MM_CONTEXT_ID
72 .endm
73
74/*
75 * mask_asid - mask the ASID from the context ID
76 */
77 .macro asid, rd, rn
78 and \rd, \rn, #255
79 .endm
80
81 .macro crval, clear, mmuset, ucset
82 .word \clear
83 .word \mmuset
84 .endm
85
86#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
87/*
88 * va2pa va, pa, tbl, msk, off, err
89 * This macro is used to translate virtual address to its physical address.
90 *
91 * va: virtual address
92 * pa: physical address, result is stored in this register
93 * tbl, msk, off: temp registers, will be destroyed
94 * err: jump to error label if the physical address not exist
95 * NOTE: all regs must be different
96 */
97 .macro va2pa, va, pa, tbl, msk, off, err=990f
98 movc \pa, p0.c2, #0
99 mov \off, \va >> #22 @ off <- index of 1st page table
100 adr \tbl, 910f @ tbl <- table of 1st page table
101900: @ ---- handle 1, 2 page table
102 add \pa, \pa, #PAGE_OFFSET @ pa <- virt addr of page table
103 ldw \pa, [\pa+], \off << #2 @ pa <- the content of pt
104 cand.a \pa, #4 @ test exist bit
105 beq \err @ if not exist
106 and \off, \pa, #3 @ off <- the last 2 bits
107 add \tbl, \tbl, \off << #3 @ cmove table pointer
108 ldw \msk, [\tbl+], #0 @ get the mask
109 ldw pc, [\tbl+], #4
110930: @ ---- handle 2nd page table
111 and \pa, \pa, \msk @ pa <- phys addr of 2nd pt
112 mov \off, \va << #10
113 cntlo \tbl, \msk @ use tbl as temp reg
114 mov \off, \off >> \tbl
115 mov \off, \off >> #2 @ off <- index of 2nd pt
116 adr \tbl, 920f @ tbl <- table of 2nd pt
117 b 900b
118910: @ 1st level page table
119 .word 0xfffff000, 930b @ second level page table
120 .word 0xfffffc00, 930b @ second level large page table
121 .word 0x00000000, \err @ invalid
122 .word 0xffc00000, 980f @ super page
123
124920: @ 2nd level page table
125 .word 0xfffff000, 980f @ page
126 .word 0xffffc000, 980f @ middle page
127 .word 0xffff0000, 980f @ large page
128 .word 0x00000000, \err @ invalid
129980:
130 andn \tbl, \va, \msk
131 and \pa, \pa, \msk
132 or \pa, \pa, \tbl
133990:
134 .endm
135#endif
136
137 .macro dcacheline_flush, addr, t1, t2
138 mov \t1, \addr << #20
139 ldw \t2, =_stext @ _stext must ALIGN(4096)
140 add \t2, \t2, \t1 >> #20
141 ldw \t1, [\t2+], #0x0000
142 ldw \t1, [\t2+], #0x1000
143 ldw \t1, [\t2+], #0x2000
144 ldw \t1, [\t2+], #0x3000
145 .endm
diff --git a/arch/unicore32/mm/proc-ucv2.S b/arch/unicore32/mm/proc-ucv2.S
new file mode 100644
index 00000000000..9d296092e36
--- /dev/null
+++ b/arch/unicore32/mm/proc-ucv2.S
@@ -0,0 +1,134 @@
1/*
2 * linux/arch/unicore32/mm/proc-ucv2.S
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/init.h>
13#include <linux/linkage.h>
14#include <asm/assembler.h>
15#include <asm/hwcap.h>
16#include <asm/pgtable-hwdef.h>
17#include <asm/pgtable.h>
18
19#include "proc-macros.S"
20
21ENTRY(cpu_proc_fin)
22 stm.w (lr), [sp-]
23 mov ip, #PSR_R_BIT | PSR_I_BIT | PRIV_MODE
24 mov.a asr, ip
25 b.l __cpuc_flush_kern_all
26 ldm.w (pc), [sp]+
27
28/*
29 * cpu_reset(loc)
30 *
31 * Perform a soft reset of the system. Put the CPU into the
32 * same state as it would be if it had been reset, and branch
33 * to what would be the reset vector.
34 *
35 * - loc - location to jump to for soft reset
36 */
37 .align 5
38ENTRY(cpu_reset)
39 mov ip, #0
40 movc p0.c5, ip, #28 @ Cache invalidate all
41 nop8
42
43 movc p0.c6, ip, #6 @ TLB invalidate all
44 nop8
45
46 movc ip, p0.c1, #0 @ ctrl register
47 or ip, ip, #0x2000 @ vector base address
48 andn ip, ip, #0x000f @ ............idam
49 movc p0.c1, ip, #0 @ disable caches and mmu
50 nop
51 mov pc, r0 @ jump to loc
52 nop8
53
54/*
55 * cpu_do_idle()
56 *
57 * Idle the processor (eg, wait for interrupt).
58 *
59 * IRQs are already disabled.
60 */
61ENTRY(cpu_do_idle)
62 mov r0, #0 @ PCI address
63 .rept 8
64 ldw r1, [r0]
65 .endr
66 mov pc, lr
67
68ENTRY(cpu_dcache_clean_area)
69#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
70 csub.a r1, #MAX_AREA_SIZE
71 bsg 101f
72 mov r9, #PAGE_SZ
73 sub r9, r9, #1 @ PAGE_MASK
741: va2pa r0, r10, r11, r12, r13 @ r10 is PA
75 b 3f
762: cand.a r0, r9
77 beq 1b
783: movc p0.c5, r10, #11 @ clean D entry
79 nop8
80 add r0, r0, #CACHE_LINESIZE
81 add r10, r10, #CACHE_LINESIZE
82 sub.a r1, r1, #CACHE_LINESIZE
83 bua 2b
84 mov pc, lr
85#endif
86101: mov ip, #0
87 movc p0.c5, ip, #10 @ Dcache clean all
88 nop8
89
90 mov pc, lr
91
92/*
93 * cpu_do_switch_mm(pgd_phys)
94 *
95 * Set the translation table base pointer to be pgd_phys
96 *
97 * - pgd_phys - physical address of new pgd
98 *
99 * It is assumed that:
100 * - we are not using split page tables
101 */
102 .align 5
103ENTRY(cpu_do_switch_mm)
104 movc p0.c2, r0, #0 @ update page table ptr
105 nop8
106
107 movc p0.c6, ip, #6 @ TLB invalidate all
108 nop8
109
110 mov pc, lr
111
112/*
113 * cpu_set_pte(ptep, pte)
114 *
115 * Set a level 2 translation table entry.
116 *
117 * - ptep - pointer to level 2 translation table entry
118 * - pte - PTE value to store
119 */
120 .align 5
121ENTRY(cpu_set_pte)
122 stw r1, [r0]
123#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
124 sub r2, r0, #PAGE_OFFSET
125 movc p0.c5, r2, #11 @ Dcache clean line
126 nop8
127#else
128 mov ip, #0
129 movc p0.c5, ip, #10 @ Dcache clean all
130 nop8
131 @dcacheline_flush r0, r2, ip
132#endif
133 mov pc, lr
134