return(ret_val);
}
+int pg_dir_clone_region(pg_dir_t *dpd, pg_dir_t *spd, region_t *reg)
+{
+ int ret_val;
+ int idx;
+
+ ret_val = -EFAULT;
+
+ /* like in pg_dir_map_region(), get a slot for the new region */
+ for(idx = 0; idx < CONFIG_PAGING_DIR_MAXREGIONS; idx++) {
+ if(!dpd->pd_regions[idx]) {
+ break;
+ }
+ }
+
+ if(idx >= CONFIG_PAGING_DIR_MAXREGIONS) {
+ ret_val = -ERANGE;
+ goto gtfo;
+ }
+
+ /* attempt to map the region */
+ ret_val = pg_dir_map(dpd, NULL, reg->reg_base,
+ reg->reg_size, reg->reg_attrs);
+
+ if(ret_val < 0) {
+ goto gtfo;
+ }
+
+ /* copy the contents of the region */
+ ret_val = pg_dir_memcpy(dpd, reg->reg_base,
+ spd, reg->reg_base,
+ reg->reg_size);
+
+ if(ret_val >= 0) {
+ /* also keep track of the region */
+ ret_val = _pg_dir_add_region(dpd, reg->reg_base, reg->reg_size,
+ reg->reg_type, reg->reg_attrs, reg->reg_flags);
+ }
+
+ if(ret_val < 0) {
+ /* if pg_dir_memcpy() or _pg_dir_add_region() failed, undo the mapping */
+ pg_dir_unmap(dpd, reg->reg_base, reg->reg_size);
+ }
+
+gtfo:
+ return(ret_val);
+}
+
int pg_dir_unmap(pg_dir_t *pd, const void *base, const u32_t size)
{
return(-ENOSYS);
int pg_dir_map(pg_dir_t*, const void*, const void*, const u32_t, const u32_t);
int pg_dir_map_region(pg_dir_t*, pg_dir_t*, region_t*);
+int pg_dir_clone_region(pg_dir_t*, pg_dir_t*, region_t*);
int pg_dir_unmap(pg_dir_t*, const void*, const u32_t);
void* pg_dir_get_pdbr(pg_dir_t*);