[coreboot-gerrit] New patch to review for coreboot: mipseb support + ath79

Alexander Couzens (lynxis@fe80.eu) gerrit at coreboot.org
Mon Sep 21 17:51:11 CET 2015


Alexander Couzens (lynxis at fe80.eu) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11694

-gerrit

commit 5883a7f34c11929e86e9137d7b0594e7d5e68eb5
Author: Alexander Couzens <lynxis at fe80.eu>
Date:   Fri Sep 18 05:23:38 2015 +0200

    mipseb support + ath79
    
    this is just hacky big stupid commit to let other people see over.
    /src/arch/mipseb/ is just copied over from  arch/mips (mipsel).
    
    /src/console must apply the same fixes for mipsel.
    
    Change-Id: I6c514d8bd75338f0f47698eee66fa2b11b80d697
    Signed-off-by: Alexander Couzens <lynxis at fe80.eu>
---
 Makefile.inc                                       |  14 +-
 src/arch/mipseb/Kconfig                            |  40 ++
 src/arch/mipseb/Makefile.inc                       |  99 ++++
 src/arch/mipseb/ashldi3.c                          |  55 ++
 src/arch/mipseb/boot.c                             |  29 ++
 src/arch/mipseb/bootblock.S                        |  48 ++
 src/arch/mipseb/bootblock_simple.c                 |  45 ++
 src/arch/mipseb/cache.c                            | 119 +++++
 src/arch/mipseb/include/arch/byteorder.h           |  29 ++
 src/arch/mipseb/include/arch/cache.h               |  48 ++
 src/arch/mipseb/include/arch/cpu.h                 | 171 +++++++
 src/arch/mipseb/include/arch/early_variables.h     |  31 ++
 src/arch/mipseb/include/arch/exception.h           |  25 +
 src/arch/mipseb/include/arch/header.ld             |  32 ++
 src/arch/mipseb/include/arch/hlt.h                 |  29 ++
 src/arch/mipseb/include/arch/io.h                  |  70 +++
 src/arch/mipseb/include/arch/memlayout.h           |  33 ++
 src/arch/mipseb/include/arch/mmu.h                 |  59 +++
 src/arch/mipseb/include/arch/pci_ops.h             |  30 ++
 src/arch/mipseb/include/arch/stages.h              |  28 ++
 src/arch/mipseb/include/arch/types.h               |  67 +++
 src/arch/mipseb/include/bootblock_common.h         |  30 ++
 src/arch/mipseb/include/stdint.h                   | 104 ++++
 src/arch/mipseb/mmu.c                              | 104 ++++
 src/arch/mipseb/stages.c                           |  32 ++
 src/arch/mipseb/tables.c                           |  61 +++
 src/console/Kconfig                                |   2 +-
 src/console/vtxprintf.c                            |   2 +
 src/cpu/mips/Kconfig                               |   7 +
 src/mainboard/ubiquity/Kconfig                     |  34 ++
 src/mainboard/ubiquity/Kconfig.name                |   2 +
 src/mainboard/ubiquity/nanostation_xm/Kconfig      |  61 +++
 src/mainboard/ubiquity/nanostation_xm/Kconfig.name |   2 +
 src/mainboard/ubiquity/nanostation_xm/Makefile.inc |  29 ++
 src/mainboard/ubiquity/nanostation_xm/bootblock.c  |  35 ++
 src/mainboard/ubiquity/nanostation_xm/clocks.c     |  23 +
 .../ubiquity/nanostation_xm/devicetree.cb          |  23 +
 src/mainboard/ubiquity/nanostation_xm/mainboard.c  |  17 +
 src/mainboard/ubiquity/nanostation_xm/memlayout.ld |   1 +
 src/soc/atheros/ar7240/Kconfig                     |  40 ++
 src/soc/atheros/ar7240/Makefile.inc                |  60 +++
 src/soc/atheros/ar7240/bootblock.c                 |  65 +++
 src/soc/atheros/ar7240/cbmem.c                     |  29 ++
 src/soc/atheros/ar7240/clocks.c                    | 101 ++++
 src/soc/atheros/ar7240/ddr1_init.c                 |   0
 src/soc/atheros/ar7240/ddr2_init.c                 |   0
 src/soc/atheros/ar7240/include/soc/clocks.h        |  91 ++++
 src/soc/atheros/ar7240/include/soc/ddr_init.h      |  26 +
 .../atheros/ar7240/include/soc/ddr_private_reg.h   | 138 +++++
 src/soc/atheros/ar7240/include/soc/gpio.h          |  25 +
 src/soc/atheros/ar7240/include/soc/memlayout.ld    |  60 +++
 src/soc/atheros/ar7240/include/soc/spi.h           | 358 +++++++++++++
 src/soc/atheros/ar7240/monotonic_timer.c           |  51 ++
 src/soc/atheros/ar7240/romstage.c                  |  10 +
 src/soc/atheros/ar7240/spi.c                       | 188 +++++++
 src/soc/atheros/ar7240/uart.c                      | 162 ++++++
 src/soc/atheros/common/include/soc/ar71xx_regs.h   | 559 +++++++++++++++++++++
 toolchain.inc                                      |   4 +
 util/crossgcc/Makefile                             |  13 +-
 util/crossgcc/README                               |   1 +
 util/crossgcc/buildgcc                             |   3 +-
 util/xcompile/xcompile                             |  20 +-
 62 files changed, 3664 insertions(+), 10 deletions(-)

diff --git a/Makefile.inc b/Makefile.inc
index 1cac01b..380fc36 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -458,9 +458,9 @@ gitconfig:
 	git config remote.origin.push HEAD:refs/for/master
 	(git config --global user.name >/dev/null && git config --global user.email >/dev/null) || (printf 'Please configure your name and email in git:\n\n git config --global user.name "Your Name Comes Here"\n git config --global user.email your.email at example.com\n'; exit 1)
 
-crossgcc: crossgcc-i386 crossgcc-x64 crossgcc-arm crossgcc-aarch64 crossgcc-mips crossgcc-riscv
+crossgcc: crossgcc-i386 crossgcc-x64 crossgcc-arm crossgcc-aarch64 crossgcc-mips crossgcc-mipseb crossgcc-riscv
 
-.PHONY: crossgcc-i386 crossgcc-x64 crossgcc-arm crossgcc-aarch64 crossgcc-mips crossgcc-riscv
+.PHONY: crossgcc-i386 crossgcc-x64 crossgcc-arm crossgcc-aarch64 crossgcc-mips crossgcc-mipseb crossgcc-riscv
 crossgcc-i386: clean-for-update
 	$(MAKE) -C util/crossgcc build-i386-without-gdb
 
@@ -476,12 +476,15 @@ crossgcc-aarch64: clean-for-update
 crossgcc-mips: clean-for-update
 	$(MAKE) -C util/crossgcc build-mips-without-gdb
 
+crossgcc-mipseb: clean-for-update
+	$(MAKE) -C util/crossgcc build-mipseb-without-gdb
+
 crossgcc-riscv: clean-for-update
 	$(MAKE) -C util/crossgcc build-riscv-without-gdb
 
-crosstools: crosstools-i386 crosstools-x64 crosstools-arm crosstools-aarch64 crosstools-mips crosstools-riscv
+crosstools: crosstools-i386 crosstools-x64 crosstools-arm crosstools-aarch64 crosstools-mips crosstools-mipseb crosstools-riscv
 
-.PHONY: crosstools-i386 crosstools-x64 crosstools-arm crosstools-aarch64 crosstools-mips crosstools-riscv
+.PHONY: crosstools-i386 crosstools-x64 crosstools-arm crosstools-aarch64 crosstools-mips crosstools-mipseb crosstools-riscv
 crosstools-i386: clean-for-update
 	$(MAKE) -C util/crossgcc build-i386
 
@@ -497,6 +500,9 @@ crosstools-aarch64: clean-for-update
 crosstools-mips: clean-for-update
 	$(MAKE) -C util/crossgcc build-mips
 
+crosstools-mipseb: clean-for-update
+	$(MAKE) -C util/crossgcc build-mipseb
+
 crosstools-riscv: clean-for-update
 	$(MAKE) -C util/crossgcc build-riscv
 
