Author: br
Date: Thu Oct 18 15:08:14 2018
New Revision: 339421
URL: https://svnweb.freebsd.org/changeset/base/339421

Log:
  Support RISC-V implementations that do not manage the A and D bits
  (e.g. RocketChip, lowRISC and derivatives).
  
  RISC-V page table entries support A (accessed) and D (dirty) bits. The
  spec makes hardware support for these bits optional. Implementations that
  do not manage these bits in hardware raise page faults for accesses to a
  valid page without A set and writes to a writable page without D set.
  Check for these types of faults when handling a page fault and fixup the
  PTE without calling vm_fault if they occur.
  
  Reviewed by:  jhb, markj
  Approved by:  re (gjb)
  Sponsored by: DARPA, AFRL
  Differential Revision:        https://reviews.freebsd.org/D17424

Modified:
  head/sys/arm/arm/pl310.c
  head/sys/arm/conf/GENERIC
  head/sys/arm/conf/GENERIC-MMCCAM
  head/sys/arm/conf/SOCDK
  head/sys/dts/arm/socfpga_arria10_socdk_sdmmc.dts
  head/sys/riscv/include/pmap.h
  head/sys/riscv/include/pte.h
  head/sys/riscv/riscv/locore.S
  head/sys/riscv/riscv/pmap.c
  head/sys/riscv/riscv/trap.c

