Xyris  0.5
Memory Namespace Reference

Namespaces

 Physical
 

Data Structures

class  MemoryMap
 
class  Section
 

Enumerations

enum  Type {
  Available, Reserved, ACPI, NVS,
  Bad, Bootloader, Kernel, Unknown
}
 

Functions

 KERNEL_PARAM (enableMappingLogs, MAPPING_OUTPUT_FLAG, argumentsCallback)
 
void init (MemoryMap *map)
 
void mapKernelPage (Arch::Memory::Address vaddr, Arch::Memory::Address paddr)
 
void mapKernelRangeVirtual (Section sect)
 
void mapKernelRangePhysical (Section sect)
 
void * newPage (size_t size)
 
void freePage (void *page, size_t size)
 
bool isPresent (uintptr_t addr)
 
uintptr_t getPageDirPhysAddr ()
 

Enumeration Type Documentation

◆ Type

Enumerator
Available 
Reserved 
ACPI 
NVS 
Bad 
Bootloader 
Kernel 
Unknown 

Definition at line 18 of file MemorySection.hpp.

18  {
19  Available,
20  Reserved,
21  ACPI,
22  NVS,
23  Bad,
24  Bootloader,
25  Kernel,
26  Unknown
27 };

Function Documentation

◆ freePage()

void Memory::freePage ( void *  page,
size_t  size 
)

Frees pages starting at a given page address.

Parameters
pageStarting location of page(s) to be freed
sizeNumber of bytes to be freed

Definition at line 246 of file paging.cpp.

247 {
248  RAIIMutex lock(pagingLock);
249  size_t page_count = PAGE_COUNT(size);
250  Arch::Memory::Address addr((uintptr_t)page);
251  for (size_t i = addr.page().tableIndex; i < addr.page().tableIndex + page_count; i++) {
252  mappedPages.Reset(i);
253  // this is the same as the line above
254  struct Arch::Memory::TableEntry* pte = &(pageTables[i / ARCH_PAGE_TABLE_ENTRIES].pages[i % ARCH_PAGE_TABLE_ENTRIES]);
255  // the frame field is actually the page frame's index basically it's frame 0, 1...(2^21-1)
256  physical.setFree(pte->frame);
257  // zero it out to unmap it
258  memset(pte, 0, sizeof(struct Arch::Memory::TableEntry));
259  // clear that tlb
260  Arch::Memory::pageInvalidate(page);
261  }
262 }
+ Here is the caller graph for this function:

◆ getPageDirPhysAddr()

uintptr_t Memory::getPageDirPhysAddr ( )

Gets the physical address of the current page directory.

Returns
the physical address of the current page directory.

Definition at line 272 of file paging.cpp.

273 {
274  return pageDirectoryAddress;
275 }

◆ init()

void Memory::init ( MemoryMap map)

Sets up the environment, page directories etc and enables paging.

Definition at line 57 of file paging.cpp.

58 {
59  // we can set breakpoints or make a futile attempt to recover.
61  // populate the physical memory map based on bootloader information
62  initPhysical(map);
63  // init our structures
64  initDirectory();
65  // identity map the first 1 MiB of RAM
66  mapEarlyMem();
67  // map in our higher-half kernel
68  mapKernel();
69  // use our new set of page tables
70  Arch::Memory::setPageDirectory(Arch::Memory::pageAlign(pageDirectoryAddress));
71  // flush the tlb and we're off to the races!
73 }

◆ isPresent()

bool Memory::isPresent ( uintptr_t  addr)

Checks whether an address is mapped into memory.

Parameters
addrAddress to be checked.
Returns
true The address is mapped in and valid.
false The address is not mapped into memory.

Definition at line 264 of file paging.cpp.

265 {
266  // Convert the address into an index and check whether the page is in the bitmap
267  // TODO: Fix this function. It's inaccurate and can result in triple faults.
268  return mappedPages[addr >> ARCH_PAGE_TABLE_ENTRY_SHIFT];
269 }

◆ KERNEL_PARAM()

Memory::KERNEL_PARAM ( enableMappingLogs  ,
MAPPING_OUTPUT_FLAG  ,
argumentsCallback   
)

◆ mapKernelPage()

void Memory::mapKernelPage ( Arch::Memory::Address  vaddr,
Arch::Memory::Address  paddr 
)

Map a page into the kernel address space.

Parameters
vaddrVirtual address (in kernel space)
paddrPhysical address

Definition at line 147 of file paging.cpp.

148 {
149  // Set the page directory entry (pde) and page table entry (pte)
150  size_t pde = vaddr.page().dirIndex;
151  size_t pte = vaddr.page().tableIndex;
152 
153  // Print a debug message to serial
154  if (is_mapping_output_enabled) {
155  Logger::Debug(__func__, "map 0x%08lx to 0x%08lx, pde = 0x%08lx, pte = 0x%08lx", paddr.val(), vaddr.val(), pde, pte);
156  }
157 
158  // If the page's virtual address is not aligned
159  if (vaddr.page().offset) {
160  panicf("Attempted to map a non-page-aligned virtual address.\n(Address: 0x%08lX)\n", vaddr.val());
161  }
162 
163  // If the page is already mapped into memory
164  Arch::Memory::TableEntry* entry = &(pageTables[pde].pages[pte]);
165  if (entry->present) {
166  if (entry->frame == paddr.frame().index) {
167  // this page was already mapped the same way
168  return;
169  }
170 
171  panic("Attempted to map already mapped page.\n");
172  }
173  // Set the page information
174  pageTables[pde].pages[pte] = {
175  .present = 1, // The page is present
176  .readWrite = 1, // The page has r/w permissions
177  .usermode = 0, // These are kernel pages
178  .writeThrough = 0, // Disable write through
179  .cacheDisable = 0, // The page is cached
180  .accessed = 0, // The page is unaccessed
181  .dirty = 0, // The page is clean
182  .pageAttrTable = 0, // The page has no attribute table
183  .global = 0, // The page is local
184  .unused = 0, // Ignored
185  .frame = paddr.frame().index, // The last 20 bits are the frame
186  };
187  // Set the associated bit in the bitmaps
188  physical.setUsed(paddr);
189  mappedPages.Set(vaddr.frame().index);
190 }
+ Here is the caller graph for this function:

