diff options
Diffstat (limited to 'arch/sh/mm')
-rw-r--r-- | arch/sh/mm/Kconfig | 233 | ||||
-rw-r--r-- | arch/sh/mm/ioremap.c | 99 |
2 files changed, 314 insertions, 18 deletions
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig new file mode 100644 index 00000000000..fb586b1cf8b --- /dev/null +++ b/arch/sh/mm/Kconfig @@ -0,0 +1,233 @@ +menu "Processor selection" + +# +# Processor families +# +config CPU_SH2 + bool + select SH_WRITETHROUGH + +config CPU_SH3 + bool + select CPU_HAS_INTEVT + select CPU_HAS_SR_RB + +config CPU_SH4 + bool + select CPU_HAS_INTEVT + select CPU_HAS_SR_RB + +config CPU_SH4A + bool + select CPU_SH4 + select CPU_HAS_INTC2_IRQ + +config CPU_SUBTYPE_ST40 + bool + select CPU_SH4 + select CPU_HAS_INTC2_IRQ + +# +# Processor subtypes +# + +comment "SH-2 Processor Support" + +config CPU_SUBTYPE_SH7604 + bool "Support SH7604 processor" + select CPU_SH2 + +comment "SH-3 Processor Support" + +config CPU_SUBTYPE_SH7300 + bool "Support SH7300 processor" + select CPU_SH3 + +config CPU_SUBTYPE_SH7705 + bool "Support SH7705 processor" + select CPU_SH3 + select CPU_HAS_PINT_IRQ + +config CPU_SUBTYPE_SH7707 + bool "Support SH7707 processor" + select CPU_SH3 + select CPU_HAS_PINT_IRQ + help + Select SH7707 if you have a 60 Mhz SH-3 HD6417707 CPU. + +config CPU_SUBTYPE_SH7708 + bool "Support SH7708 processor" + select CPU_SH3 + help + Select SH7708 if you have a 60 Mhz SH-3 HD6417708S or + if you have a 100 Mhz SH-3 HD6417708R CPU. + +config CPU_SUBTYPE_SH7709 + bool "Support SH7709 processor" + select CPU_SH3 + select CPU_HAS_PINT_IRQ + help + Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU. + +comment "SH-4 Processor Support" + +config CPU_SUBTYPE_SH7750 + bool "Support SH7750 processor" + select CPU_SH4 + help + Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. + +config CPU_SUBTYPE_SH7091 + bool "Support SH7091 processor" + select CPU_SH4 + select CPU_SUBTYPE_SH7750 + help + Select SH7091 if you have an SH-4 based Sega device (such as + the Dreamcast, Naomi, and Naomi 2). + +config CPU_SUBTYPE_SH7750R + bool "Support SH7750R processor" + select CPU_SH4 + select CPU_SUBTYPE_SH7750 + +config CPU_SUBTYPE_SH7750S + bool "Support SH7750S processor" + select CPU_SH4 + select CPU_SUBTYPE_SH7750 + +config CPU_SUBTYPE_SH7751 + bool "Support SH7751 processor" + select CPU_SH4 + help + Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU, + or if you have a HD6417751R CPU. + +config CPU_SUBTYPE_SH7751R + bool "Support SH7751R processor" + select CPU_SH4 + select CPU_SUBTYPE_SH7751 + +config CPU_SUBTYPE_SH7760 + bool "Support SH7760 processor" + select CPU_SH4 + select CPU_HAS_INTC2_IRQ + +config CPU_SUBTYPE_SH4_202 + bool "Support SH4-202 processor" + select CPU_SH4 + +comment "ST40 Processor Support" + +config CPU_SUBTYPE_ST40STB1 + bool "Support ST40STB1/ST40RA processors" + select CPU_SUBTYPE_ST40 + help + Select ST40STB1 if you have a ST40RA CPU. + This was previously called the ST40STB1, hence the option name. + +config CPU_SUBTYPE_ST40GX1 + bool "Support ST40GX1 processor" + select CPU_SUBTYPE_ST40 + help + Select ST40GX1 if you have a ST40GX1 CPU. + +comment "SH-4A Processor Support" + +config CPU_SUBTYPE_SH73180 + bool "Support SH73180 processor" + select CPU_SH4A + +config CPU_SUBTYPE_SH7770 + bool "Support SH7770 processor" + select CPU_SH4A + +config CPU_SUBTYPE_SH7780 + bool "Support SH7780 processor" + select CPU_SH4A + +endmenu + +menu "Memory management options" + +config MMU + bool "Support for memory management hardware" + depends on !CPU_SH2 + default y + help + Some SH processors (such as SH-2/SH-2A) lack an MMU. In order to + boot on these systems, this option must not be set. + + On other systems (such as the SH-3 and 4) where an MMU exists, + turning this off will boot the kernel on these machines with the + MMU implicitly switched off. + +config 32BIT + bool "Support 32-bit physical addressing through PMB" + depends on CPU_SH4A + default y + help + If you say Y here, physical addressing will be extended to + 32-bits through the SH-4A PMB. If this is not set, legacy + 29-bit physical addressing will be used. + +choice + prompt "HugeTLB page size" + depends on HUGETLB_PAGE && CPU_SH4 && MMU + default HUGETLB_PAGE_SIZE_64K + +config HUGETLB_PAGE_SIZE_64K + bool "64K" + +config HUGETLB_PAGE_SIZE_1MB + bool "1MB" + +endchoice + +source "mm/Kconfig" + +endmenu + +menu "Cache configuration" + +config SH7705_CACHE_32KB + bool "Enable 32KB cache size for SH7705" + depends on CPU_SUBTYPE_SH7705 + default y + +config SH_DIRECT_MAPPED + bool "Use direct-mapped caching" + default n + help + Selecting this option will configure the caches to be direct-mapped, + even if the cache supports a 2 or 4-way mode. This is useful primarily + for debugging on platforms with 2 and 4-way caches (SH7750R/SH7751R, + SH4-202, SH4-501, etc.) + + Turn this option off for platforms that do not have a direct-mapped + cache, and you have no need to run the caches in such a configuration. + +config SH_WRITETHROUGH + bool "Use write-through caching" + default y if CPU_SH2 + help + Selecting this option will configure the caches in write-through + mode, as opposed to the default write-back configuration. + + Since there's sill some aliasing issues on SH-4, this option will + unfortunately still require the majority of flushing functions to + be implemented to deal with aliasing. + + If unsure, say N. + +config SH_OCRAM + bool "Operand Cache RAM (OCRAM) support" + help + Selecting this option will automatically tear down the number of + sets in the dcache by half, which in turn exposes a memory range. + + The addresses for the OC RAM base will vary according to the + processor version. Consult vendor documentation for specifics. + + If unsure, say N. + +endmenu diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index e794e27a72f..96fa4a999e2 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c @@ -6,13 +6,19 @@ * 640k-1MB IO memory area on PC's * * (C) Copyright 1995 1996 Linus Torvalds + * (C) Copyright 2005, 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file "COPYING" in the main directory of this + * archive for more details. */ - #include <linux/vmalloc.h> +#include <linux/module.h> #include <linux/mm.h> #include <asm/io.h> #include <asm/page.h> #include <asm/pgalloc.h> +#include <asm/addrspace.h> #include <asm/cacheflush.h> #include <asm/tlbflush.h> @@ -80,9 +86,15 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr, if (address >= end) BUG(); do { + pud_t *pud; pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + error = -ENOMEM; + + pud = pud_alloc(&init_mm, dir, address); + if (!pud) + break; + pmd = pmd_alloc(&init_mm, pud, address); if (!pmd) break; if (remap_area_pmd(pmd, address, end - address, @@ -97,10 +109,6 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr, } /* - * Generic mapping function (not visible outside): - */ - -/* * Remap an arbitrary physical address space into the kernel virtual * address space. Needed when the kernel wants to access high addresses * directly. @@ -109,11 +117,11 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr, * have to convert them into an offset in a page-aligned mapping, but the * caller shouldn't need to know that small detail. */ -void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) +void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, + unsigned long flags) { - void * addr; struct vm_struct * area; - unsigned long offset, last_addr; + unsigned long offset, last_addr, addr, orig_addr; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -124,7 +132,7 @@ void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long fla * Don't remap the low PCI/ISA area, it's always mapped.. */ if (phys_addr >= 0xA0000 && last_addr < 0x100000) - return phys_to_virt(phys_addr); + return (void __iomem *)phys_to_virt(phys_addr); /* * Don't allow anybody to remap normal RAM that we're using.. @@ -146,16 +154,71 @@ void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long fla if (!area) return NULL; area->phys_addr = phys_addr; - addr = area->addr; - if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { - vunmap(addr); - return NULL; + orig_addr = addr = (unsigned long)area->addr; + +#ifdef CONFIG_32BIT + /* + * First try to remap through the PMB once a valid VMA has been + * established. Smaller allocations (or the rest of the size + * remaining after a PMB mapping due to the size not being + * perfectly aligned on a PMB size boundary) are then mapped + * through the UTLB using conventional page tables. + * + * PMB entries are all pre-faulted. + */ + if (unlikely(size >= 0x1000000)) { + unsigned long mapped = pmb_remap(addr, phys_addr, size, flags); + + if (likely(mapped)) { + addr += mapped; + phys_addr += mapped; + size -= mapped; + } } - return (void *) (offset + (char *)addr); +#endif + + if (likely(size)) + if (remap_area_pages(addr, phys_addr, size, flags)) { + vunmap((void *)orig_addr); + return NULL; + } + + return (void __iomem *)(offset + (char *)orig_addr); } +EXPORT_SYMBOL(__ioremap); -void p3_iounmap(void *addr) +void __iounmap(void __iomem *addr) { - if (addr > high_memory) - vfree((void *)(PAGE_MASK & (unsigned long)addr)); + unsigned long vaddr = (unsigned long __force)addr; + struct vm_struct *p; + + if (PXSEG(vaddr) < P3SEG) + return; + +#ifdef CONFIG_32BIT + /* + * Purge any PMB entries that may have been established for this + * mapping, then proceed with conventional VMA teardown. + * + * XXX: Note that due to the way that remove_vm_area() does + * matching of the resultant VMA, we aren't able to fast-forward + * the address past the PMB space until the end of the VMA where + * the page tables reside. As such, unmap_vm_area() will be + * forced to linearly scan over the area until it finds the page + * tables where PTEs that need to be unmapped actually reside, + * which is far from optimal. Perhaps we need to use a separate + * VMA for the PMB mappings? + * -- PFM. + */ + pmb_unmap(vaddr); +#endif + + p = remove_vm_area((void *)(vaddr & PAGE_MASK)); + if (!p) { + printk(KERN_ERR "%s: bad address %p\n", __FUNCTION__, addr); + return; + } + + kfree(p); } +EXPORT_SYMBOL(__iounmap); |