Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/27853
Change subject: [WIP]drivers/pc80/rtc: Add ACPI support ......................................................................
[WIP]drivers/pc80/rtc: Add ACPI support
Implement GET and SET ACPI methods that take a string to read and write the CMOS variables defined in cmos.layout.
Change-Id: I358fd745ebfcee6727890653c1f0efcdb8e870b2 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M src/drivers/pc80/rtc/Makefile.inc A src/drivers/pc80/rtc/acpi/rtc.asl M src/drivers/pc80/rtc/mc146818rtc.c M src/include/pc80/mc146818rtc.h M src/southbridge/intel/bd82x6x/acpi/lpc.asl M src/southbridge/intel/bd82x6x/lpc.c 6 files changed, 308 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/53/27853/1
diff --git a/src/drivers/pc80/rtc/Makefile.inc b/src/drivers/pc80/rtc/Makefile.inc index 998b7e7..fa4319e 100644 --- a/src/drivers/pc80/rtc/Makefile.inc +++ b/src/drivers/pc80/rtc/Makefile.inc @@ -5,6 +5,7 @@ postcar-$(CONFIG_DRIVERS_MC146818) += mc146818rtc.c romstage-$(CONFIG_DRIVERS_MC146818) += mc146818rtc.c ramstage-$(CONFIG_DRIVERS_MC146818) += mc146818rtc.c +ramstage-$(CONFIG_DRIVERS_MC146818) += mc146818rtc_ssdt.c smm-$(CONFIG_DRIVERS_MC146818) += mc146818rtc.c
ifeq ($(CONFIG_USE_OPTION_TABLE),y) diff --git a/src/drivers/pc80/rtc/acpi/rtc.asl b/src/drivers/pc80/rtc/acpi/rtc.asl new file mode 100644 index 0000000..37e03ba --- /dev/null +++ b/src/drivers/pc80/rtc/acpi/rtc.asl @@ -0,0 +1,299 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2012 The Chromium OS Authors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +Device (CMOS) +{ + Name (_HID, EISAID("PNP0B00")) + External (KEY, PkgObj) + + OperationRegion (OPR, SystemIO, 0x70, 0x04) + Field (OPR, ByteAcc, NoLock, Preserve) + { + IDX0, 7, + , 1, + DAT0, 8, + IDX1, 7, + , 1, + DAT1, 8, + } + + /* Mutex for byte read / write access */ + Mutex (MTX1, 3) + + /* + * Write byte to CMOS + * @param Arg0 Offset in CMOS (0 - 255) + * @param Arg1 Byte to write to CMOS + */ + Method (WRT, 2, Serialized, 3) + { + If (LLess(Arg1, 0x100)) + { + If (Acquire (^MTX1, 1000)) + { + Return () + } + + If (LGreater (Arg0, 0x7f)) + { + Store (Subtract(Arg0, 0x80), IDX1) + Store (Arg1, DAT1) + } + Else + { + Store (Arg0, IDX0) + Store (Arg1, DAT0) + } + + Release (^MTX1) + } + } + + /* + * Read byte from CMOS at Arg0 + * + * @Return: Returns the byte at given address + */ + Method (RD, 1, Serialized, 3) + { + Store (Zero, Local0) + + If (LLess (Arg0, 0x100)) + { + If (Acquire (^MTX1, 1000)) + { + Return (Zero) + } + + If (LGreater (Arg0, 0x7f)) + { + Store (Subtract(Arg0, 0x80), IDX1) + Store (DAT1, Local0) + } + Else + { + Store (Arg0, IDX0) + Store (DAT0, Local0) + } + + Release (^MTX1) + } + + Return (Local0) + } + + /* Mutex for bit read / write access */ + Mutex (MTX2, 2) + + /* + * Write bit to CMOS + * @param Arg0 Offset in CMOS (0 - 2047) + * @param Arg1 Bit to write to CMOS + */ + Method (WRTB, 2, Serialized, 2) + { + If (LLess(Arg0, 0x800)) + { + If (Acquire (^MTX2, 1000)) + { + Return () + } + + Store (Divide(Arg0, 8), Local0) + Store (RD (Local0), Local1) + CreateBitField (Local1, And(Arg0, 7), BIT) + + If (LGreater(Arg1, 0)) + { + Store (One, BIT) + } + Else + { + Store (Zero, BIT) + } + + WRT (Local0, Local1) + + Release (^MTX2) + } + } + + /* + * Read bit from CMOS + * @param Arg0 Offset in CMOS (0 - 2047) + * @return Ones on error + */ + Method (RDB, 1, Serialized, 2) + { + Store (Zero, Local0) + + If (LLess(Arg0, 0x800)) + { + If (Acquire (^MTX2, 1000)) + { + Return (Ones) + } + + Store (Divide(Arg0, 8), Local0) + Store (RD (Local0), Local1) + CreateBitField (Local1, And(Arg0, 7), BIT) + Store (BIT, Local0) + + Release (^MTX2) + } + + Return (Local0) + } + + /* + * Compare two buffers + * @param Arg0 Buffer + * @param Arg1 Buffer + * @return 1 if buffers match + */ + Method (CMP, 2) + { + If (LNotEqual (SizeOf (Arg1), SizeOf (Arg0))) + { + Return (0x00) + } + Store (0x00, Local0) + While (LLess (Local0, SizeOf (Arg1))) + { + If (LNotEqual (DerefOf (Index (Arg0, Local0)), DerefOf (Index (Arg1, Local0)))) + { + Return (0x00) + } + Increment (Local0) + } + Return (0x01) + } + + /* + * Find the CMOS option in the KEY lookup table and return the Package + * containing it. + * @param Arg0 String of CMOS to find + * @return index of Package in KEY, Ones on error + */ + Method (FIND, 1) + { + Store (Zero, Local0) + Store (ToString(Arg0), Local1) + While (LLess(Local0, SizeOf (KEY))) + { + Store (DerefOf (Index (KEY, Local0)), Local2) + Store (DerefOf (Index (Local2, 0)), Local3) + If (CMP(Local3, Local1)) + { + Return (Local0) + } + Increment (Local0) + } + Return (Ones) + } + + /* Mutex for CMOS option read / write access */ + Mutex (MTX3, 1) + + /* + * Patch Bit Arg1 of Object Arg0 with value Arg2 and return previous value + */ + Method (PATC, 3, Serialized, 1) + { + CreateBitField(Arg0, Arg1, BIT) + Store (BIT, Local0) + Store (Arg2, BIT) + Return (Local0) + } + + /* + * Read value to CMOS + * @param Arg0 String of CMOS to read + * @return Ones on error + */ + Method (SET, 2, Serialized, 1) + { + Store (FIND (Arg0), Local0) + If (LEqual(Local0, Ones)) + { + Return (Ones) + } + // Local0 Package at index Local0 + Store (DerefOf (Index (KEY, Local0)), Local0) + + // Local1 CMOS start bit + Store (DerefOf (Index (Local0, 1)), Local1) + // Local2 CMOS bit length + Store (DerefOf (Index (Local0, 2)), Local2) + // Local3 counter + Store (Zero, Local3) + + If (Acquire (^MTX3, 1000)) + { + Return (Ones) + } + + While (LLess(Local3, Local2)) + { + WRTB (Add(Local1, Local3), PATC(Arg1, Local3, 0)) + Increment (Local3) + } + Release (^MTX3) + + Return (Zero) + } + + /* + * Read value from CMOS + * @param Arg0 String of CMOS to write + * @return Buffer read + */ + Method (GET, 1, Serialized, 1) + { + Store (FIND (Arg0), Local0) + If (LEqual(Local0, Ones)) + { + Return (Ones) + } + // Local0 Package at index Local0 + Store (DerefOf (Index (KEY, Local0)), Local0) + + // Local1 CMOS start bit + Store (DerefOf (Index (Local0, 1)), Local1) + // Local2 CMOS bit length + Store (DerefOf (Index (Local0, 2)), Local2) + // Local3 counter + Store (Zero, Local3) + // Create buffer with length = DIV_ROUND_UP(Local2) + Store (Buffer (Divide (Add (Local2, 7), 8)) {0}, Local4) + + If (Acquire (^MTX3, 1000)) + { + Return (Ones) + } + + While (LLess(Local3, Local2)) + { + PATC (Local4, Local3, RDB (Add(Local1, Local3))) + Increment (Local3) + } + + Release (^MTX3) + + Return (Local4) + } +} diff --git a/src/drivers/pc80/rtc/mc146818rtc.c b/src/drivers/pc80/rtc/mc146818rtc.c index 34db4c3..1b5d0b7 100644 --- a/src/drivers/pc80/rtc/mc146818rtc.c +++ b/src/drivers/pc80/rtc/mc146818rtc.c @@ -240,7 +240,7 @@ return CB_SUCCESS; }
-static enum cb_err locate_cmos_layout(struct region_device *rdev) +enum cb_err locate_cmos_layout(struct region_device *rdev) { uint32_t cbfs_type = CBFS_COMPONENT_CMOS_LAYOUT; struct cbfsf fh; diff --git a/src/include/pc80/mc146818rtc.h b/src/include/pc80/mc146818rtc.h index 5d7497d..8f75b16 100644 --- a/src/include/pc80/mc146818rtc.h +++ b/src/include/pc80/mc146818rtc.h @@ -5,6 +5,7 @@
#include <arch/io.h> #include <types.h> +#include <cbfs.h>
#ifndef RTC_BASE_PORT #define RTC_BASE_PORT 0x70 @@ -256,6 +257,8 @@
#if IS_ENABLED(CONFIG_USE_OPTION_TABLE) void sanitize_cmos(void); +enum cb_err pc80_rtc_ssdt(const char *scope); +enum cb_err locate_cmos_layout(struct region_device *rdev); #else static inline void sanitize_cmos(void) {} #endif /* CONFIG_USE_OPTION_TABLE */ diff --git a/src/southbridge/intel/bd82x6x/acpi/lpc.asl b/src/southbridge/intel/bd82x6x/acpi/lpc.asl index 5204b29..cf16e4c 100644 --- a/src/southbridge/intel/bd82x6x/acpi/lpc.asl +++ b/src/southbridge/intel/bd82x6x/acpi/lpc.asl @@ -67,6 +67,7 @@ #include "irqlinks.asl"
#include "acpi/ec.asl" + #include "drivers/pc80/rtc/acpi/rtc.asl"
Device (DMAC) // DMA Controller { diff --git a/src/southbridge/intel/bd82x6x/lpc.c b/src/southbridge/intel/bd82x6x/lpc.c index d9e72b4..c17a3b8 100644 --- a/src/southbridge/intel/bd82x6x/lpc.c +++ b/src/southbridge/intel/bd82x6x/lpc.c @@ -893,9 +893,12 @@ { struct device *dev = dev_find_slot(0, PCI_DEVFN(0x1f, 0)); config_t *chip = dev->chip_info; + const char *path = acpi_device_path(dev);
intel_acpi_pcie_hotplug_generator(chip->pcie_hotplug_map, 8); intel_acpi_gen_def_acpi_pirq(dev); + if (IS_ENABLED(CONFIG_USE_OPTION_TABLE) && path != NULL) + pc80_rtc_ssdt(path); }
static void lpc_final(struct device *dev)