Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 14516
b: refs/heads/master
c: 4f1d774
h: refs/heads/master
v: v3
  • Loading branch information
Mathias Kretschmer authored and Bartlomiej Zolnierkiewicz committed Nov 19, 2005
1 parent a8c5127 commit c77348e
Show file tree
Hide file tree
Showing 51 changed files with 637 additions and 443 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8ee3f402676bf59caa454b7171ae09c8ac136627
refs/heads/master: 4f1d774aadfc5a6ed1545dca180f66ab6d0f543d
4 changes: 1 addition & 3 deletions trunk/Documentation/arm/memory.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Kernel Memory Layout on ARM Linux

Russell King <rmk@arm.linux.org.uk>
November 17, 2005 (2.6.15)
May 21, 2004 (2.6.6)

This document describes the virtual memory layout which the Linux
kernel uses for ARM processors. It indicates which regions are
Expand Down Expand Up @@ -37,8 +37,6 @@ ff000000 ffbfffff Reserved for future expansion of DMA
mapping region.

VMALLOC_END feffffff Free for platform use, recommended.
VMALLOC_END must be aligned to a 2MB
boundary.

VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space.
Memory returned by vmalloc/ioremap will
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/arm/kernel/armksyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ EXPORT_SYMBOL(__arch_strncpy_from_user);
EXPORT_SYMBOL(__get_user_1);
EXPORT_SYMBOL(__get_user_2);
EXPORT_SYMBOL(__get_user_4);
EXPORT_SYMBOL(__get_user_8);

EXPORT_SYMBOL(__put_user_1);
EXPORT_SYMBOL(__put_user_2);
Expand Down
3 changes: 2 additions & 1 deletion trunk/arch/arm/kernel/entry-common.S
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ work_pending:
mov r0, sp @ 'regs'
mov r2, why @ 'syscall'
bl do_notify_resume
b ret_slow_syscall @ Check work again
disable_irq @ disable interrupts
b no_work_pending

work_resched:
bl schedule
Expand Down
25 changes: 13 additions & 12 deletions trunk/arch/arm/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,22 +595,23 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
*/
ret |= !valid_user_regs(regs);

/*
* Block the signal if we were unsuccessful.
*/
if (ret != 0) {
force_sigsegv(sig, tsk);
return;
spin_lock_irq(&tsk->sighand->siglock);
sigorsets(&tsk->blocked, &tsk->blocked,
&ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NODEFER))
sigaddset(&tsk->blocked, sig);
recalc_sigpending();
spin_unlock_irq(&tsk->sighand->siglock);
}

/*
* Block the signal if we were successful.
*/
spin_lock_irq(&tsk->sighand->siglock);
sigorsets(&tsk->blocked, &tsk->blocked,
&ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NODEFER))
sigaddset(&tsk->blocked, sig);
recalc_sigpending();
spin_unlock_irq(&tsk->sighand->siglock);
if (ret == 0)
return;

force_sigsegv(sig, tsk);
}

/*
Expand Down
6 changes: 1 addition & 5 deletions trunk/arch/arm/kernel/vmlinux.lds.S
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,6 @@ SECTIONS
.comment 0 : { *(.comment) }
}

/*
* These must never be empty
* If you have to comment these two assert statements out, your
* binutils is too old (for other reasons as well)
*/
/* those must never be empty */
ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
11 changes: 11 additions & 0 deletions trunk/arch/arm/lib/getuser.S
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ __get_user_4:
mov r0, #0
mov pc, lr

.global __get_user_8
__get_user_8:
5: ldrt r2, [r0], #4
6: ldrt r3, [r0]
mov r0, #0
mov pc, lr

__get_user_bad_8:
mov r3, #0
__get_user_bad:
mov r2, #0
mov r0, #-EFAULT
Expand All @@ -64,4 +73,6 @@ __get_user_bad:
.long 2b, __get_user_bad
.long 3b, __get_user_bad
.long 4b, __get_user_bad
.long 5b, __get_user_bad_8
.long 6b, __get_user_bad_8
.previous
2 changes: 1 addition & 1 deletion trunk/arch/arm/mm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ obj-$(CONFIG_CPU_ARM1026) += proc-arm1026.o
obj-$(CONFIG_CPU_SA110) += proc-sa110.o
obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o
obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o
obj-$(CONFIG_CPU_V6) += proc-v6.o
obj-$(CONFIG_CPU_V6) += proc-v6.o blockops.o
185 changes: 185 additions & 0 deletions trunk/arch/arm/mm/blockops.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/mm.h>

