Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset ccc362a1 in mainline


Ignore:
Timestamp:
2017-08-21T18:46:34Z (3 years ago)
Author:
Martin Decky <martin@…>
Branches:
master
Children:
6c742f5e
Parents:
c16479e
Message:

riscv64: memory management routines, reflecting the latest Privileged Architecture specification (1.10)

Location:
kernel/arch/riscv64
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/riscv64/include/arch/arch.h

    rc16479e rccc362a1  
    3838#include <arch/boot/boot.h>
    3939
     40extern void riscv64_pre_main(bootinfo_t *);
     41
    4042#endif
    4143
  • kernel/arch/riscv64/include/arch/mm/asid.h

    rc16479e rccc362a1  
    4242typedef uint32_t asid_t;
    4343
     44#define asid_get()  (ASID_START + 1)
     45#define asid_put(asid)
     46
    4447#endif
    4548
  • kernel/arch/riscv64/include/arch/mm/frame.h

    rc16479e rccc362a1  
    4343#ifndef __ASM__
    4444
     45#include <arch/boot/boot.h>
     46
     47extern uintptr_t physmem_start;
     48extern uintptr_t htif_frame;
     49extern uintptr_t pt_frame;
     50extern memmap_t memmap;
     51
    4552extern void frame_low_arch_init(void);
    4653extern void frame_high_arch_init(void);
  • kernel/arch/riscv64/include/arch/mm/km.h

    rc16479e rccc362a1  
    3939#include <stddef.h>
    4040
     41#define KM_RISCV64_IDENTITY_START      UINT64_C(0xffff800000000000)
     42#define KM_RISCV64_IDENTITY_SIZE       UINT64_C(0x0000400000000000)
     43
     44#define KM_RISCV64_NON_IDENTITY_START  UINT64_C(0xffffc00000000000)
     45#define KM_RISCV64_NON_IDENTITY_SIZE   UINT64_C(0x0000400000000000)
     46
    4147extern void km_identity_arch_init(void);
    4248extern void km_non_identity_arch_init(void);
  • kernel/arch/riscv64/include/arch/mm/page.h

    rc16479e rccc362a1  
    5050
    5151/*
    52  * Page table entry types.
    53  *
    54  * - PTE_TYPE_PTR:         pointer to next level PTE
    55  * - PTE_TYPE_PTR_GLOBAL:  pointer to next level PTE (global mapping)
    56  *
    57  * - PTE_TYPE_SRURX:       kernel read, user read execute
    58  * - PTE_TYPE_SRWURWX:     kernel read write, user read write execute
    59  * - PTE_TYPE_SRUR:        kernel read, user read
    60  * - PTE_TYPE_SRWURW:      kernel read write, user read write
    61  * - PTE_TYPE_SRXURX:      kernel read execute, user read execute
    62  * - PTE_TYPE_SRWXURWX:    kernel read write execute, user read write execute
    63  *
    64  * - PTE_TYPE_SR:          kernel read
    65  * - PTE_TYPE_SRW:         kernel read write
    66  * - PTE_TYPE_SRX:         kernel read execute
    67  * - PTE_TYPE_SRWX:        kernel read write execute
    68  *
    69  * - PTE_TYPE_SR_GLOBAL:   kernel read (global mapping)
    70  * - PTE_TYPE_SRW_GLOBAL:  kernel read write (global mapping)
    71  * - PTE_TYPE_SRX_GLOBAL:  kernel read execute (global mapping)
    72  * - PTE_TYPE_SRWX_GLOBAL: kernel read write execute (global mapping)
    73  */
    74 
    75 #define PTE_TYPE_PTR          0
    76 #define PTE_TYPE_PTR_GLOBAL   1
    77 
    78 #define PTE_TYPE_SRURX        2
    79 #define PTE_TYPE_SRWURWX      3
    80 #define PTE_TYPE_SRUR         4
    81 #define PTE_TYPE_SRWURW       5
    82 #define PTE_TYPE_SRXURX       6
    83 #define PTE_TYPE_SRWXURWX     7
    84 
    85 #define PTE_TYPE_SR           8
    86 #define PTE_TYPE_SRW          9
    87 #define PTE_TYPE_SRX          10
    88 #define PTE_TYPE_SRWX         11
    89 
    90 #define PTE_TYPE_SR_GLOBAL    12
    91 #define PTE_TYPE_SRW_GLOBAL   13
    92 #define PTE_TYPE_SRX_GLOBAL   14
    93 #define PTE_TYPE_SRWX_GLOBAL  15
    94 
    95 /*
    9652 * Implementation of 4-level page table interface.
    9753 *
     
    12581#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x1ff)
    12682
     83/* Flags mask for non-leaf page table entries */
     84#define NON_LEAF_MASK  (~(PAGE_READ | PAGE_WRITE | PAGE_EXEC))
     85
    12786/* Get PTE address accessors for each level. */
    12887#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
     
    13998
    14099/* Set PTE address accessors for each level. */
    141 #define SET_PTL0_ADDRESS_ARCH(ptl0)
     100#define SET_PTL0_ADDRESS_ARCH(ptl0) \
     101        (write_satp((uintptr_t) (ptl0)))
    142102
    143103#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
     
    167127
    168128/* Set PTE flags accessors for each level. */
    169 #define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
    170         set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
    171 
    172 #define SET_PTL2_FLAGS_ARCH(ptl1, i, x) \
    173         set_pt_flags((pte_t *) (ptl1), (size_t) (i), (x))
    174 
    175 #define SET_PTL3_FLAGS_ARCH(ptl2, i, x) \
    176         set_pt_flags((pte_t *) (ptl2), (size_t) (i), (x))
    177 
    178 #define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
    179         set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
     129#define SET_PTL1_FLAGS_ARCH(ptl0, i, flags) \
     130        set_pt_flags((pte_t *) (ptl0), (size_t) (i), ((flags) & NON_LEAF_MASK))
     131
     132#define SET_PTL2_FLAGS_ARCH(ptl1, i, flags) \
     133        set_pt_flags((pte_t *) (ptl1), (size_t) (i), ((flags) & NON_LEAF_MASK))
     134
     135#define SET_PTL3_FLAGS_ARCH(ptl2, i, flags) \
     136        set_pt_flags((pte_t *) (ptl2), (size_t) (i), ((flags) & NON_LEAF_MASK))
     137
     138#define SET_FRAME_FLAGS_ARCH(ptl3, i, flags) \
     139        set_pt_flags((pte_t *) (ptl3), (size_t) (i), (flags))
    180140
    181141/* Set PTE present accessors for each level. */
     
    196156#define PTE_PRESENT_ARCH(pte)     ((pte)->valid != 0)
    197157#define PTE_GET_FRAME_ARCH(pte)   ((uintptr_t) (pte)->pfn << 12)
    198 
    199 #define PTE_WRITABLE_ARCH(pte) \
    200         (((pte)->type == PTE_TYPE_SRWURWX) || \
    201         ((pte)->type == PTE_TYPE_SRWURW) || \
    202         ((pte)->type == PTE_TYPE_SRWXURWX))
    203 
    204 #define PTE_EXECUTABLE_ARCH(pte) \
    205         (((pte)->type == PTE_TYPE_SRURX) || \
    206         ((pte)->type == PTE_TYPE_SRWURWX) || \
    207         ((pte)->type == PTE_TYPE_SRXURX) || \
    208         ((pte)->type == PTE_TYPE_SRWXURWX))
     158#define PTE_WRITABLE_ARCH(pte)    ((pte)->writable != 0)
     159#define PTE_EXECUTABLE_ARCH(pte)  ((pte)->executable != 0)
    209160
    210161#ifndef __ASM__
     
    217168typedef struct {
    218169        unsigned long valid : 1;       /**< Valid bit. */
    219         unsigned long type : 4;        /**< Entry type. */
    220         unsigned long referenced : 1;  /**< Refenced bit. */
     170        unsigned long readable : 1;    /**< Readable bit. */
     171        unsigned long writable : 1;    /**< Writable bit. */
     172        unsigned long executable : 1;  /**< Executable bit. */
     173        unsigned long user : 1;        /**< User mode accessible bit. */
     174        unsigned long global : 1;      /**< Global mapping bit. */
     175        unsigned long accessed : 1;    /**< Accessed bit. */
    221176        unsigned long dirty : 1;       /**< Dirty bit. */
    222         unsigned long reserved : 3;    /**< Reserved bits. */
     177        unsigned long reserved : 2;    /**< Reserved bits. */
    223178        unsigned long pfn : 54;        /**< Physical frame number. */
    224179} pte_t;
     
    229184       
    230185        return (((!entry->valid) << PAGE_PRESENT_SHIFT) |
    231             ((entry->type < PTE_TYPE_SR) << PAGE_USER_SHIFT) |
    232             PAGE_READ |
    233             (PTE_WRITABLE_ARCH(entry) << PAGE_WRITE_SHIFT) |
    234             (PTE_EXECUTABLE_ARCH(entry) << PAGE_EXEC_SHIFT) |
    235             ((entry->type >= PTE_TYPE_SR_GLOBAL) << PAGE_GLOBAL_SHIFT));
     186            (entry->user << PAGE_USER_SHIFT) |
     187            (entry->readable << PAGE_READ_SHIFT) |
     188            (entry->writable << PAGE_WRITE_SHIFT) |
     189            (entry->executable << PAGE_EXEC_SHIFT) |
     190            (entry->global << PAGE_GLOBAL_SHIFT));
    236191}
    237192
     
    241196       
    242197        entry->valid = !(flags & PAGE_NOT_PRESENT);
    243        
    244         if ((flags & PAGE_WRITE) != 0) {
    245                 if ((flags & PAGE_EXEC) != 0)
    246                         entry->type = PTE_TYPE_SRWXURWX;
    247                 else
    248                         entry->type = PTE_TYPE_SRWURW;
    249         } else {
    250                 if ((flags & PAGE_EXEC) != 0)
    251                         entry->type = PTE_TYPE_SRXURX;
    252                 else
    253                         entry->type = PTE_TYPE_SRUR;
    254         }
     198        entry->readable = (flags & PAGE_READ) != 0;
     199        entry->writable = (flags & PAGE_WRITE) != 0;
     200        entry->executable = (flags & PAGE_EXEC) != 0;
     201        entry->user = (flags & PAGE_USER) != 0;
     202        entry->global = (flags & PAGE_GLOBAL) != 0;
     203        entry->accessed = 1;
     204        entry->dirty = 1;
    255205}
    256206
     
    264214extern void page_arch_init(void);
    265215extern void page_fault(unsigned int, istate_t *);
     216extern void write_satp(uintptr_t);
    266217
    267218#endif /* __ASM__ */
  • kernel/arch/riscv64/src/mm/as.c

    rc16479e rccc362a1  
    4040}
    4141
     42/** Install address space.
     43 *
     44 * Install ASID.
     45 *
     46 * @param as Address space structure.
     47 */
     48void as_install_arch(as_t *as)
     49{
     50        // FIXME
     51}
     52
    4253/** @}
    4354 */
  • kernel/arch/riscv64/src/mm/frame.c

    rc16479e rccc362a1  
    3232
    3333#include <mm/frame.h>
     34#include <arch/boot/boot.h>
    3435#include <arch/mm/frame.h>
     36#include <arch/drivers/ucb.h>
    3537#include <mm/as.h>
    3638#include <config.h>
     
    3941#include <align.h>
    4042#include <macros.h>
    41 
    4243#include <print.h>
    4344
    44 size_t hardcoded_unmapped_ktext_size = 0;
    45 size_t hardcoded_unmapped_kdata_size = 0;
     45uintptr_t physmem_start;
     46uintptr_t htif_frame;
     47uintptr_t pt_frame;
     48memmap_t memmap;
    4649
    4750void physmem_print(void)
     
    4952}
    5053
     54static void frame_common_arch_init(bool low)
     55{
     56        pfn_t minconf =
     57            max3(ADDR2PFN(physmem_start), htif_frame + 1, pt_frame + 1);
     58       
     59        for (size_t i = 0; i < memmap.cnt; i++) {
     60                /* To be safe, make the available zone possibly smaller */
     61                uintptr_t base = ALIGN_UP((uintptr_t) memmap.zones[i].start,
     62                    FRAME_SIZE);
     63                size_t size = ALIGN_DOWN(memmap.zones[i].size -
     64                    (base - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE);
     65               
     66                if (!frame_adjust_zone_bounds(low, &base, &size))
     67                        return;
     68               
     69                pfn_t pfn = ADDR2PFN(base);
     70                size_t count = SIZE2FRAMES(size);
     71                pfn_t conf;
     72               
     73                if (low) {
     74                        if ((minconf < pfn) || (minconf >= pfn + count))
     75                                conf = pfn;
     76                        else
     77                                conf = minconf;
     78                       
     79                        zone_create(pfn, count, conf,
     80                            ZONE_AVAILABLE | ZONE_LOWMEM);
     81                } else {
     82                        conf = zone_external_conf_alloc(count);
     83                        if (conf != 0)
     84                                zone_create(pfn, count, conf,
     85                                    ZONE_AVAILABLE | ZONE_HIGHMEM);
     86                }
     87        }
     88}
    5189
    5290void frame_low_arch_init(void)
    5391{
     92        frame_common_arch_init(true);
     93       
     94        frame_mark_unavailable(htif_frame, 1);
     95        frame_mark_unavailable(pt_frame, 1);
    5496}
    5597
    5698void frame_high_arch_init(void)
    5799{
     100        frame_common_arch_init(false);
    58101}
    59102
  • kernel/arch/riscv64/src/mm/km.c

    rc16479e rccc362a1  
    3232
    3333#include <arch/mm/km.h>
     34#include <mm/km.h>
    3435#include <stdbool.h>
    3536#include <typedefs.h>
     37#include <macros.h>
    3638
    3739void km_identity_arch_init(void)
    3840{
     41        config.identity_base = KM_RISCV64_IDENTITY_START;
     42        config.identity_size = KM_RISCV64_IDENTITY_SIZE;
    3943}
    4044
    4145void km_non_identity_arch_init(void)
    4246{
     47        km_non_identity_span_add(KM_RISCV64_NON_IDENTITY_START,
     48            KM_RISCV64_NON_IDENTITY_SIZE);
    4349}
    4450
    4551bool km_is_non_identity_arch(uintptr_t addr)
    4652{
    47         return false;
     53        return iswithin(KM_RISCV64_NON_IDENTITY_START,
     54            KM_RISCV64_NON_IDENTITY_SIZE, addr, 1);
    4855}
    4956
  • kernel/arch/riscv64/src/mm/page.c

    rc16479e rccc362a1  
    4848#include <interrupt.h>
    4949
     50#define SATP_PFN_MASK  UINT64_C(0x00000fffffffffff)
     51
     52#define SATP_MODE_MASK  UINT64_C(0xf000000000000000)
     53#define SATP_MODE_BARE  UINT64_C(0x0000000000000000)
     54#define SATP_MODE_SV39  UINT64_C(0x8000000000000000)
     55#define SATP_MODE_SV48  UINT64_C(0x9000000000000000)
     56
    5057void page_arch_init(void)
    5158{
    52         if (config.cpu_active == 1)
     59        if (config.cpu_active == 1) {
    5360                page_mapping_operations = &pt_mapping_operations;
     61               
     62                page_table_lock(AS_KERNEL, true);
     63               
     64                /*
     65                 * PA2KA(identity) mapping for all low-memory frames.
     66                 */
     67                for (uintptr_t cur = 0;
     68                    cur < min(config.identity_size, config.physmem_end);
     69                    cur += FRAME_SIZE)
     70                        page_mapping_insert(AS_KERNEL, PA2KA(cur), cur,
     71                            PAGE_GLOBAL | PAGE_CACHEABLE | PAGE_EXEC | PAGE_WRITE | PAGE_READ);
     72               
     73                page_table_unlock(AS_KERNEL, true);
     74               
     75                // FIXME: register page fault extension handler
     76               
     77                write_satp((uintptr_t) AS_KERNEL->genarch.page_table);
     78               
     79                /* The boot page table is no longer needed. */
     80                // FIXME: frame_mark_available(pt_frame, 1);
     81        }
    5482}
    5583
     
    5886}
    5987
     88void write_satp(uintptr_t ptl0)
     89{
     90        uint64_t satp = ((ptl0 >> FRAME_WIDTH) & SATP_PFN_MASK) |
     91            SATP_MODE_SV48;
     92       
     93        asm volatile (
     94                "csrw sptbr, %[satp]\n"
     95                :: [satp] "r" (satp)
     96        );
     97}
     98
    6099/** @}
    61100 */
  • kernel/arch/riscv64/src/riscv64.c

    rc16479e rccc362a1  
    4949#include <console/console.h>
    5050#include <mem.h>
     51#include <str.h>
    5152
    5253char memcpy_from_uspace_failover_address;
    5354char memcpy_to_uspace_failover_address;
    5455
     56static void riscv64_post_mm_init(void);
     57
    5558arch_ops_t riscv64_ops = {
     59        .post_mm_init = riscv64_post_mm_init
    5660};
    5761
    5862arch_ops_t *arch_ops = &riscv64_ops;
     63
     64void riscv64_pre_main(bootinfo_t *bootinfo)
     65{
     66        physmem_start = bootinfo->physmem_start;
     67        htif_frame = bootinfo->htif_frame;
     68        pt_frame = bootinfo->pt_frame;
     69       
     70        htif_init(bootinfo->ucbinfo.tohost, bootinfo->ucbinfo.fromhost);
     71       
     72        /* Copy tasks map. */
     73        init.cnt = min3(bootinfo->taskmap.cnt, TASKMAP_MAX_RECORDS,
     74            CONFIG_INIT_TASKS);
     75       
     76        for (size_t i = 0; i < init.cnt; i++) {
     77                init.tasks[i].paddr = KA2PA(bootinfo->taskmap.tasks[i].addr);
     78                init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
     79                str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
     80                    bootinfo->taskmap.tasks[i].name);
     81        }
     82       
     83        /* Copy physical memory map. */
     84        memmap.total = bootinfo->memmap.total;
     85        memmap.cnt = min(bootinfo->memmap.cnt, MEMMAP_MAX_RECORDS);
     86        for (size_t i = 0; i < memmap.cnt; i++) {
     87                memmap.zones[i].start = bootinfo->memmap.zones[i].start;
     88                memmap.zones[i].size = bootinfo->memmap.zones[i].size;
     89        }
     90}
     91
     92void riscv64_post_mm_init(void)
     93{
     94        outdev_t *htifout = htifout_init();
     95        if (htifout)
     96                stdout_wire(htifout);
     97}
    5998
    6099void calibrate_delay_loop(void)
     
    90129}
    91130
    92 int context_save_arch(context_t *ctx)
    93 {
    94         return 1;
    95 }
    96 
    97 void context_restore_arch(context_t *ctx)
    98 {
    99         while (true);
    100 }
    101 
    102131void fpu_init(void)
    103132{
     
    122151}
    123152
    124 void early_putchar(wchar_t ch)
    125 {
    126 }
    127 
    128153/** @}
    129154 */
Note: See TracChangeset for help on using the changeset viewer.