Statistics
| Branch: | Revision:

root / exec.c @ 2a29ca73

History | View | Annotate | Download (4 kB)

1 54936004 bellard
/*
2 54936004 bellard
 *  virtual page mapping
3 54936004 bellard
 * 
4 54936004 bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 54936004 bellard
 *
6 54936004 bellard
 * This library is free software; you can redistribute it and/or
7 54936004 bellard
 * modify it under the terms of the GNU Lesser General Public
8 54936004 bellard
 * License as published by the Free Software Foundation; either
9 54936004 bellard
 * version 2 of the License, or (at your option) any later version.
10 54936004 bellard
 *
11 54936004 bellard
 * This library is distributed in the hope that it will be useful,
12 54936004 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 54936004 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 54936004 bellard
 * Lesser General Public License for more details.
15 54936004 bellard
 *
16 54936004 bellard
 * You should have received a copy of the GNU Lesser General Public
17 54936004 bellard
 * License along with this library; if not, write to the Free Software
18 54936004 bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 54936004 bellard
 */
20 54936004 bellard
#include <stdlib.h>
21 54936004 bellard
#include <stdio.h>
22 54936004 bellard
#include <stdarg.h>
23 54936004 bellard
#include <string.h>
24 54936004 bellard
#include <errno.h>
25 54936004 bellard
#include <unistd.h>
26 54936004 bellard
#include <inttypes.h>
27 54936004 bellard
28 54936004 bellard
#include "cpu-i386.h"
29 54936004 bellard
30 54936004 bellard
/* XXX: pack the flags in the low bits of the pointer ? */
31 54936004 bellard
typedef struct PageDesc {
32 54936004 bellard
    struct TranslationBlock *first_tb;
33 54936004 bellard
    unsigned long flags;
34 54936004 bellard
} PageDesc;
35 54936004 bellard
36 54936004 bellard
#define L2_BITS 10
37 54936004 bellard
#define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
38 54936004 bellard
39 54936004 bellard
#define L1_SIZE (1 << L1_BITS)
40 54936004 bellard
#define L2_SIZE (1 << L2_BITS)
41 54936004 bellard
42 54936004 bellard
unsigned long real_host_page_size;
43 54936004 bellard
unsigned long host_page_bits;
44 54936004 bellard
unsigned long host_page_size;
45 54936004 bellard
unsigned long host_page_mask;
46 54936004 bellard
47 54936004 bellard
static PageDesc *l1_map[L1_SIZE];
48 54936004 bellard
49 54936004 bellard
void page_init(void)
50 54936004 bellard
{
51 54936004 bellard
    /* NOTE: we can always suppose that host_page_size >=
52 54936004 bellard
       TARGET_PAGE_SIZE */
53 54936004 bellard
    real_host_page_size = getpagesize();
54 54936004 bellard
    if (host_page_size == 0)
55 54936004 bellard
        host_page_size = real_host_page_size;
56 54936004 bellard
    if (host_page_size < TARGET_PAGE_SIZE)
57 54936004 bellard
        host_page_size = TARGET_PAGE_SIZE;
58 54936004 bellard
    host_page_bits = 0;
59 54936004 bellard
    while ((1 << host_page_bits) < host_page_size)
60 54936004 bellard
        host_page_bits++;
61 54936004 bellard
    host_page_mask = ~(host_page_size - 1);
62 54936004 bellard
}
63 54936004 bellard
64 54936004 bellard
/* dump memory mappings */
65 54936004 bellard
void page_dump(FILE *f)
66 54936004 bellard
{
67 54936004 bellard
    unsigned long start, end;
68 54936004 bellard
    int i, j, prot, prot1;
69 54936004 bellard
    PageDesc *p;
70 54936004 bellard
71 54936004 bellard
    fprintf(f, "%-8s %-8s %-8s %s\n",
72 54936004 bellard
            "start", "end", "size", "prot");
73 54936004 bellard
    start = -1;
74 54936004 bellard
    end = -1;
75 54936004 bellard
    prot = 0;
76 54936004 bellard
    for(i = 0; i <= L1_SIZE; i++) {
77 54936004 bellard
        if (i < L1_SIZE)
78 54936004 bellard
            p = l1_map[i];
79 54936004 bellard
        else
80 54936004 bellard
            p = NULL;
81 54936004 bellard
        for(j = 0;j < L2_SIZE; j++) {
82 54936004 bellard
            if (!p)
83 54936004 bellard
                prot1 = 0;
84 54936004 bellard
            else
85 54936004 bellard
                prot1 = p[j].flags;
86 54936004 bellard
            if (prot1 != prot) {
87 54936004 bellard
                end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
88 54936004 bellard
                if (start != -1) {
89 54936004 bellard
                    fprintf(f, "%08lx-%08lx %08lx %c%c%c\n",
90 54936004 bellard
                            start, end, end - start, 
91 54936004 bellard
                            prot & PAGE_READ ? 'r' : '-',
92 54936004 bellard
                            prot & PAGE_WRITE ? 'w' : '-',
93 54936004 bellard
                            prot & PAGE_EXEC ? 'x' : '-');
94 54936004 bellard
                }
95 54936004 bellard
                if (prot1 != 0)
96 54936004 bellard
                    start = end;
97 54936004 bellard
                else
98 54936004 bellard
                    start = -1;
99 54936004 bellard
                prot = prot1;
100 54936004 bellard
            }
101 54936004 bellard
            if (!p)
102 54936004 bellard
                break;
103 54936004 bellard
        }
104 54936004 bellard
    }
105 54936004 bellard
}
106 54936004 bellard
107 54936004 bellard
108 54936004 bellard
static inline PageDesc *page_find_alloc(unsigned long address)
109 54936004 bellard
{
110 54936004 bellard
    unsigned int index;
111 54936004 bellard
    PageDesc **lp, *p;
112 54936004 bellard
113 54936004 bellard
    index = address >> TARGET_PAGE_BITS;
114 54936004 bellard
    lp = &l1_map[index >> L2_BITS];
115 54936004 bellard
    p = *lp;
116 54936004 bellard
    if (!p) {
117 54936004 bellard
        /* allocate if not found */
118 54936004 bellard
        p = malloc(sizeof(PageDesc) * L2_SIZE);
119 54936004 bellard
        memset(p, 0, sizeof(sizeof(PageDesc) * L2_SIZE));
120 54936004 bellard
        *lp = p;
121 54936004 bellard
    }
122 54936004 bellard
    return p + (index & (L2_SIZE - 1));
123 54936004 bellard
}
124 54936004 bellard
125 54936004 bellard
int page_get_flags(unsigned long address)
126 54936004 bellard
{
127 54936004 bellard
    unsigned int index;
128 54936004 bellard
    PageDesc *p;
129 54936004 bellard
130 54936004 bellard
    index = address >> TARGET_PAGE_BITS;
131 54936004 bellard
    p = l1_map[index >> L2_BITS];
132 54936004 bellard
    if (!p)
133 54936004 bellard
        return 0;
134 54936004 bellard
    return p[index & (L2_SIZE - 1)].flags;
135 54936004 bellard
}
136 54936004 bellard
137 54936004 bellard
void page_set_flags(unsigned long start, unsigned long end, int flags)
138 54936004 bellard
{
139 54936004 bellard
    PageDesc *p;
140 54936004 bellard
    unsigned long addr;
141 54936004 bellard
142 54936004 bellard
    start = start & TARGET_PAGE_MASK;
143 54936004 bellard
    end = TARGET_PAGE_ALIGN(end);
144 54936004 bellard
    for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
145 54936004 bellard
        p = page_find_alloc(addr);
146 54936004 bellard
        p->flags = flags;
147 54936004 bellard
    }
148 54936004 bellard
}