lib/aos/paging3.c
errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
        struct capref frame, size_t bytes, int flags)
{
    // TODO(M2): Should we get rid of this? probably won't do anything - will already be aligned
    // if they went through paging_alloc. Don't go through - their problem. 
    // align the vaddr
    assert(vaddr % BASE_PAGE_SIZE == 0);
    
    errval_t err;

    struct capref l2;
    
    // round bytes up to page size to get the number of ptes needed to be mapped
    if (bytes % BASE_PAGE_SIZE != 0) {
        bytes += (size_t) BASE_PAGE_SIZE - (bytes % BASE_PAGE_SIZE);
    }

    int pte_count = bytes / BASE_PAGE_SIZE;
    int remaining_ptes, frame_offset;
    frame_offset = 0;

    // TODO(M2): Create a node to keep track of allocated space
    // Should this be here, or in paging_alloc?
    // probably doesn't make a difference
    // insert in the list st keeps track of
    // TODO(M2): Verify that this is correct

    // Use 1 list - make coalescing easier 
    while ( pte_count > 0 )
    {
        // check if l2 pt already exists
        if (st->l2_pts[ARM_L1_OFFSET(vaddr)].initialized == true) {
            l2 = st->l2_pts[ARM_L1_OFFSET(vaddr)].cap;
        }
        // otherwise, allocate the l2 pt
        else {
            err = arml2_alloc(st, &l2);
            if (err_is_fail(err)) {
                debug_printf("arml2_alloc failed: %s\n", err_getstring(err));
                return err;
            }
            // update the l1 pt
            // need to call vnode_map
            struct capref l1mapping;
            err = st->slot_alloc->alloc(st->slot_alloc, &l1mapping);
            if (err_is_fail(err)) {
                debug_printf("slot_alloc failed: %s\n", err_getstring(err));
                return err;
            }

            err = vnode_map(st->l1_pt, l2, ARM_L1_OFFSET(vaddr), VREGION_FLAGS_READ_WRITE, 0, 1, l1mapping);
            if (err_is_fail(err)) {
                debug_printf("vnode_map failed: %s\n", err_getstring(err));
                return err;
            }
            
            // update the page_info struct to include the new l2 pt
            st->l2_pts[ARM_L1_OFFSET(vaddr)].initialized = true;
            st->l2_pts[ARM_L1_OFFSET(vaddr)].cap = l2;
        }
   
        // determine pte_count based on size of frame
        // call slot_alloc to get a capref for mapping ???
        struct capref mapping;
        
        err = st->slot_alloc->alloc(st->slot_alloc, &mapping);
        if (err_is_fail(err)) {
            debug_printf("slot_alloc failed: %s\n", err_getstring(err));
            return err;
        }

        // get the ptes available in this table past the offset
        remaining_ptes = ARM_L2_MAX_ENTRIES - ARM_L2_OFFSET(vaddr);
        if (remaining_ptes < pte_count) {
            err = vnode_map(l2, frame, ARM_L2_OFFSET(vaddr), flags, frame_offset, remaining_ptes, mapping);
            if (err_is_fail(err)) {
                debug_printf("vnode_map failed: %s\n", err_getstring(err));
                return err;
            }
            pte_count -= remaining_ptes;
            vaddr += remaining_ptes * BASE_PAGE_SIZE;
            frame_offset += remaining_ptes * BASE_PAGE_SIZE;

            // struct capref copy;
            // err = st->slot_alloc->alloc(st->slot_alloc, &copy);
            // if (err_is_fail(err)) {
            //     debug_printf("slot_alloc failed: %s\n", err_getstring(err));
            //     return err;
            // }
    
            // err = cap_copy(copy, frame);
            // if (err_is_fail(err)) {
            //     debug_printf("cap_copy failed: %s\n", err_getstring(err));
            //     return err;
            // }
            // frame = copy;
        } 
        else {
            err = vnode_map(l2, frame, ARM_L2_OFFSET(vaddr), flags, frame_offset, pte_count, mapping);
            if (err_is_fail(err)) {
                debug_printf("vnode_map failed: %s\n", err_getstring(err));
                return err;
            }
            pte_count = 0;
        }
    }
    return SYS_ERR_OK;
}
/**
 * \brief map a user provided frame at user provided VA.
 * TODO(M1): Map a frame assuming all mappings will fit into one L2 pt
 * TODO(M2): General case 
 * TODO(M2): Handle keeping track of the mapping - create a node to indicate it's been allocated
 */
