OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [alpha/] [mm/] [remap.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
#include <linux/vmalloc.h>
2
#include <asm/pgalloc.h>
3
 
4
/* called with the page_table_lock held */
5
static inline void
6
remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
7
               unsigned long phys_addr, unsigned long flags)
8
{
9
        unsigned long end;
10
 
11
        address &= ~PMD_MASK;
12
        end = address + size;
13
        if (end > PMD_SIZE)
14
                end = PMD_SIZE;
15
        if (address >= end)
16
                BUG();
17
        do {
18
                if (!pte_none(*pte)) {
19
                        printk("remap_area_pte: page already exists\n");
20
                        BUG();
21
                }
22
                set_pte(pte,
23
                        mk_pte_phys(phys_addr,
24
                                    __pgprot(_PAGE_VALID | _PAGE_ASM |
25
                                             _PAGE_KRE | _PAGE_KWE | flags)));
26
                address += PAGE_SIZE;
27
                phys_addr += PAGE_SIZE;
28
                pte++;
29
        } while (address && (address < end));
30
}
31
 
32
/* called with the page_table_lock held */
33
static inline int
34
remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
35
               unsigned long phys_addr, unsigned long flags)
36
{
37
        unsigned long end;
38
 
39
        address &= ~PGDIR_MASK;
40
        end = address + size;
41
        if (end > PGDIR_SIZE)
42
                end = PGDIR_SIZE;
43
        phys_addr -= address;
44
        if (address >= end)
45
                BUG();
46
        do {
47
                pte_t * pte = pte_alloc(&init_mm, pmd, address);
48
                if (!pte)
49
                        return -ENOMEM;
50
                remap_area_pte(pte, address, end - address,
51
                                     address + phys_addr, flags);
52
                address = (address + PMD_SIZE) & PMD_MASK;
53
                pmd++;
54
        } while (address && (address < end));
55
        return 0;
56
}
57
 
58
int
59
__alpha_remap_area_pages(unsigned long address, unsigned long phys_addr,
60
                         unsigned long size, unsigned long flags)
61
{
62
        pgd_t * dir;
63
        int error = 0;
64
        unsigned long end = address + size;
65
 
66
        phys_addr -= address;
67
        dir = pgd_offset(&init_mm, address);
68
        flush_cache_all();
69
        if (address >= end)
70
                BUG();
71
        spin_lock(&init_mm.page_table_lock);
72
        do {
73
                pmd_t *pmd;
74
                pmd = pmd_alloc(&init_mm, dir, address);
75
                error = -ENOMEM;
76
                if (!pmd)
77
                        break;
78
                if (remap_area_pmd(pmd, address, end - address,
79
                                   phys_addr + address, flags))
80
                        break;
81
                error = 0;
82
                address = (address + PGDIR_SIZE) & PGDIR_MASK;
83
                dir++;
84
        } while (address && (address < end));
85
        spin_unlock(&init_mm.page_table_lock);
86
        return error;
87
}
88
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.