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