the following patch was just integrated into master:
commit 7bed96e2243371b71678a1200e0108741deafe6f
Author: Paul Menzel <paulepanter(a)users.sourceforge.net>
Date: Sat Jan 25 15:55:28 2014 +0100
src/cpu: Fix spelling of MTTR to MTRR
Change-Id: Ia4718ac31a5b2bd12f8cda5e107aa878d74d2a03
Signed-off-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
See http://review.coreboot.org/4805 for details.
-gerrit
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4807
-gerrit
commit 677d5f77d310af10e427a76aff48a21906c01b69
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Sat Jan 25 09:40:54 2014 -0600
fintek/f81865f: Deprecate the C inclusion of early_serial.c
Including "early_serial.c" directly in romstage.c rather than
compiling and linking it is a remnant of ROMCC. Modernize this by
declaring "early_serial.c" as a Makefile.inc object, and no longer
use it by direct inclusion.
Change-Id: I40a6646fedaad5371983bfc6e6e990c4932ec9bd
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/mainboard/amd/persimmon/romstage.c | 2 +-
src/mainboard/amd/south_station/romstage.c | 2 +-
src/mainboard/via/epia-m850/Makefile.inc | 22 +----------
src/mainboard/via/epia-m850/romstage.c | 4 +-
src/superio/fintek/f81865f/Makefile.inc | 1 +
src/superio/fintek/f81865f/early_serial.c | 48 +++++++++++++++++++++++
src/superio/fintek/f81865f/f81865f.h | 2 +
src/superio/fintek/f81865f/f81865f_early_serial.c | 47 ----------------------
8 files changed, 56 insertions(+), 72 deletions(-)
diff --git a/src/mainboard/amd/persimmon/romstage.c b/src/mainboard/amd/persimmon/romstage.c
index 98c64ed..e082f60 100644
--- a/src/mainboard/amd/persimmon/romstage.c
+++ b/src/mainboard/amd/persimmon/romstage.c
@@ -31,7 +31,7 @@
#include <cpu/x86/mtrr.h>
#include "agesawrapper.h"
#include "cpu/x86/bist.h"
-#include "superio/fintek/f81865f/f81865f_early_serial.c"
+#include <superio/fintek/f81865f/f81865f.h>
#include "cpu/x86/lapic.h"
#include "drivers/pc80/i8254.c"
#include "drivers/pc80/i8259.c"
diff --git a/src/mainboard/amd/south_station/romstage.c b/src/mainboard/amd/south_station/romstage.c
index 20c973c..5614f88 100644
--- a/src/mainboard/amd/south_station/romstage.c
+++ b/src/mainboard/amd/south_station/romstage.c
@@ -32,7 +32,7 @@
#include <cpu/x86/mtrr.h>
#include "agesawrapper.h"
#include "cpu/x86/bist.h"
-#include "superio/fintek/f81865f/f81865f_early_serial.c"
+#include <superio/fintek/f81865f/f81865f.h>
#include "cpu/x86/lapic.h"
#include <sb_cimx.h>
#include "SBPLATFORM.h"
diff --git a/src/mainboard/via/epia-m850/Makefile.inc b/src/mainboard/via/epia-m850/Makefile.inc
index 9c6d31f..e9a0b69 100644
--- a/src/mainboard/via/epia-m850/Makefile.inc
+++ b/src/mainboard/via/epia-m850/Makefile.inc
@@ -1,21 +1 @@
-##
-## This file is part of the coreboot project.
-##
-## Copyright (C) 2011 Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
-##
-## 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, either version 2 of the License, or
-## (at your option) any later version.
-##
-## 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, see <http://www.gnu.org/licenses/>.
-##
-
-#romstage-y += ./../../../superio/fintek/f81865f/f81865f_early_serial.c
-
+# Nothing interesting here yet
diff --git a/src/mainboard/via/epia-m850/romstage.c b/src/mainboard/via/epia-m850/romstage.c
index 262bee7..1114cf4 100644
--- a/src/mainboard/via/epia-m850/romstage.c
+++ b/src/mainboard/via/epia-m850/romstage.c
@@ -33,11 +33,11 @@
#include <string.h>
#include <timestamp.h>
#include <console/cbmem_console.h>
+#include <superio/fintek/f81865f/f81865f.h>
#include "northbridge/via/vx900/early_vx900.h"
#include "northbridge/via/vx900/raminit.h"
-/* FIXME: This is the only .c include we couldn't get rid of */
-#include "superio/fintek/f81865f/f81865f_early_serial.c"
+
#define SERIAL_DEV PNP_DEV(0x4e, 0x10)
diff --git a/src/superio/fintek/f81865f/Makefile.inc b/src/superio/fintek/f81865f/Makefile.inc
index 1700f7c..8afb286 100644
--- a/src/superio/fintek/f81865f/Makefile.inc
+++ b/src/superio/fintek/f81865f/Makefile.inc
@@ -18,4 +18,5 @@
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
##
+romstage-$(CONFIG_SUPERIO_FINTEK_F81865F) += early_serial.c
ramstage-$(CONFIG_SUPERIO_FINTEK_F81865F) += superio.c
diff --git a/src/superio/fintek/f81865f/early_serial.c b/src/superio/fintek/f81865f/early_serial.c
new file mode 100644
index 0000000..29b5f9d
--- /dev/null
+++ b/src/superio/fintek/f81865f/early_serial.c
@@ -0,0 +1,48 @@
+/*
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/* Pre-RAM driver for the Fintek F81865F/FG Super I/O chip. */
+
+#include <arch/io.h>
+#include <device/pnp.h>
+#include "f81865f.h"
+
+static void pnp_enter_conf_state(device_t dev)
+{
+ u16 port = dev >> 8;
+ outb(0x87, port);
+ outb(0x87, port);
+}
+
+static void pnp_exit_conf_state(device_t dev)
+{
+ u16 port = dev >> 8;
+ outb(0xaa, port);
+}
+
+void f81865f_enable_serial(device_t dev, u16 iobase)
+{
+ pnp_enter_conf_state(dev);
+ pnp_set_logical_device(dev);
+ pnp_set_enable(dev, 0);
+ pnp_set_iobase(dev, PNP_IDX_IO0, iobase);
+ pnp_set_enable(dev, 1);
+ pnp_exit_conf_state(dev);
+}
diff --git a/src/superio/fintek/f81865f/f81865f.h b/src/superio/fintek/f81865f/f81865f.h
index 0c36571..7269b59 100644
--- a/src/superio/fintek/f81865f/f81865f.h
+++ b/src/superio/fintek/f81865f/f81865f.h
@@ -35,4 +35,6 @@
#define F81865F_GPIO 0x06 /* General Purpose I/O (GPIO) */
#define F81865F_PME 0x0a /* Power Management Events (PME) */
+void f81865f_enable_serial(device_t dev, u16 iobase);
+
#endif
diff --git a/src/superio/fintek/f81865f/f81865f_early_serial.c b/src/superio/fintek/f81865f/f81865f_early_serial.c
deleted file mode 100644
index 2989b5f..0000000
--- a/src/superio/fintek/f81865f/f81865f_early_serial.c
+++ /dev/null
@@ -1,47 +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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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
- */
-
-/* Pre-RAM driver for the Fintek F81865F/FG Super I/O chip. */
-
-#include <arch/io.h>
-#include "f81865f.h"
-
-static void pnp_enter_conf_state(device_t dev)
-{
- u16 port = dev >> 8;
- outb(0x87, port);
- outb(0x87, port);
-}
-
-static void pnp_exit_conf_state(device_t dev)
-{
- u16 port = dev >> 8;
- outb(0xaa, port);
-}
-
-static void f81865f_enable_serial(device_t dev, u16 iobase)
-{
- pnp_enter_conf_state(dev);
- pnp_set_logical_device(dev);
- pnp_set_enable(dev, 0);
- pnp_set_iobase(dev, PNP_IDX_IO0, iobase);
- pnp_set_enable(dev, 1);
- pnp_exit_conf_state(dev);
-}
Paul Menzel (paulepanter(a)users.sourceforge.net) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4805
-gerrit
commit 7bed96e2243371b71678a1200e0108741deafe6f
Author: Paul Menzel <paulepanter(a)users.sourceforge.net>
Date: Sat Jan 25 15:55:28 2014 +0100
src/cpu: Fix spelling of MTTR to MTRR
Change-Id: Ia4718ac31a5b2bd12f8cda5e107aa878d74d2a03
Signed-off-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
---
src/cpu/intel/haswell/cache_as_ram.inc | 12 ++++++------
src/cpu/intel/haswell/haswell.h | 16 ++++++++--------
src/cpu/intel/haswell/romstage.c | 20 ++++++++++----------
src/cpu/x86/mtrr/earlymtrr.c | 2 +-
src/cpu/x86/mtrr/mtrr.c | 6 +++---
5 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/src/cpu/intel/haswell/cache_as_ram.inc b/src/cpu/intel/haswell/cache_as_ram.inc
index 2d1e86f..36d5654 100644
--- a/src/cpu/intel/haswell/cache_as_ram.inc
+++ b/src/cpu/intel/haswell/cache_as_ram.inc
@@ -185,7 +185,7 @@ before_romstage:
call romstage_main
/* Save return value from romstage_main. It contains the stack to use
* after cache-as-ram is torn down. It also contains the information
- * for setting up MTTRs. */
+ * for setting up MTRRs. */
movl %eax, %ebx
post_code(0x2f)
@@ -249,23 +249,23 @@ before_romstage:
/* Setup stack as indicated by return value from ramstage_main(). */
movl %ebx, %esp
- /* Get number of MTTRs. */
+ /* Get number of MTRRs. */
popl %ebx
movl $MTRRphysBase_MSR(0), %ecx
1:
testl %ebx, %ebx
jz 1f
- /* Low 32 bits of MTTR base. */
+ /* Low 32 bits of MTRR base. */
popl %eax
- /* Upper 32 bits of MTTR base. */
+ /* Upper 32 bits of MTRR base. */
popl %edx
/* Write MTRR base. */
wrmsr
inc %ecx
- /* Low 32 bits of MTTR mask. */
+ /* Low 32 bits of MTRR mask. */
popl %eax
- /* Upper 32 bits of MTTR mask. */
+ /* Upper 32 bits of MTRR mask. */
popl %edx
/* Write MTRR mask. */
wrmsr
diff --git a/src/cpu/intel/haswell/haswell.h b/src/cpu/intel/haswell/haswell.h
index 9ed00af..dcd5dc7 100644
--- a/src/cpu/intel/haswell/haswell.h
+++ b/src/cpu/intel/haswell/haswell.h
@@ -175,14 +175,14 @@ void romstage_common(const struct romstage_params *params);
* torn down. The following values are pushed onto the stack to setup the
* MTRRs:
* +0: Number of MTRRs
- * +4: MTTR base 0 31:0
- * +8: MTTR base 0 63:32
- * +12: MTTR mask 0 31:0
- * +16: MTTR mask 0 63:32
- * +20: MTTR base 1 31:0
- * +24: MTTR base 1 63:32
- * +28: MTTR mask 1 31:0
- * +32: MTTR mask 1 63:32
+ * +4: MTRR base 0 31:0
+ * +8: MTRR base 0 63:32
+ * +12: MTRR mask 0 31:0
+ * +16: MTRR mask 0 63:32
+ * +20: MTRR base 1 31:0
+ * +24: MTRR base 1 63:32
+ * +28: MTRR mask 1 31:0
+ * +32: MTRR mask 1 63:32
* ...
*/
void * asmlinkage romstage_main(unsigned long bist);
diff --git a/src/cpu/intel/haswell/romstage.c b/src/cpu/intel/haswell/romstage.c
index edb2e80..40a396d 100644
--- a/src/cpu/intel/haswell/romstage.c
+++ b/src/cpu/intel/haswell/romstage.c
@@ -108,18 +108,18 @@ static void *setup_romstage_stack_after_car(void)
* of physical address bits. */
mtrr_mask_upper = (1 << ((cpuid_eax(0x80000008) & 0xff) - 32)) - 1;
- /* The order for each MTTR is value then base with upper 32-bits of
+ /* The order for each MTRR is value then base with upper 32-bits of
* each value coming before the lower 32-bits. The reasoning for
* this ordering is to create a stack layout like the following:
* +0: Number of MTRRs
- * +4: MTTR base 0 31:0
- * +8: MTTR base 0 63:32
- * +12: MTTR mask 0 31:0
- * +16: MTTR mask 0 63:32
- * +20: MTTR base 1 31:0
- * +24: MTTR base 1 63:32
- * +28: MTTR mask 1 31:0
- * +32: MTTR mask 1 63:32
+ * +4: MTRR base 0 31:0
+ * +8: MTRR base 0 63:32
+ * +12: MTRR mask 0 31:0
+ * +16: MTRR mask 0 63:32
+ * +20: MTRR base 1 31:0
+ * +24: MTRR base 1 63:32
+ * +28: MTRR mask 1 31:0
+ * +32: MTRR mask 1 63:32
*/
/* Cache the ROM as WP just below 4GiB. */
@@ -158,7 +158,7 @@ static void *setup_romstage_stack_after_car(void)
slot = stack_push(slot, top_of_ram | MTRR_TYPE_WRBACK);
num_mtrrs++;
- /* Save the number of MTTRs to setup. Return the stack location
+ /* Save the number of MTRRs to setup. Return the stack location
* pointing to the number of MTRRs. */
slot = stack_push(slot, num_mtrrs);
diff --git a/src/cpu/x86/mtrr/earlymtrr.c b/src/cpu/x86/mtrr/earlymtrr.c
index 36f94cd..0471a9e 100644
--- a/src/cpu/x86/mtrr/earlymtrr.c
+++ b/src/cpu/x86/mtrr/earlymtrr.c
@@ -30,7 +30,7 @@ static void cache_ramstage(void)
const int addr_det = 0;
-/* the fixed and variable MTTRs are power-up with random values,
+/* the fixed and variable MTRRs are power-up with random values,
* clear them to MTRR_TYPE_UNCACHEABLE for safety.
*/
static void do_early_mtrr_init(const unsigned long *mtrr_msrs)
diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c
index dd404a8..dbedf0f 100644
--- a/src/cpu/x86/mtrr/mtrr.c
+++ b/src/cpu/x86/mtrr/mtrr.c
@@ -454,7 +454,7 @@ static void write_var_mtrr(struct var_mtrr_state *var_state,
if (var_state->mtrr_index >= bios_mtrrs)
printk(BIOS_WARNING, "Taking a reserved OS MTRR.\n");
if (var_state->mtrr_index >= total_mtrrs) {
- printk(BIOS_ERR, "ERROR: Not enough MTTRs available!\n");
+ printk(BIOS_ERR, "ERROR: Not enough MTRRs available!\n");
return;
}
@@ -670,7 +670,7 @@ static int calc_var_mtrrs(struct memranges *addr_space,
struct var_mtrr_state var_state;
/* The default MTRR cacheability type is determined by calculating
- * the number of MTTRs required for each MTTR type as if it was the
+ * the number of MTRRs required for each MTRR type as if it was the
* default. */
var_state.addr_space = addr_space;
var_state.above4gb = above4gb;
@@ -776,7 +776,7 @@ static void commit_var_mtrrs(struct memranges *addr_space, int def_type,
calc_var_mtrrs_without_hole(&var_state, r);
}
- /* Clear all remaining variable MTTRs. */
+ /* Clear all remaining variable MTRRs. */
for (i = var_state.mtrr_index; i < total_mtrrs; i++)
clear_var_mtrr(i);
}
Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4817
-gerrit
commit 3a94667e934c1e6ce022f4b0f870b5a104bbcbc1
Author: Ronald G. Minnich <rminnich(a)google.com>
Date: Tue Dec 3 11:13:35 2013 -0800
cbfs: fix issues with word size and endianness.
Add XDR functions and use them to convert the ELF headers
to native headers, using the Elf64 structs to ensure we accomodate
all word sizes. Also, use these XDR functions for output.
This may seem overly complex but it turned out to be much the easiest
way to do this. Note that the basic elf parsing function
in cbfs-mkstage.c now works over all ELF files, for all architectures,
endian, and word size combinations. At the same time, the basic elf parsing
in cbfs-mkstage.c is a loop that has no architecture-specific conditionals.
Add -g to the LDFLAGS while we're here. It's on the CFLAGS so there is no
harm done.
This code has been tested on all chromebooks that use coreboot to date.
BUG=None
TEST=Build and boot for Peppy; works fine. Build and boot for nyan, works fine. Build for qemu targets and armv8 targets.
BRANCH=None
Change-Id: I5a4cee9854799189115ac701e22efc406a8d902f
Signed-off-by: Ronald G. Minnich <rminnich(a)google.com>
Reviewed-on: https://chromium-review.googlesource.com/178606
Reviewed-by: Ronald Minnich <rminnich(a)chromium.org>
Commit-Queue: Ronald Minnich <rminnich(a)chromium.org>
Tested-by: Ronald Minnich <rminnich(a)chromium.org>
---
util/cbfstool/Makefile | 12 +-
util/cbfstool/Makefile.inc | 1 +
util/cbfstool/cbfs-mkstage.c | 347 +++++++++++++++++++++++++++++++++++--------
util/cbfstool/common.h | 15 ++
util/cbfstool/xdr.c | 141 ++++++++++++++++++
5 files changed, 452 insertions(+), 64 deletions(-)
diff --git a/util/cbfstool/Makefile b/util/cbfstool/Makefile
index 3aa5edc..c9c940d 100644
--- a/util/cbfstool/Makefile
+++ b/util/cbfstool/Makefile
@@ -1,13 +1,17 @@
obj ?= $(shell pwd)
-HOSTCC ?= gcc
-CFLAGS ?= -g -Wall -Werror
-CFLAGS += -D_7ZIP_ST
+HOSTCC ?= gcc
+CFLAGS ?= -g
+CFLAGS += -D_7ZIP_ST
+CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wmissing-prototypes
+CFLAGS += -Wwrite-strings -Wredundant-decls -Wno-trigraphs
+CFLAGS += -Wstrict-aliasing -Wshadow -Werror
+LDFLAGS += -g
BINARY:=$(obj)/cbfstool
COMMON:=cbfstool.o common.o cbfs_image.o compress.o fit.o
-COMMON+=cbfs-mkstage.o cbfs-mkpayload.o
+COMMON+=cbfs-mkstage.o cbfs-mkpayload.o xdr.o
# LZMA
COMMON+=lzma/lzma.o
COMMON+=lzma/C/LzFind.o lzma/C/LzmaDec.o lzma/C/LzmaEnc.o
diff --git a/util/cbfstool/Makefile.inc b/util/cbfstool/Makefile.inc
index fc120f3..4270d75 100644
--- a/util/cbfstool/Makefile.inc
+++ b/util/cbfstool/Makefile.inc
@@ -5,6 +5,7 @@ cbfsobj += compress.o
cbfsobj += cbfs_image.o
cbfsobj += cbfs-mkstage.o
cbfsobj += cbfs-mkpayload.o
+cbfsobj += xdr.o
cbfsobj += fit.o
# LZMA
cbfsobj += lzma.o
diff --git a/util/cbfstool/cbfs-mkstage.c b/util/cbfstool/cbfs-mkstage.c
index dfc93c2..05f8283 100644
--- a/util/cbfstool/cbfs-mkstage.c
+++ b/util/cbfstool/cbfs-mkstage.c
@@ -28,46 +28,204 @@
#include "cbfs.h"
#include "elf.h"
-static unsigned int idemp(unsigned int x)
-{
- return x;
-}
+/*
+ * Short form: this is complicated, but we've tried making it simple
+ * and we keep hitting problems with our ELF parsing.
+ *
+ * The ELF parsing situation has always been a bit tricky. In fact,
+ * we (and most others) have been getting it wrong in small ways for
+ * years. Recently this has caused real trouble for the ARM V8 build.
+ * In this file we attempt to finally get it right for all variations
+ * of endian-ness and word size and target architectures and
+ * architectures we might get run on. Phew!. To do this we borrow a
+ * page from the FreeBSD NFS xdr model (see elf_ehdr and elf_phdr),
+ * the Plan 9 endianness functions (see xdr.c), and Go interfaces (see
+ * how we use buffer structs in this file). This ends up being a bit
+ * wordy at the lowest level, but greatly simplifies the elf parsing
+ * code and removes a common source of bugs, namely, forgetting to
+ * flip type endianness when referencing a struct member.
+ *
+ * ELF files can have four combinations of data layout: 32/64, and
+ * big/little endian. Further, to add to the fun, depending on the
+ * word size, the size of the ELF structs varies. The coreboot SELF
+ * format is simpler in theory: it's supposed to be always BE, and the
+ * various struct members allow room for growth: the entry point is
+ * always 64 bits, for example, so the size of a SELF struct is
+ * constant, regardless of target architecture word size. Hence, we
+ * need to do some transformation of the ELF files.
+ *
+ * A given architecture, realistically, only supports one of the four
+ * combinations at a time as the 'native' format. Hence, our code has
+ * been sprinkled with every variation of [nh]to[hn][sll] over the
+ * years. We've never quite gotten it all right, however, and a quick
+ * pass over this code revealed another bug. It's all worked because,
+ * until now, all the working platforms that had CBFS were 32 LE. Even then,
+ * however, bugs crept in: we recently realized that we're not
+ * transforming the entry point to big format when we store into the
+ * SELF image.
+ *
+ * The problem is essentially an XDR operation:
+ * we have something in a foreign format and need to transform it.
+ * It's most like XDR because:
+ * 1) the byte order can be wrong
+ * 2) the word size can be wrong
+ * 3) the size of elements in the stream depends on the value
+ * of other elements in the stream
+ * it's not like XDR because:
+ * 1) the byte order can be right
+ * 2) the word size can be right
+ * 3) the struct members are all on a natural alignment
+ *
+ * Hence, this new approach. To cover word size issues, we *always*
+ * transform the two structs we care about, the file header and
+ * program header, into a native struct in the 64 bit format:
+ *
+ * [32,little] -> [Elf64_Ehdr, Elf64_Phdr]
+ * [64,little] -> [Elf64_Ehdr, Elf64_Phdr]
+ * [32,big] -> [Elf64_Ehdr, Elf64_Phdr]
+ * [64,big] -> [Elf64_Ehdr, Elf64_Phdr]
+ * Then we just use those structs, and all the need for inline ntoh* goes away,
+ * as well as all the chances for error.
+ * This works because all the SELF structs have fields large enough for
+ * the largest ELF 64 struct members, and all the Elf64 struct members
+ * are at least large enough for all ELF 32 struct members.
+ * We end up with one function to do all our ELF parsing, and two functions
+ * to transform the headers. For the put case, we also have
+ * XDR functions, and hopefully we'll never again spend 5 years with the
+ * wrong endian-ness on an output value :-)
+ * This should work for all word sizes and endianness we hope to target.
+ * I *really* don't want to be here for 128 bit addresses.
+ *
+ * The parse functions are called with a pointer to an input buffer
+ * struct. One might ask: are there enough bytes in the input buffer?
+ * We know there need to be at *least* sizeof(Elf32_Ehdr) +
+ * sizeof(Elf32_Phdr) bytes. Realistically, there has to be some data
+ * too. If we start to worry, though we have not in the past, we
+ * might apply the simple test: the input buffer needs to be at least
+ * sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) bytes because, even if it's
+ * ELF 32, there's got to be *some* data! This is not theoretically
+ * accurate but it is actually good enough in practice. It allows the
+ * header transformation code to ignore the possibility of underrun.
+ *
+ * We also must accomodate different ELF files, and hence formats,
+ * in the same cbfs invocation. We might load a 64-bit payload
+ * on a 32-bit machine; we might even have a mixed armv7/armv8
+ * SOC or even a system with an x86/ARM!
+ *
+ * A possibly problematic (though unlikely to be so) assumption
+ * is that we expect the BIOS to remain in the lowest 32 bits
+ * of the physical address space. Since ARMV8 has standardized
+ * on that, and x86_64 also has, this seems a safe assumption.
+ *
+ * To repeat, ELF structs are different sizes because ELF struct
+ * members are different sizes, depending on values in the ELF file
+ * header. For this we use the functions defined in xdr.c, which
+ * consume bytes, convert the endianness, and advance the data pointer
+ * in the buffer struct.
+ */
-/* This is a wrapper around the swab32() macro to make it
- * usable for the current implementation of parse_elf_to_stage()
+/* Get the ident array, so we can figure out
+ * endian-ness, word size, and in future other useful
+ * parameters
*/
-static unsigned int swap32(unsigned int x)
+static void
+elf_eident(struct buffer *input, Elf64_Ehdr *ehdr)
{
- return swab32(x);
+ memmove(ehdr->e_ident, input->data, sizeof(ehdr->e_ident));
+ input->data += sizeof(ehdr->e_ident);
+ input->size -= sizeof(ehdr->e_ident);
}
-unsigned int (*elf32_to_native) (unsigned int) = idemp;
-/* returns size of result, or -1 if error */
-int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
- comp_algo algo, uint32_t *location)
+static void
+elf_ehdr(struct buffer *input, Elf64_Ehdr *ehdr, struct xdr *xdr, int bit64)
{
- Elf32_Phdr *phdr;
- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)input->data;
- char *header, *buffer;
-
- int headers;
- int i;
- struct cbfs_stage *stage;
- unsigned int data_start, data_end, mem_end;
+ ehdr->e_type = xdr->get16(input);
+ ehdr->e_machine = xdr->get16(input);
+ ehdr->e_version = xdr->get32(input);
+ if (bit64){
+ ehdr->e_entry = xdr->get64(input);
+ ehdr->e_phoff = xdr->get64(input);
+ ehdr->e_shoff = xdr->get64(input);
+ } else {
+ ehdr->e_entry = xdr->get32(input);
+ ehdr->e_phoff = xdr->get32(input);
+ ehdr->e_shoff = xdr->get32(input);
+ }
+ ehdr->e_flags = xdr->get32(input);
+ ehdr->e_ehsize = xdr->get16(input);
+ ehdr->e_phentsize = xdr->get16(input);
+ ehdr->e_phnum = xdr->get16(input);
+ ehdr->e_shentsize = xdr->get16(input);
+ ehdr->e_shnum = xdr->get16(input);
+ ehdr->e_shstrndx = xdr->get16(input);
+}
- int elf_bigendian = 0;
+static void
+elf_phdr(struct buffer *pinput, Elf64_Phdr *phdr,
+ int entsize, struct xdr *xdr, int bit64)
+{
+ /*
+ * The entsize need not be sizeof(*phdr).
+ * Hence, it is easier to keep a copy of the input,
+ * as the xdr functions may not advance the input
+ * pointer the full entsize; rather than get tricky
+ * we just advance it below.
+ */
+ struct buffer input = *pinput;
+ if (bit64){
+ phdr->p_type = xdr->get32(&input);
+ phdr->p_flags = xdr->get32(&input);
+ phdr->p_offset = xdr->get64(&input);
+ phdr->p_vaddr = xdr->get64(&input);
+ phdr->p_paddr = xdr->get64(&input);
+ phdr->p_filesz = xdr->get64(&input);
+ phdr->p_memsz = xdr->get64(&input);
+ phdr->p_align = xdr->get64(&input);
+ } else {
+ phdr->p_type = xdr->get32(&input);
+ phdr->p_offset = xdr->get32(&input);
+ phdr->p_vaddr = xdr->get32(&input);
+ phdr->p_paddr = xdr->get32(&input);
+ phdr->p_filesz = xdr->get32(&input);
+ phdr->p_memsz = xdr->get32(&input);
+ phdr->p_flags = xdr->get32(&input);
+ phdr->p_align = xdr->get32(&input);
+ }
+ pinput->size -= entsize;
+ pinput->data += entsize;
+}
- comp_func_ptr compress = compression_function(algo);
- if (!compress)
- return -1;
+/* Get the headers from the buffer.
+ * Return -1 in the event of an error.
+ */
+static int
+elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr)
+{
+ int i;
+ struct xdr *xdr = &xdr_le;
+ int bit64 = 0;
+ struct buffer input = *(struct buffer *)pinput;
+ struct buffer phdr_buf;
+ Elf64_Phdr *phdr;
- DEBUG("start: parse_elf_to_stage(location=0x%x)\n", *location);
- if (!iself((unsigned char *)input->data)) {
+ if (!iself((unsigned char *)pinput->data)) {
ERROR("The stage file is not in ELF format!\n");
return -1;
}
+ elf_eident(&input, ehdr);
+ bit64 = ehdr->e_ident[EI_CLASS] == ELFCLASS64;
+ /* Assume LE unless we are sure otherwise.
+ * We're not going to take on the task of
+ * fully validating the ELF file. That way
+ * lies madness.
+ */
+ if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
+ xdr = &xdr_be;
+
+ elf_ehdr(&input, ehdr, xdr, bit64);
+
// The tool may work in architecture-independent way.
if (arch != CBFS_ARCHITECTURE_UNKNOWN &&
!((ehdr->e_machine == EM_ARM) && (arch == CBFS_ARCHITECTURE_ARMV7)) &&
@@ -76,42 +234,84 @@ int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
return -1;
}
- if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
- elf_bigendian = 1;
+ if (pinput->size < ehdr->e_phoff){
+ ERROR("The program header offset is greater than "
+ "the remaining file size."
+ "%ld bytes left, program header offset is %ld \n",
+ pinput->size, ehdr->e_phoff);
+ return -1;
}
- if (elf_bigendian != is_big_endian()) {
- elf32_to_native = swap32;
+ /* cons up an input buffer for the headers.
+ * Note that the program headers can be anywhere,
+ * per the ELF spec, You'd be surprised how many ELF
+ * readers miss this little detail.
+ */
+ phdr_buf.data = &pinput->data[ehdr->e_phoff];
+ phdr_buf.size = ehdr->e_phentsize * ehdr->e_phnum;
+ if (phdr_buf.size > (pinput->size - ehdr->e_phoff)){
+ ERROR("The file is not large enough for the program headers."
+ "%ld bytes left, %ld bytes of headers\n",
+ pinput->size - ehdr->e_phoff, phdr_buf.size);
+ return -1;
}
+ /* gather up all the phdrs.
+ * We do them all at once because there is more
+ * than one loop over all the phdrs.
+ */
+ phdr = calloc(sizeof(*phdr), ehdr->e_phnum);
+ for (i = 0; i < ehdr->e_phnum; i++)
+ elf_phdr(&phdr_buf, &phdr[i], ehdr->e_phentsize, xdr, bit64);
+ *pphdr = phdr;
+ return 0;
+}
- headers = ehdr->e_phnum;
- header = (char *)ehdr;
+/* returns size of result, or -1 if error.
+ * Note that, with the new code, this function
+ * works for all elf files, not just the restricted set.
+ */
+int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
+ comp_algo algo, uint32_t *location)
+{
+ Elf64_Phdr *phdr;
+ Elf64_Ehdr ehdr;
+ char *buffer;
+ struct buffer outheader;
- phdr = (Elf32_Phdr *) & header[elf32_to_native(ehdr->e_phoff)];
+ int headers;
+ int i, outlen;
+ uint32_t data_start, data_end, mem_end;
- /* Now, regular headers - we only care about PT_LOAD headers,
- * because thats what we're actually going to load
- */
+ comp_func_ptr compress = compression_function(algo);
+ if (!compress)
+ return -1;
+
+ DEBUG("start: parse_elf_to_stage(location=0x%x)\n", *location);
+
+ if (elf_headers(input, &ehdr, &phdr) < 0)
+ return -1;
+
+ headers = ehdr.e_phnum;
- data_start = 0xFFFFFFFF;
+ data_start = ~0;
data_end = 0;
mem_end = 0;
for (i = 0; i < headers; i++) {
unsigned int start, mend, rend;
- if (elf32_to_native(phdr[i].p_type) != PT_LOAD)
+ if (phdr[i].p_type != PT_LOAD)
continue;
/* Empty segments are never interesting */
- if (elf32_to_native(phdr[i].p_memsz) == 0)
+ if (phdr[i].p_memsz == 0)
continue;
/* BSS */
- start = elf32_to_native(phdr[i].p_paddr);
+ start = phdr[i].p_paddr;
- mend = start + elf32_to_native(phdr[i].p_memsz);
- rend = start + elf32_to_native(phdr[i].p_filesz);
+ mend = start + phdr[i].p_memsz;
+ rend = start + phdr[i].p_filesz;
if (start < data_start)
data_start = start;
@@ -128,8 +328,9 @@ int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
}
if (data_end <= data_start) {
- ERROR("data ends before it starts. Make sure the "
- "ELF file is correct and resides in ROM space.\n");
+ ERROR("data ends (%08lx) before it starts(%08lx). Make sure the "
+ "ELF file is correct and resides in ROM space.\n",
+ (unsigned long)data_end, (unsigned long)data_start);
exit(1);
}
@@ -146,25 +347,39 @@ int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
for (i = 0; i < headers; i++) {
unsigned int l_start, l_offset = 0;
- if (elf32_to_native(phdr[i].p_type) != PT_LOAD)
+ if (phdr[i].p_type != PT_LOAD)
continue;
- if (elf32_to_native(phdr[i].p_memsz) == 0)
+ if (phdr[i].p_memsz == 0)
continue;
- l_start = elf32_to_native(phdr[i].p_paddr);
+ l_start = phdr[i].p_paddr;
if (l_start < *location) {
l_offset = *location - l_start;
l_start = *location;
}
+ /* A legal ELF file can have a program header with
+ * non-zero length but zero-length file size and a
+ * non-zero offset which, added together, are > than
+ * input->size (i.e. the total file size). So we need
+ * to not even test in the case that p_filesz is zero.
+ */
+ if (! phdr[i].p_filesz)
+ continue;
+ if (input->size < (phdr[i].p_offset + phdr[i].p_filesz)){
+ ERROR("Underflow copying out the segment."
+ "File has %ld bytes left, segment end is %ld\n",
+ input->size, phdr[i].p_offset + phdr[i].p_filesz);
+ return -1;
+ }
memcpy(buffer + (l_start - data_start),
- &header[elf32_to_native(phdr[i].p_offset)+l_offset],
- elf32_to_native(phdr[i].p_filesz)-l_offset);
+ &input->data[phdr[i].p_offset + l_offset],
+ phdr[i].p_filesz - l_offset);
}
/* Now make the output buffer */
- if (buffer_create(output, sizeof(*stage) + data_end - data_start,
+ if (buffer_create(output, sizeof(struct cbfs_stage) + data_end - data_start,
input->name) != 0) {
ERROR("Unable to allocate memory: %m\n");
free(buffer);
@@ -172,19 +387,31 @@ int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
}
memset(output->data, 0, output->size);
- stage = (struct cbfs_stage *)output->data;
-
- stage->load = data_start; /* FIXME: htonll */
- stage->memlen = mem_end - data_start;
- stage->compression = algo;
- stage->entry = ehdr->e_entry; /* FIXME: htonll */
-
- compress(buffer, data_end - data_start, (output->data + sizeof(*stage)),
- (int *)&stage->len);
+ /* Compress the data, at which point we'll know information
+ * to fill out the header. This seems backward but it works because
+ * - the output header is a known size (not always true in many xdr's)
+ * - we do need to know the compressed output size first
+ */
+ compress(buffer, data_end - data_start,
+ (output->data + sizeof(struct cbfs_stage)),
+ &outlen);
free(buffer);
+ /* Set up for output marshaling. */
+ outheader.data = output->data;
+ outheader.size = 0;
+ /* N.B. The original plan was that SELF data was B.E.
+ * but: this is all L.E.
+ * Maybe we should just change the spec.
+ */
+ xdr_le.put32(&outheader, algo);
+ xdr_le.put64(&outheader, ehdr.e_entry);
+ xdr_le.put64(&outheader, data_start);
+ xdr_le.put32(&outheader, outlen);
+ xdr_le.put32(&outheader, mem_end - data_start);
+
if (*location)
*location -= sizeof(struct cbfs_stage);
- output->size = sizeof(*stage) + stage->len;
+ output->size = sizeof(struct cbfs_stage) + outlen;
return 0;
}
diff --git a/util/cbfstool/common.h b/util/cbfstool/common.h
index 6e12fcb..8b4153f 100644
--- a/util/cbfstool/common.h
+++ b/util/cbfstool/common.h
@@ -132,5 +132,20 @@ uint32_t cbfs_find_location(const char *romfile, uint32_t filesize,
void print_supported_filetypes(void);
#define ARRAY_SIZE(a) (int)(sizeof(a) / sizeof((a)[0]))
+/* lzma/lzma.c */
+void do_lzma_compress(char *in, int in_len, char *out, int *out_len);
+void do_lzma_uncompress(char *dst, int dst_len, char *src, int src_len);
+/* xdr.c */
+struct xdr {
+ uint16_t (*get16)(struct buffer *input);
+ uint32_t (*get32)(struct buffer *input);
+ uint64_t (*get64)(struct buffer *input);
+ void (*put16)(struct buffer *input, uint16_t val);
+ void (*put32)(struct buffer *input, uint32_t val);
+ void (*put64)(struct buffer *input, uint64_t val);
+};
+
+extern struct xdr xdr_le, xdr_be;
+>>>>>>> 4f819e8... cbfs: fix issues with word size and endianness.
#endif
diff --git a/util/cbfstool/xdr.c b/util/cbfstool/xdr.c
new file mode 100644
index 0000000..c819c9c
--- /dev/null
+++ b/util/cbfstool/xdr.c
@@ -0,0 +1,141 @@
+ /*
+ * cbfstool, CLI utility for CBFS file manipulation
+ *
+ * Copyright 2013 Google 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdint.h>
+#include "common.h"
+
+/* The assumption in all this code is that we're given a pointer to enough data.
+ * Hence, we do not check for underflow.
+ */
+static uint8_t get8(struct buffer *input)
+{
+ uint8_t ret = *input->data++;
+ input->size--;
+ return ret;
+}
+
+static uint16_t get16be(struct buffer *input)
+{
+ uint16_t ret;
+ ret = get8(input)<<8;
+ ret |= get8(input);
+ return ret;
+}
+
+static uint32_t get32be(struct buffer *input)
+{
+ uint32_t ret;
+ ret = get16be(input)<<16;
+ ret |= get16be(input);
+ return ret;
+}
+
+static uint64_t get64be(struct buffer *input)
+{
+ uint64_t ret;
+ ret = get32be(input);
+ ret <<= 32;
+ ret |= get32be(input);
+ return ret;
+}
+
+static void put8(struct buffer *input, uint8_t val)
+{
+ input->data[input->size] = val;
+ input->size++;
+}
+
+static void put16be(struct buffer *input, uint16_t val)
+{
+ put8(input, val>>8);
+ put8(input, val);
+}
+
+static void put32be(struct buffer *input, uint32_t val)
+{
+ put16be(input, val>>16);
+ put16be(input, val);
+}
+
+static void put64be(struct buffer *input, uint64_t val)
+{
+ put32be(input, val>>32);
+ put32be(input, val);
+}
+
+static uint16_t get16le(struct buffer *input)
+{
+ uint16_t ret;
+ ret = get8(input);
+ ret |= get8(input) << 8;
+ return ret;
+}
+
+static uint32_t get32le(struct buffer *input)
+{
+ uint32_t ret;
+ ret = get16le(input);
+ ret |= get16le(input) << 16;
+ return ret;
+}
+
+static uint64_t get64le(struct buffer *input)
+{
+ uint64_t ret;
+ uint32_t low;
+ low = get32le(input);
+ ret = get32le(input);
+ ret <<= 32;
+ ret |= low;
+ return ret;
+}
+
+static void put16le(struct buffer *input, uint16_t val)
+{
+ put8(input, val);
+ put8(input, val>>8);
+}
+
+static void put32le(struct buffer *input, uint32_t val)
+{
+ put16le(input, val);
+ put16le(input, val>>16);
+}
+
+static void put64le(struct buffer *input, uint64_t val)
+{
+ put32le(input, val);
+ put32le(input, val>>32);
+}
+
+struct xdr xdr_be = {
+ get16be, get32be, get64be,
+ put16be, put32be, put64be
+};
+
+struct xdr xdr_le = {
+ get16le, get32le, get64le,
+ put16le, put32le, put64le
+};
+
the following patch was just integrated into master:
commit 5dfe5606d06b14fc7ab3e10b892bb8643e495ac7
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Sat Jan 25 23:17:32 2014 -0600
Revert "Makefile: Check $CC variable returned from xcompile is not empty."
This reverts commit 1287d1cc80c52ff2598f2bae235fc42d8456f44a.
This commit has the side-effect of making abuild fail, and as such is
reverted until a safe solution can be found.
Change-Id: Ib8cb78468c2922322b490e0b52c0bd24f3de7ef9
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
See http://review.coreboot.org/3269 for details.
-gerrit
Edward O'Callaghan (eocallaghan(a)alterapraxis.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4784
-gerrit
commit 7c88bbed09efddd3ffb10f243657cfb0a6d339ff
Author: Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
Date: Thu Jan 23 22:12:25 2014 +1100
superio/fintek: Add initial support for Fintek F71869AD.
Change-Id: I41f1ee20517dd179a4dee914ab7f6332739e326e
Signed-off-by: Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
---
src/superio/fintek/Kconfig | 2 +
src/superio/fintek/Makefile.inc | 1 +
src/superio/fintek/f71869ad/Makefile.inc | 22 +++++++
src/superio/fintek/f71869ad/chip.h | 32 ++++++++++
src/superio/fintek/f71869ad/early_serial.c | 68 +++++++++++++++++++++
src/superio/fintek/f71869ad/f71869ad.h | 37 ++++++++++++
src/superio/fintek/f71869ad/superio.c | 94 ++++++++++++++++++++++++++++++
7 files changed, 256 insertions(+)
diff --git a/src/superio/fintek/Kconfig b/src/superio/fintek/Kconfig
index 67d2847..938494a 100644
--- a/src/superio/fintek/Kconfig
+++ b/src/superio/fintek/Kconfig
@@ -23,6 +23,8 @@ config SUPERIO_FINTEK_F71859
bool
config SUPERIO_FINTEK_F71863FG
bool
+config SUPERIO_FINTEK_F71869AD
+ bool
config SUPERIO_FINTEK_F71872
bool
config SUPERIO_FINTEK_F71889
diff --git a/src/superio/fintek/Makefile.inc b/src/superio/fintek/Makefile.inc
index 036bb2d..541a893 100644
--- a/src/superio/fintek/Makefile.inc
+++ b/src/superio/fintek/Makefile.inc
@@ -20,6 +20,7 @@
subdirs-y += f71805f
subdirs-y += f71859
subdirs-y += f71863fg
+subdirs-y += f71869ad
subdirs-y += f71872
subdirs-y += f71889
subdirs-y += f81865f
diff --git a/src/superio/fintek/f71869ad/Makefile.inc b/src/superio/fintek/f71869ad/Makefile.inc
new file mode 100644
index 0000000..12efbeb
--- /dev/null
+++ b/src/superio/fintek/f71869ad/Makefile.inc
@@ -0,0 +1,22 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
+##
+## 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; either version 2 of the License, or
+## (at your option) any later version.
+##
+## 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
+##
+
+romstage-$(CONFIG_SUPERIO_FINTEK_F71869AD) += early_serial.c
+ramstage-$(CONFIG_SUPERIO_FINTEK_F71869AD) += superio.c
diff --git a/src/superio/fintek/f71869ad/chip.h b/src/superio/fintek/f71869ad/chip.h
new file mode 100644
index 0000000..78f3664
--- /dev/null
+++ b/src/superio/fintek/f71869ad/chip.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#ifndef SUPERIO_FINTEK_F71869AD_CHIP_H
+#define SUPERIO_FINTEK_F71869AD_CHIP_H
+
+#include <pc80/keyboard.h>
+#include <device/device.h>
+#include <uart8250.h>
+
+struct superio_fintek_f71869ad_config {
+ struct pc_keyboard keyboard;
+};
+
+#endif /* SUPERIO_FINTEK_F71869AD_CHIP_H */
diff --git a/src/superio/fintek/f71869ad/early_serial.c b/src/superio/fintek/f71869ad/early_serial.c
new file mode 100644
index 0000000..8518400
--- /dev/null
+++ b/src/superio/fintek/f71869ad/early_serial.c
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Pre-RAM driver for the Fintek F71869AD Super I/O chip.
+ *
+ * Derived from p.34 in vendor data-sheet:
+ *
+ * - default index port : 0x4E
+ * - default data port : 0x4F
+ *
+ * - enable configuration : 0x87
+ * - disable configuration : 0xAA
+ *
+ */
+
+#include <arch/io.h>
+#include <device/pnp.h>
+#include "f71869ad.h"
+
+/*
+ * Enable configuration: pass entry key '0x87' into index port dev.
+ */
+static void pnp_enter_conf_state(device_t dev)
+{
+ u16 port = dev >> 8;
+ outb(0x87, port);
+ outb(0x87, port);
+}
+
+/*
+ * Disable configuration: pass exit key '0xAA' into index port dev.
+ */
+static void pnp_exit_conf_state(device_t dev)
+{
+ u16 port = dev >> 8;
+ outb(0xaa, port);
+}
+
+/*
+ * Bring up early serial debugging output before the RAM is initialized.
+ */
+void f71869ad_enable_serial(device_t dev, u16 iobase)
+{
+ pnp_enter_conf_state(dev);
+ pnp_set_logical_device(dev);
+ pnp_set_enable(dev, 0);
+ pnp_set_iobase(dev, PNP_IDX_IO0, iobase);
+ pnp_set_enable(dev, 1);
+ pnp_exit_conf_state(dev);
+}
diff --git a/src/superio/fintek/f71869ad/f71869ad.h b/src/superio/fintek/f71869ad/f71869ad.h
new file mode 100644
index 0000000..abc0260
--- /dev/null
+++ b/src/superio/fintek/f71869ad/f71869ad.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#ifndef SUPERIO_FINTEK_F71869AD_F71869AD_H
+#define SUPERIO_FINTEK_F71869AD_F71869AD_H
+
+/* Logical Device Numbers (LDN). */
+#define F71869AD_FDC 0x00 /* Floppy */
+#define F71869AD_SP1 0x01 /* UART1 */
+#define F71869AD_SP2 0x02 /* UART2 */
+#define F71869AD_PP 0x03 /* Parallel port */
+#define F71869AD_HWM 0x04 /* Hardware monitor */
+#define F71869AD_KBC 0x05 /* PS/2 keyboard and mouse */
+#define F71869AD_GPIO 0x06 /* General Purpose I/O (GPIO) */
+#define F71869AD_BSEL 0x07 /* BSEL */
+#define F71869AD_PME 0x0a /* Power Management Events (PME) and ACPI */
+
+void f71869ad_enable_serial(device_t dev, u16 iobase);
+
+#endif /* SUPERIO_FINTEK_F71869AD_F71869AD_H */
diff --git a/src/superio/fintek/f71869ad/superio.c b/src/superio/fintek/f71869ad/superio.c
new file mode 100644
index 0000000..442ca00
--- /dev/null
+++ b/src/superio/fintek/f71869ad/superio.c
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <arch/io.h>
+#include <device/device.h>
+#include <device/pnp.h>
+#include <superio/conf_mode.h>
+#include <console/console.h>
+#include <stdlib.h>
+#include <uart8250.h>
+
+#include "chip.h"
+#include "f71869ad.h"
+
+static void f71869ad_init(device_t dev)
+{
+ struct superio_fintek_f71869ad_config *conf = dev->chip_info;
+
+ if (!dev->enabled)
+ return;
+
+ switch(dev->path.pnp.device) {
+ /* TODO: Might potentially need code for HWM or FDC etc. */
+ case F71869AD_KBC:
+ pc_keyboard_init(&conf->keyboard);
+ break;
+ }
+}
+
+static struct device_operations ops = {
+ .read_resources = pnp_read_resources,
+ .set_resources = pnp_set_resources,
+ .enable_resources = pnp_enable_resources,
+ .enable = pnp_alt_enable,
+ .init = f71869ad_init,
+ .ops_pnp_mode = &pnp_conf_mode_8787_aa,
+};
+
+/*
+ * io_info contains the mask 0x07f8. Given 16 register, each 8 bits wide of a
+ * logical device we need a mask of the following form:
+ *
+ * MSB LSB
+ * v v
+ * 0x[15..11][10..3][2..0]
+ * ------ ^^^^^ ^^^^
+ * null | |
+ * | +------ Register index
+ * |
+ * +------------- Compare against base address and
+ * asserts a chip_select on match.
+ *
+ * i.e., 0x07F8 = [00000][11111111][000]
+ *
+ * TODO: verify flags and masks are correct & move this information to Wiki.
+ */
+static struct pnp_info pnp_dev_info[] = {
+ { &ops, F71869AD_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, {0x07f8, 0}, },
+ { &ops, F71869AD_SP1, PNP_IO0 | PNP_IRQ0, {0x07f8, 0}, },
+ { &ops, F71869AD_SP2, PNP_IO0 | PNP_IRQ0, {0x07f8, 0}, },
+ { &ops, F71869AD_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, {0x07f8, 0}, },
+ { &ops, F71869AD_HWM, PNP_IO0 | PNP_IRQ0, {0x0ff8, 0}, },
+ { &ops, F71869AD_KBC, PNP_IO0 | PNP_IRQ0 | PNP_IRQ1, {0x07ff, 0}, },
+ { &ops, F71869AD_GPIO, },
+ { &ops, F71869AD_BSEL, PNP_IO0, {0x07f8, 0}, },
+ { &ops, F71869AD_PME, },
+};
+
+static void enable_dev(device_t dev)
+{
+ pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
+}
+
+struct chip_operations superio_fintek_f71869ad_ops = {
+ CHIP_NAME("Fintek F71869AD Super I/O")
+ .enable_dev = enable_dev
+};
Edward O'Callaghan (eocallaghan(a)alterapraxis.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4801
-gerrit
commit 06b981242386746f6b078e75dbbc7a3b56d1b8de
Author: Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
Date: Sat Jan 25 21:46:10 2014 +1100
Jetway NF81-T56N-LF [2/2]: actually implement mainboard support.
Step 2: change the Persimmon code to adapt it to the new board's hardware.
The NF81-T56N-LF is a IPC form factor embedded board:
- AMD Fusion G-T56N (1.65 GHz dual core) APU
- 2x SO-DIMM sockets for DDR3 800-1066 SDRAM (1.5 or 1.35V)?
- VGA and LVDS (via Analogix ANX3110)
- AMD A55E (Hudson-E1) southbridge
- 6x USB 2.0/1.1 ports
- 5x SATA3 6Gb/s, 1x mSATA socket
- 6-Channel HD Audio (via VIA VT1705)??
- PCI and ISA (via ITE IT8888)??
- NEC uPD78F0532 microcontroller on I2C ("SEMA")??
- 2x RJ45 GbE (via Realtek RTL8111E x2)
- Fintek F71869AD Super I/O
- PS/2 KB/MS port
- RS232 header (via Unisonic UTC 75232 RS232 driver/receiver)
- GPIO header
- CIR header
- 1x MXIC MX25L1606E (SO8, soldered) 16 MB SPI flash (BIOS)
Change-Id: I03ccc58bc782e800aeef0d19679ce060277b0c04
Signed-off-by: Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
---
src/mainboard/jetway/Kconfig | 3 +++
src/mainboard/jetway/nf81-t56n-lf/Kconfig | 18 +++++++++++-------
src/mainboard/jetway/nf81-t56n-lf/board_info.txt | 5 +++--
src/mainboard/jetway/nf81-t56n-lf/devicetree.cb | 14 ++++++++------
src/mainboard/jetway/nf81-t56n-lf/platform_cfg.h | 3 +++
src/mainboard/jetway/nf81-t56n-lf/romstage.c | 7 ++++---
6 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/src/mainboard/jetway/Kconfig b/src/mainboard/jetway/Kconfig
index 7e6e29d..5b55daa 100644
--- a/src/mainboard/jetway/Kconfig
+++ b/src/mainboard/jetway/Kconfig
@@ -11,6 +11,8 @@ config BOARD_JETWAY_J7F4K1G5D
bool "J7F4K1G5D"
config BOARD_JETWAY_PA78VM5
bool "PA78VM5 (Fam10)"
+config BOARD_JETWAY_NF81_T56N_LF
+ bool "NF81_T56N_LF"
endchoice
@@ -18,6 +20,7 @@ source "src/mainboard/jetway/j7f2/Kconfig"
source "src/mainboard/jetway/j7f4k1g2e/Kconfig"
source "src/mainboard/jetway/j7f4k1g5d/Kconfig"
source "src/mainboard/jetway/pa78vm5/Kconfig"
+source "src/mainboard/jetway/nf81-t56n-lf/Kconfig"
config MAINBOARD_VENDOR
string
diff --git a/src/mainboard/jetway/nf81-t56n-lf/Kconfig b/src/mainboard/jetway/nf81-t56n-lf/Kconfig
index febd8dd..9757b57 100644
--- a/src/mainboard/jetway/nf81-t56n-lf/Kconfig
+++ b/src/mainboard/jetway/nf81-t56n-lf/Kconfig
@@ -2,6 +2,7 @@
# This file is part of the coreboot project.
#
# Copyright (C) 2011 Advanced Micro Devices, Inc.
+# Copyright (C) 2014 Edward O'Callaghan <eocallaghan(a)alterapraxis.com>.
#
# 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
@@ -17,7 +18,7 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
-if BOARD_AMD_PERSIMMON
+if BOARD_JETWAY_NF81_T56N_LF
config BOARD_SPECIFIC_OPTIONS # dummy
def_bool y
@@ -25,22 +26,25 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select CPU_AMD_AGESA_FAMILY14
select NORTHBRIDGE_AMD_AGESA_FAMILY14
select SOUTHBRIDGE_AMD_CIMX_SB800
- select SUPERIO_FINTEK_F81865F
+ select SUPERIO_FINTEK_F71869AD
select HAVE_OPTION_TABLE
select HAVE_PIRQ_TABLE
select HAVE_MP_TABLE
- select HAVE_ACPI_RESUME
+# FIXME: Disable S3 for now. Enable by default once stabilised.
+# select HAVE_ACPI_RESUME
select SB_HT_CHAIN_UNITID_OFFSET_ONLY
select LIFT_BSP_APIC_ID
select SERIAL_CPU_INIT
select AMDMCT
select HAVE_ACPI_TABLES
+# FIXME: Set ROM size to be only 4MB until 16M ROM support is stabilised.
+# select BOARD_ROMSIZE_KB_16384
select BOARD_ROMSIZE_KB_4096
select GFXUMA
config MAINBOARD_DIR
string
- default amd/persimmon
+ default jetway/nf81-t56n-lf
config APIC_ID_OFFSET
hex
@@ -48,7 +52,7 @@ config APIC_ID_OFFSET
config MAINBOARD_PART_NUMBER
string
- default "Persimmon"
+ default "NF81-T56N-LF"
config HW_MEM_HOLE_SIZEK
hex
@@ -101,7 +105,7 @@ config VGA_BIOS
config VGA_BIOS_ID
string
- default "1002,9802"
+ default "1002,9806" # FUSION_G_T56N
config SB800_AHCI_ROM
bool
@@ -111,4 +115,4 @@ config DRIVERS_PS2_KEYBOARD
bool
default n
-endif # BOARD_AMD_PERSIMMON
+endif # BOARD_JETWAY_NF81_T56N_LF
diff --git a/src/mainboard/jetway/nf81-t56n-lf/board_info.txt b/src/mainboard/jetway/nf81-t56n-lf/board_info.txt
index 85cb19a..6748751 100644
--- a/src/mainboard/jetway/nf81-t56n-lf/board_info.txt
+++ b/src/mainboard/jetway/nf81-t56n-lf/board_info.txt
@@ -1,5 +1,6 @@
-Board name: DBFT1-00-EVAL-KT (Persimmon)
-Category: eval
+Board URL: http://www.jetway.com.tw/jw/ipcboard_view.asp?productid=822&proname=NF81-T5…
+Category: Mini-ITX
+ROM package: SOIC8
ROM protocol: SPI
ROM socketed: n
Flashrom support: y
diff --git a/src/mainboard/jetway/nf81-t56n-lf/devicetree.cb b/src/mainboard/jetway/nf81-t56n-lf/devicetree.cb
index 8b1acd5..4f6006a 100644
--- a/src/mainboard/jetway/nf81-t56n-lf/devicetree.cb
+++ b/src/mainboard/jetway/nf81-t56n-lf/devicetree.cb
@@ -2,6 +2,7 @@
# This file is part of the coreboot project.
#
# Copyright (C) 2011 Advanced Micro Devices, Inc.
+# Copyright (C) 2014 Edward O'Callaghan <eocallaghan(a)alterapraxis.com>.
#
# 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
@@ -29,6 +30,7 @@ chip northbridge/amd/agesa/family14/root_complex
chip northbridge/amd/agesa/family14 # PCI side of HT root complex
device pci 0.0 on end # Root Complex
device pci 1.0 on end # Internal Graphics P2P bridge 0x980[2456]
+ device pci 1.1 on end # Internal Audio P2P bridge 0x1314
device pci 4.0 on end # PCIE P2P bridge on-board NIC
device pci 5.0 off end # PCIE P2P bridge
device pci 6.0 on end # PCIE P2P bridge PCIe slot
@@ -53,7 +55,7 @@ chip northbridge/amd/agesa/family14/root_complex
device pci 14.1 on end # IDE 0x439c
device pci 14.2 on end # HDA 0x4383
device pci 14.3 on # LPC 0x439d
- chip superio/fintek/f81865f
+ chip superio/fintek/f71869ad
device pnp 4e.0 off # Floppy
io 0x60 = 0x3f0
irq 0x70 = 6
@@ -76,17 +78,17 @@ chip northbridge/amd/agesa/family14/root_complex
io 0x60 = 0x2f8
irq 0x70 = 3
end
- end # f81865f
+ end # f71869ad
end #LPC
device pci 14.4 on end # PCIB 0x4384, NOTE: PCI interface pins shared with GPIO {GPIO 35:0}
- device pci 14.5 off end # OHCI FS/LS USB
+ device pci 14.5 on end # OHCI FS/LS USB (0x4399)
device pci 14.6 off end # Hudson-E1 GbE MAC: Broadcom BCM5785 (14E4:1699)
- device pci 15.0 off end # PCIe PortA
+ device pci 15.0 on end # PCIe PortA (0x43a0) GbE MAC: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 (10ec:8168)
device pci 15.1 off end # PCIe PortB
device pci 15.2 off end # PCIe PortC
device pci 15.3 off end # PCIe PortD
- device pci 16.0 off end # OHCI USB 10-13
- device pci 16.2 off end # EHCI USB 10-13
+ device pci 16.0 on end # OHCI USB 10-13 (0x4397)
+ device pci 16.2 on end # EHCI USB 10-13 (0x4396)
register "gpp_configuration" = "0" #4:0:0:0 (really need to disable all 4 somehow)
register "boot_switch_sata_ide" = "0" # 0: boot from SATA. 1: IDE
diff --git a/src/mainboard/jetway/nf81-t56n-lf/platform_cfg.h b/src/mainboard/jetway/nf81-t56n-lf/platform_cfg.h
index 0578e27..e638892 100644
--- a/src/mainboard/jetway/nf81-t56n-lf/platform_cfg.h
+++ b/src/mainboard/jetway/nf81-t56n-lf/platform_cfg.h
@@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2011 Advanced Micro Devices, Inc.
+ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan(a)alterapraxis.com>.
*
* 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
@@ -227,6 +228,7 @@
*/
#define GEC_CONFIG 0
+/* FIXME: Verify this for sound to work! */
static const CODECENTRY persimmon_codec_alc269[] =
{
/* NID, PinConfig */
@@ -244,6 +246,7 @@ static const CODECENTRY persimmon_codec_alc269[] =
{0xff, 0xffffffff} /* end of table */
};
+/* FIXME: Verify this for sound to work! */
static const CODECTBLLIST codec_tablelist[] =
{
{0x010ec0269, (CODECENTRY*)&persimmon_codec_alc269[0]},
diff --git a/src/mainboard/jetway/nf81-t56n-lf/romstage.c b/src/mainboard/jetway/nf81-t56n-lf/romstage.c
index 98c64ed..f8271f7 100644
--- a/src/mainboard/jetway/nf81-t56n-lf/romstage.c
+++ b/src/mainboard/jetway/nf81-t56n-lf/romstage.c
@@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2011 Advanced Micro Devices, Inc.
+ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan(a)alterapraxis.com>.
*
* 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
@@ -31,7 +32,7 @@
#include <cpu/x86/mtrr.h>
#include "agesawrapper.h"
#include "cpu/x86/bist.h"
-#include "superio/fintek/f81865f/f81865f_early_serial.c"
+#include "superio/fintek/f71869ad/f71869ad.h"
#include "cpu/x86/lapic.h"
#include "drivers/pc80/i8254.c"
#include "drivers/pc80/i8259.c"
@@ -45,7 +46,7 @@
void disable_cache_as_ram(void); /* cache_as_ram.inc */
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx);
-#define SERIAL_DEV PNP_DEV(0x4e, F81865F_SP1)
+#define SERIAL_DEV PNP_DEV(0x4e, F71869AD_SP1)
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
{
@@ -70,7 +71,7 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
sb_Poweron_Init();
post_code(0x31);
- f81865f_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
+ f71869ad_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
console_init();
}