2 * UEFI Common Platform Error Record (CPER) support
4 * Copyright (C) 2010, Intel Corp.
5 * Author: Huang Ying <ying.huang@intel.com>
7 * CPER is the format used to describe platform hardware error by
8 * various APEI tables, such as ERST, BERT and HEST etc.
10 * For more information about CPER, please refer to Appendix N of UEFI
11 * Specification version 2.3.
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License version
15 * 2 as published by the Free Software Foundation.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/time.h>
30 #include <linux/cper.h>
31 #include <linux/acpi.h>
34 * CPER record ID need to be unique even after reboot, because record
35 * ID is used as index for ERST storage, while CPER records from
36 * multiple boot may co-exist in ERST.
38 u64
cper_next_record_id(void)
40 static atomic64_t seq
;
42 if (!atomic64_read(&seq
))
43 atomic64_set(&seq
, ((u64
)get_seconds()) << 32);
45 return atomic64_inc_return(&seq
);
47 EXPORT_SYMBOL_GPL(cper_next_record_id
);
49 int apei_estatus_check_header(const struct acpi_hest_generic_status
*estatus
)
51 if (estatus
->data_length
&&
52 estatus
->data_length
< sizeof(struct acpi_hest_generic_data
))
54 if (estatus
->raw_data_length
&&
55 estatus
->raw_data_offset
< sizeof(*estatus
) + estatus
->data_length
)
60 EXPORT_SYMBOL_GPL(apei_estatus_check_header
);
62 int apei_estatus_check(const struct acpi_hest_generic_status
*estatus
)
64 struct acpi_hest_generic_data
*gdata
;
65 unsigned int data_len
, gedata_len
;
68 rc
= apei_estatus_check_header(estatus
);
71 data_len
= estatus
->data_length
;
72 gdata
= (struct acpi_hest_generic_data
*)(estatus
+ 1);
73 while (data_len
> sizeof(*gdata
)) {
74 gedata_len
= gdata
->error_data_length
;
75 if (gedata_len
> data_len
- sizeof(*gdata
))
77 data_len
-= gedata_len
+ sizeof(*gdata
);
84 EXPORT_SYMBOL_GPL(apei_estatus_check
);