1*699cd480SApple OSS Distributions /* 2*699cd480SApple OSS Distributions * Copyright (c) 2013 Apple Inc. All rights reserved. 3*699cd480SApple OSS Distributions * 4*699cd480SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5*699cd480SApple OSS Distributions * 6*699cd480SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7*699cd480SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8*699cd480SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9*699cd480SApple OSS Distributions * compliance with the License. The rights granted to you under the License 10*699cd480SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11*699cd480SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12*699cd480SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13*699cd480SApple OSS Distributions * terms of an Apple operating system software license agreement. 14*699cd480SApple OSS Distributions * 15*699cd480SApple OSS Distributions * Please obtain a copy of the License at 16*699cd480SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17*699cd480SApple OSS Distributions * 18*699cd480SApple OSS Distributions * The Original Code and all software distributed under the License are 19*699cd480SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20*699cd480SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21*699cd480SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22*699cd480SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23*699cd480SApple OSS Distributions * Please see the License for the specific language governing rights and 24*699cd480SApple OSS Distributions * limitations under the License. 25*699cd480SApple OSS Distributions * 26*699cd480SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27*699cd480SApple OSS Distributions */ 28*699cd480SApple OSS Distributions 29*699cd480SApple OSS Distributions #pragma once 30*699cd480SApple OSS Distributions 31*699cd480SApple OSS Distributions #include <mach/kern_return.h> 32*699cd480SApple OSS Distributions #include <stdint.h> 33*699cd480SApple OSS Distributions #include <sys/cdefs.h> 34*699cd480SApple OSS Distributions #include <mach/vm_types.h> 35*699cd480SApple OSS Distributions 36*699cd480SApple OSS Distributions __BEGIN_DECLS 37*699cd480SApple OSS Distributions 38*699cd480SApple OSS Distributions #ifdef XNU_KERNEL_PRIVATE 39*699cd480SApple OSS Distributions extern ppnum_t *ecc_bad_pages; 40*699cd480SApple OSS Distributions extern uint32_t ecc_bad_pages_count; 41*699cd480SApple OSS Distributions 42*699cd480SApple OSS Distributions /* Counts for sysctls*/ 43*699cd480SApple OSS Distributions extern uint32_t vm_ecc_db_pages_count; 44*699cd480SApple OSS Distributions extern uint32_t vm_ecc_zero_pages_count; 45*699cd480SApple OSS Distributions extern uint32_t vm_ecc_panic_pages_count; 46*699cd480SApple OSS Distributions extern uint32_t vm_ecc_max_db_pages; 47*699cd480SApple OSS Distributions #endif 48*699cd480SApple OSS Distributions 49*699cd480SApple OSS Distributions /* Old ECC logging mechanism */ 50*699cd480SApple OSS Distributions 51*699cd480SApple OSS Distributions #define ECC_EVENT_INFO_DATA_ENTRIES 8 52*699cd480SApple OSS Distributions struct ecc_event { 53*699cd480SApple OSS Distributions uint8_t id; // ID of memory (e.g. L2C), platform-specific 54*699cd480SApple OSS Distributions uint8_t count; // Of uint64_t's used, starting at index 0 55*699cd480SApple OSS Distributions uint64_t data[ECC_EVENT_INFO_DATA_ENTRIES] __attribute__((aligned(8))); // Event-specific data 56*699cd480SApple OSS Distributions }; 57*699cd480SApple OSS Distributions 58*699cd480SApple OSS Distributions #ifdef KERNEL_PRIVATE 59*699cd480SApple OSS Distributions extern kern_return_t ecc_log_record_event(const struct ecc_event *ev); 60*699cd480SApple OSS Distributions #endif 61*699cd480SApple OSS Distributions 62*699cd480SApple OSS Distributions #ifdef XNU_KERNEL_PRIVATE 63*699cd480SApple OSS Distributions extern kern_return_t ecc_log_get_next_event(struct ecc_event *ev); 64*699cd480SApple OSS Distributions extern uint32_t ecc_log_get_correction_count(void); 65*699cd480SApple OSS Distributions #endif 66*699cd480SApple OSS Distributions 67*699cd480SApple OSS Distributions #define ECC_TESTING (DEVELOPMENT || DEBUG) 68*699cd480SApple OSS Distributions 69*699cd480SApple OSS Distributions /* New CoreAnalytics ECC logging mechanism */ 70*699cd480SApple OSS Distributions 71*699cd480SApple OSS Distributions #define VM_ECC_PAGE_POISON_GRANULE_SHIFT (7) 72*699cd480SApple OSS Distributions #define VM_ECC_PAGE_POISON_GRANULE (1 << VM_ECC_PAGE_POISON_GRANULE_SHIFT) 73*699cd480SApple OSS Distributions 74*699cd480SApple OSS Distributions /* Flags to describe ECC memory errors */ 75*699cd480SApple OSS Distributions __options_decl(ecc_flags_t, uint32_t, { 76*699cd480SApple OSS Distributions ECC_NONE = 0x00000000, 77*699cd480SApple OSS Distributions /* An error is correctable (1) or uncorrectable (0). */ 78*699cd480SApple OSS Distributions ECC_IS_CORRECTABLE = 0x00000001, 79*699cd480SApple OSS Distributions /* The database is corrupt. */ 80*699cd480SApple OSS Distributions ECC_DB_CORRUPTED = 0x00000002, 81*699cd480SApple OSS Distributions /* The error was injected for testing purposes. */ 82*699cd480SApple OSS Distributions ECC_IS_TEST_ERROR = 0x00000004, 83*699cd480SApple OSS Distributions /* Do not trigger a CA report, just record to the DB (for testing purposes) */ 84*699cd480SApple OSS Distributions ECC_DB_ONLY = 0x00000008, 85*699cd480SApple OSS Distributions }); 86*699cd480SApple OSS Distributions 87*699cd480SApple OSS Distributions /** 88*699cd480SApple OSS Distributions * ECC versions. 89*699cd480SApple OSS Distributions */ 90*699cd480SApple OSS Distributions __options_decl(ecc_version_t, uint32_t, { 91*699cd480SApple OSS Distributions ECC_V1, 92*699cd480SApple OSS Distributions 93*699cd480SApple OSS Distributions // Metadata 94*699cd480SApple OSS Distributions ECC_NUM_VERSIONS 95*699cd480SApple OSS Distributions }); 96*699cd480SApple OSS Distributions 97*699cd480SApple OSS Distributions /** 98*699cd480SApple OSS Distributions * ECC event descriptor. 99*699cd480SApple OSS Distributions * 100*699cd480SApple OSS Distributions * @note If a new ECC version has been added (e.g. future hardware must 101*699cd480SApple OSS Distributions * log new or different data) new fields should be appended to this struct to 102*699cd480SApple OSS Distributions * represent the new data. No fields should be deleted from this struct unless 103*699cd480SApple OSS Distributions * the field corresponds only to hardware that has been deprecated. 104*699cd480SApple OSS Distributions */ 105*699cd480SApple OSS Distributions typedef struct { 106*699cd480SApple OSS Distributions /* Version of this struct. */ 107*699cd480SApple OSS Distributions ecc_version_t version; 108*699cd480SApple OSS Distributions /* Flags describing the reported error. */ 109*699cd480SApple OSS Distributions ecc_flags_t flags; 110*699cd480SApple OSS Distributions /* Physical address of failure */ 111*699cd480SApple OSS Distributions uint64_t physaddr; 112*699cd480SApple OSS Distributions /* Number of CEs reported at physaddr */ 113*699cd480SApple OSS Distributions uint32_t ce_count; 114*699cd480SApple OSS Distributions /* Vendor ID */ 115*699cd480SApple OSS Distributions uint32_t vendor; 116*699cd480SApple OSS Distributions /* Reserved for future extension to report row, column, bank, etc. */ 117*699cd480SApple OSS Distributions uint32_t reserved[4]; 118*699cd480SApple OSS Distributions } ecc_event_t; 119*699cd480SApple OSS Distributions _Static_assert(sizeof(ecc_event_t) == 10 * sizeof(uint32_t), "ecc_event_t size must be updated in memory_error_notification.defs"); 120*699cd480SApple OSS Distributions 121*699cd480SApple OSS Distributions /** 122*699cd480SApple OSS Distributions * platform_error_handler_ecc_poll_t is the type of callback registered by the 123*699cd480SApple OSS Distributions * platform error handler that xnu can use to poll for ECC data. 124*699cd480SApple OSS Distributions */ 125*699cd480SApple OSS Distributions typedef int (*platform_error_handler_ecc_poll_t)(uint64_t *addrs, uint32_t *error_count); 126*699cd480SApple OSS Distributions kern_return_t kern_ecc_poll_register(platform_error_handler_ecc_poll_t poll_func, uint32_t max_errors); 127*699cd480SApple OSS Distributions 128*699cd480SApple OSS Distributions /* Flags to describe MCC memory errors */ 129*699cd480SApple OSS Distributions __options_decl(mcc_flags_t, uint32_t, { 130*699cd480SApple OSS Distributions MCC_NONE = 0x00000000, 131*699cd480SApple OSS Distributions MCC_IS_SINGLE_BIT = 0x00000001, 132*699cd480SApple OSS Distributions MCC_IS_MULTI_BIT = 0x00000002, 133*699cd480SApple OSS Distributions }); 134*699cd480SApple OSS Distributions 135*699cd480SApple OSS Distributions /** 136*699cd480SApple OSS Distributions * MCC ECC versions. 137*699cd480SApple OSS Distributions */ 138*699cd480SApple OSS Distributions typedef enum { 139*699cd480SApple OSS Distributions MCC_ECC_V1, 140*699cd480SApple OSS Distributions 141*699cd480SApple OSS Distributions // Metadata 142*699cd480SApple OSS Distributions MCC_ECC_NUM_VERSIONS 143*699cd480SApple OSS Distributions } mcc_ecc_version_t; 144*699cd480SApple OSS Distributions 145*699cd480SApple OSS Distributions /** 146*699cd480SApple OSS Distributions * MCC ECC event descriptor. 147*699cd480SApple OSS Distributions * 148*699cd480SApple OSS Distributions * @note If a new MCC ECC version has been added, because i.e. future hardware must log new or different data, 149*699cd480SApple OSS Distributions * new fields should be appended to this struct to represent the new data. No fields should be 150*699cd480SApple OSS Distributions * deleted from this struct unless the field corresponds only to hardware that has been deprecated. 151*699cd480SApple OSS Distributions */ 152*699cd480SApple OSS Distributions typedef struct { 153*699cd480SApple OSS Distributions /* Version of this struct. */ 154*699cd480SApple OSS Distributions mcc_ecc_version_t version; 155*699cd480SApple OSS Distributions /* Flags used to describe the error. */ 156*699cd480SApple OSS Distributions mcc_flags_t flags; 157*699cd480SApple OSS Distributions /* Interrupt status at the time of the MCC error. */ 158*699cd480SApple OSS Distributions uint32_t status; 159*699cd480SApple OSS Distributions /* AMCC on which the error occurred. */ 160*699cd480SApple OSS Distributions uint32_t amcc; 161*699cd480SApple OSS Distributions /* Plane of the AMCC on which the error occurred. */ 162*699cd480SApple OSS Distributions uint32_t plane; 163*699cd480SApple OSS Distributions /* MemCache error Bank of first one bit error. */ 164*699cd480SApple OSS Distributions uint32_t bank; 165*699cd480SApple OSS Distributions /* MemCache error Way of first one bit error. */ 166*699cd480SApple OSS Distributions uint32_t way; 167*699cd480SApple OSS Distributions /* MemCache error Index of first one bit error. */ 168*699cd480SApple OSS Distributions uint32_t index; 169*699cd480SApple OSS Distributions /* Indicates whether the error is in upper half cache line or lower half cache line. */ 170*699cd480SApple OSS Distributions uint32_t bit_off_cl; 171*699cd480SApple OSS Distributions /* MemCache one bit error bit offset of first one bit error with in half cache line. */ 172*699cd480SApple OSS Distributions uint32_t bit_off_within_hcl; 173*699cd480SApple OSS Distributions } mcc_ecc_event_t; 174*699cd480SApple OSS Distributions _Static_assert(sizeof(mcc_ecc_event_t) == 10 * sizeof(uint32_t), "ecc_event_t size must be updated in memory_error_notification.defs"); 175*699cd480SApple OSS Distributions 176*699cd480SApple OSS Distributions #if KERNEL_PRIVATE 177*699cd480SApple OSS Distributions 178*699cd480SApple OSS Distributions /** 179*699cd480SApple OSS Distributions * Logs any memory error. 180*699cd480SApple OSS Distributions * 181*699cd480SApple OSS Distributions * This will notify mmaintenanced of the error. The error 182*699cd480SApple OSS Distributions * will get added to a database of errors and sent to 183*699cd480SApple OSS Distributions * CoreAnalytics. If ECC_IS_CORRECTABLE == 0, 184*699cd480SApple OSS Distributions * the address will be added to dramecc.db and will 185*699cd480SApple OSS Distributions * be retired for the lifetime of the device. 186*699cd480SApple OSS Distributions * 187*699cd480SApple OSS Distributions * If it is too early in boot to send a notification directly 188*699cd480SApple OSS Distributions * to the deamon, the error will be added to an array to be serviced 189*699cd480SApple OSS Distributions * later by an mpsc_daemon_queue. 190*699cd480SApple OSS Distributions * 191*699cd480SApple OSS Distributions * If ECC_IS_CORRECTABLE flag is set with this function, it 192*699cd480SApple OSS Distributions * assumes one error. If caller wishes to report the CE count 193*699cd480SApple OSS Distributions * reported by hardware, use ecc_log_memory_error_ce(). 194*699cd480SApple OSS Distributions * 195*699cd480SApple OSS Distributions * @param physical_address address that the error occured on 196*699cd480SApple OSS Distributions * @param ecc_flags flags used to describe the error 197*699cd480SApple OSS Distributions * 198*699cd480SApple OSS Distributions * @returns KERN_SUCCESS if logging supported by hw, KERN_FAILURE if not 199*699cd480SApple OSS Distributions */ 200*699cd480SApple OSS Distributions extern kern_return_t ecc_log_memory_error(uint64_t physical_address, ecc_flags_t ecc_flags); 201*699cd480SApple OSS Distributions extern kern_return_t ecc_log_memory_error_internal(uint64_t physical_address, ecc_flags_t ecc_flags); 202*699cd480SApple OSS Distributions 203*699cd480SApple OSS Distributions /* 204*699cd480SApple OSS Distributions * Used to report delayed errors, scraped after ECC is enabled. 205*699cd480SApple OSS Distributions */ 206*699cd480SApple OSS Distributions extern kern_return_t ecc_log_memory_error_delayed(uint64_t physical_address, ecc_flags_t ecc_flags); 207*699cd480SApple OSS Distributions 208*699cd480SApple OSS Distributions /** 209*699cd480SApple OSS Distributions * Logs a correctable memory error. 210*699cd480SApple OSS Distributions * 211*699cd480SApple OSS Distributions * ECC_IS_CORRECTABLE is implied. Including this flag or not 212*699cd480SApple OSS Distributions * makes no difference for this function. 213*699cd480SApple OSS Distributions * 214*699cd480SApple OSS Distributions * @param physical_address address that the error occured on 215*699cd480SApple OSS Distributions * @param ecc_flags flags used to describe the error 216*699cd480SApple OSS Distributions * @param ce_count number of CEs occured on this page reported by HW 217*699cd480SApple OSS Distributions * 218*699cd480SApple OSS Distributions * @returns KERN_SUCCESS if logging supported by hw, KERN_FAILURE if not 219*699cd480SApple OSS Distributions */ 220*699cd480SApple OSS Distributions kern_return_t ecc_log_memory_error_ce(uint64_t physical_address, ecc_flags_t ecc_flags, uint32_t ce_count); 221*699cd480SApple OSS Distributions 222*699cd480SApple OSS Distributions /** 223*699cd480SApple OSS Distributions * Logs an MCC error. 224*699cd480SApple OSS Distributions * 225*699cd480SApple OSS Distributions * @param event Event to be logged 226*699cd480SApple OSS Distributions * @returns KERN_SUCCESS on success, KERN_FAILURE otherwise 227*699cd480SApple OSS Distributions */ 228*699cd480SApple OSS Distributions kern_return_t 229*699cd480SApple OSS Distributions mcc_log_memory_error(mcc_ecc_event_t event); 230*699cd480SApple OSS Distributions 231*699cd480SApple OSS Distributions #endif /* KERNEL_PRIVATE */ 232*699cd480SApple OSS Distributions 233*699cd480SApple OSS Distributions __END_DECLS 234