Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e85e335f authored by Max Filippov's avatar Max Filippov Committed by Chris Zankel
Browse files

xtensa: add MMU v3 support



MMUv3 comes out of reset with identity vaddr -> paddr mapping in the TLB
way 6:

Way 6 (512 MB)
        Vaddr       Paddr       ASID  Attr RWX Cache
        ----------  ----------  ----  ---- --- -------
        0x00000000  0x00000000  0x01  0x03 RWX Bypass
        0x20000000  0x20000000  0x01  0x03 RWX Bypass
        0x40000000  0x40000000  0x01  0x03 RWX Bypass
        0x60000000  0x60000000  0x01  0x03 RWX Bypass
        0x80000000  0x80000000  0x01  0x03 RWX Bypass
        0xa0000000  0xa0000000  0x01  0x03 RWX Bypass
        0xc0000000  0xc0000000  0x01  0x03 RWX Bypass
        0xe0000000  0xe0000000  0x01  0x03 RWX Bypass

This patch adds remapping code at the reset vector or at the kernel
_start (depending on CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX) that
reconfigures MMUv3 as MMUv2:

Way 5 (128 MB)
        Vaddr       Paddr       ASID  Attr RWX Cache
        ----------  ----------  ----  ---- --- -------
        0xd0000000  0x00000000  0x01  0x07 RWX WB
        0xd8000000  0x00000000  0x01  0x03 RWX Bypass
Way 6 (256 MB)
        Vaddr       Paddr       ASID  Attr RWX Cache
        ----------  ----------  ----  ---- --- -------
        0xe0000000  0xf0000000  0x01  0x07 RWX WB
        0xf0000000  0xf0000000  0x01  0x03 RWX Bypass

Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
Signed-off-by: default avatarChris Zankel <chris@zankel.net>
parent d83ff0bb
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -103,6 +103,35 @@ config MATH_EMULATION
	help
	Can we use information of configuration file?

config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
	bool "Initialize Xtensa MMU inside the Linux kernel code"
	default y
	help
	  Earlier version initialized the MMU in the exception vector
	  before jumping to _startup in head.S and had an advantage that
	  it was possible to place a software breakpoint at 'reset' and
	  then enter your normal kernel breakpoints once the MMU was mapped
	  to the kernel mappings (0XC0000000).

	  This unfortunately doesn't work for U-Boot and likley also wont
	  work for using KEXEC to have a hot kernel ready for doing a
	  KDUMP.

	  So now the MMU is initialized in head.S but it's necessary to
	  use hardware breakpoints (gdb 'hbreak' cmd) to break at _startup.
	  xt-gdb can't place a Software Breakpoint in the  0XD region prior
	  to mapping the MMU and after mapping even if the area of low memory
	  was mapped gdb wouldn't remove the breakpoint on hitting it as the
	  PC wouldn't match. Since Hardware Breakpoints are recommended for
	  Linux configurations it seems reasonable to just assume they exist
	  and leave this older mechanism for unfortunate souls that choose
	  not to follow Tensilica's recommendation.

	  Selecting this will cause U-Boot to set the KERNEL Load and Entry
	  address at 0x00003000 instead of the mapped std of 0xD0003000.

	  If in doubt, say Y.

endmenu

config XTENSA_CALIBRATE_CCOUNT
+1 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ endif

export OBJCOPY_ARGS
export CPPFLAGS_boot.lds += -P -C
export KBUILD_AFLAGS += -mtext-section-literals

boot-y		:= bootstrap.o

