diff options
Diffstat (limited to 'arch/m32r/mm')
| -rw-r--r-- | arch/m32r/mm/discontig.c | 37 | ||||
| -rw-r--r-- | arch/m32r/mm/fault-nommu.c | 33 | ||||
| -rw-r--r-- | arch/m32r/mm/fault.c | 121 | ||||
| -rw-r--r-- | arch/m32r/mm/init.c | 135 | ||||
| -rw-r--r-- | arch/m32r/mm/mmu.S | 37 |
5 files changed, 96 insertions, 267 deletions
diff --git a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c index c7efdb0aefc..27196303ce3 100644 --- a/arch/m32r/mm/discontig.c +++ b/arch/m32r/mm/discontig.c @@ -20,7 +20,6 @@ extern char _end[]; struct pglist_data *node_data[MAX_NUMNODES]; EXPORT_SYMBOL(node_data); -static bootmem_data_t node_bdata[MAX_NUMNODES] __initdata; pg_data_t m32r_node_data[MAX_NUMNODES]; @@ -33,6 +32,9 @@ typedef struct { } mem_prof_t; static mem_prof_t mem_prof[MAX_NUMNODES]; +extern unsigned long memory_start; +extern unsigned long memory_end; + static void __init mem_prof_init(void) { unsigned long start_pfn, holes, free_pfn; @@ -43,7 +45,7 @@ static void __init mem_prof_init(void) /* Node#0 SDRAM */ mp = &mem_prof[0]; mp->start_pfn = PFN_UP(CONFIG_MEMORY_START); - mp->pages = PFN_DOWN(CONFIG_MEMORY_SIZE); + mp->pages = PFN_DOWN(memory_end - memory_start); mp->holes = 0; mp->free_pfn = PFN_UP(__pa(_end)); @@ -81,7 +83,7 @@ unsigned long __init setup_memory(void) for_each_online_node(nid) { mp = &mem_prof[nid]; NODE_DATA(nid)=(pg_data_t *)&m32r_node_data[nid]; - NODE_DATA(nid)->bdata = &node_bdata[nid]; + NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; min_pfn = mp->start_pfn; max_pfn = mp->start_pfn + mp->pages; bootmap_size = init_bootmem_node(NODE_DATA(nid), mp->free_pfn, @@ -91,7 +93,8 @@ unsigned long __init setup_memory(void) PFN_PHYS(mp->pages)); reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(mp->start_pfn), - PFN_PHYS(mp->free_pfn - mp->start_pfn) + bootmap_size); + PFN_PHYS(mp->free_pfn - mp->start_pfn) + bootmap_size, + BOOTMEM_DEFAULT); if (max_low_pfn < max_pfn) max_low_pfn = max_pfn; @@ -104,16 +107,16 @@ unsigned long __init setup_memory(void) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) { reserve_bootmem_node(NODE_DATA(0), INITRD_START, - INITRD_SIZE); + INITRD_SIZE, BOOTMEM_DEFAULT); initrd_start = INITRD_START + PAGE_OFFSET; initrd_end = initrd_start + INITRD_SIZE; printk("initrd:start[%08lx],size[%08lx]\n", initrd_start, INITRD_SIZE); } else { printk("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx)\ndisabling initrd\n", + "(0x%08lx > 0x%08llx)\ndisabling initrd\n", INITRD_START + INITRD_SIZE, - PFN_PHYS(max_low_pfn)); + (unsigned long long)PFN_PHYS(max_low_pfn)); initrd_start = 0; } @@ -123,15 +126,13 @@ unsigned long __init setup_memory(void) return max_low_pfn; } -#define START_PFN(nid) \ - (NODE_DATA(nid)->bdata->node_boot_start >> PAGE_SHIFT) +#define START_PFN(nid) (NODE_DATA(nid)->bdata->node_min_pfn) #define MAX_LOW_PFN(nid) (NODE_DATA(nid)->bdata->node_low_pfn) -unsigned long __init zone_sizes_init(void) +void __init zone_sizes_init(void) { unsigned long zones_size[MAX_NR_ZONES], zholes_size[MAX_NR_ZONES]; unsigned long low, start_pfn; - unsigned long holes = 0; int nid, i; mem_prof_t *mp; @@ -145,10 +146,9 @@ unsigned long __init zone_sizes_init(void) low = MAX_LOW_PFN(nid); zones_size[ZONE_DMA] = low - start_pfn; zholes_size[ZONE_DMA] = mp->holes; - holes += zholes_size[ZONE_DMA]; - free_area_init_node(nid, NODE_DATA(nid), zones_size, - start_pfn, zholes_size); + node_set_state(nid, N_NORMAL_MEMORY); + free_area_init_node(nid, zones_size, start_pfn, zholes_size); } /* @@ -156,10 +156,7 @@ unsigned long __init zone_sizes_init(void) * Use all area of internal RAM. * see __alloc_pages() */ - NODE_DATA(1)->node_zones->pages_min = 0; - NODE_DATA(1)->node_zones->pages_low = 0; - NODE_DATA(1)->node_zones->pages_high = 0; - - return holes; + NODE_DATA(1)->node_zones->watermark[WMARK_MIN] = 0; + NODE_DATA(1)->node_zones->watermark[WMARK_LOW] = 0; + NODE_DATA(1)->node_zones->watermark[WMARK_HIGH] = 0; } - diff --git a/arch/m32r/mm/fault-nommu.c b/arch/m32r/mm/fault-nommu.c index 03fc4c858e0..80f18cc6f54 100644 --- a/arch/m32r/mm/fault-nommu.c +++ b/arch/m32r/mm/fault-nommu.c @@ -7,8 +7,6 @@ * Copyright (C) 1995 Linus Torvalds */ -/* $Id: fault-nommu.c,v 1.1 2004/03/30 06:40:59 sakugawa Exp $ */ - #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -19,13 +17,11 @@ #include <linux/mman.h> #include <linux/mm.h> #include <linux/smp.h> -#include <linux/smp_lock.h> #include <linux/interrupt.h> #include <linux/init.h> #include <linux/vt_kern.h> /* For unblank_screen() */ #include <asm/m32r.h> -#include <asm/system.h> #include <asm/uaccess.h> #include <asm/pgalloc.h> #include <asm/pgtable.h> @@ -46,32 +42,6 @@ unsigned int tlb_entry_d_dat[NR_CPUS]; #define tlb_entry_d tlb_entry_d_dat[smp_processor_id()] #endif -/* - * Unlock any spinlocks which will prevent us from getting the - * message out - */ -void bust_spinlocks(int yes) -{ - int loglevel_save = console_loglevel; - - if (yes) { - oops_in_progress = 1; - return; - } -#ifdef CONFIG_VT - unblank_screen(); -#endif - oops_in_progress = 0; - /* - * OK, the message is on the console. Now we call printk() - * without oops_in_progress set so that printk will give klogd - * a poke. Hold onto your hats... - */ - console_loglevel = 15; /* NMI oopser may have shut the console up */ - printk(" "); - console_loglevel = loglevel_save; -} - void do_BUG(const char *file, int line) { bust_spinlocks(1); @@ -124,7 +94,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, * update_mmu_cache() *======================================================================*/ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, - pte_t pte) + pte_t *ptep) { BUG(); } @@ -161,4 +131,3 @@ void local_flush_tlb_all(void) { BUG(); } - diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c index 9b9feb0f161..e9c6a8014bd 100644 --- a/arch/m32r/mm/fault.c +++ b/arch/m32r/mm/fault.c @@ -18,7 +18,6 @@ #include <linux/mman.h> #include <linux/mm.h> #include <linux/smp.h> -#include <linux/smp_lock.h> #include <linux/interrupt.h> #include <linux/init.h> #include <linux/tty.h> @@ -27,7 +26,6 @@ #include <linux/module.h> #include <asm/m32r.h> -#include <asm/system.h> #include <asm/uaccess.h> #include <asm/hardirq.h> #include <asm/mmu_context.h> @@ -49,32 +47,6 @@ unsigned int tlb_entry_d_dat[NR_CPUS]; extern void init_tlb(void); -/* - * Unlock any spinlocks which will prevent us from getting the - * message out - */ -void bust_spinlocks(int yes) -{ - int loglevel_save = console_loglevel; - - if (yes) { - oops_in_progress = 1; - return; - } -#ifdef CONFIG_VT - unblank_screen(); -#endif - oops_in_progress = 0; - /* - * OK, the message is on the console. Now we call printk() - * without oops_in_progress set so that printk will give klogd - * a poke. Hold onto your hats... - */ - console_loglevel = 15; /* NMI oopser may have shut the console up */ - printk(" "); - console_loglevel = loglevel_save; -} - /*======================================================================* * do_page_fault() *======================================================================* @@ -106,7 +78,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, struct mm_struct *mm; struct vm_area_struct * vma; unsigned long page, addr; - int write; + unsigned long flags = 0; + int fault; siginfo_t info; /* @@ -144,9 +117,12 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, if (in_atomic() || !mm) goto bad_area_nosemaphore; + if (error_code & ACE_USERMODE) + flags |= FAULT_FLAG_USER; + /* When running in the kernel we expect faults to occur only to * addresses in user space. All other faults represent errors in the - * kernel and should generate an OOPS. Unfortunatly, in the case of an + * kernel and should generate an OOPS. Unfortunately, in the case of an * erroneous fault occurring in a code path which already holds mmap_sem * we will deadlock attempting to validate the fault against the * address space. Luckily the kernel only validly references user @@ -154,7 +130,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, * exceptions table. * * As the vast majority of faults will be valid we will only perform - * the source reference check when there is a possibilty of a deadlock. + * the source reference check when there is a possibility of a deadlock. * Attempt to lock the address space, if we cannot we then validate the * source. If this is invalid we can skip the address space check, * thus avoiding the deadlock. @@ -193,14 +169,13 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, */ good_area: info.si_code = SEGV_ACCERR; - write = 0; switch (error_code & (ACE_WRITE|ACE_PROTECTION)) { default: /* 3: write, present */ /* fall through */ case ACE_WRITE: /* write, not present */ if (!(vma->vm_flags & VM_WRITE)) goto bad_area; - write++; + flags |= FAULT_FLAG_WRITE; break; case ACE_PROTECTION: /* read, present */ case 0: /* read, not present */ @@ -214,7 +189,6 @@ good_area: if ((error_code & ACE_INSTRUCTION) && !(vma->vm_flags & VM_EXEC)) goto bad_area; -survive: /* * If for any reason at all we couldn't handle the fault, * make sure we exit gracefully rather than endlessly redo @@ -222,20 +196,18 @@ survive: */ addr = (address & PAGE_MASK); set_thread_fault_code(error_code); - switch (handle_mm_fault(mm, vma, addr, write)) { - case VM_FAULT_MINOR: - tsk->min_flt++; - break; - case VM_FAULT_MAJOR: - tsk->maj_flt++; - break; - case VM_FAULT_SIGBUS: - goto do_sigbus; - case VM_FAULT_OOM: + fault = handle_mm_fault(mm, vma, addr, flags); + if (unlikely(fault & VM_FAULT_ERROR)) { + if (fault & VM_FAULT_OOM) goto out_of_memory; - default: - BUG(); + else if (fault & VM_FAULT_SIGBUS) + goto do_sigbus; + BUG(); } + if (fault & VM_FAULT_MAJOR) + tsk->maj_flt++; + else + tsk->min_flt++; set_thread_fault_code(0); up_read(&mm->mmap_sem); return; @@ -299,15 +271,10 @@ no_context: */ out_of_memory: up_read(&mm->mmap_sem); - if (is_init(tsk)) { - yield(); - down_read(&mm->mmap_sem); - goto survive; - } - printk("VM: killing process %s\n", tsk->comm); - if (error_code & ACE_USERMODE) - do_exit(SIGKILL); - goto no_context; + if (!(error_code & ACE_USERMODE)) + goto no_context; + pagefault_out_of_memory(); + return; do_sigbus: up_read(&mm->mmap_sem); @@ -362,8 +329,10 @@ vmalloc_fault: if (!pte_present(*pte_k)) goto no_context; - addr = (address & PAGE_MASK) | (error_code & ACE_INSTRUCTION); - update_mmu_cache(NULL, addr, *pte_k); + addr = (address & PAGE_MASK); + set_thread_fault_code(error_code); + update_mmu_cache(NULL, addr, pte_k); + set_thread_fault_code(0); return; } } @@ -375,9 +344,9 @@ vmalloc_fault: #define ITLB_END (unsigned long *)(ITLB_BASE + (NR_TLB_ENTRIES * 8)) #define DTLB_END (unsigned long *)(DTLB_BASE + (NR_TLB_ENTRIES * 8)) void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr, - pte_t pte) + pte_t *ptep) { - unsigned long *entry1, *entry2; + volatile unsigned long *entry1, *entry2; unsigned long pte_data, flags; unsigned int *entry_dat; int inst = get_thread_fault_code() & ACE_INSTRUCTION; @@ -391,30 +360,26 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr, vaddr = (vaddr & PAGE_MASK) | get_asid(); + pte_data = pte_val(*ptep); + #ifdef CONFIG_CHIP_OPSP entry1 = (unsigned long *)ITLB_BASE; - for(i = 0 ; i < NR_TLB_ENTRIES; i++) { - if(*entry1++ == vaddr) { - pte_data = pte_val(pte); - set_tlb_data(entry1, pte_data); - break; - } - entry1++; + for (i = 0; i < NR_TLB_ENTRIES; i++) { + if (*entry1++ == vaddr) { + set_tlb_data(entry1, pte_data); + break; + } + entry1++; } entry2 = (unsigned long *)DTLB_BASE; - for(i = 0 ; i < NR_TLB_ENTRIES ; i++) { - if(*entry2++ == vaddr) { - pte_data = pte_val(pte); - set_tlb_data(entry2, pte_data); - break; - } - entry2++; + for (i = 0; i < NR_TLB_ENTRIES; i++) { + if (*entry2++ == vaddr) { + set_tlb_data(entry2, pte_data); + break; + } + entry2++; } - local_irq_restore(flags); - return; #else - pte_data = pte_val(pte); - /* * Update TLB entries * entry1: ITLB entry address @@ -439,6 +404,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr, "i" (MSVA_offset), "i" (MTOP_offset), "i" (MIDXI_offset) : "r4", "memory" ); +#endif if ((!inst && entry2 >= DTLB_END) || (inst && entry1 >= ITLB_END)) goto notfound; @@ -482,7 +448,6 @@ notfound: set_tlb_data(entry1, pte_data); goto found; -#endif } /*======================================================================* diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c index bbd97c85bc5..0d4146f644d 100644 --- a/arch/m32r/mm/init.c +++ b/arch/m32r/mm/init.c @@ -19,6 +19,7 @@ #include <linux/bitops.h> #include <linux/nodemask.h> #include <linux/pfn.h> +#include <linux/gfp.h> #include <asm/types.h> #include <asm/processor.h> #include <asm/page.h> @@ -27,51 +28,10 @@ #include <asm/mmu_context.h> #include <asm/setup.h> #include <asm/tlb.h> - -/* References to section boundaries */ -extern char _text, _etext, _edata; -extern char __init_begin, __init_end; +#include <asm/sections.h> pgd_t swapper_pg_dir[1024]; -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); - -void show_mem(void) -{ - int total = 0, reserved = 0; - int shared = 0, cached = 0; - int highmem = 0; - struct page *page; - pg_data_t *pgdat; - unsigned long i; - - printk("Mem-info:\n"); - show_free_areas(); - printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); - for_each_online_pgdat(pgdat) { - unsigned long flags; - pgdat_resize_lock(pgdat, &flags); - for (i = 0; i < pgdat->node_spanned_pages; ++i) { - page = pgdat_page_nr(pgdat, i); - total++; - if (PageHighMem(page)) - highmem++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (page_count(page)) - shared += page_count(page) - 1; - } - pgdat_resize_unlock(pgdat, &flags); - } - printk("%d pages of RAM\n", total); - printk("%d pages of HIGHMEM\n",highmem); - printk("%d reserved pages\n",reserved); - printk("%d pages shared\n",shared); - printk("%d pages swap cached\n",cached); -} - /* * Cache of MMU context last used. */ @@ -80,7 +40,6 @@ unsigned long mmu_context_cache_dat; #else unsigned long mmu_context_cache_dat[NR_CPUS]; #endif -static unsigned long hole_pages; /* * function prototype @@ -93,12 +52,11 @@ void free_initrd_mem(unsigned long, unsigned long); #endif /* It'd be good if these lines were in the standard header file. */ -#define START_PFN(nid) \ - (NODE_DATA(nid)->bdata->node_boot_start >> PAGE_SHIFT) +#define START_PFN(nid) (NODE_DATA(nid)->bdata->node_min_pfn) #define MAX_LOW_PFN(nid) (NODE_DATA(nid)->bdata->node_low_pfn) #ifndef CONFIG_DISCONTIGMEM -unsigned long __init zone_sizes_init(void) +void __init zone_sizes_init(void) { unsigned long zones_size[MAX_NR_ZONES] = {0, }; unsigned long max_dma; @@ -123,12 +81,10 @@ unsigned long __init zone_sizes_init(void) start_pfn = __MEMORY_START >> PAGE_SHIFT; #endif /* CONFIG_MMU */ - free_area_init_node(0, NODE_DATA(0), zones_size, start_pfn, 0); - - return 0; + free_area_init_node(0, zones_size, start_pfn, 0); } #else /* CONFIG_DISCONTIGMEM */ -extern unsigned long zone_sizes_init(void); +extern void zone_sizes_init(void); #endif /* CONFIG_DISCONTIGMEM */ /*======================================================================* @@ -146,24 +102,7 @@ void __init paging_init(void) for (i = 0 ; i < USER_PTRS_PER_PGD * 2 ; i++) pgd_val(pg_dir[i]) = 0; #endif /* CONFIG_MMU */ - hole_pages = zone_sizes_init(); -} - -int __init reservedpages_count(void) -{ - int reservedpages, nid, i; - - reservedpages = 0; - for_each_online_node(nid) { - unsigned long flags; - pgdat_resize_lock(NODE_DATA(nid), &flags); - for (i = 0 ; i < MAX_LOW_PFN(nid) - START_PFN(nid) ; i++) - if (PageReserved(nid_page_nr(nid, i))) - reservedpages++; - pgdat_resize_unlock(NODE_DATA(nid), &flags); - } - - return reservedpages; + zone_sizes_init(); } /*======================================================================* @@ -172,48 +111,20 @@ int __init reservedpages_count(void) *======================================================================*/ void __init mem_init(void) { - int codesize, reservedpages, datasize, initsize; - int nid; #ifndef CONFIG_MMU extern unsigned long memory_end; -#endif - num_physpages = 0; - for_each_online_node(nid) - num_physpages += MAX_LOW_PFN(nid) - START_PFN(nid) + 1; - - num_physpages -= hole_pages; - -#ifndef CONFIG_DISCONTIGMEM - max_mapnr = num_physpages; -#endif /* CONFIG_DISCONTIGMEM */ - -#ifdef CONFIG_MMU - high_memory = (void *)__va(PFN_PHYS(MAX_LOW_PFN(0))); -#else high_memory = (void *)(memory_end & PAGE_MASK); +#else + high_memory = (void *)__va(PFN_PHYS(MAX_LOW_PFN(0))); #endif /* CONFIG_MMU */ /* clear the zero-page */ memset(empty_zero_page, 0, PAGE_SIZE); - /* this will put all low memory onto the freelists */ - for_each_online_node(nid) - totalram_pages += free_all_bootmem_node(NODE_DATA(nid)); - - reservedpages = reservedpages_count() - hole_pages; - codesize = (unsigned long) &_etext - (unsigned long)&_text; - datasize = (unsigned long) &_edata - (unsigned long)&_etext; - initsize = (unsigned long) &__init_end - (unsigned long)&__init_begin; - - printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, " - "%dk reserved, %dk data, %dk init)\n", - (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), - num_physpages << (PAGE_SHIFT-10), - codesize >> 10, - reservedpages << (PAGE_SHIFT-10), - datasize >> 10, - initsize >> 10); + set_max_mapnr(get_num_physpages()); + free_all_bootmem(); + mem_init_print_info(NULL); } /*======================================================================* @@ -222,17 +133,7 @@ void __init mem_init(void) *======================================================================*/ void free_initmem(void) { - unsigned long addr; - - addr = (unsigned long)(&__init_begin); - for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { - ClearPageReserved(virt_to_page(addr)); - init_page_count(virt_to_page(addr)); - free_page(addr); - totalram_pages++; - } - printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", \ - (int)(&__init_end - &__init_begin) >> 10); + free_initmem_default(-1); } #ifdef CONFIG_BLK_DEV_INITRD @@ -242,14 +143,6 @@ void free_initmem(void) *======================================================================*/ void free_initrd_mem(unsigned long start, unsigned long end) { - unsigned long p; - for (p = start; p < end; p += PAGE_SIZE) { - ClearPageReserved(virt_to_page(p)); - init_page_count(virt_to_page(p)); - free_page(p); - totalram_pages++; - } - printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + free_reserved_area((void *)start, (void *)end, -1, "initrd"); } #endif - diff --git a/arch/m32r/mm/mmu.S b/arch/m32r/mm/mmu.S index 9a4d40b3d6a..e9491a5ae82 100644 --- a/arch/m32r/mm/mmu.S +++ b/arch/m32r/mm/mmu.S @@ -4,8 +4,6 @@ * Copyright (C) 2001 by Hiroyuki Kondo */ -/* $Id: mmu.S,v 1.15 2004/03/16 02:56:27 takata Exp $ */ - #include <linux/linkage.h> #include <asm/assembler.h> #include <asm/smp.h> @@ -152,9 +150,13 @@ ENTRY(tme_handler) ; pmd = pmd_offset(pgd, address); ld r3, @r3 ; r3: pmd data - ldi r2, #-4096 beqz r3, 3f ; pmd_none(*pmd) ? + and3 r2, r3, #0xfff + add3 r2, r2, #-355 ; _KERNPG_TABLE(=0x163) + bnez r2, 3f ; pmd_bad(*pmd) ? + ldi r2, #-4096 + ; pte = pte_offset(pmd, address); and r2, r3 ; r2: pte base addr srl3 r3, r0, #10 @@ -165,7 +167,8 @@ ENTRY(tme_handler) ; pte_data = (unsigned long)pte_val(*pte); ld r2, @r3 ; r2: pte data - or3 r2, r2, #2 ; _PAGE_PRESENT(=2) + and3 r3, r2, #2 ; _PAGE_PRESENT(=2) check + beqz r3, 3f .fillinsn 5: @@ -264,13 +267,10 @@ ENTRY(tme_handler) ld r1, @r3 ; r1: pmd beqz r1, 3f ; pmd_none(*pmd) ? ; - and3 r1, r1, #0xeff - ldi r4, #611 ; _KERNPG_TABLE(=611) - beq r1, r4, 4f ; !pmd_bad(*pmd) ? - .fillinsn -3: - ldi r1, #0 ; r1: pte_data = 0 - bra 5f + and3 r1, r1, #0x3ff + ldi r4, #0x163 ; _KERNPG_TABLE(=0x163) + bne r1, r4, 3f ; pmd_bad(*pmd) ? + .fillinsn 4: ; pte = pte_offset(pmd, address); @@ -284,8 +284,10 @@ ENTRY(tme_handler) add r4, r3 ; r4: pte ; pte_data = (unsigned long)pte_val(*pte); ld r1, @r4 ; r1: pte_data - .fillinsn + and3 r3, r1, #2 ; _PAGE_PRESENT(=2) check + beqz r3, 3f + .fillinsn ;; set tlb ; r0: address, r1: pte_data, r2: entry ; r3,r4: (free) @@ -297,8 +299,7 @@ ENTRY(tme_handler) and3 r4, r4, #(MMU_CONTEXT_ASID_MASK) or r3, r4 st r3, @r2 - or3 r4, r1, #2 ; _PAGE_PRESENT(=2) - st r4, @(4,r2) ; set_tlb_data(entry, pte_data); + st r1, @(4,r2) ; set_tlb_data(entry, pte_data); ld r4, @sp+ ld r3, @sp+ @@ -308,6 +309,11 @@ ENTRY(tme_handler) ld sp, @sp+ rte + .fillinsn +3: + ldi r1, #2 ; r1: pte_data = 0 | _PAGE_PRESENT(=2) + bra 5b + #else #error unknown isa configuration #endif @@ -345,5 +351,4 @@ ENTRY(m32r_otlb_entrys) #endif /* CONFIG_MMU */ -.end - + .end |
