/kernel/trunk/arch/mips32/src/mm/tlb.c |
---|
45,7 → 45,7 |
static pte_t *find_mapping_and_check(__address badvaddr); |
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn); |
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn); |
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr); |
/** Initialize TLB |
104,7 → 104,7 |
pte->a = 1; |
prepare_entry_hi(&hi, AS->asid, badvaddr); |
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
prepare_entry_lo(&lo, pte->lo.g, pte->lo.v, pte->lo.d, pte->lo.c, pte->lo.pfn); |
/* |
* New entry is to be inserted into TLB |
178,7 → 178,7 |
*/ |
pte->a = 1; |
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
prepare_entry_lo(&lo, pte->lo.g, pte->lo.v, pte->lo.d, pte->lo.c, pte->lo.pfn); |
/* |
* The entry is to be updated in TLB. |
252,9 → 252,9 |
* Record access and write to PTE. |
*/ |
pte->a = 1; |
pte->d = 1; |
pte->lo.d = 1; |
prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn); |
prepare_entry_lo(&lo, pte->lo.g, pte->lo.v, pte->w, pte->lo.c, pte->lo.pfn); |
/* |
* The entry is to be updated in TLB. |
337,7 → 337,7 |
* Check if the mapping exists in page tables. |
*/ |
pte = page_mapping_find(AS, badvaddr); |
if (pte && pte->p) { |
if (pte && pte->lo.v) { |
/* |
* Mapping found in page tables. |
* Immediately succeed. |
354,7 → 354,7 |
* The mapping ought to be in place. |
*/ |
pte = page_mapping_find(AS, badvaddr); |
ASSERT(pte && pte->p); |
ASSERT(pte && pte->lo.v); |
return pte; |
} |
} |
370,7 → 370,7 |
/* |
* Handler cannot succeed if the mapping is marked as invalid. |
*/ |
if (!pte->p) { |
if (!pte->lo.v) { |
printf("Invalid mapping.\n"); |
return NULL; |
} |
378,13 → 378,13 |
return pte; |
} |
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn) |
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn) |
{ |
lo->value = 0; |
lo->g = g; |
lo->v = v; |
lo->d = d; |
lo->c = cacheable ? PAGE_CACHEABLE_EXC_WRITE : PAGE_UNCACHED; |
lo->c = c; |
lo->pfn = pfn; |
} |
/kernel/trunk/arch/mips32/include/mm/page.h |
---|
48,9 → 48,6 |
* - 32-bit virtual addresses |
* - Offset is 14 bits => pages are 16K long |
* - PTE's use similar format as CP0 EntryLo[01] registers => PTE is therefore 4 bytes long |
* - PTE's replace EntryLo v (valid) bit with p (present) bit |
* - PTE's use only one bit to distinguish between cacheable and uncacheable mappings |
* - PTE's define soft_valid field to ensure there is at least one 1 bit even if the p bit is cleared |
* - PTE's make use of CP0 EntryLo's two-bit reserved field for bit W (writable) and bit A (accessed) |
* - PTL0 has 64 entries (6 bits) |
* - PTL1 is not used |
65,15 → 62,15 |
#define SET_PTL0_ADDRESS_ARCH(ptl0) |
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) (((pte_t *)(ptl0))[(i)].pfn<<12) |
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) (((pte_t *)(ptl0))[(i)].lo.pfn<<12) |
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) (ptl1) |
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) (ptl2) |
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) (((pte_t *)(ptl3))[(i)].pfn<<12) |
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) (((pte_t *)(ptl3))[(i)].lo.pfn<<12) |
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) (((pte_t *)(ptl0))[(i)].pfn = (a)>>12) |
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) (((pte_t *)(ptl0))[(i)].lo.pfn = (a)>>12) |
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) |
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) |
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) (((pte_t *)(ptl3))[(i)].pfn = (a)>>12) |
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) (((pte_t *)(ptl3))[(i)].lo.pfn = (a)>>12) |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *)(ptl0), (index_t)(i)) |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) PAGE_PRESENT |
97,13 → 94,13 |
pte_t *p = &pt[i]; |
return ( |
(p->cacheable<<PAGE_CACHEABLE_SHIFT) | |
((!p->p)<<PAGE_PRESENT_SHIFT) | |
((p->lo.c>PAGE_UNCACHED)<<PAGE_CACHEABLE_SHIFT) | |
((!p->lo.v)<<PAGE_PRESENT_SHIFT) | |
(1<<PAGE_USER_SHIFT) | |
(1<<PAGE_READ_SHIFT) | |
((p->w)<<PAGE_WRITE_SHIFT) | |
(1<<PAGE_EXEC_SHIFT) | |
(p->g<<PAGE_GLOBAL_SHIFT) |
p->lo.g<<PAGE_GLOBAL_SHIFT |
); |
} |
112,15 → 109,10 |
{ |
pte_t *p = &pt[i]; |
p->cacheable = (flags & PAGE_CACHEABLE) != 0; |
p->p = !(flags & PAGE_NOT_PRESENT); |
p->g = (flags & PAGE_GLOBAL) != 0; |
p->lo.c = (flags & PAGE_CACHEABLE) != 0 ? PAGE_CACHEABLE_EXC_WRITE : PAGE_UNCACHED; |
p->lo.v = !(flags & PAGE_NOT_PRESENT); |
p->lo.g = (flags & PAGE_GLOBAL) != 0; |
p->w = (flags & PAGE_WRITE) != 0; |
/* |
* Ensure that valid entries have at least one bit set. |
*/ |
p->soft_valid = 1; |
} |
extern void page_arch_init(void); |
/kernel/trunk/arch/mips32/include/mm/tlb.h |
---|
63,17 → 63,13 |
__u32 value; |
}; |
/** Page Table Entry. */ |
struct pte { |
unsigned g : 1; /**< Global bit. */ |
unsigned p : 1; /**< Present bit. */ |
unsigned d : 1; /**< Dirty bit. */ |
unsigned cacheable : 1; /**< Cacheable bit. */ |
unsigned : 1; /**< Unused. */ |
unsigned soft_valid : 1; /**< Valid content even if not present. */ |
unsigned pfn : 24; /**< Physical frame number. */ |
unsigned w : 1; /**< Page writable bit. */ |
unsigned a : 1; /**< Accessed bit. */ |
union pte { |
entry_lo_t lo; |
struct { |
unsigned : 30; |
unsigned w : 1; /* writable */ |
unsigned a : 1; /* accessed */ |
} __attribute__ ((packed)); |
}; |
union entry_hi { |
/kernel/trunk/arch/mips32/include/types.h |
---|
49,7 → 49,7 |
typedef __u32 __native; |
typedef struct pte pte_t; |
typedef union pte pte_t; |
typedef __u32 pfn_t; |
/kernel/trunk/arch/amd64/include/mm/page.h |
---|
75,7 → 75,6 |
#ifndef __ASM__ |
/** Page Table Entry. */ |
struct page_specifier { |
unsigned present : 1; |
unsigned writeable : 1; |
86,8 → 85,7 |
unsigned dirty : 1; |
unsigned unused: 1; |
unsigned global : 1; |
unsigned soft_valid : 1; /**< Valid content even if present bit is cleared. */ |
unsigned avl : 2; |
unsigned avl : 3; |
unsigned addr_12_31 : 30; |
unsigned addr_32_51 : 21; |
unsigned no_execute : 1; |
126,11 → 124,6 |
p->writeable = (flags & PAGE_WRITE) != 0; |
p->no_execute = (flags & PAGE_EXEC) == 0; |
p->global = (flags & PAGE_GLOBAL) != 0; |
/* |
* Ensure that there is at least one bit set even if the present bit is cleared. |
*/ |
p->soft_valid = 1; |
} |
extern void page_arch_init(void); |
/kernel/trunk/arch/ia32/include/mm/page.h |
---|
77,7 → 77,6 |
#include <arch/mm/frame.h> |
#include <typedefs.h> |
/** Page Table Entry. */ |
struct page_specifier { |
unsigned present : 1; |
unsigned writeable : 1; |
88,8 → 87,7 |
unsigned dirty : 1; |
unsigned pat : 1; |
unsigned global : 1; |
unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */ |
unsigned avl : 2; |
unsigned avl : 3; |
unsigned frame_address : 20; |
} __attribute__ ((packed)); |
117,11 → 115,6 |
p->uaccessible = (flags & PAGE_USER) != 0; |
p->writeable = (flags & PAGE_WRITE) != 0; |
p->global = (flags & PAGE_GLOBAL) != 0; |
/* |
* Ensure that there is at least one bit set even if the present bit is cleared. |
*/ |
p->soft_valid = true; |
} |
extern void page_arch_init(void); |