Modified: head/sys/arm/arm/pl310.c
==============================================================================
--- head/sys/arm/arm/pl310.c    Thu Oct 18 15:02:57 2018        (r339420)
+++ head/sys/arm/arm/pl310.c    Thu Oct 18 15:08:14 2018        (r339421)
@@ -168,27 +168,34 @@ pl310_set_ram_latency(struct pl310_softc *sc, uint32_t
 {
        uint32_t v;
 
+       printf("%s\n", __func__);
        KASSERT(which_reg == PL310_TAG_RAM_CTRL ||
            which_reg == PL310_DATA_RAM_CTRL,
            ("bad pl310 ram latency register address"));
 
+       printf("%s\n", __func__);
        v = pl310_read4(sc, which_reg);
+       printf("%s\n", __func__);
        if (setup != 0) {
                KASSERT(setup <= 8, ("bad pl310 setup latency: %d", setup));
                v &= ~RAM_CTRL_SETUP_MASK;
                v |= (setup - 1) << RAM_CTRL_SETUP_SHIFT;
        }
+       printf("%s\n", __func__);
        if (read != 0) {
                KASSERT(read <= 8, ("bad pl310 read latency: %d", read));
                v &= ~RAM_CTRL_READ_MASK;
                v |= (read - 1) << RAM_CTRL_READ_SHIFT;
        }
+       printf("%s\n", __func__);
        if (write != 0) {
                KASSERT(write <= 8, ("bad pl310 write latency: %d", write));
                v &= ~RAM_CTRL_WRITE_MASK;
                v |= (write - 1) << RAM_CTRL_WRITE_SHIFT;
        }
+       printf("%s wr\n", __func__);
        pl310_write4(sc, which_reg, v);
+       printf("%s done\n", __func__);
 }
 
 static int
@@ -482,6 +489,8 @@ pl310_attach(device_t dev)
        uint32_t cache_id, debug_ctrl;
        phandle_t node;
 
+       printf("%s\n", __func__);
+
        sc->sc_dev = dev;
        rid = 0;
        sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
@@ -489,6 +498,8 @@ pl310_attach(device_t dev)
        if (sc->sc_mem_res == NULL)
                panic("%s: Cannot map registers", device_get_name(dev));
 
+       printf("%s\n", __func__);
+
        /* Allocate an IRQ resource */
        rid = 0;
        sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
@@ -497,10 +508,16 @@ pl310_attach(device_t dev)
                device_printf(dev, "cannot allocate IRQ, not using 
interrupt\n");
        }
 
+       printf("%s: mtx init\n", __func__);
        pl310_softc = sc;
        mtx_init(&sc->sc_mtx, "pl310lock", NULL, MTX_SPIN);
 
+       printf("%s: pl310_read4\n", __func__);
+       printf("%s: pl310_read4\n", __func__);
+       printf("%s: pl310_read4\n", __func__);
+
        cache_id = pl310_read4(sc, PL310_CACHE_ID);
+       printf("%s\n", __func__);
        sc->sc_rtl_revision = (cache_id >> CACHE_ID_RELEASE_SHIFT) &
            CACHE_ID_RELEASE_MASK;
        device_printf(dev, "Part number: 0x%x, release: 0x%x\n",

Modified: head/sys/arm/conf/GENERIC
==============================================================================
--- head/sys/arm/conf/GENERIC   Thu Oct 18 15:02:57 2018        (r339420)
+++ head/sys/arm/conf/GENERIC   Thu Oct 18 15:08:14 2018        (r339421)
@@ -36,6 +36,7 @@ files         "../allwinner/a31/files.a31"
 files          "../allwinner/a33/files.a33"
 files          "../allwinner/a83t/files.a83t"
 files          "../allwinner/h3/files.h3"
+files          "../altera/socfpga/files.socfpga"
 files          "../broadcom/bcm2835/files.bcm2836"
 files          "../broadcom/bcm2835/files.bcm283x"
 files          "../freescale/imx/files.imx6"
@@ -56,6 +57,8 @@ options       SOC_ALLWINNER_A33
 options        SOC_ALLWINNER_A83T
 options        SOC_ALLWINNER_H2PLUS
 options        SOC_ALLWINNER_H3
+options        SOC_ALTERA_ARRIA10
+options        SOC_ALTERA_CYCLONE5
 options        SOC_BCM2836
 options        SOC_MV_ARMADA38X
 options        SOC_MV_ARMADAXP
@@ -89,10 +92,15 @@ device              pmu
 device         generic_timer
 device         mpcore_timer
 
+# DMA support
+device         xdma
+device         pl330
+
 # MMC/SD/SDIO Card slot support
 device         sdhci                   # SD controller
 device         mmc                     # mmc/sd bus
 device         mmcsd                   # mmc/sd flash cards
+device         dwmmc
 
 # ATA controllers
 device         ahci                    # AHCI-compatible SATA controllers
@@ -169,7 +177,9 @@ device              aw_cir
 device         spibus
 device         spigen
 device         bcm2835_spi
+device         cqspi                   # Cadence Quad SPI Flash Controller
 device         ti_spi
+device         n25q                    # n25q Quad SPI Flash
 
 # ADC support
 device         ti_adc

Modified: head/sys/arm/conf/GENERIC-MMCCAM
==============================================================================
--- head/sys/arm/conf/GENERIC-MMCCAM    Thu Oct 18 15:02:57 2018        
(r339420)
+++ head/sys/arm/conf/GENERIC-MMCCAM    Thu Oct 18 15:08:14 2018        
(r339421)
@@ -20,3 +20,6 @@ device                pass
 
 nodevice       mmc
 nodevice       mmcsd
+
+# dwmmc_altera.c fails to build
+nodevice       dwmmc

Modified: head/sys/arm/conf/SOCDK
==============================================================================
--- head/sys/arm/conf/SOCDK     Thu Oct 18 15:02:57 2018        (r339420)
+++ head/sys/arm/conf/SOCDK     Thu Oct 18 15:08:14 2018        (r339421)
@@ -20,7 +20,7 @@
 
 #NO_UNIVERSE
 
-include        "SOCFPGA"
+include        "GENERIC"
 ident          SOCDK
 
 options                ROOTDEVNAME=\"ufs:/dev/mmcsd0s4\"

Modified: head/sys/dts/arm/socfpga_arria10_socdk_sdmmc.dts
==============================================================================
--- head/sys/dts/arm/socfpga_arria10_socdk_sdmmc.dts    Thu Oct 18 15:02:57 
2018        (r339420)
+++ head/sys/dts/arm/socfpga_arria10_socdk_sdmmc.dts    Thu Oct 18 15:08:14 
2018        (r339421)
@@ -61,6 +61,10 @@
        };
 };
 
+&L2 {
+       status = "disabled";
+};
+
 &uart1 {
        clock-frequency = < 50000000 >;
 };

