Changeset 94d211e in mainline for kernel/generic


Ignore:
Timestamp:
2018-03-21T19:32:48Z (8 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Children:
1c7a170
Parents:
973be387
Message:

Change the way page flags work. TODO description

Location:
kernel/generic
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/mm/mm.h

    r973be387 r94d211e  
    3636#define KERN_MM_H_
    3737
    38 #define PAGE_CACHEABLE_SHIFT            0
    39 #define PAGE_NOT_CACHEABLE_SHIFT        PAGE_CACHEABLE_SHIFT
    40 #define PAGE_PRESENT_SHIFT              1
    41 #define PAGE_NOT_PRESENT_SHIFT          PAGE_PRESENT_SHIFT
    42 #define PAGE_USER_SHIFT                 2
    43 #define PAGE_KERNEL_SHIFT               PAGE_USER_SHIFT
     38#include <assert.h>
     39#include <stdbool.h>
     40
     41#define PAGE_NOT_CACHEABLE_SHIFT        0
     42#define PAGE_CACHEABLE_SHIFT            1
     43#define PAGE_NOT_PRESENT_SHIFT          2
    4444#define PAGE_READ_SHIFT                 3
    4545#define PAGE_WRITE_SHIFT                4
    4646#define PAGE_EXEC_SHIFT                 5
    4747#define PAGE_GLOBAL_SHIFT               6
     48#define PAGE_USER_SHIFT                 7
     49#define PAGE_KERNEL_SHIFT               8
    4850
    49 #define PAGE_NOT_CACHEABLE              (0 << PAGE_CACHEABLE_SHIFT)
     51/* Cacheability.
     52 * Platform-independent code should always use PAGE_CACHEABLE for normal memory,
     53 * and PAGE_NOT_CACHEABLE for I/O memory.
     54 * In particular, setting PAGE_NOT_CACHEABLE on normal memory does not prevent
     55 * caching on all platforms. You have been warned.
     56 * Exactly one must be present for leaf pages.
     57 * None may be present for non-leaf entries.
     58 */
     59
     60#define PAGE_NOT_CACHEABLE              (1 << PAGE_NOT_CACHEABLE_SHIFT)
    5061#define PAGE_CACHEABLE                  (1 << PAGE_CACHEABLE_SHIFT)
    5162
    52 #define PAGE_PRESENT                    (0 << PAGE_PRESENT_SHIFT)
    53 #define PAGE_NOT_PRESENT                (1 << PAGE_PRESENT_SHIFT)
    5463
    55 #define PAGE_USER                       (1 << PAGE_USER_SHIFT)
    56 #define PAGE_KERNEL                     (0 << PAGE_USER_SHIFT)
     64/* Discriminant, exactly one of the following seven must be set for
     65 * the flags to be valid. Furthermore, the first two are only legal
     66 * for setting individual page table entries. Setting an entry
     67 * to PAGE_NOT_PRESENT renders the entry eligible for removal.
     68 * In an earlier iteration of this interface, page could be not
     69 * present but valid, preventing removal. This has been changed, and
     70 * if future iterations allow kernel to hide data (e.g. swap identifiers)
     71 * in page tables, it should be achieved by adding a separate discriminant.
     72 */
     73#define PAGE_NOT_PRESENT          (1 << PAGE_NOT_PRESENT_SHIFT)
    5774
    58 #define PAGE_READ                       (1 << PAGE_READ_SHIFT)
    59 #define PAGE_WRITE                      (1 << PAGE_WRITE_SHIFT)
    60 #define PAGE_EXEC                       (1 << PAGE_EXEC_SHIFT)
     75// TODO: This will be a separate flag.
     76#define PAGE_NEXT_LEVEL_PT        (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC | PAGE_USER | PAGE_CACHEABLE)
    6177
    62 #define PAGE_GLOBAL                     (1 << PAGE_GLOBAL_SHIFT)
     78#define PAGE_READ_ONLY            (_PAGE_READ)
     79#define PAGE_READ_EXECUTE         (_PAGE_READ | _PAGE_EXEC)
     80#define PAGE_READ_WRITE           (_PAGE_READ | _PAGE_WRITE)
     81#define PAGE_READ_WRITE_EXECUTE   (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC)
     82#define PAGE_EXECUTE_ONLY         (_PAGE_EXEC)
     83
     84/* Individual permissions.
     85 * Only used when the flags are tested or translated from other
     86 * format. In constant flags, use one of the combinations above.
     87 */
     88#define _PAGE_READ                (1 << PAGE_READ_SHIFT)
     89#define _PAGE_WRITE               (1 << PAGE_WRITE_SHIFT)
     90#define _PAGE_EXEC                (1 << PAGE_EXEC_SHIFT)
     91
     92/* Global page. Can be combined with anything except PAGE_NOT_PRESENT.
     93 * PAGE_GLOBAL on non-leaf entry means all the leaf entries under it are global,
     94 * even if they don't have the PAGE_GLOBAL flag themselves.
     95 */
     96#define PAGE_GLOBAL               (1 << PAGE_GLOBAL_SHIFT)
     97
     98/* Protection.
     99 * PAGE_USER for memory accessible to userspace programs, PAGE_KERNEL for
     100 * memory accessible only to the kernel. Note that on some platforms,
     101 * PAGE_USER pages are accessible to kernel, while on others, they are not.
     102 * For non-leaf entries, PAGE_USER means that all of the lower-level pages
     103 * are PAGE_USER, likewise with PAGE_KERNEL. Exactly one of these two must be
     104 * used for leaf entries, but it may be omitted for non-leaf entries.
     105 */
     106#define PAGE_USER                 (1 << PAGE_USER_SHIFT)
     107#define PAGE_KERNEL               (1 << PAGE_KERNEL_SHIFT)
     108
     109
     110
     111static inline bool PAGE_FLAGS_VALID(unsigned flags) {
     112        // TODO
     113
     114        /* Empty entry supports no flags. */
     115        if (flags & PAGE_NOT_PRESENT)
     116                return flags == PAGE_NOT_PRESENT;
     117
     118        /* PAGE_USER and PAGE_KERNEL are mutually exclusive. */
     119        if ((flags & PAGE_USER) && (flags & PAGE_KERNEL))
     120                return false;
     121
     122        /* Check allowed flags for non-leaf entry. */
     123        if (flags & PAGE_NEXT_LEVEL_PT)
     124                return flags == (flags & (PAGE_NEXT_LEVEL_PT | PAGE_GLOBAL | PAGE_USER | PAGE_KERNEL));
     125
     126        /* Leaf entries only. */
     127
     128        /* Check that at least one permission is set. */
     129        if (!(flags & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC)))
     130                return false;
     131
     132        /* Check that write implies read. */
     133        if ((flags & _PAGE_WRITE) && !(flags & _PAGE_READ))
     134                return false;
     135
     136        /* One of PAGE_USER and PAGE_KERNEL must be used. */
     137        if (!(flags & (PAGE_USER | PAGE_KERNEL)))
     138                return false;
     139
     140        /* One of PAGE_CACHEABLE and PAGE_NOT_CACHEABLE must be used. */
     141        if ((flags & PAGE_CACHEABLE) && (flags & PAGE_NOT_CACHEABLE))
     142                return false;
     143        if (!(flags & (PAGE_CACHEABLE | PAGE_NOT_CACHEABLE)))
     144                return false;
     145
     146        return true;
     147}
    63148
    64149#endif
  • kernel/generic/include/mm/page.h

    r973be387 r94d211e  
    4949        void (*mapping_remove)(as_t *, uintptr_t);
    5050        bool (*mapping_find)(as_t *, uintptr_t, bool, pte_t *);
    51         void (*mapping_update)(as_t *, uintptr_t, bool, pte_t *);
     51        void (*mapping_update)(as_t *, uintptr_t, bool, const pte_t *);
    5252        void (*mapping_make_global)(uintptr_t, size_t);
    5353} page_mapping_operations_t;
  • kernel/generic/src/console/cmd.c

    r973be387 r94d211e  
    727727        else
    728728#endif
    729                 ptr = (uint8_t *) km_map(argv[0].intval, sizeof(uint8_t),
    730                     PAGE_NOT_CACHEABLE);
     729                ptr = (uint8_t *) km_map(
     730                    argv[0].intval, sizeof(uint8_t),
     731                    PAGE_READ_ONLY | PAGE_KERNEL | PAGE_NOT_CACHEABLE);
    731732
    732733        const uint8_t val = pio_read_8(ptr);
     
    749750 */
    750751static int cmd_pio_read_16(cmd_arg_t *argv)
     752{
     753        uint16_t *ptr = NULL;
     754
     755#ifdef IO_SPACE_BOUNDARY
     756        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     757                ptr = (void *) argv[0].intval;
     758        else
     759#endif
     760                ptr = (uint16_t *) km_map(
     761                    argv[0].intval, sizeof(uint16_t),
     762                    PAGE_READ_ONLY | PAGE_KERNEL | PAGE_NOT_CACHEABLE);
     763
     764        const uint16_t val = pio_read_16(ptr);
     765        printf("read %" PRIxn ": %" PRIx16 "\n", argv[0].intval, val);
     766
     767#ifdef IO_SPACE_BOUNDARY
     768        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     769                return 1;
     770#endif
     771
     772        km_unmap((uintptr_t) ptr, sizeof(uint16_t));
     773        return 1;
     774}
     775
     776/** Read 4 bytes from phys memory or io port.
     777 *
     778 * @param argv Argument vector.
     779 *
     780 * @return 0 on failure, 1 on success.
     781 */
     782static int cmd_pio_read_32(cmd_arg_t *argv)
     783{
     784        uint32_t *ptr = NULL;
     785
     786#ifdef IO_SPACE_BOUNDARY
     787        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     788                ptr = (void *) argv[0].intval;
     789        else
     790#endif
     791                ptr = (uint32_t *) km_map(
     792                    argv[0].intval, sizeof(uint32_t),
     793                    PAGE_READ_ONLY | PAGE_KERNEL | PAGE_NOT_CACHEABLE);
     794
     795        const uint32_t val = pio_read_32(ptr);
     796        printf("read %" PRIxn ": %" PRIx32 "\n", argv[0].intval, val);
     797
     798#ifdef IO_SPACE_BOUNDARY
     799        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     800                return 1;
     801#endif
     802
     803        km_unmap((uintptr_t) ptr, sizeof(uint32_t));
     804        return 1;
     805}
     806
     807/** Write 1 byte to phys memory or io port.
     808 *
     809 * @param argv Argument vector.
     810 *
     811 * @return 0 on failure, 1 on success.
     812 */
     813static int cmd_pio_write_8(cmd_arg_t *argv)
     814{
     815        uint8_t *ptr = NULL;
     816
     817#ifdef IO_SPACE_BOUNDARY
     818        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     819                ptr = (void *) argv[0].intval;
     820        else
     821#endif
     822                ptr = (uint8_t *) km_map(argv[0].intval, sizeof(uint8_t),
     823                    PAGE_READ_WRITE | PAGE_KERNEL | PAGE_NOT_CACHEABLE);
     824
     825        printf("write %" PRIxn ": %" PRIx8 "\n", argv[0].intval,
     826            (uint8_t) argv[1].intval);
     827        pio_write_8(ptr, (uint8_t) argv[1].intval);
     828
     829#ifdef IO_SPACE_BOUNDARY
     830        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     831                return 1;
     832#endif
     833
     834        km_unmap((uintptr_t) ptr, sizeof(uint8_t));
     835        return 1;
     836}
     837
     838/** Write 2 bytes to phys memory or io port.
     839 *
     840 * @param argv Argument vector.
     841 *
     842 * @return 0 on failure, 1 on success.
     843 */
     844static int cmd_pio_write_16(cmd_arg_t *argv)
    751845{
    752846        uint16_t *ptr = NULL;
     
    758852#endif
    759853                ptr = (uint16_t *) km_map(argv[0].intval, sizeof(uint16_t),
    760                     PAGE_NOT_CACHEABLE);
    761 
    762         const uint16_t val = pio_read_16(ptr);
    763         printf("read %" PRIxn ": %" PRIx16 "\n", argv[0].intval, val);
     854                    PAGE_READ_WRITE | PAGE_KERNEL | PAGE_NOT_CACHEABLE);
     855
     856        printf("write %" PRIxn ": %" PRIx16 "\n", argv[0].intval,
     857            (uint16_t) argv[1].intval);
     858        pio_write_16(ptr, (uint16_t) argv[1].intval);
    764859
    765860#ifdef IO_SPACE_BOUNDARY
     
    772867}
    773868
    774 /** Read 4 bytes from phys memory or io port.
     869/** Write 4 bytes to phys memory or io port.
    775870 *
    776871 * @param argv Argument vector.
     
    778873 * @return 0 on failure, 1 on success.
    779874 */
    780 static int cmd_pio_read_32(cmd_arg_t *argv)
     875static int cmd_pio_write_32(cmd_arg_t *argv)
    781876{
    782877        uint32_t *ptr = NULL;
     
    788883#endif
    789884                ptr = (uint32_t *) km_map(argv[0].intval, sizeof(uint32_t),
    790                     PAGE_NOT_CACHEABLE);
    791 
    792         const uint32_t val = pio_read_32(ptr);
    793         printf("read %" PRIxn ": %" PRIx32 "\n", argv[0].intval, val);
    794 
    795 #ifdef IO_SPACE_BOUNDARY
    796         if ((void *) argv->intval < IO_SPACE_BOUNDARY)
    797                 return 1;
    798 #endif
    799 
    800         km_unmap((uintptr_t) ptr, sizeof(uint32_t));
    801         return 1;
    802 }
    803 
    804 /** Write 1 byte to phys memory or io port.
    805  *
    806  * @param argv Argument vector.
    807  *
    808  * @return 0 on failure, 1 on success.
    809  */
    810 static int cmd_pio_write_8(cmd_arg_t *argv)
    811 {
    812         uint8_t *ptr = NULL;
    813 
    814 #ifdef IO_SPACE_BOUNDARY
    815         if ((void *) argv->intval < IO_SPACE_BOUNDARY)
    816                 ptr = (void *) argv[0].intval;
    817         else
    818 #endif
    819                 ptr = (uint8_t *) km_map(argv[0].intval, sizeof(uint8_t),
    820                     PAGE_NOT_CACHEABLE);
    821 
    822         printf("write %" PRIxn ": %" PRIx8 "\n", argv[0].intval,
    823             (uint8_t) argv[1].intval);
    824         pio_write_8(ptr, (uint8_t) argv[1].intval);
    825 
    826 #ifdef IO_SPACE_BOUNDARY
    827         if ((void *) argv->intval < IO_SPACE_BOUNDARY)
    828                 return 1;
    829 #endif
    830 
    831         km_unmap((uintptr_t) ptr, sizeof(uint8_t));
    832         return 1;
    833 }
    834 
    835 /** Write 2 bytes to phys memory or io port.
    836  *
    837  * @param argv Argument vector.
    838  *
    839  * @return 0 on failure, 1 on success.
    840  */
    841 static int cmd_pio_write_16(cmd_arg_t *argv)
    842 {
    843         uint16_t *ptr = NULL;
    844 
    845 #ifdef IO_SPACE_BOUNDARY
    846         if ((void *) argv->intval < IO_SPACE_BOUNDARY)
    847                 ptr = (void *) argv[0].intval;
    848         else
    849 #endif
    850                 ptr = (uint16_t *) km_map(argv[0].intval, sizeof(uint16_t),
    851                     PAGE_NOT_CACHEABLE);
    852 
    853         printf("write %" PRIxn ": %" PRIx16 "\n", argv[0].intval,
    854             (uint16_t) argv[1].intval);
    855         pio_write_16(ptr, (uint16_t) argv[1].intval);
    856 
    857 #ifdef IO_SPACE_BOUNDARY
    858         if ((void *) argv->intval < IO_SPACE_BOUNDARY)
    859                 return 1;
    860 #endif
    861 
    862         km_unmap((uintptr_t) ptr, sizeof(uint16_t));
    863         return 1;
    864 }
    865 
    866 /** Write 4 bytes to phys memory or io port.
    867  *
    868  * @param argv Argument vector.
    869  *
    870  * @return 0 on failure, 1 on success.
    871  */
    872 static int cmd_pio_write_32(cmd_arg_t *argv)
    873 {
    874         uint32_t *ptr = NULL;
    875 
    876 #ifdef IO_SPACE_BOUNDARY
    877         if ((void *) argv->intval < IO_SPACE_BOUNDARY)
    878                 ptr = (void *) argv[0].intval;
    879         else
    880 #endif
    881                 ptr = (uint32_t *) km_map(argv[0].intval, sizeof(uint32_t),
    882                     PAGE_NOT_CACHEABLE);
     885                    PAGE_READ_WRITE | PAGE_KERNEL | PAGE_NOT_CACHEABLE);
    883886
    884887        printf("write %" PRIxn ": %" PRIx32 "\n", argv[0].intval,
  • kernel/generic/src/ipc/irq.c

    r973be387 r94d211e  
    9393#endif
    9494                ranges[i].base = km_map(pbase[i], ranges[i].size,
    95                     PAGE_READ | PAGE_WRITE | PAGE_KERNEL | PAGE_NOT_CACHEABLE);
     95                    PAGE_READ_WRITE | PAGE_KERNEL | PAGE_NOT_CACHEABLE);
    9696                if (!ranges[i].base) {
    9797                        ranges_unmap(ranges, i);
  • kernel/generic/src/main/kinit.c

    r973be387 r94d211e  
    250250                uintptr_t page = km_map(init.tasks[i].paddr,
    251251                    init.tasks[i].size,
    252                     PAGE_READ | PAGE_WRITE | PAGE_CACHEABLE);
     252                    PAGE_READ_WRITE | PAGE_KERNEL | PAGE_CACHEABLE);
    253253                assert(page);
    254254
  • kernel/generic/src/mm/as.c

    r973be387 r94d211e  
    12171217NO_TRACE static unsigned int area_flags_to_page_flags(unsigned int aflags)
    12181218{
    1219         unsigned int flags = PAGE_USER | PAGE_PRESENT;
     1219        unsigned int flags = PAGE_USER;
    12201220
    12211221        if (aflags & AS_AREA_READ)
    1222                 flags |= PAGE_READ;
     1222                flags |= _PAGE_READ;
    12231223
    12241224        if (aflags & AS_AREA_WRITE)
    1225                 flags |= PAGE_WRITE;
     1225                flags |= _PAGE_WRITE;
    12261226
    12271227        if (aflags & AS_AREA_EXEC)
    1228                 flags |= PAGE_EXEC;
     1228                flags |= _PAGE_EXEC;
    12291229
    12301230        if (aflags & AS_AREA_CACHEABLE)
    12311231                flags |= PAGE_CACHEABLE;
     1232        else
     1233                flags |= PAGE_NOT_CACHEABLE;
    12321234
    12331235        return flags;
  • kernel/generic/src/mm/km.c

    r973be387 r94d211e  
    257257        if (frame) {
    258258                page = km_map(frame, PAGE_SIZE,
    259                     PAGE_READ | PAGE_WRITE | PAGE_CACHEABLE);
     259                    PAGE_READ_WRITE | PAGE_KERNEL | PAGE_CACHEABLE);
    260260                if (!page) {
    261261                        frame_free(frame, 1);
Note: See TracChangeset for help on using the changeset viewer.