Statistics
| Branch: | Revision:

root / exec.c @ 2a29ca73

History | View | Annotate | Download (4 kB)

1
/*
2
 *  virtual page mapping
3
 * 
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <stdarg.h>
23
#include <string.h>
24
#include <errno.h>
25
#include <unistd.h>
26
#include <inttypes.h>
27

    
28
#include "cpu-i386.h"
29

    
30
/* XXX: pack the flags in the low bits of the pointer ? */
31
typedef struct PageDesc {
32
    struct TranslationBlock *first_tb;
33
    unsigned long flags;
34
} PageDesc;
35

    
36
#define L2_BITS 10
37
#define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
38

    
39
#define L1_SIZE (1 << L1_BITS)
40
#define L2_SIZE (1 << L2_BITS)
41

    
42
unsigned long real_host_page_size;
43
unsigned long host_page_bits;
44
unsigned long host_page_size;
45
unsigned long host_page_mask;
46

    
47
static PageDesc *l1_map[L1_SIZE];
48

    
49
void page_init(void)
50
{
51
    /* NOTE: we can always suppose that host_page_size >=
52
       TARGET_PAGE_SIZE */
53
    real_host_page_size = getpagesize();
54
    if (host_page_size == 0)
55
        host_page_size = real_host_page_size;
56
    if (host_page_size < TARGET_PAGE_SIZE)
57
        host_page_size = TARGET_PAGE_SIZE;
58
    host_page_bits = 0;
59
    while ((1 << host_page_bits) < host_page_size)
60
        host_page_bits++;
61
    host_page_mask = ~(host_page_size - 1);
62
}
63

    
64
/* dump memory mappings */
65
void page_dump(FILE *f)
66
{
67
    unsigned long start, end;
68
    int i, j, prot, prot1;
69
    PageDesc *p;
70

    
71
    fprintf(f, "%-8s %-8s %-8s %s\n",
72
            "start", "end", "size", "prot");
73
    start = -1;
74
    end = -1;
75
    prot = 0;
76
    for(i = 0; i <= L1_SIZE; i++) {
77
        if (i < L1_SIZE)
78
            p = l1_map[i];
79
        else
80
            p = NULL;
81
        for(j = 0;j < L2_SIZE; j++) {
82
            if (!p)
83
                prot1 = 0;
84
            else
85
                prot1 = p[j].flags;
86
            if (prot1 != prot) {
87
                end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
88
                if (start != -1) {
89
                    fprintf(f, "%08lx-%08lx %08lx %c%c%c\n",
90
                            start, end, end - start, 
91
                            prot & PAGE_READ ? 'r' : '-',
92
                            prot & PAGE_WRITE ? 'w' : '-',
93
                            prot & PAGE_EXEC ? 'x' : '-');
94
                }
95
                if (prot1 != 0)
96
                    start = end;
97
                else
98
                    start = -1;
99
                prot = prot1;
100
            }
101
            if (!p)
102
                break;
103
        }
104
    }
105
}
106

    
107

    
108
static inline PageDesc *page_find_alloc(unsigned long address)
109
{
110
    unsigned int index;
111
    PageDesc **lp, *p;
112

    
113
    index = address >> TARGET_PAGE_BITS;
114
    lp = &l1_map[index >> L2_BITS];
115
    p = *lp;
116
    if (!p) {
117
        /* allocate if not found */
118
        p = malloc(sizeof(PageDesc) * L2_SIZE);
119
        memset(p, 0, sizeof(sizeof(PageDesc) * L2_SIZE));
120
        *lp = p;
121
    }
122
    return p + (index & (L2_SIZE - 1));
123
}
124

    
125
int page_get_flags(unsigned long address)
126
{
127
    unsigned int index;
128
    PageDesc *p;
129

    
130
    index = address >> TARGET_PAGE_BITS;
131
    p = l1_map[index >> L2_BITS];
132
    if (!p)
133
        return 0;
134
    return p[index & (L2_SIZE - 1)].flags;
135
}
136

    
137
void page_set_flags(unsigned long start, unsigned long end, int flags)
138
{
139
    PageDesc *p;
140
    unsigned long addr;
141

    
142
    start = start & TARGET_PAGE_MASK;
143
    end = TARGET_PAGE_ALIGN(end);
144
    for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
145
        p = page_find_alloc(addr);
146
        p->flags = flags;
147
    }
148
}