Pull xtensa update from Chris Zankel:
"Added features:
- add support for thread local storage (TLS)
- add accept4 and finit_module syscalls
- support medium-priority interrupts
- add support for dc232c processor variant
- support file-base simulated disk for ISS simulator
Bug fixes:
- fix return values returned by the str[n]cmp functions
- avoid mmap cache aliasing
- fix handling of 'windowed registers' in ptrace"
* tag 'xtensa-next-
20130225' of git://github.com/czankel/xtensa-linux:
xtensa: add accept4 syscall
xtensa: add support for TLS
xtensa: add missing include asm/uaccess.h to checksum.h
xtensa: do not enable GENERIC_GPIO by default
xtensa: complete ptrace handling of register windows
xtensa: add support for oprofile
xtensa: move spill_registers to traps.h
xtensa: ISS: add host file-based simulated disk
xtensa: fix str[n]cmp return value
xtensa: avoid mmap cache aliasing
xtensa: add finit_module syscall
xtensa: pull signal definitions from signal-defs.h
xtensa: fix ipc_parse_version selection
xtensa: dispatch medium-priority interrupts
xtensa: Add config files for Diamond 233L - Rev C processor variant
xtensa: use new common dtc rule
xtensa: rename prom_update_property to of_update_property
select GENERIC_CPU_DEVICES
select MODULES_USE_ELF_RELA
select GENERIC_PCI_IOMAP
+ select ARCH_WANT_IPC_PARSE_VERSION
select ARCH_WANT_OPTIONAL_GPIOLIB
select CLONE_BACKWARDS
select IRQ_DOMAIN
+ select HAVE_OPROFILE
help
Xtensa processors are 32-bit RISC machines designed by Tensilica
primarily for embedded systems. These processors are both
configurable and extensible. The Linux port to the Xtensa
architecture supports all processor configurations and extensions,
with reasonable minimum requirements. The Xtensa Linux project has
- a home page at <http://xtensa.sourceforge.net/>.
+ a home page at <http://www.linux-xtensa.org/>.
config RWSEM_XCHGADD_ALGORITHM
def_bool y
def_bool y
config GENERIC_GPIO
- def_bool y
+ bool
config ARCH_HAS_ILOG2_U32
def_bool n
help
This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE).
+ config XTENSA_VARIANT_DC233C
+ bool "dc233c - Diamond 233L Standard Core Rev.C (LE)"
+ select MMU
+ help
+ This variant refers to Tensilica's Diamond 233L Standard core Rev.C (LE).
+
config XTENSA_VARIANT_S6000
bool "s6000 - Stretch software configurable processor"
select VARIANT_IRQ_SWITCH
config XTENSA_PLATFORM_ISS
bool "ISS"
+ depends on TTY
select XTENSA_CALIBRATE_CCOUNT
select SERIAL_CONSOLE
select XTENSA_ISS_NETWORK
string "DTB to build into the kernel image"
depends on OF
+ config BLK_DEV_SIMDISK
+ tristate "Host file-based simulated block device support"
+ default n
+ depends on XTENSA_PLATFORM_ISS
+ help
+ Create block devices that map to files in the host file system.
+ Device binding to host file may be changed at runtime via proc
+ interface provided the device is not in use.
+
+ config BLK_DEV_SIMDISK_COUNT
+ int "Number of host file-based simulated block devices"
+ range 1 10
+ depends on BLK_DEV_SIMDISK
+ default 2
+ help
+ This is the default minimal number of created block devices.
+ Kernel/module parameter 'simdisk_count' may be used to change this
+ value at runtime. More file names (but no more than 10) may be
+ specified as parameters, simdisk_count grows accordingly.
+
+ config SIMDISK0_FILENAME
+ string "Host filename for the first simulated device"
+ depends on BLK_DEV_SIMDISK = y
+ default ""
+ help
+ Attach a first simdisk to a host file. Conventionally, this file
+ contains a root file system.
+
+ config SIMDISK1_FILENAME
+ string "Host filename for the second simulated device"
+ depends on BLK_DEV_SIMDISK = y && BLK_DEV_SIMDISK_COUNT != 1
+ default ""
+ help
+ Another simulated disk in a host file for a buildroot-independent
+ storage.
+
source "mm/Kconfig"
source "drivers/pcmcia/Kconfig"
#define __NR_restart_syscall 223
__SYSCALL(223, sys_restart_syscall, 0)
#define __NR_sigaltstack 224
-__SYSCALL(224, xtensa_sigaltstack, 2)
+__SYSCALL(224, sys_sigaltstack, 2)
#define __NR_rt_sigreturn 225
__SYSCALL(225, xtensa_rt_sigreturn, 1)
#define __NR_rt_sigaction 226
#define __NR_kcmp 331
__SYSCALL(331, sys_kcmp, 5)
+ #define __NR_finit_module 332
+ __SYSCALL(332, sys_finit_module, 3)
- #define __NR_syscall_count 332
+ #define __NR_accept4 333
+ __SYSCALL(333, sys_accept4, 4)
+
+ #define __NR_syscall_count 334
/*
* sysxtensa syscall handler
ret = regs->areg[2];
- if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->areg[1]) == -EFAULT)
+ if (restore_altstack(&frame->uc.uc_stack))
goto badframe;
return ret;
struct rt_sigframe *frame;
int err = 0;
int signal;
- unsigned long sp, ra;
+ unsigned long sp, ra, tp;
sp = regs->areg[1];
err |= __put_user(0, &frame->uc.uc_flags);
err |= __put_user(0, &frame->uc.uc_link);
- err |= __put_user((void *)current->sas_ss_sp,
- &frame->uc.uc_stack.ss_sp);
- err |= __put_user(sas_ss_flags(regs->areg[1]),
- &frame->uc.uc_stack.ss_flags);
- err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+ err |= __save_altstack(&frame->uc.uc_stack, regs->areg[1]);
err |= setup_sigcontext(frame, regs);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
* Return context not modified until this point.
*/
- /* Set up registers for signal handler */
+ /* Set up registers for signal handler; preserve the threadptr */
+ tp = regs->threadptr;
start_thread(regs, (unsigned long) ka->sa.sa_handler,
(unsigned long) frame);
regs->areg[6] = (unsigned long) signal;
regs->areg[7] = (unsigned long) &frame->info;
regs->areg[8] = (unsigned long) &frame->uc;
+ regs->threadptr = tp;
/* Set access mode to USER_DS. Nomenclature is outdated, but
* functionality is used in uaccess.h
return -EFAULT;
}
-asmlinkage long xtensa_sigaltstack(const stack_t __user *uss,
- stack_t __user *uoss,
- long a2, long a3, long a4, long a5,
- struct pt_regs *regs)
-{
- return do_sigaltstack(uss, uoss, regs->areg[1]);
-}
-
-
-
/*
* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
+ #include <asm/traps.h>
#ifdef CONFIG_KGDB
extern int gdb_enter;
}
/*
- * Level-1 interrupt.
- * We currently have no priority encoding.
+ * IRQ handler.
+ * PS.INTLEVEL is the current IRQ priority level.
*/
- unsigned long ignored_level1_interrupts;
extern void do_IRQ(int, struct pt_regs *);
- void do_interrupt (struct pt_regs *regs)
+ void do_interrupt(struct pt_regs *regs)
{
- unsigned long intread = get_sr (interrupt);
- unsigned long intenable = get_sr (intenable);
- int i, mask;
-
- /* Handle all interrupts (no priorities).
- * (Clear the interrupt before processing, in case it's
- * edge-triggered or software-generated)
- */
+ static const unsigned int_level_mask[] = {
+ 0,
+ XCHAL_INTLEVEL1_MASK,
+ XCHAL_INTLEVEL2_MASK,
+ XCHAL_INTLEVEL3_MASK,
+ XCHAL_INTLEVEL4_MASK,
+ XCHAL_INTLEVEL5_MASK,
+ XCHAL_INTLEVEL6_MASK,
+ XCHAL_INTLEVEL7_MASK,
+ };
+ unsigned level = get_sr(ps) & PS_INTLEVEL_MASK;
+
+ if (WARN_ON_ONCE(level >= ARRAY_SIZE(int_level_mask)))
+ return;
- for (i=0, mask = 1; i < XCHAL_NUM_INTERRUPTS; i++, mask <<= 1) {
- if (mask & (intread & intenable)) {
- set_sr (mask, intclear);
- do_IRQ (i,regs);
+ for (;;) {
+ unsigned intread = get_sr(interrupt);
+ unsigned intenable = get_sr(intenable);
+ unsigned int_at_level = intread & intenable &
+ int_level_mask[level];
+
+ if (!int_at_level)
+ return;
+
+ /*
+ * Clear the interrupt before processing, in case it's
+ * edge-triggered or software-generated
+ */
+ while (int_at_level) {
+ unsigned i = __ffs(int_at_level);
+ unsigned mask = 1 << i;
+
+ int_at_level ^= mask;
+ set_sr(mask, intclear);
+ do_IRQ(i, regs);
}
}
}
return sp;
}
- static inline void spill_registers(void)
- {
- unsigned int a0, ps;
-
- __asm__ __volatile__ (
- "movi a14, " __stringify(PS_EXCM_BIT | 1) "\n\t"
- "mov a12, a0\n\t"
- "rsr a13, sar\n\t"
- "xsr a14, ps\n\t"
- "movi a0, _spill_registers\n\t"
- "rsync\n\t"
- "callx0 a0\n\t"
- "mov a0, a12\n\t"
- "wsr a13, sar\n\t"
- "wsr a14, ps\n\t"
- :: "a" (&a0), "a" (&ps)
- : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15",
- "memory");
- }
-
void show_trace(struct task_struct *task, unsigned long *sp)
{
unsigned long a0, a1, pc;
if (!user_mode(regs))
show_stack(NULL, (unsigned long*)regs->areg[1]);
- add_taint(TAINT_DIE);
+ add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
spin_unlock_irq(&die_lock);
if (in_interrupt())