Statistics
| Branch: | Revision:

root / softmmu_header.h @ 61382a50

History | View | Annotate | Download (4 kB)

1
/*
2
 *  Software MMU support
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
#if DATA_SIZE == 8
21
#define SUFFIX q
22
#define USUFFIX q
23
#define DATA_TYPE uint64_t
24
#elif DATA_SIZE == 4
25
#define SUFFIX l
26
#define USUFFIX l
27
#define DATA_TYPE uint32_t
28
#elif DATA_SIZE == 2
29
#define SUFFIX w
30
#define USUFFIX uw
31
#define DATA_TYPE uint16_t
32
#define DATA_STYPE int16_t
33
#elif DATA_SIZE == 1
34
#define SUFFIX b
35
#define USUFFIX ub
36
#define DATA_TYPE uint8_t
37
#define DATA_STYPE int8_t
38
#else
39
#error unsupported data size
40
#endif
41

    
42
#if ACCESS_TYPE == 0
43

    
44
#define CPU_MEM_INDEX 0
45
#define MMUSUFFIX _mmu
46

    
47
#elif ACCESS_TYPE == 1
48

    
49
#define CPU_MEM_INDEX 1
50
#define MMUSUFFIX _mmu
51

    
52
#elif ACCESS_TYPE == 2
53

    
54
#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
55
#define MMUSUFFIX _mmu
56

    
57
#elif ACCESS_TYPE == 3
58

    
59
#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
60
#define MMUSUFFIX _cmmu
61

    
62
#else
63
#error invalid ACCESS_TYPE
64
#endif
65

    
66
#if DATA_SIZE == 8
67
#define RES_TYPE uint64_t
68
#else
69
#define RES_TYPE int
70
#endif
71

    
72

    
73
DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr,
74
                                                         int is_user);
75
void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(unsigned long addr, DATA_TYPE v, int is_user);
76

    
77
static inline int glue(glue(ld, USUFFIX), MEMSUFFIX)(void *ptr)
78
{
79
    int index;
80
    RES_TYPE res;
81
    unsigned long addr, physaddr;
82
    int is_user;
83

    
84
    addr = (unsigned long)ptr;
85
    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
86
    is_user = CPU_MEM_INDEX;
87
    if (__builtin_expect(env->tlb_read[is_user][index].address != 
88
                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
89
        res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
90
    } else {
91
        physaddr = addr + env->tlb_read[is_user][index].addend;
92
        res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
93
    }
94
    return res;
95
}
96

    
97
#if DATA_SIZE <= 2
98
static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(void *ptr)
99
{
100
    int res, index;
101
    unsigned long addr, physaddr;
102
    int is_user;
103

    
104
    addr = (unsigned long)ptr;
105
    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
106
    is_user = CPU_MEM_INDEX;
107
    if (__builtin_expect(env->tlb_read[is_user][index].address != 
108
                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
109
        res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
110
    } else {
111
        physaddr = addr + env->tlb_read[is_user][index].addend;
112
        res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
113
    }
114
    return res;
115
}
116
#endif
117

    
118
static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v)
119
{
120
    int index;
121
    unsigned long addr, physaddr;
122
    int is_user;
123

    
124
    addr = (unsigned long)ptr;
125
    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
126
    is_user = CPU_MEM_INDEX;
127
    if (__builtin_expect(env->tlb_write[is_user][index].address != 
128
                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
129
        glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
130
    } else {
131
        physaddr = addr + env->tlb_write[is_user][index].addend;
132
        glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
133
    }
134
}
135

    
136
#undef RES_TYPE
137
#undef DATA_TYPE
138
#undef DATA_STYPE
139
#undef SUFFIX
140
#undef USUFFIX
141
#undef DATA_SIZE
142
#undef CPU_MEM_INDEX
143
#undef MMUSUFFIX