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