Module Name:    src
Committed By:   bouyer
Date:           Sat May  2 16:44:36 UTC 2020

Modified Files:
        src/sys/arch/amd64/amd64: autoconf.c genassym.cf locore.S machdep.c
        src/sys/arch/amd64/conf: GENERIC
        src/sys/arch/i386/i386: autoconf.c genassym.cf locore.S machdep.c
        src/sys/arch/x86/acpi: acpi_machdep.c
        src/sys/arch/x86/include: cpu.h
        src/sys/arch/x86/isa: clock.c isa_machdep.c
        src/sys/arch/x86/x86: consinit.c cpu.c lapic.c pmap.c x86_autoconf.c
            x86_machdep.c
        src/sys/arch/xen/conf: Makefile.xen files.xen
        src/sys/arch/xen/include: hypervisor.h xen.h
        src/sys/arch/xen/x86: autoconf.c hypervisor_machdep.c x86_xpmap.c
            xen_mainbus.c
        src/sys/arch/xen/xen: hypervisor.c xen_clock.c xen_machdep.c
Added Files:
        src/sys/arch/xen/x86: pvh_consinit.c

Log Message:
Introduce Xen PVH support in GENERIC.
This is compiled in with
options XENPVHVM
x86 changes:
- add Xen section and xen pvh entry points to locore.S. Set vm_guest
  to VM_GUEST_XENPVH in this entry point.
  Most of the boot procedure (especially page table setup and switch to
  paged mode) is shared with native.
- change some x86_delay() to delay_func(), which points to x86_delay() for
  native/HVM, and xen_delay() for PVH

Xen changes:
- remove Xen bits from init_x86_64_ksyms() and init386_ksyms()
  and move to xen_init_ksyms(), used for both PV and PVH
- set ISA no-legacy-devices property for PVH
- factor out code from Xen's cpu_bootconf() to xen_bootconf()
  in xen_machdep.c
- set up a specific pvh_consinit() which starts with printk()
  (which uses a simple hypercall that is available early) and switch to
  xencons when we can use pmap_kenter_pa().


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/sys/arch/amd64/amd64/autoconf.c
cvs rdiff -u -r1.83 -r1.84 src/sys/arch/amd64/amd64/genassym.cf
cvs rdiff -u -r1.205 -r1.206 src/sys/arch/amd64/amd64/locore.S
cvs rdiff -u -r1.351 -r1.352 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.566 -r1.567 src/sys/arch/amd64/conf/GENERIC
cvs rdiff -u -r1.106 -r1.107 src/sys/arch/i386/i386/autoconf.c
cvs rdiff -u -r1.121 -r1.122 src/sys/arch/i386/i386/genassym.cf
cvs rdiff -u -r1.181 -r1.182 src/sys/arch/i386/i386/locore.S
cvs rdiff -u -r1.828 -r1.829 src/sys/arch/i386/i386/machdep.c
cvs rdiff -u -r1.29 -r1.30 src/sys/arch/x86/acpi/acpi_machdep.c
cvs rdiff -u -r1.124 -r1.125 src/sys/arch/x86/include/cpu.h
cvs rdiff -u -r1.37 -r1.38 src/sys/arch/x86/isa/clock.c
cvs rdiff -u -r1.45 -r1.46 src/sys/arch/x86/isa/isa_machdep.c
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/x86/x86/consinit.c
cvs rdiff -u -r1.188 -r1.189 src/sys/arch/x86/x86/cpu.c
cvs rdiff -u -r1.77 -r1.78 src/sys/arch/x86/x86/lapic.c
cvs rdiff -u -r1.386 -r1.387 src/sys/arch/x86/x86/pmap.c
cvs rdiff -u -r1.81 -r1.82 src/sys/arch/x86/x86/x86_autoconf.c
cvs rdiff -u -r1.140 -r1.141 src/sys/arch/x86/x86/x86_machdep.c
cvs rdiff -u -r1.49 -r1.50 src/sys/arch/xen/conf/Makefile.xen
cvs rdiff -u -r1.182 -r1.183 src/sys/arch/xen/conf/files.xen
cvs rdiff -u -r1.51 -r1.52 src/sys/arch/xen/include/hypervisor.h
cvs rdiff -u -r1.46 -r1.47 src/sys/arch/xen/include/xen.h
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/xen/x86/autoconf.c
cvs rdiff -u -r1.38 -r1.39 src/sys/arch/xen/x86/hypervisor_machdep.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/xen/x86/pvh_consinit.c
cvs rdiff -u -r1.85 -r1.86 src/sys/arch/xen/x86/x86_xpmap.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/xen/x86/xen_mainbus.c
cvs rdiff -u -r1.78 -r1.79 src/sys/arch/xen/xen/hypervisor.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/xen/xen/xen_clock.c
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/xen/xen/xen_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/amd64/autoconf.c
diff -u src/sys/arch/amd64/amd64/autoconf.c:1.29 src/sys/arch/amd64/amd64/autoconf.c:1.30
--- src/sys/arch/amd64/amd64/autoconf.c:1.29	Fri Dec 27 12:51:56 2019
+++ src/sys/arch/amd64/amd64/autoconf.c	Sat May  2 16:44:34 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.29 2019/12/27 12:51:56 ad Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.30 2020/05/02 16:44:34 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.29 2019/12/27 12:51:56 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.30 2020/05/02 16:44:34 bouyer Exp $");
 
 #include "opt_multiprocessor.h"
 #include "opt_intrdebug.h"
@@ -92,7 +92,14 @@ extern void platform_init(void);
 void
 cpu_configure(void)
 {
+#ifdef XEN
+	if (vm_guest == VM_GUEST_XENPVH)
+		xen_startrtclock();
+	else
+		startrtclock();
+#else
 	startrtclock();
+#endif
 
 #if NBIOS32 > 0
 	efi_init();

Index: src/sys/arch/amd64/amd64/genassym.cf
diff -u src/sys/arch/amd64/amd64/genassym.cf:1.83 src/sys/arch/amd64/amd64/genassym.cf:1.84
--- src/sys/arch/amd64/amd64/genassym.cf:1.83	Sat Apr 25 15:26:16 2020
+++ src/sys/arch/amd64/amd64/genassym.cf	Sat May  2 16:44:34 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.83 2020/04/25 15:26:16 bouyer Exp $
+#	$NetBSD: genassym.cf,v 1.84 2020/05/02 16:44:34 bouyer Exp $
 
 #
 # Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -120,6 +120,7 @@ endif
 
 ifdef XEN
 include <xen/include/public/xen.h>
+include <xen/include/public/arch-x86/hvm/start_info.h>
 endif  
 
 include <sys/bus.h>
@@ -361,6 +362,7 @@ define	X86_BUS_SPACE_IO	X86_BUS_SPACE_IO
 define	BST_TYPE		offsetof(struct bus_space_tag, bst_type)
 
 define	VM_GUEST_XENPV		VM_GUEST_XENPV
+define	VM_GUEST_XENPVH		VM_GUEST_XENPVH
 
 ifdef XEN
 define CPU_INFO_VCPU		offsetof(struct cpu_info, ci_vcpu)
@@ -373,7 +375,7 @@ define XEN_PT_BASE		offsetof(struct star
 define XEN_NR_PT_FRAMES		offsetof(struct start_info, nr_pt_frames)
 define __HYPERVISOR_iret	__HYPERVISOR_iret
 endif /* XENPV */
-endif
+endif /* XEN */
 
 define	NKL4_KIMG_ENTRIES	NKL4_KIMG_ENTRIES
 define	NKL3_KIMG_ENTRIES	NKL3_KIMG_ENTRIES

Index: src/sys/arch/amd64/amd64/locore.S
diff -u src/sys/arch/amd64/amd64/locore.S:1.205 src/sys/arch/amd64/amd64/locore.S:1.206
--- src/sys/arch/amd64/amd64/locore.S:1.205	Sat May  2 16:28:37 2020
+++ src/sys/arch/amd64/amd64/locore.S	Sat May  2 16:44:34 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.205 2020/05/02 16:28:37 maxv Exp $	*/
+/*	$NetBSD: locore.S,v 1.206 2020/05/02 16:44:34 bouyer Exp $	*/
 
 /*
  * Copyright-o-rama!
@@ -279,9 +279,7 @@
 #define __ASSEMBLY__
 #include <xen/include/public/elfnote.h>
 #include <xen/include/public/xen.h>
-#endif	/* XEN */
 
-#ifdef XENPV	
 #define ELFNOTE(name, type, desctype, descdata...) \
 .pushsection .note.name			;	\
   .align 4				;	\
@@ -302,11 +300,16 @@
 	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, "4.99")
 	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
 	ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .quad,  KERNBASE)
+#ifdef XENPV
 	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .quad,  KERNBASE)
 	ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .quad,  start)
+#else
+	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .quad,  0)
+	ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY,   .long,  RELOC(start_xen32))
+#endif /* XENPV */
 	ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad,  hypercall_page)
 	ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW,   .quad,  HYPERVISOR_VIRT_START)
-	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "")
+	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_descriptor_tables|auto_translated_physmap|supervisor_mode_kernel|hvm_callback_vector")
 	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
 	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .long,  PTE_P, PTE_P)\
 	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")     
@@ -314,7 +317,7 @@
 #if NKSYMS > 0 || defined(DDB) || defined(MODULAR)
 	ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB,     .asciz, "yes")
 #endif
-#endif  /* XENPV */	
+#endif  /* XEN */
 
 /*
  * Initialization
@@ -418,6 +421,21 @@ _C_LABEL(farjmp64):
 	.word	GSEL(GCODE_SEL, SEL_KPL)
 END(farjmp64)
 
+#ifdef XEN
+/* 32bit GDT */
+gdtdesc32:
+	.word	gdt32end - gdt32
+	.long	RELOC(gdt32)
+	.long	0
+gdt32:  
+	.long	0			# null descriptor
+	.long	0
+	.long	0x0000ffff		# %cs
+	.long	0x00cf9a00 
+	.long	0x0000ffff		# %ds, %es, %ss
+	.long	0x00cf9200
+gdt32end:
+#endif /* XEN */
 #endif	/* !XENPV */
 
 	/* Space for the temporary stack */
@@ -973,6 +991,9 @@ longmode_hi:
 #endif	/* XENPV */
 
 	pushq	%rdi
+#if defined(XEN) && !defined(XENPV)
+	call	_C_LABEL(init_xen_early)
+#endif
 	call	_C_LABEL(init_bootspace)
 #ifdef KASAN
 	movq	_C_LABEL(lwp0uarea)(%rip),%rdi
@@ -984,6 +1005,64 @@ longmode_hi:
 	call 	_C_LABEL(main)
 END(start)
 
+#ifndef XENPV
+/* entry point for Xen PVH */
+	.code32
+ENTRY(start_xen32)
+	/* Xen doesn't start us with a valid gdt */
+	movl    $RELOC(gdtdesc32), %eax
+	lgdt    (%eax)
+	jmp     $GSEL(GCODE_SEL, SEL_KPL), $RELOC(.Lreload_cs)
+
+.Lreload_cs:
+	movw    $GSEL(GDATA_SEL, SEL_KPL), %ax          
+	movw    %ax, %ds
+	movw    %ax, %es
+	movw    %ax, %ss   
+
+	/* we need a valid stack */
+	movl	$RELOC(tmpstk),%esp
+
+	/* clear BSS */
+        xorl    %eax,%eax
+	movl    $RELOC(__bss_start),%edi
+	movl    $RELOC(_end),%ecx
+	subl    %edi,%ecx
+	rep
+	stosb
+
+	/*
+	 * save addr of the hvm_start_info structure. This is also the end
+	 * of the symbol table
+	 */
+	movl	%ebx, RELOC(hvm_start_paddr)
+	movl	%ebx, %eax
+	addl	$KERNBASE_LO,%eax
+	movl	$RELOC(esym),%ebp
+	movl	%eax,(%ebp)
+	movl	$KERNBASE_HI,4(%ebp)
+	/* get a page for HYPERVISOR_shared_info */
+	addl	$PAGE_SIZE, %ebx
+	addl	$PGOFSET,%ebx
+	andl	$~PGOFSET,%ebx
+	movl	$RELOC(HYPERVISOR_shared_info_pa),%ebp
+	movl	%ebx,(%ebp)
+	movl	$0,4(%ebp)
+	/* XXX assume hvm_start_info+dependant struture fits in a single page */
+	addl	$PAGE_SIZE, %ebx
+	addl	$PGOFSET,%ebx
+	andl	$~PGOFSET,%ebx
+	addl	$KERNBASE_LO,%ebx
+	movl	$RELOC(eblob),%ebp
+	movl	%ebx,(%ebp)
+	movl	$KERNBASE_HI,4(%ebp)
+
+	/* annouce ourself */
+	movl	$VM_GUEST_XENPVH, RELOC(vm_guest)
+	jmp .Lbiosbasemem_finished
+END(start_xen32)
+	.code64
+#endif /* XENPV */
 #if defined(XEN)
 /* space for the hypercall call page */
 #define HYPERCALL_PAGE_OFFSET 0x1000

Index: src/sys/arch/amd64/amd64/machdep.c
diff -u src/sys/arch/amd64/amd64/machdep.c:1.351 src/sys/arch/amd64/amd64/machdep.c:1.352
--- src/sys/arch/amd64/amd64/machdep.c:1.351	Sat May  2 16:28:37 2020
+++ src/sys/arch/amd64/amd64/machdep.c	Sat May  2 16:44:34 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.351 2020/05/02 16:28:37 maxv Exp $	*/
+/*	$NetBSD: machdep.c,v 1.352 2020/05/02 16:44:34 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011
@@ -110,7 +110,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.351 2020/05/02 16:28:37 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.352 2020/05/02 16:44:34 bouyer Exp $");
 
 #include "opt_modular.h"
 #include "opt_user_ldt.h"
@@ -1483,22 +1483,20 @@ extern vector IDTVEC(syscall32);
 extern vector IDTVEC(osyscall);
 extern vector *x86_exceptions[];
 
+#ifndef XENPV
 static void
 init_x86_64_ksyms(void)
 {
 #if NKSYMS || defined(DDB) || defined(MODULAR)
 	extern int end;
 	extern int *esym;
-#ifndef XENPV
 	struct btinfo_symtab *symtab;
 	vaddr_t tssym, tesym;
-#endif
 
 #ifdef DDB
 	db_machine_init();
 #endif
 
-#ifndef XENPV
 	symtab = lookup_bootinfo(BTINFO_SYMTAB);
 	if (symtab) {
 #ifdef KASLR
@@ -1512,15 +1510,9 @@ init_x86_64_ksyms(void)
 	} else
 		ksyms_addsyms_elf(*(long *)(void *)&end,
 		    ((long *)(void *)&end) + 1, esym);
-#else  /* XENPV */
-	esym = xen_start_info.mod_start ?
-	    (void *)xen_start_info.mod_start :
-	    (void *)xen_start_info.mfn_list;
-	ksyms_addsyms_elf(*(int *)(void *)&end,
-	    ((int *)(void *)&end) + 1, esym);
-#endif /* XENPV */
 #endif
 }
+#endif /* XENPV */
 
 void __noasan
 init_bootspace(void)
@@ -1676,6 +1668,10 @@ init_x86_64(paddr_t first_avail)
 	cpu_info_primary.ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[0];
 #endif
 
+#ifdef XEN
+	if (vm_guest == VM_GUEST_XENPVH)
+		xen_parse_cmdline(XEN_PARSE_BOOTFLAGS, NULL);
+#endif
 	init_pte();
 
 	uvm_lwp_setuarea(&lwp0, lwp0uarea);
@@ -1903,7 +1899,16 @@ init_x86_64(paddr_t first_avail)
 
 	cpu_init_idt();
 
-	init_x86_64_ksyms();
+#ifdef XENPV
+	xen_init_ksyms();
+#else /* XENPV */
+#ifdef XEN
+	if (vm_guest == VM_GUEST_XENPVH)
+		xen_init_ksyms();
+	else
+#endif /* XEN */
+		init_x86_64_ksyms();
+#endif /* XENPV */
 
 #ifndef XENPV
 	intr_default_setup();

Index: src/sys/arch/amd64/conf/GENERIC
diff -u src/sys/arch/amd64/conf/GENERIC:1.566 src/sys/arch/amd64/conf/GENERIC:1.567
--- src/sys/arch/amd64/conf/GENERIC:1.566	Sat Apr 25 15:26:16 2020
+++ src/sys/arch/amd64/conf/GENERIC	Sat May  2 16:44:35 2020
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.566 2020/04/25 15:26:16 bouyer Exp $
+# $NetBSD: GENERIC,v 1.567 2020/05/02 16:44:35 bouyer Exp $
 #
 # GENERIC machine description file
 #
@@ -22,7 +22,7 @@ include 	"arch/amd64/conf/std.amd64"
 
 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident		"GENERIC-$Revision: 1.566 $"
+#ident		"GENERIC-$Revision: 1.567 $"
 
 maxusers	64		# estimated number of users
 
@@ -121,6 +121,7 @@ options 	DDB_HISTORY_SIZE=512	# enable h
 #options 	KGDB		# remote debugger
 #options 	KGDB_DEVNAME="\"com\"",KGDB_DEVADDR=0x3f8,KGDB_DEVRATE=9600
 makeoptions	DEBUG="-g"	# compile full symbol table for CTF
+options DDB_COMMANDONENTER="trace;show registers"
 #options 	KUBSAN		# Kernel Undefined Behavior Sanitizer (kUBSan)
 #options 	UBSAN_ALWAYS_FATAL	# (optional) Panic on all kUBSan reports
 #options 	SYSCALL_STATS	# per syscall counts

Index: src/sys/arch/i386/i386/autoconf.c
diff -u src/sys/arch/i386/i386/autoconf.c:1.106 src/sys/arch/i386/i386/autoconf.c:1.107
--- src/sys/arch/i386/i386/autoconf.c:1.106	Fri Dec 27 12:51:56 2019
+++ src/sys/arch/i386/i386/autoconf.c	Sat May  2 16:44:35 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.106 2019/12/27 12:51:56 ad Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.107 2020/05/02 16:44:35 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.106 2019/12/27 12:51:56 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.107 2020/05/02 16:44:35 bouyer Exp $");
 
 #include "opt_intrdebug.h"
 #include "opt_multiprocessor.h"
@@ -105,7 +105,14 @@ cpu_configure(void)
 {
 	struct pcb *pcb;
 
+#ifdef XEN
+       if (vm_guest == VM_GUEST_XENPVH)
+	       xen_startrtclock();
+       else
+		startrtclock();
+#else
 	startrtclock();
+#endif
 
 #if NBIOS32 > 0
 	efi_init();

Index: src/sys/arch/i386/i386/genassym.cf
diff -u src/sys/arch/i386/i386/genassym.cf:1.121 src/sys/arch/i386/i386/genassym.cf:1.122
--- src/sys/arch/i386/i386/genassym.cf:1.121	Sat Apr 25 15:26:17 2020
+++ src/sys/arch/i386/i386/genassym.cf	Sat May  2 16:44:35 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.121 2020/04/25 15:26:17 bouyer Exp $
+#	$NetBSD: genassym.cf,v 1.122 2020/05/02 16:44:35 bouyer Exp $
 
 #
 # Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -99,6 +99,7 @@ include <machine/segments.h>
 
 ifdef XEN
 include <xen/include/public/sched.h>
+include <xen/include/public/arch-x86/hvm/start_info.h>
 endif
 
 if defined(_KERNEL) && defined(_KERNEL_OPT)
@@ -372,6 +373,7 @@ define	PGOFSET			PGOFSET
 define	PGSHIFT			PGSHIFT
 
 define	VM_GUEST_XENPV		VM_GUEST_XENPV
+define	VM_GUEST_XENPVH		VM_GUEST_XENPVH
 
 ifdef XEN
 define CPU_INFO_VCPU		offsetof(struct cpu_info, ci_vcpu)
@@ -388,4 +390,4 @@ define EVTCHN_UPCALL_MASK	offsetof(struc
 
 define HYPERVISOR_sched_op	__HYPERVISOR_sched_op
 define SCHEDOP_yield		SCHEDOP_yield
-endif
+endif /* XEN */

Index: src/sys/arch/i386/i386/locore.S
diff -u src/sys/arch/i386/i386/locore.S:1.181 src/sys/arch/i386/i386/locore.S:1.182
--- src/sys/arch/i386/i386/locore.S:1.181	Thu Apr 30 17:17:33 2020
+++ src/sys/arch/i386/i386/locore.S	Sat May  2 16:44:35 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.181 2020/04/30 17:17:33 maxv Exp $	*/
+/*	$NetBSD: locore.S,v 1.182 2020/05/02 16:44:35 bouyer Exp $	*/
 
 /*
  * Copyright-o-rama!
@@ -128,7 +128,7 @@
  */
 
 #include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.181 2020/04/30 17:17:33 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.182 2020/05/02 16:44:35 bouyer Exp $");
 
 #include "opt_copy_symtab.h"
 #include "opt_ddb.h"
@@ -243,37 +243,48 @@ __KERNEL_RCSID(0, "$NetBSD: locore.S,v 1
 
 
 #ifdef XEN
-/*
- * Unfortunately, the Xen codebase uses nonstandard preprocessing tools.
- * See: https://xenbits.xen.org/gitweb/?p=xen.git&a=search&h=HEAD&st=grep&s=__UnDeF__
- * for a fine selection of examples.
- *
- * What this means for us here is that we can't include the standard
- * xen.h header in assembler code.
- *
- * So we have to manually define, and keep track of the values we need, ourselves.
- */
-#define __HYPERVISOR_xen_version          17
-#endif	/* XEN */
+#define __ASSEMBLY__
+#include <xen/include/public/elfnote.h>
+#include <xen/include/public/xen.h>
+
+#define ELFNOTE(name, type, desctype, descdata...) \
+.pushsection .note.name			;	\
+  .align 4				;	\
+  .long 2f - 1f		/* namesz */	;	\
+  .long 4f - 3f		/* descsz */	;	\
+  .long type				;	\
+1:.asciz #name				;	\
+2:.align 4				;	\
+3:desctype descdata			;	\
+4:.align 4				;	\
+.popsection
 
-#ifdef XENPV
 /*
  * Xen guest identifier and loader selection
  */
 .section __xen_guest
-	.ascii	"GUEST_OS=netbsd,GUEST_VER=3.0,XEN_VER=xen-3.0"
-	.ascii	",VIRT_BASE=0xc0000000" /* KERNBASE */
-	.ascii	",ELF_PADDR_OFFSET=0xc0000000" /* KERNBASE */
-	.ascii	",VIRT_ENTRY=0xc0100000" /* KERNTEXTOFF */
-	.ascii	",HYPERCALL_PAGE=0x00000101"
-		/* (???+HYPERCALL_PAGE_OFFSET)/PAGE_SIZE) */
-	.ascii	",PAE=yes[extended-cr3]"
-	.ascii	",LOADER=generic"
-#if (NKSYMS || defined(DDB) || defined(MODULAR)) && !defined(makeoptions_COPY_SYMTAB)
-	.ascii	",BSD_SYMTAB=yes"
+	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz, "NetBSD")
+	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, "4.99")
+	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
+	ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .long,  KERNBASE)
+#ifdef XENPV
+	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long,  KERNBASE)
+	ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .long,  start)
+#else
+	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long,  0)
+	ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY,   .long,  RELOC(start_xenpvh))
+#endif /* XENPV */
+	ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long,  hypercall_page)
+	ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW,   .long,  HYPERVISOR_VIRT_START)
+	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_descriptor_tables|auto_translated_physmap|supervisor_mode_kernel|hvm_callback_vector")
+	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
+	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .quad,  PTE_P, PTE_P)\
+	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")     
+	ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long,  0)
+#if NKSYMS > 0 || defined(DDB) || defined(MODULAR)
+	ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB,     .asciz, "yes")
 #endif
