Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Xing Lin
qemu
Commits
61382a50
Commit
61382a50
authored
Oct 27, 2003
by
bellard
Browse files
full softmmu support
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@410
c046a42c-6fe2-441c-8c8c-71466251a162
parent
3a51dee6
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
cpu-all.h
View file @
61382a50
...
...
@@ -20,18 +20,19 @@
#ifndef CPU_ALL_H
#define CPU_ALL_H
/* all CPU memory access use these macros */
static
inline
int
ldub
(
void
*
ptr
)
/* CPU memory access without any memory or io remapping */
static
inline
int
ldub_raw
(
void
*
ptr
)
{
return
*
(
uint8_t
*
)
ptr
;
}
static
inline
int
ldsb
(
void
*
ptr
)
static
inline
int
ldsb
_raw
(
void
*
ptr
)
{
return
*
(
int8_t
*
)
ptr
;
}
static
inline
void
stb
(
void
*
ptr
,
int
v
)
static
inline
void
stb
_raw
(
void
*
ptr
,
int
v
)
{
*
(
uint8_t
*
)
ptr
=
v
;
}
...
...
@@ -42,7 +43,7 @@ static inline void stb(void *ptr, int v)
#if defined(WORDS_BIGENDIAN) || defined(__arm__)
/* conservative code for little endian unaligned accesses */
static
inline
int
lduw
(
void
*
ptr
)
static
inline
int
lduw
_raw
(
void
*
ptr
)
{
#ifdef __powerpc__
int
val
;
...
...
@@ -54,7 +55,7 @@ static inline int lduw(void *ptr)
#endif
}
static
inline
int
ldsw
(
void
*
ptr
)
static
inline
int
ldsw
_raw
(
void
*
ptr
)
{
#ifdef __powerpc__
int
val
;
...
...
@@ -66,7 +67,7 @@ static inline int ldsw(void *ptr)
#endif
}
static
inline
int
ldl
(
void
*
ptr
)
static
inline
int
ldl
_raw
(
void
*
ptr
)
{
#ifdef __powerpc__
int
val
;
...
...
@@ -78,16 +79,16 @@ static inline int ldl(void *ptr)
#endif
}
static
inline
uint64_t
ldq
(
void
*
ptr
)
static
inline
uint64_t
ldq
_raw
(
void
*
ptr
)
{
uint8_t
*
p
=
ptr
;
uint32_t
v1
,
v2
;
v1
=
ldl
(
p
);
v2
=
ldl
(
p
+
4
);
v1
=
ldl
_raw
(
p
);
v2
=
ldl
_raw
(
p
+
4
);
return
v1
|
((
uint64_t
)
v2
<<
32
);
}
static
inline
void
stw
(
void
*
ptr
,
int
v
)
static
inline
void
stw
_raw
(
void
*
ptr
,
int
v
)
{
#ifdef __powerpc__
__asm__
__volatile__
(
"sthbrx %1,0,%2"
:
"=m"
(
*
(
uint16_t
*
)
ptr
)
:
"r"
(
v
),
"r"
(
ptr
));
...
...
@@ -98,7 +99,7 @@ static inline void stw(void *ptr, int v)
#endif
}
static
inline
void
stl
(
void
*
ptr
,
int
v
)
static
inline
void
stl
_raw
(
void
*
ptr
,
int
v
)
{
#ifdef __powerpc__
__asm__
__volatile__
(
"stwbrx %1,0,%2"
:
"=m"
(
*
(
uint32_t
*
)
ptr
)
:
"r"
(
v
),
"r"
(
ptr
));
...
...
@@ -111,104 +112,104 @@ static inline void stl(void *ptr, int v)
#endif
}
static
inline
void
stq
(
void
*
ptr
,
uint64_t
v
)
static
inline
void
stq
_raw
(
void
*
ptr
,
uint64_t
v
)
{
uint8_t
*
p
=
ptr
;
stl
(
p
,
(
uint32_t
)
v
);
stl
(
p
+
4
,
v
>>
32
);
stl
_raw
(
p
,
(
uint32_t
)
v
);
stl
_raw
(
p
+
4
,
v
>>
32
);
}
/* float access */
static
inline
float
ldfl
(
void
*
ptr
)
static
inline
float
ldfl
_raw
(
void
*
ptr
)
{
union
{
float
f
;
uint32_t
i
;
}
u
;
u
.
i
=
ldl
(
ptr
);
u
.
i
=
ldl
_raw
(
ptr
);
return
u
.
f
;
}
static
inline
void
stfl
(
void
*
ptr
,
float
v
)
static
inline
void
stfl
_raw
(
void
*
ptr
,
float
v
)
{
union
{
float
f
;
uint32_t
i
;
}
u
;
u
.
f
=
v
;
stl
(
ptr
,
u
.
i
);
stl
_raw
(
ptr
,
u
.
i
);
}
#if defined(__arm__) && !defined(WORDS_BIGENDIAN)
/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
static
inline
double
ldfq
(
void
*
ptr
)
static
inline
double
ldfq
_raw
(
void
*
ptr
)
{
union
{
double
d
;
uint32_t
tab
[
2
];
}
u
;
u
.
tab
[
1
]
=
ldl
(
ptr
);
u
.
tab
[
0
]
=
ldl
(
ptr
+
4
);
u
.
tab
[
1
]
=
ldl
_raw
(
ptr
);
u
.
tab
[
0
]
=
ldl
_raw
(
ptr
+
4
);
return
u
.
d
;
}
static
inline
void
stfq
(
void
*
ptr
,
double
v
)
static
inline
void
stfq
_raw
(
void
*
ptr
,
double
v
)
{
union
{
double
d
;
uint32_t
tab
[
2
];
}
u
;
u
.
d
=
v
;
stl
(
ptr
,
u
.
tab
[
1
]);
stl
(
ptr
+
4
,
u
.
tab
[
0
]);
stl
_raw
(
ptr
,
u
.
tab
[
1
]);
stl
_raw
(
ptr
+
4
,
u
.
tab
[
0
]);
}
#else
static
inline
double
ldfq
(
void
*
ptr
)
static
inline
double
ldfq
_raw
(
void
*
ptr
)
{
union
{
double
d
;
uint64_t
i
;
}
u
;
u
.
i
=
ldq
(
ptr
);
u
.
i
=
ldq
_raw
(
ptr
);
return
u
.
d
;
}
static
inline
void
stfq
(
void
*
ptr
,
double
v
)
static
inline
void
stfq
_raw
(
void
*
ptr
,
double
v
)
{
union
{
double
d
;
uint64_t
i
;
}
u
;
u
.
d
=
v
;
stq
(
ptr
,
u
.
i
);
stq
_raw
(
ptr
,
u
.
i
);
}
#endif
#elif defined(TARGET_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN)
static
inline
int
lduw
(
void
*
ptr
)
static
inline
int
lduw
_raw
(
void
*
ptr
)
{
uint8_t
*
b
=
(
uint8_t
*
)
ptr
;
return
(
b
[
0
]
<<
8
|
b
[
1
]);
}
static
inline
int
ldsw
(
void
*
ptr
)
static
inline
int
ldsw
_raw
(
void
*
ptr
)
{
int8_t
*
b
=
(
int8_t
*
)
ptr
;
return
(
b
[
0
]
<<
8
|
b
[
1
]);
}
static
inline
int
ldl
(
void
*
ptr
)
static
inline
int
ldl
_raw
(
void
*
ptr
)
{
uint8_t
*
b
=
(
uint8_t
*
)
ptr
;
return
(
b
[
0
]
<<
24
|
b
[
1
]
<<
16
|
b
[
2
]
<<
8
|
b
[
3
]);
}
static
inline
uint64_t
ldq
(
void
*
ptr
)
static
inline
uint64_t
ldq
_raw
(
void
*
ptr
)
{
uint32_t
a
,
b
;
a
=
ldl
(
ptr
);
...
...
@@ -216,14 +217,14 @@ static inline uint64_t ldq(void *ptr)
return
(((
uint64_t
)
a
<<
32
)
|
b
);
}
static
inline
void
stw
(
void
*
ptr
,
int
v
)
static
inline
void
stw
_raw
(
void
*
ptr
,
int
v
)
{
uint8_t
*
d
=
(
uint8_t
*
)
ptr
;
d
[
0
]
=
v
>>
8
;
d
[
1
]
=
v
;
}
static
inline
void
stl
(
void
*
ptr
,
int
v
)
static
inline
void
stl
_raw
(
void
*
ptr
,
int
v
)
{
uint8_t
*
d
=
(
uint8_t
*
)
ptr
;
d
[
0
]
=
v
>>
24
;
...
...
@@ -232,7 +233,7 @@ static inline void stl(void *ptr, int v)
d
[
3
]
=
v
;
}
static
inline
void
stq
(
void
*
ptr
,
uint64_t
v
)
static
inline
void
stq
_raw
(
void
*
ptr
,
uint64_t
v
)
{
stl
(
ptr
,
v
);
stl
(
ptr
+
4
,
v
>>
32
);
...
...
@@ -240,64 +241,102 @@ static inline void stq(void *ptr, uint64_t v)
#else
static
inline
int
lduw
(
void
*
ptr
)
static
inline
int
lduw
_raw
(
void
*
ptr
)
{
return
*
(
uint16_t
*
)
ptr
;
}
static
inline
int
ldsw
(
void
*
ptr
)
static
inline
int
ldsw
_raw
(
void
*
ptr
)
{
return
*
(
int16_t
*
)
ptr
;
}
static
inline
int
ldl
(
void
*
ptr
)
static
inline
int
ldl
_raw
(
void
*
ptr
)
{
return
*
(
uint32_t
*
)
ptr
;
}
static
inline
uint64_t
ldq
(
void
*
ptr
)
static
inline
uint64_t
ldq
_raw
(
void
*
ptr
)
{
return
*
(
uint64_t
*
)
ptr
;
}
static
inline
void
stw
(
void
*
ptr
,
int
v
)
static
inline
void
stw
_raw
(
void
*
ptr
,
int
v
)
{
*
(
uint16_t
*
)
ptr
=
v
;
}
static
inline
void
stl
(
void
*
ptr
,
int
v
)
static
inline
void
stl
_raw
(
void
*
ptr
,
int
v
)
{
*
(
uint32_t
*
)
ptr
=
v
;
}
static
inline
void
stq
(
void
*
ptr
,
uint64_t
v
)
static
inline
void
stq
_raw
(
void
*
ptr
,
uint64_t
v
)
{
*
(
uint64_t
*
)
ptr
=
v
;
}
/* float access */
static
inline
float
ldfl
(
void
*
ptr
)
static
inline
float
ldfl
_raw
(
void
*
ptr
)
{
return
*
(
float
*
)
ptr
;
}
static
inline
double
ldfq
(
void
*
ptr
)
static
inline
double
ldfq
_raw
(
void
*
ptr
)
{
return
*
(
double
*
)
ptr
;
}
static
inline
void
stfl
(
void
*
ptr
,
float
v
)
static
inline
void
stfl
_raw
(
void
*
ptr
,
float
v
)
{
*
(
float
*
)
ptr
=
v
;
}
static
inline
void
stfq
(
void
*
ptr
,
double
v
)
static
inline
void
stfq
_raw
(
void
*
ptr
,
double
v
)
{
*
(
double
*
)
ptr
=
v
;
}
#endif
/* MMU memory access macros */
#if defined(CONFIG_USER_ONLY)
/* if user mode, no other memory access functions */
#define ldub(p) ldub_raw(p)
#define ldsb(p) ldsb_raw(p)
#define lduw(p) lduw_raw(p)
#define ldsw(p) ldsw_raw(p)
#define ldl(p) ldl_raw(p)
#define ldq(p) ldq_raw(p)
#define ldfl(p) ldfl_raw(p)
#define ldfq(p) ldfq_raw(p)
#define stb(p, v) stb_raw(p, v)
#define stw(p, v) stw_raw(p, v)
#define stl(p, v) stl_raw(p, v)
#define stq(p, v) stq_raw(p, v)
#define stfl(p, v) stfl_raw(p, v)
#define stfq(p, v) stfq_raw(p, v)
#define ldub_code(p) ldub_raw(p)
#define ldsb_code(p) ldsb_raw(p)
#define lduw_code(p) lduw_raw(p)
#define ldsw_code(p) ldsw_raw(p)
#define ldl_code(p) ldl_raw(p)
#define ldub_kernel(p) ldub_raw(p)
#define ldsb_kernel(p) ldsb_raw(p)
#define lduw_kernel(p) lduw_raw(p)
#define ldsw_kernel(p) ldsw_raw(p)
#define ldl_kernel(p) ldl_raw(p)
#define stb_kernel(p, v) stb_raw(p, v)
#define stw_kernel(p, v) stw_raw(p, v)
#define stl_kernel(p, v) stl_raw(p, v)
#define stq_kernel(p, v) stq_raw(p, v)
#endif
/* defined(CONFIG_USER_ONLY) */
/* page related stuff */
#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
...
...
exec.c
View file @
61382a50
...
...
@@ -444,16 +444,20 @@ static inline void tb_alloc_page(TranslationBlock *tb, unsigned int page_index)
prot
=
0
;
for
(
addr
=
host_start
;
addr
<
host_end
;
addr
+=
TARGET_PAGE_SIZE
)
prot
|=
page_get_flags
(
addr
);
#if !defined(CONFIG_SOFTMMU)
mprotect
((
void
*
)
host_start
,
host_page_size
,
(
prot
&
PAGE_BITS
)
&
~
PAGE_WRITE
);
#endif
#if !defined(CONFIG_USER_ONLY)
/* suppress soft TLB */
/* XXX: must flush on all processor with same address space */
tlb_flush_page_write
(
cpu_single_env
,
host_start
);
#endif
#ifdef DEBUG_TB_INVALIDATE
printf
(
"protecting code page: 0x%08lx
\n
"
,
host_start
);
#endif
p
->
flags
&=
~
PAGE_WRITE
;
#ifdef DEBUG_TB_CHECK
tb_page_check
();
#endif
}
}
...
...
@@ -483,6 +487,9 @@ void tb_link(TranslationBlock *tb)
if
(
page_index2
!=
page_index1
)
{
tb_alloc_page
(
tb
,
page_index2
);
}
#ifdef DEBUG_TB_CHECK
tb_page_check
();
#endif
tb
->
jmp_first
=
(
TranslationBlock
*
)((
long
)
tb
|
2
);
tb
->
jmp_next
[
0
]
=
NULL
;
tb
->
jmp_next
[
1
]
=
NULL
;
...
...
@@ -517,20 +524,23 @@ int page_unprotect(unsigned long address)
/* if the page was really writable, then we change its
protection back to writable */
if
(
prot
&
PAGE_WRITE_ORG
)
{
mprotect
((
void
*
)
host_start
,
host_page_size
,
(
prot
&
PAGE_BITS
)
|
PAGE_WRITE
);
pindex
=
(
address
-
host_start
)
>>
TARGET_PAGE_BITS
;
p1
[
pindex
].
flags
|=
PAGE_WRITE
;
/* and since the content will be modified, we must invalidate
the corresponding translated code. */
tb_invalidate_page
(
address
);
if
(
!
(
p1
[
pindex
].
flags
&
PAGE_WRITE
))
{
#if !defined(CONFIG_SOFTMMU)
mprotect
((
void
*
)
host_start
,
host_page_size
,
(
prot
&
PAGE_BITS
)
|
PAGE_WRITE
);
#endif
p1
[
pindex
].
flags
|=
PAGE_WRITE
;
/* and since the content will be modified, we must invalidate
the corresponding translated code. */
tb_invalidate_page
(
address
);
#ifdef DEBUG_TB_CHECK
tb_invalidate_check
(
address
);
tb_invalidate_check
(
address
);
#endif
return
1
;
}
else
{
return
0
;
return
1
;
}
}
return
0
;
}
/* call this function when system calls directly modify a memory area */
...
...
@@ -734,13 +744,17 @@ void cpu_abort(CPUState *env, const char *fmt, ...)
/* unmap all maped pages and flush all associated code */
void
page_unmap
(
void
)
{
PageDesc
*
p
,
*
pmap
;
unsigned
long
addr
;
int
i
,
j
,
ret
,
j1
;
PageDesc
*
pmap
;
int
i
;
for
(
i
=
0
;
i
<
L1_SIZE
;
i
++
)
{
pmap
=
l1_map
[
i
];
if
(
pmap
)
{
#if !defined(CONFIG_SOFTMMU)
PageDesc
*
p
;
unsigned
long
addr
;
int
j
,
ret
,
j1
;
p
=
pmap
;
for
(
j
=
0
;
j
<
L2_SIZE
;)
{
if
(
p
->
flags
&
PAGE_VALID
)
{
...
...
@@ -763,6 +777,7 @@ void page_unmap(void)
j
++
;
}
}
#endif
free
(
pmap
);
l1_map
[
i
]
=
NULL
;
}
...
...
@@ -773,7 +788,7 @@ void page_unmap(void)
void
tlb_flush
(
CPUState
*
env
)
{
#if defined(
TARGET_I386
)
#if
!
defined(
CONFIG_USER_ONLY
)
int
i
;
for
(
i
=
0
;
i
<
CPU_TLB_SIZE
;
i
++
)
{
env
->
tlb_read
[
0
][
i
].
address
=
-
1
;
...
...
@@ -784,16 +799,38 @@ void tlb_flush(CPUState *env)
#endif
}
static
inline
void
tlb_flush_entry
(
CPUTLBEntry
*
tlb_entry
,
uint32_t
addr
)
{
if
(
addr
==
(
tlb_entry
->
address
&
(
TARGET_PAGE_MASK
|
TLB_INVALID_MASK
)))
tlb_entry
->
address
=
-
1
;
}
void
tlb_flush_page
(
CPUState
*
env
,
uint32_t
addr
)
{
#if defined(TARGET_I386)
#if !defined(CONFIG_USER_ONLY)
int
i
;
addr
&=
TARGET_PAGE_MASK
;
i
=
(
addr
>>
TARGET_PAGE_BITS
)
&
(
CPU_TLB_SIZE
-
1
);
tlb_flush_entry
(
&
env
->
tlb_read
[
0
][
i
],
addr
);
tlb_flush_entry
(
&
env
->
tlb_write
[
0
][
i
],
addr
);
tlb_flush_entry
(
&
env
->
tlb_read
[
1
][
i
],
addr
);
tlb_flush_entry
(
&
env
->
tlb_write
[
1
][
i
],
addr
);
#endif
}
/* make all write to page 'addr' trigger a TLB exception to detect
self modifying code */
void
tlb_flush_page_write
(
CPUState
*
env
,
uint32_t
addr
)
{
#if !defined(CONFIG_USER_ONLY)
int
i
;
addr
&=
TARGET_PAGE_MASK
;
i
=
(
addr
>>
TARGET_PAGE_BITS
)
&
(
CPU_TLB_SIZE
-
1
);
env
->
tlb_read
[
0
][
i
].
address
=
-
1
;
env
->
tlb_write
[
0
][
i
].
address
=
-
1
;
env
->
tlb_read
[
1
][
i
].
address
=
-
1
;
env
->
tlb_write
[
1
][
i
].
address
=
-
1
;
tlb_flush_entry
(
&
env
->
tlb_write
[
0
][
i
],
addr
);
tlb_flush_entry
(
&
env
->
tlb_write
[
1
][
i
],
addr
);
#endif
}
...
...
@@ -900,3 +937,25 @@ int cpu_register_io_memory(int io_index,
}
return
io_index
<<
IO_MEM_SHIFT
;
}
#if !defined(CONFIG_USER_ONLY)
#define MMUSUFFIX _cmmu
#define GETPC() NULL
#define env cpu_single_env
#define SHIFT 0
#include
"softmmu_template.h"
#define SHIFT 1
#include
"softmmu_template.h"
#define SHIFT 2
#include
"softmmu_template.h"
#define SHIFT 3
#include
"softmmu_template.h"
#undef env
#endif
hw/vga_template.h
View file @
61382a50
...
...
@@ -354,7 +354,7 @@ static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d,
w
=
width
;
do
{
v
=
lduw
((
void
*
)
s
);
v
=
lduw
_raw
((
void
*
)
s
);
r
=
(
v
>>
7
)
&
0xf8
;
g
=
(
v
>>
2
)
&
0xf8
;
b
=
(
v
<<
3
)
&
0xf8
;
...
...
@@ -379,7 +379,7 @@ static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d,
w
=
width
;
do
{
v
=
lduw
((
void
*
)
s
);
v
=
lduw
_raw
((
void
*
)
s
);
r
=
(
v
>>
8
)
&
0xf8
;
g
=
(
v
>>
3
)
&
0xfc
;
b
=
(
v
<<
3
)
&
0xf8
;
...
...
softmmu_header.h
View file @
61382a50
...
...
@@ -19,26 +19,48 @@
*/
#if DATA_SIZE == 8
#define SUFFIX q
#define USUFFIX q
#define DATA_TYPE uint64_t
#elif DATA_SIZE == 4
#define SUFFIX l
#define USUFFIX l
#define DATA_TYPE uint32_t
#elif DATA_SIZE == 2
#define SUFFIX w
#define USUFFIX uw
#define DATA_TYPE uint16_t
#define DATA_STYPE int16_t
#elif DATA_SIZE == 1
#define SUFFIX b
#define USUFFIX ub
#define DATA_TYPE uint8_t
#define DATA_STYPE int8_t
#else
#error unsupported data size
#endif
#if MEMUSER == 0
#define MEMSUFFIX _kernel
#if ACCESS_TYPE == 0
#define CPU_MEM_INDEX 0
#define MMUSUFFIX _mmu
#elif ACCESS_TYPE == 1
#define CPU_MEM_INDEX 1
#define MMUSUFFIX _mmu
#elif ACCESS_TYPE == 2
#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
#define MMUSUFFIX _mmu
#elif ACCESS_TYPE == 3
#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
#define MMUSUFFIX _cmmu
#else
#
define MEMSUFFIX _user
#
error invalid ACCESS_TYPE
#endif
#if DATA_SIZE == 8
...
...
@@ -48,24 +70,26 @@
#endif
#if MEMUSER == 0
DATA_TYPE
REGPARM
(
1
)
glue
(
glue
(
__ld
,
SUFFIX
),
_mmu
)(
unsigned
long
addr
);
void
REGPARM
(
2
)
glue
(
glue
(
__st
,
SUFFIX
),
_mmu
)(
unsigned
long
addr
,
DATA_TYPE
v
);
#endif
DATA_TYPE
REGPARM
(
1
)
glue
(
glue
(
__ld
,
SUFFIX
),
MMUSUFFIX
)(
unsigned
long
addr
,
int
is_user
);
void
REGPARM
(
2
)
glue
(
glue
(
__st
,
SUFFIX
),
MMUSUFFIX
)(
unsigned
long
addr
,
DATA_TYPE
v
,
int
is_user
);
static
inline
int
glue
(
glue
(
ld
u
,
SUFFIX
),
MEMSUFFIX
)(
void
*
ptr
)
static
inline
int
glue
(
glue
(
ld
,
U
SUFFIX
),
MEMSUFFIX
)(
void
*
ptr
)
{
int
index
;
RES_TYPE
res
;
unsigned
long
addr
,
physaddr
;
int
is_user
;
addr
=
(
unsigned
long
)
ptr
;
index
=
(
addr
>>
TARGET_PAGE_BITS
)
&
(
CPU_TLB_SIZE
-
1
);
if
(
__builtin_expect
(
env
->
tlb_read
[
MEMUSER
][
index
].
address
!=
is_user
=
CPU_MEM_INDEX
;
if
(
__builtin_expect
(
env
->
tlb_read
[
is_user
][
index
].
address
!=
(
addr
&
(
TARGET_PAGE_MASK
|
(
DATA_SIZE
-
1
))),
0
))
{
res
=
glue
(
glue
(
__ld
,
SUFFIX
),
_mmu
)(
add
r
);
res
=
glue
(
glue
(
__ld
,
SUFFIX
),
MMUSUFFIX
)(
addr
,
is_use
r
);
}
else
{
physaddr
=
addr
+
env
->
tlb_read
[
MEMUSER
][
index
].
addend
;
res
=
glue
(
glue
(
ld
u
,
SUFFIX
),
_raw
)((
uint8_t
*
)
physaddr
);
physaddr
=
addr
+
env
->
tlb_read
[
is_user
][
index
].
addend
;
res
=
glue
(
glue
(
ld
,
U
SUFFIX
),
_raw
)((
uint8_t
*
)
physaddr
);
}
return
res
;
}
...
...
@@ -75,13 +99,16 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(void *ptr)
{
int
res
,
index
;
unsigned
long
addr
,
physaddr
;
int
is_user
;
addr
=
(
unsigned
long
)
ptr
;
index
=
(
addr
>>
TARGET_PAGE_BITS
)
&
(
CPU_TLB_SIZE
-
1
);
if
(
__builtin_expect
(
env
->
tlb_read
[
MEMUSER
][
index
].
address
!=
is_user
=
CPU_MEM_INDEX
;
if
(
__builtin_expect
(
env
->
tlb_read
[
is_user
][
index
].
address
!=
(
addr
&
(
TARGET_PAGE_MASK
|
(
DATA_SIZE
-
1
))),
0
))
{
res
=
(
DATA_STYPE
)
glue
(
glue
(
__ld
,
SUFFIX
),
_mmu
)(
add
r
);
res
=
(
DATA_STYPE
)
glue
(
glue
(
__ld
,
SUFFIX
),
MMUSUFFIX
)(
addr
,
is_use
r
);
}
else
{
physaddr
=
addr
+
env
->
tlb_read
[
MEMUSER
][
index
].
addend
;
physaddr
=
addr
+
env
->
tlb_read
[
is_user
][
index
].
addend
;
res
=
glue
(
glue
(
lds
,
SUFFIX
),
_raw
)((
uint8_t
*
)
physaddr
);
}