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