#include <asm/memory.h>
#include <asm/ptrace.h>
#include <asm/cacheflush.h>
#include <asm/traps.h>

extern struct cpu_cache_fns blk_cache_fns;

#define HARVARD_CACHE

/*
* blk_flush_kern_dcache_page(kaddr)
*
* Ensure that the data held in the page kaddr is written back
* to the page in question.
*
* - kaddr - kernel address (guaranteed to be page aligned)
*/
static void __attribute__((naked))
blk_flush_kern_dcache_page(void *kaddr)
{
asm(
"add r1, r0, %0 \n\
sub r1, r1, %1 \n\
1: .word 0xec401f0e @ mcrr p15, 0, r0, r1, c14, 0 @ blocking \n\
mov r0, #0 \n\
mcr p15, 0, r0, c7, c5, 0 \n\
mcr p15, 0, r0, c7, c10, 4 \n\
mov pc, lr"
:
: "I" (PAGE_SIZE), "I" (L1_CACHE_BYTES));
}

/*
* blk_dma_inv_range(start,end)
*
* Invalidate the data cache within the specified region; we will
* be performing a DMA operation in this region and we want to
* purge old data in the cache.
*
* - start - virtual start address of region
* - end - virtual end address of region
*/
static void __attribute__((naked))
blk_dma_inv_range_unified(unsigned long start, unsigned long end)
{
asm(
"tst r0, %0 \n\
mcrne p15, 0, r0, c7, c11, 1 @ clean unified line \n\
tst r1, %0 \n\
mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line\n\
.word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0 @ blocking \n\
mov r0, #0 \n\
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\
mov pc, lr"
:
: "I" (L1_CACHE_BYTES - 1));
}

static void __attribute__((naked))
blk_dma_inv_range_harvard(unsigned long start, unsigned long end)
{
asm(
"tst r0, %0 \n\
mcrne p15, 0, r0, c7, c10, 1 @ clean D line \n\
tst r1, %0 \n\
mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line \n\
.word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0 @ blocking \n\
mov r0, #0 \n\
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\
mov pc, lr"
:
: "I" (L1_CACHE_BYTES - 1));
}

/*
* blk_dma_clean_range(start,end)
* - start - virtual start address of region
* - end - virtual end address of region
*/
static void __attribute__((naked))
blk_dma_clean_range(unsigned long start, unsigned long end)
{
asm(
".word 0xec401f0c @ mcrr p15, 0, r1, r0, c12, 0 @ blocking \n\
mov r0, #0 \n\
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\
mov pc, lr");
}

/*
* blk_dma_flush_range(start,end)
* - start - virtual start address of region
* - end - virtual end address of region
*/
static void __attribute__((naked))
blk_dma_flush_range(unsigned long start, unsigned long end)
{
asm(
".word 0xec401f0e @ mcrr p15, 0, r1, r0, c14, 0 @ blocking \n\
mov pc, lr");
}

static int blockops_trap(struct pt_regs *regs, unsigned int instr)
{
regs->ARM_r4 |= regs->ARM_r2;
regs->ARM_pc += 4;
return 0;
}

static char *func[] = {
"Prefetch data range",
"Clean+Invalidate data range",
"Clean data range",
"Invalidate data range",
"Invalidate instr range"
};

static struct undef_hook blockops_hook __initdata = {
.instr_mask = 0x0fffffd0,
.instr_val = 0x0c401f00,
.cpsr_mask = PSR_T_BIT,
.cpsr_val = 0,
.fn = blockops_trap,
};

