Compare commits
2 commits
0014a79ecb
...
b99db4048d
| Author | SHA1 | Date | |
|---|---|---|---|
| b99db4048d | |||
| ba6a17373e |
7 changed files with 42 additions and 13 deletions
|
|
@ -26,6 +26,7 @@ struct va va_from_vpn(struct vpn vpn);
|
|||
struct va va_from_vpn_with_offset(struct vpn vpn, uint64_t offset);
|
||||
uint64_t va_to_value(struct va va);
|
||||
uint64_t va_to_canonical(struct va va);
|
||||
uint64_t va_offset(struct va va);
|
||||
|
||||
struct vpn vpn_from_pagenum(uint64_t pagenum);
|
||||
struct vpn vpn_from_aligned_va(struct va va);
|
||||
|
|
@ -37,6 +38,7 @@ struct pa pa_from_ppn(struct ppn ppn);
|
|||
struct pa pa_from_ppn_with_offset(struct ppn ppn, uint64_t offset);
|
||||
uint64_t pa_to_value(struct pa pa);
|
||||
void *pa_to_pointer(struct pa pa);
|
||||
uint64_t pa_offset(struct pa pa);
|
||||
|
||||
struct ppn ppn_from_pagenum(uint64_t pagenum);
|
||||
struct ppn ppn_from_aligned_pa(struct pa pa);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ void out8(int port, uint8_t value);
|
|||
void out16(int port, uint16_t value);
|
||||
void out32(int port, uint32_t value);
|
||||
|
||||
uint64_t get_cr0(void);
|
||||
uint64_t get_cr3(void);
|
||||
uint64_t get_cr4(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ struct mem_range {
|
|||
uint64_t npages;
|
||||
};
|
||||
|
||||
void mem_range_print(const struct mem_range *mr);
|
||||
|
||||
struct mem_range_buf {
|
||||
struct mem_range *ptr;
|
||||
uint64_t next_entry;
|
||||
|
|
@ -57,7 +59,6 @@ struct mem_range_buf {
|
|||
var < (buf)->ptr + (buf)->next_entry; \
|
||||
var++)
|
||||
|
||||
void mem_range_print(const struct mem_range *mr);
|
||||
void pt_get_ranges(struct mem_range_buf *buf_out);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -189,6 +189,8 @@ void _start() {
|
|||
printf("stack: %p -> %p\n", &temp_local_var, stack_phys);
|
||||
printf("code: %p -> %p\n", &check_initrd, code_phys);
|
||||
|
||||
uint64_t cr0 = get_cr0();
|
||||
printf("wp=%d\n", (cr0 >> 16) & 1);
|
||||
// hang for now
|
||||
PANIC("end of kernel");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@ uint64_t va_to_canonical(struct va va) {
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t va_offset(struct va va) {
|
||||
return va.value & 0xfff;
|
||||
}
|
||||
|
||||
struct vpn vpn_from_pagenum(uint64_t pagenum) {
|
||||
ASSERT(pagenum < (1ull << 36));
|
||||
return (struct vpn){ .pagenum = pagenum };
|
||||
|
|
@ -81,6 +85,10 @@ void *pa_to_pointer(struct pa pa) {
|
|||
return (void*)PHYS_TO_IDMAPPED(pa.value);
|
||||
}
|
||||
|
||||
uint64_t pa_offset(struct pa pa) {
|
||||
return pa.value & 0xfff;
|
||||
}
|
||||
|
||||
struct ppn ppn_from_pagenum(uint64_t pagenum) {
|
||||
ASSERT(pagenum < (1ull << 24));
|
||||
return (struct ppn){ .pagenum = pagenum };
|
||||
|
|
|
|||
|
|
@ -30,8 +30,20 @@ void out32(int port, uint32_t value) {
|
|||
__asm__("outl %%dx" ::"d"(port), "a"(value));
|
||||
}
|
||||
|
||||
uint64_t get_cr0(void) {
|
||||
uint64_t cr0;
|
||||
__asm__("mov %%cr0, %0" : "=r"(cr0)::);
|
||||
return cr0;
|
||||
}
|
||||
|
||||
uint64_t get_cr3(void) {
|
||||
uint64_t cr3;
|
||||
__asm__("mov %%cr3, %0" : "=r"(cr3)::);
|
||||
return cr3;
|
||||
}
|
||||
|
||||
uint64_t get_cr4(void) {
|
||||
uint64_t cr4;
|
||||
__asm__("mov %%cr4, %0" : "=r"(cr4)::);
|
||||
return cr4;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ bool pt_translate(struct va va, struct ppn cr3, struct pa *pa_out) {
|
|||
}
|
||||
struct pt_entry ent;
|
||||
pt_entry_unpack(*leaf_ptr, &ent);
|
||||
*pa_out = pa_from_ppn_with_offset(ent.ppn, va_to_value(va) & 0xfff); // TODO offset func
|
||||
*pa_out = pa_from_ppn_with_offset(ent.ppn, va_offset(va));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -270,6 +270,17 @@ void mem_range_print(const struct mem_range *mr) {
|
|||
mr->npages << 12);
|
||||
}
|
||||
|
||||
static bool pt_contiguous(struct mem_range *mr, struct vpn vpn, struct pt_entry *ent) {
|
||||
return vpn_to_pagenum(vpn) == vpn_to_pagenum(mr->vpn_start) + mr->npages
|
||||
&& ppn_to_pagenum(ent->ppn) == ppn_to_pagenum(mr->entry_start.ppn) + mr->npages
|
||||
&& ent->writable == mr->entry_start.writable
|
||||
&& ent->supervisor == mr->entry_start.supervisor
|
||||
&& ent->writethrough == mr->entry_start.writethrough
|
||||
&& ent->cache_disable == mr->entry_start.cache_disable
|
||||
&& ent->global == mr->entry_start.global;
|
||||
// TODO should PAT also be same?
|
||||
}
|
||||
|
||||
#define LOWEST_LEVEL(level) ((level) == 1)
|
||||
#define LEAF(level, ent) (LOWEST_LEVEL(level) || (ent).page_attr_table_low)
|
||||
|
||||
|
|
@ -296,15 +307,7 @@ static void pt_get_ranges_rec(struct ppn ppn, int level, uint64_t virt_prev,
|
|||
curr_range->entry_start = ent;
|
||||
curr_range->npages = num_pages_covered;
|
||||
} else {
|
||||
if (vpn_to_pagenum(curr_vpn) == vpn_to_pagenum(curr_range->vpn_start) + curr_range->npages
|
||||
&& ppn_to_pagenum(ent.ppn) == ppn_to_pagenum(curr_range->entry_start.ppn) + curr_range->npages
|
||||
&& ent.writable == curr_range->entry_start.writable
|
||||
&& ent.supervisor == curr_range->entry_start.supervisor
|
||||
&& ent.writethrough == curr_range->entry_start.writethrough
|
||||
&& ent.cache_disable == curr_range->entry_start.cache_disable
|
||||
&& ent.global == curr_range->entry_start.global)
|
||||
// TODO should PAT also be same?
|
||||
{
|
||||
if (pt_contiguous(curr_range, curr_vpn, &ent)) {
|
||||
curr_range->npages += num_pages_covered;
|
||||
} else {
|
||||
// copy last range and start new one
|
||||
|
|
@ -325,8 +328,7 @@ static void pt_get_ranges_rec(struct ppn ppn, int level, uint64_t virt_prev,
|
|||
#define CR4_LA57 12
|
||||
|
||||
void pt_get_ranges(struct mem_range_buf *buf_out) {
|
||||
uint64_t cr4;
|
||||
__asm__("mov %%cr4, %0" : "=r"(cr4)::);
|
||||
uint64_t cr4 = get_cr4();
|
||||
|
||||
// find out if we have 5 levels or 4
|
||||
if (cr4 & (1ull << CR4_LA57)) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue