mirror of https://gitee.com/openkylin/linux.git
Merge master.kernel.org:/home/rmk/linux-2.6-arm
This commit is contained in:
commit
89de09a9ba
|
@ -324,7 +324,7 @@ menu "Kernel Features"
|
|||
|
||||
config SMP
|
||||
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL && BROKEN #&& n
|
||||
depends on EXPERIMENTAL && REALVIEW_MPCORE
|
||||
help
|
||||
This enables support for systems with more than one CPU. If you have
|
||||
a system with only one CPU, like most personal computers, say N. If
|
||||
|
@ -585,7 +585,7 @@ config FPE_NWFPE
|
|||
|
||||
config FPE_NWFPE_XP
|
||||
bool "Support extended precision"
|
||||
depends on FPE_NWFPE && !CPU_BIG_ENDIAN
|
||||
depends on FPE_NWFPE
|
||||
help
|
||||
Say Y to include 80-bit support in the kernel floating-point
|
||||
emulator. Otherwise, only 32 and 64-bit support is compiled in.
|
||||
|
|
|
@ -84,63 +84,54 @@ static struct map_desc ixp2000_io_desc[] __initdata = {
|
|||
.virtual = IXP2000_CAP_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE),
|
||||
.length = IXP2000_CAP_SIZE,
|
||||
.type = MT_DEVICE
|
||||
.type = MT_IXP2000_DEVICE,
|
||||
}, {
|
||||
.virtual = IXP2000_INTCTL_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE),
|
||||
.length = IXP2000_INTCTL_SIZE,
|
||||
.type = MT_DEVICE
|
||||
.type = MT_IXP2000_DEVICE,
|
||||
}, {
|
||||
.virtual = IXP2000_PCI_CREG_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE),
|
||||
.length = IXP2000_PCI_CREG_SIZE,
|
||||
.type = MT_DEVICE
|
||||
.type = MT_IXP2000_DEVICE,
|
||||
}, {
|
||||
.virtual = IXP2000_PCI_CSR_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE),
|
||||
.length = IXP2000_PCI_CSR_SIZE,
|
||||
.type = MT_DEVICE
|
||||
.type = MT_IXP2000_DEVICE,
|
||||
}, {
|
||||
.virtual = IXP2000_MSF_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE),
|
||||
.length = IXP2000_MSF_SIZE,
|
||||
.type = MT_DEVICE
|
||||
.type = MT_IXP2000_DEVICE,
|
||||
}, {
|
||||
.virtual = IXP2000_PCI_IO_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
|
||||
.length = IXP2000_PCI_IO_SIZE,
|
||||
.type = MT_DEVICE
|
||||
.type = MT_IXP2000_DEVICE,
|
||||
}, {
|
||||
.virtual = IXP2000_PCI_CFG0_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE),
|
||||
.length = IXP2000_PCI_CFG0_SIZE,
|
||||
.type = MT_DEVICE
|
||||
.type = MT_IXP2000_DEVICE,
|
||||
}, {
|
||||
.virtual = IXP2000_PCI_CFG1_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE),
|
||||
.length = IXP2000_PCI_CFG1_SIZE,
|
||||
.type = MT_DEVICE
|
||||
.type = MT_IXP2000_DEVICE,
|
||||
}
|
||||
};
|
||||
|
||||
void __init ixp2000_map_io(void)
|
||||
{
|
||||
extern unsigned int processor_id;
|
||||
|
||||
/*
|
||||
* On IXP2400 CPUs we need to use MT_IXP2000_DEVICE for
|
||||
* tweaking the PMDs so XCB=101. On IXP2800s we use the normal
|
||||
* PMD flags.
|
||||
* On IXP2400 CPUs we need to use MT_IXP2000_DEVICE so that
|
||||
* XCB=101 (to avoid triggering erratum #66), and given that
|
||||
* this mode speeds up I/O accesses and we have write buffer
|
||||
* flushes in the right places anyway, it doesn't hurt to use
|
||||
* XCB=101 for all IXP2000s.
|
||||
*/
|
||||
if ((processor_id & 0xfffffff0) == 0x69054190) {
|
||||
int i;
|
||||
|
||||
printk(KERN_INFO "Enabling IXP2400 erratum #66 workaround\n");
|
||||
|
||||
for(i=0;i<ARRAY_SIZE(ixp2000_io_desc);i++)
|
||||
ixp2000_io_desc[i].type = MT_IXP2000_DEVICE;
|
||||
}
|
||||
|
||||
iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc));
|
||||
|
||||
/* Set slowport to 8-bit mode. */
|
||||
|
|
|
@ -8,4 +8,13 @@ config MACH_REALVIEW_EB
|
|||
help
|
||||
Include support for the ARM(R) RealView Emulation Baseboard platform.
|
||||
|
||||
config REALVIEW_MPCORE
|
||||
bool "Support MPcore tile"
|
||||
depends on MACH_REALVIEW_EB
|
||||
help
|
||||
Enable support for the MPCore tile on the Realview platform.
|
||||
Since there are device address and interrupt differences, a
|
||||
kernel built with this option enabled is not compatible with
|
||||
other tiles.
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
|
||||
obj-y := core.o clock.o
|
||||
obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o
|
||||
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define __ASM_ARCH_REALVIEW_H
|
||||
|
||||
#include <asm/hardware/amba.h>
|
||||
#include <asm/leds.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define __io_address(n) __io(IO_ADDRESS(n))
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-realview/headsmp.S
|
||||
*
|
||||
* Copyright (c) 2003 ARM Limited
|
||||
* All Rights Reserved
|
||||
*
|
||||
* 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 <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
__INIT
|
||||
|
||||
/*
|
||||
* Realview specific entry point for secondary CPUs. This provides
|
||||
* a "holding pen" into which all secondary cores are held until we're
|
||||
* ready for them to initialise.
|
||||
*/
|
||||
ENTRY(realview_secondary_startup)
|
||||
mrc p15, 0, r0, c0, c0, 5
|
||||
and r0, r0, #15
|
||||
adr r4, 1f
|
||||
ldmia r4, {r5, r6}
|
||||
sub r4, r4, r5
|
||||
add r6, r6, r4
|
||||
pen: ldr r7, [r6]
|
||||
cmp r7, r0
|
||||
bne pen
|
||||
|
||||
/*
|
||||
* we've been released from the holding pen: secondary_stack
|
||||
* should now contain the SVC stack for this core
|
||||
*/
|
||||
b secondary_startup
|
||||
|
||||
1: .long .
|
||||
.long pen_release
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-realview/platsmp.c
|
||||
*
|
||||
* Copyright (C) 2002 ARM Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* 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 <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/hardware/arm_scu.h>
|
||||
#include <asm/hardware.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
extern void realview_secondary_startup(void);
|
||||
|
||||
/*
|
||||
* control for which core is the next to come out of the secondary
|
||||
* boot "holding pen"
|
||||
*/
|
||||
volatile int __cpuinitdata pen_release = -1;
|
||||
|
||||
static unsigned int __init get_core_count(void)
|
||||
{
|
||||
unsigned int ncores;
|
||||
|
||||
ncores = __raw_readl(IO_ADDRESS(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG);
|
||||
|
||||
return (ncores & 0x03) + 1;
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(boot_lock);
|
||||
|
||||
void __cpuinit platform_secondary_init(unsigned int cpu)
|
||||
{
|
||||
/*
|
||||
* the primary core may have used a "cross call" soft interrupt
|
||||
* to get this processor out of WFI in the BootMonitor - make
|
||||
* sure that we are no longer being sent this soft interrupt
|
||||
*/
|
||||
smp_cross_call_done(cpumask_of_cpu(cpu));
|
||||
|
||||
/*
|
||||
* if any interrupts are already enabled for the primary
|
||||
* core (e.g. timer irq), then they will not have been enabled
|
||||
* for us: do so
|
||||
*/
|
||||
gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
|
||||
|
||||
/*
|
||||
* let the primary processor know we're out of the
|
||||
* pen, then head off into the C entry point
|
||||
*/
|
||||
pen_release = -1;
|
||||
|
||||
/*
|
||||
* Synchronise with the boot thread.
|
||||
*/
|
||||
spin_lock(&boot_lock);
|
||||
spin_unlock(&boot_lock);
|
||||
}
|
||||
|
||||
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
{
|
||||
unsigned long timeout;
|
||||
|
||||
/*
|
||||
* set synchronisation state between this boot processor
|
||||
* and the secondary one
|
||||
*/
|
||||
spin_lock(&boot_lock);
|
||||
|
||||
/*
|
||||
* The secondary processor is waiting to be released from
|
||||
* the holding pen - release it, then wait for it to flag
|
||||
* that it has been released by resetting pen_release.
|
||||
*
|
||||
* Note that "pen_release" is the hardware CPU ID, whereas
|
||||
* "cpu" is Linux's internal ID.
|
||||
*/
|
||||
pen_release = cpu;
|
||||
flush_cache_all();
|
||||
|
||||
/*
|
||||
* XXX
|
||||
*
|
||||
* This is a later addition to the booting protocol: the
|
||||
* bootMonitor now puts secondary cores into WFI, so
|
||||
* poke_milo() no longer gets the cores moving; we need
|
||||
* to send a soft interrupt to wake the secondary core.
|
||||
* Use smp_cross_call() for this, since there's little
|
||||
* point duplicating the code here
|
||||
*/
|
||||
smp_cross_call(cpumask_of_cpu(cpu));
|
||||
|
||||
timeout = jiffies + (1 * HZ);
|
||||
while (time_before(jiffies, timeout)) {
|
||||
if (pen_release == -1)
|
||||
break;
|
||||
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
/*
|
||||
* now the secondary core is starting up let it run its
|
||||
* calibrations, then wait for it to finish
|
||||
*/
|
||||
spin_unlock(&boot_lock);
|
||||
|
||||
return pen_release != -1 ? -ENOSYS : 0;
|
||||
}
|
||||
|
||||
static void __init poke_milo(void)
|
||||
{
|
||||
extern void secondary_startup(void);
|
||||
|
||||
/* nobody is to be released from the pen yet */
|
||||
pen_release = -1;
|
||||
|
||||
/*
|
||||
* write the address of secondary startup into the system-wide
|
||||
* flags register, then clear the bottom two bits, which is what
|
||||
* BootMonitor is waiting for
|
||||
*/
|
||||
#if 1
|
||||
#define REALVIEW_SYS_FLAGSS_OFFSET 0x30
|
||||
__raw_writel(virt_to_phys(realview_secondary_startup),
|
||||
(IO_ADDRESS(REALVIEW_SYS_BASE) +
|
||||
REALVIEW_SYS_FLAGSS_OFFSET));
|
||||
#define REALVIEW_SYS_FLAGSC_OFFSET 0x34
|
||||
__raw_writel(3,
|
||||
(IO_ADDRESS(REALVIEW_SYS_BASE) +
|
||||
REALVIEW_SYS_FLAGSC_OFFSET));
|
||||
#endif
|
||||
|
||||
mb();
|
||||
}
|
||||
|
||||
void __init smp_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
unsigned int ncores = get_core_count();
|
||||
unsigned int cpu = smp_processor_id();
|
||||
int i;
|
||||
|
||||
/* sanity check */
|
||||
if (ncores == 0) {
|
||||
printk(KERN_ERR
|
||||
"Realview: strange CM count of 0? Default to 1\n");
|
||||
|
||||
ncores = 1;
|
||||
}
|
||||
|
||||
if (ncores > NR_CPUS) {
|
||||
printk(KERN_WARNING
|
||||
"Realview: no. of cores (%d) greater than configured "
|
||||
"maximum of %d - clipping\n",
|
||||
ncores, NR_CPUS);
|
||||
ncores = NR_CPUS;
|
||||
}
|
||||
|
||||
smp_store_cpu_info(cpu);
|
||||
|
||||
/*
|
||||
* are we trying to boot more cores than exist?
|
||||
*/
|
||||
if (max_cpus > ncores)
|
||||
max_cpus = ncores;
|
||||
|
||||
/*
|
||||
* Initialise the possible/present maps.
|
||||
* cpu_possible_map describes the set of CPUs which may be present
|
||||
* cpu_present_map describes the set of CPUs populated
|
||||
*/
|
||||
for (i = 0; i < max_cpus; i++) {
|
||||
cpu_set(i, cpu_possible_map);
|
||||
cpu_set(i, cpu_present_map);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do we need any more CPUs? If so, then let them know where
|
||||
* to start. Note that, on modern versions of MILO, the "poke"
|
||||
* doesn't actually do anything until each individual core is
|
||||
* sent a soft interrupt to get it out of WFI
|
||||
*/
|
||||
if (max_cpus > 1)
|
||||
poke_milo();
|
||||
}
|
|
@ -136,6 +136,11 @@ static struct amba_device *amba_devs[] __initdata = {
|
|||
|
||||
static void __init gic_init_irq(void)
|
||||
{
|
||||
#ifdef CONFIG_REALVIEW_MPCORE
|
||||
writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK));
|
||||
writel(0x008003c0, __io_address(REALVIEW_SYS_BASE) + 0xd8);
|
||||
writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
|
||||
#endif
|
||||
gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE));
|
||||
gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
|
||||
}
|
||||
|
|
|
@ -354,7 +354,7 @@ void __init build_mem_type_table(void)
|
|||
{
|
||||
struct cachepolicy *cp;
|
||||
unsigned int cr = get_cr();
|
||||
unsigned int user_pgprot;
|
||||
unsigned int user_pgprot, kern_pgprot;
|
||||
int cpu_arch = cpu_architecture();
|
||||
int i;
|
||||
|
||||
|
@ -381,7 +381,7 @@ void __init build_mem_type_table(void)
|
|||
}
|
||||
|
||||
cp = &cache_policies[cachepolicy];
|
||||
user_pgprot = cp->pte;
|
||||
kern_pgprot = user_pgprot = cp->pte;
|
||||
|
||||
/*
|
||||
* ARMv6 and above have extended page tables.
|
||||
|
@ -393,6 +393,7 @@ void __init build_mem_type_table(void)
|
|||
*/
|
||||
mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4;
|
||||
mem_types[MT_ROM].prot_sect &= ~PMD_BIT4;
|
||||
|
||||
/*
|
||||
* Mark cache clean areas and XIP ROM read only
|
||||
* from SVC mode and no access from userspace.
|
||||
|
@ -412,32 +413,47 @@ void __init build_mem_type_table(void)
|
|||
* (iow, non-global)
|
||||
*/
|
||||
user_pgprot |= L_PTE_ASID;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* Mark memory with the "shared" attribute for SMP systems
|
||||
*/
|
||||
user_pgprot |= L_PTE_SHARED;
|
||||
kern_pgprot |= L_PTE_SHARED;
|
||||
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
unsigned long v = pgprot_val(protection_map[i]);
|
||||
v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot;
|
||||
protection_map[i] = __pgprot(v);
|
||||
}
|
||||
|
||||
mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot;
|
||||
mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot;
|
||||
|
||||
if (cpu_arch >= CPU_ARCH_ARMv5) {
|
||||
mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
|
||||
mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
|
||||
#ifndef CONFIG_SMP
|
||||
/*
|
||||
* Only use write-through for non-SMP systems
|
||||
*/
|
||||
mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
|
||||
mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
|
||||
#endif
|
||||
} else {
|
||||
mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte;
|
||||
mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte;
|
||||
mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
|
||||
}
|
||||
|
||||
pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
|
||||
L_PTE_DIRTY | L_PTE_WRITE |
|
||||
L_PTE_EXEC | kern_pgprot);
|
||||
|
||||
mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
|
||||
mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
|
||||
mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
|
||||
mem_types[MT_ROM].prot_sect |= cp->pmd;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
unsigned long v = pgprot_val(protection_map[i]);
|
||||
v = (v & ~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
|
||||
protection_map[i] = __pgprot(v);
|
||||
}
|
||||
|
||||
pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
|
||||
L_PTE_DIRTY | L_PTE_WRITE |
|
||||
L_PTE_EXEC | cp->pte);
|
||||
|
||||
switch (cp->pmd) {
|
||||
case PMD_SECT_WT:
|
||||
mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/hardware/arm_scu.h>
|
||||
#include <asm/procinfo.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
|
@ -112,6 +113,9 @@ ENTRY(cpu_v6_dcache_clean_area)
|
|||
ENTRY(cpu_v6_switch_mm)
|
||||
mov r2, #0
|
||||
ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
|
||||
#ifdef CONFIG_SMP
|
||||
orr r0, r0, #2 @ set shared pgtable
|
||||
#endif
|
||||
mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
|
||||
mcr p15, 0, r2, c7, c10, 4 @ drain write buffer
|
||||
mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
|
||||
|
@ -140,7 +144,7 @@ ENTRY(cpu_v6_switch_mm)
|
|||
ENTRY(cpu_v6_set_pte)
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
bic r2, r1, #0x000007f0
|
||||
bic r2, r1, #0x000003f0
|
||||
bic r2, r2, #0x00000003
|
||||
orr r2, r2, #PTE_EXT_AP0 | 2
|
||||
|
||||
|
@ -191,6 +195,23 @@ cpu_v6_name:
|
|||
* - cache type register is implemented
|
||||
*/
|
||||
__v6_setup:
|
||||
#ifdef CONFIG_SMP
|
||||
/* Set up the SCU on core 0 only */
|
||||
mrc p15, 0, r0, c0, c0, 5 @ CPU core number
|
||||
ands r0, r0, #15
|
||||
moveq r0, #0x10000000 @ SCU_BASE
|
||||
orreq r0, r0, #0x00100000
|
||||
ldreq r5, [r0, #SCU_CTRL]
|
||||
orreq r5, r5, #1
|
||||
streq r5, [r0, #SCU_CTRL]
|
||||
|
||||
#ifndef CONFIG_CPU_DCACHE_DISABLE
|
||||
mrc p15, 0, r0, c1, c0, 1 @ Enable SMP/nAMP mode
|
||||
orr r0, r0, #0x20
|
||||
mcr p15, 0, r0, c1, c0, 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache
|
||||
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
|
||||
|
@ -198,6 +219,9 @@ __v6_setup:
|
|||
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
|
||||
mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
|
||||
mcr p15, 0, r0, c2, c0, 2 @ TTB control register
|
||||
#ifdef CONFIG_SMP
|
||||
orr r4, r4, #2 @ set shared pgtable
|
||||
#endif
|
||||
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
|
||||
#ifdef CONFIG_VFP
|
||||
mrc p15, 0, r0, c1, c0, 2
|
||||
|
|
|
@ -60,7 +60,7 @@ typedef union tagFPREG {
|
|||
#ifdef CONFIG_FPE_NWFPE_XP
|
||||
floatx80 fExtended;
|
||||
#else
|
||||
int padding[3];
|
||||
u32 padding[3];
|
||||
#endif
|
||||
} FPREG;
|
||||
|
||||
|
|
|
@ -59,8 +59,13 @@ static inline void loadExtended(const unsigned int Fn, const unsigned int __user
|
|||
p = (unsigned int *) &fpa11->fpreg[Fn].fExtended;
|
||||
fpa11->fType[Fn] = typeExtended;
|
||||
get_user(p[0], &pMem[0]); /* sign & exponent */
|
||||
#ifdef __ARMEB__
|
||||
get_user(p[1], &pMem[1]); /* ms bits */
|
||||
get_user(p[2], &pMem[2]); /* ls bits */
|
||||
#else
|
||||
get_user(p[1], &pMem[2]); /* ls bits */
|
||||
get_user(p[2], &pMem[1]); /* ms bits */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -177,8 +182,13 @@ static inline void storeExtended(const unsigned int Fn, unsigned int __user *pMe
|
|||
}
|
||||
|
||||
put_user(val.i[0], &pMem[0]); /* sign & exp */
|
||||
#ifdef __ARMEB__
|
||||
put_user(val.i[1], &pMem[1]); /* msw */
|
||||
put_user(val.i[2], &pMem[2]);
|
||||
#else
|
||||
put_user(val.i[1], &pMem[2]);
|
||||
put_user(val.i[2], &pMem[1]); /* msw */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -29,14 +29,14 @@
|
|||
|
||||
#ifdef CONFIG_FPE_NWFPE_XP
|
||||
const floatx80 floatx80Constant[] = {
|
||||
{0x0000, 0x0000000000000000ULL}, /* extended 0.0 */
|
||||
{0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */
|
||||
{0x4000, 0x8000000000000000ULL}, /* extended 2.0 */
|
||||
{0x4000, 0xc000000000000000ULL}, /* extended 3.0 */
|
||||
{0x4001, 0x8000000000000000ULL}, /* extended 4.0 */
|
||||
{0x4001, 0xa000000000000000ULL}, /* extended 5.0 */
|
||||
{0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */
|
||||
{0x4002, 0xa000000000000000ULL} /* extended 10.0 */
|
||||
{ .high = 0x0000, .low = 0x0000000000000000ULL},/* extended 0.0 */
|
||||
{ .high = 0x3fff, .low = 0x8000000000000000ULL},/* extended 1.0 */
|
||||
{ .high = 0x4000, .low = 0x8000000000000000ULL},/* extended 2.0 */
|
||||
{ .high = 0x4000, .low = 0xc000000000000000ULL},/* extended 3.0 */
|
||||
{ .high = 0x4001, .low = 0x8000000000000000ULL},/* extended 4.0 */
|
||||
{ .high = 0x4001, .low = 0xa000000000000000ULL},/* extended 5.0 */
|
||||
{ .high = 0x3ffe, .low = 0x8000000000000000ULL},/* extended 0.5 */
|
||||
{ .high = 0x4002, .low = 0xa000000000000000ULL},/* extended 10.0 */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -332,6 +332,7 @@ static floatx80 commonNaNToFloatx80( commonNaNT a )
|
|||
|
||||
z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
|
||||
z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
|
||||
}
|
||||
|
|
|
@ -531,6 +531,7 @@ INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
|
|||
|
||||
z.low = zSig;
|
||||
z.high = ( ( (bits16) zSign )<<15 ) + zExp;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
|
||||
}
|
||||
|
@ -2831,6 +2832,7 @@ static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, flo
|
|||
roundData->exception |= float_flag_invalid;
|
||||
z.low = floatx80_default_nan_low;
|
||||
z.high = floatx80_default_nan_high;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
}
|
||||
if ( aExp == 0 ) {
|
||||
|
@ -2950,6 +2952,7 @@ floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b )
|
|||
roundData->exception |= float_flag_invalid;
|
||||
z.low = floatx80_default_nan_low;
|
||||
z.high = floatx80_default_nan_high;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
}
|
||||
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
|
||||
|
@ -3015,6 +3018,7 @@ floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b )
|
|||
roundData->exception |= float_flag_invalid;
|
||||
z.low = floatx80_default_nan_low;
|
||||
z.high = floatx80_default_nan_high;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
}
|
||||
roundData->exception |= float_flag_divbyzero;
|
||||
|
@ -3093,6 +3097,7 @@ floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b )
|
|||
roundData->exception |= float_flag_invalid;
|
||||
z.low = floatx80_default_nan_low;
|
||||
z.high = floatx80_default_nan_high;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
}
|
||||
normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
|
||||
|
@ -3184,6 +3189,7 @@ floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a )
|
|||
roundData->exception |= float_flag_invalid;
|
||||
z.low = floatx80_default_nan_low;
|
||||
z.high = floatx80_default_nan_high;
|
||||
z.__padding = 0;
|
||||
return z;
|
||||
}
|
||||
if ( aExp == 0 ) {
|
||||
|
|
|
@ -51,11 +51,17 @@ input or output the `floatx80' type will be defined.
|
|||
Software IEC/IEEE floating-point types.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
typedef unsigned long int float32;
|
||||
typedef unsigned long long float64;
|
||||
typedef u32 float32;
|
||||
typedef u64 float64;
|
||||
typedef struct {
|
||||
unsigned short high;
|
||||
unsigned long long low;
|
||||
#ifdef __ARMEB__
|
||||
u16 __padding;
|
||||
u16 high;
|
||||
#else
|
||||
u16 high;
|
||||
u16 __padding;
|
||||
#endif
|
||||
u64 low;
|
||||
} floatx80;
|
||||
|
||||
/*
|
||||
|
|
|
@ -47,3 +47,17 @@
|
|||
cmpcs \irqnr, \irqnr
|
||||
|
||||
.endm
|
||||
|
||||
/* We assume that irqstat (the raw value of the IRQ acknowledge
|
||||
* register) is preserved from the macro above.
|
||||
* If there is an IPI, we immediately signal end of interrupt on the
|
||||
* controller, since this requires the original irqstat value which
|
||||
* we won't easily be able to recreate later.
|
||||
*/
|
||||
|
||||
.macro test_for_ipi, irqnr, irqstat, base, tmp
|
||||
bic \irqnr, \irqstat, #0x1c00
|
||||
cmp \irqnr, #16
|
||||
strcc \irqstat, [\base, #GIC_CPU_EOI]
|
||||
cmpcs \irqnr, \irqnr
|
||||
.endm
|
||||
|
|
|
@ -203,8 +203,14 @@
|
|||
/* Reserved 0x1001A000 - 0x1001FFFF */
|
||||
#define REALVIEW_CLCD_BASE 0x10020000 /* CLCD */
|
||||
#define REALVIEW_DMAC_BASE 0x10030000 /* DMA controller */
|
||||
#ifndef CONFIG_REALVIEW_MPCORE
|
||||
#define REALVIEW_GIC_CPU_BASE 0x10040000 /* Generic interrupt controller CPU interface */
|
||||
#define REALVIEW_GIC_DIST_BASE 0x10041000 /* Generic interrupt controller distributor */
|
||||
#else
|
||||
#define REALVIEW_MPCORE_SCU_BASE 0x10100000 /* SCU registers */
|
||||
#define REALVIEW_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */
|
||||
#define REALVIEW_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */
|
||||
#endif
|
||||
#define REALVIEW_SMC_BASE 0x10080000 /* SMC */
|
||||
/* Reserved 0x10090000 - 0x100EFFFF */
|
||||
|
||||
|
@ -265,6 +271,7 @@
|
|||
* Interrupts - bit assignment (primary)
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef CONFIG_REALVIEW_MPCORE
|
||||
#define INT_WDOGINT 0 /* Watchdog timer */
|
||||
#define INT_SOFTINT 1 /* Software interrupt */
|
||||
#define INT_COMMRx 2 /* Debug Comm Rx interrupt */
|
||||
|
@ -297,6 +304,55 @@
|
|||
#define INT_USB 29 /* USB controller */
|
||||
#define INT_TSPENINT 30 /* Touchscreen pen */
|
||||
#define INT_TSKPADINT 31 /* Touchscreen keypad */
|
||||
#else
|
||||
#define INT_LOCALTIMER 29
|
||||
#define INT_LOCALWDOG 30
|
||||
|
||||
#define INT_AACI 0
|
||||
#define INT_TIMERINT0_1 1
|
||||
#define INT_TIMERINT2_3 2
|
||||
#define INT_USB 3
|
||||
#define INT_UARTINT0 4
|
||||
#define INT_UARTINT1 5
|
||||
#define INT_RTCINT 6
|
||||
#define INT_KMI0 7
|
||||
#define INT_KMI1 8
|
||||
#define INT_ETH 9
|
||||
#define INT_EB_IRQ1 10 /* main GIC */
|
||||
#define INT_EB_IRQ2 11 /* tile GIC */
|
||||
#define INT_EB_FIQ1 12 /* main GIC */
|
||||
#define INT_EB_FIQ2 13 /* tile GIC */
|
||||
#define INT_MMCI0A 14
|
||||
#define INT_MMCI0B 15
|
||||
|
||||
#define INT_PMU_CPU0 17
|
||||
#define INT_PMU_CPU1 18
|
||||
#define INT_PMU_CPU2 19
|
||||
#define INT_PMU_CPU3 20
|
||||
#define INT_PMU_SCU0 21
|
||||
#define INT_PMU_SCU1 22
|
||||
#define INT_PMU_SCU2 23
|
||||
#define INT_PMU_SCU3 24
|
||||
#define INT_PMU_SCU4 25
|
||||
#define INT_PMU_SCU5 26
|
||||
#define INT_PMU_SCU6 27
|
||||
#define INT_PMU_SCU7 28
|
||||
|
||||
#define INT_L220_EVENT 29
|
||||
#define INT_L220_SLAVE 30
|
||||
#define INT_L220_DECODE 31
|
||||
|
||||
#define INT_UARTINT2 -1
|
||||
#define INT_UARTINT3 -1
|
||||
#define INT_CLCDINT -1
|
||||
#define INT_DMAINT -1
|
||||
#define INT_WDOGINT -1
|
||||
#define INT_GPIOINT0 -1
|
||||
#define INT_GPIOINT1 -1
|
||||
#define INT_GPIOINT2 -1
|
||||
#define INT_SCIINT -1
|
||||
#define INT_SSPINT -1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Interrupt bit positions
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef ASMARM_ARCH_SMP_H
|
||||
#define ASMARM_ARCH_SMP_H
|
||||
|
||||
#include <linux/config.h>
|
||||
|
||||
#include <asm/hardware/gic.h>
|
||||
|
||||
#define hard_smp_processor_id() \
|
||||
({ \
|
||||
unsigned int cpunum; \
|
||||
__asm__("mrc p15, 0, %0, c0, c0, 5" \
|
||||
: "=r" (cpunum)); \
|
||||
cpunum &= 0x0F; \
|
||||
})
|
||||
|
||||
/*
|
||||
* We use IRQ1 as the IPI
|
||||
*/
|
||||
static inline void smp_cross_call(cpumask_t callmap)
|
||||
{
|
||||
gic_raise_softirq(callmap, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do nothing on MPcore.
|
||||
*/
|
||||
static inline void smp_cross_call_done(cpumask_t callmap)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef ASMARM_HARDWARE_ARM_SCU_H
|
||||
#define ASMARM_HARDWARE_ARM_SCU_H
|
||||
|
||||
/*
|
||||
* SCU registers
|
||||
*/
|
||||
#define SCU_CTRL 0x00
|
||||
#define SCU_CONFIG 0x04
|
||||
#define SCU_CPU_STATUS 0x08
|
||||
#define SCU_INVALIDATE 0x0c
|
||||
#define SCU_FPGA_REVISION 0x10
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue