Home | History | Annotate | Line # | Download | only in riscv
riscv_machdep.c revision 1.21
      1  1.21    skrll /*	$NetBSD: riscv_machdep.c,v 1.21 2022/10/16 06:14:53 skrll Exp $	*/
      2  1.12    skrll 
      3   1.1     matt /*-
      4  1.18    skrll  * Copyright (c) 2014, 2019, 2022 The NetBSD Foundation, Inc.
      5   1.1     matt  * All rights reserved.
      6   1.1     matt  *
      7   1.1     matt  * This code is derived from software contributed to The NetBSD Foundation
      8  1.18    skrll  * by Matt Thomas of 3am Software Foundry, and by Nick Hudson.
      9   1.1     matt  *
     10   1.1     matt  * Redistribution and use in source and binary forms, with or without
     11   1.1     matt  * modification, are permitted provided that the following conditions
     12   1.1     matt  * are met:
     13   1.1     matt  * 1. Redistributions of source code must retain the above copyright
     14   1.1     matt  *    notice, this list of conditions and the following disclaimer.
     15   1.1     matt  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1     matt  *    notice, this list of conditions and the following disclaimer in the
     17   1.1     matt  *    documentation and/or other materials provided with the distribution.
     18   1.1     matt  *
     19   1.1     matt  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1     matt  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1     matt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1     matt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1     matt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1     matt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1     matt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1     matt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1     matt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1     matt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1     matt  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1     matt  */
     31   1.1     matt 
     32  1.18    skrll #include "opt_modular.h"
     33  1.18    skrll #include "opt_riscv_debug.h"
     34  1.18    skrll 
     35   1.1     matt #include <sys/cdefs.h>
     36  1.21    skrll __RCSID("$NetBSD: riscv_machdep.c,v 1.21 2022/10/16 06:14:53 skrll Exp $");
     37   1.1     matt 
     38  1.16    skrll #include <sys/param.h>
     39   1.1     matt 
     40  1.18    skrll #include <sys/boot_flag.h>
     41   1.1     matt #include <sys/cpu.h>
     42   1.1     matt #include <sys/exec.h>
     43   1.1     matt #include <sys/kmem.h>
     44   1.1     matt #include <sys/ktrace.h>
     45  1.16    skrll #include <sys/lwp.h>
     46   1.1     matt #include <sys/module.h>
     47  1.18    skrll #include <sys/msgbuf.h>
     48   1.1     matt #include <sys/proc.h>
     49   1.1     matt #include <sys/reboot.h>
     50   1.1     matt #include <sys/syscall.h>
     51  1.16    skrll #include <sys/systm.h>
     52   1.1     matt 
     53  1.18    skrll #include <dev/cons.h>
     54   1.1     matt #include <uvm/uvm_extern.h>
     55   1.1     matt 
     56   1.1     matt #include <riscv/locore.h>
     57  1.18    skrll #include <riscv/machdep.h>
     58  1.18    skrll #include <riscv/pte.h>
     59   1.1     matt 
     60   1.1     matt int cpu_printfataltraps;
     61   1.1     matt char machine[] = MACHINE;
     62   1.1     matt char machine_arch[] = MACHINE_ARCH;
     63   1.1     matt 
     64  1.18    skrll #include <libfdt.h>
     65  1.18    skrll #include <dev/fdt/fdtvar.h>
     66  1.18    skrll #include <dev/fdt/fdt_memory.h>
     67  1.18    skrll 
     68  1.18    skrll #ifdef VERBOSE_INIT_RISCV
     69  1.20   simonb #define	VPRINTF(...)	printf(__VA_ARGS__)
     70  1.18    skrll #else
     71  1.20   simonb #define	VPRINTF(...)	__nothing
     72  1.18    skrll #endif
     73  1.18    skrll 
     74  1.18    skrll #ifndef FDT_MAX_BOOT_STRING
     75  1.20   simonb #define	FDT_MAX_BOOT_STRING 1024
     76  1.18    skrll #endif
     77  1.18    skrll 
     78  1.18    skrll char bootargs[FDT_MAX_BOOT_STRING] = "";
     79  1.18    skrll char *boot_args = NULL;
     80  1.18    skrll 
     81  1.18    skrll static void
     82  1.18    skrll earlyconsputc(dev_t dev, int c)
     83  1.18    skrll {
     84  1.18    skrll 	uartputc(c);
     85  1.18    skrll }
     86  1.18    skrll 
     87  1.18    skrll static int
     88  1.18    skrll earlyconsgetc(dev_t dev)
     89  1.18    skrll {
     90  1.19    skrll 	return uartgetc();
     91  1.18    skrll }
     92  1.18    skrll 
     93  1.18    skrll static struct consdev earlycons = {
     94  1.18    skrll 	.cn_putc = earlyconsputc,
     95  1.18    skrll 	.cn_getc = earlyconsgetc,
     96  1.18    skrll 	.cn_pollc = nullcnpollc,
     97  1.18    skrll };
     98  1.18    skrll 
     99   1.1     matt struct vm_map *phys_map;
    100   1.1     matt 
    101   1.1     matt struct trapframe cpu_ddb_regs;
    102   1.1     matt 
    103   1.1     matt struct cpu_info cpu_info_store = {
    104   1.1     matt 	.ci_cpl = IPL_HIGH,
    105   1.1     matt 	.ci_ddb_regs = &cpu_ddb_regs,
    106   1.1     matt };
    107   1.1     matt 
    108   1.1     matt const pcu_ops_t * const pcu_ops_md_defs[PCU_UNIT_COUNT] = {
    109  1.14    skrll #ifdef FPE
    110   1.1     matt 	[PCU_FPU] = &pcu_fpu_ops,
    111  1.14    skrll #endif
    112   1.1     matt };
    113   1.1     matt 
    114  1.18    skrll /*
    115  1.18    skrll  * Used by PHYSTOV and VTOPHYS -- Will be set be BSS is zeroed so
    116  1.18    skrll  * keep it in data
    117  1.18    skrll  */
    118  1.18    skrll unsigned long kern_vtopdiff __attribute__((__section__(".data")));
    119  1.18    skrll 
    120   1.1     matt void
    121   1.1     matt delay(unsigned long us)
    122   1.1     matt {
    123   1.1     matt 	const uint32_t cycles_per_us = curcpu()->ci_data.cpu_cc_freq / 1000000;
    124   1.1     matt 	const uint64_t cycles = (uint64_t)us * cycles_per_us;
    125   1.1     matt 	const uint64_t finish = riscvreg_cycle_read() + cycles;
    126   1.1     matt 
    127   1.1     matt 	while (riscvreg_cycle_read() < finish) {
    128   1.1     matt 		/* spin, baby spin */
    129   1.1     matt 	}
    130   1.1     matt }
    131   1.1     matt 
    132   1.1     matt #ifdef MODULAR
    133   1.1     matt /*
    134  1.10    skrll  * Push any modules loaded by the boot loader.
    135   1.1     matt  */
    136   1.1     matt void
    137   1.1     matt module_init_md(void)
    138   1.1     matt {
    139   1.1     matt }
    140   1.1     matt #endif /* MODULAR */
    141   1.1     matt 
    142   1.1     matt /*
    143   1.1     matt  * Set registers on exec.
    144   1.1     matt  * Clear all registers except sp, pc, and t9.
    145   1.1     matt  * $sp is set to the stack pointer passed in.  $pc is set to the entry
    146   1.1     matt  * point given by the exec_package passed in, as is $t9 (used for PIC
    147   1.1     matt  * code by the MIPS elf abi).
    148   1.1     matt  */
    149   1.1     matt void
    150   1.1     matt setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
    151   1.1     matt {
    152   1.1     matt 	struct trapframe * const tf = l->l_md.md_utf;
    153   1.1     matt 	struct proc * const p = l->l_proc;
    154   1.1     matt 
    155   1.1     matt 	memset(tf, 0, sizeof(struct trapframe));
    156   1.1     matt 	tf->tf_sp = (intptr_t)stack_align(stack);
    157   1.1     matt 	tf->tf_pc = (intptr_t)pack->ep_entry & ~1;
    158   1.1     matt #ifdef _LP64
    159   1.1     matt 	tf->tf_sr = (p->p_flag & PK_32) ? SR_USER32 : SR_USER;
    160   1.1     matt #else
    161   1.1     matt 	tf->tf_sr = SR_USER;
    162   1.1     matt #endif
    163   1.1     matt 	// Set up arguments for _start(obj, cleanup, ps_strings)
    164   1.1     matt 	tf->tf_a0 = 0;			// obj
    165   1.1     matt 	tf->tf_a1 = 0;			// cleanup
    166   1.1     matt 	tf->tf_a2 = p->p_psstrp;	// ps_strings
    167   1.1     matt }
    168   1.1     matt 
    169   1.1     matt void
    170   1.4    kamil md_child_return(struct lwp *l)
    171   1.1     matt {
    172   1.1     matt 	struct trapframe * const tf = l->l_md.md_utf;
    173   1.1     matt 
    174   1.1     matt 	tf->tf_a0 = 0;
    175   1.1     matt 	tf->tf_a1 = 1;
    176  1.13    skrll #ifdef FPE
    177   1.1     matt 	tf->tf_sr &= ~SR_EF;		/* Disable FP as we can't be them. */
    178  1.13    skrll #endif
    179   1.1     matt }
    180   1.1     matt 
    181   1.1     matt void
    182   1.1     matt cpu_spawn_return(struct lwp *l)
    183   1.1     matt {
    184   1.1     matt 	userret(l);
    185   1.1     matt }
    186   1.1     matt 
    187  1.10    skrll /*
    188   1.1     matt  * Start a new LWP
    189   1.1     matt  */
    190   1.1     matt void
    191   1.1     matt startlwp(void *arg)
    192   1.1     matt {
    193   1.1     matt 	ucontext_t * const uc = arg;
    194   1.1     matt 	lwp_t * const l = curlwp;
    195   1.1     matt 	int error __diagused;
    196   1.1     matt 
    197   1.1     matt 	error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
    198   1.1     matt 	KASSERT(error == 0);
    199   1.1     matt 
    200   1.1     matt 	kmem_free(uc, sizeof(ucontext_t));
    201   1.1     matt 	userret(l);
    202   1.1     matt }
    203   1.1     matt 
    204   1.1     matt // We've worked hard to make sure struct reg and __gregset_t are the same.
    205   1.1     matt // Ditto for struct fpreg and fregset_t.
    206   1.1     matt 
    207  1.15    skrll #ifdef _LP64
    208   1.1     matt CTASSERT(sizeof(struct reg) == sizeof(__gregset_t));
    209  1.15    skrll #endif
    210   1.1     matt CTASSERT(sizeof(struct fpreg) == sizeof(__fregset_t));
    211   1.1     matt 
    212   1.1     matt void
    213   1.1     matt cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags)
    214   1.1     matt {
    215   1.1     matt 	const struct trapframe * const tf = l->l_md.md_utf;
    216   1.1     matt 
    217   1.1     matt 	/* Save register context. */
    218   1.1     matt 	*(struct reg *)mcp->__gregs = tf->tf_regs;
    219   1.1     matt 
    220   1.1     matt 	mcp->__private = (intptr_t)l->l_private;
    221   1.1     matt 
    222   1.1     matt 	*flags |= _UC_CPU | _UC_TLSBASE;
    223   1.1     matt 
    224   1.1     matt 	/* Save floating point register context, if any. */
    225   1.1     matt 	KASSERT(l == curlwp);
    226   1.2      chs 	if (fpu_valid_p(l)) {
    227   1.1     matt 		/*
    228   1.1     matt 		 * If this process is the current FP owner, dump its
    229   1.1     matt 		 * context to the PCB first.
    230   1.1     matt 		 */
    231   1.2      chs 		fpu_save(l);
    232   1.1     matt 
    233   1.1     matt 		struct pcb * const pcb = lwp_getpcb(l);
    234   1.1     matt 		*(struct fpreg *)mcp->__fregs = pcb->pcb_fpregs;
    235   1.1     matt 		*flags |= _UC_FPU;
    236   1.1     matt 	}
    237   1.1     matt }
    238   1.1     matt 
    239   1.1     matt int
    240   1.1     matt cpu_mcontext_validate(struct lwp *l, const mcontext_t *mcp)
    241   1.1     matt {
    242   1.1     matt 	/*
    243   1.1     matt 	 * Verify that at least the PC and SP are user addresses.
    244   1.1     matt 	 */
    245   1.1     matt 	if ((intptr_t) mcp->__gregs[_REG_PC] < 0
    246   1.1     matt 	    || (intptr_t) mcp->__gregs[_REG_SP] < 0
    247   1.1     matt 	    || (mcp->__gregs[_REG_PC] & 1))
    248   1.1     matt 		return EINVAL;
    249   1.1     matt 
    250   1.1     matt 	return 0;
    251   1.1     matt }
    252   1.1     matt 
    253   1.1     matt int
    254   1.1     matt cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
    255   1.1     matt {
    256   1.1     matt 	struct trapframe * const tf = l->l_md.md_utf;
    257   1.1     matt 	struct proc * const p = l->l_proc;
    258   1.1     matt 	const __greg_t * const gr = mcp->__gregs;
    259   1.1     matt 	int error;
    260   1.1     matt 
    261   1.1     matt 	/* Restore register context, if any. */
    262   1.1     matt 	if (flags & _UC_CPU) {
    263   1.1     matt 		error = cpu_mcontext_validate(l, mcp);
    264   1.1     matt 		if (error)
    265   1.1     matt 			return error;
    266   1.1     matt 
    267   1.1     matt 		/* Save register context. */
    268   1.1     matt 		tf->tf_regs = *(const struct reg *)gr;
    269   1.1     matt 	}
    270   1.1     matt 
    271   1.1     matt 	/* Restore the private thread context */
    272   1.1     matt 	if (flags & _UC_TLSBASE) {
    273   1.1     matt 		lwp_setprivate(l, (void *)(intptr_t)mcp->__private);
    274   1.1     matt 	}
    275   1.1     matt 
    276   1.1     matt 	/* Restore floating point register context, if any. */
    277   1.1     matt 	if (flags & _UC_FPU) {
    278   1.1     matt 		KASSERT(l == curlwp);
    279   1.1     matt 		/* Tell PCU we are replacing the FPU contents. */
    280   1.2      chs 		fpu_replace(l);
    281   1.1     matt 
    282   1.1     matt 		/*
    283   1.1     matt 		 * The PCB FP regs struct includes the FP CSR, so use the
    284   1.1     matt 		 * proper size of fpreg when copying.
    285   1.1     matt 		 */
    286   1.1     matt 		struct pcb * const pcb = lwp_getpcb(l);
    287   1.1     matt 		pcb->pcb_fpregs = *(const struct fpreg *)mcp->__fregs;
    288   1.1     matt 	}
    289   1.1     matt 
    290   1.1     matt 	mutex_enter(p->p_lock);
    291   1.1     matt 	if (flags & _UC_SETSTACK)
    292   1.1     matt 		l->l_sigstk.ss_flags |= SS_ONSTACK;
    293   1.1     matt 	if (flags & _UC_CLRSTACK)
    294   1.1     matt 		l->l_sigstk.ss_flags &= ~SS_ONSTACK;
    295   1.1     matt 	mutex_exit(p->p_lock);
    296   1.1     matt 
    297   1.1     matt 	return (0);
    298   1.1     matt }
    299   1.1     matt 
    300   1.1     matt void
    301   1.6       ad cpu_need_resched(struct cpu_info *ci, struct lwp *l, int flags)
    302   1.1     matt {
    303   1.1     matt 	KASSERT(kpreempt_disabled());
    304   1.1     matt 
    305   1.6       ad 	if ((flags & RESCHED_KPREEMPT) != 0) {
    306   1.1     matt #ifdef __HAVE_PREEMPTION
    307   1.6       ad 		if ((flags & RESCHED_REMOTE) != 0) {
    308  1.17    skrll 			cpu_send_ipi(ci, IPI_KPREEMPT);
    309   1.6       ad 		} else {
    310   1.1     matt 			softint_trigger(SOFTINT_KPREEMPT);
    311  1.17    skrll 		}
    312   1.1     matt #endif
    313   1.1     matt 		return;
    314   1.1     matt 	}
    315   1.6       ad 	if ((flags & RESCHED_REMOTE) != 0) {
    316   1.1     matt #ifdef MULTIPROCESSOR
    317   1.1     matt 		cpu_send_ipi(ci, IPI_AST);
    318   1.1     matt #endif
    319   1.6       ad 	} else {
    320   1.6       ad 		l->l_md.md_astpending = 1;		/* force call to ast() */
    321   1.6       ad 	}
    322   1.1     matt }
    323   1.1     matt 
    324   1.1     matt void
    325   1.1     matt cpu_signotify(struct lwp *l)
    326   1.1     matt {
    327   1.1     matt 	KASSERT(kpreempt_disabled());
    328   1.1     matt #ifdef __HAVE_FAST_SOFTINTS
    329   1.1     matt 	KASSERT(lwp_locked(l, NULL));
    330   1.1     matt #endif
    331   1.1     matt 
    332   1.6       ad 	if (l->l_cpu != curcpu()) {
    333   1.6       ad #ifdef MULTIPROCESSOR
    334   1.6       ad 		cpu_send_ipi(ci, IPI_AST);
    335   1.6       ad #endif
    336   1.6       ad 	} else {
    337   1.6       ad 		l->l_md.md_astpending = 1; 	/* force call to ast() */
    338   1.6       ad 	}
    339   1.1     matt }
    340   1.1     matt 
    341   1.1     matt void
    342   1.1     matt cpu_need_proftick(struct lwp *l)
    343   1.1     matt {
    344   1.1     matt 	KASSERT(kpreempt_disabled());
    345   1.1     matt 	KASSERT(l->l_cpu == curcpu());
    346   1.1     matt 
    347   1.1     matt 	l->l_pflag |= LP_OWEUPC;
    348   1.1     matt 	l->l_md.md_astpending = 1;		/* force call to ast() */
    349   1.1     matt }
    350   1.1     matt 
    351   1.1     matt void
    352   1.1     matt cpu_reboot(int how, char *bootstr)
    353   1.1     matt {
    354   1.1     matt 	for (;;) {
    355   1.1     matt 	}
    356   1.1     matt }
    357   1.1     matt 
    358   1.1     matt void
    359   1.1     matt cpu_dumpconf(void)
    360   1.1     matt {
    361   1.1     matt 	// TBD!!
    362   1.1     matt }
    363   1.1     matt 
    364   1.1     matt void
    365   1.1     matt cpu_startup(void)
    366   1.1     matt {
    367   1.1     matt 	vaddr_t minaddr, maxaddr;
    368   1.1     matt 	char pbuf[9];	/* "99999 MB" */
    369   1.1     matt 
    370   1.1     matt 	/*
    371   1.1     matt 	 * Good {morning,afternoon,evening,night}.
    372   1.1     matt 	 */
    373   1.1     matt 	printf("%s%s", copyright, version);
    374   1.1     matt 	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
    375   1.1     matt 	printf("total memory = %s\n", pbuf);
    376   1.1     matt 
    377   1.1     matt 	minaddr = 0;
    378   1.1     matt 	/*
    379   1.1     matt 	 * Allocate a submap for physio.
    380   1.1     matt 	 */
    381   1.1     matt 	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
    382   1.1     matt 	    VM_PHYS_SIZE, 0, FALSE, NULL);
    383   1.1     matt 
    384  1.11       ad 	format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false)));
    385   1.1     matt 	printf("avail memory = %s\n", pbuf);
    386   1.1     matt }
    387   1.1     matt 
    388  1.18    skrll static void
    389  1.18    skrll riscv_init_lwp0_uarea(void)
    390  1.18    skrll {
    391  1.18    skrll 	extern char lwp0uspace[];
    392  1.18    skrll 
    393  1.18    skrll 	uvm_lwp_setuarea(&lwp0, (vaddr_t)lwp0uspace);
    394  1.18    skrll 	memset(&lwp0.l_md, 0, sizeof(lwp0.l_md));
    395  1.18    skrll 	memset(lwp_getpcb(&lwp0), 0, sizeof(struct pcb));
    396  1.18    skrll 
    397  1.18    skrll 	struct trapframe *tf = (struct trapframe *)(lwp0uspace + USPACE) - 1;
    398  1.18    skrll 	memset(tf, 0, sizeof(struct trapframe));
    399  1.18    skrll 
    400  1.18    skrll 	lwp0.l_md.md_utf = lwp0.l_md.md_ktf = tf;
    401  1.18    skrll }
    402  1.18    skrll 
    403  1.18    skrll 
    404  1.18    skrll static void
    405  1.18    skrll riscv_print_memory(const struct fdt_memory *m, void *arg)
    406  1.18    skrll {
    407  1.18    skrll 
    408  1.18    skrll 	VPRINTF("FDT /memory @ 0x%" PRIx64 " size 0x%" PRIx64 "\n",
    409  1.18    skrll 	    m->start, m->end - m->start);
    410  1.18    skrll }
    411  1.18    skrll 
    412  1.18    skrll 
    413  1.18    skrll static void
    414  1.18    skrll parse_bi_bootargs(char *args)
    415  1.18    skrll {
    416  1.18    skrll 	int howto;
    417  1.18    skrll 
    418  1.18    skrll 	for (char *cp = args; *cp; cp++) {
    419  1.18    skrll 		/* Ignore superfluous '-', if there is one */
    420  1.18    skrll 		if (*cp == '-')
    421  1.18    skrll 			continue;
    422  1.18    skrll 
    423  1.18    skrll 		howto = 0;
    424  1.18    skrll 		BOOT_FLAG(*cp, howto);
    425  1.18    skrll 		if (!howto)
    426  1.18    skrll 			printf("bootflag '%c' not recognised\n", *cp);
    427  1.18    skrll 		else
    428  1.18    skrll 			boothowto |= howto;
    429  1.18    skrll 	}
    430  1.18    skrll }
    431  1.18    skrll 
    432  1.18    skrll 
    433   1.1     matt void
    434  1.21    skrll init_riscv(register_t hartid, paddr_t dtb)
    435   1.1     matt {
    436   1.9  thorpej 
    437  1.18    skrll 	/* set temporally to work printf()/panic() even before consinit() */
    438  1.18    skrll 	cn_tab = &earlycons;
    439  1.18    skrll 
    440  1.18    skrll 	/* Load FDT */
    441  1.21    skrll 	const vaddr_t dtbva = VM_KERNEL_DTB_BASE + (dtb & (NBSEG - 1));
    442  1.21    skrll 	void *fdt_data = (void *)dtbva;
    443  1.18    skrll 	int error = fdt_check_header(fdt_data);
    444  1.18    skrll 	if (error != 0)
    445  1.18    skrll 	    panic("fdt_check_header failed: %s", fdt_strerror(error));
    446  1.18    skrll 
    447  1.18    skrll 	fdtbus_init(fdt_data);
    448  1.18    skrll 
    449  1.18    skrll #if 0
    450  1.18    skrll 	/* Lookup platform specific backend */
    451  1.18    skrll 	plat = riscv_fdt_platform();
    452  1.18    skrll 	if (plat == NULL)
    453  1.18    skrll 		panic("Kernel does not support this device");
    454  1.18    skrll 
    455  1.18    skrll #endif
    456  1.18    skrll 	/* Early console may be available, announce ourselves. */
    457  1.18    skrll 	VPRINTF("FDT<%p>\n", fdt_data);
    458  1.18    skrll 
    459  1.18    skrll 	const int chosen = OF_finddevice("/chosen");
    460  1.18    skrll 	if (chosen >= 0)
    461  1.18    skrll 		OF_getprop(chosen, "bootargs", bootargs, sizeof(bootargs));
    462  1.18    skrll 	boot_args = bootargs;
    463  1.18    skrll 
    464  1.18    skrll #if 0
    465  1.18    skrll 	/*
    466  1.18    skrll 	 * If stdout-path is specified on the command line, override the
    467  1.18    skrll 	 * value in /chosen/stdout-path before initializing console.
    468  1.18    skrll 	 */
    469  1.18    skrll 	VPRINTF("stdout\n");
    470  1.18    skrll 	fdt_update_stdout_path();
    471  1.18    skrll #endif
    472  1.18    skrll 
    473  1.18    skrll 	/*
    474  1.18    skrll 	 * Done making changes to the FDT.
    475  1.18    skrll 	 */
    476  1.18    skrll 	fdt_pack(fdt_data);
    477  1.18    skrll 
    478  1.18    skrll 	VPRINTF("consinit ");
    479  1.18    skrll 	consinit();
    480  1.18    skrll 	VPRINTF("ok\n");
    481  1.18    skrll 
    482  1.18    skrll 	/* Talk to the user */
    483  1.18    skrll 	printf("NetBSD/riscv (fdt) booting ...\n");
    484  1.18    skrll 
    485  1.18    skrll #ifdef BOOT_ARGS
    486  1.18    skrll 	char mi_bootargs[] = BOOT_ARGS;
    487  1.18    skrll 	parse_bi_bootargs(mi_bootargs);
    488  1.18    skrll #endif
    489  1.18    skrll 
    490  1.18    skrll 	/* SPAM me while testing */
    491  1.18    skrll 	boothowto |= AB_DEBUG;
    492  1.18    skrll 
    493  1.18    skrll 	uint64_t memory_start, memory_end;
    494  1.18    skrll 	fdt_memory_get(&memory_start, &memory_end);
    495  1.18    skrll 
    496  1.18    skrll 	fdt_memory_foreach(riscv_print_memory, NULL);
    497  1.18    skrll 
    498  1.18    skrll 	/* Cannot map memory above largest page number */
    499  1.18    skrll 	const uint64_t maxppn = __SHIFTOUT_MASK(PTE_PPN) - 1;
    500  1.18    skrll 	const uint64_t memory_limit = ptoa(maxppn);
    501  1.18    skrll 
    502  1.18    skrll 	if (memory_end > memory_limit) {
    503  1.18    skrll 		fdt_memory_remove_range(memory_limit, memory_end);
    504  1.18    skrll 		memory_end = memory_limit;
    505  1.18    skrll 	}
    506  1.18    skrll 
    507  1.18    skrll 	uint64_t memory_size __unused = memory_end - memory_start;
    508  1.18    skrll 
    509  1.18    skrll 	VPRINTF("%s: memory start %" PRIx64 " end %" PRIx64 " (len %"
    510  1.18    skrll 	    PRIx64 ")\n", __func__, memory_start, memory_end, memory_size);
    511  1.18    skrll 
    512  1.18    skrll 	/* Perform PT build and VM init */
    513  1.18    skrll 	//cpu_kernel_vm_init();
    514  1.18    skrll 
    515  1.18    skrll 	VPRINTF("bootargs: %s\n", bootargs);
    516  1.18    skrll 
    517  1.18    skrll 	parse_bi_bootargs(boot_args);
    518  1.18    skrll 
    519  1.18    skrll 
    520  1.18    skrll 	// initarm_common
    521  1.18    skrll 	extern char __kernel_text[];
    522  1.18    skrll 	extern char _end[];
    523  1.18    skrll 
    524  1.18    skrll 	vaddr_t kernstart = trunc_page((vaddr_t)__kernel_text);
    525  1.18    skrll 	vaddr_t kernend = round_page((vaddr_t)_end);
    526  1.18    skrll 	paddr_t kernstart_phys __unused = KERN_VTOPHYS(kernstart);
    527  1.18    skrll 	paddr_t kernend_phys __unused = KERN_VTOPHYS(kernend);
    528  1.18    skrll 
    529  1.18    skrll 	vaddr_t kernelvmstart;
    530  1.18    skrll 
    531  1.18    skrll 	vaddr_t kernstart_mega __unused = MEGAPAGE_TRUNC(kernstart);
    532  1.18    skrll 	vaddr_t kernend_mega = MEGAPAGE_ROUND(kernend);
    533  1.18    skrll 
    534  1.18    skrll 	kernelvmstart = kernend_mega;
    535  1.18    skrll 
    536  1.20   simonb #define	DPRINTF(v)	VPRINTF("%24s = 0x%16lx\n", #v, (unsigned long)v);
    537  1.18    skrll 
    538  1.18    skrll 	VPRINTF("------------------------------------------\n");
    539  1.18    skrll 	DPRINTF(kern_vtopdiff);
    540  1.18    skrll 	DPRINTF(memory_start);
    541  1.18    skrll 	DPRINTF(memory_end);
    542  1.18    skrll 	DPRINTF(memory_size);
    543  1.18    skrll 	DPRINTF(kernstart_phys);
    544  1.18    skrll 	DPRINTF(kernend_phys)
    545  1.18    skrll 	DPRINTF(VM_MIN_KERNEL_ADDRESS);
    546  1.18    skrll 	DPRINTF(kernstart_mega);
    547  1.18    skrll 	DPRINTF(kernstart);
    548  1.18    skrll 	DPRINTF(kernend);
    549  1.18    skrll 	DPRINTF(kernend_mega);
    550  1.18    skrll 	DPRINTF(VM_MAX_KERNEL_ADDRESS);
    551  1.18    skrll 	VPRINTF("------------------------------------------\n");
    552  1.18    skrll 
    553  1.18    skrll #undef DPRINTF
    554  1.18    skrll 
    555  1.18    skrll 	KASSERT(kernelvmstart < VM_KERNEL_VM_BASE);
    556  1.18    skrll 
    557  1.18    skrll 	kernelvmstart = VM_KERNEL_VM_BASE;
    558  1.18    skrll 
    559  1.18    skrll 	/*
    560  1.18    skrll 	 * msgbuf is allocated from the bottom of any one of memory blocks
    561  1.18    skrll 	 * to avoid corruption due to bootloader or changing kernel layout.
    562  1.18    skrll 	 */
    563  1.18    skrll 	paddr_t msgbufaddr = 0;
    564  1.18    skrll 
    565  1.18    skrll 	KASSERT(msgbufaddr != 0);	/* no space for msgbuf */
    566  1.18    skrll #ifdef _LP64
    567  1.18    skrll 	initmsgbuf((void *)RISCV_PA_TO_KVA(msgbufaddr), MSGBUFSIZE);
    568  1.18    skrll #endif
    569  1.18    skrll 
    570  1.18    skrll 	uvm_md_init();
    571  1.18    skrll 
    572  1.18    skrll 	pmap_bootstrap(kernelvmstart, VM_MAX_KERNEL_ADDRESS);
    573  1.18    skrll 
    574  1.18    skrll 	/* Finish setting up lwp0 on our end before we call main() */
    575  1.18    skrll 	riscv_init_lwp0_uarea();
    576   1.1     matt }
    577