Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 831 → Rev 832

/kernel/trunk/doc/TODO
4,13 → 4,12
+ [ia32] use int 0x15 ax=0xe820 to get memory map and memory size [DONE]
+ [mips] use some heuristics to get memory map and memory size
+ reimplement heap so that it can allocate/deallocate
itself frames as necessary
itself frames as necessary [DONE]
+ provide native four-level portable page table interface [DONE]
+ every architecture uses its native page table format
+ kernel provides unified four-level page table interface
for all architectures
+ track usage of frames containing middle-level page tables
(frame leak)
or page hash table interface to architectures
+ deallocation of memory of empty page tables [DONE]
 
+ get user mode support for all architectures
 
/kernel/trunk/genarch/include/mm/page_pt.h
40,6 → 40,14
#include <mm/page.h>
 
/*
* Number of entries in each level.
*/
#define PTL0_ENTRIES PTL0_ENTRIES_ARCH
#define PTL1_ENTRIES PTL1_ENTRIES_ARCH
#define PTL2_ENTRIES PTL2_ENTRIES_ARCH
#define PTL3_ENTRIES PTL3_ENTRIES_ARCH
 
/*
* These macros process vaddr and extract those portions
* of it that function as indices to respective page tables.
*/
84,6 → 92,11
#define SET_PTL3_FLAGS(ptl2, i, x) SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS(ptl3, i, x) SET_FRAME_FLAGS_ARCH(ptl3, i, x)
 
/*
* Determine whether the mapping is valid.
*/
#define PTE_VALID(p) PTE_VALID_ARCH((p))
 
extern page_mapping_operations_t pt_mapping_operations;
 
extern void page_mapping_insert_pt(as_t *as, __address page, __address frame, int flags);
/kernel/trunk/genarch/src/mm/page_pt.c
103,6 → 103,8
* TLB shootdown should follow in order to make effects of
* this call visible.
*
* Empty page tables except PTL0 are freed.
*
* The address space must be locked and interrupts must be disabled.
*
* @param as Address space to wich page belongs.
111,7 → 113,13
void pt_mapping_remove(as_t *as, __address page)
{
pte_t *ptl0, *ptl1, *ptl2, *ptl3;
bool empty = true;
int i;
 
/*
* First, remove the mapping, if it exists.
*/
 
ptl0 = (pte_t *) PA2KA((__address) as->page_table);
 
if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
131,6 → 139,86
 
/* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */
memsetb((__address) &ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
 
/*
* Second, free all empty tables along the way from PTL3 down to PTL0.
*/
/* check PTL3 */
for (i = 0; i < PTL3_ENTRIES; i++) {
if (PTE_VALID(&ptl3[i])) {
empty = false;
break;
}
}
if (empty) {
/*
* PTL3 is empty.
* Release the frame and remove PTL3 pointer from preceding table.
*/
frame_free(ADDR2PFN(KA2PA((__address) ptl3)));
if (PTL2_ENTRIES)
memsetb((__address) &ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0);
else if (PTL1_ENTRIES)
memsetb((__address) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
else
memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
} else {
/*
* PTL3 is not empty.
* Therefore, there must be a path from PTL0 to PTL3 and
* thus nothing to free in higher levels.
*/
return;
}
/* check PTL2, empty is still true */
if (PTL2_ENTRIES) {
for (i = 0; i < PTL2_ENTRIES; i++) {
if (PTE_VALID(&ptl2[i])) {
empty = false;
break;
}
}
if (empty) {
/*
* PTL2 is empty.
* Release the frame and remove PTL2 pointer from preceding table.
*/
frame_free(ADDR2PFN(KA2PA((__address) ptl2)));
if (PTL1_ENTRIES)
memsetb((__address) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
else
memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
}
else {
/*
* PTL2 is not empty.
* Therefore, there must be a path from PTL0 to PTL2 and
* thus nothing to free in higher levels.
*/
return;
}
}
 
/* check PTL1, empty is still true */
if (PTL1_ENTRIES) {
for (i = 0; i < PTL1_ENTRIES; i++) {
if (PTE_VALID(&ptl1[i])) {
empty = false;
break;
}
}
if (empty) {
/*
* PTL1 is empty.
* Release the frame and remove PTL1 pointer from preceding table.
*/
frame_free(ADDR2PFN(KA2PA((__address) ptl1)));
memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
}
}
 
}
 
/** Find mapping for virtual page in hierarchical page tables.
/kernel/trunk/arch/amd64/include/mm/page.h
47,6 → 47,11
# define PA2KA(x) ((x) + 0xffffffff80000000)
#endif
 
#define PTL0_ENTRIES_ARCH 512
#define PTL1_ENTRIES_ARCH 512
#define PTL2_ENTRIES_ARCH 512
#define PTL3_ENTRIES_ARCH 512
 
#define PTL0_INDEX_ARCH(vaddr) (((vaddr)>>39)&0x1ff)
#define PTL1_INDEX_ARCH(vaddr) (((vaddr)>>30)&0x1ff)
#define PTL2_INDEX_ARCH(vaddr) (((vaddr)>>21)&0x1ff)
73,6 → 78,8
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) set_pt_flags((pte_t *)(ptl2), (index_t)(i), (x))
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))
 
#define PTE_VALID_ARCH(p) (*((__u64 *) (p)) != 0)
 
#ifndef __ASM__
 
/** Page Table Entry. */
/kernel/trunk/arch/mips32/include/mm/page.h
58,6 → 58,11
* - PTL3 has 4096 entries (12 bits)
*/
#define PTL0_ENTRIES_ARCH 64
#define PTL1_ENTRIES_ARCH 0
#define PTL2_ENTRIES_ARCH 0
#define PTL3_ENTRIES_ARCH 4096
 
#define PTL0_INDEX_ARCH(vaddr) ((vaddr)>>26)
#define PTL1_INDEX_ARCH(vaddr) 0
#define PTL2_INDEX_ARCH(vaddr) 0
85,6 → 90,8
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))
 
#define PTE_VALID_ARCH(p) (*((__u32 *) (p)) != 0)
 
#ifndef __ASM__
 
#include <arch/mm/tlb.h>
/kernel/trunk/arch/ia32/include/mm/page.h
44,6 → 44,11
* Implementation of generic 4-level page table interface.
* IA-32 has 2-level page tables, so PTL1 and PTL2 are left out.
*/
#define PTL0_ENTRIES_ARCH 1024
#define PTL1_ENTRIES_ARCH 0
#define PTL2_ENTRIES_ARCH 0
#define PTL3_ENTRIES_ARCH 1024
 
#define PTL0_INDEX_ARCH(vaddr) (((vaddr)>>22)&0x3ff)
#define PTL1_INDEX_ARCH(vaddr) 0
#define PTL2_INDEX_ARCH(vaddr) 0
70,6 → 75,8
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))
 
#define PTE_VALID_ARCH(p) (*((__u32 *) (p)) != 0)
 
#ifndef __ASM__
 
#include <mm/page.h>