[coreboot-gerrit] New patch to review for coreboot: 3895151 ARMv7: flatten arch/armv7 source tree
Gabe Black (gabeblack@chromium.org)
gerrit at coreboot.org
Tue Jul 9 05:29:07 CEST 2013
Gabe Black (gabeblack at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3659
-gerrit
commit 38951512433087bce6c6a9d17572cc469e80cc47
Author: Stefan Reinauer <reinauer at chromium.org>
Date: Fri May 24 14:38:48 2013 -0700
ARMv7: flatten arch/armv7 source tree
With only 19 source files it doesn't make a whole lot of sense to
create sub directories in arch/armv7, especially since the files
were distributed somewhat randomly.
Change-Id: I029c7848e915edf1737e1c401c034837c95d179d
Signed-off-by: Stefan Reinauer <reinauer at chromium.org>
Signed-off-by: Gabe Black <gabeblack at chromium.org>
---
src/arch/armv7/Makefile.inc | 25 ++-
src/arch/armv7/boot.c | 189 +++++++++++++++++++++++
src/arch/armv7/boot/Makefile.inc | 12 --
src/arch/armv7/boot/boot.c | 189 -----------------------
src/arch/armv7/boot/tables.c | 79 ----------
src/arch/armv7/cache.c | 308 +++++++++++++++++++++++++++++++++++++
src/arch/armv7/div0.c | 33 ++++
src/arch/armv7/eabi_compat.c | 31 ++++
src/arch/armv7/early_console.c | 81 ++++++++++
src/arch/armv7/id.inc | 18 +++
src/arch/armv7/interrupts.c | 197 ++++++++++++++++++++++++
src/arch/armv7/lib/Makefile.inc | 20 ---
src/arch/armv7/lib/cache.c | 308 -------------------------------------
src/arch/armv7/lib/div0.c | 33 ----
src/arch/armv7/lib/eabi_compat.c | 31 ----
src/arch/armv7/lib/early_console.c | 81 ----------
src/arch/armv7/lib/id.inc | 18 ---
src/arch/armv7/lib/interrupts.c | 197 ------------------------
src/arch/armv7/lib/memcpy.S | 243 -----------------------------
src/arch/armv7/lib/memset.S | 126 ---------------
src/arch/armv7/lib/mmu.c | 157 -------------------
src/arch/armv7/memcpy.S | 243 +++++++++++++++++++++++++++++
src/arch/armv7/memset.S | 126 +++++++++++++++
src/arch/armv7/mmu.c | 157 +++++++++++++++++++
src/arch/armv7/tables.c | 79 ++++++++++
25 files changed, 1486 insertions(+), 1495 deletions(-)
diff --git a/src/arch/armv7/Makefile.inc b/src/arch/armv7/Makefile.inc
index 1045774..a249655 100644
--- a/src/arch/armv7/Makefile.inc
+++ b/src/arch/armv7/Makefile.inc
@@ -161,6 +161,29 @@ $(obj)/mainboard/$(MAINBOARDDIR)/romstage.pre.inc: $(src)/mainboard/$(MAINBOARDD
ramstage-y += exception.c
ramstage-y += exception_asm.S
+bootblock-$(CONFIG_EARLY_CONSOLE) += early_console.c
+bootblock-y += cache.c
+
+romstage-y += cache.c
+romstage-y += div0.c
+romstage-$(CONFIG_EARLY_CONSOLE) += early_console.c
+
+ramstage-y += div0.c
+#ramstage-y += interrupts.c
+#ramstage-y += memcpy.S
+#ramstage-y += memset.S
+ramstage-y += cache.c
+ramstage-y += mmu.c
+
+romstage-y += eabi_compat.c
+ramstage-y += eabi_compat.c
+bootblock-y += eabi_compat.c
+
+ramstage-y += boot.c
+ramstage-y += tables.c
+
+$(obj)/arch/armv7/coreboot_table.ramstage.o : $(OPTION_TABLE_H)
+
romstage-srcs += $(objgenerated)/crt0.s
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/mainboard.c
ifeq ($(CONFIG_GENERATE_PIRQ_TABLE),y)
@@ -194,7 +217,7 @@ bootblock_lds = $(src)/arch/armv7/bootblock.lds
bootblock_lds += $(chipset_bootblock_lds)
bootblock_inc += $(src)/arch/armv7/bootblock.inc
-bootblock_inc += $(src)/arch/armv7/lib/id.inc
+bootblock_inc += $(src)/arch/armv7/id.inc
bootblock_inc += $(chipset_bootblock_inc)
bootblock_inc += $(objgenerated)/bootblock.inc
diff --git a/src/arch/armv7/boot.c b/src/arch/armv7/boot.c
new file mode 100644
index 0000000..ab531be
--- /dev/null
+++ b/src/arch/armv7/boot.c
@@ -0,0 +1,189 @@
+#include <console/console.h>
+#include <ip_checksum.h>
+#include <boot/elf.h>
+#include <boot/elf_boot.h>
+#include <string.h>
+#include <cpu/x86/multiboot.h>
+#include <arch/stages.h>
+
+
+#ifndef CMD_LINE
+#define CMD_LINE ""
+#endif
+
+
+
+#define UPSZ(X) ((sizeof(X) + 3) &~3)
+
+static struct {
+ Elf_Bhdr hdr;
+ Elf_Nhdr ft_hdr;
+ unsigned char ft_desc[UPSZ(FIRMWARE_TYPE)];
+ Elf_Nhdr bl_hdr;
+ unsigned char bl_desc[UPSZ(BOOTLOADER)];
+ Elf_Nhdr blv_hdr;
+ unsigned char blv_desc[UPSZ(BOOTLOADER_VERSION)];
+ Elf_Nhdr cmd_hdr;
+ unsigned char cmd_desc[UPSZ(CMD_LINE)];
+} elf_boot_notes = {
+ .hdr = {
+ .b_signature = 0x0E1FB007,
+ .b_size = sizeof(elf_boot_notes),
+ .b_checksum = 0,
+ .b_records = 4,
+ },
+ .ft_hdr = {
+ .n_namesz = 0,
+ .n_descsz = sizeof(FIRMWARE_TYPE),
+ .n_type = EBN_FIRMWARE_TYPE,
+ },
+ .ft_desc = FIRMWARE_TYPE,
+ .bl_hdr = {
+ .n_namesz = 0,
+ .n_descsz = sizeof(BOOTLOADER),
+ .n_type = EBN_BOOTLOADER_NAME,
+ },
+ .bl_desc = BOOTLOADER,
+ .blv_hdr = {
+ .n_namesz = 0,
+ .n_descsz = sizeof(BOOTLOADER_VERSION),
+ .n_type = EBN_BOOTLOADER_VERSION,
+ },
+ .blv_desc = BOOTLOADER_VERSION,
+ .cmd_hdr = {
+ .n_namesz = 0,
+ .n_descsz = sizeof(CMD_LINE),
+ .n_type = EBN_COMMAND_LINE,
+ },
+ .cmd_desc = CMD_LINE,
+};
+
+
+int elf_check_arch(Elf_ehdr *ehdr)
+{
+ return (
+ ((ehdr->e_machine == EM_386) || (ehdr->e_machine == EM_486)) &&
+ (ehdr->e_ident[EI_CLASS] == ELFCLASS32) &&
+ (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
+ );
+
+}
+
+void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long size)
+{
+ extern unsigned char _ram_seg, _eram_seg;
+ unsigned long lb_start, lb_size;
+ unsigned long adjust, adjusted_boot_notes;
+
+ elf_boot_notes.hdr.b_checksum =
+ compute_ip_checksum(&elf_boot_notes, sizeof(elf_boot_notes));
+
+ lb_start = (unsigned long)&_ram_seg;
+ lb_size = (unsigned long)(&_eram_seg - &_ram_seg);
+ adjust = buffer + size - lb_start;
+
+ adjusted_boot_notes = (unsigned long)&elf_boot_notes;
+ adjusted_boot_notes += adjust;
+
+ printk(BIOS_SPEW, "entry = 0x%08lx\n", (unsigned long)entry);
+ printk(BIOS_SPEW, "lb_start = 0x%08lx\n", lb_start);
+ printk(BIOS_SPEW, "lb_size = 0x%08lx\n", lb_size);
+ printk(BIOS_SPEW, "adjust = 0x%08lx\n", adjust);
+ printk(BIOS_SPEW, "buffer = 0x%08lx\n", buffer);
+ printk(BIOS_SPEW, " elf_boot_notes = 0x%08lx\n", (unsigned long)&elf_boot_notes);
+ printk(BIOS_SPEW, "adjusted_boot_notes = 0x%08lx\n", adjusted_boot_notes);
+
+ stage_exit(entry);
+#if 0
+ /* FIXME: do we need any of this? */
+ /* Jump to kernel */
+ __asm__ __volatile__(
+ " cld \n\t"
+ /* Save the callee save registers... */
+ " pushl %%esi\n\t"
+ " pushl %%edi\n\t"
+ " pushl %%ebx\n\t"
+ /* Save the parameters I was passed */
+ " pushl $0\n\t" /* 20 adjust */
+ " pushl %0\n\t" /* 16 lb_start */
+ " pushl %1\n\t" /* 12 buffer */
+ " pushl %2\n\t" /* 8 lb_size */
+ " pushl %3\n\t" /* 4 entry */
+ " pushl %4\n\t" /* 0 elf_boot_notes */
+ /* Compute the adjustment */
+ " xorl %%eax, %%eax\n\t"
+ " subl 16(%%esp), %%eax\n\t"
+ " addl 12(%%esp), %%eax\n\t"
+ " addl 8(%%esp), %%eax\n\t"
+ " movl %%eax, 20(%%esp)\n\t"
+ /* Place a copy of coreboot in its new location */
+ /* Move ``longs'' the coreboot size is 4 byte aligned */
+ " movl 12(%%esp), %%edi\n\t"
+ " addl 8(%%esp), %%edi\n\t"
+ " movl 16(%%esp), %%esi\n\t"
+ " movl 8(%%esp), %%ecx\n\n"
+ " shrl $2, %%ecx\n\t"
+ " rep movsl\n\t"
+
+ /* Adjust the stack pointer to point into the new coreboot image */
+ " addl 20(%%esp), %%esp\n\t"
+ /* Adjust the instruction pointer to point into the new coreboot image */
+ " movl $1f, %%eax\n\t"
+ " addl 20(%%esp), %%eax\n\t"
+ " jmp *%%eax\n\t"
+ "1: \n\t"
+
+ /* Copy the coreboot bounce buffer over coreboot */
+ /* Move ``longs'' the coreboot size is 4 byte aligned */
+ " movl 16(%%esp), %%edi\n\t"
+ " movl 12(%%esp), %%esi\n\t"
+ " movl 8(%%esp), %%ecx\n\t"
+ " shrl $2, %%ecx\n\t"
+ " rep movsl\n\t"
+
+ /* Now jump to the loaded image */
+ " movl %5, %%eax\n\t"
+ " movl 0(%%esp), %%ebx\n\t"
+ " call *4(%%esp)\n\t"
+
+ /* The loaded image returned? */
+ " cli \n\t"
+ " cld \n\t"
+
+ /* Copy the saved copy of coreboot where coreboot runs */
+ /* Move ``longs'' the coreboot size is 4 byte aligned */
+ " movl 16(%%esp), %%edi\n\t"
+ " movl 12(%%esp), %%esi\n\t"
+ " addl 8(%%esp), %%esi\n\t"
+ " movl 8(%%esp), %%ecx\n\t"
+ " shrl $2, %%ecx\n\t"
+ " rep movsl\n\t"
+
+ /* Adjust the stack pointer to point into the old coreboot image */
+ " subl 20(%%esp), %%esp\n\t"
+
+ /* Adjust the instruction pointer to point into the old coreboot image */
+ " movl $1f, %%eax\n\t"
+ " subl 20(%%esp), %%eax\n\t"
+ " jmp *%%eax\n\t"
+ "1: \n\t"
+
+ /* Drop the parameters I was passed */
+ " addl $24, %%esp\n\t"
+
+ /* Restore the callee save registers */
+ " popl %%ebx\n\t"
+ " popl %%edi\n\t"
+ " popl %%esi\n\t"
+
+ ::
+ "ri" (lb_start), "ri" (buffer), "ri" (lb_size),
+ "ri" (entry),
+#if CONFIG_MULTIBOOT
+ "ri"(mbi), "ri" (MB_MAGIC2)
+#else
+ "ri"(adjusted_boot_notes), "ri" (0x0E1FB007)
+#endif
+ );
+#endif
+}
diff --git a/src/arch/armv7/boot/Makefile.inc b/src/arch/armv7/boot/Makefile.inc
deleted file mode 100644
index 8d24fae..0000000
--- a/src/arch/armv7/boot/Makefile.inc
+++ /dev/null
@@ -1,12 +0,0 @@
-ramstage-y += boot.c
-#ramstage-$(CONFIG_MULTIBOOT) += multiboot.c
-ramstage-y += tables.c
-#ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c
-#ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpigen.c
-#ramstage-$(CONFIG_HAVE_ACPI_RESUME) += wakeup.S
-
-#FIXME(dhendrix): is there anything preventing multiboot from
-#working on ARM?
-
-$(obj)/arch/armv7/boot/coreboot_table.ramstage.o : $(OPTION_TABLE_H)
-#$(obj)/arch/x86/boot/smbios.ramstage.o: $(obj)/build.h
diff --git a/src/arch/armv7/boot/boot.c b/src/arch/armv7/boot/boot.c
deleted file mode 100644
index ab531be..0000000
--- a/src/arch/armv7/boot/boot.c
+++ /dev/null
@@ -1,189 +0,0 @@
-#include <console/console.h>
-#include <ip_checksum.h>
-#include <boot/elf.h>
-#include <boot/elf_boot.h>
-#include <string.h>
-#include <cpu/x86/multiboot.h>
-#include <arch/stages.h>
-
-
-#ifndef CMD_LINE
-#define CMD_LINE ""
-#endif
-
-
-
-#define UPSZ(X) ((sizeof(X) + 3) &~3)
-
-static struct {
- Elf_Bhdr hdr;
- Elf_Nhdr ft_hdr;
- unsigned char ft_desc[UPSZ(FIRMWARE_TYPE)];
- Elf_Nhdr bl_hdr;
- unsigned char bl_desc[UPSZ(BOOTLOADER)];
- Elf_Nhdr blv_hdr;
- unsigned char blv_desc[UPSZ(BOOTLOADER_VERSION)];
- Elf_Nhdr cmd_hdr;
- unsigned char cmd_desc[UPSZ(CMD_LINE)];
-} elf_boot_notes = {
- .hdr = {
- .b_signature = 0x0E1FB007,
- .b_size = sizeof(elf_boot_notes),
- .b_checksum = 0,
- .b_records = 4,
- },
- .ft_hdr = {
- .n_namesz = 0,
- .n_descsz = sizeof(FIRMWARE_TYPE),
- .n_type = EBN_FIRMWARE_TYPE,
- },
- .ft_desc = FIRMWARE_TYPE,
- .bl_hdr = {
- .n_namesz = 0,
- .n_descsz = sizeof(BOOTLOADER),
- .n_type = EBN_BOOTLOADER_NAME,
- },
- .bl_desc = BOOTLOADER,
- .blv_hdr = {
- .n_namesz = 0,
- .n_descsz = sizeof(BOOTLOADER_VERSION),
- .n_type = EBN_BOOTLOADER_VERSION,
- },
- .blv_desc = BOOTLOADER_VERSION,
- .cmd_hdr = {
- .n_namesz = 0,
- .n_descsz = sizeof(CMD_LINE),
- .n_type = EBN_COMMAND_LINE,
- },
- .cmd_desc = CMD_LINE,
-};
-
-
-int elf_check_arch(Elf_ehdr *ehdr)
-{
- return (
- ((ehdr->e_machine == EM_386) || (ehdr->e_machine == EM_486)) &&
- (ehdr->e_ident[EI_CLASS] == ELFCLASS32) &&
- (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
- );
-
-}
-
-void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long size)
-{
- extern unsigned char _ram_seg, _eram_seg;
- unsigned long lb_start, lb_size;
- unsigned long adjust, adjusted_boot_notes;
-
- elf_boot_notes.hdr.b_checksum =
- compute_ip_checksum(&elf_boot_notes, sizeof(elf_boot_notes));
-
- lb_start = (unsigned long)&_ram_seg;
- lb_size = (unsigned long)(&_eram_seg - &_ram_seg);
- adjust = buffer + size - lb_start;
-
- adjusted_boot_notes = (unsigned long)&elf_boot_notes;
- adjusted_boot_notes += adjust;
-
- printk(BIOS_SPEW, "entry = 0x%08lx\n", (unsigned long)entry);
- printk(BIOS_SPEW, "lb_start = 0x%08lx\n", lb_start);
- printk(BIOS_SPEW, "lb_size = 0x%08lx\n", lb_size);
- printk(BIOS_SPEW, "adjust = 0x%08lx\n", adjust);
- printk(BIOS_SPEW, "buffer = 0x%08lx\n", buffer);
- printk(BIOS_SPEW, " elf_boot_notes = 0x%08lx\n", (unsigned long)&elf_boot_notes);
- printk(BIOS_SPEW, "adjusted_boot_notes = 0x%08lx\n", adjusted_boot_notes);
-
- stage_exit(entry);
-#if 0
- /* FIXME: do we need any of this? */
- /* Jump to kernel */
- __asm__ __volatile__(
- " cld \n\t"
- /* Save the callee save registers... */
- " pushl %%esi\n\t"
- " pushl %%edi\n\t"
- " pushl %%ebx\n\t"
- /* Save the parameters I was passed */
- " pushl $0\n\t" /* 20 adjust */
- " pushl %0\n\t" /* 16 lb_start */
- " pushl %1\n\t" /* 12 buffer */
- " pushl %2\n\t" /* 8 lb_size */
- " pushl %3\n\t" /* 4 entry */
- " pushl %4\n\t" /* 0 elf_boot_notes */
- /* Compute the adjustment */
- " xorl %%eax, %%eax\n\t"
- " subl 16(%%esp), %%eax\n\t"
- " addl 12(%%esp), %%eax\n\t"
- " addl 8(%%esp), %%eax\n\t"
- " movl %%eax, 20(%%esp)\n\t"
- /* Place a copy of coreboot in its new location */
- /* Move ``longs'' the coreboot size is 4 byte aligned */
- " movl 12(%%esp), %%edi\n\t"
- " addl 8(%%esp), %%edi\n\t"
- " movl 16(%%esp), %%esi\n\t"
- " movl 8(%%esp), %%ecx\n\n"
- " shrl $2, %%ecx\n\t"
- " rep movsl\n\t"
-
- /* Adjust the stack pointer to point into the new coreboot image */
- " addl 20(%%esp), %%esp\n\t"
- /* Adjust the instruction pointer to point into the new coreboot image */
- " movl $1f, %%eax\n\t"
- " addl 20(%%esp), %%eax\n\t"
- " jmp *%%eax\n\t"
- "1: \n\t"
-
- /* Copy the coreboot bounce buffer over coreboot */
- /* Move ``longs'' the coreboot size is 4 byte aligned */
- " movl 16(%%esp), %%edi\n\t"
- " movl 12(%%esp), %%esi\n\t"
- " movl 8(%%esp), %%ecx\n\t"
- " shrl $2, %%ecx\n\t"
- " rep movsl\n\t"
-
- /* Now jump to the loaded image */
- " movl %5, %%eax\n\t"
- " movl 0(%%esp), %%ebx\n\t"
- " call *4(%%esp)\n\t"
-
- /* The loaded image returned? */
- " cli \n\t"
- " cld \n\t"
-
- /* Copy the saved copy of coreboot where coreboot runs */
- /* Move ``longs'' the coreboot size is 4 byte aligned */
- " movl 16(%%esp), %%edi\n\t"
- " movl 12(%%esp), %%esi\n\t"
- " addl 8(%%esp), %%esi\n\t"
- " movl 8(%%esp), %%ecx\n\t"
- " shrl $2, %%ecx\n\t"
- " rep movsl\n\t"
-
- /* Adjust the stack pointer to point into the old coreboot image */
- " subl 20(%%esp), %%esp\n\t"
-
- /* Adjust the instruction pointer to point into the old coreboot image */
- " movl $1f, %%eax\n\t"
- " subl 20(%%esp), %%eax\n\t"
- " jmp *%%eax\n\t"
- "1: \n\t"
-
- /* Drop the parameters I was passed */
- " addl $24, %%esp\n\t"
-
- /* Restore the callee save registers */
- " popl %%ebx\n\t"
- " popl %%edi\n\t"
- " popl %%esi\n\t"
-
- ::
- "ri" (lb_start), "ri" (buffer), "ri" (lb_size),
- "ri" (entry),
-#if CONFIG_MULTIBOOT
- "ri"(mbi), "ri" (MB_MAGIC2)
-#else
- "ri"(adjusted_boot_notes), "ri" (0x0E1FB007)
-#endif
- );
-#endif
-}
diff --git a/src/arch/armv7/boot/tables.c b/src/arch/armv7/boot/tables.c
deleted file mode 100644
index 0fc7399..0000000
--- a/src/arch/armv7/boot/tables.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#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)
-
-/*
- * TODO: "High" tables are a convention used on x86. Maybe we can
- * clean up that naming at some point.
- */
-uint64_t high_tables_base = 0;
-uint64_t high_tables_size;
-
-void cbmem_arch_init(void)
-{
-}
-
-struct lb_memory *write_tables(void)
-{
- unsigned long table_pointer, new_table_pointer;
-
- if (!high_tables_base) {
- printk(BIOS_ERR, "ERROR: high_tables_base is not set.\n");
- }
-
- printk(BIOS_DEBUG, "high_tables_base: %llx.\n", high_tables_base);
-
- 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 NULL;
- }
-
- 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();
-
- return get_lb_mem();
-}
diff --git a/src/arch/armv7/cache.c b/src/arch/armv7/cache.c
new file mode 100644
index 0000000..04eaa88
--- /dev/null
+++ b/src/arch/armv7/cache.c
@@ -0,0 +1,308 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * cache.c: Cache maintenance routines for ARMv7-A and ARMv7-R
+ *
+ * Reference: ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition
+ */
+
+#include <stdint.h>
+
+#include <arch/cache.h>
+
+#define bitmask(high, low) ((1UL << (high)) + \
+ ((1UL << (high)) - 1) - ((1UL << (low)) - 1))
+
+/* Basic log2() implementation. Note: log2(0) is 0 for our purposes. */
+/* FIXME: src/include/lib.h is difficult to work with due to romcc */
+static unsigned long log2(unsigned long u)
+{
+ int i = 0;
+
+ while (u >>= 1)
+ i++;
+
+ return i;
+}
+
+void tlb_invalidate_all(void)
+{
+ /*
+ * FIXME: ARMv7 Architecture Ref. Manual claims that the distinction
+ * instruction vs. data TLBs is deprecated in ARMv7, however this does
+ * not seem to be the case as of Cortex-A15.
+ */
+ tlbiall();
+ dtlbiall();
+ itlbiall();
+ isb();
+ dsb();
+}
+
+void icache_invalidate_all(void)
+{
+ /*
+ * icache can be entirely invalidated with one operation.
+ * Note: If branch predictors are architecturally-visible, ICIALLU
+ * also performs a BPIALL operation (B2-1283 in arch manual)
+ */
+ iciallu();
+ isb();
+}
+
+enum dcache_op {
+ OP_DCCISW,
+ OP_DCISW,
+ OP_DCCIMVAC,
+ OP_DCCMVAC,
+};
+
+/*
+ * Do a dcache operation on entire cache by set/way. This is done for
+ * portability because mapping of memory address to cache location is
+ * implementation defined (See note on "Requirements for operations by
+ * set/way" in arch ref. manual).
+ */
+static void dcache_op_set_way(enum dcache_op op)
+{
+ uint32_t ccsidr;
+ unsigned int associativity, num_sets, linesize_bytes;
+ unsigned int set, way;
+ unsigned int level;
+
+ level = (read_csselr() >> 1) & 0x7;
+
+ /*
+ * dcache must be invalidated by set/way for portability since virtual
+ * memory mapping is system-defined. The number of sets and
+ * associativity is given by CCSIDR. We'll use DCISW to invalidate the
+ * dcache.
+ */
+ ccsidr = read_ccsidr();
+
+ /* FIXME: rounding up required here? */
+ num_sets = ((ccsidr & bitmask(27, 13)) >> 13) + 1;
+ associativity = ((ccsidr & bitmask(12, 3)) >> 3) + 1;
+ /* FIXME: do we need to use CTR.DminLine here? */
+ linesize_bytes = (1 << ((ccsidr & 0x7) + 2)) * 4;
+
+ dsb();
+
+ /*
+ * Set/way operations require an interesting bit packing. See section
+ * B4-35 in the ARMv7 Architecture Reference Manual:
+ *
+ * A: Log2(associativity)
+ * B: L+S
+ * L: Log2(linesize)
+ * S: Log2(num_sets)
+ *
+ * The bits are packed as follows:
+ * 31 31-A B B-1 L L-1 4 3 1 0
+ * |---|-------------|--------|-------|-----|-|
+ * |Way| zeros | Set | zeros |level|0|
+ * |---|-------------|--------|-------|-----|-|
+ */
+ for (way = 0; way < associativity; way++) {
+ for (set = 0; set < num_sets; set++) {
+ uint32_t val = 0;
+ val |= way << (32 - log2(associativity));
+ val |= set << log2(linesize_bytes);
+ val |= level << 1;
+ switch(op) {
+ case OP_DCCISW:
+ dccisw(val);
+ break;
+ case OP_DCISW:
+ dcisw(val);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ isb();
+}
+
+static void dcache_foreach(enum dcache_op op)
+{
+ uint32_t clidr;
+ int level;
+
+ clidr = read_clidr();
+ for (level = 0; level < 7; level++) {
+ unsigned int ctype = (clidr >> (level * 3)) & 0x7;
+ uint32_t csselr;
+
+ switch(ctype) {
+ case 0x2:
+ case 0x3:
+ case 0x4:
+ csselr = level << 1;
+ write_csselr(csselr);
+ dcache_op_set_way(op);
+ break;
+ default:
+ /* no cache, icache only, or reserved */
+ break;
+ }
+ }
+}
+
+void dcache_clean_invalidate_all(void)
+{
+ dcache_foreach(OP_DCCISW);
+}
+
+void dcache_invalidate_all(void)
+{
+ dcache_foreach(OP_DCISW);
+}
+
+static unsigned int line_bytes(void)
+{
+ uint32_t ccsidr;
+ unsigned int size;
+
+ ccsidr = read_ccsidr();
+ /* [2:0] - Indicates (Log2(number of words in cache line)) - 2 */
+ size = 1 << ((ccsidr & 0x7) + 2); /* words per line */
+ size *= sizeof(unsigned int); /* bytes per line */
+
+ return size;
+}
+
+/*
+ * Do a dcache operation by modified virtual address. This is useful for
+ * maintaining coherency in drivers which do DMA transfers and only need to
+ * perform cache maintenance on a particular memory range rather than the
+ * entire cache.
+ */
+static void dcache_op_mva(unsigned long addr,
+ unsigned long len, enum dcache_op op)
+{
+ unsigned long line, linesize;
+
+ linesize = line_bytes();
+ line = addr & ~(linesize - 1);
+
+ dsb();
+ while (line < addr + len) {
+ switch(op) {
+ case OP_DCCIMVAC:
+ dccimvac(line);
+ break;
+ default:
+ break;
+ }
+ line += linesize;
+ }
+ isb();
+}
+
+void dcache_clean_by_mva(unsigned long addr, unsigned long len)
+{
+ dcache_op_mva(addr, len, OP_DCCMVAC);
+}
+
+void dcache_clean_invalidate_by_mva(unsigned long addr, unsigned long len)
+{
+ dcache_op_mva(addr, len, OP_DCCIMVAC);
+}
+
+void dcache_mmu_disable(void)
+{
+ uint32_t sctlr;
+
+ dcache_clean_invalidate_all();
+ sctlr = read_sctlr();
+ sctlr &= ~(SCTLR_C | SCTLR_M);
+ write_sctlr(sctlr);
+}
+
+
+void dcache_mmu_enable(void)
+{
+ uint32_t sctlr;
+
+ sctlr = read_sctlr();
+ dcache_clean_invalidate_all();
+ sctlr |= SCTLR_C | SCTLR_M;
+ write_sctlr(sctlr);
+}
+
+void armv7_invalidate_caches(void)
+{
+ uint32_t clidr;
+ int level;
+
+ /* Invalidate branch predictor */
+ bpiall();
+
+ /* Iterate thru each cache identified in CLIDR and invalidate */
+ clidr = read_clidr();
+ for (level = 0; level < 7; level++) {
+ unsigned int ctype = (clidr >> (level * 3)) & 0x7;
+ uint32_t csselr;
+
+ switch(ctype) {
+ case 0x0:
+ /* no cache */
+ break;
+ case 0x1:
+ /* icache only */
+ csselr = (level << 1) | 1;
+ write_csselr(csselr);
+ icache_invalidate_all();
+ break;
+ case 0x2:
+ case 0x4:
+ /* dcache only or unified cache */
+ csselr = level << 1;
+ write_csselr(csselr);
+ dcache_invalidate_all();
+ break;
+ case 0x3:
+ /* separate icache and dcache */
+ csselr = (level << 1) | 1;
+ write_csselr(csselr);
+ icache_invalidate_all();
+
+ csselr = level << 1;
+ write_csselr(csselr);
+ dcache_invalidate_all();
+ break;
+ default:
+ /* reserved */
+ break;
+ }
+ }
+
+ /* Invalidate TLB */
+ tlb_invalidate_all();
+}
diff --git a/src/arch/armv7/div0.c b/src/arch/armv7/div0.c
new file mode 100644
index 0000000..ab06ad3
--- /dev/null
+++ b/src/arch/armv7/div0.c
@@ -0,0 +1,33 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <console/console.h>
+
+void __div0(void); // called from asm so no need for a prototype in a header
+
+/* Replacement (=dummy) for GNU/Linux division-by zero handler */
+/* recursion is ok here because we have no formats ... */
+void __div0 (void)
+{
+ printk(BIOS_EMERG, "DIVIDE BY ZERO! continuing ... \n");
+}
diff --git a/src/arch/armv7/eabi_compat.c b/src/arch/armv7/eabi_compat.c
new file mode 100644
index 0000000..c063c85
--- /dev/null
+++ b/src/arch/armv7/eabi_compat.c
@@ -0,0 +1,31 @@
+/*
+ * Utility functions needed for (some) EABI conformant tool chains.
+ *
+ * (C) Copyright 2009 Wolfgang Denk <wd at denx.de>
+ *
+ * This program is Free Software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <console/console.h>
+
+/* FIXME(dhendrix): prototypes added for assembler */
+int raise (int signum);
+int raise (int signum)
+{
+ printk(BIOS_CRIT, "raise: Signal # %d caught\n", signum);
+ return 0;
+}
+
+/* Dummy function to avoid linker complaints */
+void __aeabi_unwind_cpp_pr0(void);
+void __aeabi_unwind_cpp_pr0(void)
+{
+};
+
+void __aeabi_unwind_cpp_pr1(void);
+void __aeabi_unwind_cpp_pr1(void)
+{
+};
diff --git a/src/arch/armv7/early_console.c b/src/arch/armv7/early_console.c
new file mode 100644
index 0000000..68e81c6
--- /dev/null
+++ b/src/arch/armv7/early_console.c
@@ -0,0 +1,81 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <console/vtxprintf.h>
+
+/* FIXME: need to make console driver more generic */
+void console_tx_byte(unsigned char byte)
+{
+ if (byte == '\n')
+ console_tx_byte('\r');
+
+#if CONFIG_CONSOLE_SERIAL8250MEM
+ if (oxford_oxpcie_present) {
+ uart8250_mem_tx_byte(
+ CONFIG_OXFORD_OXPCIE_BASE_ADDRESS + 0x1000, byte);
+ }
+#endif
+#if CONFIG_CONSOLE_SERIAL8250
+ uart8250_tx_byte(CONFIG_TTYS0_BASE, byte);
+#endif
+#if CONFIG_CONSOLE_SERIAL_UART
+ uart_tx_byte(byte);
+#endif
+#if CONFIG_USBDEBUG
+ usbdebug_tx_byte(0, byte);
+#endif
+#if CONFIG_CONSOLE_CBMEM
+ cbmemc_tx_byte(byte);
+#endif
+}
+
+static void _console_tx_flush(void)
+{
+#if CONFIG_CONSOLE_SERIAL8250MEM
+ uart8250_mem_tx_flush(CONFIG_OXFORD_OXPCIE_BASE_ADDRESS + 0x1000);
+#endif
+#if CONFIG_CONSOLE_SERIAL8250
+ uart8250_tx_flush(CONFIG_TTYS0_BASE);
+#endif
+#if CONFIG_CONSOLE_SERIAL_UART
+ uart_tx_flush();
+#endif
+#if CONFIG_USBDEBUG
+ usbdebug_tx_flush(0);
+#endif
+}
+
+int do_printk(int msg_level, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ if (msg_level > console_loglevel) {
+ return 0;
+ }
+
+ va_start(args, fmt);
+ i = vtxprintf(console_tx_byte, fmt, args);
+ va_end(args);
+
+ _console_tx_flush();
+
+ return i;
+}
diff --git a/src/arch/armv7/id.inc b/src/arch/armv7/id.inc
new file mode 100644
index 0000000..ffe547d
--- /dev/null
+++ b/src/arch/armv7/id.inc
@@ -0,0 +1,18 @@
+ .section ".id", "a", %progbits
+
+ .globl __id_start
+__id_start:
+ver:
+ .asciz COREBOOT_VERSION
+vendor:
+ .asciz CONFIG_MAINBOARD_VENDOR
+part:
+ .asciz CONFIG_MAINBOARD_PART_NUMBER
+.long __id_end - ver /* Reverse offset to the vendor id */
+.long __id_end - vendor /* Reverse offset to the vendor id */
+.long __id_end - part /* Reverse offset to the part number */
+.long CONFIG_ROM_SIZE /* Size of this romimage */
+ .globl __id_end
+
+__id_end:
+.previous
diff --git a/src/arch/armv7/interrupts.c b/src/arch/armv7/interrupts.c
new file mode 100644
index 0000000..7508c69
--- /dev/null
+++ b/src/arch/armv7/interrupts.c
@@ -0,0 +1,197 @@
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger at sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu at sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <garyj at denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin at arm.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <reset.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_USE_IRQ
+int interrupt_init (void)
+{
+ /*
+ * setup up stacks if necessary
+ */
+ IRQ_STACK_START = gd->irq_sp - 4;
+ IRQ_STACK_START_IN = gd->irq_sp + 8;
+ FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
+
+ return arch_interrupt_init();
+}
+
+/* enable IRQ interrupts */
+void enable_interrupts (void)
+{
+ unsigned long temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "bic %0, %0, #0x80\n"
+ "msr cpsr_c, %0"
+ : "=r" (temp)
+ :
+ : "memory");
+}
+
+
+/*
+ * disable IRQ/FIQ interrupts
+ * returns true if interrupts had been enabled before we disabled them
+ */
+int disable_interrupts (void)
+{
+ unsigned long old,temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "orr %1, %0, #0xc0\n"
+ "msr cpsr_c, %1"
+ : "=r" (old), "=r" (temp)
+ :
+ : "memory");
+ return (old & 0x80) == 0;
+}
+#else
+int interrupt_init (void)
+{
+ /*
+ * setup up stacks if necessary
+ */
+ IRQ_STACK_START_IN = gd->irq_sp + 8;
+
+ return 0;
+}
+
+void enable_interrupts (void)
+{
+ return;
+}
+int disable_interrupts (void)
+{
+ return 0;
+}
+#endif
+
+
+void bad_mode (void)
+{
+ panic ("Resetting CPU ...\n");
+ soft_reset();
+}
+
+void show_regs (struct pt_regs *regs)
+{
+ unsigned long flags;
+ const char *processor_modes[] = {
+ "USER_26", "FIQ_26", "IRQ_26", "SVC_26",
+ "UK4_26", "UK5_26", "UK6_26", "UK7_26",
+ "UK8_26", "UK9_26", "UK10_26", "UK11_26",
+ "UK12_26", "UK13_26", "UK14_26", "UK15_26",
+ "USER_32", "FIQ_32", "IRQ_32", "SVC_32",
+ "UK4_32", "UK5_32", "UK6_32", "ABT_32",
+ "UK8_32", "UK9_32", "UK10_32", "UND_32",
+ "UK12_32", "UK13_32", "UK14_32", "SYS_32",
+ };
+
+ flags = condition_codes (regs);
+
+ printf ("pc : [<%08lx>] lr : [<%08lx>]\n"
+ "sp : %08lx ip : %08lx fp : %08lx\n",
+ instruction_pointer (regs),
+ regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+ printf ("r10: %08lx r9 : %08lx r8 : %08lx\n",
+ regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
+ printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
+ regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
+ printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
+ regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
+ printf ("Flags: %c%c%c%c",
+ flags & CC_N_BIT ? 'N' : 'n',
+ flags & CC_Z_BIT ? 'Z' : 'z',
+ flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
+ printf (" IRQs %s FIQs %s Mode %s%s\n",
+ interrupts_enabled (regs) ? "on" : "off",
+ fast_interrupts_enabled (regs) ? "on" : "off",
+ processor_modes[processor_mode (regs)],
+ thumb_mode (regs) ? " (T)" : "");
+}
+
+void do_undefined_instruction (struct pt_regs *pt_regs)
+{
+ printf ("undefined instruction\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_software_interrupt (struct pt_regs *pt_regs)
+{
+ printf ("software interrupt\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_prefetch_abort (struct pt_regs *pt_regs)
+{
+ printf ("prefetch abort\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_data_abort (struct pt_regs *pt_regs)
+{
+ printf ("data abort\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_not_used (struct pt_regs *pt_regs)
+{
+ printf ("not used\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+void do_fiq (struct pt_regs *pt_regs)
+{
+ printf ("fast interrupt request\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+
+#ifndef CONFIG_USE_IRQ
+void do_irq (struct pt_regs *pt_regs)
+{
+ printf ("interrupt request\n");
+ show_regs (pt_regs);
+ bad_mode ();
+}
+#endif
diff --git a/src/arch/armv7/lib/Makefile.inc b/src/arch/armv7/lib/Makefile.inc
deleted file mode 100644
index b10c1ab..0000000
--- a/src/arch/armv7/lib/Makefile.inc
+++ /dev/null
@@ -1,20 +0,0 @@
-#FIXME: cache_v7 and cache-cp15 will go away eventually
-
-bootblock-$(CONFIG_EARLY_CONSOLE) += early_console.c
-bootblock-y += cache.c
-
-romstage-y += cache.c
-romstage-y += div0.c
-romstage-$(CONFIG_EARLY_CONSOLE) += early_console.c
-
-ramstage-y += div0.c
-#ramstage-y += interrupts.c
-#ramstage-y += memcpy.S
-#ramstage-y += memset.S
-ramstage-y += cache.c
-ramstage-y += mmu.c
-
-#FIXME(dhendrix): should this be a config option?
-romstage-y += eabi_compat.c
-ramstage-y += eabi_compat.c
-bootblock-y += eabi_compat.c
diff --git a/src/arch/armv7/lib/cache.c b/src/arch/armv7/lib/cache.c
deleted file mode 100644
index 04eaa88..0000000
--- a/src/arch/armv7/lib/cache.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2013 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * cache.c: Cache maintenance routines for ARMv7-A and ARMv7-R
- *
- * Reference: ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition
- */
-
-#include <stdint.h>
-
-#include <arch/cache.h>
-
-#define bitmask(high, low) ((1UL << (high)) + \
- ((1UL << (high)) - 1) - ((1UL << (low)) - 1))
-
-/* Basic log2() implementation. Note: log2(0) is 0 for our purposes. */
-/* FIXME: src/include/lib.h is difficult to work with due to romcc */
-static unsigned long log2(unsigned long u)
-{
- int i = 0;
-
- while (u >>= 1)
- i++;
-
- return i;
-}
-
-void tlb_invalidate_all(void)
-{
- /*
- * FIXME: ARMv7 Architecture Ref. Manual claims that the distinction
- * instruction vs. data TLBs is deprecated in ARMv7, however this does
- * not seem to be the case as of Cortex-A15.
- */
- tlbiall();
- dtlbiall();
- itlbiall();
- isb();
- dsb();
-}
-
-void icache_invalidate_all(void)
-{
- /*
- * icache can be entirely invalidated with one operation.
- * Note: If branch predictors are architecturally-visible, ICIALLU
- * also performs a BPIALL operation (B2-1283 in arch manual)
- */
- iciallu();
- isb();
-}
-
-enum dcache_op {
- OP_DCCISW,
- OP_DCISW,
- OP_DCCIMVAC,
- OP_DCCMVAC,
-};
-
-/*
- * Do a dcache operation on entire cache by set/way. This is done for
- * portability because mapping of memory address to cache location is
- * implementation defined (See note on "Requirements for operations by
- * set/way" in arch ref. manual).
- */
-static void dcache_op_set_way(enum dcache_op op)
-{
- uint32_t ccsidr;
- unsigned int associativity, num_sets, linesize_bytes;
- unsigned int set, way;
- unsigned int level;
-
- level = (read_csselr() >> 1) & 0x7;
-
- /*
- * dcache must be invalidated by set/way for portability since virtual
- * memory mapping is system-defined. The number of sets and
- * associativity is given by CCSIDR. We'll use DCISW to invalidate the
- * dcache.
- */
- ccsidr = read_ccsidr();
-
- /* FIXME: rounding up required here? */
- num_sets = ((ccsidr & bitmask(27, 13)) >> 13) + 1;
- associativity = ((ccsidr & bitmask(12, 3)) >> 3) + 1;
- /* FIXME: do we need to use CTR.DminLine here? */
- linesize_bytes = (1 << ((ccsidr & 0x7) + 2)) * 4;
-
- dsb();
-
- /*
- * Set/way operations require an interesting bit packing. See section
- * B4-35 in the ARMv7 Architecture Reference Manual:
- *
- * A: Log2(associativity)
- * B: L+S
- * L: Log2(linesize)
- * S: Log2(num_sets)
- *
- * The bits are packed as follows:
- * 31 31-A B B-1 L L-1 4 3 1 0
- * |---|-------------|--------|-------|-----|-|
- * |Way| zeros | Set | zeros |level|0|
- * |---|-------------|--------|-------|-----|-|
- */
- for (way = 0; way < associativity; way++) {
- for (set = 0; set < num_sets; set++) {
- uint32_t val = 0;
- val |= way << (32 - log2(associativity));
- val |= set << log2(linesize_bytes);
- val |= level << 1;
- switch(op) {
- case OP_DCCISW:
- dccisw(val);
- break;
- case OP_DCISW:
- dcisw(val);
- break;
- default:
- break;
- }
- }
- }
- isb();
-}
-
-static void dcache_foreach(enum dcache_op op)
-{
- uint32_t clidr;
- int level;
-
- clidr = read_clidr();
- for (level = 0; level < 7; level++) {
- unsigned int ctype = (clidr >> (level * 3)) & 0x7;
- uint32_t csselr;
-
- switch(ctype) {
- case 0x2:
- case 0x3:
- case 0x4:
- csselr = level << 1;
- write_csselr(csselr);
- dcache_op_set_way(op);
- break;
- default:
- /* no cache, icache only, or reserved */
- break;
- }
- }
-}
-
-void dcache_clean_invalidate_all(void)
-{
- dcache_foreach(OP_DCCISW);
-}
-
-void dcache_invalidate_all(void)
-{
- dcache_foreach(OP_DCISW);
-}
-
-static unsigned int line_bytes(void)
-{
- uint32_t ccsidr;
- unsigned int size;
-
- ccsidr = read_ccsidr();
- /* [2:0] - Indicates (Log2(number of words in cache line)) - 2 */
- size = 1 << ((ccsidr & 0x7) + 2); /* words per line */
- size *= sizeof(unsigned int); /* bytes per line */
-
- return size;
-}
-
-/*
- * Do a dcache operation by modified virtual address. This is useful for
- * maintaining coherency in drivers which do DMA transfers and only need to
- * perform cache maintenance on a particular memory range rather than the
- * entire cache.
- */
-static void dcache_op_mva(unsigned long addr,
- unsigned long len, enum dcache_op op)
-{
- unsigned long line, linesize;
-
- linesize = line_bytes();
- line = addr & ~(linesize - 1);
-
- dsb();
- while (line < addr + len) {
- switch(op) {
- case OP_DCCIMVAC:
- dccimvac(line);
- break;
- default:
- break;
- }
- line += linesize;
- }
- isb();
-}
-
-void dcache_clean_by_mva(unsigned long addr, unsigned long len)
-{
- dcache_op_mva(addr, len, OP_DCCMVAC);
-}
-
-void dcache_clean_invalidate_by_mva(unsigned long addr, unsigned long len)
-{
- dcache_op_mva(addr, len, OP_DCCIMVAC);
-}
-
-void dcache_mmu_disable(void)
-{
- uint32_t sctlr;
-
- dcache_clean_invalidate_all();
- sctlr = read_sctlr();
- sctlr &= ~(SCTLR_C | SCTLR_M);
- write_sctlr(sctlr);
-}
-
-
-void dcache_mmu_enable(void)
-{
- uint32_t sctlr;
-
- sctlr = read_sctlr();
- dcache_clean_invalidate_all();
- sctlr |= SCTLR_C | SCTLR_M;
- write_sctlr(sctlr);
-}
-
-void armv7_invalidate_caches(void)
-{
- uint32_t clidr;
- int level;
-
- /* Invalidate branch predictor */
- bpiall();
-
- /* Iterate thru each cache identified in CLIDR and invalidate */
- clidr = read_clidr();
- for (level = 0; level < 7; level++) {
- unsigned int ctype = (clidr >> (level * 3)) & 0x7;
- uint32_t csselr;
-
- switch(ctype) {
- case 0x0:
- /* no cache */
- break;
- case 0x1:
- /* icache only */
- csselr = (level << 1) | 1;
- write_csselr(csselr);
- icache_invalidate_all();
- break;
- case 0x2:
- case 0x4:
- /* dcache only or unified cache */
- csselr = level << 1;
- write_csselr(csselr);
- dcache_invalidate_all();
- break;
- case 0x3:
- /* separate icache and dcache */
- csselr = (level << 1) | 1;
- write_csselr(csselr);
- icache_invalidate_all();
-
- csselr = level << 1;
- write_csselr(csselr);
- dcache_invalidate_all();
- break;
- default:
- /* reserved */
- break;
- }
- }
-
- /* Invalidate TLB */
- tlb_invalidate_all();
-}
diff --git a/src/arch/armv7/lib/div0.c b/src/arch/armv7/lib/div0.c
deleted file mode 100644
index ab06ad3..0000000
--- a/src/arch/armv7/lib/div0.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <console/console.h>
-
-void __div0(void); // called from asm so no need for a prototype in a header
-
-/* Replacement (=dummy) for GNU/Linux division-by zero handler */
-/* recursion is ok here because we have no formats ... */
-void __div0 (void)
-{
- printk(BIOS_EMERG, "DIVIDE BY ZERO! continuing ... \n");
-}
diff --git a/src/arch/armv7/lib/eabi_compat.c b/src/arch/armv7/lib/eabi_compat.c
deleted file mode 100644
index c063c85..0000000
--- a/src/arch/armv7/lib/eabi_compat.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Utility functions needed for (some) EABI conformant tool chains.
- *
- * (C) Copyright 2009 Wolfgang Denk <wd at denx.de>
- *
- * This program is Free Software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- */
-
-#include <console/console.h>
-
-/* FIXME(dhendrix): prototypes added for assembler */
-int raise (int signum);
-int raise (int signum)
-{
- printk(BIOS_CRIT, "raise: Signal # %d caught\n", signum);
- return 0;
-}
-
-/* Dummy function to avoid linker complaints */
-void __aeabi_unwind_cpp_pr0(void);
-void __aeabi_unwind_cpp_pr0(void)
-{
-};
-
-void __aeabi_unwind_cpp_pr1(void);
-void __aeabi_unwind_cpp_pr1(void)
-{
-};
diff --git a/src/arch/armv7/lib/early_console.c b/src/arch/armv7/lib/early_console.c
deleted file mode 100644
index 68e81c6..0000000
--- a/src/arch/armv7/lib/early_console.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-#include <console/console.h>
-#include <console/vtxprintf.h>
-
-/* FIXME: need to make console driver more generic */
-void console_tx_byte(unsigned char byte)
-{
- if (byte == '\n')
- console_tx_byte('\r');
-
-#if CONFIG_CONSOLE_SERIAL8250MEM
- if (oxford_oxpcie_present) {
- uart8250_mem_tx_byte(
- CONFIG_OXFORD_OXPCIE_BASE_ADDRESS + 0x1000, byte);
- }
-#endif
-#if CONFIG_CONSOLE_SERIAL8250
- uart8250_tx_byte(CONFIG_TTYS0_BASE, byte);
-#endif
-#if CONFIG_CONSOLE_SERIAL_UART
- uart_tx_byte(byte);
-#endif
-#if CONFIG_USBDEBUG
- usbdebug_tx_byte(0, byte);
-#endif
-#if CONFIG_CONSOLE_CBMEM
- cbmemc_tx_byte(byte);
-#endif
-}
-
-static void _console_tx_flush(void)
-{
-#if CONFIG_CONSOLE_SERIAL8250MEM
- uart8250_mem_tx_flush(CONFIG_OXFORD_OXPCIE_BASE_ADDRESS + 0x1000);
-#endif
-#if CONFIG_CONSOLE_SERIAL8250
- uart8250_tx_flush(CONFIG_TTYS0_BASE);
-#endif
-#if CONFIG_CONSOLE_SERIAL_UART
- uart_tx_flush();
-#endif
-#if CONFIG_USBDEBUG
- usbdebug_tx_flush(0);
-#endif
-}
-
-int do_printk(int msg_level, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- if (msg_level > console_loglevel) {
- return 0;
- }
-
- va_start(args, fmt);
- i = vtxprintf(console_tx_byte, fmt, args);
- va_end(args);
-
- _console_tx_flush();
-
- return i;
-}
diff --git a/src/arch/armv7/lib/id.inc b/src/arch/armv7/lib/id.inc
deleted file mode 100644
index ffe547d..0000000
--- a/src/arch/armv7/lib/id.inc
+++ /dev/null
@@ -1,18 +0,0 @@
- .section ".id", "a", %progbits
-
- .globl __id_start
-__id_start:
-ver:
- .asciz COREBOOT_VERSION
-vendor:
- .asciz CONFIG_MAINBOARD_VENDOR
-part:
- .asciz CONFIG_MAINBOARD_PART_NUMBER
-.long __id_end - ver /* Reverse offset to the vendor id */
-.long __id_end - vendor /* Reverse offset to the vendor id */
-.long __id_end - part /* Reverse offset to the part number */
-.long CONFIG_ROM_SIZE /* Size of this romimage */
- .globl __id_end
-
-__id_end:
-.previous
diff --git a/src/arch/armv7/lib/interrupts.c b/src/arch/armv7/lib/interrupts.c
deleted file mode 100644
index 7508c69..0000000
--- a/src/arch/armv7/lib/interrupts.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * (C) Copyright 2003
- * Texas Instruments <www.ti.com>
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger at sysgo.de>
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Alex Zuepke <azu at sysgo.de>
- *
- * (C) Copyright 2002-2004
- * Gary Jennejohn, DENX Software Engineering, <garyj at denx.de>
- *
- * (C) Copyright 2004
- * Philippe Robin, ARM Ltd. <philippe.robin at arm.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <reset.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#ifdef CONFIG_USE_IRQ
-int interrupt_init (void)
-{
- /*
- * setup up stacks if necessary
- */
- IRQ_STACK_START = gd->irq_sp - 4;
- IRQ_STACK_START_IN = gd->irq_sp + 8;
- FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
-
- return arch_interrupt_init();
-}
-
-/* enable IRQ interrupts */
-void enable_interrupts (void)
-{
- unsigned long temp;
- __asm__ __volatile__("mrs %0, cpsr\n"
- "bic %0, %0, #0x80\n"
- "msr cpsr_c, %0"
- : "=r" (temp)
- :
- : "memory");
-}
-
-
-/*
- * disable IRQ/FIQ interrupts
- * returns true if interrupts had been enabled before we disabled them
- */
-int disable_interrupts (void)
-{
- unsigned long old,temp;
- __asm__ __volatile__("mrs %0, cpsr\n"
- "orr %1, %0, #0xc0\n"
- "msr cpsr_c, %1"
- : "=r" (old), "=r" (temp)
- :
- : "memory");
- return (old & 0x80) == 0;
-}
-#else
-int interrupt_init (void)
-{
- /*
- * setup up stacks if necessary
- */
- IRQ_STACK_START_IN = gd->irq_sp + 8;
-
- return 0;
-}
-
-void enable_interrupts (void)
-{
- return;
-}
-int disable_interrupts (void)
-{
- return 0;
-}
-#endif
-
-
-void bad_mode (void)
-{
- panic ("Resetting CPU ...\n");
- soft_reset();
-}
-
-void show_regs (struct pt_regs *regs)
-{
- unsigned long flags;
- const char *processor_modes[] = {
- "USER_26", "FIQ_26", "IRQ_26", "SVC_26",
- "UK4_26", "UK5_26", "UK6_26", "UK7_26",
- "UK8_26", "UK9_26", "UK10_26", "UK11_26",
- "UK12_26", "UK13_26", "UK14_26", "UK15_26",
- "USER_32", "FIQ_32", "IRQ_32", "SVC_32",
- "UK4_32", "UK5_32", "UK6_32", "ABT_32",
- "UK8_32", "UK9_32", "UK10_32", "UND_32",
- "UK12_32", "UK13_32", "UK14_32", "SYS_32",
- };
-
- flags = condition_codes (regs);
-
- printf ("pc : [<%08lx>] lr : [<%08lx>]\n"
- "sp : %08lx ip : %08lx fp : %08lx\n",
- instruction_pointer (regs),
- regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
- printf ("r10: %08lx r9 : %08lx r8 : %08lx\n",
- regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
- printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
- regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
- printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
- regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
- printf ("Flags: %c%c%c%c",
- flags & CC_N_BIT ? 'N' : 'n',
- flags & CC_Z_BIT ? 'Z' : 'z',
- flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
- printf (" IRQs %s FIQs %s Mode %s%s\n",
- interrupts_enabled (regs) ? "on" : "off",
- fast_interrupts_enabled (regs) ? "on" : "off",
- processor_modes[processor_mode (regs)],
- thumb_mode (regs) ? " (T)" : "");
-}
-
-void do_undefined_instruction (struct pt_regs *pt_regs)
-{
- printf ("undefined instruction\n");
- show_regs (pt_regs);
- bad_mode ();
-}
-
-void do_software_interrupt (struct pt_regs *pt_regs)
-{
- printf ("software interrupt\n");
- show_regs (pt_regs);
- bad_mode ();
-}
-
-void do_prefetch_abort (struct pt_regs *pt_regs)
-{
- printf ("prefetch abort\n");
- show_regs (pt_regs);
- bad_mode ();
-}
-
-void do_data_abort (struct pt_regs *pt_regs)
-{
- printf ("data abort\n");
- show_regs (pt_regs);
- bad_mode ();
-}
-
-void do_not_used (struct pt_regs *pt_regs)
-{
- printf ("not used\n");
- show_regs (pt_regs);
- bad_mode ();
-}
-
-void do_fiq (struct pt_regs *pt_regs)
-{
- printf ("fast interrupt request\n");
- show_regs (pt_regs);
- bad_mode ();
-}
-
-#ifndef CONFIG_USE_IRQ
-void do_irq (struct pt_regs *pt_regs)
-{
- printf ("interrupt request\n");
- show_regs (pt_regs);
- bad_mode ();
-}
-#endif
diff --git a/src/arch/armv7/lib/memcpy.S b/src/arch/armv7/lib/memcpy.S
deleted file mode 100644
index f04113f..0000000
--- a/src/arch/armv7/lib/memcpy.S
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * linux/arch/arm/lib/memcpy.S
- *
- * Author: Nicolas Pitre
- * Created: Sep 28, 2005
- * Copyright: MontaVista Software, Inc.
- *
- * 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.
- */
-
-#include <assembler.h>
-
-#define W(instr) instr
-
-#define LDR1W_SHIFT 0
-#define STR1W_SHIFT 0
-
- .macro ldr1w ptr reg abort
- W(ldr) \reg, [\ptr], #4
- .endm
-
- .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
- ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
- .endm
-
- .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
- ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
- .endm
-
- .macro ldr1b ptr reg cond=al abort
- ldr\cond\()b \reg, [\ptr], #1
- .endm
-
- .macro str1w ptr reg abort
- W(str) \reg, [\ptr], #4
- .endm
-
- .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
- stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
- .endm
-
- .macro str1b ptr reg cond=al abort
- str\cond\()b \reg, [\ptr], #1
- .endm
-
- .macro enter reg1 reg2
- stmdb sp!, {r0, \reg1, \reg2}
- .endm
-
- .macro exit reg1 reg2
- ldmfd sp!, {r0, \reg1, \reg2}
- .endm
-
- .text
-
-/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
-
-.globl memcpy
-memcpy:
-
- cmp r0, r1
- moveq pc, lr
-
- enter r4, lr
-
- subs r2, r2, #4
- blt 8f
- ands ip, r0, #3
- PLD( pld [r1, #0] )
- bne 9f
- ands ip, r1, #3
- bne 10f
-
-1: subs r2, r2, #(28)
- stmfd sp!, {r5 - r8}
- blt 5f
-
- CALGN( ands ip, r0, #31 )
- CALGN( rsb r3, ip, #32 )
- CALGN( sbcnes r4, r3, r2 ) @ C is always set here
- CALGN( bcs 2f )
- CALGN( adr r4, 6f )
- CALGN( subs r2, r2, r3 ) @ C gets set
- CALGN( add pc, r4, ip )
-
- PLD( pld [r1, #0] )
-2: PLD( subs r2, r2, #96 )
- PLD( pld [r1, #28] )
- PLD( blt 4f )
- PLD( pld [r1, #60] )
- PLD( pld [r1, #92] )
-
-3: PLD( pld [r1, #124] )
-4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
- subs r2, r2, #32
- str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
- bge 3b
- PLD( cmn r2, #96 )
- PLD( bge 4b )
-
-5: ands ip, r2, #28
- rsb ip, ip, #32
-#if LDR1W_SHIFT > 0
- lsl ip, ip, #LDR1W_SHIFT
-#endif
- addne pc, pc, ip @ C is always clear here
- b 7f
-6:
- .rept (1 << LDR1W_SHIFT)
- W(nop)
- .endr
- ldr1w r1, r3, abort=20f
- ldr1w r1, r4, abort=20f
- ldr1w r1, r5, abort=20f
- ldr1w r1, r6, abort=20f
- ldr1w r1, r7, abort=20f
- ldr1w r1, r8, abort=20f
- ldr1w r1, lr, abort=20f
-
-#if LDR1W_SHIFT < STR1W_SHIFT
- lsl ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
-#elif LDR1W_SHIFT > STR1W_SHIFT
- lsr ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
-#endif
- add pc, pc, ip
- nop
- .rept (1 << STR1W_SHIFT)
- W(nop)
- .endr
- str1w r0, r3, abort=20f
- str1w r0, r4, abort=20f
- str1w r0, r5, abort=20f
- str1w r0, r6, abort=20f
- str1w r0, r7, abort=20f
- str1w r0, r8, abort=20f
- str1w r0, lr, abort=20f
-
- CALGN( bcs 2b )
-
-7: ldmfd sp!, {r5 - r8}
-
-8: movs r2, r2, lsl #31
- ldr1b r1, r3, ne, abort=21f
- ldr1b r1, r4, cs, abort=21f
- ldr1b r1, ip, cs, abort=21f
- str1b r0, r3, ne, abort=21f
- str1b r0, r4, cs, abort=21f
- str1b r0, ip, cs, abort=21f
-
- exit r4, pc
-
-9: rsb ip, ip, #4
- cmp ip, #2
- ldr1b r1, r3, gt, abort=21f
- ldr1b r1, r4, ge, abort=21f
- ldr1b r1, lr, abort=21f
- str1b r0, r3, gt, abort=21f
- str1b r0, r4, ge, abort=21f
- subs r2, r2, ip
- str1b r0, lr, abort=21f
- blt 8b
- ands ip, r1, #3
- beq 1b
-
-10: bic r1, r1, #3
- cmp ip, #2
- ldr1w r1, lr, abort=21f
- beq 17f
- bgt 18f
-
-
- .macro forward_copy_shift pull push
-
- subs r2, r2, #28
- blt 14f
-
- CALGN( ands ip, r0, #31 )
- CALGN( rsb ip, ip, #32 )
- CALGN( sbcnes r4, ip, r2 ) @ C is always set here
- CALGN( subcc r2, r2, ip )
- CALGN( bcc 15f )
-
-11: stmfd sp!, {r5 - r9}
-
- PLD( pld [r1, #0] )
- PLD( subs r2, r2, #96 )
- PLD( pld [r1, #28] )
- PLD( blt 13f )
- PLD( pld [r1, #60] )
- PLD( pld [r1, #92] )
-
-12: PLD( pld [r1, #124] )
-13: ldr4w r1, r4, r5, r6, r7, abort=19f
- mov r3, lr, pull #\pull
- subs r2, r2, #32
- ldr4w r1, r8, r9, ip, lr, abort=19f
- orr r3, r3, r4, push #\push
- mov r4, r4, pull #\pull
- orr r4, r4, r5, push #\push
- mov r5, r5, pull #\pull
- orr r5, r5, r6, push #\push
- mov r6, r6, pull #\pull
- orr r6, r6, r7, push #\push
- mov r7, r7, pull #\pull
- orr r7, r7, r8, push #\push
- mov r8, r8, pull #\pull
- orr r8, r8, r9, push #\push
- mov r9, r9, pull #\pull
- orr r9, r9, ip, push #\push
- mov ip, ip, pull #\pull
- orr ip, ip, lr, push #\push
- str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
- bge 12b
- PLD( cmn r2, #96 )
- PLD( bge 13b )
-
- ldmfd sp!, {r5 - r9}
-
-14: ands ip, r2, #28
- beq 16f
-
-15: mov r3, lr, pull #\pull
- ldr1w r1, lr, abort=21f
- subs ip, ip, #4
- orr r3, r3, lr, push #\push
- str1w r0, r3, abort=21f
- bgt 15b
- CALGN( cmp r2, #0 )
- CALGN( bge 11b )
-
-16: sub r1, r1, #(\push / 8)
- b 8b
-
- .endm
-
-
- forward_copy_shift pull=8 push=24
-
-17: forward_copy_shift pull=16 push=16
-
-18: forward_copy_shift pull=24 push=8
diff --git a/src/arch/armv7/lib/memset.S b/src/arch/armv7/lib/memset.S
deleted file mode 100644
index 3ea2721..0000000
--- a/src/arch/armv7/lib/memset.S
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * linux/arch/arm/lib/memset.S
- *
- * Copyright (C) 1995-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 version 2 as
- * published by the Free Software Foundation.
- *
- * ASM optimised string functions
- */
-#include <assembler.h>
-
- .text
- .align 5
- .word 0
-
-1: subs r2, r2, #4 @ 1 do we have enough
- blt 5f @ 1 bytes to align with?
- cmp r3, #2 @ 1
- strltb r1, [r0], #1 @ 1
- strleb r1, [r0], #1 @ 1
- strb r1, [r0], #1 @ 1
- add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
-/*
- * The pointer is now aligned and the length is adjusted. Try doing the
- * memset again.
- */
-
-.globl memset
-memset:
- ands r3, r0, #3 @ 1 unaligned?
- bne 1b @ 1
-/*
- * we know that the pointer in r0 is aligned to a word boundary.
- */
- orr r1, r1, r1, lsl #8
- orr r1, r1, r1, lsl #16
- mov r3, r1
- cmp r2, #16
- blt 4f
-
-#if ! CALGN(1)+0
-
-/*
- * We need an extra register for this loop - save the return address and
- * use the LR
- */
- str lr, [sp, #-4]!
- mov ip, r1
- mov lr, r1
-
-2: subs r2, r2, #64
- stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
- stmgeia r0!, {r1, r3, ip, lr}
- stmgeia r0!, {r1, r3, ip, lr}
- stmgeia r0!, {r1, r3, ip, lr}
- bgt 2b
- ldmeqfd sp!, {pc} @ Now <64 bytes to go.
-/*
- * No need to correct the count; we're only testing bits from now on
- */
- tst r2, #32
- stmneia r0!, {r1, r3, ip, lr}
- stmneia r0!, {r1, r3, ip, lr}
- tst r2, #16
- stmneia r0!, {r1, r3, ip, lr}
- ldr lr, [sp], #4
-
-#else
-
-/*
- * This version aligns the destination pointer in order to write
- * whole cache lines at once.
- */
-
- stmfd sp!, {r4-r7, lr}
- mov r4, r1
- mov r5, r1
- mov r6, r1
- mov r7, r1
- mov ip, r1
- mov lr, r1
-
- cmp r2, #96
- tstgt r0, #31
- ble 3f
-
- and ip, r0, #31
- rsb ip, ip, #32
- sub r2, r2, ip
- movs ip, ip, lsl #(32 - 4)
- stmcsia r0!, {r4, r5, r6, r7}
- stmmiia r0!, {r4, r5}
- tst ip, #(1 << 30)
- mov ip, r1
- strne r1, [r0], #4
-
-3: subs r2, r2, #64
- stmgeia r0!, {r1, r3-r7, ip, lr}
- stmgeia r0!, {r1, r3-r7, ip, lr}
- bgt 3b
- ldmeqfd sp!, {r4-r7, pc}
-
- tst r2, #32
- stmneia r0!, {r1, r3-r7, ip, lr}
- tst r2, #16
- stmneia r0!, {r4-r7}
- ldmfd sp!, {r4-r7, lr}
-
-#endif
-
-4: tst r2, #8
- stmneia r0!, {r1, r3}
- tst r2, #4
- strne r1, [r0], #4
-/*
- * When we get here, we've got less than 4 bytes to zero. We
- * may have an unaligned pointer as well.
- */
-5: tst r2, #2
- strneb r1, [r0], #1
- strneb r1, [r0], #1
- tst r2, #1
- strneb r1, [r0], #1
- mov pc, lr
diff --git a/src/arch/armv7/lib/mmu.c b/src/arch/armv7/lib/mmu.c
deleted file mode 100644
index 7d6d46a..0000000
--- a/src/arch/armv7/lib/mmu.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2013 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <cbmem.h>
-#include <console/console.h>
-
-#include <arch/cache.h>
-#include <arch/io.h>
-
-#define L1_TLB_ENTRIES 4096 /* 1 entry for each 1MB address space */
-
-static uintptr_t ttb_addr;
-
-void mmu_disable_range(unsigned long start_mb, unsigned long size_mb)
-{
- unsigned int i;
- uint32_t *ttb_entry = (uint32_t *)ttb_addr;
- printk(BIOS_DEBUG, "Disabling: 0x%08lx:0x%08lx\n",
- start_mb*MiB, start_mb*MiB + size_mb*MiB - 1);
-
- for (i = start_mb; i < start_mb + size_mb; i++)
- writel(0, &ttb_entry[i]);
-
- for (i = start_mb; i < start_mb + size_mb; i++) {
- dccmvac((uintptr_t)&ttb_entry[i]);
- tlbimvaa(i*MiB);
- }
-}
-
-void mmu_config_range(unsigned long start_mb, unsigned long size_mb,
- enum dcache_policy policy)
-{
- unsigned int i;
- uint32_t attr;
- uint32_t *ttb_entry = (uint32_t *)ttb_addr;
- const char *str = NULL;
-
- /*
- * Section entry bits:
- * 31:20 - section base address
- * 18 - 0 to indicate normal section (versus supersection)
- * 17 - nG, 0 to indicate page is global
- * 16 - S, 0 for non-shareable (?)
- * 15 - APX, 0 for full access
- * 14:12 - TEX, 0b000 for outer and inner write-back
- * 11:10 - AP, 0b11 for full access
- * 9 - P, ? (FIXME: not described or possibly obsolete?)
- * 8: 5 - Domain
- * 4 - XN, 1 to set execute-never (and also avoid prefetches)
- * 3 - C, 1 for cacheable
- * 2 - B, 1 for bufferable
- * 1: 0 - 0b10 to indicate section entry
- */
-
- switch(policy) {
- case DCACHE_OFF:
- /* XN set to avoid prefetches to uncached/unbuffered regions */
- attr = (0x3 << 10) | (1 << 4) | 0x2;
- str = "off";
- break;
- case DCACHE_WRITEBACK:
- attr = (0x3 << 10) | (1 << 3) | (1 << 2) | 0x2;
- str = "writeback";
- break;
- case DCACHE_WRITETHROUGH:
- attr = (0x3 << 10) | (1 << 3) | (1 << 2) | 0x2;
- str = "writethrough";
- break;
- default:
- printk(BIOS_ERR, "unknown dcache policy: %02x\n", policy);
- return;
- }
-
- printk(BIOS_DEBUG, "Setting dcache policy: 0x%08lx:0x%08lx [%s]\n",
- start_mb << 20, ((start_mb + size_mb) << 20) - 1, str);
-
- /* Write out page table entries. */
- for (i = start_mb; i < start_mb + size_mb; i++)
- writel((i << 20) | attr, &ttb_entry[i]);
-
- /* Flush the page table entries, and old translations from the TLB. */
- for (i = start_mb; i < start_mb + size_mb; i++) {
- dccmvac((uintptr_t)&ttb_entry[i]);
- tlbimvaa(i*MiB);
- }
-}
-
-void mmu_init(void)
-{
- unsigned int ttb_size;
- uint32_t ttbcr;
-
- /*
- * For coreboot's purposes, we will create a simple L1 page table
- * in RAM with 1MB section translation entries over the 4GB address
- * space.
- * (ref: section 10.2 and example 15-4 in Cortex-A series
- * programmer's guide)
- *
- * FIXME: TLB needs to be aligned to 16KB, but cbmem_add() aligns to
- * 512 bytes. So allocate some extra space in cbmem and fix-up the
- * pointer.
- */
- ttb_size = L1_TLB_ENTRIES * sizeof(uint32_t);
- ttb_addr = (uintptr_t)cbmem_add(CBMEM_ID_GDT, ttb_size + 16*KiB);
- ttb_addr = ALIGN(ttb_addr, 16*KiB);
- printk(BIOS_DEBUG, "Translation table is @ 0x%08x\n", ttb_addr);
-
- /*
- * Disable TTBR1 by setting TTBCR.N to 0b000, which means the TTBR0
- * table size is 16KB and has indices VA[31:20].
- *
- * ref: Arch Ref. Manual for ARMv7-A, B3.5.4,
- */
- ttbcr = read_ttbcr();
- ttbcr &= ~(0x3);
- write_ttbcr(ttbcr);
-
- /*
- * Translation table base 0 address is in bits 31:14-N, where N is given
- * by bits 2:0 in TTBCR (which we set to 0). All lower bits in this
- * register should be zero for coreboot.
- */
- write_ttbr0(ttb_addr);
-
- /* disable domain-level checking of permissions */
- write_dacr(~0);
-}
diff --git a/src/arch/armv7/memcpy.S b/src/arch/armv7/memcpy.S
new file mode 100644
index 0000000..f04113f
--- /dev/null
+++ b/src/arch/armv7/memcpy.S
@@ -0,0 +1,243 @@
+/*
+ * linux/arch/arm/lib/memcpy.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 28, 2005
+ * Copyright: MontaVista Software, Inc.
+ *
+ * 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.
+ */
+
+#include <assembler.h>
+
+#define W(instr) instr
+
+#define LDR1W_SHIFT 0
+#define STR1W_SHIFT 0
+
+ .macro ldr1w ptr reg abort
+ W(ldr) \reg, [\ptr], #4
+ .endm
+
+ .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
+ .endm
+
+ .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
+
+ .macro ldr1b ptr reg cond=al abort
+ ldr\cond\()b \reg, [\ptr], #1
+ .endm
+
+ .macro str1w ptr reg abort
+ W(str) \reg, [\ptr], #4
+ .endm
+
+ .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
+
+ .macro str1b ptr reg cond=al abort
+ str\cond\()b \reg, [\ptr], #1
+ .endm
+
+ .macro enter reg1 reg2
+ stmdb sp!, {r0, \reg1, \reg2}
+ .endm
+
+ .macro exit reg1 reg2
+ ldmfd sp!, {r0, \reg1, \reg2}
+ .endm
+
+ .text
+
+/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
+
+.globl memcpy
+memcpy:
+
+ cmp r0, r1
+ moveq pc, lr
+
+ enter r4, lr
+
+ subs r2, r2, #4
+ blt 8f
+ ands ip, r0, #3
+ PLD( pld [r1, #0] )
+ bne 9f
+ ands ip, r1, #3
+ bne 10f
+
+1: subs r2, r2, #(28)
+ stmfd sp!, {r5 - r8}
+ blt 5f
+
+ CALGN( ands ip, r0, #31 )
+ CALGN( rsb r3, ip, #32 )
+ CALGN( sbcnes r4, r3, r2 ) @ C is always set here
+ CALGN( bcs 2f )
+ CALGN( adr r4, 6f )
+ CALGN( subs r2, r2, r3 ) @ C gets set
+ CALGN( add pc, r4, ip )
+
+ PLD( pld [r1, #0] )
+2: PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #28] )
+ PLD( blt 4f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+3: PLD( pld [r1, #124] )
+4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ subs r2, r2, #32
+ str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ bge 3b
+ PLD( cmn r2, #96 )
+ PLD( bge 4b )
+
+5: ands ip, r2, #28
+ rsb ip, ip, #32
+#if LDR1W_SHIFT > 0
+ lsl ip, ip, #LDR1W_SHIFT
+#endif
+ addne pc, pc, ip @ C is always clear here
+ b 7f
+6:
+ .rept (1 << LDR1W_SHIFT)
+ W(nop)
+ .endr
+ ldr1w r1, r3, abort=20f
+ ldr1w r1, r4, abort=20f
+ ldr1w r1, r5, abort=20f
+ ldr1w r1, r6, abort=20f
+ ldr1w r1, r7, abort=20f
+ ldr1w r1, r8, abort=20f
+ ldr1w r1, lr, abort=20f
+
+#if LDR1W_SHIFT < STR1W_SHIFT
+ lsl ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
+#elif LDR1W_SHIFT > STR1W_SHIFT
+ lsr ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
+#endif
+ add pc, pc, ip
+ nop
+ .rept (1 << STR1W_SHIFT)
+ W(nop)
+ .endr
+ str1w r0, r3, abort=20f
+ str1w r0, r4, abort=20f
+ str1w r0, r5, abort=20f
+ str1w r0, r6, abort=20f
+ str1w r0, r7, abort=20f
+ str1w r0, r8, abort=20f
+ str1w r0, lr, abort=20f
+
+ CALGN( bcs 2b )
+
+7: ldmfd sp!, {r5 - r8}
+
+8: movs r2, r2, lsl #31
+ ldr1b r1, r3, ne, abort=21f
+ ldr1b r1, r4, cs, abort=21f
+ ldr1b r1, ip, cs, abort=21f
+ str1b r0, r3, ne, abort=21f
+ str1b r0, r4, cs, abort=21f
+ str1b r0, ip, cs, abort=21f
+
+ exit r4, pc
+
+9: rsb ip, ip, #4
+ cmp ip, #2
+ ldr1b r1, r3, gt, abort=21f
+ ldr1b r1, r4, ge, abort=21f
+ ldr1b r1, lr, abort=21f
+ str1b r0, r3, gt, abort=21f
+ str1b r0, r4, ge, abort=21f
+ subs r2, r2, ip
+ str1b r0, lr, abort=21f
+ blt 8b
+ ands ip, r1, #3
+ beq 1b
+
+10: bic r1, r1, #3
+ cmp ip, #2
+ ldr1w r1, lr, abort=21f
+ beq 17f
+ bgt 18f
+
+
+ .macro forward_copy_shift pull push
+
+ subs r2, r2, #28
+ blt 14f
+
+ CALGN( ands ip, r0, #31 )
+ CALGN( rsb ip, ip, #32 )
+ CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( subcc r2, r2, ip )
+ CALGN( bcc 15f )
+
+11: stmfd sp!, {r5 - r9}
+
+ PLD( pld [r1, #0] )
+ PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #28] )
+ PLD( blt 13f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+12: PLD( pld [r1, #124] )
+13: ldr4w r1, r4, r5, r6, r7, abort=19f
+ mov r3, lr, pull #\pull
+ subs r2, r2, #32
+ ldr4w r1, r8, r9, ip, lr, abort=19f
+ orr r3, r3, r4, push #\push
+ mov r4, r4, pull #\pull
+ orr r4, r4, r5, push #\push
+ mov r5, r5, pull #\pull
+ orr r5, r5, r6, push #\push
+ mov r6, r6, pull #\pull
+ orr r6, r6, r7, push #\push
+ mov r7, r7, pull #\pull
+ orr r7, r7, r8, push #\push
+ mov r8, r8, pull #\pull
+ orr r8, r8, r9, push #\push
+ mov r9, r9, pull #\pull
+ orr r9, r9, ip, push #\push
+ mov ip, ip, pull #\pull
+ orr ip, ip, lr, push #\push
+ str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
+ bge 12b
+ PLD( cmn r2, #96 )
+ PLD( bge 13b )
+
+ ldmfd sp!, {r5 - r9}
+
+14: ands ip, r2, #28
+ beq 16f
+
+15: mov r3, lr, pull #\pull
+ ldr1w r1, lr, abort=21f
+ subs ip, ip, #4
+ orr r3, r3, lr, push #\push
+ str1w r0, r3, abort=21f
+ bgt 15b
+ CALGN( cmp r2, #0 )
+ CALGN( bge 11b )
+
+16: sub r1, r1, #(\push / 8)
+ b 8b
+
+ .endm
+
+
+ forward_copy_shift pull=8 push=24
+
+17: forward_copy_shift pull=16 push=16
+
+18: forward_copy_shift pull=24 push=8
diff --git a/src/arch/armv7/memset.S b/src/arch/armv7/memset.S
new file mode 100644
index 0000000..3ea2721
--- /dev/null
+++ b/src/arch/armv7/memset.S
@@ -0,0 +1,126 @@
+/*
+ * linux/arch/arm/lib/memset.S
+ *
+ * Copyright (C) 1995-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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ASM optimised string functions
+ */
+#include <assembler.h>
+
+ .text
+ .align 5
+ .word 0
+
+1: subs r2, r2, #4 @ 1 do we have enough
+ blt 5f @ 1 bytes to align with?
+ cmp r3, #2 @ 1
+ strltb r1, [r0], #1 @ 1
+ strleb r1, [r0], #1 @ 1
+ strb r1, [r0], #1 @ 1
+ add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted. Try doing the
+ * memset again.
+ */
+
+.globl memset
+memset:
+ ands r3, r0, #3 @ 1 unaligned?
+ bne 1b @ 1
+/*
+ * we know that the pointer in r0 is aligned to a word boundary.
+ */
+ orr r1, r1, r1, lsl #8
+ orr r1, r1, r1, lsl #16
+ mov r3, r1
+ cmp r2, #16
+ blt 4f
+
+#if ! CALGN(1)+0
+
+/*
+ * We need an extra register for this loop - save the return address and
+ * use the LR
+ */
+ str lr, [sp, #-4]!
+ mov ip, r1
+ mov lr, r1
+
+2: subs r2, r2, #64
+ stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
+ stmgeia r0!, {r1, r3, ip, lr}
+ stmgeia r0!, {r1, r3, ip, lr}
+ stmgeia r0!, {r1, r3, ip, lr}
+ bgt 2b
+ ldmeqfd sp!, {pc} @ Now <64 bytes to go.
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+ tst r2, #32
+ stmneia r0!, {r1, r3, ip, lr}
+ stmneia r0!, {r1, r3, ip, lr}
+ tst r2, #16
+ stmneia r0!, {r1, r3, ip, lr}
+ ldr lr, [sp], #4
+
+#else
+
+/*
+ * This version aligns the destination pointer in order to write
+ * whole cache lines at once.
+ */
+
+ stmfd sp!, {r4-r7, lr}
+ mov r4, r1
+ mov r5, r1
+ mov r6, r1
+ mov r7, r1
+ mov ip, r1
+ mov lr, r1
+
+ cmp r2, #96
+ tstgt r0, #31
+ ble 3f
+
+ and ip, r0, #31
+ rsb ip, ip, #32
+ sub r2, r2, ip
+ movs ip, ip, lsl #(32 - 4)
+ stmcsia r0!, {r4, r5, r6, r7}
+ stmmiia r0!, {r4, r5}
+ tst ip, #(1 << 30)
+ mov ip, r1
+ strne r1, [r0], #4
+
+3: subs r2, r2, #64
+ stmgeia r0!, {r1, r3-r7, ip, lr}
+ stmgeia r0!, {r1, r3-r7, ip, lr}
+ bgt 3b
+ ldmeqfd sp!, {r4-r7, pc}
+
+ tst r2, #32
+ stmneia r0!, {r1, r3-r7, ip, lr}
+ tst r2, #16
+ stmneia r0!, {r4-r7}
+ ldmfd sp!, {r4-r7, lr}
+
+#endif
+
+4: tst r2, #8
+ stmneia r0!, {r1, r3}
+ tst r2, #4
+ strne r1, [r0], #4
+/*
+ * When we get here, we've got less than 4 bytes to zero. We
+ * may have an unaligned pointer as well.
+ */
+5: tst r2, #2
+ strneb r1, [r0], #1
+ strneb r1, [r0], #1
+ tst r2, #1
+ strneb r1, [r0], #1
+ mov pc, lr
diff --git a/src/arch/armv7/mmu.c b/src/arch/armv7/mmu.c
new file mode 100644
index 0000000..7d6d46a
--- /dev/null
+++ b/src/arch/armv7/mmu.c
@@ -0,0 +1,157 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <cbmem.h>
+#include <console/console.h>
+
+#include <arch/cache.h>
+#include <arch/io.h>
+
+#define L1_TLB_ENTRIES 4096 /* 1 entry for each 1MB address space */
+
+static uintptr_t ttb_addr;
+
+void mmu_disable_range(unsigned long start_mb, unsigned long size_mb)
+{
+ unsigned int i;
+ uint32_t *ttb_entry = (uint32_t *)ttb_addr;
+ printk(BIOS_DEBUG, "Disabling: 0x%08lx:0x%08lx\n",
+ start_mb*MiB, start_mb*MiB + size_mb*MiB - 1);
+
+ for (i = start_mb; i < start_mb + size_mb; i++)
+ writel(0, &ttb_entry[i]);
+
+ for (i = start_mb; i < start_mb + size_mb; i++) {
+ dccmvac((uintptr_t)&ttb_entry[i]);
+ tlbimvaa(i*MiB);
+ }
+}
+
+void mmu_config_range(unsigned long start_mb, unsigned long size_mb,
+ enum dcache_policy policy)
+{
+ unsigned int i;
+ uint32_t attr;
+ uint32_t *ttb_entry = (uint32_t *)ttb_addr;
+ const char *str = NULL;
+
+ /*
+ * Section entry bits:
+ * 31:20 - section base address
+ * 18 - 0 to indicate normal section (versus supersection)
+ * 17 - nG, 0 to indicate page is global
+ * 16 - S, 0 for non-shareable (?)
+ * 15 - APX, 0 for full access
+ * 14:12 - TEX, 0b000 for outer and inner write-back
+ * 11:10 - AP, 0b11 for full access
+ * 9 - P, ? (FIXME: not described or possibly obsolete?)
+ * 8: 5 - Domain
+ * 4 - XN, 1 to set execute-never (and also avoid prefetches)
+ * 3 - C, 1 for cacheable
+ * 2 - B, 1 for bufferable
+ * 1: 0 - 0b10 to indicate section entry
+ */
+
+ switch(policy) {
+ case DCACHE_OFF:
+ /* XN set to avoid prefetches to uncached/unbuffered regions */
+ attr = (0x3 << 10) | (1 << 4) | 0x2;
+ str = "off";
+ break;
+ case DCACHE_WRITEBACK:
+ attr = (0x3 << 10) | (1 << 3) | (1 << 2) | 0x2;
+ str = "writeback";
+ break;
+ case DCACHE_WRITETHROUGH:
+ attr = (0x3 << 10) | (1 << 3) | (1 << 2) | 0x2;
+ str = "writethrough";
+ break;
+ default:
+ printk(BIOS_ERR, "unknown dcache policy: %02x\n", policy);
+ return;
+ }
+
+ printk(BIOS_DEBUG, "Setting dcache policy: 0x%08lx:0x%08lx [%s]\n",
+ start_mb << 20, ((start_mb + size_mb) << 20) - 1, str);
+
+ /* Write out page table entries. */
+ for (i = start_mb; i < start_mb + size_mb; i++)
+ writel((i << 20) | attr, &ttb_entry[i]);
+
+ /* Flush the page table entries, and old translations from the TLB. */
+ for (i = start_mb; i < start_mb + size_mb; i++) {
+ dccmvac((uintptr_t)&ttb_entry[i]);
+ tlbimvaa(i*MiB);
+ }
+}
+
+void mmu_init(void)
+{
+ unsigned int ttb_size;
+ uint32_t ttbcr;
+
+ /*
+ * For coreboot's purposes, we will create a simple L1 page table
+ * in RAM with 1MB section translation entries over the 4GB address
+ * space.
+ * (ref: section 10.2 and example 15-4 in Cortex-A series
+ * programmer's guide)
+ *
+ * FIXME: TLB needs to be aligned to 16KB, but cbmem_add() aligns to
+ * 512 bytes. So allocate some extra space in cbmem and fix-up the
+ * pointer.
+ */
+ ttb_size = L1_TLB_ENTRIES * sizeof(uint32_t);
+ ttb_addr = (uintptr_t)cbmem_add(CBMEM_ID_GDT, ttb_size + 16*KiB);
+ ttb_addr = ALIGN(ttb_addr, 16*KiB);
+ printk(BIOS_DEBUG, "Translation table is @ 0x%08x\n", ttb_addr);
+
+ /*
+ * Disable TTBR1 by setting TTBCR.N to 0b000, which means the TTBR0
+ * table size is 16KB and has indices VA[31:20].
+ *
+ * ref: Arch Ref. Manual for ARMv7-A, B3.5.4,
+ */
+ ttbcr = read_ttbcr();
+ ttbcr &= ~(0x3);
+ write_ttbcr(ttbcr);
+
+ /*
+ * Translation table base 0 address is in bits 31:14-N, where N is given
+ * by bits 2:0 in TTBCR (which we set to 0). All lower bits in this
+ * register should be zero for coreboot.
+ */
+ write_ttbr0(ttb_addr);
+
+ /* disable domain-level checking of permissions */
+ write_dacr(~0);
+}
diff --git a/src/arch/armv7/tables.c b/src/arch/armv7/tables.c
new file mode 100644
index 0000000..0fc7399
--- /dev/null
+++ b/src/arch/armv7/tables.c
@@ -0,0 +1,79 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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)
+
+/*
+ * TODO: "High" tables are a convention used on x86. Maybe we can
+ * clean up that naming at some point.
+ */
+uint64_t high_tables_base = 0;
+uint64_t high_tables_size;
+
+void cbmem_arch_init(void)
+{
+}
+
+struct lb_memory *write_tables(void)
+{
+ unsigned long table_pointer, new_table_pointer;
+
+ if (!high_tables_base) {
+ printk(BIOS_ERR, "ERROR: high_tables_base is not set.\n");
+ }
+
+ printk(BIOS_DEBUG, "high_tables_base: %llx.\n", high_tables_base);
+
+ 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 NULL;
+ }
+
+ 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();
+
+ return get_lb_mem();
+}
More information about the coreboot-gerrit
mailing list