#include <mapping_struct.h>
#include <kmalloc.h>
#include <i386.h>
#include <string.h>
#include <stddef.h>
#define TABLE_INDEX(offset) ((offset) / PAGE_SIZE)
#define DIR_INDEX(offset) ((offset) / PAGE_SIZE / (PAGE_SIZE / 4))
void mapping_init(struct mapping_struct *mapping)
{
mapping->directory = NULL;
}
void mapping_destroy(struct mapping_struct *mapping)
{
unsigned long **dir_ent;
if (mapping->directory) {
for (dir_ent = &mapping->directory[0]; dir_ent < &mapping->directory[PAGE_SIZE / 4]; dir_ent++)
if (*dir_ent)
kfree(*dir_ent, PAGE_SIZE);
kfree(mapping->directory, PAGE_SIZE);
}
}
void mapping_copy(const struct mapping_struct *src, struct mapping_struct *dest)
{
dest->directory = src->directory;
}
unsigned long mapping_get_page_frame(const struct mapping_struct *mapping, unsigned long offset)
{
unsigned long *table;
if (!mapping->directory)
return 0;
if (!(table = mapping->directory[DIR_INDEX(offset)]))
return 0;
return table[TABLE_INDEX(offset)];
}
void mapping_set_page_frame(struct mapping_struct *mapping, unsigned long offset, unsigned long page_frame)
{
unsigned long *table;
if (!mapping->directory) {
if (!(mapping->directory = kmalloc(PAGE_SIZE)))
return;
memset(mapping->directory, 0, PAGE_SIZE);
}
if (!(table = mapping->directory[DIR_INDEX(offset)])) {
if (!(table = kmalloc(PAGE_SIZE)))
return;
memset(table, 0, PAGE_SIZE);
mapping->directory[DIR_INDEX(offset)] = table;
}
table[TABLE_INDEX(offset)] = page_frame;
}
void mapping_delete_page_frame(struct mapping_struct *mapping, unsigned long offset, unsigned long page_frame)
{
unsigned long *table;
if (!mapping->directory)
return;
if (!(table = mapping->directory[DIR_INDEX(offset)]))
return;
if (table[TABLE_INDEX(offset)] == page_frame)
table[TABLE_INDEX(offset)] = 0;
}