-	.byte	0
-#endif	/* XENPV */
+#endif  /* XEN */
 
 /*
  * Initialization
@@ -580,7 +591,7 @@ multiboot2_loader:
 	pushl	%ebx		/* Address of Multiboot information */
 	call	_C_LABEL(multiboot2_pre_reloc)
 	addl	$4,%esp
-	jmp	2f
+	jmp	.Lstart_common
 #endif /* MULTIBOOT */
 
 1:
@@ -597,7 +608,7 @@ multiboot2_loader:
 	call	_C_LABEL(native_loader)
 	addl	$24,%esp
 
-2:
+.Lstart_common:
 	/* First, reset the PSL. */
 	pushl	$PSL_MBO
 	popfl
@@ -1071,6 +1082,9 @@ begin:
 	pushl	$0	/* init386() expects a 64 bits paddr_t with PAE */
 #endif
 	pushl	%eax
+#if defined(XEN) && !defined(XENPV)
+        call    _C_LABEL(init_xen_early)
+#endif
 	call	_C_LABEL(init_bootspace)
 	call	_C_LABEL(init386)
 	addl	$PDE_SIZE,%esp		/* pop paddr_t */
@@ -1150,6 +1164,74 @@ begin:
 #endif /* XENPV */
 END(start)
 
+#ifndef XENPV
+/* entry point for Xen PVH */
+ENTRY(start_xenpvh)
+	/* Xen doesn't start us with a valid gdt */
+	movl    $RELOC(gdtdesc_xenpvh), %eax
+	lgdt    (%eax)
+	jmp     $GSEL(GCODE_SEL, SEL_KPL), $RELOC(.Lreload_cs)
+
+.Lreload_cs:
+	movw    $GSEL(GDATA_SEL, SEL_KPL), %ax          
+	movw    %ax, %ds
+	movw    %ax, %es
+	movw    %ax, %ss   
+
+	/* we need a valid stack */
+	movl	$RELOC(tmpstk),%esp
+
+	/* clear BSS */
+        xorl    %eax,%eax
+	movl    $RELOC(__bss_start),%edi
+	movl    $RELOC(_end),%ecx
+	subl    %edi,%ecx
+	rep
+	stosb
+
+	/*
+	 * save addr of the hvm_start_info structure. This is also the end
+	 * of the symbol table
+	 */
+	movl	%ebx, RELOC(hvm_start_paddr)
+	movl	%ebx, %eax
+	addl	$KERNBASE,%eax
+	movl	$RELOC(esym),%ebp
+	movl	%eax,(%ebp)
+	/* get a page for HYPERVISOR_shared_info */
+	addl	$PAGE_SIZE, %ebx
+	addl	$PGOFSET,%ebx
+	andl	$~PGOFSET,%ebx
+	movl	$RELOC(HYPERVISOR_shared_info_pa),%ebp
+	movl	%ebx,(%ebp)
+	/* XXX assume hvm_start_info+dependant struture fits in a single page */
+	addl	$PAGE_SIZE, %ebx
+	addl	$PGOFSET,%ebx
+	andl	$~PGOFSET,%ebx
+	addl	$KERNBASE,%ebx
+	movl	$RELOC(eblob),%ebp
+	movl	%ebx,(%ebp)
+	/* annouce ourself */
+	movl	$VM_GUEST_XENPVH, RELOC(vm_guest)
+	jmp	.Lstart_common
+END(start_xenpvh)
+	.align 8
+gdtdesc_xenpvh:
+	.word	gdt_xenpvhend - gdt_xenpvh
+	.long	RELOC(gdt_xenpvh)
+	.word	0
+gdt_xenpvh:
+	.long   0			# null descriptor
+	.long   0
+	.long   0x0000ffff		# %cs
+	.long   0x00cf9a00
+	.long   0x0000ffff		# %ds, %es, %ss
+	.long   0x00cf9200
+gdt_xenpvhend:
+	.align 4
+#endif /* XENPV */
+
+
 #if defined(XEN)
 /* space for the hypercall call page */
 #define HYPERCALL_PAGE_OFFSET 0x1000

Index: src/sys/arch/i386/i386/machdep.c
diff -u src/sys/arch/i386/i386/machdep.c:1.828 src/sys/arch/i386/i386/machdep.c:1.829
--- src/sys/arch/i386/i386/machdep.c:1.828	Thu Apr 30 03:29:19 2020
+++ src/sys/arch/i386/i386/machdep.c	Sat May  2 16:44:35 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.828 2020/04/30 03:29:19 riastradh Exp $	*/
+/*	$NetBSD: machdep.c,v 1.829 2020/05/02 16:44:35 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009, 2017
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.828 2020/04/30 03:29:19 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.829 2020/05/02 16:44:35 bouyer Exp $");
 
 #include "opt_beep.h"
 #include "opt_compat_freebsd.h"
@@ -1044,8 +1044,9 @@ init386_pte0(void)
 	/* make sure it is clean before using */
 	memset((void *)vaddr, 0, PAGE_SIZE);
 }
-#endif /* !XENPV */
+#endif /* !XENPV && NBIOSCALL > 0 */
 
+#ifndef XENPV
 static void
 init386_ksyms(void)
 {
@@ -1075,6 +1076,7 @@ init386_ksyms(void)
 	ksyms_addsyms_elf(symtab->nsym, (int *)symtab->ssym, (int *)symtab->esym);
 #endif
 }
+#endif /* XENPV */
 
 void
 init_bootspace(void)
@@ -1140,12 +1142,17 @@ init386(paddr_t first_avail)
 	cpu_info_primary.ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[0];
 #endif
 
+#ifdef XEN
+	if (vm_guest == VM_GUEST_XENPVH)
+		xen_parse_cmdline(XEN_PARSE_BOOTFLAGS, NULL);
+#endif
+
 	uvm_lwp_setuarea(&lwp0, lwp0uarea);
 
 	cpu_probe(&cpu_info_primary);
 	cpu_rng_init();
 	cpu_init_msrs(&cpu_info_primary, true);
-#ifndef XEN
+#ifndef XENPV
 	cpu_speculation_init(&cpu_info_primary);
 #endif
 
@@ -1366,7 +1373,16 @@ init386(paddr_t first_avail)
 	lldt(GSEL(GLDT_SEL, SEL_KPL));
 	cpu_init_idt();
 
-	init386_ksyms();
+#ifdef XENPV
+	xen_init_ksyms();
+#else /* XENPV */
+#ifdef XEN
+	if (vm_guest == VM_GUEST_XENPVH)
+		xen_init_ksyms();
+	else
+#endif /* XEN */
+		init386_ksyms();
+#endif /* XENPV */
 
 #if NMCA > 0
 	/* 
@@ -1376,7 +1392,7 @@ init386(paddr_t first_avail)
 	 * And we do not search for MCA using bioscall() on EFI systems
 	 * that lacks it (they lack MCA too, anyway).
 	 */
-	if (lookup_bootinfo(BTINFO_EFI) == NULL)
+	if (lookup_bootinfo(BTINFO_EFI) == NULL && vm_guest != VM_GUEST_XENPVH)
 		mca_busprobe();
 #endif
 

Index: src/sys/arch/x86/acpi/acpi_machdep.c
diff -u src/sys/arch/x86/acpi/acpi_machdep.c:1.29 src/sys/arch/x86/acpi/acpi_machdep.c:1.30
--- src/sys/arch/x86/acpi/acpi_machdep.c:1.29	Sun Dec 22 15:57:07 2019
+++ src/sys/arch/x86/acpi/acpi_machdep.c	Sat May  2 16:44:35 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_machdep.c,v 1.29 2019/12/22 15:57:07 thorpej Exp $ */
+/* $NetBSD: acpi_machdep.c,v 1.30 2020/05/02 16:44:35 bouyer Exp $ */
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.29 2019/12/22 15:57:07 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.30 2020/05/02 16:44:35 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -79,6 +79,10 @@ __KERNEL_RCSID(0, "$NetBSD: acpi_machdep
 #include "opt_acpi.h"
 #include "opt_vga.h"
 
+#ifdef XEN
+#include <xen/hypervisor.h>
+#endif
+
 /*
  * Default VBIOS reset method for non-HW accelerated VGA drivers.
  */
@@ -151,6 +155,13 @@ out:
 			return PhysicalAddress;
 	}
 #else
