return(ret_val);
}
+int _pg_dir_memset(struct pagedir *ddir, void *dvaddr, int c, u32_t n)
+{
+ int ret_val;
+ u32_t dpaddr;
+ u32_t wsize;
+
+ ret_val = _pg_dir_vpxlate(ddir, (u32_t)dvaddr, (u32_t*)&dpaddr);
+
+ if(ret_val < 0) {
+ goto gtfo;
+ }
+
+ /*
+ * Calculate the number of bytes we can set without crossing
+ * page boundaries, writing into possibly unrelated pages.
+ */
+ ret_val = _pg_dir_pagesize(ddir, (u32_t)dvaddr, &wsize);
+
+ if(ret_val < 0) {
+ goto gtfo;
+ }
+
+ wsize = ALIGN((u32_t)dvaddr, wsize) - (u32_t)dvaddr;
+
+ memset((void*)dpaddr, c, wsize);
+ ret_val = (int)wsize;
+
+gtfo:
+ return(ret_val);
+}
+
+int pg_dir_memset(struct pagedir *ddir, void *dvaddr,
+ int c, u32_t n)
+{
+ int ret_val;
+
+ ret_val = 0;
+
+ if(!ddir) {
+ /* kernel pagedir - just call memset() */
+ memset(dvaddr, c, n);
+ return((int)n);
+ }
+
+ while(n > 0) {
+ int set;
+
+ set = _pg_dir_memset(ddir, dvaddr, c, n);
+
+ if(set < 0) {
+ ret_val = set;
+ break;
+ }
+
+ dvaddr += set;
+ n -= set;
+ ret_val += set;
+ }
+
+ return(ret_val);
+}
+
int _pg_dir_xfer(struct pagedir *ddir, void *dvaddr,
struct pagedir *sdir, void *svaddr, u32_t bytes)
{
}
static int _pg_dir_add_region(pg_dir_t *pd, void *base, u32_t size,
- u32_t type, u32_t attrs, u32_t flags)
+ u32_t type, u32_t attrs, u32_t flags)
{
struct region *reg;
int ret_val;
return;
}
-int pg_dir_mmap(pg_dir_t *pgdir, void *addr, u32_t size, int prot, int flags, void **dst)
+int pg_dir_mmap(pg_dir_t *pgdir, void *addr, u32_t size,
+ int prot, int flags, void **dst)
{
int ret_val;
ret_val = -EINVAL;
if(pgdir && dst) {
+ u32_t attrs;
+ u32_t rflags;
+ void* vaddr;
+ void* paddr;
+
ret_val = -EFAULT;
/* FIXME: Lock the page directory */
- if(flags & MAP_PHYS) {
- u32_t attrs;
+ attrs = PAGE_ATTR_PRESENT;
- /* map the physical memory addr:size into the page directory */
- /* FIXME: Add another flag for identity mappings and otherwise map non-identically */
+ if(!(prot & PROT_EXEC)) {
+ attrs |= PAGE_ATTR_NO_EXEC;
+ }
- attrs = PAGE_ATTR_PRESENT;
+ if(prot & PROT_WRITE) {
+ attrs |= PAGE_ATTR_WRITABLE;
+ }
- if(!(prot & PROT_EXEC)) {
- attrs |= PAGE_ATTR_NO_EXEC;
- }
+ if(prot & PROT_READ) {
+ attrs |= PAGE_ATTR_USER;
+ }
- if(prot & PROT_WRITE) {
- attrs |= PAGE_ATTR_WRITABLE;
- }
+ rflags = REGION_PRIV;
- if(prot & PROT_READ) {
- attrs |= PAGE_ATTR_USER;
- }
+ if(flags & MAP_PHYS) {
+ /*
+ * Map the physical memory addr:size into
+ * the page directory
+ */
- ret_val = pg_dir_map(pgdir, addr, addr, size, attrs);
+ vaddr = addr;
+ paddr = addr;
+ rflags = REGION_SHARED;
+ }
- if(!ret_val) {
- /* also account for the new region */
- ret_val = _pg_dir_add_region(pgdir, addr, size,
- REGION_MMAP, 0, REGION_SHARED);
+ /*
+ * FIXME: Add another flag for identity mappings and
+ * otherwise map non-identically
+ */
+ ret_val = pg_dir_map(pgdir, paddr, vaddr, size, attrs);
- /* or unmap if it can't be accounted for */
- if(ret_val < 0) {
- pg_dir_unmap(pgdir, addr, size);
- }
+ if(!ret_val) {
+ /* also account for the new region */
+ ret_val = _pg_dir_add_region(pgdir, addr, size,
+ REGION_MMAP, 0,
+ rflags);
+
+ /* or unmap if it can't be accounted for */
+ if(ret_val < 0) {
+ pg_dir_unmap(pgdir, addr, size);
}
}