Modified: head/sys/riscv/include/pmap.h
==============================================================================
--- head/sys/riscv/include/pmap.h       Thu Oct 18 15:02:57 2018        
(r339420)
+++ head/sys/riscv/include/pmap.h       Thu Oct 18 15:08:14 2018        
(r339421)
@@ -153,6 +153,8 @@ bool        pmap_get_tables(pmap_t, vm_offset_t, pd_entry_t 
*
 
 #define        pmap_page_is_mapped(m)  (!TAILQ_EMPTY(&(m)->md.pv_list))
 
+int pmap_fault_fixup(pmap_t, vm_offset_t, vm_prot_t);
+
 #endif /* _KERNEL */
 
 #endif /* !LOCORE */

Modified: head/sys/riscv/include/pte.h
==============================================================================
--- head/sys/riscv/include/pte.h        Thu Oct 18 15:02:57 2018        
(r339420)
+++ head/sys/riscv/include/pte.h        Thu Oct 18 15:08:14 2018        
(r339421)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2014 Andrew Turner
- * Copyright (c) 2015-2016 Ruslan Bukin <b...@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <b...@bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -65,7 +65,7 @@ typedef       uint64_t        pn_t;                   /* page 
number */
 #define        Ln_ENTRIES      (1 << 9)
 #define        Ln_ADDR_MASK    (Ln_ENTRIES - 1)
 
-/* Bits 9:7 are reserved for software */
+/* Bits 9:8 are reserved for software */
 #define        PTE_SW_MANAGED  (1 << 9)
 #define        PTE_SW_WIRED    (1 << 8)
 #define        PTE_D           (1 << 7) /* Dirty */
@@ -78,6 +78,7 @@ typedef       uint64_t        pn_t;                   /* page 
number */
 #define        PTE_V           (1 << 0) /* Valid */
 #define        PTE_RWX         (PTE_R | PTE_W | PTE_X)
 #define        PTE_RX          (PTE_R | PTE_X)
+#define        PTE_KERN        (PTE_V | PTE_RWX | PTE_A | PTE_D)
 
 #define        PTE_PPN0_S      10
 #define        PTE_PPN1_S      19

Modified: head/sys/riscv/riscv/locore.S
==============================================================================
--- head/sys/riscv/riscv/locore.S       Thu Oct 18 15:02:57 2018        
(r339420)
+++ head/sys/riscv/riscv/locore.S       Thu Oct 18 15:08:14 2018        
(r339421)
@@ -94,7 +94,7 @@ _start:
        add     t3, t4, t2
        li      t5, 0
 2:
-       li      t0, (PTE_V | PTE_RWX | PTE_D)
+       li      t0, (PTE_KERN)
        slli    t2, t4, PTE_PPN1_S      /* << PTE_PPN1_S */
        or      t5, t0, t2
        sd      t5, (s1)                /* Store PTE entry to position */
@@ -126,7 +126,7 @@ _start:
        mv      s2, s11
        srli    s2, s2, PAGE_SHIFT
 
-       li      t0, (PTE_V | PTE_RWX | PTE_D)
+       li      t0, (PTE_KERN)
        slli    t2, s2, PTE_PPN0_S      /* << PTE_PPN0_S */
        or      t0, t0, t2
 

Modified: head/sys/riscv/riscv/pmap.c
==============================================================================
--- head/sys/riscv/riscv/pmap.c Thu Oct 18 15:02:57 2018        (r339420)
+++ head/sys/riscv/riscv/pmap.c Thu Oct 18 15:08:14 2018        (r339421)
@@ -15,7 +15,7 @@
  * All rights reserved.
  * Copyright (c) 2014 The FreeBSD Foundation
  * All rights reserved.
- * Copyright (c) 2015-2017 Ruslan Bukin <b...@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <b...@bsdpad.com>
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
@@ -487,7 +487,7 @@ pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t mi
 
                /* superpages */
                pn = (pa / PAGE_SIZE);
-               entry = (PTE_V | PTE_RWX);
+               entry = PTE_KERN;
                entry |= (pn << PTE_PPN0_S);
                pmap_load_store(&l1[l1_slot], entry);
        }