\brief map a user provided frame at user provided VA.
TODO(M1): Map a frame assuming all mappings will fit into one L2 pt
TODO(M2): General case
TODO(M2): Handle keeping track of the mapping - create a node to indicate it's been allocated
\ brief map a user provided frame at user provided VA . TODO ( M1 ) : Map a frame assuming all mappings will fit into one L2 pt TODO ( M2 ) : General case TODO ( M2 ) : Handle keeping track of the mapping - create a node to indicate it ' s been allocated
errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
        struct capref frame, size_t bytes, int flags)
{
    assert(vaddr % BASE_PAGE_SIZE == 0);
    errval_t err;
    struct capref l2;
    if (bytes % BASE_PAGE_SIZE != 0) {
        bytes += (size_t) BASE_PAGE_SIZE - (bytes % BASE_PAGE_SIZE);
    }
    int pte_count = bytes / BASE_PAGE_SIZE;
    int remaining_ptes, frame_offset;
    frame_offset = 0;
    while ( pte_count > 0 )
    {
        if (st->l2_pts[ARM_L1_OFFSET(vaddr)].initialized == true) {
            l2 = st->l2_pts[ARM_L1_OFFSET(vaddr)].cap;
        }
        else {
            err = arml2_alloc(st, &l2);
            if (err_is_fail(err)) {
                debug_printf("arml2_alloc failed: %s\n", err_getstring(err));
                return err;
            }
            struct capref l1mapping;
            err = st->slot_alloc->alloc(st->slot_alloc, &l1mapping);
            if (err_is_fail(err)) {
                debug_printf("slot_alloc failed: %s\n", err_getstring(err));
                return err;
            }
            err = vnode_map(st->l1_pt, l2, ARM_L1_OFFSET(vaddr), VREGION_FLAGS_READ_WRITE, 0, 1, l1mapping);
            if (err_is_fail(err)) {
                debug_printf("vnode_map failed: %s\n", err_getstring(err));
                return err;
            }
            st->l2_pts[ARM_L1_OFFSET(vaddr)].initialized = true;
            st->l2_pts[ARM_L1_OFFSET(vaddr)].cap = l2;
        }
        struct capref mapping;
        err = st->slot_alloc->alloc(st->slot_alloc, &mapping);
        if (err_is_fail(err)) {
            debug_printf("slot_alloc failed: %s\n", err_getstring(err));
            return err;
        }
        remaining_ptes = ARM_L2_MAX_ENTRIES - ARM_L2_OFFSET(vaddr);
        if (remaining_ptes < pte_count) {
            err = vnode_map(l2, frame, ARM_L2_OFFSET(vaddr), flags, frame_offset, remaining_ptes, mapping);
            if (err_is_fail(err)) {
                debug_printf("vnode_map failed: %s\n", err_getstring(err));
                return err;
            }
            pte_count -= remaining_ptes;
            vaddr += remaining_ptes * BASE_PAGE_SIZE;
            frame_offset += remaining_ptes * BASE_PAGE_SIZE;
        } 
        else {
            err = vnode_map(l2, frame, ARM_L2_OFFSET(vaddr), flags, frame_offset, pte_count, mapping);
            if (err_is_fail(err)) {
                debug_printf("vnode_map failed: %s\n", err_getstring(err));
                return err;
            }
            pte_count = 0;
        }
    }
    return SYS_ERR_OK;
}
errval_t paging_map_fixed_attr ( struct paging_state * st , lvaddr_t vaddr , struct capref frame , size_t bytes , int flags ) { assert ( vaddr % BASE_PAGE_SIZE == 0 ) ; errval_t err ; struct capref l2 ; if ( bytes % BASE_PAGE_SIZE != 0 ) { bytes += ( size_t ) BASE_PAGE_SIZE - ( bytes % BASE_PAGE_SIZE ) ; } int pte_count = bytes / BASE_PAGE_SIZE ; int remaining_ptes , frame_offset ; frame_offset = 0 ; while ( pte_count > 0 ) { if ( st -> l2_pts [ ARM_L1_OFFSET ( vaddr ) ] . initialized == true ) { l2 = st -> l2_pts [ ARM_L1_OFFSET ( vaddr ) ] . cap ; } else { err = arml2_alloc ( st , & l2 ) ; if ( err_is_fail ( err ) ) { debug_printf ( " \n " , err_getstring ( err ) ) ; return err ; } struct capref l1mapping ; err = st -> slot_alloc -> alloc ( st -> slot_alloc , & l1mapping ) ; if ( err_is_fail ( err ) ) { debug_printf ( " \n " , err_getstring ( err ) ) ; return err ; } err = vnode_map ( st -> l1_pt , l2 , ARM_L1_OFFSET ( vaddr ) , VREGION_FLAGS_READ_WRITE , 0 , 1 , l1mapping ) ; if ( err_is_fail ( err ) ) { debug_printf ( " \n " , err_getstring ( err ) ) ; return err ; } st -> l2_pts [ ARM_L1_OFFSET ( vaddr ) ] . initialized = true ; st -> l2_pts [ ARM_L1_OFFSET ( vaddr ) ] . cap = l2 ; } struct capref mapping ; err = st -> slot_alloc -> alloc ( st -> slot_alloc , & mapping ) ; if ( err_is_fail ( err ) ) { debug_printf ( " \n " , err_getstring ( err ) ) ; return err ; } remaining_ptes = ARM_L2_MAX_ENTRIES - ARM_L2_OFFSET ( vaddr ) ; if ( remaining_ptes < pte_count ) { err = vnode_map ( l2 , frame , ARM_L2_OFFSET ( vaddr ) , flags , frame_offset , remaining_ptes , mapping ) ; if ( err_is_fail ( err ) ) { debug_printf ( " \n " , err_getstring ( err ) ) ; return err ; } pte_count -= remaining_ptes ; vaddr += remaining_ptes * BASE_PAGE_SIZE ; frame_offset += remaining_ptes * BASE_PAGE_SIZE ; } else { err = vnode_map ( l2 , frame , ARM_L2_OFFSET ( vaddr ) , flags , frame_offset , pte_count , mapping ) ; if ( err_is_fail ( err ) ) { debug_printf ( " \n " , err_getstring ( err ) ) ; return err ; } pte_count = 0 ; } } return SYS_ERR_OK ; }
\brief map a user provided frame at user provided VA.
 TODO(M1): Map a frame assuming all mappings will fit into one L2 pt
 TODO(M2): General case
 TODO(M2): Handle keeping track of the mapping - create a node to indicate it's been allocated
