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-2018 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$
   35  */
   36 
   37 #include "assym.inc"
   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         .globl  kernbase
   47         .set    kernbase, KERNBASE
   48 
   49         /* Trap entries */
   50         .text
   51 
   52         /* Reset vector */
   53         .text
   54         .globl _start
   55 _start:
   56         /*
   57          * a0 = hart id
   58          * a1 = dtbp
   59          */
   60 
   61         /* Pick a hart to run the boot process. */
   62         lla     t0, hart_lottery
   63         li      t1, 1
   64         amoadd.w t0, t1, 0(t0)
   65 
   66         /*
   67          * We must jump to mpentry in the non-BSP case because the offset is
   68          * too large to fit in a 12-bit branch immediate.
   69          */
   70         beqz    t0, 1f
   71         j       mpentry
   72 
   73         /*
   74          * Page tables
   75          */
   76 1:
   77         /* Get the kernel's load address */
   78         jal     get_physmem
   79 
   80         /* Add L1 entry for kernel */
   81         lla     s1, pagetable_l1
   82         lla     s2, pagetable_l2        /* Link to next level PN */
   83         srli    s2, s2, PAGE_SHIFT
   84 
   85         li      a5, KERNBASE
   86         srli    a5, a5, L1_SHIFT        /* >> L1_SHIFT */
   87         andi    a5, a5, 0x1ff           /* & 0x1ff */
   88         li      t4, PTE_V
   89         slli    t5, s2, PTE_PPN0_S      /* (s2 << PTE_PPN0_S) */
   90         or      t6, t4, t5
   91 
   92         /* Store L1 PTE entry to position */
   93         li      a6, PTE_SIZE
   94         mulw    a5, a5, a6
   95         add     t0, s1, a5
   96         sd      t6, (t0)
   97 
   98         /* Level 2 superpages (512 x 2MiB) */
   99         lla     s1, pagetable_l2
  100         srli    t4, s9, 21              /* Div physmem base by 2 MiB */
  101         li      t2, 512                 /* Build 512 entries */
  102         add     t3, t4, t2
  103         li      t5, 0
  104 2:
  105         li      t0, (PTE_KERN | PTE_X)
  106         slli    t2, t4, PTE_PPN1_S      /* << PTE_PPN1_S */
  107         or      t5, t0, t2
  108         sd      t5, (s1)                /* Store PTE entry to position */
  109         addi    s1, s1, PTE_SIZE
  110 
  111         addi    t4, t4, 1
  112         bltu    t4, t3, 2b
  113 
  114         /* Create an L1 page for early devmap */
  115         lla     s1, pagetable_l1
  116         lla     s2, pagetable_l2_devmap /* Link to next level PN */
  117         srli    s2, s2, PAGE_SHIFT
  118 
  119         li      a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE)
  120         srli    a5, a5, L1_SHIFT        /* >> L1_SHIFT */
  121         andi    a5, a5, 0x1ff           /* & 0x1ff */
  122         li      t4, PTE_V
  123         slli    t5, s2, PTE_PPN0_S      /* (s2 << PTE_PPN0_S) */
  124         or      t6, t4, t5
  125 
  126         /* Store single level1 PTE entry to position */
  127         li      a6, PTE_SIZE
  128         mulw    a5, a5, a6
  129         add     t0, s1, a5
  130         sd      t6, (t0)
  131 
  132         /* Create an L2 page superpage for DTB */
  133         lla     s1, pagetable_l2_devmap
  134         mv      s2, a1
  135         srli    s2, s2, PAGE_SHIFT
  136 
  137         li      t0, (PTE_KERN)
  138         slli    t2, s2, PTE_PPN0_S      /* << PTE_PPN0_S */
  139         or      t0, t0, t2
  140 
  141         /* Store PTE entry to position */
  142         li      a6, PTE_SIZE
  143         li      a5, 510
  144         mulw    a5, a5, a6
  145         add     t1, s1, a5
  146         sd      t0, (t1)
  147 
  148         /* Page tables END */
  149 
  150         /* Setup supervisor trap vector */
  151         lla     t0, va
  152         sub     t0, t0, s9
  153         li      t1, KERNBASE
  154         add     t0, t0, t1
  155         csrw    stvec, t0
  156 
  157         /* Set page tables base register */
  158         lla     s2, pagetable_l1
  159         srli    s2, s2, PAGE_SHIFT
  160         li      t0, SATP_MODE_SV39
  161         or      s2, s2, t0
  162         sfence.vma
  163         csrw    satp, s2
  164 
  165         .align 2
  166 va:
  167 
  168         /* Setup supervisor trap vector */
  169         la      t0, cpu_exception_handler
  170         csrw    stvec, t0
  171 
  172         /* Ensure sscratch is zero */
  173         li      t0, 0
  174         csrw    sscratch, t0
  175 
  176         /* Set the global pointer */
  177 .option push
  178 .option norelax
  179         la      gp, __global_pointer$
  180 .option pop
  181 
  182         /* Initialize stack pointer */
  183         la      s3, initstack_end
  184         mv      sp, s3
  185         addi    sp, sp, -PCB_SIZE
  186 
  187         /* Clear BSS */
  188         la      s0, _C_LABEL(__bss_start)
  189         la      s1, _C_LABEL(_end)
  190 1:
  191         sd      zero, 0(s0)
  192         addi    s0, s0, 8
  193         bltu    s0, s1, 1b
  194 
  195 #ifdef SMP
  196         /* Store boot hart id. */
  197         la      t0, boot_hart
  198         sw      a0, 0(t0)
  199 #endif
  200 
  201         /* Fill riscv_bootparams */
  202         addi    sp, sp, -40
  203 
  204         la      t0, pagetable_l1
  205         sd      t0, 0(sp) /* kern_l1pt */
  206         sd      s9, 8(sp) /* kern_phys */
  207 
  208         la      t0, initstack
  209         sd      t0, 16(sp) /* kern_stack */
  210 
  211         li      t0, (VM_MAX_KERNEL_ADDRESS - 2 * L2_SIZE)
  212         sd      t0, 24(sp) /* dtbp_virt */
  213         sd      a1, 32(sp) /* dtbp_phys */
  214 
  215         mv      a0, sp
  216         call    _C_LABEL(initriscv)     /* Off we go */
  217         call    _C_LABEL(mi_startup)
  218 
  219 /*
  220  * Get the physical address the kernel is loaded to. Returned in s9.
  221  */
  222 get_physmem:
  223         lla     t0, virt_map    /* physical address of virt_map */
  224         ld      t1, 0(t0)       /* virtual address of virt_map */
  225         sub     t1, t1, t0      /* calculate phys->virt delta */
  226         li      t2, KERNBASE
  227         sub     s9, t2, t1      /* s9 = physmem base */
  228         ret
  229 
  230         .align  4
  231 initstack:
  232         .space  (PAGE_SIZE * KSTACK_PAGES)
  233 initstack_end:
  234 
  235 ENTRY(sigcode)
  236         mv      a0, sp
  237         addi    a0, a0, SF_UC
  238 
  239 1:
  240         li      t0, SYS_sigreturn
  241         ecall
  242 
  243         /* sigreturn failed, exit */
  244         li      t0, SYS_exit
  245         ecall
  246 
  247         j       1b
  248 END(sigcode)
  249         /* This may be copied to the stack, keep it 16-byte aligned */
  250         .align  3
  251 esigcode:
  252 
  253         .data
  254         .align  3
  255         .global szsigcode
  256 szsigcode:
  257         .quad   esigcode - sigcode
  258 
  259         .align  12
  260 pagetable_l1:
  261         .space  PAGE_SIZE
  262 pagetable_l2:
  263         .space  PAGE_SIZE
  264 pagetable_l2_devmap:
  265         .space  PAGE_SIZE
  266 
  267         .align 3
  268 virt_map:
  269         .quad   virt_map
  270 hart_lottery:
  271         .space  4
  272 
  273         .globl init_pt_va
  274 init_pt_va:
  275         .quad pagetable_l2      /* XXX: Keep page tables VA */
  276 
  277 #ifndef SMP
  278 ENTRY(mpentry)
  279 1:
  280         wfi
  281         j       1b
  282 END(mpentry)
  283 #else
  284 /*
  285  * mpentry(unsigned long)
  286  *
  287  * Called by a core when it is being brought online.
  288  */
  289 ENTRY(mpentry)
  290         /*
  291          * Calculate the offset to __riscv_boot_ap
  292          * for the current core, cpuid is in a0.
  293          */
  294         li      t1, 4
  295         mulw    t1, t1, a0
  296         /* Get the pointer */
  297         lla     t0, __riscv_boot_ap
  298         add     t0, t0, t1
  299 
  300 1:
  301         /* Wait the kernel to be ready */
  302         lw      t1, 0(t0)
  303         beqz    t1, 1b
  304 
  305         /* Setup stack pointer */
  306         lla     t0, bootstack
  307         ld      sp, 0(t0)
  308 
  309         /* Get the kernel's load address */
  310         jal get_physmem
  311 
  312         /* Setup supervisor trap vector */
  313         lla     t0, mpva
  314         sub     t0, t0, s9
  315         li      t1, KERNBASE
  316         add     t0, t0, t1
  317         csrw    stvec, t0
  318 
  319         /* Set page tables base register */
  320         lla     s2, pagetable_l1
  321         srli    s2, s2, PAGE_SHIFT
  322         li      t0, SATP_MODE_SV39
  323         or      s2, s2, t0
  324         sfence.vma
  325         csrw    satp, s2
  326 
  327         .align 2
  328 mpva:
  329         /* Setup supervisor trap vector */
  330         la      t0, cpu_exception_handler
  331         csrw    stvec, t0
  332 
  333         /* Ensure sscratch is zero */
  334         li      t0, 0
  335         csrw    sscratch, t0
  336 
  337         /* Set the global pointer */
  338 .option push
  339 .option norelax
  340         la      gp, __global_pointer$
  341 .option pop
  342 
  343         call    init_secondary
  344 END(mpentry)
  345 #endif

Cache object: c377e23a125f7d8849c022211fe9fc44


[ 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.