1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
#ifndef _MMU_TLB_H_
#define _MMU_TLB_H_
typedef enum tlb_mapping_t
{
TLB_INVALID = 0,
TLB_SMALLPAGE = 1,
TLB_LARGEPAGE = 2,
TLB_SECTION = 3,
TLB_ESMALLPAGE = 4,
TLB_TINYPAGE = 5
} tlb_mapping_t;
extern ARMword tlb_masks[];
/* Permissions bits in a TLB entry:
*
* 31 12 11 10 9 8 7 6 5 4 3 2 1 0
* +-------------+-----+-----+-----+-----+---+---+-------+
* Page:| | ap3 | ap2 | ap1 | ap0 | C | B | |
* +-------------+-----+-----+-----+-----+---+---+-------+
*
* 31 12 11 10 9 4 3 2 1 0
* +-------------+-----+-----------------+---+---+-------+
* Section: | | AP | | C | B | |
* +-------------+-----+-----------------+---+---+-------+
*/
/*
section:
section base address [31:20]
AP - table 8-2, page 8-8
domain
C,B
page:
page base address [31:16] or [31:12]
ap[3:0]
domain (from L1)
C,B
*/
typedef struct tlb_entry_t
{
ARMword virt_addr;
ARMword phys_addr;
ARMword perms;
ARMword domain;
tlb_mapping_t mapping;
} tlb_entry_t;
typedef struct tlb_s
{
int num; /*num of tlb entry */
int cycle; /*current tlb cycle */
tlb_entry_t *entrys;
} tlb_s;
#define tlb_c_flag(tlb) \
((tlb)->perms & 0x8)
#define tlb_b_flag(tlb) \
((tlb)->perms & 0x4)
#define tlb_va_to_pa(tlb, va) ((tlb->phys_addr & tlb_masks[tlb->mapping]) | (va & ~tlb_masks[tlb->mapping]))
fault_t
check_access (ARMul_State * state, ARMword virt_addr, tlb_entry_t * tlb,
int read);
fault_t
translate (ARMul_State * state, ARMword virt_addr, tlb_s * tlb_t,
tlb_entry_t ** tlb);
int mmu_tlb_init (tlb_s * tlb_t, int num);
void mmu_tlb_exit (tlb_s * tlb_t);
void mmu_tlb_invalidate_all (ARMul_State * state, tlb_s * tlb_t);
void
mmu_tlb_invalidate_entry (ARMul_State * state, tlb_s * tlb_t, ARMword addr);
tlb_entry_t *mmu_tlb_search (ARMul_State * state, tlb_s * tlb_t,
ARMword virt_addr);
#endif /*_MMU_TLB_H_*/
|