···192193 iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));194 iotable_init(mach_desc, size);0195 /* rename any peripherals used differing from the s3c2410 */196197- s3c_device_i2c.name = "s3c2440-i2c";0198199 /* change irq for watchdog */200···227 break;228229 case S3C2440_CLKDIVN_HDIVN_2:230- hdiv = 1;231 break;232233 case S3C2440_CLKDIVN_HDIVN_4_8:
···192193 iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));194 iotable_init(mach_desc, size);195+196 /* rename any peripherals used differing from the s3c2410 */197198+ s3c_device_i2c.name = "s3c2440-i2c";199+ s3c_device_nand.name = "s3c2440-nand";200201 /* change irq for watchdog */202···225 break;226227 case S3C2440_CLKDIVN_HDIVN_2:228+ hdiv = 2;229 break;230231 case S3C2440_CLKDIVN_HDIVN_4_8:
+10-11
arch/arm/mm/Kconfig
···412413config TLS_REG_EMUL414 bool415- default y if (SMP || CPU_32v6) && (CPU_32v5 || CPU_32v4 || CPU_32v3)416 help417- We might be running on an ARMv6+ processor which should have the TLS418- register but for some reason we can't use it, or maybe an SMP system419- using a pre-ARMv6 processor (there are apparently a few prototypes420- like that in existence) and therefore access to that register must421- be emulated.422423config HAS_TLS_REG424 bool425- depends on CPU_32v6426- default y if !TLS_REG_EMUL427 help428 This selects support for the CP15 thread register.429- It is defined to be available on ARMv6 or later. If a particular430- ARMv6 or later CPU doesn't support it then it must omc;ide "select431- TLS_REG_EMUL" along with its other caracteristics.0432
···412413config TLS_REG_EMUL414 bool415+ default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3)416 help417+ An SMP system using a pre-ARMv6 processor (there are apparently418+ a few prototypes like that in existence) and therefore access to419+ that required register must be emulated.00420421config HAS_TLS_REG422 bool423+ depends on !TLS_REG_EMUL424+ default y if SMP || CPU_32v7425 help426 This selects support for the CP15 thread register.427+ It is defined to be available on some ARMv6 processors (including428+ all SMP capable ARMv6's) or later processors. User space may429+ assume directly accessing that register and always obtain the430+ expected value only on ARMv7 and above.431
-80
arch/arm/mm/copypage-v4mc.S
···1-/*2- * linux/arch/arm/lib/copy_page-armv4mc.S3- *4- * Copyright (C) 1995-2001 Russell King5- *6- * This program is free software; you can redistribute it and/or modify7- * it under the terms of the GNU General Public License version 2 as8- * published by the Free Software Foundation.9- *10- * ASM optimised string functions11- */12-#include <linux/linkage.h>13-#include <linux/init.h>14-#include <asm/constants.h>15-16- .text17- .align 518-/*19- * ARMv4 mini-dcache optimised copy_user_page20- *21- * We flush the destination cache lines just before we write the data into the22- * corresponding address. Since the Dcache is read-allocate, this removes the23- * Dcache aliasing issue. The writes will be forwarded to the write buffer,24- * and merged as appropriate.25- *26- * Note: We rely on all ARMv4 processors implementing the "invalidate D line"27- * instruction. If your processor does not supply this, you have to write your28- * own copy_user_page that does the right thing.29- */30-ENTRY(v4_mc_copy_user_page)31- stmfd sp!, {r4, lr} @ 232- mov r4, r033- mov r0, r134- bl map_page_minicache35- mov r1, #PAGE_SZ/64 @ 136- ldmia r0!, {r2, r3, ip, lr} @ 437-1: mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line38- stmia r4!, {r2, r3, ip, lr} @ 439- ldmia r0!, {r2, r3, ip, lr} @ 4+140- stmia r4!, {r2, r3, ip, lr} @ 441- ldmia r0!, {r2, r3, ip, lr} @ 442- mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line43- stmia r4!, {r2, r3, ip, lr} @ 444- ldmia r0!, {r2, r3, ip, lr} @ 445- subs r1, r1, #1 @ 146- stmia r4!, {r2, r3, ip, lr} @ 447- ldmneia r0!, {r2, r3, ip, lr} @ 448- bne 1b @ 149- ldmfd sp!, {r4, pc} @ 350-51- .align 552-/*53- * ARMv4 optimised clear_user_page54- *55- * Same story as above.56- */57-ENTRY(v4_mc_clear_user_page)58- str lr, [sp, #-4]!59- mov r1, #PAGE_SZ/64 @ 160- mov r2, #0 @ 161- mov r3, #0 @ 162- mov ip, #0 @ 163- mov lr, #0 @ 164-1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line65- stmia r0!, {r2, r3, ip, lr} @ 466- stmia r0!, {r2, r3, ip, lr} @ 467- mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line68- stmia r0!, {r2, r3, ip, lr} @ 469- stmia r0!, {r2, r3, ip, lr} @ 470- subs r1, r1, #1 @ 171- bne 1b @ 172- ldr pc, [sp], #473-74- __INITDATA75-76- .type v4_mc_user_fns, #object77-ENTRY(v4_mc_user_fns)78- .long v4_mc_clear_user_page79- .long v4_mc_copy_user_page80- .size v4_mc_user_fns, . - v4_mc_user_fns
···1+/*2+ * linux/arch/arm/lib/copypage-armv4mc.S3+ *4+ * Copyright (C) 1995-2005 Russell King5+ *6+ * This program is free software; you can redistribute it and/or modify7+ * it under the terms of the GNU General Public License version 2 as8+ * published by the Free Software Foundation.9+ *10+ * This handles the mini data cache, as found on SA11x0 and XScale11+ * processors. When we copy a user page page, we map it in such a way12+ * that accesses to this page will not touch the main data cache, but13+ * will be cached in the mini data cache. This prevents us thrashing14+ * the main data cache on page faults.15+ */16+#include <linux/init.h>17+#include <linux/mm.h>18+19+#include <asm/page.h>20+#include <asm/pgtable.h>21+#include <asm/tlbflush.h>22+23+/*24+ * 0xffff8000 to 0xffffffff is reserved for any ARM architecture25+ * specific hacks for copying pages efficiently.26+ */27+#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \28+ L_PTE_CACHEABLE)29+30+#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)31+32+static DEFINE_SPINLOCK(minicache_lock);33+34+/*35+ * ARMv4 mini-dcache optimised copy_user_page36+ *37+ * We flush the destination cache lines just before we write the data into the38+ * corresponding address. Since the Dcache is read-allocate, this removes the39+ * Dcache aliasing issue. The writes will be forwarded to the write buffer,40+ * and merged as appropriate.41+ *42+ * Note: We rely on all ARMv4 processors implementing the "invalidate D line"43+ * instruction. If your processor does not supply this, you have to write your44+ * own copy_user_page that does the right thing.45+ */46+static void __attribute__((naked))47+mc_copy_user_page(void *from, void *to)48+{49+ asm volatile(50+ "stmfd sp!, {r4, lr} @ 2\n\51+ mov r4, %2 @ 1\n\52+ ldmia %0!, {r2, r3, ip, lr} @ 4\n\53+1: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\54+ stmia %1!, {r2, r3, ip, lr} @ 4\n\55+ ldmia %0!, {r2, r3, ip, lr} @ 4+1\n\56+ stmia %1!, {r2, r3, ip, lr} @ 4\n\57+ ldmia %0!, {r2, r3, ip, lr} @ 4\n\58+ mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\59+ stmia %1!, {r2, r3, ip, lr} @ 4\n\60+ ldmia %0!, {r2, r3, ip, lr} @ 4\n\61+ subs r4, r4, #1 @ 1\n\62+ stmia %1!, {r2, r3, ip, lr} @ 4\n\63+ ldmneia %0!, {r2, r3, ip, lr} @ 4\n\64+ bne 1b @ 1\n\65+ ldmfd sp!, {r4, pc} @ 3"66+ :67+ : "r" (from), "r" (to), "I" (PAGE_SIZE / 64));68+}69+70+void v4_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)71+{72+ spin_lock(&minicache_lock);73+74+ set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));75+ flush_tlb_kernel_page(COPYPAGE_MINICACHE);76+77+ mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);78+79+ spin_unlock(&minicache_lock);80+}81+82+/*83+ * ARMv4 optimised clear_user_page84+ */85+void __attribute__((naked))86+v4_mc_clear_user_page(void *kaddr, unsigned long vaddr)87+{88+ asm volatile(89+ "str lr, [sp, #-4]!\n\90+ mov r1, %0 @ 1\n\91+ mov r2, #0 @ 1\n\92+ mov r3, #0 @ 1\n\93+ mov ip, #0 @ 1\n\94+ mov lr, #0 @ 1\n\95+1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\96+ stmia r0!, {r2, r3, ip, lr} @ 4\n\97+ stmia r0!, {r2, r3, ip, lr} @ 4\n\98+ mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\99+ stmia r0!, {r2, r3, ip, lr} @ 4\n\100+ stmia r0!, {r2, r3, ip, lr} @ 4\n\101+ subs r1, r1, #1 @ 1\n\102+ bne 1b @ 1\n\103+ ldr pc, [sp], #4"104+ :105+ : "I" (PAGE_SIZE / 64));106+}107+108+struct cpu_user_fns v4_mc_user_fns __initdata = {109+ .cpu_clear_user_page = v4_mc_clear_user_page, 110+ .cpu_copy_user_page = v4_mc_copy_user_page,111+};
···1314#include <asm/cacheflush.h>15#include <asm/system.h>000000000000000000000001617static void __flush_dcache_page(struct address_space *mapping, struct page *page)18{···60 return;6162 /*00000000000063 * There are possible user space mappings of this page:64 * - VIVT cache: we need to also write back and invalidate all user65 * data in the current VM view associated with this page.···92 continue;93 offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;94 flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page));95- if (cache_is_vipt())96- break;97 }98 flush_dcache_mmap_unlock(mapping);99}
···1314#include <asm/cacheflush.h>15#include <asm/system.h>16+#include <asm/tlbflush.h>17+18+#ifdef CONFIG_CPU_CACHE_VIPT19+#define ALIAS_FLUSH_START 0xffff400020+21+#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)22+23+static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)24+{25+ unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);26+27+ set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL));28+ flush_tlb_kernel_page(to);29+30+ asm( "mcrr p15, 0, %1, %0, c14\n"31+ " mcrr p15, 0, %1, %0, c5\n"32+ :33+ : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES)34+ : "cc");35+}36+#else37+#define flush_pfn_alias(pfn,vaddr) do { } while (0)38+#endif3940static void __flush_dcache_page(struct address_space *mapping, struct page *page)41{···37 return;3839 /*40+ * This is a page cache page. If we have a VIPT cache, we41+ * only need to do one flush - which would be at the relevant42+ * userspace colour, which is congruent with page->index.43+ */44+ if (cache_is_vipt()) {45+ if (cache_is_vipt_aliasing())46+ flush_pfn_alias(page_to_pfn(page),47+ page->index << PAGE_CACHE_SHIFT);48+ return;49+ }50+51+ /*52 * There are possible user space mappings of this page:53 * - VIVT cache: we need to also write back and invalidate all user54 * data in the current VM view associated with this page.···57 continue;58 offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;59 flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page));0060 }61 flush_dcache_mmap_unlock(mapping);62}
+19-8
arch/arm/mm/mm-armv.c
···3738EXPORT_SYMBOL(pgprot_kernel);390040struct cachepolicy {41 const char policy[16];42 unsigned int cr_mask;···144145#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)1460000000000147/*148 * need to get a 16k page for level 1149 */···232 return;233234 /* pgd is always present and good */235- pmd = (pmd_t *)pgd;236 if (pmd_none(*pmd))237 goto free;238 if (pmd_bad(*pmd)) {···258static inline void259alloc_init_section(unsigned long virt, unsigned long phys, int prot)260{261- pmd_t *pmdp;262263- pmdp = pmd_offset(pgd_offset_k(virt), virt);264 if (virt & (1 << 20))265 pmdp++;266···294static inline void295alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)296{297- pmd_t *pmdp;298 pte_t *ptep;299-300- pmdp = pmd_offset(pgd_offset_k(virt), virt);301302 if (pmd_none(*pmdp)) {303 unsigned long pmdval;···319 */320static inline void clear_mapping(unsigned long virt)321{322- pmd_clear(pmd_offset(pgd_offset_k(virt), virt));323}324325struct mem_types {···587 PMD_TYPE_SECT;588 if (cpu_arch <= CPU_ARCH_ARMv5)589 pmdval |= PMD_BIT4;590- pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);591 pmd[0] = __pmd(pmdval);592 pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));593 flush_pmd_entry(pmd);···684685 flush_cache_all();686 flush_tlb_all();00687}688689/*
···3738EXPORT_SYMBOL(pgprot_kernel);3940+pmd_t *top_pmd;41+42struct cachepolicy {43 const char policy[16];44 unsigned int cr_mask;···142143#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)144145+static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)146+{147+ return pmd_offset(pgd, virt);148+}149+150+static inline pmd_t *pmd_off_k(unsigned long virt)151+{152+ return pmd_off(pgd_offset_k(virt), virt);153+}154+155/*156 * need to get a 16k page for level 1157 */···220 return;221222 /* pgd is always present and good */223+ pmd = pmd_off(pgd, 0);224 if (pmd_none(*pmd))225 goto free;226 if (pmd_bad(*pmd)) {···246static inline void247alloc_init_section(unsigned long virt, unsigned long phys, int prot)248{249+ pmd_t *pmdp = pmd_off_k(virt);2500251 if (virt & (1 << 20))252 pmdp++;253···283static inline void284alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)285{286+ pmd_t *pmdp = pmd_off_k(virt);287 pte_t *ptep;00288289 if (pmd_none(*pmdp)) {290 unsigned long pmdval;···310 */311static inline void clear_mapping(unsigned long virt)312{313+ pmd_clear(pmd_off_k(virt));314}315316struct mem_types {···578 PMD_TYPE_SECT;579 if (cpu_arch <= CPU_ARCH_ARMv5)580 pmdval |= PMD_BIT4;581+ pmd = pmd_off(pgd, i << PGDIR_SHIFT);582 pmd[0] = __pmd(pmdval);583 pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));584 flush_pmd_entry(pmd);···675676 flush_cache_all();677 flush_tlb_all();678+679+ top_pmd = pmd_off_k(VECTORS_HIGH);680}681682/*
···1/* linux/include/asm-arm/arch-s3c2410/regs-nand.h2 *3- * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>4 * http://www.simtec.co.uk/products/SWLINUX/5 *6 * This program is free software; you can redistribute it and/or modify7 * it under the terms of the GNU General Public License version 2 as8 * published by the Free Software Foundation.9 *10- * S3C2410 clock register definitions11 *12 * Changelog:13 * 18-Aug-2004 BJD Copied file from 2.4 and updated014*/1516#ifndef __ASM_ARM_REGS_NAND···27#define S3C2410_NFSTAT S3C2410_NFREG(0x10)28#define S3C2410_NFECC S3C2410_NFREG(0x14)29000000000000000030#define S3C2410_NFCONF_EN (1<<15)31#define S3C2410_NFCONF_512BYTE (1<<14)32#define S3C2410_NFCONF_4STEP (1<<13)···5455#define S3C2410_NFSTAT_BUSY (1<<0)5657-/* think ECC can only be 8bit read? */0000000000000000000005859#endif /* __ASM_ARM_REGS_NAND */60
···1/* linux/include/asm-arm/arch-s3c2410/regs-nand.h2 *3+ * Copyright (c) 2004,2005 Simtec Electronics <linux@simtec.co.uk>4 * http://www.simtec.co.uk/products/SWLINUX/5 *6 * This program is free software; you can redistribute it and/or modify7 * it under the terms of the GNU General Public License version 2 as8 * published by the Free Software Foundation.9 *10+ * S3C2410 NAND register definitions11 *12 * Changelog:13 * 18-Aug-2004 BJD Copied file from 2.4 and updated14+ * 01-May-2005 BJD Added definitions for s3c2440 controller15*/1617#ifndef __ASM_ARM_REGS_NAND···26#define S3C2410_NFSTAT S3C2410_NFREG(0x10)27#define S3C2410_NFECC S3C2410_NFREG(0x14)2829+#define S3C2440_NFCONT S3C2410_NFREG(0x04)30+#define S3C2440_NFCMD S3C2410_NFREG(0x08)31+#define S3C2440_NFADDR S3C2410_NFREG(0x0C)32+#define S3C2440_NFDATA S3C2410_NFREG(0x10)33+#define S3C2440_NFECCD0 S3C2410_NFREG(0x14)34+#define S3C2440_NFECCD1 S3C2410_NFREG(0x18)35+#define S3C2440_NFECCD S3C2410_NFREG(0x1C)36+#define S3C2440_NFSTAT S3C2410_NFREG(0x20)37+#define S3C2440_NFESTAT0 S3C2410_NFREG(0x24)38+#define S3C2440_NFESTAT1 S3C2410_NFREG(0x28)39+#define S3C2440_NFMECC0 S3C2410_NFREG(0x2C)40+#define S3C2440_NFMECC1 S3C2410_NFREG(0x30)41+#define S3C2440_NFSECC S3C2410_NFREG(0x34)42+#define S3C2440_NFSBLK S3C2410_NFREG(0x38)43+#define S3C2440_NFEBLK S3C2410_NFREG(0x3C)44+45#define S3C2410_NFCONF_EN (1<<15)46#define S3C2410_NFCONF_512BYTE (1<<14)47#define S3C2410_NFCONF_4STEP (1<<13)···3738#define S3C2410_NFSTAT_BUSY (1<<0)3940+#define S3C2440_NFCONF_BUSWIDTH_8 (0<<0)41+#define S3C2440_NFCONF_BUSWIDTH_16 (1<<0)42+#define S3C2440_NFCONF_ADVFLASH (1<<3)43+#define S3C2440_NFCONF_TACLS(x) ((x)<<12)44+#define S3C2440_NFCONF_TWRPH0(x) ((x)<<8)45+#define S3C2440_NFCONF_TWRPH1(x) ((x)<<4)46+47+#define S3C2440_NFCONT_LOCKTIGHT (1<<13)48+#define S3C2440_NFCONT_SOFTLOCK (1<<12)49+#define S3C2440_NFCONT_ILLEGALACC_EN (1<<10)50+#define S3C2440_NFCONT_RNBINT_EN (1<<9)51+#define S3C2440_NFCONT_RN_FALLING (1<<8)52+#define S3C2440_NFCONT_SPARE_ECCLOCK (1<<6)53+#define S3C2440_NFCONT_MAIN_ECCLOCK (1<<5)54+#define S3C2440_NFCONT_INITECC (1<<4)55+#define S3C2440_NFCONT_nFCE (1<<1)56+#define S3C2440_NFCONT_ENABLE (1<<0)57+58+#define S3C2440_NFSTAT_READY (1<<0)59+#define S3C2440_NFSTAT_nCE (1<<1)60+#define S3C2440_NFSTAT_RnB_CHANGE (1<<2)61+#define S3C2440_NFSTAT_ILLEGAL_ACCESS (1<<3)6263#endif /* __ASM_ARM_REGS_NAND */64
+5-13
include/asm-arm/page.h
···114 unsigned long user);115#endif116117-#define clear_user_page(addr,vaddr,pg) \118- do { \119- preempt_disable(); \120- __cpu_clear_user_page(addr, vaddr); \121- preempt_enable(); \122- } while (0)123-124-#define copy_user_page(to,from,vaddr,pg) \125- do { \126- preempt_disable(); \127- __cpu_copy_user_page(to, from, vaddr); \128- preempt_enable(); \129- } while (0)130131#define clear_page(page) memzero((void *)(page), PAGE_SIZE)132extern void copy_page(void *to, const void *from);···159#define __pgprot(x) (x)160161#endif /* STRICT_MM_TYPECHECKS */000162163/* Pure 2^n version of get_order */164static inline int get_order(unsigned long size)
···114 unsigned long user);115#endif116117+#define clear_user_page(addr,vaddr,pg) __cpu_clear_user_page(addr, vaddr)118+#define copy_user_page(to,from,vaddr,pg) __cpu_copy_user_page(to, from, vaddr)00000000000119120#define clear_page(page) memzero((void *)(page), PAGE_SIZE)121extern void copy_page(void *to, const void *from);···170#define __pgprot(x) (x)171172#endif /* STRICT_MM_TYPECHECKS */173+174+/* the upper-most page table pointer */175+extern pmd_t *top_pmd;176177/* Pure 2^n version of get_order */178static inline int get_order(unsigned long size)