1,5 → 1,5 |
/* |
* Copyright (c) 2003-2004 Jakub Jermar |
* Copyright (c) 2007 Pavel Jancik, Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,23 → 30,81 |
* @{ |
*/ |
/** @file |
* @brief Paging related functions. |
*/ |
|
#include <arch/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <mm/page.h> |
#include <align.h> |
#include <config.h> |
#include <arch/exception.h> |
#include <typedefs.h> |
#include <arch/types.h> |
#include <interrupt.h> |
#include <arch/mm/frame.h> |
|
/** Initializes page tables. |
* |
* 1:1 virtual-physical mapping is created in kernel address space. Mapping |
* for table with exception vectors is also created. |
*/ |
void page_arch_init(void) |
{ |
uintptr_t cur; |
int flags; |
|
page_mapping_operations = &pt_mapping_operations; |
|
flags = PAGE_CACHEABLE; |
|
/* PA2KA(identity) mapping for all frames until last_frame */ |
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); |
} |
|
/** Map device into kernel space. */ |
/* create mapping for exception table at high offset */ |
#ifdef HIGH_EXCEPTION_VECTORS |
void *virtaddr = frame_alloc(ONE_FRAME, FRAME_KA); |
page_mapping_insert(AS_KERNEL, EXC_BASE_ADDRESS, KA2PA(virtaddr), flags); |
#else |
#error "Only high exception vector supported now" |
#endif |
|
as_switch(NULL, AS_KERNEL); |
|
boot_page_table_free(); |
} |
|
/** Maps device into the kernel space. |
* |
* Maps physical address of device into kernel virtual address space (so it can |
* be accessed only by kernel through virtual address). |
* |
* @param physaddr Physical address where device is connected. |
* @param size Length of area where device is present. |
* |
* @return Virtual address where device will be accessible. |
*/ |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
/* TODO */ |
return NULL; |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > |
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) { |
panic("Unable to map physical memory %p (%d bytes)", |
physaddr, size) |
} |
|
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) { |
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), |
physaddr + PFN2ADDR(i), |
PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL); |
} |
|
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); |
return virtaddr; |
} |
|
/** @} |
*/ |