blob: 65c007f9e6b19edc4c9879042abbdd5fa9cb0559 [file] [log] [blame]
Jeenu Viswambharan19f6cf22017-12-07 08:43:05 +00001/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <ras_arch.h>
7#include <utils_def.h>
8
9/*
10 * Probe for error in memory-mapped registers containing error records
11 * implemented Standard Error Record format. Upon detecting an error, set probe
12 * data to the index of the record in error, and return 1; otherwise, return 0.
13 */
14int ser_probe_memmap(uintptr_t base, unsigned int size_num_k, int *probe_data)
15{
16 int num_records, num_group_regs, i;
17 uint64_t gsr;
18
19 assert(base != 0);
20
21 /* Only 4K supported for now */
22 assert(size_num_k == STD_ERR_NODE_SIZE_NUM_K);
23
24 num_records = (mmio_read_32(ERR_DEVID(base, size_num_k)) & ERR_DEVID_MASK);
25
26 /* A group register shows error status for 2^6 error records */
27 num_group_regs = (num_records >> 6) + 1;
28
29 /* Iterate through group registers to find a record in error */
30 for (i = 0; i < num_group_regs; i++) {
31 gsr = mmio_read_64(ERR_GSR(base, size_num_k, i));
32 if (gsr == 0)
33 continue;
34
35 /* Return the index of the record in error */
36 if (probe_data != NULL)
37 *probe_data = ((i << 6) + __builtin_ctz(gsr));
38
39 return 1;
40 }
41
42 return 0;
43}
44
45/*
46 * Probe for error in System Registers where error records are implemented in
47 * Standard Error Record format. Upon detecting an error, set probe data to the
48 * index of the record in error, and return 1; otherwise, return 0.
49 */
50int ser_probe_sysreg(unsigned int idx_start, unsigned int num_idx, int *probe_data)
51{
52 int i;
53 uint64_t status;
54 unsigned int max_idx __unused = read_erridr_el1() & ERRIDR_MASK;
55
56 assert(idx_start < max_idx);
57 assert(check_u32_overflow(idx_start, num_idx) == 0);
58 assert((idx_start + num_idx - 1) < max_idx);
59
60 for (i = 0; i < num_idx; i++) {
61 /* Select the error record */
62 ser_sys_select_record(idx_start + i);
63
64 /* Retrieve status register from the error record */
65 status = read_erxstatus_el1();
66
67 /* Check for valid field in status */
68 if (ERR_STATUS_GET_FIELD(status, V)) {
69 if (probe_data != NULL)
70 *probe_data = i;
71 return 1;
72 }
73 }
74
75 return 0;
76}