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