Statistics
| Branch: | Revision:

root / softmmu_header.h @ dbc5594c

History | View | Annotate | Download (3.3 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 DATA_TYPE uint64_t
23
#elif DATA_SIZE == 4
24
#define SUFFIX l
25
#define DATA_TYPE uint32_t
26
#elif DATA_SIZE == 2
27
#define SUFFIX w
28
#define DATA_TYPE uint16_t
29
#define DATA_STYPE int16_t
30
#elif DATA_SIZE == 1
31
#define SUFFIX b
32
#define DATA_TYPE uint8_t
33
#define DATA_STYPE int8_t
34
#else
35
#error unsupported data size
36
#endif
37

    
38
#if MEMUSER == 0
39
#define MEMSUFFIX _kernel
40
#else
41
#define MEMSUFFIX _user
42
#endif
43

    
44
#if DATA_SIZE == 8
45
#define RES_TYPE uint64_t
46
#else
47
#define RES_TYPE int
48
#endif
49

    
50

    
51
#if MEMUSER == 0
52
DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), _mmu)(unsigned long addr);
53
void REGPARM(2) glue(glue(__st, SUFFIX), _mmu)(unsigned long addr, DATA_TYPE v);
54
#endif
55

    
56
static inline int glue(glue(ldu, SUFFIX), MEMSUFFIX)(void *ptr)
57
{
58
    int index;
59
    RES_TYPE res;
60
    unsigned long addr, physaddr;
61
    addr = (unsigned long)ptr;
62
    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
63
    if (__builtin_expect(env->tlb_read[MEMUSER][index].address != 
64
                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
65
        res = glue(glue(__ld, SUFFIX), _mmu)(addr);
66
    } else {
67
        physaddr = addr + env->tlb_read[MEMUSER][index].addend;
68
        res = glue(glue(ldu, SUFFIX), _raw)((uint8_t *)physaddr);
69
    }
70
    return res;
71
}
72

    
73
#if DATA_SIZE <= 2
74
static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(void *ptr)
75
{
76
    int res, index;
77
    unsigned long addr, physaddr;
78
    addr = (unsigned long)ptr;
79
    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
80
    if (__builtin_expect(env->tlb_read[MEMUSER][index].address != 
81
                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
82
        res = (DATA_STYPE)glue(glue(__ld, SUFFIX), _mmu)(addr);
83
    } else {
84
        physaddr = addr + env->tlb_read[MEMUSER][index].addend;
85
        res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
86
    }
87
    return res;
88
}
89
#endif
90

    
91
static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v)
92
{
93
    int index;
94
    unsigned long addr, physaddr;
95
    addr = (unsigned long)ptr;
96
    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
97
    if (__builtin_expect(env->tlb_write[MEMUSER][index].address != 
98
                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
99
        glue(glue(__st, SUFFIX), _mmu)(addr, v);
100
    } else {
101
        physaddr = addr + env->tlb_write[MEMUSER][index].addend;
102
        glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
103
    }
104
}
105

    
106
#undef RES_TYPE
107
#undef DATA_TYPE
108
#undef DATA_STYPE
109
#undef SUFFIX
110
#undef DATA_SIZE
111
#undef MEMSUFFIX