Skip to content

Instantly share code, notes, and snippets.

@pcercuei
Created March 2, 2023 10:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pcercuei/0dc33dbf8d532a52ff5c986091337565 to your computer and use it in GitHub Desktop.
Save pcercuei/0dc33dbf8d532a52ff5c986091337565 to your computer and use it in GitHub Desktop.
#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