Skip to content

Commit 9d635ba

Browse files
committed
Merge: Print AMD last reset reason into the kernel logs
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6996 JIRA: https://issues.redhat.com/browse/RHEL-89441 This patch series will will print the last reset reason into the kernel logs. This is very helpful information for finding patterns of problems so that they can be reproduced and debugged. Signed-off-by: David Arcari <darcari@redhat.com> Approved-by: Tony Camuso <tcamuso@redhat.com> Approved-by: Prarit Bhargava <prarit@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Augusto Caringi <acaringi@redhat.com>
2 parents 5f71d45 + 507df76 commit 9d635ba

File tree

11 files changed

+524
-43
lines changed

11 files changed

+524
-43
lines changed

Documentation/arch/x86/amd-debugging.rst

Lines changed: 368 additions & 0 deletions
Large diffs are not rendered by default.

Documentation/arch/x86/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ x86-specific Documentation
2424
intel-hfi
2525
intel-iommu
2626
intel_txt
27+
amd-debugging
2728
amd-memory-encryption
2829
amd_hsmp
2930
tdx

Documentation/arch/x86/resume.svg

Lines changed: 4 additions & 0 deletions
Loading

Documentation/arch/x86/suspend.svg

Lines changed: 4 additions & 0 deletions
Loading

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9150,7 +9150,7 @@ F: drivers/i2c/busses/i2c-i801.c
91509150
F: drivers/i2c/busses/i2c-isch.c
91519151
F: drivers/i2c/busses/i2c-nforce2-s4985.c
91529152
F: drivers/i2c/busses/i2c-nforce2.c
9153-
F: drivers/i2c/busses/i2c-piix4.c
9153+
F: drivers/i2c/busses/i2c-piix4.*
91549154
F: drivers/i2c/busses/i2c-sis5595.c
91559155
F: drivers/i2c/busses/i2c-sis630.c
91569156
F: drivers/i2c/busses/i2c-sis96x.c

arch/x86/include/asm/amd/fch.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _ASM_X86_AMD_FCH_H_
3+
#define _ASM_X86_AMD_FCH_H_
4+
5+
#define FCH_PM_BASE 0xFED80300
6+
7+
/* Register offsets from PM base: */
8+
#define FCH_PM_DECODEEN 0x00
9+
#define FCH_PM_DECODEEN_SMBUS0SEL GENMASK(20, 19)
10+
#define FCH_PM_SCRATCH 0x80
11+
#define FCH_PM_S5_RESET_STATUS 0xC0
12+
13+
#endif /* _ASM_X86_AMD_FCH_H_ */

arch/x86/kernel/cpu/amd.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/sched/clock.h>
1010
#include <linux/random.h>
1111
#include <linux/topology.h>
12+
#include <asm/amd/fch.h>
1213
#include <asm/processor.h>
1314
#include <asm/apic.h>
1415
#include <asm/cacheinfo.h>
@@ -1211,3 +1212,56 @@ void noinstr amd_clear_divider(void)
12111212
:: "a" (0), "d" (0), "r" (1));
12121213
}
12131214
EXPORT_SYMBOL_GPL(amd_clear_divider);
1215+
1216+
static const char * const s5_reset_reason_txt[] = {
1217+
[0] = "thermal pin BP_THERMTRIP_L was tripped",
1218+
[1] = "power button was pressed for 4 seconds",
1219+
[2] = "shutdown pin was tripped",
1220+
[4] = "remote ASF power off command was received",
1221+
[9] = "internal CPU thermal limit was tripped",
1222+
[16] = "system reset pin BP_SYS_RST_L was tripped",
1223+
[17] = "software issued PCI reset",
1224+
[18] = "software wrote 0x4 to reset control register 0xCF9",
1225+
[19] = "software wrote 0x6 to reset control register 0xCF9",
1226+
[20] = "software wrote 0xE to reset control register 0xCF9",
1227+
[21] = "ACPI power state transition occurred",
1228+
[22] = "keyboard reset pin KB_RST_L was tripped",
1229+
[23] = "internal CPU shutdown event occurred",
1230+
[24] = "system failed to boot before failed boot timer expired",
1231+
[25] = "hardware watchdog timer expired",
1232+
[26] = "remote ASF reset command was received",
1233+
[27] = "an uncorrected error caused a data fabric sync flood event",
1234+
[29] = "FCH and MP1 failed warm reset handshake",
1235+
[30] = "a parity error occurred",
1236+
[31] = "a software sync flood event occurred",
1237+
};
1238+
1239+
static __init int print_s5_reset_status_mmio(void)
1240+
{
1241+
unsigned long value;
1242+
void __iomem *addr;
1243+
int i;
1244+
1245+
if (!cpu_feature_enabled(X86_FEATURE_ZEN))
1246+
return 0;
1247+
1248+
addr = ioremap(FCH_PM_BASE + FCH_PM_S5_RESET_STATUS, sizeof(value));
1249+
if (!addr)
1250+
return 0;
1251+
1252+
value = ioread32(addr);
1253+
iounmap(addr);
1254+
1255+
for (i = 0; i < ARRAY_SIZE(s5_reset_reason_txt); i++) {
1256+
if (!(value & BIT(i)))
1257+
continue;
1258+
1259+
if (s5_reset_reason_txt[i]) {
1260+
pr_info("x86/amd: Previous system reset reason [0x%08lx]: %s\n",
1261+
value, s5_reset_reason_txt[i]);
1262+
}
1263+
}
1264+
1265+
return 0;
1266+
}
1267+
late_initcall(print_s5_reset_status_mmio);