diff --git a/src/arch/mipseb/Kconfig b/src/arch/mipseb/Kconfig
new file mode 100644
index 0000000..874c52f
--- /dev/null
+++ b/src/arch/mipseb/Kconfig
@@ -0,0 +1,40 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2014 Imagination Technologies
+#
+# 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.
+#
+
+config ARCH_MIPSEB
+	bool
+	default n
+
+config ARCH_BOOTBLOCK_MIPSEB
+	bool
+	default n
+	select ARCH_MIPSEB
+
+config ARCH_VERSTAGE_MIPSEB
+	bool
+	default n
+
+config ARCH_ROMSTAGE_MIPSEB
+	bool
+	default n
+
+config ARCH_RAMSTAGE_MIPSEB
+	bool
+	default n
diff --git a/src/arch/mipseb/Makefile.inc b/src/arch/mipseb/Makefile.inc
new file mode 100644
index 0000000..cd94b09
--- /dev/null
+++ b/src/arch/mipseb/Makefile.inc
@@ -0,0 +1,99 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2014 Imagination Technologies
+#
+# 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.
+#
+
+###############################################################################
+# MIPS specific options
+###############################################################################
+
+ifeq ($(CONFIG_ARCH_ROMSTAGE_MIPSEB),y)
+CBFSTOOL_PRE1_OPTS = -m mips -s $(CONFIG_CBFS_SIZE)
+endif
+
+###############################################################################
+# bootblock
+###############################################################################
+
+ifeq ($(CONFIG_ARCH_ROMSTAGE_MIPSEB),y)
+
+bootblock-y += boot.c
+bootblock-y += bootblock.S
+bootblock-y += bootblock_simple.c
+bootblock-y += cache.c
+bootblock-y += mmu.c
+bootblock-y += stages.c
+bootblock-y += ../../lib/memcpy.c
+bootblock-y += ../../lib/memmove.c
+bootblock-y += ../../lib/memset.c
+
+# Much of the assembly code is generated by the compiler, and may contain
+# terms which the preprocessor will happily go on to replace. For example
+# "mips" would be replaced with "1". Clear all the built in definitions to
+# prevent that.
+bootblock-S-ccopts += -undef
+
+$(objcbfs)/bootblock.debug: $$(bootblock-objs) $(obj)/config.h
+	@printf "    LINK       $(subst $(obj)/,,$(@))\n"
+	$(LD_bootblock) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.bootblock.ld --whole-archive --start-group $(filter-out %.ld,$(bootblock-objs)) --end-group
+
+endif # CONFIG_ARCH_ROMSTAGE_MIPSEB
+
+###############################################################################
+# romstage
+###############################################################################
+
+ifeq ($(CONFIG_ARCH_ROMSTAGE_MIPSEB),y)
+
+romstage-y += boot.c
+romstage-y += cache.c
+romstage-y += mmu.c
+romstage-y += stages.c
+romstage-y += ../../lib/memcpy.c
+romstage-y += ../../lib/memmove.c
+romstage-y += ../../lib/memset.c
+
+$(objcbfs)/romstage.debug: $$(romstage-objs)
+	@printf "    LINK       $(subst $(obj)/,,$(@))\n"
+	$(LD_romstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.romstage.ld --whole-archive --start-group $(filter-out %.ld,$(romstage-objs)) --end-group
+
+endif # CONFIG_ARCH_ROMSTAGE_MIPS CONFIG_ARCH_ROMSTAGE_MIPSEB
+
+###############################################################################
+# ramstage
+###############################################################################
+
+ifeq ($(CONFIG_ARCH_RAMSTAGE_MIPSEB),y)
+
+ramstage-y += ashldi3.c
+ramstage-y += boot.c
+ramstage-y += cache.c
+ramstage-y += mmu.c
+ramstage-y += stages.c
+ramstage-y += tables.c
+ramstage-y += ../../lib/memcpy.c
+ramstage-y += ../../lib/memmove.c
+ramstage-y += ../../lib/memset.c
+
+ramstage-srcs += $(wildcard src/mainboard/$(MAINBOARDDIR)/mainboard.c)
+
+$(objcbfs)/ramstage.debug: $$(ramstage-objs)
+	@printf "    CC         $(subst $(obj)/,,$(@))\n"
+	$(LD_ramstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.ramstage.ld --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group
+
+endif # CONFIG_ARCH_RAMSTAGE_MIPSEB
diff --git a/src/arch/mipseb/ashldi3.c b/src/arch/mipseb/ashldi3.c
new file mode 100644
index 0000000..5bc73f2
--- /dev/null
+++ b/src/arch/mipseb/ashldi3.c
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * Based on linux arch/mips/lib/ashldi3.c
+ *
+ * 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.
+ */
+
+typedef unsigned word_type;
+long long __ashldi3(long long u, word_type b);
+
+struct DWstruct {
+	int low, high;
+};
+typedef union {
+	struct DWstruct s;
+	long long ll;
+} DWunion;
+
+long long __ashldi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		w.s.low = 0;
+		w.s.high = (unsigned int) uu.s.low << -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.low >> bm;
+
+		w.s.low = (unsigned int) uu.s.low << b;
+		w.s.high = ((unsigned int) uu.s.high << b) | carries;
+	}
+
+	return w.ll;
+}
diff --git a/src/arch/mipseb/boot.c b/src/arch/mipseb/boot.c
new file mode 100644
index 0000000..c09af05
--- /dev/null
+++ b/src/arch/mipseb/boot.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#include <arch/stages.h>
+#include <program_loading.h>
+
+void arch_prog_run(struct prog *prog)
+{
+	void *cb_tables = prog_entry_arg(prog);
+	void (*doit)(void *) = prog_entry(prog);
+
+	doit(cb_tables);
+}
diff --git a/src/arch/mipseb/bootblock.S b/src/arch/mipseb/bootblock.S
new file mode 100644
index 0000000..e24848d
--- /dev/null
+++ b/src/arch/mipseb/bootblock.S
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+.set	noreorder	/* Prevent assembler from "optimizing" this code. */
+
+.section ".text._start", "ax", %progbits
+.globl _start
+_start:
+	/* Set the stack pointer */
+	la	$sp, _estack
+
+	/*
+	 * Initialise the stack to a known value, used later to check for
+	 * overflow.
+	 */
+	la	$t0, _stack
+	addi	$t1, $sp, -4
+	li	$t2, 0xdeadbeef
+1:	sw	$t2, 0($t0)
+	bne	$t0, $t1, 1b
+	addi	$t0, $t0, 4
+
+	/* Run main */
+	b	main
+
+	/*
+	 * Should never return from main. Make sure there is no branch in the
+	 * branch delay slot.
+	 */
+2:	nop
+	b	2b
+	nop	/* Make sure there is no branch after this either. */
diff --git a/src/arch/mipseb/bootblock_simple.c b/src/arch/mipseb/bootblock_simple.c
new file mode 100644
index 0000000..1a3c677
--- /dev/null
+++ b/src/arch/mipseb/bootblock_simple.c
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#include <bootblock_common.h>
+#include <console/console.h>
+#include <halt.h>
+#include <program_loading.h>
+
+void main(void)
+{
+	bootblock_cpu_init();
+
+	/* Mainboard basic init */
+	bootblock_mainboard_init();
+
+#if CONFIG_BOOTBLOCK_CONSOLE
+	console_init();
+#endif
+
+	bootblock_mmu_init();
+
+	if (init_extra_hardware()) {
+		printk(BIOS_ERR, "bootblock_simple: failed to init HW.\n");
+	} else {
+		run_romstage();
+	}
+	halt();
+}
diff --git a/src/arch/mipseb/cache.c b/src/arch/mipseb/cache.c
new file mode 100644
index 0000000..c7a125f
--- /dev/null
+++ b/src/arch/mipseb/cache.c
@@ -0,0 +1,119 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#include <arch/cache.h>
+#include <arch/cpu.h>
+#include <console/console.h>
+#include <program_loading.h>
+#include <symbols.h>
+
+/* cache_op: issues cache operation for specified address */
+#define cache_op(op, addr)						\
+({									\
+	__asm__ __volatile__(						\
+		".set push\n\t"						\
+		".set noreorder\n\t"					\
+		".set mips32\n\t"					\
+		"cache %0, %1\n\t"					\
+		".set mips0\n\t"					\
+		".set pop\n\t"						\
+		:							\
+		: "i" (op), "R" (*(unsigned char *)(addr)));		\
+})
+
+#define MIPS_CONFIG1_DL_SHIFT	10
+#define MIPS_CONFIG1_DL_MASK	(0x00000007)
+#define MIPS_CONFIG1_IL_SHIFT	19
+#define MIPS_CONFIG1_IL_MASK	(0x00000007)
+#define MIPS_CONFIG2_SL_SHIFT	4
+#define MIPS_CONFIG2_SL_MASK	(0x0000000F)
+
+/*
+ * get_cache_line_size:
+ * Read config register
+ * Isolate instruction cache line size
+ * Interpret value as per MIPS manual: 2 << value
+ * Return cache line size
+ */
+static int get_cache_line_size(uint8_t type)
+{
+	switch (type) {
+	case ICACHE:
+		return 2 << ((read_c0_config1() >> MIPS_CONFIG1_IL_SHIFT) &
+				MIPS_CONFIG1_IL_MASK);
+	case DCACHE:
+		return 2 << ((read_c0_config1() >> MIPS_CONFIG1_DL_SHIFT) &
+				MIPS_CONFIG1_DL_MASK);
+	case L2CACHE:
+		return 2 << ((read_c0_config2() >> MIPS_CONFIG2_SL_SHIFT) &
+				MIPS_CONFIG2_SL_MASK);
+	default:
+		printk(BIOS_ERR, "%s: Error: unsupported cache type.\n",
+				__func__);
+		return 0;
+	}
+	return 0;
+}
+
+void perform_cache_operation(uintptr_t start, size_t size, uint8_t operation)
+{
+	u32 line_size, line_mask;
+	uintptr_t end;
+
+	line_size = get_cache_line_size((operation >> CACHE_TYPE_SHIFT) &
+					CACHE_TYPE_MASK);
+	if (!line_size)
+		return;
+	line_mask = ~(line_size-1);
+	end = (start + (line_size - 1) + size) & line_mask;
+	start &= line_mask;
+	if ((operation & L2CACHE) == L2CACHE)
+		write_c0_l23taglo(0);
+	while (start < end) {
+		switch (operation) {
+		case CACHE_CODE(ICACHE, WB_INVD):
+			cache_op(CACHE_CODE(ICACHE, WB_INVD), start);
+			break;
+		case CACHE_CODE(DCACHE, WB_INVD):
+			cache_op(CACHE_CODE(DCACHE, WB_INVD), start);
+			break;
+		case CACHE_CODE(L2CACHE, WB_INVD):
+			cache_op(CACHE_CODE(L2CACHE, WB_INVD), start);
+			break;
+		default:
+			return;
+		}
+		start += line_size;
+	}
+	asm("sync");
+}
+
+void cache_invalidate_all(uintptr_t start, size_t size)
+{
+	perform_cache_operation(start, size, CACHE_CODE(ICACHE, WB_INVD));
+	perform_cache_operation(start, size, CACHE_CODE(DCACHE, WB_INVD));
+	perform_cache_operation(start, size, CACHE_CODE(L2CACHE, WB_INVD));
+}
+
+void arch_segment_loaded(uintptr_t start, size_t size, int flags)
+{
+	cache_invalidate_all(start, size);
+	if (flags & SEG_FINAL)
+		cache_invalidate_all((uintptr_t)_cbfs_cache, _cbfs_cache_size);
+}
diff --git a/src/arch/mipseb/include/arch/byteorder.h b/src/arch/mipseb/include/arch/byteorder.h
new file mode 100644
index 0000000..a4360ed
--- /dev/null
+++ b/src/arch/mipseb/include/arch/byteorder.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#ifndef __MIPS_ARCH_BYTEORDER_H
+#define __MIPS_ARCH_BYTEORDER_H
+
+#ifndef __ORDER_LITTLE_ENDIAN__
+#errror "What endian are you!?"
+#endif
+
+#define __LITTLE_ENDIAN 1234
+
+#endif /* __MIPS_ARCH_BYTEORDER_H */
diff --git a/src/arch/mipseb/include/arch/cache.h b/src/arch/mipseb/include/arch/cache.h
new file mode 100644
index 0000000..a6fda1e
--- /dev/null
+++ b/src/arch/mipseb/include/arch/cache.h
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#ifndef __MIPS_ARCH_CACHE_H
+#define __MIPS_ARCH_CACHE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define CACHE_TYPE_SHIFT	(0)
+#define CACHE_OP_SHIFT		(2)
+#define CACHE_TYPE_MASK		(0x3)
+#define CACHE_OP_MASK		(0x7)
+
+/* Cache type */
+#define ICACHE			0x00
+#define DCACHE			0x01
+#define L2CACHE			0x03
+
+/* Cache operation*/
+#define WB_INVD			0x05
+
+#define CACHE_CODE(type, op)	((((type) & (CACHE_TYPE_MASK)) <<	\
+				(CACHE_TYPE_SHIFT)) |			\
+				(((op) & (CACHE_OP_MASK)) << (CACHE_OP_SHIFT)))
+
+/* Perform cache operation on cache lines for target addresses */
+void perform_cache_operation(uintptr_t start, size_t size, uint8_t operation);
+/* Invalidate all caches: instruction, data, L2 data */
+void cache_invalidate_all(uintptr_t start, size_t size);
+
+#endif /* __MIPS_ARCH_CACHE_H */
diff --git a/src/arch/mipseb/include/arch/cpu.h b/src/arch/mipseb/include/arch/cpu.h
new file mode 100644
index 0000000..a13113c
--- /dev/null
+++ b/src/arch/mipseb/include/arch/cpu.h
@@ -0,0 +1,171 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#ifndef __MIPS_ARCH_CPU_H
+#define __MIPS_ARCH_CPU_H
+
+#define asmlinkage
+
+#ifndef __PRE_RAM__
+
+#include <device/device.h>
+
+struct cpu_driver {
+	struct device_operations *ops;
+	struct cpu_device_id *id_table;
+};
+
+struct thread;
+
+struct cpu_info {
+	device_t cpu;
+	unsigned long index;
+};
+
+#endif /* !__PRE_RAM__ */
+
+/***************************************************************************
+ * The following section was copied from arch/mips/include/asm/mipsregs.h in
+ * the 3.14 kernel tree.
+ */
+
+/*
+ * Macros to access the system control coprocessor
+ */
+
+#define __read_32bit_c0_register(source, sel)				\
+({ int __res;								\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			"mfc0\t%0, " #source "\n\t"			\
+			: "=r" (__res));				\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips32\n\t"				\
+			"mfc0\t%0, " #source ", " #sel "\n\t"		\
+			".set\tmips0\n\t"				\
+			: "=r" (__res));				\
+	__res;								\
+})
+
+#define __write_32bit_c0_register(register, sel, value)			\
+do {									\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			"mtc0\t%z0, " #register "\n\t"			\
+			: : "Jr" ((unsigned int)(value)));		\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips32\n\t"				\
+			"mtc0\t%z0, " #register ", " #sel "\n\t"	\
+			".set\tmips0"					\
+			: : "Jr" ((unsigned int)(value)));		\
+} while (0)
+
+/* Shortcuts to access various internal registers, keep adding as needed. */
+#define read_c0_index()		__read_32bit_c0_register($0, 0)
+#define write_c0_index(val)	__write_32bit_c0_register($0, 0, (val))
+
+#define read_c0_entrylo0()	__read_32bit_c0_register($2, 0)
+#define write_c0_entrylo0(val)	__write_32bit_c0_register($2, 0, (val))
+
+#define read_c0_entrylo1()	__read_32bit_c0_register($3, 0)
+#define write_c0_entrylo1(val)	__write_32bit_c0_register($3, 0, (val))
+
+#define read_c0_pagemask()	__read_32bit_c0_register($5, 0)
+#define write_c0_pagemask(val)	__write_32bit_c0_register($5, 0, (val))
+
+#define read_c0_wired()		__read_32bit_c0_register($6, 0)
+#define write_c0_wired(val)	__write_32bit_c0_register($6, 0, (val))
+
+#define read_c0_count()		__read_32bit_c0_register($9, 0)
+#define write_c0_count(val)	__write_32bit_c0_register($9, 0, (val))
+
+#define read_c0_entryhi()	__read_32bit_c0_register($10, 0)
+#define write_c0_entryhi(val)	__write_32bit_c0_register($10, 0, (val))
+
+#define read_c0_cause()		__read_32bit_c0_register($13, 0)
+#define write_c0_cause(val)	__write_32bit_c0_register($13, 0, (val))
+
+#define read_c0_config1()	__read_32bit_c0_register($16, 1)
+#define write_c0_config1(val)	__write_32bit_c0_register($16, 1, (val))
+
+#define read_c0_config2()	__read_32bit_c0_register($16, 2)
+#define write_c0_config2(val)	__write_32bit_c0_register($16, 2, (val))
+
+#define read_c0_l23taglo()	__read_32bit_c0_register($28, 4)
+#define write_c0_l23taglo(val)	__write_32bit_c0_register($28, 4, (val))
+
+
+#define C0_ENTRYLO_PFN_SHIFT 6
+#define C0_ENTRYLO_WB (0x3 << 3) /* Cacheable, write-back, non-coherent */
+#define C0_ENTRYLO_D (0x1 << 2) /* Writeable */
+#define C0_ENTRYLO_V (0x1 << 1) /* Valid */
+#define C0_ENTRYLO_G (0x1 << 0) /* Global */
+
+#define C0_PAGEMASK_SHIFT 13
+#define C0_PAGEMASK_MASK 0xffff
+
+#define C0_WIRED_MASK 0x3f
+
+#define C0_CAUSE_DC (1 << 27)
+
+#define C0_CONFIG1_MMUSIZE_SHIFT 25
+#define C0_CONFIG1_MMUSIZE_MASK 0x3f
+
+/* Hazard handling */
+static inline void __nop(void)
+{
+	__asm__ __volatile__("nop");
+}
+
+static inline void __ssnop(void)
+{
+	__asm__ __volatile__("sll\t$0, $0, 1");
+}
+
+#define mtc0_tlbw_hazard()						\
+do {									\
+	__nop();							\
+	__nop();							\
+} while (0)
+
+#define tlbw_use_hazard()						\
+do {									\
+	__nop();							\
+	__nop();							\
+	__nop();							\
+} while (0)
+
+#define tlb_probe_hazard()						\
+do {									\
+	__nop();							\
+	__nop();							\
+	__nop();							\
+} while (0)
+
+#define back_to_back_c0_hazard()					\
+do {									\
+	__ssnop();							\
+	__ssnop();							\
+	__ssnop();							\
+} while (0)
+/**************************************************************************/
+
+#endif /* __MIPS_ARCH_CPU_H */
diff --git a/src/arch/mipseb/include/arch/early_variables.h b/src/arch/mipseb/include/arch/early_variables.h
new file mode 100644
index 0000000..c21fa8c
--- /dev/null
+++ b/src/arch/mipseb/include/arch/early_variables.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#ifndef __MIPS_ARCH_EARLY_VARIABLES_H
+#define __MIPS_ARCH_EARLY_VARIABLES_H
+
+#define CAR_GLOBAL
+#define CAR_MIGRATE(migrate_fn_)
+
+static inline void *car_get_var_ptr(void *var) { return var; }
+#define car_get_var(var) (var)
+#define car_sync_var(var) (var)
+#define car_set_var(var, val) { (var) = (val); }
+
+#endif /* __MIPS_ARCH_EARLY_VARIABLES_H */
diff --git a/src/arch/mipseb/include/arch/exception.h b/src/arch/mipseb/include/arch/exception.h
new file mode 100644
index 0000000..a872c04
--- /dev/null
+++ b/src/arch/mipseb/include/arch/exception.h
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#ifndef __MIPS_ARCH_EXCEPTION_H
+#define __MIPS_ARCH_EXCEPTION_H
+
+static inline void exception_init(void) {}
+
+#endif /* __MIPS_ARCH_EXCEPTION_H */
diff --git a/src/arch/mipseb/include/arch/header.ld b/src/arch/mipseb/include/arch/header.ld
new file mode 100644
index 0000000..9310e33
--- /dev/null
+++ b/src/arch/mipseb/include/arch/header.ld
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 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.
+ */
+
+/* We use ELF as output format. So that we can debug the code in some form. */
+OUTPUT_ARCH(mips)
+
+PHDRS
+{
+	to_load PT_LOAD;
+}
+
+#ifdef __BOOTBLOCK__
+ENTRY(_start)
+#else
+ENTRY(stage_entry)
+#endif
diff --git a/src/arch/mipseb/include/arch/hlt.h b/src/arch/mipseb/include/arch/hlt.h
new file mode 100644
index 0000000..3d66beb
--- /dev/null
+++ b/src/arch/mipseb/include/arch/hlt.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#ifndef __MIPS_ARCH_HLT_H
+#define __MIPS_ARCH_HLT_H
+
+static inline __attribute__((always_inline)) void hlt(void)
+{
+	for (;;)
+		;
+}
+
+#endif /* __MIPS_ARCH_HLT_H */
diff --git a/src/arch/mipseb/include/arch/io.h b/src/arch/mipseb/include/arch/io.h
new file mode 100644
index 0000000..95c40d8
--- /dev/null
+++ b/src/arch/mipseb/include/arch/io.h
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * Based on arch/armv7/include/arch/io.h:
+ *   Copyright 2013 Google Inc.
+ *   Copyright (C) 1996-2000 Russell King
+ *
+ * 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.
+ */
+
+#ifndef __MIPS_ARCH_IO_H
+#define __MIPS_ARCH_IO_H
+
+#include <types.h>
+#include <arch/cache.h>
+#include <endian.h>
+
+static inline uint8_t read8(unsigned long addr)
+{
+	asm("sync");
+	return *(volatile uint8_t *)addr;
+}
+
+static inline uint16_t read16(unsigned long addr)
+{
+	asm("sync");
+	return *(volatile uint16_t *)addr;
+}
+
+static inline uint32_t read32(unsigned long addr)
+{
+	asm("sync");
+	return *(volatile uint32_t *)addr;
+}
+
+static inline void write8(unsigned long addr, uint8_t val)
+{
+	asm("sync");
+	*(volatile uint8_t *)addr = val;
+	asm("sync");
+}
+
+static inline void write16(unsigned long addr, uint16_t val)
+{
+	asm("sync");
+	*(volatile uint16_t *)addr = val;
+	asm("sync");
+}
+
+static inline void write32(unsigned long addr, uint32_t val)
+{
+	asm("sync");
+	*(volatile uint32_t *)addr = val;
+	asm("sync");
+}
+
+#endif	/* __MIPS_ARCH_IO_H */
diff --git a/src/arch/mipseb/include/arch/memlayout.h b/src/arch/mipseb/include/arch/memlayout.h
new file mode 100644
index 0000000..946fcf3
--- /dev/null
+++ b/src/arch/mipseb/include/arch/memlayout.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 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.
+ */
+
+/* This file contains macro definitions for memlayout.ld linker scripts. */
+
+#ifndef __ARCH_MEMLAYOUT_H
+#define __ARCH_MEMLAYOUT_H
+
+/* MIPS stacks need 8-byte alignment and stay in one place through ramstage. */
+/* TODO: Double-check that that's the correct alignment for our ABI. */
+#define STACK(addr, size) \
+	REGION(stack, addr, size, 8) \
+	_ = ASSERT(size >= 2K, "stack should be >= 2K, see toolchain.inc");
+
+#define DMA_COHERENT(addr, size) REGION(dma_coherent, addr, size, 4K)
+
+#endif /* __ARCH_MEMLAYOUT_H */
diff --git a/src/arch/mipseb/include/arch/mmu.h b/src/arch/mipseb/include/arch/mmu.h
new file mode 100644
index 0000000..e931ad9
--- /dev/null
+++ b/src/arch/mipseb/include/arch/mmu.h
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef __MIPS_ARCH_MMU_H
+#define __MIPS_ARCH_MMU_H
+
+#include <arch/cpu.h>
+#include <stddef.h>
+#include <stdint.h>
+
+static inline void tlb_write_indexed(void)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"tlbwi\n\t"
+		".set reorder");
+}
+
+static inline uint32_t get_max_pagesize(void)
+{
+	uint32_t max_pgsize;
+
+	write_c0_pagemask(C0_PAGEMASK_MASK << C0_PAGEMASK_SHIFT);
+	back_to_back_c0_hazard();
+	max_pgsize = (((read_c0_pagemask() >> C0_PAGEMASK_SHIFT) &
+		       C0_PAGEMASK_MASK) + 1) * 4 * KiB;
+
+	return max_pgsize;
+}
+
+static inline uint32_t get_tlb_size(void)
+{
+	uint32_t tlbsize;
+
+	tlbsize = ((read_c0_config1() >> C0_CONFIG1_MMUSIZE_SHIFT) &
+		   C0_CONFIG1_MMUSIZE_MASK) + 1;
+
+	return tlbsize;
+}
+
+int identity_map(uint32_t start, size_t len);
+
+#endif /* __MIPS_ARCH_MMU_H */
diff --git a/src/arch/mipseb/include/arch/pci_ops.h b/src/arch/mipseb/include/arch/pci_ops.h
new file mode 100644
index 0000000..df51a5a
--- /dev/null
+++ b/src/arch/mipseb/include/arch/pci_ops.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ */
+
+#ifndef ARCH_MIPS_PCI_OPS_H
+#define ARCH_MIPS_PCI_OPS_H
+
+#include <stddef.h>
+
+static inline const struct pci_bus_operations *pci_config_default(void)
+{
+	return NULL;
+}
+
+#endif
diff --git a/src/arch/mipseb/include/arch/stages.h b/src/arch/mipseb/include/arch/stages.h
new file mode 100644
index 0000000..17115cb
--- /dev/null
+++ b/src/arch/mipseb/include/arch/stages.h
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#ifndef __MIPS_ARCH_STAGES_H
+#define __MIPS_ARCH_STAGES_H
+
+extern void main(void);
+
+void stage_entry(void);
+void stage_exit(void *);
+
+#endif /* __MIPS_ARCH_STAGES_H */
diff --git a/src/arch/mipseb/include/arch/types.h b/src/arch/mipseb/include/arch/types.h
new file mode 100644
index 0000000..4e12181
--- /dev/null
+++ b/src/arch/mipseb/include/arch/types.h
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * Based on src/arch/armv7/include/arch/types.h
+ *
+ * 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.
+ */
+
+#ifndef __MIPS_ARCH_TYPES_H
+#define __MIPS_ARCH_TYPES_H
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
+#endif
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+
+typedef unsigned long phys_addr_t;
+typedef unsigned long phys_size_t;
+
+#endif /* __MIPS_ARCH_TYPES_H */
diff --git a/src/arch/mipseb/include/bootblock_common.h b/src/arch/mipseb/include/bootblock_common.h
new file mode 100644
index 0000000..4b2fd08
--- /dev/null
+++ b/src/arch/mipseb/include/bootblock_common.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#ifdef CONFIG_BOOTBLOCK_CPU_INIT
+#include CONFIG_BOOTBLOCK_CPU_INIT
+#endif
+
+#ifdef CONFIG_BOOTBLOCK_MAINBOARD_INIT
+#include CONFIG_BOOTBLOCK_MAINBOARD_INIT
+#else
+static void bootblock_mainboard_init(void)
+{
+}
+#endif
diff --git a/src/arch/mipseb/include/stdint.h b/src/arch/mipseb/include/stdint.h
new file mode 100644
index 0000000..a9579f5
--- /dev/null
+++ b/src/arch/mipseb/include/stdint.h
@@ -0,0 +1,104 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Based on src/arch/armv7/include/stdint.h
+ *
+ * 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.
+ */
+
+#ifndef __MIPS_STDINT_H
+#define __MIPS_STDINT_H
+
+#if defined(__GNUC__)
+#define __HAVE_LONG_LONG__ 1
+#else
+#define __HAVE_LONG_LONG__ 0
+#endif
+
+/* Exact integral types */
+typedef unsigned char      uint8_t;
+typedef signed char        int8_t;
+
+typedef unsigned short     uint16_t;
+typedef signed short       int16_t;
+
+typedef unsigned int       uint32_t;
+typedef signed int         int32_t;
+
+#if __HAVE_LONG_LONG__
+typedef unsigned long long uint64_t;
+typedef signed long long   int64_t;
+#endif
+
+/* Small types */
+typedef unsigned char      uint_least8_t;
+typedef signed char        int_least8_t;
+
+typedef unsigned short     uint_least16_t;
+typedef signed short       int_least16_t;
+
+typedef unsigned int       uint_least32_t;
+typedef signed int         int_least32_t;
+
+#if __HAVE_LONG_LONG__
+typedef unsigned long long uint_least64_t;
+typedef signed long long   int_least64_t;
+#endif
+
+/* Fast Types */
+typedef unsigned char      uint_fast8_t;
+typedef signed char        int_fast8_t;
+
+typedef unsigned int       uint_fast16_t;
+typedef signed int         int_fast16_t;
+
+typedef unsigned int       uint_fast32_t;
+typedef signed int         int_fast32_t;
+
+#if __HAVE_LONG_LONG__
+typedef unsigned long long uint_fast64_t;
+typedef signed long long   int_fast64_t;
+#endif
+
+/* Types for `void *' pointers.  */
+typedef int                intptr_t;
+typedef unsigned int       uintptr_t;
+
+/* Largest integral types */
+#if __HAVE_LONG_LONG__
+typedef long long int      intmax_t;
+typedef unsigned long long uintmax_t;
+#else
+typedef long int           intmax_t;
+typedef unsigned long int  uintmax_t;
+#endif
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+#if __HAVE_LONG_LONG__
+typedef uint64_t u64;
+#endif
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+
+typedef uint8_t bool;
+#define true	1
+#define false	0
+
+
+#undef __HAVE_LONG_LONG__
+
+#endif /* __MIPS_STDINT_H */
diff --git a/src/arch/mipseb/mmu.c b/src/arch/mipseb/mmu.c
new file mode 100644
index 0000000..706d05e
--- /dev/null
+++ b/src/arch/mipseb/mmu.c
@@ -0,0 +1,104 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 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.
+ */
+
+#include <arch/cpu.h>
+#include <arch/mmu.h>
+#include <console/console.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#define MIN_PAGE_SIZE (4 * KiB)
+
+static int add_wired_tlb_entry(uint32_t entrylo0, uint32_t entrylo1,
+			       uint32_t entryhi, uint32_t pgsize)
+{
+	uint32_t tlbindex;
+
+	tlbindex = read_c0_wired();
+	if (tlbindex >= get_tlb_size() || tlbindex >= C0_WIRED_MASK) {
+		printk(BIOS_ERR, "Ran out of TLB entries\n");
+		return -1;
+	}
+	write_c0_wired(tlbindex + 1);
+	write_c0_index(tlbindex);
+	write_c0_pagemask(((pgsize / MIN_PAGE_SIZE) - 1) << C0_PAGEMASK_SHIFT);
+	write_c0_entryhi(entryhi);
+	write_c0_entrylo0(entrylo0);
+	write_c0_entrylo1(entrylo1);
+	mtc0_tlbw_hazard();
+	tlb_write_indexed();
+	tlbw_use_hazard();
+
+	return 0;
+}
+
+static uint32_t pick_pagesize(uint32_t start, uint32_t len)
+{
+	uint32_t pgsize, max_pgsize;
+
+	max_pgsize = get_max_pagesize();
+	for (pgsize = max_pgsize;
+	     pgsize >= MIN_PAGE_SIZE;
+	     pgsize = pgsize / 4) {
+		/*
+		 * Each TLB entry maps a pair of virtual pages.  To avoid
+		 * aliasing, pick the largest page size that is at most
+		 * half the size of the region we're trying to map.
+		 */
+		if (IS_ALIGNED(start, 2 * pgsize) && (2 * pgsize <= len))
+			break;
+	}
+
+	return pgsize;
+}
+
+/*
+ * Identity map the memory from [start,start+len] in the TLB using the
+ * largest suitable page size so as to conserve TLB entries.
+ */
+int identity_map(uint32_t start, size_t len)
+{
+	uint32_t pgsize, pfn, entryhi, entrylo0, entrylo1;
+
+	while (len > 0) {
+		pgsize = pick_pagesize(start, len);
+		entryhi = start;
+		pfn = start >> 12;
+		entrylo0 = (pfn << C0_ENTRYLO_PFN_SHIFT) | C0_ENTRYLO_WB |
+			C0_ENTRYLO_D | C0_ENTRYLO_V | C0_ENTRYLO_G;
+		start += pgsize;
+		len -= MIN(len, pgsize);
+		if (len >= pgsize) {
+			pfn = start >> 12;
+			entrylo1 = (pfn << C0_ENTRYLO_PFN_SHIFT) |
+				C0_ENTRYLO_WB | C0_ENTRYLO_D | C0_ENTRYLO_V |
+				C0_ENTRYLO_G;
+			start += pgsize;
+			len -= MIN(len, pgsize);
+		} else {
+			entrylo1 = 0;
+		}
+		if (add_wired_tlb_entry(entrylo0, entrylo1, entryhi, pgsize))
+			return -1;
+	}
+
+	return 0;
+}
diff --git a/src/arch/mipseb/stages.c b/src/arch/mipseb/stages.c
new file mode 100644
index 0000000..f6cefbb
--- /dev/null
+++ b/src/arch/mipseb/stages.c
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#include <arch/stages.h>
+#include <arch/cache.h>
+
+void stage_entry(void)
+{
+	main();
+}
+
+void stage_exit(void *addr)
+{
+	void (*doit)(void) = addr;
+	doit();
+}
diff --git a/src/arch/mipseb/tables.c b/src/arch/mipseb/tables.c
new file mode 100644
index 0000000..3d6d701
--- /dev/null
+++ b/src/arch/mipseb/tables.c
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Based on src/arch/armv7/tables.c:
+ *   Copyright (C) 2003 Eric Biederman
+ *   Copyright (C) 2005 Steve Magnani
+ *   Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * 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.
+ */
+
+#include <console/console.h>
+#include <cpu/cpu.h>
+#include <boot/tables.h>
+#include <boot/coreboot_tables.h>
+#include <string.h>
+#include <cbmem.h>
+#include <lib.h>
+
+#define MAX_COREBOOT_TABLE_SIZE (8 * 1024)
+
+void write_tables(void)
+{
+	unsigned long table_pointer, new_table_pointer;
+
+	post_code(0x9d);
+
+	table_pointer = (unsigned long)cbmem_add(CBMEM_ID_CBTABLE,
+						 MAX_COREBOOT_TABLE_SIZE);
+	if (!table_pointer) {
+		printk(BIOS_ERR, "Could not add CBMEM for coreboot table.\n");
+		return;
+	}
+
+	new_table_pointer = write_coreboot_table(0UL, 0UL, table_pointer,
+						 table_pointer);
+
+	if (new_table_pointer > (table_pointer + MAX_COREBOOT_TABLE_SIZE))
+		printk(BIOS_ERR, "coreboot table didn't fit (%lx/%x bytes)\n",
+		       new_table_pointer - table_pointer,
+		       MAX_COREBOOT_TABLE_SIZE);
+
+	printk(BIOS_DEBUG, "coreboot table: %ld bytes.\n",
+	       new_table_pointer - table_pointer);
+
+	post_code(0x9e);
+
+	/* Print CBMEM sections */
+	cbmem_list();
+}
diff --git a/src/console/Kconfig b/src/console/Kconfig
index 7d6fa0e..60d9ce0 100644
--- a/src/console/Kconfig
+++ b/src/console/Kconfig
@@ -2,7 +2,7 @@ menu "Console"
 
 config BOOTBLOCK_CONSOLE
 	bool "Enable early (bootblock) console output."
