soc/amd/stoneyridge: Add ELOG to SMM
1. Add ELOG entries to smihandler.c 2. Add save_state utilities that are needed by southbridge_smi_gsmi BUG=b:65485690 Change-Id: I458babe1694f042215dd0e1c3277856e340de86f Signed-off-by: John E. Kabat Jr <john.kabat@scarletltd.com> Reviewed-on: https://review.coreboot.org/21728 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
		
				
					committed by
					
						
						Martin Roth
					
				
			
			
				
	
			
			
			
						parent
						
							0e022038fc
						
					
				
				
					commit
					7057a27a44
				
			@@ -24,6 +24,66 @@
 | 
				
			|||||||
#include <device/pci_def.h>
 | 
					#include <device/pci_def.h>
 | 
				
			||||||
#include <soc/smi.h>
 | 
					#include <soc/smi.h>
 | 
				
			||||||
#include <soc/southbridge.h>
 | 
					#include <soc/southbridge.h>
 | 
				
			||||||
 | 
					#include <elog.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* bits in smm_io_trap   */
 | 
				
			||||||
 | 
					#define SMM_IO_TRAP_PORT_OFFSET		16
 | 
				
			||||||
 | 
					#define SMM_IO_TRAP_PORT_ADDRESS_MASK	0xffff
 | 
				
			||||||
 | 
					#define SMM_IO_TRAP_RW			(1 << 0)
 | 
				
			||||||
 | 
					#define SMM_IO_TRAP_VALID		(1 << 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u16 get_io_address(u32 info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return ((info >> SMM_IO_TRAP_PORT_OFFSET) &
 | 
				
			||||||
 | 
							SMM_IO_TRAP_PORT_ADDRESS_MASK);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void *find_save_state(int cmd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int core;
 | 
				
			||||||
 | 
						amd64_smm_state_save_area_t *state;
 | 
				
			||||||
 | 
						u32 smm_io_trap;
 | 
				
			||||||
 | 
						u8 reg_al;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Check all nodes looking for the one that issued the IO */
 | 
				
			||||||
 | 
						for (core = 0; core < CONFIG_MAX_CPUS; core++) {
 | 
				
			||||||
 | 
							state = smm_get_save_state(core);
 | 
				
			||||||
 | 
							smm_io_trap = state->smm_io_trap_offset;
 | 
				
			||||||
 | 
							/* Check for Valid IO Trap Word (bit1==1) */
 | 
				
			||||||
 | 
							if (!(smm_io_trap & SMM_IO_TRAP_VALID))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							/* Make sure it was a write (bit0==0) */
 | 
				
			||||||
 | 
							if (smm_io_trap & SMM_IO_TRAP_RW)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							/* Check for APMC IO port */
 | 
				
			||||||
 | 
							if (pm_acpi_smi_cmd_port() != get_io_address(smm_io_trap))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							/* Check AL against the requested command */
 | 
				
			||||||
 | 
							reg_al = state->rax;
 | 
				
			||||||
 | 
							if (reg_al == cmd)
 | 
				
			||||||
 | 
								return state;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void southbridge_smi_gsmi(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 sub_command;
 | 
				
			||||||
 | 
						amd64_smm_state_save_area_t *io_smi;
 | 
				
			||||||
 | 
						u32 reg_ebx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						io_smi = find_save_state(ELOG_GSMI_APM_CNT);
 | 
				
			||||||
 | 
						if (!io_smi)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						/* Command and return value in EAX */
 | 
				
			||||||
 | 
						sub_command = (io_smi->rax >> 8) & 0xff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Parameter buffer in EBX */
 | 
				
			||||||
 | 
						reg_ebx = io_smi->rbx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* drivers/elog/gsmi.c */
 | 
				
			||||||
 | 
						io_smi->rax = gsmi_exec(sub_command, ®_ebx);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void sb_apmc_smi_handler(void)
 | 
					static void sb_apmc_smi_handler(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -41,6 +101,10 @@ static void sb_apmc_smi_handler(void)
 | 
				
			|||||||
		reg32 &= ~(1 << 0);	/* clear SCI_EN */
 | 
							reg32 &= ~(1 << 0);	/* clear SCI_EN */
 | 
				
			||||||
		outl(ACPI_PM1_CNT_BLK, reg32);
 | 
							outl(ACPI_PM1_CNT_BLK, reg32);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case ELOG_GSMI_APM_CNT:
 | 
				
			||||||
 | 
							if (IS_ENABLED(CONFIG_ELOG_GSMI))
 | 
				
			||||||
 | 
								southbridge_smi_gsmi();
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mainboard_smi_apmc(cmd);
 | 
						mainboard_smi_apmc(cmd);
 | 
				
			||||||
@@ -88,6 +152,10 @@ static void sb_slp_typ_handler(void)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (slp_typ >= ACPI_S3) {
 | 
						if (slp_typ >= ACPI_S3) {
 | 
				
			||||||
 | 
							/* Sleep Type Elog S3, S4, and S5 entry */
 | 
				
			||||||
 | 
							if (IS_ENABLED(CONFIG_ELOG_GSMI))
 | 
				
			||||||
 | 
								elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		wbinvd();
 | 
							wbinvd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		disable_all_smi_status();
 | 
							disable_all_smi_status();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user