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