cmos post: Guard with spinlock
The CMOS post code storage mechanism does back-to-back CMOS reads and writes that may be interleaved during CPU bringup, leading to corruption of the log or of other parts of CMOS. Change-Id: I704813cc917a659fe034b71c2ff9eb9b80f7c949 Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/58102 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/4227 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
35bd3fedfe
commit
e807c34a5e
|
@ -1,6 +1,8 @@
|
|||
#ifndef ARCH_SMP_SPINLOCK_H
|
||||
#define ARCH_SMP_SPINLOCK_H
|
||||
|
||||
#ifndef __PRE_RAM__
|
||||
|
||||
/*
|
||||
* Your basic SMP spinlocks, allowing only a single CPU anywhere
|
||||
*/
|
||||
|
@ -61,4 +63,16 @@ static inline __attribute__((always_inline)) void cpu_relax(void)
|
|||
__asm__ __volatile__("rep;nop": : :"memory");
|
||||
}
|
||||
|
||||
#else /* !__PRE_RAM__ */
|
||||
|
||||
#define DECLARE_SPIN_LOCK(x)
|
||||
#define barrier() do {} while(0)
|
||||
#define spin_is_locked(lock) 0
|
||||
#define spin_unlock_wait(lock) do {} while(0)
|
||||
#define spin_lock(lock) do {} while(0)
|
||||
#define spin_unlock(lock) do {} while(0)
|
||||
#define cpu_relax() do {} while(0)
|
||||
|
||||
#endif /* !__PRE_RAM__ */
|
||||
|
||||
#endif /* ARCH_SMP_SPINLOCK_H */
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <console/console.h>
|
||||
#if CONFIG_CMOS_POST
|
||||
#include <pc80/mc146818rtc.h>
|
||||
#include <smp/spinlock.h>
|
||||
#endif
|
||||
#include <elog.h>
|
||||
|
||||
|
@ -44,10 +45,14 @@ void __attribute__((weak)) mainboard_post(uint8_t value)
|
|||
|
||||
#if CONFIG_CMOS_POST
|
||||
|
||||
DECLARE_SPIN_LOCK(cmos_post_lock)
|
||||
|
||||
#if !defined(__PRE_RAM__)
|
||||
void cmos_post_log(void)
|
||||
{
|
||||
u8 code;
|
||||
u8 code = 0;
|
||||
|
||||
spin_lock(&cmos_post_lock);
|
||||
|
||||
/* Get post code from other bank */
|
||||
switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
|
||||
|
@ -57,10 +62,10 @@ void cmos_post_log(void)
|
|||
case CMOS_POST_BANK_1_MAGIC:
|
||||
code = cmos_read(CMOS_POST_BANK_0_OFFSET);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
spin_unlock(&cmos_post_lock);
|
||||
|
||||
/* Check last post code in previous boot against normal list */
|
||||
switch (code) {
|
||||
case POST_OS_BOOT:
|
||||
|
@ -80,6 +85,8 @@ void cmos_post_log(void)
|
|||
|
||||
static void cmos_post_code(u8 value)
|
||||
{
|
||||
spin_lock(&cmos_post_lock);
|
||||
|
||||
switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
|
||||
case CMOS_POST_BANK_0_MAGIC:
|
||||
cmos_write(value, CMOS_POST_BANK_0_OFFSET);
|
||||
|
@ -88,6 +95,8 @@ static void cmos_post_code(u8 value)
|
|||
cmos_write(value, CMOS_POST_BANK_1_OFFSET);
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock(&cmos_post_lock);
|
||||
}
|
||||
#endif /* CONFIG_CMOS_POST */
|
||||
|
||||
|
|
Loading…
Reference in New Issue