+#ifdef XEN
+	if (vm_guest == VM_GUEST_XENPVH) {
+		PhysicalAddress = hvm_start_info->rsdp_paddr;
+		if (PhysicalAddress)
+			return PhysicalAddress;
+	}
+#endif
 	/* 
 	 * Get the ACPI RSDP from EFI SystemTable. This works when the 
 	 * kernel was loaded from EFI bootloader.

Index: src/sys/arch/x86/include/cpu.h
diff -u src/sys/arch/x86/include/cpu.h:1.124 src/sys/arch/x86/include/cpu.h:1.125
--- src/sys/arch/x86/include/cpu.h:1.124	Thu Apr 30 22:05:17 2020
+++ src/sys/arch/x86/include/cpu.h	Sat May  2 16:44:35 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.124 2020/04/30 22:05:17 bouyer Exp $	*/
+/*	$NetBSD: cpu.h,v 1.125 2020/05/02 16:44:35 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1990 The Regents of the University of California.
@@ -516,6 +516,18 @@ vm_guest_is_xenpv(void)
 	}
 }
 
+static __inline bool __unused
+vm_guest_is_xenpvh_or_pvhvm(void)
+{
+	switch(vm_guest) {
+	case VM_GUEST_XENPVH:
+	case VM_GUEST_XENPVHVM:
+		return true;
+	default:
+		return false;
+	}
+}
+
 /* cpu_topology.c */
 void	x86_cpu_topology(struct cpu_info *);
 

Index: src/sys/arch/x86/isa/clock.c
diff -u src/sys/arch/x86/isa/clock.c:1.37 src/sys/arch/x86/isa/clock.c:1.38
--- src/sys/arch/x86/isa/clock.c:1.37	Sat Apr 25 15:26:18 2020
+++ src/sys/arch/x86/isa/clock.c	Sat May  2 16:44:35 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: clock.c,v 1.37 2020/04/25 15:26:18 bouyer Exp $	*/
+/*	$NetBSD: clock.c,v 1.38 2020/05/02 16:44:35 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -121,7 +121,7 @@ WITH THE USE OR PERFORMANCE OF THIS SOFT
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.37 2020/04/25 15:26:18 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.38 2020/05/02 16:44:35 bouyer Exp $");
 
 /* #define CLOCKDEBUG */
 /* #define CLOCK_PARANOIA */
@@ -304,6 +304,9 @@ initrtclock(u_long freq)
 {
 	u_long tval;
 
+	if (vm_guest == VM_GUEST_XENPVH)
+		return;
+
 	/*
 	 * Compute timer_count, the count-down count the timer will be
 	 * set to.  Also, correctly round
@@ -512,6 +515,8 @@ i8254_delay(unsigned int n)
 int
 sysbeepmatch(device_t parent, cfdata_t match, void *aux)
 {
+	if (vm_guest == VM_GUEST_XENPVH)
+		return 0;
 	return (!ppi_attached);
 }
 

Index: src/sys/arch/x86/isa/isa_machdep.c
diff -u src/sys/arch/x86/isa/isa_machdep.c:1.45 src/sys/arch/x86/isa/isa_machdep.c:1.46
--- src/sys/arch/x86/isa/isa_machdep.c:1.45	Sat Apr 25 15:26:18 2020
+++ src/sys/arch/x86/isa/isa_machdep.c	Sat May  2 16:44:35 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: isa_machdep.c,v 1.45 2020/04/25 15:26:18 bouyer Exp $	*/
+/*	$NetBSD: isa_machdep.c,v 1.46 2020/05/02 16:44:35 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: isa_machdep.c,v 1.45 2020/04/25 15:26:18 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: isa_machdep.c,v 1.46 2020/05/02 16:44:35 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -365,6 +365,9 @@ device_isa_register(device_t dev, void *
 			    	return dev;
 		}
 	}
+	if (vm_guest == VM_GUEST_XENPVH)
+		prop_dictionary_set_bool(device_properties(dev),
+		    "no-legacy-devices", true);
 #if NACPICA > 0
 #if notyet
 	if (device_is_a(dev, "isa") && acpi_active) {

Index: src/sys/arch/x86/x86/consinit.c
diff -u src/sys/arch/x86/x86/consinit.c:1.32 src/sys/arch/x86/x86/consinit.c:1.33
--- src/sys/arch/x86/x86/consinit.c:1.32	Sat Apr 25 15:26:18 2020
+++ src/sys/arch/x86/x86/consinit.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: consinit.c,v 1.32 2020/04/25 15:26:18 bouyer Exp $	*/
+/*	$NetBSD: consinit.c,v 1.33 2020/05/02 16:44:36 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1998
@@ -27,10 +27,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: consinit.c,v 1.32 2020/04/25 15:26:18 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: consinit.c,v 1.33 2020/05/02 16:44:36 bouyer Exp $");
 
 #include "opt_kgdb.h"
 #include "opt_puc.h"
+#include "opt_xen.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -98,6 +99,10 @@ __KERNEL_RCSID(0, "$NetBSD: consinit.c,v
 #endif
 #endif
 
+#ifdef XENPVHVM
+#include <xen/xen.h>
+#endif
+
 #ifndef CONSDEVNAME
 #define CONSDEVNAME "pc"
 #endif
@@ -166,6 +171,12 @@ consinit(void)
 	int rv;
 #endif
 
+#ifdef XENPVHVM
+	if (vm_guest == VM_GUEST_XENPVH) {
+		xen_pvh_consinit();
+		return;
+	}
+#endif
 	if (initted)
 		return;
 	initted = 1;

Index: src/sys/arch/x86/x86/cpu.c
diff -u src/sys/arch/x86/x86/cpu.c:1.188 src/sys/arch/x86/x86/cpu.c:1.189
--- src/sys/arch/x86/x86/cpu.c:1.188	Wed Apr 29 22:03:09 2020
+++ src/sys/arch/x86/x86/cpu.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.188 2020/04/29 22:03:09 ad Exp $	*/
+/*	$NetBSD: cpu.c,v 1.189 2020/05/02 16:44:36 bouyer Exp $	*/
 
 /*
  * Copyright (c) 2000-2012 NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.188 2020/04/29 22:03:09 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.189 2020/05/02 16:44:36 bouyer Exp $");
 
 #include "opt_ddb.h"
 #include "opt_mpbios.h"		/* for MPDEBUG */
@@ -447,7 +447,7 @@ cpu_attach(device_t parent, device_t sel
 			/* Enable lapic. */
 			lapic_enable();
 			lapic_set_lvt();
-			if (vm_guest != VM_GUEST_XENPVHVM)
+			if (!vm_guest_is_xenpvh_or_pvhvm())
 				lapic_calibrate_timer(ci);
 		}
 #endif
@@ -824,7 +824,7 @@ cpu_start_secondary(struct cpu_info *ci)
 	KASSERT(cpu_starting == NULL);
 	cpu_starting = ci;
 	for (i = 100000; (!(ci->ci_flags & CPUF_PRESENT)) && i > 0; i--) {
-		x86_delay(10);
+		delay_func(10);
 	}
 
 	if ((ci->ci_flags & CPUF_PRESENT) == 0) {
@@ -860,7 +860,7 @@ cpu_boot_secondary(struct cpu_info *ci)
 
 	atomic_or_32(&ci->ci_flags, CPUF_GO);
 	for (i = 100000; (!(ci->ci_flags & CPUF_RUNNING)) && i > 0; i--) {
-		x86_delay(10);
+		delay_func(10);
 	}
 	if ((ci->ci_flags & CPUF_RUNNING) == 0) {
 		aprint_error_dev(ci->ci_dev, "failed to start\n");
@@ -1143,7 +1143,7 @@ mp_cpu_start(struct cpu_info *ci, paddr_
 			    __func__);
 			return error;
 		}
-		x86_delay(10000);
+		delay_func(10000);
 
 		error = x86_ipi_startup(ci->ci_cpuid, target / PAGE_SIZE);
 		if (error != 0) {
@@ -1151,7 +1151,7 @@ mp_cpu_start(struct cpu_info *ci, paddr_
 			    __func__);
 			return error;
 		}
-		x86_delay(200);
+		delay_func(200);
 
 		error = x86_ipi_startup(ci->ci_cpuid, target / PAGE_SIZE);
 		if (error != 0) {
@@ -1159,7 +1159,7 @@ mp_cpu_start(struct cpu_info *ci, paddr_
 			    __func__);
 			return error;
 		}
-		x86_delay(200);
+		delay_func(200);
 	}
 
 	return 0;
@@ -1321,7 +1321,7 @@ cpu_get_tsc_freq(struct cpu_info *ci)
 	} else {
 		/* Calibrate TSC frequency. */
 		last_tsc = cpu_counter_serializing();
-		x86_delay(100000);
+		delay_func(100000);
 		ci->ci_data.cpu_cc_freq =
 		    (cpu_counter_serializing() - last_tsc) * 10;
 	}

Index: src/sys/arch/x86/x86/lapic.c
diff -u src/sys/arch/x86/x86/lapic.c:1.77 src/sys/arch/x86/x86/lapic.c:1.78
--- src/sys/arch/x86/x86/lapic.c:1.77	Sat Apr 25 15:26:18 2020
+++ src/sys/arch/x86/x86/lapic.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: lapic.c,v 1.77 2020/04/25 15:26:18 bouyer Exp $	*/
+/*	$NetBSD: lapic.c,v 1.78 2020/05/02 16:44:36 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2000, 2008 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.77 2020/04/25 15:26:18 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.78 2020/05/02 16:44:36 bouyer Exp $");
 
 #include "acpica.h"
 #include "ioapic.h"
@@ -789,7 +789,7 @@ i82489_ipi_init(int target)
 
 	i82489_writereg(LAPIC_ICRLO, LAPIC_DLMODE_INIT | LAPIC_LEVEL_ASSERT);
 	i82489_icr_wait();
-	x86_delay(10000);
+	delay_func(10000);
 	i82489_writereg(LAPIC_ICRLO,
 	    LAPIC_DLMODE_INIT | LAPIC_TRIGMODE_LEVEL | LAPIC_LEVEL_DEASSERT);
 	i82489_icr_wait();
@@ -861,7 +861,7 @@ x2apic_ipi_init(int target)
 
 	x2apic_write_icr(target, LAPIC_DLMODE_INIT | LAPIC_LEVEL_ASSERT);
 
-	x86_delay(10000);
+	delay_func(10000);
 
 	x2apic_write_icr(0,
 	    LAPIC_DLMODE_INIT | LAPIC_TRIGMODE_LEVEL | LAPIC_LEVEL_DEASSERT);

Index: src/sys/arch/x86/x86/pmap.c
diff -u src/sys/arch/x86/x86/pmap.c:1.386 src/sys/arch/x86/x86/pmap.c:1.387
--- src/sys/arch/x86/x86/pmap.c:1.386	Sat May  2 16:28:37 2020
+++ src/sys/arch/x86/x86/pmap.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.386 2020/05/02 16:28:37 maxv Exp $	*/
+/*	$NetBSD: pmap.c,v 1.387 2020/05/02 16:44:36 bouyer Exp $	*/
 
 /*
  * Copyright (c) 2008, 2010, 2016, 2017, 2019, 2020 The NetBSD Foundation, Inc.
@@ -130,7 +130,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.386 2020/05/02 16:28:37 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.387 2020/05/02 16:44:36 bouyer Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -1335,8 +1335,10 @@ pmap_bootstrap(vaddr_t kva_start)
 	extern volatile struct xencons_interface *xencons_interface; /* XXX */
 	extern struct xenstore_domain_interface *xenstore_interface; /* XXX */
 
