summaryrefslogtreecommitdiffstats
path: root/arch/csky/abiv2/inc/abi/ckmmu.h
blob: 530d2c7edc85600b348cd1049632d1e34c3b71ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* SPDX-License-Identifier: GPL-2.0 */
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.

#ifndef __ASM_CSKY_CKMMUV2_H
#define __ASM_CSKY_CKMMUV2_H

#include <abi/reg_ops.h>
#include <asm/barrier.h>

static inline int read_mmu_index(void)
{
	return mfcr("cr<0, 15>");
}

static inline void write_mmu_index(int value)
{
	mtcr("cr<0, 15>", value);
}

static inline int read_mmu_entrylo0(void)
{
	return mfcr("cr<2, 15>");
}

static inline int read_mmu_entrylo1(void)
{
	return mfcr("cr<3, 15>");
}

static inline void write_mmu_pagemask(int value)
{
	mtcr("cr<6, 15>", value);
}

static inline int read_mmu_entryhi(void)
{
	return mfcr("cr<4, 15>");
}

static inline void write_mmu_entryhi(int value)
{
	mtcr("cr<4, 15>", value);
}

static inline unsigned long read_mmu_msa0(void)
{
	return mfcr("cr<30, 15>");
}

static inline void write_mmu_msa0(unsigned long value)
{
	mtcr("cr<30, 15>", value);
}

static inline unsigned long read_mmu_msa1(void)
{
	return mfcr("cr<31, 15>");
}

static inline void write_mmu_msa1(unsigned long value)
{
	mtcr("cr<31, 15>", value);
}

/*
 * TLB operations.
 */
static inline void tlb_probe(void)
{
	mtcr("cr<8, 15>", 0x80000000);
}

static inline void tlb_read(void)
{
	mtcr("cr<8, 15>", 0x40000000);
}

static inline void tlb_invalid_all(void)
{
#ifdef CONFIG_CPU_HAS_TLBI
	sync_is();
	asm volatile(
		"tlbi.alls	\n"
		"sync.i		\n"
		:
		:
		: "memory");
#else
	mtcr("cr<8, 15>", 0x04000000);
#endif
}

static inline void local_tlb_invalid_all(void)
{
#ifdef CONFIG_CPU_HAS_TLBI
	sync_is();
	asm volatile(
		"tlbi.all	\n"
		"sync.i		\n"
		:
		:
		: "memory");
#else
	tlb_invalid_all();
#endif
}

static inline void tlb_invalid_indexed(void)
{
	mtcr("cr<8, 15>", 0x02000000);
}

#define NOP32 ".long 0x4820c400\n"

static inline void setup_pgd(pgd_t *pgd, int asid)
{
#ifdef CONFIG_CPU_HAS_TLBI
	sync_is();
#else
	mb();
#endif
	asm volatile(
#ifdef CONFIG_CPU_HAS_TLBI
		"mtcr %1, cr<28, 15>	\n"
#endif
		"mtcr %1, cr<29, 15>	\n"
		"mtcr %0, cr< 4, 15>	\n"
		".rept 64		\n"
		NOP32
		".endr			\n"
		:
		:"r"(asid), "r"(__pa(pgd) | BIT(0))
		:"memory");
}

static inline pgd_t *get_pgd(void)
{
	return __va(mfcr("cr<29, 15>") & ~BIT(0));
}
#endif /* __ASM_CSKY_CKMMUV2_H */