\ brief map a user provided frame at user provided VA . TODO ( M1 ) : Map a frame assuming all mappings will fit into one L2 pt TODO ( M2 ) : General case TODO ( M2 ) : Handle keeping track of the mapping - create a node to indicate it ' s been allocated
// TODO(M2): Should we get rid of this? probably won't do anything - will already be aligned // if they went through paging_alloc. Don't go through - their problem.  // align the vaddr // round bytes up to page size to get the number of ptes needed to be mapped // TODO(M2): Create a node to keep track of allocated space // Should this be here, or in paging_alloc? // probably doesn't make a difference // insert in the list st keeps track of // TODO(M2): Verify that this is correct // Use 1 list - make coalescing easier  // check if l2 pt already exists // otherwise, allocate the l2 pt // update the l1 pt // need to call vnode_map // update the page_info struct to include the new l2 pt // determine pte_count based on size of frame // call slot_alloc to get a capref for mapping ??? // get the ptes available in this table past the offset // struct capref copy; // err = st->slot_alloc->alloc(st->slot_alloc, &copy); // if (err_is_fail(err)) { //     debug_printf("slot_alloc failed: %s\n", err_getstring(err)); //     return err; // } // err = cap_copy(copy, frame); // if (err_is_fail(err)) { //     debug_printf("cap_copy failed: %s\n", err_getstring(err)); //     return err; // } // frame = copy;