-	HYPERVISOR_shared_info = (void *) pmap_bootstrap_valloc(1);
-	HYPERVISOR_shared_info_pa = pmap_bootstrap_palloc(1);
+	if (vm_guest != VM_GUEST_XENPVH) {
+		HYPERVISOR_shared_info = (void *) pmap_bootstrap_valloc(1);
+		HYPERVISOR_shared_info_pa = pmap_bootstrap_palloc(1);
+	}
 	xencons_interface = (void *) pmap_bootstrap_valloc(1);
 	xenstore_interface = (void *) pmap_bootstrap_valloc(1);
 #endif

Index: src/sys/arch/x86/x86/x86_autoconf.c
diff -u src/sys/arch/x86/x86/x86_autoconf.c:1.81 src/sys/arch/x86/x86/x86_autoconf.c:1.82
--- src/sys/arch/x86/x86/x86_autoconf.c:1.81	Tue Apr 28 15:43:34 2020
+++ src/sys/arch/x86/x86/x86_autoconf.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: x86_autoconf.c,v 1.81 2020/04/28 15:43:34 bouyer Exp $	*/
+/*	$NetBSD: x86_autoconf.c,v 1.82 2020/05/02 16:44:36 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_autoconf.c,v 1.81 2020/04/28 15:43:34 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_autoconf.c,v 1.82 2020/05/02 16:44:36 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -54,6 +54,8 @@ __KERNEL_RCSID(0, "$NetBSD: x86_autoconf
 #include <machine/bootinfo.h>
 #include <machine/pio.h>
 
+#include <xen/xen.h>
+
 #include <dev/i2c/i2cvar.h>
 
 #include "acpica.h"
@@ -535,6 +537,12 @@ findroot(void)
 void
 cpu_bootconf(void)
 {
+#ifdef XEN
+	if (vm_guest == VM_GUEST_XENPVH) {
+		xen_bootconf();
+		return;
+	}
+#endif
 	findroot();
 	matchbiosdisks();
 }

Index: src/sys/arch/x86/x86/x86_machdep.c
diff -u src/sys/arch/x86/x86/x86_machdep.c:1.140 src/sys/arch/x86/x86/x86_machdep.c:1.141
--- src/sys/arch/x86/x86/x86_machdep.c:1.140	Fri May  1 14:16:15 2020
+++ src/sys/arch/x86/x86/x86_machdep.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: x86_machdep.c,v 1.140 2020/05/01 14:16:15 hannken Exp $	*/
+/*	$NetBSD: x86_machdep.c,v 1.141 2020/05/02 16:44:36 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.140 2020/05/01 14:16:15 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.141 2020/05/02 16:44:36 bouyer Exp $");
 
 #include "opt_modular.h"
 #include "opt_physmem.h"
@@ -95,6 +95,11 @@ void (*x86_cpu_idle)(void);
 static bool x86_cpu_idle_ipi;
 static char x86_cpu_idle_text[16];
 
+#ifdef XEN
+
+#include <xen/xen.h>
+#include <xen/hypervisor.h>
+#endif
 #ifdef XENPV
 char module_machine_amd64_xen[] = "amd64-xen";
 char module_machine_i386pae_xen[] = "i386pae-xen";
@@ -855,6 +860,27 @@ init_x86_clusters(void)
 	 * Check to see if we have a memory map from the BIOS (passed to us by
 	 * the boot program).
 	 */
+#ifdef XEN
+	if (vm_guest == VM_GUEST_XENPVH) {
+		struct hvm_memmap_table_entry *map_entry;
+		map_entry = (void *)((uintptr_t)hvm_start_info->memmap_paddr + KERNBASE);
+		for (int i = 0; i < hvm_start_info->memmap_entries; i++) {
+			if (map_entry[i].size < PAGE_SIZE)
+				continue;
+			switch(map_entry[i].type) {
+			case XEN_HVM_MEMMAP_TYPE_RAM:
+				x86_add_cluster(map_entry[i].addr,
+				    map_entry[i].size, BIM_Memory);
+				break;
+			case XEN_HVM_MEMMAP_TYPE_ACPI:
+				x86_add_cluster(map_entry[i].addr,
+				    map_entry[i].size, BIM_ACPI);
+				break;
+			}
+		}
+	}
+#endif /* XEN */
+
 #ifdef i386
 	extern int biosmem_implicit;
 	biem = lookup_bootinfo(BTINFO_EFIMEMMAP);

Index: src/sys/arch/xen/conf/Makefile.xen
diff -u src/sys/arch/xen/conf/Makefile.xen:1.49 src/sys/arch/xen/conf/Makefile.xen:1.50
--- src/sys/arch/xen/conf/Makefile.xen:1.49	Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/conf/Makefile.xen	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.xen,v 1.49 2020/04/25 15:26:17 bouyer Exp $
+#	$NetBSD: Makefile.xen,v 1.50 2020/05/02 16:44:36 bouyer Exp $
 #	NetBSD: Makefile.i386,v 1.132 2003/07/05 16:56:10 simonb Exp 
 
 # Makefile for NetBSD
@@ -41,7 +41,7 @@ ARCH_INC=	$S/arch/xen/include/${XEN_BUIL
 ## (2) compile settings
 ##
 CPPFLAGS+=	-D${XEN_BUILD}
-AFLAGS+=	-x assembler-with-cpp ${DBG} -D__XEN__
+AFLAGS+=	-x assembler-with-cpp ${DBG}
 EXTRA_INCLUDES=	-I${.CURDIR}/xen-ma -I$S/external/mit/xen-include-public/dist/
 
 .if ${XEN_BUILD} == "amd64"

Index: src/sys/arch/xen/conf/files.xen
diff -u src/sys/arch/xen/conf/files.xen:1.182 src/sys/arch/xen/conf/files.xen:1.183
--- src/sys/arch/xen/conf/files.xen:1.182	Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/conf/files.xen	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: files.xen,v 1.182 2020/04/25 15:26:17 bouyer Exp $
+#	$NetBSD: files.xen,v 1.183 2020/05/02 16:44:36 bouyer Exp $
 
 defflag	opt_xen.h			XEN XENPVH XENPVHVM PAE
 
@@ -11,6 +11,8 @@ file	arch/xen/x86/xen_mainbus.c		xen
 file	arch/xen/xen/xen_clock.c		xen
 file	arch/xen/x86/xen_bus_dma.c		xen
 
+file	arch/xen/x86/hvm_consinit.c		xenpvhvm
+
 define hypervisorbus {}
 define xendevbus {}
 

Index: src/sys/arch/xen/include/hypervisor.h
diff -u src/sys/arch/xen/include/hypervisor.h:1.51 src/sys/arch/xen/include/hypervisor.h:1.52
--- src/sys/arch/xen/include/hypervisor.h:1.51	Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/include/hypervisor.h	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: hypervisor.h,v 1.51 2020/04/25 15:26:17 bouyer Exp $	*/
+/*	$NetBSD: hypervisor.h,v 1.52 2020/05/02 16:44:36 bouyer Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -99,6 +99,7 @@ struct xen_npx_attach_args {
 #include <xen/include/public/memory.h>
 #include <xen/include/public/io/netif.h>
 #include <xen/include/public/io/blkif.h>
+#include <xen/include/public/arch-x86/hvm/start_info.h>
 
 #if __XEN_INTERFACE_VERSION < 0x00030208
 /* Undo namespace damage from xen/include/public/io/ring.h
@@ -138,9 +139,14 @@ union start_info_union
 extern union start_info_union start_info_union;
 #define xen_start_info (start_info_union.start_info)
 
+extern struct hvm_start_info *hvm_start_info;
+
 /* For use in guest OSes. */
 extern volatile shared_info_t *HYPERVISOR_shared_info;
 
+/* console */
+extern volatile struct xencons_interface *xencons_interface;
+
 
 /* Structural guest handles introduced in 0x00030201. */
 #if __XEN_INTERFACE_VERSION__ >= 0x00030201
@@ -197,4 +203,6 @@ hypervisor_notify_via_evtchn(unsigned in
 	(void)HYPERVISOR_event_channel_op(&op);
 }
 
+void xen_init_ksyms(void);
+
 #endif /* _XEN_HYPERVISOR_H_ */

Index: src/sys/arch/xen/include/xen.h
diff -u src/sys/arch/xen/include/xen.h:1.46 src/sys/arch/xen/include/xen.h:1.47
--- src/sys/arch/xen/include/xen.h:1.46	Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/include/xen.h	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: xen.h,v 1.46 2020/04/25 15:26:17 bouyer Exp $	*/
+/*	$NetBSD: xen.h,v 1.47 2020/05/02 16:44:36 bouyer Exp $	*/
 
 /*
  *
@@ -60,6 +60,8 @@ void	xen_parse_cmdline(int, union xen_cm
 
 void	xenconscn_attach(void);
 
+void 	xen_pvh_consinit(void);
+
 void	xenprivcmd_init(void);
 
 void	xbdback_init(void);
@@ -294,6 +296,8 @@ xen_feature(int f)
 	return xen_feature_tables[f];
 }
 
+void xen_bootconf(void);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _OS_H_ */

Index: src/sys/arch/xen/x86/autoconf.c
diff -u src/sys/arch/xen/x86/autoconf.c:1.24 src/sys/arch/xen/x86/autoconf.c:1.25
--- src/sys/arch/xen/x86/autoconf.c:1.24	Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/x86/autoconf.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.24 2020/04/25 15:26:17 bouyer Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.25 2020/05/02 16:44:36 bouyer Exp $	*/
 /*	NetBSD: autoconf.c,v 1.75 2003/12/30 12:33:22 pk Exp 	*/
 
 /*-
@@ -45,7 +45,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.24 2020/04/25 15:26:17 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.25 2020/05/02 16:44:36 bouyer Exp $");
 
 #include "opt_xen.h"
 #include "opt_multiprocessor.h"
@@ -82,8 +82,6 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v
 #include <machine/pcb.h>
 #include <machine/bootinfo.h>
 
-static int is_valid_disk(device_t);
-
 struct disklist *x86_alldisks;
 int x86_ndisks;
 int x86_found_console;
@@ -116,7 +114,7 @@ cpu_configure(void)
 {
 	struct pcb *pcb;
 
-	startrtclock();
+	xen_startrtclock();
 
 #if defined(DOM0OPS)
 	if (xendomain_is_dom0()) {
@@ -171,69 +169,8 @@ cpu_rootconf(void)
 void
 cpu_bootconf(void)
 {
-	device_t dv;
-	deviter_t di;
-	union xen_cmdline_parseinfo xcp;
-	static char bootspecbuf[sizeof(xcp.xcp_bootdev)];
-
-	if (booted_device) {
-		DPRINTF(("%s: preset booted_device: %s\n", __func__, device_xname(booted_device)));
-		return;
-	}
-
-	xen_parse_cmdline(XEN_PARSE_BOOTDEV, &xcp);
-
-	for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
-	     dv != NULL;
-	     dv = deviter_next(&di)) {
-		bool is_ifnet, is_disk;
-		const char *devname;
-
-		is_ifnet = (device_class(dv) == DV_IFNET);
-		is_disk = is_valid_disk(dv);
-		devname = device_xname(dv);
-
-		if (!is_ifnet && !is_disk)
-			continue;
-
-		if (is_disk && xcp.xcp_bootdev[0] == 0) {
-			booted_device = dv;
-			break;
-		}
-
-		if (strncmp(xcp.xcp_bootdev, devname, strlen(devname)))
-			continue;
-
-		if (is_disk && strlen(xcp.xcp_bootdev) > strlen(devname)) {
-			/* XXX check device_cfdata as in x86_autoconf.c? */
-			booted_partition = toupper(
-				xcp.xcp_bootdev[strlen(devname)]) - 'A';
-			DPRINTF(("%s: booted_partition: %d\n", __func__, booted_partition));
-		}
-
-		booted_device = dv;
-		booted_method = "bootinfo/bootdev";
-		break;
-	}
-	deviter_release(&di);
-
-	if (booted_device) {
-		DPRINTF(("%s: booted_device: %s\n", __func__, device_xname(booted_device)));
-		return;
-	}
-
-	/*
-	 * not a boot device name, pass through to MI code
-	 */
-	if (xcp.xcp_bootdev[0] != '\0') {
-		strlcpy(bootspecbuf, xcp.xcp_bootdev, sizeof(bootspecbuf));
-		bootspec = bootspecbuf;
-		booted_method = "bootinfo/bootspec";
-		DPRINTF(("%s: bootspec: %s\n", __func__, bootspec));
-		return;
-	}
+	xen_bootconf();
 }