drivers/i2c/busses/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,8 @@ config I2C_ISMT
196196

197197
config I2C_PIIX4
198198
tristate "Intel PIIX4 and compatible (ATI/AMD/Serverworks/Broadcom/SMSC)"
199-
depends on PCI
199+
depends on PCI && X86
200+
select I2C_SMBUS
200201
help
201202
If you say yes to this option, support will be included for the Intel
202203
PIIX4 family of mainboard I2C interfaces. Specifically, the following

drivers/i2c/busses/i2c-piix4.c

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,14 @@
2929
#include <linux/stddef.h>
3030
#include <linux/ioport.h>
3131
#include <linux/i2c.h>
32+
#include <linux/i2c-smbus.h>
3233
#include <linux/slab.h>
3334
#include <linux/dmi.h>
3435
#include <linux/acpi.h>
3536
#include <linux/io.h>
37+
#include <asm/amd/fch.h>
3638

37-
38-
/* PIIX4 SMBus address offsets */
39-
#define SMBHSTSTS (0 + piix4_smba)
40-
#define SMBHSLVSTS (1 + piix4_smba)
41-
#define SMBHSTCNT (2 + piix4_smba)
42-
#define SMBHSTCMD (3 + piix4_smba)
43-
#define SMBHSTADD (4 + piix4_smba)
44-
#define SMBHSTDAT0 (5 + piix4_smba)
45-
#define SMBHSTDAT1 (6 + piix4_smba)
46-
#define SMBBLKDAT (7 + piix4_smba)
47-
#define SMBSLVCNT (8 + piix4_smba)
48-
#define SMBSHDWCMD (9 + piix4_smba)
49-
#define SMBSLVEVT (0xA + piix4_smba)
50-
#define SMBSLVDAT (0xC + piix4_smba)
39+
#include "i2c-piix4.h"
5140

5241
/* count for request_region */
5342
#define SMBIOSIZE 9
@@ -69,7 +58,6 @@
6958
#define PIIX4_BYTE 0x04
7059
#define PIIX4_BYTE_DATA 0x08
7160
#define PIIX4_WORD_DATA 0x0C
72-
#define PIIX4_BLOCK_DATA 0x14
7361

7462
/* Multi-port constants */
7563
#define PIIX4_MAX_ADAPTERS 4
@@ -93,12 +81,11 @@
9381
#define SB800_PIIX4_PORT_IDX_MASK 0x06
9482
#define SB800_PIIX4_PORT_IDX_SHIFT 1
9583

96-
/* On kerncz and Hudson2, SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */
97-
#define SB800_PIIX4_PORT_IDX_KERNCZ 0x02
98-
#define SB800_PIIX4_PORT_IDX_MASK_KERNCZ 0x18
84+
/* SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */
85+
#define SB800_PIIX4_PORT_IDX_KERNCZ (FCH_PM_DECODEEN + 0x02)
86+
#define SB800_PIIX4_PORT_IDX_MASK_KERNCZ (FCH_PM_DECODEEN_SMBUS0SEL >> 16)
9987
#define SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ 3
10088

101-
#define SB800_PIIX4_FCH_PM_ADDR 0xFED80300
10289
#define SB800_PIIX4_FCH_PM_SIZE 8
10390