static int __init blockops_check(void)
{
register unsigned int err asm("r4") = 0;
unsigned int err_pos = 1;
unsigned int cache_type;
int i;

asm("mrc p15, 0, %0, c0, c0, 1" : "=r" (cache_type));

printk("Checking V6 block cache operations:\n");
register_undef_hook(&blockops_hook);

__asm__ ("mov r0, %0\n\t"
"mov r1, %1\n\t"
"mov r2, #1\n\t"
".word 0xec401f2c @ mcrr p15, 0, r1, r0, c12, 2\n\t"
"mov r2, #2\n\t"
".word 0xec401f0e @ mcrr p15, 0, r1, r0, c14, 0\n\t"
"mov r2, #4\n\t"
".word 0xec401f0c @ mcrr p15, 0, r1, r0, c12, 0\n\t"
"mov r2, #8\n\t"
".word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0\n\t"
"mov r2, #16\n\t"
".word 0xec401f05 @ mcrr p15, 0, r1, r0, c5, 0\n\t"
:
: "r" (PAGE_OFFSET), "r" (PAGE_OFFSET + 128)
: "r0", "r1", "r2");

unregister_undef_hook(&blockops_hook);

for (i = 0; i < ARRAY_SIZE(func); i++, err_pos <<= 1)
printk("%30s: %ssupported\n", func[i], err & err_pos ? "not " : "");

if ((err & 8) == 0) {
printk(" --> Using %s block cache invalidate\n",
cache_type & (1 << 24) ? "harvard" : "unified");
if (cache_type & (1 << 24))
cpu_cache.dma_inv_range = blk_dma_inv_range_harvard;
else
cpu_cache.dma_inv_range = blk_dma_inv_range_unified;
}
if ((err & 4) == 0) {
printk(" --> Using block cache clean\n");
cpu_cache.dma_clean_range = blk_dma_clean_range;
}
if ((err & 2) == 0) {
printk(" --> Using block cache clean+invalidate\n");
cpu_cache.dma_flush_range = blk_dma_flush_range;
cpu_cache.flush_kern_dcache_page = blk_flush_kern_dcache_page;
}

return 0;
}

__initcall(blockops_check);
24 changes: 11 additions & 13 deletions trunk/arch/arm/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,21 +420,14 @@ static void __init bootmem_init(struct meminfo *mi)
* Set up device the mappings. Since we clear out the page tables for all
* mappings above VMALLOC_END, we will remove any debug device mappings.
* This means you have to be careful how you debug this function, or any
* called function. This means you can't use any function or debugging
* method which may touch any device, otherwise the kernel _will_ crash.
* called function. (Do it by code inspection!)
*/
static void __init devicemaps_init(struct machine_desc *mdesc)
{
struct map_desc map;
unsigned long addr;
void *vectors;

/*
* Allocate the vector page early.
*/
vectors = alloc_bootmem_low_pages(PAGE_SIZE);
BUG_ON(!vectors);

for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
pmd_clear(pmd_off_k(addr));

Expand Down Expand Up @@ -468,6 +461,12 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
create_mapping(&map);
#endif

flush_cache_all();
local_flush_tlb_all();

vectors = alloc_bootmem_low_pages(PAGE_SIZE);
BUG_ON(!vectors);

/*
* Create a mapping for the machine vectors at the high-vectors
* location (0xffff0000). If we aren't using high-vectors, also
Expand All @@ -492,13 +491,12 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
mdesc->map_io();

/*
* Finally flush the caches and tlb to ensure that we're in a
* consistent state wrt the writebuffer. This also ensures that
* any write-allocated cache lines in the vector page are written
* back. After this point, we can start to touch devices again.
* Finally flush the tlb again - this ensures that we're in a
* consistent state wrt the writebuffer if the writebuffer needs
* draining. After this point, we can start to touch devices
* again.
*/
local_flush_tlb_all();
flush_cache_all();
}

/*
Expand Down
3 changes: 2 additions & 1 deletion trunk/arch/arm/mm/ioremap.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ remap_area_pages(unsigned long start, unsigned long phys_addr,
* mapping. See include/asm-arm/proc-armv/pgtable.h for more information.
*/
void __iomem *
__ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
__ioremap(unsigned long phys_addr, size_t size, unsigned long flags,
unsigned long align)
{
void * addr;
struct vm_struct * area;
Expand Down
Loading

0 comments on commit c77348e

Please sign in to comment.