Skip to content

Commit

Permalink
Merge git://git.linux-xtensa.org/kernel/xtensa-feed
Browse files Browse the repository at this point in the history
* git://git.linux-xtensa.org/kernel/xtensa-feed:
  [patch 1/2] Xtensa: enable arbitary tty speed setting ioctls
  [patch 2/2] xtensa console.c: remove duplicate #include
  [XTENSA] Add support for cache-aliasing
  [XTENSA] Add kernel module support
  [XTENSA] Add support for executable/non-executable feature in the mmu
  [XTENSA] Use the generic version of get_order
  [XTENSA] Initialize semaphore_wake_lock
  [XTENSA] Add typecast macro for constants
  [XTENSA] Fix timer instabilities.
  [XTENSA] Fix fadvise64_64
  [XTENSA] Remove extraneous include statement
  [XTENSA] Move string-io functions to io.c from pci.c
  [XTENSA] Move pre-initialized structures to init_task.c
  [XTENSA] Add freestanding option to CFLAGS
  [XTENSA] Add getpgrp system-call to unistd.h
  [XTENSA] add missing system calls
  [XTENSA] fix wrong usage of __init and __initdata in traps.c
  • Loading branch information
Linus Torvalds committed Sep 15, 2007
2 parents 53a3f30 + ebb2a97 commit 2605a10
Show file tree
Hide file tree
Showing 36 changed files with 1,515 additions and 704 deletions.
7 changes: 6 additions & 1 deletion arch/xtensa/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss
PLATFORM = $(platform-y)
export PLATFORM

CFLAGS += -pipe -mlongcalls
# temporarily until string.h is fixed
cflags-y += -ffreestanding

cflags-y += -pipe -mlongcalls

CFLAGS += $(cflags-y)

KBUILD_DEFCONFIG := iss_defconfig

Expand Down
2 changes: 1 addition & 1 deletion arch/xtensa/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ extra-y := head.o vmlinux.lds

obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o semaphore.o \
setup.o signal.o syscall.o time.o traps.o vectors.o platform.o \
pci-dma.o
pci-dma.o init_task.o io.o

## windowspill.o

Expand Down
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;
}


115 changes: 98 additions & 17 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 @@ -1572,10 +1572,12 @@ ENTRY(fast_second_level_miss)
l32i a0, a1, TASK_MM # tsk->mm
beqz a0, 9f

8: rsr a1, EXCVADDR # fault address
_PGD_OFFSET(a0, a1, a1)

/* We deliberately destroy a3 that holds the exception table. */

8: rsr a3, EXCVADDR # fault address
_PGD_OFFSET(a0, a3, a1)
l32i a0, a0, 0 # read pmdval
//beqi a0, _PAGE_USER, 2f
beqz a0, 2f

/* Read ptevaddr and convert to top of page-table page.
Expand All @@ -1588,28 +1590,42 @@ 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
add a0, a0, a1 # pmdval - PAGE_OFFSET
extui a1, a0, 0, PAGE_SHIFT # ... & PAGE_MASK
xor a0, a0, a1


movi a1, PAGE_DIRECTORY
movi a1, _PAGE_DIRECTORY
or a0, a0, a1 # ... | PAGE_DIRECTORY

/*
* 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:
* 0,1 -> way 7 program (0040.0000) and virtual (c000.0000)
* 2 -> way 8 shared libaries (2000.0000)
* 3 -> way 0 stack (3000.0000)
*/

extui a3, a3, 28, 2 # addr. bit 28 and 29 0,1,2,3
rsr a1, PTEVADDR
addx2 a3, a3, a3 # -> 0,3,6,9
srli a1, a1, PAGE_SHIFT
extui a3, a3, 2, 2 # -> 0,0,1,2
slli a1, a1, PAGE_SHIFT # ptevaddr & PAGE_MASK
addi a1, a1, DTLB_WAY_PGD # ... + way_number
addi a3, a3, DTLB_WAY_PGD
add a1, a1, a3 # ... + way_number

