Automatic merge of master.kernel.org:/home/rmk/linux-2.6-arm
This commit is contained in:
commit
35d1bc9054
|
@ -47,3 +47,10 @@ __XScale_start:
|
||||||
orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00)
|
orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_IXP2000
|
||||||
|
mov r1, #-1
|
||||||
|
mov r0, #0xd6000000
|
||||||
|
str r1, [r0, #0x14]
|
||||||
|
str r1, [r0, #0x18]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -304,6 +304,15 @@ static void __init mainstone_map_io(void)
|
||||||
PWER = 0xC0000002;
|
PWER = 0xC0000002;
|
||||||
PRER = 0x00000002;
|
PRER = 0x00000002;
|
||||||
PFER = 0x00000002;
|
PFER = 0x00000002;
|
||||||
|
/* for use I SRAM as framebuffer. */
|
||||||
|
PSLR |= 0xF04;
|
||||||
|
PCFR = 0x66;
|
||||||
|
/* For Keypad wakeup. */
|
||||||
|
KPC &=~KPC_ASACT;
|
||||||
|
KPC |=KPC_AS;
|
||||||
|
PKWR = 0x000FD000;
|
||||||
|
/* Need read PKWR back after set it. */
|
||||||
|
PKWR;
|
||||||
}
|
}
|
||||||
|
|
||||||
MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
|
MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
|
||||||
|
|
|
@ -29,9 +29,6 @@
|
||||||
*/
|
*/
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
|
|
||||||
extern void pxa_cpu_suspend(void);
|
|
||||||
extern void pxa_cpu_resume(void);
|
|
||||||
|
|
||||||
#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
|
#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
|
||||||
#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
|
#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
|
||||||
|
|
||||||
|
@ -63,6 +60,12 @@ enum { SLEEP_SAVE_START = 0,
|
||||||
SLEEP_SAVE_ICMR,
|
SLEEP_SAVE_ICMR,
|
||||||
SLEEP_SAVE_CKEN,
|
SLEEP_SAVE_CKEN,
|
||||||
|
|
||||||
|
#ifdef CONFIG_PXA27x
|
||||||
|
SLEEP_SAVE_MDREFR,
|
||||||
|
SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
|
||||||
|
SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
|
||||||
|
#endif
|
||||||
|
|
||||||
SLEEP_SAVE_CKSUM,
|
SLEEP_SAVE_CKSUM,
|
||||||
|
|
||||||
SLEEP_SAVE_SIZE
|
SLEEP_SAVE_SIZE
|
||||||
|
@ -75,9 +78,7 @@ static int pxa_pm_enter(suspend_state_t state)
|
||||||
unsigned long checksum = 0;
|
unsigned long checksum = 0;
|
||||||
struct timespec delta, rtc;
|
struct timespec delta, rtc;
|
||||||
int i;
|
int i;
|
||||||
|
extern void pxa_cpu_pm_enter(suspend_state_t state);
|
||||||
if (state != PM_SUSPEND_MEM)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
#ifdef CONFIG_IWMMXT
|
#ifdef CONFIG_IWMMXT
|
||||||
/* force any iWMMXt context to ram **/
|
/* force any iWMMXt context to ram **/
|
||||||
|
@ -100,16 +101,17 @@ static int pxa_pm_enter(suspend_state_t state)
|
||||||
SAVE(GAFR2_L); SAVE(GAFR2_U);
|
SAVE(GAFR2_L); SAVE(GAFR2_U);
|
||||||
|
|
||||||
#ifdef CONFIG_PXA27x
|
#ifdef CONFIG_PXA27x
|
||||||
|
SAVE(MDREFR);
|
||||||
SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3);
|
SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3);
|
||||||
SAVE(GAFR3_L); SAVE(GAFR3_U);
|
SAVE(GAFR3_L); SAVE(GAFR3_U);
|
||||||
|
SAVE(PWER); SAVE(PCFR); SAVE(PRER);
|
||||||
|
SAVE(PFER); SAVE(PKWR);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SAVE(ICMR);
|
SAVE(ICMR);
|
||||||
ICMR = 0;
|
ICMR = 0;
|
||||||
|
|
||||||
SAVE(CKEN);
|
SAVE(CKEN);
|
||||||
CKEN = 0;
|
|
||||||
|
|
||||||
SAVE(PSTR);
|
SAVE(PSTR);
|
||||||
|
|
||||||
/* Note: wake up source are set up in each machine specific files */
|
/* Note: wake up source are set up in each machine specific files */
|
||||||
|
@ -123,16 +125,13 @@ static int pxa_pm_enter(suspend_state_t state)
|
||||||
/* Clear sleep reset status */
|
/* Clear sleep reset status */
|
||||||
RCSR = RCSR_SMR;
|
RCSR = RCSR_SMR;
|
||||||
|
|
||||||
/* set resume return address */
|
|
||||||
PSPR = virt_to_phys(pxa_cpu_resume);
|
|
||||||
|
|
||||||
/* before sleeping, calculate and save a checksum */
|
/* before sleeping, calculate and save a checksum */
|
||||||
for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
|
for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
|
||||||
checksum += sleep_save[i];
|
checksum += sleep_save[i];
|
||||||
sleep_save[SLEEP_SAVE_CKSUM] = checksum;
|
sleep_save[SLEEP_SAVE_CKSUM] = checksum;
|
||||||
|
|
||||||
/* *** go zzz *** */
|
/* *** go zzz *** */
|
||||||
pxa_cpu_suspend();
|
pxa_cpu_pm_enter(state);
|
||||||
|
|
||||||
/* after sleeping, validate the checksum */
|
/* after sleeping, validate the checksum */
|
||||||
checksum = 0;
|
checksum = 0;
|
||||||
|
@ -145,7 +144,7 @@ static int pxa_pm_enter(suspend_state_t state)
|
||||||
LUB_HEXLED = 0xbadbadc5;
|
LUB_HEXLED = 0xbadbadc5;
|
||||||
#endif
|
#endif
|
||||||
while (1)
|
while (1)
|
||||||
pxa_cpu_suspend();
|
pxa_cpu_pm_enter(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ensure not to come back here if it wasn't intended */
|
/* ensure not to come back here if it wasn't intended */
|
||||||
|
@ -162,8 +161,11 @@ static int pxa_pm_enter(suspend_state_t state)
|
||||||
RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
|
RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
|
||||||
|
|
||||||
#ifdef CONFIG_PXA27x
|
#ifdef CONFIG_PXA27x
|
||||||
|
RESTORE(MDREFR);
|
||||||
RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3);
|
RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3);
|
||||||
RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
|
RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
|
||||||
|
RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
|
||||||
|
RESTORE(PFER); RESTORE(PKWR);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PSSR = PSSR_RDH | PSSR_PH;
|
PSSR = PSSR_RDH | PSSR_PH;
|
||||||
|
@ -197,7 +199,9 @@ unsigned long sleep_phys_sp(void *sp)
|
||||||
*/
|
*/
|
||||||
static int pxa_pm_prepare(suspend_state_t state)
|
static int pxa_pm_prepare(suspend_state_t state)
|
||||||
{
|
{
|
||||||
return 0;
|
extern int pxa_cpu_pm_prepare(suspend_state_t state);
|
||||||
|
|
||||||
|
return pxa_cpu_pm_prepare(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -102,3 +102,32 @@ unsigned int get_lcdclk_frequency_10khz(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
|
EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
|
||||||
|
|
||||||
|
|
||||||
|
int pxa_cpu_pm_prepare(suspend_state_t state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case PM_SUSPEND_MEM:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pxa_cpu_pm_enter(suspend_state_t state)
|
||||||
|
{
|
||||||
|
extern void pxa_cpu_suspend(unsigned int);
|
||||||
|
extern void pxa_cpu_resume(void);
|
||||||
|
|
||||||
|
CKEN = 0;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case PM_SUSPEND_MEM:
|
||||||
|
/* set resume return address */
|
||||||
|
PSPR = virt_to_phys(pxa_cpu_resume);
|
||||||
|
pxa_cpu_suspend(3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -120,6 +120,38 @@ EXPORT_SYMBOL(get_clk_frequency_khz);
|
||||||
EXPORT_SYMBOL(get_memclk_frequency_10khz);
|
EXPORT_SYMBOL(get_memclk_frequency_10khz);
|
||||||
EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
|
EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
|
||||||
|
|
||||||
|
int pxa_cpu_pm_prepare(suspend_state_t state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case PM_SUSPEND_MEM:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pxa_cpu_pm_enter(suspend_state_t state)
|
||||||
|
{
|
||||||
|
extern void pxa_cpu_standby(void);
|
||||||
|
extern void pxa_cpu_suspend(unsigned int);
|
||||||
|
extern void pxa_cpu_resume(void);
|
||||||
|
|
||||||
|
CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
|
||||||
|
|
||||||
|
/* ensure voltage-change sequencer not initiated, which hangs */
|
||||||
|
PCFR &= ~PCFR_FVC;
|
||||||
|
|
||||||
|
/* Clear edge-detect status register. */
|
||||||
|
PEDR = 0xDF12FE1B;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case PM_SUSPEND_MEM:
|
||||||
|
/* set resume return address */
|
||||||
|
PSPR = virt_to_phys(pxa_cpu_resume);
|
||||||
|
pxa_cpu_suspend(3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* device registration specific to PXA27x.
|
* device registration specific to PXA27x.
|
||||||
|
|
|
@ -785,6 +785,10 @@ int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client)
|
||||||
chan->client = NULL;
|
chan->client = NULL;
|
||||||
chan->in_use = 0;
|
chan->in_use = 0;
|
||||||
|
|
||||||
|
if (chan->irq_claimed)
|
||||||
|
free_irq(chan->irq, (void *)chan);
|
||||||
|
chan->irq_claimed = 0;
|
||||||
|
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -228,7 +228,6 @@ config CPU_SA1100
|
||||||
select CPU_CACHE_V4WB
|
select CPU_CACHE_V4WB
|
||||||
select CPU_CACHE_VIVT
|
select CPU_CACHE_VIVT
|
||||||
select CPU_TLB_V4WB
|
select CPU_TLB_V4WB
|
||||||
select CPU_MINICACHE
|
|
||||||
|
|
||||||
# XScale
|
# XScale
|
||||||
config CPU_XSCALE
|
config CPU_XSCALE
|
||||||
|
@ -239,7 +238,6 @@ config CPU_XSCALE
|
||||||
select CPU_ABRT_EV5T
|
select CPU_ABRT_EV5T
|
||||||
select CPU_CACHE_VIVT
|
select CPU_CACHE_VIVT
|
||||||
select CPU_TLB_V4WBI
|
select CPU_TLB_V4WBI
|
||||||
select CPU_MINICACHE
|
|
||||||
|
|
||||||
# ARMv6
|
# ARMv6
|
||||||
config CPU_V6
|
config CPU_V6
|
||||||
|
@ -345,11 +343,6 @@ config CPU_TLB_V4WBI
|
||||||
config CPU_TLB_V6
|
config CPU_TLB_V6
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config CPU_MINICACHE
|
|
||||||
bool
|
|
||||||
help
|
|
||||||
Processor has a minicache.
|
|
||||||
|
|
||||||
comment "Processor Features"
|
comment "Processor Features"
|
||||||
|
|
||||||
config ARM_THUMB
|
config ARM_THUMB
|
||||||
|
|
|
@ -31,8 +31,6 @@ obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o mmu.o
|
||||||
obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o
|
obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o
|
||||||
obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o
|
obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o
|
||||||
|
|
||||||
obj-$(CONFIG_CPU_MINICACHE) += minicache.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o
|
obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o
|
||||||
obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o
|
obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o
|
||||||
obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o
|
obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
/*
|
|
||||||
* linux/arch/arm/lib/copypage-xscale.S
|
|
||||||
*
|
|
||||||
* Copyright (C) 2001 Russell King
|
|
||||||
*
|
|
||||||
* 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>
|
|
||||||
#include <asm/constants.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* General note:
|
|
||||||
* We don't really want write-allocate cache behaviour for these functions
|
|
||||||
* since that will just eat through 8K of the cache.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.text
|
|
||||||
.align 5
|
|
||||||
/*
|
|
||||||
* XScale optimised copy_user_page
|
|
||||||
* r0 = destination
|
|
||||||
* r1 = source
|
|
||||||
* r2 = virtual user address of ultimate destination page
|
|
||||||
*
|
|
||||||
* The source page may have some clean entries in the cache already, but we
|
|
||||||
* can safely ignore them - break_cow() will flush them out of the cache
|
|
||||||
* if we eventually end up using our copied page.
|
|
||||||
*
|
|
||||||
* What we could do is use the mini-cache to buffer reads from the source
|
|
||||||
* page. We rely on the mini-cache being smaller than one page, so we'll
|
|
||||||
* cycle through the complete cache anyway.
|
|
||||||
*/
|
|
||||||
ENTRY(xscale_mc_copy_user_page)
|
|
||||||
stmfd sp!, {r4, r5, lr}
|
|
||||||
mov r5, r0
|
|
||||||
mov r0, r1
|
|
||||||
bl map_page_minicache
|
|
||||||
mov r1, r5
|
|
||||||
mov lr, #PAGE_SZ/64-1
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Strangely enough, best performance is achieved
|
|
||||||
* when prefetching destination as well. (NP)
|
|
||||||
*/
|
|
||||||
pld [r0, #0]
|
|
||||||
pld [r0, #32]
|
|
||||||
pld [r1, #0]
|
|
||||||
pld [r1, #32]
|
|
||||||
|
|
||||||
1: pld [r0, #64]
|
|
||||||
pld [r0, #96]
|
|
||||||
pld [r1, #64]
|
|
||||||
pld [r1, #96]
|
|
||||||
|
|
||||||
2: ldrd r2, [r0], #8
|
|
||||||
ldrd r4, [r0], #8
|
|
||||||
mov ip, r1
|
|
||||||
strd r2, [r1], #8
|
|
||||||
ldrd r2, [r0], #8
|
|
||||||
strd r4, [r1], #8
|
|
||||||
ldrd r4, [r0], #8
|
|
||||||
strd r2, [r1], #8
|
|
||||||
strd r4, [r1], #8
|
|
||||||
mcr p15, 0, ip, c7, c10, 1 @ clean D line
|
|
||||||
ldrd r2, [r0], #8
|
|
||||||
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line
|
|
||||||
ldrd r4, [r0], #8
|
|
||||||
mov ip, r1
|
|
||||||
strd r2, [r1], #8
|
|
||||||
ldrd r2, [r0], #8
|
|
||||||
strd r4, [r1], #8
|
|
||||||
ldrd r4, [r0], #8
|
|
||||||
strd r2, [r1], #8
|
|
||||||
strd r4, [r1], #8
|
|
||||||
mcr p15, 0, ip, c7, c10, 1 @ clean D line
|
|
||||||
subs lr, lr, #1
|
|
||||||
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line
|
|
||||||
bgt 1b
|
|
||||||
beq 2b
|
|
||||||
|
|
||||||
ldmfd sp!, {r4, r5, pc}
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
/*
|
|
||||||
* XScale optimised clear_user_page
|
|
||||||
* r0 = destination
|
|
||||||
* r1 = virtual user address of ultimate destination page
|
|
||||||
*/
|
|
||||||
ENTRY(xscale_mc_clear_user_page)
|
|
||||||
mov r1, #PAGE_SZ/32
|
|
||||||
mov r2, #0
|
|
||||||
mov r3, #0
|
|
||||||
1: mov ip, r0
|
|
||||||
strd r2, [r0], #8
|
|
||||||
strd r2, [r0], #8
|
|
||||||
strd r2, [r0], #8
|
|
||||||
strd r2, [r0], #8
|
|
||||||
mcr p15, 0, ip, c7, c10, 1 @ clean D line
|
|
||||||
subs r1, r1, #1
|
|
||||||
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line
|
|
||||||
bne 1b
|
|
||||||
mov pc, lr
|
|
||||||
|
|
||||||
__INITDATA
|
|
||||||
|
|
||||||
.type xscale_mc_user_fns, #object
|
|
||||||
ENTRY(xscale_mc_user_fns)
|
|
||||||
.long xscale_mc_clear_user_page
|
|
||||||
.long xscale_mc_copy_user_page
|
|
||||||
.size xscale_mc_user_fns, . - xscale_mc_user_fns
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/lib/copypage-xscale.S
|
||||||
|
*
|
||||||
|
* Copyright (C) 1995-2005 Russell King
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This handles the mini data cache, as found on SA11x0 and XScale
|
||||||
|
* processors. When we copy a user page page, we map it in such a way
|
||||||
|
* that accesses to this page will not touch the main data cache, but
|
||||||
|
* will be cached in the mini data cache. This prevents us thrashing
|
||||||
|
* the main data cache on page faults.
|
||||||
|
*/
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
|
||||||
|
#include <asm/page.h>
|
||||||
|
#include <asm/pgtable.h>
|
||||||
|
#include <asm/tlbflush.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 0xffff8000 to 0xffffffff is reserved for any ARM architecture
|
||||||
|
* specific hacks for copying pages efficiently.
|
||||||
|
*/
|
||||||
|
#define COPYPAGE_MINICACHE 0xffff8000
|
||||||
|
|
||||||
|
#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
|
||||||
|
L_PTE_CACHEABLE)
|
||||||
|
|
||||||
|
#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
|
||||||
|
|
||||||
|
static DEFINE_SPINLOCK(minicache_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XScale mini-dcache optimised copy_user_page
|
||||||
|
*
|
||||||
|
* We flush the destination cache lines just before we write the data into the
|
||||||
|
* corresponding address. Since the Dcache is read-allocate, this removes the
|
||||||
|
* Dcache aliasing issue. The writes will be forwarded to the write buffer,
|
||||||
|
* and merged as appropriate.
|
||||||
|
*/
|
||||||
|
static void __attribute__((naked))
|
||||||
|
mc_copy_user_page(void *from, void *to)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Strangely enough, best performance is achieved
|
||||||
|
* when prefetching destination as well. (NP)
|
||||||
|
*/
|
||||||
|
asm volatile(
|
||||||
|
"stmfd sp!, {r4, r5, lr} \n\
|
||||||
|
mov lr, %2 \n\
|
||||||
|
pld [r0, #0] \n\
|
||||||
|
pld [r0, #32] \n\
|
||||||
|
pld [r1, #0] \n\
|
||||||
|
pld [r1, #32] \n\
|
||||||
|
1: pld [r0, #64] \n\
|
||||||
|
pld [r0, #96] \n\
|
||||||
|
pld [r1, #64] \n\
|
||||||
|
pld [r1, #96] \n\
|
||||||
|
2: ldrd r2, [r0], #8 \n\
|
||||||
|
ldrd r4, [r0], #8 \n\
|
||||||
|
mov ip, r1 \n\
|
||||||
|
strd r2, [r1], #8 \n\
|
||||||
|
ldrd r2, [r0], #8 \n\
|
||||||
|
strd r4, [r1], #8 \n\
|
||||||
|
ldrd r4, [r0], #8 \n\
|
||||||
|
strd r2, [r1], #8 \n\
|
||||||
|
strd r4, [r1], #8 \n\
|
||||||
|
mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
|
||||||
|
ldrd r2, [r0], #8 \n\
|
||||||
|
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
|
||||||
|
ldrd r4, [r0], #8 \n\
|
||||||
|
mov ip, r1 \n\
|
||||||
|
strd r2, [r1], #8 \n\
|
||||||
|
ldrd r2, [r0], #8 \n\
|
||||||
|
strd r4, [r1], #8 \n\
|
||||||
|
ldrd r4, [r0], #8 \n\
|
||||||
|
strd r2, [r1], #8 \n\
|
||||||
|
strd r4, [r1], #8 \n\
|
||||||
|
mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
|
||||||
|
subs lr, lr, #1 \n\
|
||||||
|
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
|
||||||
|
bgt 1b \n\
|
||||||
|
beq 2b \n\
|
||||||
|
ldmfd sp!, {r4, r5, pc} "
|
||||||
|
:
|
||||||
|
: "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
|
||||||
|
{
|
||||||
|
spin_lock(&minicache_lock);
|
||||||
|
|
||||||
|
set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
|
||||||
|
flush_tlb_kernel_page(COPYPAGE_MINICACHE);
|
||||||
|
|
||||||
|
mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
|
||||||
|
|
||||||
|
spin_unlock(&minicache_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XScale optimised clear_user_page
|
||||||
|
*/
|
||||||
|
void __attribute__((naked))
|
||||||
|
xscale_mc_clear_user_page(void *kaddr, unsigned long vaddr)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
"mov r1, %0 \n\
|
||||||
|
mov r2, #0 \n\
|
||||||
|
mov r3, #0 \n\
|
||||||
|
1: mov ip, r0 \n\
|
||||||
|
strd r2, [r0], #8 \n\
|
||||||
|
strd r2, [r0], #8 \n\
|
||||||
|
strd r2, [r0], #8 \n\
|
||||||
|
strd r2, [r0], #8 \n\
|
||||||
|
mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
|
||||||
|
subs r1, r1, #1 \n\
|
||||||
|
mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
|
||||||
|
bne 1b \n\
|
||||||
|
mov pc, lr"
|
||||||
|
:
|
||||||
|
: "I" (PAGE_SIZE / 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cpu_user_fns xscale_mc_user_fns __initdata = {
|
||||||
|
.cpu_clear_user_page = xscale_mc_clear_user_page,
|
||||||
|
.cpu_copy_user_page = xscale_mc_copy_user_page,
|
||||||
|
};
|
|
@ -1,73 +0,0 @@
|
||||||
/*
|
|
||||||
* linux/arch/arm/mm/minicache.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 2001 Russell King
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* This handles the mini data cache, as found on SA11x0 and XScale
|
|
||||||
* processors. When we copy a user page page, we map it in such a way
|
|
||||||
* that accesses to this page will not touch the main data cache, but
|
|
||||||
* will be cached in the mini data cache. This prevents us thrashing
|
|
||||||
* the main data cache on page faults.
|
|
||||||
*/
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
|
|
||||||
#include <asm/page.h>
|
|
||||||
#include <asm/pgtable.h>
|
|
||||||
#include <asm/tlbflush.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 0xffff8000 to 0xffffffff is reserved for any ARM architecture
|
|
||||||
* specific hacks for copying pages efficiently.
|
|
||||||
*/
|
|
||||||
#define minicache_address (0xffff8000)
|
|
||||||
#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
|
|
||||||
L_PTE_CACHEABLE)
|
|
||||||
|
|
||||||
static pte_t *minicache_pte;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that this is intended to be called only from the copy_user_page
|
|
||||||
* asm code; anything else will require special locking to prevent the
|
|
||||||
* mini-cache space being re-used. (Note: probably preempt unsafe).
|
|
||||||
*
|
|
||||||
* We rely on the fact that the minicache is 2K, and we'll be pushing
|
|
||||||
* 4K of data through it, so we don't actually have to specifically
|
|
||||||
* flush the minicache when we change the mapping.
|
|
||||||
*
|
|
||||||
* Note also: assert(PAGE_OFFSET <= virt < high_memory).
|
|
||||||
* Unsafe: preempt, kmap.
|
|
||||||
*/
|
|
||||||
unsigned long map_page_minicache(unsigned long virt)
|
|
||||||
{
|
|
||||||
set_pte(minicache_pte, pfn_pte(__pa(virt) >> PAGE_SHIFT, minicache_pgprot));
|
|
||||||
flush_tlb_kernel_page(minicache_address);
|
|
||||||
|
|
||||||
return minicache_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init minicache_init(void)
|
|
||||||
{
|
|
||||||
pgd_t *pgd;
|
|
||||||
pmd_t *pmd;
|
|
||||||
|
|
||||||
spin_lock(&init_mm.page_table_lock);
|
|
||||||
|
|
||||||
pgd = pgd_offset_k(minicache_address);
|
|
||||||
pmd = pmd_alloc(&init_mm, pgd, minicache_address);
|
|
||||||
if (!pmd)
|
|
||||||
BUG();
|
|
||||||
minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address);
|
|
||||||
if (!minicache_pte)
|
|
||||||
BUG();
|
|
||||||
|
|
||||||
spin_unlock(&init_mm.page_table_lock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
core_initcall(minicache_init);
|
|
|
@ -75,8 +75,8 @@ static inline void insw(u32 ptr, void *buf, int length)
|
||||||
* Is this cycle meant for the CS8900?
|
* Is this cycle meant for the CS8900?
|
||||||
*/
|
*/
|
||||||
if ((machine_is_ixdp2401() || machine_is_ixdp2801()) &&
|
if ((machine_is_ixdp2401() || machine_is_ixdp2801()) &&
|
||||||
((port >= IXDP2X01_CS8900_VIRT_BASE) &&
|
(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
|
||||||
(port <= IXDP2X01_CS8900_VIRT_END))) {
|
((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
|
||||||
u8 *buf8 = (u8*)buf;
|
u8 *buf8 = (u8*)buf;
|
||||||
register u32 tmp32;
|
register u32 tmp32;
|
||||||
|
|
||||||
|
@ -100,8 +100,8 @@ static inline void outsw(u32 ptr, void *buf, int length)
|
||||||
* Is this cycle meant for the CS8900?
|
* Is this cycle meant for the CS8900?
|
||||||
*/
|
*/
|
||||||
if ((machine_is_ixdp2401() || machine_is_ixdp2801()) &&
|
if ((machine_is_ixdp2401() || machine_is_ixdp2801()) &&
|
||||||
((port >= IXDP2X01_CS8900_VIRT_BASE) &&
|
(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
|
||||||
(port <= IXDP2X01_CS8900_VIRT_END))) {
|
((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
|
||||||
register u32 tmp32;
|
register u32 tmp32;
|
||||||
u8 *buf8 = (u8*)buf;
|
u8 *buf8 = (u8*)buf;
|
||||||
do {
|
do {
|
||||||
|
@ -124,8 +124,8 @@ static inline u16 inw(u32 ptr)
|
||||||
* Is this cycle meant for the CS8900?
|
* Is this cycle meant for the CS8900?
|
||||||
*/
|
*/
|
||||||
if ((machine_is_ixdp2401() || machine_is_ixdp2801()) &&
|
if ((machine_is_ixdp2401() || machine_is_ixdp2801()) &&
|
||||||
((port >= IXDP2X01_CS8900_VIRT_BASE) &&
|
(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
|
||||||
(port <= IXDP2X01_CS8900_VIRT_END))) {
|
((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
|
||||||
return (u16)(*port);
|
return (u16)(*port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,8 +137,8 @@ static inline void outw(u16 value, u32 ptr)
|
||||||
register volatile u32 *port = (volatile u32 *)ptr;
|
register volatile u32 *port = (volatile u32 *)ptr;
|
||||||
|
|
||||||
if ((machine_is_ixdp2401() || machine_is_ixdp2801()) &&
|
if ((machine_is_ixdp2401() || machine_is_ixdp2801()) &&
|
||||||
((port >= IXDP2X01_CS8900_VIRT_BASE) &&
|
(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
|
||||||
(port <= IXDP2X01_CS8900_VIRT_END))) {
|
((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
|
||||||
*port = value;
|
*port = value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,9 +38,9 @@ typedef struct user_fp elf_fpregset_t;
|
||||||
*/
|
*/
|
||||||
#define ELF_CLASS ELFCLASS32
|
#define ELF_CLASS ELFCLASS32
|
||||||
#ifdef __ARMEB__
|
#ifdef __ARMEB__
|
||||||
#define ELF_DATA ELFDATA2MSB;
|
#define ELF_DATA ELFDATA2MSB
|
||||||
#else
|
#else
|
||||||
#define ELF_DATA ELFDATA2LSB;
|
#define ELF_DATA ELFDATA2LSB
|
||||||
#endif
|
#endif
|
||||||
#define ELF_ARCH EM_ARM
|
#define ELF_ARCH EM_ARM
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ typedef struct { void *null; } elf_fpregset_t;
|
||||||
* These are used to set parameters in the core dumps.
|
* These are used to set parameters in the core dumps.
|
||||||
*/
|
*/
|
||||||
#define ELF_CLASS ELFCLASS32
|
#define ELF_CLASS ELFCLASS32
|
||||||
#define ELF_DATA ELFDATA2LSB;
|
#define ELF_DATA ELFDATA2LSB
|
||||||
#define ELF_ARCH EM_ARM
|
#define ELF_ARCH EM_ARM
|
||||||
|
|
||||||
#define USE_ELF_CORE_DUMP
|
#define USE_ELF_CORE_DUMP
|
||||||
|
|
Loading…
Reference in New Issue