-	depends on ARCH_ARM || ARCH_RISCV || ARCH_MIPS
+	depends on ARCH_ARM || ARCH_RISCV || ARCH_MIPS || ARCH_MIPSEB
 	default n
 	help
 	  Use console during the bootblock if supported
diff --git a/src/console/vtxprintf.c b/src/console/vtxprintf.c
index 2fcefd2..4213baa 100644
--- a/src/console/vtxprintf.c
+++ b/src/console/vtxprintf.c
@@ -11,8 +11,10 @@
 #define call_tx(x) tx_byte(x, data)
 
 #if !CONFIG_ARCH_MIPS
+#if !CONFIG_ARCH_MIPSEB
 #define SUPPORT_64BIT_INTS
 #endif
+#endif
 
 /* haha, don't need ctype.c */
 #define isdigit(c)	((c) >= '0' && (c) <= '9')
diff --git a/src/cpu/mips/Kconfig b/src/cpu/mips/Kconfig
index d0fa1ac..c8e02f0 100644
--- a/src/cpu/mips/Kconfig
+++ b/src/cpu/mips/Kconfig
@@ -24,3 +24,10 @@ config CPU_MIPS
 	select ARCH_VERSTAGE_MIPS
 	select ARCH_ROMSTAGE_MIPS
 	select ARCH_RAMSTAGE_MIPS
+
+config CPU_MIPSEB
+	bool
+	select ARCH_BOOTBLOCK_MIPSEB
+	select ARCH_VERSTAGE_MIPSEB
+	select ARCH_ROMSTAGE_MIPSEB
+	select ARCH_RAMSTAGE_MIPSEB
diff --git a/src/mainboard/ubiquity/Kconfig b/src/mainboard/ubiquity/Kconfig
new file mode 100644
index 0000000..6f82401
--- /dev/null
+++ b/src/mainboard/ubiquity/Kconfig
@@ -0,0 +1,34 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2012 The ChromiumOS Authors
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## 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.
+##
+if VENDOR_UBIQUITY
+
+choice
+	prompt "Mainboard model"
+
+source "src/mainboard/ubiquity/*/Kconfig.name"
+
+endchoice
+
+source "src/mainboard/ubiquity/*/Kconfig"
+
+config MAINBOARD_VENDOR
+	string "Mainboard Vendor"
+	default "ubiquity"
+
+endif # VENDOR_UBIQUITY
diff --git a/src/mainboard/ubiquity/Kconfig.name b/src/mainboard/ubiquity/Kconfig.name
new file mode 100644
index 0000000..94aa98f
--- /dev/null
+++ b/src/mainboard/ubiquity/Kconfig.name
@@ -0,0 +1,2 @@
+config VENDOR_UBIQUITY
+	bool "Ubiquity"
diff --git a/src/mainboard/ubiquity/nanostation_xm/Kconfig b/src/mainboard/ubiquity/nanostation_xm/Kconfig
new file mode 100644
index 0000000..2a6d3f7
--- /dev/null
+++ b/src/mainboard/ubiquity/nanostation_xm/Kconfig
@@ -0,0 +1,61 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2014 Imagination Technologies
+#
+# 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.
+#
+
+if BOARD_UBIQUITY_NANOSTATION_XM
+
+config BOARD_SPECIFIC_OPTIONS
+	def_bool y
+	select BOARD_ROMSIZE_KB_512
+	select BOOTBLOCK_CONSOLE
+	select SPI_FLASH_WINBOND
+	select CPU_ATHEROS_AR7240
+	select COMMON_CBFS_SPI_WRAPPER
+	select SPI_FLASH
+
+config MAINBOARD_DIR
+	string
+	default "ubiquity/nanostation_xm"
+
+config MAINBOARD_PART_NUMBER
+	string
+	default "Ubiquity Nanostation"
+
+config BOOTBLOCK_MAINBOARD_INIT
+	string
+	default "mainboard/ubiquity/nanostation_xm/bootblock.c"
+
+config DRAM_SIZE_MB
+	int
+	default 32
+
+config TTYS0_LCS
+	int
+	default 3
+
+config CONSOLE_SERIAL_UART_ADDRESS
+	hex
+	depends on DRIVERS_UART
+	default 0xB8101500
+
+config BOOT_MEDIA_SPI_BUS
+	int
+	default 1
+
+endif
diff --git a/src/mainboard/ubiquity/nanostation_xm/Kconfig.name b/src/mainboard/ubiquity/nanostation_xm/Kconfig.name
new file mode 100644
index 0000000..9f75675
--- /dev/null
+++ b/src/mainboard/ubiquity/nanostation_xm/Kconfig.name
@@ -0,0 +1,2 @@
+config BOARD_UBIQUITY_NANOSTATION_XM
+	bool "Nanostation XM"
diff --git a/src/mainboard/ubiquity/nanostation_xm/Makefile.inc b/src/mainboard/ubiquity/nanostation_xm/Makefile.inc
new file mode 100644
index 0000000..47206e4
--- /dev/null
+++ b/src/mainboard/ubiquity/nanostation_xm/Makefile.inc
@@ -0,0 +1,29 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright 2015 Alexander Couzens <lynxis at fe80.eu>
+#
+# 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.
+#
+
+bootblock-y += clocks.c
+romstage-y += clocks.c
+ramstage-y += clocks.c
+
+ramstage-y += mainboard.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/ubiquity/nanostation_xm/bootblock.c b/src/mainboard/ubiquity/nanostation_xm/bootblock.c
new file mode 100644
index 0000000..edd017f
--- /dev/null
+++ b/src/mainboard/ubiquity/nanostation_xm/bootblock.c
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#include <arch/io.h>
+#include <stdint.h>
+#include <soc/clocks.h>
+#include <assert.h>
+#include <boardid.h>
+
+static void bootblock_mainboard_init(void)
+{
+}
+
+
+static int init_extra_hardware(void)
+{
+	return 0;
+}
diff --git a/src/mainboard/ubiquity/nanostation_xm/clocks.c b/src/mainboard/ubiquity/nanostation_xm/clocks.c
new file mode 100644
index 0000000..d7ed892
--- /dev/null
+++ b/src/mainboard/ubiquity/nanostation_xm/clocks.c
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexander Couzens <lynxis at fe80.eu>
+ *
+ * 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.
+ *
+ */
+
+#include <soc/clocks.h>
+
+int ar71xx_get_ref_clock_mhz()
+{
+	return 40;
+}
diff --git a/src/mainboard/ubiquity/nanostation_xm/devicetree.cb b/src/mainboard/ubiquity/nanostation_xm/devicetree.cb
new file mode 100644
index 0000000..7b74d7e
--- /dev/null
+++ b/src/mainboard/ubiquity/nanostation_xm/devicetree.cb
@@ -0,0 +1,23 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2015 Alexander Couzens <lynxis at fe80.eu>
+#
+# 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.
+#
+
+chip soc/atheros/ar7240
+	device cpu_cluster 0 on end
+end
diff --git a/src/mainboard/ubiquity/nanostation_xm/mainboard.c b/src/mainboard/ubiquity/nanostation_xm/mainboard.c
new file mode 100644
index 0000000..c02e833
--- /dev/null
+++ b/src/mainboard/ubiquity/nanostation_xm/mainboard.c
@@ -0,0 +1,17 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexander Couzens <lynxis at fe80.eu>
+ *
+ * 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.
+ *
+ */
+
diff --git a/src/mainboard/ubiquity/nanostation_xm/memlayout.ld b/src/mainboard/ubiquity/nanostation_xm/memlayout.ld
new file mode 100644
index 0000000..ead7f47
--- /dev/null
+++ b/src/mainboard/ubiquity/nanostation_xm/memlayout.ld
@@ -0,0 +1 @@
+#include <soc/memlayout.ld>
diff --git a/src/soc/atheros/ar7240/Kconfig b/src/soc/atheros/ar7240/Kconfig
new file mode 100644
index 0000000..17d29ec
--- /dev/null
+++ b/src/soc/atheros/ar7240/Kconfig
@@ -0,0 +1,40 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2014 Imagination Technologies
+#
+# 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.
+#
+
+config CPU_ATHEROS_AR7240
+	select CPU_MIPSEB
+	select GENERIC_UDELAY
+	select HAVE_MONOTONIC_TIMER
+	select HAVE_UART_SPECIAL
+	select GENERIC_GPIO_LIB
+	bool
+
+if CPU_ATHEROS_AR7240
+
+config BOOTBLOCK_CPU_INIT
+	string
+	default "soc/atheros/ar7240/bootblock.c"
+
+config CONSOLE_SERIAL_UART_ADDRESS
+        hex
+        depends on DRIVERS_UART
+        default 0xB8020000
+
+endif
diff --git a/src/soc/atheros/ar7240/Makefile.inc b/src/soc/atheros/ar7240/Makefile.inc
new file mode 100644
index 0000000..94a06e0
--- /dev/null
+++ b/src/soc/atheros/ar7240/Makefile.inc
@@ -0,0 +1,60 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2015 Alexander Couzens <lynxis at fe80.eu>
+#
+# 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.
+#
+
+ifeq ($(CONFIG_CPU_ATHEROS_AR7240),y)
+
+# We enable CBFS_SPI_WRAPPER for Pistachio targets.
+bootblock-y += clocks.c
+bootblock-y += spi.c
+romstage-y += spi.c
+ramstage-y += spi.c
+
+ifeq ($(CONFIG_DRIVERS_UART),y)
+bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += uart.c
+romstage-y += uart.c
+ramstage-y += uart.c
+endif
+
+bootblock-y += monotonic_timer.c
+
+ramstage-y += cbmem.c
+ramstage-y += monotonic_timer.c
+
+romstage-y += cbmem.c
+romstage-y += ddr1_init.c
+romstage-y += ddr2_init.c
+romstage-y += romstage.c
+romstage-y += monotonic_timer.c
+
+CPPFLAGS_common += -Isrc/soc/atheros/ar7240/include/
+CPPFLAGS_common += -Isrc/soc/atheros/common/include/
+
+# Generate the actual coreboot bootblock code
+$(objcbfs)/bootblock.raw: $(objcbfs)/bootblock.elf
+	@printf "    OBJCOPY    $(subst $(obj)/,,$(@))\n"
+	$(OBJCOPY_bootblock) -O binary $< $@.tmp
+	@mv $@.tmp $@
+
+# Create a complete bootblock which will start up the system
+$(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.raw $(BIMGTOOL)
+	@printf "    BIMGTOOL   $(subst $(obj)/,,$(@))\n"
+	$(BIMGTOOL) $< $@ $(call loadaddr,bootblock)
+
+endif
diff --git a/src/soc/atheros/ar7240/bootblock.c b/src/soc/atheros/ar7240/bootblock.c
new file mode 100644
index 0000000..a047954
--- /dev/null
+++ b/src/soc/atheros/ar7240/bootblock.c
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#include <arch/cpu.h>
+#include <arch/mmu.h>
+#include <assert.h>
+#include <stdint.h>
+#include <symbols.h>
+
+static void bootblock_cpu_init(void)
+{
+	uint32_t cause;
+
+	/*
+	 * Make sure the count register is counting by clearing the "Disable
+	 * Counter" bit, in case it is set.
+	 */
+	cause = read_c0_cause();
+	if (cause & C0_CAUSE_DC)
+		write_c0_cause(cause & ~(C0_CAUSE_DC));
+
+	/* And make sure that it starts from zero. */
+	write_c0_count(0);
+}
+
+static void bootblock_mmu_init(void)
+{
+	uint32_t null_guard_size =  1 * MiB;
+	uint32_t dram_base, dram_size;
+
+	write_c0_wired(0);
+
+	dram_base = (uint32_t)_dram;
+	dram_size = CONFIG_DRAM_SIZE_MB * MiB;
+
+	/*
+	 * To be able to catch NULL pointer dereference attempts, lets not map
+	 * memory close to zero.
+	 */
+	if (dram_base < null_guard_size) {
+		dram_base += null_guard_size;
+		dram_size -= null_guard_size;
+	}
+
+	/* use config ifdef when something doesnt have sram? */
+	assert(!identity_map(dram_base, dram_size));
+	//assert(!identity_map((uint32_t)_sram, _sram_size));
+}
diff --git a/src/soc/atheros/ar7240/cbmem.c b/src/soc/atheros/ar7240/cbmem.c
new file mode 100644
index 0000000..227fd74
--- /dev/null
+++ b/src/soc/atheros/ar7240/cbmem.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexander Couzens <lynxis at fe80.eu>
+ *
+ * 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.
+ */
+
+#include <cbmem.h>
+#include <stdlib.h>
+#include <symbols.h>
+
+void *cbmem_top(void)
+{
+	/* the stack lives on the end */
+	return _dram + (CONFIG_DRAM_SIZE_MB << 20) - 8 * 1024;
+}
diff --git a/src/soc/atheros/ar7240/clocks.c b/src/soc/atheros/ar7240/clocks.c
new file mode 100644
index 0000000..631b2dd
--- /dev/null
+++ b/src/soc/atheros/ar7240/clocks.c
@@ -0,0 +1,101 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ */
+
+#include <arch/io.h>
+#include <soc/ar71xx_regs.h>
+#include <assert.h>
+#include <delay.h>
+#include <soc/clocks.h>
+#include <timer.h>
+
+#include <soc/clocks.h>
+
+/* read, modify with mask + val and write it back */
+static inline void rmw32(unsigned long addr, uint32_t mask, uint32_t val) {
+	uint32_t value = read32(addr);
+	value &= ~mask;
+	value |= val;
+	write32(addr, value);
+}
+
+int ath7240_set_pll(struct pll_parameters *params) {
+	uint32_t cpu_config = 0;
+	uint32_t bypass = AR724X_CPU_PLL_BYPASS | AR724X_CPU_PLL_RESET | AR724X_CPU_PLL_NOPWD;
+
+	/* check if pll params are valid */
+	if(params->div_multiplier >= (1 << 10))
+		return 1;
+
+	if(params->refdiv >= (1 << 4))
+		return 1;
+
+	/* check if we already initilized the pll
+	 * the cpu will reset when we setup our plls and this code aren't allowed to run again
+	 * otherwise we get into a endless loop
+	 */
+	//if (read32(AR71XX_PLL_BASE + AR724X_PLL_REG_CPU_CLOCK_CTRL)
+	//		& AR724X_CPU_PLL_RESET_SWITCH) {
+	//	return 0;
+	//}
+
+	/* bypass cpu pll, reset pll, pretend powerdown of pll */
+	rmw32(AR71XX_PLL_BASE + AR724X_PLL_REG_CPU_CONFIG,
+			bypass,
+			bypass);
+
+	/* set plls */
+	cpu_config = (params->div_multiplier & AR724X_PLL_FB_MASK) << AR724X_PLL_FB_SHIFT;
+	cpu_config |= (params->refdiv & AR724X_PLL_REF_DIV_MASK) << AR724X_PLL_REF_DIV_SHIFT;
+	cpu_config |= (params->divisor_ahb & AR724X_AHB_DIV_MASK) << AR724X_AHB_DIV_SHIFT;
+	cpu_config |= (params->divisor_ddr & AR724X_DDR_DIV_MASK) << AR724X_DDR_DIV_SHIFT;
+
+	write32(AR724X_PLL_REG_CPU_CONFIG, cpu_config | bypass);
+
+	/* take pll out of reset */
+	bypass &= ~AR724X_CPU_PLL_RESET;
+	write32(AR724X_PLL_REG_CPU_CONFIG, cpu_config | bypass);
+
+	/* wait until pll is done updateing */
+	while ((read32(AR724X_PLL_REG_CPU_CONFIG) & AR724X_CPU_PLL_UPDATING) == 0)
+		;
+
+	/* disable bypass */
+	write32(AR724X_PLL_REG_CPU_CONFIG, cpu_config);
+
+	/* setting and clearing reset clock switch is taken from u-boot source GPL */
+	/* TODO: check if this is really needed. why do we need to reset the cpu ? */
+	/* cause the reset of the cpu using reset switch */
+/*	rmw32(AR71XX_PLL_BASE + AR724X_PLL_REG_CPU_CLOCK_CTRL,
+			AR724X_CPU_PLL_CTRL_RESET_SWITCH,
+			AR724X_CPU_PLL_CTRL_RESET_SWITCH);
+
+	rmw32(AR71XX_PLL_BASE + AR724X_PLL_REG_CPU_CLOCK_CTRL,
+			AR724X_CPU_PLL_CTRL_CLOCK_SWITCH,
+			AR724X_CPU_PLL_CTRL_CLOCK_SWITCH); */
+
+	/* clear AR724X_CPU_PLL_CTRL_RESET_SWITCH & AR724X_CPU_PLL_CTRL_CLOCK_SWITCH */
+/*	rmw32(AR71XX_PLL_BASE + AR724X_PLL_REG_CPU_CLOCK_CTRL,
+			AR724X_CPU_PLL_CTRL_RESET_SWITCH,,
+			0);
+	rmw32(AR71XX_PLL_BASE + AR724X_PLL_REG_CPU_CLOCK_CTRL,
+			AR724X_CPU_PLL_CTRL_CLOCK_SWITCH,,
+			0); */
+	return 0;
+}
diff --git a/src/soc/atheros/ar7240/ddr1_init.c b/src/soc/atheros/ar7240/ddr1_init.c
new file mode 100644
index 0000000..e69de29
diff --git a/src/soc/atheros/ar7240/ddr2_init.c b/src/soc/atheros/ar7240/ddr2_init.c
new file mode 100644
index 0000000..e69de29
diff --git a/src/soc/atheros/ar7240/include/soc/clocks.h b/src/soc/atheros/ar7240/include/soc/clocks.h
new file mode 100644
index 0000000..640fb4b
--- /dev/null
+++ b/src/soc/atheros/ar7240/include/soc/clocks.h
@@ -0,0 +1,91 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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.
+ *
+ */
+
+#ifndef __SOC_ATHEROS_AR7240_CLOCKS_H__
+#define __SOC_ATHEROS_AR7240_CLOCKS_H__
+
+/* atheros has 4 main clock source
+ * all clocks are derived from the external crystal (ref clock) via PLL.
+ *
+ * taken from Atheros Datasheet AR7242 April 2011, p 20, Figure 2-4 Basic Clocking Diagram
+ *
+ *   | Ref Clk
+ * -----
+ * |PLL|
+ * -----
+ *   |
+ * ----------
+ * \        /-- PLL Bypass
+ *  \------/
+ *    |
+ *    |---------------------------------------------------
+ *    |            |                               |
+ *    |        |----------|                  |-----------|
+ *    |        |  DIV     |                  |  DIV      |
+ *    |        | by 1 or 2| Ref Clk          | by 2 or 4 | Ref Clk
+ *    |        |----------|  |               |-----------|  |
+ *    |           |          |                   |          |
+ *    |        ----------------                ---------------
+ *    |        \              /-- PLL Bypass   \             /-- PLL Bypass
+ *    |         \------------/                  \-----------/
+ *    |              |                               |
+ *    |              |                               |
+ *    |             DDR Clock                     AHB Clock
+ *    |
+ *    |
+ *    CPU Clock
+ *
+ * Ref clock - the external crystal. 25mhz or 40mhz
+ * CPU clock
+ * DDR clock
+ * AHB clock - from this clock most subsystem will derive it's clocksa
+ *
+ */
+
+enum ref_clock {
+	REF_CLOCK25MHZ = 0,
+	REF_CLOCK40MHZ,
+};
+
+enum divisor_ddr {
+	DIV_DDR_BY_1 = 0,
+	DIV_DDR_BY_2 = 1,
+};
+
+enum divisor_ahb {
+	DIV_AHB_BY_2 = 0,
+	DIV_AHB_BY_4 = 1,
+};
+
+/* cpu clock freq calculation
+ * freq = (div_multiplier / refclock_div) * ref_clock /2
+ *
+ */
+struct pll_parameters {
+	enum ref_clock refclock;
+	enum divisor_ddr divisor_ddr;
+	enum divisor_ahb divisor_ahb;
+	int div_multiplier; /* primary multiplier - named DIV in datasheet. p51 CPU_PLL_CONFIG (AR71XX_PLL_REG_CPU_CONFIG) */
+	int refdiv; /* reference clock divider */
+};
+
+int ath7240_set_pll(struct pll_parameters *params);
+
+int get_count_mhz_freq(void);
+int ar71xx_get_ref_clock_mhz(void);
+
+#endif
diff --git a/src/soc/atheros/ar7240/include/soc/ddr_init.h b/src/soc/atheros/ar7240/include/soc/ddr_init.h
new file mode 100644
index 0000000..48bbf4e
--- /dev/null
+++ b/src/soc/atheros/ar7240/include/soc/ddr_init.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexander Couzens <lynxis at fe80.eu>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __SOC_IMGTEC_AR7240_DDR_INIT_H__
+#define __SOC_IMGTEC_AR7240_DDR_INIT_H__
+
+#define DDR_TIMEOUT			-1
+
+int init_ddr1(void);
+int init_ddr2(void);
+
+#endif
diff --git a/src/soc/atheros/ar7240/include/soc/ddr_private_reg.h b/src/soc/atheros/ar7240/include/soc/ddr_private_reg.h
new file mode 100644
index 0000000..5d04922
--- /dev/null
+++ b/src/soc/atheros/ar7240/include/soc/ddr_private_reg.h
@@ -0,0 +1,138 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexander Couzens <lynxis at fe80.eu>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __SOC_IMGTEC_AR7240_DDR_PRIVATE_REG_H__
+#define __SOC_IMGTEC_AR7240_DDR_PRIVATE_REG_H__
+
+#include <timer.h>
+
+#define MAX_WAIT_MICROS			100000
+
+#define TOPLEVEL_REGS			0xB8149000
+
+#define DDR_CTRL_OFFSET			(0x0020)
+#define DDR_CLK_EN_MASK			(0x00000002)
+#define DDR_CLK_EN_SHIFT		(1)
+#define DDR_CLK_EN_LENGTH		(1)
+
+#define DDR_PCTL			0xB8180000
+#define DDR_PCTL_SCFG_OFFSET		(0x0000)
+#define DDR_PCTL_SCTL_OFFSET		(0x0004)
+#define DDR_PCTL_STAT_OFFSET		(0x0008)
+#define DDR_PCTL_MCMD_OFFSET		(0x0040)
+#define DDR_PCTL_POWCTL_OFFSET		(0x0044)
+#define DDR_PCTL_POWSTAT_OFFSET		(0x0048)
+#define DDR_PCTL_CMDTSTAT_OFFSET	(0x004C)
+#define DDR_PCTL_CMDTSTATEN_OFFSET	(0x0050)
+#define DDR_PCTL_MCFG1_OFFSET		(0x007C)
+#define DDR_PCTL_MCFG_OFFSET		(0x0080)
+#define DDR_PCTL_MSTAT_OFFSET		(0x0088)
+#define DDR_PCTL_DTUAWDT_OFFSET		(0x00B0)
+#define DDR_PCTL_TOGCNT1U_OFFSET	(0x00C0)
+#define DDR_PCTL_TINIT_OFFSET		(0x00C4)
+#define DDR_PCTL_TRSTH_OFFSET		(0x00C8)
+#define DDR_PCTL_TOGG_CNTR_100NS_OFFSET	(0x00CC)
+#define DDR_PCTL_TREFI_OFFSET		(0x00D0)
+#define DDR_PCTL_TMRD_OFFSET		(0x00D4)
+#define DDR_PCTL_TRFC_OFFSET		(0x00D8)
+#define DDR_PCTL_TRP_OFFSET		(0x00DC)
+#define DDR_PCTL_TRTW_OFFSET		(0x00E0)
+#define DDR_PCTL_TAL_OFFSET		(0x00E4)
+#define DDR_PCTL_TCL_OFFSET		(0x00E8)
+#define DDR_PCTL_TCWL_OFFSET		(0x00EC)
+#define DDR_PCTL_TRAS_OFFSET		(0x00F0)
+#define DDR_PCTL_TRC_OFFSET		(0x00F4)
+#define DDR_PCTL_TRCD_OFFSET		(0x00F8)
+#define DDR_PCTL_TRRD_OFFSET		(0x00FC)
+#define DDR_PCTL_TRTP_OFFSET		(0x0100)
+#define DDR_PCTL_TWR_OFFSET		(0x0104)
+#define DDR_PCTL_TWTR_OFFSET		(0x0108)
+#define DDR_PCTL_TEXSR_OFFSET		(0x010C)
+#define DDR_PCTL_TXP_OFFSET		(0x0110)
+#define DDR_PCTL_TXPDLL_OFFSET		(0x0114)
+#define DDR_PCTL_TZQCS_OFFSET		(0x0118)
+#define DDR_PCTL_TDQS_OFFSET		(0x0120)
+#define DDR_PCTL_TCKE_OFFSET		(0x012C)
+#define DDR_PCTL_TMOD_OFFSET		(0x0130)
+#define DDR_PCTL_TZQCL_OFFSET		(0x0138)
+#define DDR_PCTL_TCKESR_OFFSET		(0x0140)
+#define DDR_PCTL_TREFI_MEM_DDR3_OFFSET	(0x0148)
+#define DDR_PCTL_DTUWACTL_OFFSET	(0x0200)
+#define DDR_PCTL_DTURACTL_OFFSET	(0x0204)
+#define DDR_PCTL_DTUCFG_OFFSET		(0x0208)
+#define DDR_PCTL_DTUECTL_OFFSET		(0x020C)
+#define DDR_PCTL_DTUWD0_OFFSET		(0x0210)
+#define DDR_PCTL_DTUWD1_OFFSET		(0x0214)
+#define DDR_PCTL_DTUWD2_OFFSET		(0x0218)
+#define DDR_PCTL_DTUWD3_OFFSET		(0x021C)
+#define DDR_PCTL_DFIODTCFG_OFFSET	(0x0244)
+#define DDR_PCTL_DFIODTCFG1_OFFSET	(0x0248)
+#define DDR_PCTL_DFITPHYWRDATA_OFFSET	(0x0250)
+#define DDR_PCTL_DFIWRLAT_OFFSET	(0x0254)
+#define DDR_PCTL_DFITRDDATAEN_OFFSET	(0x0260)
+#define DDR_PCTL_DFITPHYRDLAT_OFFSET	(0x0264)
+#define DDR_PCTL_DFIUPDCFG_OFFSET	(0x0290)
+#define DDR_PCTL_DFISTAT0_OFFSET	(0x02C0)
+#define DDR_PCTL_DFISTCFG0_OFFSET	(0x02C4)
+#define DDR_PCTL_DFISTCFG1_OFFSET	(0x02C8)
+#define DDR_PCTL_DFISTCFG2_OFFSET	(0x02D8)
+#define DDR_PCTL_DFILPCFG0_OFFSET	(0x02F0)
+#define DDR_PCTL_PCFG0_OFFSET		(0x0400)
+#define DDR_PCTL_CCFG_OFFSET		(0x0480)
+#define DDR_PCTL_DCFG_OFFSET		(0x0484)
+#define DDR_PCTL_CCFG1_OFFSET		(0x048C)
+
+#define DDR_PHY				0xB8180800
+#define DDRPHY_PIR_OFFSET		(0x0004)
+#define DDRPHY_PGCR_OFFSET		(0x0008)
+#define DDRPHY_PGSR_OFFSET		(0x000C)
+#define DDRPHY_DLLGCR_OFFSET		(0x0010)
+#define DDRPHY_PTR0_OFFSET		(0x0018)
+#define DDRPHY_PTR1_OFFSET		(0x001C)
+#define DDRPHY_DSGCR_OFFSET		(0x002C)
+#define DDRPHY_DCR_OFFSET		(0x0030)
+#define DDRPHY_DTPR0_OFFSET		(0x0034)
+#define DDRPHY_DTPR1_OFFSET		(0x0038)
+#define DDRPHY_DTPR2_OFFSET		(0x003C)
+#define DDRPHY_MR_OFFSET		(0x0040)
+#define DDRPHY_EMR_OFFSET		(0x0044)
+#define DDRPHY_EMR2_OFFSET		(0x0048)
+#define DDRPHY_EMR3_OFFSET		(0x004C)
+#define DDRPHY_DTAR_OFFSET		(0x0054)
+#define DDRPHY_BISTRR_OFFSET		(0x0100)
+#define DDRPHY_BISTWCR_OFFSET		(0x010C)
+#define DDRPHY_BISTAR0_OFFSET		(0x0114)
+#define DDRPHY_BISTAR1_OFFSET		(0x0118)
+#define DDRPHY_BISTAR2_OFFSET		(0x011C)
+#define DDRPHY_BISTUDPR_OFFSET		(0x0120)
+#define DDRPHY_BISTGSR_OFFSET		(0x0124)
+
+#define DDR_TIMEOUT_VALUE_US		100000
+
+static int wait_for_completion(u32 reg, u32 exp_val)
+{
+	struct stopwatch sw;
+
+	stopwatch_init_usecs_expire(&sw, DDR_TIMEOUT_VALUE_US);
+	while (read32(reg) != exp_val) {
+		if (stopwatch_expired(&sw))
+			return DDR_TIMEOUT;
+	}
+	return 0;
+}
+
+#endif
diff --git a/src/soc/atheros/ar7240/include/soc/gpio.h b/src/soc/atheros/ar7240/include/soc/gpio.h
new file mode 100644
index 0000000..ec31e43
--- /dev/null
+++ b/src/soc/atheros/ar7240/include/soc/gpio.h
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Alexander Couzens <lynxis at fe80.eu>
+ *
+ * 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.
+ */
+
+#ifndef __SOC_ATHEROS_AR7240_GPIO_H__
+#define __SOC_ATHEROS_AR7240_GPIO_H__
+
+typedef unsigned gpio_t;
+
+#endif // __SOC_ATHEROS_AR7240_GPIO_H__
diff --git a/src/soc/atheros/ar7240/include/soc/memlayout.ld b/src/soc/atheros/ar7240/include/soc/memlayout.ld
new file mode 100644
index 0000000..00c17f4
--- /dev/null
+++ b/src/soc/atheros/ar7240/include/soc/memlayout.ld
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Alexander Couzens <lynxis at fe80.eu>
+ *
+ * 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.
+ */
+
+#include <memlayout.h>
+#include <vendorcode/google/chromeos/memlayout.h>
+
+#include <arch/header.ld>
+
+SECTIONS
+{
+	/*
+	 * All of DRAM (other than the DMA coherent area) is accessed through
+	 * the identity mapping.
+	 */
+	DRAM_START(0x00000000)
+	/* DMA coherent area: accessed via KSEG1. */
+	DMA_COHERENT(0x00100000, 1M)
+	POSTRAM_CBFS_CACHE(0x00200000, 192K)
+	PRERAM_CBFS_CACHE(0x00230000, 56K)
+	RAMSTAGE(0x0023e000, 128K)
+	STACK(0x00ffd000, 8K)
+
+	/*
+	 * GRAM becomes the SRAM.  Accessed through KSEG0 in the bootblock
+	 * and then through the identity mapping in ROM stage.
+	 */
+/*	SRAM_START(0x1a000000)
+	ROMSTAGE(0x1a005000, 40K)
+	PRERAM_CBFS_CACHE(0x1a012000, 56K)
+	SRAM_END(0x1a020000) */
+
+	/* Bootblock executes out of KSEG0 and sets up the identity mapping.
+	 * This is identical to SRAM above, and thus also limited 64K and
+	 * needs to avoid conflicts with items set up above.
+	 */
+	BOOTBLOCK(0xbfc00000, 32K)
+	ROMSTAGE(0xbfc08000, 32K)
+
+	/*
+	 * Let's use SRAM for stack and CBMEM console.  Always accessed
+	 * through KSEG0.
+	 */
+/*	PRERAM_CBMEM_CONSOLE(0x9b002000, 8K) */
+}
diff --git a/src/soc/atheros/ar7240/include/soc/spi.h b/src/soc/atheros/ar7240/include/soc/spi.h
new file mode 100644
index 0000000..fb24f2b
--- /dev/null
+++ b/src/soc/atheros/ar7240/include/soc/spi.h
@@ -0,0 +1,358 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexander Couzens <lynxis at fe80.eu>
+ *
+ * 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.
+ */
+
+
+#ifndef __SOC_ATHEROS_AR7240_SPI_H__
+#define __SOC_ATHEROS_AR7240_SPI_H__
+
+#include <arch/io.h>
+#include <arch/types.h>
+
+#define spi_read_reg_field(regval, field)		\
+(							\
+	((field##_MASK) == 0xFFFFFFFF) ?		\
+	(regval) :					\
+	(((regval) & (field##_MASK)) >> (field##_SHIFT))\
+)
+
+#define spi_write_reg_field(regval, field, val)		\
+(							\
+	((field##_MASK) == 0xFFFFFFFF) ?		\
+	(val) :						\
+	(((regval) & ~(field##_MASK)) |			\
+	(((val) << (field##_SHIFT)) & (field##_MASK)))	\
+)
+
+/*
+ * Parameter register
+ * Each of these corresponds to a single port (ie CS line) in the interface
+ * Fields	Name		Description
+ * ======	====		===========
+ * b31:24	CLK_RATE	Bit Clock rate = (24.576 * value / 512) MHz
+ * b23:16	CS_SETUP	Chip Select setup = (40 * value) ns
+ * b15:8	CS_HOLD		Chip Select hold = (40 * value) ns
+ * b7:0		CS_DELAY	Chip Select delay = (40 * value) ns
+ */
+
+#define SPIM_CLK_DIVIDE_MASK     (0xFF000000)
+#define SPIM_CS_SETUP_MASK       (0x00FF0000)
+#define SPIM_CS_HOLD_MASK        (0x0000FF00)
+#define SPIM_CS_DELAY_MASK       (0x000000FF)
+#define SPIM_CS_PARAM_MASK      (SPIM_CS_SETUP_MASK \
+				| SPIM_CS_HOLD_MASK \
+				| SPIM_CS_DELAY_MASK)
+
+#define SPIM_CLK_DIVIDE_SHIFT            (24)
+#define SPIM_CS_SETUP_SHIFT              (16)
+#define SPIM_CS_HOLD_SHIFT                (8)
+#define SPIM_CS_DELAY_SHIFT               (0)
+#define SPIM_CS_PARAM_SHIFT               (0)
+
+/* Control register */
+
+#define SPFI_DRIBBLE_COUNT_MASK  (0x000e0000)
+#define SPFI_MEMORY_IF_MASK      (0x00008000)
+#define SPIM_BYTE_DELAY_MASK     (0x00004000)
+#define SPIM_CS_DEASSERT_MASK    (0x00002000)
+#define SPIM_CONTINUE_MASK       (0x00001000)
+#define SPIM_SOFT_RESET_MASK     (0x00000800)
+#define SPIM_SEND_DMA_MASK       (0x00000400)
+#define SPIM_GET_DMA_MASK        (0x00000200)
+#define SPIM_EDGE_TX_RX_MASK     (0x00000100)
+#define SPFI_TRNSFR_MODE_MASK    (0x000000e0)
+#define SPFI_TRNSFR_MODE_DQ_MASK (0x0000001c)
+#define SPFI_TX_RX_MASK          (0x00000002)
+#define SPFI_EN_MASK             (0x00000001)
+
+#define SPFI_DRIBBLE_COUNT_SHIFT         (17)
+#define SPFI_MEMORY_IF_SHIFT             (15)
+#define SPIM_BYTE_DELAY_SHIFT            (14)
+#define SPIM_CS_DEASSERT_SHIFT           (13)
+#define SPIM_CONTINUE_SHIFT              (12)
+#define SPIM_SOFT_RESET_SHIFT            (11)
+#define SPIM_SEND_DMA_SHIFT              (10)
+#define   SPIM_GET_DMA_SHIFT              (9)
+#define SPIM_EDGE_TX_RX_SHIFT             (8)
+#define SPFI_TRNSFR_MODE_SHIFT            (5)
+#define SPFI_TRNSFR_MODE_DQ_SHIFT         (2)
+#define SPFI_TX_RX_SHIFT                  (1)
+#define SPFI_EN_SHIFT                     (0)
+
+/* Transaction register */
+
+#define SPFI_TSIZE_MASK           (0xffff0000)
+#define SPFI_CMD_LENGTH_MASK      (0x0000e000)
+#define SPFI_ADDR_LENGTH_MASK     (0x00001c00)
+#define SPFI_DUMMY_LENGTH_MASK    (0x000003e0)
+#define SPFI_PI_LENGTH_MASK       (0x0000001c)
+
+#define SPFI_TSIZE_SHIFT                  (16)
+#define SPFI_CMD_LENGTH_SHIFT             (13)
+#define SPFI_ADDR_LENGTH_SHIFT            (10)
+#define SPFI_DUMMY_LENGTH_SHIFT            (5)
+#define SPFI_PI_LENGTH_SHIFT               (2)
+
+/* Port state register */
+
+#define SPFI_PORT_SELECT_MASK    (0x00700000)
+/* WARNING the following bits are reversed */
+#define SPFI_CLOCK0_IDLE_MASK    (0x000f8000)
+#define SPFI_CLOCK0_PHASE_MASK   (0x00007c00)
+#define SPFI_CS0_IDLE_MASK       (0x000003e0)
+#define SPFI_DATA0_IDLE_MASK     (0x0000001f)
+
+#define SPIM_CLOCK0_IDLE_MASK    (0x000f8000)
+#define SPIM_CLOCK0_PHASE_MASK   (0x00007c00)
+#define SPIM_CS0_IDLE_MASK       (0x000003e0)
+#define SPIM_DATA0_IDLE_MASK     (0x0000001f)
+
+#define SPIM_PORT0_MASK          (0x00084210)
+
+#define SPFI_PORT_SELECT_SHIFT           (20)
+/* WARNING the following bits are reversed, bit 0 is highest */
+#define SPFI_CLOCK0_IDLE_SHIFT           (19)
+#define SPFI_CLOCK0_PHASE_SHIFT          (14)
+#define SPFI_CS0_IDLE_SHIFT               (9)
+#define SPFI_DATA0_IDLE_SHIFT             (4)
+
+#define SPIM_CLOCK0_IDLE_SHIFT           (19)
+#define SPIM_CLOCK0_PHASE_SHIFT          (14)
+#define SPIM_CS0_IDLE_SHIFT               (9)
+#define SPIM_DATA0_IDLE_SHIFT             (4)
+
+
+/*
+ * Interrupt registers
+ * SPFI_GDOF_MASK means Rx buffer full, not an overflow, because clock stalls
+ * SPFI_SDUF_MASK means Tx buffer empty, not an underflow, because clock stalls
+ */
+#define SPFI_IACCESS_MASK        (0x00001000)
+#define SPFI_GDEX8BIT_MASK       (0x00000800)
+#define SPFI_ALLDONE_MASK        (0x00000200)
+#define SPFI_GDFUL_MASK          (0x00000100)
+#define SPFI_GDHF_MASK           (0x00000080)
+#define SPFI_GDEX32BIT_MASK      (0x00000040)
+#define SPFI_GDTRIG_MASK         (0x00000020)
+#define SPFI_SDFUL_MASK          (0x00000008)
+#define SPFI_SDHF_MASK           (0x00000004)
+#define SPFI_SDE_MASK            (0x00000002)
+#define SPFI_SDTRIG_MASK         (0x00000001)
+
+#define SPFI_IACCESS_SHIFT               (12)
+#define SPFI_GDEX8BIT_SHIFT              (11)
+#define SPFI_ALLDONE_SHIFT                (9)
+#define SPFI_GDFUL_SHIFT                  (8)
+#define SPFI_GDHF_SHIFT                   (7)
+#define SPFI_GDEX32BIT_SHIFT              (6)
+#define SPFI_GDTRIG_SHIFT                 (5)
+#define SPFI_SDFUL_SHIFT                  (3)
+#define SPFI_SDHF_SHIFT                   (2)
+#define SPFI_SDE_SHIFT                    (1)
+#define SPFI_SDTRIG_SHIFT                 (0)
+
+
+/* SPFI register block */
+
+#define SPFI_PORT_0_PARAM_REG_OFFSET             (0x00)
+#define SPFI_PORT_1_PARAM_REG_OFFSET             (0x04)
+#define SPFI_PORT_2_PARAM_REG_OFFSET             (0x08)
+#define SPFI_PORT_3_PARAM_REG_OFFSET             (0x0C)
+#define SPFI_PORT_4_PARAM_REG_OFFSET             (0x10)
+#define SPFI_CONTROL_REG_OFFSET                  (0x14)
+#define SPFI_TRANSACTION_REG_OFFSET              (0x18)
+#define SPFI_PORT_STATE_REG_OFFSET               (0x1C)
+
+#define SPFI_SEND_LONG_REG_OFFSET                (0x20)
+#define SPFI_SEND_BYTE_REG_OFFSET                (0x24)
+#define SPFI_GET_LONG_REG_OFFSET                 (0x28)
+#define SPFI_GET_BYTE_REG_OFFSET                 (0x2C)
+
+#define SPFI_INT_STATUS_REG_OFFSET               (0x30)
+#define SPFI_INT_ENABLE_REG_OFFSET               (0x34)
+#define SPFI_INT_CLEAR_REG_OFFSET                (0x38)
+
+#define SPFI_IMMEDIATE_STATUS_REG_OFFSET         (0x3c)
+
+#define SPFI_FLASH_BASE_ADDRESS_REG_OFFSET       (0x48)
+#define SPFI_FLASH_STATUS_REG_OFFSET             (0x4C)
+
+#define IMG_FALSE				0
+#define IMG_TRUE				1
+
+/* Number of SPIM interfaces*/
+#define SPIM_NUM_BLOCKS				2
+/* Number of chip select lines supported by the SPI master port. */
+#define SPIM_NUM_PORTS_PER_BLOCK		(SPIM_DUMMY_CS)
+/* Maximum transfer size (in bytes) for the SPI master port. */
+#define SPIM_MAX_TRANSFER_BYTES			(0xFFFF)
+/* Maximum size of a flash command: command bytes+address_bytes. */
+#define SPIM_MAX_FLASH_COMMAND_BYTES		(0x8)
+/* Write operation to fifo done in blocks of 16 words (64 bytes) */
+#define SPIM_MAX_BLOCK_BYTES			(0x40)
+/* Number of tries until timeout error is returned*/
+#define SPI_TIMEOUT_VALUE_US			500000
+
+/* SPIM initialisation function return value.*/
+enum spim_return {
+	/* Initialisation parameters are valid. */
+	SPIM_OK = 0,
+	/* Mode parameter is invalid. */
+	SPIM_INVALID_SPI_MODE,
+	/* Chip select idle level is invalid. */
+	SPIM_INVALID_CS_IDLE_LEVEL,
+	/* Data idle level is invalid. */
+	SPIM_INVALID_DATA_IDLE_LEVEL,
+	/* Chip select line parameter is invalid. */
+	SPIM_INVALID_CS_LINE,
+	/* Transfer size parameter is invalid. */
+	SPIM_INVALID_SIZE,
+	/* Read/write parameter is invalid. */
+	SPIM_INVALID_READ_WRITE,
+	/* Continue parameter is invalid. */
+	SPIM_INVALID_CONTINUE,
+	/* Invalid block index */
+	SPIM_INVALID_BLOCK_INDEX,
+	/* Extended error values */
+	/* Invalid bit rate */
+	SPIM_INVALID_BIT_RATE,
+	/* Invalid CS hold value */
+	SPIM_INVALID_CS_HOLD_VALUE,
+	/* API function called before API is initialised */
+	SPIM_API_NOT_INITIALISED,
+	/* SPI driver initialisation failed */
+	SPIM_DRIVER_INIT_ERROR,
+	/* Invalid transfer description */
+	SPIM_INVALID_TRANSFER_DESC,
+	/* Timeout */
+	SPIM_TIMEOUT
+
+};
+
+/* This type defines the SPI Mode.*/
+enum spim_mode {
+	/* Mode 0 (clock idle low, data valid on first clock transition). */
+	SPIM_MODE_0 = 0,
+	/* Mode 1 (clock idle low, data valid on second clock transition). */
+	SPIM_MODE_1,
+	/* Mode 2 (clock idle high, data valid on first clock transition). */
+	SPIM_MODE_2,
+	/* Mode 3 (clock idle high, data valid on second clock transition). */
+	SPIM_MODE_3
+
+};
+
+/* This type defines the SPIM device numbers (chip select lines). */
+enum spim_device {
+	/* Device 0 (CS0). */
+	SPIM_DEVICE0 = 0,
+	/* Device 1 (CS1). */
+	SPIM_DEVICE1,
+	/* Device 2 (CS2). */
+	SPIM_DEVICE2,
+	/* Device 3 (CS3). */
+	SPIM_DEVICE3,
+	/* Device 4 (CS4). */
+	SPIM_DEVICE4,
+	/* Dummy chip select. */
+	SPIM_DUMMY_CS
+
+};
+
+/* This structure defines communication parameters for a slave device */
+struct spim_device_parameters {
+	/* Bit rate value.*/
+	unsigned char bitrate;
+	/*
+	 * Chip select set up time.
+	 * Time taken between chip select going active and activity occurring
+	 * on the clock, calculated by dividing the desired set up time in ns
+	 * by the Input clock period. (setup time / Input clock freq)
+	 */
+	unsigned char cs_setup;
+	/*
+	 * Chip select hold time.
+	 * Time after the last clock pulse before chip select goes inactive,
+	 * calculated by dividing the desired hold time in ns by the
+	 * Input clock period (hold time / Input clock freq).
+	 */
+	unsigned char cs_hold;
+	/*
+	 * Chip select delay time (CS minimum inactive time).
+	 * Minimum time after chip select goes inactive before chip select
+	 * can go active again, calculated by dividing the desired delay time
+	 * in ns by the Input clock period (delay time / Input clock freq).
+	 */
+	unsigned char cs_delay;
+	/* SPI Mode. */
+	enum spim_mode spi_mode;
+	/* Chip select idle level (0=low, 1=high, Others=invalid). */
+	unsigned int cs_idle_level;
+	/* Data idle level (0=low, 1=high, Others=invalid). */
+	unsigned int data_idle_level;
+
+};
+
+/* Command transfer mode */
+enum command_mode {
+	/* Command, address, dummy and PI cycles are transferred on sio0 */
+	SPIM_CMD_MODE_0 = 0,
+	/*
+	 * Command and Address are transferred on sio0 port only but dummy
+	 * cycles and PI is transferred on all the interface ports.
+	 */
+	SPIM_CMD_MODE_1,
+	/*
+	 * Command is transferred on sio0 port only but address, dummy
+	 * and PI is transferred on all the interface portS
+	 */
+	SPIM_CMD_MODE_2,
+	/*
+	 * Command, address, dummy and PI bytes are transferred on all
+	 * the interfaces
+	 */
+	SPIM_CMD_MODE_3
+};
+
+/* Data transfer mode */
+enum transfer_mode {
+	/* Transfer data in single mode */
+	SPIM_DMODE_SINGLE = 0,
+	/* Transfer data in dual mode */
+	SPIM_DMODE_DUAL,
+	/* Transfer data in quad mode */
+	SPIM_DMODE_QUAD
+};
+
+/* This structure contains parameters that describe an SPIM operation. */
+struct spim_buffer {
+	/* The buffer to read from or write to. */
+	unsigned char *buffer;
+
+	/* Number of bytes to read/write. Valid range is 0 to 65536 bytes. */
+	unsigned int size;
+
+	/* Read/write select. TRUE for read, FALSE for write, Others-invalid.*/
+	int isread;
+
+	/*
+	 * ByteDelay select.
+	 * Selects whether or not a delay is inserted between bytes.
+	 * 0 - Minimum inter-byte delay
+	 * 1 - Inter-byte delay of (cs_hold/master_clk half period)*master_clk.
+	 */
+	int inter_byte_delay;
+};
+
+#endif /* __SOC_ATHEROS_AR7240_SPI_H__ */
diff --git a/src/soc/atheros/ar7240/monotonic_timer.c b/src/soc/atheros/ar7240/monotonic_timer.c
new file mode 100644
index 0000000..eba7868
--- /dev/null
+++ b/src/soc/atheros/ar7240/monotonic_timer.c
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Alexander Couzens <lynxis at fe80.eu>
+ *
+ * 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.
+ */
+
+#include <arch/cpu.h>
+#include <soc/clocks.h>
+#include <arch/io.h>
+#include <stdint.h>
+#include <timer.h>
+#include <timestamp.h>
+
+#include <soc/ar71xx_regs.h>
+
+int get_count_mhz_freq(void)
+{
+	uint32_t cpu_config;
+
+	uint32_t div_multiplier;
+	uint32_t ref_div;
+	
+	cpu_config = read32(AR71XX_PLL_BASE + AR724X_PLL_REG_CPU_CONFIG);
+
+	if (cpu_config & AR724X_CPU_PLL_BYPASS) {
+		return ar71xx_get_ref_clock_mhz();
+	}
+
+	div_multiplier = cpu_config & AR724X_PLL_FB_MASK;
+	ref_div = (cpu_config >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK;
+
+	return ((div_multiplier / ref_div) * ar71xx_get_ref_clock_mhz()) / 2;
+}
+
+void timer_monotonic_get(struct mono_time *mt)
+{
+	mono_time_set_usecs(mt, read_c0_count() / get_count_mhz_freq());
+}
diff --git a/src/soc/atheros/ar7240/romstage.c b/src/soc/atheros/ar7240/romstage.c
new file mode 100644
index 0000000..f2eb78a
--- /dev/null
+++ b/src/soc/atheros/ar7240/romstage.c
@@ -0,0 +1,10 @@
+
+#include <cbmem.h>
+#include <console/console.h>
+#include <halt.h>
+#include <program_loading.h>
+#include <soc/ddr_init.h>
+
+void main(void)
+{
+}
diff --git a/src/soc/atheros/ar7240/spi.c b/src/soc/atheros/ar7240/spi.c
new file mode 100644
index 0000000..cb3e178
--- /dev/null
+++ b/src/soc/atheros/ar7240/spi.c
@@ -0,0 +1,188 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexander Couzens <lynxis at fe80.eu>
+ *
+ * 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.
+ */
+
+#include <soc/ar71xx_regs.h>
+#include <soc/spi.h>
+#include <spi_flash.h>
+#include <spi-generic.h>
+#include <stdlib.h>
+#include <string.h>
+#include <timer.h>
+
+
+/* based on u-boot sources (GPL) */
+
+#define AR7240_SPI_FS           0x1f000000
+#define AR7240_SPI_CLOCK        0x1f000004
+#define AR7240_SPI_WRITE        0x1f000008
+#define AR7240_SPI_READ         0x1f000000
+#define AR7240_SPI_RD_STATUS    0x1f00000c
+
+#define AR7240_SPI_CS_DIS       0x70000
+#define AR7240_SPI_CE_LOW       0x60000
+#define AR7240_SPI_CE_HIGH      0x60100
+
+#define AR7240_SPI_CMD_WREN         0x06
+#define AR7240_SPI_CMD_RD_STATUS    0x05
+#define AR7240_SPI_CMD_FAST_READ    0x0b
+#define AR7240_SPI_CMD_PAGE_PROG    0x02
+#define AR7240_SPI_CMD_SECTOR_ERASE 0xd8
+
+#define AR7240_SPI_SECTOR_SIZE      (1024*64)
+#define AR7240_SPI_PAGE_SIZE        256
+
+#define ar7240_be_msb(_val, _i) (((_val) & (1 << (7 - _i))) >> (7 - _i))
+
+#define ar7240_spi_bit_banger(_byte)  do {        \
+    int i;                                      \
+    for(i = 0; i < 8; i++) {                    \
+        ar7240_reg_wr_nf(AR7240_SPI_WRITE,      \
+                        AR7240_SPI_CE_LOW | ar7240_be_msb(_byte, i));  \
+        ar7240_reg_wr_nf(AR7240_SPI_WRITE,      \
+                        AR7240_SPI_CE_HIGH | ar7240_be_msb(_byte, i)); \
+    }       \
+}while(0);
+
+#define ar7240_spi_go() do {        \
+    ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CE_LOW); \
+    ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS); \
+}while(0);
+
+#define ar7240_spi_send_addr(_addr) do {                    \
+    ar7240_spi_bit_banger(((addr & 0xff0000) >> 16));                 \
+    ar7240_spi_bit_banger(((addr & 0x00ff00) >> 8));                 \
+    ar7240_spi_bit_banger(addr & 0x0000ff);                 \
+}while(0);
+
+#define ar7240_spi_delay_8()    ar7240_spi_bit_banger(0)
+#define ar7240_spi_done()       ar7240_reg_wr_nf(AR7240_SPI_FS, 0)
+
+#define ATHEROS_MAX_SPI_SLAVE 3
+
+static struct spi_slave slaves[ATHEROS_MAX_SPI_SLAVE];
+static int spi_initialized;
+
+static inline void ath79_spi_wr(unsigned long addr, uint32_t val)
+{
+	write32(AR71XX_SPI_BASE + addr, val);
+}
+
+static inline uint32_t ath79_spi_rr(unsigned long addr)
+{
+	return read32(AR71XX_SPI_BASE + addr);
+}
+
+void spi_init(void)
+{
+	spi_initialized = 0;
+	memset(slaves, 0, sizeof(slaves));
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+{
+	if (bus != 0 || cs >= ATHEROS_MAX_SPI_SLAVE) {
+		printk(BIOS_ERR, "%s: Invalid spi settings bus 0x%x cs 0x%x\n",
+				__func__, bus, cs);
+		return NULL;
+	}
+
+	slaves[cs].bus = bus;
+	slaves[cs].cs = cs;
+	slaves[cs].rw = SPI_READ_FLAG & SPI_WRITE_FLAG;
+
+	return &slaves[cs];
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+	
+	if (!spi_initialized) {
+		spi_initialized = 1;
+
+		/* enable gpio mode */
+		ath79_spi_wr(AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
+
+		/* disable remap (0x40) + set up clock divider 0x3
+		* freq = AHB_CLK / ((CLOCK_DIVIDE +1) * 2)
+		*/
+		ath79_spi_wr(AR71XX_SPI_REG_CTRL, 0x43);
+	}
+
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+}
+
+int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bytesout,
+		void *din, unsigned int bytesin)
+{
+	int csbit = slave->cs + 16;
+	int transfer_max = max(bytesin, bytesout);
+	int readed = 0;
+	uint8_t data = 0;
+	
+	ath79_spi_wr(AR71XX_SPI_REG_IOC, csbit);
+
+	for(int i=0; i<transfer_max; i++) {
+		if(bytesout <= i)
+			data = 0; /* dummy write to read data */
+		else
+			data = *(((uint8_t *)dout) + i);
+
+		/* write data 8 bit data */
+		for(int j=0; j<8; j++) {
+			ath79_spi_wr(AR71XX_SPI_REG_IOC,
+					csbit | ar7240_be_msb(data, j));
+			ath79_spi_wr(AR71XX_SPI_REG_IOC,
+					csbit | AR71XX_SPI_IOC_CLK | ar7240_be_msb(data, j));
+		}
+
+		/* read data in from data register */
+		if(i % 4 == 0 && i > 0) {
+			if(bytesin == readed) {
+				/* do nothing */
+			} else if(bytesin-readed >= 4) {
+				*(((uint32_t *)din) + (readed % 4)) = ath79_spi_rr(AR71XX_SPI_REG_RDS);
+				readed += 4;
+			} else {
+				/* partial read until full. max 3 bytes are read */
+				for (int j=0; bytesin != readed; j++) {
+					*(((uint32_t *)din) + readed) = (readed >> (24 - j*8));
+					readed++;
+				}
+			}
+		}
+	}
+
+	/* check if we have to read_data once more */
+	if (bytesin != readed) {
+		/* partial read until full. max 3 bytes are read */
+		for (int j=0; bytesin != readed; j++) {
+			*(((uint32_t *)din) + readed) = (readed >> (24 - j*8));
+			readed++;
+		}
+	}
+
+
+	return 0;
+}
+
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
+{
+	return buf_len;
+}
+
diff --git a/src/soc/atheros/ar7240/uart.c b/src/soc/atheros/ar7240/uart.c
new file mode 100644
index 0000000..3f99cfb
--- /dev/null
+++ b/src/soc/atheros/ar7240/uart.c
@@ -0,0 +1,162 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexander Couzens <lynxis at fe80.eu>
+ *
+ * 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.
+ */
+
+#include <arch/io.h>
+#include <boot/coreboot_tables.h>
+#include <console/console.h>
+#include <console/uart.h>
+#include <device/device.h>
+#include <delay.h>
+#include <drivers/uart/uart8250reg.h>
+
+/* Should support 8250, 16450, 16550, 16550A type UARTs */
+
+/* Expected character delay at 1200bps is 9ms for a working UART
+ * and no flow-control. Assume UART as stuck if shift register
+ * or FIFO takes more than 50ms per character to appear empty.
+ */
+#define SINGLE_CHAR_TIMEOUT	(50 * 1000)
+#define FIFO_TIMEOUT		(16 * SINGLE_CHAR_TIMEOUT)
+#define UART_SHIFT		2
+
+#define GEN_ACCESSOR(name, idx)						\
+static inline uint8_t read_##name(unsigned base_port)			\
+{									\
+	return read8(base_port + (idx << UART_SHIFT));			\
+}									\
+									\
+static inline void write_##name(unsigned base_port, uint8_t val)	\
+{									\
+	write8(base_port + (idx << UART_SHIFT), val);			\
+}
+
+GEN_ACCESSOR(rbr, UART8250_RBR)
+GEN_ACCESSOR(tbr, UART8250_TBR)
+GEN_ACCESSOR(ier, UART8250_IER)
+GEN_ACCESSOR(fcr, UART8250_FCR)
+GEN_ACCESSOR(lcr, UART8250_LCR)
+GEN_ACCESSOR(mcr, UART8250_MCR)
+GEN_ACCESSOR(lsr, UART8250_LSR)
+GEN_ACCESSOR(dll, UART8250_DLL)
+GEN_ACCESSOR(dlm, UART8250_DLM)
+
+static int uart8250_mem_can_tx_byte(unsigned base_port)
+{
+	return read_lsr(base_port) & UART8250_LSR_THRE;
+}
+
+static void uart8250_mem_tx_byte(unsigned base_port, unsigned char data)
+{
+	unsigned long int i = SINGLE_CHAR_TIMEOUT;
+	while (i-- && !uart8250_mem_can_tx_byte(base_port))
+		udelay(1);
+	write_tbr(base_port, data);
+}
+
+static void uart8250_mem_tx_flush(unsigned base_port)
+{
+	unsigned long int i = FIFO_TIMEOUT;
+	while (i-- && !(read_lsr(base_port) & UART8250_LSR_TEMT))
+		udelay(1);
+}
+
+static int uart8250_mem_can_rx_byte(unsigned base_port)
+{
+	return read_lsr(base_port) & UART8250_LSR_DR;
+}
+
+static unsigned char uart8250_mem_rx_byte(unsigned base_port)
+{
+	unsigned long int i = SINGLE_CHAR_TIMEOUT;
+	while (i-- && !uart8250_mem_can_rx_byte(base_port))
+		udelay(1);
+	if (i)
+		return read_rbr(base_port);
+	else
+		return 0x0;
+}
+
+static void uart8250_mem_init(unsigned base_port, unsigned divisor)
+{
+	/* Disable interrupts */
+	write_ier(base_port, 0x0);
+	/* Enable FIFOs */
+	write_fcr(base_port, UART8250_FCR_FIFO_EN);
+
+	/* Assert DTR and RTS so the other end is happy */
+	write_mcr(base_port, UART8250_MCR_DTR | UART8250_MCR_RTS);
+
+	/* DLAB on */
+	write_lcr(base_port, UART8250_LCR_DLAB | CONFIG_TTYS0_LCS);
+
+	write_dll(base_port, divisor & 0xFF);
+	write_dlm(base_port, (divisor >> 8) & 0xFF);
+
+	/* Set to 3 for 8N1 */
+	write_lcr(base_port, CONFIG_TTYS0_LCS);
+}
+
+unsigned int uart_platform_refclk(void)
+{
+	/* TODO: for now this is hardcoded */
+	/* uart uses AHB as base clock */
+	return 195 * 1000 * 1000;
+}
+
+void uart_init(int idx)
+{
+	u32 base = CONFIG_CONSOLE_SERIAL_UART_ADDRESS;
+	if (!base)
+		return;
+
+	unsigned int div;
+	div = uart_baudrate_divisor(CONFIG_TTYS0_BAUD,
+				    uart_platform_refclk(), 16);
+	uart8250_mem_init(base, div);
+}
+
+void uart_tx_byte(int idx, unsigned char data)
+{
+	uart8250_mem_tx_byte(CONFIG_CONSOLE_SERIAL_UART_ADDRESS, data);
+}
+
+unsigned char uart_rx_byte(int idx)
+{
+	return uart8250_mem_rx_byte(CONFIG_CONSOLE_SERIAL_UART_ADDRESS);
+}
+
+void uart_tx_flush(int idx)
+{
+	uart8250_mem_tx_flush(CONFIG_CONSOLE_SERIAL_UART_ADDRESS);
+}
+
+#ifndef __PRE_RAM__
+void uart_fill_lb(void *data)
+{
+	struct lb_serial serial;
+	serial.type = LB_SERIAL_TYPE_MEMORY_MAPPED;
+	serial.baseaddr = CONFIG_CONSOLE_SERIAL_UART_ADDRESS;
+	serial.baud = default_baudrate();
+	serial.regwidth = 1 << UART_SHIFT;
+	lb_add_serial(&serial, data);
+
+	lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM, data);
+}
+#endif
diff --git a/src/soc/atheros/common/include/soc/ar71xx_regs.h b/src/soc/atheros/common/include/soc/ar71xx_regs.h
new file mode 100644
index 0000000..3f0cfbe
--- /dev/null
+++ b/src/soc/atheros/common/include/soc/ar71xx_regs.h
@@ -0,0 +1,559 @@
+/*
+ *  Atheros AR71XX/AR724X/AR913X SoC register definitions
+ *
+ *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan at atheros.com>
+ *  Copyright (C) 2008-2010 Gabor Juhos <juhosg at openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz at openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_AR71XX_REGS_H
+#define __ASM_MACH_AR71XX_REGS_H
+
+#define AR71XX_APB_BASE		0x18000000
+#define AR71XX_EHCI_BASE	0x1b000000
+#define AR71XX_EHCI_SIZE	0x1000
+#define AR71XX_OHCI_BASE	0x1c000000
+#define AR71XX_OHCI_SIZE	0x1000
+#define AR71XX_SPI_BASE		0x1f000000
+#define AR71XX_SPI_SIZE		0x01000000
+
+#define AR71XX_DDR_CTRL_BASE	(AR71XX_APB_BASE + 0x00000000)
+#define AR71XX_DDR_CTRL_SIZE	0x100
+#define AR71XX_UART_BASE	(AR71XX_APB_BASE + 0x00020000)
+#define AR71XX_UART_SIZE	0x100
+#define AR71XX_USB_CTRL_BASE	(AR71XX_APB_BASE + 0x00030000)
+#define AR71XX_USB_CTRL_SIZE	0x100
+#define AR71XX_GPIO_BASE	(AR71XX_APB_BASE + 0x00040000)
+#define AR71XX_GPIO_SIZE	0x100
+#define AR71XX_PLL_BASE		(AR71XX_APB_BASE + 0x00050000)
+#define AR71XX_PLL_SIZE		0x100
+#define AR71XX_RESET_BASE	(AR71XX_APB_BASE + 0x00060000)
+#define AR71XX_RESET_SIZE	0x100
+
+#define AR71XX_PCI_MEM_BASE	0x10000000
+#define AR71XX_PCI_MEM_SIZE	0x07000000
+
+#define AR71XX_PCI_WIN0_OFFS	0x10000000
+#define AR71XX_PCI_WIN1_OFFS	0x11000000
+#define AR71XX_PCI_WIN2_OFFS	0x12000000
+#define AR71XX_PCI_WIN3_OFFS	0x13000000
+#define AR71XX_PCI_WIN4_OFFS	0x14000000
+#define AR71XX_PCI_WIN5_OFFS	0x15000000
+#define AR71XX_PCI_WIN6_OFFS	0x16000000
+#define AR71XX_PCI_WIN7_OFFS	0x07000000
+
+#define AR71XX_PCI_CFG_BASE	\
+	(AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000)
+#define AR71XX_PCI_CFG_SIZE	0x100
+
+#define AR7240_USB_CTRL_BASE	(AR71XX_APB_BASE + 0x00030000)
+#define AR7240_USB_CTRL_SIZE	0x100
+#define AR7240_OHCI_BASE	0x1b000000
+#define AR7240_OHCI_SIZE	0x1000
+
+#define AR724X_PCI_MEM_BASE	0x10000000
+#define AR724X_PCI_MEM_SIZE	0x04000000
+
+#define AR724X_PCI_CFG_BASE	0x14000000
+#define AR724X_PCI_CFG_SIZE	0x1000
+#define AR724X_PCI_CRP_BASE	(AR71XX_APB_BASE + 0x000c0000)
+#define AR724X_PCI_CRP_SIZE	0x1000
+#define AR724X_PCI_CTRL_BASE	(AR71XX_APB_BASE + 0x000f0000)
+#define AR724X_PCI_CTRL_SIZE	0x100
+
+#define AR724X_EHCI_BASE	0x1b000000
+#define AR724X_EHCI_SIZE	0x1000
+
+#define AR913X_EHCI_BASE	0x1b000000
+#define AR913X_EHCI_SIZE	0x1000
+#define AR913X_WMAC_BASE	(AR71XX_APB_BASE + 0x000C0000)
+#define AR913X_WMAC_SIZE	0x30000
+
+#define AR933X_UART_BASE	(AR71XX_APB_BASE + 0x00020000)
+#define AR933X_UART_SIZE	0x14
+#define AR933X_WMAC_BASE	(AR71XX_APB_BASE + 0x00100000)
+#define AR933X_WMAC_SIZE	0x20000
+#define AR933X_EHCI_BASE	0x1b000000
+#define AR933X_EHCI_SIZE	0x1000
+
+#define AR934X_WMAC_BASE	(AR71XX_APB_BASE + 0x00100000)
+#define AR934X_WMAC_SIZE	0x20000
+#define AR934X_EHCI_BASE	0x1b000000
+#define AR934X_EHCI_SIZE	0x200
+#define AR934X_SRIF_BASE	(AR71XX_APB_BASE + 0x00116000)
+#define AR934X_SRIF_SIZE	0x1000
+
+#define QCA955X_PCI_MEM_BASE0	0x10000000
+#define QCA955X_PCI_MEM_BASE1	0x12000000
+#define QCA955X_PCI_MEM_SIZE	0x02000000
+#define QCA955X_PCI_CFG_BASE0	0x14000000
+#define QCA955X_PCI_CFG_BASE1	0x16000000
+#define QCA955X_PCI_CFG_SIZE	0x1000
+#define QCA955X_PCI_CRP_BASE0	(AR71XX_APB_BASE + 0x000c0000)
+#define QCA955X_PCI_CRP_BASE1	(AR71XX_APB_BASE + 0x00250000)
+#define QCA955X_PCI_CRP_SIZE	0x1000
+#define QCA955X_PCI_CTRL_BASE0	(AR71XX_APB_BASE + 0x000f0000)
+#define QCA955X_PCI_CTRL_BASE1	(AR71XX_APB_BASE + 0x00280000)
+#define QCA955X_PCI_CTRL_SIZE	0x100
+
+#define QCA955X_WMAC_BASE	(AR71XX_APB_BASE + 0x00100000)
+#define QCA955X_WMAC_SIZE	0x20000
+#define QCA955X_EHCI0_BASE	0x1b000000
+#define QCA955X_EHCI1_BASE	0x1b400000
+#define QCA955X_EHCI_SIZE	0x1000
+
+/*
+ * DDR_CTRL block
+ */
+#define AR71XX_DDR_REG_PCI_WIN0		0x7c
+#define AR71XX_DDR_REG_PCI_WIN1		0x80
+#define AR71XX_DDR_REG_PCI_WIN2		0x84
+#define AR71XX_DDR_REG_PCI_WIN3		0x88
+#define AR71XX_DDR_REG_PCI_WIN4		0x8c
+#define AR71XX_DDR_REG_PCI_WIN5		0x90
+#define AR71XX_DDR_REG_PCI_WIN6		0x94
+#define AR71XX_DDR_REG_PCI_WIN7		0x98
+#define AR71XX_DDR_REG_FLUSH_GE0	0x9c
+#define AR71XX_DDR_REG_FLUSH_GE1	0xa0
+#define AR71XX_DDR_REG_FLUSH_USB	0xa4
+#define AR71XX_DDR_REG_FLUSH_PCI	0xa8
+
+#define AR724X_DDR_REG_FLUSH_GE0	0x7c
+#define AR724X_DDR_REG_FLUSH_GE1	0x80
+#define AR724X_DDR_REG_FLUSH_USB	0x84
+#define AR724X_DDR_REG_FLUSH_PCIE	0x88
+
+#define AR913X_DDR_REG_FLUSH_GE0	0x7c
+#define AR913X_DDR_REG_FLUSH_GE1	0x80
+#define AR913X_DDR_REG_FLUSH_USB	0x84
+#define AR913X_DDR_REG_FLUSH_WMAC	0x88
+
+#define AR933X_DDR_REG_FLUSH_GE0	0x7c
+#define AR933X_DDR_REG_FLUSH_GE1	0x80
+#define AR933X_DDR_REG_FLUSH_USB	0x84
+#define AR933X_DDR_REG_FLUSH_WMAC	0x88
+
+#define AR934X_DDR_REG_FLUSH_GE0	0x9c
+#define AR934X_DDR_REG_FLUSH_GE1	0xa0
+#define AR934X_DDR_REG_FLUSH_USB	0xa4
+#define AR934X_DDR_REG_FLUSH_PCIE	0xa8
+#define AR934X_DDR_REG_FLUSH_WMAC	0xac
+
+/*
+ * PLL block
+ */
+#define AR71XX_PLL_REG_CPU_CONFIG	0x00
+#define AR71XX_PLL_REG_SEC_CONFIG	0x04
+#define AR71XX_PLL_REG_ETH0_INT_CLOCK	0x10
+#define AR71XX_PLL_REG_ETH1_INT_CLOCK	0x14
+
+#define AR71XX_PLL_FB_SHIFT		3
+#define AR71XX_PLL_FB_MASK		0x1f
+#define AR71XX_CPU_DIV_SHIFT		16
+#define AR71XX_CPU_DIV_MASK		0x3
+#define AR71XX_DDR_DIV_SHIFT		18
+#define AR71XX_DDR_DIV_MASK		0x3
+#define AR71XX_AHB_DIV_SHIFT		20
+#define AR71XX_AHB_DIV_MASK		0x7
+
+#define AR724X_PLL_REG_CPU_CONFIG	0x00
+#define AR724X_PLL_REG_CPU_CLOCK_CTRL	0x08
+#define AR724X_PLL_REG_PCIE_CONFIG	0x18
+
+#define AR724X_PLL_FB_SHIFT		0
+#define AR724X_PLL_FB_MASK		0x3ff
+#define AR724X_PLL_REF_DIV_SHIFT	10
+#define AR724X_PLL_REF_DIV_MASK		0xf
+#define AR724X_AHB_DIV_SHIFT		19
+#define AR724X_AHB_DIV_MASK		0x1
+#define AR724X_DDR_DIV_SHIFT		22
+#define AR724X_DDR_DIV_MASK		0x3
+#define AR724X_CPU_PLL_BYPASS		BIT(16)
+#define AR724X_CPU_PLL_UPDATING		BIT(17) /* is 0 when PLL update is pendig */
+#define AR724X_CPU_PLL_NOPWD		BIT(19)
+#define AR724X_CPU_PLL_RESET		BIT(25)
+
+#define AR724X_CPU_PLL_CTRL_CLOCK_SWITCH	0x1
+#define AR724X_CPU_PLL_CTRL_RESET_SWITCH	0x2
+
+#define AR913X_PLL_REG_CPU_CONFIG	0x00
+#define AR913X_PLL_REG_ETH_CONFIG	0x04
+#define AR913X_PLL_REG_ETH0_INT_CLOCK	0x14
+#define AR913X_PLL_REG_ETH1_INT_CLOCK	0x18
+
+#define AR913X_PLL_FB_SHIFT		0
+#define AR913X_PLL_FB_MASK		0x3ff
+#define AR913X_DDR_DIV_SHIFT		22
+#define AR913X_DDR_DIV_MASK		0x3
+#define AR913X_AHB_DIV_SHIFT		19
+#define AR913X_AHB_DIV_MASK		0x1
+
+#define AR933X_PLL_CPU_CONFIG_REG	0x00
+#define AR933X_PLL_CLOCK_CTRL_REG	0x08
+
+#define AR933X_PLL_CPU_CONFIG_NINT_SHIFT	10
+#define AR933X_PLL_CPU_CONFIG_NINT_MASK		0x3f
+#define AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT	16
+#define AR933X_PLL_CPU_CONFIG_REFDIV_MASK	0x1f
+#define AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT	23
+#define AR933X_PLL_CPU_CONFIG_OUTDIV_MASK	0x7
+
+#define AR933X_PLL_CLOCK_CTRL_BYPASS		BIT(2)
+#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT	5
+#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK	0x3
+#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT	10
+#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK	0x3
+#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT	15
+#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK	0x7
+
+#define AR934X_PLL_CPU_CONFIG_REG		0x00
+#define AR934X_PLL_DDR_CONFIG_REG		0x04
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_REG		0x08
+
+#define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT	0
+#define AR934X_PLL_CPU_CONFIG_NFRAC_MASK	0x3f
+#define AR934X_PLL_CPU_CONFIG_NINT_SHIFT	6
+#define AR934X_PLL_CPU_CONFIG_NINT_MASK		0x3f
+#define AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT	12
+#define AR934X_PLL_CPU_CONFIG_REFDIV_MASK	0x1f
+#define AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT	19
+#define AR934X_PLL_CPU_CONFIG_OUTDIV_MASK	0x3
+
+#define AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT	0
+#define AR934X_PLL_DDR_CONFIG_NFRAC_MASK	0x3ff
+#define AR934X_PLL_DDR_CONFIG_NINT_SHIFT	10
+#define AR934X_PLL_DDR_CONFIG_NINT_MASK		0x3f
+#define AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT	16
+#define AR934X_PLL_DDR_CONFIG_REFDIV_MASK	0x1f
+#define AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT	23
+#define AR934X_PLL_DDR_CONFIG_OUTDIV_MASK	0x7
+
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS	BIT(2)
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS	BIT(3)
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS	BIT(4)
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT	5
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK	0x1f
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT	10
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK	0x1f
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT	15
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK	0x1f
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL	BIT(20)
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL	BIT(21)
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL	BIT(24)
+
+#define QCA955X_PLL_CPU_CONFIG_REG		0x00
+#define QCA955X_PLL_DDR_CONFIG_REG		0x04
+#define QCA955X_PLL_CLK_CTRL_REG		0x08
+
+#define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT	0
+#define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK	0x3f
+#define QCA955X_PLL_CPU_CONFIG_NINT_SHIFT	6
+#define QCA955X_PLL_CPU_CONFIG_NINT_MASK	0x3f
+#define QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT	12
+#define QCA955X_PLL_CPU_CONFIG_REFDIV_MASK	0x1f
+#define QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT	19
+#define QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK	0x3
+
+#define QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT	0
+#define QCA955X_PLL_DDR_CONFIG_NFRAC_MASK	0x3ff
+#define QCA955X_PLL_DDR_CONFIG_NINT_SHIFT	10
+#define QCA955X_PLL_DDR_CONFIG_NINT_MASK	0x3f
+#define QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT	16
+#define QCA955X_PLL_DDR_CONFIG_REFDIV_MASK	0x1f
+#define QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT	23
+#define QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK	0x7
+
+#define QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS		BIT(2)
+#define QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS		BIT(3)
+#define QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS		BIT(4)
+#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT		5
+#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK		0x1f
+#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT		10
+#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK		0x1f
+#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT		15
+#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK		0x1f
+#define QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL		BIT(20)
+#define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL		BIT(21)
+#define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL		BIT(24)
+
+/*
+ * USB_CONFIG block
+ */
+#define AR71XX_USB_CTRL_REG_FLADJ	0x00
+#define AR71XX_USB_CTRL_REG_CONFIG	0x04
+
+/*
+ * RESET block
+ */
+#define AR71XX_RESET_REG_TIMER			0x00
+#define AR71XX_RESET_REG_TIMER_RELOAD		0x04
+#define AR71XX_RESET_REG_WDOG_CTRL		0x08
+#define AR71XX_RESET_REG_WDOG			0x0c
+#define AR71XX_RESET_REG_MISC_INT_STATUS	0x10
+#define AR71XX_RESET_REG_MISC_INT_ENABLE	0x14
+#define AR71XX_RESET_REG_PCI_INT_STATUS		0x18
+#define AR71XX_RESET_REG_PCI_INT_ENABLE		0x1c
+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS	0x20
+#define AR71XX_RESET_REG_RESET_MODULE		0x24
+#define AR71XX_RESET_REG_PERFC_CTRL		0x2c
+#define AR71XX_RESET_REG_PERFC0			0x30
+#define AR71XX_RESET_REG_PERFC1			0x34
+#define AR71XX_RESET_REG_REV_ID			0x90
+
+#define AR913X_RESET_REG_GLOBAL_INT_STATUS	0x18
+#define AR913X_RESET_REG_RESET_MODULE		0x1c
+#define AR913X_RESET_REG_PERF_CTRL		0x20
+#define AR913X_RESET_REG_PERFC0			0x24
+#define AR913X_RESET_REG_PERFC1			0x28
+
+#define AR724X_RESET_REG_RESET_MODULE		0x1c
+
+#define AR933X_RESET_REG_RESET_MODULE		0x1c
+#define AR933X_RESET_REG_BOOTSTRAP		0xac
+
+#define AR934X_RESET_REG_RESET_MODULE		0x1c
+#define AR934X_RESET_REG_BOOTSTRAP		0xb0
+#define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS	0xac
+
+#define QCA955X_RESET_REG_RESET_MODULE		0x1c
+#define QCA955X_RESET_REG_BOOTSTRAP		0xb0
+#define QCA955X_RESET_REG_EXT_INT_STATUS	0xac
+
+#define MISC_INT_ETHSW			BIT(12)
+#define MISC_INT_TIMER4			BIT(10)
+#define MISC_INT_TIMER3			BIT(9)
+#define MISC_INT_TIMER2			BIT(8)
+#define MISC_INT_DMA			BIT(7)
+#define MISC_INT_OHCI			BIT(6)
+#define MISC_INT_PERFC			BIT(5)
+#define MISC_INT_WDOG			BIT(4)
+#define MISC_INT_UART			BIT(3)
+#define MISC_INT_GPIO			BIT(2)
+#define MISC_INT_ERROR			BIT(1)
+#define MISC_INT_TIMER			BIT(0)
+
+#define AR71XX_RESET_EXTERNAL		BIT(28)
+#define AR71XX_RESET_FULL_CHIP		BIT(24)
+#define AR71XX_RESET_CPU_NMI		BIT(21)
+#define AR71XX_RESET_CPU_COLD		BIT(20)
+#define AR71XX_RESET_DMA		BIT(19)
+#define AR71XX_RESET_SLIC		BIT(18)
+#define AR71XX_RESET_STEREO		BIT(17)
+#define AR71XX_RESET_DDR		BIT(16)
+#define AR71XX_RESET_GE1_MAC		BIT(13)
+#define AR71XX_RESET_GE1_PHY		BIT(12)
+#define AR71XX_RESET_USBSUS_OVERRIDE	BIT(10)
+#define AR71XX_RESET_GE0_MAC		BIT(9)
+#define AR71XX_RESET_GE0_PHY		BIT(8)
+#define AR71XX_RESET_USB_OHCI_DLL	BIT(6)
+#define AR71XX_RESET_USB_HOST		BIT(5)
+#define AR71XX_RESET_USB_PHY		BIT(4)
+#define AR71XX_RESET_PCI_BUS		BIT(1)
+#define AR71XX_RESET_PCI_CORE		BIT(0)
+
+#define AR7240_RESET_USB_HOST		BIT(5)
+#define AR7240_RESET_OHCI_DLL		BIT(3)
+
+#define AR724X_RESET_GE1_MDIO		BIT(23)
+#define AR724X_RESET_GE0_MDIO		BIT(22)
+#define AR724X_RESET_PCIE_PHY_SERIAL	BIT(10)
+#define AR724X_RESET_PCIE_PHY		BIT(7)
+#define AR724X_RESET_PCIE		BIT(6)
+#define AR724X_RESET_USB_HOST		BIT(5)
+#define AR724X_RESET_USB_PHY		BIT(4)
+#define AR724X_RESET_USBSUS_OVERRIDE	BIT(3)
+
+#define AR913X_RESET_AMBA2WMAC		BIT(22)
+#define AR913X_RESET_USBSUS_OVERRIDE	BIT(10)
+#define AR913X_RESET_USB_HOST		BIT(5)
+#define AR913X_RESET_USB_PHY		BIT(4)
+
+#define AR933X_RESET_WMAC		BIT(11)
+#define AR933X_RESET_USB_HOST		BIT(5)
+#define AR933X_RESET_USB_PHY		BIT(4)
+#define AR933X_RESET_USBSUS_OVERRIDE	BIT(3)
+
+#define AR934X_RESET_USB_PHY_ANALOG	BIT(11)
+#define AR934X_RESET_USB_HOST		BIT(5)
+#define AR934X_RESET_USB_PHY		BIT(4)
+#define AR934X_RESET_USBSUS_OVERRIDE	BIT(3)
+
+#define AR933X_BOOTSTRAP_REF_CLK_40	BIT(0)
+
+#define AR934X_BOOTSTRAP_SW_OPTION8	BIT(23)
+#define AR934X_BOOTSTRAP_SW_OPTION7	BIT(22)
+#define AR934X_BOOTSTRAP_SW_OPTION6	BIT(21)
+#define AR934X_BOOTSTRAP_SW_OPTION5	BIT(20)
+#define AR934X_BOOTSTRAP_SW_OPTION4	BIT(19)
+#define AR934X_BOOTSTRAP_SW_OPTION3	BIT(18)
+#define AR934X_BOOTSTRAP_SW_OPTION2	BIT(17)
+#define AR934X_BOOTSTRAP_SW_OPTION1	BIT(16)
+#define AR934X_BOOTSTRAP_USB_MODE_DEVICE BIT(7)
+#define AR934X_BOOTSTRAP_PCIE_RC	BIT(6)
+#define AR934X_BOOTSTRAP_EJTAG_MODE	BIT(5)
+#define AR934X_BOOTSTRAP_REF_CLK_40	BIT(4)
+#define AR934X_BOOTSTRAP_BOOT_FROM_SPI	BIT(2)
+#define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1)
+#define AR934X_BOOTSTRAP_DDR1		BIT(0)
+
+#define QCA955X_BOOTSTRAP_REF_CLK_40	BIT(4)
+
+#define AR934X_PCIE_WMAC_INT_WMAC_MISC		BIT(0)
+#define AR934X_PCIE_WMAC_INT_WMAC_TX		BIT(1)
+#define AR934X_PCIE_WMAC_INT_WMAC_RXLP		BIT(2)
+#define AR934X_PCIE_WMAC_INT_WMAC_RXHP		BIT(3)
+#define AR934X_PCIE_WMAC_INT_PCIE_RC		BIT(4)
+#define AR934X_PCIE_WMAC_INT_PCIE_RC0		BIT(5)
+#define AR934X_PCIE_WMAC_INT_PCIE_RC1		BIT(6)
+#define AR934X_PCIE_WMAC_INT_PCIE_RC2		BIT(7)
+#define AR934X_PCIE_WMAC_INT_PCIE_RC3		BIT(8)
+#define AR934X_PCIE_WMAC_INT_WMAC_ALL \
+	(AR934X_PCIE_WMAC_INT_WMAC_MISC | AR934X_PCIE_WMAC_INT_WMAC_TX | \
+	 AR934X_PCIE_WMAC_INT_WMAC_RXLP | AR934X_PCIE_WMAC_INT_WMAC_RXHP)
+
+#define AR934X_PCIE_WMAC_INT_PCIE_ALL \
+	(AR934X_PCIE_WMAC_INT_PCIE_RC | AR934X_PCIE_WMAC_INT_PCIE_RC0 | \
+	 AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \
+	 AR934X_PCIE_WMAC_INT_PCIE_RC3)
+
+#define QCA955X_EXT_INT_WMAC_MISC		BIT(0)
+#define QCA955X_EXT_INT_WMAC_TX			BIT(1)
+#define QCA955X_EXT_INT_WMAC_RXLP		BIT(2)
+#define QCA955X_EXT_INT_WMAC_RXHP		BIT(3)
+#define QCA955X_EXT_INT_PCIE_RC1		BIT(4)
+#define QCA955X_EXT_INT_PCIE_RC1_INT0		BIT(5)
+#define QCA955X_EXT_INT_PCIE_RC1_INT1		BIT(6)
+#define QCA955X_EXT_INT_PCIE_RC1_INT2		BIT(7)
+#define QCA955X_EXT_INT_PCIE_RC1_INT3		BIT(8)
+#define QCA955X_EXT_INT_PCIE_RC2		BIT(12)
+#define QCA955X_EXT_INT_PCIE_RC2_INT0		BIT(13)
+#define QCA955X_EXT_INT_PCIE_RC2_INT1		BIT(14)
+#define QCA955X_EXT_INT_PCIE_RC2_INT2		BIT(15)
+#define QCA955X_EXT_INT_PCIE_RC2_INT3		BIT(16)
+#define QCA955X_EXT_INT_USB1			BIT(24)
+#define QCA955X_EXT_INT_USB2			BIT(28)
+
+#define QCA955X_EXT_INT_WMAC_ALL \
+	(QCA955X_EXT_INT_WMAC_MISC | QCA955X_EXT_INT_WMAC_TX | \
+	 QCA955X_EXT_INT_WMAC_RXLP | QCA955X_EXT_INT_WMAC_RXHP)
+
+#define QCA955X_EXT_INT_PCIE_RC1_ALL \
+	(QCA955X_EXT_INT_PCIE_RC1 | QCA955X_EXT_INT_PCIE_RC1_INT0 | \
+	 QCA955X_EXT_INT_PCIE_RC1_INT1 | QCA955X_EXT_INT_PCIE_RC1_INT2 | \
+	 QCA955X_EXT_INT_PCIE_RC1_INT3)
+
+#define QCA955X_EXT_INT_PCIE_RC2_ALL \
+	(QCA955X_EXT_INT_PCIE_RC2 | QCA955X_EXT_INT_PCIE_RC2_INT0 | \
+	 QCA955X_EXT_INT_PCIE_RC2_INT1 | QCA955X_EXT_INT_PCIE_RC2_INT2 | \
+	 QCA955X_EXT_INT_PCIE_RC2_INT3)
+
+#define REV_ID_MAJOR_MASK		0xfff0
+#define REV_ID_MAJOR_AR71XX		0x00a0
+#define REV_ID_MAJOR_AR913X		0x00b0
+#define REV_ID_MAJOR_AR7240		0x00c0
+#define REV_ID_MAJOR_AR7241		0x0100
+#define REV_ID_MAJOR_AR7242		0x1100
+#define REV_ID_MAJOR_AR9330		0x0110
+#define REV_ID_MAJOR_AR9331		0x1110
+#define REV_ID_MAJOR_AR9341		0x0120
+#define REV_ID_MAJOR_AR9342		0x1120
+#define REV_ID_MAJOR_AR9344		0x2120
+#define REV_ID_MAJOR_QCA9556		0x0130
+#define REV_ID_MAJOR_QCA9558		0x1130
+
+#define AR71XX_REV_ID_MINOR_MASK	0x3
+#define AR71XX_REV_ID_MINOR_AR7130	0x0
+#define AR71XX_REV_ID_MINOR_AR7141	0x1
+#define AR71XX_REV_ID_MINOR_AR7161	0x2
+#define AR71XX_REV_ID_REVISION_MASK	0x3
+#define AR71XX_REV_ID_REVISION_SHIFT	2
+
+#define AR913X_REV_ID_MINOR_MASK	0x3
+#define AR913X_REV_ID_MINOR_AR9130	0x0
+#define AR913X_REV_ID_MINOR_AR9132	0x1
+#define AR913X_REV_ID_REVISION_MASK	0x3
+#define AR913X_REV_ID_REVISION_SHIFT	2
+
+#define AR933X_REV_ID_REVISION_MASK	0x3
+
+#define AR724X_REV_ID_REVISION_MASK	0x3
+
+#define AR934X_REV_ID_REVISION_MASK	0xf
+
+#define QCA955X_REV_ID_REVISION_MASK	0xf
+
+/*
+ * SPI block
+ */
+#define AR71XX_SPI_REG_FS	0x00	/* Function Select */
+#define AR71XX_SPI_REG_CTRL	0x04	/* SPI Control */
+#define AR71XX_SPI_REG_IOC	0x08	/* SPI I/O Control */
+#define AR71XX_SPI_REG_RDS	0x0c	/* Read Data Shift */
+
+#define AR71XX_SPI_FS_GPIO	BIT(0)	/* Enable GPIO mode */
+
+#define AR71XX_SPI_CTRL_RD	BIT(6)	/* Remap Disable */
+#define AR71XX_SPI_CTRL_DIV_MASK 0x3f
+
+#define AR71XX_SPI_IOC_DO	BIT(0)	/* Data Out pin */
+#define AR71XX_SPI_IOC_CLK	BIT(8)	/* CLK pin */
+#define AR71XX_SPI_IOC_CS(n)	BIT(16 + (n))
+#define AR71XX_SPI_IOC_CS0	AR71XX_SPI_IOC_CS(0)
+#define AR71XX_SPI_IOC_CS1	AR71XX_SPI_IOC_CS(1)
+#define AR71XX_SPI_IOC_CS2	AR71XX_SPI_IOC_CS(2)
+#define AR71XX_SPI_IOC_CS_ALL	(AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1 | \
+				 AR71XX_SPI_IOC_CS2)
+
+/*
+ * GPIO block
+ */
+#define AR71XX_GPIO_REG_OE		0x00
+#define AR71XX_GPIO_REG_IN		0x04
+#define AR71XX_GPIO_REG_OUT		0x08
+#define AR71XX_GPIO_REG_SET		0x0c
+#define AR71XX_GPIO_REG_CLEAR		0x10
+#define AR71XX_GPIO_REG_INT_MODE	0x14
+#define AR71XX_GPIO_REG_INT_TYPE	0x18
+#define AR71XX_GPIO_REG_INT_POLARITY	0x1c
+#define AR71XX_GPIO_REG_INT_PENDING	0x20
+#define AR71XX_GPIO_REG_INT_ENABLE	0x24
+#define AR71XX_GPIO_REG_FUNC		0x28
+
+#define AR934X_GPIO_REG_FUNC		0x6c
+
+#define AR71XX_GPIO_COUNT		16
+#define AR7240_GPIO_COUNT		18
+#define AR7241_GPIO_COUNT		20
+#define AR913X_GPIO_COUNT		22
+#define AR933X_GPIO_COUNT		30
+#define AR934X_GPIO_COUNT		23
+#define QCA955X_GPIO_COUNT		24
+
+/*
+ * SRIF block
+ */
+#define AR934X_SRIF_CPU_DPLL1_REG	0x1c0
+#define AR934X_SRIF_CPU_DPLL2_REG	0x1c4
+#define AR934X_SRIF_CPU_DPLL3_REG	0x1c8
+
+#define AR934X_SRIF_DDR_DPLL1_REG	0x240
+#define AR934X_SRIF_DDR_DPLL2_REG	0x244
+#define AR934X_SRIF_DDR_DPLL3_REG	0x248
+
+#define AR934X_SRIF_DPLL1_REFDIV_SHIFT	27
+#define AR934X_SRIF_DPLL1_REFDIV_MASK	0x1f
+#define AR934X_SRIF_DPLL1_NINT_SHIFT	18
+#define AR934X_SRIF_DPLL1_NINT_MASK	0x1ff
+#define AR934X_SRIF_DPLL1_NFRAC_MASK	0x0003ffff
+
+#define AR934X_SRIF_DPLL2_LOCAL_PLL	BIT(30)
+#define AR934X_SRIF_DPLL2_OUTDIV_SHIFT	13
+#define AR934X_SRIF_DPLL2_OUTDIV_MASK	0x7
+
+#endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/toolchain.inc b/toolchain.inc
index 195ed77..3e4b7e3 100644
--- a/toolchain.inc
+++ b/toolchain.inc
@@ -61,10 +61,12 @@ ARCHDIR-arm	:= arm
 ARCHDIR-arm64	:= arm64
 ARCHDIR-riscv	:= riscv
 ARCHDIR-mips	:= mips
+ARCHDIR-mipseb	:= mipseb
 
 CFLAGS_arm      +=
 CFLAGS_arm64    += -mgeneral-regs-only
 CFLAGS_mips	+= -mips32r2 -G 0 -mno-abicalls -fno-pic
+CFLAGS_mipseb	+= -mips32r2 -G 0 -mno-abicalls -fno-pic
 CFLAGS_riscv	+=
 CFLAGS_x86_32	+=
 CFLAGS_x86_64   += -mcmodel=large -mno-red-zone
@@ -85,6 +87,7 @@ CFLAGS_x86_64   += -mcmodel=large -mno-red-zone
 CFLAGS_arm	+= -Wstack-usage=1536
 CFLAGS_arm64	+= -Wstack-usage=1536
 CFLAGS_mips	+= -Wstack-usage=1536
+CFLAGS_mipseb	+= -Wstack-usage=1536
 CFLAGS_riscv	+= -Wstack-usage=1536
 
 toolchain_to_dir = \
@@ -139,6 +142,7 @@ endef
 # initialize standard toolchain (CC,AS and others) for give stage
 # @1 : stage for which the toolchain is to be initialized
 init_standard_toolchain = \
+	$(echo $(1) >> /tmp/fa ) \
 	$(eval $(call set_stage_toolchain,$(1))) \
 	$(eval $(call create_class_compiler,$(1),$(ARCH-$(1)-y)))
 
diff --git a/util/crossgcc/Makefile b/util/crossgcc/Makefile
index b1fba4a..885dbfa 100644
--- a/util/crossgcc/Makefile
+++ b/util/crossgcc/Makefile
@@ -2,13 +2,13 @@
 BUILD_PLATFORM ?= i386-elf
 
 all:
-	$(MAKE) BUILDGCC_OPTIONS=-t build-i386 build-x64 build-armv7a build-mips build-riscv build-aarch64 \
+	$(MAKE) BUILDGCC_OPTIONS=-t build-i386 build-x64 build-armv7a build-mips build-mipseb build-riscv build-aarch64 \
 	        build_clang
 	$(MAKE) clean_tempfiles
 
 all_without_gdb:
 	$(MAKE) BUILDGCC_OPTIONS=-t build-i386-without-gdb build-x64-without-gdb build-armv7a-without-gdb \
-	        build-mips-without-gdb build-riscv-without-gdb build-aarch64-without-gdb build_clang
+	        build-mips-without-gdb build-mipseb-without-gdb build-riscv-without-gdb build-aarch64-without-gdb build_clang
 	$(MAKE) clean_tempfiles
 
 build_tools: build_gcc build_iasl build_gdb
@@ -47,6 +47,9 @@ build-aarch64:
 build-mips:
 	@$(MAKE) build_tools BUILD_PLATFORM=mipsel-elf
 
+build-mipseb:
+	@$(MAKE) build_tools BUILD_PLATFORM=mipseb-elf
+
 build-riscv:
 	@$(MAKE) build_tools BUILD_PLATFORM=riscv-elf
 
@@ -67,6 +70,9 @@ build-aarch64-without-gdb:
 build-mips-without-gdb:
 	@$(MAKE) build_tools_without_gdb BUILD_PLATFORM=mipsel-elf
 
+build-mipseb-without-gdb:
+	@$(MAKE) build_tools_without_gdb BUILD_PLATFORM=mipseb-elf
+
 build-riscv-without-gdb:
 	@$(MAKE) build_tools_without_gdb BUILD_PLATFORM=riscv-elf
 
@@ -86,5 +92,6 @@ distclean: clean
 
 .PHONY: build_gcc build_iasl build_gdb build_tools build_tools_without_gdb \
 	build-i386-without-gdb build-x64-without-gdb build-armv7a-without-gdb \
-	build-aarch64-without-gdb build-mips-without-gdb build-riscv-without-gdb \
+	build-aarch64-without-gdb build-mips-without-gdb build-mipseb-without-gdb \
+	build-riscv-without-gdb \
 	all build clean distclean clean_tempfiles all_without_gdb
diff --git a/util/crossgcc/README b/util/crossgcc/README
index 5ce9304..89fb2c9 100644
--- a/util/crossgcc/README
+++ b/util/crossgcc/README
@@ -7,6 +7,7 @@ known working:
   i386-elf
   x86_64-elf
   powerpc-elf
+  mipseb-elf
   mipsel-elf
   arm-elf
   armv7a-eabi
diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc
index 49e41e5..c7cd41b 100755
--- a/util/crossgcc/buildgcc
+++ b/util/crossgcc/buildgcc
@@ -315,7 +315,7 @@ myhelp()
 	printf "                                  (defaults to $TARGETARCH)\n"
 	printf "    [-S|--scripting]              build scripting support for GDB\n\n"
 	printf "Platforms for GCC & GDB:\n"
-	printf "    x86_64 i386-elf i386-mingw32 mipsel-elf riscv-elf arm aarch64\n\n"
+	printf "    x86_64 i386-elf i386-mingw32 mipseb-elf mipsel-elf riscv-elf arm aarch64\n\n"
 }
 
 myversion()
@@ -545,6 +545,7 @@ case "$TARGETARCH" in
 	x86_64*)	TARGETARCH=x86_64-elf;;
 	i386-elf)	;;
 	i386-mingw32)	;;
+	mipseb-elf)	TARGETARCH=mips-elf;;
 	mipsel-elf)	;;
 	riscv-elf)	;;
 	i386*)		TARGETARCH=i386-elf;;
