Changeset 386 for trunk/hal/x86_64


Ignore:
Timestamp:
Aug 16, 2017, 2:09:16 PM (7 years ago)
Author:
max@…
Message:

Implement several GPT functions.

Location:
trunk/hal/x86_64/core
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/x86_64/core/hal_boot.h

    r272 r386  
    9090#define PG_AVAIL3       0x0000000000000800
    9191#define PG_LGPAT        0x0000000000001000      /* PAT on large pages */
    92 #define PG_FRAME        0x000ffffffffff000
    9392#define PG_NX           0x8000000000000000
    9493
     94#define PG_FRAME        0x000ffffffffff000
    9595#define PG_2MFRAME      0x000fffffffe00000      /* large (2M) page frame mask */
    9696#define PG_1GFRAME      0x000fffffc0000000      /* large (1G) page frame mask */
    97 #define PG_LGFRAME      PG_2MFRAME
    9897
    9998/* Short forms of protection codes. */
  • trunk/hal/x86_64/core/hal_gpt.c

    r383 r386  
    236236/* -------------------------------------------------------------------------- */
    237237
     238static uint32_t hal_gpt_pte_to_attr(pt_entry_t *pte)
     239{
     240        uint32_t attr = 0;
     241
     242        if (*pte & PG_V)
     243                attr |= (GPT_MAPPED | GPT_READABLE);
     244        if (*pte & PG_RW)
     245                attr |= GPT_WRITABLE;
     246        if (!(*pte & PG_NX))
     247                attr |= GPT_EXECUTABLE;
     248        if (*pte & PG_u)
     249                attr |= GPT_USER;
     250        if (!(*pte & PG_PS))
     251                attr |= GPT_SMALL;
     252
     253        return attr;
     254}
     255
     256static pt_entry_t hal_gpt_attr_to_pte(uint32_t attr)
     257{
     258        pt_entry_t pte = 0;
     259
     260        if (attr & GPT_MAPPED)
     261                pte |= PG_V;
     262        if (attr & GPT_WRITABLE)
     263                pte |= PG_RW;
     264        if (!(attr & GPT_EXECUTABLE))
     265                pte |= PG_NX;
     266        if (attr & GPT_USER)
     267                pte |= PG_u;
     268
     269        return pte;
     270}
     271
    238272error_t hal_gpt_create(gpt_t *gpt)
    239273{
     
    293327}
    294328
    295 error_t hal_gpt_set_pte( gpt_t   * gpt,
    296                          vpn_t     vpn,
    297                          ppn_t     ppn,
    298                          uint32_t  attr )
    299 {
    300         x86_panic((char *)__func__);
     329error_t hal_gpt_set_pte(gpt_t *gpt, vpn_t vpn, ppn_t ppn, uint32_t attr)
     330{
     331        vaddr_t va = vpn << CONFIG_PPM_PAGE_SHIFT;
     332        paddr_t pa;
     333        kmem_req_t req;
     334        page_t *page;
     335        xptr_t page_xp;
     336
     337        req.type  = KMEM_PAGE;
     338        req.size  = 0;
     339        req.flags = AF_KERNEL | AF_ZERO;
     340
     341        if (!(attr & GPT_MAPPED))
     342                x86_panic("hal_gpt_set_pte: unmapped!");
     343        if (!(attr & GPT_USER))
     344                x86_panic("hal_gpt_set_pte: kernel!");
     345        if (!(attr & GPT_SMALL))
     346                x86_panic("hal_gpt_set_pte: large!");
     347
     348        if (!(L4_BASE[pl4_i(va)] & PG_V)) {
     349                /* if L4 is not present, create it */
     350                page = (page_t *)kmem_alloc(&req);
     351                if (page == NULL) {
     352                        x86_panic("out of memory in hal_gpt_set_pte (L4)!");
     353                        return ENOMEM;
     354                }
     355
     356                page_xp = XPTR(local_cxy, page);       
     357                pa = (paddr_t)PADDR(local_cxy, ppm_page2base(page_xp));
     358
     359                L4_BASE[pl4_i(va)] = pa | PG_V | PG_u | PG_RW;
     360
     361        }
     362
     363        if (!(L3_BASE[pl3_i(va)] & PG_V)) {
     364                /* if L3 is not present, create it */
     365                page = (page_t *)kmem_alloc(&req);
     366                if (page == NULL) {
     367                        x86_panic("out of memory in hal_gpt_set_pte (L3)!");
     368                        return ENOMEM;
     369                }
     370
     371                page_xp = XPTR(local_cxy, page);       
     372                pa = (paddr_t)PADDR(local_cxy, ppm_page2base(page_xp));
     373
     374                L3_BASE[pl3_i(va)] = pa | PG_V | PG_u | PG_RW;
     375        }
     376
     377        if (!(L2_BASE[pl2_i(va)] & PG_V)) {
     378                /* if L2 is not present, create it */
     379                page = (page_t *)kmem_alloc(&req);
     380                if (page == NULL) {
     381                        x86_panic("out of memory in hal_gpt_set_pte (L2)!");
     382                        return ENOMEM;
     383                }
     384
     385                page_xp = XPTR(local_cxy, page);       
     386                pa = (paddr_t)PADDR(local_cxy, ppm_page2base(page_xp));
     387
     388                L2_BASE[pl2_i(va)] = pa | PG_V | PG_u | PG_RW;
     389        }
     390
     391        pa = ppn << CONFIG_PPM_PAGE_SHIFT;
     392        L1_BASE[pl1_i(va)] = pa | hal_gpt_attr_to_pte(attr);
     393
    301394        return 0;
    302395}
    303396
    304 void hal_gpt_get_pte( gpt_t    * gpt,
    305                       vpn_t      vpn,
    306                       uint32_t * attr,
    307                       ppn_t    * ppn )
    308 {
     397void hal_gpt_get_pte(gpt_t *gpt, vpn_t vpn, uint32_t *attr, ppn_t *ppn)
     398{
     399        vaddr_t va = vpn << CONFIG_PPM_PAGE_SHIFT;
     400
     401        *attr = 0;
     402        if (!(L4_BASE[pl4_i(va)] & PG_V)) {
     403                return;
     404        }
     405        if (!(L3_BASE[pl3_i(va)] & PG_V)) {
     406                return;
     407        }
     408        if (!(L2_BASE[pl2_i(va)] & PG_V)) {
     409                return;
     410        }
     411
     412        if (L2_BASE[pl2_i(va)] & PG_PS) {
     413                /* large page */
     414                *attr = hal_gpt_pte_to_attr(&L2_BASE[pl2_i(va)]);
     415                *ppn = (L2_BASE[pl2_i(va)] & PG_2MFRAME) >> CONFIG_PPM_PAGE_SHIFT;
     416        } else {
     417                /* small page */
     418                *attr = hal_gpt_pte_to_attr(&L1_BASE[pl1_i(va)]);
     419                *ppn = (L1_BASE[pl1_i(va)] & PG_FRAME) >> CONFIG_PPM_PAGE_SHIFT;
     420        }
     421
    309422        x86_panic((char *)__func__);
    310423}
Note: See TracChangeset for help on using the changeset viewer.