10491
/* insmod parameters */
@@ -145,7 +132,7 @@ static const struct dmi_system_id piix4_dmi_ibm[] = {
145132
.ident = "IBM",
146133
.matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
147134
},
148-
{ },
135+
{ }
149136
};
150137

151138
/*
@@ -159,11 +146,6 @@ static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = {
159146
};
160147
static const char *piix4_aux_port_name_sb800 = " port 1";
161148

162-
struct sb800_mmio_cfg {
163-
void __iomem *addr;
164-
bool use_mmio;
165-
};
166-
167149
struct i2c_piix4_adapdata {
168150
unsigned short smba;
169151

@@ -174,25 +156,24 @@ struct i2c_piix4_adapdata {
174156
struct sb800_mmio_cfg mmio_cfg;
175157
};
176158

177-
static int piix4_sb800_region_request(struct device *dev,
178-
struct sb800_mmio_cfg *mmio_cfg)
159+
int piix4_sb800_region_request(struct device *dev, struct sb800_mmio_cfg *mmio_cfg)
179160
{
180161
if (mmio_cfg->use_mmio) {
181162
void __iomem *addr;
182163

183-
if (!request_mem_region_muxed(SB800_PIIX4_FCH_PM_ADDR,
164+
if (!request_mem_region_muxed(FCH_PM_BASE,
184165
SB800_PIIX4_FCH_PM_SIZE,
185166
"sb800_piix4_smb")) {
186167
dev_err(dev,
187168
"SMBus base address memory region 0x%x already in use.\n",
188-
SB800_PIIX4_FCH_PM_ADDR);
169+
FCH_PM_BASE);
189170
return -EBUSY;
190171
}
191172

192-
addr = ioremap(SB800_PIIX4_FCH_PM_ADDR,
173+
addr = ioremap(FCH_PM_BASE,
193174
SB800_PIIX4_FCH_PM_SIZE);
194175
if (!addr) {
195-
release_mem_region(SB800_PIIX4_FCH_PM_ADDR,
176+
release_mem_region(FCH_PM_BASE,
196177
SB800_PIIX4_FCH_PM_SIZE);
197178
dev_err(dev, "SMBus base address mapping failed.\n");
198179
return -ENOMEM;
@@ -213,19 +194,20 @@ static int piix4_sb800_region_request(struct device *dev,
213194

214195
return 0;
215196
}
197+
EXPORT_SYMBOL_NS_GPL(piix4_sb800_region_request, PIIX4_SMBUS);
216198

217-
static void piix4_sb800_region_release(struct device *dev,
218-
struct sb800_mmio_cfg *mmio_cfg)
199+
void piix4_sb800_region_release(struct device *dev, struct sb800_mmio_cfg *mmio_cfg)
219200
{
220201
if (mmio_cfg->use_mmio) {
221202
iounmap(mmio_cfg->addr);
222-
release_mem_region(SB800_PIIX4_FCH_PM_ADDR,
203+
release_mem_region(FCH_PM_BASE,
223204
SB800_PIIX4_FCH_PM_SIZE);
224205
return;
225206
}
226207

227208
release_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE);
228209
}
210+
EXPORT_SYMBOL_NS_GPL(piix4_sb800_region_release, PIIX4_SMBUS);
229211

230212
static bool piix4_sb800_use_mmio(struct pci_dev *PIIX4_dev)
231213
{
@@ -535,10 +517,8 @@ static int piix4_setup_aux(struct pci_dev *PIIX4_dev,
535517
return piix4_smba;
536518
}
537519

538-
static int piix4_transaction(struct i2c_adapter *piix4_adapter)
520+
int piix4_transaction(struct i2c_adapter *piix4_adapter, unsigned short piix4_smba)
539521
{
540-
struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter);
541-
unsigned short piix4_smba = adapdata->smba;
542522
int temp;
543523
int result = 0;
544524
int timeout = 0;
@@ -589,7 +569,7 @@ static int piix4_transaction(struct i2c_adapter *piix4_adapter)
589569
result = -EIO;
590570
dev_dbg(&piix4_adapter->dev, "Bus collision! SMBus may be "
591571
"locked until next hard reset. (sorry!)\n");
592-
/* Clock stops and slave is stuck in mid-transmission */
572+
/* Clock stops and target is stuck in mid-transmission */
593573
}
594574

