Skip to content

Commit

Permalink
[XTENSA] Add support for cache-aliasing
Browse files Browse the repository at this point in the history
Add support for processors that have cache-aliasing issues, such as
the Stretch S5000 processor. Cache-aliasing means that the size of
the cache (for one way) is larger than the page size, thus, a page
can end up in several places in cache depending on the virtual to
physical translation. The method used here is to map a user page
temporarily through the auto-refill way 0 and of of the DTLB.
We probably will want to revisit this issue and use a better
approach with kmap/kunmap.

Signed-off-by: Chris Zankel <chris@zankel.net>
  • Loading branch information
Chris Zankel committed Aug 27, 2007
1 parent ff6fd46 commit 6656920
Show file tree
Hide file tree
Showing 14 changed files with 816 additions and 414 deletions.
13 changes: 6 additions & 7 deletions arch/xtensa/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
#include <linux/stddef.h>
#include <linux/thread_info.h>
#include <linux/ptrace.h>
#include <linux/mm.h>

#include <asm/ptrace.h>
#include <asm/processor.h>
#include <asm/uaccess.h>

#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
#define BLANK() asm volatile("\n->" : : )

int main(void)
{
Expand Down Expand Up @@ -63,7 +64,6 @@ int main(void)
DEFINE(PT_SIZE, sizeof(struct pt_regs));
DEFINE(PT_AREG_END, offsetof (struct pt_regs, areg[XCHAL_NUM_AREGS]));
DEFINE(PT_USER_SIZE, offsetof(struct pt_regs, areg[XCHAL_NUM_AREGS]));
BLANK();

/* struct task_struct */
DEFINE(TASK_PTRACE, offsetof (struct task_struct, ptrace));
Expand All @@ -73,27 +73,26 @@ int main(void)
DEFINE(TASK_THREAD, offsetof (struct task_struct, thread));
DEFINE(TASK_THREAD_INFO, offsetof (struct task_struct, stack));
DEFINE(TASK_STRUCT_SIZE, sizeof (struct task_struct));
BLANK();

/* struct thread_info (offset from start_struct) */
DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
DEFINE(THREAD_CP_SAVE, offsetof (struct task_struct, thread.cp_save));
DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds));
BLANK();

/* struct mm_struct */
DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users));
DEFINE(MM_PGD, offsetof (struct mm_struct, pgd));
DEFINE(MM_CONTEXT, offsetof (struct mm_struct, context));
BLANK();
DEFINE(PT_SINGLESTEP_BIT, PT_SINGLESTEP_BIT);

/* struct page */
DEFINE(PAGE_FLAGS, offsetof(struct page, flags));

/* constants */
DEFINE(_CLONE_VM, CLONE_VM);
DEFINE(_CLONE_UNTRACED, CLONE_UNTRACED);
DEFINE(PG_ARCH_1, PG_arch_1);

return 0;
}


75 changes: 71 additions & 4 deletions arch/xtensa/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2004-2005 by Tensilica Inc.
* Copyright (C) 2004-2007 by Tensilica Inc.
*
* Chris Zankel <chris@zankel.net>
*
Expand Down Expand Up @@ -169,7 +169,7 @@ _user_exception:
* We have to save all registers up to the first '1' from
* the right, except the current frame (bit 0).
* Assume a2 is: 001001000110001
* All regiser frames starting from the top fiel to the marked '1'
* All register frames starting from the top field to the marked '1'
* must be saved.
*/

Expand Down Expand Up @@ -1590,7 +1590,7 @@ ENTRY(fast_second_level_miss)
* The messy computation for 'pteval' above really simplifies
* into the following:
*
* pteval = ((pmdval - PAGE_OFFSET) & PAGE_MASK) | PAGE_KERNEL
* pteval = ((pmdval - PAGE_OFFSET) & PAGE_MASK) | PAGE_DIRECTORY
*/

movi a1, -PAGE_OFFSET
Expand All @@ -1602,7 +1602,7 @@ ENTRY(fast_second_level_miss)
or a0, a0, a1 # ... | PAGE_DIRECTORY

/*
* We utilize all three wired-ways (7-9( to hold pmd translations.
* We utilize all three wired-ways (7-9) to hold pmd translations.
* Memory regions are mapped to the DTLBs according to bits 28 and 29.
* This allows to map the three most common regions to three different
* DTLBs:
Expand Down Expand Up @@ -1652,6 +1652,73 @@ ENTRY(fast_second_level_miss)
9: l32i a0, a1, TASK_ACTIVE_MM # unlikely case mm == 0
j 8b

#if (DCACHE_WAY_SIZE > PAGE_SIZE)

2: /* Special case for cache aliasing.
* We (should) only get here if a clear_user_page, copy_user_page
* or the aliased cache flush functions got preemptively interrupted
* by another task. Re-establish temporary mapping to the
* TLBTEMP_BASE areas.
*/

/* We shouldn't be in a double exception */

l32i a0, a2, PT_DEPC
bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 2f

/* Make sure the exception originated in the special functions */

movi a0, __tlbtemp_mapping_start
rsr a3, EPC_1
bltu a3, a0, 2f
movi a0, __tlbtemp_mapping_end
bgeu a3, a0, 2f

/* Check if excvaddr was in one of the TLBTEMP_BASE areas. */

movi a3, TLBTEMP_BASE_1
rsr a0, EXCVADDR
bltu a0, a3, 2f

addi a1, a0, -(2 << (DCACHE_ALIAS_ORDER + PAGE_SHIFT))
bgeu a1, a3, 2f

/* Check if we have to restore an ITLB mapping. */

movi a1, __tlbtemp_mapping_itlb
rsr a3, EPC_1
sub a3, a3, a1

/* Calculate VPN */

movi a1, PAGE_MASK
and a1, a1, a0

/* Jump for ITLB entry */

bgez a3, 1f

/* We can use up to two TLBTEMP areas, one for src and one for dst. */

extui a3, a0, PAGE_SHIFT + DCACHE_ALIAS_ORDER, 1
add a1, a3, a1

/* PPN is in a6 for the first TLBTEMP area and in a7 for the second. */

mov a0, a6
movnez a0, a7, a3
j 3b

/* ITLB entry. We only use dst in a6. */

1: witlb a6, a1
isync
j 4b


#endif // DCACHE_WAY_SIZE > PAGE_SIZE


2: /* Invalid PGD, default exception handling */

movi a3, exc_table
Expand Down
6 changes: 1 addition & 5 deletions arch/xtensa/mm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,5 @@
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definition is now in the main makefile...

obj-y := init.o fault.o tlb.o misc.o
obj-m :=
obj-n :=
obj- :=
obj-y := init.o fault.o tlb.o misc.o cache.o
Loading

0 comments on commit 6656920

Please sign in to comment.