-
 #include "pci.h"
 
 #include <dev/isa/isavar.h>
@@ -370,17 +307,3 @@ found:
 	}
 	booted_device = dev;
 }
-
-static int
-is_valid_disk(device_t dv)
-{
-	if (device_class(dv) != DV_DISK)
-		return (0);
-
-	return (device_is_a(dv, "dk") ||
-		device_is_a(dv, "sd") ||
-		device_is_a(dv, "wd") ||
-		device_is_a(dv, "ld") ||
-		device_is_a(dv, "ed") ||
-		device_is_a(dv, "xbd"));
-}

Index: src/sys/arch/xen/x86/hypervisor_machdep.c
diff -u src/sys/arch/xen/x86/hypervisor_machdep.c:1.38 src/sys/arch/xen/x86/hypervisor_machdep.c:1.39
--- src/sys/arch/xen/x86/hypervisor_machdep.c:1.38	Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/x86/hypervisor_machdep.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: hypervisor_machdep.c,v 1.38 2020/04/25 15:26:17 bouyer Exp $	*/
+/*	$NetBSD: hypervisor_machdep.c,v 1.39 2020/05/02 16:44:36 bouyer Exp $	*/
 
 /*
  *
@@ -54,12 +54,13 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hypervisor_machdep.c,v 1.38 2020/04/25 15:26:17 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hypervisor_machdep.c,v 1.39 2020/05/02 16:44:36 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kmem.h>
 #include <sys/cpu.h>
+#include <sys/ksyms.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -76,8 +77,18 @@ __KERNEL_RCSID(0, "$NetBSD: hypervisor_m
 #include <xen/xenpmap.h>
 
 #include "opt_xen.h"
+#include "opt_modular.h"
+#include "opt_ddb.h"
 #include "isa.h"
 #include "pci.h"
+#include "ksyms.h"
+
+#ifdef DDB
+#include <machine/db_machdep.h>
+#include <ddb/db_extern.h>
+#include <ddb/db_output.h>
+#include <ddb/db_interface.h>
+#endif
 
 #ifdef XENPV
 /*
@@ -569,3 +580,24 @@ update_p2m_frame_list_list(void)
 
 }
 #endif /* XENPV */
+
+void
+xen_init_ksyms(void)
+{
+#if NKSYMS || defined(DDB) || defined(MODULAR)
+	extern int end;
+	extern int *esym;
+#ifdef DDB
+	db_machine_init();
+#endif
+
+#ifdef XENPV
+	esym = xen_start_info.mod_start ?
+	    (void *)xen_start_info.mod_start :
+	    (void *)xen_start_info.mfn_list;
+#endif /* XENPV */
+	/* for PVH, esym is set in locore.S */
+	ksyms_addsyms_elf(*(int *)(void *)&end,
+	    ((int *)(void *)&end) + 1, esym);
+#endif
+}

Index: src/sys/arch/xen/x86/x86_xpmap.c
diff -u src/sys/arch/xen/x86/x86_xpmap.c:1.85 src/sys/arch/xen/x86/x86_xpmap.c:1.86
--- src/sys/arch/xen/x86/x86_xpmap.c:1.85	Wed Oct 30 07:40:06 2019
+++ src/sys/arch/xen/x86/x86_xpmap.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: x86_xpmap.c,v 1.85 2019/10/30 07:40:06 maxv Exp $	*/
+/*	$NetBSD: x86_xpmap.c,v 1.86 2020/05/02 16:44:36 bouyer Exp $	*/
 
 /*
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -95,7 +95,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c,v 1.85 2019/10/30 07:40:06 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c,v 1.86 2020/05/02 16:44:36 bouyer Exp $");
 
 #include "opt_xen.h"
 #include "opt_ddb.h"
@@ -135,7 +135,6 @@ static mmu_update_t xpq_queue_array[MAXC
 
 void xen_failsafe_handler(void);
 
-extern volatile struct xencons_interface *xencons_interface; /* XXX */
 extern struct xenstore_domain_interface *xenstore_interface; /* XXX */
 
 static void xen_bt_set_readonly(vaddr_t);

