Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/stand/arm64/libarm64/cache.c
34860 views
1
/*-
2
* Copyright (c) 2014 The FreeBSD Foundation
3
*
4
* This software was developed by Semihalf under
5
* the sponsorship of the FreeBSD Foundation.
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*/
27
28
#include <sys/param.h>
29
30
#include <machine/armreg.h>
31
#include <machine/atomic.h>
32
33
#include <stand.h>
34
35
#include "bootstrap.h"
36
#include "cache.h"
37
38
static long cache_flags;
39
#define CACHE_FLAG_DIC_OFF (1<<0)
40
#define CACHE_FLAG_IDC_OFF (1<<1)
41
42
static bool
43
get_cache_dic(uint64_t ctr)
44
{
45
if ((cache_flags & CACHE_FLAG_DIC_OFF) != 0) {
46
return (false);
47
}
48
49
return (CTR_DIC_VAL(ctr) != 0);
50
}
51
52
static bool
53
get_cache_idc(uint64_t ctr)
54
{
55
if ((cache_flags & CACHE_FLAG_IDC_OFF) != 0) {
56
return (false);
57
}
58
59
return (CTR_IDC_VAL(ctr) != 0);
60
}
61
62
static unsigned int
63
get_dcache_line_size(uint64_t ctr)
64
{
65
unsigned int dcl_size;
66
67
/*
68
* Relevant field [19:16] is LOG2
69
* of the number of words in DCache line
70
*/
71
dcl_size = CTR_DLINE_SIZE(ctr);
72
73
/* Size of word shifted by cache line size */
74
return (sizeof(int) << dcl_size);
75
}
76
77
void
78
cpu_flush_dcache(const void *ptr, size_t len)
79
{
80
uint64_t cl_size, ctr;
81
vm_offset_t addr, end;
82
83
/* Accessible from all security levels */
84
ctr = READ_SPECIALREG(ctr_el0);
85
86
if (get_cache_idc(ctr)) {
87
dsb(ishst);
88
} else {
89
cl_size = get_dcache_line_size(ctr);
90
91
/* Calculate end address to clean */
92
end = (vm_offset_t)ptr + (vm_offset_t)len;
93
/* Align start address to cache line */
94
addr = (vm_offset_t)ptr;
95
addr = rounddown2(addr, cl_size);
96
97
for (; addr < end; addr += cl_size)
98
__asm __volatile("dc civac, %0" : : "r" (addr) :
99
"memory");
100
/* Full system DSB */
101
dsb(ish);
102
}
103
}
104
105
void
106
cpu_inval_icache(void)
107
{
108
uint64_t ctr;
109
110
/* Accessible from all security levels */
111
ctr = READ_SPECIALREG(ctr_el0);
112
113
if (get_cache_dic(ctr)) {
114
isb();
115
} else {
116
__asm __volatile(
117
"ic ialluis \n"
118
"dsb ish \n"
119
"isb \n"
120
: : : "memory");
121
}
122
}
123
124
static int
125
command_cache_flags(int argc, char *argv[])
126
{
127
char *cp;
128
long new_flags;
129
130
if (argc == 3) {
131
if (strcmp(argv[1], "set") == 0) {
132
new_flags = strtol(argv[2], &cp, 0);
133
if (cp[0] != '\0') {
134
printf("Invalid flags\n");
135
} else {
136
printf("Setting cache flags to %#lx\n",
137
new_flags);
138
cache_flags = new_flags;
139
return (CMD_OK);
140
}
141
}
142
}
143
144
printf("usage: cache_flags set <value>\n");
145
return (CMD_ERROR);
146
}
147
COMMAND_SET(cache_flags, "cache_flags", "Set cache flags", command_cache_flags);
148
149