Changeset ff9f858 in mainline for arch/ia32


Ignore:
Timestamp:
2005-06-30T23:27:02Z (20 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a1a03f9
Parents:
992bbb97
Message:

Generic 4-level page tables interface & implementation (review & test).
Implement more architecture dependant macros on IA-32.
Provide fake implementation on IA-64 and MIPS.
Convert map_page_to_frame() to use the new interface.
Move adjusted map_page_to_frame() from IA-32's arch/mm/page.c to the generic mm/page.c.

Location:
arch/ia32
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • arch/ia32/include/mm/page.h

    r992bbb97 rff9f858  
    3030#define __ia32_PAGE_H__
    3131
     32#include <mm/page.h>
    3233#include <arch/types.h>
    3334#include <arch/mm/frame.h>
     35#include <typedefs.h>
    3436
    3537#define PAGE_SIZE       FRAME_SIZE
     
    4749#define PTL3_INDEX_ARCH(vaddr)  (((vaddr)>>12)&0x3ff)
    4850
     51#define GET_PTL0_ADDRESS_ARCH()                 ((pte_t *) read_cr3())
    4952#define GET_PTL1_ADDRESS_ARCH(ptl0, i)          ((pte_t *)((((pte_t *)(ptl0))[(i)].frame_address)<<12))
    5053#define GET_PTL2_ADDRESS_ARCH(ptl1, i)          (ptl1)
     
    5255#define GET_FRAME_ADDRESS_ARCH(ptl3, i)         ((__address)((((pte_t *)(ptl3))[(i)].frame_address)<<12))
    5356
     57#define SET_PTL0_ADDRESS_ARCH(ptl0)             (write_cr3((__address) (ptl0)))
     58#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)       (((pte_t *)(ptl0))[(i)].frame_address = (a)>>12)
     59#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
     60#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
     61#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)      (((pte_t *)(ptl3))[(i)].frame_address = (a)>>12)
     62
     63#define GET_PTL1_FLAGS_ARCH(ptl0, i)            get_pt_flags((pte_t *)(ptl0), (index_t)(i))
     64#define GET_PTL2_FLAGS_ARCH(ptl1, i)            PAGE_PRESENT
     65#define GET_PTL3_FLAGS_ARCH(ptl2, i)            PAGE_PRESENT
     66#define GET_FRAME_FLAGS_ARCH(ptl3, i)           get_pt_flags((pte_t *)(ptl3), (index_t)(i))
     67
     68#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)         set_pt_flags((pte_t *)(ptl0), (index_t)(i), (x))
     69#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
     70#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
     71#define SET_FRAME_FLAGS_ARCH(ptl3, i, x)        set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))
    5472
    5573struct page_specifier {
     
    6684} __attribute__ ((packed));
    6785
    68 typedef struct page_specifier   pte_t;
     86typedef struct page_specifier pte_t;
     87
     88static inline int get_pt_flags(pte_t *pt, index_t i)
     89{
     90        pte_t *p = &pt[i];
     91       
     92        return (
     93                (!p->page_cache_disable)<<PAGE_CACHEABLE_SHIFT |
     94                (!p->present)<<PAGE_PRESENT_SHIFT |
     95                p->uaccessible<<PAGE_USER_SHIFT |
     96                1<<PAGE_READ_SHIFT |
     97                p->writeable<<PAGE_WRITE_SHIFT |
     98                1<<PAGE_EXEC_SHIFT
     99        );
     100}
     101
     102static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
     103{
     104        pte_t *p = &pt[i];
     105       
     106        p->page_cache_disable = !(flags & PAGE_CACHEABLE);
     107        p->present = !(flags & PAGE_NOT_PRESENT);
     108        p->uaccessible = flags & PAGE_USER;
     109        p->writeable = flags & PAGE_WRITE;
     110}
    69111
    70112extern void page_arch_init(void);
  • arch/ia32/src/mm/page.c

    r992bbb97 rff9f858  
    8787        paging_on();
    8888}
    89 
    90 /*
    91  * Besides mapping pages to frames, this function also sets the present bit of
    92  * the page's specifier in both page directory and respective page table. If
    93  * the page table for this page has not been allocated so far, it will take
    94  * care of it and allocate the necessary frame.
    95  *
    96  * PAGE_CACHEABLE flag: when set, it turns caches for that page on
    97  * PAGE_NOT_PRESENT flag: when set, it marks the page not present
    98  * PAGE_USER flag: when set, the page is accessible from userspace
    99  *
    100  * When the root parameter is non-zero, it is used as the page directory address.
    101  * Otherwise, the page directory address is read from CPU.
    102  */
    103 void map_page_to_frame(__address page, __address frame, int flags, __address root)
    104 {
    105         struct page_specifier *pd, *pt;
    106         __address dba, newpt;
    107         int pde, pte;
    108 
    109         if (root) dba = root;
    110         else dba = read_cr3();
    111 
    112         pde = page >> 22;               /* page directory entry */
    113         pte = (page >> 12) & 0x3ff;     /* page table entry */
    114        
    115         pd = (struct page_specifier *) PA2KA(dba);
    116        
    117         if (!pd[pde].present) {
    118                 /*
    119                  * There is currently no page table for this address. Allocate
    120                  * frame for the page table and clean it.
    121                  */
    122                 newpt = frame_alloc(FRAME_KA);
    123                 pd[pde].frame_address = KA2PA(newpt) >> 12;
    124                 memsetb(newpt, PAGE_SIZE, 0);
    125                 pd[pde].present = 1;
    126                 pd[pde].uaccessible = 1;
    127         }
    128        
    129         pt = (struct page_specifier *) PA2KA((pd[pde].frame_address << 12));
    130 
    131         pt[pte].frame_address = frame >> 12;
    132         pt[pte].present = !(flags & PAGE_NOT_PRESENT);
    133         pt[pte].page_cache_disable = !(flags & PAGE_CACHEABLE);
    134         pt[pte].uaccessible = (flags & PAGE_USER) != 0;
    135         pt[pte].writeable = (flags & PAGE_WRITE) != 0; 
    136 }
Note: See TracChangeset for help on using the changeset viewer.