Index: src/sys/arch/xen/x86/xen_mainbus.c
diff -u src/sys/arch/xen/x86/xen_mainbus.c:1.7 src/sys/arch/xen/x86/xen_mainbus.c:1.8
--- src/sys/arch/xen/x86/xen_mainbus.c:1.7	Sat Apr 25 15:26:17 2020
+++ src/sys/arch/xen/x86/xen_mainbus.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: xen_mainbus.c,v 1.7 2020/04/25 15:26:17 bouyer Exp $	*/
+/*	$NetBSD: xen_mainbus.c,v 1.8 2020/05/02 16:44:36 bouyer Exp $	*/
 /*	NetBSD: mainbus.c,v 1.19 2017/05/23 08:54:39 nonaka Exp 	*/
 /*	NetBSD: mainbus.c,v 1.53 2003/10/27 14:11:47 junyoung Exp 	*/
 
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xen_mainbus.c,v 1.7 2020/04/25 15:26:17 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_mainbus.c,v 1.8 2020/05/02 16:44:36 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -131,6 +131,7 @@ xen_mainbus_attach(device_t parent, devi
 			config_found_ia(self, "ipmibus", &mba.mba_ipmi, 0);
 #endif
 	/* FALLTHROUGH */
+	case VM_GUEST_XENPVH:
 	case VM_GUEST_XENPVHVM:
 		mba.mba_haa.haa_busname = "hypervisor";
 		config_found_ia(self, "hypervisorbus",

Index: src/sys/arch/xen/xen/hypervisor.c
diff -u src/sys/arch/xen/xen/hypervisor.c:1.78 src/sys/arch/xen/xen/hypervisor.c:1.79
--- src/sys/arch/xen/xen/hypervisor.c:1.78	Tue Apr 28 15:43:34 2020
+++ src/sys/arch/xen/xen/hypervisor.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: hypervisor.c,v 1.78 2020/04/28 15:43:34 bouyer Exp $ */
+/* $NetBSD: hypervisor.c,v 1.79 2020/05/02 16:44:36 bouyer Exp $ */
 
 /*
  * Copyright (c) 2005 Manuel Bouyer.
@@ -53,7 +53,7 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.78 2020/04/28 15:43:34 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.79 2020/05/02 16:44:36 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -163,8 +163,9 @@ struct  x86_isa_chipset x86_isa_chipset;
 #endif
 #endif
 
-#if defined(XENPVHVM)
+#if defined(XENPVHVM) || defined(XENPVH)
 #include <xen/include/public/arch-x86/cpuid.h>
+#include <xen/include/public/arch-x86/hvm/start_info.h>
 #include <xen/include/public/hvm/hvm_op.h>
 #include <xen/include/public/hvm/params.h>
 #include <xen/include/public/vcpu.h>
@@ -179,12 +180,12 @@ extern vector IDTVEC(osyscall);
 extern vector *x86_exceptions[];
 
 extern vector IDTVEC(hypervisor_pvhvm_callback);
-extern volatile struct xencons_interface *xencons_interface; /* XXX */
 extern struct xenstore_domain_interface *xenstore_interface; /* XXX */
 
 volatile shared_info_t *HYPERVISOR_shared_info __read_mostly;
 paddr_t HYPERVISOR_shared_info_pa;
 union start_info_union start_info_union __aligned(PAGE_SIZE);
+struct hvm_start_info *hvm_start_info;
 
 static int xen_hvm_vec = 0;
 #endif
@@ -209,6 +210,64 @@ enum {
 
 bool xenhvm_use_percpu_callback = 0;
 
+static void
+xen_init_hypercall_page(void)
+{
+	extern vaddr_t hypercall_page;
+	u_int descs[4];
+
+	x86_cpuid(XEN_CPUID_LEAF(2), descs);
+
+	/* 
+	 * Given 32 bytes per hypercall stub, and an optimistic number
+	 * of 100 hypercalls ( the current max is 55), there shouldn't
+	 * be any reason to spill over the arbitrary number of 1
+	 * hypercall page. This is what we allocate in locore.S
+	 * anyway. Make sure the allocation matches the registration.
+	 */
+
+	KASSERT(descs[0] == 1);
+
+	/* XXX: vtophys(&hypercall_page) */
+	wrmsr(descs[1], (uintptr_t)&hypercall_page - KERNBASE);
+}
+
+uint32_t hvm_start_paddr;
+
+void init_xen_early(void);
+void
+init_xen_early(void)
+{
+	const char *cmd_line;
+	if (vm_guest != VM_GUEST_XENPVH)
+		return;
+	xen_init_hypercall_page();
+	hvm_start_info = (void *)((uintptr_t)hvm_start_paddr + KERNBASE);
+
+	HYPERVISOR_shared_info = (void *)(HYPERVISOR_shared_info_pa + KERNBASE);
+	struct xen_add_to_physmap xmap = {
+		.domid = DOMID_SELF,
+		.space = XENMAPSPACE_shared_info,
+		.idx = 0, /* Important - XEN checks for this */
+		.gpfn = atop(HYPERVISOR_shared_info_pa)
+	};
+
+	int err;
+
+	if ((err = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xmap)) < 0) {
+		printk(
+		    "Xen HVM: Unable to register HYPERVISOR_shared_info %d\n", err);
+	}
+	delay_func = xen_delay;
+	x86_initclock_func = xen_initclocks;
+	x86_cpu_initclock_func = xen_cpu_initclocks;
+	cmd_line =
+	    (void *)((uintptr_t)hvm_start_info->cmdline_paddr + KERNBASE);
+	strlcpy(xen_start_info.cmd_line, cmd_line,
+	    sizeof(xen_start_info.cmd_line));
+}
+
+
 static bool
 xen_check_hypervisordev(void)
 {
@@ -227,51 +286,17 @@ xen_check_hypervisordev(void)
 	}
 	return 0;
 }
-int
-xen_hvm_init(void)
-{
-	extern vaddr_t hypercall_page;
-	u_int descs[4];
-
-	/*
-	 * We need to setup the HVM interfaces early, so that we can
-	 * properly setup the CPUs later (especially, all CPUs needs to
-	 * run x86_cpuid() locally to get their vcpuid.
-	 *
-	 * if everything goes fine, we switch vm_guest to VM_GUEST_XENPVHVM
-	 */
 
-	if (vm_guest != VM_GUEST_XENHVM)
-		return 0;
-
-	/* check if hypervisor was disabled with userconf */
-	if (!xen_check_hypervisordev())
+static int
+xen_hvm_init_late(void)
+{
+	if (HYPERVISOR_xen_version(XENVER_version, NULL) < 0) {
+		aprint_error("Xen HVM: hypercall page not working\n");
 		return 0;
-
-	aprint_normal("Identified Guest XEN in HVM mode.\n");
-
-	x86_cpuid(XEN_CPUID_LEAF(2), descs);
-
-	/* 
-	 * Given 32 bytes per hypercall stub, and an optimistic number
-	 * of 100 hypercalls ( the current max is 55), there shouldn't
-	 * be any reason to spill over the arbitrary number of 1
-	 * hypercall page. This is what we allocate in locore.S
-	 * anyway. Make sure the allocation matches the registration.
-	 */
-
-	KASSERT(descs[0] == 1);
-
-	/* XXX: vtophys(&hypercall_page) */
-	wrmsr(descs[1], (uintptr_t)&hypercall_page - KERNBASE);
-
-	if (-1 != HYPERVISOR_xen_version(XENVER_version, NULL)) {
-		printf("Xen HVM: detected functional hypercall page.\n");
-		xen_init_features();
 	}
+	xen_init_features();
 
 	/* Init various preset boot time data structures  */
-
 	/* XEN xenstore shared page address, event channel */
 	struct xen_hvm_param xen_hvm_param;
 
@@ -301,31 +326,59 @@ xen_hvm_init(void)
 
 	xen_start_info.store_evtchn = xen_hvm_param.value;
 
-	xen_hvm_param.domid = DOMID_SELF;
-	xen_hvm_param.index = HVM_PARAM_CONSOLE_PFN;
-	
-	if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
-		aprint_error(
-		    "Xen HVM: Unable to obtain xencons page address\n");
+	/*
+	 * First register callback: here's why
+	 * http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7b5b8ca7dffde866d851f0b87b994e0b13e5b867
+	 */
+
+	/*
+	 * Check for XENFEAT_hvm_callback_vector. Can't proceed
+	 * without it.
+	 */
+	if (!xen_feature(XENFEAT_hvm_callback_vector)) {
+		aprint_error("Xen HVM: XENFEAT_hvm_callback_vector"
+		    "not available, cannot proceed");
 		return 0;
 	}
 
-	/* Re-use PV field */
-	xen_start_info.console.domU.mfn = xen_hvm_param.value;
+	/*
+	 * prepare vector.
+	 * We don't really care where it is, as long as it's free
+	 */
+	xen_hvm_vec = idt_vec_alloc(129, 255);
+	idt_vec_set(xen_hvm_vec, &IDTVEC(hypervisor_pvhvm_callback));
 
-	pmap_kenter_pa((vaddr_t) xencons_interface, ptoa(xen_start_info.console.domU.mfn),
-	    VM_PROT_READ|VM_PROT_WRITE, 0);
+	events_default_setup();
+	return 1;
+}
 
-	xen_hvm_param.domid = DOMID_SELF;
-	xen_hvm_param.index = HVM_PARAM_CONSOLE_EVTCHN;
+int
+xen_hvm_init(void)
+{
+	/*
+	 * We need to setup the HVM interfaces early, so that we can
+	 * properly setup the CPUs later (especially, all CPUs needs to
+	 * run x86_cpuid() locally to get their vcpuid.
+	 *
+	 * For PVH, part of it has already been done.
+	 */
+	if (vm_guest == VM_GUEST_XENPVH) {
+		if (xen_hvm_init_late() == 0) {
+			panic("hvm_init failed");
+		}
+		return 1;
+	}
 
-	if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
-		aprint_error(
-		    "Xen HVM: Unable to obtain xencons event channel\n");
+	if (vm_guest != VM_GUEST_XENHVM)
 		return 0;
-	}
 
-	xen_start_info.console.domU.evtchn = xen_hvm_param.value;
+	/* check if hypervisor was disabled with userconf */
+	if (!xen_check_hypervisordev())
+		return 0;
+
+	aprint_normal("Identified Guest XEN in HVM mode.\n");
+
+	xen_init_hypercall_page();
 
 	/* HYPERVISOR_shared_info */
 	struct xen_add_to_physmap xmap = {
@@ -345,33 +398,41 @@ xen_hvm_init(void)
 	pmap_kenter_pa((vaddr_t) HYPERVISOR_shared_info,
 	    HYPERVISOR_shared_info_pa, VM_PROT_READ|VM_PROT_WRITE, 0);
 
-	/*
-	 * First register callback: here's why
-	 * http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7b5b8ca7dffde866d851f0b87b994e0b13e5b867
-	 */
+	if (xen_hvm_init_late() == 0)
+		return 0;
 
-	/*
-	 * Check for XENFEAT_hvm_callback_vector. Can't proceed
-	 * without it.
-	 */
-	if (!xen_feature(XENFEAT_hvm_callback_vector)) {
-		aprint_error("Xen HVM: XENFEAT_hvm_callback_vector"
-		    "not available, cannot proceed");
+	struct xen_hvm_param xen_hvm_param;
+	xen_hvm_param.domid = DOMID_SELF;
+	xen_hvm_param.index = HVM_PARAM_CONSOLE_PFN;
+	
+	if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
+		aprint_error(
+		    "Xen HVM: Unable to obtain xencons page address\n");
 		return 0;
 	}
 
-	/*
-	 * prepare vector.
-	 * We don't really care where it is, as long as it's free
-	 */
-	xen_hvm_vec = idt_vec_alloc(129, 255);
-	idt_vec_set(xen_hvm_vec, &IDTVEC(hypervisor_pvhvm_callback));
+	/* Re-use PV field */
+	xen_start_info.console.domU.mfn = xen_hvm_param.value;
+
+	pmap_kenter_pa((vaddr_t) xencons_interface, ptoa(xen_start_info.console.domU.mfn),
+	    VM_PROT_READ|VM_PROT_WRITE, 0);
+
+	xen_hvm_param.domid = DOMID_SELF;
+	xen_hvm_param.index = HVM_PARAM_CONSOLE_EVTCHN;
+
+	if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
+		aprint_error(
+		    "Xen HVM: Unable to obtain xencons event channel\n");
+		return 0;
+	}
+
+	xen_start_info.console.domU.evtchn = xen_hvm_param.value;
 
-	events_default_setup();
 
 	delay_func = xen_delay;
 	x86_initclock_func = xen_initclocks;
 	x86_cpu_initclock_func = xen_cpu_initclocks;
+
 	vm_guest = VM_GUEST_XENPVHVM; /* Be more specific */
 	return 1;
 }
@@ -384,7 +445,7 @@ xen_hvm_init_cpu(struct cpu_info *ci)
 	int error;
 	static bool again = 0;
 
-	if (vm_guest != VM_GUEST_XENPVHVM)
+	if (!vm_guest_is_xenpvh_or_pvhvm())
 		return 0;
 
 	KASSERT(ci == curcpu());
@@ -464,7 +525,7 @@ hypervisor_match(device_t parent, cfdata
 
 
 #ifdef XENPVHVM
-	if (vm_guest != VM_GUEST_XENPVHVM)
+	if (!vm_guest_is_xenpvh_or_pvhvm())
 		return 0;
 #endif
 	/* If we got here, it must mean we matched */
@@ -499,11 +560,15 @@ hypervisor_attach(device_t parent, devic
 	const struct sysctlnode *node = NULL;
 
 #ifdef XENPVHVM
-	/* disable emulated devices */
-	if (inw(XEN_MAGIC_IOPORT) == XMI_MAGIC) {
-		outw(XEN_MAGIC_IOPORT, XMI_UNPLUG_IDE_DISKS | XMI_UNPLUG_NICS);
-	} else {
-		aprint_error_dev(self, "Unable to disable emulated devices\n");
+	if (vm_guest == VM_GUEST_XENPVHVM) {
+		/* disable emulated devices */
+		if (inw(XEN_MAGIC_IOPORT) == XMI_MAGIC) {
+			outw(XEN_MAGIC_IOPORT,
+			    XMI_UNPLUG_IDE_DISKS | XMI_UNPLUG_NICS);
+		} else {
+			aprint_error_dev(self,
+			    "Unable to disable emulated devices\n");
+		}
 	}
 #endif /* XENPVHVM */
 	xenkernfs_init();

Index: src/sys/arch/xen/xen/xen_clock.c
diff -u src/sys/arch/xen/xen/xen_clock.c:1.3 src/sys/arch/xen/xen/xen_clock.c:1.4
--- src/sys/arch/xen/xen/xen_clock.c:1.3	Sun Apr 26 20:41:30 2020
+++ src/sys/arch/xen/xen/xen_clock.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: xen_clock.c,v 1.3 2020/04/26 20:41:30 roy Exp $	*/
+/*	$NetBSD: xen_clock.c,v 1.4 2020/05/02 16:44:36 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2017, 2018 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xen_clock.c,v 1.3 2020/04/26 20:41:30 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_clock.c,v 1.4 2020/05/02 16:44:36 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -382,7 +382,6 @@ xen_vcputime_raw_systime_ns(void)
 	return raw_systime_ns;
 }
 
-#ifdef XENPV
 /*
  * struct xen_wallclock_ticket
  *
@@ -437,7 +436,6 @@ xen_wallclock_exit(struct xen_wallclock_
 
 	return tp->version == HYPERVISOR_shared_info->wc_version;
 }
-#endif
 
 /*
  * xen_global_systime_ns()
@@ -892,7 +890,6 @@ sysctl_xen_timepush(SYSCTLFN_ARGS)
 
 #endif	/* DOM0OPS */
 
-#ifdef XENPV
 static int	xen_rtc_get(struct todr_chip_handle *, struct timeval *);
 static int	xen_rtc_set(struct todr_chip_handle *, struct timeval *);
 static void	xen_wallclock_time(struct timespec *);
@@ -907,31 +904,18 @@ static struct todr_chip_handle xen_todr_
 };
 
 /*
- * startrtclock()
+ * xen_startrtclock()
  *
  *	Initialize the real-time clock from x86 machdep autoconf.
  */
 void
-startrtclock(void)
+xen_startrtclock(void)
 {
 
 	todr_attach(&xen_todr_chip);
 }
 
 /*
- * setstatclockrate(rate)
- *
- *	Set the statclock to run at rate, in units of ticks per second.
- *
- *	Currently Xen does not have a separate statclock, so this is a
- *	noop; instad the statclock runs in hardclock.
- */
-void
-setstatclockrate(int rate)
-{
-}
-
-/*
  * xen_rtc_get(todr, tv)
  *
  *	Get the current real-time clock from the Xen wall clock time
@@ -1012,4 +996,17 @@ xen_wallclock_time(struct timespec *tsp)
 	tsp->tv_nsec = systime_ns % 1000000000ull;
 }
 
+#ifdef XENPV
+/*
+ * setstatclockrate(rate)
+ *
+ *	Set the statclock to run at rate, in units of ticks per second.
+ *
+ *	Currently Xen does not have a separate statclock, so this is a
+ *	noop; instad the statclock runs in hardclock.
+ */
+void
+setstatclockrate(int rate)
+{
+}
 #endif /* XENPV */

Index: src/sys/arch/xen/xen/xen_machdep.c
diff -u src/sys/arch/xen/xen/xen_machdep.c:1.23 src/sys/arch/xen/xen/xen_machdep.c:1.24
--- src/sys/arch/xen/xen/xen_machdep.c:1.23	Sat Apr 25 15:26:18 2020
+++ src/sys/arch/xen/xen/xen_machdep.c	Sat May  2 16:44:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: xen_machdep.c,v 1.23 2020/04/25 15:26:18 bouyer Exp $	*/
+/*	$NetBSD: xen_machdep.c,v 1.24 2020/05/02 16:44:36 bouyer Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -53,13 +53,16 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xen_machdep.c,v 1.23 2020/04/25 15:26:18 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_machdep.c,v 1.24 2020/05/02 16:44:36 bouyer Exp $");
 
 #include "opt_xen.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/boot_flag.h>
+#include <sys/conf.h>
+#include <sys/disk.h>
+#include <sys/device.h>
 #include <sys/mount.h>
 #include <sys/reboot.h>
 #include <sys/timetc.h>
@@ -77,17 +80,16 @@ __KERNEL_RCSID(0, "$NetBSD: xen_machdep.
 #define DPRINTK(x)
 #endif
 
-u_int	tsc_get_timecount(struct timecounter *);
+#ifdef DEBUG_GEOM
+#define DPRINTF(a) printf a
+#else
+#define DPRINTF(a)
+#endif
 
-bool xen_suspend_allow;
 
-#ifdef XENPV
-extern uint64_t tsc_freq;	/* XXX */
+u_int	tsc_get_timecount(struct timecounter *);
 
-static int sysctl_xen_suspend(SYSCTLFN_ARGS);
-static void xen_suspend_domain(void);
-static void xen_prepare_suspend(void);
-static void xen_prepare_resume(void);
+bool xen_suspend_allow;
 
 void
 xen_parse_cmdline(int what, union xen_cmdline_parseinfo *xcp)
@@ -217,6 +219,14 @@ xen_parse_cmdline(int what, union xen_cm
 	}
 }
 
+#ifdef XENPV
+extern uint64_t tsc_freq;	/* XXX */
+
+static int sysctl_xen_suspend(SYSCTLFN_ARGS);
+static void xen_suspend_domain(void);
+static void xen_prepare_suspend(void);
+static void xen_prepare_resume(void);
+
 u_int
 tsc_get_timecount(struct timecounter *tc)
 {
@@ -455,3 +465,87 @@ xen_init_features(void)
 		}
 	}
 }
+
+/*
+ * Attempt to find the device from which we were booted.
+ */
+
+static int
+is_valid_disk(device_t dv)
+{
+	if (device_class(dv) != DV_DISK)
+		return (0);
+
+	return (device_is_a(dv, "dk") ||
+		device_is_a(dv, "sd") ||
+		device_is_a(dv, "wd") ||
+		device_is_a(dv, "ld") ||
+		device_is_a(dv, "ed") ||
+		device_is_a(dv, "xbd"));
+}
+
+void
+xen_bootconf(void)
+{
+	device_t dv;
+	deviter_t di;
+	union xen_cmdline_parseinfo xcp;
+	static char bootspecbuf[sizeof(xcp.xcp_bootdev)];
+
+	if (booted_device) {
+		DPRINTF(("%s: preset booted_device: %s\n", __func__, device_xname(booted_device)));
+		return;
+	}
+
+	xen_parse_cmdline(XEN_PARSE_BOOTDEV, &xcp);
+
+	for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
+	     dv != NULL;
+	     dv = deviter_next(&di)) {
+		bool is_ifnet, is_disk;
+		const char *devname;
+
+		is_ifnet = (device_class(dv) == DV_IFNET);
+		is_disk = is_valid_disk(dv);
+		devname = device_xname(dv);
+
+		if (!is_ifnet && !is_disk)
+			continue;
+
+		if (is_disk && xcp.xcp_bootdev[0] == 0) {
+			booted_device = dv;
+			break;
+		}
+
+		if (strncmp(xcp.xcp_bootdev, devname, strlen(devname)))
+			continue;
+
+		if (is_disk && strlen(xcp.xcp_bootdev) > strlen(devname)) {
+			/* XXX check device_cfdata as in x86_autoconf.c? */
+			booted_partition = toupper(
+				xcp.xcp_bootdev[strlen(devname)]) - 'A';
+			DPRINTF(("%s: booted_partition: %d\n", __func__, booted_partition));
+		}
+
+		booted_device = dv;
+		booted_method = "bootinfo/bootdev";
+		break;
+	}
+	deviter_release(&di);
+
+	if (booted_device) {
+		DPRINTF(("%s: booted_device: %s\n", __func__, device_xname(booted_device)));
+		return;
+	}
+
+	/*
+	 * not a boot device name, pass through to MI code
+	 */
+	if (xcp.xcp_bootdev[0] != '\0') {
+		strlcpy(bootspecbuf, xcp.xcp_bootdev, sizeof(bootspecbuf));
+		bootspec = bootspecbuf;
+		booted_method = "bootinfo/bootspec";
+		DPRINTF(("%s: bootspec: %s\n", __func__, bootspec));
+		return;
+	}
+}

