/* * linux/include/asm-arm/cpu-multi32.h * * Copyright (C) 2000 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. */ #ifndef __ASSEMBLY__ #include #include /* forward-declare task_struct */ struct task_struct; /* * Don't change this structure - ASM code * relies on it. */ extern struct processor { /* MISC * get data abort address/flags */ void (*_data_abort)(unsigned long pc); /* * check for any bugs */ void (*_check_bugs)(void); /* * Set up any processor specifics */ void (*_proc_init)(void); /* * Disable any processor specifics */ void (*_proc_fin)(void); /* * Special stuff for a reset */ volatile void (*reset)(unsigned long addr); /* * Idle the processor */ int (*_do_idle)(int mode); /* * Processor architecture specific */ struct { /* CACHE */ /* * flush all caches */ void (*clean_invalidate_all)(void); /* * flush a specific page or pages */ void (*clean_invalidate_range)(unsigned long address, unsigned long end, int flags); /* * flush a page to RAM */ void (*_flush_ram_page)(void *virt_page); } cache; struct { /* D-cache */ /* * invalidate the specified data range */ void (*invalidate_range)(unsigned long start, unsigned long end); /* * clean specified data range */ void (*clean_range)(unsigned long start, unsigned long end); /* * obsolete flush cache entry */ void (*clean_page)(void *virt_page); /* * clean a virtual address range from the * D-cache without flushing the cache. */ void (*clean_entry)(unsigned long start); } dcache; struct { /* I-cache */ /* * invalidate the I-cache for the specified range */ void (*invalidate_range)(unsigned long start, unsigned long end); /* * invalidate the I-cache for the specified virtual page */ void (*invalidate_page)(void *virt_page); } icache; struct { /* TLB */ /* * flush all TLBs */ void (*invalidate_all)(void); /* * flush a specific TLB */ void (*invalidate_range)(unsigned long address, unsigned long end); /* * flush a specific TLB */ void (*invalidate_page)(unsigned long address, int flags); } tlb; struct { /* PageTable */ /* * Set the page table */ void (*set_pgd)(unsigned long pgd_phys); /* * Set a PMD (handling IMP bit 4) */ void (*set_pmd)(pmd_t *pmdp, pmd_t pmd); /* * Set a PTE */ void (*set_pte)(pte_t *ptep, pte_t pte); } pgtable; } processor; extern const struct processor arm6_processor_functions; extern const struct processor arm7_processor_functions; extern const struct processor sa110_processor_functions; #define cpu_data_abort(pc) processor._data_abort(pc) #define cpu_check_bugs() processor._check_bugs() #define cpu_proc_init() processor._proc_init() #define cpu_proc_fin() processor._proc_fin() #define cpu_reset(addr) processor.reset(addr) #define cpu_do_idle(mode) processor._do_idle(mode) #define cpu_cache_clean_invalidate_all() processor.cache.clean_invalidate_all() #define cpu_cache_clean_invalidate_range(s,e,f) processor.cache.clean_invalidate_range(s,e,f) #define cpu_flush_ram_page(vp) processor.cache._flush_ram_page(vp) #define cpu_dcache_clean_page(vp) processor.dcache.clean_page(vp) #define cpu_dcache_clean_entry(addr) processor.dcache.clean_entry(addr) #define cpu_dcache_clean_range(s,e) processor.dcache.clean_range(s,e) #define cpu_dcache_invalidate_range(s,e) processor.dcache.invalidate_range(s,e) #define cpu_icache_invalidate_range(s,e) processor.icache.invalidate_range(s,e) #define cpu_icache_invalidate_page(vp) processor.icache.invalidate_page(vp) #define cpu_tlb_invalidate_all() processor.tlb.invalidate_all() #define cpu_tlb_invalidate_range(s,e) processor.tlb.invalidate_range(s,e) #define cpu_tlb_invalidate_page(vp,f) processor.tlb.invalidate_page(vp,f) #define cpu_set_pgd(pgd) processor.pgtable.set_pgd(pgd) #define cpu_set_pmd(pmdp, pmd) processor.pgtable.set_pmd(pmdp, pmd) #define cpu_set_pte(ptep, pte) processor.pgtable.set_pte(ptep, pte) #define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd))) #define cpu_get_pgd() \ ({ \ unsigned long pg; \ __asm__("mrc p15, 0, %0, c2, c0, 0" \ : "=r" (pg)); \ pg &= ~0x3fff; \ (pgd_t *)phys_to_virt(pg); \ }) #endif