+26 −38
Original line number Diff line number Diff line
#include <variant/core.h>
/*
 *  linux/arch/xtensa/boot/boot-elf/boot.lds.S
 *
 *  Copyright (C) 2008 - 2013 by Tensilica Inc.
 *
 *  Chris Zankel <chris@zankel.net>
 *  Marc Gauthier <marc@tensilica.com
 *  Pete Delaney <piet@tensilica.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <asm/vectors.h>
OUTPUT_ARCH(xtensa)
ENTRY(_ResetVector)

SECTIONS
{
	.start 0xD0000000 : { *(.start) }

	.text 0xD0000000:
	{
		__reloc_start = . ;
		_text_start = . ;
		*(.literal .text.literal .text)
		_text_end = . ;
	}

	.rodata ALIGN(0x04):
	{
		*(.rodata)
		*(.rodata1)
	}

	.data ALIGN(0x04):
	.ResetVector.text XCHAL_RESET_VECTOR_VADDR :
	{
		*(.data)
		*(.data1)
		*(.sdata)
		*(.sdata2)
		*(.got.plt)
		*(.got)
		*(.dynamic)
		*(.ResetVector.text)
	}

	__reloc_end = . ;

	. = ALIGN(0x10);
	__image_load = . ;
	.image 0xd0001000:
	.image KERNELOFFSET: AT (LOAD_MEMORY_ADDRESS)
	{
		_image_start = .;
		*(image)
@@ -43,7 +31,6 @@ SECTIONS
		_image_end = .	;
	}


	.bss ((LOADADDR(.image) + SIZEOF(.image) + 3) & ~ 3):
	{
		__bss_start = .;
@@ -53,14 +40,15 @@ SECTIONS
		*(.bss)
		__bss_end = .;
	}
	_end = .;
	_param_start = .;

	.ResetVector.text XCHAL_RESET_VECTOR_VADDR :
	/*
	 * This is a remapped copy of the Reset Vector Code.
	 * It keeps gdb in sync with the PC after switching
	 * to the temporary mapping used while setting up
	 * the V2 MMU mappings for Linux.
	 */
	.ResetVector.remapped_text 0x46000000 (INFO):
	{
		*(.ResetVector.text)
		*(.ResetVector.remapped_text)
	}


	PROVIDE (end = .);
}
+86 −15
Original line number Diff line number Diff line
/*
 * arch/xtensa/boot/boot-elf/bootstrap.S
 *
 * Low-level exception handling
 *
 * 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.
 *
 * Copyright (C) 2004 - 2013 by Tensilica Inc.
 *
 * Chris Zankel <chris@zankel.net>
 * Marc Gauthier <marc@tensilica.com>
 * Piet Delaney <piet@tensilica.com>
 */

#include <asm/bootparam.h>
#include <asm/processor.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/cacheasm.h>
#include <asm/initialize_mmu.h>
#include <linux/linkage.h>


/* ResetVector
 */
	.section	.ResetVector.text, "ax"
	.global         _ResetVector
	.global         reset

_ResetVector:
	_j reset
	_j _SetupMMU

	.begin  no-absolute-literals
	.literal_position

	.align 4
RomInitAddr:
	.word 0xd0001000
#if defined(CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX) && \
	XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
	.word 0x00003000
#else
	.word 0xd0003000
#endif
RomBootParam:
	.word _bootparam
_bootparam:
	.short	BP_TAG_FIRST
	.short	4
	.long	BP_VERSION
	.short	BP_TAG_LAST
	.short	0
	.long	0

	.align  4
_SetupMMU:
	movi	a0, 0
	wsr	a0, windowbase
	rsync
	movi	a0, 1
	wsr	a0, windowstart
	rsync
	movi	a0, 0x1F
	wsr	a0, ps
	rsync

	Offset = _SetupMMU - _ResetVector

#ifndef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
	initialize_mmu
#endif

	.end    no-absolute-literals

	rsil    a0, XCHAL_DEBUGLEVEL-1
	rsync
reset:
	l32r    a0, RomInitAddr
	l32r	a2, RomBootParam
@@ -21,13 +80,25 @@ reset:
	jx      a0

	.align 4
	.section .bootstrap.data, "aw"

	.globl _bootparam
_bootparam:
	.short	BP_TAG_FIRST
	.short	4
	.long	BP_VERSION
	.short	BP_TAG_LAST
	.short	0
	.long	0
	.section	.ResetVector.remapped_text, "x"
	.global         _RemappedResetVector

	/* Do org before literals */
	.org 0

_RemappedResetVector:
	.begin  no-absolute-literals
	.literal_position

	_j	_RemappedSetupMMU

	/* Position Remapped code at the same location as the original code */
	. = _RemappedResetVector + Offset

_RemappedSetupMMU:
#ifndef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
	initialize_mmu
#endif

	.end    no-absolute-literals
+5 −1
Original line number Diff line number Diff line
@@ -4,7 +4,11 @@
# for more details.
#

UIMAGE_LOADADDR = 0xd0001000
ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
UIMAGE_LOADADDR = 0x00003000
else
UIMAGE_LOADADDR = 0xd0003000
endif
UIMAGE_COMPRESSION = gzip

$(obj)/../uImage: vmlinux.bin.gz FORCE
Loading