◆ mapKernelRangePhysical()

void Memory::mapKernelRangePhysical ( Section  sect)

Map a kernel address range into physical memory.

Parameters
sectMemory section

Definition at line 199 of file paging.cpp.

200 {
201  for (Arch::Memory::Address a(sect.base()); a < sect.end(); a += ARCH_PAGE_SIZE) {
202  Arch::Memory::Address phys(KADDR_TO_PHYS(a));
203  mapKernelPage(a, phys);
204  }
205 }
+ Here is the call graph for this function:

◆ mapKernelRangeVirtual()

void Memory::mapKernelRangeVirtual ( Section  sect)

Map an address range into the kernel virtual address space.

Parameters
sectMemory section

Definition at line 192 of file paging.cpp.

193 {
194  for (Arch::Memory::Address a(sect.base()); a < sect.end(); a += ARCH_PAGE_SIZE) {
195  mapKernelPage(a, a);
196  }
197 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ newPage()

void * Memory::newPage ( size_t  size)

Returns a new page in memory for use. If less than one page is requested, exactly one page will be allocated and returned.

Parameters
sizePage size in bytes
Returns
void* Page memory address

Definition at line 228 of file paging.cpp.

229 {
230  RAIIMutex lock(pagingLock);
231  size_t page_count = PAGE_COUNT(size);
232  size_t free_idx = findNextFreeVirtualAddress(page_count);
233  if (free_idx == SIZE_MAX)
234  return NULL;
235  for (size_t i = free_idx; i < free_idx + page_count; i++) {
236  size_t phys_page_idx = physical.findNextFreePhysicalAddress();
237  if (phys_page_idx == SIZE_MAX)
238  return NULL;
239  Arch::Memory::Address phys(phys_page_idx * ARCH_PAGE_SIZE);
240  Arch::Memory::Address vaddr(i * ARCH_PAGE_SIZE);
241  mapKernelPage(vaddr, phys);
242  }
243  return (void*)(free_idx * ARCH_PAGE_SIZE);
244 }
+ Here is the caller graph for this function:
size
uint16_t size
Definition: regs.hpp:2
Arch::Memory::pagingEnable
void pagingEnable()
Enable hardware paging.
Definition: Arch.i686.cpp:94
Memory::ACPI
@ ACPI
Definition: MemorySection.hpp:21
Memory::mapKernelPage
void mapKernelPage(Arch::Memory::Address vaddr, Arch::Memory::Address paddr)
Map a page into the kernel address space.
Definition: paging.cpp:147
Bitset::Set
void Set(size_t pos)
Set the bit for a given position.
Definition: Bitset.hpp:60
Interrupts::EXCEPTION_PAGE_FAULT
@ EXCEPTION_PAGE_FAULT
Definition: isr.hpp:40
ARCH_PAGE_TABLE_ENTRY_SHIFT
#define ARCH_PAGE_TABLE_ENTRY_SHIFT
Definition: Memory.i686.hpp:24
ARCH_PAGE_TABLE_ENTRIES
#define ARCH_PAGE_TABLE_ENTRIES
Definition: Memory.i686.hpp:20
Memory::Physical::PhysicalManager::setFree
void setFree(Section &sect)
Definition: Physical.hpp:33
Interrupts::registerHandler
void registerHandler(uint8_t interrupt, InterruptHandler_t handler)
Definition: isr.cpp:98
Memory::NVS
@ NVS
Definition: MemorySection.hpp:22
Memory::Bad
@ Bad
Definition: MemorySection.hpp:23
PAGE_COUNT
#define PAGE_COUNT(s)
Definition: paging.cpp:26
panicf
void panicf(const char *fmt,...)
Halt the system and print the provided message and arguments on the panic screen.
Definition: Panic.cpp:87
Memory::Reserved
@ Reserved
Definition: MemorySection.hpp:20
Logger::Debug
static void Debug(const char *tag, const char *fmt,...)
Definition: Logger.cpp:71
RAIIMutex
Definition: RAII.hpp:16
panic
void panic(const char *msg)
Halt the system and print the provided message on the panic screen.
Definition: Panic.cpp:82
Memory::Physical::PhysicalManager::setUsed
void setUsed(Section &sect)
Definition: Physical.hpp:40
ARCH_PAGE_SIZE
#define ARCH_PAGE_SIZE
Definition: Memory.i686.hpp:21
memset
void * memset(void *bufptr, int value, size_t size)
Sets the number of bytes in memory at ptr to the value.
Definition: string.cpp:106
KADDR_TO_PHYS
#define KADDR_TO_PHYS(addr)
Definition: Physical.hpp:20
Memory::Kernel
@ Kernel
Definition: MemorySection.hpp:25
Memory::Available
@ Available
Definition: MemorySection.hpp:19
Memory::Unknown
@ Unknown
Definition: MemorySection.hpp:26
Memory::Physical::PhysicalManager::findNextFreePhysicalAddress
uintptr_t findNextFreePhysicalAddress()
Definition: Physical.hpp:100
Memory::Bootloader
@ Bootloader
Definition: MemorySection.hpp:24
Bitset::Reset
void Reset(size_t pos)
Reset (clear) the bit at the given position.
Definition: Bitset.hpp:70