Compare commits

...

2 commits

Author SHA1 Message Date
b99db4048d
moved out contiguous page checking; get_cr0 and cr4 2025-03-19 18:33:24 +01:00
ba6a17373e
address _offset functions 2025-03-17 16:55:18 +01:00
7 changed files with 42 additions and 13 deletions

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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");
}

View file

@ -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 };

View file

@ -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;
}

View file

@ -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)) {