Kyösti Mälkki (kyosti.malkki(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7104
-gerrit
commit a1458416041a96b44d995fbd3be7164d603b9210
Author: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Date: Fri Oct 17 16:44:48 2014 +0300
asus/m5a88-v: Fix southbridge init
This amdfam10 board was by mistake modified with commit
b6f3da4 AGESA CIMx: Move late init out of get_bus_conf()
Change-Id: I8edf6f7f4cc635d31e7e485e3f6de57ef8ed7b1e
Signed-off-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
---
src/mainboard/asus/m5a88-v/get_bus_conf.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/mainboard/asus/m5a88-v/get_bus_conf.c b/src/mainboard/asus/m5a88-v/get_bus_conf.c
index 3a9133c..f90c6b8 100644
--- a/src/mainboard/asus/m5a88-v/get_bus_conf.c
+++ b/src/mainboard/asus/m5a88-v/get_bus_conf.c
@@ -27,6 +27,9 @@
#include <cpu/amd/multicore.h>
#endif
#include <cpu/amd/amdfam10_sysconf.h>
+#if CONFIG_AMD_SB_CIMX
+#include <sb_cimx.h>
+#endif
/* Global variables for MB layouts and these will be shared by irqtable mptable
* and acpi_tables busnum is default.
@@ -132,4 +135,7 @@ void get_bus_conf(void)
#endif
apicid_sb800 = apicid_base + 0;
+#if CONFIG_AMD_SB_CIMX
+ sb_Late_Post();
+#endif
}
Nicolas Reinecke (nr(a)das-labor.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7103
-gerrit
commit 2e0545c9a93ebeafca881101c716788c85ad0e07
Author: Nicolas Reinecke <nr(a)das-labor.org>
Date: Fri Oct 17 15:13:44 2014 +0200
lenovo/t520: fix board info
Change-Id: Ieeefbe4617ea6c131236d8c94e9990f7b797192b
Signed-off-by: Nicolas Reinecke <nr(a)das-labor.org>
---
src/mainboard/lenovo/t520/board_info.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/mainboard/lenovo/t520/board_info.txt b/src/mainboard/lenovo/t520/board_info.txt
index 8d44122..d48aa5f 100644
--- a/src/mainboard/lenovo/t520/board_info.txt
+++ b/src/mainboard/lenovo/t520/board_info.txt
@@ -1,6 +1,6 @@
Category: laptop
Board name: T520
-ROM package: SOIC-8
+ROM package: WSON-8
ROM protocol: SPI
ROM socketed: n
-Flashrom support: y
+Flashrom support: n
Nicolas Reinecke (nr(a)das-labor.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7102
-gerrit
commit d786f4a0a56c335b280c0f1847abf1cbda59f08e
Author: Nicolas Reinecke <nr(a)das-labor.org>
Date: Fri Oct 17 15:09:05 2014 +0200
lenovo/t520: Apply ME workaround for S3 resume
Without this patch the laptop powers down after resume.
Change-Id: Ic6486fd4c4cc55b1ac5695f9d6d83fc2193b7eba
Signed-off-by: Nicolas Reinecke <nr(a)das-labor.org>
---
src/mainboard/lenovo/t520/acpi/platform.asl | 6 +++++-
src/mainboard/lenovo/t520/dsdt.asl | 1 +
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/mainboard/lenovo/t520/acpi/platform.asl b/src/mainboard/lenovo/t520/acpi/platform.asl
index 5466bed..f937dc5 100644
--- a/src/mainboard/lenovo/t520/acpi/platform.asl
+++ b/src/mainboard/lenovo/t520/acpi/platform.asl
@@ -68,6 +68,10 @@ Method(_PTS,1)
Method(_WAK,1)
{
- /* Not implemented. */
+ /* ME may not be up yet. */
+ Store (0, \_TZ.MEB1)
+ Store (0, \_TZ.MEB2)
+
+ /* Not implemented. */
Return(Package(){0,0})
}
diff --git a/src/mainboard/lenovo/t520/dsdt.asl b/src/mainboard/lenovo/t520/dsdt.asl
index e48a590..b6b4b33 100644
--- a/src/mainboard/lenovo/t520/dsdt.asl
+++ b/src/mainboard/lenovo/t520/dsdt.asl
@@ -24,6 +24,7 @@
#define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.LCD0.DECB
#define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0
#define RP04_IS_EXPRESSCARD 1
+#define EC_LENOVO_H8_ME_WORKAROUND 1
#define HAVE_LCD_SCREEN 1
DefinitionBlock(
Idwer Vollering (vidwer(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7081
-gerrit
commit 57dd06cf48026ef7253b740b36d83d0213330273
Author: Paul Menzel <paulepanter(a)users.sourceforge.net>
Date: Fri Oct 17 09:49:14 2014 +0200
util/board_status: Create the build directory before populating it
Running util/board_status/board_status.sh fails when the output directory build/ does not exist.
Ensure that the directory build exists, before copying the cbfstool binary into it.
Change-Id: I44155a0ca1eccc7b447b88ffaf6f3591b87fbad0
Signed-off-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
---
util/board_status/board_status.sh | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/util/board_status/board_status.sh b/util/board_status/board_status.sh
index 49d2c73..c5cb071 100755
--- a/util/board_status/board_status.sh
+++ b/util/board_status/board_status.sh
@@ -215,9 +215,10 @@ tmpdir=$(mktemp -d --tmpdir coreboot_board_status.XXXXXXXX)
# Obtain board and revision info to form the directory structure:
# <vendor>/<board>/<revision>/<timestamp>
-cbfstool_cmd="build/cbfstool"
-if test ! -x build/cbfstool; then
- make -C util/cbfstool/ && cp util/cbfstool/cbfstool build/cbfstool
+cbfstool_cmd="util/cbfstool/cbfstool"
+if test ! -x cbfstool_cmd; then
+ mkdir -p build
+ make -C util/cbfstool/
fi
test_cmd $LOCAL "$cbfstool_cmd"
$cbfstool_cmd build/coreboot.rom extract -n config -f ${tmpdir}/config.txt
Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7065
-gerrit
commit 4ab4a64e265a2311f2c27e94f1de4e9733fc784f
Author: Ronald G. Minnich <rminnich(a)gmail.com>
Date: Thu Oct 16 10:49:52 2014 +0000
RISCV: initial pass
It lives.
Script started on Fri Oct 17 11:15:01 2014
root@419e0b3bdb44:~/projects/coreboot# spike -d build/coreboot.rom
: rs 100000
coreboot-4.0-7036-g0be28e2 Fri Oct 17 10:55:46 UTC 2014 starting...
Script done on Fri Oct 17 11:15:11 2014
This is now getting into the bootblock. The sp setting
is a hack but we'll run with it for now.
Compilation started at Thu Oct 16 13:16:33
make -k
make: -ffunction-sections: Command not found
CC mainboard/emulation/qemu-riscv/media.ramstage.o
CC cbfs/fallback/ramstage.debug
OBJCOPY cbfs/fallback/ramstage.elf
CBFS coreboot.rom
PAYLOAD none (as specified by user)
CONFIG .config
CBFSPRINT coreboot.rom
coreboot.rom: 16384 kB, bootblocksize 56, romsize 16777216, offset 0x110000
alignment: 64 bytes, architecture: riscv
Name Offset Type Size
fallback/romstage 0x110000 stage 44
fallback/ramstage 0x110080 stage 51968
config 0x11cbc0 raw 1930
(empty) 0x11d380 null 15608856
with this command it boots:
riscv-objcopy --set-section-flags .data=code --adjust-vma 0x2000 -I binary -O elf64-littleriscv build/coreboot.rom -B riscv xzc
riscv-spike xzc
Change-Id: Ie06c63db252babf4fd4b3df00fff8f5fdfc81c12
Signed-off-by: Ronald G. Minnich <rminnich(a)gmail.com>
---
Makefile.inc | 5 +-
src/Kconfig | 16 +
src/arch/riscv/Kconfig | 26 +
src/arch/riscv/LICENSE | 24 +
src/arch/riscv/Makefile.inc | 119 ++++
src/arch/riscv/boot.c | 28 +
src/arch/riscv/bootblock.S | 91 +++
src/arch/riscv/bootblock.ld | 58 ++
src/arch/riscv/bootblock_simple.c | 73 +++
src/arch/riscv/cbmem.c | 30 +
src/arch/riscv/id.lds | 6 +
src/arch/riscv/include/arch/atomic.h | 75 +++
src/arch/riscv/include/arch/byteorder.h | 27 +
src/arch/riscv/include/arch/cpu.h | 53 ++
src/arch/riscv/include/arch/early_variables.h | 35 ++
src/arch/riscv/include/arch/encoding.h | 727 ++++++++++++++++++++++
src/arch/riscv/include/arch/exception.h | 39 ++
src/arch/riscv/include/arch/hlt.h | 6 +
src/arch/riscv/include/arch/io.h | 35 ++
src/arch/riscv/include/arch/stages.h | 29 +
src/arch/riscv/include/bootblock_common.h | 16 +
src/arch/riscv/include/stdint.h | 60 ++
src/arch/riscv/misc.c | 9 +
src/arch/riscv/prologue.inc | 22 +
src/arch/riscv/ramstage.ld | 136 ++++
src/arch/riscv/rom_media.c | 93 +++
src/arch/riscv/romstage.ld | 54 ++
src/arch/riscv/stages.c | 52 ++
src/arch/riscv/tables.c | 93 +++
src/console/Kconfig | 2 +-
src/lib/Makefile.inc | 2 +-
src/mainboard/emulation/Kconfig | 4 +
src/mainboard/emulation/qemu-riscv/Kconfig | 93 +++
src/mainboard/emulation/qemu-riscv/Makefile.inc | 20 +
src/mainboard/emulation/qemu-riscv/board_info.txt | 2 +
src/mainboard/emulation/qemu-riscv/bootblock.c | 56 ++
src/mainboard/emulation/qemu-riscv/devicetree.cb | 19 +
src/mainboard/emulation/qemu-riscv/frontend.c | 32 +
src/mainboard/emulation/qemu-riscv/frontend.h | 8 +
src/mainboard/emulation/qemu-riscv/mainboard.c | 26 +
src/mainboard/emulation/qemu-riscv/media.c | 74 +++
src/mainboard/emulation/qemu-riscv/romstage.c | 29 +
src/mainboard/emulation/qemu-riscv/uart.c | 64 ++
src/soc/Kconfig | 1 +
src/soc/Makefile.inc | 1 +
src/soc/ucb/Kconfig | 1 +
src/soc/ucb/Makefile.inc | 1 +
src/soc/ucb/riscv/Kconfig | 69 ++
toolchain.inc | 1 +
49 files changed, 2539 insertions(+), 3 deletions(-)
diff --git a/Makefile.inc b/Makefile.inc
index daf4cf4..f1ee12b 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -68,7 +68,7 @@ PHONY+= clean-abuild coreboot lint lint-stable build-dirs
subdirs-y := src/lib src/console src/device src/ec src/southbridge src/soc
subdirs-y += src/northbridge src/superio src/drivers src/cpu src/vendorcode
subdirs-y += util/cbfstool util/sconfig util/nvramtool
-subdirs-y += src/arch/arm src/arch/arm64 src/arch/x86
+subdirs-y += src/arch/arm src/arch/arm64 src/arch/x86 src/arch/riscv
subdirs-y += src/mainboard/$(MAINBOARDDIR)
subdirs-y += site-local
@@ -571,6 +571,9 @@ endif
ifeq ($(CONFIG_ARCH_ROMSTAGE_ARM64),y)
ROMSTAGE_ELF := romstage.elf
endif
+ifeq ($(CONFIG_ARCH_ROMSTAGE_RISCV),y)
+ROMSTAGE_ELF := romstage.elf
+endif
ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32),y)
ROMSTAGE_ELF := romstage_xip.elf
endif
diff --git a/src/Kconfig b/src/Kconfig
index c08fd27..6a105a5 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -218,9 +218,14 @@ config ARCH_ARM64
bool
default n
+config ARCH_RISCV
+ bool
+ default n
+
source src/arch/x86/Kconfig
source src/arch/arm/Kconfig
source src/arch/arm64/Kconfig
+source src/arch/riscv/Kconfig
source src/vendorcode/Kconfig
@@ -442,6 +447,8 @@ config HAVE_ACPI_TABLES
help
This variable specifies whether a given board has ACPI table support.
It is usually set in mainboard/*/Kconfig.
+ Whether or not the ACPI tables are actually generated by coreboot
+ is configurable by the user via GENERATE_ACPI_TABLES.
config HAVE_MP_TABLE
bool
@@ -479,6 +486,15 @@ config PER_DEVICE_ACPI_TABLES
menu "System tables"
+config GENERATE_ACPI_TABLES
+ prompt "Generate ACPI tables" if HAVE_ACPI_TABLES
+ bool
+ default HAVE_ACPI_TABLES
+ help
+ Generate ACPI tables for this board.
+
+ If unsure, say Y.
+
config GENERATE_MP_TABLE
prompt "Generate an MP table" if HAVE_MP_TABLE || DRIVERS_GENERIC_IOAPIC
bool
diff --git a/src/arch/riscv/Kconfig b/src/arch/riscv/Kconfig
new file mode 100644
index 0000000..120203d
--- /dev/null
+++ b/src/arch/riscv/Kconfig
@@ -0,0 +1,26 @@
+config ARCH_BOOTBLOCK_RISCV
+ bool
+ default n
+ select ARCH_RISCV
+
+config ARCH_ROMSTAGE_RISCV
+ bool
+ default n
+
+config ARCH_RAMSTAGE_RISCV
+ bool
+ default n
+
+# If a custom bootblock is necessary, this option should be "select"-ed by
+# the thing that needs it, probably the CPU.
+config RISCV_BOOTBLOCK_CUSTOM
+ bool
+ default n
+
+config CPU_HAS_BOOTBLOCK_INIT
+ bool
+ default n
+
+config MAINBOARD_HAS_BOOTBLOCK_INIT
+ bool
+ default n
diff --git a/src/arch/riscv/LICENSE b/src/arch/riscv/LICENSE
new file mode 100644
index 0000000..53e0e66
--- /dev/null
+++ b/src/arch/riscv/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2013, The Regents of the University of California (Regents).
+All Rights Reserved.
+
+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. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc
new file mode 100644
index 0000000..6ca15a4
--- /dev/null
+++ b/src/arch/riscv/Makefile.inc
@@ -0,0 +1,119 @@
+################################################################################
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+################################################################################
+
+riscv_flags = -march=elf64-littleriscv -I$(src)/arch/riscv/
+
+riscv_asm_flags = $(riscv_flags)
+
+################################################################################
+## bootblock
+################################################################################
+ifeq ($(CONFIG_ARCH_BOOTBLOCK_RISCV),y)
+
+bootblock_lds = $(src)/arch/riscv/bootblock.ld
+
+bootblock-y = bootblock.S stages.c
+bootblock-y += rom_media.c
+bootblock-y += \
+ $(top)/src/lib/memchr.c \
+ $(top)/src/lib/memcmp.c \
+ $(top)/src/lib/memcpy.c \
+ $(top)/src/lib/memmove.c \
+ $(top)/src/lib/memset.c
+
+$(objcbfs)/bootblock.debug: $(src)/arch/riscv/bootblock.ld $(obj)/ldoptions $$(bootblock-objs)
+ @printf " LINK $(subst $(obj)/,,$(@))\n"
+ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
+ $(LD_bootblock) -m elf64-littleriscv --gc-sections -static -o $@ -L$(obj) $< -T $(src)/arch/riscv/bootblock.ld
+else
+ $(CC_bootblock) $(CFLAGS_bootblock) -nostartfiles -Wl,--gc-sections -static -o $@ -L$(obj) -T $(src)/arch/riscv/bootblock.ld -Wl,--start-group $(bootblock-objs) $(LIBGCC_FILE_NAME_bootblock) -Wl,--end-group
+endif
+
+endif
+
+################################################################################
+## romstage
+################################################################################
+ifeq ($(CONFIG_ARCH_ROMSTAGE_RISCV),y)
+
+romstage-y += stages.c
+romstage-y += rom_media.c
+romstage-y += \
+ $(top)/src/lib/memchr.c \
+ $(top)/src/lib/memcmp.c \
+ $(top)/src/lib/memcpy.c \
+ $(top)/src/lib/memmove.c \
+ $(top)/src/lib/memset.c
+
+romstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
+
+# Build the romstage
+
+$(objcbfs)/romstage.debug: $$(romstage-objs) $(src)/arch/riscv/romstage.ld $(obj)/ldoptions
+ @printf " LINK $(subst $(obj)/,,$(@))\n"
+ $(CC_romstage) $(CFLAGS_romstage) -nostdlib -Wl,--gc-sections -static -o $@ -L$(obj) -T $(src)/arch/riscv/romstage.ld -Wl,--start-group $(romstage-objs) -Wl,--end-group
+
+romstage-c-ccopts += $(riscv_flags)
+romstage-S-ccopts += $(riscv_asm_flags)
+
+CBFSTOOL_PRE1_OPTS = -m riscv -b $(CONFIG_BOOTBLOCK_ROM_OFFSET) -H $(CONFIG_CBFS_HEADER_ROM_OFFSET) -o $(CONFIG_CBFS_ROM_OFFSET)
+
+endif
+
+################################################################################
+## ramstage
+################################################################################
+ifeq ($(CONFIG_ARCH_RAMSTAGE_RISCV),y)
+
+ramstage-y =
+romstage-y += rom_media.c
+ramstage-y += stages.c
+ramstage-y += misc.c
+ramstage-y += boot.c
+ramstage-y += cbmem.c
+ramstage-y += tables.c
+ramstage-y += \
+ $(top)/src/lib/memchr.c \
+ $(top)/src/lib/memcmp.c \
+ $(top)/src/lib/memcpy.c \
+ $(top)/src/lib/memmove.c \
+ $(top)/src/lib/memset.c
+
+$(eval $(call create_class_compiler,rmodules,riscv))
+
+ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
+
+ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/mainboard.c
+
+# Build the ramstage
+
+$(objcbfs)/ramstage.debug: $$(ramstage-objs) $(src)/arch/riscv/ramstage.ld $(obj)/ldoptions
+ @printf " CC $(subst $(obj)/,,$(@))\n"
+ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
+ $(LD_ramstage) -nostdlib -m elf64-littleriscv --gc-sections -o $@ --wrap __divdi3 --wrap __udivdi3 --wrap __moddi3 --wrap __umoddi3 --wrap __uidiv --start-group $(ramstage-objs) --end-group -T $(src)/arch/riscv/ramstage.ld
+else
+ $(CC_ramstage) $(CFLAGS_ramstage) -nostdlib -Wl,--gc-sections -static -o $@ -L$(obj) -Wl,--start-group $(ramstage-objs) -Wl,--end-group -T $(src)/arch/riscv/ramstage.ld
+endif
+
+ramstage-c-ccopts += $(riscv_flags)
+ramstage-S-ccopts += $(riscv_asm_flags)
+
+endif
diff --git a/src/arch/riscv/boot.c b/src/arch/riscv/boot.c
new file mode 100644
index 0000000..d872a79
--- /dev/null
+++ b/src/arch/riscv/boot.c
@@ -0,0 +1,28 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <arch/stages.h>
+#include <payload_loader.h>
+
+void arch_payload_run(const struct payload *payload)
+{
+ printk(BIOS_SPEW, "entry = %p\n", payload->entry);
+ stage_exit(payload->entry);
+}
diff --git a/src/arch/riscv/bootblock.S b/src/arch/riscv/bootblock.S
new file mode 100644
index 0000000..03b90dd
--- /dev/null
+++ b/src/arch/riscv/bootblock.S
@@ -0,0 +1,91 @@
+/*
+ * Early initialization code for aarch64 (a.k.a. armv8)
+ *
+ * Copyright 2013Google 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+// See LICENSE for license details. relating to the _start code in this file.
+#include <arch/encoding.h>
+
+.section ".start", "ax", %progbits
+.globl _start
+_start:
+
+ // pending figuring out this f-ing toolchain. Hardcode what we know works.
+ la sp, 0x4ef0 // .stacktop
+// la a0, trap_entry
+// la gp, _gp
+// csrw evec, a0
+
+ # clear any pending interrupts
+ csrwi clear_ipi, 0
+
+ li a0, SR_S | SR_PS | SR_EI | SR_S64 | SR_U64
+ or a1, a0, SR_EF | SR_EA
+ csrw status, a1
+ csrr a1, status
+ csrw status, a0
+
+// and a2, a1, SR_EF
+// sw a2, have_fp, t0
+
+// and a2, a1, SR_EA
+// sw a2, have_accelerator, t0
+ call main
+.=0x2000
+.stack:
+.align 8
+ .space 0xf00
+.stacktop:
+.align 3
+.stack_size:
+ .balignl 16,0xdeadbeef
+
+.globl _cbfs_master_header
+_cbfs_master_header:
+ /* The CBFS master header is inserted by cbfstool at the first
+ * aligned offset after the above anchor string is found.
+ * Hence, we leave some space for it.
+ * Assumes 64-byte alignment.
+ */
+ .skip 128
+
+reset:
+init_stack_loop:
+
+ .word CONFIG_STACK_SIZE
+ .section ".id", "a", %progbits
+
+ .section ".id", "a", @progbits
+
+ .globl __id_start
+ // fix this bs later. What's wrong with the riscv gcc?
+__id_start:
+ver:
+ .asciz "1" //COREBOOT_VERSION
+vendor:
+ .asciz "ucb" //CONFIG_MAINBOARD_VENDOR
+part:
+ .asciz "1" //CONFIG_MAINBOARD_PART_NUMBER
+.long __id_end + CONFIG_ID_SECTION_OFFSET - ver /* Reverse offset to the vendor id */
+.long __id_end + CONFIG_ID_SECTION_OFFSET - vendor /* Reverse offset to the vendor id */
+.long __id_end + CONFIG_ID_SECTION_OFFSET - 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/riscv/bootblock.ld b/src/arch/riscv/bootblock.ld
new file mode 100644
index 0000000..9f5f53b
--- /dev/null
+++ b/src/arch/riscv/bootblock.ld
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 Advanced Micro Devices, Inc.
+ * Copyright (C) 2008-2010 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
+ */
+
+/* We use ELF as output format. So that we can debug the code in some form. */
+OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
+OUTPUT_ARCH(riscv)
+INCLUDE ldoptions
+
+PHDRS
+{
+ to_load PT_LOAD;
+}
+
+ENTRY(_start)
+TARGET(binary)
+SECTIONS
+{
+ . = CONFIG_BOOTBLOCK_BASE;
+
+ .bootblock . : {
+ *(.start);
+ KEEP(*(.id));
+ *(.text);
+ *(.text.*);
+ *(.rodata);
+ *(.rodata.*);
+ *(.data);
+ *(.data.*);
+ *(.bss);
+ *(.bss.*);
+ *(.sbss);
+ *(.sbss.*);
+ } : to_load = 0xff
+
+ /DISCARD/ : {
+ *(.comment)
+ *(.note)
+ *(.comment.*)
+ *(.note.*)
+ }
+}
diff --git a/src/arch/riscv/bootblock_simple.c b/src/arch/riscv/bootblock_simple.c
new file mode 100644
index 0000000..d8339d1
--- /dev/null
+++ b/src/arch/riscv/bootblock_simple.c
@@ -0,0 +1,73 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <bootblock_common.h>
+#include <arch/cache.h>
+#include <arch/hlt.h>
+#include <arch/stages.h>
+#include <arch/exception.h>
+#include <cbfs.h>
+#include <console/console.h>
+
+static int boot_cpu(void)
+{
+ /*
+ * FIXME: This is a stub for now. All non-boot CPUs should be
+ * waiting for an interrupt. We could move the chunk of assembly
+ * which puts them to sleep in here...
+ */
+ return 1;
+}
+
+void main(void)
+{
+ const char *stage_name = CONFIG_CBFS_PREFIX"/romstage";
+ void *entry = NULL;
+
+ /* Globally disable MMU, caches, and branch prediction (these should
+ * be disabled by default on reset) */
+ dcache_mmu_disable();
+
+ /*
+ * Re-enable icache and branch prediction. MMU and dcache will be
+ * set up later.
+ *
+ * Note: If booting from USB, we need to disable branch prediction
+ * before copying from USB into RAM (FIXME: why?)
+ */
+
+ if (boot_cpu()) {
+ //bootblock_cpu_init();
+ //bootblock_mainboard_init();
+ }
+
+#ifdef CONFIG_BOOTBLOCK_CONSOLE
+ console_init();
+ exception_init();
+#endif
+
+ entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, stage_name);
+
+ printk(BIOS_SPEW, "stage_name %s, entry %p\n", stage_name, entry);
+
+ if (entry) stage_exit(entry);
+ hlt();
+}
diff --git a/src/arch/riscv/cbmem.c b/src/arch/riscv/cbmem.c
new file mode 100644
index 0000000..2f562af
--- /dev/null
+++ b/src/arch/riscv/cbmem.c
@@ -0,0 +1,30 @@
+/*
+ * 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 <cbmem.h>
+#include <cbmem.h>
+
+
+unsigned long get_top_of_ram(void)
+{
+ return CONFIG_RAMTOP;
+}
+
+void *cbmem_top(void)
+{
+ return (void *)get_top_of_ram();
+}
diff --git a/src/arch/riscv/id.lds b/src/arch/riscv/id.lds
new file mode 100644
index 0000000..cfd091d
--- /dev/null
+++ b/src/arch/riscv/id.lds
@@ -0,0 +1,6 @@
+SECTIONS {
+ . = (0xffffffff - CONFIG_ID_SECTION_OFFSET) - (__id_end - __id_start) + 1;
+ .id (.): {
+ *(.id)
+ }
+}
diff --git a/src/arch/riscv/include/arch/atomic.h b/src/arch/riscv/include/arch/atomic.h
new file mode 100644
index 0000000..b3e5d24
--- /dev/null
+++ b/src/arch/riscv/include/arch/atomic.h
@@ -0,0 +1,75 @@
+// See LICENSE for license details.
+
+#ifndef _RISCV_ATOMIC_H
+#define _RISCV_ATOMIC_H
+
+#include <arch/encoding.h>
+
+typedef struct { volatile long val; } atomic_t;
+typedef struct { atomic_t lock; } spinlock_t;
+#define SPINLOCK_INIT {{0}}
+
+#define mb() __sync_synchronize()
+
+static inline void atomic_set(atomic_t* a, long val)
+{
+ a->val = val;
+}
+
+static inline long atomic_read(atomic_t* a)
+{
+ return a->val;
+}
+
+static inline long atomic_add(atomic_t* a, long inc)
+{
+ long ret = atomic_read(a);
+ atomic_set(a, ret + inc);
+ return ret;
+}
+
+static inline long atomic_swap(atomic_t* a, long val)
+{
+ long ret = atomic_read(a);
+ atomic_set(a, val);
+ return ret;
+}
+
+static inline long atomic_cas(atomic_t* a, long compare, long swap)
+{
+ long ret = atomic_read(a);
+ if (ret == compare)
+ atomic_set(a, swap);
+ return ret;
+}
+
+static inline void spinlock_lock(spinlock_t* lock)
+{
+ do
+ {
+ while (atomic_read(&lock->lock))
+ ;
+ } while (atomic_swap(&lock->lock, -1));
+ mb();
+}
+
+static inline void spinlock_unlock(spinlock_t* lock)
+{
+ mb();
+ atomic_set(&lock->lock,0);
+}
+
+static inline long spinlock_lock_irqsave(spinlock_t* lock)
+{
+ long flags = clear_csr(status, SR_EI);
+ spinlock_lock(lock);
+ return flags;
+}
+
+static inline void spinlock_unlock_irqrestore(spinlock_t* lock, long flags)
+{
+ spinlock_unlock(lock);
+ set_csr(status, flags & SR_EI);
+}
+
+#endif
diff --git a/src/arch/riscv/include/arch/byteorder.h b/src/arch/riscv/include/arch/byteorder.h
new file mode 100644
index 0000000..8dc069f
--- /dev/null
+++ b/src/arch/riscv/include/arch/byteorder.h
@@ -0,0 +1,27 @@
+#ifndef _BYTEORDER_H
+#define _BYTEORDER_H
+
+#define __LITTLE_ENDIAN 1234
+
+#include <stdint.h>
+#include <swab.h>
+
+#define cpu_to_le64(x) ((uint64_t)(x))
+#define le64_to_cpu(x) ((uint64_t)(x))
+#define cpu_to_le32(x) ((uint32_t)(x))
+#define le32_to_cpu(x) ((uint32_t)(x))
+#define cpu_to_le16(x) ((uint16_t)(x))
+#define le16_to_cpu(x) ((uint16_t)(x))
+#define cpu_to_be64(x) swab64(x)
+#define be64_to_cpu(x) swab64(x)
+#define cpu_to_be32(x) swab32((x))
+#define be32_to_cpu(x) swab32((x))
+#define cpu_to_be16(x) swab16((x))
+#define be16_to_cpu(x) swab16((x))
+
+#define ntohll(x) be64_to_cpu(x)
+#define htonll(x) cpu_to_be64(x)
+#define ntohl(x) be32_to_cpu(x)
+#define htonl(x) cpu_to_be32(x)
+
+#endif /* _BYTEORDER_H */
diff --git a/src/arch/riscv/include/arch/cpu.h b/src/arch/riscv/include/arch/cpu.h
new file mode 100644
index 0000000..7fc85a5
--- /dev/null
+++ b/src/arch/riscv/include/arch/cpu.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2012 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#ifndef __ARCH_CPU_H__
+#define __ARCH_CPU_H__
+
+#define asmlinkage
+
+#if !defined(__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;
+#if CONFIG_COOP_MULTITASKING
+ struct thread *thread;
+#endif
+};
+
+struct cpuinfo_riscv {
+ uint8_t riscv; /* CPU family */
+ uint8_t riscv_vendor; /* CPU vendor */
+ uint8_t riscv_model;
+};
+
+#endif
+
+struct cpu_info *cpu_info(void);
+#endif /* __ARCH_CPU_H__ */
+
diff --git a/src/arch/riscv/include/arch/early_variables.h b/src/arch/riscv/include/arch/early_variables.h
new file mode 100644
index 0000000..3a1f20d
--- /dev/null
+++ b/src/arch/riscv/include/arch/early_variables.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
+ *
+ * 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
+ */
+
+#ifndef ARCH_EARLY_VARIABLES_H
+#define ARCH_EARLY_VARIABLES_H
+
+#if defined(CONFIG_CAR_MIGRATION) && CONFIG_CAR_MIGRATION
+ #error "This is RISCV, silly... we don't have CAR here."
+#endif
+
+#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_set_var(var, val) do { (var) = (val); } while (0)
+static inline void car_migrate_variables(void) { }
+
+#endif
diff --git a/src/arch/riscv/include/arch/encoding.h b/src/arch/riscv/include/arch/encoding.h
new file mode 100644
index 0000000..089a8a9
--- /dev/null
+++ b/src/arch/riscv/include/arch/encoding.h
@@ -0,0 +1,727 @@
+// See LICENSE for license details.
+
+#ifndef RISCV_CSR_ENCODING_H
+#define RISCV_CSR_ENCODING_H
+
+#define SR_S 0x00000001
+#define SR_PS 0x00000002
+#define SR_EI 0x00000004
+#define SR_PEI 0x00000008
+#define SR_EF 0x00000010
+#define SR_U64 0x00000020
+#define SR_S64 0x00000040
+#define SR_VM 0x00000080
+#define SR_EA 0x00000100
+#define SR_IM 0x00FF0000
+#define SR_IP 0xFF000000
+#define SR_ZERO ~(SR_S|SR_PS|SR_EI|SR_PEI|SR_EF|SR_U64|SR_S64|SR_VM|SR_EA|SR_IM|SR_IP)
+#define SR_IM_SHIFT 16
+#define SR_IP_SHIFT 24
+
+#define IRQ_COP 2
+#define IRQ_IPI 5
+#define IRQ_HOST 6
+#define IRQ_TIMER 7
+
+#define IMPL_SPIKE 1
+#define IMPL_ROCKET 2
+
+// page table entry (PTE) fields
+#define PTE_V 0x001 // Entry is a page Table descriptor
+#define PTE_T 0x002 // Entry is a page Table, not a terminal node
+#define PTE_G 0x004 // Global
+#define PTE_UR 0x008 // User Write permission
+#define PTE_UW 0x010 // User Read permission
+#define PTE_UX 0x020 // User eXecute permission
+#define PTE_SR 0x040 // Supervisor Read permission
+#define PTE_SW 0x080 // Supervisor Write permission
+#define PTE_SX 0x100 // Supervisor eXecute permission
+#define PTE_PERM (PTE_SR | PTE_SW | PTE_SX | PTE_UR | PTE_UW | PTE_UX)
+
+#ifdef __riscv
+
+#ifdef __riscv64
+# define RISCV_PGLEVELS 3
+# define RISCV_PGSHIFT 13
+#else
+# define RISCV_PGLEVELS 2
+# define RISCV_PGSHIFT 12
+#endif
+#define RISCV_PGLEVEL_BITS 10
+#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
+
+#ifndef __ASSEMBLER__
+
+#define read_csr(reg) ({ long __tmp; \
+ asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+
+#define write_csr(reg, val) \
+ asm volatile ("csrw " #reg ", %0" :: "r"(val))
+
+#define swap_csr(reg, val) ({ long __tmp; \
+ asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
+ __tmp; })
+
+#define set_csr(reg, bit) ({ long __tmp; \
+ if (__builtin_constant_p(bit) && (bit) < 32) \
+ asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
+ else \
+ asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
+ __tmp; })
+
+#define clear_csr(reg, bit) ({ long __tmp; \
+ if (__builtin_constant_p(bit) && (bit) < 32) \
+ asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
+ else \
+ asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
+ __tmp; })
+
+#define rdtime() ({ unsigned long __tmp; \
+ asm volatile ("rdtime %0" : "=r"(__tmp)); \
+ __tmp; })
+
+#define rdcycle() ({ unsigned long __tmp; \
+ asm volatile ("rdcycle %0" : "=r"(__tmp)); \
+ __tmp; })
+
+#define rdinstret() ({ unsigned long __tmp; \
+ asm volatile ("rdinstret %0" : "=r"(__tmp)); \
+ __tmp; })
+
+#endif
+
+#endif
+
+#endif
+/* Automatically generated by parse-opcodes */
+#ifndef RISCV_ENCODING_H
+#define RISCV_ENCODING_H
+#define MATCH_FMV_S_X 0xf0000053
+#define MASK_FMV_S_X 0xfff0707f
+#define MATCH_AMOXOR_W 0x2000202f
+#define MASK_AMOXOR_W 0xf800707f
+#define MATCH_REMUW 0x200703b
+#define MASK_REMUW 0xfe00707f
+#define MATCH_FMIN_D 0x2a000053
+#define MASK_FMIN_D 0xfe00707f
+#define MATCH_AMOMAX_D 0xa000302f
+#define MASK_AMOMAX_D 0xf800707f
+#define MATCH_BLTU 0x6063
+#define MASK_BLTU 0x707f
+#define MATCH_FSGNJN_D 0x22001053
+#define MASK_FSGNJN_D 0xfe00707f
+#define MATCH_FMIN_S 0x28000053
+#define MASK_FMIN_S 0xfe00707f
+#define MATCH_CSRRW 0x1073
+#define MASK_CSRRW 0x707f
+#define MATCH_SLLIW 0x101b
+#define MASK_SLLIW 0xfe00707f
+#define MATCH_LB 0x3
+#define MASK_LB 0x707f
+#define MATCH_FMAX_S 0x28001053
+#define MASK_FMAX_S 0xfe00707f
+#define MATCH_LH 0x1003
+#define MASK_LH 0x707f
+#define MATCH_FCVT_D_W 0xd2000053
+#define MASK_FCVT_D_W 0xfff0007f
+#define MATCH_LW 0x2003
+#define MASK_LW 0x707f
+#define MATCH_ADD 0x33
+#define MASK_ADD 0xfe00707f
+#define MATCH_CSRRC 0x3073
+#define MASK_CSRRC 0x707f
+#define MATCH_FMAX_D 0x2a001053
+#define MASK_FMAX_D 0xfe00707f
+#define MATCH_BNE 0x1063
+#define MASK_BNE 0x707f
+#define MATCH_FCVT_S_D 0x40100053
+#define MASK_FCVT_S_D 0xfff0007f
+#define MATCH_BGEU 0x7063
+#define MASK_BGEU 0x707f
+#define MATCH_FADD_D 0x2000053
+#define MASK_FADD_D 0xfe00007f
+#define MATCH_SLTIU 0x3013
+#define MASK_SLTIU 0x707f
+#define MATCH_FADD_S 0x53
+#define MASK_FADD_S 0xfe00007f
+#define MATCH_FCLASS_D 0xe2001053
+#define MASK_FCLASS_D 0xfff0707f
+#define MATCH_FCVT_S_W 0xd0000053
+#define MASK_FCVT_S_W 0xfff0007f
+#define MATCH_MUL 0x2000033
+#define MASK_MUL 0xfe00707f
+#define MATCH_AMOMINU_D 0xc000302f
+#define MASK_AMOMINU_D 0xf800707f
+#define MATCH_FCVT_S_LU 0xd0300053
+#define MASK_FCVT_S_LU 0xfff0007f
+#define MATCH_SRLI 0x5013
+#define MASK_SRLI 0xfc00707f
+#define MATCH_AMOMINU_W 0xc000202f
+#define MASK_AMOMINU_W 0xf800707f
+#define MATCH_DIVUW 0x200503b
+#define MASK_DIVUW 0xfe00707f
+#define MATCH_MULW 0x200003b
+#define MASK_MULW 0xfe00707f
+#define MATCH_SRLW 0x503b
+#define MASK_SRLW 0xfe00707f
+#define MATCH_DIV 0x2004033
+#define MASK_DIV 0xfe00707f
+#define MATCH_FDIV_D 0x1a000053
+#define MASK_FDIV_D 0xfe00007f
+#define MATCH_FENCE 0xf
+#define MASK_FENCE 0x707f
+#define MATCH_FNMSUB_S 0x4b
+#define MASK_FNMSUB_S 0x600007f
+#define MATCH_FCVT_L_S 0xc0200053
+#define MASK_FCVT_L_S 0xfff0007f
+#define MATCH_SBREAK 0x100073
+#define MASK_SBREAK 0xffffffff
+#define MATCH_FLE_S 0xa0000053
+#define MASK_FLE_S 0xfe00707f
+#define MATCH_FDIV_S 0x18000053
+#define MASK_FDIV_S 0xfe00007f
+#define MATCH_FLE_D 0xa2000053
+#define MASK_FLE_D 0xfe00707f
+#define MATCH_FENCE_I 0x100f
+#define MASK_FENCE_I 0x707f
+#define MATCH_FNMSUB_D 0x200004b
+#define MASK_FNMSUB_D 0x600007f
+#define MATCH_ADDW 0x3b
+#define MASK_ADDW 0xfe00707f
+#define MATCH_SLL 0x1033
+#define MASK_SLL 0xfe00707f
+#define MATCH_XOR 0x4033
+#define MASK_XOR 0xfe00707f
+#define MATCH_SUB 0x40000033
+#define MASK_SUB 0xfe00707f
+#define MATCH_BLT 0x4063
+#define MASK_BLT 0x707f
+#define MATCH_SCALL 0x73
+#define MASK_SCALL 0xffffffff
+#define MATCH_FCLASS_S 0xe0001053
+#define MASK_FCLASS_S 0xfff0707f
+#define MATCH_SC_W 0x1800202f
+#define MASK_SC_W 0xf800707f
+#define MATCH_REM 0x2006033
+#define MASK_REM 0xfe00707f
+#define MATCH_SRLIW 0x501b
+#define MASK_SRLIW 0xfe00707f
+#define MATCH_LUI 0x37
+#define MASK_LUI 0x7f
+#define MATCH_CSRRCI 0x7073
+#define MASK_CSRRCI 0x707f
+#define MATCH_ADDI 0x13
+#define MASK_ADDI 0x707f
+#define MATCH_MULH 0x2001033
+#define MASK_MULH 0xfe00707f
+#define MATCH_FMUL_S 0x10000053
+#define MASK_FMUL_S 0xfe00007f
+#define MATCH_CSRRSI 0x6073
+#define MASK_CSRRSI 0x707f
+#define MATCH_SRAI 0x40005013
+#define MASK_SRAI 0xfc00707f
+#define MATCH_AMOAND_D 0x6000302f
+#define MASK_AMOAND_D 0xf800707f
+#define MATCH_FLT_D 0xa2001053
+#define MASK_FLT_D 0xfe00707f
+#define MATCH_SRAW 0x4000503b
+#define MASK_SRAW 0xfe00707f
+#define MATCH_FMUL_D 0x12000053
+#define MASK_FMUL_D 0xfe00007f
+#define MATCH_LD 0x3003
+#define MASK_LD 0x707f
+#define MATCH_ORI 0x6013
+#define MASK_ORI 0x707f
+#define MATCH_CSRRS 0x2073
+#define MASK_CSRRS 0x707f
+#define MATCH_FLT_S 0xa0001053
+#define MASK_FLT_S 0xfe00707f
+#define MATCH_ADDIW 0x1b
+#define MASK_ADDIW 0x707f
+#define MATCH_AMOAND_W 0x6000202f
+#define MASK_AMOAND_W 0xf800707f
+#define MATCH_FEQ_S 0xa0002053
+#define MASK_FEQ_S 0xfe00707f
+#define MATCH_FSGNJX_D 0x22002053
+#define MASK_FSGNJX_D 0xfe00707f
+#define MATCH_SRA 0x40005033
+#define MASK_SRA 0xfe00707f
+#define MATCH_BGE 0x5063
+#define MASK_BGE 0x707f
+#define MATCH_SRAIW 0x4000501b
+#define MASK_SRAIW 0xfe00707f
+#define MATCH_SRL 0x5033
+#define MASK_SRL 0xfe00707f
+#define MATCH_FSUB_D 0xa000053
+#define MASK_FSUB_D 0xfe00007f
+#define MATCH_FSGNJX_S 0x20002053
+#define MASK_FSGNJX_S 0xfe00707f
+#define MATCH_FEQ_D 0xa2002053
+#define MASK_FEQ_D 0xfe00707f
+#define MATCH_FCVT_D_WU 0xd2100053
+#define MASK_FCVT_D_WU 0xfff0007f
+#define MATCH_OR 0x6033
+#define MASK_OR 0xfe00707f
+#define MATCH_FCVT_WU_D 0xc2100053
+#define MASK_FCVT_WU_D 0xfff0007f
+#define MATCH_SUBW 0x4000003b
+#define MASK_SUBW 0xfe00707f
+#define MATCH_FCVT_D_L 0xd2200053
+#define MASK_FCVT_D_L 0xfff0007f
+#define MATCH_AMOMAXU_D 0xe000302f
+#define MASK_AMOMAXU_D 0xf800707f
+#define MATCH_XORI 0x4013
+#define MASK_XORI 0x707f
+#define MATCH_AMOXOR_D 0x2000302f
+#define MASK_AMOXOR_D 0xf800707f
+#define MATCH_AMOMAXU_W 0xe000202f
+#define MASK_AMOMAXU_W 0xf800707f
+#define MATCH_FCVT_WU_S 0xc0100053
+#define MASK_FCVT_WU_S 0xfff0007f
+#define MATCH_ANDI 0x7013
+#define MASK_ANDI 0x707f
+#define MATCH_FMV_X_S 0xe0000053
+#define MASK_FMV_X_S 0xfff0707f
+#define MATCH_SRET 0x80000073
+#define MASK_SRET 0xffffffff
+#define MATCH_FNMADD_S 0x4f
+#define MASK_FNMADD_S 0x600007f
+#define MATCH_JAL 0x6f
+#define MASK_JAL 0x7f
+#define MATCH_LWU 0x6003
+#define MASK_LWU 0x707f
+#define MATCH_FMV_X_D 0xe2000053
+#define MASK_FMV_X_D 0xfff0707f
+#define MATCH_FCVT_D_S 0x42000053
+#define MASK_FCVT_D_S 0xfff0007f
+#define MATCH_FNMADD_D 0x200004f
+#define MASK_FNMADD_D 0x600007f
+#define MATCH_AMOADD_D 0x302f
+#define MASK_AMOADD_D 0xf800707f
+#define MATCH_LR_D 0x1000302f
+#define MASK_LR_D 0xf9f0707f
+#define MATCH_FCVT_W_S 0xc0000053
+#define MASK_FCVT_W_S 0xfff0007f
+#define MATCH_MULHSU 0x2002033
+#define MASK_MULHSU 0xfe00707f
+#define MATCH_AMOADD_W 0x202f
+#define MASK_AMOADD_W 0xf800707f
+#define MATCH_FCVT_D_LU 0xd2300053
+#define MASK_FCVT_D_LU 0xfff0007f
+#define MATCH_LR_W 0x1000202f
+#define MASK_LR_W 0xf9f0707f
+#define MATCH_FCVT_W_D 0xc2000053
+#define MASK_FCVT_W_D 0xfff0007f
+#define MATCH_SLT 0x2033
+#define MASK_SLT 0xfe00707f
+#define MATCH_SLLW 0x103b
+#define MASK_SLLW 0xfe00707f
+#define MATCH_AMOOR_D 0x4000302f
+#define MASK_AMOOR_D 0xf800707f
+#define MATCH_SLTI 0x2013
+#define MASK_SLTI 0x707f
+#define MATCH_REMU 0x2007033
+#define MASK_REMU 0xfe00707f
+#define MATCH_FLW 0x2007
+#define MASK_FLW 0x707f
+#define MATCH_REMW 0x200603b
+#define MASK_REMW 0xfe00707f
+#define MATCH_SLTU 0x3033
+#define MASK_SLTU 0xfe00707f
+#define MATCH_SLLI 0x1013
+#define MASK_SLLI 0xfc00707f
+#define MATCH_AMOOR_W 0x4000202f
+#define MASK_AMOOR_W 0xf800707f
+#define MATCH_BEQ 0x63
+#define MASK_BEQ 0x707f
+#define MATCH_FLD 0x3007
+#define MASK_FLD 0x707f
+#define MATCH_FSUB_S 0x8000053
+#define MASK_FSUB_S 0xfe00007f
+#define MATCH_AND 0x7033
+#define MASK_AND 0xfe00707f
+#define MATCH_FMV_D_X 0xf2000053
+#define MASK_FMV_D_X 0xfff0707f
+#define MATCH_LBU 0x4003
+#define MASK_LBU 0x707f
+#define MATCH_FSGNJ_S 0x20000053
+#define MASK_FSGNJ_S 0xfe00707f
+#define MATCH_AMOMAX_W 0xa000202f
+#define MASK_AMOMAX_W 0xf800707f
+#define MATCH_FSGNJ_D 0x22000053
+#define MASK_FSGNJ_D 0xfe00707f
+#define MATCH_MULHU 0x2003033
+#define MASK_MULHU 0xfe00707f
+#define MATCH_FCVT_L_D 0xc2200053
+#define MASK_FCVT_L_D 0xfff0007f
+#define MATCH_FCVT_S_WU 0xd0100053
+#define MASK_FCVT_S_WU 0xfff0007f
+#define MATCH_FCVT_LU_S 0xc0300053
+#define MASK_FCVT_LU_S 0xfff0007f
+#define MATCH_FCVT_S_L 0xd0200053
+#define MASK_FCVT_S_L 0xfff0007f
+#define MATCH_AUIPC 0x17
+#define MASK_AUIPC 0x7f
+#define MATCH_FCVT_LU_D 0xc2300053
+#define MASK_FCVT_LU_D 0xfff0007f
+#define MATCH_CSRRWI 0x5073
+#define MASK_CSRRWI 0x707f
+#define MATCH_SC_D 0x1800302f
+#define MASK_SC_D 0xf800707f
+#define MATCH_FMADD_S 0x43
+#define MASK_FMADD_S 0x600007f
+#define MATCH_FSQRT_S 0x58000053
+#define MASK_FSQRT_S 0xfff0007f
+#define MATCH_AMOMIN_W 0x8000202f
+#define MASK_AMOMIN_W 0xf800707f
+#define MATCH_FSGNJN_S 0x20001053
+#define MASK_FSGNJN_S 0xfe00707f
+#define MATCH_AMOSWAP_D 0x800302f
+#define MASK_AMOSWAP_D 0xf800707f
+#define MATCH_FSQRT_D 0x5a000053
+#define MASK_FSQRT_D 0xfff0007f
+#define MATCH_FMADD_D 0x2000043
+#define MASK_FMADD_D 0x600007f
+#define MATCH_DIVW 0x200403b
+#define MASK_DIVW 0xfe00707f
+#define MATCH_AMOMIN_D 0x8000302f
+#define MASK_AMOMIN_D 0xf800707f
+#define MATCH_DIVU 0x2005033
+#define MASK_DIVU 0xfe00707f
+#define MATCH_AMOSWAP_W 0x800202f
+#define MASK_AMOSWAP_W 0xf800707f
+#define MATCH_JALR 0x67
+#define MASK_JALR 0x707f
+#define MATCH_FSD 0x3027
+#define MASK_FSD 0x707f
+#define MATCH_SW 0x2023
+#define MASK_SW 0x707f
+#define MATCH_FMSUB_S 0x47
+#define MASK_FMSUB_S 0x600007f
+#define MATCH_LHU 0x5003
+#define MASK_LHU 0x707f
+#define MATCH_SH 0x1023
+#define MASK_SH 0x707f
+#define MATCH_FSW 0x2027
+#define MASK_FSW 0x707f
+#define MATCH_SB 0x23
+#define MASK_SB 0x707f
+#define MATCH_FMSUB_D 0x2000047
+#define MASK_FMSUB_D 0x600007f
+#define MATCH_SD 0x3023
+#define MASK_SD 0x707f
+#define CSR_FFLAGS 0x1
+#define CSR_FRM 0x2
+#define CSR_FCSR 0x3
+#define CSR_STATS 0xc0
+#define CSR_SUP0 0x500
+#define CSR_SUP1 0x501
+#define CSR_EPC 0x502
+#define CSR_BADVADDR 0x503
+#define CSR_PTBR 0x504
+#define CSR_ASID 0x505
+#define CSR_COUNT 0x506
+#define CSR_COMPARE 0x507
+#define CSR_EVEC 0x508
+#define CSR_CAUSE 0x509
+#define CSR_STATUS 0x50a
+#define CSR_HARTID 0x50b
+#define CSR_IMPL 0x50c
+#define CSR_FATC 0x50d
+#define CSR_SEND_IPI 0x50e
+#define CSR_CLEAR_IPI 0x50f
+#define CSR_RESET 0x51d
+#define CSR_TOHOST 0x51e
+#define CSR_FROMHOST 0x51f
+#define CSR_CYCLE 0xc00
+#define CSR_TIME 0xc01
+#define CSR_INSTRET 0xc02
+#define CSR_UARCH0 0xcc0
+#define CSR_UARCH1 0xcc1
+#define CSR_UARCH2 0xcc2
+#define CSR_UARCH3 0xcc3
+#define CSR_UARCH4 0xcc4
+#define CSR_UARCH5 0xcc5
+#define CSR_UARCH6 0xcc6
+#define CSR_UARCH7 0xcc7
+#define CSR_UARCH8 0xcc8
+#define CSR_UARCH9 0xcc9
+#define CSR_UARCH10 0xcca
+#define CSR_UARCH11 0xccb
+#define CSR_UARCH12 0xccc
+#define CSR_UARCH13 0xccd
+#define CSR_UARCH14 0xcce
+#define CSR_UARCH15 0xccf
+#define CSR_COUNTH 0x586
+#define CSR_CYCLEH 0xc80
+#define CSR_TIMEH 0xc81
+#define CSR_INSTRETH 0xc82
+#define CAUSE_MISALIGNED_FETCH 0x0
+#define CAUSE_FAULT_FETCH 0x1
+#define CAUSE_ILLEGAL_INSTRUCTION 0x2
+#define CAUSE_PRIVILEGED_INSTRUCTION 0x3
+#define CAUSE_FP_DISABLED 0x4
+#define CAUSE_SYSCALL 0x6
+#define CAUSE_BREAKPOINT 0x7
+#define CAUSE_MISALIGNED_LOAD 0x8
+#define CAUSE_MISALIGNED_STORE 0x9
+#define CAUSE_FAULT_LOAD 0xa
+#define CAUSE_FAULT_STORE 0xb
+#define CAUSE_ACCELERATOR_DISABLED 0xc
+#endif
+#ifdef DECLARE_INSN
+DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X)
+DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
+DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)
+DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D)
+DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D)
+DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU)
+DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D)
+DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S)
+DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)
+DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW)
+DECLARE_INSN(lb, MATCH_LB, MASK_LB)
+DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S)
+DECLARE_INSN(lh, MATCH_LH, MASK_LH)
+DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W)
+DECLARE_INSN(lw, MATCH_LW, MASK_LW)
+DECLARE_INSN(add, MATCH_ADD, MASK_ADD)
+DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC)
+DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D)
+DECLARE_INSN(bne, MATCH_BNE, MASK_BNE)
+DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D)
+DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU)
+DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D)
+DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU)
+DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S)
+DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D)
+DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W)
+DECLARE_INSN(mul, MATCH_MUL, MASK_MUL)
+DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D)
+DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU)
+DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI)
+DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W)
+DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)
+DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW)
+DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW)
+DECLARE_INSN(div, MATCH_DIV, MASK_DIV)
+DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D)
+DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE)
+DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S)
+DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S)
+DECLARE_INSN(sbreak, MATCH_SBREAK, MASK_SBREAK)
+DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S)
+DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S)
+DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D)
+DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I)
+DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D)
+DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW)
+DECLARE_INSN(sll, MATCH_SLL, MASK_SLL)
+DECLARE_INSN(xor, MATCH_XOR, MASK_XOR)
+DECLARE_INSN(sub, MATCH_SUB, MASK_SUB)
+DECLARE_INSN(blt, MATCH_BLT, MASK_BLT)
+DECLARE_INSN(scall, MATCH_SCALL, MASK_SCALL)
+DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S)
+DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W)
+DECLARE_INSN(rem, MATCH_REM, MASK_REM)
+DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW)
+DECLARE_INSN(lui, MATCH_LUI, MASK_LUI)
+DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI)
+DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI)
+DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH)
+DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S)
+DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI)
+DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI)
+DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D)
+DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D)
+DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW)
+DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D)
+DECLARE_INSN(ld, MATCH_LD, MASK_LD)
+DECLARE_INSN(ori, MATCH_ORI, MASK_ORI)
+DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS)
+DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S)
+DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW)
+DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W)
+DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S)
+DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D)
+DECLARE_INSN(sra, MATCH_SRA, MASK_SRA)
+DECLARE_INSN(bge, MATCH_BGE, MASK_BGE)
+DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW)
+DECLARE_INSN(srl, MATCH_SRL, MASK_SRL)
+DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D)
+DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S)
+DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D)
+DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU)
+DECLARE_INSN(or, MATCH_OR, MASK_OR)
+DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D)
+DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW)
+DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L)
+DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D)
+DECLARE_INSN(xori, MATCH_XORI, MASK_XORI)
+DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D)
+DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W)
+DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S)
+DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI)
+DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S)
+DECLARE_INSN(sret, MATCH_SRET, MASK_SRET)
+DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S)
+DECLARE_INSN(jal, MATCH_JAL, MASK_JAL)
+DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU)
+DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D)
+DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S)
+DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D)
+DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D)
+DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)
+DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S)
+DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU)
+DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
+DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU)
+DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W)
+DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D)
+DECLARE_INSN(slt, MATCH_SLT, MASK_SLT)
+DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW)
+DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D)
+DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI)
+DECLARE_INSN(remu, MATCH_REMU, MASK_REMU)
+DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)
+DECLARE_INSN(remw, MATCH_REMW, MASK_REMW)
+DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU)
+DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI)
+DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)
+DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
+DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)
+DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S)
+DECLARE_INSN(and, MATCH_AND, MASK_AND)
+DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X)
+DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU)
+DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S)
+DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W)
+DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D)
+DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU)
+DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D)
+DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU)
+DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S)
+DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L)
+DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC)
+DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D)
+DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI)
+DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D)
+DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S)
+DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S)
+DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W)
+DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S)
+DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D)
+DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D)
+DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D)
+DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)
+DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D)
+DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU)
+DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W)
+DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR)
+DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD)
+DECLARE_INSN(sw, MATCH_SW, MASK_SW)
+DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S)
+DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU)
+DECLARE_INSN(sh, MATCH_SH, MASK_SH)
+DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW)
+DECLARE_INSN(sb, MATCH_SB, MASK_SB)
+DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D)
+DECLARE_INSN(sd, MATCH_SD, MASK_SD)
+#endif
+#ifdef DECLARE_CSR
+DECLARE_CSR(fflags, CSR_FFLAGS)
+DECLARE_CSR(frm, CSR_FRM)
+DECLARE_CSR(fcsr, CSR_FCSR)
+DECLARE_CSR(stats, CSR_STATS)
+DECLARE_CSR(sup0, CSR_SUP0)
+DECLARE_CSR(sup1, CSR_SUP1)
+DECLARE_CSR(epc, CSR_EPC)
+DECLARE_CSR(badvaddr, CSR_BADVADDR)
+DECLARE_CSR(ptbr, CSR_PTBR)
+DECLARE_CSR(asid, CSR_ASID)
+DECLARE_CSR(count, CSR_COUNT)
+DECLARE_CSR(compare, CSR_COMPARE)
+DECLARE_CSR(evec, CSR_EVEC)
+DECLARE_CSR(cause, CSR_CAUSE)
+DECLARE_CSR(status, CSR_STATUS)
+DECLARE_CSR(hartid, CSR_HARTID)
+DECLARE_CSR(impl, CSR_IMPL)
+DECLARE_CSR(fatc, CSR_FATC)
+DECLARE_CSR(send_ipi, CSR_SEND_IPI)
+DECLARE_CSR(clear_ipi, CSR_CLEAR_IPI)
+DECLARE_CSR(reset, CSR_RESET)
+DECLARE_CSR(tohost, CSR_TOHOST)
+DECLARE_CSR(fromhost, CSR_FROMHOST)
+DECLARE_CSR(cycle, CSR_CYCLE)
+DECLARE_CSR(time, CSR_TIME)
+DECLARE_CSR(instret, CSR_INSTRET)
+DECLARE_CSR(uarch0, CSR_UARCH0)
+DECLARE_CSR(uarch1, CSR_UARCH1)
+DECLARE_CSR(uarch2, CSR_UARCH2)
+DECLARE_CSR(uarch3, CSR_UARCH3)
+DECLARE_CSR(uarch4, CSR_UARCH4)
+DECLARE_CSR(uarch5, CSR_UARCH5)
+DECLARE_CSR(uarch6, CSR_UARCH6)
+DECLARE_CSR(uarch7, CSR_UARCH7)
+DECLARE_CSR(uarch8, CSR_UARCH8)
+DECLARE_CSR(uarch9, CSR_UARCH9)
+DECLARE_CSR(uarch10, CSR_UARCH10)
+DECLARE_CSR(uarch11, CSR_UARCH11)
+DECLARE_CSR(uarch12, CSR_UARCH12)
+DECLARE_CSR(uarch13, CSR_UARCH13)
+DECLARE_CSR(uarch14, CSR_UARCH14)
+DECLARE_CSR(uarch15, CSR_UARCH15)
+DECLARE_CSR(counth, CSR_COUNTH)
+DECLARE_CSR(cycleh, CSR_CYCLEH)
+DECLARE_CSR(timeh, CSR_TIMEH)
+DECLARE_CSR(instreth, CSR_INSTRETH)
+#endif
+#ifdef DECLARE_CAUSE
+DECLARE_CAUSE("fflags", CAUSE_FFLAGS)
+DECLARE_CAUSE("frm", CAUSE_FRM)
+DECLARE_CAUSE("fcsr", CAUSE_FCSR)
+DECLARE_CAUSE("stats", CAUSE_STATS)
+DECLARE_CAUSE("sup0", CAUSE_SUP0)
+DECLARE_CAUSE("sup1", CAUSE_SUP1)
+DECLARE_CAUSE("epc", CAUSE_EPC)
+DECLARE_CAUSE("badvaddr", CAUSE_BADVADDR)
+DECLARE_CAUSE("ptbr", CAUSE_PTBR)
+DECLARE_CAUSE("asid", CAUSE_ASID)
+DECLARE_CAUSE("count", CAUSE_COUNT)
+DECLARE_CAUSE("compare", CAUSE_COMPARE)
+DECLARE_CAUSE("evec", CAUSE_EVEC)
+DECLARE_CAUSE("cause", CAUSE_CAUSE)
+DECLARE_CAUSE("status", CAUSE_STATUS)
+DECLARE_CAUSE("hartid", CAUSE_HARTID)
+DECLARE_CAUSE("impl", CAUSE_IMPL)
+DECLARE_CAUSE("fatc", CAUSE_FATC)
+DECLARE_CAUSE("send_ipi", CAUSE_SEND_IPI)
+DECLARE_CAUSE("clear_ipi", CAUSE_CLEAR_IPI)
+DECLARE_CAUSE("reset", CAUSE_RESET)
+DECLARE_CAUSE("tohost", CAUSE_TOHOST)
+DECLARE_CAUSE("fromhost", CAUSE_FROMHOST)
+DECLARE_CAUSE("cycle", CAUSE_CYCLE)
+DECLARE_CAUSE("time", CAUSE_TIME)
+DECLARE_CAUSE("instret", CAUSE_INSTRET)
+DECLARE_CAUSE("uarch0", CAUSE_UARCH0)
+DECLARE_CAUSE("uarch1", CAUSE_UARCH1)
+DECLARE_CAUSE("uarch2", CAUSE_UARCH2)
+DECLARE_CAUSE("uarch3", CAUSE_UARCH3)
+DECLARE_CAUSE("uarch4", CAUSE_UARCH4)
+DECLARE_CAUSE("uarch5", CAUSE_UARCH5)
+DECLARE_CAUSE("uarch6", CAUSE_UARCH6)
+DECLARE_CAUSE("uarch7", CAUSE_UARCH7)
+DECLARE_CAUSE("uarch8", CAUSE_UARCH8)
+DECLARE_CAUSE("uarch9", CAUSE_UARCH9)
+DECLARE_CAUSE("uarch10", CAUSE_UARCH10)
+DECLARE_CAUSE("uarch11", CAUSE_UARCH11)
+DECLARE_CAUSE("uarch12", CAUSE_UARCH12)
+DECLARE_CAUSE("uarch13", CAUSE_UARCH13)
+DECLARE_CAUSE("uarch14", CAUSE_UARCH14)
+DECLARE_CAUSE("uarch15", CAUSE_UARCH15)
+DECLARE_CAUSE("counth", CAUSE_COUNTH)
+DECLARE_CAUSE("cycleh", CAUSE_CYCLEH)
+DECLARE_CAUSE("timeh", CAUSE_TIMEH)
+DECLARE_CAUSE("instreth", CAUSE_INSTRETH)
+#endif
diff --git a/src/arch/riscv/include/arch/exception.h b/src/arch/riscv/include/arch/exception.h
new file mode 100644
index 0000000..befab1f
--- /dev/null
+++ b/src/arch/riscv/include/arch/exception.h
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the libpayload 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.
+ */
+
+#ifndef _ARCH_EXCEPTION_H
+#define _ARCH_EXCEPTION_H
+
+#include <stdint.h>
+
+static inline void exception_init(void)
+{
+}
+
+#endif
diff --git a/src/arch/riscv/include/arch/hlt.h b/src/arch/riscv/include/arch/hlt.h
new file mode 100644
index 0000000..12099a9
--- /dev/null
+++ b/src/arch/riscv/include/arch/hlt.h
@@ -0,0 +1,6 @@
+static inline __attribute__((always_inline)) void hlt(void)
+{
+ while(1);
+}
+
+
diff --git a/src/arch/riscv/include/arch/io.h b/src/arch/riscv/include/arch/io.h
new file mode 100644
index 0000000..1890925
--- /dev/null
+++ b/src/arch/riscv/include/arch/io.h
@@ -0,0 +1,35 @@
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+#include <stdint.h>
+
+static inline void outb(uint8_t value, uint16_t port)
+{
+}
+
+static inline void outw(uint16_t value, uint16_t port)
+{
+}
+
+static inline void outl(uint32_t value, uint16_t port)
+{
+}
+
+
+static inline uint8_t inb(uint16_t port)
+{
+ return 0;
+}
+
+
+static inline uint16_t inw(uint16_t port)
+{
+ return 0;
+}
+
+static inline uint32_t inl(uint16_t port)
+{
+ return 0;
+}
+
+#endif
diff --git a/src/arch/riscv/include/arch/stages.h b/src/arch/riscv/include/arch/stages.h
new file mode 100644
index 0000000..2d1192a
--- /dev/null
+++ b/src/arch/riscv/include/arch/stages.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __ARCH_STAGES_H
+#define __ARCH_STAGES_H
+
+extern void main(void);
+
+void stage_entry(void) __attribute__((section(".text.stage_entry.riscv")));
+void stage_exit(void *);
+void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long size);
+
+#endif
diff --git a/src/arch/riscv/include/bootblock_common.h b/src/arch/riscv/include/bootblock_common.h
new file mode 100644
index 0000000..fe2c982
--- /dev/null
+++ b/src/arch/riscv/include/bootblock_common.h
@@ -0,0 +1,16 @@
+#ifdef CONFIG_BOOTBLOCK_CPU_INIT
+#include CONFIG_BOOTBLOCK_CPU_INIT
+#endif
+
+// I'm disappointed that we let this kind of thing creep in.
+// we null out functions with this kind of stuff, AND weak symbols,
+// AND empty cpp function defines. What's next? Ouija boards?
+#if 0
+#ifdef CONFIG_BOOTBLOCK_MAINBOARD_INIT
+#include CONFIG_BOOTBLOCK_MAINBOARD_INIT
+#else
+static void bootblock_mainboard_init(void)
+{
+}
+#endif
+#endif
diff --git a/src/arch/riscv/include/stdint.h b/src/arch/riscv/include/stdint.h
new file mode 100644
index 0000000..a14d053
--- /dev/null
+++ b/src/arch/riscv/include/stdint.h
@@ -0,0 +1,60 @@
+#ifndef RISCV_STDINT_H
+#define RISCV_STDINT_H
+
+/* 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;
+
+typedef unsigned long long uint64_t;
+typedef signed long long int64_t;
+
+/* 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;
+
+typedef unsigned long long uint_least64_t;
+typedef signed long long int_least64_t;
+
+/* 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;
+
+typedef unsigned long long uint_fast64_t;
+typedef signed long long int_fast64_t;
+
+typedef long long int intmax_t;
+typedef unsigned long long uintmax_t;
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+
+
+/* Types for `void *' pointers. */
+typedef s64 intptr_t;
+typedef u64 uintptr_t;
+
+#endif /* RISCV_STDINT_H */
diff --git a/src/arch/riscv/misc.c b/src/arch/riscv/misc.c
new file mode 100644
index 0000000..6e64028
--- /dev/null
+++ b/src/arch/riscv/misc.c
@@ -0,0 +1,9 @@
+#include <delay.h>
+
+void init_timer(void)
+{
+}
+
+void udelay(unsigned int n)
+{
+}
diff --git a/src/arch/riscv/prologue.inc b/src/arch/riscv/prologue.inc
new file mode 100644
index 0000000..8cf67c0
--- /dev/null
+++ b/src/arch/riscv/prologue.inc
@@ -0,0 +1,22 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2002 Eric Biederman
+ *
+ * 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
+ */
+
+.section ".rom.data", "a", @progbits
+.section ".rom.text", "ax", @progbits
+
diff --git a/src/arch/riscv/ramstage.ld b/src/arch/riscv/ramstage.ld
new file mode 100644
index 0000000..f668090
--- /dev/null
+++ b/src/arch/riscv/ramstage.ld
@@ -0,0 +1,136 @@
+/*
+ * Memory map:
+ *
+ * CONFIG_RAMBASE : text segment
+ * : rodata segment
+ * : data segment
+ * : bss segment
+ * : stack
+ * : heap
+ */
+/*
+ * Copyright 2013 Google Inc.
+ * Bootstrap code for the STPC Consumer
+ * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
+ */
+
+/*
+ * Written by Johan Rydberg, based on work by Daniel Kahlin.
+ * Rewritten by Eric Biederman
+ * 2005.12 yhlu add ramstage cross the vga font buffer handling
+ */
+
+/* We use ELF as output format. So that we can debug the code in some form. */
+INCLUDE ldoptions
+
+ENTRY(stage_entry)
+
+PHDRS
+{
+ to_load PT_LOAD;
+}
+
+SECTIONS
+{
+ . = CONFIG_SYS_SDRAM_BASE;
+ /* First we place the code and read only data (typically const declared).
+ * This could theoretically be placed in rom.
+ */
+ .text : {
+ _text = .;
+ _start = .;
+ *(.text.stage_entry.riscv);
+ *(.text);
+ *(.text.*);
+ . = ALIGN(16);
+ _etext = .;
+ } : to_load
+
+ .ctors : {
+ . = ALIGN(0x100);
+ __CTOR_LIST__ = .;
+ *(.ctors);
+ LONG(0);
+ __CTOR_END__ = .;
+ }
+
+ .rodata : {
+ _rodata = .;
+ . = ALIGN(4);
+ console_drivers = .;
+ *(.rodata.console_drivers)
+ econsole_drivers = . ;
+ . = ALIGN(4);
+ pci_drivers = . ;
+ *(.rodata.pci_driver)
+ epci_drivers = . ;
+ cpu_drivers = . ;
+ *(.rodata.cpu_driver)
+ ecpu_drivers = . ;
+ _bs_init_begin = .;
+ *(.bs_init)
+ _bs_init_end = .;
+ *(.rodata)
+ *(.rodata.*)
+ /* kevinh/Ispiri - Added an align, because the objcopy tool
+ * incorrectly converts sections that are not long word aligned.
+ */
+ . = ALIGN(4);
+
+ _erodata = .;
+ }
+ /* After the code we place initialized data (typically initialized
+ * global variables). This gets copied into ram by startup code.
+ * __data_start and __data_end shows where in ram this should be placed,
+ * whereas __data_loadstart and __data_loadend shows where in rom to
+ * copy from.
+ */
+ .data : {
+ _data = .;
+ *(.data)
+ _edata = .;
+ }
+
+ /* bss does not contain data, it is just a space that should be zero
+ * initialized on startup. (typically uninitialized global variables)
+ * crt0.S fills between _bss and _ebss with zeroes.
+ */
+ _bss = .;
+ .bss . : {
+ *(.bss)
+ *(.sbss)
+ *(COMMON)
+ }
+ _ebss = .;
+ _end = .;
+
+ /* coreboot really "ends" here. Only heap and stack are placed after
+ * this line.
+ */
+
+ _heap = .;
+ .heap . : {
+ /* Reserve CONFIG_HEAP_SIZE bytes for the heap */
+ . = CONFIG_HEAP_SIZE ;
+ . = ALIGN(4);
+ }
+ _eheap = .;
+
+ _stack = CONFIG_STACK_BOTTOM;
+ _estack = CONFIG_STACK_TOP;
+
+ /* The ram segment. This includes all memory used by the memory
+ * resident copy of coreboot, except the tables that are produced on
+ * the fly, but including stack and heap.
+ */
+ _ram_seg = _text;
+ _eram_seg = _eheap;
+
+ /* Discard the sections we don't need/want */
+
+ /DISCARD/ : {
+ *(.comment)
+ *(.note)
+ *(.note.*)
+ }
+}
diff --git a/src/arch/riscv/rom_media.c b/src/arch/riscv/rom_media.c
new file mode 100644
index 0000000..e50026a
--- /dev/null
+++ b/src/arch/riscv/rom_media.c
@@ -0,0 +1,93 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 The Chromium OS Authors. All rights reserved.
+ *
+ * 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 <cbfs.h>
+#include <string.h>
+
+#ifdef LIBPAYLOAD
+# define printk(x...)
+# define init_default_cbfs_media libpayload_init_default_cbfs_media
+ extern int libpayload_init_default_cbfs_media(struct cbfs_media *media);
+#else
+# include <console/console.h>
+#endif
+
+// Implementation of memory-mapped ROM media source on X86.
+
+static int rom_media_open(struct cbfs_media *media) {
+ return 0;
+}
+
+static void *rom_media_map(struct cbfs_media *media, size_t offset, size_t count) {
+ void *ptr;
+ // Some address (ex, pointer to master header) may be given in memory
+ // mapped location. To workaround that, we handle >0xf0000000 as real
+ // memory pointer.
+
+ ptr = (void*)offset;
+ return ptr;
+}
+
+static void *rom_media_unmap(struct cbfs_media *media, const void *address) {
+ return NULL;
+}
+
+static size_t rom_media_read(struct cbfs_media *media, void *dest, size_t offset,
+ size_t count) {
+ void *ptr = rom_media_map(media, offset, count);
+ memcpy(dest, ptr, count);
+ rom_media_unmap(media, ptr);
+ return count;
+}
+
+static int rom_media_close(struct cbfs_media *media) {
+ return 0;
+}
+
+static int init_rom_media_cbfs(struct cbfs_media *media) {
+ extern unsigned long _cbfs_master_header;
+ // On X86, we always keep a reference of pointer to CBFS header in
+ // 0xfffffffc, and the pointer is still a memory-mapped address.
+ // Since the CBFS core always use ROM offset, we need to figure out
+ // header->romsize even before media is initialized.
+ struct cbfs_header *header = (struct cbfs_header*)_cbfs_master_header;
+ if (CBFS_HEADER_MAGIC != ntohl(header->magic)) {
+ printk(BIOS_ERR, "Invalid CBFS master header at %p\n", header);
+ return -1;
+ } else {
+ uint32_t romsize = ntohl(header->romsize);
+ media->context = (void*)(uintptr_t)romsize;
+#if defined(CONFIG_ROM_SIZE)
+ if (CONFIG_ROM_SIZE != romsize)
+ printk(BIOS_INFO, "Warning: rom size unmatch (%d/%d)\n",
+ CONFIG_ROM_SIZE, romsize);
+#endif
+ }
+ media->open = rom_media_open;
+ media->close = rom_media_close;
+ media->map = rom_media_map;
+ media->unmap = rom_media_unmap;
+ media->read = rom_media_read;
+ return 0;
+}
+
+int init_default_cbfs_media(struct cbfs_media *media) {
+ return init_rom_media_cbfs(media);
+}
diff --git a/src/arch/riscv/romstage.ld b/src/arch/riscv/romstage.ld
new file mode 100644
index 0000000..32dc2cb
--- /dev/null
+++ b/src/arch/riscv/romstage.ld
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 Advanced Micro Devices, Inc.
+ * Copyright (C) 2008-2010 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
+ */
+
+/* We use ELF as output format. So that we can debug the code in some form. */
+OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
+OUTPUT_ARCH(riscv)
+
+TARGET(binary)
+SECTIONS
+{
+ . = 0x2000 /*ROMSTAGE_BASE*/;
+
+ .rom . : {
+ _rom = .;
+ *(.rom.text);
+ *(.rom.data);
+ *(.rodata);
+ *(.rodata.*);
+ *(.rom.data.*);
+ . = ALIGN(16);
+ _car_migrate_start = .;
+ *(.car.migrate);
+ LONG(0);
+ _car_migrate_end = .;
+ . = ALIGN(16);
+ _erom = .;
+ }
+
+ /DISCARD/ : {
+ *(.comment)
+ *(.note)
+ *(.comment.*)
+ *(.note.*)
+ *(.eh_frame);
+ }
+
+}
diff --git a/src/arch/riscv/stages.c b/src/arch/riscv/stages.c
new file mode 100644
index 0000000..570ba9e
--- /dev/null
+++ b/src/arch/riscv/stages.c
@@ -0,0 +1,52 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * This file contains entry/exit functions for each stage during coreboot
+ * execution (bootblock entry and ramstage exit will depend on external
+ * loading).
+ *
+ * Entry points must be placed at the location the previous stage jumps
+ * to (the lowest address in the stage image). This is done by giving
+ * stage_entry() its own section in .text and placing it first in the
+ * linker script.
+ */
+
+#include <arch/stages.h>
+
+void stage_entry(void)
+{
+ main();
+}
+
+/* we had marked 'doit' as 'noreturn'.
+ * There is no apparent harm in leaving it as something we can return from, and in the one
+ * case where we call a payload, the payload is allowed to return.
+ * Hence, leave it as something we can return from.
+ */
+void stage_exit(void *addr)
+{
+ void (*doit)(void) = addr;
+ /*
+ * Most stages load code so we need to sync caches here. Should maybe
+ * go into cbfs_load_stage() instead...
+ */
+ //cache_sync_instructions();
+ doit();
+}
diff --git a/src/arch/riscv/tables.c b/src/arch/riscv/tables.c
new file mode 100644
index 0000000..58c9e7d
--- /dev/null
+++ b/src/arch/riscv/tables.c
@@ -0,0 +1,93 @@
+/*
+ * 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)
+
+#if ! CONFIG_DYNAMIC_CBMEM
+/*
+ * 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;
+#endif
+
+void cbmem_arch_init(void)
+{
+}
+
+// WTF. this does not agre with the prototype!
+static struct lb_memory *wtf_write_tables(void)
+{
+ unsigned long table_pointer, new_table_pointer;
+
+#if ! CONFIG_DYNAMIC_CBMEM
+ 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);
+#endif
+
+ 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();
+ return NULL;
+}
+void write_tables(void)
+{
+ wtf_write_tables();
+}
+
+void cbmem_fail_resume(void)
+{
+}
diff --git a/src/console/Kconfig b/src/console/Kconfig
index 619af56..0d32011 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
+ depends on ARCH_ARM || ARCH_RISCV
default n
help
Use console during the bootblock if supported
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 8de4fb7..e6a5575 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -57,7 +57,7 @@ ramstage-y += fallback_boot.c
ramstage-y += compute_ip_checksum.c
ramstage-y += version.c
ramstage-y += cbfs.c
-ramstage-y += lzma.c
+ramstage-$(CONFIG_COMPRESSED_PAYLOAD_LZMA) += lzma.c
#ramstage-y += lzmadecode.c
ramstage-y += stack.c
ramstage-y += clog2.c
diff --git a/src/mainboard/emulation/Kconfig b/src/mainboard/emulation/Kconfig
index 3fbc415..a1ee02d 100644
--- a/src/mainboard/emulation/Kconfig
+++ b/src/mainboard/emulation/Kconfig
@@ -12,6 +12,9 @@ config BOARD_EMULATION_QEMU_X86_Q35
config BOARD_EMULATION_QEMU_ARMV7
bool "QEMU armv7 (vexpress-a9)"
+config BOARD_EMULATION_QEMU_UCB_RISCV
+ bool "QEMU ucb riscv"
+
endchoice
config BOARD_EMULATION_QEMU_X86
@@ -22,6 +25,7 @@ config BOARD_EMULATION_QEMU_X86
source "src/mainboard/emulation/qemu-i440fx/Kconfig"
source "src/mainboard/emulation/qemu-q35/Kconfig"
source "src/mainboard/emulation/qemu-armv7/Kconfig"
+source "src/mainboard/emulation/qemu-riscv/Kconfig"
config MAINBOARD_VENDOR
string
diff --git a/src/mainboard/emulation/qemu-riscv/Kconfig b/src/mainboard/emulation/qemu-riscv/Kconfig
new file mode 100644
index 0000000..8f9c167
--- /dev/null
+++ b/src/mainboard/emulation/qemu-riscv/Kconfig
@@ -0,0 +1,93 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 Google Inc.
+##
+## This software is licensed under the terms of the GNU General Public
+## License version 2, as published by the Free Software Foundation, and
+## may be copied, distributed, and modified under those terms.
+##
+## 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.
+
+# To execute, do:
+# qemu-system-arm -M vexpress-a9 -m 1024M -nographic -kernel build/coreboot.rom
+
+if BOARD_EMULATION_QEMU_UCB_RISCV
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select SOC_UCB_RISCV
+ select BOARD_ROMSIZE_KB_4096
+ select ARCH_BOOTBLOCK_RISCV
+ select HAVE_UART_SPECIAL
+
+config MAINBOARD_DIR
+ string
+ default emulation/qemu-riscv
+
+config MAINBOARD_PART_NUMBER
+ string
+ default "QEMU RISCV"
+
+config MAX_CPUS
+ int
+ default 1
+
+config MAINBOARD_VENDOR
+ string
+ default "UCB"
+
+config DRAM_SIZE_MB
+ int
+ default 1024
+
+# Memory map for qemu riscv
+#
+# 0x0000_0000: jump instruction (by qemu)
+# 0x0002_0000: bootblock (entry of kernel / firmware)
+# 0x0003_0000: romstage, assume up to 128KB in size.
+# 0x0007_ff00: stack pointer
+# 0x0010_0000: CBFS header
+# 0x0011_0000: CBFS data
+# 0x0100_0000: reserved for ramstage
+
+config BOOTBLOCK_BASE
+ hex
+ default 0x00002000
+
+config ROMSTAGE_BASE
+ hex
+ default 0x00020000
+
+config RAMSTAGE_BASE
+ hex
+ default SYS_SDRAM_BASE
+
+config BOOTBLOCK_ROM_OFFSET
+ hex
+ default 0x0
+
+config CBFS_HEADER_ROM_OFFSET
+ hex
+ default 0x0100000
+
+config CBFS_ROM_OFFSET
+ hex
+ default 0x0110000
+
+config STACK_TOP
+ hex
+ default 0x0007ff00
+
+config STACK_BOTTOM
+ hex
+ default 0x00040000
+
+config STACK_SIZE
+ hex
+ default 0x0003ff00
+
+endif # BOARD_EMULATION_QEMU_UCB_RISCV
diff --git a/src/mainboard/emulation/qemu-riscv/Makefile.inc b/src/mainboard/emulation/qemu-riscv/Makefile.inc
new file mode 100644
index 0000000..cb1507d
--- /dev/null
+++ b/src/mainboard/emulation/qemu-riscv/Makefile.inc
@@ -0,0 +1,20 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2013 Google Inc.
+##
+## This software is licensed under the terms of the GNU General Public
+## License version 2, as published by the Free Software Foundation, and
+## may be copied, distributed, and modified under those terms.
+##
+## 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.
+
+bootblock-y += bootblock.c
+bootblock-y += uart.c frontend.c
+romstage-y += romstage.c
+romstage-y += uart.c frontend.c
+ramstage-y += media.c
+ramstage-y += uart.c frontend.c
diff --git a/src/mainboard/emulation/qemu-riscv/board_info.txt b/src/mainboard/emulation/qemu-riscv/board_info.txt
new file mode 100644
index 0000000..811e8e0
--- /dev/null
+++ b/src/mainboard/emulation/qemu-riscv/board_info.txt
@@ -0,0 +1,2 @@
+Board name: QEMU RISCV
+Category: emulation
diff --git a/src/mainboard/emulation/qemu-riscv/bootblock.c b/src/mainboard/emulation/qemu-riscv/bootblock.c
new file mode 100644
index 0000000..ed10032
--- /dev/null
+++ b/src/mainboard/emulation/qemu-riscv/bootblock.c
@@ -0,0 +1,56 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/exception.h>
+#include <arch/hlt.h>
+#include <bootblock_common.h>
+#include <cbfs.h>
+#include <console/console.h>
+#include <arch/stages.h>
+
+// the qemu part of all this is very, very non-hardware like.
+// so it gets its own bootblock.
+void main(void)
+{
+ // unclear we need it.
+ // vm_init();
+
+ void *entry;
+
+ if (CONFIG_BOOTBLOCK_CONSOLE) {
+ console_init();
+ exception_init();
+ }
+
+ //clock_init();
+
+ //bootblock_mainboard_init();
+ // SOON.
+ entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/romstage");
+ if (! entry) {
+ printk(BIOS_EMERG, "AAAAAAAAAAAAAA no romstage!\n");
+ while (1);
+ } else {
+ //clock_cpu0_config_and_reset(entry);
+ }
+
+ // clean up any clocks. placeholder
+ //clock_halt_avp();
+ stage_exit(entry);
+}
diff --git a/src/mainboard/emulation/qemu-riscv/devicetree.cb b/src/mainboard/emulation/qemu-riscv/devicetree.cb
new file mode 100644
index 0000000..c32cc59
--- /dev/null
+++ b/src/mainboard/emulation/qemu-riscv/devicetree.cb
@@ -0,0 +1,19 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 Google, Inc.
+##
+## This software is licensed under the terms of the GNU General Public
+## License version 2, as published by the Free Software Foundation, and
+## may be copied, distributed, and modified under those terms.
+##
+## 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.
+
+chip soc/ucb/riscv
+ chip drivers/generic/generic # I2C0 controller
+ device i2c 6 on end # Fake component for testing
+ end
+end
diff --git a/src/mainboard/emulation/qemu-riscv/frontend.c b/src/mainboard/emulation/qemu-riscv/frontend.c
new file mode 100644
index 0000000..9c3ab27
--- /dev/null
+++ b/src/mainboard/emulation/qemu-riscv/frontend.c
@@ -0,0 +1,32 @@
+// See LICENSE for license details.
+
+#include <arch/atomic.h>
+#include <stdint.h>
+#include "frontend.h"
+
+long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4)
+{
+ static volatile uint64_t magic_mem[8];
+
+ static spinlock_t lock = SPINLOCK_INIT;
+ long irq = spinlock_lock_irqsave(&lock);
+
+ magic_mem[0] = n;
+ magic_mem[1] = a0;
+ magic_mem[2] = a1;
+ magic_mem[3] = a2;
+ magic_mem[4] = a3;
+ magic_mem[5] = a4;
+
+ mb();
+
+ write_csr(tohost, magic_mem);
+ while (swap_csr(fromhost, 0) == 0);
+
+ mb();
+
+ long ret = magic_mem[0];
+
+ spinlock_unlock_irqrestore(&lock, irq);
+ return ret;
+}
diff --git a/src/mainboard/emulation/qemu-riscv/frontend.h b/src/mainboard/emulation/qemu-riscv/frontend.h
new file mode 100644
index 0000000..edbf22a
--- /dev/null
+++ b/src/mainboard/emulation/qemu-riscv/frontend.h
@@ -0,0 +1,8 @@
+// See LICENSE for license details.
+
+#ifndef _RISCV_FRONTEND_H
+#define _RISCV_FRONTEND_H
+
+long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4);
+
+#endif
diff --git a/src/mainboard/emulation/qemu-riscv/mainboard.c b/src/mainboard/emulation/qemu-riscv/mainboard.c
new file mode 100644
index 0000000..e75ea4e
--- /dev/null
+++ b/src/mainboard/emulation/qemu-riscv/mainboard.c
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <console/console.h>
+#include <device/device.h>
+
+static void mainboard_enable(device_t dev)
+{
+ printk(BIOS_INFO, "Enable qemu/riscv device...\n");
+}
+
+struct chip_operations mainboard_ops = {
+ .enable_dev = mainboard_enable,
+};
diff --git a/src/mainboard/emulation/qemu-riscv/media.c b/src/mainboard/emulation/qemu-riscv/media.c
new file mode 100644
index 0000000..c01185b
--- /dev/null
+++ b/src/mainboard/emulation/qemu-riscv/media.c
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <cbfs.h>
+#include <string.h>
+#include <console/console.h>
+#include <lib.h>
+
+/* Simple memory-mapped ROM emulation. */
+
+static int emu_rom_open(struct cbfs_media *media)
+{
+ return 0;
+}
+
+static void *emu_rom_map(struct cbfs_media *media, size_t offset, size_t count)
+{
+ return (void*)0;
+}
+
+static void *emu_rom_unmap(struct cbfs_media *media, const void *address)
+{
+ return NULL;
+}
+
+static size_t emu_rom_read(struct cbfs_media *media, void *dest, size_t offset,
+ size_t count)
+{
+/* void *ptr = emu_rom_map(media, offset, count);
+ memcpy(dest, ptr, count);
+ emu_rom_unmap(media, ptr);*/
+ return count;
+}
+
+static int emu_rom_close(struct cbfs_media *media)
+{
+ return 0;
+}
+
+int init_emu_rom_cbfs_media(struct cbfs_media *media);
+
+int init_emu_rom_cbfs_media(struct cbfs_media *media)
+{
+ media->open = emu_rom_open;
+ media->close = emu_rom_close;
+ media->map = emu_rom_map;
+ media->unmap = emu_rom_unmap;
+ media->read = emu_rom_read;
+ return 0;
+}
+
+int init_default_cbfs_media(struct cbfs_media *media)
+{
+ return init_emu_rom_cbfs_media(media);
+}
+
+// bug in coreboot. Fix me.
+// even if you have no use for lzma cbfs demands it.
+// and the ulzma code is terrible -- full of bad 32/64 bad things.
+unsigned long ulzma(unsigned char *src, unsigned char *dst)
+{
+ return 0;
+}
diff --git a/src/mainboard/emulation/qemu-riscv/romstage.c b/src/mainboard/emulation/qemu-riscv/romstage.c
new file mode 100644
index 0000000..00dfecd
--- /dev/null
+++ b/src/mainboard/emulation/qemu-riscv/romstage.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <cbfs.h>
+#include <console/console.h>
+#include <arch/stages.h>
+
+void main(void)
+{
+ void *entry;
+
+ console_init();
+
+ entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/ramstage");
+
+ stage_exit(entry);
+}
diff --git a/src/mainboard/emulation/qemu-riscv/uart.c b/src/mainboard/emulation/qemu-riscv/uart.c
new file mode 100644
index 0000000..9063419
--- /dev/null
+++ b/src/mainboard/emulation/qemu-riscv/uart.c
@@ -0,0 +1,64 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <types.h>
+#include <console/uart.h>
+#include <arch/io.h>
+#include <boot/coreboot_tables.h>
+#include "frontend.h"
+
+static int buf[1];
+uintptr_t uart_platform_base(int idx)
+{
+ return 1;
+}
+
+void uart_init(int idx)
+{
+ //populate_mapping(buf, size, PROT_WRITE);
+}
+
+unsigned char uart_rx_byte(int idx)
+{
+ frontend_syscall(63, 0, (uintptr_t)buf, 1, 0, 0);
+ return buf[0];
+}
+
+void uart_tx_byte(int idx, unsigned char data)
+{
+ buf[0] = data;
+ frontend_syscall(64, 1, (uintptr_t)buf, 1, 0, 0);
+}
+
+void uart_tx_flush(int idx)
+{
+}
+
+#ifndef __PRE_RAM__
+void uart_fill_lb(void *data)
+{
+ struct lb_serial serial;
+ serial.type = LB_SERIAL_TYPE_MEMORY_MAPPED;
+ serial.baseaddr = 0;
+ serial.baud = 115200;
+ lb_add_serial(&serial, data);
+
+ lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM, data);
+}
+#endif
diff --git a/src/soc/Kconfig b/src/soc/Kconfig
index 53d7b90..0412919 100644
--- a/src/soc/Kconfig
+++ b/src/soc/Kconfig
@@ -2,3 +2,4 @@ source src/soc/intel/Kconfig
source src/soc/nvidia/Kconfig
source src/soc/qualcomm/Kconfig
source src/soc/samsung/Kconfig
+source src/soc/ucb/Kconfig
diff --git a/src/soc/Makefile.inc b/src/soc/Makefile.inc
index 6939346..ab3e166 100644
--- a/src/soc/Makefile.inc
+++ b/src/soc/Makefile.inc
@@ -5,3 +5,4 @@ subdirs-y += intel
subdirs-y += nvidia
subdirs-y += qualcomm
subdirs-y += samsung
+subdirs-y += ucb
diff --git a/src/soc/ucb/Kconfig b/src/soc/ucb/Kconfig
new file mode 100644
index 0000000..7af50cb
--- /dev/null
+++ b/src/soc/ucb/Kconfig
@@ -0,0 +1 @@
+source src/soc/ucb/riscv/Kconfig
diff --git a/src/soc/ucb/Makefile.inc b/src/soc/ucb/Makefile.inc
new file mode 100644
index 0000000..35bc728
--- /dev/null
+++ b/src/soc/ucb/Makefile.inc
@@ -0,0 +1 @@
+subdirs-$(CONFIG_CPU_UCB_RISCV) += riscv
diff --git a/src/soc/ucb/riscv/Kconfig b/src/soc/ucb/riscv/Kconfig
new file mode 100644
index 0000000..9bfd5d0
--- /dev/null
+++ b/src/soc/ucb/riscv/Kconfig
@@ -0,0 +1,69 @@
+config SOC_UCB_RISCV
+ select ARCH_RISCV
+ select ARCH_BOOTBLOCK_RISCV
+ select ARCH_ROMSTAGE_RISCV
+ select ARCH_RAMSTAGE_RISCV
+ select DYNAMIC_CBMEM
+ bool
+ default n
+
+if SOC_UCB_RISCV
+
+# ROM image layout.
+#
+# 0x02000 Bootblock
+
+config BOOTBLOCK_ROM_OFFSET
+ hex
+ default 0x0
+
+config CBFS_HEADER_ROM_OFFSET
+ hex "offset of master CBFS header in ROM"
+ default 0x18000
+
+config CBFS_ROM_OFFSET
+ hex "offset of CBFS data in ROM"
+ default 0x18080
+
+config SYS_SDRAM_BASE
+ hex
+ default 0x80000000
+
+config BOOTBLOCK_BASE
+ hex
+ default 0x4000e000
+
+config ROMSTAGE_BASE
+ hex
+ default 0x40017000
+
+config RAMSTAGE_BASE
+ hex
+ default 0x80200000
+
+config STACK_TOP
+ hex
+ default 0x4000c000
+
+config STACK_BOTTOM
+ hex
+ default 0x40004000
+
+config STACK_SIZE
+ hex
+ default 0x800
+
+# TTB needs to be aligned to 16KB. Stick it in iRAM.
+config TTB_BUFFER
+ hex "memory address of the TTB buffer"
+ default 0x40000000
+
+config CBFS_CACHE_ADDRESS
+ hex "memory address to put CBFS cache data"
+ default 0x40020000
+
+config CBFS_CACHE_SIZE
+ hex "size of CBFS cache data"
+ default 0x00020000
+
+endif
diff --git a/toolchain.inc b/toolchain.inc
index 2a68576..3db2957 100644
--- a/toolchain.inc
+++ b/toolchain.inc
@@ -57,6 +57,7 @@ ARCHDIR-i386 := x86
ARCHDIR-x86_32 := x86
ARCHDIR-arm := arm
ARCHDIR-arm64 := arm64
+ARCHDIR-riscv := riscv
CFLAGS_arm := -mno-unaligned-access -ffunction-sections -fdata-sections
Paul Menzel (paulepanter(a)users.sourceforge.net) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7091
-gerrit
commit 67cff825b2b33353900c3f4821fcd3075985b918
Author: Paul Menzel <paulepanter(a)users.sourceforge.net>
Date: Fri Oct 17 12:54:13 2014 +0200
util/cbmem/cbmem: Remove obsolete comment
Originally the utility cbmem was just used for reading out the time
stamps and was later extented. The removed comment is currently at the
wrong place and `cbmem` does much more now, so that the comment is just
removed.
Change-Id: Ief1d7aef38a4b439e3e224e6e6c65f7aa57f821f
Signed-off-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
---
util/cbmem/cbmem.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/util/cbmem/cbmem.c b/util/cbmem/cbmem.c
index 4dcfe91..3a5a428 100644
--- a/util/cbmem/cbmem.c
+++ b/util/cbmem/cbmem.c
@@ -212,7 +212,6 @@ static int parse_cbtable(u64 address)
debug("Found!\n");
for (j = 0; j < lbh->table_bytes; j += lbr_p->size) {
- /* look for the timestamp table */
lbr_p = (struct lb_record*) ((char *)lbtable + j);
debug(" coreboot table entry 0x%02x\n", lbr_p->tag);
switch (lbr_p->tag) {
the following patch was just integrated into master:
commit 7f7fb6f9baea8df19190f637e1395658a6be0c4a
Author: Vladimir Serbinenko <phcoder(a)gmail.com>
Date: Wed Oct 15 22:30:16 2014 +0200
macbook21: Kill empty gpe.asl
Change-Id: I4ed04ecbc9e11200577cc2b6ede0e05af9f346fa
Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com>
Reviewed-on: http://review.coreboot.org/7082
Tested-by: build bot (Jenkins)
Reviewed-by: Idwer Vollering <vidwer(a)gmail.com>
See http://review.coreboot.org/7082 for details.
-gerrit
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4304
-gerrit
commit 9d6230d299aff1289571448b24747f9c181efc3a
Author: Stefan Reinauer <reinauer(a)chromium.org>
Date: Mon Dec 2 15:47:13 2013 -0800
filo: initial ARM support
Change-Id: I058340985d3aad6ff408f3d0db7d52a45e35a21a
---
Config.in | 17 +++-
Makefile | 37 ++++++--
arm/Makefile.inc | 23 +++++
arm/include/arch/elf.h | 5 +
arm/include/arch/timer.h | 32 +++++++
arm/ldscript | 93 ++++++++++++++++++
main/grub/builtins.c | 6 ++
util/xcompile/xcompile | 242 ++++++++++++++++++++++++++++++++++-------------
8 files changed, 378 insertions(+), 77 deletions(-)
diff --git a/Config.in b/Config.in
index cc48bd3..67766fd 100644
--- a/Config.in
+++ b/Config.in
@@ -5,12 +5,21 @@
mainmenu "FILO Configuration"
# When (if) we support multiple architectures, this will become an option.
+choice
+ prompt "Build for architecture"
+ default TARGET_I386
+
config TARGET_I386
- bool
- default y
+ bool "x86"
+
+config TARGET_ARM
+ bool "ARM"
+
+endchoice
config MULTIBOOT_IMAGE
bool "Include a MultiBoot header"
+ depends on TARGET_I386
default y
help
Including a MultiBoot header makes FILO chainloadable by MultiBoot
@@ -104,6 +113,7 @@ menu "Drivers"
config IDE_DISK
bool "IDE DISK support"
default y
+ depends on TARGET_I386
help
Driver for hard disk, CompactFlash, and CD-ROM on IDE bus
@@ -140,6 +150,7 @@ config IDE_NEW_DISK
bool "New IDE driver"
default n
depends on !IDE_DISK
+ depends on TARGET_I386
help
Jens Axboe's fine IDE driver
@@ -234,7 +245,7 @@ config FSYS_ISO9660
config ELTORITO
bool "El Torito bootable CDROMs"
default y
- depends on FSYS_ISO9660
+ depends on FSYS_ISO9660 && TARGET_I386
help
Support for boot disk image in bootable CD-ROM (El Torito)
diff --git a/Makefile b/Makefile
index a860236..a0aa552 100644
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,7 @@ export obj := $(src)/build
export objk := $(src)/build/util/kconfig
ifndef LIBCONFIG_PATH
- LIBCONFIG_PATH := $(src)/../libpayload
+ LIBCONFIG_PATH := $(src)/../coreboot/payloads/libpayload
endif
export LIBCONFIG_PATH
@@ -57,17 +57,9 @@ try-run = $(shell set -e; \
fi; \
rm -rf "$$TMP")
-cc-option = $(call try-run,$(CC) $(1) -S -xc /dev/null -o "$$TMP",$(1),$(2))
-
$(if $(wildcard .xcompile),,$(shell bash util/xcompile/xcompile > .xcompile))
include .xcompile
-CROSS_PREFIX ?=
-CC ?= $(CROSS_PREFIX)gcc -m32
-AS ?= $(CROSS_PREFIX)as --32
-LD ?= $(CROSS_PREFIX)ld -belf32-i386
-NM ?= $(CROSS_PREFIX)nm
-STRIP ?= $(CROSS_PREFIX)strip
HOSTCC ?= gcc
HOSTCXX ?= g++
HOSTCFLAGS := -I$(srck) -I$(objk) -pipe
@@ -81,6 +73,30 @@ include util/kconfig/Makefile
else
include $(src)/.config
+ARCH-$(CONFIG_TARGET_I386) := x86
+ARCH-$(CONFIG_TARGET_ARM) := arm
+
+CC := $(CC_$(ARCH-y))
+AS := $(AS_$(ARCH-y))
+LD := $(LD_$(ARCH-y))
+NM := $(NM_$(ARCH-y))
+OBJCOPY := $(OBJCOPY_$(ARCH-y))
+OBJDUMP := $(OBJDUMP_$(ARCH-y))
+READELF := $(READELF_$(ARCH-y))
+STRIP := $(STRIP_$(ARCH-y))
+AR := $(AR_$(ARCH-y))
+
+CFLAGS += $(CFLAGS_$(ARCH-y))
+
+cc-option = $(call try-run,$(CC) $(1) -S -xc /dev/null -o "$$TMP",$(1),$(2))
+
+CROSS_PREFIX ?=
+
+CC ?= $(CROSS_PREFIX)gcc -m32
+AS ?= $(CROSS_PREFIX)as --32
+LD ?= $(CROSS_PREFIX)ld -belf32-i386
+NM ?= $(CROSS_PREFIX)nm
+STRIP ?= $(CROSS_PREFIX)strip
LIBPAYLOAD_PREFIX ?= $(obj)/libpayload
LIBPAYLOAD = $(LIBPAYLOAD_PREFIX)/lib/libpayload.a
@@ -89,6 +105,7 @@ LIBGCC = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
GCCINCDIR = $(shell $(CC) -print-search-dirs | head -n 1 | cut -d' ' -f2)include
ARCHDIR-$(CONFIG_TARGET_I386) := x86
+ARCHDIR-$(CONFIG_TARGET_ARM) := arm
CPPFLAGS := -nostdinc -imacros $(obj)/config.h
CPPFLAGS += -I$(INCPAYLOAD) -I$(INCPAYLOAD)/$(ARCHDIR-y)
@@ -120,7 +137,7 @@ else
libpayload: $(LIBPAYLOAD)
$(LIBPAYLOAD): $(src)/$(LIB_CONFIG)
@printf "Building libpayload...\n"
- $(MAKE) -C $(LIBCONFIG_PATH) obj=$(obj)/libpayload-build distclean
+ CROSS_COMPILE_$(ARCH-y)=$(CROSS_COMPILE_$(ARCH-y)) $(MAKE) -C $(LIBCONFIG_PATH) obj=$(obj)/libpayload-build distclean
cp lib.config $(LIBCONFIG_PATH)/.config
mkdir -p $(LIBCONFIG_PATH)/build
$(MAKE) -C $(LIBCONFIG_PATH) obj=$(obj)/libpayload-build oldconfig
diff --git a/arm/Makefile.inc b/arm/Makefile.inc
new file mode 100644
index 0000000..4ccb409
--- /dev/null
+++ b/arm/Makefile.inc
@@ -0,0 +1,23 @@
+#
+# 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; 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+#TARGETS-$(CONFIG_TARGET_I386) += x86/context.o x86/switch.S.o x86/segment.o
+#TARGETS-$(CONFIG_TARGET_I386) += x86/timer.o x86/sys_info.o
+#TARGETS-$(CONFIG_LINUX_LOADER) += x86/linux_load.o
+#TARGETS-$(CONFIG_WINCE_LOADER) += x86/wince_load.o
+#TARGETS-$(CONFIG_ARTEC_BOOT) += x86/artecboot.o
diff --git a/arm/include/arch/elf.h b/arm/include/arch/elf.h
new file mode 100644
index 0000000..2a5bbbf
--- /dev/null
+++ b/arm/include/arch/elf.h
@@ -0,0 +1,5 @@
+#define ARCH_ELF_CLASS ELFCLASS32
+#define ARCH_ELF_DATA ELFDATA2LSB
+#define ARCH_ELF_MACHINE_OK(x) ((x)==EM_ARM)
+typedef Elf32_Ehdr Elf_ehdr;
+typedef Elf32_Phdr Elf_phdr;
diff --git a/arm/include/arch/timer.h b/arm/include/arch/timer.h
new file mode 100644
index 0000000..3cdd9b4
--- /dev/null
+++ b/arm/include/arch/timer.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of FILO.
+ *
+ * (C) 2004-2008 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
+ */
+
+#ifndef TIMER_H
+#define TIMER_H
+
+extern u32 cpu_khz;
+
+u64 currticks(void);
+int getrtsecs (void);
+
+#define TICKS_PER_SEC (cpu_khz * 1000)
+#define TICKS_PER_USEC (cpu_khz / 1000)
+
+
+#endif /* TIMER_H */
diff --git a/arm/ldscript b/arm/ldscript
new file mode 100644
index 0000000..a6c7e11
--- /dev/null
+++ b/arm/ldscript
@@ -0,0 +1,93 @@
+/*
+ * This file is part of FILO.
+ *
+ * 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
+ */
+
+/* When started from General Software BIOS */
+/* BASE_ADDR = 0x40000; */
+/* When started from coreboot */
+BASE_ADDR = 0x100000;
+
+
+OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+ENTRY(entry)
+
+/* 1024KB heap and 64KB stack */
+HEAP_SIZE = 1 * 1024 * 1024;
+STACK_SIZE = 64 * 1024;
+
+SECTIONS
+{
+ . = BASE_ADDR;
+
+ /* Put Multiboot header near beginning of file, if any. */
+ .hdr : { *(.hdr) *(.hdr.*) }
+
+ /* Start of the program.
+ * Now the version string is in the note, we must include it
+ * in the program. Otherwise we lose the string after relocation. */
+ . = ALIGN(4096);
+ _start = .;
+
+ /* Putting ELF notes near beginning of file might help bootloaders.
+ * We discard .note sections other than .note.ELFBoot and .note.pinfo,
+ * because some versions of GCC generates useless ones. */
+ .note : { *(.note.ELFBoot) *(note.pinfo) }
+
+ /* Normal sections */
+ .boot : { *(.boot) *(.boot.*) }
+ .text : { *(.text) *(.text.*) }
+ .rodata : {
+ . = ALIGN(4);
+ drivers_start = .;
+ *(.rodata.drivers)
+ drivers_end = .;
+ *(.rodata)
+ *(.rodata.*)
+ }
+ .data : { *(.data) *(.data.*) }
+
+ .bss : {
+ *(.sbss)
+ *(.sbss.*)
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+
+ /* heap and stack */
+
+ . = ALIGN(16);
+ _heap = .;
+ . += HEAP_SIZE;
+ . = ALIGN(16);
+ _eheap = .;
+
+ _stack = .;
+ . += STACK_SIZE;
+ . = ALIGN(16);
+ _estack = .;
+ }
+
+ .initctx : {
+ /* Initial contents of stack. This MUST BE just after the stack. */
+ *(.initctx)
+ }
+
+ _end = .;
+
+ /DISCARD/ : { *(.comment) *(.note) }
+}
diff --git a/main/grub/builtins.c b/main/grub/builtins.c
index cd079d1..a2385c5 100644
--- a/main/grub/builtins.c
+++ b/main/grub/builtins.c
@@ -461,6 +461,7 @@ static struct builtin builtin_dumpmem = {
/* dumppm */
static int dumppm_func(char *arg, int flags)
{
+#if CONFIG_TARGET_I386
u16 pmbase;
pmbase = pci_read_config16(PCI_DEV(0,0x1f, 0), 0x40) & 0xfffe;
@@ -495,6 +496,7 @@ static int dumppm_func(char *arg, int flags)
grub_printf("pmbase+0x0070: 0x%02x (TCO_SW_IRQ_GEN)\n", inb(pmbase+0x0070));
grub_printf("pmbase+0x0072: 0x%04x (TCO_TMR)\n", inw(pmbase+0x0072));
#endif
+#endif
return 0;
}
@@ -857,6 +859,7 @@ static struct builtin builtin_initrd = {
#ifdef CONFIG_DEVELOPER_TOOLS
+#ifdef CONFIG_TARGET_I386
/* io */
static int io_func(char *arg, int flags)
{
@@ -964,6 +967,7 @@ static struct builtin builtin_io = {
"Read/write IO ports."
};
#endif
+#endif
/* kernel */
static int kernel_func(char *arg, int flags)
@@ -1931,8 +1935,10 @@ struct builtin *builtin_table[] = {
&builtin_hiddenmenu,
&builtin_initrd,
#ifdef CONFIG_DEVELOPER_TOOLS
+#ifdef CONFIG_TARGET_I386
&builtin_io,
#endif
+#endif
&builtin_kernel,
&builtin_keymap,
&builtin_lock,
diff --git a/util/xcompile/xcompile b/util/xcompile/xcompile
index 7c1adf3..9019788 100644
--- a/util/xcompile/xcompile
+++ b/util/xcompile/xcompile
@@ -3,6 +3,7 @@
# This file is part of the coreboot project.
#
# Copyright (C) 2007-2010 coresystems GmbH
+# Copyright (C) 2012 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
@@ -15,89 +16,202 @@
#
# 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
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
-testcc()
-{
- echo "_start(void) {}" > .$$$$.c
- $1 -nostdlib $2 .$$$$.c -o .$$$$.tmp 2>/dev/null >/dev/null
- ret=$?
- rm -f .$$$$.c .$$$$.tmp
- return $ret
+TMPFILE=""
+
+die() {
+ echo "ERROR: $*" >&2
+ exit 1
}
-for make in make gmake gnumake; do
- if [ "`$make --version 2>/dev/null | grep -c GNU`" -gt 0 ]; then
- MAKE=$make
- break
+clean_up() {
+ if [ -n "$TMPFILE" ]; then
+ rm -f "$TMPFILE" "$TMPFILE.c" "$TMPFILE.o"
fi
-done
+}
+
+program_exists() {
+ type "$1" >/dev/null 2>&1
+}
-GCCPREFIX=invalid
-TMPFILE=`mktemp /tmp/temp.XXXXXX 2>/dev/null || echo /tmp/temp.78gOIUGz`
-touch $TMPFILE
+testcc() {
+ local tmp_c="$TMPFILE.c"
+ local tmp_o="$TMPFILE.o"
+ rm -f "$tmp_c" "$tmp_o"
+ echo "void _start(void) {}" >"$tmp_c"
+ "$1" -nostdlib -Werror $2 "$tmp_c" -o "$tmp_o" >/dev/null 2>&1
+}
+
+testas() {
+ local gccprefixes="$1"
+ local twidth="$2"
+ local arch="$3"
+ local use_dash_twidth="$4"
+ local obj_file="$TMPFILE.o"
+ local full_arch="elf$twidth-$arch"
+
+ rm -f "$obj_file"
+ [ -n "$use_dash_twidth" ] && use_dash_twidth="--$twidth"
+ ${gccprefixes}as $use_dash_twidth -o "$obj_file" $TMPFILE 2>/dev/null ||
+ return 1
+
+ # Check output content type.
+ local obj_type="$(${gccprefixes}objdump -p $obj_file)"
+ local obj_arch="$(expr "$obj_type" : '.*format \(.[a-z0-9-]*\)')"
+ [ "$obj_arch" = "$full_arch" ] || return 1
+
+ # Architecture matched.
+ GCCPREFIX="$gccprefixes"
+
+ if [ -z "$use_dash_twidth" ]; then
+ ASFLAGS=""
+ CFLAGS=""
+ LDFLAGS=""
+ else
+ ASFLAGS="--$twidth"
+ CFLAGS="-m$twidth"
+ LDFLAGS="-b $full_arch"
-# This should be a loop over all supported architectures
-TARCH=i386
-TWIDTH=32
-for gccprefixes in `pwd`/../../util/crossgcc/xgcc/bin/${TARCH}-elf- ${TARCH}-elf- ""; do
- if ! which ${gccprefixes}as 2>/dev/null >/dev/null; then
- continue
- fi
- rm -f ${TMPFILE}.o
- if ${gccprefixes}as -o ${TMPFILE}.o ${TMPFILE}; then
- TYPE=`${gccprefixes}objdump -p ${TMPFILE}.o`
- if [ ${TYPE##* } == "elf${TWIDTH}-${TARCH}" ]; then
- GCCPREFIX=$gccprefixes
- ASFLAGS=
- CFLAGS=
- LDFLAGS=
- break
- fi
fi
- if ${gccprefixes}as --32 -o ${TMPFILE}.o ${TMPFILE}; then
- TYPE=`${gccprefixes}objdump -p ${TMPFILE}.o`
- if [ ${TYPE##* } == "elf${TWIDTH}-${TARCH}" ]; then
- GCCPREFIX=$gccprefixes
- ASFLAGS=--32
- CFLAGS="-m32 "
- LDFLAGS="-b elf32-i386"
- break
- fi
+
+ # Special parameters only available in dash_twidth mode.
+ [ -n "$use_dash_twidth" ] && case "$full_arch" in
+ "elf32-i386" )
+ LDFLAGS="$LDFLAGS -melf_i386"
+ CFLAGS="$CFLAGS -Wl,-b,elf32-i386 -Wl,-melf_i386"
+ ;;
+ esac
+
+ return 0
+}
+
+detect_special_flags() {
+ local architecture="$1"
+ # GCC 4.6 is much more picky about unused variables.
+ # Turn off it's warnings for now:
+ testcc "$CC" "$CFLAGS -Wno-unused-but-set-variable " &&
+ CFLAGS="$CFLAGS -Wno-unused-but-set-variable "
+
+ testcc "$CC" "$CFLAGS -Wa,--divide" &&
+ CFLAGS="$CFLAGS -Wa,--divide"
+ testcc "$CC" "$CFLAGS -fno-stack-protector"&&
+ CFLAGS="$CFLAGS -fno-stack-protector"
+ testcc "$CC" "$CFLAGS -Wl,--build-id=none" &&
+ CFLAGS="$CFLAGS -Wl,--build-id=none"
+
+ case "$architecture" in
+ x86 )
+ # Use bfd linker instead of gold if available:
+ testcc "$CC" "$CFLAGS -fuse-ld=bfd" &&
+ CFLAGS="$CFLAGS -fuse-ld=bfd" && LINKER_SUFFIX_i386='.bfd'
+ # Always build for i686 -- no sse/mmx instructions since SMM
+ # modules are compiled using these flags. Note that this
+ # doesn't prevent a project using xcompile to explicitly
+ # specify -mmsse, etc flags.
+ CFLAGS="$CFLAGS -march=i686"
+ ;;
+ arm )
+ ARMFLAGS=""
+ testcc "$CC" "$CFLAGS $ARMFLAGS" && CFLAGS="$CFLAGS $ARMFLAGS"
+ ;;
+ esac
+}
+
+report_arch_toolchain() {
+ cat <<EOF
+# elf${TWIDTH}-${TBFDARCH} toolchain (${GCCPREFIX}gcc)
+CC_${TARCH}:=${GCCPREFIX}gcc ${CFLAGS}
+AS_${TARCH}:=${GCCPREFIX}as ${ASFLAGS}
+LD_${TARCH}:=${GCCPREFIX}ld$(eval echo \${LINKER_SUFFIX_${TARCH}}) ${LDFLAGS}
+NM_${TARCH}:=${GCCPREFIX}nm
+OBJCOPY_${TARCH}:=${GCCPREFIX}objcopy
+OBJDUMP_${TARCH}:=${GCCPREFIX}objdump
+READELF_${TARCH}:=${GCCPREFIX}readelf
+STRIP_${TARCH}:=${GCCPREFIX}strip
+AR_${TARCH}:=${GCCPREFIX}ar
+
+EOF
+}
+
+# Create temporary file(s).
+TMPFILE="$(mktemp /tmp/temp.XXXX 2>/dev/null || echo /tmp/temp.78gOIUGz)"
+touch "$TMPFILE"
+trap clean_up EXIT
+
+# Architecture definition
+SUPPORTED_ARCHITECTURE="x86 arm"
+
+# ARM Architecture
+TARCH_arm="arm"
+TBFDARCH_arm="littlearm"
+TCLIST_arm="armv7a"
+TWIDTH_arm="32"
+
+# X86 Architecture
+TARCH_x86="i386"
+TBFDARCH_x86="i386"
+TCLIST_x86="i386 x86_64"
+TWIDTH_x86="32"
+XGCCPATH=${1:-"`pwd`/util/crossgcc/xgcc/bin/"}
+
+# This loops over all supported architectures.
+for architecture in $SUPPORTED_ARCHITECTURE; do
+ GCCPREFIX="invalid"
+ TARCH="$(eval echo \$TARCH_$architecture)"
+ TBFDARCH="$(eval echo \$TBFDARCH_$architecture)"
+ TCLIST="$(eval echo \$TCLIST_$architecture)"
+ TWIDTH="$(eval echo \$TWIDTH_$architecture)"
+ [ -z "$TARCH" -o -z "$TCLIST" -o -z "$TWIDTH" ] &&
+ die "Missing architecture definition for $architecture."
+
+ # To override toolchain, define CROSS_COMPILE_$arch or CROSS_COMPILE as
+ # environment variable.
+ # Ex: CROSS_COMPILE_arm="armv7a-cros-linux-gnueabi-"
+ # CROSS_COMPILE_x86="i686-pc-linux-gnu-"
+ search="$(eval echo \$CROSS_COMPILE_$architecture 2>/dev/null)"
+ search="$search $CROSS_COMPILE"
+ for toolchain in $TCLIST; do
+ search="$search $XGCCPATH$toolchain-elf-"
+ search="$search $toolchain-elf-"
+ search="$search $XGCCPATH$toolchain-eabi-"
+ search="$search $toolchain-eabi-"
+ done
+ echo "# $architecture TARCH_SEARCH=$search"
+
+ # Search toolchain by checking assembler capability.
+ for gccprefixes in $search ""; do
+ program_exists "${gccprefixes}as" || continue
+ testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "" && break
+ testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "TRUE" && break
+ done
+
+ if [ "$GCCPREFIX" = "invalid" ]; then
+ echo "Warning: no suitable GCC for $architecture." >&2
+ continue
fi
+ CC="${GCCPREFIX}"gcc
+
+ detect_special_flags "$architecture"
+ report_arch_toolchain
done
-rm -f $TMPFILE ${TMPFILE}.o
-if [ "$GCCPREFIX" = "invalid" ]; then
- echo '$(error no suitable gcc found)'
- exit 1
+if [ "$(${XGCCPATH}/iasl 2>/dev/null | grep -c ACPI)" -gt 0 ]; then
+ IASL=${XGCCPATH}iasl
+else
+ IASL=iasl
fi
-CC="${GCCPREFIX}gcc"
-testcc "$CC" "$CFLAGS-Wa,--divide " && CFLAGS="$CFLAGS-Wa,--divide "
-testcc "$CC" "$CFLAGS-fno-stack-protector " && CFLAGS="$CFLAGS-fno-stack-protector "
-testcc "$CC" "$CFLAGS-Wl,--build-id=none " && CFLAGS="$CFLAGS-Wl,--build-id=none "
-
-if which gcc 2>/dev/null >/dev/null; then
+if program_exists gcc; then
HOSTCC=gcc
else
HOSTCC=cc
fi
-cat << EOF
-# elf${TWIDTH}-${TARCH} toolchain
-AS:=${GCCPREFIX}as ${ASFLAGS}
-CC:=${GCCPREFIX}gcc ${CFLAGS}
-CPP:=${GCCPREFIX}cpp
-AR:=${GCCPREFIX}ar
-LD:=${GCCPREFIX}ld ${LDFLAGS}
-STRIP:=${GCCPREFIX}strip
-NM:=${GCCPREFIX}nm
-OBJCOPY:=${GCCPREFIX}objcopy
-OBJDUMP:=${GCCPREFIX}objdump
+cat <<EOF
+IASL:=${IASL}
# native toolchain
HOSTCC:=${HOSTCC}
EOF
-