#!/bin/sh
# For this to work:
#  - io386 module needs to be enabled in board config (sandy/ivy/haswell know to work)
#  - coreboot config need to enable CONFIG_BOOTMEDIA_LOCK_CONTROLLER=y without enabling CONFIG_INTEL_CHIPSET_LOCKDOWN
#  - Heads is actually doing the CONFIG_INTEL_CHIPSET_LOCKDOWN equivalent here.
# TODO: If more platforms are able to enable CONFIG_INTEL_CHIPSET_LOCKDOWN in the future, have board config export APM_CNT and FIN_CODE and modify this script accordingly

#include ash shell functions (TRACE requires it)
. /etc/ash_functions

TRACE "Under /bin/lock_chip"
if [ "$CONFIG_FINALIZE_PLATFORM_LOCKING_PRESKYLAKE" = "y" ]; then
	APM_CNT=0xb2
	FIN_CODE=0xcb
fi

if [ -n "$APM_CNT" -a -n "$FIN_CODE" ]; then
	# SMI PR0 lockdown is implemented by Intel as part of the SMM Supervisor feature.
	# SMM Supervisor is a software component that runs in SMM and acts as a gatekeeper
	# for SMM access.
	#
	# It uses the processor’s memory protection and paging mechanisms to restrict what
	# SMM code can read and write. SMM Supervisor marks critical pages, such as its
	# own code, data, and page tables, as supervisor pages, which are only accessible
	# from the most privileged level (CPL0).
	#
	# It also marks the rest of the SMM memory as user pages, which are accessible
	# from any privilege level.
	#
	# This way, SMM Supervisor can isolate itself from other SMM code and enforce a policy
	# that states what resources the SMI handlers (the interrupt handlers that run in SMM)
	# require access to.
	#
	# SMI PR0 lockdown is enabled by setting a lock bit (FLOCKDN) in the SPI controller,
	# which prevents further changes to the SMM memory and configuration.
	# Once SMI PR0 lockdown is enabled, it cannot be disabled until the next system reset.
	# This ensures that malicious code cannot tamper with the SMM Supervisor or the SMI handlers
	# after the system boots.
	echo "Finalizing chipset Write Protection through SMI PR0 lockdown call"
	io386 -o b -b x $APM_CNT $FIN_CODE
else
	echo "NOT Finalizing chipset"
	echo "lock_chip called without valid APM_CNT and FIN_CODE defined under bin/lock_chip."
fi