wdtlb a0, a1
3: wdtlb a0, a1
dsync

/* Exit critical section. */

4: movi a3, exc_table # restore a3
movi a0, 0
s32i a0, a3, EXC_TABLE_FIXUP

Expand All @@ -1636,8 +1652,76 @@ 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
rsr a1, DEPC
xsr a3, EXCSAVE_1
s32i a1, a2, PT_AREG2
Expand Down Expand Up @@ -1682,15 +1766,15 @@ ENTRY(fast_store_prohibited)
8: rsr a1, EXCVADDR # fault address
_PGD_OFFSET(a0, a1, a4)
l32i a0, a0, 0
//beqi a0, _PAGE_USER, 2f # FIXME use _PAGE_INVALID
beqz a0, 2f

/* Note that we assume _PAGE_WRITABLE_BIT is only set if pte is valid.*/

_PTE_OFFSET(a0, a1, a4)
l32i a4, a0, 0 # read pteval
movi a1, _PAGE_VALID | _PAGE_RW
bnall a4, a1, 2f
bbci.l a4, _PAGE_WRITABLE_BIT, 2f

movi a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_WRENABLE
movi a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_HW_WRITE
or a4, a4, a1
rsr a1, EXCVADDR
s32i a4, a0, 0
Expand All @@ -1700,10 +1784,7 @@ ENTRY(fast_store_prohibited)
dhwb a0, 0
#endif
pdtlb a0, a1
beqz a0, 1f
idtlb a0 // FIXME do we need this?
wdtlb a4, a0
1:

/* Exit critical section. */

Expand Down
38 changes: 38 additions & 0 deletions arch/xtensa/kernel/init_task.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* arch/xtensa/kernel/init_task.c
*
* Xtensa Processor version.
*
* 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) 2007 Tensilica Inc.
*
* Chris Zankel <chris@zankel.net>
*/

#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/module.h>
#include <linux/mqueue.h>

#include <asm/uaccess.h>

static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);

EXPORT_SYMBOL(init_mm);

union thread_union init_thread_union
__attribute__((__section__(".data.init_task"))) =
{ INIT_THREAD_INFO(init_task) };

struct task_struct init_task = INIT_TASK(init_task);

EXPORT_SYMBOL(init_task);
75 changes: 75 additions & 0 deletions arch/xtensa/kernel/io.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* arch/xtensa/io.c
*
* IO primitives
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* Copied from sparc.
*
* Chris Zankel <chris@zankel.net>
*
*/

#include <asm/io.h>
#include <asm/byteorder.h>

void outsb(unsigned long addr, const void *src, unsigned long count) {
while (count) {
count -= 1;
writeb(*(const char *)src, addr);
src += 1;
addr += 1;
}
}

void outsw(unsigned long addr, const void *src, unsigned long count) {
while (count) {
count -= 2;
writew(*(const short *)src, addr);
src += 2;
addr += 2;
}
}

void outsl(unsigned long addr, const void *src, unsigned long count) {
while (count) {
count -= 4;
writel(*(const long *)src, addr);
src += 4;
addr += 4;
}
}

void insb(unsigned long addr, void *dst, unsigned long count) {
while (count) {
count -= 1;
*(unsigned char *)dst = readb(addr);
dst += 1;
addr += 1;
}
}

void insw(unsigned long addr, void *dst, unsigned long count) {
while (count) {
count -= 2;
*(unsigned short *)dst = readw(addr);
dst += 2;
addr += 2;
}
}

void insl(unsigned long addr, void *dst, unsigned long count) {
while (count) {
count -= 4;
/*
* XXX I am sure we are in for an unaligned trap here.
*/
*(unsigned long *)dst = readl(addr);
dst += 4;
addr += 4;
}
}
Loading

0 comments on commit 2605a10

Please sign in to comment.