提交 49cf7510 编写于 作者: T Tom Rini

Merge tag 'mips-pull-2020-07-18' of https://gitlab.denx.de/u-boot/custodians/u-boot-mips

- MIPS: refactor cache init and setup in start.S
- MIPS: sync asm header files with Linux 5.7
- MIPS: add initial support for Marvell Octeon MIPS64
......@@ -770,6 +770,13 @@ M: Ezequiel Garcia <ezequiel@collabora.com>
S: Maintained
F: arch/mips/mach-jz47xx/
MIPS Octeon
M: Aaron Williams <awilliams@marvell.com>
S: Maintained
F: arch/mips/mach-octeon/
F: arch/mips/include/asm/arch-octeon/
F: arch/mips/dts/mrvl,cn73xx.dtsi
MMC
M: Peng Fan <peng.fan@nxp.com>
S: Maintained
......
......@@ -106,6 +106,26 @@ config ARCH_JZ47XX
select OF_CONTROL
select DM
config ARCH_OCTEON
bool "Support Marvell Octeon CN7xxx platforms"
select CPU_CAVIUM_OCTEON
select DISPLAY_CPUINFO
select DMA_ADDR_T_64BIT
select DM
select DM_SERIAL
select DM_GPIO
select DM_ETH
select MIPS_L2_CACHE
select MIPS_MACH_EARLY_INIT
select MIPS_TUNE_OCTEON3
select ROM_EXCEPTION_VECTORS
select SUPPORTS_BIG_ENDIAN
select SUPPORTS_CPU_MIPS64_OCTEON
select PHYS_64BIT
select OF_CONTROL
select OF_LIVE
imply CMD_DM
config MACH_PIC32
bool "Support Microchip PIC32"
select DM
......@@ -160,6 +180,7 @@ source "arch/mips/mach-bmips/Kconfig"
source "arch/mips/mach-jz47xx/Kconfig"
source "arch/mips/mach-pic32/Kconfig"
source "arch/mips/mach-mtmips/Kconfig"
source "arch/mips/mach-octeon/Kconfig"
if MIPS
......@@ -233,6 +254,14 @@ config CPU_MIPS64_R6
Choose this option to build a kernel for release 6 or later of the
MIPS64 architecture.
config CPU_MIPS64_OCTEON
bool "Marvell Octeon series of CPUs"
depends on SUPPORTS_CPU_MIPS64_OCTEON
select 64BIT
help
Choose this option for Marvell Octeon CPUs. These CPUs are between
MIPS64 R5 and R6 with other extensions.
endchoice
menu "General setup"
......@@ -270,6 +299,39 @@ config MIPS_CACHE_INDEX_BASE
Normally this is CKSEG0. If the MIPS system needs to move this block
to some SRAM or ScratchPad RAM, adapt this option accordingly.
config MIPS_MACH_EARLY_INIT
bool "Enable mach specific very early init code"
help
Use this to enable the call to mips_mach_early_init() very early
from start.S. This function can be used e.g. to do some very early
CPU / SoC intitialization or image copying. Its called very early
and at this stage the PC might not match the linking address
(CONFIG_TEXT_BASE) - no absolute jump done until this call.
config MIPS_CACHE_SETUP
bool "Allow generic start code to initialize and setup caches"
default n if SKIP_LOWLEVEL_INIT
default y
help
This allows the generic start code to invoke the generic initialization
of the CPU caches. Disabling this can be useful for RAM boot scenarios
(EJTAG, SPL payload) or for machines which don't need cache initialization
or which want to provide their own cache implementation.
If unsure, say yes.
config MIPS_CACHE_DISABLE
bool "Allow generic start code to initially disable caches"
default n if SKIP_LOWLEVEL_INIT
default y
help
This allows the generic start code to initially disable the CPU caches
and run uncached until the caches are initialized and enabled. Disabling
this can be useful on machines which don't need cache initialization or
which want to provide their own cache implementation.
If unsure, say yes.
config MIPS_RELOCATION_TABLE_SIZE
hex "Relocation table size"
range 0x100 0x10000
......@@ -398,6 +460,12 @@ config SUPPORTS_CPU_MIPS64_R2
config SUPPORTS_CPU_MIPS64_R6
bool
config SUPPORTS_CPU_MIPS64_OCTEON
bool
config CPU_CAVIUM_OCTEON
bool
config CPU_MIPS32
bool
default y if CPU_MIPS32_R1 || CPU_MIPS32_R2 || CPU_MIPS32_R6
......@@ -405,6 +473,7 @@ config CPU_MIPS32
config CPU_MIPS64
bool
default y if CPU_MIPS64_R1 || CPU_MIPS64_R2 || CPU_MIPS64_R6
default y if CPU_MIPS64_OCTEON
config MIPS_TUNE_4KC
bool
......@@ -421,6 +490,9 @@ config MIPS_TUNE_34KC
config MIPS_TUNE_74KC
bool
config MIPS_TUNE_OCTEON3
bool
config 32BIT
bool
......@@ -453,6 +525,11 @@ config MIPS_SRAM_INIT
before it can be used. If enabled, a function mips_sram_init() will
be called just before setup_stack_gd.
config DMA_ADDR_T_64BIT
bool
help
Select this to enable 64-bit DMA addressing
config SYS_DCACHE_SIZE
int
default 0
......
......@@ -17,6 +17,7 @@ machine-$(CONFIG_ARCH_JZ47XX) += jz47xx
machine-$(CONFIG_MACH_PIC32) += pic32
machine-$(CONFIG_ARCH_MTMIPS) += mtmips
machine-$(CONFIG_ARCH_MSCC) += mscc
machine-${CONFIG_ARCH_OCTEON} += octeon
machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
libs-y += $(machdirs)
......@@ -30,6 +31,7 @@ arch-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,-mips32r6
arch-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,-mips64
arch-$(CONFIG_CPU_MIPS64_R2) += -march=mips64r2 -Wa,-mips64r2
arch-$(CONFIG_CPU_MIPS64_R6) += -march=mips64r6 -Wa,-mips64r6
arch-${CONFIG_CPU_MIPS64_OCTEON} += -march=octeon2
# Allow extra optimization for specific CPUs/SoCs
tune-$(CONFIG_MIPS_TUNE_4KC) += -mtune=4kc
......@@ -37,6 +39,7 @@ tune-$(CONFIG_MIPS_TUNE_14KC) += -mtune=14kc
tune-$(CONFIG_MIPS_TUNE_24KC) += -mtune=24kc
tune-$(CONFIG_MIPS_TUNE_34KC) += -mtune=34kc
tune-$(CONFIG_MIPS_TUNE_74KC) += -mtune=74kc
tune-${CONFIG_MIPS_TUNE_OCTEON3} += -mtune=octeon2
# Include default header files
cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
......
......@@ -17,19 +17,10 @@
#endif
#ifdef CONFIG_32BIT
# define MIPS_RELOC 3
# define STATUS_SET 0
#endif
#ifdef CONFIG_64BIT
# ifdef CONFIG_SYS_LITTLE_ENDIAN
# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
(((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym))
# else
# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24)
# endif
# define MIPS_RELOC MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03)
# define STATUS_SET ST0_KX
#endif
......@@ -147,7 +138,7 @@ reset:
and t0, t0, (1 << 31)
#else
1: mfc0 t0, CP0_EBASE
and t0, t0, EBASE_CPUNUM
and t0, t0, MIPS_EBASE_CPUNUM
#endif
/* Hang if this isn't the first CPU in the system */
......@@ -204,12 +195,11 @@ wr_done:
/* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
mtc0 zero, CP0_COMPARE
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
mfc0 t0, CP0_CONFIG
and t0, t0, MIPS_CONF_IMPL
or t0, t0, CONF_CM_UNCACHED
mtc0 t0, CP0_CONFIG
ehb
#ifdef CONFIG_MIPS_CACHE_DISABLE
/* Disable caches */
PTR_LA t9, mips_cache_disable
jalr t9
nop
#endif
#ifdef CONFIG_MIPS_CM
......@@ -244,12 +234,21 @@ wr_done:
jalr t9
nop
# endif
#endif
#ifdef CONFIG_MIPS_MACH_EARLY_INIT
bal mips_mach_early_init
nop
#endif
#ifdef CONFIG_MIPS_CACHE_SETUP
/* Initialize caches... */
PTR_LA t9, mips_cache_reset
jalr t9
nop
#endif
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
# ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
/* Initialize any external memory */
PTR_LA t9, lowlevel_init
......
......@@ -13,7 +13,9 @@ unsigned long notrace timer_read_counter(void)
return read_c0_count();
}
#if defined(CONFIG_SYS_MIPS_TIMER_FREQ)
ulong notrace __weak get_tbclk(void)
{
return CONFIG_SYS_MIPS_TIMER_FREQ;
}
#endif
......@@ -18,6 +18,7 @@ dtb-$(CONFIG_BOARD_COMTREND_VR3032U) += comtrend,vr-3032u.dtb
dtb-$(CONFIG_BOARD_COMTREND_WAP5813N) += comtrend,wap-5813n.dtb
dtb-$(CONFIG_BOARD_HUAWEI_HG556A) += huawei,hg556a.dtb
dtb-$(CONFIG_BOARD_MT7628_RFB) += mediatek,mt7628-rfb.dtb
dtb-$(CONFIG_TARGET_OCTEON_EBB7304) += mrvl,octeon-ebb7304.dtb
dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb
dtb-$(CONFIG_BOARD_NETGEAR_DGND3700V2) += netgear,dgnd3700v2.dtb
dtb-$(CONFIG_BOARD_SAGEM_FAST1704) += sagem,f@st1704.dtb
......
// SPDX-License-Identifier: GPL-2.0+
/*
* Marvell / Cavium Inc. CN73xx
*/
/dts-v1/;
/ {
#address-cells = <2>;
#size-cells = <2>;
soc0: soc@0 {
interrupt-parent = <&ciu3>;
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges; /* Direct mapping */
ciu3: interrupt-controller@1010000000000 {
compatible = "cavium,octeon-7890-ciu3";
interrupt-controller;
/*
* Interrupts are specified by two parts:
* 1) Source number (20 significant bits)
* 2) Trigger type: (4 == level, 1 == edge)
*/
#address-cells = <0>;
#interrupt-cells = <2>;
reg = <0x10100 0x00000000 0x0 0xb0000000>;
};
bootbus: bootbus@1180000000000 {
compatible = "cavium,octeon-3860-bootbus","simple-bus";
reg = <0x11800 0x00000000 0x0 0x200>;
/* The chip select number and offset */
#address-cells = <2>;
/* The size of the chip select region */
#size-cells = <1>;
};
reset: reset@1180006001600 {
compatible = "mrvl,cn7xxx-rst";
reg = <0x11800 0x06001600 0x0 0x200>;
};
uart0: serial@1180000000800 {
compatible = "cavium,octeon-3860-uart","ns16550";
reg = <0x11800 0x00000800 0x0 0x400>;
clock-frequency = <0>;
current-speed = <115200>;
reg-shift = <3>;
interrupts = <0x08000 4>;
};
uart1: serial@1180000000c00 {
compatible = "cavium,octeon-3860-uart","ns16550";
reg = <0x11800 0x00000c00 0x0 0x400>;
clock-frequency = <0>;
current-speed = <115200>;
reg-shift = <3>;
interrupts = <0x08040 4>;
};
};
};
// SPDX-License-Identifier: GPL-2.0+
/*
* Marvell / Cavium Inc. EVB CN7300
*/
/dts-v1/;
/include/ "mrvl,cn73xx.dtsi"
/ {
model = "cavium,ebb7304";
compatible = "cavium,ebb7304";
aliases {
serial0 = &uart0;
};
chosen {
stdout-path = &uart0;
};
};
&bootbus {
/*
* bootbus CS0 for CFI flash is remapped (0x1fc0.0000 -> 1f40.0000)
* as the initial size is too small for the 8MiB flash device
*/
ranges = <0 0 0 0x1f400000 0xc00000>,
<1 0 0x10000 0x10000000 0>,
<2 0 0x10000 0x20000000 0>,
<3 0 0x10000 0x30000000 0>,
<4 0 0 0x1d020000 0x10000>,
<5 0 0x10000 0x50000000 0>,
<6 0 0x10000 0x60000000 0>,
<7 0 0x10000 0x70000000 0>;
cavium,cs-config@0 {
compatible = "cavium,octeon-3860-bootbus-config";
cavium,cs-index = <0>;
cavium,t-adr = <10>;
cavium,t-ce = <50>;
cavium,t-oe = <50>;
cavium,t-we = <35>;
cavium,t-rd-hld = <25>;
cavium,t-wr-hld = <35>;
cavium,t-pause = <0>;
cavium,t-wait = <50>;
cavium,t-page = <30>;
cavium,t-rd-dly = <0>;
cavium,page-mode = <1>;
cavium,pages = <8>;
cavium,bus-width = <8>;
};
cavium,cs-config@4 {
compatible = "cavium,octeon-3860-bootbus-config";
cavium,cs-index = <4>;
cavium,t-adr = <10>;
cavium,t-ce = <10>;
cavium,t-oe = <160>;
cavium,t-we = <100>;
cavium,t-rd-hld = <10>;
cavium,t-wr-hld = <0>;
cavium,t-pause = <50>;
cavium,t-wait = <50>;
cavium,t-page = <10>;
cavium,t-rd-dly = <10>;
cavium,pages = <0>;
cavium,bus-width = <8>;
};
flash0: nor@0,0 {
compatible = "cfi-flash";
reg = <0 0 0x800000>;
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "bootloader";
reg = <0 0x340000>;
read-only;
};
partition@300000 {
label = "storage";
reg = <0x340000 0x4be000>;
};
partition@7fe000 {
label = "environment";
reg = <0x7fe000 0x2000>;
read-only;
};
};
};
&uart0 {
clock-frequency = <1200000000>;
};
......@@ -42,7 +42,7 @@
/*
* Returns the kernel segment base of a given address
*/
#define KSEGX(a) ((_ACAST32_ (a)) & 0xe0000000)
#define KSEGX(a) ((_ACAST32_(a)) & _ACAST32_(0xe0000000))
/*
* Returns the physical address of a CKSEGx / XKPHYS address
......@@ -123,21 +123,7 @@
#define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED, (p))
#define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE, (p))
#define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK)
#define PHYS_TO_XKPHYS(cm, a) (_CONST64_(0x8000000000000000) | \
(_CONST64_(cm) << 59) | (a))
/*
* Returns the uncached address of a sdram address
*/
#ifndef __ASSEMBLY__
#if defined(CONFIG_TB0229)
/* We use a 36 bit physical address map here and
cannot access physical memory directly from core */
#define UNCACHED_SDRAM(a) (((unsigned long)(a)) | 0x20000000)
#else /* !CONFIG_TB0229 */
#define UNCACHED_SDRAM(a) CKSEG1ADDR(a)
#endif /* CONFIG_TB0229 */
#endif /* __ASSEMBLY__ */
#define PHYS_TO_XKPHYS(cm, a) (XKPHYS | (_ACAST64_(cm) << 59) | (a))
/*
* The ultimate limited of the 64-bit MIPS architecture: 2 bits for selecting
......@@ -146,18 +132,9 @@
*/
#define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */
#ifndef CONFIG_CPU_R8000
/*
* The R8000 doesn't have the 32-bit compat spaces so we don't define them
* in order to catch bugs in the source code.
*/
#define COMPAT_K1BASE32 _CONST64_(0xffffffffa0000000)
#define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
#endif
#define KDM_TO_PHYS(x) (_ACAST64_ (x) & TO_PHYS_MASK)
#define PHYS_TO_K0(x) (_ACAST64_ (x) | CAC_BASE)
......
......@@ -16,37 +16,12 @@
#include <asm/sgidefs.h>
#ifndef CAT
#ifdef __STDC__
#define __CAT(str1, str2) str1##str2
#else
#define __CAT(str1, str2) str1/**/str2
#endif
#define CAT(str1, str2) __CAT(str1, str2)
#endif
/*
* PIC specific declarations
* Not used for the kernel but here seems to be the right place.
*/
#ifdef __PIC__
#define CPRESTORE(register) \
.cprestore register
#define CPADD(register) \
.cpadd register
#define CPLOAD(register) \
.cpload register
#else
#define CPRESTORE(register)
#define CPADD(register)
#define CPLOAD(register)
#endif
#define ENTRY(symbol) \
.globl symbol; \
.type symbol, @function; \
.ent symbol, 0; \
symbol:
symbol: .cfi_startproc; \
.insn
/*
* LEAF - declare leaf routine
......@@ -57,7 +32,9 @@ symbol:
.type symbol, @function; \
.ent symbol, 0; \
.section .text.symbol, "x"; \
symbol: .frame sp, 0, ra
symbol: .frame sp, 0, ra; \
.cfi_startproc; \
.insn
/*
* NESTED - declare nested routine entry point
......@@ -68,12 +45,15 @@ symbol: .frame sp, 0, ra
.type symbol, @function; \
.ent symbol, 0; \
.section .text.symbol, "x"; \
symbol: .frame sp, framesize, rpc
symbol: .frame sp, framesize, rpc; \
.cfi_startproc; \
.insn
/*
* END - mark end of function
*/
#define END(function) \
.cfi_endproc; \
.end function; \
.size function, .-function
......@@ -90,7 +70,7 @@ symbol:
#define FEXPORT(symbol) \
.globl symbol; \
.type symbol, @function; \
symbol:
symbol: .insn
/*
* ABS - export absolute symbol
......@@ -128,96 +108,6 @@ symbol = value
8: .asciiz msg; \
.popsection;
/*
* Build text tables
*/
#define TTABLE(string) \
.pushsection .text; \
.word 1f; \
.popsection \
.pushsection .data; \
1: .asciiz string; \
.popsection
/*
* MIPS IV pref instruction.
* Use with .set noreorder only!
*
* MIPS IV implementations are free to treat this as a nop. The R5000
* is one of them. So we should have an option not to use this instruction.
*/
#ifdef CONFIG_CPU_HAS_PREFETCH
#define PREF(hint, addr) \
.set push; \
.set arch=r5000; \
pref hint, addr; \
.set pop
#define PREFE(hint, addr) \
.set push; \
.set mips0; \
.set eva; \
prefe hint, addr; \
.set pop
#define PREFX(hint, addr) \
.set push; \
.set arch=r5000; \
prefx hint, addr; \
.set pop
#else /* !CONFIG_CPU_HAS_PREFETCH */
#define PREF(hint, addr)
#define PREFE(hint, addr)
#define PREFX(hint, addr)
#endif /* !CONFIG_CPU_HAS_PREFETCH */
/*
* MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
*/
#if (_MIPS_ISA == _MIPS_ISA_MIPS1)
#define MOVN(rd, rs, rt) \
.set push; \
.set reorder; \
beqz rt, 9f; \
move rd, rs; \
.set pop; \
9:
#define MOVZ(rd, rs, rt) \
.set push; \
.set reorder; \
bnez rt, 9f; \
move rd, rs; \
.set pop; \
9:
#endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
#define MOVN(rd, rs, rt) \
.set push; \
.set noreorder; \
bnezl rt, 9f; \
move rd, rs; \
.set pop; \
9:
#define MOVZ(rd, rs, rt) \
.set push; \
.set noreorder; \
beqzl rt, 9f; \
move rd, rs; \
.set pop; \
9:
#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
#if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
(_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
#define MOVN(rd, rs, rt) \
movn rd, rs, rt
#define MOVZ(rd, rs, rt) \
movz rd, rs, rt
#endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */
/*
* Stack alignment
*/
......
......@@ -41,6 +41,7 @@
#include <asm/io.h>
#include <linux/bitops.h>
#if CONFIG_IS_ENABLED(MIPS_CM)
static inline void *mips_cm_base(void)
{
return (void *)CKSEG1ADDR(CONFIG_MIPS_CM_BASE);
......@@ -56,6 +57,17 @@ static inline unsigned long mips_cm_l2_line_size(void)
line_sz &= GENMASK(GCR_L2_CONFIG_LINESZ_BITS - 1, 0);
return line_sz ? (2 << line_sz) : 0;
}
#else
static inline void *mips_cm_base(void)
{
return NULL;
}
static inline unsigned long mips_cm_l2_line_size(void)
{
return 0;
}
#endif
#endif /* !__ASSEMBLY__ */
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2004, 2007 Maciej W. Rozycki
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#ifndef _ASM_COMPILER_H
#define _ASM_COMPILER_H
/*
* With GCC 4.5 onwards we can use __builtin_unreachable to indicate to the
* compiler that a particular code path will never be hit. This allows it to be
* optimised out of the generated binary.
*
* Unfortunately at least GCC 4.6.3 through 7.3.0 inclusive suffer from a bug
* that can lead to instructions from beyond an unreachable statement being
* incorrectly reordered into earlier delay slots if the unreachable statement
* is the only content of a case in a switch statement. This can lead to
* seemingly random behaviour, such as invalid memory accesses from incorrectly
* reordered loads or stores. See this potential GCC fix for details:
*
* https://gcc.gnu.org/ml/gcc-patches/2015-09/msg00360.html
*
* It is unclear whether GCC 8 onwards suffer from the same issue - nothing
* relevant is mentioned in GCC 8 release notes and nothing obviously relevant
* stands out in GCC commit logs, but these newer GCC versions generate very
* different code for the testcase which doesn't exhibit the bug.
*
* GCC also handles stack allocation suboptimally when calling noreturn
* functions or calling __builtin_unreachable():
*
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365
*
* We work around both of these issues by placing a volatile asm statement,
* which GCC is prevented from reordering past, prior to __builtin_unreachable
* calls.
*
* The .insn statement is required to ensure that any branches to the
* statement, which sadly must be kept due to the asm statement, are known to
* be branches to code and satisfy linker requirements for microMIPS kernels.
*/
#undef barrier_before_unreachable
#define barrier_before_unreachable() asm volatile(".insn")
#if !defined(CONFIG_CC_IS_GCC) || \
(__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
# define GCC_OFF_SMALL_ASM() "ZC"
#elif defined(CONFIG_CPU_MICROMIPS)
# error "microMIPS compilation unsupported with GCC older than 4.9"
#else
# define GCC_OFF_SMALL_ASM() "R"
#endif
#ifdef CONFIG_CPU_MIPSR6
#define MIPS_ISA_LEVEL "mips64r6"
#define MIPS_ISA_ARCH_LEVEL MIPS_ISA_LEVEL
#define MIPS_ISA_LEVEL_RAW mips64r6
#define MIPS_ISA_ARCH_LEVEL_RAW MIPS_ISA_LEVEL_RAW
#else
/* MIPS64 is a superset of MIPS32 */
#define MIPS_ISA_LEVEL "mips64r2"
#define MIPS_ISA_ARCH_LEVEL "arch=r4000"
#define MIPS_ISA_LEVEL_RAW mips64r2
#define MIPS_ISA_ARCH_LEVEL_RAW MIPS_ISA_LEVEL_RAW
#endif /* CONFIG_CPU_MIPSR6 */
#endif /* _ASM_COMPILER_H */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2018 MIPS Tech, LLC
* Author: Matt Redfearn <matt.redfearn@mips.com>
*/
#ifndef __MIPS_ASM_ISA_REV_H__
#define __MIPS_ASM_ISA_REV_H__
/*
* The ISA revision level. This is 0 for MIPS I to V and N for
* MIPS{32,64}rN.
*/
/* If the compiler has defined __mips_isa_rev, believe it. */
#ifdef __mips_isa_rev
#define MIPS_ISA_REV __mips_isa_rev
#else
/* The compiler hasn't defined the isa rev so assume it's MIPS I - V (0) */
#define MIPS_ISA_REV 0
#endif
#endif /* __MIPS_ASM_ISA_REV_H__ */
......@@ -10,6 +10,8 @@
#ifndef _ASM_MIPSREGS_H
#define _ASM_MIPSREGS_H
#include <asm/compiler.h>
#include <asm/isa-rev.h>
/*
* The following macros are especially useful for __asm__
* inline assembler.
......@@ -26,9 +28,10 @@
*/
#ifdef __ASSEMBLY__
#define _ULCAST_
#define _U64CAST_
#else
#include <linux/bitops.h>
#define _ULCAST_ (unsigned long)
#define _U64CAST_ (u64)
#endif
/*
......@@ -42,15 +45,25 @@
#define CP0_GLOBALNUMBER $3, 1
#define CP0_CONTEXT $4
#define CP0_PAGEMASK $5
#define CP0_PAGEGRAIN $5, 1
#define CP0_SEGCTL0 $5, 2
#define CP0_SEGCTL1 $5, 3
#define CP0_SEGCTL2 $5, 4
#define CP0_WIRED $6
#define CP0_INFO $7
#define CP0_HWRENA $7, 0
#define CP0_HWRENA $7
#define CP0_BADVADDR $8
#define CP0_BADINSTR $8, 1
#define CP0_COUNT $9
#define CP0_ENTRYHI $10
#define CP0_GUESTCTL1 $10, 4
#define CP0_GUESTCTL2 $10, 5
#define CP0_GUESTCTL3 $10, 6
#define CP0_COMPARE $11
#define CP0_GUESTCTL0EXT $11, 4
#define CP0_STATUS $12
#define CP0_GUESTCTL0 $12, 6
#define CP0_GTOFFSET $12, 7
#define CP0_CAUSE $13
#define CP0_EPC $14
#define CP0_PRID $15
......@@ -59,6 +72,7 @@
#define CP0_CONFIG $16
#define CP0_CONFIG3 $16, 3
#define CP0_CONFIG5 $16, 5
#define CP0_CONFIG6 $16, 6
#define CP0_LLADDR $17
#define CP0_WATCHLO $18
#define CP0_WATCHHI $19
......@@ -130,6 +144,16 @@
#define MIPS_ENTRYLO_XI (_ULCAST_(1) << (BITS_PER_LONG - 2))
#define MIPS_ENTRYLO_RI (_ULCAST_(1) << (BITS_PER_LONG - 1))
/*
* MIPSr6+ GlobalNumber register definitions
*/
#define MIPS_GLOBALNUMBER_VP_SHF 0
#define MIPS_GLOBALNUMBER_VP (_ULCAST_(0xff) << MIPS_GLOBALNUMBER_VP_SHF)
#define MIPS_GLOBALNUMBER_CORE_SHF 8
#define MIPS_GLOBALNUMBER_CORE (_ULCAST_(0xff) << MIPS_GLOBALNUMBER_CORE_SHF)
#define MIPS_GLOBALNUMBER_CLUSTER_SHF 16
#define MIPS_GLOBALNUMBER_CLUSTER (_ULCAST_(0xf) << MIPS_GLOBALNUMBER_CLUSTER_SHF)
/*
* Values for PageMask register
*/
......@@ -189,6 +213,8 @@
/* MIPS32/64 EntryHI bit definitions */
#define MIPS_ENTRYHI_EHINV (_ULCAST_(1) << 10)
#define MIPS_ENTRYHI_ASIDX (_ULCAST_(0x3) << 8)
#define MIPS_ENTRYHI_ASID (_ULCAST_(0xff) << 0)
/*
* R4x00 interrupt enable / cause bits
......@@ -351,10 +377,14 @@
#define CAUSEF_IP7 (_ULCAST_(1) << 15)
#define CAUSEB_FDCI 21
#define CAUSEF_FDCI (_ULCAST_(1) << 21)
#define CAUSEB_WP 22
#define CAUSEF_WP (_ULCAST_(1) << 22)
#define CAUSEB_IV 23
#define CAUSEF_IV (_ULCAST_(1) << 23)
#define CAUSEB_PCI 26
#define CAUSEF_PCI (_ULCAST_(1) << 26)
#define CAUSEB_DC 27
#define CAUSEF_DC (_ULCAST_(1) << 27)
#define CAUSEB_CE 28
#define CAUSEF_CE (_ULCAST_(3) << 28)
#define CAUSEB_TI 30
......@@ -363,9 +393,36 @@
#define CAUSEF_BD (_ULCAST_(1) << 31)
/*
* Bits in the coprocessor 0 EBase register.
* Cause.ExcCode trap codes.
*/
#define EBASE_CPUNUM 0x3ff
#define EXCCODE_INT 0 /* Interrupt pending */
#define EXCCODE_MOD 1 /* TLB modified fault */
#define EXCCODE_TLBL 2 /* TLB miss on load or ifetch */
#define EXCCODE_TLBS 3 /* TLB miss on a store */
#define EXCCODE_ADEL 4 /* Address error on a load or ifetch */
#define EXCCODE_ADES 5 /* Address error on a store */
#define EXCCODE_IBE 6 /* Bus error on an ifetch */
#define EXCCODE_DBE 7 /* Bus error on a load or store */
#define EXCCODE_SYS 8 /* System call */
#define EXCCODE_BP 9 /* Breakpoint */
#define EXCCODE_RI 10 /* Reserved instruction exception */
#define EXCCODE_CPU 11 /* Coprocessor unusable */
#define EXCCODE_OV 12 /* Arithmetic overflow */
#define EXCCODE_TR 13 /* Trap instruction */
#define EXCCODE_MSAFPE 14 /* MSA floating point exception */
#define EXCCODE_FPE 15 /* Floating point exception */
#define EXCCODE_TLBRI 19 /* TLB Read-Inhibit exception */
#define EXCCODE_TLBXI 20 /* TLB Execution-Inhibit exception */
#define EXCCODE_MSADIS 21 /* MSA disabled exception */
#define EXCCODE_MDMX 22 /* MDMX unusable exception */
#define EXCCODE_WATCH 23 /* Watch address reference */
#define EXCCODE_MCHECK 24 /* Machine check */
#define EXCCODE_THREAD 25 /* Thread exceptions (MT) */
#define EXCCODE_DSPDIS 26 /* DSP disabled exception */
#define EXCCODE_GE 27 /* Virtualized guest exception (VZ) */
/* Implementation specific trap codes used by MIPS cores */
#define MIPS_EXCCODE_TLBPAR 16 /* TLB parity error exception */
/*
* Bits in the coprocessor 0 config register.
......@@ -393,7 +450,7 @@
#define CONF_SM (_ULCAST_(1) << 16)
#define CONF_SC (_ULCAST_(1) << 17)
#define CONF_EW (_ULCAST_(3) << 18)
#define CONF_EP (_ULCAST_(15) << 24)
#define CONF_EP (_ULCAST_(15)<< 24)
#define CONF_EC (_ULCAST_(7) << 28)
#define CONF_CM (_ULCAST_(1) << 31)
......@@ -419,7 +476,7 @@
#define R10K_CONF_CT (_ULCAST_(1) << 5)
#define R10K_CONF_PE (_ULCAST_(1) << 6)
#define R10K_CONF_PM (_ULCAST_(3) << 7)
#define R10K_CONF_EC (_ULCAST_(15) << 9)
#define R10K_CONF_EC (_ULCAST_(15)<< 9)
#define R10K_CONF_SB (_ULCAST_(1) << 13)
#define R10K_CONF_SK (_ULCAST_(1) << 14)
#define R10K_CONF_SS (_ULCAST_(7) << 16)
......@@ -452,6 +509,7 @@
#define TX49_CONF_CWFON (_ULCAST_(1) << 27)
/* Bits specific to the MIPS32/64 PRA. */
#define MIPS_CONF_VI (_ULCAST_(1) << 3)
#define MIPS_CONF_MT (_ULCAST_(7) << 7)
#define MIPS_CONF_MT_TLB (_ULCAST_(1) << 7)
#define MIPS_CONF_MT_FTLB (_ULCAST_(4) << 7)
......@@ -548,7 +606,8 @@
#define MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT (_ULCAST_(1) << 14)
#define MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT (_ULCAST_(2) << 14)
#define MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT (_ULCAST_(3) << 14)
#define MIPS_CONF4_KSCREXIST (_ULCAST_(255) << 16)
#define MIPS_CONF4_KSCREXIST_SHIFT (16)
#define MIPS_CONF4_KSCREXIST (_ULCAST_(255) << MIPS_CONF4_KSCREXIST_SHIFT)
#define MIPS_CONF4_VTLBSIZEEXT_SHIFT (24)
#define MIPS_CONF4_VTLBSIZEEXT (_ULCAST_(15) << MIPS_CONF4_VTLBSIZEEXT_SHIFT)
#define MIPS_CONF4_AE (_ULCAST_(1) << 28)
......@@ -561,9 +620,13 @@
#define MIPS_CONF5_LLB (_ULCAST_(1) << 4)
#define MIPS_CONF5_MVH (_ULCAST_(1) << 5)
#define MIPS_CONF5_VP (_ULCAST_(1) << 7)
#define MIPS_CONF5_SBRI (_ULCAST_(1) << 6)
#define MIPS_CONF5_FRE (_ULCAST_(1) << 8)
#define MIPS_CONF5_UFE (_ULCAST_(1) << 9)
#define MIPS_CONF5_L2C (_ULCAST_(1) << 10)
#define MIPS_CONF5_CA2 (_ULCAST_(1) << 14)
#define MIPS_CONF5_MI (_ULCAST_(1) << 17)
#define MIPS_CONF5_CRCP (_ULCAST_(1) << 18)
#define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27)
#define MIPS_CONF5_EVA (_ULCAST_(1) << 28)
#define MIPS_CONF5_CV (_ULCAST_(1) << 29)
......@@ -572,6 +635,8 @@
#define MIPS_CONF6_SYND (_ULCAST_(1) << 13)
/* proAptiv FTLB on/off bit */
#define MIPS_CONF6_FTLBEN (_ULCAST_(1) << 15)
/* Loongson-3 FTLB on/off bit */
#define MIPS_CONF6_FTLBDIS (_ULCAST_(1) << 22)
/* FTLB probability bits */
#define MIPS_CONF6_FTLBP_SHIFT (16)
......@@ -581,19 +646,95 @@
#define MIPS_CONF7_IAR (_ULCAST_(1) << 10)
#define MIPS_CONF7_AR (_ULCAST_(1) << 16)
/* FTLB probability bits for R6 */
#define MIPS_CONF7_FTLBP_SHIFT (18)
/* Ingenic HPTLB off bits */
#define XBURST_PAGECTRL_HPTLB_DIS 0xa9000000
/* Ingenic Config7 bits */
#define MIPS_CONF7_BTB_LOOP_EN (_ULCAST_(1) << 4)
/* Config7 Bits specific to MIPS Technologies. */
/* Performance counters implemented Per TC */
#define MTI_CONF7_PTC (_ULCAST_(1) << 19)
/* WatchLo* register definitions */
#define MIPS_WATCHLO_IRW (_ULCAST_(0x7) << 0)
/* WatchHi* register definitions */
#define MIPS_WATCHHI_M (_ULCAST_(1) << 31)
#define MIPS_WATCHHI_G (_ULCAST_(1) << 30)
#define MIPS_WATCHHI_WM (_ULCAST_(0x3) << 28)
#define MIPS_WATCHHI_WM_R_RVA (_ULCAST_(0) << 28)
#define MIPS_WATCHHI_WM_R_GPA (_ULCAST_(1) << 28)
#define MIPS_WATCHHI_WM_G_GVA (_ULCAST_(2) << 28)
#define MIPS_WATCHHI_EAS (_ULCAST_(0x3) << 24)
#define MIPS_WATCHHI_ASID (_ULCAST_(0xff) << 16)
#define MIPS_WATCHHI_MASK (_ULCAST_(0x1ff) << 3)
#define MIPS_WATCHHI_I (_ULCAST_(1) << 2)
#define MIPS_WATCHHI_R (_ULCAST_(1) << 1)
#define MIPS_WATCHHI_W (_ULCAST_(1) << 0)
#define MIPS_WATCHHI_IRW (_ULCAST_(0x7) << 0)
/* PerfCnt control register definitions */
#define MIPS_PERFCTRL_EXL (_ULCAST_(1) << 0)
#define MIPS_PERFCTRL_K (_ULCAST_(1) << 1)
#define MIPS_PERFCTRL_S (_ULCAST_(1) << 2)
#define MIPS_PERFCTRL_U (_ULCAST_(1) << 3)
#define MIPS_PERFCTRL_IE (_ULCAST_(1) << 4)
#define MIPS_PERFCTRL_EVENT_S 5
#define MIPS_PERFCTRL_EVENT (_ULCAST_(0x3ff) << MIPS_PERFCTRL_EVENT_S)
#define MIPS_PERFCTRL_PCTD (_ULCAST_(1) << 15)
#define MIPS_PERFCTRL_EC (_ULCAST_(0x3) << 23)
#define MIPS_PERFCTRL_EC_R (_ULCAST_(0) << 23)
#define MIPS_PERFCTRL_EC_RI (_ULCAST_(1) << 23)
#define MIPS_PERFCTRL_EC_G (_ULCAST_(2) << 23)
#define MIPS_PERFCTRL_EC_GRI (_ULCAST_(3) << 23)
#define MIPS_PERFCTRL_W (_ULCAST_(1) << 30)
#define MIPS_PERFCTRL_M (_ULCAST_(1) << 31)
/* PerfCnt control register MT extensions used by MIPS cores */
#define MIPS_PERFCTRL_VPEID_S 16
#define MIPS_PERFCTRL_VPEID (_ULCAST_(0xf) << MIPS_PERFCTRL_VPEID_S)
#define MIPS_PERFCTRL_TCID_S 22
#define MIPS_PERFCTRL_TCID (_ULCAST_(0xff) << MIPS_PERFCTRL_TCID_S)
#define MIPS_PERFCTRL_MT_EN (_ULCAST_(0x3) << 20)
#define MIPS_PERFCTRL_MT_EN_ALL (_ULCAST_(0) << 20)
#define MIPS_PERFCTRL_MT_EN_VPE (_ULCAST_(1) << 20)
#define MIPS_PERFCTRL_MT_EN_TC (_ULCAST_(2) << 20)
/* PerfCnt control register MT extensions used by BMIPS5000 */
#define BRCM_PERFCTRL_TC (_ULCAST_(1) << 30)
/* PerfCnt control register MT extensions used by Netlogic XLR */
#define XLR_PERFCTRL_ALLTHREADS (_ULCAST_(1) << 13)
/* MAAR bit definitions */
#define MIPS_MAAR_VH (_U64CAST_(1) << 63)
#define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12)
#define MIPS_MAAR_ADDR_SHIFT 12
#define MIPS_MAAR_S (_ULCAST_(1) << 1)
#define MIPS_MAAR_V (_ULCAST_(1) << 0)
#define MIPS_MAAR_VL (_ULCAST_(1) << 0)
/* MAARI bit definitions */
#define MIPS_MAARI_INDEX (_ULCAST_(0x3f) << 0)
/* EBase bit definitions */
#define MIPS_EBASE_CPUNUM_SHIFT 0
#define MIPS_EBASE_CPUNUM (_ULCAST_(0x3ff) << 0)
#define MIPS_EBASE_WG_SHIFT 11
#define MIPS_EBASE_WG (_ULCAST_(1) << 11)
#define MIPS_EBASE_BASE_SHIFT 12
#define MIPS_EBASE_BASE (~_ULCAST_((1 << MIPS_EBASE_BASE_SHIFT) - 1))
/* CMGCRBase bit definitions */
#define MIPS_CMGCRB_BASE 11
#define MIPS_CMGCRF_BASE (~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1))
/* LLAddr bit definitions */
#define MIPS_LLADDR_LLB_SHIFT 0
#define MIPS_LLADDR_LLB (_ULCAST_(1) << MIPS_LLADDR_LLB_SHIFT)
/*
* Bits in the MIPS32 Memory Segmentation registers.
*/
......@@ -625,6 +766,8 @@
#define MIPS_PWFIELD_PTEI_SHIFT 0
#define MIPS_PWFIELD_PTEI_MASK 0x0000003f
#define MIPS_PWSIZE_PS_SHIFT 30
#define MIPS_PWSIZE_PS_MASK 0x40000000
#define MIPS_PWSIZE_GDW_SHIFT 24
#define MIPS_PWSIZE_GDW_MASK 0x3f000000
#define MIPS_PWSIZE_UDW_SHIFT 18
......@@ -638,6 +781,12 @@
#define MIPS_PWCTL_PWEN_SHIFT 31
#define MIPS_PWCTL_PWEN_MASK 0x80000000
#define MIPS_PWCTL_XK_SHIFT 28
#define MIPS_PWCTL_XK_MASK 0x10000000
#define MIPS_PWCTL_XS_SHIFT 27
#define MIPS_PWCTL_XS_MASK 0x08000000
#define MIPS_PWCTL_XU_SHIFT 26
#define MIPS_PWCTL_XU_MASK 0x04000000
#define MIPS_PWCTL_DPH_SHIFT 7
#define MIPS_PWCTL_DPH_MASK 0x00000080
#define MIPS_PWCTL_HUGEPG_SHIFT 6
......@@ -645,6 +794,94 @@
#define MIPS_PWCTL_PSN_SHIFT 0
#define MIPS_PWCTL_PSN_MASK 0x0000003f
/* GuestCtl0 fields */
#define MIPS_GCTL0_GM_SHIFT 31
#define MIPS_GCTL0_GM (_ULCAST_(1) << MIPS_GCTL0_GM_SHIFT)
#define MIPS_GCTL0_RI_SHIFT 30
#define MIPS_GCTL0_RI (_ULCAST_(1) << MIPS_GCTL0_RI_SHIFT)
#define MIPS_GCTL0_MC_SHIFT 29
#define MIPS_GCTL0_MC (_ULCAST_(1) << MIPS_GCTL0_MC_SHIFT)
#define MIPS_GCTL0_CP0_SHIFT 28
#define MIPS_GCTL0_CP0 (_ULCAST_(1) << MIPS_GCTL0_CP0_SHIFT)
#define MIPS_GCTL0_AT_SHIFT 26
#define MIPS_GCTL0_AT (_ULCAST_(0x3) << MIPS_GCTL0_AT_SHIFT)
#define MIPS_GCTL0_GT_SHIFT 25
#define MIPS_GCTL0_GT (_ULCAST_(1) << MIPS_GCTL0_GT_SHIFT)
#define MIPS_GCTL0_CG_SHIFT 24
#define MIPS_GCTL0_CG (_ULCAST_(1) << MIPS_GCTL0_CG_SHIFT)
#define MIPS_GCTL0_CF_SHIFT 23
#define MIPS_GCTL0_CF (_ULCAST_(1) << MIPS_GCTL0_CF_SHIFT)
#define MIPS_GCTL0_G1_SHIFT 22
#define MIPS_GCTL0_G1 (_ULCAST_(1) << MIPS_GCTL0_G1_SHIFT)
#define MIPS_GCTL0_G0E_SHIFT 19
#define MIPS_GCTL0_G0E (_ULCAST_(1) << MIPS_GCTL0_G0E_SHIFT)
#define MIPS_GCTL0_PT_SHIFT 18
#define MIPS_GCTL0_PT (_ULCAST_(1) << MIPS_GCTL0_PT_SHIFT)
#define MIPS_GCTL0_RAD_SHIFT 9
#define MIPS_GCTL0_RAD (_ULCAST_(1) << MIPS_GCTL0_RAD_SHIFT)
#define MIPS_GCTL0_DRG_SHIFT 8
#define MIPS_GCTL0_DRG (_ULCAST_(1) << MIPS_GCTL0_DRG_SHIFT)
#define MIPS_GCTL0_G2_SHIFT 7
#define MIPS_GCTL0_G2 (_ULCAST_(1) << MIPS_GCTL0_G2_SHIFT)
#define MIPS_GCTL0_GEXC_SHIFT 2
#define MIPS_GCTL0_GEXC (_ULCAST_(0x1f) << MIPS_GCTL0_GEXC_SHIFT)
#define MIPS_GCTL0_SFC2_SHIFT 1
#define MIPS_GCTL0_SFC2 (_ULCAST_(1) << MIPS_GCTL0_SFC2_SHIFT)
#define MIPS_GCTL0_SFC1_SHIFT 0
#define MIPS_GCTL0_SFC1 (_ULCAST_(1) << MIPS_GCTL0_SFC1_SHIFT)
/* GuestCtl0.AT Guest address translation control */
#define MIPS_GCTL0_AT_ROOT 1 /* Guest MMU under Root control */
#define MIPS_GCTL0_AT_GUEST 3 /* Guest MMU under Guest control */
/* GuestCtl0.GExcCode Hypervisor exception cause codes */
#define MIPS_GCTL0_GEXC_GPSI 0 /* Guest Privileged Sensitive Instruction */
#define MIPS_GCTL0_GEXC_GSFC 1 /* Guest Software Field Change */
#define MIPS_GCTL0_GEXC_HC 2 /* Hypercall */
#define MIPS_GCTL0_GEXC_GRR 3 /* Guest Reserved Instruction Redirect */
#define MIPS_GCTL0_GEXC_GVA 8 /* Guest Virtual Address available */
#define MIPS_GCTL0_GEXC_GHFC 9 /* Guest Hardware Field Change */
#define MIPS_GCTL0_GEXC_GPA 10 /* Guest Physical Address available */
/* GuestCtl0Ext fields */
#define MIPS_GCTL0EXT_RPW_SHIFT 8
#define MIPS_GCTL0EXT_RPW (_ULCAST_(0x3) << MIPS_GCTL0EXT_RPW_SHIFT)
#define MIPS_GCTL0EXT_NCC_SHIFT 6
#define MIPS_GCTL0EXT_NCC (_ULCAST_(0x3) << MIPS_GCTL0EXT_NCC_SHIFT)
#define MIPS_GCTL0EXT_CGI_SHIFT 4
#define MIPS_GCTL0EXT_CGI (_ULCAST_(1) << MIPS_GCTL0EXT_CGI_SHIFT)
#define MIPS_GCTL0EXT_FCD_SHIFT 3
#define MIPS_GCTL0EXT_FCD (_ULCAST_(1) << MIPS_GCTL0EXT_FCD_SHIFT)
#define MIPS_GCTL0EXT_OG_SHIFT 2
#define MIPS_GCTL0EXT_OG (_ULCAST_(1) << MIPS_GCTL0EXT_OG_SHIFT)
#define MIPS_GCTL0EXT_BG_SHIFT 1
#define MIPS_GCTL0EXT_BG (_ULCAST_(1) << MIPS_GCTL0EXT_BG_SHIFT)
#define MIPS_GCTL0EXT_MG_SHIFT 0
#define MIPS_GCTL0EXT_MG (_ULCAST_(1) << MIPS_GCTL0EXT_MG_SHIFT)
/* GuestCtl0Ext.RPW Root page walk configuration */
#define MIPS_GCTL0EXT_RPW_BOTH 0 /* Root PW for GPA->RPA and RVA->RPA */
#define MIPS_GCTL0EXT_RPW_GPA 2 /* Root PW for GPA->RPA */
#define MIPS_GCTL0EXT_RPW_RVA 3 /* Root PW for RVA->RPA */
/* GuestCtl0Ext.NCC Nested cache coherency attributes */
#define MIPS_GCTL0EXT_NCC_IND 0 /* Guest CCA independent of Root CCA */
#define MIPS_GCTL0EXT_NCC_MOD 1 /* Guest CCA modified by Root CCA */
/* GuestCtl1 fields */
#define MIPS_GCTL1_ID_SHIFT 0
#define MIPS_GCTL1_ID_WIDTH 8
#define MIPS_GCTL1_ID (_ULCAST_(0xff) << MIPS_GCTL1_ID_SHIFT)
#define MIPS_GCTL1_RID_SHIFT 16
#define MIPS_GCTL1_RID_WIDTH 8
#define MIPS_GCTL1_RID (_ULCAST_(0xff) << MIPS_GCTL1_RID_SHIFT)
#define MIPS_GCTL1_EID_SHIFT 24
#define MIPS_GCTL1_EID_WIDTH 8
#define MIPS_GCTL1_EID (_ULCAST_(0xff) << MIPS_GCTL1_EID_SHIFT)
/* GuestID reserved for root context */
#define MIPS_GCTL1_ROOT_GUESTID 0
/* CDMMBase register bit definitions */
#define MIPS_CDMMBASE_SIZE_SHIFT 0
#define MIPS_CDMMBASE_SIZE (_ULCAST_(511) << MIPS_CDMMBASE_SIZE_SHIFT)
......@@ -653,6 +890,24 @@
#define MIPS_CDMMBASE_ADDR_SHIFT 11
#define MIPS_CDMMBASE_ADDR_START 15
/* RDHWR register numbers */
#define MIPS_HWR_CPUNUM 0 /* CPU number */
#define MIPS_HWR_SYNCISTEP 1 /* SYNCI step size */
#define MIPS_HWR_CC 2 /* Cycle counter */
#define MIPS_HWR_CCRES 3 /* Cycle counter resolution */
#define MIPS_HWR_ULR 29 /* UserLocal */
#define MIPS_HWR_IMPL1 30 /* Implementation dependent */
#define MIPS_HWR_IMPL2 31 /* Implementation dependent */
/* Bits in HWREna register */
#define MIPS_HWRENA_CPUNUM (_ULCAST_(1) << MIPS_HWR_CPUNUM)
#define MIPS_HWRENA_SYNCISTEP (_ULCAST_(1) << MIPS_HWR_SYNCISTEP)
#define MIPS_HWRENA_CC (_ULCAST_(1) << MIPS_HWR_CC)
#define MIPS_HWRENA_CCRES (_ULCAST_(1) << MIPS_HWR_CCRES)
#define MIPS_HWRENA_ULR (_ULCAST_(1) << MIPS_HWR_ULR)
#define MIPS_HWRENA_IMPL1 (_ULCAST_(1) << MIPS_HWR_IMPL1)
#define MIPS_HWRENA_IMPL2 (_ULCAST_(1) << MIPS_HWR_IMPL2)
/*
* Bitfields in the TX39 family CP0 Configuration Register 3
*/
......@@ -696,6 +951,31 @@
/* Disable Branch Return Cache */
#define R10K_DIAG_D_BRC (_ULCAST_(1) << 22)
/* Flush ITLB */
#define LOONGSON_DIAG_ITLB (_ULCAST_(1) << 2)
/* Flush DTLB */
#define LOONGSON_DIAG_DTLB (_ULCAST_(1) << 3)
/* Flush VTLB */
#define LOONGSON_DIAG_VTLB (_ULCAST_(1) << 12)
/* Flush FTLB */
#define LOONGSON_DIAG_FTLB (_ULCAST_(1) << 13)
/* CvmCtl register field definitions */
#define CVMCTL_IPPCI_SHIFT 7
#define CVMCTL_IPPCI (_U64CAST_(0x7) << CVMCTL_IPPCI_SHIFT)
#define CVMCTL_IPTI_SHIFT 4
#define CVMCTL_IPTI (_U64CAST_(0x7) << CVMCTL_IPTI_SHIFT)
/* CvmMemCtl2 register field definitions */
#define CVMMEMCTL2_INHIBITTS (_U64CAST_(1) << 17)
/* CvmVMConfig register field definitions */
#define CVMVMCONF_DGHT (_U64CAST_(1) << 60)
#define CVMVMCONF_MMUSIZEM1_S 12
#define CVMVMCONF_MMUSIZEM1 (_U64CAST_(0xff) << CVMVMCONF_MMUSIZEM1_S)
#define CVMVMCONF_RMMUSIZEM1_S 0
#define CVMVMCONF_RMMUSIZEM1 (_U64CAST_(0xff) << CVMVMCONF_RMMUSIZEM1_S)
/*
* Coprocessor 1 (FPU) register names
*/
......@@ -779,9 +1059,12 @@
/*
* Bits 22:20 of the FPU Status Register will be read as 0,
* and should be written as zero.
* MAC2008 was removed in Release 5 so we still treat it as
* reserved.
*/
#define FPU_CSR_RSVD (_ULCAST_(7) << 20)
#define FPU_CSR_MAC2008 (_ULCAST_(1) << 20)
#define FPU_CSR_ABS2008 (_ULCAST_(1) << 19)
#define FPU_CSR_NAN2008 (_ULCAST_(1) << 18)
......@@ -829,11 +1112,11 @@
defined(CONFIG_SYS_SUPPORTS_MICROMIPS)
#define get_isa16_mode(x) ((x) & 0x1)
#define msk_isa16_mode(x) ((x) & ~0x1)
#define set_isa16_mode(x) do { (x) |= 0x1; } while (0)
#define set_isa16_mode(x) do { (x) |= 0x1; } while(0)
#else
#define get_isa16_mode(x) 0
#define msk_isa16_mode(x) (x)
#define set_isa16_mode(x) do { } while (0)
#define set_isa16_mode(x) do { } while(0)
#endif
/*
......@@ -847,6 +1130,123 @@ static inline int mm_insn_16bit(u16 insn)
return (opcode >= 1 && opcode <= 3) ? 1 : 0;
}
/*
* Helper macros for generating raw instruction encodings in inline asm.
*/
#ifdef CONFIG_CPU_MICROMIPS
#define _ASM_INSN16_IF_MM(_enc) \
".insn\n\t" \
".hword (" #_enc ")\n\t"
#define _ASM_INSN32_IF_MM(_enc) \
".insn\n\t" \
".hword ((" #_enc ") >> 16)\n\t" \
".hword ((" #_enc ") & 0xffff)\n\t"
#else
#define _ASM_INSN_IF_MIPS(_enc) \
".insn\n\t" \
".word (" #_enc ")\n\t"
#endif
#ifndef _ASM_INSN16_IF_MM
#define _ASM_INSN16_IF_MM(_enc)
#endif
#ifndef _ASM_INSN32_IF_MM
#define _ASM_INSN32_IF_MM(_enc)
#endif
#ifndef _ASM_INSN_IF_MIPS
#define _ASM_INSN_IF_MIPS(_enc)
#endif
/*
* parse_r var, r - Helper assembler macro for parsing register names.
*
* This converts the register name in $n form provided in \r to the
* corresponding register number, which is assigned to the variable \var. It is
* needed to allow explicit encoding of instructions in inline assembly where
* registers are chosen by the compiler in $n form, allowing us to avoid using
* fixed register numbers.
*
* It also allows newer instructions (not implemented by the assembler) to be
* transparently implemented using assembler macros, instead of needing separate
* cases depending on toolchain support.
*
* Simple usage example:
* __asm__ __volatile__("parse_r __rt, %0\n\t"
* ".insn\n\t"
* "# di %0\n\t"
* ".word (0x41606000 | (__rt << 16))"
* : "=r" (status);
*/
/* Match an individual register number and assign to \var */
#define _IFC_REG(n) \
".ifc \\r, $" #n "\n\t" \
"\\var = " #n "\n\t" \
".endif\n\t"
__asm__(".macro parse_r var r\n\t"
"\\var = -1\n\t"
_IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3)
_IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7)
_IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11)
_IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15)
_IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19)
_IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23)
_IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27)
_IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31)
".iflt \\var\n\t"
".error \"Unable to parse register name \\r\"\n\t"
".endif\n\t"
".endm");
#undef _IFC_REG
/*
* C macros for generating assembler macros for common instruction formats.
*
* The names of the operands can be chosen by the caller, and the encoding of
* register operand \<Rn> is assigned to __<Rn> where it can be accessed from
* the ENC encodings.
*/
/* Instructions with no operands */
#define _ASM_MACRO_0(OP, ENC) \
__asm__(".macro " #OP "\n\t" \
ENC \
".endm")
/* Instructions with 1 register operand & 1 immediate operand */
#define _ASM_MACRO_1R1I(OP, R1, I2, ENC) \
__asm__(".macro " #OP " " #R1 ", " #I2 "\n\t" \
"parse_r __" #R1 ", \\" #R1 "\n\t" \
ENC \
".endm")
/* Instructions with 2 register operands */
#define _ASM_MACRO_2R(OP, R1, R2, ENC) \
__asm__(".macro " #OP " " #R1 ", " #R2 "\n\t" \
"parse_r __" #R1 ", \\" #R1 "\n\t" \
"parse_r __" #R2 ", \\" #R2 "\n\t" \
ENC \
".endm")
/* Instructions with 3 register operands */
#define _ASM_MACRO_3R(OP, R1, R2, R3, ENC) \
__asm__(".macro " #OP " " #R1 ", " #R2 ", " #R3 "\n\t" \
"parse_r __" #R1 ", \\" #R1 "\n\t" \
"parse_r __" #R2 ", \\" #R2 "\n\t" \
"parse_r __" #R3 ", \\" #R3 "\n\t" \
ENC \
".endm")
/* Instructions with 2 register operands and 1 optional select operand */
#define _ASM_MACRO_2R_1S(OP, R1, R2, SEL3, ENC) \
__asm__(".macro " #OP " " #R1 ", " #R2 ", " #SEL3 " = 0\n\t" \
"parse_r __" #R1 ", \\" #R1 "\n\t" \
"parse_r __" #R2 ", \\" #R2 "\n\t" \
ENC \
".endm")
/*
* TLB Invalidate Flush
*/
......@@ -855,7 +1255,9 @@ static inline void tlbinvf(void)
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
".word 0x42000004\n\t" /* tlbinvf */
"# tlbinvf\n\t"
_ASM_INSN_IF_MIPS(0x42000004)
_ASM_INSN32_IF_MM(0x0000537c)
".set pop");
}
......@@ -910,40 +1312,55 @@ do { \
* Macros to access the system control coprocessor
*/
#define __read_32bit_c0_register(source, sel) \
#define ___read_32bit_c0_register(source, sel, vol) \
({ unsigned int __res; \
if (sel == 0) \
__asm__ __volatile__( \
__asm__ vol( \
"mfc0\t%0, " #source "\n\t" \
: "=r" (__res)); \
else \
__asm__ __volatile__( \
__asm__ vol( \
".set\tpush\n\t" \
".set\tmips32\n\t" \
"mfc0\t%0, " #source ", " #sel "\n\t" \
".set\tmips0\n\t" \
".set\tpop\n\t" \
: "=r" (__res)); \
__res; \
})
#define __read_64bit_c0_register(source, sel) \
#define ___read_64bit_c0_register(source, sel, vol) \
({ unsigned long long __res; \
if (sizeof(unsigned long) == 4) \
__res = __read_64bit_c0_split(source, sel); \
__res = __read_64bit_c0_split(source, sel, vol); \
else if (sel == 0) \
__asm__ __volatile__( \
__asm__ vol( \
".set\tpush\n\t" \
".set\tmips3\n\t" \
"dmfc0\t%0, " #source "\n\t" \
".set\tmips0" \
".set\tpop" \
: "=r" (__res)); \
else \
__asm__ __volatile__( \
__asm__ vol( \
".set\tpush\n\t" \
".set\tmips64\n\t" \
"dmfc0\t%0, " #source ", " #sel "\n\t" \
".set\tmips0" \
".set\tpop" \
: "=r" (__res)); \
__res; \
})
#define __read_32bit_c0_register(source, sel) \
___read_32bit_c0_register(source, sel, __volatile__)
#define __read_const_32bit_c0_register(source, sel) \
___read_32bit_c0_register(source, sel,)
#define __read_64bit_c0_register(source, sel) \
___read_64bit_c0_register(source, sel, __volatile__)
#define __read_const_64bit_c0_register(source, sel) \
___read_64bit_c0_register(source, sel,)
#define __write_32bit_c0_register(register, sel, value) \
do { \
if (sel == 0) \
......@@ -952,9 +1369,10 @@ do { \
: : "Jr" ((unsigned int)(value))); \
else \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips32\n\t" \
"mtc0\t%z0, " #register ", " #sel "\n\t" \
".set\tmips0" \
".set\tpop" \
: : "Jr" ((unsigned int)(value))); \
} while (0)
......@@ -964,15 +1382,17 @@ do { \
__write_64bit_c0_split(register, sel, value); \
else if (sel == 0) \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips3\n\t" \
"dmtc0\t%z0, " #register "\n\t" \
".set\tmips0" \
".set\tpop" \
: : "Jr" (value)); \
else \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips64\n\t" \
"dmtc0\t%z0, " #register ", " #sel "\n\t" \
".set\tmips0" \
".set\tpop" \
: : "Jr" (value)); \
} while (0)
......@@ -981,6 +1401,11 @@ do { \
(unsigned long) __read_32bit_c0_register(reg, sel) : \
(unsigned long) __read_64bit_c0_register(reg, sel))
#define __read_const_ulong_c0_register(reg, sel) \
((sizeof(unsigned long) == 4) ? \
(unsigned long) __read_const_32bit_c0_register(reg, sel) : \
(unsigned long) __read_const_64bit_c0_register(reg, sel))
#define __write_ulong_c0_register(reg, sel, val) \
do { \
if (sizeof(unsigned long) == 4) \
......@@ -1011,27 +1436,27 @@ do { \
* These versions are only needed for systems with more than 38 bits of
* physical address space running the 32-bit kernel. That's none atm :-)
*/
#define __read_64bit_c0_split(source, sel) \
#define __read_64bit_c0_split(source, sel, vol) \
({ \
unsigned long long __val; \
\
if (sel == 0) \
__asm__ __volatile__( \
__asm__ vol( \
".set\tpush\n\t" \
".set\tmips64\n\t" \
"dmfc0\t%M0, " #source "\n\t" \
"dsll\t%L0, %M0, 32\n\t" \
"dsra\t%M0, %M0, 32\n\t" \
"dsra\t%L0, %L0, 32\n\t" \
".set\tmips0" \
"dmfc0\t%L0, " #source "\n\t" \
"dsra\t%M0, %L0, 32\n\t" \
"sll\t%L0, %L0, 0\n\t" \
".set\tpop" \
: "=r" (__val)); \
else \
__asm__ __volatile__( \
__asm__ vol( \
".set\tpush\n\t" \
".set\tmips64\n\t" \
"dmfc0\t%M0, " #source ", " #sel "\n\t" \
"dsll\t%L0, %M0, 32\n\t" \
"dsra\t%M0, %M0, 32\n\t" \
"dsra\t%L0, %L0, 32\n\t" \
".set\tmips0" \
"dmfc0\t%L0, " #source ", " #sel "\n\t" \
"dsra\t%M0, %L0, 32\n\t" \
"sll\t%L0, %L0, 0\n\t" \
".set\tpop" \
: "=r" (__val)); \
\
__val; \
......@@ -1039,60 +1464,77 @@ do { \
#define __write_64bit_c0_split(source, sel, val) \
do { \
if (sel == 0) \
unsigned long long __tmp = (val); \
if (MIPS_ISA_REV >= 2) \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\t" MIPS_ISA_LEVEL "\n\t" \
"dins\t%L0, %M0, 32, 32\n\t" \
"dmtc0\t%L0, " #source ", " #sel "\n\t" \
".set\tpop" \
: "+r" (__tmp)); \
else if (sel == 0) \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips64\n\t" \
"dsll\t%L0, %L0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
"dsll\t%M0, %M0, 32\n\t" \
"or\t%L0, %L0, %M0\n\t" \
"dmtc0\t%L0, " #source "\n\t" \
".set\tmips0" \
: : "r" (val)); \
".set\tpop" \
: "+r" (__tmp)); \
else \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips64\n\t" \
"dsll\t%L0, %L0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
"dsll\t%M0, %M0, 32\n\t" \
"or\t%L0, %L0, %M0\n\t" \
"dmtc0\t%L0, " #source ", " #sel "\n\t" \
".set\tmips0" \
: : "r" (val)); \
".set\tpop" \
: "+r" (__tmp)); \
} while (0)
#define __readx_32bit_c0_register(source) \
#ifndef TOOLCHAIN_SUPPORTS_XPA
_ASM_MACRO_2R_1S(mfhc0, rt, rs, sel,
_ASM_INSN_IF_MIPS(0x40400000 | __rt << 16 | __rs << 11 | \\sel)
_ASM_INSN32_IF_MM(0x000000f4 | __rt << 21 | __rs << 16 | \\sel << 11));
_ASM_MACRO_2R_1S(mthc0, rt, rd, sel,
_ASM_INSN_IF_MIPS(0x40c00000 | __rt << 16 | __rd << 11 | \\sel)
_ASM_INSN32_IF_MM(0x000002f4 | __rt << 21 | __rd << 16 | \\sel << 11));
#define _ASM_SET_XPA ""
#else /* !TOOLCHAIN_SUPPORTS_XPA */
#define _ASM_SET_XPA ".set\txpa\n\t"
#endif
#define __readx_32bit_c0_register(source, sel) \
({ \
unsigned int __res; \
\
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
" .set mips32r2 \n" \
" .insn \n" \
" # mfhc0 $1, %1 \n" \
" .word (0x40410000 | ((%1 & 0x1f) << 11)) \n" \
" move %0, $1 \n" \
_ASM_SET_XPA \
" mfhc0 %0, " #source ", %1 \n" \
" .set pop \n" \
: "=r" (__res) \
: "i" (source)); \
: "i" (sel)); \
__res; \
})
#define __writex_32bit_c0_register(register, value) \
({ \
#define __writex_32bit_c0_register(register, sel, value) \
do { \
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
" .set mips32r2 \n" \
" move $1, %0 \n" \
" # mthc0 $1, %1 \n" \
" .insn \n" \
" .word (0x40c10000 | ((%1 & 0x1f) << 11)) \n" \
_ASM_SET_XPA \
" mthc0 %z0, " #register ", %1 \n" \
" .set pop \n" \
: \
: "r" (value), "i" (register)); \
})
: "Jr" (value), "i" (sel)); \
} while (0)
#define read_c0_index() __read_32bit_c0_register($0, 0)
#define write_c0_index(val) __write_32bit_c0_register($0, 0, val)
......@@ -1103,24 +1545,35 @@ do { \
#define read_c0_entrylo0() __read_ulong_c0_register($2, 0)
#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val)
#define readx_c0_entrylo0() __readx_32bit_c0_register(2)
#define writex_c0_entrylo0(val) __writex_32bit_c0_register(2, val)
#define readx_c0_entrylo0() __readx_32bit_c0_register($2, 0)
#define writex_c0_entrylo0(val) __writex_32bit_c0_register($2, 0, val)
#define read_c0_entrylo1() __read_ulong_c0_register($3, 0)
#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val)
#define readx_c0_entrylo1() __readx_32bit_c0_register(3)
#define writex_c0_entrylo1(val) __writex_32bit_c0_register(3, val)
#define readx_c0_entrylo1() __readx_32bit_c0_register($3, 0)
#define writex_c0_entrylo1(val) __writex_32bit_c0_register($3, 0, val)
#define read_c0_conf() __read_32bit_c0_register($3, 0)
#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val)
#define read_c0_globalnumber() __read_32bit_c0_register($3, 1)
#define read_c0_context() __read_ulong_c0_register($4, 0)
#define write_c0_context(val) __write_ulong_c0_register($4, 0, val)
#define read_c0_contextconfig() __read_32bit_c0_register($4, 1)
#define write_c0_contextconfig(val) __write_32bit_c0_register($4, 1, val)
#define read_c0_userlocal() __read_ulong_c0_register($4, 2)
#define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val)
#define read_c0_xcontextconfig() __read_ulong_c0_register($4, 3)
#define write_c0_xcontextconfig(val) __write_ulong_c0_register($4, 3, val)
#define read_c0_memorymapid() __read_32bit_c0_register($4, 5)
#define write_c0_memorymapid(val) __write_32bit_c0_register($4, 5, val)
#define read_c0_pagemask() __read_32bit_c0_register($5, 0)
#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val)
......@@ -1138,6 +1591,9 @@ do { \
#define read_c0_badvaddr() __read_ulong_c0_register($8, 0)
#define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val)
#define read_c0_badinstr() __read_32bit_c0_register($8, 1)
#define read_c0_badinstrp() __read_32bit_c0_register($8, 2)
#define read_c0_count() __read_32bit_c0_register($9, 0)
#define write_c0_count(val) __write_32bit_c0_register($9, 0, val)
......@@ -1150,9 +1606,21 @@ do { \
#define read_c0_entryhi() __read_ulong_c0_register($10, 0)
#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val)
#define read_c0_guestctl1() __read_32bit_c0_register($10, 4)
#define write_c0_guestctl1(val) __write_32bit_c0_register($10, 4, val)
#define read_c0_guestctl2() __read_32bit_c0_register($10, 5)
#define write_c0_guestctl2(val) __write_32bit_c0_register($10, 5, val)
#define read_c0_guestctl3() __read_32bit_c0_register($10, 6)
#define write_c0_guestctl3(val) __write_32bit_c0_register($10, 6, val)
#define read_c0_compare() __read_32bit_c0_register($11, 0)
#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val)
#define read_c0_guestctl0ext() __read_32bit_c0_register($11, 4)
#define write_c0_guestctl0ext(val) __write_32bit_c0_register($11, 4, val)
#define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */
#define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val)
......@@ -1163,13 +1631,19 @@ do { \
#define write_c0_status(val) __write_32bit_c0_register($12, 0, val)
#define read_c0_guestctl0() __read_32bit_c0_register($12, 6)
#define write_c0_guestctl0(val) __write_32bit_c0_register($12, 6, val)
#define read_c0_gtoffset() __read_32bit_c0_register($12, 7)
#define write_c0_gtoffset(val) __write_32bit_c0_register($12, 7, 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_epc() __read_ulong_c0_register($14, 0)
#define write_c0_epc(val) __write_ulong_c0_register($14, 0, val)
#define read_c0_prid() __read_32bit_c0_register($15, 0)
#define read_c0_prid() __read_const_32bit_c0_register($15, 0)
#define read_c0_cmgcrbase() __read_ulong_c0_register($15, 3)
......@@ -1348,6 +1822,9 @@ do { \
#define read_c0_ebase() __read_32bit_c0_register($15, 1)
#define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val)
#define read_c0_ebase_64() __read_64bit_c0_register($15, 1)
#define write_c0_ebase_64(val) __write_64bit_c0_register($15, 1, val)
#define read_c0_cdmmbase() __read_ulong_c0_register($15, 2)
#define write_c0_cdmmbase(val) __write_ulong_c0_register($15, 2, val)
......@@ -1374,6 +1851,12 @@ do { \
#define read_c0_pwctl() __read_32bit_c0_register($6, 6)
#define write_c0_pwctl(val) __write_32bit_c0_register($6, 6, val)
#define read_c0_pgd() __read_64bit_c0_register($9, 7)
#define write_c0_pgd(val) __write_64bit_c0_register($9, 7, val)
#define read_c0_kpgd() __read_64bit_c0_register($31, 7)
#define write_c0_kpgd(val) __write_64bit_c0_register($31, 7, val)
/* Cavium OCTEON (cnMIPS) */
#define read_c0_cvmcount() __read_ulong_c0_register($9, 6)
#define write_c0_cvmcount(val) __write_ulong_c0_register($9, 6, val)
......@@ -1383,6 +1866,13 @@ do { \
#define read_c0_cvmmemctl() __read_64bit_c0_register($11, 7)
#define write_c0_cvmmemctl(val) __write_64bit_c0_register($11, 7, val)
#define read_c0_cvmmemctl2() __read_64bit_c0_register($16, 6)
#define write_c0_cvmmemctl2(val) __write_64bit_c0_register($16, 6, val)
#define read_c0_cvmvmconfig() __read_64bit_c0_register($16, 7)
#define write_c0_cvmvmconfig(val) __write_64bit_c0_register($16, 7, val)
/*
* The cacheerr registers are not standardized. On OCTEON, they are
* 64 bits wide.
......@@ -1438,6 +1928,306 @@ do { \
#define read_c0_brcm_sleepcount() __read_32bit_c0_register($22, 7)
#define write_c0_brcm_sleepcount(val) __write_32bit_c0_register($22, 7, val)
/* Ingenic page ctrl register */
#define write_c0_page_ctrl(val) __write_32bit_c0_register($5, 4, val)
/*
* Macros to access the guest system control coprocessor
*/
#ifndef TOOLCHAIN_SUPPORTS_VIRT
_ASM_MACRO_2R_1S(mfgc0, rt, rs, sel,
_ASM_INSN_IF_MIPS(0x40600000 | __rt << 16 | __rs << 11 | \\sel)
_ASM_INSN32_IF_MM(0x000004fc | __rt << 21 | __rs << 16 | \\sel << 11));
_ASM_MACRO_2R_1S(dmfgc0, rt, rs, sel,
_ASM_INSN_IF_MIPS(0x40600100 | __rt << 16 | __rs << 11 | \\sel)
_ASM_INSN32_IF_MM(0x580004fc | __rt << 21 | __rs << 16 | \\sel << 11));
_ASM_MACRO_2R_1S(mtgc0, rt, rd, sel,
_ASM_INSN_IF_MIPS(0x40600200 | __rt << 16 | __rd << 11 | \\sel)
_ASM_INSN32_IF_MM(0x000006fc | __rt << 21 | __rd << 16 | \\sel << 11));
_ASM_MACRO_2R_1S(dmtgc0, rt, rd, sel,
_ASM_INSN_IF_MIPS(0x40600300 | __rt << 16 | __rd << 11 | \\sel)
_ASM_INSN32_IF_MM(0x580006fc | __rt << 21 | __rd << 16 | \\sel << 11));
_ASM_MACRO_0(tlbgp, _ASM_INSN_IF_MIPS(0x42000010)
_ASM_INSN32_IF_MM(0x0000017c));
_ASM_MACRO_0(tlbgr, _ASM_INSN_IF_MIPS(0x42000009)
_ASM_INSN32_IF_MM(0x0000117c));
_ASM_MACRO_0(tlbgwi, _ASM_INSN_IF_MIPS(0x4200000a)
_ASM_INSN32_IF_MM(0x0000217c));
_ASM_MACRO_0(tlbgwr, _ASM_INSN_IF_MIPS(0x4200000e)
_ASM_INSN32_IF_MM(0x0000317c));
_ASM_MACRO_0(tlbginvf, _ASM_INSN_IF_MIPS(0x4200000c)
_ASM_INSN32_IF_MM(0x0000517c));
#define _ASM_SET_VIRT ""
#else /* !TOOLCHAIN_SUPPORTS_VIRT */
#define _ASM_SET_VIRT ".set\tvirt\n\t"
#endif
#define __read_32bit_gc0_register(source, sel) \
({ int __res; \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips32r2\n\t" \
_ASM_SET_VIRT \
"mfgc0\t%0, " #source ", %1\n\t" \
".set\tpop" \
: "=r" (__res) \
: "i" (sel)); \
__res; \
})
#define __read_64bit_gc0_register(source, sel) \
({ unsigned long long __res; \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips64r2\n\t" \
_ASM_SET_VIRT \
"dmfgc0\t%0, " #source ", %1\n\t" \
".set\tpop" \
: "=r" (__res) \
: "i" (sel)); \
__res; \
})
#define __write_32bit_gc0_register(register, sel, value) \
do { \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips32r2\n\t" \
_ASM_SET_VIRT \
"mtgc0\t%z0, " #register ", %1\n\t" \
".set\tpop" \
: : "Jr" ((unsigned int)(value)), \
"i" (sel)); \
} while (0)
#define __write_64bit_gc0_register(register, sel, value) \
do { \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips64r2\n\t" \
_ASM_SET_VIRT \
"dmtgc0\t%z0, " #register ", %1\n\t" \
".set\tpop" \
: : "Jr" (value), \
"i" (sel)); \
} while (0)
#define __read_ulong_gc0_register(reg, sel) \
((sizeof(unsigned long) == 4) ? \
(unsigned long) __read_32bit_gc0_register(reg, sel) : \
(unsigned long) __read_64bit_gc0_register(reg, sel))
#define __write_ulong_gc0_register(reg, sel, val) \
do { \
if (sizeof(unsigned long) == 4) \
__write_32bit_gc0_register(reg, sel, val); \
else \
__write_64bit_gc0_register(reg, sel, val); \
} while (0)
#define read_gc0_index() __read_32bit_gc0_register($0, 0)
#define write_gc0_index(val) __write_32bit_gc0_register($0, 0, val)
#define read_gc0_entrylo0() __read_ulong_gc0_register($2, 0)
#define write_gc0_entrylo0(val) __write_ulong_gc0_register($2, 0, val)
#define read_gc0_entrylo1() __read_ulong_gc0_register($3, 0)
#define write_gc0_entrylo1(val) __write_ulong_gc0_register($3, 0, val)
#define read_gc0_context() __read_ulong_gc0_register($4, 0)
#define write_gc0_context(val) __write_ulong_gc0_register($4, 0, val)
#define read_gc0_contextconfig() __read_32bit_gc0_register($4, 1)
#define write_gc0_contextconfig(val) __write_32bit_gc0_register($4, 1, val)
#define read_gc0_userlocal() __read_ulong_gc0_register($4, 2)
#define write_gc0_userlocal(val) __write_ulong_gc0_register($4, 2, val)
#define read_gc0_xcontextconfig() __read_ulong_gc0_register($4, 3)
#define write_gc0_xcontextconfig(val) __write_ulong_gc0_register($4, 3, val)
#define read_gc0_pagemask() __read_32bit_gc0_register($5, 0)
#define write_gc0_pagemask(val) __write_32bit_gc0_register($5, 0, val)
#define read_gc0_pagegrain() __read_32bit_gc0_register($5, 1)
#define write_gc0_pagegrain(val) __write_32bit_gc0_register($5, 1, val)
#define read_gc0_segctl0() __read_ulong_gc0_register($5, 2)
#define write_gc0_segctl0(val) __write_ulong_gc0_register($5, 2, val)
#define read_gc0_segctl1() __read_ulong_gc0_register($5, 3)
#define write_gc0_segctl1(val) __write_ulong_gc0_register($5, 3, val)
#define read_gc0_segctl2() __read_ulong_gc0_register($5, 4)
#define write_gc0_segctl2(val) __write_ulong_gc0_register($5, 4, val)
#define read_gc0_pwbase() __read_ulong_gc0_register($5, 5)
#define write_gc0_pwbase(val) __write_ulong_gc0_register($5, 5, val)
#define read_gc0_pwfield() __read_ulong_gc0_register($5, 6)
#define write_gc0_pwfield(val) __write_ulong_gc0_register($5, 6, val)
#define read_gc0_pwsize() __read_ulong_gc0_register($5, 7)
#define write_gc0_pwsize(val) __write_ulong_gc0_register($5, 7, val)
#define read_gc0_wired() __read_32bit_gc0_register($6, 0)
#define write_gc0_wired(val) __write_32bit_gc0_register($6, 0, val)
#define read_gc0_pwctl() __read_32bit_gc0_register($6, 6)
#define write_gc0_pwctl(val) __write_32bit_gc0_register($6, 6, val)
#define read_gc0_hwrena() __read_32bit_gc0_register($7, 0)
#define write_gc0_hwrena(val) __write_32bit_gc0_register($7, 0, val)
#define read_gc0_badvaddr() __read_ulong_gc0_register($8, 0)
#define write_gc0_badvaddr(val) __write_ulong_gc0_register($8, 0, val)
#define read_gc0_badinstr() __read_32bit_gc0_register($8, 1)
#define write_gc0_badinstr(val) __write_32bit_gc0_register($8, 1, val)
#define read_gc0_badinstrp() __read_32bit_gc0_register($8, 2)
#define write_gc0_badinstrp(val) __write_32bit_gc0_register($8, 2, val)
#define read_gc0_count() __read_32bit_gc0_register($9, 0)
#define read_gc0_entryhi() __read_ulong_gc0_register($10, 0)
#define write_gc0_entryhi(val) __write_ulong_gc0_register($10, 0, val)
#define read_gc0_compare() __read_32bit_gc0_register($11, 0)
#define write_gc0_compare(val) __write_32bit_gc0_register($11, 0, val)
#define read_gc0_status() __read_32bit_gc0_register($12, 0)
#define write_gc0_status(val) __write_32bit_gc0_register($12, 0, val)
#define read_gc0_intctl() __read_32bit_gc0_register($12, 1)
#define write_gc0_intctl(val) __write_32bit_gc0_register($12, 1, val)
#define read_gc0_cause() __read_32bit_gc0_register($13, 0)
#define write_gc0_cause(val) __write_32bit_gc0_register($13, 0, val)
#define read_gc0_epc() __read_ulong_gc0_register($14, 0)
#define write_gc0_epc(val) __write_ulong_gc0_register($14, 0, val)
#define read_gc0_prid() __read_32bit_gc0_register($15, 0)
#define read_gc0_ebase() __read_32bit_gc0_register($15, 1)
#define write_gc0_ebase(val) __write_32bit_gc0_register($15, 1, val)
#define read_gc0_ebase_64() __read_64bit_gc0_register($15, 1)
#define write_gc0_ebase_64(val) __write_64bit_gc0_register($15, 1, val)
#define read_gc0_config() __read_32bit_gc0_register($16, 0)
#define read_gc0_config1() __read_32bit_gc0_register($16, 1)
#define read_gc0_config2() __read_32bit_gc0_register($16, 2)
#define read_gc0_config3() __read_32bit_gc0_register($16, 3)
#define read_gc0_config4() __read_32bit_gc0_register($16, 4)
#define read_gc0_config5() __read_32bit_gc0_register($16, 5)
#define read_gc0_config6() __read_32bit_gc0_register($16, 6)
#define read_gc0_config7() __read_32bit_gc0_register($16, 7)
#define write_gc0_config(val) __write_32bit_gc0_register($16, 0, val)
#define write_gc0_config1(val) __write_32bit_gc0_register($16, 1, val)
#define write_gc0_config2(val) __write_32bit_gc0_register($16, 2, val)
#define write_gc0_config3(val) __write_32bit_gc0_register($16, 3, val)
#define write_gc0_config4(val) __write_32bit_gc0_register($16, 4, val)
#define write_gc0_config5(val) __write_32bit_gc0_register($16, 5, val)
#define write_gc0_config6(val) __write_32bit_gc0_register($16, 6, val)
#define write_gc0_config7(val) __write_32bit_gc0_register($16, 7, val)
#define read_gc0_lladdr() __read_ulong_gc0_register($17, 0)
#define write_gc0_lladdr(val) __write_ulong_gc0_register($17, 0, val)
#define read_gc0_watchlo0() __read_ulong_gc0_register($18, 0)
#define read_gc0_watchlo1() __read_ulong_gc0_register($18, 1)
#define read_gc0_watchlo2() __read_ulong_gc0_register($18, 2)
#define read_gc0_watchlo3() __read_ulong_gc0_register($18, 3)
#define read_gc0_watchlo4() __read_ulong_gc0_register($18, 4)
#define read_gc0_watchlo5() __read_ulong_gc0_register($18, 5)
#define read_gc0_watchlo6() __read_ulong_gc0_register($18, 6)
#define read_gc0_watchlo7() __read_ulong_gc0_register($18, 7)
#define write_gc0_watchlo0(val) __write_ulong_gc0_register($18, 0, val)
#define write_gc0_watchlo1(val) __write_ulong_gc0_register($18, 1, val)
#define write_gc0_watchlo2(val) __write_ulong_gc0_register($18, 2, val)
#define write_gc0_watchlo3(val) __write_ulong_gc0_register($18, 3, val)
#define write_gc0_watchlo4(val) __write_ulong_gc0_register($18, 4, val)
#define write_gc0_watchlo5(val) __write_ulong_gc0_register($18, 5, val)
#define write_gc0_watchlo6(val) __write_ulong_gc0_register($18, 6, val)
#define write_gc0_watchlo7(val) __write_ulong_gc0_register($18, 7, val)
#define read_gc0_watchhi0() __read_32bit_gc0_register($19, 0)
#define read_gc0_watchhi1() __read_32bit_gc0_register($19, 1)
#define read_gc0_watchhi2() __read_32bit_gc0_register($19, 2)
#define read_gc0_watchhi3() __read_32bit_gc0_register($19, 3)
#define read_gc0_watchhi4() __read_32bit_gc0_register($19, 4)
#define read_gc0_watchhi5() __read_32bit_gc0_register($19, 5)
#define read_gc0_watchhi6() __read_32bit_gc0_register($19, 6)
#define read_gc0_watchhi7() __read_32bit_gc0_register($19, 7)
#define write_gc0_watchhi0(val) __write_32bit_gc0_register($19, 0, val)
#define write_gc0_watchhi1(val) __write_32bit_gc0_register($19, 1, val)
#define write_gc0_watchhi2(val) __write_32bit_gc0_register($19, 2, val)
#define write_gc0_watchhi3(val) __write_32bit_gc0_register($19, 3, val)
#define write_gc0_watchhi4(val) __write_32bit_gc0_register($19, 4, val)
#define write_gc0_watchhi5(val) __write_32bit_gc0_register($19, 5, val)
#define write_gc0_watchhi6(val) __write_32bit_gc0_register($19, 6, val)
#define write_gc0_watchhi7(val) __write_32bit_gc0_register($19, 7, val)
#define read_gc0_xcontext() __read_ulong_gc0_register($20, 0)
#define write_gc0_xcontext(val) __write_ulong_gc0_register($20, 0, val)
#define read_gc0_perfctrl0() __read_32bit_gc0_register($25, 0)
#define write_gc0_perfctrl0(val) __write_32bit_gc0_register($25, 0, val)
#define read_gc0_perfcntr0() __read_32bit_gc0_register($25, 1)
#define write_gc0_perfcntr0(val) __write_32bit_gc0_register($25, 1, val)
#define read_gc0_perfcntr0_64() __read_64bit_gc0_register($25, 1)
#define write_gc0_perfcntr0_64(val) __write_64bit_gc0_register($25, 1, val)
#define read_gc0_perfctrl1() __read_32bit_gc0_register($25, 2)
#define write_gc0_perfctrl1(val) __write_32bit_gc0_register($25, 2, val)
#define read_gc0_perfcntr1() __read_32bit_gc0_register($25, 3)
#define write_gc0_perfcntr1(val) __write_32bit_gc0_register($25, 3, val)
#define read_gc0_perfcntr1_64() __read_64bit_gc0_register($25, 3)
#define write_gc0_perfcntr1_64(val) __write_64bit_gc0_register($25, 3, val)
#define read_gc0_perfctrl2() __read_32bit_gc0_register($25, 4)
#define write_gc0_perfctrl2(val) __write_32bit_gc0_register($25, 4, val)
#define read_gc0_perfcntr2() __read_32bit_gc0_register($25, 5)
#define write_gc0_perfcntr2(val) __write_32bit_gc0_register($25, 5, val)
#define read_gc0_perfcntr2_64() __read_64bit_gc0_register($25, 5)
#define write_gc0_perfcntr2_64(val) __write_64bit_gc0_register($25, 5, val)
#define read_gc0_perfctrl3() __read_32bit_gc0_register($25, 6)
#define write_gc0_perfctrl3(val) __write_32bit_gc0_register($25, 6, val)
#define read_gc0_perfcntr3() __read_32bit_gc0_register($25, 7)
#define write_gc0_perfcntr3(val) __write_32bit_gc0_register($25, 7, val)
#define read_gc0_perfcntr3_64() __read_64bit_gc0_register($25, 7)
#define write_gc0_perfcntr3_64(val) __write_64bit_gc0_register($25, 7, val)
#define read_gc0_errorepc() __read_ulong_gc0_register($30, 0)
#define write_gc0_errorepc(val) __write_ulong_gc0_register($30, 0, val)
#define read_gc0_kscratch1() __read_ulong_gc0_register($31, 2)
#define read_gc0_kscratch2() __read_ulong_gc0_register($31, 3)
#define read_gc0_kscratch3() __read_ulong_gc0_register($31, 4)
#define read_gc0_kscratch4() __read_ulong_gc0_register($31, 5)
#define read_gc0_kscratch5() __read_ulong_gc0_register($31, 6)
#define read_gc0_kscratch6() __read_ulong_gc0_register($31, 7)
#define write_gc0_kscratch1(val) __write_ulong_gc0_register($31, 2, val)
#define write_gc0_kscratch2(val) __write_ulong_gc0_register($31, 3, val)
#define write_gc0_kscratch3(val) __write_ulong_gc0_register($31, 4, val)
#define write_gc0_kscratch4(val) __write_ulong_gc0_register($31, 5, val)
#define write_gc0_kscratch5(val) __write_ulong_gc0_register($31, 6, val)
#define write_gc0_kscratch6(val) __write_ulong_gc0_register($31, 7, val)
/* Cavium OCTEON (cnMIPS) */
#define read_gc0_cvmcount() __read_ulong_gc0_register($9, 6)
#define write_gc0_cvmcount(val) __write_ulong_gc0_register($9, 6, val)
#define read_gc0_cvmctl() __read_64bit_gc0_register($9, 7)
#define write_gc0_cvmctl(val) __write_64bit_gc0_register($9, 7, val)
#define read_gc0_cvmmemctl() __read_64bit_gc0_register($11, 7)
#define write_gc0_cvmmemctl(val) __write_64bit_gc0_register($11, 7, val)
#define read_gc0_cvmmemctl2() __read_64bit_gc0_register($16, 6)
#define write_gc0_cvmmemctl2(val) __write_64bit_gc0_register($16, 6, val)
/*
* Macros to access the floating point coprocessor control registers
*/
......@@ -1459,7 +2249,7 @@ do { \
})
#define _write_32bit_cp1_register(dest, val, gas_hardfloat) \
({ \
do { \
__asm__ __volatile__( \
" .set push \n" \
" .set reorder \n" \
......@@ -1467,7 +2257,7 @@ do { \
" ctc1 %0,"STR(dest)" \n" \
" .set pop \n" \
: : "r" (val)); \
})
} while (0)
#ifdef GAS_HAS_SET_HARDFLOAT
#define read_32bit_cp1_register(source) \
......@@ -1481,13 +2271,14 @@ do { \
_write_32bit_cp1_register(dest, val, )
#endif
#ifdef HAVE_AS_DSP
#ifdef TOOLCHAIN_SUPPORTS_DSP
#define rddsp(mask) \
({ \
unsigned int __dspctl; \
\
__asm__ __volatile__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" rddsp %0, %x1 \n" \
" .set pop \n" \
......@@ -1497,21 +2288,23 @@ do { \
})
#define wrdsp(val, mask) \
({ \
do { \
__asm__ __volatile__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" wrdsp %0, %x1 \n" \
" .set pop \n" \
: \
: "r" (val), "i" (mask)); \
})
} while (0)
#define mflo0() \
({ \
long mflo0; \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mflo %0, $ac0 \n" \
" .set pop \n" \
......@@ -1524,6 +2317,7 @@ do { \
long mflo1; \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mflo %0, $ac1 \n" \
" .set pop \n" \
......@@ -1536,6 +2330,7 @@ do { \
long mflo2; \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mflo %0, $ac2 \n" \
" .set pop \n" \
......@@ -1548,6 +2343,7 @@ do { \
long mflo3; \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mflo %0, $ac3 \n" \
" .set pop \n" \
......@@ -1560,6 +2356,7 @@ do { \
long mfhi0; \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mfhi %0, $ac0 \n" \
" .set pop \n" \
......@@ -1572,6 +2369,7 @@ do { \
long mfhi1; \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mfhi %0, $ac1 \n" \
" .set pop \n" \
......@@ -1584,6 +2382,7 @@ do { \
long mfhi2; \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mfhi %0, $ac2 \n" \
" .set pop \n" \
......@@ -1596,6 +2395,7 @@ do { \
long mfhi3; \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mfhi %0, $ac3 \n" \
" .set pop \n" \
......@@ -1608,6 +2408,7 @@ do { \
({ \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mtlo %0, $ac0 \n" \
" .set pop \n" \
......@@ -1619,6 +2420,7 @@ do { \
({ \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mtlo %0, $ac1 \n" \
" .set pop \n" \
......@@ -1630,6 +2432,7 @@ do { \
({ \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mtlo %0, $ac2 \n" \
" .set pop \n" \
......@@ -1641,6 +2444,7 @@ do { \
({ \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mtlo %0, $ac3 \n" \
" .set pop \n" \
......@@ -1652,6 +2456,7 @@ do { \
({ \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mthi %0, $ac0 \n" \
" .set pop \n" \
......@@ -1663,6 +2468,7 @@ do { \
({ \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mthi %0, $ac1 \n" \
" .set pop \n" \
......@@ -1674,6 +2480,7 @@ do { \
({ \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mthi %0, $ac2 \n" \
" .set pop \n" \
......@@ -1685,6 +2492,7 @@ do { \
({ \
__asm__( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" .set dsp \n" \
" mthi %0, $ac3 \n" \
" .set pop \n" \
......@@ -1694,7 +2502,6 @@ do { \
#else
#ifdef CONFIG_CPU_MICROMIPS
#define rddsp(mask) \
({ \
unsigned int __res; \
......@@ -1703,8 +2510,8 @@ do { \
" .set push \n" \
" .set noat \n" \
" # rddsp $1, %x1 \n" \
" .hword ((0x0020067c | (%x1 << 14)) >> 16) \n" \
" .hword ((0x0020067c | (%x1 << 14)) & 0xffff) \n" \
_ASM_INSN_IF_MIPS(0x7c000cb8 | (%x1 << 16)) \
_ASM_INSN32_IF_MM(0x0020067c | (%x1 << 14)) \
" move %0, $1 \n" \
" .set pop \n" \
: "=r" (__res) \
......@@ -1713,28 +2520,28 @@ do { \
})
#define wrdsp(val, mask) \
({ \
do { \
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
" move $1, %0 \n" \
" # wrdsp $1, %x1 \n" \
" .hword ((0x0020167c | (%x1 << 14)) >> 16) \n" \
" .hword ((0x0020167c | (%x1 << 14)) & 0xffff) \n" \
_ASM_INSN_IF_MIPS(0x7c2004f8 | (%x1 << 11)) \
_ASM_INSN32_IF_MM(0x0020167c | (%x1 << 14)) \
" .set pop \n" \
: \
: "r" (val), "i" (mask)); \
})
} while (0)
#define _umips_dsp_mfxxx(ins) \
#define _dsp_mfxxx(ins) \
({ \
unsigned long __treg; \
\
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
" .hword 0x0001 \n" \
" .hword %x1 \n" \
_ASM_INSN_IF_MIPS(0x00000810 | %X1) \
_ASM_INSN32_IF_MM(0x0001007c | %x1) \
" move %0, $1 \n" \
" .set pop \n" \
: "=r" (__treg) \
......@@ -1742,101 +2549,28 @@ do { \
__treg; \
})
#define _umips_dsp_mtxxx(val, ins) \
({ \
#define _dsp_mtxxx(val, ins) \
do { \
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
" move $1, %0 \n" \
" .hword 0x0001 \n" \
" .hword %x1 \n" \
_ASM_INSN_IF_MIPS(0x00200011 | %X1) \
_ASM_INSN32_IF_MM(0x0001207c | %x1) \
" .set pop \n" \
: \
: "r" (val), "i" (ins)); \
})
#define _umips_dsp_mflo(reg) _umips_dsp_mfxxx((reg << 14) | 0x107c)
#define _umips_dsp_mfhi(reg) _umips_dsp_mfxxx((reg << 14) | 0x007c)
#define _umips_dsp_mtlo(val, reg) _umips_dsp_mtxxx(val, ((reg << 14) | 0x307c))
#define _umips_dsp_mthi(val, reg) _umips_dsp_mtxxx(val, ((reg << 14) | 0x207c))
#define mflo0() _umips_dsp_mflo(0)
#define mflo1() _umips_dsp_mflo(1)
#define mflo2() _umips_dsp_mflo(2)
#define mflo3() _umips_dsp_mflo(3)
} while (0)
#define mfhi0() _umips_dsp_mfhi(0)
#define mfhi1() _umips_dsp_mfhi(1)
#define mfhi2() _umips_dsp_mfhi(2)
#define mfhi3() _umips_dsp_mfhi(3)
#ifdef CONFIG_CPU_MICROMIPS
#define mtlo0(x) _umips_dsp_mtlo(x, 0)
#define mtlo1(x) _umips_dsp_mtlo(x, 1)
#define mtlo2(x) _umips_dsp_mtlo(x, 2)
#define mtlo3(x) _umips_dsp_mtlo(x, 3)
#define _dsp_mflo(reg) _dsp_mfxxx((reg << 14) | 0x1000)
#define _dsp_mfhi(reg) _dsp_mfxxx((reg << 14) | 0x0000)
#define mthi0(x) _umips_dsp_mthi(x, 0)
#define mthi1(x) _umips_dsp_mthi(x, 1)
#define mthi2(x) _umips_dsp_mthi(x, 2)
#define mthi3(x) _umips_dsp_mthi(x, 3)
#define _dsp_mtlo(val, reg) _dsp_mtxxx(val, ((reg << 14) | 0x1000))
#define _dsp_mthi(val, reg) _dsp_mtxxx(val, ((reg << 14) | 0x0000))
#else /* !CONFIG_CPU_MICROMIPS */
#define rddsp(mask) \
({ \
unsigned int __res; \
\
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
" # rddsp $1, %x1 \n" \
" .word 0x7c000cb8 | (%x1 << 16) \n" \
" move %0, $1 \n" \
" .set pop \n" \
: "=r" (__res) \
: "i" (mask)); \
__res; \
})
#define wrdsp(val, mask) \
({ \
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
" move $1, %0 \n" \
" # wrdsp $1, %x1 \n" \
" .word 0x7c2004f8 | (%x1 << 11) \n" \
" .set pop \n" \
: \
: "r" (val), "i" (mask)); \
})
#define _dsp_mfxxx(ins) \
({ \
unsigned long __treg; \
\
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
" .word (0x00000810 | %1) \n" \
" move %0, $1 \n" \
" .set pop \n" \
: "=r" (__treg) \
: "i" (ins)); \
__treg; \
})
#define _dsp_mtxxx(val, ins) \
({ \
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
" move $1, %0 \n" \
" .word (0x00200011 | %1) \n" \
" .set pop \n" \
: \
: "r" (val), "i" (ins)); \
})
#define _dsp_mflo(reg) _dsp_mfxxx((reg << 21) | 0x0002)
#define _dsp_mfhi(reg) _dsp_mfxxx((reg << 21) | 0x0000)
......@@ -1844,6 +2578,8 @@ do { \
#define _dsp_mtlo(val, reg) _dsp_mtxxx(val, ((reg << 11) | 0x0002))
#define _dsp_mthi(val, reg) _dsp_mtxxx(val, ((reg << 11) | 0x0000))
#endif /* CONFIG_CPU_MICROMIPS */
#define mflo0() _dsp_mflo(0)
#define mflo1() _dsp_mflo(1)
#define mflo2() _dsp_mflo(2)
......@@ -1864,7 +2600,6 @@ do { \
#define mthi2(x) _dsp_mthi(x, 2)
#define mthi3(x) _dsp_mthi(x, 3)
#endif /* CONFIG_CPU_MICROMIPS */
#endif
/*
......@@ -1934,54 +2669,123 @@ static inline void tlb_write_random(void)
}
/*
* Manipulate bits in a c0 register.
* Guest TLB operations.
*
* It is responsibility of the caller to take care of any TLB hazards.
*/
#define __BUILD_SET_C0(name) \
static inline void guest_tlb_probe(void)
{
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
_ASM_SET_VIRT
"tlbgp\n\t"
".set pop");
}
static inline void guest_tlb_read(void)
{
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
_ASM_SET_VIRT
"tlbgr\n\t"
".set pop");
}
static inline void guest_tlb_write_indexed(void)
{
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
_ASM_SET_VIRT
"tlbgwi\n\t"
".set pop");
}
static inline void guest_tlb_write_random(void)
{
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
_ASM_SET_VIRT
"tlbgwr\n\t"
".set pop");
}
/*
* Guest TLB Invalidate Flush
*/
static inline void guest_tlbinvf(void)
{
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
_ASM_SET_VIRT
"tlbginvf\n\t"
".set pop");
}
/*
* Manipulate bits in a register.
*/
#define __BUILD_SET_COMMON(name) \
static inline unsigned int \
set_c0_##name(unsigned int set) \
set_##name(unsigned int set) \
{ \
unsigned int res, new; \
\
res = read_c0_##name(); \
res = read_##name(); \
new = res | set; \
write_c0_##name(new); \
write_##name(new); \
\
return res; \
} \
\
static inline unsigned int \
clear_c0_##name(unsigned int clear) \
clear_##name(unsigned int clear) \
{ \
unsigned int res, new; \
\
res = read_c0_##name(); \
res = read_##name(); \
new = res & ~clear; \
write_c0_##name(new); \
write_##name(new); \
\
return res; \
} \
\
static inline unsigned int \
change_c0_##name(unsigned int change, unsigned int val) \
change_##name(unsigned int change, unsigned int val) \
{ \
unsigned int res, new; \
\
res = read_c0_##name(); \
res = read_##name(); \
new = res & ~change; \
new |= (val & change); \
write_c0_##name(new); \
write_##name(new); \
\
return res; \
}
/*
* Manipulate bits in a c0 register.
*/
#define __BUILD_SET_C0(name) __BUILD_SET_COMMON(c0_##name)
__BUILD_SET_C0(status)
__BUILD_SET_C0(cause)
__BUILD_SET_C0(config)
__BUILD_SET_C0(config5)
__BUILD_SET_C0(config7)
__BUILD_SET_C0(intcontrol)
__BUILD_SET_C0(intctl)
__BUILD_SET_C0(srsmap)
__BUILD_SET_C0(pagegrain)
__BUILD_SET_C0(guestctl0)
__BUILD_SET_C0(guestctl0ext)
__BUILD_SET_C0(guestctl1)
__BUILD_SET_C0(guestctl2)
__BUILD_SET_C0(guestctl3)
__BUILD_SET_C0(brcm_config_0)
__BUILD_SET_C0(brcm_bus_pll)
__BUILD_SET_C0(brcm_reset)
......@@ -1990,13 +2794,24 @@ __BUILD_SET_C0(brcm_cmt_ctrl)
__BUILD_SET_C0(brcm_config)
__BUILD_SET_C0(brcm_mode)
/*
* Manipulate bits in a guest c0 register.
*/
#define __BUILD_SET_GC0(name) __BUILD_SET_COMMON(gc0_##name)
__BUILD_SET_GC0(wired)
__BUILD_SET_GC0(status)
__BUILD_SET_GC0(cause)
__BUILD_SET_GC0(ebase)
__BUILD_SET_GC0(config1)
/*
* Return low 10 bits of ebase.
* Note that under KVM (MIPSVZ) this returns vcpu id.
*/
static inline unsigned int get_ebase_cpunum(void)
{
return read_c0_ebase() & 0x3ff;
return read_c0_ebase() & MIPS_EBASE_CPUNUM;
}
static inline void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0,
......
......@@ -8,7 +8,7 @@
#ifndef __ASM_MIPS_RELOCS_H__
#define __ASM_MIPS_RELOCS_H__
#define R_MIPS_NONE 0
#define R_MIPS_NONE 0xbeef7531
#define R_MIPS_32 2
#define R_MIPS_26 4
#define R_MIPS_HI16 5
......
......@@ -51,7 +51,7 @@ void arch_lmb_reserve(struct lmb *lmb)
static void linux_cmdline_init(void)
{
linux_argc = 1;
linux_argv = (char **)UNCACHED_SDRAM(gd->bd->bi_boot_params);
linux_argv = (char **)CKSEG1ADDR(gd->bd->bi_boot_params);
linux_argv[0] = 0;
linux_argp = (char *)(linux_argv + LINUX_MAX_ARGS);
}
......@@ -186,7 +186,7 @@ static void linux_env_legacy(bootm_headers_t *images)
(ulong)(gd->ram_size >> 20));
}
rd_start = UNCACHED_SDRAM(images->initrd_start);
rd_start = CKSEG1ADDR(images->initrd_start);
rd_size = images->initrd_end - images->initrd_start;
linux_env_init();
......
......@@ -8,9 +8,7 @@
#include <cpu_func.h>
#include <asm/cache.h>
#include <asm/cacheops.h>
#ifdef CONFIG_MIPS_L2_CACHE
#include <asm/cm.h>
#endif
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
......@@ -109,7 +107,7 @@ static inline unsigned long scache_line_size(void)
} \
} while (0)
void flush_cache(ulong start_addr, ulong size)
void __weak flush_cache(ulong start_addr, ulong size)
{
unsigned long ilsize = icache_line_size();
unsigned long dlsize = dcache_line_size();
......@@ -161,7 +159,7 @@ void __weak flush_dcache_range(ulong start_addr, ulong stop)
sync();
}
void invalidate_dcache_range(ulong start_addr, ulong stop)
void __weak invalidate_dcache_range(ulong start_addr, ulong stop)
{
unsigned long lsize = dcache_line_size();
unsigned long slsize = scache_line_size();
......
......@@ -79,6 +79,21 @@
.set pop
.endm
/*
* The changing of Kernel mode cacheability must be done from KSEG1.
* If the code is executing from KSEG0, jump to KSEG1 during the execution
* of change_k0_cca. change_k0_cca itself clears all hazards when returning.
*/
.macro change_k0_cca_kseg1 mode
PTR_LA t0, change_k0_cca
li t1, CPHYSADDR(~0)
and t0, t0, t1
PTR_LI t1, CKSEG1
or t0, t0, t1
li a0, \mode
jalr t0
.endm
/*
* mips_cache_reset - low level initialisation of the primary caches
*
......@@ -317,18 +332,9 @@ l1_init:
sync
/*
* Enable use of the I-cache by setting Config.K0. The code for this
* must be executed from KSEG1. Jump from KSEG0 to KSEG1 to do this.
* Jump back to KSEG0 after caches are enabled and insert an
* instruction hazard barrier.
* Enable use of the I-cache by setting Config.K0.
*/
PTR_LA t0, change_k0_cca
li t1, CPHYSADDR(~0)
and t0, t0, t1
PTR_LI t1, CKSEG1
or t0, t0, t1
li a0, CONF_CM_CACHABLE_NONCOHERENT
jalr.hb t0
change_k0_cca_kseg1 CONF_CM_CACHABLE_NONCOHERENT
/*
* then initialize D-cache.
......@@ -388,9 +394,7 @@ l2_unbypass:
beqz t0, 2f
/* Change Config.K0 to a coherent CCA */
PTR_LA t0, change_k0_cca
li a0, CONF_CM_CACHABLE_COW
jalr t0
change_k0_cca_kseg1 CONF_CM_CACHABLE_COW
/*
* Join the coherent domain such that the caches of this core are kept
......@@ -414,6 +418,12 @@ return:
jr R_RETURN
END(mips_cache_reset)
LEAF(mips_cache_disable)
move R_RETURN, ra
change_k0_cca_kseg1 CONF_CM_UNCACHED
jr R_RETURN
END(mips_cache_disable)
LEAF(change_k0_cca)
mfc0 t0, CP0_CONFIG
#if __mips_isa_rev >= 2
......
......@@ -67,7 +67,7 @@ static unsigned long read_uint(uint8_t **buf)
* intentionally simple, and does the bare minimum needed to fixup the
* relocated U-Boot - in particular, it does not check for overflows.
*/
static void apply_reloc(unsigned int type, void *addr, long off)
static void apply_reloc(unsigned int type, void *addr, long off, uint8_t *buf)
{
uint32_t u32;
......@@ -92,7 +92,8 @@ static void apply_reloc(unsigned int type, void *addr, long off)
break;
default:
panic("Unhandled reloc type %u\n", type);
panic("Unhandled reloc type %u (@ %p), bss used before relocation?\n",
type, buf);
}
}
......@@ -137,7 +138,7 @@ void relocate_code(ulong start_addr_sp, gd_t *new_gd, ulong relocaddr)
break;
addr += read_uint(&buf) << 2;
apply_reloc(type, (void *)addr, off);
apply_reloc(type, (void *)addr, off, buf);
}
/* Ensure the icache is coherent */
......
......@@ -108,6 +108,10 @@ void trap_init(ulong reloc_addr)
saved_ebase = read_c0_ebase() & 0xfffff000;
/* Set WG bit on Octeon to enable writing to bits 63:30 */
if (IS_ENABLED(CONFIG_ARCH_OCTEON))
ebase |= MIPS_EBASE_WG;
write_c0_ebase(ebase);
clear_c0_status(ST0_BEV);
execution_hazard_barrier();
......
menu "Octeon platforms"
depends on ARCH_OCTEON
config SYS_SOC
string
default "octeon"
config OCTEON_CN7XXX
bool "Octeon CN7XXX SoC"
config OCTEON_CN70XX
bool "Octeon CN70XX SoC"
select OCTEON_CN7XXX
config OCTEON_CN73XX
bool "Octeon CN73XX SoC"
select OCTEON_CN7XXX
config OCTEON_CN78XX
bool "Octeon CN78XX SoC"
select OCTEON_CN7XXX
choice
prompt "Octeon MIPS family select"
config SOC_OCTEON3
bool "Octeon III family"
help
This selects the Octeon III SoC family CN70xx, CN73XX, CN78xx
and CNF75XX.
endchoice
choice
prompt "Octeon 3 board select"
default TARGET_OCTEON_EBB7304
config TARGET_OCTEON_EBB7304
bool "Marvell Octeon EBB7304"
select OCTEON_CN73XX
help
Choose this for the Octeon EBB7304 board
endchoice
config SYS_DCACHE_SIZE
default 32768
config SYS_DCACHE_LINE_SIZE
default 128
config SYS_ICACHE_SIZE
default 79872
config SYS_ICACHE_LINE_SIZE
default 128
source "board/Marvell/octeon_ebb7304/Kconfig"
endmenu
# (C) Copyright 2019 Marvell, Inc.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += lowlevel_init.o
obj-y += cache.o
obj-y += clock.o
obj-y += cpu.o
obj-y += dram.o
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020 Marvell International Ltd.
*/
#include <cpu_func.h>
/*
* The Octeon platform is cache coherent and cache flushes and invalidates
* are not needed. Define some platform specific empty flush_foo()
* functions here to overwrite the _weak common function as a no-op.
* This effectively disables all cache operations.
*/
void flush_dcache_range(ulong start_addr, ulong stop)
{
}
void flush_cache(ulong start_addr, ulong size)
{
}
void invalidate_dcache_range(ulong start_addr, ulong stop)
{
}
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018, 2019 Marvell International Ltd.
*/
#include <asm/global_data.h>
#include <mach/clock.h>
DECLARE_GLOBAL_DATA_PTR;
ulong notrace get_tbclk(void)
{
return gd->cpu_clk;
}
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020 Marvell International Ltd.
*/
#include <asm/global_data.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/compat.h>
#include <linux/io.h>
#include <mach/clock.h>
#include <mach/cavm-reg.h>
DECLARE_GLOBAL_DATA_PTR;
static int get_clocks(void)
{
const u64 ref_clock = PLL_REF_CLK;
void __iomem *rst_boot;
u64 val;
rst_boot = ioremap(CAVM_RST_BOOT, 0);
val = ioread64(rst_boot);
gd->cpu_clk = ref_clock * FIELD_GET(RST_BOOT_C_MUL, val);
gd->bus_clk = ref_clock * FIELD_GET(RST_BOOT_PNR_MUL, val);
debug("%s: cpu: %lu, bus: %lu\n", __func__, gd->cpu_clk, gd->bus_clk);
return 0;
}
/* Early mach init code run from flash */
int mach_cpu_init(void)
{
void __iomem *mio_boot_reg_cfg0;
/* Remap boot-bus 0x1fc0.0000 -> 0x1f40.0000 */
/* ToDo: Move this to an early running bus (bootbus) DM driver */
mio_boot_reg_cfg0 = ioremap(CAVM_MIO_BOOT_REG_CFG0, 0);
clrsetbits_be64(mio_boot_reg_cfg0, 0xffff, 0x1f40);
/* Get clocks and store them in GD */
get_clocks();
return 0;
}
/**
* Returns number of cores
*
* @return number of CPU cores for the specified node
*/
static int cavm_octeon_num_cores(void)
{
void __iomem *ciu_fuse;
ciu_fuse = ioremap(CAVM_CIU_FUSE, 0);
return fls64(ioread64(ciu_fuse) & 0xffffffffffff);
}
int print_cpuinfo(void)
{
printf("SoC: Octeon CN73xx (%d cores)\n", cavm_octeon_num_cores());
return 0;
}
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) Stefan Roese <sr@denx.de>
*/
#include <dm.h>
#include <ram.h>
#include <asm/global_data.h>
#include <linux/compat.h>
DECLARE_GLOBAL_DATA_PTR;
int dram_init(void)
{
/*
* No DDR init yet -> run in L2 cache
*/
gd->ram_size = (4 << 20);
gd->bd->bi_dram[0].size = gd->ram_size;
gd->bd->bi_dram[1].size = 0;
return 0;
}
ulong board_get_usable_ram_top(ulong total_size)
{
return gd->ram_top;
}
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_MACH_OCTEON_IOREMAP_H
#define __ASM_MACH_OCTEON_IOREMAP_H
#include <linux/types.h>
/*
* Allow physical addresses to be fixed up to help peripherals located
* outside the low 32-bit range -- generic pass-through version.
*/
static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr,
phys_addr_t size)
{
return phys_addr;
}
static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
unsigned long flags)
{
return (void __iomem *)(XKPHYS | offset);
}
static inline int plat_iounmap(const volatile void __iomem *addr)
{
return 0;
}
#define _page_cachable_default _CACHE_CACHABLE_NONCOHERENT
#endif /* __ASM_MACH_OCTEON_IOREMAP_H */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 Marvell International Ltd.
*/
#ifndef __CAVM_REG_H__
/* Register offsets */
#define CAVM_CIU_FUSE 0x00010100000001a0
#define CAVM_MIO_BOOT_REG_CFG0 0x0001180000000000
#define CAVM_RST_BOOT 0x0001180006001600
/* Register bits */
#define RST_BOOT_C_MUL GENMASK_ULL(36, 30)
#define RST_BOOT_PNR_MUL GENMASK_ULL(29, 24)
#endif /* __CAVM_REG_H__ */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2018, 2019 Marvell International Ltd.
*/
#ifndef __CLOCK_H__
/** System PLL reference clock */
#define PLL_REF_CLK 50000000 /* 50 MHz */
#define NS_PER_REF_CLK_TICK (1000000000 / PLL_REF_CLK)
#endif /* __CLOCK_H__ */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 Stefan Roese <sr@denx.de>
*/
#include <config.h>
#include <asm-offsets.h>
#include <asm/cacheops.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <asm/asm.h>
.set noreorder
LEAF(lowlevel_init)
jr ra
nop
END(lowlevel_init)
LEAF(mips_mach_early_init)
move s0, ra
bal __dummy
nop
__dummy:
/* Get the actual address that we are running at */
PTR_LA a7, __dummy
dsubu t3, ra, a7 /* t3 now has reloc offset */
PTR_LA t1, _start
daddu t0, t1, t3 /* t0 now has actual address of _start */
/* Calculate end address of copy loop */
PTR_LA t2, _end
daddiu t2, t2, 0x4000 /* Increase size to include appended DTB */
daddiu t2, t2, 127
ins t2, zero, 0, 7 /* Round up to cache line for memcpy */
/* Copy ourself to the L2 cache from flash, 32 bytes at a time */
1:
ld a0, 0(t0)
ld a1, 8(t0)
ld a2, 16(t0)
ld a3, 24(t0)
sd a0, 0(t1)
sd a1, 8(t1)
sd a2, 16(t1)
sd a3, 24(t1)
addiu t0, 32
addiu t1, 32
bne t1, t2, 1b
nop
sync
/*
* Return to start.S now running from TEXT_BASE, which points
* to DRAM address space, which effectively is L2 cache now.
* This speeds up the init process extremely, especially the
* DDR init code.
*/
dsubu s0, s0, t3 /* Fixup return address with reloc offset */
jr.hb s0 /* Jump back with hazard barrier */
nop
END(mips_mach_early_init)
if TARGET_OCTEON_EBB7304
config SYS_BOARD
string
default "octeon_ebb7304"
config SYS_VENDOR
string
default "Marvell"
config SYS_CONFIG_NAME
string
default "octeon_ebb7304"
config DEFAULT_DEVICE_TREE
string
default "mrvl,octeon-ebb7304"
endif
OCTEON_EBB7304 BOARD
M: Aaron Williams <awilliams@marvell.com>
S: Maintained
F: board/Marvell/octeon_ebb7304/*
F: configs/octeon_ebb7304_defconfig
F: include/configs/octeon_ebb7304.h
F: arch/mips/dts/mrvl,octeon-ebb7304.dts
#
# Copyright (C) 2020 Stefan Roese <sr@denx.de>
# Copyright (C) 2019-2020 Marvell International Ltd.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := board.o
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020 Stefan Roese <sr@denx.de>
*/
/*
* Nothing included right now. Code will be added in follow-up
* patches.
*/
CONFIG_MIPS=y
CONFIG_SYS_TEXT_BASE=0xffffffff80000000
CONFIG_SYS_MALLOC_F_LEN=0x4000
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_SECT_SIZE=0x10000
CONFIG_NR_DRAM_BANKS=2
CONFIG_DEBUG_UART_BASE=0x8001180000000800
CONFIG_DEBUG_UART_CLOCK=1200000000
CONFIG_ARCH_OCTEON=y
# CONFIG_MIPS_CACHE_SETUP is not set
# CONFIG_MIPS_CACHE_DISABLE is not set
CONFIG_DEBUG_UART=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_MTD=y
CONFIG_CMD_PCI=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_ENV_IS_IN_FLASH=y
CONFIG_ENV_ADDR=0x1FBFE000
CONFIG_CLK=y
# CONFIG_INPUT is not set
CONFIG_MTD=y
CONFIG_DM_MTD=y
CONFIG_MTD_NOR_FLASH=y
CONFIG_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
CONFIG_FLASH_CFI_MTD=y
CONFIG_SYS_FLASH_CFI=y
# CONFIG_NETDEVICES is not set
CONFIG_DEBUG_UART_SHIFT=3
CONFIG_DEBUG_UART_ANNOUNCE=y
CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
CONFIG_SYSRESET_OCTEON=y
CONFIG_HEXDUMP=y
......@@ -57,6 +57,13 @@ config SYSRESET_MICROBLAZE
help
This is soft reset on Microblaze which does jump to 0x0 address.
config SYSRESET_OCTEON
bool "Enable support for Marvell Octeon SoC family"
depends on ARCH_OCTEON
help
This enables the system reset driver support for Marvell Octeon
SoCs.
config SYSRESET_PSCI
bool "Enable support for PSCI System Reset"
depends on ARM_PSCI_FW
......
......@@ -10,6 +10,7 @@ obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
obj-$(CONFIG_SYSRESET_GPIO) += sysreset_gpio.o
obj-$(CONFIG_SYSRESET_MPC83XX) += sysreset_mpc83xx.o
obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o
obj-$(CONFIG_SYSRESET_OCTEON) += sysreset_octeon.o
obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
obj-$(CONFIG_SYSRESET_SOCFPGA) += sysreset_socfpga.o
obj-$(CONFIG_SYSRESET_SOCFPGA_S10) += sysreset_socfpga_s10.o
......
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020 Stefan Roese <sr@denx.de>
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <sysreset.h>
#include <asm/io.h>
#define RST_SOFT_RST 0x0080
struct octeon_sysreset_data {
void __iomem *base;
};
static int octeon_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
struct octeon_sysreset_data *data = dev_get_priv(dev);
writeq(1, data->base + RST_SOFT_RST);
return -EINPROGRESS;
}
static int octeon_sysreset_probe(struct udevice *dev)
{
struct octeon_sysreset_data *data = dev_get_priv(dev);
data->base = dev_remap_addr(dev);
return 0;
}
static struct sysreset_ops octeon_sysreset = {
.request = octeon_sysreset_request,
};
static const struct udevice_id octeon_sysreset_ids[] = {
{ .compatible = "mrvl,cn7xxx-rst" },
{ }
};
U_BOOT_DRIVER(sysreset_octeon) = {
.id = UCLASS_SYSRESET,
.name = "octeon_sysreset",
.priv_auto_alloc_size = sizeof(struct octeon_sysreset_data),
.ops = &octeon_sysreset,
.probe = octeon_sysreset_probe,
.of_match = octeon_sysreset_ids,
};
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2019-2020
* Marvell <www.marvell.com>
*/
#ifndef __OCTEON_COMMON_H__
#define __OCTEON_COMMON_H__
/* No DDR init yet -> run in L2 cache with limited resources */
#define CONFIG_SYS_MALLOC_LEN (256 << 10)
#define CONFIG_SYS_SDRAM_BASE 0xffffffff80000000
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + (1 << 20))
#define CONFIG_SYS_INIT_SP_OFFSET 0x180000
#endif /* __OCTEON_COMMON_H__ */
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2019-2020
* Marvell <www.marvell.com>
*/
#ifndef __CONFIG_H__
#define __CONFIG_H__
#include "octeon_common.h"
/*
* CFI flash
*/
#define CONFIG_SYS_MAX_FLASH_BANKS 1
#define CONFIG_SYS_MAX_FLASH_SECT 256
#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_8BIT
#define CONFIG_SYS_FLASH_EMPTY_INFO /* flinfo indicates empty blocks */
#endif /* __CONFIG_H__ */
......@@ -228,7 +228,6 @@ CONFIG_CPLD_BR_PRELIM
CONFIG_CPLD_OR_PRELIM
CONFIG_CPM2
CONFIG_CPU_ARMV8
CONFIG_CPU_CAVIUM_OCTEON
CONFIG_CPU_FREQ_HZ
CONFIG_CPU_HAS_LLSC
CONFIG_CPU_HAS_PREFETCH
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册