@@ -81,6 +81,7 @@ static inline bool acpi_pptt_match_type(int table_type, int type)
81
81
* acpi_pptt_walk_cache() - Attempt to find the requested acpi_pptt_cache
82
82
* @table_hdr: Pointer to the head of the PPTT table
83
83
* @local_level: passed res reflects this cache level
84
+ * @split_levels: Number of split cache levels (data/instruction).
84
85
* @res: cache resource in the PPTT we want to walk
85
86
* @found: returns a pointer to the requested level if found
86
87
* @level: the requested cache level
@@ -100,6 +101,7 @@ static inline bool acpi_pptt_match_type(int table_type, int type)
100
101
*/
101
102
static unsigned int acpi_pptt_walk_cache (struct acpi_table_header * table_hdr ,
102
103
unsigned int local_level ,
104
+ unsigned int * split_levels ,
103
105
struct acpi_subtable_header * res ,
104
106
struct acpi_pptt_cache * * found ,
105
107
unsigned int level , int type )
@@ -113,8 +115,17 @@ static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr,
113
115
while (cache ) {
114
116
local_level ++ ;
115
117
118
+ if (!(cache -> flags & ACPI_PPTT_CACHE_TYPE_VALID )) {
119
+ cache = fetch_pptt_cache (table_hdr , cache -> next_level_of_cache );
120
+ continue ;
121
+ }
122
+
123
+ if (split_levels &&
124
+ (acpi_pptt_match_type (cache -> attributes , ACPI_PPTT_CACHE_TYPE_DATA ) ||
125
+ acpi_pptt_match_type (cache -> attributes , ACPI_PPTT_CACHE_TYPE_INSTR )))
126
+ * split_levels = local_level ;
127
+
116
128
if (local_level == level &&
117
- cache -> flags & ACPI_PPTT_CACHE_TYPE_VALID &&
118
129
acpi_pptt_match_type (cache -> attributes , type )) {
119
130
if (* found != NULL && cache != * found )
120
131
pr_warn ("Found duplicate cache level/type unable to determine uniqueness\n" );
@@ -135,8 +146,8 @@ static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr,
135
146
static struct acpi_pptt_cache *
136
147
acpi_find_cache_level (struct acpi_table_header * table_hdr ,
137
148
struct acpi_pptt_processor * cpu_node ,
138
- unsigned int * starting_level , unsigned int level ,
139
- int type )
149
+ unsigned int * starting_level , unsigned int * split_levels ,
150
+ unsigned int level , int type )
140
151
{
141
152
struct acpi_subtable_header * res ;
142
153
unsigned int number_of_levels = * starting_level ;
@@ -149,7 +160,8 @@ acpi_find_cache_level(struct acpi_table_header *table_hdr,
149
160
resource ++ ;
150
161
151
162
local_level = acpi_pptt_walk_cache (table_hdr , * starting_level ,
152
- res , & ret , level , type );
163
+ split_levels , res , & ret ,
164
+ level , type );
153
165
/*
154
166
* we are looking for the max depth. Since its potentially
155
167
* possible for a given node to have resources with differing
@@ -165,29 +177,29 @@ acpi_find_cache_level(struct acpi_table_header *table_hdr,
165
177
}
166
178
167
179
/**
168
- * acpi_count_levels() - Given a PPTT table, and a CPU node, count the caches
180
+ * acpi_count_levels() - Given a PPTT table, and a CPU node, count the cache
181
+ * levels and split cache levels (data/instruction).
169
182
* @table_hdr: Pointer to the head of the PPTT table
170
183
* @cpu_node: processor node we wish to count caches for
184
+ * @levels: Number of levels if success.
185
+ * @split_levels: Number of split cache levels (data/instruction) if
186
+ * success. Can by NULL.
171
187
*
172
188
* Given a processor node containing a processing unit, walk into it and count
173
189
* how many levels exist solely for it, and then walk up each level until we hit
174
190
* the root node (ignore the package level because it may be possible to have
175
- * caches that exist across packages). Count the number of cache levels that
176
- * exist at each level on the way up.
177
- *
178
- * Return: Total number of levels found.
191
+ * caches that exist across packages). Count the number of cache levels and
192
+ * split cache levels (data/instruction) that exist at each level on the way
193
+ * up.
179
194
*/
180
- static int acpi_count_levels (struct acpi_table_header * table_hdr ,
181
- struct acpi_pptt_processor * cpu_node )
195
+ static void acpi_count_levels (struct acpi_table_header * table_hdr ,
196
+ struct acpi_pptt_processor * cpu_node ,
197
+ unsigned int * levels , unsigned int * split_levels )
182
198
{
183
- int total_levels = 0 ;
184
-
185
199
do {
186
- acpi_find_cache_level (table_hdr , cpu_node , & total_levels , 0 , 0 );
200
+ acpi_find_cache_level (table_hdr , cpu_node , levels , split_levels , 0 , 0 );
187
201
cpu_node = fetch_pptt_node (table_hdr , cpu_node -> parent );
188
202
} while (cpu_node );
189
-
190
- return total_levels ;
191
203
}
192
204
193
205
/**
@@ -321,7 +333,7 @@ static struct acpi_pptt_cache *acpi_find_cache_node(struct acpi_table_header *ta
321
333
322
334
while (cpu_node && !found ) {
323
335
found = acpi_find_cache_level (table_hdr , cpu_node ,
324
- & total_levels , level , acpi_type );
336
+ & total_levels , NULL , level , acpi_type );
325
337
* node = cpu_node ;
326
338
cpu_node = fetch_pptt_node (table_hdr , cpu_node -> parent );
327
339
}
@@ -589,36 +601,48 @@ static int check_acpi_cpu_flag(unsigned int cpu, int rev, u32 flag)
589
601
}
590
602
591
603
/**
592
- * acpi_find_last_cache_level() - Determines the number of cache levels for a PE
604
+ * acpi_get_cache_info() - Determine the number of cache levels and
605
+ * split cache levels (data/instruction) and for a PE.
593
606
* @cpu: Kernel logical CPU number
607
+ * @levels: Number of levels if success.
608
+ * @split_levels: Number of levels being split (i.e. data/instruction)
609
+ * if success. Can by NULL.
594
610
*
595
611
* Given a logical CPU number, returns the number of levels of cache represented
596
612
* in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0
597
613
* indicating we didn't find any cache levels.
598
614
*
599
- * Return: Cache levels visible to this core.
615
+ * Return: -ENOENT if no PPTT table or no PPTT processor struct found.
616
+ * 0 on success.
600
617
*/
601
- int acpi_find_last_cache_level (unsigned int cpu )
618
+ int acpi_get_cache_info (unsigned int cpu , unsigned int * levels ,
619
+ unsigned int * split_levels )
602
620
{
603
621
struct acpi_pptt_processor * cpu_node ;
604
622
struct acpi_table_header * table ;
605
- int number_of_levels = 0 ;
606
623
u32 acpi_cpu_id ;
607
624
625
+ * levels = 0 ;
626
+ if (split_levels )
627
+ * split_levels = 0 ;
628
+
608
629
table = acpi_get_pptt ();
609
630
if (!table )
610
631
return - ENOENT ;
611
632
612
- pr_debug ("Cache Setup find last level CPU=%d\n" , cpu );
633
+ pr_debug ("Cache Setup: find cache levels for CPU=%d\n" , cpu );
613
634
614
635
acpi_cpu_id = get_acpi_id_for_cpu (cpu );
615
636
cpu_node = acpi_find_processor_node (table , acpi_cpu_id );
616
- if (cpu_node )
617
- number_of_levels = acpi_count_levels ( table , cpu_node ) ;
637
+ if (! cpu_node )
638
+ return - ENOENT ;
618
639
619
- pr_debug ( "Cache Setup find last level level=%d\n" , number_of_levels );
640
+ acpi_count_levels ( table , cpu_node , levels , split_levels );
620
641
621
- return number_of_levels ;
642
+ pr_debug ("Cache Setup: last_level=%d split_levels=%d\n" ,
643
+ * levels , split_levels ? * split_levels : -1 );
644
+
645
+ return 0 ;
622
646
}
623
647
624
648
/**
0 commit comments