Date: Wed, 15 Oct 2008 05:44:08 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r183906 - in projects/releng_6_xen/sys/i386: conf i386 include include/xen xen Message-ID: <200810150544.m9F5i8D2025472@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kmacy Date: Wed Oct 15 05:44:08 2008 New Revision: 183906 URL: http://svn.freebsd.org/changeset/base/183906 Log: Add i386 specific xen support Added: projects/releng_6_xen/sys/i386/conf/XEN projects/releng_6_xen/sys/i386/include/xen/ projects/releng_6_xen/sys/i386/include/xen/evtchn.h (contents, props changed) projects/releng_6_xen/sys/i386/include/xen/features.h (contents, props changed) projects/releng_6_xen/sys/i386/include/xen/hypercall.h (contents, props changed) projects/releng_6_xen/sys/i386/include/xen/hypervisor.h (contents, props changed) projects/releng_6_xen/sys/i386/include/xen/synch_bitops.h (contents, props changed) projects/releng_6_xen/sys/i386/include/xen/xen-os.h (contents, props changed) projects/releng_6_xen/sys/i386/include/xen/xen_intr.h (contents, props changed) projects/releng_6_xen/sys/i386/include/xen/xenbus.h (contents, props changed) projects/releng_6_xen/sys/i386/include/xen/xenfunc.h (contents, props changed) projects/releng_6_xen/sys/i386/include/xen/xenpmap.h (contents, props changed) projects/releng_6_xen/sys/i386/include/xen/xenstored.h (contents, props changed) projects/releng_6_xen/sys/i386/include/xen/xenvar.h (contents, props changed) projects/releng_6_xen/sys/i386/xen/ projects/releng_6_xen/sys/i386/xen/clock.c (contents, props changed) projects/releng_6_xen/sys/i386/xen/exception.s (contents, props changed) projects/releng_6_xen/sys/i386/xen/locore.s (contents, props changed) projects/releng_6_xen/sys/i386/xen/machdep.c (contents, props changed) projects/releng_6_xen/sys/i386/xen/pmap.c (contents, props changed) projects/releng_6_xen/sys/i386/xen/xen_bus.c (contents, props changed) projects/releng_6_xen/sys/i386/xen/xen_machdep.c (contents, props changed) Modified: projects/releng_6_xen/sys/i386/conf/DEFAULTS projects/releng_6_xen/sys/i386/i386/genassym.c projects/releng_6_xen/sys/i386/i386/machdep.c projects/releng_6_xen/sys/i386/include/asmacros.h projects/releng_6_xen/sys/i386/include/pcpu.h projects/releng_6_xen/sys/i386/include/pmap.h projects/releng_6_xen/sys/i386/include/segments.h Modified: projects/releng_6_xen/sys/i386/conf/DEFAULTS ============================================================================== --- projects/releng_6_xen/sys/i386/conf/DEFAULTS Wed Oct 15 05:43:13 2008 (r183905) +++ projects/releng_6_xen/sys/i386/conf/DEFAULTS Wed Oct 15 05:44:08 2008 (r183906) @@ -15,3 +15,5 @@ device npx # Pseudo devices. device mem # Memory and kernel memory devices device io # I/O device + +options NATIVE Added: projects/releng_6_xen/sys/i386/conf/XEN ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/releng_6_xen/sys/i386/conf/XEN Wed Oct 15 05:44:08 2008 (r183906) @@ -0,0 +1,153 @@ +# +# GENERIC -- Generic kernel configuration file for FreeBSD/i386 +# +# For more information on this file, please read the handbook section on +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD$ + +machine i386 +cpu I686_CPU +ident XEN + +# To statically compile in device wiring instead of /boot/device.hints +#hints "GENERIC.hints" # Default places to look for devices. + +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +makeoptions MODULES_OVERRIDE="" + +#options SCHED_ULE # ULE scheduler +#options PREEMPTION # Enable kernel thread preemption +options SCHED_4BSD +options INET # InterNETworking +options INET6 # IPv6 communications protocols +options FFS # Berkeley Fast Filesystem +options SOFTUPDATES # Enable FFS soft updates support +options UFS_ACL # Support for access control lists +options UFS_DIRHASH # Improve performance on big directories +options MD_ROOT # MD is a potential root device +options NFSCLIENT # Network Filesystem Client +options NFSSERVER # Network Filesystem Server +options NFS_ROOT # NFS usable as /, requires NFSCLIENT +options MSDOSFS # MSDOS Filesystem +options CD9660 # ISO 9660 Filesystem +options PROCFS # Process filesystem (requires PSEUDOFS) +options PSEUDOFS # Pseudo-filesystem framework +options GEOM_LABEL # Provides labelization +options COMPAT_FREEBSD4 # Compatible with FreeBSD4 +options COMPAT_FREEBSD5 # Compatible with FreeBSD5 +options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI +options KTRACE # ktrace(1) support +options SYSVSHM # SYSV-style shared memory +options SYSVMSG # SYSV-style message queues +options SYSVSEM # SYSV-style semaphores +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options AUDIT # Security event auditing + +# Debugging for use in -current +options KDB # Enable kernel debugger support. +options DDB # Support DDB. +options GDB # Support remote GDB. +options INVARIANTS # Enable calls of extra sanity checking +options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS # Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed + +# To make an SMP kernel, the next two lines are needed +#options SMP # Symmetric MultiProcessor Kernel +#device apic # I/O APIC +options PAE + + +# CPU frequency control +#device cpufreq # native only + +# Bus support. +#device pci + +# SCSI peripherals +device scbus # SCSI bus (required for SCSI) +device ch # SCSI media changers +device da # Direct Access (disks) +device sa # Sequential Access (tape etc) +device cd # CD +device pass # Passthrough device (direct SCSI access) +device ses # SCSI Environmental Services (and SAF-TE) + +# atkbdc0 controls both the keyboard and the PS/2 mouse +device atkbdc # AT keyboard controller +device atkbd # AT keyboard +device psm # PS/2 mouse +device kbdmux # keyboard multiplexer +#device vga # VGA video card driver +device splash # Splash screen and screen saver support + +# syscons is the default console driver, resembling an SCO console + +#device agp # support several AGP chipsets + +# Power management support (see NOTES for more options) +#device apm +# Add suspend/resume support for the i8254. +#device pmtimer # native + +# Serial (COM) ports +device uart # Generic UART driver + +# If you've got a "dumb" serial or parallel PCI card that is +# supported by the puc(4) glue driver, uncomment the following +# line to enable it (connects to sio, uart and/or ppc drivers): +#device puc + +# PCI Ethernet NICs. +device em # Intel PRO/1000 adapter Gigabit Ethernet Card + +# PCI Ethernet NICs that use the common MII bus controller code. +# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs! +device miibus # MII bus support + +# Pseudo devices. +device loop # Network loopback +device random # Entropy device +device ether # Ethernet support +device sl # Kernel SLIP +device ppp # Kernel PPP +device tun # Packet tunnel. +device pty # Pseudo-ttys (telnet etc) +device md # Memory "disks" +device gif # IPv6 and IPv4 tunneling +device faith # IPv6-to-IPv4 relaying (translation) +device firmware # firmware assist module + +# The `bpf' device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +# Note that 'bpf' is required for DHCP. +device bpf # Berkeley packet filter + + +options XEN +nooption NATIVE +nodevice atpic +options MCLSHIFT=12 + +nodevice isa +nooption ISAPNP + +options KTR +options KTR_COMPILE=(KTR_PMAP) +options KTR_CPUMASK=0xff +options KTR_ENTRIES=65536 +options KTR_MASK=(KTR_PMAP) Modified: projects/releng_6_xen/sys/i386/i386/genassym.c ============================================================================== --- projects/releng_6_xen/sys/i386/i386/genassym.c Wed Oct 15 05:43:13 2008 (r183905) +++ projects/releng_6_xen/sys/i386/i386/genassym.c Wed Oct 15 05:44:08 2008 (r183906) @@ -227,3 +227,9 @@ ASSYM(MTX_RECURSECNT, offsetof(struct mt ASSYM(BUS_SPACE_HANDLE_BASE, offsetof(struct bus_space_handle, bsh_base)); ASSYM(BUS_SPACE_HANDLE_IAT, offsetof(struct bus_space_handle, bsh_iat)); #endif + +#ifdef XEN +#include <machine/xen/hypervisor.h> +ASSYM(PC_CR3, offsetof(struct pcpu, pc_cr3)); +ASSYM(HYPERVISOR_VIRT_START, __HYPERVISOR_VIRT_START); +#endif Modified: projects/releng_6_xen/sys/i386/i386/machdep.c ============================================================================== --- projects/releng_6_xen/sys/i386/i386/machdep.c Wed Oct 15 05:43:13 2008 (r183905) +++ projects/releng_6_xen/sys/i386/i386/machdep.c Wed Oct 15 05:44:08 2008 (r183906) @@ -141,6 +141,25 @@ int arch_i386_is_xbox = 0; uint32_t arch_i386_xbox_memsize = 0; #endif +#ifdef XEN +/* XEN includes */ +#include <machine/xen/hypervisor.h> +#include <machine/xen/xen-os.h> +#include <machine/xen/xenvar.h> +#include <machine/xen/xenfunc.h> +#include <machine/xen/xen_intr.h> + +void Xhypervisor_callback(void); +void failsafe_callback(void); + +int gdt_set; +extern trap_info_t trap_table[]; +struct proc_ldt default_proc_ldt; +extern int init_first; +int running_xen = 1; +extern unsigned long physfree; +#endif /* XEN */ + /* Sanity check for __curthread() */ CTASSERT(offsetof(struct pcpu, pc_curthread) == 0); @@ -282,8 +301,9 @@ cpu_startup(dummy) */ bufinit(); vm_pager_bufferinit(); - +#ifndef XEN cpu_setregs(); +#endif } /* @@ -1108,6 +1128,25 @@ cpu_est_clockrate(int cpu_id, uint64_t * return (0); } +static int cpu_idle_hlt = 1; +SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW, + &cpu_idle_hlt, 0, "Idle loop HLT enable"); +#ifdef XEN + +void +cpu_halt(void) +{ + HYPERVISOR_shutdown(SHUTDOWN_poweroff); +} + +static void +cpu_idle_default(void) +{ + idle_block(); +} + +#else + /* * Shutdown the CPU as much as possible */ @@ -1133,9 +1172,6 @@ cpu_halt(void) * XXX I'm turning it on for SMP as well by default for now. It seems to * help lock contention somewhat, and this is critical for HTT. -Peter */ -static int cpu_idle_hlt = 1; -SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW, - &cpu_idle_hlt, 0, "Idle loop HLT enable"); static void cpu_idle_default(void) @@ -1147,6 +1183,7 @@ cpu_idle_default(void) */ __asm __volatile("sti; hlt"); } +#endif /* !XEN */ /* * Note that we have to be careful here to avoid a race between checking @@ -1317,10 +1354,16 @@ SYSCTL_ULONG(_machdep, OID_AUTO, guessed */ int _default_ldt; + +#ifdef XEN +union descriptor *gdt; +union descriptor *ldt; +#else union descriptor gdt[NGDT * MAXCPU]; /* global descriptor table */ +union descriptor ldt[NLDT]; /* local descriptor table */ +#endif static struct gate_descriptor idt0[NIDT]; struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */ -union descriptor ldt[NLDT]; /* local descriptor table */ struct region_descriptor r_gdt, r_idt; /* table descriptors */ int private_tss; /* flag indicating private tss */ @@ -1355,7 +1398,7 @@ struct soft_segment_descriptor gdt_segs[ { 0x0, /* segment base address */ 0xfffff, /* length - all address space */ SDT_MEMRWA, /* segment type */ - 0, /* segment descriptor priority level */ + SEL_KPL, /* segment descriptor priority level */ 1, /* segment descriptor present */ 0, 0, 1, /* default 32 vs 16 bit size */ @@ -1382,7 +1425,7 @@ struct soft_segment_descriptor gdt_segs[ { 0x0, /* segment base address */ 0xfffff, /* length - all address space */ SDT_MEMERA, /* segment type */ - 0, /* segment descriptor priority level */ + SEL_KPL, /* segment descriptor priority level */ 1, /* segment descriptor present */ 0, 0, 1, /* default 32 vs 16 bit size */ @@ -1391,7 +1434,7 @@ struct soft_segment_descriptor gdt_segs[ { 0x0, /* segment base address */ 0xfffff, /* length - all address space */ SDT_MEMRWA, /* segment type */ - 0, /* segment descriptor priority level */ + SEL_KPL, /* segment descriptor priority level */ 1, /* segment descriptor present */ 0, 0, 1, /* default 32 vs 16 bit size */ @@ -1418,11 +1461,12 @@ struct soft_segment_descriptor gdt_segs[ { 0x400, /* segment base address */ 0xfffff, /* length */ SDT_MEMRWA, /* segment type */ - 0, /* segment descriptor priority level */ + SEL_KPL, /* segment descriptor priority level */ 1, /* segment descriptor present */ 0, 0, 1, /* default 32 vs 16 bit size */ 1 /* limit granularity (byte/page units)*/ }, +#ifndef XEN /* GPROC0_SEL 9 Proc 0 Tss Descriptor */ { 0x0, /* segment base address */ @@ -1514,6 +1558,7 @@ struct soft_segment_descriptor gdt_segs[ 0, 0, 0, /* default 32 vs 16 bit size */ 0 /* limit granularity (byte/page units)*/ }, +#endif /* !XEN */ }; static struct soft_segment_descriptor ldt_segs[] = { @@ -1735,7 +1780,17 @@ getmemsize(int first) goto physmap_done; } #endif - +#ifdef XEN + has_smap = 0; + Maxmem = xen_start_info->nr_pages - init_first; + physmem = Maxmem; + basemem = 0; + physmap[0] = init_first << PAGE_SHIFT; + physmap[1] = ptoa(Maxmem) - round_page(MSGBUF_SIZE); + physmap_idx = 0; + goto physmap_done; +#endif + hasbrokenint12 = 0; TUNABLE_INT_FETCH("hw.hasbrokenint12", &hasbrokenint12); bzero(&vmf, sizeof(vmf)); @@ -1898,7 +1953,7 @@ int15e820: vmf.vmf_ah = 0x88; vm86_intcall(0x15, &vmf); extmem = vmf.vmf_ax; -#else +#elif !defined(XEN) /* * Prefer the RTC value for extended memory. */ @@ -1988,7 +2043,7 @@ physmap_done: if (getenv_quad("dcons.addr", &dcons_addr) == 0 || getenv_quad("dcons.size", &dcons_size) == 0) dcons_addr = 0; - +#ifndef XEN /* * physmap is in bytes, so when converting to page boundaries, * round up the start address and round down the end address. @@ -2106,7 +2161,10 @@ do_next: } *pte = 0; invltlb(); - +#else + phys_avail[0] = physfree; + phys_avail[1] = xen_start_info->nr_pages*PAGE_SIZE; +#endif /* * XXX * The last chunk must contain at least one page plus the message @@ -2128,6 +2186,257 @@ do_next: avail_end = phys_avail[pa_indx]; } +#ifdef XEN + +#define MTOPSIZE (1<<(14 + PAGE_SHIFT)) +void +init386(int first) +{ + int error, gsel_tss, metadata_missing, x; + unsigned long off, gdtmachpfn; + struct pcpu *pc; + struct callback_register event = { + .type = CALLBACKTYPE_event, + .address = {GSEL(GCODE_SEL, SEL_KPL), (unsigned long)Xhypervisor_callback }, + }; + struct callback_register failsafe = { + .type = CALLBACKTYPE_failsafe, + .address = {GSEL(GCODE_SEL, SEL_KPL), (unsigned long)failsafe_callback }, + }; + + thread0.td_kstack = proc0kstack; + thread0.td_pcb = (struct pcb *) + (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; + + /* + * This may be done better later if it gets more high level + * components in it. If so just link td->td_proc here. + */ + proc_linkup(&proc0, &ksegrp0, &thread0); + + metadata_missing = 0; + if (xen_start_info->mod_start) { + preload_metadata = (caddr_t)xen_start_info->mod_start; + preload_bootstrap_relocate(KERNBASE); + } else { + metadata_missing = 1; + } + if (envmode == 1) + kern_envp = static_env; + else if ((caddr_t)xen_start_info->cmd_line) + kern_envp = xen_setbootenv((caddr_t)xen_start_info->cmd_line); + + boothowto |= xen_boothowto(kern_envp); + + /* Init basic tunables, hz etc */ + init_param1(); + + /* + * XEN occupies a portion of the upper virtual address space + * At its base it manages an array mapping machine page frames + * to physical page frames - hence we need to be able to + * access 4GB - (64MB - 4MB + 64k) + */ + gdt_segs[GPRIV_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); + gdt_segs[GUFS_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); + gdt_segs[GUGS_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); + gdt_segs[GCODE_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); + gdt_segs[GDATA_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); + gdt_segs[GUCODE_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); + gdt_segs[GUDATA_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); + gdt_segs[GBIOSLOWMEM_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); + + pc = &__pcpu[0]; + gdt_segs[GPRIV_SEL].ssd_base = (int) pc; + gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss; + + PT_SET_MA(gdt, xpmap_ptom(VTOP(gdt)) | PG_V | PG_RW); + bzero(gdt, PAGE_SIZE); + for (x = 0; x < NGDT; x++) + ssdtosd(&gdt_segs[x], &gdt[x].sd); + + + printk("gdt=%p\n", gdt); + printk("PTmap=%p\n", PTmap); + printk("addr=%p\n", *vtopte((unsigned long)gdt) & ~PG_RW); + + gdtmachpfn = vtomach(gdt) >> PAGE_SHIFT; + PT_SET_MA(gdt, *vtopte((unsigned long)gdt) & ~(PG_RW|PG_M|PG_A)); + PANIC_IF(HYPERVISOR_set_gdt(&gdtmachpfn, 512) != 0); + lgdt(&r_gdt /* unused */); + gdt_set = 1; + + if ((error = HYPERVISOR_set_trap_table(trap_table)) != 0) { + panic("set_trap_table failed - error %d\n", error); + } + + error = HYPERVISOR_callback_op(CALLBACKOP_register, &event); + if (error == 0) + error = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe); +#if CONFIG_XEN_COMPAT <= 0x030002 + if (error == -ENOXENSYS) + HYPERVISOR_set_callbacks(GSEL(GCODE_SEL, SEL_KPL), + (unsigned long)Xhypervisor_callback, + GSEL(GCODE_SEL, SEL_KPL), (unsigned long)failsafe_callback); +#endif + pcpu_init(pc, 0, sizeof(struct pcpu)); + PCPU_SET(prvspace, pc); + PCPU_SET(curthread, &thread0); + PCPU_SET(curpcb, thread0.td_pcb); + PCPU_SET(pdir, (unsigned long)IdlePTD); + + /* + * Initialize mutexes. + * + * icu_lock: in order to allow an interrupt to occur in a critical + * section, to set pcpu->ipending (etc...) properly, we + * must be able to get the icu lock, so it can't be + * under witness. + */ + mutex_init(); + mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS); + + /* make ldt memory segments */ + PT_SET_MA(ldt, xpmap_ptom(VTOP(ldt)) | PG_V | PG_RW); + bzero(ldt, PAGE_SIZE); + ldt_segs[LUCODE_SEL].ssd_limit = atop(0 - 1); + ldt_segs[LUDATA_SEL].ssd_limit = atop(0 - 1); + for (x = 0; x < sizeof ldt_segs / sizeof ldt_segs[0]; x++) + ssdtosd(&ldt_segs[x], &ldt[x].sd); + + default_proc_ldt.ldt_base = (caddr_t)ldt; + default_proc_ldt.ldt_len = 6; + _default_ldt = (int)&default_proc_ldt; + PCPU_SET(currentldt, _default_ldt) + PT_SET_MA(ldt, *vtopte((unsigned long)ldt) & ~PG_RW); + xen_set_ldt((unsigned long) ldt, (sizeof ldt_segs / sizeof ldt_segs[0])); + +#ifdef XBOX + /* + * The following code queries the PCI ID of 0:0:0. For the XBOX, + * This should be 0x10de / 0x02a5. + * + * This is exactly what Linux does. + */ + outl(0xcf8, 0x80000000); + if (inl(0xcfc) == 0x02a510de) { + arch_i386_is_xbox = 1; + pic16l_setled(XBOX_LED_GREEN); + + /* + * We are an XBOX, but we may have either 64MB or 128MB of + * memory. The PCI host bridge should be programmed for this, + * so we just query it. + */ + outl(0xcf8, 0x80000084); + arch_i386_xbox_memsize = (inl(0xcfc) == 0x7FFFFFF) ? 128 : 64; + } +#endif /* XBOX */ +#if defined (XEN_PRIVILEGED) + /* + * Initialize the i8254 before the console so that console + * initialization can use DELAY(). + */ + i8254_init(); +#endif + /* + * Initialize the console before we print anything out. + */ + cninit(); + + if (metadata_missing) + printf("WARNING: loader(8) metadata is missing!\n"); + +#ifdef DEV_ISA + if (xen_start_info->flags & SIF_PRIVILEGED) { + elcr_probe(); +#ifdef DEV_ATPIC + atpic_startup(); +#endif + } +#endif + +#ifdef DDB + ksym_start = bootinfo.bi_symtab; + ksym_end = bootinfo.bi_esymtab; +#endif + + kdb_init(); + +#ifdef KDB + if (boothowto & RB_KDB) + kdb_enter("Boot flags requested debugger"); +#endif + + finishidentcpu(); /* Final stage of CPU initialization */ + setidt(IDT_UD, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); + setidt(IDT_GP, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); + initializecpu(); /* Initialize CPU registers */ + + /* make an initial tss so cpu can get interrupt stack on syscall! */ + /* Note: -16 is so we can grow the trapframe if we came from vm86 */ + PCPU_SET(common_tss.tss_esp0, thread0.td_kstack + + KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16); + PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL)); + gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + HYPERVISOR_stack_switch(GSEL(GDATA_SEL, SEL_KPL), + PCPU_GET(common_tss.tss_esp0)); + + + /* pointer to selector slot for %fs/%gs */ + PCPU_SET(fsgs_gdt, &gdt[GUFS_SEL].sd); + + dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = + dblfault_tss.tss_esp2 = (int)&dblfault_stack[sizeof(dblfault_stack)]; + dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = + dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); +#ifdef PAE + dblfault_tss.tss_cr3 = (int)IdlePDPT; +#else + dblfault_tss.tss_cr3 = (int)IdlePTD; +#endif + dblfault_tss.tss_eip = (int)dblfault_handler; + dblfault_tss.tss_eflags = PSL_KERNEL; + dblfault_tss.tss_ds = dblfault_tss.tss_es = + dblfault_tss.tss_gs = GSEL(GDATA_SEL, SEL_KPL); + dblfault_tss.tss_fs = GSEL(GPRIV_SEL, SEL_KPL); + dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL); + dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL); + + vm86_initialize(); + getmemsize(first); + init_param2(physmem); + + + /* Map the message buffer. */ + for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE) + pmap_kenter((vm_offset_t)msgbufp + off, avail_end + off); + + /* now running on new page tables, configured,and u/iom is accessible */ + + msgbufinit(msgbufp, MSGBUF_SIZE); + + /* transfer to user mode */ + + _ucodesel = GSEL(GUCODE_SEL, SEL_UPL); + _udatasel = GSEL(GUDATA_SEL, SEL_UPL); + + /* setup proc 0's pcb */ + thread0.td_pcb->pcb_flags = 0; +#ifdef PAE + thread0.td_pcb->pcb_cr3 = (int)IdlePDPT; +#else + thread0.td_pcb->pcb_cr3 = (int)IdlePTD; +#endif + thread0.td_pcb->pcb_ext = 0; + thread0.td_frame = &proc0_tf; + thread0.td_pcb->pcb_fsd = PCPU_GET(fsgs_gdt)[0]; + thread0.td_pcb->pcb_gsd = PCPU_GET(fsgs_gdt)[1]; +} + +#else void init386(first) int first; @@ -2389,6 +2698,7 @@ init386(first) thread0.td_pcb->pcb_ext = 0; thread0.td_frame = &proc0_tf; } +#endif /* !XEN */ void cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) Modified: projects/releng_6_xen/sys/i386/include/asmacros.h ============================================================================== --- projects/releng_6_xen/sys/i386/include/asmacros.h Wed Oct 15 05:43:13 2008 (r183905) +++ projects/releng_6_xen/sys/i386/include/asmacros.h Wed Oct 15 05:44:08 2008 (r183906) @@ -134,6 +134,46 @@ #define MEXITCOUNT #endif /* GPROF */ +/* + * Setup the kernel segment registers. + */ +#define SET_KERNEL_SREGS \ + movl $KDSEL, %eax ; /* reload with kernel's data segment */ \ + movl %eax, %ds ; \ + movl %eax, %es ; \ + movl $KPSEL, %eax ; /* reload with per-CPU data segment */ \ + movl %eax, %fs + +#ifdef XEN +#define LOAD_CR3(reg) \ + movl reg,PCPU(CR3); \ + pushl %ecx ; \ + pushl %edx ; \ + pushl %esi ; \ + pushl reg ; \ + call xen_load_cr3 ; \ + addl $4,%esp ; \ + popl %esi ; \ + popl %edx ; \ + popl %ecx ; \ + +#define READ_CR3(reg) movl PCPU(CR3),reg; +#define LLDT(arg) \ + pushl %edx ; \ + pushl %eax ; \ + xorl %eax,%eax ; \ + movl %eax,%gs ; \ + call i386_reset_ldt ; \ + popl %eax ; \ + popl %edx +#define CLI call ni_cli +#else +#define LOAD_CR3(reg) movl reg,%cr3; +#define READ_CR3(reg) movl %cr3,reg; +#define LLDT(arg) lldt arg; +#define CLI cli +#endif /* !XEN */ + #ifdef LOCORE /* * Convenience macros for declaring interrupt entry points and trap @@ -145,4 +185,30 @@ #endif /* LOCORE */ +#ifdef __STDC__ +#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 +#else /* !__STDC__, i.e. -traditional */ +#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 +#endif /* __STDC__ */ + #endif /* !_MACHINE_ASMACROS_H_ */ Modified: projects/releng_6_xen/sys/i386/include/pcpu.h ============================================================================== --- projects/releng_6_xen/sys/i386/include/pcpu.h Wed Oct 15 05:43:13 2008 (r183905) +++ projects/releng_6_xen/sys/i386/include/pcpu.h Wed Oct 15 05:44:08 2008 (r183906) @@ -45,6 +45,28 @@ * to each CPU's data can be set up for things like "check curproc on all * other processors" */ + +#ifdef XEN +#define PCPU_MD_FIELDS \ + struct pcpu *pc_prvspace; /* Self-reference */ \ + struct pmap *pc_curpmap; \ + struct i386tss pc_common_tss; \ + struct segment_descriptor pc_common_tssd; \ + struct segment_descriptor *pc_tss_gdt; \ + struct segment_descriptor *pc_fsgs_gdt; \ + vm_paddr_t *pc_pdir_shadow; \ + int pc_currentldt; \ + u_int pc_acpi_id; /* ACPI CPU id */ \ + u_int pc_apic_id; \ + int pc_private_tss; /* Flag indicating private tss*/\ + u_int pc_cr3; /* track cr3 for R1/R3*/ \ + u_int pc_pdir; \ + u_int pc_lazypmap; \ + u_int pc_rendezvous; \ + u_int pc_cpuast + + +#else #define PCPU_MD_FIELDS \ struct pcpu *pc_prvspace; /* Self-reference */ \ struct pmap *pc_curpmap; \ @@ -55,7 +77,7 @@ int pc_currentldt; \ u_int pc_acpi_id; \ u_int pc_apic_id - +#endif #if defined(lint) extern struct pcpu *pcpup; Modified: projects/releng_6_xen/sys/i386/include/pmap.h ============================================================================== --- projects/releng_6_xen/sys/i386/include/pmap.h Wed Oct 15 05:43:13 2008 (r183905) +++ projects/releng_6_xen/sys/i386/include/pmap.h Wed Oct 15 05:44:08 2008 (r183906) @@ -68,7 +68,14 @@ /* Our various interpretations of the above */ #define PG_W PG_AVAIL1 /* "Wired" pseudoflag */ #define PG_MANAGED PG_AVAIL2 + +#ifdef PAE +#define PG_FRAME (0x000ffffffffff000ull) +#define PG_PS_FRAME (0x000fffffffe00000ull) +#else #define PG_FRAME (~((vm_paddr_t)PAGE_MASK)) +#define PG_PS_FRAME (0xffc00000) +#endif #define PG_PROT (PG_RW|PG_U) /* all protection bits . */ #define PG_N (PG_NC_PWT|PG_NC_PCD) /* Non-cacheable */ @@ -175,6 +182,77 @@ extern pd_entry_t *IdlePTD; /* physical * the corresponding pde that in turn maps it. */ #define vtopte(va) (PTmap + i386_btop(va)) +#define vtophys(va) pmap_kextract(((vm_offset_t) (va))) + +#ifdef XEN +#include <machine/xen/xen-os.h> +#include <machine/xen/xenvar.h> +#include <machine/xen/xenpmap.h> +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define PG_KERNEL (PG_V | PG_A | PG_RW | PG_M) + +#define MACH_TO_VM_PAGE(ma) PHYS_TO_VM_PAGE(xpmap_mtop((ma))) +#define VM_PAGE_TO_MACH(m) xpmap_ptom(VM_PAGE_TO_PHYS((m))) + +static __inline vm_paddr_t +pmap_kextract_ma(vm_offset_t va) +{ + vm_paddr_t ma; + if ((ma = PTD[va >> PDRSHIFT]) & PG_PS) { + ma = (ma & ~(NBPDR - 1)) | (va & (NBPDR - 1)); + } else { + ma = (*vtopte(va) & PG_FRAME) | (va & PAGE_MASK); + } + return ma; +} + +static __inline vm_paddr_t +pmap_kextract(vm_offset_t va) +{ + return xpmap_mtop(pmap_kextract_ma(va)); +} +#define vtomach(va) pmap_kextract_ma(((vm_offset_t) (va))) + +vm_paddr_t pmap_extract_ma(struct pmap *pmap, vm_offset_t va); + +void pmap_kenter_ma(vm_offset_t va, vm_paddr_t pa); +void pmap_map_readonly(struct pmap *pmap, vm_offset_t va, int len); +void pmap_map_readwrite(struct pmap *pmap, vm_offset_t va, int len); + +static __inline pt_entry_t +pte_load_store(pt_entry_t *ptep, pt_entry_t v) +{ + pt_entry_t r; + + v = xpmap_ptom(v); + r = *ptep; + PT_SET_VA(ptep, v, TRUE); + return (r); +} + +static __inline pt_entry_t +pte_load_store_ma(pt_entry_t *ptep, pt_entry_t v) +{ + pt_entry_t r; + + r = *ptep; + PT_SET_VA_MA(ptep, v, TRUE); + return (r); +} + +#define pte_load_clear(ptep) pte_load_store((ptep), (pt_entry_t)0ULL) + +#define pte_store(ptep, pte) pte_load_store((ptep), (pt_entry_t)pte) +#define pte_store_ma(ptep, pte) pte_load_store_ma((ptep), (pt_entry_t)pte) +#define pde_store_ma(ptep, pte) pte_load_store_ma((ptep), (pt_entry_t)pte) + +#elif !defined(XEN) /* * Routine: pmap_kextract @@ -195,10 +273,9 @@ pmap_kextract(vm_offset_t va) } return pa; } +#endif -#define vtophys(va) pmap_kextract(((vm_offset_t) (va))) - -#ifdef PAE +#if defined(PAE) && !defined(XEN) static __inline pt_entry_t pte_load(pt_entry_t *ptep) @@ -231,7 +308,7 @@ pte_load_store(pt_entry_t *ptep, pt_entr #define pte_store(ptep, pte) pte_load_store((ptep), (pt_entry_t)pte) -#else /* PAE */ +#elif !defined (PAE) && !defined(XEN) static __inline pt_entry_t pte_load(pt_entry_t *ptep) Modified: projects/releng_6_xen/sys/i386/include/segments.h ============================================================================== --- projects/releng_6_xen/sys/i386/include/segments.h Wed Oct 15 05:43:13 2008 (r183905) +++ projects/releng_6_xen/sys/i386/include/segments.h Wed Oct 15 05:44:08 2008 (r183906) @@ -47,7 +47,11 @@ */ #define ISPL(s) ((s)&3) /* what is the priority level of a selector */ +#ifndef XEN #define SEL_KPL 0 /* kernel priority level */ +#else +#define SEL_KPL 1 /* kernel priority level */ +#endif #define SEL_UPL 3 /* user priority level */ #define ISLDT(s) ((s)&SEL_LDT) /* is it local or global */ #define SEL_LDT 4 /* local descriptor table */ @@ -222,8 +226,11 @@ struct region_descriptor { #define GBIOSARGS_SEL 17 /* BIOS interface (Arguments) */ #define GNDIS_SEL 18 /* For the NDIS layer */ +#ifndef XEN #define NGDT 19 - +#else +#define NGDT 9 +#endif /* * Entries in the Local Descriptor Table (LDT) */ @@ -240,10 +247,16 @@ struct region_descriptor { #ifdef _KERNEL extern int _default_ldt; +#ifndef XEN +extern union descriptor ldt[NLDT]; extern union descriptor gdt[]; +#else +extern union descriptor *ldt; +extern union descriptor *gdt; +#endif + extern struct soft_segment_descriptor gdt_segs[]; extern struct gate_descriptor *idt; -extern union descriptor ldt[NLDT]; extern struct region_descriptor r_gdt, r_idt; void lgdt(struct region_descriptor *rdp); Added: projects/releng_6_xen/sys/i386/include/xen/evtchn.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/releng_6_xen/sys/i386/include/xen/evtchn.h Wed Oct 15 05:44:08 2008 (r183906) @@ -0,0 +1,81 @@ +/****************************************************************************** + * evtchn.h + * + * Communication via Xen event channels. + * Also definitions for the device that demuxes notifications to userspace. + * + * Copyright (c) 2004, K A Fraser + */ + +#ifndef __ASM_EVTCHN_H__ +#define __ASM_EVTCHN_H__ +#include <machine/pcpu.h> +#include <machine/xen/hypervisor.h> +#include <machine/xen/synch_bitops.h> +#include <machine/frame.h> + +/* + * LOW-LEVEL DEFINITIONS + */ + +/* + * Unlike notify_remote_via_evtchn(), this is safe to use across + * save/restore. Notifications on a broken connection are silently dropped. + */ +void notify_remote_via_irq(int irq); + + +/* Entry point for notifications into Linux subsystems. */ +void evtchn_do_upcall(struct intrframe *frame); + +/* Entry point for notifications into the userland character device. */ +void evtchn_device_upcall(int port); + +void mask_evtchn(int port); + +void unmask_evtchn(int port); + + + +static inline void +clear_evtchn(int port) +{ + shared_info_t *s = HYPERVISOR_shared_info; + synch_clear_bit(port, &s->evtchn_pending[0]); +} + +static inline void +notify_remote_via_evtchn(int port) +{ + struct evtchn_send send = { .port = port }; + (void)HYPERVISOR_event_channel_op(EVTCHNOP_send, &send); +} + +/* + * Use these to access the event channel underlying the IRQ handle returned + * by bind_*_to_irqhandler(). + */ +int irq_to_evtchn_port(int irq); + +void ipi_pcpu(unsigned int cpu, int vector); + +/* + * CHARACTER-DEVICE DEFINITIONS + */ + +#define PORT_NORMAL 0x0000 +#define PORT_EXCEPTION 0x8000 +#define PORTIDX_MASK 0x7fff + +/* /dev/xen/evtchn resides at device number major=10, minor=200 */ +#define EVTCHN_MINOR 200 + +/* /dev/xen/evtchn ioctls: */ +/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */ *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810150544.m9F5i8D2025472>