diff --git a/util/xcompile/xcompile b/util/xcompile/xcompile
index 46a30d1..bf8e08aa 100755
--- a/util/xcompile/xcompile
+++ b/util/xcompile/xcompile
@@ -180,6 +180,14 @@ detect_special_flags() {
 		  "$LDFLAGS --fix-cortex-a53-843419" && \
 		  LDFLAGS_ARM64_A53_ERRATUM_843419+=" --fix-cortex-a53-843419"
 		;;
+	mipseb)
+		testcc "$GCC" "$CFLAGS_GCC -mno-abicalls -fno-pic" && \
+		  CFLAGS_GCC+=" -mno-abicalls -fno-pic"
+
+                # Enforce big endian mode.
+		testcc "$GCC" "$CFLAGS_GCC -EB" && \
+		  CFLAGS_GCC+=" -EB"
+		;;
 	mipsel)
 		testcc "$GCC" "$CFLAGS_GCC -mno-abicalls -fno-pic" && \
 		  CFLAGS_GCC+=" -mno-abicalls -fno-pic"
@@ -235,7 +243,7 @@ EOF
 }
 
 # Architecture definitions
-SUPPORTED_ARCHITECTURES="arm arm64 mipsel riscv x64 x86"
+SUPPORTED_ARCHITECTURES="arm arm64 mipseb mipsel riscv x64 x86"
 
 arch_config_arm() {
 	TARCH="arm"
@@ -280,6 +288,16 @@ arch_config_x86() {
 	CC_RT_EXTRA_GCC="--wrap __divdi3 --wrap __udivdi3 --wrap __moddi3 --wrap __umoddi3"
 }
 
+arch_config_mipseb() {
+	TARCH="mipseb"
+	TBFDARCHS="tradbigmips bigmips"
+	TCLIST="mips"
+	TWIDTH="32"
+	TSUPP="mips mipseb"
+	TABI="elf"
+	TENDIAN="EB"
+}
+
 arch_config_mipsel() {
 	TARCH="mips"
 	TBFDARCHS="tradlittlemips littlemips"



More information about the coreboot-gerrit mailing list