Timothy Pearson (tpearson(a)raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/12289
-gerrit
commit 62d320df70ef2aca2a0227e39f229efdff07da43
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Sun Nov 1 02:13:17 2015 -0600
drivers/pc80: Rework normal / fallback selector code
Per IRC and Gerrit discussion, the normal / fallback
selector code is a rather weak spot in coreboot, and
did not function correctly for certain use cases.
Rework the selector to more clearly indicate proper
operation, and also remove dead code. Also tentatively
abandon use of RTC bit 385; a follow-up patch will
remove said bit from all affected mainboards.
The correct operation of the fallback code selector
approximates that of a power line recloser, with
a user option to attempt normal boot that can be
cleared by firmware, but never set by firmware.
Additionally, if cleared by user, the fallback
path should always be used on the next reboot.
Change-Id: I753ae9f0710c524875a85354ac2547df0c305569
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
---
src/drivers/pc80/mc146818rtc_early.c | 56 +++++++++++++++++++-----------------
src/include/pc80/mc146818rtc.h | 2 ++
src/lib/fallback_boot.c | 25 +++++++++-------
3 files changed, 46 insertions(+), 37 deletions(-)
diff --git a/src/drivers/pc80/mc146818rtc_early.c b/src/drivers/pc80/mc146818rtc_early.c
index 421af2f..1de920e 100644
--- a/src/drivers/pc80/mc146818rtc_early.c
+++ b/src/drivers/pc80/mc146818rtc_early.c
@@ -41,12 +41,24 @@ static int cmos_chksum_valid(void)
#endif
}
+static inline __attribute__((unused)) int boot_count(uint8_t rtc_byte)
+{
+ return rtc_byte >> 4;
+}
-static inline __attribute__((unused)) int last_boot_normal(void)
+static inline __attribute__((unused)) uint8_t increment_boot_count(uint8_t rtc_byte)
{
- unsigned char byte;
- byte = cmos_read(RTC_BOOT_BYTE);
- return (byte & (1 << 1));
+ return rtc_byte + (1 << 4);
+}
+
+static inline __attribute__((unused)) uint8_t boot_use_fallback(uint8_t rtc_byte)
+{
+ return rtc_byte & ~RTC_BOOT_NORMAL;
+}
+
+static inline __attribute__((unused)) int boot_use_normal(uint8_t rtc_byte)
+{
+ return rtc_byte & RTC_BOOT_NORMAL;
}
static inline __attribute__((unused)) int do_normal_boot(void)
@@ -54,42 +66,32 @@ static inline __attribute__((unused)) int do_normal_boot(void)
unsigned char byte;
if (cmos_error() || !cmos_chksum_valid()) {
- /* There are no impossible values, no checksums so just
- * trust whatever value we have in the the cmos,
- * but clear the fallback bit.
+ /* Invalid CMOS checksum detected!
+ * Force fallback boot...
*/
byte = cmos_read(RTC_BOOT_BYTE);
- byte &= 0x0c;
- byte |= CONFIG_MAX_REBOOT_CNT << 4;
+ byte &= boot_use_fallback(byte) & 0x0f;
+ byte |= 0xf << 4;
cmos_write(byte, RTC_BOOT_BYTE);
}
/* The RTC_BOOT_BYTE is now o.k. see where to go. */
byte = cmos_read(RTC_BOOT_BYTE);
- if (!IS_ENABLED(CONFIG_SKIP_MAX_REBOOT_CNT_CLEAR))
- /* Are we in normal mode? */
- if (byte & 1)
- byte &= 0x0f; /* yes, clear the boot count */
-
- /* Properly set the last boot flag */
- byte &= 0xfc;
- if ((byte >> 4) < CONFIG_MAX_REBOOT_CNT) {
- byte |= (1<<1);
- }
-
- /* Are we already at the max count? */
- if ((byte >> 4) < CONFIG_MAX_REBOOT_CNT) {
- byte += 1 << 4; /* No, add 1 to the count */
- }
- else {
- byte &= 0xfc; /* Yes, put in fallback mode */
+ /* Are we attempting to boot normally? */
+ if (byte & RTC_BOOT_NORMAL) {
+ /* Are we already at the max count? */
+ if (boot_count(byte) < CONFIG_MAX_REBOOT_CNT)
+ byte = increment_boot_count(byte);
+ else
+ byte = boot_use_fallback(byte);
}
/* Save the boot byte */
cmos_write(byte, RTC_BOOT_BYTE);
- return (byte & (1<<1));
+ /* Return selected code path for this boot attempt */
+ return (byte & RTC_BOOT_NORMAL);
}
unsigned read_option_lowlevel(unsigned start, unsigned size, unsigned def)
diff --git a/src/include/pc80/mc146818rtc.h b/src/include/pc80/mc146818rtc.h
index 0e15273..38f2ad0 100644
--- a/src/include/pc80/mc146818rtc.h
+++ b/src/include/pc80/mc146818rtc.h
@@ -25,6 +25,8 @@
**********************************************************************/
#define RTC_FREQ_SELECT RTC_REG_A
+#define RTC_BOOT_NORMAL 0x1
+
/* update-in-progress - set to "1" 244 microsecs before RTC goes off the bus,
* reset after update (may take 1.984ms @ 32768Hz RefClock) is complete,
* totaling to a max high interval of 2.228 ms.
diff --git a/src/lib/fallback_boot.c b/src/lib/fallback_boot.c
index 74572df..b1b37a7 100644
--- a/src/lib/fallback_boot.c
+++ b/src/lib/fallback_boot.c
@@ -8,23 +8,28 @@
static void set_boot_successful(void)
{
- /* Remember I successfully booted by setting
- * the initial boot direction
- * to the direction that I booted.
- */
- unsigned char index, byte;
+ uint8_t index, byte;
+
index = inb(RTC_PORT(0)) & 0x80;
index |= RTC_BOOT_BYTE;
outb(index, RTC_PORT(0));
byte = inb(RTC_PORT(1));
- byte &= 0xfe;
- byte |= (byte & (1 << 1)) >> 1;
- /* If we are in normal mode set the boot count to 0 */
- if (!IS_ENABLED(CONFIG_SKIP_MAX_REBOOT_CNT_CLEAR))
- if(byte & 1)
+ if (IS_ENABLED(CONFIG_SKIP_MAX_REBOOT_CNT_CLEAR)) {
+ /* Set the fallback boot bit to allow for recovery if
+ * the payload fails to boot.
+ * It is the responsibility of the payload to reset
+ * the normal boot bit to 1 if desired
+ */
+ byte &= ~RTC_BOOT_NORMAL;
+ } else {
+ /* If we are in normal mode set the boot count to 0 */
+ if(byte & RTC_BOOT_NORMAL)
byte &= 0x0f;
+
+ }
+
outb(byte, RTC_PORT(1));
}
#else
Timothy Pearson (tpearson(a)raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/12289
-gerrit
commit 97beeedf265bca4088c9ac9a598085c637560900
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Sun Nov 1 02:13:17 2015 -0600
drivers/pc80: Rework normal / fallback selector code
Per IRC and Gerrit discussion, the normal / fallback
selector code is a rather weak spot in coreboot, and
did not function correctly for certain use cases.
Rework the selector to more clearly indicate proper
operation, and also remove dead code. Also tentatively
abandon use of RTC bit 385; a follow-up patch will
remove said bit from all affected mainboards.
The correct operation of the fallback code selector
approximates that of a power line recloser, with
a user option to attempt normal boot that can be
cleared by firmware, but never set by firmware.
Additionally, if cleared by user, the fallback
path should always be used on the next reboot.
Change-Id: I753ae9f0710c524875a85354ac2547df0c305569
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
---
src/drivers/pc80/mc146818rtc_early.c | 49 +++++++++++++++++++++---------------
src/lib/fallback_boot.c | 25 ++++++++----------
2 files changed, 40 insertions(+), 34 deletions(-)
diff --git a/src/drivers/pc80/mc146818rtc_early.c b/src/drivers/pc80/mc146818rtc_early.c
index 421af2f..2eb4a15 100644
--- a/src/drivers/pc80/mc146818rtc_early.c
+++ b/src/drivers/pc80/mc146818rtc_early.c
@@ -12,6 +12,8 @@
#error "CONFIG_MAX_REBOOT_CNT too high"
#endif
+#define RTC_BOOT_NORMAL 0x1
+
static int cmos_error(void)
{
unsigned char reg_d;
@@ -41,12 +43,28 @@ static int cmos_chksum_valid(void)
#endif
}
+static inline __attribute__((unused)) int boot_count(void)
+{
+ unsigned char byte;
+ byte = cmos_read(RTC_BOOT_BYTE);
+ return byte >> 4;
+}
+
+static inline __attribute__((unused)) uint8_t increment_boot_count(uint8_t rtc_byte)
+{
+ return rtc_byte + (1 << 4);
+}
+
+static inline __attribute__((unused)) uint8_t boot_use_fallback(uint8_t rtc_byte)
+{
+ return rtc_byte & ~RTC_BOOT_NORMAL;
+}
static inline __attribute__((unused)) int last_boot_normal(void)
{
unsigned char byte;
byte = cmos_read(RTC_BOOT_BYTE);
- return (byte & (1 << 1));
+ return (byte & RTC_BOOT_NORMAL);
}
static inline __attribute__((unused)) int do_normal_boot(void)
@@ -59,7 +77,7 @@ static inline __attribute__((unused)) int do_normal_boot(void)
* but clear the fallback bit.
*/
byte = cmos_read(RTC_BOOT_BYTE);
- byte &= 0x0c;
+ byte &= RTC_BOOT_NORMAL;
byte |= CONFIG_MAX_REBOOT_CNT << 4;
cmos_write(byte, RTC_BOOT_BYTE);
}
@@ -67,29 +85,20 @@ static inline __attribute__((unused)) int do_normal_boot(void)
/* The RTC_BOOT_BYTE is now o.k. see where to go. */
byte = cmos_read(RTC_BOOT_BYTE);
- if (!IS_ENABLED(CONFIG_SKIP_MAX_REBOOT_CNT_CLEAR))
- /* Are we in normal mode? */
- if (byte & 1)
- byte &= 0x0f; /* yes, clear the boot count */
-
- /* Properly set the last boot flag */
- byte &= 0xfc;
- if ((byte >> 4) < CONFIG_MAX_REBOOT_CNT) {
- byte |= (1<<1);
- }
-
- /* Are we already at the max count? */
- if ((byte >> 4) < CONFIG_MAX_REBOOT_CNT) {
- byte += 1 << 4; /* No, add 1 to the count */
- }
- else {
- byte &= 0xfc; /* Yes, put in fallback mode */
+ /* Are we attempting to boot normally? */
+ if (byte & RTC_BOOT_NORMAL) {
+ /* Are we already at the max count? */
+ if (boot_count() < CONFIG_MAX_REBOOT_CNT)
+ byte = increment_boot_count(byte);
+ else
+ byte = boot_use_fallback(byte);
}
/* Save the boot byte */
cmos_write(byte, RTC_BOOT_BYTE);
- return (byte & (1<<1));
+ /* Return selected code path for this boot attempt */
+ return (byte & RTC_BOOT_NORMAL);
}
unsigned read_option_lowlevel(unsigned start, unsigned size, unsigned def)
diff --git a/src/lib/fallback_boot.c b/src/lib/fallback_boot.c
index 74572df..5f1d078 100644
--- a/src/lib/fallback_boot.c
+++ b/src/lib/fallback_boot.c
@@ -8,24 +8,21 @@
static void set_boot_successful(void)
{
- /* Remember I successfully booted by setting
- * the initial boot direction
- * to the direction that I booted.
- */
- unsigned char index, byte;
- index = inb(RTC_PORT(0)) & 0x80;
- index |= RTC_BOOT_BYTE;
- outb(index, RTC_PORT(0));
-
- byte = inb(RTC_PORT(1));
- byte &= 0xfe;
- byte |= (byte & (1 << 1)) >> 1;
+ uint8_t index, byte;
/* If we are in normal mode set the boot count to 0 */
- if (!IS_ENABLED(CONFIG_SKIP_MAX_REBOOT_CNT_CLEAR))
+ if (!IS_ENABLED(CONFIG_SKIP_MAX_REBOOT_CNT_CLEAR)) {
+ index = inb(RTC_PORT(0)) & 0x80;
+ index |= RTC_BOOT_BYTE;
+ outb(index, RTC_PORT(0));
+
+ byte = inb(RTC_PORT(1));
+
if(byte & 1)
byte &= 0x0f;
- outb(byte, RTC_PORT(1));
+
+ outb(byte, RTC_PORT(1));
+ }
}
#else
static void set_boot_successful(void)
Timothy Pearson (tpearson(a)raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/12289
-gerrit
commit 960caf3775e1eb2da79260cdab65be667a6ccf0b
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Sun Nov 1 02:13:17 2015 -0600
drivers/pc80: Rework normal / fallback selector code
Per IRC and Gerrit discussion, the normal / fallback
selector code is a rather weak spot in coreboot, and
did not function correctly for certain use cases.
Rework the selector to more clearly indicate proper
operation, and also remove dead code. Also tentatively
abandon use of RTC bit 385; a follow-up patch will
remove said bit from all affected mainboards.
The correct operation of the fallback code selector
approximates that of a power line recloser, with
a user option to attempt normal boot that can be
cleared by firmware, but never set by firmware.
Additionally, if cleared by user, the fallback
path should always be used on the next reboot.
Change-Id: I753ae9f0710c524875a85354ac2547df0c305569
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
---
src/drivers/pc80/mc146818rtc_early.c | 49 +++++++++++++++++++++---------------
1 file changed, 29 insertions(+), 20 deletions(-)
diff --git a/src/drivers/pc80/mc146818rtc_early.c b/src/drivers/pc80/mc146818rtc_early.c
index 421af2f..2eb4a15 100644
--- a/src/drivers/pc80/mc146818rtc_early.c
+++ b/src/drivers/pc80/mc146818rtc_early.c
@@ -12,6 +12,8 @@
#error "CONFIG_MAX_REBOOT_CNT too high"
#endif
+#define RTC_BOOT_NORMAL 0x1
+
static int cmos_error(void)
{
unsigned char reg_d;
@@ -41,12 +43,28 @@ static int cmos_chksum_valid(void)
#endif
}
+static inline __attribute__((unused)) int boot_count(void)
+{
+ unsigned char byte;
+ byte = cmos_read(RTC_BOOT_BYTE);
+ return byte >> 4;
+}
+
+static inline __attribute__((unused)) uint8_t increment_boot_count(uint8_t rtc_byte)
+{
+ return rtc_byte + (1 << 4);
+}
+
+static inline __attribute__((unused)) uint8_t boot_use_fallback(uint8_t rtc_byte)
+{
+ return rtc_byte & ~RTC_BOOT_NORMAL;
+}
static inline __attribute__((unused)) int last_boot_normal(void)
{
unsigned char byte;
byte = cmos_read(RTC_BOOT_BYTE);
- return (byte & (1 << 1));
+ return (byte & RTC_BOOT_NORMAL);
}
static inline __attribute__((unused)) int do_normal_boot(void)
@@ -59,7 +77,7 @@ static inline __attribute__((unused)) int do_normal_boot(void)
* but clear the fallback bit.
*/
byte = cmos_read(RTC_BOOT_BYTE);
- byte &= 0x0c;
+ byte &= RTC_BOOT_NORMAL;
byte |= CONFIG_MAX_REBOOT_CNT << 4;
cmos_write(byte, RTC_BOOT_BYTE);
}
@@ -67,29 +85,20 @@ static inline __attribute__((unused)) int do_normal_boot(void)
/* The RTC_BOOT_BYTE is now o.k. see where to go. */
byte = cmos_read(RTC_BOOT_BYTE);
- if (!IS_ENABLED(CONFIG_SKIP_MAX_REBOOT_CNT_CLEAR))
- /* Are we in normal mode? */
- if (byte & 1)
- byte &= 0x0f; /* yes, clear the boot count */
-
- /* Properly set the last boot flag */
- byte &= 0xfc;
- if ((byte >> 4) < CONFIG_MAX_REBOOT_CNT) {
- byte |= (1<<1);
- }
-
- /* Are we already at the max count? */
- if ((byte >> 4) < CONFIG_MAX_REBOOT_CNT) {
- byte += 1 << 4; /* No, add 1 to the count */
- }
- else {
- byte &= 0xfc; /* Yes, put in fallback mode */
+ /* Are we attempting to boot normally? */
+ if (byte & RTC_BOOT_NORMAL) {
+ /* Are we already at the max count? */
+ if (boot_count() < CONFIG_MAX_REBOOT_CNT)
+ byte = increment_boot_count(byte);
+ else
+ byte = boot_use_fallback(byte);
}
/* Save the boot byte */
cmos_write(byte, RTC_BOOT_BYTE);
- return (byte & (1<<1));
+ /* Return selected code path for this boot attempt */
+ return (byte & RTC_BOOT_NORMAL);
}
unsigned read_option_lowlevel(unsigned start, unsigned size, unsigned def)
Timothy Pearson (tpearson(a)raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/12289
-gerrit
commit 32cbe28e4e5e2ffc8b913d5a423ef35954f4bf58
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Sun Nov 1 02:13:17 2015 -0600
drivers/pc80: Rework normal / fallback selector code
Per IRC and Gerrit discussion, the normal / fallback
selector code is a rather weak spot in coreboot, and
did not function correctly for certain use cases.
Rework the selector to more clearly indicate proper
operation, and also remove dead code. Also tentatively
abandon use of RTC bit 385; a follow-up patch will
remove said bit from all affected mainboards.
The correct operation of the fallback code selector
approximates that of a power line recloser, with
a user option to attempt normal boot that can be
cleared by firmware, but never set by firmware.
Additionally, if cleared by user, the fallback
path should always be used on the next reboot.
Change-Id: I753ae9f0710c524875a85354ac2547df0c305569
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
---
src/drivers/pc80/mc146818rtc_early.c | 50 +++++++++++++++++++++---------------
1 file changed, 30 insertions(+), 20 deletions(-)
diff --git a/src/drivers/pc80/mc146818rtc_early.c b/src/drivers/pc80/mc146818rtc_early.c
index 421af2f..1bc641e 100644
--- a/src/drivers/pc80/mc146818rtc_early.c
+++ b/src/drivers/pc80/mc146818rtc_early.c
@@ -12,6 +12,8 @@
#error "CONFIG_MAX_REBOOT_CNT too high"
#endif
+#define RTC_BOOT_NORMAL 0x1
+
static int cmos_error(void)
{
unsigned char reg_d;
@@ -41,12 +43,28 @@ static int cmos_chksum_valid(void)
#endif
}
+static inline __attribute__((unused)) int boot_count(void)
+{
+ unsigned char byte;
+ byte = cmos_read(RTC_BOOT_BYTE);
+ return byte >> 4;
+}
+
+static inline __attribute__((unused)) void increment_boot_count(uint8_t &rtc_byte)
+{
+ rtc_byte += (1 << 4);
+}
+
+static inline __attribute__((unused)) void boot_use_fallback(uint8_t &rtc_byte)
+{
+ rtc_byte &= ~RTC_BOOT_NORMAL;
+}
static inline __attribute__((unused)) int last_boot_normal(void)
{
unsigned char byte;
byte = cmos_read(RTC_BOOT_BYTE);
- return (byte & (1 << 1));
+ return (byte & RTC_BOOT_NORMAL);
}
static inline __attribute__((unused)) int do_normal_boot(void)
@@ -59,7 +77,7 @@ static inline __attribute__((unused)) int do_normal_boot(void)
* but clear the fallback bit.
*/
byte = cmos_read(RTC_BOOT_BYTE);
- byte &= 0x0c;
+ byte &= RTC_BOOT_NORMAL;
byte |= CONFIG_MAX_REBOOT_CNT << 4;
cmos_write(byte, RTC_BOOT_BYTE);
}
@@ -67,29 +85,21 @@ static inline __attribute__((unused)) int do_normal_boot(void)
/* The RTC_BOOT_BYTE is now o.k. see where to go. */
byte = cmos_read(RTC_BOOT_BYTE);
- if (!IS_ENABLED(CONFIG_SKIP_MAX_REBOOT_CNT_CLEAR))
- /* Are we in normal mode? */
- if (byte & 1)
- byte &= 0x0f; /* yes, clear the boot count */
-
- /* Properly set the last boot flag */
- byte &= 0xfc;
- if ((byte >> 4) < CONFIG_MAX_REBOOT_CNT) {
- byte |= (1<<1);
- }
-
- /* Are we already at the max count? */
- if ((byte >> 4) < CONFIG_MAX_REBOOT_CNT) {
- byte += 1 << 4; /* No, add 1 to the count */
- }
- else {
- byte &= 0xfc; /* Yes, put in fallback mode */
+ /* Are we attempting to boot normally? */
+ if (byte & RTC_BOOT_NORMAL) {
+ /* Are we already at the max count? */
+ if (boot_count() < CONFIG_MAX_REBOOT_CNT) {
+ increment_boot_count(byte)
+ } else {
+ boot_use_fallback(byte);
+ }
}
/* Save the boot byte */
cmos_write(byte, RTC_BOOT_BYTE);
- return (byte & (1<<1));
+ /* Return selected code path for this boot attempt */
+ return (byte & RTC_BOOT_NORMAL);
}
unsigned read_option_lowlevel(unsigned start, unsigned size, unsigned def)
Timothy Pearson (tpearson(a)raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/12289
-gerrit
commit 3bfed20f15080a3689e4b6e1621f72783fc7ff89
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Sun Nov 1 02:13:17 2015 -0600
drivers/pc80: Rework normal / fallback selector code
Per IRC and Gerrit discussion, the normal / fallback
selector code is a rather weak spot in coreboot, and
did not function correctly for certain use cases.
Rework the selector to more clearly indicate proper
operation, and also remove dead code. Also tentatively
abandon use of RTC bit 385; a follow-up patch will
remove said bit from all affected mainboards.
The correct operation of the fallback code selector
approximates that of a power line recloser, with
a user option to attempt normal boot that can be
cleared by firmware, but never set by firmware.
Additionally, if cleared by user, the fallback
patch should be used on the next reboot.
Change-Id: I753ae9f0710c524875a85354ac2547df0c305569
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
---
src/drivers/pc80/mc146818rtc_early.c | 50 +++++++++++++++++++++---------------
1 file changed, 30 insertions(+), 20 deletions(-)
diff --git a/src/drivers/pc80/mc146818rtc_early.c b/src/drivers/pc80/mc146818rtc_early.c
index 421af2f..1bc641e 100644
--- a/src/drivers/pc80/mc146818rtc_early.c
+++ b/src/drivers/pc80/mc146818rtc_early.c
@@ -12,6 +12,8 @@
#error "CONFIG_MAX_REBOOT_CNT too high"
#endif
+#define RTC_BOOT_NORMAL 0x1
+
static int cmos_error(void)
{
unsigned char reg_d;
@@ -41,12 +43,28 @@ static int cmos_chksum_valid(void)
#endif
}
+static inline __attribute__((unused)) int boot_count(void)
+{
+ unsigned char byte;
+ byte = cmos_read(RTC_BOOT_BYTE);
+ return byte >> 4;
+}
+
+static inline __attribute__((unused)) void increment_boot_count(uint8_t &rtc_byte)
+{
+ rtc_byte += (1 << 4);
+}
+
+static inline __attribute__((unused)) void boot_use_fallback(uint8_t &rtc_byte)
+{
+ rtc_byte &= ~RTC_BOOT_NORMAL;
+}
static inline __attribute__((unused)) int last_boot_normal(void)
{
unsigned char byte;
byte = cmos_read(RTC_BOOT_BYTE);
- return (byte & (1 << 1));
+ return (byte & RTC_BOOT_NORMAL);
}
static inline __attribute__((unused)) int do_normal_boot(void)
@@ -59,7 +77,7 @@ static inline __attribute__((unused)) int do_normal_boot(void)
* but clear the fallback bit.
*/
byte = cmos_read(RTC_BOOT_BYTE);
- byte &= 0x0c;
+ byte &= RTC_BOOT_NORMAL;
byte |= CONFIG_MAX_REBOOT_CNT << 4;
cmos_write(byte, RTC_BOOT_BYTE);
}
@@ -67,29 +85,21 @@ static inline __attribute__((unused)) int do_normal_boot(void)
/* The RTC_BOOT_BYTE is now o.k. see where to go. */
byte = cmos_read(RTC_BOOT_BYTE);
- if (!IS_ENABLED(CONFIG_SKIP_MAX_REBOOT_CNT_CLEAR))
- /* Are we in normal mode? */
- if (byte & 1)
- byte &= 0x0f; /* yes, clear the boot count */
-
- /* Properly set the last boot flag */
- byte &= 0xfc;
- if ((byte >> 4) < CONFIG_MAX_REBOOT_CNT) {
- byte |= (1<<1);
- }
-
- /* Are we already at the max count? */
- if ((byte >> 4) < CONFIG_MAX_REBOOT_CNT) {
- byte += 1 << 4; /* No, add 1 to the count */
- }
- else {
- byte &= 0xfc; /* Yes, put in fallback mode */
+ /* Are we attempting to boot normally? */
+ if (byte & RTC_BOOT_NORMAL) {
+ /* Are we already at the max count? */
+ if (boot_count() < CONFIG_MAX_REBOOT_CNT) {
+ increment_boot_count(byte)
+ } else {
+ boot_use_fallback(byte);
+ }
}
/* Save the boot byte */
cmos_write(byte, RTC_BOOT_BYTE);
- return (byte & (1<<1));
+ /* Return selected code path for this boot attempt */
+ return (byte & RTC_BOOT_NORMAL);
}
unsigned read_option_lowlevel(unsigned start, unsigned size, unsigned def)
Patrick Rudolph (siro(a)das-labor.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11918
-gerrit
commit 10cc3f8111bcc7b7a747e67f5d634eec03250de2
Author: Patrick Rudolph <siro(a)das-labor.org>
Date: Thu Oct 15 15:33:25 2015 +0200
nb/intel/sandybridge/northbridge: Initialize uma_memory_base in all cases
Issue observed:
Coreboot stops at: "Not enough MTRRs available!"
Test system:
* Gigabyte GA-B75M-D3H
* Intel Pentium CPU G2130
* ATI Radeon HD4780
Problem description:
In case the IGD does not claim VGA decode, the code path taken results
in an integer overflow as uma_memory_base isn't initialized.
The MTRR assignment will fail, because of invalid memory regions.
Problem solution:
Properly initialize uma_memory_base to prevent possible integer overflow.
Final testing results:
The system boots again with IGD not claiming VGA decode.
Change-Id: I025be23b1defb6155469a3eee66569e49a695e7f
Signed-off-by: Patrick Rudolph <siro(a)das-labor.org>
---
src/northbridge/intel/sandybridge/northbridge.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/northbridge/intel/sandybridge/northbridge.c b/src/northbridge/intel/sandybridge/northbridge.c
index 76f03f3..5c1f366 100644
--- a/src/northbridge/intel/sandybridge/northbridge.c
+++ b/src/northbridge/intel/sandybridge/northbridge.c
@@ -189,6 +189,7 @@ static void pci_domain_set_resources(device_t dev)
printk(BIOS_DEBUG, "MEBASE 0x%llx\n", me_base);
+ uma_memory_base = tolud;
tomk = tolud >> 10;
if (me_base == tolud) {
/* ME is from MEBASE-TOM */
Patrick Rudolph (siro(a)das-labor.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11917
-gerrit
commit aa5a4dbf869a264089f4a72172c8b154d3c859ec
Author: Patrick Rudolph <siro(a)das-labor.org>
Date: Thu Oct 15 11:09:15 2015 +0200
[NEEDS TEST] nb/intel/sandybridge: start PEG link training
Issue observed:
The PCIe Root port shows up in GNU/Linux but no device.
Test system:
* Gigabyte GA-B75M-D3H (Intel Pentium CPU G2130)
* Lenovo T530 (Intel Core i5-3320M CPU)
Problem description:
The PEG Root port link training on Ivy Bridge needs to be started by hand.
(The PEG Root port on Sandy Bridge works out of the box.)
Problem solution:
The bits are set in early_init to meet PCIe reset timeout of 100msec.
The bits should be set in PCI device enable function, but this causes the
PCI enumeration to not detect the card, as it's still booting. Adding
a fixed delay of 100msec resolves this problem, but this would
increase boot time.
Tested with:
* Nvidia NVS 5400M (PCIe2)
* ATI Radeon HD4780 (PCIe2)
* Nvidia GeForce 8600 GT (PCIe1)
Untested:
* PCIe3 devices
Final test results:
The PEG device shows up under GNU/Linux and can be used without issues.
Change-Id: Id8cfc43e5c4630b0ac217d98bb857c3308e6015b
Signed-off-by: Patrick Rudolph <siro(a)das-labor.org>
---
src/northbridge/intel/sandybridge/early_init.c | 42 ++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/src/northbridge/intel/sandybridge/early_init.c b/src/northbridge/intel/sandybridge/early_init.c
index b3a829d..7e5ace6 100644
--- a/src/northbridge/intel/sandybridge/early_init.c
+++ b/src/northbridge/intel/sandybridge/early_init.c
@@ -148,6 +148,39 @@ static void sandybridge_setup_graphics(void)
MCHBAR32(0x5418) = reg32;
}
+static void start_peg_link_training(void)
+{
+ u32 tmp;
+ u32 deven;
+
+ /* skip on SandyBridge */
+ if ((pci_read_config16(PCI_DEV(0, 0, 0), PCI_DEVICE_ID) &
+ BASE_REV_MASK) != BASE_REV_IVB)
+ return;
+
+ deven = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
+
+ if (deven & DEVEN_PEG10) {
+ tmp = pci_read_config32(PCI_DEV(0, 1, 0), 0xC24) & ~(1 << 16);
+ pci_write_config32(PCI_DEV(0, 1, 0), 0xC24, tmp | (1 << 5));
+ }
+
+ if (deven & DEVEN_PEG11) {
+ tmp = pci_read_config32(PCI_DEV(0, 1, 1), 0xC24) & ~(1 << 16);
+ pci_write_config32(PCI_DEV(0, 1, 1), 0xC24, tmp | (1 << 5));
+ }
+
+ if (deven & DEVEN_PEG12) {
+ tmp = pci_read_config32(PCI_DEV(0, 1, 2), 0xC24) & ~(1 << 16);
+ pci_write_config32(PCI_DEV(0, 1, 2), 0xC24, tmp | (1 << 5));
+ }
+
+ if (deven & DEVEN_PEG60) {
+ tmp = pci_read_config32(PCI_DEV(0, 6, 0), 0xC24) & ~(1 << 16);
+ pci_write_config32(PCI_DEV(0, 6, 0), 0xC24, tmp | (1 << 5));
+ }
+}
+
void sandybridge_early_initialization(int chipset_type)
{
u32 capid0_a;
@@ -174,6 +207,15 @@ void sandybridge_early_initialization(int chipset_type)
pci_write_config32(PCI_DEV(0, 0, 0), DEVEN, deven);
sandybridge_setup_graphics();
+
+ /* Write magic value to start PEG link training.
+ * This should be done in PCI device enumeration, but
+ * the PCIe specification requires to wait at least 100msec
+ * after reset for devices to come up.
+ * As we don't want to increase boot time, enable it early and
+ * assume the PEG is up as soon as PCI enumeration starts.
+ * TODO: use time stamps to ensure the timings are met */
+ start_peg_link_training();
}
void northbridge_romstage_finalize(int s3resume)