#include <Errors.h>
#include <OS.h>
#include <string.h>
#include "debug.h"
#include "util.h"
spinlock slock = B_SPINLOCK_INITIALIZER;
uint32 round_to_pagesize(uint32 size);
cpu_status
lock(void)
{
cpu_status status = disable_interrupts();
acquire_spinlock(&slock);
return status;
}
void
unlock(cpu_status status)
{
release_spinlock(&slock);
restore_interrupts(status);
}
uint32
round_to_pagesize(uint32 size)
{
return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
}
area_id
alloc_mem(phys_addr_t *phy, void **log, size_t size, const char *name, bool user)
{
physical_entry pe;
void * logadr;
area_id area;
status_t rv;
uint32 protection;
LOG(("allocating %d bytes for %s\n",size,name));
protection = B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA;
if (user)
protection = B_READ_AREA | B_WRITE_AREA;
size = round_to_pagesize(size);
area = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS, size,
B_32_BIT_CONTIGUOUS, protection);
if (area < B_OK) {
PRINT(("couldn't allocate area %s\n", name));
return B_ERROR;
}
rv = get_memory_map(logadr, size, &pe, 1);
if (rv < B_OK) {
delete_area(area);
PRINT(("couldn't map %s\n",name));
return B_ERROR;
}
if (user)
user_memset(logadr, 0, size);
else
memset(logadr, 0, size);
if (log)
*log = logadr;
if (phy)
*phy = pe.address;
LOG(("area = %d, size = %d, log = %#08X, phy = %#08X\n", area, size, logadr,
pe.address));
return area;
}
area_id
map_mem(void **log, phys_addr_t phy, size_t size, const char *name)
{
uint32 offset;
phys_addr_t phyadr;
void *mapadr;
area_id area;
LOG(("mapping physical address %p with %#x bytes for %s\n",phy,size,name));
offset = (uint32)phy & (B_PAGE_SIZE - 1);
phyadr = phy - offset;
size = round_to_pagesize(size + offset);
area = map_physical_memory(name, phyadr, size, B_ANY_KERNEL_ADDRESS,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, &mapadr);
*log = (void *)((uintptr_t)mapadr + (uintptr_t)offset);
LOG(("physical = %p, logical = %p, offset = %#x, phyadr = %p, mapadr = %p, size = %#x, area = %#x\n",
phy, *log, offset, phyadr, mapadr, size, area));
return area;
}