Created
March 2, 2023 10:20
-
-
Save pcercuei/0dc33dbf8d532a52ff5c986091337565 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <errno.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <kos.h> | |
static volatile uint32_t * const pteh = (uint32 *)(0xff000000); | |
static volatile uint32_t * const ptel = (uint32 *)(0xff000004); | |
static volatile uint32_t * const mmucr = (uint32 *)(0xff000010); | |
#define BUILD_PTEH(VA, ASID) \ | |
( ((VA) & 0xfffffc00) | ((ASID) & 0xff) ) | |
#define SET_PTEH(VA, ASID) \ | |
do { *pteh = BUILD_PTEH(VA, ASID); } while(0) | |
#define BUILD_PTEL(PA, V, SZ, PR, C, D, SH, WT) \ | |
( ((PA) & 0x1ffffc00) | ((V) << 8) \ | |
| ( ((SZ) & 2) << 6 ) | ( ((SZ) & 1) << 4 ) \ | |
| ( (PR) << 5 ) \ | |
| ( (C) << 3 ) \ | |
| ( (D) << 2 ) \ | |
| ( (SH) << 1 ) \ | |
| ( (WT) << 0 ) ) | |
#define SET_PTEL(PA, V, SZ, PR, C, D, SH, WT) \ | |
do { *ptel = BUILD_PTEL(PA, V, SZ, PR, C, D, SH, WT); } while (0) | |
#define SET_MMUCR(URB, URC, SQMD, SV, TI, AT) \ | |
do { *mmucr = ((URB) << 18) \ | |
| ((URC) << 10) \ | |
| ((SQMD) << 9) \ | |
| ((SV) << 8) \ | |
| ((TI) << 2) \ | |
| ((AT) << 0); } while(0) | |
#define SET_URC(URC) \ | |
do { *mmucr = (*mmucr & ~(63 << 10)) \ | |
| (((URC) & 63) << 10); } while(0) | |
#define GET_URC() ((*mmucr >> 10) & 63) | |
#define INCR_URC() \ | |
do { SET_URC(GET_URC() + 1); } while(0) | |
KOS_INIT_FLAGS(INIT_DEFAULT); | |
enum page_size { | |
PAGE_SIZE_1K, | |
PAGE_SIZE_4K, | |
PAGE_SIZE_64K, | |
PAGE_SIZE_1M, | |
}; | |
enum page_prot { | |
PAGE_PROT_RO, | |
PAGE_PROT_RW, | |
PAGE_PROT_RO_U, | |
PAGE_PROT_RW_U, | |
}; | |
static int map_page(void *ptr, uint32_t virt_addr, enum page_size size) | |
{ | |
unsigned int page_mask[] = { 0x3ff, 0xfff, 0xffff, 0xfffff }; | |
uint32_t phys_addr = (uint32_t)ptr; | |
if (phys_addr & virt_addr & page_mask[size]) | |
return -EINVAL; | |
SET_PTEH(virt_addr, 0); | |
SET_PTEL(phys_addr, 1, size, PAGE_PROT_RW, 1, 0, 0, 0); | |
__asm__("ldtlb"); | |
INCR_URC(); | |
return 0; | |
} | |
void mmu_reset_itlb(); | |
int main(void) | |
{ | |
unsigned int i; | |
char *addr; | |
int err; | |
fclose(stdout); | |
stdout = stderr; | |
printf("Hello world.\n"); | |
/* Turn ON MMU */ | |
SET_MMUCR(0x3f, 0, 0, 1, 1, 1); | |
mmu_reset_itlb(); | |
printf("MMU enabled.\n"); | |
addr = aligned_alloc(1024 * 1024, 2 * 1024 * 1024); | |
if (!addr) { | |
printf("Could not allocate memory\n"); | |
return 1; | |
} | |
printf("Memory allocated to 0x%x\n", (unsigned int)addr); | |
err = map_page(addr, 0x0, PAGE_SIZE_1M); | |
if (err) | |
goto handle_err; | |
printf("Mapped correctly!\n"); | |
*(unsigned int *)addr = 0xdeadbeef; | |
printf("Reading from virtual memory: 0x%x\n", *(unsigned int *)0x0); | |
handle_err: | |
if (err) | |
printf("Could not map page: %d\n", err); | |
printf("Free address\n"); | |
free(addr); | |
#if 1 | |
/* Turn OFF MMU */ | |
*mmucr = 0x00000204; | |
#endif | |
return err != 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment