xref: /linux/drivers/gpu/drm/amd/ras/core/core.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright 2025 Advanced Micro Devices, Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  */
24 #include "ras.h"
25 #include "core_status.h"
26 
27 #define RAS_SEQNO_FIFO_SIZE (128 * sizeof(uint64_t))
28 
29 #define IS_LEAP_YEAR(x) ((x % 4 == 0 && x % 100 != 0) || x % 400 == 0)
30 
31 enum RAS_DEBUG_MASK {
32 	RAS_DEBUG_DISABLE_RAS_CE_LOG = 9,
33 };
34 
35 static const char * const ras_block_name[] = {
36 	"umc",
37 	"sdma",
38 	"gfx",
39 	"mmhub",
40 	"athub",
41 	"pcie_bif",
42 	"hdp",
43 	"xgmi_wafl",
44 	"df",
45 	"smn",
46 	"sem",
47 	"mp0",
48 	"mp1",
49 	"fuse",
50 	"mca",
51 	"vcn",
52 	"jpeg",
53 	"ih",
54 	"mpio",
55 };
56 
57 const char *ras_core_get_ras_block_name(enum ras_block_id block_id)
58 {
59 	if (block_id >= ARRAY_SIZE(ras_block_name))
60 		return "";
61 
62 	return ras_block_name[block_id];
63 }
64 
65 int ras_core_convert_timestamp_to_time(struct ras_core_context *ras_core,
66 			uint64_t timestamp, struct ras_time *tm)
67 {
68 	int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
69 	uint64_t month = 0, day = 0, hour = 0, minute = 0, second = 0, remainder;
70 	uint32_t year = 0;
71 	int seconds_per_day = 24 * 60 * 60;
72 	int seconds_per_hour = 60 * 60;
73 	int seconds_per_minute = 60;
74 	int days, remaining_seconds;
75 
76 	if (!tm)
77 		return -EINVAL;
78 
79 	days = div64_u64_rem(timestamp, seconds_per_day, &remainder);
80 	/* remainder will always be less than seconds_per_day. */
81 	remaining_seconds = remainder;
82 
83 	/* utc_timestamp follows the Unix epoch */
84 	year = 1970;
85 	while (days >= 365) {
86 		if (IS_LEAP_YEAR(year)) {
87 			if (days < 366)
88 				break;
89 			days -= 366;
90 		} else {
91 			days -= 365;
92 		}
93 		year++;
94 	}
95 
96 	days_in_month[1] += IS_LEAP_YEAR(year);
97 
98 	month = 0;
99 	while (days >= days_in_month[month]) {
100 		days -= days_in_month[month];
101 		month++;
102 	}
103 	month++;
104 	day = days + 1;
105 
106 	if (remaining_seconds) {
107 		hour = remaining_seconds / seconds_per_hour;
108 		minute = (remaining_seconds % seconds_per_hour) / seconds_per_minute;
109 		second = remaining_seconds % seconds_per_minute;
110 	}
111 
112 	tm->tm_year = year;
113 	tm->tm_mon = month;
114 	tm->tm_mday = day;
115 	tm->tm_hour = hour;
116 	tm->tm_min = minute;
117 	tm->tm_sec = second;
118 
119 	return 0;
120 }
121 
122 bool ras_core_gpu_in_reset(struct ras_core_context *ras_core)
123 {
124 	uint32_t status = 0;
125 
126 	if (!ras_core)
127 		return false;
128 
129 	if (ras_core->sys_fn &&
130 		ras_core->sys_fn->check_gpu_status)
131 		ras_core->sys_fn->check_gpu_status(ras_core, &status);
132 
133 	return (status & RAS_GPU_STATUS__IN_RESET) ? true : false;
134 }
135 
136 bool ras_core_gpu_is_vf(struct ras_core_context *ras_core)
137 {
138 	uint32_t status = 0;
139 
140 	if (!ras_core)
141 		return false;
142 
143 	if (ras_core->sys_fn &&
144 		ras_core->sys_fn->check_gpu_status)
145 		ras_core->sys_fn->check_gpu_status(ras_core, &status);
146 
147 	return (status & RAS_GPU_STATUS__IS_VF) ? true : false;
148 }
149 
150 bool ras_core_gpu_device_lost(struct ras_core_context *ras_core)
151 {
152 	uint32_t status = 0;
153 
154 	if (!ras_core)
155 		return false;
156 
157 	if (ras_core->sys_fn &&
158 		ras_core->sys_fn->check_gpu_status)
159 		ras_core->sys_fn->check_gpu_status(ras_core, &status);
160 
161 	return (status & RAS_GPU_STATUS__DEVICE_LOST) ? true : false;
162 }
163 
164 bool ras_core_gpu_is_rma(struct ras_core_context *ras_core)
165 {
166 	if (!ras_core)
167 		return false;
168 
169 	return ras_core->is_rma;
170 }
171 
172 int ras_core_set_debug_mode(struct ras_core_context *ras_core, bool enable)
173 {
174 	return ras_mp1_set_debug_mode(ras_core, enable);
175 }
176 
177 static int ras_core_seqno_fifo_write(struct ras_core_context *ras_core,
178 		enum ras_seqno_fifo fifo_type, uint64_t seqno)
179 {
180 	int ret = 0;
181 	struct kfifo *seqno_fifo = NULL;
182 
183 	if (fifo_type == SEQNO_FIFO_POISON_CREATION)
184 		seqno_fifo = &ras_core->de_seqno_fifo;
185 	else if (fifo_type == SEQNO_FIFO_POISON_CONSUMPTION)
186 		seqno_fifo = &ras_core->consumption_seqno_fifo;
187 
188 	if (seqno_fifo)
189 		ret = kfifo_in_spinlocked(seqno_fifo,
190 			&seqno, sizeof(seqno), &ras_core->seqno_lock);
191 
192 	return ret ? 0 : -EINVAL;
193 }
194 
195 static int ras_core_seqno_fifo_read(struct ras_core_context *ras_core,
196 		enum ras_seqno_fifo fifo_type, uint64_t *seqno, bool pop)
197 {
198 	int ret = 0;
199 	struct kfifo *seqno_fifo = NULL;
200 
201 	if (fifo_type == SEQNO_FIFO_POISON_CREATION)
202 		seqno_fifo = &ras_core->de_seqno_fifo;
203 	else if (fifo_type == SEQNO_FIFO_POISON_CONSUMPTION)
204 		seqno_fifo = &ras_core->consumption_seqno_fifo;
205 
206 	if (seqno_fifo) {
207 		if (pop)
208 			ret = kfifo_out_spinlocked(seqno_fifo,
209 				seqno, sizeof(*seqno), &ras_core->seqno_lock);
210 		else
211 			ret = kfifo_out_peek(seqno_fifo, seqno, sizeof(*seqno));
212 	}
213 
214 	return ret ? 0 : -EINVAL;
215 }
216 
217 uint64_t ras_core_gen_seqno(struct ras_core_context *ras_core,
218 			enum ras_seqno_type type)
219 {
220 	uint64_t seqno = 0;
221 
222 	if (ras_core->sys_fn && ras_core->sys_fn->gen_seqno &&
223 	    ras_core->sys_fn->gen_seqno(ras_core, type, &seqno))
224 		return 0;
225 
226 	return seqno;
227 }
228 
229 int ras_core_put_seqno(struct ras_core_context *ras_core,
230 		enum ras_seqno_type seqno_type, uint64_t seqno)
231 {
232 	int ret = 0;
233 
234 	if (seqno_type >= RAS_SEQNO_TYPE_COUNT_MAX)
235 		return -EINVAL;
236 
237 	if (seqno_type == RAS_SEQNO_TYPE_DE)
238 		ret = ras_core_seqno_fifo_write(ras_core,
239 				SEQNO_FIFO_POISON_CREATION, seqno);
240 	else if (seqno_type == RAS_SEQNO_TYPE_POISON_CONSUMPTION)
241 		ret = ras_core_seqno_fifo_write(ras_core,
242 				SEQNO_FIFO_POISON_CONSUMPTION, seqno);
243 	else
244 		ret = -EINVAL;
245 
246 	return ret;
247 }
248 
249 uint64_t ras_core_get_seqno(struct ras_core_context *ras_core,
250 			enum ras_seqno_type seqno_type, bool pop)
251 {
252 	uint64_t seq_no;
253 	int ret = -ENODATA;
254 
255 	if (seqno_type >= RAS_SEQNO_TYPE_COUNT_MAX)
256 		return 0;
257 
258 	if (seqno_type == RAS_SEQNO_TYPE_DE)
259 		ret = ras_core_seqno_fifo_read(ras_core,
260 				SEQNO_FIFO_POISON_CREATION, &seq_no, pop);
261 	else if (seqno_type == RAS_SEQNO_TYPE_POISON_CONSUMPTION)
262 		ret = ras_core_seqno_fifo_read(ras_core,
263 				SEQNO_FIFO_POISON_CONSUMPTION, &seq_no, pop);
264 
265 	if (ret)
266 		seq_no = ras_core_gen_seqno(ras_core, seqno_type);
267 
268 	return seq_no;
269 }
270 
271 static int ras_core_eeprom_recovery(struct ras_core_context *ras_core)
272 {
273 	int count;
274 	int ret;
275 
276 	if (ras_fw_eeprom_supported(ras_core))
277 		count = ras_fw_eeprom_get_record_count(ras_core);
278 	else
279 		count = ras_eeprom_get_record_count(ras_core);
280 	if (!count)
281 		return 0;
282 
283 	/* Avoid bad page to be loaded again after gpu reset */
284 	if (ras_umc_get_saved_eeprom_count(ras_core) >= count)
285 		return 0;
286 
287 	ret = ras_umc_load_bad_pages(ras_core);
288 	if (ret) {
289 		RAS_DEV_ERR(ras_core->dev, "ras_umc_load_bad_pages failed: %d\n", ret);
290 		return ret;
291 	}
292 
293 	if (ras_fw_eeprom_supported(ras_core))
294 		ras_fw_eeprom_sync_info(ras_core);
295 	else
296 		ras_eeprom_sync_info(ras_core);
297 
298 	return ret;
299 }
300 
301 struct ras_core_context *ras_core_create(struct ras_core_config *init_config)
302 {
303 	struct ras_core_context *ras_core;
304 	struct ras_core_config *config;
305 
306 	if (!init_config)
307 		return NULL;
308 
309 	ras_core = kzalloc_obj(*ras_core);
310 	if (!ras_core)
311 		return NULL;
312 
313 	config = kzalloc_obj(*config);
314 	if (!config) {
315 		kfree(ras_core);
316 		return NULL;
317 	}
318 
319 	memcpy(config, init_config, sizeof(*config));
320 	ras_core->config = config;
321 
322 	return ras_core;
323 }
324 
325 void ras_core_destroy(struct ras_core_context *ras_core)
326 {
327 	if (ras_core)
328 		kfree(ras_core->config);
329 
330 	kfree(ras_core);
331 }
332 
333 int ras_core_sw_init(struct ras_core_context *ras_core)
334 {
335 	int ret;
336 
337 	if (!ras_core->config) {
338 		RAS_DEV_ERR(ras_core->dev, "No ras core config!\n");
339 		return -EINVAL;
340 	}
341 
342 	ras_core->sys_fn = ras_core->config->sys_fn;
343 	if (!ras_core->sys_fn)
344 		return -EINVAL;
345 
346 	ret = kfifo_alloc(&ras_core->de_seqno_fifo,
347 		 RAS_SEQNO_FIFO_SIZE, GFP_KERNEL);
348 	if (ret)
349 		return ret;
350 
351 	ret = kfifo_alloc(&ras_core->consumption_seqno_fifo,
352 		 RAS_SEQNO_FIFO_SIZE, GFP_KERNEL);
353 	if (ret)
354 		return ret;
355 
356 	spin_lock_init(&ras_core->seqno_lock);
357 
358 	ret = ras_aca_sw_init(ras_core);
359 	if (ret)
360 		return ret;
361 
362 	ret = ras_umc_sw_init(ras_core);
363 	if (ret)
364 		return ret;
365 
366 	ret = ras_cmd_init(ras_core);
367 	if (ret)
368 		return ret;
369 
370 	ret = ras_log_ring_sw_init(ras_core);
371 	if (ret)
372 		return ret;
373 
374 	ret = ras_psp_sw_init(ras_core);
375 	if (ret)
376 		return ret;
377 
378 	return 0;
379 }
380 
381 int ras_core_sw_fini(struct ras_core_context *ras_core)
382 {
383 	kfifo_free(&ras_core->de_seqno_fifo);
384 	kfifo_free(&ras_core->consumption_seqno_fifo);
385 
386 	ras_psp_sw_fini(ras_core);
387 	ras_log_ring_sw_fini(ras_core);
388 	ras_cmd_fini(ras_core);
389 	ras_umc_sw_fini(ras_core);
390 	ras_aca_sw_fini(ras_core);
391 
392 	return 0;
393 }
394 
395 int ras_core_hw_init(struct ras_core_context *ras_core)
396 {
397 	int ret;
398 
399 	ras_core->ras_eeprom_supported =
400 			ras_core->config->ras_eeprom_supported;
401 
402 	ras_core->poison_supported = ras_core->config->poison_supported;
403 
404 	ret = ras_psp_hw_init(ras_core);
405 	if (ret)
406 		return ret;
407 
408 	ret = ras_aca_hw_init(ras_core);
409 	if (ret)
410 		goto init_err1;
411 
412 	ret = ras_mp1_hw_init(ras_core);
413 	if (ret)
414 		goto init_err2;
415 
416 	ret = ras_nbio_hw_init(ras_core);
417 	if (ret)
418 		goto init_err3;
419 
420 	ret = ras_umc_hw_init(ras_core);
421 	if (ret)
422 		goto init_err4;
423 
424 	ret = ras_gfx_hw_init(ras_core);
425 	if (ret)
426 		goto init_err5;
427 
428 	ras_fw_init_feature_flags(ras_core);
429 
430 	if (ras_fw_eeprom_supported(ras_core))
431 		ret = ras_fw_eeprom_hw_init(ras_core);
432 	else
433 		ret = ras_eeprom_hw_init(ras_core);
434 	if (ret)
435 		goto init_err6;
436 
437 	ret = ras_core_eeprom_recovery(ras_core);
438 	if (ret) {
439 		RAS_DEV_ERR(ras_core->dev,
440 			"Failed to recovery ras core, ret:%d\n", ret);
441 		goto init_err6;
442 	}
443 
444 	if (ras_fw_eeprom_supported(ras_core))
445 		ret = ras_fw_eeprom_check_storage_status(ras_core);
446 	else
447 		ret = ras_eeprom_check_storage_status(ras_core);
448 	if (ret)
449 		goto init_err6;
450 
451 	ret = ras_process_init(ras_core);
452 	if (ret)
453 		goto init_err7;
454 
455 	ras_core->is_initialized = true;
456 
457 	return 0;
458 
459 init_err7:
460 	if (ras_fw_eeprom_supported(ras_core))
461 		ras_fw_eeprom_hw_fini(ras_core);
462 	else
463 		ras_eeprom_hw_fini(ras_core);
464 init_err6:
465 	ras_gfx_hw_fini(ras_core);
466 init_err5:
467 	ras_umc_hw_fini(ras_core);
468 init_err4:
469 	ras_nbio_hw_fini(ras_core);
470 init_err3:
471 	ras_mp1_hw_fini(ras_core);
472 init_err2:
473 	ras_aca_hw_fini(ras_core);
474 init_err1:
475 	ras_psp_hw_fini(ras_core);
476 	return ret;
477 }
478 
479 int ras_core_hw_fini(struct ras_core_context *ras_core)
480 {
481 	ras_core->is_initialized = false;
482 
483 	ras_process_fini(ras_core);
484 	if (ras_fw_eeprom_supported(ras_core))
485 		ras_fw_eeprom_hw_fini(ras_core);
486 	else
487 		ras_eeprom_hw_fini(ras_core);
488 	ras_gfx_hw_fini(ras_core);
489 	ras_nbio_hw_fini(ras_core);
490 	ras_umc_hw_fini(ras_core);
491 	ras_mp1_hw_fini(ras_core);
492 	ras_aca_hw_fini(ras_core);
493 	ras_psp_hw_fini(ras_core);
494 
495 	return 0;
496 }
497 
498 bool ras_core_handle_nbio_irq(struct ras_core_context *ras_core, void *data)
499 {
500 	return ras_nbio_handle_irq_error(ras_core, data);
501 }
502 
503 int ras_core_handle_fatal_error(struct ras_core_context *ras_core)
504 {
505 	int ret = 0;
506 
507 	ras_aca_mark_fatal_flag(ras_core);
508 
509 	ret = ras_core_event_notify(ras_core,
510 			RAS_EVENT_ID__FATAL_ERROR_DETECTED, NULL);
511 
512 	return ret;
513 }
514 
515 uint32_t ras_core_get_curr_nps_mode(struct ras_core_context *ras_core)
516 {
517 	if (!ras_core)
518 		return 0;
519 
520 	if (ras_core->ras_nbio.ip_func &&
521 	    ras_core->ras_nbio.ip_func->get_memory_partition_mode)
522 		return ras_core->ras_nbio.ip_func->get_memory_partition_mode(ras_core);
523 
524 	RAS_DEV_ERR(ras_core->dev, "Failed to get gpu memory nps mode!\n");
525 	return 0;
526 }
527 
528 int ras_core_update_ecc_info(struct ras_core_context *ras_core)
529 {
530 	int ret;
531 
532 	ret = ras_aca_update_ecc(ras_core, RAS_ERR_TYPE__CE, NULL);
533 	if (!ret)
534 		ret = ras_aca_update_ecc(ras_core, RAS_ERR_TYPE__UE, NULL);
535 
536 	return ret;
537 }
538 
539 int ras_core_query_block_ecc_data(struct ras_core_context *ras_core,
540 			enum ras_block_id block, struct ras_ecc_count *ecc_count)
541 {
542 	int ret;
543 
544 	if (!ecc_count || (block >= RAS_BLOCK_ID__LAST) || !ras_core)
545 		return -EINVAL;
546 
547 	ret = ras_aca_get_block_ecc_count(ras_core, block, ecc_count);
548 	if (!ret)
549 		ras_aca_clear_block_new_ecc_count(ras_core, block);
550 
551 	return ret;
552 }
553 
554 int ras_core_set_status(struct ras_core_context *ras_core, bool enable)
555 {
556 	ras_core->ras_core_enabled = enable;
557 
558 	return 0;
559 }
560 
561 bool ras_core_is_enabled(struct ras_core_context *ras_core)
562 {
563 	return ras_core->ras_core_enabled;
564 }
565 
566 bool ras_core_is_ce_log_disabled(struct ras_core_context *ras_core)
567 {
568 	return !!(ras_core->config->ras_debug_mask & BIT(RAS_DEBUG_DISABLE_RAS_CE_LOG));
569 }
570 
571 uint64_t ras_core_get_utc_second_timestamp(struct ras_core_context *ras_core)
572 {
573 	if (!ras_core)
574 		return 0;
575 
576 	if (ras_core->sys_fn &&
577 	    ras_core->sys_fn->get_utc_second_timestamp)
578 		return ras_core->sys_fn->get_utc_second_timestamp(ras_core);
579 
580 	RAS_DEV_ERR(ras_core->dev, "Failed to get system timestamp!\n");
581 	return 0;
582 }
583 
584 int ras_core_translate_soc_pa_and_bank(struct ras_core_context *ras_core,
585 	uint64_t *soc_pa, struct umc_bank_addr *bank_addr, bool bank_to_pa)
586 {
587 	if (!ras_core || !soc_pa || !bank_addr)
588 		return -EINVAL;
589 
590 	return ras_umc_translate_soc_pa_and_bank(ras_core, soc_pa, bank_addr, bank_to_pa);
591 }
592 
593 bool ras_core_ras_interrupt_detected(struct ras_core_context *ras_core)
594 {
595 	if (ras_core && ras_core->sys_fn &&
596 		ras_core->sys_fn->detect_ras_interrupt)
597 		return ras_core->sys_fn->detect_ras_interrupt(ras_core);
598 
599 	if (ras_core && ras_core->dev)
600 		RAS_DEV_ERR(ras_core->dev, "Failed to detect ras interrupt!\n");
601 
602 	return false;
603 }
604 
605 int ras_core_get_gpu_mem(struct ras_core_context *ras_core,
606 	enum gpu_mem_type mem_type, struct gpu_mem_block *gpu_mem)
607 {
608 	if (!ras_core || !gpu_mem)
609 		return -EINVAL;
610 	if (ras_core->sys_fn && ras_core->sys_fn->get_gpu_mem)
611 		return ras_core->sys_fn->get_gpu_mem(ras_core, mem_type, gpu_mem);
612 
613 	RAS_DEV_ERR(ras_core->dev, "Not config get gpu memory API!\n");
614 	return -EACCES;
615 }
616 
617 int ras_core_put_gpu_mem(struct ras_core_context *ras_core,
618 	enum gpu_mem_type mem_type, struct gpu_mem_block *gpu_mem)
619 {
620 	if (!ras_core || !gpu_mem)
621 		return -EINVAL;
622 	if (ras_core->sys_fn && ras_core->sys_fn->put_gpu_mem)
623 		return ras_core->sys_fn->put_gpu_mem(ras_core, mem_type, gpu_mem);
624 
625 	RAS_DEV_ERR(ras_core->dev, "Not config put gpu memory API!!\n");
626 	return -EACCES;
627 }
628 
629 bool ras_core_is_ready(struct ras_core_context *ras_core)
630 {
631 	return ras_core ? ras_core->is_initialized : false;
632 }
633 
634 bool ras_core_check_safety_watermark(struct ras_core_context *ras_core)
635 {
636 	if (ras_fw_eeprom_supported(ras_core))
637 		return ras_fw_eeprom_check_safety_watermark(ras_core);
638 
639 	return ras_eeprom_check_safety_watermark(ras_core);
640 }
641 
642 int ras_core_down_trylock_gpu_reset_lock(struct ras_core_context *ras_core)
643 {
644 	if (ras_core->sys_fn && ras_core->sys_fn->gpu_reset_lock)
645 		return ras_core->sys_fn->gpu_reset_lock(ras_core, true, true);
646 
647 	return 1;
648 }
649 
650 void ras_core_down_gpu_reset_lock(struct ras_core_context *ras_core)
651 {
652 	if (ras_core->sys_fn && ras_core->sys_fn->gpu_reset_lock)
653 		ras_core->sys_fn->gpu_reset_lock(ras_core, true, false);
654 }
655 
656 void ras_core_up_gpu_reset_lock(struct ras_core_context *ras_core)
657 {
658 	if (ras_core->sys_fn && ras_core->sys_fn->gpu_reset_lock)
659 		ras_core->sys_fn->gpu_reset_lock(ras_core, false, false);
660 }
661 
662 int ras_core_event_notify(struct ras_core_context *ras_core,
663 		enum ras_notify_event event_id, void *data)
664 {
665 	if (ras_core && ras_core->sys_fn &&
666 		ras_core->sys_fn->ras_notifier)
667 		return ras_core->sys_fn->ras_notifier(ras_core, event_id, data);
668 
669 	return -RAS_CORE_NOT_SUPPORTED;
670 }
671 
672 int ras_core_get_device_system_info(struct ras_core_context *ras_core,
673 		struct device_system_info *dev_info)
674 {
675 	if (!dev_info)
676 		return -EINVAL;
677 
678 	if (ras_core && ras_core->sys_fn &&
679 		ras_core->sys_fn->get_device_system_info)
680 		return ras_core->sys_fn->get_device_system_info(ras_core, dev_info);
681 
682 	return -RAS_CORE_NOT_SUPPORTED;
683 }
684 
685 int ras_core_convert_soc_pa_to_cur_nps_pages(struct ras_core_context *ras_core,
686 		uint64_t soc_pa, uint64_t *page_pfn, uint32_t max_pages)
687 {
688 	struct eeprom_umc_record record;
689 	uint32_t cur_nps_mode;
690 	int count = 0;
691 
692 	if (!ras_core || !page_pfn || !max_pages)
693 		return -EINVAL;
694 
695 	cur_nps_mode = ras_core_get_curr_nps_mode(ras_core);
696 	if (!cur_nps_mode || cur_nps_mode > UMC_MEMORY_PARTITION_MODE_NPS8)
697 		return -EINVAL;
698 
699 	memset(&record, 0, sizeof(record));
700 	record.cur_nps_retired_row_pfn = RAS_ADDR_TO_PFN(soc_pa);
701 
702 	count = ras_umc_convert_record_to_nps_pages(ras_core,
703 				&record, cur_nps_mode, page_pfn, max_pages);
704 
705 	return count;
706 }
707 
708 int ras_core_check_address_sanity(struct ras_core_context *ras_core,
709 		uint64_t addr)
710 {
711 	if (ras_core && ras_core->sys_fn &&
712 		ras_core->sys_fn->check_address_sanity)
713 		return ras_core->sys_fn->check_address_sanity(ras_core, addr);
714 
715 	return 0;
716 }
717