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/machdep.c

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) 2014 Andrew Turner
    3  * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com>
    4  * All rights reserved.
    5  *
    6  * Portions of this software were developed by SRI International and the
    7  * University of Cambridge Computer Laboratory under DARPA/AFRL contract
    8  * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
    9  *
   10  * Portions of this software were developed by the University of Cambridge
   11  * Computer Laboratory as part of the CTSRD Project, with support from the
   12  * UK Higher Education Innovation Fund (HEIF).
   13  *
   14  * Redistribution and use in source and binary forms, with or without
   15  * modification, are permitted provided that the following conditions
   16  * are met:
   17  * 1. Redistributions of source code must retain the above copyright
   18  *    notice, this list of conditions and the following disclaimer.
   19  * 2. Redistributions in binary form must reproduce the above copyright
   20  *    notice, this list of conditions and the following disclaimer in the
   21  *    documentation and/or other materials provided with the distribution.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  */
   35 
   36 #include "opt_platform.h"
   37 
   38 #include <sys/cdefs.h>
   39 __FBSDID("$FreeBSD$");
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/buf.h>
   44 #include <sys/bus.h>
   45 #include <sys/cons.h>
   46 #include <sys/cpu.h>
   47 #include <sys/exec.h>
   48 #include <sys/imgact.h>
   49 #include <sys/kdb.h>
   50 #include <sys/kernel.h>
   51 #include <sys/limits.h>
   52 #include <sys/linker.h>
   53 #include <sys/msgbuf.h>
   54 #include <sys/pcpu.h>
   55 #include <sys/proc.h>
   56 #include <sys/ptrace.h>
   57 #include <sys/reboot.h>
   58 #include <sys/rwlock.h>
   59 #include <sys/sched.h>
   60 #include <sys/signalvar.h>
   61 #include <sys/syscallsubr.h>
   62 #include <sys/sysent.h>
   63 #include <sys/sysproto.h>
   64 #include <sys/ucontext.h>
   65 
   66 #include <vm/vm.h>
   67 #include <vm/vm_kern.h>
   68 #include <vm/vm_object.h>
   69 #include <vm/vm_page.h>
   70 #include <vm/pmap.h>
   71 #include <vm/vm_map.h>
   72 #include <vm/vm_pager.h>
   73 
   74 #include <machine/riscvreg.h>
   75 #include <machine/cpu.h>
   76 #include <machine/kdb.h>
   77 #include <machine/machdep.h>
   78 #include <machine/pcb.h>
   79 #include <machine/reg.h>
   80 #include <machine/trap.h>
   81 #include <machine/vmparam.h>
   82 #include <machine/intr.h>
   83 
   84 #include <machine/asm.h>
   85 
   86 #ifdef VFP
   87 #include <machine/vfp.h>
   88 #endif
   89 
   90 #ifdef FDT
   91 #include <dev/fdt/fdt_common.h>
   92 #include <dev/ofw/openfirm.h>
   93 #endif
   94 
   95 struct pcpu __pcpu[MAXCPU];
   96 
   97 static struct trapframe proc0_tf;
   98 
   99 vm_paddr_t phys_avail[PHYS_AVAIL_SIZE + 2];
  100 vm_paddr_t dump_avail[PHYS_AVAIL_SIZE + 2];
  101 
  102 int early_boot = 1;
  103 int cold = 1;
  104 long realmem = 0;
  105 long Maxmem = 0;
  106 
  107 #define PHYSMAP_SIZE    (2 * (VM_PHYSSEG_MAX - 1))
  108 vm_paddr_t physmap[PHYSMAP_SIZE];
  109 u_int physmap_idx;
  110 
  111 struct kva_md_info kmi;
  112 
  113 int64_t dcache_line_size;       /* The minimum D cache line size */
  114 int64_t icache_line_size;       /* The minimum I cache line size */
  115 int64_t idcache_line_size;      /* The minimum cache line size */
  116 
  117 extern int *end;
  118 extern int *initstack_end;
  119 
  120 struct pcpu *pcpup;
  121 
  122 uintptr_t mcall_trap(uintptr_t mcause, uintptr_t* regs);
  123 
  124 uintptr_t
  125 mcall_trap(uintptr_t mcause, uintptr_t* regs)
  126 {
  127 
  128         return (0);
  129 }
  130 
  131 static void
  132 cpu_startup(void *dummy)
  133 {
  134 
  135         identify_cpu();
  136 
  137         vm_ksubmap_init(&kmi);
  138         bufinit();
  139         vm_pager_bufferinit();
  140 }
  141 
  142 SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
  143 
  144 int
  145 cpu_idle_wakeup(int cpu)
  146 {
  147 
  148         return (0);
  149 }
  150 
  151 void
  152 bzero(void *buf, size_t len)
  153 {
  154         uint8_t *p;
  155 
  156         p = buf;
  157         while(len-- > 0)
  158                 *p++ = 0;
  159 }
  160 
  161 int
  162 fill_regs(struct thread *td, struct reg *regs)
  163 {
  164         struct trapframe *frame;
  165 
  166         frame = td->td_frame;
  167         regs->sepc = frame->tf_sepc;
  168         regs->sstatus = frame->tf_sstatus;
  169         regs->ra = frame->tf_ra;
  170         regs->sp = frame->tf_sp;
  171         regs->gp = frame->tf_gp;
  172         regs->tp = frame->tf_tp;
  173 
  174         memcpy(regs->t, frame->tf_t, sizeof(regs->t));
  175         memcpy(regs->s, frame->tf_s, sizeof(regs->s));
  176         memcpy(regs->a, frame->tf_a, sizeof(regs->a));
  177 
  178         return (0);
  179 }
  180 
  181 int
  182 set_regs(struct thread *td, struct reg *regs)
  183 {
  184         struct trapframe *frame;
  185 
  186         frame = td->td_frame;
  187         frame->tf_sepc = regs->sepc;
  188         frame->tf_sstatus = regs->sstatus;
  189         frame->tf_ra = regs->ra;
  190         frame->tf_sp = regs->sp;
  191         frame->tf_gp = regs->gp;
  192         frame->tf_tp = regs->tp;
  193 
  194         memcpy(frame->tf_t, regs->t, sizeof(frame->tf_t));
  195         memcpy(frame->tf_s, regs->s, sizeof(frame->tf_s));
  196         memcpy(frame->tf_a, regs->a, sizeof(frame->tf_a));
  197 
  198         return (0);
  199 }
  200 
  201 int
  202 fill_fpregs(struct thread *td, struct fpreg *regs)
  203 {
  204 
  205         /* TODO */
  206         bzero(regs, sizeof(*regs));
  207         return (0);
  208 }
  209 
  210 int
  211 set_fpregs(struct thread *td, struct fpreg *regs)
  212 {
  213 
  214         /* TODO */
  215         return (0);
  216 }
  217 
  218 int
  219 fill_dbregs(struct thread *td, struct dbreg *regs)
  220 {
  221 
  222         panic("fill_dbregs");
  223 }
  224 
  225 int
  226 set_dbregs(struct thread *td, struct dbreg *regs)
  227 {
  228 
  229         panic("set_dbregs");
  230 }
  231 
  232 int
  233 ptrace_set_pc(struct thread *td, u_long addr)
  234 {
  235 
  236         panic("ptrace_set_pc");
  237         return (0);
  238 }
  239 
  240 int
  241 ptrace_single_step(struct thread *td)
  242 {
  243 
  244         /* TODO; */
  245         return (0);
  246 }
  247 
  248 int
  249 ptrace_clear_single_step(struct thread *td)
  250 {
  251 
  252         /* TODO; */
  253         return (0);
  254 }
  255 
  256 void
  257 exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
  258 {
  259         struct trapframe *tf;
  260 
  261         tf = td->td_frame;
  262 
  263         memset(tf, 0, sizeof(struct trapframe));
  264 
  265         /*
  266          * We need to set a0 for init as it doesn't call
  267          * cpu_set_syscall_retval to copy the value. We also
  268          * need to set td_retval for the cases where we do.
  269          */
  270         tf->tf_a[0] = td->td_retval[0] = stack;
  271         tf->tf_sp = STACKALIGN(stack);
  272         tf->tf_ra = imgp->entry_addr;
  273         tf->tf_sepc = imgp->entry_addr;
  274 }
  275 
  276 /* Sanity check these are the same size, they will be memcpy'd to and fro */
  277 CTASSERT(sizeof(((struct trapframe *)0)->tf_a) ==
  278     sizeof((struct gpregs *)0)->gp_a);
  279 CTASSERT(sizeof(((struct trapframe *)0)->tf_s) ==
  280     sizeof((struct gpregs *)0)->gp_s);
  281 CTASSERT(sizeof(((struct trapframe *)0)->tf_t) ==
  282     sizeof((struct gpregs *)0)->gp_t);
  283 CTASSERT(sizeof(((struct trapframe *)0)->tf_a) ==
  284     sizeof((struct reg *)0)->a);
  285 CTASSERT(sizeof(((struct trapframe *)0)->tf_s) ==
  286     sizeof((struct reg *)0)->s);
  287 CTASSERT(sizeof(((struct trapframe *)0)->tf_t) ==
  288     sizeof((struct reg *)0)->t);
  289 
  290 int
  291 get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
  292 {
  293         struct trapframe *tf = td->td_frame;
  294 
  295         memcpy(mcp->mc_gpregs.gp_t, tf->tf_t, sizeof(mcp->mc_gpregs.gp_t));
  296         memcpy(mcp->mc_gpregs.gp_s, tf->tf_s, sizeof(mcp->mc_gpregs.gp_s));
  297         memcpy(mcp->mc_gpregs.gp_a, tf->tf_a, sizeof(mcp->mc_gpregs.gp_a));
  298 
  299         if (clear_ret & GET_MC_CLEAR_RET) {
  300                 mcp->mc_gpregs.gp_a[0] = 0;
  301                 mcp->mc_gpregs.gp_t[0] = 0; /* clear syscall error */
  302         }
  303 
  304         mcp->mc_gpregs.gp_ra = tf->tf_ra;
  305         mcp->mc_gpregs.gp_sp = tf->tf_sp;
  306         mcp->mc_gpregs.gp_gp = tf->tf_gp;
  307         mcp->mc_gpregs.gp_tp = tf->tf_tp;
  308         mcp->mc_gpregs.gp_sepc = tf->tf_sepc;
  309         mcp->mc_gpregs.gp_sstatus = tf->tf_sstatus;
  310 
  311         return (0);
  312 }
  313 
  314 int
  315 set_mcontext(struct thread *td, mcontext_t *mcp)
  316 {
  317         struct trapframe *tf;
  318 
  319         tf = td->td_frame;
  320 
  321         memcpy(tf->tf_t, mcp->mc_gpregs.gp_t, sizeof(tf->tf_t));
  322         memcpy(tf->tf_s, mcp->mc_gpregs.gp_s, sizeof(tf->tf_s));
  323         memcpy(tf->tf_a, mcp->mc_gpregs.gp_a, sizeof(tf->tf_a));
  324 
  325         tf->tf_ra = mcp->mc_gpregs.gp_ra;
  326         tf->tf_sp = mcp->mc_gpregs.gp_sp;
  327         tf->tf_gp = mcp->mc_gpregs.gp_gp;
  328         tf->tf_tp = mcp->mc_gpregs.gp_tp;
  329         tf->tf_sepc = mcp->mc_gpregs.gp_sepc;
  330         tf->tf_sstatus = mcp->mc_gpregs.gp_sstatus;
  331 
  332         return (0);
  333 }
  334 
  335 static void
  336 get_fpcontext(struct thread *td, mcontext_t *mcp)
  337 {
  338         /* TODO */
  339 }
  340 
  341 static void
  342 set_fpcontext(struct thread *td, mcontext_t *mcp)
  343 {
  344         /* TODO */
  345 }
  346 
  347 void
  348 cpu_idle(int busy)
  349 {
  350 
  351         spinlock_enter();
  352         if (!busy)
  353                 cpu_idleclock();
  354         if (!sched_runnable())
  355                 __asm __volatile(
  356                     "fence \n"
  357                     "wfi   \n");
  358         if (!busy)
  359                 cpu_activeclock();
  360         spinlock_exit();
  361 }
  362 
  363 void
  364 cpu_halt(void)
  365 {
  366 
  367         panic("cpu_halt");
  368 }
  369 
  370 /*
  371  * Flush the D-cache for non-DMA I/O so that the I-cache can
  372  * be made coherent later.
  373  */
  374 void
  375 cpu_flush_dcache(void *ptr, size_t len)
  376 {
  377 
  378         /* TBD */
  379 }
  380 
  381 /* Get current clock frequency for the given CPU ID. */
  382 int
  383 cpu_est_clockrate(int cpu_id, uint64_t *rate)
  384 {
  385 
  386         panic("cpu_est_clockrate");
  387 }
  388 
  389 void
  390 cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
  391 {
  392 }
  393 
  394 void
  395 spinlock_enter(void)
  396 {
  397         struct thread *td;
  398 
  399         td = curthread;
  400         if (td->td_md.md_spinlock_count == 0) {
  401                 td->td_md.md_spinlock_count = 1;
  402                 td->td_md.md_saved_sstatus_ie = intr_disable();
  403         } else
  404                 td->td_md.md_spinlock_count++;
  405         critical_enter();
  406 }
  407 
  408 void
  409 spinlock_exit(void)
  410 {
  411         struct thread *td;
  412         register_t sstatus_ie;
  413 
  414         td = curthread;
  415         critical_exit();
  416         sstatus_ie = td->td_md.md_saved_sstatus_ie;
  417         td->td_md.md_spinlock_count--;
  418         if (td->td_md.md_spinlock_count == 0)
  419                 intr_restore(sstatus_ie);
  420 }
  421 
  422 #ifndef _SYS_SYSPROTO_H_
  423 struct sigreturn_args {
  424         ucontext_t *ucp;
  425 };
  426 #endif
  427 
  428 int
  429 sys_sigreturn(struct thread *td, struct sigreturn_args *uap)
  430 {
  431         uint64_t sstatus;
  432         ucontext_t uc;
  433         int error;
  434 
  435         if (uap == NULL)
  436                 return (EFAULT);
  437         if (copyin(uap->sigcntxp, &uc, sizeof(uc)))
  438                 return (EFAULT);
  439 
  440         /*
  441          * Make sure the processor mode has not been tampered with and
  442          * interrupts have not been disabled.
  443          */
  444         sstatus = uc.uc_mcontext.mc_gpregs.gp_sstatus;
  445         if ((sstatus & SSTATUS_PS) != 0 ||
  446             (sstatus & SSTATUS_PIE) == 0)
  447                 return (EINVAL);
  448 
  449         error = set_mcontext(td, &uc.uc_mcontext);
  450         if (error != 0)
  451                 return (error);
  452 
  453         set_fpcontext(td, &uc.uc_mcontext);
  454 
  455         /* Restore signal mask. */
  456         kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
  457 
  458         return (EJUSTRETURN);
  459 }
  460 
  461 /*
  462  * Construct a PCB from a trapframe. This is called from kdb_trap() where
  463  * we want to start a backtrace from the function that caused us to enter
  464  * the debugger. We have the context in the trapframe, but base the trace
  465  * on the PCB. The PCB doesn't have to be perfect, as long as it contains
  466  * enough for a backtrace.
  467  */
  468 void
  469 makectx(struct trapframe *tf, struct pcb *pcb)
  470 {
  471 
  472         memcpy(pcb->pcb_t, tf->tf_t, sizeof(tf->tf_t));
  473         memcpy(pcb->pcb_s, tf->tf_s, sizeof(tf->tf_s));
  474         memcpy(pcb->pcb_a, tf->tf_a, sizeof(tf->tf_a));
  475 
  476         pcb->pcb_ra = tf->tf_ra;
  477         pcb->pcb_sp = tf->tf_sp;
  478         pcb->pcb_gp = tf->tf_gp;
  479         pcb->pcb_tp = tf->tf_tp;
  480         pcb->pcb_sepc = tf->tf_sepc;
  481 }
  482 
  483 void
  484 sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
  485 {
  486         struct sigframe *fp, frame;
  487         struct sysentvec *sysent;
  488         struct trapframe *tf;
  489         struct sigacts *psp;
  490         struct thread *td;
  491         struct proc *p;
  492         int onstack;
  493         int code;
  494         int sig;
  495 
  496         td = curthread;
  497         p = td->td_proc;
  498         PROC_LOCK_ASSERT(p, MA_OWNED);
  499 
  500         sig = ksi->ksi_signo;
  501         code = ksi->ksi_code;
  502         psp = p->p_sigacts;
  503         mtx_assert(&psp->ps_mtx, MA_OWNED);
  504 
  505         tf = td->td_frame;
  506         onstack = sigonstack(tf->tf_sp);
  507 
  508         CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
  509             catcher, sig);
  510 
  511         /* Allocate and validate space for the signal handler context. */
  512         if ((td->td_pflags & TDP_ALTSTACK) != 0 && !onstack &&
  513             SIGISMEMBER(psp->ps_sigonstack, sig)) {
  514                 fp = (struct sigframe *)((uintptr_t)td->td_sigstk.ss_sp +
  515                     td->td_sigstk.ss_size);
  516         } else {
  517                 fp = (struct sigframe *)td->td_frame->tf_sp;
  518         }
  519 
  520         /* Make room, keeping the stack aligned */
  521         fp--;
  522         fp = (struct sigframe *)STACKALIGN(fp);
  523 
  524         /* Fill in the frame to copy out */
  525         bzero(&frame, sizeof(frame));
  526         get_mcontext(td, &frame.sf_uc.uc_mcontext, 0);
  527         get_fpcontext(td, &frame.sf_uc.uc_mcontext);
  528         frame.sf_si = ksi->ksi_info;
  529         frame.sf_uc.uc_sigmask = *mask;
  530         frame.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) ?
  531             ((onstack) ? SS_ONSTACK : 0) : SS_DISABLE;
  532         frame.sf_uc.uc_stack = td->td_sigstk;
  533         mtx_unlock(&psp->ps_mtx);
  534         PROC_UNLOCK(td->td_proc);
  535 
  536         /* Copy the sigframe out to the user's stack. */
  537         if (copyout(&frame, fp, sizeof(*fp)) != 0) {
  538                 /* Process has trashed its stack. Kill it. */
  539                 CTR2(KTR_SIG, "sendsig: sigexit td=%p fp=%p", td, fp);
  540                 PROC_LOCK(p);
  541                 sigexit(td, SIGILL);
  542         }
  543 
  544         tf->tf_a[0] = sig;
  545         tf->tf_a[1] = (register_t)&fp->sf_si;
  546         tf->tf_a[2] = (register_t)&fp->sf_uc;
  547 
  548         tf->tf_sepc = (register_t)catcher;
  549         tf->tf_sp = (register_t)fp;
  550 
  551         sysent = p->p_sysent;
  552         if (sysent->sv_sigcode_base != 0)
  553                 tf->tf_ra = (register_t)sysent->sv_sigcode_base;
  554         else
  555                 tf->tf_ra = (register_t)(sysent->sv_psstrings -
  556                     *(sysent->sv_szsigcode));
  557 
  558         CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_sepc,
  559             tf->tf_sp);
  560 
  561         PROC_LOCK(p);
  562         mtx_lock(&psp->ps_mtx);
  563 }
  564 
  565 static void
  566 init_proc0(vm_offset_t kstack)
  567 {
  568 
  569         pcpup = &__pcpu[0];
  570 
  571         proc_linkup0(&proc0, &thread0);
  572         thread0.td_kstack = kstack;
  573         thread0.td_pcb = (struct pcb *)(thread0.td_kstack) - 1;
  574         thread0.td_frame = &proc0_tf;
  575         pcpup->pc_curpcb = thread0.td_pcb;
  576 }
  577 
  578 static int
  579 add_physmap_entry(uint64_t base, uint64_t length, vm_paddr_t *physmap,
  580     u_int *physmap_idxp)
  581 {
  582         u_int i, insert_idx, _physmap_idx;
  583 
  584         _physmap_idx = *physmap_idxp;
  585 
  586         if (length == 0)
  587                 return (1);
  588 
  589         /*
  590          * Find insertion point while checking for overlap.  Start off by
  591          * assuming the new entry will be added to the end.
  592          */
  593         insert_idx = _physmap_idx;
  594         for (i = 0; i <= _physmap_idx; i += 2) {
  595                 if (base < physmap[i + 1]) {
  596                         if (base + length <= physmap[i]) {
  597                                 insert_idx = i;
  598                                 break;
  599                         }
  600                         if (boothowto & RB_VERBOSE)
  601                                 printf(
  602                     "Overlapping memory regions, ignoring second region\n");
  603                         return (1);
  604                 }
  605         }
  606 
  607         /* See if we can prepend to the next entry. */
  608         if (insert_idx <= _physmap_idx &&
  609             base + length == physmap[insert_idx]) {
  610                 physmap[insert_idx] = base;
  611                 return (1);
  612         }
  613 
  614         /* See if we can append to the previous entry. */
  615         if (insert_idx > 0 && base == physmap[insert_idx - 1]) {
  616                 physmap[insert_idx - 1] += length;
  617                 return (1);
  618         }
  619 
  620         _physmap_idx += 2;
  621         *physmap_idxp = _physmap_idx;
  622         if (_physmap_idx == PHYSMAP_SIZE) {
  623                 printf(
  624                 "Too many segments in the physical address map, giving up\n");
  625                 return (0);
  626         }
  627 
  628         /*
  629          * Move the last 'N' entries down to make room for the new
  630          * entry if needed.
  631          */
  632         for (i = _physmap_idx; i > insert_idx; i -= 2) {
  633                 physmap[i] = physmap[i - 2];
  634                 physmap[i + 1] = physmap[i - 1];
  635         }
  636 
  637         /* Insert the new entry. */
  638         physmap[insert_idx] = base;
  639         physmap[insert_idx + 1] = base + length;
  640 
  641         printf("physmap[%d] = 0x%016lx\n", insert_idx, base);
  642         printf("physmap[%d] = 0x%016lx\n", insert_idx + 1, base + length);
  643         return (1);
  644 }
  645 
  646 #ifdef FDT
  647 static void
  648 try_load_dtb(caddr_t kmdp)
  649 {
  650         vm_offset_t dtbp;
  651 
  652         dtbp = (vm_offset_t)&fdt_static_dtb;
  653         if (dtbp == (vm_offset_t)NULL) {
  654                 printf("ERROR loading DTB\n");
  655                 return;
  656         }
  657 
  658         if (OF_install(OFW_FDT, 0) == FALSE)
  659                 panic("Cannot install FDT");
  660 
  661         if (OF_init((void *)dtbp) != 0)
  662                 panic("OF_init failed with the found device tree");
  663 }
  664 #endif
  665 
  666 static void
  667 cache_setup(void)
  668 {
  669 
  670         /* TODO */
  671 }
  672 
  673 /*
  674  * Fake up a boot descriptor table.
  675  * RISCVTODO: This needs to be done via loader (when it's available).
  676  */
  677 vm_offset_t
  678 fake_preload_metadata(struct riscv_bootparams *rvbp __unused)
  679 {
  680 #ifdef DDB
  681         vm_offset_t zstart = 0, zend = 0;
  682 #endif
  683         vm_offset_t lastaddr;
  684         int i = 0;
  685         static uint32_t fake_preload[35];
  686 
  687         fake_preload[i++] = MODINFO_NAME;
  688         fake_preload[i++] = strlen("kernel") + 1;
  689         strcpy((char*)&fake_preload[i++], "kernel");
  690         i += 1;
  691         fake_preload[i++] = MODINFO_TYPE;
  692         fake_preload[i++] = strlen("elf64 kernel") + 1;
  693         strcpy((char*)&fake_preload[i++], "elf64 kernel");
  694         i += 3;
  695         fake_preload[i++] = MODINFO_ADDR;
  696         fake_preload[i++] = sizeof(vm_offset_t);
  697         fake_preload[i++] = (uint64_t)(KERNBASE + KERNENTRY);
  698         i += 1;
  699         fake_preload[i++] = MODINFO_SIZE;
  700         fake_preload[i++] = sizeof(uint64_t);
  701         printf("end is 0x%016lx\n", (uint64_t)&end);
  702         fake_preload[i++] = (uint64_t)&end - (uint64_t)(KERNBASE + KERNENTRY);
  703         i += 1;
  704 #ifdef DDB
  705 #if 0
  706         /* RISCVTODO */
  707         if (*(uint32_t *)KERNVIRTADDR == MAGIC_TRAMP_NUMBER) {
  708                 fake_preload[i++] = MODINFO_METADATA|MODINFOMD_SSYM;
  709                 fake_preload[i++] = sizeof(vm_offset_t);
  710                 fake_preload[i++] = *(uint32_t *)(KERNVIRTADDR + 4);
  711                 fake_preload[i++] = MODINFO_METADATA|MODINFOMD_ESYM;
  712                 fake_preload[i++] = sizeof(vm_offset_t);
  713                 fake_preload[i++] = *(uint32_t *)(KERNVIRTADDR + 8);
  714                 lastaddr = *(uint32_t *)(KERNVIRTADDR + 8);
  715                 zend = lastaddr;
  716                 zstart = *(uint32_t *)(KERNVIRTADDR + 4);
  717                 db_fetch_ksymtab(zstart, zend);
  718         } else
  719 #endif
  720 #endif
  721                 lastaddr = (vm_offset_t)&end;
  722         fake_preload[i++] = 0;
  723         fake_preload[i] = 0;
  724         preload_metadata = (void *)fake_preload;
  725 
  726         return (lastaddr);
  727 }
  728 
  729 void
  730 initriscv(struct riscv_bootparams *rvbp)
  731 {
  732         struct mem_region mem_regions[FDT_MEM_REGIONS];
  733         vm_offset_t lastaddr;
  734         int mem_regions_sz;
  735         vm_size_t kernlen;
  736         caddr_t kmdp;
  737         int i;
  738 
  739         /* Set the module data location */
  740         lastaddr = fake_preload_metadata(rvbp);
  741 
  742         /* Find the kernel address */
  743         kmdp = preload_search_by_type("elf kernel");
  744         if (kmdp == NULL)
  745                 kmdp = preload_search_by_type("elf64 kernel");
  746 
  747         boothowto = 0;
  748 
  749         kern_envp = NULL;
  750 
  751 #ifdef FDT
  752         try_load_dtb(kmdp);
  753 #endif
  754 
  755         /* Load the physical memory ranges */
  756         physmap_idx = 0;
  757 
  758         /* Grab physical memory regions information from device tree. */
  759         if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, NULL) != 0)
  760                 panic("Cannot get physical memory regions");
  761         for (i = 0; i < mem_regions_sz; i++)
  762                 add_physmap_entry(mem_regions[i].mr_start,
  763                     mem_regions[i].mr_size, physmap, &physmap_idx);
  764 
  765         /* Set the pcpu data, this is needed by pmap_bootstrap */
  766         pcpup = &__pcpu[0];
  767         pcpu_init(pcpup, 0, sizeof(struct pcpu));
  768 
  769         /* Set the pcpu pointer */
  770         __asm __volatile("mv gp, %0" :: "r"(pcpup));
  771 
  772         PCPU_SET(curthread, &thread0);
  773 
  774         /* Do basic tuning, hz etc */
  775         init_param1();
  776 
  777         cache_setup();
  778 
  779         /* Bootstrap enough of pmap  to enter the kernel proper */
  780         kernlen = (lastaddr - KERNBASE);
  781         pmap_bootstrap(rvbp->kern_l1pt, KERNENTRY, kernlen);
  782 
  783         cninit();
  784 
  785         init_proc0(rvbp->kern_stack);
  786 
  787         /* set page table base register for thread0 */
  788         thread0.td_pcb->pcb_l1addr = (rvbp->kern_l1pt - KERNBASE);
  789 
  790         msgbufinit(msgbufp, msgbufsize);
  791         mutex_init();
  792         init_param2(physmem);
  793         kdb_init();
  794 
  795         riscv_init_interrupts();
  796 
  797         early_boot = 0;
  798 }

Cache object: 1a6bcef66e9f22bc8a952400463e6bc8


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