|
| 1 | +#include <string.h> |
| 2 | +#include <stdio.h> |
| 3 | +#include <assert.h> |
| 4 | +#include "mcelog.h" |
| 5 | +#include "core2.h" |
| 6 | + |
| 7 | +/* Decode P6 family (Core2) model specific errors. |
| 8 | + The generic errors are decoded in p4.c */ |
| 9 | + |
| 10 | +/* [19..24] */ |
| 11 | +static char *bus_queue_req_type[] = { |
| 12 | + [0] = "BQ_DCU_READ_TYPE", |
| 13 | + [2] = "BQ_IFU_DEMAND_TYPE", |
| 14 | + [3] = "BQ_IFU_DEMAND_NC_TYPE", |
| 15 | + [4] = "BQ_DCU_RFO_TYPE", |
| 16 | + [5] = "BQ_DCU_RFO_LOCK_TYPE", |
| 17 | + [6] = "BQ_DCU_ITOM_TYPE", |
| 18 | + [8] = "BQ_DCU_WB_TYPE", |
| 19 | + [10] = "BC_DCU_WCEVICT_TYPE", |
| 20 | + [11] = "BQ_DCU_WCLINE_TYPE", |
| 21 | + [12] = "BQ_DCU_BTM_TYPE", |
| 22 | + [13] = "BQ_DCU_INTACK_TYPE", |
| 23 | + [14] = "BQ_DCU_INVALL2_TYPE", |
| 24 | + [15] = "BQ_DCU_FLUSHL2_TYPE", |
| 25 | + [16] = "BQ_DCU_PART_RD_TYPE", |
| 26 | + [18] = "BQ_DCU_PART_WR_TYPE", |
| 27 | + [20] = "BQ_DCU_SPEC_CYC_TYPE", |
| 28 | + [24] = "BQ_DCU_IO_RD_TYPE", |
| 29 | + [25] = "BQ_DCU_IO_WR_TYPE", |
| 30 | + [28] = "BQ_DCU_LOCK_RD_TYPE", |
| 31 | + [30] = "BQ_DCU_SPLOCK_RD_TYPE", |
| 32 | + [29] = "BQ_DCU_LOCK_WR_TYPE", |
| 33 | +}; |
| 34 | + |
| 35 | +/* [25..27] */ |
| 36 | +static char *bus_queue_error_type[] = { |
| 37 | + [0] = "BQ_ERR_HARD_TYPE", |
| 38 | + [1] = "BQ_ERR_DOUBLE_TYPE", |
| 39 | + [2] = "BQ_ERR_AERR2_TYPE", |
| 40 | + [4] = "BQ_ERR_SINGLE_TYPE", |
| 41 | + [5] = "BQ_ERR_AERR1_TYPE", |
| 42 | +}; |
| 43 | + |
| 44 | +static char *reserved_3bits[8]; |
| 45 | +static char *reserved_1bit[2]; |
| 46 | +static char *reserved_2bits[4]; |
| 47 | + |
| 48 | +#define SINGLEBIT(n,d) static char *n[2] = { [1] = d }; |
| 49 | + |
| 50 | +SINGLEBIT(frc, "FRC error"); |
| 51 | +SINGLEBIT(berr, "BERR"); |
| 52 | +SINGLEBIT(int_binit, "internal BINIT"); |
| 53 | +SINGLEBIT(ext_binit, "external BINIT"); |
| 54 | +SINGLEBIT(response_parity, "response parity error"); |
| 55 | +SINGLEBIT(bus_binit, "bus BINIT"); |
| 56 | +SINGLEBIT(timeout_binit, "timeout BINIT (ROB timeout)"); |
| 57 | +SINGLEBIT(hard_err, "hard error"); |
| 58 | +SINGLEBIT(ierr, "IERR"); |
| 59 | +SINGLEBIT(aerr, "parity error"); |
| 60 | +SINGLEBIT(uecc, "uncorrectable ECC"); |
| 61 | +SINGLEBIT(cecc, "correctable ECC"); |
| 62 | + |
| 63 | +struct field { |
| 64 | + int start_bit; |
| 65 | + char **str; |
| 66 | + int stringlen; |
| 67 | +}; |
| 68 | + |
| 69 | +#define FIELD(start_bit, name) { start_bit, name, NELE(name) } |
| 70 | + |
| 71 | +struct field fields[] = { |
| 72 | + FIELD(16, reserved_3bits), |
| 73 | + FIELD(19, bus_queue_req_type), |
| 74 | + FIELD(25, bus_queue_error_type), |
| 75 | + FIELD(25, bus_queue_error_type), |
| 76 | + FIELD(28, frc), |
| 77 | + FIELD(29, berr), |
| 78 | + FIELD(30, int_binit), |
| 79 | + FIELD(31, reserved_1bit), |
| 80 | + FIELD(32, reserved_3bits), |
| 81 | + FIELD(35, ext_binit), |
| 82 | + FIELD(36, response_parity), |
| 83 | + FIELD(37, bus_binit), |
| 84 | + FIELD(38, timeout_binit), |
| 85 | + FIELD(39, reserved_3bits), |
| 86 | + FIELD(42, hard_err), |
| 87 | + FIELD(43, ierr), |
| 88 | + FIELD(44, aerr), |
| 89 | + FIELD(45, uecc), |
| 90 | + FIELD(46, cecc), |
| 91 | + /* [47..54]: ECC syndrome */ |
| 92 | + FIELD(55, reserved_2bits), |
| 93 | + {}, |
| 94 | +}; |
| 95 | + |
| 96 | +static u64 bitmask(u64 i) |
| 97 | +{ |
| 98 | + u64 mask = 1; |
| 99 | + while (mask < i) |
| 100 | + mask = (mask << 1) | 1; |
| 101 | + return mask; |
| 102 | +} |
| 103 | + |
| 104 | +void core2_decode_model(u64 status) |
| 105 | +{ |
| 106 | + struct field *f; |
| 107 | + int linelen = 0; |
| 108 | + char *delim = ""; |
| 109 | + |
| 110 | + for (f = &fields[0]; f->str; f++) { |
| 111 | + u64 v = (status >> f->start_bit) & bitmask(f->stringlen - 1); |
| 112 | + char *s = NULL; |
| 113 | + if (v < f->stringlen) |
| 114 | + s = f->str[v]; |
| 115 | + if (!s) { |
| 116 | + if (v == 0) |
| 117 | + continue; |
| 118 | + char buf[60]; |
| 119 | + s = buf; |
| 120 | + snprintf(buf, sizeof buf, "<%u:%Lx>", f->start_bit, v); |
| 121 | + } |
| 122 | + int len = strlen(s); |
| 123 | + if (linelen + len > 75) { |
| 124 | + delim = "\n"; |
| 125 | + linelen = 0; |
| 126 | + } |
| 127 | + Wprintf("%s%s", delim, s); |
| 128 | + delim = " "; |
| 129 | + linelen += len + 1; |
| 130 | + } |
| 131 | + if (linelen > 0) |
| 132 | + Wprintf("\n"); |
| 133 | + if ((status >> 47) & 0xff) |
| 134 | + Wprintf("ECC syndrome: %Lx\n", (status >> 47) & 0xff); |
| 135 | +} |
0 commit comments