]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/riscv/riscv/machdep.c
MFV r314565,314567,314570:
[FreeBSD/FreeBSD.git] / sys / riscv / riscv / machdep.c
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 #include <machine/sbi.h>
84
85 #include <machine/asm.h>
86
87 #ifdef FPE
88 #include <machine/fpe.h>
89 #endif
90
91 #ifdef FDT
92 #include <dev/fdt/fdt_common.h>
93 #include <dev/ofw/openfirm.h>
94 #endif
95
96 struct pcpu __pcpu[MAXCPU];
97
98 static struct trapframe proc0_tf;
99
100 vm_paddr_t phys_avail[PHYS_AVAIL_SIZE + 2];
101 vm_paddr_t dump_avail[PHYS_AVAIL_SIZE + 2];
102
103 int early_boot = 1;
104 int cold = 1;
105 long realmem = 0;
106 long Maxmem = 0;
107
108 #define PHYSMAP_SIZE    (2 * (VM_PHYSSEG_MAX - 1))
109 vm_paddr_t physmap[PHYSMAP_SIZE];
110 u_int physmap_idx;
111
112 struct kva_md_info kmi;
113
114 int64_t dcache_line_size;       /* The minimum D cache line size */
115 int64_t icache_line_size;       /* The minimum I cache line size */
116 int64_t idcache_line_size;      /* The minimum cache line size */
117
118 extern int *end;
119 extern int *initstack_end;
120 extern memory_block_info memory_info;
121
122 struct pcpu *pcpup;
123
124 uintptr_t mcall_trap(uintptr_t mcause, uintptr_t* regs);
125
126 uintptr_t
127 mcall_trap(uintptr_t mcause, uintptr_t* regs)
128 {
129
130         return (0);
131 }
132
133 static void
134 cpu_startup(void *dummy)
135 {
136
137         identify_cpu();
138
139         vm_ksubmap_init(&kmi);
140         bufinit();
141         vm_pager_bufferinit();
142 }
143
144 SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
145
146 int
147 cpu_idle_wakeup(int cpu)
148 {
149
150         return (0);
151 }
152
153 void
154 bzero(void *buf, size_t len)
155 {
156         uint8_t *p;
157
158         p = buf;
159         while(len-- > 0)
160                 *p++ = 0;
161 }
162
163 int
164 fill_regs(struct thread *td, struct reg *regs)
165 {
166         struct trapframe *frame;
167
168         frame = td->td_frame;
169         regs->sepc = frame->tf_sepc;
170         regs->sstatus = frame->tf_sstatus;
171         regs->ra = frame->tf_ra;
172         regs->sp = frame->tf_sp;
173         regs->gp = frame->tf_gp;
174         regs->tp = frame->tf_tp;
175
176         memcpy(regs->t, frame->tf_t, sizeof(regs->t));
177         memcpy(regs->s, frame->tf_s, sizeof(regs->s));
178         memcpy(regs->a, frame->tf_a, sizeof(regs->a));
179
180         return (0);
181 }
182
183 int
184 set_regs(struct thread *td, struct reg *regs)
185 {
186         struct trapframe *frame;
187
188         frame = td->td_frame;
189         frame->tf_sepc = regs->sepc;
190         frame->tf_sstatus = regs->sstatus;
191         frame->tf_ra = regs->ra;
192         frame->tf_sp = regs->sp;
193         frame->tf_gp = regs->gp;
194         frame->tf_tp = regs->tp;
195
196         memcpy(frame->tf_t, regs->t, sizeof(frame->tf_t));
197         memcpy(frame->tf_s, regs->s, sizeof(frame->tf_s));
198         memcpy(frame->tf_a, regs->a, sizeof(frame->tf_a));
199
200         return (0);
201 }
202
203 int
204 fill_fpregs(struct thread *td, struct fpreg *regs)
205 {
206 #ifdef FPE
207         struct pcb *pcb;
208
209         pcb = td->td_pcb;
210
211         if ((pcb->pcb_fpflags & PCB_FP_STARTED) != 0) {
212                 /*
213                  * If we have just been running FPE instructions we will
214                  * need to save the state to memcpy it below.
215                  */
216                 fpe_state_save(td);
217
218                 memcpy(regs->fp_x, pcb->pcb_x, sizeof(regs->fp_x));
219                 regs->fp_fcsr = pcb->pcb_fcsr;
220         } else
221 #endif
222                 memset(regs->fp_x, 0, sizeof(regs->fp_x));
223
224         return (0);
225 }
226
227 int
228 set_fpregs(struct thread *td, struct fpreg *regs)
229 {
230 #ifdef FPE
231         struct pcb *pcb;
232
233         pcb = td->td_pcb;
234
235         memcpy(pcb->pcb_x, regs->fp_x, sizeof(regs->fp_x));
236         pcb->pcb_fcsr = regs->fp_fcsr;
237 #endif
238
239         return (0);
240 }
241
242 int
243 fill_dbregs(struct thread *td, struct dbreg *regs)
244 {
245
246         panic("fill_dbregs");
247 }
248
249 int
250 set_dbregs(struct thread *td, struct dbreg *regs)
251 {
252
253         panic("set_dbregs");
254 }
255
256 int
257 ptrace_set_pc(struct thread *td, u_long addr)
258 {
259
260         panic("ptrace_set_pc");
261         return (0);
262 }
263
264 int
265 ptrace_single_step(struct thread *td)
266 {
267
268         /* TODO; */
269         return (0);
270 }
271
272 int
273 ptrace_clear_single_step(struct thread *td)
274 {
275
276         /* TODO; */
277         return (0);
278 }
279
280 void
281 exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
282 {
283         struct trapframe *tf;
284         struct pcb *pcb;
285
286         tf = td->td_frame;
287         pcb = td->td_pcb;
288
289         memset(tf, 0, sizeof(struct trapframe));
290
291         /*
292          * We need to set a0 for init as it doesn't call
293          * cpu_set_syscall_retval to copy the value. We also
294          * need to set td_retval for the cases where we do.
295          */
296         tf->tf_a[0] = td->td_retval[0] = stack;
297         tf->tf_sp = STACKALIGN(stack);
298         tf->tf_ra = imgp->entry_addr;
299         tf->tf_sepc = imgp->entry_addr;
300
301         pcb->pcb_fpflags &= ~PCB_FP_STARTED;
302 }
303
304 /* Sanity check these are the same size, they will be memcpy'd to and fro */
305 CTASSERT(sizeof(((struct trapframe *)0)->tf_a) ==
306     sizeof((struct gpregs *)0)->gp_a);
307 CTASSERT(sizeof(((struct trapframe *)0)->tf_s) ==
308     sizeof((struct gpregs *)0)->gp_s);
309 CTASSERT(sizeof(((struct trapframe *)0)->tf_t) ==
310     sizeof((struct gpregs *)0)->gp_t);
311 CTASSERT(sizeof(((struct trapframe *)0)->tf_a) ==
312     sizeof((struct reg *)0)->a);
313 CTASSERT(sizeof(((struct trapframe *)0)->tf_s) ==
314     sizeof((struct reg *)0)->s);
315 CTASSERT(sizeof(((struct trapframe *)0)->tf_t) ==
316     sizeof((struct reg *)0)->t);
317
318 int
319 get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
320 {
321         struct trapframe *tf = td->td_frame;
322
323         memcpy(mcp->mc_gpregs.gp_t, tf->tf_t, sizeof(mcp->mc_gpregs.gp_t));
324         memcpy(mcp->mc_gpregs.gp_s, tf->tf_s, sizeof(mcp->mc_gpregs.gp_s));
325         memcpy(mcp->mc_gpregs.gp_a, tf->tf_a, sizeof(mcp->mc_gpregs.gp_a));
326
327         if (clear_ret & GET_MC_CLEAR_RET) {
328                 mcp->mc_gpregs.gp_a[0] = 0;
329                 mcp->mc_gpregs.gp_t[0] = 0; /* clear syscall error */
330         }
331
332         mcp->mc_gpregs.gp_ra = tf->tf_ra;
333         mcp->mc_gpregs.gp_sp = tf->tf_sp;
334         mcp->mc_gpregs.gp_gp = tf->tf_gp;
335         mcp->mc_gpregs.gp_tp = tf->tf_tp;
336         mcp->mc_gpregs.gp_sepc = tf->tf_sepc;
337         mcp->mc_gpregs.gp_sstatus = tf->tf_sstatus;
338
339         return (0);
340 }
341
342 int
343 set_mcontext(struct thread *td, mcontext_t *mcp)
344 {
345         struct trapframe *tf;
346
347         tf = td->td_frame;
348
349         memcpy(tf->tf_t, mcp->mc_gpregs.gp_t, sizeof(tf->tf_t));
350         memcpy(tf->tf_s, mcp->mc_gpregs.gp_s, sizeof(tf->tf_s));
351         memcpy(tf->tf_a, mcp->mc_gpregs.gp_a, sizeof(tf->tf_a));
352
353         tf->tf_ra = mcp->mc_gpregs.gp_ra;
354         tf->tf_sp = mcp->mc_gpregs.gp_sp;
355         tf->tf_gp = mcp->mc_gpregs.gp_gp;
356         tf->tf_tp = mcp->mc_gpregs.gp_tp;
357         tf->tf_sepc = mcp->mc_gpregs.gp_sepc;
358         tf->tf_sstatus = mcp->mc_gpregs.gp_sstatus;
359
360         return (0);
361 }
362
363 static void
364 get_fpcontext(struct thread *td, mcontext_t *mcp)
365 {
366 #ifdef FPE
367         struct pcb *curpcb;
368
369         critical_enter();
370
371         curpcb = curthread->td_pcb;
372
373         KASSERT(td->td_pcb == curpcb, ("Invalid fpe pcb"));
374
375         if ((curpcb->pcb_fpflags & PCB_FP_STARTED) != 0) {
376                 /*
377                  * If we have just been running FPE instructions we will
378                  * need to save the state to memcpy it below.
379                  */
380                 fpe_state_save(td);
381
382                 KASSERT((curpcb->pcb_fpflags & ~PCB_FP_USERMASK) == 0,
383                     ("Non-userspace FPE flags set in get_fpcontext"));
384                 memcpy(mcp->mc_fpregs.fp_x, curpcb->pcb_x,
385                     sizeof(mcp->mc_fpregs));
386                 mcp->mc_fpregs.fp_fcsr = curpcb->pcb_fcsr;
387                 mcp->mc_fpregs.fp_flags = curpcb->pcb_fpflags;
388                 mcp->mc_flags |= _MC_FP_VALID;
389         }
390
391         critical_exit();
392 #endif
393 }
394
395 static void
396 set_fpcontext(struct thread *td, mcontext_t *mcp)
397 {
398 #ifdef FPE
399         struct pcb *curpcb;
400
401         critical_enter();
402
403         if ((mcp->mc_flags & _MC_FP_VALID) != 0) {
404                 curpcb = curthread->td_pcb;
405                 /* FPE usage is enabled, override registers. */
406                 memcpy(curpcb->pcb_x, mcp->mc_fpregs.fp_x,
407                     sizeof(mcp->mc_fpregs));
408                 curpcb->pcb_fcsr = mcp->mc_fpregs.fp_fcsr;
409                 curpcb->pcb_fpflags = mcp->mc_fpregs.fp_flags & PCB_FP_USERMASK;
410         }
411
412         critical_exit();
413 #endif
414 }
415
416 void
417 cpu_idle(int busy)
418 {
419
420         spinlock_enter();
421         if (!busy)
422                 cpu_idleclock();
423         if (!sched_runnable())
424                 __asm __volatile(
425                     "fence \n"
426                     "wfi   \n");
427         if (!busy)
428                 cpu_activeclock();
429         spinlock_exit();
430 }
431
432 void
433 cpu_halt(void)
434 {
435
436         panic("cpu_halt");
437 }
438
439 /*
440  * Flush the D-cache for non-DMA I/O so that the I-cache can
441  * be made coherent later.
442  */
443 void
444 cpu_flush_dcache(void *ptr, size_t len)
445 {
446
447         /* TBD */
448 }
449
450 /* Get current clock frequency for the given CPU ID. */
451 int
452 cpu_est_clockrate(int cpu_id, uint64_t *rate)
453 {
454
455         panic("cpu_est_clockrate");
456 }
457
458 void
459 cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
460 {
461 }
462
463 void
464 spinlock_enter(void)
465 {
466         struct thread *td;
467
468         td = curthread;
469         if (td->td_md.md_spinlock_count == 0) {
470                 td->td_md.md_spinlock_count = 1;
471                 td->td_md.md_saved_sstatus_ie = intr_disable();
472         } else
473                 td->td_md.md_spinlock_count++;
474         critical_enter();
475 }
476
477 void
478 spinlock_exit(void)
479 {
480         struct thread *td;
481         register_t sstatus_ie;
482
483         td = curthread;
484         critical_exit();
485         sstatus_ie = td->td_md.md_saved_sstatus_ie;
486         td->td_md.md_spinlock_count--;
487         if (td->td_md.md_spinlock_count == 0)
488                 intr_restore(sstatus_ie);
489 }
490
491 #ifndef _SYS_SYSPROTO_H_
492 struct sigreturn_args {
493         ucontext_t *ucp;
494 };
495 #endif
496
497 int
498 sys_sigreturn(struct thread *td, struct sigreturn_args *uap)
499 {
500         uint64_t sstatus;
501         ucontext_t uc;
502         int error;
503
504         if (uap == NULL)
505                 return (EFAULT);
506         if (copyin(uap->sigcntxp, &uc, sizeof(uc)))
507                 return (EFAULT);
508
509         /*
510          * Make sure the processor mode has not been tampered with and
511          * interrupts have not been disabled.
512          * Supervisor interrupts in user mode are always enabled.
513          */
514         sstatus = uc.uc_mcontext.mc_gpregs.gp_sstatus;
515         if ((sstatus & SSTATUS_SPP) != 0)
516                 return (EINVAL);
517
518         error = set_mcontext(td, &uc.uc_mcontext);
519         if (error != 0)
520                 return (error);
521
522         set_fpcontext(td, &uc.uc_mcontext);
523
524         /* Restore signal mask. */
525         kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
526
527         return (EJUSTRETURN);
528 }
529
530 /*
531  * Construct a PCB from a trapframe. This is called from kdb_trap() where
532  * we want to start a backtrace from the function that caused us to enter
533  * the debugger. We have the context in the trapframe, but base the trace
534  * on the PCB. The PCB doesn't have to be perfect, as long as it contains
535  * enough for a backtrace.
536  */
537 void
538 makectx(struct trapframe *tf, struct pcb *pcb)
539 {
540
541         memcpy(pcb->pcb_t, tf->tf_t, sizeof(tf->tf_t));
542         memcpy(pcb->pcb_s, tf->tf_s, sizeof(tf->tf_s));
543         memcpy(pcb->pcb_a, tf->tf_a, sizeof(tf->tf_a));
544
545         pcb->pcb_ra = tf->tf_ra;
546         pcb->pcb_sp = tf->tf_sp;
547         pcb->pcb_gp = tf->tf_gp;
548         pcb->pcb_tp = tf->tf_tp;
549         pcb->pcb_sepc = tf->tf_sepc;
550 }
551
552 void
553 sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
554 {
555         struct sigframe *fp, frame;
556         struct sysentvec *sysent;
557         struct trapframe *tf;
558         struct sigacts *psp;
559         struct thread *td;
560         struct proc *p;
561         int onstack;
562         int code;
563         int sig;
564
565         td = curthread;
566         p = td->td_proc;
567         PROC_LOCK_ASSERT(p, MA_OWNED);
568
569         sig = ksi->ksi_signo;
570         code = ksi->ksi_code;
571         psp = p->p_sigacts;
572         mtx_assert(&psp->ps_mtx, MA_OWNED);
573
574         tf = td->td_frame;
575         onstack = sigonstack(tf->tf_sp);
576
577         CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
578             catcher, sig);
579
580         /* Allocate and validate space for the signal handler context. */
581         if ((td->td_pflags & TDP_ALTSTACK) != 0 && !onstack &&
582             SIGISMEMBER(psp->ps_sigonstack, sig)) {
583                 fp = (struct sigframe *)((uintptr_t)td->td_sigstk.ss_sp +
584                     td->td_sigstk.ss_size);
585         } else {
586                 fp = (struct sigframe *)td->td_frame->tf_sp;
587         }
588
589         /* Make room, keeping the stack aligned */
590         fp--;
591         fp = (struct sigframe *)STACKALIGN(fp);
592
593         /* Fill in the frame to copy out */
594         get_mcontext(td, &frame.sf_uc.uc_mcontext, 0);
595         get_fpcontext(td, &frame.sf_uc.uc_mcontext);
596         frame.sf_si = ksi->ksi_info;
597         frame.sf_uc.uc_sigmask = *mask;
598         frame.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) ?
599             ((onstack) ? SS_ONSTACK : 0) : SS_DISABLE;
600         frame.sf_uc.uc_stack = td->td_sigstk;
601         mtx_unlock(&psp->ps_mtx);
602         PROC_UNLOCK(td->td_proc);
603
604         /* Copy the sigframe out to the user's stack. */
605         if (copyout(&frame, fp, sizeof(*fp)) != 0) {
606                 /* Process has trashed its stack. Kill it. */
607                 CTR2(KTR_SIG, "sendsig: sigexit td=%p fp=%p", td, fp);
608                 PROC_LOCK(p);
609                 sigexit(td, SIGILL);
610         }
611
612         tf->tf_a[0] = sig;
613         tf->tf_a[1] = (register_t)&fp->sf_si;
614         tf->tf_a[2] = (register_t)&fp->sf_uc;
615
616         tf->tf_sepc = (register_t)catcher;
617         tf->tf_sp = (register_t)fp;
618
619         sysent = p->p_sysent;
620         if (sysent->sv_sigcode_base != 0)
621                 tf->tf_ra = (register_t)sysent->sv_sigcode_base;
622         else
623                 tf->tf_ra = (register_t)(sysent->sv_psstrings -
624                     *(sysent->sv_szsigcode));
625
626         CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_sepc,
627             tf->tf_sp);
628
629         PROC_LOCK(p);
630         mtx_lock(&psp->ps_mtx);
631 }
632
633 static void
634 init_proc0(vm_offset_t kstack)
635 {
636
637         pcpup = &__pcpu[0];
638
639         proc_linkup0(&proc0, &thread0);
640         thread0.td_kstack = kstack;
641         thread0.td_pcb = (struct pcb *)(thread0.td_kstack) - 1;
642         thread0.td_pcb->pcb_fpflags = 0;
643         thread0.td_frame = &proc0_tf;
644         pcpup->pc_curpcb = thread0.td_pcb;
645 }
646
647 static int
648 add_physmap_entry(uint64_t base, uint64_t length, vm_paddr_t *physmap,
649     u_int *physmap_idxp)
650 {
651         u_int i, insert_idx, _physmap_idx;
652
653         _physmap_idx = *physmap_idxp;
654
655         if (length == 0)
656                 return (1);
657
658         /*
659          * Find insertion point while checking for overlap.  Start off by
660          * assuming the new entry will be added to the end.
661          */
662         insert_idx = _physmap_idx;
663         for (i = 0; i <= _physmap_idx; i += 2) {
664                 if (base < physmap[i + 1]) {
665                         if (base + length <= physmap[i]) {
666                                 insert_idx = i;
667                                 break;
668                         }
669                         if (boothowto & RB_VERBOSE)
670                                 printf(
671                     "Overlapping memory regions, ignoring second region\n");
672                         return (1);
673                 }
674         }
675
676         /* See if we can prepend to the next entry. */
677         if (insert_idx <= _physmap_idx &&
678             base + length == physmap[insert_idx]) {
679                 physmap[insert_idx] = base;
680                 return (1);
681         }
682
683         /* See if we can append to the previous entry. */
684         if (insert_idx > 0 && base == physmap[insert_idx - 1]) {
685                 physmap[insert_idx - 1] += length;
686                 return (1);
687         }
688
689         _physmap_idx += 2;
690         *physmap_idxp = _physmap_idx;
691         if (_physmap_idx == PHYSMAP_SIZE) {
692                 printf(
693                 "Too many segments in the physical address map, giving up\n");
694                 return (0);
695         }
696
697         /*
698          * Move the last 'N' entries down to make room for the new
699          * entry if needed.
700          */
701         for (i = _physmap_idx; i > insert_idx; i -= 2) {
702                 physmap[i] = physmap[i - 2];
703                 physmap[i + 1] = physmap[i - 1];
704         }
705
706         /* Insert the new entry. */
707         physmap[insert_idx] = base;
708         physmap[insert_idx + 1] = base + length;
709
710         printf("physmap[%d] = 0x%016lx\n", insert_idx, base);
711         printf("physmap[%d] = 0x%016lx\n", insert_idx + 1, base + length);
712         return (1);
713 }
714
715 #ifdef FDT
716 static void
717 try_load_dtb(caddr_t kmdp)
718 {
719         vm_offset_t dtbp;
720
721         dtbp = (vm_offset_t)&fdt_static_dtb;
722         if (dtbp == (vm_offset_t)NULL) {
723                 printf("ERROR loading DTB\n");
724                 return;
725         }
726
727         if (OF_install(OFW_FDT, 0) == FALSE)
728                 panic("Cannot install FDT");
729
730         if (OF_init((void *)dtbp) != 0)
731                 panic("OF_init failed with the found device tree");
732 }
733 #endif
734
735 static void
736 cache_setup(void)
737 {
738
739         /* TODO */
740 }
741
742 /*
743  * Fake up a boot descriptor table.
744  * RISCVTODO: This needs to be done via loader (when it's available).
745  */
746 vm_offset_t
747 fake_preload_metadata(struct riscv_bootparams *rvbp __unused)
748 {
749 #ifdef DDB
750         vm_offset_t zstart = 0, zend = 0;
751 #endif
752         vm_offset_t lastaddr;
753         int i = 0;
754         static uint32_t fake_preload[35];
755
756         fake_preload[i++] = MODINFO_NAME;
757         fake_preload[i++] = strlen("kernel") + 1;
758         strcpy((char*)&fake_preload[i++], "kernel");
759         i += 1;
760         fake_preload[i++] = MODINFO_TYPE;
761         fake_preload[i++] = strlen("elf64 kernel") + 1;
762         strcpy((char*)&fake_preload[i++], "elf64 kernel");
763         i += 3;
764         fake_preload[i++] = MODINFO_ADDR;
765         fake_preload[i++] = sizeof(vm_offset_t);
766         fake_preload[i++] = (uint64_t)(KERNBASE + KERNENTRY);
767         i += 1;
768         fake_preload[i++] = MODINFO_SIZE;
769         fake_preload[i++] = sizeof(uint64_t);
770         printf("end is 0x%016lx\n", (uint64_t)&end);
771         fake_preload[i++] = (uint64_t)&end - (uint64_t)(KERNBASE + KERNENTRY);
772         i += 1;
773 #ifdef DDB
774 #if 0
775         /* RISCVTODO */
776         if (*(uint32_t *)KERNVIRTADDR == MAGIC_TRAMP_NUMBER) {
777                 fake_preload[i++] = MODINFO_METADATA|MODINFOMD_SSYM;
778                 fake_preload[i++] = sizeof(vm_offset_t);
779                 fake_preload[i++] = *(uint32_t *)(KERNVIRTADDR + 4);
780                 fake_preload[i++] = MODINFO_METADATA|MODINFOMD_ESYM;
781                 fake_preload[i++] = sizeof(vm_offset_t);
782                 fake_preload[i++] = *(uint32_t *)(KERNVIRTADDR + 8);
783                 lastaddr = *(uint32_t *)(KERNVIRTADDR + 8);
784                 zend = lastaddr;
785                 zstart = *(uint32_t *)(KERNVIRTADDR + 4);
786                 db_fetch_ksymtab(zstart, zend);
787         } else
788 #endif
789 #endif
790                 lastaddr = (vm_offset_t)&end;
791         fake_preload[i++] = 0;
792         fake_preload[i] = 0;
793         preload_metadata = (void *)fake_preload;
794
795         return (lastaddr);
796 }
797
798 void
799 initriscv(struct riscv_bootparams *rvbp)
800 {
801         vm_offset_t lastaddr;
802         vm_size_t kernlen;
803         caddr_t kmdp;
804
805         /* Set the module data location */
806         lastaddr = fake_preload_metadata(rvbp);
807
808         /* Find the kernel address */
809         kmdp = preload_search_by_type("elf kernel");
810         if (kmdp == NULL)
811                 kmdp = preload_search_by_type("elf64 kernel");
812
813         boothowto = RB_VERBOSE | RB_SINGLE;
814         boothowto = RB_VERBOSE;
815
816         kern_envp = NULL;
817
818 #ifdef FDT
819         try_load_dtb(kmdp);
820 #endif
821
822         /* Load the physical memory ranges */
823         physmap_idx = 0;
824
825 #if 0
826         struct mem_region mem_regions[FDT_MEM_REGIONS];
827         int mem_regions_sz;
828         int i;
829         /* Grab physical memory regions information from device tree. */
830         if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, NULL) != 0)
831                 panic("Cannot get physical memory regions");
832         for (i = 0; i < mem_regions_sz; i++)
833                 add_physmap_entry(mem_regions[i].mr_start,
834                     mem_regions[i].mr_size, physmap, &physmap_idx);
835 #endif
836
837         add_physmap_entry(memory_info.base, memory_info.size,
838             physmap, &physmap_idx);
839
840         /* Set the pcpu data, this is needed by pmap_bootstrap */
841         pcpup = &__pcpu[0];
842         pcpu_init(pcpup, 0, sizeof(struct pcpu));
843
844         /* Set the pcpu pointer */
845         __asm __volatile("mv gp, %0" :: "r"(pcpup));
846
847         PCPU_SET(curthread, &thread0);
848
849         /* Do basic tuning, hz etc */
850         init_param1();
851
852         cache_setup();
853
854         /* Bootstrap enough of pmap to enter the kernel proper */
855         kernlen = (lastaddr - KERNBASE);
856         pmap_bootstrap(rvbp->kern_l1pt, memory_info.base, kernlen);
857
858         cninit();
859
860         init_proc0(rvbp->kern_stack);
861
862         /* set page table base register for thread0 */
863         thread0.td_pcb->pcb_l1addr = \
864             (rvbp->kern_l1pt - KERNBASE + memory_info.base);
865
866         msgbufinit(msgbufp, msgbufsize);
867         mutex_init();
868         init_param2(physmem);
869         kdb_init();
870
871         riscv_init_interrupts();
872
873         early_boot = 0;
874 }