@@ -965,7 +965,7 @@ pmap_kenter_device(vm_offset_t sva, vm_size_t size, vm
                KASSERT(l3 != NULL, ("Invalid page table, va: 0x%lx", va));
 
                pn = (pa / PAGE_SIZE);
-               entry = (PTE_V | PTE_RWX);
+               entry = PTE_KERN;
                entry |= (pn << PTE_PPN0_S);
                pmap_load_store(l3, entry);
 
@@ -1063,7 +1063,7 @@ pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count)
                pn = (pa / PAGE_SIZE);
                l3 = pmap_l3(kernel_pmap, va);
 
-               entry = (PTE_V | PTE_RWX);
+               entry = PTE_KERN;
                entry |= (pn << PTE_PPN0_S);
                pmap_load_store(l3, entry);
 
@@ -1465,7 +1465,8 @@ pmap_growkernel(vm_offset_t addr)
                        continue; /* try again */
                }
                l2 = pmap_l1_to_l2(l1, kernel_vm_end);
-               if ((pmap_load(l2) & PTE_A) != 0) {
+               if ((pmap_load(l2) & PTE_V) != 0 &&
+                   (pmap_load(l2) & PTE_RWX) == 0) {
                        kernel_vm_end = (kernel_vm_end + L2_SIZE) & ~L2_OFFSET;
                        if (kernel_vm_end - 1 >= vm_map_max(kernel_map)) {
                                kernel_vm_end = vm_map_max(kernel_map);
@@ -2008,6 +2009,41 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t
        PMAP_UNLOCK(pmap);
 }
 
+int
+pmap_fault_fixup(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
+{
+       pt_entry_t orig_l3;
+       pt_entry_t new_l3;
+       pt_entry_t *l3;
+
+       l3 = pmap_l3(pmap, va);
+       if (l3 == NULL)
+               return (0);
+
+       orig_l3 = pmap_load(l3);
+       if ((orig_l3 & PTE_V) == 0 ||
+           ((prot & VM_PROT_WRITE) != 0 && (orig_l3 & PTE_W) == 0) ||
+           ((prot & VM_PROT_READ) != 0 && (orig_l3 & PTE_R) == 0))
+               return (0);
+
+       new_l3 = orig_l3 | PTE_A;
+       if ((prot & VM_PROT_WRITE) != 0)
+               new_l3 |= PTE_D;
+
+       if (orig_l3 != new_l3) {
+               pmap_load_store(l3, new_l3);
+               pmap_invalidate_page(pmap, va);
+               return (1);
+       }
+
+       /*      
+        * XXX: This case should never happen since it means
+        * the PTE shouldn't have resulted in a fault.
+        */
+
+       return (0);
+}
+
 /*
  *     Insert the given physical page (p) at
  *     the specified virtual address (v) in the
@@ -2415,8 +2451,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, v
        pa = VM_PAGE_TO_PHYS(m);
        pn = (pa / PAGE_SIZE);
 
-       /* RISCVTODO: check permissions */
-       entry = (PTE_V | PTE_RWX);
+       entry = (PTE_V | PTE_R | PTE_X);
        entry |= (pn << PTE_PPN0_S);
 
        /*

Modified: head/sys/riscv/riscv/trap.c
==============================================================================
--- head/sys/riscv/riscv/trap.c Thu Oct 18 15:02:57 2018        (r339420)
+++ head/sys/riscv/riscv/trap.c Thu Oct 18 15:08:14 2018        (r339421)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015-2017 Ruslan Bukin <b...@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <b...@bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -212,6 +212,9 @@ data_abort(struct trapframe *frame, int lower)
                ftype = (VM_PROT_READ);
        }
 
+       if (pmap_fault_fixup(map->pmap, va, ftype))
+               goto done;
+
        if (map != kernel_map) {
                /*
                 * Keep swapout from messing with us during this
@@ -256,6 +259,7 @@ data_abort(struct trapframe *frame, int lower)
                }
        }
 
+done:
        if (lower)
                userret(td, frame);
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to