Added files:

Index: src/sys/arch/xen/x86/pvh_consinit.c
diff -u /dev/null src/sys/arch/xen/x86/pvh_consinit.c:1.1
--- /dev/null	Sat May  2 16:44:37 2020
+++ src/sys/arch/xen/x86/pvh_consinit.c	Sat May  2 16:44:36 2020
@@ -0,0 +1,115 @@
+/* $NetBSD: pvh_consinit.c,v 1.1 2020/05/02 16:44:36 bouyer Exp $ */
+
+/*
+ * Copyright (c) 2020 Manuel Bouyer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: pvh_consinit.c,v 1.1 2020/05/02 16:44:36 bouyer Exp $");
+
+#include "xencons.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <uvm/uvm_extern.h>
+#include <uvm/uvm_prot.h>
+
+#include <dev/cons.h>
+#include <xen/xen.h>
+#include <xen/hypervisor.h>
+#include <xen/include/public/hvm/hvm_op.h>
+#include <xen/include/public/hvm/params.h>
+
+static int pvh_xenconscn_getc(dev_t);
+static void pvh_xenconscn_putc(dev_t, int);
+static void pvh_xenconscn_pollc(dev_t, int);
+
+static struct consdev pvh_xencons = {
+        NULL, NULL, pvh_xenconscn_getc, pvh_xenconscn_putc, pvh_xenconscn_pollc,
+	NULL, NULL, NULL, NODEV, CN_NORMAL
+};
+
+
+void
+xen_pvh_consinit(void)
+{
+	/*
+	 * hugly hack because we're called multiple times at different
+	 * boot stage.
+	 */
+	static int initted = 0;
+	if (initted == 0) {
+		/* pmap not up yet, fall back to printk() */
+		cn_tab = &pvh_xencons;
+		initted++;
+		return;
+	} else if (initted > 1) {
+		return;
+	}
+	initted++;
+#if NXENCONS > 0
+	/* we can now map the xencons rings. */
+	struct xen_hvm_param xen_hvm_param;
+
+
+	xen_hvm_param.domid = DOMID_SELF;
+	xen_hvm_param.index = HVM_PARAM_CONSOLE_PFN;
+
+	if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) 
+		panic("xen_pvh_consinit: can't get console PFN");
+
+	xen_start_info.console.domU.mfn = xen_hvm_param.value;
+	pmap_kenter_pa((vaddr_t) xencons_interface, ptoa(xen_hvm_param.value),
+	    VM_PROT_READ|VM_PROT_WRITE, 0);
+
+	xen_hvm_param.domid = DOMID_SELF;
+	xen_hvm_param.index = HVM_PARAM_CONSOLE_EVTCHN;
+
+	if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0)
+		panic("xen_pvh_consinit: can't get console event");
+
+	xen_start_info.console.domU.evtchn = xen_hvm_param.value;
+	xenconscn_attach();
+#endif
+}
+
+static int
+pvh_xenconscn_getc(dev_t dev)
+{
+	while(1)
+		;
+	return -1;
+}
+
+static void
+pvh_xenconscn_putc(dev_t dev, int c)
+{
+	printk("%c", c);
+}
+
+static void
+pvh_xenconscn_pollc(dev_t dev, int on)
+{
+	return;
+}

Reply via email to