595575
if (temp & 0x04) {
@@ -610,6 +590,7 @@ static int piix4_transaction(struct i2c_adapter *piix4_adapter)
610590
inb_p(SMBHSTDAT1));
611591
return result;
612592
}
593+
EXPORT_SYMBOL_NS_GPL(piix4_transaction, PIIX4_SMBUS);
613594

614595
/* Return negative errno on error. */
615596
static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
@@ -674,7 +655,7 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
674655

675656
outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT);
676657

677-
status = piix4_transaction(adap);
658+
status = piix4_transaction(adap, piix4_smba);
678659
if (status)
679660
return status;
680661

@@ -763,7 +744,7 @@ static void piix4_imc_wakeup(void)
763744
release_region(KERNCZ_IMC_IDX, 2);
764745
}
765746

766-
static int piix4_sb800_port_sel(u8 port, struct sb800_mmio_cfg *mmio_cfg)
747+
int piix4_sb800_port_sel(u8 port, struct sb800_mmio_cfg *mmio_cfg)
767748
{
768749
u8 smba_en_lo, val;
769750

@@ -785,6 +766,7 @@ static int piix4_sb800_port_sel(u8 port, struct sb800_mmio_cfg *mmio_cfg)
785766

786767
return (smba_en_lo & piix4_port_mask_sb800);
787768
}
769+
EXPORT_SYMBOL_NS_GPL(piix4_sb800_port_sel, PIIX4_SMBUS);
788770

789771
/*
790772
* Handles access to multiple SMBus ports on the SB800.
@@ -982,6 +964,14 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
982964
return retval;
983965
}
984966

967+
/*
968+
* The AUX bus can not be probed as on some platforms it reports all
969+
* devices present and all reads return "0".
970+
* This would allow the ee1004 to be probed incorrectly.
971+
*/
972+
if (port == 0)
973+
i2c_register_spd(adap);
974+
985975
*padap = adap;
986976
return 0;
987977
}
@@ -1080,6 +1070,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
10801070
"", &piix4_main_adapters[0]);
10811071
if (retval < 0)
10821072
return retval;
1073+
piix4_adapter_count = 1;
10831074
}
10841075

10851076
/* Check for auxiliary SMBus on some AMD chipsets */

drivers/i2c/busses/i2c-piix4.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
/*
3+
* PIIX4/SB800 SMBus Interfaces
4+
*
5+
* Copyright (c) 2024, Advanced Micro Devices, Inc.
6+
* All Rights Reserved.
7+
*
8+
* Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
9+
* Sanket Goswami <Sanket.Goswami@amd.com>
10+
*/
11+
12+
#ifndef I2C_PIIX4_H
13+
#define I2C_PIIX4_H
14+
15+
#include <linux/types.h>
16+
17+
/* PIIX4 SMBus address offsets */
18+
#define SMBHSTSTS (0x00 + piix4_smba)
19+
#define SMBHSLVSTS (0x01 + piix4_smba)
20+
#define SMBHSTCNT (0x02 + piix4_smba)
21+
#define SMBHSTCMD (0x03 + piix4_smba)
22+
#define SMBHSTADD (0x04 + piix4_smba)
23+
#define SMBHSTDAT0 (0x05 + piix4_smba)
24+
#define SMBHSTDAT1 (0x06 + piix4_smba)
25+
#define SMBBLKDAT (0x07 + piix4_smba)
26+
#define SMBSLVCNT (0x08 + piix4_smba)
27+
#define SMBSHDWCMD (0x09 + piix4_smba)
28+
#define SMBSLVEVT (0x0A + piix4_smba)
29+
#define SMBSLVDAT (0x0C + piix4_smba)
30+
31+
/* PIIX4 constants */
32+
#define PIIX4_BLOCK_DATA 0x14
33+
34+
struct sb800_mmio_cfg {
35+
void __iomem *addr;
36+
bool use_mmio;
37+
};
38+
39+
int piix4_sb800_port_sel(u8 port, struct sb800_mmio_cfg *mmio_cfg);
40+
int piix4_transaction(struct i2c_adapter *piix4_adapter, unsigned short piix4_smba);
41+
int piix4_sb800_region_request(struct device *dev, struct sb800_mmio_cfg *mmio_cfg);
42+
void piix4_sb800_region_release(struct device *dev, struct sb800_mmio_cfg *mmio_cfg);
43+
44+
#endif /* I2C_PIIX4_H */

0 commit comments

Comments
 (0)