The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/riscv/riscv/locore.S

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com>
    3  * All rights reserved.
    4  *
    5  * Portions of this software were developed by SRI International and the
    6  * University of Cambridge Computer Laboratory under DARPA/AFRL contract
    7  * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
    8  *
    9  * Portions of this software were developed by the University of Cambridge
   10  * Computer Laboratory as part of the CTSRD Project, with support from the
   11  * UK Higher Education Innovation Fund (HEIF).
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  *
   34  * $FreeBSD: releng/11.2/sys/riscv/riscv/locore.S 298580 2016-04-25 14:47:51Z br $
   35  */
   36 
   37 #include "assym.s"
   38 
   39 #include <sys/syscall.h>
   40 #include <machine/asm.h>
   41 #include <machine/param.h>
   42 #include <machine/trap.h>
   43 #include <machine/riscvreg.h>
   44 #include <machine/pte.h>
   45 
   46 #define HTIF_RING_NENTRIES      (512)
   47 #define HTIF_RING_ENTRY_SZ      (24)
   48 #define HTIF_RING_SIZE          (HTIF_RING_ENTRY_SZ * HTIF_RING_NENTRIES)
   49 #define HW_STACK_SIZE           (96)
   50 
   51 /*
   52  * Event queue for each CPU core:
   53  *
   54  * struct htif_ring {
   55  *     uint64_t data;
   56  *     uint64_t used;
   57  *     uint64_t next;
   58  * } htif_ring[HTIF_RING_NENTRIES];
   59  * uint64_t htif_ring_cursor;
   60  * uint64_t htif_ring_last;
   61  */
   62 
   63 .macro build_ring
   64         la      t0, htif_ring
   65 #ifdef SMP
   66         csrr    a0, mhartid
   67         li      s0, (HTIF_RING_SIZE + 16)
   68         mulw    s0, a0, s0
   69         add     t0, t0, s0
   70 #endif
   71         li      t1, 0
   72         sd      t1, 0(t0)       /* zero data */
   73         sd      t1, 8(t0)       /* zero used */
   74         mv      t2, t0
   75         mv      t3, t0
   76         li      t5, (HTIF_RING_SIZE)
   77         li      t6, 0
   78         add     t4, t0, t5
   79 1:
   80         addi    t3, t3, HTIF_RING_ENTRY_SZ      /* pointer to next */
   81         beq     t3, t4, 2f                      /* finish */
   82         sd      t3, 16(t2)                      /* store pointer */
   83         addi    t2, t2, HTIF_RING_ENTRY_SZ      /* next entry */
   84         addi    t6, t6, 1                       /* counter */
   85         j       1b
   86 2:
   87         addi    t3, t3, -HTIF_RING_ENTRY_SZ
   88         sd      t0, 16(t3)                      /* last -> first */
   89 
   90         li      t2, (HTIF_RING_SIZE)
   91         add     s0, t0, t2
   92         sd      t0, 0(s0)       /* cursor */
   93         sd      t0, 8(s0)       /* last */
   94         /* finish building ring */
   95 .endm
   96 
   97         .globl  kernbase
   98         .set    kernbase, KERNBASE
   99 
  100         /* Trap entries */
  101         .text
  102 
  103 mentry:
  104         /* User mode entry point (mtvec + 0x000) */
  105         .align 6
  106         j       user_trap
  107 
  108         /* Supervisor mode entry point (mtvec + 0x040) */
  109         .align 6
  110         j       supervisor_trap
  111 
  112         /* Hypervisor mode entry point (mtvec + 0x080) */
  113         .align 6
  114         j       bad_trap
  115 
  116         /* Machine mode entry point (mtvec + 0x0C0) */
  117         .align 6
  118         j       bad_trap
  119 
  120         /* Reset vector */
  121         .text
  122         .align 8
  123         .globl _start
  124 _start:
  125         /* Direct secondary cores to mpentry */
  126         csrr    a0, mhartid
  127         bnez    a0, mpentry
  128 
  129         /* Build event queue for current core */
  130         build_ring
  131 
  132         /* Setup machine-mode stack for CPU 0 */
  133         la      t0, hardstack_end
  134         csrw    mscratch, t0
  135 
  136         li      t0, 0
  137         csrw    sscratch, t0
  138 
  139         li      s10, PAGE_SIZE
  140         li      s9, (PAGE_SIZE * KSTACK_PAGES)
  141 
  142         /* Page tables */
  143 
  144         /* Create an L1 page for early devmap */
  145         la      s1, pagetable_l1
  146         la      s2, pagetable_l2_devmap /* Link to next level PN */
  147         srli    s2, s2, PAGE_SHIFT
  148 
  149         li      a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE)
  150         srli    a5, a5, L1_SHIFT        /* >> L1_SHIFT */
  151         andi    a5, a5, 0x1ff           /* & 0x1ff */
  152         li      t4, (PTE_VALID | (PTE_TYPE_PTR << PTE_TYPE_S))
  153         slli    t5, s2, PTE_PPN0_S      /* (s2 << PTE_PPN0_S) */
  154         or      t6, t4, t5
  155 
  156         /* Store single level1 PTE entry to position */
  157         li      a6, PTE_SIZE
  158         mulw    a5, a5, a6
  159         add     t0, s1, a5
  160         sd      t6, (t0)
  161 
  162         /* Add single Level 1 entry for kernel */
  163         la      s1, pagetable_l1
  164         la      s2, pagetable_l2        /* Link to next level PN */
  165         srli    s2, s2, PAGE_SHIFT
  166 
  167         li      a5, KERNBASE
  168         srli    a5, a5, L1_SHIFT        /* >> L1_SHIFT */
  169         andi    a5, a5, 0x1ff           /* & 0x1ff */
  170         li      t4, (PTE_VALID | (PTE_TYPE_PTR << PTE_TYPE_S))
  171         slli    t5, s2, PTE_PPN0_S      /* (s2 << PTE_PPN0_S) */
  172         or      t6, t4, t5
  173 
  174         /* Store single level1 PTE entry to position */
  175         li      a6, PTE_SIZE
  176         mulw    a5, a5, a6
  177         add     t0, s1, a5
  178         sd      t6, (t0)
  179 
  180         /* Level 2 superpages (512 x 2MiB) */
  181         la      s1, pagetable_l2
  182         li      t3, 512                 /* Build 512 entries */
  183         li      t4, 0                   /* Counter */
  184         li      t5, 0
  185 2:
  186         li      t0, (PTE_VALID | (PTE_TYPE_SRWX << PTE_TYPE_S))
  187         slli    t2, t4, PTE_PPN1_S      /* << PTE_PPN1_S */
  188         or      t5, t0, t2
  189         sd      t5, (s1)                /* Store PTE entry to position */
  190         addi    s1, s1, PTE_SIZE
  191 
  192         addi    t4, t4, 1
  193         bltu    t4, t3, 2b
  194 
  195         /* Set page tables base register */
  196         la      s1, pagetable_l1
  197         csrw    sptbr, s1
  198 
  199         /* Page tables END */
  200 
  201         /* Enter supervisor mode */
  202         li      s0, ((MSTATUS_VM_SV39 << MSTATUS_VM_SHIFT) | \
  203                      (MSTATUS_PRV_M << MSTATUS_PRV_SHIFT) | \
  204                      (MSTATUS_PRV_S << MSTATUS_PRV1_SHIFT) | \
  205                      (MSTATUS_PRV_U << MSTATUS_PRV2_SHIFT));
  206         csrw    mstatus, s0
  207 
  208         /*
  209          * Enable machine-mode software interrupts
  210          * so we can deliver IPI to this core.
  211          */
  212         li      t0, MIE_MSIE
  213         csrs    mie, t0
  214 
  215         /* Exit from machine mode */
  216         la      t0, .Lmmu_on
  217         li      s11, KERNBASE
  218         add     t0, t0, s11
  219         csrw    mepc, t0
  220         eret
  221 
  222 .Lmmu_on:
  223         /* Initialize stack pointer */
  224         la      s3, initstack_end
  225         mv      sp, s3
  226         addi    sp, sp, -PCB_SIZE
  227 
  228         /* Clear BSS  */
  229         la      a0, _C_LABEL(__bss_start)
  230         la      s1, _C_LABEL(_end)
  231 1:
  232         sd      zero, 0(a0)
  233         addi    a0, a0, 8
  234         bltu    a0, s1, 1b
  235 
  236         /* Fill riscv_bootparams */
  237         addi    sp, sp, -16
  238         la      t0, pagetable_l1
  239         sd      t0, 0(sp) /* kern_l1pt */
  240         la      t0, initstack_end
  241         sd      t0, 8(sp) /* kern_stack */
  242 
  243         mv      a0, sp
  244         call    _C_LABEL(initriscv)     /* Off we go */
  245         call    _C_LABEL(mi_startup)
  246 
  247         .align  4
  248 initstack:
  249         .space  (PAGE_SIZE * KSTACK_PAGES)
  250 initstack_end:
  251 hardstack:
  252         .space  (HW_STACK_SIZE * MAXCPU)
  253 hardstack_end:
  254 
  255         .globl htif_ring
  256 htif_ring:
  257         .space ((HTIF_RING_SIZE + 16) * MAXCPU)
  258 
  259         .globl console_intr
  260 console_intr:
  261         .space (8)
  262 
  263 ENTRY(sigcode)
  264         mv      a0, sp
  265         addi    a0, a0, SF_UC
  266 
  267 1:
  268         li      t0, SYS_sigreturn
  269         ecall
  270 
  271         /* sigreturn failed, exit */
  272         li      t0, SYS_exit
  273         ecall
  274 
  275         j       1b
  276 END(sigcode)
  277         /* This may be copied to the stack, keep it 16-byte aligned */
  278         .align  3
  279 esigcode:
  280 
  281         .data
  282         .align  3
  283         .global szsigcode
  284 szsigcode:
  285         .quad   esigcode - sigcode
  286 
  287         .align  12
  288 pagetable_l1:
  289         .space  PAGE_SIZE
  290 pagetable_l2:
  291         .space  PAGE_SIZE
  292 pagetable_l2_devmap:
  293         .space  PAGE_SIZE
  294 
  295         .globl init_pt_va
  296 init_pt_va:
  297         .quad pagetable_l2      /* XXX: Keep page tables VA */
  298 
  299 #ifndef SMP
  300 ENTRY(mpentry)
  301 1:
  302         wfi
  303         j       1b
  304 END(mpentry)
  305 #else
  306 /*
  307  * mpentry(unsigned long)
  308  *
  309  * Called by a core when it is being brought online.
  310  * The data in x0 is passed straight to init_secondary.
  311  */
  312 ENTRY(mpentry)
  313         /*
  314          * Calculate the offset to __riscv_boot_ap
  315          * for current core, cpuid in a0.
  316          */
  317         li      t1, 4
  318         mulw    t1, t1, a0
  319         /* Get pointer */
  320         la      t0, __riscv_boot_ap
  321         add     t0, t0, t1
  322 
  323 1:
  324         /* Wait the kernel to be ready */
  325         lw      t1, 0(t0)
  326         beqz    t1, 1b
  327 
  328         /* Build event queue ring for this core */
  329         build_ring
  330 
  331         /* Set page tables base register */
  332         la      t0, pagetable_l1
  333         csrw    sptbr, t0
  334 
  335         /* Configure mstatus */
  336         li      s0, ((MSTATUS_VM_SV39 << MSTATUS_VM_SHIFT) | \
  337                      (MSTATUS_PRV_M << MSTATUS_PRV_SHIFT) | \
  338                      (MSTATUS_PRV_S << MSTATUS_PRV1_SHIFT) | \
  339                      (MSTATUS_PRV_U << MSTATUS_PRV2_SHIFT));
  340         csrw    mstatus, s0
  341 
  342         /* Setup stack for machine mode exceptions */
  343         la      t0, hardstack_end
  344         li      t1, HW_STACK_SIZE
  345         mulw    t1, t1, a0
  346         sub     t0, t0, t1
  347         csrw    mscratch, t0
  348 
  349         li      t0, 0
  350         csrw    sscratch, t0
  351 
  352         /*
  353          * Enable machine-mode software interrupts
  354          * so we can deliver IPI to this core.
  355          */
  356         li      t0, MIE_MSIE
  357         csrs    mie, t0
  358 
  359         /*
  360          * Exit from machine mode and go to
  361          * the virtual address space.
  362          */
  363         la      t0, mp_virtdone
  364         li      s11, KERNBASE
  365         add     t0, t0, s11
  366         csrw    mepc, t0
  367         eret
  368 
  369 mp_virtdone:
  370         /* We are now in virtual address space */
  371 
  372         /* Setup stack pointer */
  373         la      t0, secondary_stacks
  374         li      t1, (PAGE_SIZE * KSTACK_PAGES)
  375         mulw    t1, t1, a0
  376         add     sp, t0, t1
  377 
  378         call    init_secondary
  379 END(mpentry)
  380 #endif
  381 
  382 #include "exception.S"

Cache object: 5f1580abc8c1c52b1c7d545262dea6f6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.