the following patch was just integrated into master:
commit a5ddac02f40e2ebe5606ea65e5c22c63baa2c1c9
Author: Paul Menzel <paulepanter(a)users.sourceforge.net>
Date: Sun Mar 3 10:56:15 2013 +0100
AMD CIMx SB800 boards: platform_cfg.h: Integrate Kconfig SATA Mode choice
Currently for Advansus A785E-I, ASRock E350M1 and ASUS M5A88-V
despite what is chosen in Kconfig »Chipset« menu item,
$ more .config
[…]
# CONFIG_ENABLE_IDE_COMBINED_MODE is not set
CONFIG_IDE_COMBINED_MODE=0x1
# CONFIG_SB800_SATA_IDE is not set
CONFIG_SB800_SATA_AHCI=y
# CONFIG_SB800_SATA_RAID is not set
CONFIG_SB800_SATA_MODE=0x2
[…]
the SATA controller is put into IDE mode.
$ lspci -nn | grep SATA
00:11.0 SATA controller [0106]: Advanced Micro Devices [AMD] nee ATI SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode] [1002:4390] (rev 40)
Commit »sb800: Add sata ahci/raid mode kconfig option«
(d4a0e7d0) [1] added the options above to configure the mode
using Kconfig and some SB800 boards were adapted already. For
example commit »persimmon: sb800 sata mode configure update«
(1386fa74) [2] did so for AMD Persimmon.
Doing the same by assigning the Kconfig variable to the value in
`platform_cfg.h` integrates this with the three remaining boards
listed above.
The patch is successfully tested with the ASRock E350M1.
$ lspci -nn | grep SATA
00:11.0 SATA controller [0106]: Advanced Micro Devices [AMD] nee ATI SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] [1002:4391] (rev 40)
[1] http://review.coreboot.org/225
[2] http://review.coreboot.org/227
Change-Id: I227257e2c8f04f18c27ff00fe62d42e372de67e4
Signed-off-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Reviewed-on: http://review.coreboot.org/2610
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martin.roth(a)se-eng.com>
Build-Tested: build bot (Jenkins) at Fri Mar 8 15:54:28 2013, giving +1
Reviewed-By: Martin Roth <martin.roth(a)se-eng.com> at Fri Mar 8 17:38:51 2013, giving +2
See http://review.coreboot.org/2610 for details.
-gerrit
the following patch was just integrated into master:
commit b55b74fc24afc5f64dd93dd402d44e9d453bb8ea
Author: Paul Menzel <paulepanter(a)users.sourceforge.net>
Date: Thu Mar 7 22:41:25 2013 +0100
AMD Persimmon: mainboard.c: Make comment generic to reduce difference
Replace »persimmon« by »board« in comment to keep `diff` output
between boards small.
Change-Id: Ieae2a63782c488ae35f22eb30f5b1049200d12c8
Signed-off-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Reviewed-on: http://review.coreboot.org/2611
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martin.roth(a)se-eng.com>
Build-Tested: build bot (Jenkins) at Thu Mar 7 23:19:08 2013, giving +1
Reviewed-By: Martin Roth <martin.roth(a)se-eng.com> at Fri Mar 8 17:40:34 2013, giving +2
See http://review.coreboot.org/2611 for details.
-gerrit
Kimarie Hoot (kimarie.hoot(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2607
-gerrit
commit 80ee5eb3aa93949698da6cb3db2faec90ab186e8
Author: Kimarie Hoot <kimarie.hoot(a)se-eng.com>
Date: Wed Mar 6 16:18:09 2013 -0700
AMD Inagua: Use SPD read code from F14 wrapper
Changes:
- Get rid of the inagua mainboard specific code and use the
platform generic function wrapper that was added in change
http://review.coreboot.org/#/c/2497/
AMD f14: Add SPD read functions to wrapper code
- Move DIMM addresses into devicetree.cb
- Add the ASF init that used to be in the SPD read code into
mainboard_enable()
Notes:
- The DIMM reads only happen in romstage, so the function is not
available in ramstage. Point the read-SPD callback to a generic
function in ramstage.
Change-Id: Id05227fcf18c6ab94ffe1beb50b533ab7b0535db
Signed-off-by: Kimarie Hoot <kimarie.hoot(a)se-eng.com>
---
src/mainboard/amd/inagua/BiosCallOuts.c | 8 +-
src/mainboard/amd/inagua/Makefile.inc | 2 -
src/mainboard/amd/inagua/devicetree.cb | 5 +
src/mainboard/amd/inagua/dimmSpd.c | 159 --------------------------------
src/mainboard/amd/inagua/dimmSpd.h | 63 -------------
src/mainboard/amd/inagua/mainboard.c | 11 ++-
6 files changed, 21 insertions(+), 227 deletions(-)
diff --git a/src/mainboard/amd/inagua/BiosCallOuts.c b/src/mainboard/amd/inagua/BiosCallOuts.c
index 23e020f..452a592 100644
--- a/src/mainboard/amd/inagua/BiosCallOuts.c
+++ b/src/mainboard/amd/inagua/BiosCallOuts.c
@@ -19,10 +19,10 @@
#include "agesawrapper.h"
#include "amdlib.h"
-#include "dimmSpd.h"
#include "BiosCallOuts.h"
#include "heapManager.h"
#include "SB800.h"
+#include <northbridge/amd/agesa/family14/dimmSpd.h>
STATIC BIOS_CALLOUT_STRUCT BiosCallouts[] =
{
@@ -419,7 +419,11 @@ AGESA_STATUS BiosReset (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
AGESA_STATUS BiosReadSpd (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
{
AGESA_STATUS Status;
- Status = AmdMemoryReadSPD (Func, Data, (AGESA_READ_SPD_PARAMS *)ConfigPtr);
+#ifdef __PRE_RAM__
+ Status = agesa_ReadSPD (Func, Data, ConfigPtr);
+#else
+ Status = AGESA_UNSUPPORTED;
+#endif
return Status;
}
diff --git a/src/mainboard/amd/inagua/Makefile.inc b/src/mainboard/amd/inagua/Makefile.inc
index b1a3014..17443bc 100644
--- a/src/mainboard/amd/inagua/Makefile.inc
+++ b/src/mainboard/amd/inagua/Makefile.inc
@@ -26,13 +26,11 @@ endif
romstage-y += buildOpts.c
romstage-y += agesawrapper.c
-romstage-y += dimmSpd.c
romstage-y += BiosCallOuts.c
romstage-y += PlatformGnbPcie.c
ramstage-y += buildOpts.c
ramstage-y += agesawrapper.c
-ramstage-y += dimmSpd.c
ramstage-y += BiosCallOuts.c
ramstage-y += PlatformGnbPcie.c
diff --git a/src/mainboard/amd/inagua/devicetree.cb b/src/mainboard/amd/inagua/devicetree.cb
index 3d8ccb4..67c3a1a 100644
--- a/src/mainboard/amd/inagua/devicetree.cb
+++ b/src/mainboard/amd/inagua/devicetree.cb
@@ -86,6 +86,11 @@ chip northbridge/amd/agesa/family14/root_complex
device pci 18.5 on end
device pci 18.6 on end
device pci 18.7 on end
+
+ register "spdAddrLookup" = "
+ {
+ { {0xA0, 0xA2}, {0x00, 0x00}, }, // socket 0 - Channel 0 & 1 - 8-bit SPD addresses
+ }"
end #chip northbridge/amd/agesa/family14 # CPU side of HT root complex
end #domain
end #northbridge/amd/agesa/family14/root_complex
diff --git a/src/mainboard/amd/inagua/dimmSpd.c b/src/mainboard/amd/inagua/dimmSpd.c
deleted file mode 100644
index 730a2d0..0000000
--- a/src/mainboard/amd/inagua/dimmSpd.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 Advanced Micro Devices, Inc.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "Porting.h"
-#include "AGESA.h"
-#include "amdlib.h"
-#include "OEM.h" /* SMBUS0_BASE_ADDRESS */
-
-AGESA_STATUS AmdMemoryReadSPD (UINT32 unused1, UINT32 unused2, AGESA_READ_SPD_PARAMS *info);
-#define DIMENSION(array)(sizeof (array)/ sizeof (array [0]))
-
-/*#pragma optimize ("", off) // for source level debug
- *---------------------------------------------------------------------------
- *
- * SPD address table - porting required
- */
-
-static const UINT8 spdAddressLookup [1] [2] [2] = // socket, channel, dimm
-{
- // socket 0
- {
- {0xA0, 0xA2}, // channel 0 dimms
- {0x00, 0x00}, // channel 1 dimms
- },
-};
-
-/*-----------------------------------------------------------------------------
- *
- * readSmbusByteData - read a single SPD byte from any offset
- */
-
-static int readSmbusByteData (int iobase, int address, char *buffer, int offset)
-{
- unsigned int status;
- UINT64 limit;
-
- address |= 1; // set read bit
-
- __outbyte (iobase + 0, 0xFF); // clear error status
- __outbyte (iobase + 1, 0x1F); // clear error status
- __outbyte (iobase + 3, offset); // offset in eeprom
- __outbyte (iobase + 4, address); // slave address and read bit
- __outbyte (iobase + 2, 0x48); // read byte command
-
- // time limit to avoid hanging for unexpected error status (should never happen)
- limit = __rdtsc () + 2000000000 / 10;
- for (;;) {
- status = __inbyte (iobase);
- if (__rdtsc () > limit) break;
- if ((status & 2) == 0) continue; // SMBusInterrupt not set, keep waiting
- if ((status & 1) == 1) continue; // HostBusy set, keep waiting
- break;
- }
-
- buffer [0] = __inbyte (iobase + 5);
- if (status == 2) status = 0; // check for done with no errors
- return status;
-}
-
-/*-----------------------------------------------------------------------------
- *
- * readSmbusByte - read a single SPD byte from the default offset
- * this function is faster function readSmbusByteData
- */
-
-static int readSmbusByte (int iobase, int address, char *buffer)
-{
- unsigned int status;
- UINT64 limit;
-
- __outbyte (iobase + 0, 0xFF); // clear error status
- __outbyte (iobase + 2, 0x44); // read command
-
- // time limit to avoid hanging for unexpected error status
- limit = __rdtsc () + 2000000000 / 10;
- for (;;) {
- status = __inbyte (iobase);
- if (__rdtsc () > limit) break;
- if ((status & 2) == 0) continue; // SMBusInterrupt not set, keep waiting
- if ((status & 1) == 1) continue; // HostBusy set, keep waiting
- break;
- }
-
- buffer [0] = __inbyte (iobase + 5);
- if (status == 2) status = 0; // check for done with no errors
- return status;
-}
-
-/*---------------------------------------------------------------------------
- *
- * readspd - Read one or more SPD bytes from a DIMM.
- * Start with offset zero and read sequentially.
- * Optimization relies on autoincrement to avoid
- * sending offset for every byte.
- * Reads 128 bytes in 7-8 ms at 400 KHz.
- */
-
-static int readspd (int iobase, int SmbusSlaveAddress, char *buffer, int count)
-{
- int index, error;
-
- /* read the first byte using offset zero */
- error = readSmbusByteData (iobase, SmbusSlaveAddress, buffer, 0);
- if (error) return error;
-
- /* read the remaining bytes using auto-increment for speed */
- for (index = 1; index < count; index++) {
- error = readSmbusByte (iobase, SmbusSlaveAddress, &buffer [index]);
- if (error) return error;
- }
-
- return 0;
-}
-
-static void writePmReg (int reg, int data)
-{
- __outbyte (0xCD6, reg);
- __outbyte (0xCD7, data);
-}
-
-static void setupFch (int ioBase)
-{
- writePmReg (0x2D, ioBase >> 8);
- writePmReg (0x2C, ioBase | 1);
- writePmReg (0x29, 0x80);
- writePmReg (0x28, 0x61);
- __outbyte (ioBase + 0x0E, 66000000 / 400000 / 4); // set SMBus clock to 400 KHz
-}
-
-AGESA_STATUS AmdMemoryReadSPD (UINT32 unused1, UINT32 unused2, AGESA_READ_SPD_PARAMS *info)
-{
- int spdAddress, ioBase;
-
- if (info->SocketId >= DIMENSION (spdAddressLookup )) return AGESA_ERROR;
- if (info->MemChannelId >= DIMENSION (spdAddressLookup[0] )) return AGESA_ERROR;
- if (info->DimmId >= DIMENSION (spdAddressLookup[0][0])) return AGESA_ERROR;
-
- spdAddress = spdAddressLookup [info->SocketId] [info->MemChannelId] [info->DimmId];
- if (spdAddress == 0) return AGESA_ERROR;
- ioBase = SMBUS0_BASE_ADDRESS;
- setupFch (ioBase);
- return readspd (ioBase, spdAddress, (void *) info->Buffer, 128);
-}
diff --git a/src/mainboard/amd/inagua/dimmSpd.h b/src/mainboard/amd/inagua/dimmSpd.h
deleted file mode 100644
index 81ab02e..0000000
--- a/src/mainboard/amd/inagua/dimmSpd.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 Advanced Micro Devices, Inc.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*----------------------------------------------------------------------------------------
- * M O D U L E S U S E D
- *----------------------------------------------------------------------------------------
- */
-
-#ifndef _DIMMSPD_H_
-#define _DIMMSPD_H_
-
-#include "Porting.h"
-#include "AGESA.h"
-
-/*----------------------------------------------------------------------------------------
- * D E F I N I T I O N S A N D M A C R O S
- *----------------------------------------------------------------------------------------
- */
-
-/*----------------------------------------------------------------------------------------
- * T Y P E D E F S A N D S T R U C T U R E S
- *----------------------------------------------------------------------------------------
- */
-
-/*----------------------------------------------------------------------------------------
- * P R O T O T Y P E S O F L O C A L F U N C T I O N S
- *----------------------------------------------------------------------------------------
- */
-
-/*----------------------------------------------------------------------------------------
- * E X P O R T E D F U N C T I O N S
- *----------------------------------------------------------------------------------------
- */
-
-AGESA_STATUS
-AmdMemoryReadSPD (
- IN UINT32 Func,
- IN UINT32 Data,
- IN OUT AGESA_READ_SPD_PARAMS *SpdData
- );
-
-/*---------------------------------------------------------------------------------------
- * L O C A L F U N C T I O N S
- *---------------------------------------------------------------------------------------
- */
-
-#endif
diff --git a/src/mainboard/amd/inagua/mainboard.c b/src/mainboard/amd/inagua/mainboard.c
index 8907ebb..8e92d6a 100644
--- a/src/mainboard/amd/inagua/mainboard.c
+++ b/src/mainboard/amd/inagua/mainboard.c
@@ -24,7 +24,7 @@
#include <cpu/x86/msr.h>
#include <cpu/amd/mtrr.h>
#include <device/pci_def.h>
-//#include <southbridge/amd/sb800/sb800.h>
+#include <southbridge/amd/sb800/sb800.h>
#include "SBPLATFORM.h" /* Platfrom Specific Definitions */
void set_pcie_reset(void);
@@ -79,6 +79,15 @@ static void mainboard_enable(device_t dev)
/* Inagua mainboard specific setting */
set_pcie_dereset();
+
+ /*
+ * Initialize ASF registers to an arbitrary address because someone
+ * long ago set things up this way inside the SPD read code. The
+ * SPD read code has been made generic and moved out of the board
+ * directory, so the ASF init is being done here.
+ */
+ pm_iowrite(0x29, 0x80);
+ pm_iowrite(0x28, 0x61);
}
struct chip_operations mainboard_ops = {
the following patch was just integrated into master:
commit 9ca4f51bd441638f177a18a744c78c3655988a4d
Author: Kimarie Hoot <kimarie.hoot(a)se-eng.com>
Date: Thu Mar 7 09:10:29 2013 -0700
AMD Union Station: Use SPD read code from F14 wrapper
Changes:
- Get rid of the union_station mainboard specific code and
use the platform generic function wrapper that was added
in change http://review.coreboot.org/#/c/2497/
AMD f14: Add SPD read functions to wrapper code
- Move DIMM addresses into devicetree.cb
- Add the ASF init that used to be in the SPD read code into
mainboard_enable()
Notes:
- The DIMM reads only happen in romstage, so the function is not
available in ramstage. Point the read-SPD callback to a generic
function in ramstage.
Change-Id: I19d6b0d674b67294519383f80928471b37da1e14
Signed-off-by: Kimarie Hoot <kimarie.hoot(a)se-eng.com>
Reviewed-on: http://review.coreboot.org/2609
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martin.roth(a)se-eng.com>
Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Build-Tested: build bot (Jenkins) at Fri Mar 8 18:34:41 2013, giving +1
Reviewed-By: Martin Roth <martin.roth(a)se-eng.com> at Fri Mar 8 19:00:50 2013, giving +2
Reviewed-By: Paul Menzel <paulepanter(a)users.sourceforge.net> at Fri Mar 8 22:18:50 2013, giving +2
See http://review.coreboot.org/2609 for details.
-gerrit
the following patch was just integrated into master:
commit a2f8eb98f5dcc9551a6cfc0ce83eee3eb8fb564f
Author: Kimarie Hoot <kimarie.hoot(a)se-eng.com>
Date: Thu Mar 7 08:54:36 2013 -0700
AMD South Station: Use SPD read code from F14 wrapper
Changes:
- Get rid of the south_station mainboard specific code and
use the platform generic function wrapper that was added
in change http://review.coreboot.org/#/c/2497/
AMD f14: Add SPD read functions to wrapper code
- Move DIMM addresses into devicetree.cb
- Add the ASF init that used to be in the SPD read code into
mainboard_enable()
Notes:
- The DIMM reads only happen in romstage, so the function is not
available in ramstage. Point the read-SPD callback to a generic
function in ramstage.
Change-Id: If4291d25ea81bf375f55b64c07c223a847a211d0
Signed-off-by: Kimarie Hoot <kimarie.hoot(a)se-eng.com>
Reviewed-on: http://review.coreboot.org/2608
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martin.roth(a)se-eng.com>
Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Build-Tested: build bot (Jenkins) at Fri Mar 8 18:44:30 2013, giving +1
Reviewed-By: Martin Roth <martin.roth(a)se-eng.com> at Fri Mar 8 18:59:42 2013, giving +2
Reviewed-By: Paul Menzel <paulepanter(a)users.sourceforge.net> at Fri Mar 8 22:16:30 2013, giving +2
See http://review.coreboot.org/2608 for details.
-gerrit
the following patch was just integrated into master:
commit b21eaa74a656fa33f943f76ea0c53ca8374760f6
Author: Ronald G. Minnich <rminnich(a)gmail.com>
Date: Thu Mar 7 15:23:45 2013 -0800
ARMV7 and Google/Snow: Add exception support code to the ramstage
This is previously used exception code from libpayload.
On startup it installs and then tests an exception handler.
The test is an unaligned memory operation.
Yes, we've seen what might be exceptions in the ramstage, and
it makes sense to handle them. This code is identical in structure
and operation to the previously committed payload exception handler,
though we reserve the right to change it as circumstances require.
The remaining question is whether we need it in romstage.
Change-Id: I24484686c33c9757af8ba171ebae9773828fb69d
Signed-off-by: Gabe Black <gabeblack(a)google.com>
Signed-off-by: Ronald G. Minnich <rminnich(a)gmail.com>
Reviewed-on: http://review.coreboot.org/2614
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix(a)chromium.org>
Build-Tested: build bot (Jenkins) at Fri Mar 8 21:27:38 2013, giving +1
Reviewed-By: David Hendricks <dhendrix(a)chromium.org> at Fri Mar 8 21:30:06 2013, giving +2
See http://review.coreboot.org/2614 for details.
-gerrit
AGESA code have two mechanisms to run tasks on AP cores. The first one is used before "Relinquish control of APs", and the second one is used after it.
I doubt in the second one, cause it is used only in probe filter initialization (and now OS can't boot with this feature)
I walked "RunLateApTaskOnAllAPs(..)" function [the second mechanism] step by step and didn't find of how system transmits task poinetrs to APs. It seems like code executes on BSC (boot strap core) as many times as APs present in system.
AGESA code is very complicated, we traveles a lot to final function, that is located in the same file. If someone look at code, I drew little scheme of this travel.
Here it is: http://tinypic.com/r/25sx7p3/6
Maybe i'am missing something, but I can't see the point, where agesa transmits pointers to APs.
Also i put LibAmdMsrRead function in DisableAllCaches function and read MSRs containing NodeId and BSC bits. And for all cases of its execution DisableAllCaches prints that NodeId=0 and BSC=1. If i didn't mess up, it proves my theory above.
So... How does "RunLateApTaskOnAllAPs(..)" work?
______________
Aladyshev Konstantin
Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2614
-gerrit
commit 6df801330002ead50bc12edd118159a57257ce90
Author: Ronald G. Minnich <rminnich(a)gmail.com>
Date: Thu Mar 7 15:23:45 2013 -0800
ARMV7 and Google/Snow: Add exception support code to the ramstage
This is previously used exception code from libpayload.
On startup it installs and then tests an exception handler.
The test is an unaligned memory operation.
Yes, we've seen what might be exceptions in the ramstage, and
it makes sense to handle them. This code is identical in structure
and operation to the previously committed payload exception handler,
though we reserve the right to change it as circumstances require.
The remaining question is whether we need it in romstage.
Change-Id: I24484686c33c9757af8ba171ebae9773828fb69d
Signed-off-by: Gabe Black <gabeblack(a)google.com>
Signed-off-by: Ronald G. Minnich <rminnich(a)gmail.com>
---
src/arch/armv7/Makefile.inc | 3 +
src/arch/armv7/exception.c | 158 ++++++++++++++++++++++++++++++++
src/arch/armv7/exception_asm.S | 115 +++++++++++++++++++++++
src/arch/armv7/include/arch/exception.h | 38 ++++++++
src/mainboard/google/snow/ramstage.c | 5 +-
5 files changed, 318 insertions(+), 1 deletion(-)
diff --git a/src/arch/armv7/Makefile.inc b/src/arch/armv7/Makefile.inc
index 0595ae2..e708f6d 100644
--- a/src/arch/armv7/Makefile.inc
+++ b/src/arch/armv7/Makefile.inc
@@ -158,6 +158,9 @@ $(obj)/mainboard/$(MAINBOARDDIR)/romstage.pre.inc: $(src)/mainboard/$(MAINBOARDD
$(CC) -MMD $(CFLAGS) -D__PRE_RAM__ -I$(src) -I. -I$(obj) -c -S $< -o $@
# Things that appear in every board
+ramstage-y += exception.c
+ramstage-y += exception_asm.S
+
romstage-srcs += $(objgenerated)/crt0.s
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/mainboard.c
ifeq ($(CONFIG_GENERATE_PIRQ_TABLE),y)
diff --git a/src/arch/armv7/exception.c b/src/arch/armv7/exception.c
new file mode 100644
index 0000000..14f8216
--- /dev/null
+++ b/src/arch/armv7/exception.c
@@ -0,0 +1,158 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <console/console.h>
+#include <arch/exception.h>
+#include <stdint.h>
+
+void exception_test(void);
+
+static int test_abort;
+
+void exception_undefined_instruction(uint32_t *);
+void exception_software_interrupt(uint32_t *);
+void exception_prefetch_abort(uint32_t *);
+void exception_data_abort(uint32_t *);
+void exception_not_used(uint32_t *);
+void exception_irq(uint32_t *);
+void exception_fiq(uint32_t *);
+
+static void print_regs(uint32_t *regs)
+{
+ int i;
+ /* Don't print the link register and stack pointer since we don't have their
+ * actual value. They are hidden by the 'shadow' registers provided
+ * by the trap hardware.
+ */
+ for (i = 0; i < 16; i++) {
+ if (i == 15)
+ printk(BIOS_ERR, "PC");
+ else if (i == 14)
+ continue; /* LR */
+ else if (i == 13)
+ continue; /* SP */
+ else if (i == 12)
+ printk(BIOS_ERR, "IP");
+ else
+ printk(BIOS_ERR, "R%d", i);
+ printk(BIOS_ERR, " = 0x%08x\n", regs[i]);
+ }
+}
+
+void exception_undefined_instruction(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _undefined_instruction\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_software_interrupt(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _software_interrupt\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_prefetch_abort(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _prefetch_abort\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_data_abort(uint32_t *regs)
+{
+ if (test_abort) {
+ regs[15] = regs[0];
+ return;
+ } else {
+ printk(BIOS_ERR, "exception _data_abort\n");
+ print_regs(regs);
+ }
+ die("exception");
+}
+
+void exception_not_used(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _not_used\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_irq(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _irq\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_fiq(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _fiq\n");
+ print_regs(regs);
+ die("exception");
+}
+
+static inline uint32_t get_sctlr(void)
+{
+ uint32_t val;
+ asm("mrc p15, 0, %0, c1, c0, 0" : "=r" (val));
+ return val;
+}
+
+static inline void set_sctlr(uint32_t val)
+{
+ asm volatile("mcr p15, 0, %0, c1, c0, 0" :: "r" (val));
+ asm volatile("" ::: "memory");
+}
+
+void exception_init(void)
+{
+ static const uint32_t sctlr_te = (0x1 << 30);
+ static const uint32_t sctlr_v = (0x1 << 13);
+ static const uint32_t sctlr_a = (0x1 << 1);
+
+ uint32_t sctlr = get_sctlr();
+ /* Handle exceptions in ARM mode. */
+ sctlr &= ~sctlr_te;
+ /* Set V=0 in SCTLR so VBAR points to the exception vector table. */
+ sctlr &= ~sctlr_v;
+ /* Enforce alignment. */
+ sctlr |= sctlr_a;
+ set_sctlr(sctlr);
+
+ extern uint32_t exception_table[];
+ set_vbar((uintptr_t)exception_table);
+
+ test_abort = 1;
+ printk(BIOS_ERR, "Testing exceptions\n");
+ exception_test();
+ test_abort = 0;
+ printk(BIOS_ERR, "Testing exceptions: DONE\n");
+}
diff --git a/src/arch/armv7/exception_asm.S b/src/arch/armv7/exception_asm.S
new file mode 100644
index 0000000..e46f4bc
--- /dev/null
+++ b/src/arch/armv7/exception_asm.S
@@ -0,0 +1,115 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+exception_stack:
+ .align 5
+ .skip 0x2000, 0xa5
+exception_stack_end:
+ .word exception_stack_end
+
+exception_handler:
+ .word 0
+
+
+ .align 6
+ .arm
+ .global exception_table
+exception_table:
+ b 1f
+ b 2f
+ b 3f
+ b 4f
+ b 5f
+ b 6f
+ b 7f
+ b 8f
+
+1:
+ ldr sp, _not_used
+ b exception_common
+2:
+ ldr sp, _undefined_instruction
+ b exception_common
+3:
+ ldr sp, _software_interrupt
+ b exception_common
+4:
+ ldr sp, _prefetch_abort
+ b exception_common
+5:
+ ldr sp, _data_abort
+ b exception_common
+6:
+ ldr sp, _not_used
+ b exception_common
+7:
+ ldr sp, _irq
+ b exception_common
+8:
+ ldr sp, _fiq
+ b exception_common
+
+exception_common:
+ str sp, exception_handler
+ ldr sp, exception_stack_end
+ push { lr }
+ sub sp, sp, $8
+ push { r0 - r12 }
+ mov r0, sp
+ mov lr, pc
+ ldr pc, exception_handler
+ pop { r0 - r12 }
+ add sp, sp, $8
+ ldm sp!, { pc }^
+
+
+_undefined_instruction: .word exception_undefined_instruction
+_software_interrupt: .word exception_software_interrupt
+_prefetch_abort: .word exception_prefetch_abort
+_data_abort: .word exception_data_abort
+_not_used: .word exception_not_used
+_irq: .word exception_irq
+_fiq: .word exception_fiq
+
+ .thumb
+ .global set_vbar
+ .thumb_func
+set_vbar:
+ mcr p15, 0, r0, c12, c0, 0
+ bx lr
+
+ .global exception_test
+ .thumb_func
+exception_test:
+ mov r1, $1
+ mov r0, pc
+ add r0, $3
+ ldr r1, [r1]
+ bx lr
+
diff --git a/src/arch/armv7/include/arch/exception.h b/src/arch/armv7/include/arch/exception.h
new file mode 100644
index 0000000..57076bd
--- /dev/null
+++ b/src/arch/armv7/include/arch/exception.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ARCH_EXCEPTION_H
+#define _ARCH_EXCEPTION_H
+
+#include <stdint.h>
+
+void exception_init(void);
+void set_vbar(uint32_t vbar);
+
+#endif
diff --git a/src/mainboard/google/snow/ramstage.c b/src/mainboard/google/snow/ramstage.c
index 9f259ef..be5216f 100644
--- a/src/mainboard/google/snow/ramstage.c
+++ b/src/mainboard/google/snow/ramstage.c
@@ -19,6 +19,7 @@
#include <console/console.h>
#include <cbmem.h>
+#include <arch/exception.h>
#include <cpu/samsung/exynos5250/clk.h>
#include <cpu/samsung/exynos5250/power.h>
@@ -26,8 +27,10 @@ void hardwaremain(int boot_complete);
void main(void)
{
console_init();
- printk(BIOS_INFO, "hello from ramstage\n");
+ printk(BIOS_INFO, "hello from ramstage; now with deluxe exception handling.\n");
+ /* this is going to move, but we must have it now and we're not sure where */
+ exception_init();
/* place at top of physical memory */
high_tables_size = CONFIG_COREBOOT_TABLES_SIZE;
high_tables_base = CONFIG_SYS_SDRAM_BASE +
Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2614
-gerrit
commit 7f91aa109455f7c6005e6c9764fba74b5f3baa0f
Author: Ronald G. Minnich <rminnich(a)gmail.com>
Date: Thu Mar 7 15:23:45 2013 -0800
ARMV7 and Google/Snow: Add exception support code to the ramstage
This is previously used exception code from libpayload.
On startup it installs and then tests an exception handler.
The test is an unaligned memory operation.
Yes, we've seen what might be exceptions in the ramstage, and
it makes sense to handle them. This code is identical in structure
and operation to the previously committed payload exception handler,
though we reserve the right to change it as circumstances require.
The remaining question is whether we need it in romstage.
Change-Id: I24484686c33c9757af8ba171ebae9773828fb69d
Signed-off-by: Gabe Black <gabeblack(a)google.com>
Signed-off-by: Ronald G. Minnich <rminnich(a)gmail.com>
---
src/arch/armv7/Makefile.inc | 3 +
src/arch/armv7/exception.c | 158 ++++++++++++++++++++++++++++++++
src/arch/armv7/exception_asm.S | 115 +++++++++++++++++++++++
src/arch/armv7/include/arch/exception.h | 38 ++++++++
src/mainboard/google/snow/ramstage.c | 5 +-
5 files changed, 318 insertions(+), 1 deletion(-)
diff --git a/src/arch/armv7/Makefile.inc b/src/arch/armv7/Makefile.inc
index 0595ae2..e708f6d 100644
--- a/src/arch/armv7/Makefile.inc
+++ b/src/arch/armv7/Makefile.inc
@@ -158,6 +158,9 @@ $(obj)/mainboard/$(MAINBOARDDIR)/romstage.pre.inc: $(src)/mainboard/$(MAINBOARDD
$(CC) -MMD $(CFLAGS) -D__PRE_RAM__ -I$(src) -I. -I$(obj) -c -S $< -o $@
# Things that appear in every board
+ramstage-y += exception.c
+ramstage-y += exception_asm.S
+
romstage-srcs += $(objgenerated)/crt0.s
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/mainboard.c
ifeq ($(CONFIG_GENERATE_PIRQ_TABLE),y)
diff --git a/src/arch/armv7/exception.c b/src/arch/armv7/exception.c
new file mode 100644
index 0000000..14f8216
--- /dev/null
+++ b/src/arch/armv7/exception.c
@@ -0,0 +1,158 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <console/console.h>
+#include <arch/exception.h>
+#include <stdint.h>
+
+void exception_test(void);
+
+static int test_abort;
+
+void exception_undefined_instruction(uint32_t *);
+void exception_software_interrupt(uint32_t *);
+void exception_prefetch_abort(uint32_t *);
+void exception_data_abort(uint32_t *);
+void exception_not_used(uint32_t *);
+void exception_irq(uint32_t *);
+void exception_fiq(uint32_t *);
+
+static void print_regs(uint32_t *regs)
+{
+ int i;
+ /* Don't print the link register and stack pointer since we don't have their
+ * actual value. They are hidden by the 'shadow' registers provided
+ * by the trap hardware.
+ */
+ for (i = 0; i < 16; i++) {
+ if (i == 15)
+ printk(BIOS_ERR, "PC");
+ else if (i == 14)
+ continue; /* LR */
+ else if (i == 13)
+ continue; /* SP */
+ else if (i == 12)
+ printk(BIOS_ERR, "IP");
+ else
+ printk(BIOS_ERR, "R%d", i);
+ printk(BIOS_ERR, " = 0x%08x\n", regs[i]);
+ }
+}
+
+void exception_undefined_instruction(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _undefined_instruction\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_software_interrupt(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _software_interrupt\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_prefetch_abort(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _prefetch_abort\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_data_abort(uint32_t *regs)
+{
+ if (test_abort) {
+ regs[15] = regs[0];
+ return;
+ } else {
+ printk(BIOS_ERR, "exception _data_abort\n");
+ print_regs(regs);
+ }
+ die("exception");
+}
+
+void exception_not_used(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _not_used\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_irq(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _irq\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_fiq(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _fiq\n");
+ print_regs(regs);
+ die("exception");
+}
+
+static inline uint32_t get_sctlr(void)
+{
+ uint32_t val;
+ asm("mrc p15, 0, %0, c1, c0, 0" : "=r" (val));
+ return val;
+}
+
+static inline void set_sctlr(uint32_t val)
+{
+ asm volatile("mcr p15, 0, %0, c1, c0, 0" :: "r" (val));
+ asm volatile("" ::: "memory");
+}
+
+void exception_init(void)
+{
+ static const uint32_t sctlr_te = (0x1 << 30);
+ static const uint32_t sctlr_v = (0x1 << 13);
+ static const uint32_t sctlr_a = (0x1 << 1);
+
+ uint32_t sctlr = get_sctlr();
+ /* Handle exceptions in ARM mode. */
+ sctlr &= ~sctlr_te;
+ /* Set V=0 in SCTLR so VBAR points to the exception vector table. */
+ sctlr &= ~sctlr_v;
+ /* Enforce alignment. */
+ sctlr |= sctlr_a;
+ set_sctlr(sctlr);
+
+ extern uint32_t exception_table[];
+ set_vbar((uintptr_t)exception_table);
+
+ test_abort = 1;
+ printk(BIOS_ERR, "Testing exceptions\n");
+ exception_test();
+ test_abort = 0;
+ printk(BIOS_ERR, "Testing exceptions: DONE\n");
+}
diff --git a/src/arch/armv7/exception_asm.S b/src/arch/armv7/exception_asm.S
new file mode 100644
index 0000000..e46f4bc
--- /dev/null
+++ b/src/arch/armv7/exception_asm.S
@@ -0,0 +1,115 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+exception_stack:
+ .align 5
+ .skip 0x2000, 0xa5
+exception_stack_end:
+ .word exception_stack_end
+
+exception_handler:
+ .word 0
+
+
+ .align 6
+ .arm
+ .global exception_table
+exception_table:
+ b 1f
+ b 2f
+ b 3f
+ b 4f
+ b 5f
+ b 6f
+ b 7f
+ b 8f
+
+1:
+ ldr sp, _not_used
+ b exception_common
+2:
+ ldr sp, _undefined_instruction
+ b exception_common
+3:
+ ldr sp, _software_interrupt
+ b exception_common
+4:
+ ldr sp, _prefetch_abort
+ b exception_common
+5:
+ ldr sp, _data_abort
+ b exception_common
+6:
+ ldr sp, _not_used
+ b exception_common
+7:
+ ldr sp, _irq
+ b exception_common
+8:
+ ldr sp, _fiq
+ b exception_common
+
+exception_common:
+ str sp, exception_handler
+ ldr sp, exception_stack_end
+ push { lr }
+ sub sp, sp, $8
+ push { r0 - r12 }
+ mov r0, sp
+ mov lr, pc
+ ldr pc, exception_handler
+ pop { r0 - r12 }
+ add sp, sp, $8
+ ldm sp!, { pc }^
+
+
+_undefined_instruction: .word exception_undefined_instruction
+_software_interrupt: .word exception_software_interrupt
+_prefetch_abort: .word exception_prefetch_abort
+_data_abort: .word exception_data_abort
+_not_used: .word exception_not_used
+_irq: .word exception_irq
+_fiq: .word exception_fiq
+
+ .thumb
+ .global set_vbar
+ .thumb_func
+set_vbar:
+ mcr p15, 0, r0, c12, c0, 0
+ bx lr
+
+ .global exception_test
+ .thumb_func
+exception_test:
+ mov r1, $1
+ mov r0, pc
+ add r0, $3
+ ldr r1, [r1]
+ bx lr
+
diff --git a/src/arch/armv7/include/arch/exception.h b/src/arch/armv7/include/arch/exception.h
new file mode 100644
index 0000000..57076bd
--- /dev/null
+++ b/src/arch/armv7/include/arch/exception.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ARCH_EXCEPTION_H
+#define _ARCH_EXCEPTION_H
+
+#include <stdint.h>
+
+void exception_init(void);
+void set_vbar(uint32_t vbar);
+
+#endif
diff --git a/src/mainboard/google/snow/ramstage.c b/src/mainboard/google/snow/ramstage.c
index 9f259ef..883bfff 100644
--- a/src/mainboard/google/snow/ramstage.c
+++ b/src/mainboard/google/snow/ramstage.c
@@ -25,9 +25,12 @@
void hardwaremain(int boot_complete);
void main(void)
{
+ /* this is going to move, but we must have it now and we're not sure where */
+ void exception_init(void);
console_init();
- printk(BIOS_INFO, "hello from ramstage\n");
+ printk(BIOS_INFO, "hello from ramstage; now with deluxe exception handling.\n");
+ exception_init();
/* place at top of physical memory */
high_tables_size = CONFIG_COREBOOT_TABLES_SIZE;
high_tables_base = CONFIG_SYS_SDRAM_BASE +
Kimarie Hoot (kimarie.hoot(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2607
-gerrit
commit 30a9de69e2f13aa62978e9817975776565a09010
Author: Kimarie Hoot <kimarie.hoot(a)se-eng.com>
Date: Wed Mar 6 16:18:09 2013 -0700
AMD Inagua: Use SPD read code from F14 wrapper
Changes:
- Get rid of the inagua mainboard specific code and uses the
platform generic function wrapper that was added in change
http://review.coreboot.org/#/c/2497/
AMD f14: Add SPD read functions to wrapper code
- Move DIMM addresses into devicetree.cb
- Add the ASF init that used to be in the SPD read code into
mainboard_enable()
Notes:
- The DIMM reads only happen in romstage, so the function is not
available in ramstage. Point the read-SPD callback to a generic
function in ramstage.
Change-Id: Id05227fcf18c6ab94ffe1beb50b533ab7b0535db
Signed-off-by: Kimarie Hoot <kimarie.hoot(a)se-eng.com>
---
src/mainboard/amd/inagua/BiosCallOuts.c | 8 +-
src/mainboard/amd/inagua/Makefile.inc | 2 -
src/mainboard/amd/inagua/devicetree.cb | 5 +
src/mainboard/amd/inagua/dimmSpd.c | 159 --------------------------------
src/mainboard/amd/inagua/dimmSpd.h | 63 -------------
src/mainboard/amd/inagua/mainboard.c | 11 ++-
6 files changed, 21 insertions(+), 227 deletions(-)
diff --git a/src/mainboard/amd/inagua/BiosCallOuts.c b/src/mainboard/amd/inagua/BiosCallOuts.c
index 23e020f..452a592 100644
--- a/src/mainboard/amd/inagua/BiosCallOuts.c
+++ b/src/mainboard/amd/inagua/BiosCallOuts.c
@@ -19,10 +19,10 @@
#include "agesawrapper.h"
#include "amdlib.h"
-#include "dimmSpd.h"
#include "BiosCallOuts.h"
#include "heapManager.h"
#include "SB800.h"
+#include <northbridge/amd/agesa/family14/dimmSpd.h>
STATIC BIOS_CALLOUT_STRUCT BiosCallouts[] =
{
@@ -419,7 +419,11 @@ AGESA_STATUS BiosReset (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
AGESA_STATUS BiosReadSpd (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
{
AGESA_STATUS Status;
- Status = AmdMemoryReadSPD (Func, Data, (AGESA_READ_SPD_PARAMS *)ConfigPtr);
+#ifdef __PRE_RAM__
+ Status = agesa_ReadSPD (Func, Data, ConfigPtr);
+#else
+ Status = AGESA_UNSUPPORTED;
+#endif
return Status;
}
diff --git a/src/mainboard/amd/inagua/Makefile.inc b/src/mainboard/amd/inagua/Makefile.inc
index b1a3014..17443bc 100644
--- a/src/mainboard/amd/inagua/Makefile.inc
+++ b/src/mainboard/amd/inagua/Makefile.inc
@@ -26,13 +26,11 @@ endif
romstage-y += buildOpts.c
romstage-y += agesawrapper.c
-romstage-y += dimmSpd.c
romstage-y += BiosCallOuts.c
romstage-y += PlatformGnbPcie.c
ramstage-y += buildOpts.c
ramstage-y += agesawrapper.c
-ramstage-y += dimmSpd.c
ramstage-y += BiosCallOuts.c
ramstage-y += PlatformGnbPcie.c
diff --git a/src/mainboard/amd/inagua/devicetree.cb b/src/mainboard/amd/inagua/devicetree.cb
index 3d8ccb4..67c3a1a 100644
--- a/src/mainboard/amd/inagua/devicetree.cb
+++ b/src/mainboard/amd/inagua/devicetree.cb
@@ -86,6 +86,11 @@ chip northbridge/amd/agesa/family14/root_complex
device pci 18.5 on end
device pci 18.6 on end
device pci 18.7 on end
+
+ register "spdAddrLookup" = "
+ {
+ { {0xA0, 0xA2}, {0x00, 0x00}, }, // socket 0 - Channel 0 & 1 - 8-bit SPD addresses
+ }"
end #chip northbridge/amd/agesa/family14 # CPU side of HT root complex
end #domain
end #northbridge/amd/agesa/family14/root_complex
diff --git a/src/mainboard/amd/inagua/dimmSpd.c b/src/mainboard/amd/inagua/dimmSpd.c
deleted file mode 100644
index 730a2d0..0000000
--- a/src/mainboard/amd/inagua/dimmSpd.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 Advanced Micro Devices, Inc.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "Porting.h"
-#include "AGESA.h"
-#include "amdlib.h"
-#include "OEM.h" /* SMBUS0_BASE_ADDRESS */
-
-AGESA_STATUS AmdMemoryReadSPD (UINT32 unused1, UINT32 unused2, AGESA_READ_SPD_PARAMS *info);
-#define DIMENSION(array)(sizeof (array)/ sizeof (array [0]))
-
-/*#pragma optimize ("", off) // for source level debug
- *---------------------------------------------------------------------------
- *
- * SPD address table - porting required
- */
-
-static const UINT8 spdAddressLookup [1] [2] [2] = // socket, channel, dimm
-{
- // socket 0
- {
- {0xA0, 0xA2}, // channel 0 dimms
- {0x00, 0x00}, // channel 1 dimms
- },
-};
-
-/*-----------------------------------------------------------------------------
- *
- * readSmbusByteData - read a single SPD byte from any offset
- */
-
-static int readSmbusByteData (int iobase, int address, char *buffer, int offset)
-{
- unsigned int status;
- UINT64 limit;
-
- address |= 1; // set read bit
-
- __outbyte (iobase + 0, 0xFF); // clear error status
- __outbyte (iobase + 1, 0x1F); // clear error status
- __outbyte (iobase + 3, offset); // offset in eeprom
- __outbyte (iobase + 4, address); // slave address and read bit
- __outbyte (iobase + 2, 0x48); // read byte command
-
- // time limit to avoid hanging for unexpected error status (should never happen)
- limit = __rdtsc () + 2000000000 / 10;
- for (;;) {
- status = __inbyte (iobase);
- if (__rdtsc () > limit) break;
- if ((status & 2) == 0) continue; // SMBusInterrupt not set, keep waiting
- if ((status & 1) == 1) continue; // HostBusy set, keep waiting
- break;
- }
-
- buffer [0] = __inbyte (iobase + 5);
- if (status == 2) status = 0; // check for done with no errors
- return status;
-}
-
-/*-----------------------------------------------------------------------------
- *
- * readSmbusByte - read a single SPD byte from the default offset
- * this function is faster function readSmbusByteData
- */
-
-static int readSmbusByte (int iobase, int address, char *buffer)
-{
- unsigned int status;
- UINT64 limit;
-
- __outbyte (iobase + 0, 0xFF); // clear error status
- __outbyte (iobase + 2, 0x44); // read command
-
- // time limit to avoid hanging for unexpected error status
- limit = __rdtsc () + 2000000000 / 10;
- for (;;) {
- status = __inbyte (iobase);
- if (__rdtsc () > limit) break;
- if ((status & 2) == 0) continue; // SMBusInterrupt not set, keep waiting
- if ((status & 1) == 1) continue; // HostBusy set, keep waiting
- break;
- }
-
- buffer [0] = __inbyte (iobase + 5);
- if (status == 2) status = 0; // check for done with no errors
- return status;
-}
-
-/*---------------------------------------------------------------------------
- *
- * readspd - Read one or more SPD bytes from a DIMM.
- * Start with offset zero and read sequentially.
- * Optimization relies on autoincrement to avoid
- * sending offset for every byte.
- * Reads 128 bytes in 7-8 ms at 400 KHz.
- */
-
-static int readspd (int iobase, int SmbusSlaveAddress, char *buffer, int count)
-{
- int index, error;
-
- /* read the first byte using offset zero */
- error = readSmbusByteData (iobase, SmbusSlaveAddress, buffer, 0);
- if (error) return error;
-
- /* read the remaining bytes using auto-increment for speed */
- for (index = 1; index < count; index++) {
- error = readSmbusByte (iobase, SmbusSlaveAddress, &buffer [index]);
- if (error) return error;
- }
-
- return 0;
-}
-
-static void writePmReg (int reg, int data)
-{
- __outbyte (0xCD6, reg);
- __outbyte (0xCD7, data);
-}
-
-static void setupFch (int ioBase)
-{
- writePmReg (0x2D, ioBase >> 8);
- writePmReg (0x2C, ioBase | 1);
- writePmReg (0x29, 0x80);
- writePmReg (0x28, 0x61);
- __outbyte (ioBase + 0x0E, 66000000 / 400000 / 4); // set SMBus clock to 400 KHz
-}
-
-AGESA_STATUS AmdMemoryReadSPD (UINT32 unused1, UINT32 unused2, AGESA_READ_SPD_PARAMS *info)
-{
- int spdAddress, ioBase;
-
- if (info->SocketId >= DIMENSION (spdAddressLookup )) return AGESA_ERROR;
- if (info->MemChannelId >= DIMENSION (spdAddressLookup[0] )) return AGESA_ERROR;
- if (info->DimmId >= DIMENSION (spdAddressLookup[0][0])) return AGESA_ERROR;
-
- spdAddress = spdAddressLookup [info->SocketId] [info->MemChannelId] [info->DimmId];
- if (spdAddress == 0) return AGESA_ERROR;
- ioBase = SMBUS0_BASE_ADDRESS;
- setupFch (ioBase);
- return readspd (ioBase, spdAddress, (void *) info->Buffer, 128);
-}
diff --git a/src/mainboard/amd/inagua/dimmSpd.h b/src/mainboard/amd/inagua/dimmSpd.h
deleted file mode 100644
index 81ab02e..0000000
--- a/src/mainboard/amd/inagua/dimmSpd.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 Advanced Micro Devices, Inc.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*----------------------------------------------------------------------------------------
- * M O D U L E S U S E D
- *----------------------------------------------------------------------------------------
- */
-
-#ifndef _DIMMSPD_H_
-#define _DIMMSPD_H_
-
-#include "Porting.h"
-#include "AGESA.h"
-
-/*----------------------------------------------------------------------------------------
- * D E F I N I T I O N S A N D M A C R O S
- *----------------------------------------------------------------------------------------
- */
-
-/*----------------------------------------------------------------------------------------
- * T Y P E D E F S A N D S T R U C T U R E S
- *----------------------------------------------------------------------------------------
- */
-
-/*----------------------------------------------------------------------------------------
- * P R O T O T Y P E S O F L O C A L F U N C T I O N S
- *----------------------------------------------------------------------------------------
- */
-
-/*----------------------------------------------------------------------------------------
- * E X P O R T E D F U N C T I O N S
- *----------------------------------------------------------------------------------------
- */
-
-AGESA_STATUS
-AmdMemoryReadSPD (
- IN UINT32 Func,
- IN UINT32 Data,
- IN OUT AGESA_READ_SPD_PARAMS *SpdData
- );
-
-/*---------------------------------------------------------------------------------------
- * L O C A L F U N C T I O N S
- *---------------------------------------------------------------------------------------
- */
-
-#endif
diff --git a/src/mainboard/amd/inagua/mainboard.c b/src/mainboard/amd/inagua/mainboard.c
index 8907ebb..8e92d6a 100644
--- a/src/mainboard/amd/inagua/mainboard.c
+++ b/src/mainboard/amd/inagua/mainboard.c
@@ -24,7 +24,7 @@
#include <cpu/x86/msr.h>
#include <cpu/amd/mtrr.h>
#include <device/pci_def.h>
-//#include <southbridge/amd/sb800/sb800.h>
+#include <southbridge/amd/sb800/sb800.h>
#include "SBPLATFORM.h" /* Platfrom Specific Definitions */
void set_pcie_reset(void);
@@ -79,6 +79,15 @@ static void mainboard_enable(device_t dev)
/* Inagua mainboard specific setting */
set_pcie_dereset();
+
+ /*
+ * Initialize ASF registers to an arbitrary address because someone
+ * long ago set things up this way inside the SPD read code. The
+ * SPD read code has been made generic and moved out of the board
+ * directory, so the ASF init is being done here.
+ */
+ pm_iowrite(0x29, 0x80);
+ pm_iowrite(0x28, 0x61);
}
struct chip_operations mainboard_ops = {