summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deleted_files/usr/src/cmd/eeprom/common/Makefile (renamed from usr/src/cmd/eeprom/common/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/eeprom/eeprom.xml (renamed from usr/src/cmd/eeprom/eeprom.xml)0
-rw-r--r--deleted_files/usr/src/cmd/eeprom/i386/common/benv_sync.c (renamed from usr/src/cmd/eeprom/i386/common/benv_sync.c)0
-rw-r--r--deleted_files/usr/src/cmd/eeprom/i386/i86pc/Makefile (renamed from usr/src/cmd/eeprom/i386/i86pc/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/eeprom/sparc/sun4u/Makefile (renamed from usr/src/cmd/eeprom/sparc/sun4u/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/eeprom/sparc/sun4v/Makefile (renamed from usr/src/cmd/eeprom/sparc/sun4v/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/mdb/common/kmdb/kmdb_kdi_impl.h (renamed from usr/src/cmd/mdb/common/kmdb/kmdb_kdi_impl.h)0
-rw-r--r--deleted_files/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.h (renamed from usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.h)0
-rw-r--r--deleted_files/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.s (renamed from usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.s)0
-rw-r--r--deleted_files/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_resume.s (renamed from usr/src/cmd/mdb/intel/amd64/kmdb/kaif_resume.s)0
-rw-r--r--deleted_files/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.h (renamed from usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.h)0
-rw-r--r--deleted_files/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.s (renamed from usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.s)0
-rw-r--r--deleted_files/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_resume.s (renamed from usr/src/cmd/mdb/intel/ia32/kmdb/kaif_resume.s)0
-rw-r--r--deleted_files/usr/src/cmd/mdb/intel/kmdb/kaif_activate.c (renamed from usr/src/cmd/mdb/intel/kmdb/kaif_activate.c)0
-rw-r--r--deleted_files/usr/src/cmd/mdb/intel/kmdb/kaif_start_isadep.c (renamed from usr/src/cmd/mdb/intel/kmdb/kaif_start_isadep.c)0
-rw-r--r--deleted_files/usr/src/cmd/mdb/sparc/kmdb/kaif_enter.s (renamed from usr/src/cmd/mdb/sparc/kmdb/kaif_enter.s)0
-rw-r--r--deleted_files/usr/src/cmd/prtdiag/i386/i86pc/Makefile (renamed from usr/src/cmd/prtdiag/i386/i86pc/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/svc/profile/platform_i86pc.xml (renamed from usr/src/cmd/svc/profile/platform_i86pc.xml)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/alloc.c (renamed from usr/src/psm/stand/boot/amd64/alloc.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/alloc.h (renamed from usr/src/psm/stand/boot/amd64/amd64/alloc.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/amd64.h (renamed from usr/src/psm/stand/boot/amd64/amd64/amd64.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/amd64_page.h (renamed from usr/src/psm/stand/boot/amd64/amd64/amd64_page.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/auxv64.h (renamed from usr/src/psm/stand/boot/amd64/amd64/auxv64.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/boothooks.h (renamed from usr/src/psm/stand/boot/amd64/amd64/boothooks.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/bootops64.h (renamed from usr/src/psm/stand/boot/amd64/amd64/bootops64.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/bootsvcs64.h (renamed from usr/src/psm/stand/boot/amd64/amd64/bootsvcs64.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/cpu.h (renamed from usr/src/psm/stand/boot/amd64/amd64/cpu.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/debug.h (renamed from usr/src/psm/stand/boot/amd64/amd64/debug.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/machregs.h (renamed from usr/src/psm/stand/boot/amd64/amd64/machregs.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/memlist64.h (renamed from usr/src/psm/stand/boot/amd64/amd64/memlist64.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/msr.h (renamed from usr/src/psm/stand/boot/amd64/amd64/msr.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/print.h (renamed from usr/src/psm/stand/boot/amd64/amd64/print.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/segments.h (renamed from usr/src/psm/stand/boot/amd64/amd64/segments.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/tss.h (renamed from usr/src/psm/stand/boot/amd64/amd64/tss.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/amd64/types.h (renamed from usr/src/psm/stand/boot/amd64/amd64/types.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/context.c (renamed from usr/src/psm/stand/boot/amd64/context.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/cpu.c (renamed from usr/src/psm/stand/boot/amd64/cpu.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/exception.s (renamed from usr/src/psm/stand/boot/amd64/exception.s)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/genassym.c (renamed from usr/src/psm/stand/boot/amd64/genassym.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/handoff.c (renamed from usr/src/psm/stand/boot/amd64/handoff.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/i386_subr.s (renamed from usr/src/psm/stand/boot/amd64/i386_subr.s)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/locore.s (renamed from usr/src/psm/stand/boot/amd64/locore.s)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/memlist.c (renamed from usr/src/psm/stand/boot/amd64/memlist.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/offsets.in (renamed from usr/src/psm/stand/boot/amd64/offsets.in)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/print.c (renamed from usr/src/psm/stand/boot/amd64/print.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/ptops.c (renamed from usr/src/psm/stand/boot/amd64/ptops.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/ptxlate.c (renamed from usr/src/psm/stand/boot/amd64/ptxlate.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/segments.c (renamed from usr/src/psm/stand/boot/amd64/segments.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/amd64/vtrap.c (renamed from usr/src/psm/stand/boot/amd64/vtrap.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/Makefile (renamed from usr/src/psm/stand/boot/i386/Makefile)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/Makefile.com (renamed from usr/src/psm/stand/boot/i386/Makefile.com)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/bios.c (renamed from usr/src/psm/stand/boot/i386/common/bios.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/biosint.h (renamed from usr/src/psm/stand/boot/i386/common/biosint.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/biosint.map (renamed from usr/src/psm/stand/boot/i386/common/biosint.map)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/biosutil.c (renamed from usr/src/psm/stand/boot/i386/common/biosutil.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/boot_plat.c (renamed from usr/src/psm/stand/boot/i386/common/boot_plat.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/boot_ramdisk.c (renamed from usr/src/psm/stand/boot/i386/common/boot_ramdisk.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/bootenv.c (renamed from usr/src/psm/stand/boot/i386/common/bootenv.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/bootflags.c (renamed from usr/src/psm/stand/boot/i386/common/bootflags.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/bootops.c (renamed from usr/src/psm/stand/boot/i386/common/bootops.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/bootprop.c (renamed from usr/src/psm/stand/boot/i386/common/bootprop.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/bootprop.h (renamed from usr/src/psm/stand/boot/i386/common/bootprop.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/chario.h (renamed from usr/src/psm/stand/boot/i386/common/chario.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/check_iopath.c (renamed from usr/src/psm/stand/boot/i386/common/check_iopath.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/cpu_id.h (renamed from usr/src/psm/stand/boot/i386/common/cpu_id.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/debug.h (renamed from usr/src/psm/stand/boot/i386/common/debug.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/i86.il (renamed from usr/src/psm/stand/boot/i386/common/i86.il)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/machine.h (renamed from usr/src/psm/stand/boot/i386/common/machine.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/mapfile (renamed from usr/src/psm/stand/boot/i386/common/mapfile)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/memory.c (renamed from usr/src/psm/stand/boot/i386/common/memory.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/mkbin.c (renamed from usr/src/psm/stand/boot/i386/common/mkbin.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/multiboot.c (renamed from usr/src/psm/stand/boot/i386/common/multiboot.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/multiboot.h (renamed from usr/src/psm/stand/boot/i386/common/multiboot.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/standalloc.c (renamed from usr/src/psm/stand/boot/i386/common/standalloc.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/standalloc.h (renamed from usr/src/psm/stand/boot/i386/common/standalloc.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/util.h (renamed from usr/src/psm/stand/boot/i386/common/util.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/common/vgaprobe.c (renamed from usr/src/psm/stand/boot/i386/common/vgaprobe.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/i86pc/Makefile (renamed from usr/src/psm/stand/boot/i386/i86pc/Makefile)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/i86pc/asm.s (renamed from usr/src/psm/stand/boot/i386/i86pc/asm.s)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/i86pc/biosint.s (renamed from usr/src/psm/stand/boot/i386/i86pc/biosint.s)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/i86pc/cpu_id.s (renamed from usr/src/psm/stand/boot/i386/i86pc/cpu_id.s)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/i86pc/idttab.s (renamed from usr/src/psm/stand/boot/i386/i86pc/idttab.s)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/i386/i86pc/samuldiv64.s (renamed from usr/src/psm/stand/boot/i386/i86pc/samuldiv64.s)0
-rw-r--r--deleted_files/usr/src/uts/common/zmod/mapfile (renamed from usr/src/uts/common/zmod/mapfile)0
-rw-r--r--deleted_files/usr/src/uts/intel/amd64/Makefile.rules (renamed from usr/src/uts/intel/amd64/Makefile.rules)0
-rw-r--r--deleted_files/usr/src/uts/intel/ia32/Makefile.rules (renamed from usr/src/uts/intel/ia32/Makefile.rules)0
-rw-r--r--deleted_files/usr/src/uts/intel/ia32/os/arch_kdi.c (renamed from usr/src/uts/intel/ia32/os/arch_kdi.c)0
-rw-r--r--deleted_files/usr/src/uts/intel/ia32/sys/mmu.h (renamed from usr/src/uts/intel/ia32/sys/mmu.h)0
-rw-r--r--deleted_files/usr/src/uts/intel/krtld/Makefile (renamed from usr/src/uts/intel/krtld/Makefile)0
-rw-r--r--deleted_files/usr/src/uts/intel/sys/immu.h (renamed from usr/src/uts/intel/sys/immu.h)0
-rw-r--r--deleted_files/usr/src/uts/intel/sys/mmu.h (renamed from usr/src/uts/intel/sys/mmu.h)0
-rw-r--r--deleted_files/usr/src/uts/intel/zmod/Makefile (renamed from usr/src/uts/intel/zmod/Makefile)0
-rw-r--r--deleted_files/usr/src/uts/sparc/zmod/Makefile (renamed from usr/src/uts/sparc/zmod/Makefile)0
-rw-r--r--usr/src/Makefile.master4
-rw-r--r--usr/src/Makefile.psm9
-rw-r--r--usr/src/Makefile.psm.targ10
-rw-r--r--usr/src/Targetdirs7
-rw-r--r--usr/src/cmd/Makefile.cmd6
-rw-r--r--usr/src/cmd/boot/Makefile8
-rw-r--r--usr/src/cmd/boot/bootadm/Makefile13
-rw-r--r--usr/src/cmd/boot/bootadm/bootadm.c811
-rw-r--r--usr/src/cmd/boot/bootadm/bootadm.h184
-rw-r--r--usr/src/cmd/boot/bootadm/bootadm_upgrade.c575
-rw-r--r--usr/src/cmd/boot/bootadm/message.h48
-rw-r--r--usr/src/cmd/boot/scripts/Makefile.com4
-rw-r--r--usr/src/cmd/boot/scripts/create_ramdisk.ksh310
-rw-r--r--usr/src/cmd/boot/scripts/root_archive.ksh6
-rw-r--r--usr/src/cmd/boot/scripts/update_grub.ksh125
-rw-r--r--usr/src/cmd/boot/symdef/Makefile58
-rw-r--r--usr/src/cmd/boot/symdef/symdef.c117
-rw-r--r--usr/src/cmd/devfsadm/i386/misc_link_i386.c25
-rw-r--r--usr/src/cmd/eeprom/Makefile29
-rw-r--r--usr/src/cmd/eeprom/Makefile.com47
-rw-r--r--usr/src/cmd/eeprom/Makefile.targ15
-rw-r--r--usr/src/cmd/eeprom/i386/Makefile32
-rw-r--r--usr/src/cmd/eeprom/i386/benv.c (renamed from usr/src/cmd/eeprom/i386/common/benv.c)421
-rw-r--r--usr/src/cmd/eeprom/i386/benv.h (renamed from usr/src/cmd/eeprom/i386/common/benv.h)0
-rw-r--r--usr/src/cmd/eeprom/i386/benv_kvm.c (renamed from usr/src/cmd/eeprom/i386/common/benv_kvm.c)0
-rw-r--r--usr/src/cmd/eeprom/sparc/Makefile27
-rw-r--r--usr/src/cmd/eeprom/sparc/loadlogo.c (renamed from usr/src/cmd/eeprom/common/loadlogo.c)0
-rw-r--r--usr/src/cmd/eeprom/sparc/openprom.c (renamed from usr/src/cmd/eeprom/common/openprom.c)0
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kaif_start.c36
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kaif_start.h15
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kctl/kctl.h6
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kctl/kctl_auxv.c28
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kctl/kctl_dmod.c6
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kctl/kctl_main.c47
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kctl/kctl_wr.c9
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kmdb_dpi_impl.h11
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kmdb_kdi.c17
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kmdb_kdi.h12
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c58
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kmdb_promif.c61
-rw-r--r--usr/src/cmd/mdb/common/kmdb/kvm.h3
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_ks.h4
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_kvm.c59
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_kvm.h8
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/Makefile.files68
-rw-r--r--usr/src/cmd/mdb/common/modules/libc/libc.c7
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/common/intr_common.c (renamed from usr/src/cmd/mdb/i86pc/modules/uppc/intr_common.c)230
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/common/intr_common.h (renamed from usr/src/cmd/mdb/i86pc/modules/uppc/intr_common.h)16
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/pcplusmp/amd64/Makefile6
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c165
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/pcplusmp/ia32/Makefile6
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile9
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.c267
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.h10
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/unix/ia32/Makefile9
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/unix/unix.c240
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/uppc/amd64/Makefile5
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/uppc/ia32/Makefile5
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/uppc/uppc.c4
-rw-r--r--usr/src/cmd/mdb/intel/Makefile.kmdb6
-rw-r--r--usr/src/cmd/mdb/intel/amd64/Makefile.kmdb16
-rw-r--r--usr/src/cmd/mdb/intel/amd64/genunix/Makefile39
-rw-r--r--usr/src/cmd/mdb/intel/amd64/kmdb/Makefile5
-rw-r--r--usr/src/cmd/mdb/intel/amd64/kmdb/kaif_startup.s323
-rw-r--r--usr/src/cmd/mdb/intel/ia32/Makefile.kmdb16
-rw-r--r--usr/src/cmd/mdb/intel/ia32/genunix/Makefile39
-rw-r--r--usr/src/cmd/mdb/intel/ia32/kmdb/Makefile5
-rw-r--r--usr/src/cmd/mdb/intel/ia32/kmdb/kaif_startup.s369
-rw-r--r--usr/src/cmd/mdb/intel/ia32/kmdb/kvm_cpu_p6.c21
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kaif.c309
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kaif.h68
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kaif_idt.c181
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kaif_regs.h105
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kctl/kctl_isadep.c80
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.c9
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.h27
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.c83
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.h31
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kvm_cpu_amd.c29
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kvm_cpu_p4.c127
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kvm_isadep.c4
-rw-r--r--usr/src/cmd/mdb/intel/kmdb/kvm_isadep.h10
-rw-r--r--usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c9
-rw-r--r--usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c13
-rw-r--r--usr/src/cmd/mdb/intel/mdb/mdb_kreg.h140
-rw-r--r--usr/src/cmd/mdb/sparc/kmdb/kaif.c11
-rw-r--r--usr/src/cmd/mdb/sparc/kmdb/kaif.h10
-rw-r--r--usr/src/cmd/mdb/sparc/kmdb/kaif_activate.c15
-rw-r--r--usr/src/cmd/mdb/sparc/kmdb/kctl/kctl_isadep.c11
-rw-r--r--usr/src/cmd/mdb/sparc/kmdb/kmdb_kdi_isadep.c76
-rw-r--r--usr/src/cmd/mdb/sparc/v9/genunix/Makefile39
-rw-r--r--usr/src/cmd/mdb/sun4u/Makefile.kmdb8
-rw-r--r--usr/src/cmd/mdb/sun4v/Makefile.kmdb3
-rw-r--r--usr/src/cmd/prtdiag/Makefile11
-rw-r--r--usr/src/cmd/prtdiag/Makefile.com8
-rw-r--r--usr/src/cmd/prtdiag/i386/Makefile30
-rw-r--r--usr/src/cmd/prtdiag/i386/Makefile.targ46
-rw-r--r--usr/src/cmd/prtdiag/i386/smbios.c (renamed from usr/src/cmd/prtdiag/i386/i86pc/smbios.c)0
-rw-r--r--usr/src/cmd/prtdiag/sparc/Makefile.targ (renamed from usr/src/cmd/prtdiag/Makefile.targ)15
-rw-r--r--usr/src/cmd/prtdiag/sparc/sun4u/Makefile9
-rw-r--r--usr/src/cmd/prtdiag/sparc/sun4v/Makefile9
-rw-r--r--usr/src/cmd/svc/profile/Makefile3
-rw-r--r--usr/src/common/elfcap/elfcap.c14
-rw-r--r--usr/src/common/fs/decompress.c308
-rw-r--r--usr/src/common/fs/hsfs.c74
-rw-r--r--usr/src/common/fs/ufsops.c136
-rw-r--r--usr/src/common/util/bzero.c9
-rw-r--r--usr/src/common/util/memcpy.c8
-rw-r--r--usr/src/common/util/memcpy.h44
-rw-r--r--usr/src/common/util/memset.c13
-rw-r--r--usr/src/common/util/memset.h44
-rw-r--r--usr/src/common/util/sscanf.c633
-rw-r--r--usr/src/common/util/sscanf.h47
-rw-r--r--usr/src/common/util/string.c36
-rw-r--r--usr/src/common/util/string.h87
-rw-r--r--usr/src/grub/grub-0.95/grub/asmstub.c27
-rw-r--r--usr/src/grub/grub-0.95/stage2/asm.S76
-rw-r--r--usr/src/grub/grub-0.95/stage2/builtins.c296
-rw-r--r--usr/src/grub/grub-0.95/stage2/controlregs.h161
-rw-r--r--usr/src/grub/grub-0.95/stage2/cpu.h73
-rw-r--r--usr/src/grub/install_menu8
-rw-r--r--usr/src/grub/menu.lst9
-rw-r--r--usr/src/lib/libc/amd64/threads/amd64.il12
-rw-r--r--usr/src/lib/libc/amd64/threads/machdep.c10
-rw-r--r--usr/src/lib/libc/i386/threads/i386.il12
-rw-r--r--usr/src/lib/libc/i386/threads/machdep.c10
-rw-r--r--usr/src/lib/libc/inc/thr_inlines.h16
-rw-r--r--usr/src/lib/libc/inc/thr_uberdata.h6
-rw-r--r--usr/src/lib/libc/port/threads/sigaction.c6
-rw-r--r--usr/src/lib/libc/port/threads/thr.c7
-rw-r--r--usr/src/lib/libc/sparc/threads/sparc.il11
-rw-r--r--usr/src/lib/libc/sparcv9/threads/sparcv9.il11
-rw-r--r--usr/src/lib/libdtrace/common/dt_module.c14
-rw-r--r--usr/src/pkgdefs/Makefile5
-rw-r--r--usr/src/pkgdefs/SUNWagp/prototype_i38624
-rw-r--r--usr/src/pkgdefs/SUNWcakr.i/prototype_com45
-rw-r--r--usr/src/pkgdefs/SUNWckr/prototype_i38636
-rw-r--r--usr/src/pkgdefs/SUNWckr/prototype_sparc3
-rw-r--r--usr/src/pkgdefs/SUNWcsr/postinstall15
-rw-r--r--usr/src/pkgdefs/SUNWcsr/prototype_i3866
-rw-r--r--usr/src/pkgdefs/SUNWcsu/prototype_com3
-rw-r--r--usr/src/pkgdefs/SUNWcsu/prototype_i3863
-rw-r--r--usr/src/pkgdefs/SUNWcsu/prototype_sparc1
-rwxr-xr-xusr/src/pkgdefs/SUNWdrmr/prototype_i38613
-rw-r--r--usr/src/pkgdefs/SUNWhea/prototype_i38613
-rw-r--r--usr/src/pkgdefs/SUNWkvm.i/prototype_com14
-rw-r--r--usr/src/pkgdefs/SUNWkvm.u/prototype_com10
-rw-r--r--usr/src/pkgdefs/SUNWkvm.v/prototype_com3
-rw-r--r--usr/src/pkgdefs/SUNWos86r/prototype_i38615
-rw-r--r--usr/src/pkgdefs/SUNWpsdcr/prototype_i38660
-rw-r--r--usr/src/pkgdefs/SUNWpsdir/prototype_i38625
-rw-r--r--usr/src/pkgdefs/SUNWxsvc/Makefile37
-rw-r--r--usr/src/pkgdefs/SUNWxsvc/depend52
-rw-r--r--usr/src/pkgdefs/SUNWxsvc/pkginfo.tmpl50
-rw-r--r--usr/src/pkgdefs/SUNWxsvc/postinstall46
-rw-r--r--usr/src/pkgdefs/SUNWxsvc/postremove35
-rw-r--r--usr/src/pkgdefs/SUNWxsvc/prototype_i38657
-rw-r--r--usr/src/pkgdefs/etc/exception_list_sparc3
-rw-r--r--usr/src/pkgdefs/etc/proto_list_ihv_i3865
-rw-r--r--usr/src/psm/stand/boot/Makefile8
-rw-r--r--usr/src/psm/stand/boot/i386/common/console.c677
-rw-r--r--usr/src/psm/stand/boot/i386/common/serial.h83
-rw-r--r--usr/src/psm/stand/cpr/common/Makefile.com10
-rw-r--r--usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.c13
-rw-r--r--usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.h9
-rw-r--r--usr/src/psm/stand/cpr/sparcv9/sun4u/pages.c15
-rw-r--r--usr/src/tools/Makefile8
-rw-r--r--usr/src/tools/ctf/cvt/ctfmerge.c17
-rw-r--r--usr/src/tools/ctf/cvt/dwarf.c32
-rw-r--r--usr/src/tools/elfextract/Makefile44
-rw-r--r--usr/src/tools/elfextract/elfextract.c274
-rw-r--r--usr/src/tools/findunref/exception_list4
-rw-r--r--usr/src/tools/mbh_patch/Makefile45
-rw-r--r--usr/src/tools/mbh_patch/mbh_patch.c213
-rw-r--r--usr/src/tools/protocmp/arch.c11
-rw-r--r--usr/src/tools/protocmp/list.h20
-rw-r--r--usr/src/tools/protocmp/proto_list.c11
-rw-r--r--usr/src/tools/scripts/Install.sh7
-rw-r--r--usr/src/tools/scripts/bfu.sh517
-rw-r--r--usr/src/uts/Makefile.targ11
-rw-r--r--usr/src/uts/Makefile.uts56
-rw-r--r--usr/src/uts/common/Makefile.files35
-rw-r--r--usr/src/uts/common/cpr/cpr_driver.c37
-rw-r--r--usr/src/uts/common/cpr/cpr_dump.c91
-rw-r--r--usr/src/uts/common/cpr/cpr_main.c69
-rw-r--r--usr/src/uts/common/cpr/cpr_misc.c62
-rw-r--r--usr/src/uts/common/cpr/cpr_mod.c11
-rw-r--r--usr/src/uts/common/cpr/cpr_stat.c11
-rw-r--r--usr/src/uts/common/cpr/cpr_uthread.c30
-rw-r--r--usr/src/uts/common/crypto/io/swrand.c28
-rw-r--r--usr/src/uts/common/dtrace/profile.c31
-rw-r--r--usr/src/uts/common/fs/fsflush.c6
-rw-r--r--usr/src/uts/common/fs/sockfs/socktpi.c2
-rw-r--r--usr/src/uts/common/fs/specfs/specvnops.c4
-rw-r--r--usr/src/uts/common/fs/tmpfs/tmp_vnops.c4
-rw-r--r--usr/src/uts/common/fs/vfs.c37
-rw-r--r--usr/src/uts/common/io/audio/inc.flg8
-rw-r--r--usr/src/uts/common/io/avintr.c9
-rw-r--r--usr/src/uts/common/io/busra.c11
-rw-r--r--usr/src/uts/common/io/consconfig_dacf.c78
-rw-r--r--usr/src/uts/common/io/mem.c27
-rw-r--r--usr/src/uts/common/io/power.c7
-rw-r--r--usr/src/uts/common/kmdb/kdrv.c4
-rw-r--r--usr/src/uts/common/krtld/bootrd.c31
-rw-r--r--usr/src/uts/common/krtld/kobj.c296
-rw-r--r--usr/src/uts/common/krtld/kobj_kdi.c8
-rw-r--r--usr/src/uts/common/os/acct.c19
-rw-r--r--usr/src/uts/common/os/clock.c11
-rw-r--r--usr/src/uts/common/os/core.c13
-rw-r--r--usr/src/uts/common/os/cpu.c36
-rw-r--r--usr/src/uts/common/os/dumpsubr.c10
-rw-r--r--usr/src/uts/common/os/fork.c24
-rw-r--r--usr/src/uts/common/os/grow.c4
-rw-r--r--usr/src/uts/common/os/kdi.c49
-rw-r--r--usr/src/uts/common/os/main.c19
-rw-r--r--usr/src/uts/common/os/mem_config.c61
-rw-r--r--usr/src/uts/common/os/mem_config_stubs.c28
-rw-r--r--usr/src/uts/common/os/policy.c4
-rw-r--r--usr/src/uts/common/os/shm.c32
-rw-r--r--usr/src/uts/common/os/sig.c38
-rw-r--r--usr/src/uts/common/os/vm_pageout.c6
-rw-r--r--usr/src/uts/common/os/zone.c12
-rw-r--r--usr/src/uts/common/sys/auxv_386.h11
-rw-r--r--usr/src/uts/common/sys/bootprops.h8
-rw-r--r--usr/src/uts/common/sys/cpr.h53
-rw-r--r--usr/src/uts/common/sys/cpuvar.h15
-rw-r--r--usr/src/uts/common/sys/dtrace.h4
-rw-r--r--usr/src/uts/common/sys/dumphdr.h10
-rw-r--r--usr/src/uts/common/sys/filep.h15
-rw-r--r--usr/src/uts/common/sys/hold_page.h76
-rw-r--r--usr/src/uts/common/sys/isa_defs.h8
-rw-r--r--usr/src/uts/common/sys/kdi.h33
-rw-r--r--usr/src/uts/common/sys/kdi_impl.h43
-rw-r--r--usr/src/uts/common/sys/mem.h10
-rw-r--r--usr/src/uts/common/sys/mem_config.h12
-rw-r--r--usr/src/uts/common/sys/memlist.h11
-rw-r--r--usr/src/uts/common/sys/multiboot.h174
-rw-r--r--usr/src/uts/common/sys/ontrap.h11
-rw-r--r--usr/src/uts/common/sys/param.h13
-rw-r--r--usr/src/uts/common/sys/systm.h148
-rw-r--r--usr/src/uts/common/sys/time.h5
-rw-r--r--usr/src/uts/common/sys/types.h9
-rw-r--r--usr/src/uts/common/sys/user.h3
-rw-r--r--usr/src/uts/common/syscall/mkdir.c13
-rw-r--r--usr/src/uts/common/syscall/mknod.c9
-rw-r--r--usr/src/uts/common/syscall/open.c9
-rw-r--r--usr/src/uts/common/syscall/sigaction.c35
-rw-r--r--usr/src/uts/common/syscall/ssig.c11
-rw-r--r--usr/src/uts/common/syscall/uadmin.c20
-rw-r--r--usr/src/uts/common/syscall/umask.c18
-rw-r--r--usr/src/uts/common/vm/page.h14
-rw-r--r--usr/src/uts/common/vm/page_lock.c55
-rw-r--r--usr/src/uts/common/zmod/zmod.c33
-rw-r--r--usr/src/uts/i86pc/Makefile28
-rw-r--r--usr/src/uts/i86pc/Makefile.files151
-rw-r--r--usr/src/uts/i86pc/Makefile.i86pc.shared88
-rw-r--r--usr/src/uts/i86pc/Makefile.rules199
-rw-r--r--usr/src/uts/i86pc/Makefile.workarounds6
-rw-r--r--usr/src/uts/i86pc/boot/boot_console.c556
-rw-r--r--usr/src/uts/i86pc/boot/boot_gdt.s108
-rw-r--r--usr/src/uts/i86pc/boot/boot_keyboard.c (renamed from usr/src/psm/stand/boot/i386/common/keyboard.c)64
-rw-r--r--usr/src/uts/i86pc/boot/boot_keyboard.h46
-rw-r--r--usr/src/uts/i86pc/boot/boot_keyboard_table.c (renamed from usr/src/psm/stand/boot/i386/common/keyboard_table.c)13
-rw-r--r--usr/src/uts/i86pc/boot/boot_keyboard_table.h (renamed from usr/src/psm/stand/boot/i386/common/keyboard_table.h)37
-rw-r--r--usr/src/uts/i86pc/boot/boot_mmu.c121
-rw-r--r--usr/src/uts/i86pc/boot/boot_serial.h148
-rw-r--r--usr/src/uts/i86pc/boot/boot_vga.c (renamed from usr/src/psm/stand/boot/i386/common/vga.c)16
-rw-r--r--usr/src/uts/i86pc/boot/boot_vga.h (renamed from usr/src/psm/stand/boot/i386/common/vga.h)13
-rw-r--r--usr/src/uts/i86pc/conf/Mapfile22
-rw-r--r--usr/src/uts/i86pc/conf/Mapfile.amd6421
-rw-r--r--usr/src/uts/i86pc/conf/Mapfile.bios30
-rw-r--r--usr/src/uts/i86pc/consconfig_dacf/Makefile (renamed from usr/src/uts/intel/consconfig_dacf/Makefile)10
-rw-r--r--usr/src/uts/i86pc/dboot/dboot_elfload.c168
-rw-r--r--usr/src/uts/i86pc/dboot/dboot_elfload.h42
-rw-r--r--usr/src/uts/i86pc/dboot/dboot_grub.s283
-rw-r--r--usr/src/uts/i86pc/dboot/dboot_printf.c205
-rw-r--r--usr/src/uts/i86pc/dboot/dboot_printf.h57
-rw-r--r--usr/src/uts/i86pc/dboot/dboot_startkern.c827
-rw-r--r--usr/src/uts/i86pc/dboot/dboot_xboot.h83
-rw-r--r--usr/src/uts/i86pc/genassym/Makefile16
-rw-r--r--usr/src/uts/i86pc/io/cbe.c17
-rw-r--r--usr/src/uts/i86pc/io/consplat.c (renamed from usr/src/uts/intel/io/consplat.c)0
-rw-r--r--usr/src/uts/i86pc/io/hardclk.c (renamed from usr/src/uts/common/io/pit.c)54
-rw-r--r--usr/src/uts/i86pc/io/mp_platform_common.c3736
-rw-r--r--usr/src/uts/i86pc/io/pci/pci_common.c4
-rw-r--r--usr/src/uts/i86pc/io/pci/pci_kstats.c4
-rw-r--r--usr/src/uts/i86pc/io/pci/pci_tools.c11
-rw-r--r--usr/src/uts/i86pc/io/pciex/inc.flg17
-rw-r--r--usr/src/uts/i86pc/io/pcplusmp/apic.c4059
-rw-r--r--usr/src/uts/i86pc/io/pcplusmp/apic_introp.c158
-rw-r--r--usr/src/uts/i86pc/io/psm/uppc.c18
-rw-r--r--usr/src/uts/i86pc/io/todpc_subr.c (renamed from usr/src/uts/common/io/hardclk.c)73
-rw-r--r--usr/src/uts/i86pc/io/xsvc/xsvc.c974
-rw-r--r--usr/src/uts/i86pc/io/xsvc/xsvc.conf34
-rw-r--r--usr/src/uts/i86pc/ml/amd64.il183
-rw-r--r--usr/src/uts/i86pc/ml/bios_call_src.s565
-rw-r--r--usr/src/uts/i86pc/ml/genassym.c19
-rw-r--r--usr/src/uts/i86pc/ml/ia32.il187
-rw-r--r--usr/src/uts/i86pc/ml/interrupt.s1495
-rw-r--r--usr/src/uts/i86pc/ml/kdi_subr.s160
-rw-r--r--usr/src/uts/i86pc/ml/locore.s828
-rw-r--r--usr/src/uts/i86pc/ml/mpcore.s103
-rw-r--r--usr/src/uts/i86pc/ml/notes.s12
-rw-r--r--usr/src/uts/i86pc/ml/offsets.in7
-rw-r--r--usr/src/uts/i86pc/ml/syscall_asm.s29
-rw-r--r--usr/src/uts/i86pc/ml/syscall_asm_amd64.s40
-rw-r--r--usr/src/uts/i86pc/os/acpi_fw.h148
-rw-r--r--usr/src/uts/i86pc/os/cmi.c20
-rw-r--r--usr/src/uts/i86pc/os/cpuid.c170
-rw-r--r--usr/src/uts/i86pc/os/dtrace_subr.c12
-rw-r--r--usr/src/uts/i86pc/os/fakebop.c1503
-rw-r--r--usr/src/uts/i86pc/os/fpu_subr.c193
-rw-r--r--usr/src/uts/i86pc/os/hold_page.c42
-rw-r--r--usr/src/uts/i86pc/os/intr.c520
-rw-r--r--usr/src/uts/i86pc/os/mach_kdi.c262
-rw-r--r--usr/src/uts/i86pc/os/machdep.c100
-rw-r--r--usr/src/uts/i86pc/os/memscrub.c9
-rw-r--r--usr/src/uts/i86pc/os/mlsetup.c144
-rw-r--r--usr/src/uts/i86pc/os/mp_call.c18
-rw-r--r--usr/src/uts/i86pc/os/mp_implfuncs.c13
-rw-r--r--usr/src/uts/i86pc/os/mp_machdep.c219
-rw-r--r--usr/src/uts/i86pc/os/mp_pc.c287
-rw-r--r--usr/src/uts/i86pc/os/mp_startup.c863
-rw-r--r--usr/src/uts/i86pc/os/startup.c1103
-rw-r--r--usr/src/uts/i86pc/os/timestamp.c48
-rw-r--r--usr/src/uts/i86pc/os/trap.c250
-rw-r--r--usr/src/uts/i86pc/os/x_call.c188
-rw-r--r--usr/src/uts/i86pc/pcplusmp/Makefile4
-rw-r--r--usr/src/uts/i86pc/sys/Makefile14
-rw-r--r--usr/src/uts/i86pc/sys/apic.h (renamed from usr/src/uts/i86pc/io/pcplusmp/apic.h)207
-rw-r--r--usr/src/uts/i86pc/sys/asm_misc.h43
-rw-r--r--usr/src/uts/i86pc/sys/boot_console.h (renamed from usr/src/psm/stand/boot/i386/common/console.h)36
-rw-r--r--usr/src/uts/i86pc/sys/clock.h16
-rw-r--r--usr/src/uts/i86pc/sys/debug_info.h49
-rw-r--r--usr/src/uts/i86pc/sys/mach_mmu.h165
-rw-r--r--usr/src/uts/i86pc/sys/machclock.h66
-rw-r--r--usr/src/uts/i86pc/sys/machcpuvar.h27
-rw-r--r--usr/src/uts/i86pc/sys/machparam.h58
-rw-r--r--usr/src/uts/i86pc/sys/machprivregs.h172
-rw-r--r--usr/src/uts/i86pc/sys/machsystm.h26
-rw-r--r--usr/src/uts/i86pc/sys/pc_mmu.h66
-rw-r--r--usr/src/uts/i86pc/sys/psm_types.h19
-rw-r--r--usr/src/uts/i86pc/sys/rm_platter.h14
-rw-r--r--usr/src/uts/i86pc/sys/smp_impldefs.h4
-rw-r--r--usr/src/uts/i86pc/sys/x_call.h29
-rw-r--r--usr/src/uts/i86pc/sys/xsvc.h134
-rw-r--r--usr/src/uts/i86pc/unix/Makefile89
-rw-r--r--usr/src/uts/i86pc/unix/dboot/Mapfile.dboot32
-rw-r--r--usr/src/uts/i86pc/vm/Makefile12
-rw-r--r--usr/src/uts/i86pc/vm/hat_i86.c692
-rw-r--r--usr/src/uts/i86pc/vm/hat_i86.h32
-rw-r--r--usr/src/uts/i86pc/vm/hat_kdi.c67
-rw-r--r--usr/src/uts/i86pc/vm/hat_pte.h158
-rw-r--r--usr/src/uts/i86pc/vm/htable.c1066
-rw-r--r--usr/src/uts/i86pc/vm/htable.h72
-rw-r--r--usr/src/uts/i86pc/vm/i86_mmu.c408
-rw-r--r--usr/src/uts/i86pc/vm/kboot_mmu.c420
-rw-r--r--usr/src/uts/i86pc/vm/kboot_mmu.h106
-rw-r--r--usr/src/uts/i86pc/vm/mach_i86mmu.c708
-rw-r--r--usr/src/uts/i86pc/vm/vm_dep.h5
-rw-r--r--usr/src/uts/i86pc/vm/vm_machdep.c128
-rw-r--r--usr/src/uts/i86pc/xsvc/Makefile95
-rw-r--r--usr/src/uts/intel/Makefile23
-rw-r--r--usr/src/uts/intel/Makefile.files77
-rw-r--r--usr/src/uts/intel/Makefile.intel.shared73
-rw-r--r--usr/src/uts/intel/Makefile.rules212
-rw-r--r--usr/src/uts/intel/acpica/Makefile (renamed from usr/src/uts/i86pc/acpica/Makefile)9
-rw-r--r--usr/src/uts/intel/agpgart/Makefile (renamed from usr/src/uts/i86pc/agpgart/Makefile)12
-rw-r--r--usr/src/uts/intel/agpmaster/Makefile (renamed from usr/src/uts/i86pc/agpmaster/Makefile)14
-rw-r--r--usr/src/uts/intel/agptarget/Makefile (renamed from usr/src/uts/i86pc/agptarget/Makefile)10
-rw-r--r--usr/src/uts/intel/amd64/krtld/kobj_boot.c369
-rw-r--r--usr/src/uts/intel/amd64/krtld/kobj_crt.s16
-rw-r--r--usr/src/uts/intel/amd64/ml/amd64.il169
-rw-r--r--usr/src/uts/intel/amd64/ml/mach_offsets.in9
-rw-r--r--usr/src/uts/intel/amd64/sys/Makefile8
-rw-r--r--usr/src/uts/intel/amd64/sys/kdi_regs.h97
-rw-r--r--usr/src/uts/intel/amd64/sys/privregs.h149
-rw-r--r--usr/src/uts/intel/amd64_gart/Makefile (renamed from usr/src/uts/i86pc/amd64_gart/Makefile)10
-rw-r--r--usr/src/uts/intel/ata/Makefile (renamed from usr/src/uts/i86pc/ata/Makefile)12
-rw-r--r--usr/src/uts/intel/audio810/Makefile (renamed from usr/src/uts/i86pc/audio810/Makefile)8
-rw-r--r--usr/src/uts/intel/audiohd/Makefile (renamed from usr/src/uts/i86pc/audiohd/Makefile)8
-rw-r--r--usr/src/uts/intel/audioixp/Makefile (renamed from usr/src/uts/i86pc/audioixp/Makefile)8
-rw-r--r--usr/src/uts/intel/bootdev/Makefile (renamed from usr/src/uts/i86pc/bootdev/Makefile)17
-rw-r--r--usr/src/uts/intel/ctf/Makefile4
-rw-r--r--usr/src/uts/intel/dnet/Makefile (renamed from usr/src/uts/i86pc/dnet/Makefile)12
-rw-r--r--usr/src/uts/intel/drm/Makefile (renamed from usr/src/uts/i86pc/drm/Makefile)10
-rw-r--r--usr/src/uts/intel/dtrace/dtrace_isa.c13
-rw-r--r--usr/src/uts/intel/dtrace/fasttrap_isa.c7
-rw-r--r--usr/src/uts/intel/dtrace/fbt.c16
-rw-r--r--usr/src/uts/intel/fd/Makefile (renamed from usr/src/uts/i86pc/fd/Makefile)14
-rw-r--r--usr/src/uts/intel/fdc/Makefile (renamed from usr/src/uts/i86pc/fdc/Makefile)12
-rw-r--r--usr/src/uts/intel/fs/proc/prmachdep.c9
-rw-r--r--usr/src/uts/intel/genunix/Makefile10
-rw-r--r--usr/src/uts/intel/i915/Makefile (renamed from usr/src/uts/i86pc/i915/Makefile)18
-rw-r--r--usr/src/uts/intel/ia32/krtld/kobj_boot.c347
-rw-r--r--usr/src/uts/intel/ia32/krtld/kobj_crt.s15
-rw-r--r--usr/src/uts/intel/ia32/ml/copy.s30
-rw-r--r--usr/src/uts/intel/ia32/ml/desctbls_asm.s146
-rw-r--r--usr/src/uts/intel/ia32/ml/exception.s207
-rw-r--r--usr/src/uts/intel/ia32/ml/float.s640
-rw-r--r--usr/src/uts/intel/ia32/ml/i86_subr.s803
-rw-r--r--usr/src/uts/intel/ia32/ml/ia32.il179
-rw-r--r--usr/src/uts/intel/ia32/ml/lock_prim.s53
-rw-r--r--usr/src/uts/intel/ia32/ml/sseblk.s124
-rw-r--r--usr/src/uts/intel/ia32/ml/swtch.s90
-rw-r--r--usr/src/uts/intel/ia32/os/archdep.c27
-rw-r--r--usr/src/uts/intel/ia32/os/cpc_subr.c12
-rw-r--r--usr/src/uts/intel/ia32/os/desctbls.c591
-rw-r--r--usr/src/uts/intel/ia32/os/fpu.c21
-rw-r--r--usr/src/uts/intel/ia32/os/sendsig.c8
-rw-r--r--usr/src/uts/intel/ia32/os/sundep.c195
-rw-r--r--usr/src/uts/intel/ia32/os/sysi86.c8
-rw-r--r--usr/src/uts/intel/ia32/promif/prom_enter.c9
-rw-r--r--usr/src/uts/intel/ia32/promif/prom_exit.c9
-rw-r--r--usr/src/uts/intel/ia32/promif/prom_panic.c9
-rw-r--r--usr/src/uts/intel/ia32/sys/Makefile9
-rw-r--r--usr/src/uts/intel/ia32/sys/kdi_regs.h87
-rw-r--r--usr/src/uts/intel/ia32/sys/machtypes.h28
-rw-r--r--usr/src/uts/intel/ia32/sys/privregs.h65
-rw-r--r--usr/src/uts/intel/ia32/sys/psw.h9
-rw-r--r--usr/src/uts/intel/ia32/sys/pte.h8
-rw-r--r--usr/src/uts/intel/ia32/sys/traptrace.h70
-rw-r--r--usr/src/uts/intel/ia32/syscall/lwp_private.c72
-rw-r--r--usr/src/uts/intel/io/acpica/README.txt (renamed from usr/src/uts/i86pc/io/acpica/README.txt)0
-rw-r--r--usr/src/uts/intel/io/acpica/acpi_enum.c (renamed from usr/src/uts/i86pc/io/acpica/acpi_enum.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/acpica.c (renamed from usr/src/uts/i86pc/io/acpica/acpica.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/acpica_ec.c (renamed from usr/src/uts/i86pc/io/acpica/acpica_ec.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/changes.txt (renamed from usr/src/uts/i86pc/io/acpica/changes.txt)0
-rwxr-xr-xusr/src/uts/intel/io/acpica/cmp_ca.sh (renamed from usr/src/uts/i86pc/io/acpica/cmp_ca.sh)4
-rw-r--r--usr/src/uts/intel/io/acpica/debugger/dbcmds.c (renamed from usr/src/uts/i86pc/io/acpica/debugger/dbcmds.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/debugger/dbdisply.c (renamed from usr/src/uts/i86pc/io/acpica/debugger/dbdisply.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/debugger/dbexec.c (renamed from usr/src/uts/i86pc/io/acpica/debugger/dbexec.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/debugger/dbfileio.c (renamed from usr/src/uts/i86pc/io/acpica/debugger/dbfileio.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/debugger/dbhistry.c (renamed from usr/src/uts/i86pc/io/acpica/debugger/dbhistry.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/debugger/dbinput.c (renamed from usr/src/uts/i86pc/io/acpica/debugger/dbinput.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/debugger/dbstats.c (renamed from usr/src/uts/i86pc/io/acpica/debugger/dbstats.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/debugger/dbutils.c (renamed from usr/src/uts/i86pc/io/acpica/debugger/dbutils.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/debugger/dbxface.c (renamed from usr/src/uts/i86pc/io/acpica/debugger/dbxface.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/disassembler/dmbuffer.c (renamed from usr/src/uts/i86pc/io/acpica/disassembler/dmbuffer.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/disassembler/dmnames.c (renamed from usr/src/uts/i86pc/io/acpica/disassembler/dmnames.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/disassembler/dmobject.c (renamed from usr/src/uts/i86pc/io/acpica/disassembler/dmobject.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/disassembler/dmopcode.c (renamed from usr/src/uts/i86pc/io/acpica/disassembler/dmopcode.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/disassembler/dmresrc.c (renamed from usr/src/uts/i86pc/io/acpica/disassembler/dmresrc.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/disassembler/dmresrcl.c (renamed from usr/src/uts/i86pc/io/acpica/disassembler/dmresrcl.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/disassembler/dmresrcs.c (renamed from usr/src/uts/i86pc/io/acpica/disassembler/dmresrcs.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/disassembler/dmutils.c (renamed from usr/src/uts/i86pc/io/acpica/disassembler/dmutils.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/disassembler/dmwalk.c (renamed from usr/src/uts/i86pc/io/acpica/disassembler/dmwalk.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/events/evevent.c (renamed from usr/src/uts/i86pc/io/acpica/events/evevent.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/events/evgpe.c (renamed from usr/src/uts/i86pc/io/acpica/events/evgpe.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/events/evgpeblk.c (renamed from usr/src/uts/i86pc/io/acpica/events/evgpeblk.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/events/evmisc.c (renamed from usr/src/uts/i86pc/io/acpica/events/evmisc.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/events/evregion.c (renamed from usr/src/uts/i86pc/io/acpica/events/evregion.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/events/evrgnini.c (renamed from usr/src/uts/i86pc/io/acpica/events/evrgnini.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/events/evsci.c (renamed from usr/src/uts/i86pc/io/acpica/events/evsci.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/events/evxface.c (renamed from usr/src/uts/i86pc/io/acpica/events/evxface.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/events/evxfevnt.c (renamed from usr/src/uts/i86pc/io/acpica/events/evxfevnt.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/events/evxfregn.c (renamed from usr/src/uts/i86pc/io/acpica/events/evxfregn.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/hardware/hwacpi.c (renamed from usr/src/uts/i86pc/io/acpica/hardware/hwacpi.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/hardware/hwgpe.c (renamed from usr/src/uts/i86pc/io/acpica/hardware/hwgpe.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/hardware/hwregs.c (renamed from usr/src/uts/i86pc/io/acpica/hardware/hwregs.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/hardware/hwsleep.c (renamed from usr/src/uts/i86pc/io/acpica/hardware/hwsleep.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/hardware/hwtimer.c (renamed from usr/src/uts/i86pc/io/acpica/hardware/hwtimer.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsfield.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsfield.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsinit.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsinit.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsmethod.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsmethod.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsmthdat.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsmthdat.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsobject.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsobject.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsopcode.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsopcode.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsutils.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsutils.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/dispatcher/dswexec.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dswexec.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/dispatcher/dswload.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dswload.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/dispatcher/dswscope.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dswscope.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/dispatcher/dswstate.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dswstate.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exconfig.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exconfig.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exconvrt.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exconvrt.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/excreate.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/excreate.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exdump.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exdump.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exfield.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exfield.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exfldio.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exfldio.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exmisc.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exmisc.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exmutex.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exmutex.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exnames.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exnames.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exoparg1.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exoparg1.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exoparg2.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exoparg2.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exoparg3.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exoparg3.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exoparg6.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exoparg6.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exprep.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exprep.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exregion.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exregion.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exresnte.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exresnte.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exresolv.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exresolv.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exresop.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exresop.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exstore.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exstore.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exstoren.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exstoren.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exstorob.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exstorob.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exsystem.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exsystem.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/executer/exutils.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/executer/exutils.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/parser/psargs.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/parser/psargs.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/parser/psloop.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/parser/psloop.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/parser/psopcode.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/parser/psopcode.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/parser/psparse.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/parser/psparse.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/parser/psscope.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/parser/psscope.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/parser/pstree.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/parser/pstree.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/parser/psutils.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/parser/psutils.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/parser/pswalk.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/parser/pswalk.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/interpreter/parser/psxface.c (renamed from usr/src/uts/i86pc/io/acpica/interpreter/parser/psxface.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/master_ops.c (renamed from usr/src/uts/i86pc/io/acpica/master_ops.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsaccess.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsaccess.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsalloc.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsalloc.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsdump.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsdump.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsdumpdv.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsdumpdv.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nseval.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nseval.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsinit.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsinit.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsload.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsload.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsnames.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsnames.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsobject.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsobject.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsparse.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsparse.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nssearch.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nssearch.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsutils.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsutils.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nswalk.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nswalk.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsxfeval.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsxfeval.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsxfname.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsxfname.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsxfobj.c (renamed from usr/src/uts/i86pc/io/acpica/namespace/nsxfobj.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/osl.c (renamed from usr/src/uts/i86pc/io/acpica/osl.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/osl_ml.s (renamed from usr/src/uts/i86pc/io/acpica/osl_ml.s)0
-rw-r--r--usr/src/uts/intel/io/acpica/resources/rsaddr.c (renamed from usr/src/uts/i86pc/io/acpica/resources/rsaddr.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/resources/rscalc.c (renamed from usr/src/uts/i86pc/io/acpica/resources/rscalc.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/resources/rscreate.c (renamed from usr/src/uts/i86pc/io/acpica/resources/rscreate.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/resources/rsdump.c (renamed from usr/src/uts/i86pc/io/acpica/resources/rsdump.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/resources/rsinfo.c (renamed from usr/src/uts/i86pc/io/acpica/resources/rsinfo.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/resources/rsio.c (renamed from usr/src/uts/i86pc/io/acpica/resources/rsio.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/resources/rsirq.c (renamed from usr/src/uts/i86pc/io/acpica/resources/rsirq.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/resources/rslist.c (renamed from usr/src/uts/i86pc/io/acpica/resources/rslist.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/resources/rsmemory.c (renamed from usr/src/uts/i86pc/io/acpica/resources/rsmemory.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/resources/rsmisc.c (renamed from usr/src/uts/i86pc/io/acpica/resources/rsmisc.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/resources/rsutils.c (renamed from usr/src/uts/i86pc/io/acpica/resources/rsutils.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/resources/rsxface.c (renamed from usr/src/uts/i86pc/io/acpica/resources/rsxface.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/tables/tbconvrt.c (renamed from usr/src/uts/i86pc/io/acpica/tables/tbconvrt.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/tables/tbget.c (renamed from usr/src/uts/i86pc/io/acpica/tables/tbget.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/tables/tbgetall.c (renamed from usr/src/uts/i86pc/io/acpica/tables/tbgetall.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/tables/tbinstal.c (renamed from usr/src/uts/i86pc/io/acpica/tables/tbinstal.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/tables/tbrsdt.c (renamed from usr/src/uts/i86pc/io/acpica/tables/tbrsdt.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/tables/tbutils.c (renamed from usr/src/uts/i86pc/io/acpica/tables/tbutils.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/tables/tbxface.c (renamed from usr/src/uts/i86pc/io/acpica/tables/tbxface.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/tables/tbxfroot.c (renamed from usr/src/uts/i86pc/io/acpica/tables/tbxfroot.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utalloc.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utalloc.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utcache.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utcache.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utclib.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utclib.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utcopy.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utcopy.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utdebug.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utdebug.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utdelete.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utdelete.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/uteval.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/uteval.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utglobal.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utglobal.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utinit.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utinit.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utmath.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utmath.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utmisc.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utmisc.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utmutex.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utmutex.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utobject.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utobject.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utresrc.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utresrc.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utstate.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utstate.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/uttrack.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/uttrack.c)0
-rw-r--r--usr/src/uts/intel/io/acpica/utilities/utxface.c (renamed from usr/src/uts/i86pc/io/acpica/utilities/utxface.c)0
-rw-r--r--usr/src/uts/intel/io/agpgart/agp_kstat.c (renamed from usr/src/uts/i86pc/io/agpgart/agp_kstat.c)0
-rw-r--r--usr/src/uts/intel/io/agpgart/agpgart.c (renamed from usr/src/uts/i86pc/io/agpgart/agpgart.c)0
-rw-r--r--usr/src/uts/intel/io/agpgart/agpgart.conf (renamed from usr/src/uts/i86pc/io/agpgart/agpgart.conf)0
-rw-r--r--usr/src/uts/intel/io/agpgart/agptarget.c (renamed from usr/src/uts/i86pc/io/agpgart/agptarget.c)0
-rw-r--r--usr/src/uts/intel/io/agpgart/amd64_gart.c (renamed from usr/src/uts/i86pc/io/agpgart/amd64_gart.c)0
-rw-r--r--usr/src/uts/intel/io/agpmaster/agpmaster.c (renamed from usr/src/uts/i86pc/io/agpmaster/agpmaster.c)0
-rw-r--r--usr/src/uts/intel/io/dktp/controller/ata/ata_disk.c15
-rw-r--r--usr/src/uts/intel/io/dktp/controller/ata/atapi.c6
-rw-r--r--usr/src/uts/intel/io/dnet.c (renamed from usr/src/uts/i86pc/io/dnet.c)0
-rw-r--r--usr/src/uts/intel/io/dnet.conf (renamed from usr/src/uts/i86pc/io/dnet.conf)0
-rw-r--r--usr/src/uts/intel/io/drm/drm_asm.s (renamed from usr/src/uts/i86pc/io/drm/drm_asm.s)0
-rw-r--r--usr/src/uts/intel/io/drm/i915_dma.c (renamed from usr/src/uts/i86pc/io/drm/i915_dma.c)0
-rw-r--r--usr/src/uts/intel/io/drm/i915_drm.h (renamed from usr/src/uts/i86pc/io/drm/i915_drm.h)0
-rw-r--r--usr/src/uts/intel/io/drm/i915_drv.c (renamed from usr/src/uts/i86pc/io/drm/i915_drv.c)0
-rw-r--r--usr/src/uts/intel/io/drm/i915_drv.h (renamed from usr/src/uts/i86pc/io/drm/i915_drv.h)0
-rw-r--r--usr/src/uts/intel/io/drm/i915_irq.c (renamed from usr/src/uts/i86pc/io/drm/i915_irq.c)0
-rw-r--r--usr/src/uts/intel/io/drm/i915_mem.c (renamed from usr/src/uts/i86pc/io/drm/i915_mem.c)0
-rw-r--r--usr/src/uts/intel/io/drm/i915_sundrv.c (renamed from usr/src/uts/i86pc/io/drm/i915_sundrv.c)0
-rw-r--r--usr/src/uts/intel/io/fd.conf (renamed from usr/src/uts/i86pc/io/fd.conf)0
-rw-r--r--usr/src/uts/intel/io/i8254.c (renamed from usr/src/uts/common/io/i8254.c)21
-rw-r--r--usr/src/uts/intel/io/logi.c (renamed from usr/src/uts/i86pc/io/logi.c)0
-rw-r--r--usr/src/uts/intel/io/mii.c (renamed from usr/src/uts/i86pc/io/mii.c)0
-rw-r--r--usr/src/uts/intel/io/mscsi.c (renamed from usr/src/uts/i86pc/io/mscsi.c)0
-rw-r--r--usr/src/uts/intel/io/mscsi.conf (renamed from usr/src/uts/i86pc/io/mscsi.conf)0
-rw-r--r--usr/src/uts/intel/io/msm.c (renamed from usr/src/uts/i86pc/io/msm.c)0
-rw-r--r--usr/src/uts/intel/io/pci/mps_table.h (renamed from usr/src/uts/i86pc/io/pci/mps_table.h)0
-rw-r--r--usr/src/uts/intel/io/pci/pci_autoconfig.c (renamed from usr/src/uts/i86pc/io/pci/pci_autoconfig.c)0
-rw-r--r--usr/src/uts/intel/io/pci/pci_boot.c (renamed from usr/src/uts/i86pc/io/pci/pci_boot.c)0
-rw-r--r--usr/src/uts/intel/io/pci/pci_memlist.c (renamed from usr/src/uts/i86pc/io/pci/pci_memlist.c)0
-rw-r--r--usr/src/uts/intel/io/pci/pci_pci.c (renamed from usr/src/uts/i86pc/io/pci/pci_pci.c)0
-rw-r--r--usr/src/uts/intel/io/pci/pci_resource.c (renamed from usr/src/uts/i86pc/io/pci/pci_resource.c)0
-rw-r--r--usr/src/uts/intel/io/pci/pcihrt.h (renamed from usr/src/uts/i86pc/io/pci/pcihrt.h)0
-rw-r--r--usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_acpi.c (renamed from usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_acpi.c)33
-rw-r--r--usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_acpi.h (renamed from usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_acpi.h)0
-rw-r--r--usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_nvidia.c (renamed from usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_nvidia.c)0
-rw-r--r--usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_nvidia.h (renamed from usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_nvidia.h)0
-rw-r--r--usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_x86.c (renamed from usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_x86.c)0
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_error.c (renamed from usr/src/uts/i86pc/io/pciex/pcie_error.c)0
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_error.h (renamed from usr/src/uts/i86pc/io/pciex/pcie_error.h)0
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_nvidia.c (renamed from usr/src/uts/i86pc/io/pciex/pcie_nvidia.c)0
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_nvidia.h (renamed from usr/src/uts/i86pc/io/pciex/pcie_nvidia.h)0
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_pci.c (renamed from usr/src/uts/i86pc/io/pciex/pcie_pci.c)0
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_pci.conf (renamed from usr/src/uts/i86pc/io/pciex/pcie_pci.conf)0
-rw-r--r--usr/src/uts/intel/io/smcp/smcp.c (renamed from usr/src/uts/i86pc/io/smcp/smcp.c)0
-rw-r--r--usr/src/uts/intel/io/smcp/smcp.h (renamed from usr/src/uts/i86pc/io/smcp/smcp.h)0
-rw-r--r--usr/src/uts/intel/kb8042/Makefile (renamed from usr/src/uts/i86pc/kb8042/Makefile)12
-rw-r--r--usr/src/uts/intel/kdi/amd64/kdi_asm.s641
-rw-r--r--usr/src/uts/intel/kdi/ia32/kdi_asm.s692
-rw-r--r--usr/src/uts/intel/kdi/kdi_idt.c555
-rw-r--r--usr/src/uts/intel/kdi/kdi_idthdl.s (renamed from usr/src/cmd/mdb/intel/kmdb/kaif_idthdl.s)109
-rw-r--r--usr/src/uts/intel/kdi/kdi_offsets.in (renamed from usr/src/cmd/mdb/intel/kmdb/kaif_off.in)40
-rw-r--r--usr/src/uts/intel/logi/Makefile (renamed from usr/src/uts/i86pc/logi/Makefile)12
-rw-r--r--usr/src/uts/intel/mscsi/Makefile (renamed from usr/src/uts/i86pc/mscsi/Makefile)19
-rw-r--r--usr/src/uts/intel/msm/Makefile (renamed from usr/src/uts/i86pc/msm/Makefile)12
-rw-r--r--usr/src/uts/intel/os/arch_kdi.c169
-rw-r--r--usr/src/uts/intel/pci_autoconfig/Makefile (renamed from usr/src/uts/i86pc/pci_autoconfig/Makefile)13
-rw-r--r--usr/src/uts/intel/pci_pci/Makefile (renamed from usr/src/uts/i86pc/pci_pci/Makefile)12
-rw-r--r--usr/src/uts/intel/pcic/Makefile (renamed from usr/src/uts/i86pc/pcic/Makefile)8
-rw-r--r--usr/src/uts/intel/pcie_pci/Makefile (renamed from usr/src/uts/i86pc/pcie_pci/Makefile)12
-rw-r--r--usr/src/uts/intel/pciehpc/Makefile (renamed from usr/src/uts/i86pc/pciehpc/Makefile)10
-rw-r--r--usr/src/uts/intel/power/Makefile (renamed from usr/src/uts/i86pc/power/Makefile)12
-rw-r--r--usr/src/uts/intel/swrand/Makefile3
-rw-r--r--usr/src/uts/intel/sys/Makefile4
-rw-r--r--usr/src/uts/intel/sys/archsystm.h53
-rw-r--r--usr/src/uts/intel/sys/bootconf.h20
-rw-r--r--usr/src/uts/intel/sys/bootinfo.h99
-rw-r--r--usr/src/uts/intel/sys/controlregs.h58
-rw-r--r--usr/src/uts/intel/sys/fp.h23
-rw-r--r--usr/src/uts/intel/sys/kdi_machimpl.h103
-rw-r--r--usr/src/uts/intel/sys/kdi_regs.h135
-rw-r--r--usr/src/uts/intel/sys/pmem.h (renamed from usr/src/uts/i86pc/sys/pmem.h)0
-rw-r--r--usr/src/uts/intel/sys/segments.h98
-rw-r--r--usr/src/uts/intel/sys/x86_archext.h78
-rw-r--r--usr/src/uts/intel/vuid2ps2/Makefile (renamed from usr/src/uts/i86pc/vuid2ps2/Makefile)12
-rw-r--r--usr/src/uts/intel/vuid3ps2/Makefile (renamed from usr/src/uts/i86pc/vuid3ps2/Makefile)12
-rw-r--r--usr/src/uts/intel/vuidm3p/Makefile (renamed from usr/src/uts/i86pc/vuidm3p/Makefile)12
-rw-r--r--usr/src/uts/intel/vuidm4p/Makefile (renamed from usr/src/uts/i86pc/vuidm4p/Makefile)12
-rw-r--r--usr/src/uts/intel/vuidm5p/Makefile (renamed from usr/src/uts/i86pc/vuidm5p/Makefile)12
-rw-r--r--usr/src/uts/sparc/Makefile6
-rw-r--r--usr/src/uts/sparc/Makefile.files8
-rw-r--r--usr/src/uts/sparc/Makefile.sparc.shared1
-rw-r--r--usr/src/uts/sparc/ctf/Makefile4
-rw-r--r--usr/src/uts/sparc/dtrace/fbt.c13
-rw-r--r--usr/src/uts/sparc/krtld/mapfile3
-rw-r--r--usr/src/uts/sparc/os/sundep.c9
-rw-r--r--usr/src/uts/sparc/sys/archsystm.h12
-rw-r--r--usr/src/uts/sparc/sys/kdi_machimpl.h9
-rw-r--r--usr/src/uts/sparc/v9/os/v9dep.c6
-rw-r--r--usr/src/uts/sun/sys/bootconf.h3
-rw-r--r--usr/src/uts/sun4/ml/subr_asm.s18
-rw-r--r--usr/src/uts/sun4/os/cpu_states.c5
-rw-r--r--usr/src/uts/sun4/os/dtrace_subr.c12
-rw-r--r--usr/src/uts/sun4/os/machdep.c60
-rw-r--r--usr/src/uts/sun4/os/mlsetup.c2
-rw-r--r--usr/src/uts/sun4/os/prom_subr.c10
-rw-r--r--usr/src/uts/sun4/os/startup.c15
-rw-r--r--usr/src/uts/sun4u/Makefile9
-rw-r--r--usr/src/uts/sun4u/Makefile.sun4u.shared7
-rw-r--r--usr/src/uts/sun4u/boston/Makefile3
-rw-r--r--usr/src/uts/sun4u/boston/Makefile.boston3
-rw-r--r--usr/src/uts/sun4u/boston/Makefile.targ5
-rw-r--r--usr/src/uts/sun4u/mpxu/Makefile8
-rw-r--r--usr/src/uts/sun4u/mpxu/Makefile.mpxu.shared3
-rw-r--r--usr/src/uts/sun4u/mpxu/Makefile.targ.shared10
-rw-r--r--usr/src/uts/sun4u/opl/Makefile3
-rw-r--r--usr/src/uts/sun4u/opl/Makefile.opl.shared3
-rw-r--r--usr/src/uts/sun4u/opl/Makefile.targ.shared5
-rw-r--r--usr/src/uts/sun4u/os/cpr_impl.c111
-rw-r--r--usr/src/uts/sun4u/os/mach_trap.c9
-rw-r--r--usr/src/uts/sun4u/schumacher/Makefile8
-rw-r--r--usr/src/uts/sun4u/schumacher/Makefile.schumacher8
-rw-r--r--usr/src/uts/sun4u/schumacher/Makefile.targ10
-rw-r--r--usr/src/uts/sun4u/seattle/Makefile3
-rw-r--r--usr/src/uts/sun4u/seattle/Makefile.seattle3
-rw-r--r--usr/src/uts/sun4u/seattle/Makefile.targ5
-rw-r--r--usr/src/uts/sun4u/snowbird/Makefile8
-rw-r--r--usr/src/uts/sun4u/snowbird/Makefile.snowbird3
-rw-r--r--usr/src/uts/sun4u/snowbird/Makefile.targ10
-rw-r--r--usr/src/uts/sun4u/sys/cpr_impl.h9
-rw-r--r--usr/src/uts/sun4u/sys/machparam.h8
-rw-r--r--usr/src/uts/sun4u/vm/mach_kpm.c12
-rw-r--r--usr/src/uts/sun4v/Makefile4
-rw-r--r--usr/src/uts/sun4v/Makefile.sun4v.shared5
-rw-r--r--usr/src/uts/sun4v/os/mach_trap.c9
-rw-r--r--usr/src/uts/sun4v/sys/machparam.h8
-rw-r--r--usr/src/xmod/xmod_files4
780 files changed, 31254 insertions, 18941 deletions
diff --git a/usr/src/cmd/eeprom/common/Makefile b/deleted_files/usr/src/cmd/eeprom/common/Makefile
index 9828df5a79..9828df5a79 100644
--- a/usr/src/cmd/eeprom/common/Makefile
+++ b/deleted_files/usr/src/cmd/eeprom/common/Makefile
diff --git a/usr/src/cmd/eeprom/eeprom.xml b/deleted_files/usr/src/cmd/eeprom/eeprom.xml
index 48db9f3599..48db9f3599 100644
--- a/usr/src/cmd/eeprom/eeprom.xml
+++ b/deleted_files/usr/src/cmd/eeprom/eeprom.xml
diff --git a/usr/src/cmd/eeprom/i386/common/benv_sync.c b/deleted_files/usr/src/cmd/eeprom/i386/common/benv_sync.c
index 5faf7e68ab..5faf7e68ab 100644
--- a/usr/src/cmd/eeprom/i386/common/benv_sync.c
+++ b/deleted_files/usr/src/cmd/eeprom/i386/common/benv_sync.c
diff --git a/usr/src/cmd/eeprom/i386/i86pc/Makefile b/deleted_files/usr/src/cmd/eeprom/i386/i86pc/Makefile
index da26f7f3a7..da26f7f3a7 100644
--- a/usr/src/cmd/eeprom/i386/i86pc/Makefile
+++ b/deleted_files/usr/src/cmd/eeprom/i386/i86pc/Makefile
diff --git a/usr/src/cmd/eeprom/sparc/sun4u/Makefile b/deleted_files/usr/src/cmd/eeprom/sparc/sun4u/Makefile
index 2cb9c73cfb..2cb9c73cfb 100644
--- a/usr/src/cmd/eeprom/sparc/sun4u/Makefile
+++ b/deleted_files/usr/src/cmd/eeprom/sparc/sun4u/Makefile
diff --git a/usr/src/cmd/eeprom/sparc/sun4v/Makefile b/deleted_files/usr/src/cmd/eeprom/sparc/sun4v/Makefile
index d4cb137cff..d4cb137cff 100644
--- a/usr/src/cmd/eeprom/sparc/sun4v/Makefile
+++ b/deleted_files/usr/src/cmd/eeprom/sparc/sun4v/Makefile
diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_kdi_impl.h b/deleted_files/usr/src/cmd/mdb/common/kmdb/kmdb_kdi_impl.h
index 3ff5deb4ee..3ff5deb4ee 100644
--- a/usr/src/cmd/mdb/common/kmdb/kmdb_kdi_impl.h
+++ b/deleted_files/usr/src/cmd/mdb/common/kmdb/kmdb_kdi_impl.h
diff --git a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.h b/deleted_files/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.h
index 6abe1ba166..6abe1ba166 100644
--- a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.h
+++ b/deleted_files/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.h
diff --git a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.s b/deleted_files/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.s
index 4861bcc476..4861bcc476 100644
--- a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.s
+++ b/deleted_files/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.s
diff --git a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_resume.s b/deleted_files/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_resume.s
index 8574be2336..8574be2336 100644
--- a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_resume.s
+++ b/deleted_files/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_resume.s
diff --git a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.h b/deleted_files/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.h
index 0ed570f1d2..0ed570f1d2 100644
--- a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.h
+++ b/deleted_files/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.h
diff --git a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.s b/deleted_files/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.s
index f695047c52..f695047c52 100644
--- a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.s
+++ b/deleted_files/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.s
diff --git a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_resume.s b/deleted_files/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_resume.s
index c9693b8212..c9693b8212 100644
--- a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_resume.s
+++ b/deleted_files/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_resume.s
diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif_activate.c b/deleted_files/usr/src/cmd/mdb/intel/kmdb/kaif_activate.c
index 17294e5bb7..17294e5bb7 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kaif_activate.c
+++ b/deleted_files/usr/src/cmd/mdb/intel/kmdb/kaif_activate.c
diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif_start_isadep.c b/deleted_files/usr/src/cmd/mdb/intel/kmdb/kaif_start_isadep.c
index 708cbb390c..708cbb390c 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kaif_start_isadep.c
+++ b/deleted_files/usr/src/cmd/mdb/intel/kmdb/kaif_start_isadep.c
diff --git a/usr/src/cmd/mdb/sparc/kmdb/kaif_enter.s b/deleted_files/usr/src/cmd/mdb/sparc/kmdb/kaif_enter.s
index 4275773a71..4275773a71 100644
--- a/usr/src/cmd/mdb/sparc/kmdb/kaif_enter.s
+++ b/deleted_files/usr/src/cmd/mdb/sparc/kmdb/kaif_enter.s
diff --git a/usr/src/cmd/prtdiag/i386/i86pc/Makefile b/deleted_files/usr/src/cmd/prtdiag/i386/i86pc/Makefile
index 77891ef8e4..77891ef8e4 100644
--- a/usr/src/cmd/prtdiag/i386/i86pc/Makefile
+++ b/deleted_files/usr/src/cmd/prtdiag/i386/i86pc/Makefile
diff --git a/usr/src/cmd/svc/profile/platform_i86pc.xml b/deleted_files/usr/src/cmd/svc/profile/platform_i86pc.xml
index 3c196487c1..3c196487c1 100644
--- a/usr/src/cmd/svc/profile/platform_i86pc.xml
+++ b/deleted_files/usr/src/cmd/svc/profile/platform_i86pc.xml
diff --git a/usr/src/psm/stand/boot/amd64/alloc.c b/deleted_files/usr/src/psm/stand/boot/amd64/alloc.c
index 4da403f0e1..4da403f0e1 100644
--- a/usr/src/psm/stand/boot/amd64/alloc.c
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/alloc.c
diff --git a/usr/src/psm/stand/boot/amd64/amd64/alloc.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/alloc.h
index ba6a8c8da5..ba6a8c8da5 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/alloc.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/alloc.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/amd64.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/amd64.h
index c7518b84c8..c7518b84c8 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/amd64.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/amd64.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/amd64_page.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/amd64_page.h
index c2e7115205..c2e7115205 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/amd64_page.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/amd64_page.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/auxv64.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/auxv64.h
index 42e897e7ce..42e897e7ce 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/auxv64.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/auxv64.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/boothooks.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/boothooks.h
index becc1ef9b9..becc1ef9b9 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/boothooks.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/boothooks.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/bootops64.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/bootops64.h
index e45872ca47..e45872ca47 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/bootops64.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/bootops64.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/bootsvcs64.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/bootsvcs64.h
index 4fd533e2df..4fd533e2df 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/bootsvcs64.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/bootsvcs64.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/cpu.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/cpu.h
index 9f035799f3..9f035799f3 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/cpu.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/cpu.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/debug.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/debug.h
index d62d24c927..d62d24c927 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/debug.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/debug.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/machregs.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/machregs.h
index 6784059966..6784059966 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/machregs.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/machregs.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/memlist64.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/memlist64.h
index ce3978e1e8..ce3978e1e8 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/memlist64.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/memlist64.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/msr.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/msr.h
index 4bbba75b9b..4bbba75b9b 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/msr.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/msr.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/print.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/print.h
index 0db7816902..0db7816902 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/print.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/print.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/segments.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/segments.h
index 478fc99790..478fc99790 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/segments.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/segments.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/tss.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/tss.h
index 1aff429e8d..1aff429e8d 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/tss.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/tss.h
diff --git a/usr/src/psm/stand/boot/amd64/amd64/types.h b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/types.h
index 127effff25..127effff25 100644
--- a/usr/src/psm/stand/boot/amd64/amd64/types.h
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/amd64/types.h
diff --git a/usr/src/psm/stand/boot/amd64/context.c b/deleted_files/usr/src/psm/stand/boot/amd64/context.c
index 7fb2d61c7f..7fb2d61c7f 100644
--- a/usr/src/psm/stand/boot/amd64/context.c
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/context.c
diff --git a/usr/src/psm/stand/boot/amd64/cpu.c b/deleted_files/usr/src/psm/stand/boot/amd64/cpu.c
index 668d2f17e6..668d2f17e6 100644
--- a/usr/src/psm/stand/boot/amd64/cpu.c
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/cpu.c
diff --git a/usr/src/psm/stand/boot/amd64/exception.s b/deleted_files/usr/src/psm/stand/boot/amd64/exception.s
index 0d696a6120..0d696a6120 100644
--- a/usr/src/psm/stand/boot/amd64/exception.s
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/exception.s
diff --git a/usr/src/psm/stand/boot/amd64/genassym.c b/deleted_files/usr/src/psm/stand/boot/amd64/genassym.c
index cba7592a16..cba7592a16 100644
--- a/usr/src/psm/stand/boot/amd64/genassym.c
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/genassym.c
diff --git a/usr/src/psm/stand/boot/amd64/handoff.c b/deleted_files/usr/src/psm/stand/boot/amd64/handoff.c
index dafc7ad751..dafc7ad751 100644
--- a/usr/src/psm/stand/boot/amd64/handoff.c
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/handoff.c
diff --git a/usr/src/psm/stand/boot/amd64/i386_subr.s b/deleted_files/usr/src/psm/stand/boot/amd64/i386_subr.s
index 2f4846e927..2f4846e927 100644
--- a/usr/src/psm/stand/boot/amd64/i386_subr.s
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/i386_subr.s
diff --git a/usr/src/psm/stand/boot/amd64/locore.s b/deleted_files/usr/src/psm/stand/boot/amd64/locore.s
index a127e02f05..a127e02f05 100644
--- a/usr/src/psm/stand/boot/amd64/locore.s
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/locore.s
diff --git a/usr/src/psm/stand/boot/amd64/memlist.c b/deleted_files/usr/src/psm/stand/boot/amd64/memlist.c
index da62480d1d..da62480d1d 100644
--- a/usr/src/psm/stand/boot/amd64/memlist.c
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/memlist.c
diff --git a/usr/src/psm/stand/boot/amd64/offsets.in b/deleted_files/usr/src/psm/stand/boot/amd64/offsets.in
index b07ea48e76..b07ea48e76 100644
--- a/usr/src/psm/stand/boot/amd64/offsets.in
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/offsets.in
diff --git a/usr/src/psm/stand/boot/amd64/print.c b/deleted_files/usr/src/psm/stand/boot/amd64/print.c
index 7f2f7f3aef..7f2f7f3aef 100644
--- a/usr/src/psm/stand/boot/amd64/print.c
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/print.c
diff --git a/usr/src/psm/stand/boot/amd64/ptops.c b/deleted_files/usr/src/psm/stand/boot/amd64/ptops.c
index 3b6244efe9..3b6244efe9 100644
--- a/usr/src/psm/stand/boot/amd64/ptops.c
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/ptops.c
diff --git a/usr/src/psm/stand/boot/amd64/ptxlate.c b/deleted_files/usr/src/psm/stand/boot/amd64/ptxlate.c
index 80e20f783a..80e20f783a 100644
--- a/usr/src/psm/stand/boot/amd64/ptxlate.c
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/ptxlate.c
diff --git a/usr/src/psm/stand/boot/amd64/segments.c b/deleted_files/usr/src/psm/stand/boot/amd64/segments.c
index f384110045..f384110045 100644
--- a/usr/src/psm/stand/boot/amd64/segments.c
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/segments.c
diff --git a/usr/src/psm/stand/boot/amd64/vtrap.c b/deleted_files/usr/src/psm/stand/boot/amd64/vtrap.c
index 95c4ee32a4..95c4ee32a4 100644
--- a/usr/src/psm/stand/boot/amd64/vtrap.c
+++ b/deleted_files/usr/src/psm/stand/boot/amd64/vtrap.c
diff --git a/usr/src/psm/stand/boot/i386/Makefile b/deleted_files/usr/src/psm/stand/boot/i386/Makefile
index ad7f5d24a0..ad7f5d24a0 100644
--- a/usr/src/psm/stand/boot/i386/Makefile
+++ b/deleted_files/usr/src/psm/stand/boot/i386/Makefile
diff --git a/usr/src/psm/stand/boot/i386/Makefile.com b/deleted_files/usr/src/psm/stand/boot/i386/Makefile.com
index 06e00ac095..06e00ac095 100644
--- a/usr/src/psm/stand/boot/i386/Makefile.com
+++ b/deleted_files/usr/src/psm/stand/boot/i386/Makefile.com
diff --git a/usr/src/psm/stand/boot/i386/common/bios.c b/deleted_files/usr/src/psm/stand/boot/i386/common/bios.c
index e80d0ad55d..e80d0ad55d 100644
--- a/usr/src/psm/stand/boot/i386/common/bios.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/bios.c
diff --git a/usr/src/psm/stand/boot/i386/common/biosint.h b/deleted_files/usr/src/psm/stand/boot/i386/common/biosint.h
index 0372ed078a..0372ed078a 100644
--- a/usr/src/psm/stand/boot/i386/common/biosint.h
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/biosint.h
diff --git a/usr/src/psm/stand/boot/i386/common/biosint.map b/deleted_files/usr/src/psm/stand/boot/i386/common/biosint.map
index 8780bf99b3..8780bf99b3 100644
--- a/usr/src/psm/stand/boot/i386/common/biosint.map
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/biosint.map
diff --git a/usr/src/psm/stand/boot/i386/common/biosutil.c b/deleted_files/usr/src/psm/stand/boot/i386/common/biosutil.c
index ad262ae4b4..ad262ae4b4 100644
--- a/usr/src/psm/stand/boot/i386/common/biosutil.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/biosutil.c
diff --git a/usr/src/psm/stand/boot/i386/common/boot_plat.c b/deleted_files/usr/src/psm/stand/boot/i386/common/boot_plat.c
index 3de61380da..3de61380da 100644
--- a/usr/src/psm/stand/boot/i386/common/boot_plat.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/boot_plat.c
diff --git a/usr/src/psm/stand/boot/i386/common/boot_ramdisk.c b/deleted_files/usr/src/psm/stand/boot/i386/common/boot_ramdisk.c
index b380e3149c..b380e3149c 100644
--- a/usr/src/psm/stand/boot/i386/common/boot_ramdisk.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/boot_ramdisk.c
diff --git a/usr/src/psm/stand/boot/i386/common/bootenv.c b/deleted_files/usr/src/psm/stand/boot/i386/common/bootenv.c
index 30eb186b93..30eb186b93 100644
--- a/usr/src/psm/stand/boot/i386/common/bootenv.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/bootenv.c
diff --git a/usr/src/psm/stand/boot/i386/common/bootflags.c b/deleted_files/usr/src/psm/stand/boot/i386/common/bootflags.c
index 26bd0de1b8..26bd0de1b8 100644
--- a/usr/src/psm/stand/boot/i386/common/bootflags.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/bootflags.c
diff --git a/usr/src/psm/stand/boot/i386/common/bootops.c b/deleted_files/usr/src/psm/stand/boot/i386/common/bootops.c
index b7fe051099..b7fe051099 100644
--- a/usr/src/psm/stand/boot/i386/common/bootops.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/bootops.c
diff --git a/usr/src/psm/stand/boot/i386/common/bootprop.c b/deleted_files/usr/src/psm/stand/boot/i386/common/bootprop.c
index 466f27338b..466f27338b 100644
--- a/usr/src/psm/stand/boot/i386/common/bootprop.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/bootprop.c
diff --git a/usr/src/psm/stand/boot/i386/common/bootprop.h b/deleted_files/usr/src/psm/stand/boot/i386/common/bootprop.h
index 7c25e8e69d..7c25e8e69d 100644
--- a/usr/src/psm/stand/boot/i386/common/bootprop.h
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/bootprop.h
diff --git a/usr/src/psm/stand/boot/i386/common/chario.h b/deleted_files/usr/src/psm/stand/boot/i386/common/chario.h
index 7023c17134..7023c17134 100644
--- a/usr/src/psm/stand/boot/i386/common/chario.h
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/chario.h
diff --git a/usr/src/psm/stand/boot/i386/common/check_iopath.c b/deleted_files/usr/src/psm/stand/boot/i386/common/check_iopath.c
index fb842546f0..fb842546f0 100644
--- a/usr/src/psm/stand/boot/i386/common/check_iopath.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/check_iopath.c
diff --git a/usr/src/psm/stand/boot/i386/common/cpu_id.h b/deleted_files/usr/src/psm/stand/boot/i386/common/cpu_id.h
index 8948d8031b..8948d8031b 100644
--- a/usr/src/psm/stand/boot/i386/common/cpu_id.h
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/cpu_id.h
diff --git a/usr/src/psm/stand/boot/i386/common/debug.h b/deleted_files/usr/src/psm/stand/boot/i386/common/debug.h
index 858cb21245..858cb21245 100644
--- a/usr/src/psm/stand/boot/i386/common/debug.h
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/debug.h
diff --git a/usr/src/psm/stand/boot/i386/common/i86.il b/deleted_files/usr/src/psm/stand/boot/i386/common/i86.il
index 180cb5135a..180cb5135a 100644
--- a/usr/src/psm/stand/boot/i386/common/i86.il
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/i86.il
diff --git a/usr/src/psm/stand/boot/i386/common/machine.h b/deleted_files/usr/src/psm/stand/boot/i386/common/machine.h
index d841cb8526..d841cb8526 100644
--- a/usr/src/psm/stand/boot/i386/common/machine.h
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/machine.h
diff --git a/usr/src/psm/stand/boot/i386/common/mapfile b/deleted_files/usr/src/psm/stand/boot/i386/common/mapfile
index 85a3c88c5d..85a3c88c5d 100644
--- a/usr/src/psm/stand/boot/i386/common/mapfile
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/mapfile
diff --git a/usr/src/psm/stand/boot/i386/common/memory.c b/deleted_files/usr/src/psm/stand/boot/i386/common/memory.c
index 591c7781fe..591c7781fe 100644
--- a/usr/src/psm/stand/boot/i386/common/memory.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/memory.c
diff --git a/usr/src/psm/stand/boot/i386/common/mkbin.c b/deleted_files/usr/src/psm/stand/boot/i386/common/mkbin.c
index 423ecec781..423ecec781 100644
--- a/usr/src/psm/stand/boot/i386/common/mkbin.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/mkbin.c
diff --git a/usr/src/psm/stand/boot/i386/common/multiboot.c b/deleted_files/usr/src/psm/stand/boot/i386/common/multiboot.c
index 79bacf01ba..79bacf01ba 100644
--- a/usr/src/psm/stand/boot/i386/common/multiboot.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/multiboot.c
diff --git a/usr/src/psm/stand/boot/i386/common/multiboot.h b/deleted_files/usr/src/psm/stand/boot/i386/common/multiboot.h
index 7674c16faf..7674c16faf 100644
--- a/usr/src/psm/stand/boot/i386/common/multiboot.h
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/multiboot.h
diff --git a/usr/src/psm/stand/boot/i386/common/standalloc.c b/deleted_files/usr/src/psm/stand/boot/i386/common/standalloc.c
index 4e8af8667a..4e8af8667a 100644
--- a/usr/src/psm/stand/boot/i386/common/standalloc.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/standalloc.c
diff --git a/usr/src/psm/stand/boot/i386/common/standalloc.h b/deleted_files/usr/src/psm/stand/boot/i386/common/standalloc.h
index ee99de104b..ee99de104b 100644
--- a/usr/src/psm/stand/boot/i386/common/standalloc.h
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/standalloc.h
diff --git a/usr/src/psm/stand/boot/i386/common/util.h b/deleted_files/usr/src/psm/stand/boot/i386/common/util.h
index 0aa18da2a6..0aa18da2a6 100644
--- a/usr/src/psm/stand/boot/i386/common/util.h
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/util.h
diff --git a/usr/src/psm/stand/boot/i386/common/vgaprobe.c b/deleted_files/usr/src/psm/stand/boot/i386/common/vgaprobe.c
index d93df5a3ac..d93df5a3ac 100644
--- a/usr/src/psm/stand/boot/i386/common/vgaprobe.c
+++ b/deleted_files/usr/src/psm/stand/boot/i386/common/vgaprobe.c
diff --git a/usr/src/psm/stand/boot/i386/i86pc/Makefile b/deleted_files/usr/src/psm/stand/boot/i386/i86pc/Makefile
index 672e381b2c..672e381b2c 100644
--- a/usr/src/psm/stand/boot/i386/i86pc/Makefile
+++ b/deleted_files/usr/src/psm/stand/boot/i386/i86pc/Makefile
diff --git a/usr/src/psm/stand/boot/i386/i86pc/asm.s b/deleted_files/usr/src/psm/stand/boot/i386/i86pc/asm.s
index 27dbb67aac..27dbb67aac 100644
--- a/usr/src/psm/stand/boot/i386/i86pc/asm.s
+++ b/deleted_files/usr/src/psm/stand/boot/i386/i86pc/asm.s
diff --git a/usr/src/psm/stand/boot/i386/i86pc/biosint.s b/deleted_files/usr/src/psm/stand/boot/i386/i86pc/biosint.s
index dd5326c9e5..dd5326c9e5 100644
--- a/usr/src/psm/stand/boot/i386/i86pc/biosint.s
+++ b/deleted_files/usr/src/psm/stand/boot/i386/i86pc/biosint.s
diff --git a/usr/src/psm/stand/boot/i386/i86pc/cpu_id.s b/deleted_files/usr/src/psm/stand/boot/i386/i86pc/cpu_id.s
index 8301a2a3b0..8301a2a3b0 100644
--- a/usr/src/psm/stand/boot/i386/i86pc/cpu_id.s
+++ b/deleted_files/usr/src/psm/stand/boot/i386/i86pc/cpu_id.s
diff --git a/usr/src/psm/stand/boot/i386/i86pc/idttab.s b/deleted_files/usr/src/psm/stand/boot/i386/i86pc/idttab.s
index f205856ab6..f205856ab6 100644
--- a/usr/src/psm/stand/boot/i386/i86pc/idttab.s
+++ b/deleted_files/usr/src/psm/stand/boot/i386/i86pc/idttab.s
diff --git a/usr/src/psm/stand/boot/i386/i86pc/samuldiv64.s b/deleted_files/usr/src/psm/stand/boot/i386/i86pc/samuldiv64.s
index fae6774331..fae6774331 100644
--- a/usr/src/psm/stand/boot/i386/i86pc/samuldiv64.s
+++ b/deleted_files/usr/src/psm/stand/boot/i386/i86pc/samuldiv64.s
diff --git a/usr/src/uts/common/zmod/mapfile b/deleted_files/usr/src/uts/common/zmod/mapfile
index 460b10cc10..460b10cc10 100644
--- a/usr/src/uts/common/zmod/mapfile
+++ b/deleted_files/usr/src/uts/common/zmod/mapfile
diff --git a/usr/src/uts/intel/amd64/Makefile.rules b/deleted_files/usr/src/uts/intel/amd64/Makefile.rules
index 83dfec5f2a..83dfec5f2a 100644
--- a/usr/src/uts/intel/amd64/Makefile.rules
+++ b/deleted_files/usr/src/uts/intel/amd64/Makefile.rules
diff --git a/usr/src/uts/intel/ia32/Makefile.rules b/deleted_files/usr/src/uts/intel/ia32/Makefile.rules
index d8b526458e..d8b526458e 100644
--- a/usr/src/uts/intel/ia32/Makefile.rules
+++ b/deleted_files/usr/src/uts/intel/ia32/Makefile.rules
diff --git a/usr/src/uts/intel/ia32/os/arch_kdi.c b/deleted_files/usr/src/uts/intel/ia32/os/arch_kdi.c
index 2ac020245a..2ac020245a 100644
--- a/usr/src/uts/intel/ia32/os/arch_kdi.c
+++ b/deleted_files/usr/src/uts/intel/ia32/os/arch_kdi.c
diff --git a/usr/src/uts/intel/ia32/sys/mmu.h b/deleted_files/usr/src/uts/intel/ia32/sys/mmu.h
index 135882602a..135882602a 100644
--- a/usr/src/uts/intel/ia32/sys/mmu.h
+++ b/deleted_files/usr/src/uts/intel/ia32/sys/mmu.h
diff --git a/usr/src/uts/intel/krtld/Makefile b/deleted_files/usr/src/uts/intel/krtld/Makefile
index 9b88eaad0a..9b88eaad0a 100644
--- a/usr/src/uts/intel/krtld/Makefile
+++ b/deleted_files/usr/src/uts/intel/krtld/Makefile
diff --git a/usr/src/uts/intel/sys/immu.h b/deleted_files/usr/src/uts/intel/sys/immu.h
index ac9af15bf6..ac9af15bf6 100644
--- a/usr/src/uts/intel/sys/immu.h
+++ b/deleted_files/usr/src/uts/intel/sys/immu.h
diff --git a/usr/src/uts/intel/sys/mmu.h b/deleted_files/usr/src/uts/intel/sys/mmu.h
index 167a7ee895..167a7ee895 100644
--- a/usr/src/uts/intel/sys/mmu.h
+++ b/deleted_files/usr/src/uts/intel/sys/mmu.h
diff --git a/usr/src/uts/intel/zmod/Makefile b/deleted_files/usr/src/uts/intel/zmod/Makefile
index 267187911e..267187911e 100644
--- a/usr/src/uts/intel/zmod/Makefile
+++ b/deleted_files/usr/src/uts/intel/zmod/Makefile
diff --git a/usr/src/uts/sparc/zmod/Makefile b/deleted_files/usr/src/uts/sparc/zmod/Makefile
index 2cd46b6a11..2cd46b6a11 100644
--- a/usr/src/uts/sparc/zmod/Makefile
+++ b/deleted_files/usr/src/uts/sparc/zmod/Makefile
diff --git a/usr/src/Makefile.master b/usr/src/Makefile.master
index e43a36e3b7..a433e01aa7 100644
--- a/usr/src/Makefile.master
+++ b/usr/src/Makefile.master
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -132,6 +132,8 @@ SFWLIBDIR64= $(SFW_ROOT)/lib/$(MACH64)
RPCGEN= /usr/bin/rpcgen
STABS= $(ONBLD_TOOLS)/bin/$(MACH)/stabs
+ELFEXTRACT= $(ONBLD_TOOLS)/bin/$(MACH)/elfextract
+MBH_PATCH= $(ONBLD_TOOLS)/bin/$(MACH)/mbh_patch
ECHO= echo
INS= install
TRUE= true
diff --git a/usr/src/Makefile.psm b/usr/src/Makefile.psm
index 7528b5af60..dfcb70c8eb 100644
--- a/usr/src/Makefile.psm
+++ b/usr/src/Makefile.psm
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -180,6 +179,8 @@ ROOT_US3_CRYPTO_DIR_64 = $(ROOT_US3_MOD_DIR)/crypto/$(SUBDIR64)
ROOT_US3_CRYPTO_DIR = $(ROOT_US3_CRYPTO_DIR_$(CLASS))
ROOT_US3_CRYPTO_LINK = $(ROOT_US3_CRYPTO_DIR_64:$(ROOT_PLAT_DIR)%=../../../..%)
+ROOT_BOOT_PSM_KERN_DIR = $(ROOT)/boot/platform/$(PLATFORM)/kernel
+
#
# The following are for the installation of objects in PSM directories.
#
diff --git a/usr/src/Makefile.psm.targ b/usr/src/Makefile.psm.targ
index 5c70a081ef..fce4f698e0 100644
--- a/usr/src/Makefile.psm.targ
+++ b/usr/src/Makefile.psm.targ
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -36,6 +35,9 @@ $(ROOT_PLAT_DIR) $(USR_PLAT_DIR):
$(ROOT_PSM_DIR): $(ROOT_PLAT_DIR)
-$(INS.dir.root.sys)
+$(ROOT_BOOT_PSM_KERN_DIR):
+ -$(INS.dir.root.sys)
+
$(ROOT_PSM_LIB_DIR) \
$(ROOT_PSM_SBIN_DIR): $(ROOT_PSM_DIR)
-$(INS.dir.root.sys)
diff --git a/usr/src/Targetdirs b/usr/src/Targetdirs
index bba9d08d16..0872287d8a 100644
--- a/usr/src/Targetdirs
+++ b/usr/src/Targetdirs
@@ -54,7 +54,8 @@ i386_ROOT.SYS= \
/boot/grub \
/boot/grub/bin \
/boot/solaris \
- /boot/solaris/bin
+ /boot/solaris/bin \
+ /platform/i86pc
sparc_ROOT.SYS=
@@ -173,7 +174,6 @@ ROOT.SYS= \
/var/svc/manifest/application/security \
/var/svc/manifest/application/print \
/var/svc/manifest/platform \
- /var/svc/manifest/platform/i86pc \
/var/svc/manifest/platform/sun4u \
/var/svc/manifest/platform/sun4v \
/var/svc/manifest/site \
@@ -320,7 +320,8 @@ sparcv9_ROOT.BIN64= \
/usr/platform/sun4u-us3/lib \
/usr/platform/sun4u-opl/lib
-amd64_ROOT.BIN64=
+amd64_ROOT.BIN64= \
+ /platform/i86pc/amd64
ROOT.BIN64= \
$($(MACH64)_ROOT.BIN64) \
diff --git a/usr/src/cmd/Makefile.cmd b/usr/src/cmd/Makefile.cmd
index 791f10dbbd..4730cb6506 100644
--- a/usr/src/cmd/Makefile.cmd
+++ b/usr/src/cmd/Makefile.cmd
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -208,7 +208,6 @@ ROOTSVCNETWORKSECURITY= $(ROOTSVCNETWORK)/security
ROOTSVCNETWORKSSL= $(ROOTSVCNETWORK)/ssl
ROOTSVCNETWORKSHARES= $(ROOTSVCNETWORK)/shares
ROOTSVCPLATFORM= $(ROOTVARSVCMANIFEST)/platform
-ROOTSVCPLATFORMI86PC= $(ROOTSVCPLATFORM)/i86pc
ROOTSVCPLATFORMSUN4U= $(ROOTSVCPLATFORM)/sun4u
ROOTSVCPLATFORMSUN4V= $(ROOTSVCPLATFORM)/sun4v
ROOTSVCAPPLICATION= $(ROOTVARSVCMANIFEST)/application
@@ -385,9 +384,6 @@ $(ROOTSVCAPPLICATIONPRINT)/%: %
$(ROOTSVCPLATFORM)/%: %
$(INS.file)
-$(ROOTSVCPLATFORMI86PC)/%: %
- $(INS.file)
-
$(ROOTSVCPLATFORMSUN4U)/%: %
$(INS.file)
diff --git a/usr/src/cmd/boot/Makefile b/usr/src/cmd/boot/Makefile
index a1dcfd5a18..51b1ebf3d8 100644
--- a/usr/src/cmd/boot/Makefile
+++ b/usr/src/cmd/boot/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -35,7 +35,8 @@ COMMON_SUBDIRS= \
i386_SUBDIRS= \
installgrub \
- mbr
+ mbr \
+ symdef
sparc_SUBDIRS=
@@ -43,7 +44,8 @@ COMMON_LINTSUBDIRS= \
bootadm
i386_LINTSUBDIRS= \
- installgrub
+ installgrub \
+ symdef
sparc_LINTSUBDIRS=
diff --git a/usr/src/cmd/boot/bootadm/Makefile b/usr/src/cmd/boot/bootadm/Makefile
index a71f5bf32a..fc4a370cef 100644
--- a/usr/src/cmd/boot/bootadm/Makefile
+++ b/usr/src/cmd/boot/bootadm/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -31,7 +31,7 @@ i386_DATA= filelist.ramdisk filelist.safe
SBINLINKS= $(PROG)
-OBJS = bootadm.o
+OBJS= bootadm.o bootadm_upgrade.o
SRCS = $(OBJS:.o=.c)
include ../Makefile.com
@@ -52,9 +52,13 @@ LDLIBS += -lnvpair
CFLAGS += $(XSTRCONST)
CPPFLAGS += -D_FILE_OFFSET_BITS=64
+# Add paths to pick up headers
+CFLAGS += -I../../../uts/common
+LINTFLAGS += -I../../../uts/common
+
all: $(PROG)
-$(PROG): $(OBJS)
+$(PROG): $(OBJS) bootadm.h
$(LINK.c) -o $@ $(OBJS) $(LDLIBS)
$(POST_PROCESS)
@@ -64,9 +68,10 @@ $(ROOTUSRSBINLINKS):
install: all $(ROOTSBINPROG) $(ROOTBOOTSOLARISDATA) .WAIT $(ROOTUSRSBINLINKS)
clean:
+ -$(RM) $(OBJS)
_msg:
-lint: lint_PROG
+lint: lint_SRCS
include ../Makefile.targ
diff --git a/usr/src/cmd/boot/bootadm/bootadm.c b/usr/src/cmd/boot/bootadm/bootadm.c
index 80c2b75592..2475aba1d3 100644
--- a/usr/src/cmd/boot/bootadm/bootadm.c
+++ b/usr/src/cmd/boot/bootadm/bootadm.c
@@ -58,12 +58,12 @@
#include <grp.h>
#include <device_info.h>
-#include <libintl.h>
#include <locale.h>
#include <assert.h>
#include "message.h"
+#include "bootadm.h"
#ifndef TEXT_DOMAIN
#define TEXT_DOMAIN "SUNW_OST_OSCMD"
@@ -77,56 +77,12 @@ typedef enum {
BAM_ARCHIVE
} subcmd_t;
-/* GRUB menu per-line classification */
-typedef enum {
- BAM_INVALID = 0,
- BAM_EMPTY,
- BAM_COMMENT,
- BAM_GLOBAL,
- BAM_ENTRY,
- BAM_TITLE
-} menu_flag_t;
-
-/* struct for menu.lst contents */
-typedef struct line {
- int lineNum; /* Line number in menu.lst */
- int entryNum; /* menu boot entry #. ENTRY_INIT if not applicable */
- char *cmd;
- char *sep;
- char *arg;
- char *line;
- menu_flag_t flags;
- struct line *next;
- struct line *prev;
-} line_t;
-
-typedef struct entry {
- struct entry *next;
- struct entry *prev;
- line_t *start;
- line_t *end;
-} entry_t;
-
-typedef struct {
- line_t *start;
- line_t *end;
- line_t *curdefault; /* line containing default */
- line_t *olddefault; /* old default line (commented) */
- entry_t *entries; /* os entries */
-} menu_t;
-
typedef enum {
OPT_ABSENT = 0, /* No option */
OPT_REQ, /* option required */
OPT_OPTIONAL /* option may or may not be present */
} option_t;
-typedef enum {
- BAM_ERROR = -1, /* Must be negative. add_boot_entry() depends on it */
- BAM_SUCCESS = 0,
- BAM_WRITE = 2
-} error_t;
-
typedef struct {
char *subcmd;
option_t option;
@@ -134,16 +90,11 @@ typedef struct {
int unpriv; /* is this an unprivileged command */
} subcmd_defn_t;
-
-#define BAM_MAXLINE 8192
-
#define LINE_INIT 0 /* lineNum initial value */
#define ENTRY_INIT -1 /* entryNum initial value */
#define ALL_ENTRIES -2 /* selects all boot entries */
#define GRUB_DIR "/boot/grub"
-#define MULTI_BOOT "/platform/i86pc/multiboot"
-#define BOOT_ARCHIVE "/platform/i86pc/boot_archive"
#define GRUB_MENU "/boot/grub/menu.lst"
#define MENU_TMP "/boot/grub/menu.lst.tmp"
#define RAMDISK_SPECIAL "/ramdisk"
@@ -180,26 +131,19 @@ typedef struct {
* Menu related
* menu_cmd_t and menu_cmds must be kept in sync
*/
-typedef enum {
- DEFAULT_CMD = 0,
- TIMEOUT_CMD,
- TITLE_CMD,
- ROOT_CMD,
- KERNEL_CMD,
- MODULE_CMD,
- SEP_CMD,
- COMMENT_CMD
-} menu_cmd_t;
-
-static char *menu_cmds[] = {
+char *menu_cmds[] = {
"default", /* DEFAULT_CMD */
"timeout", /* TIMEOUT_CMD */
"title", /* TITLE_CMD */
"root", /* ROOT_CMD */
"kernel", /* KERNEL_CMD */
+ "kernel$", /* KERNEL_DOLLAR_CMD */
"module", /* MODULE_CMD */
+ "module$", /* MODULE_DOLLAR_CMD */
" ", /* SEP_CMD */
"#", /* COMMENT_CMD */
+ "chainloader", /* CHAINLOADER_CMD */
+ "args", /* ARGS_CMD */
NULL
};
@@ -221,11 +165,9 @@ typedef struct {
#define DIR_PERMS (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
#define FILE_STAT_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
-#define BAM_HDR "---------- ADDED BY BOOTADM - DO NOT EDIT ----------"
-#define BAM_FTR "---------------------END BOOTADM--------------------"
-#define BAM_OLDDEF "BOOTADM SAVED DEFAULT: "
-
/* Globals */
+int bam_verbose;
+int bam_force;
static char *prog;
static subcmd_t bam_cmd;
static char *bam_root;
@@ -237,8 +179,6 @@ static char *bam_opt;
static int bam_debug;
static char **bam_argv;
static int bam_argc;
-static int bam_force;
-static int bam_verbose;
static int bam_check;
static int bam_smf_check;
static int bam_lock_fd = -1;
@@ -251,7 +191,6 @@ static void parse_args(int argc, char *argv[]);
static error_t bam_menu(char *subcmd, char *opt, int argc, char *argv[]);
static error_t bam_archive(char *subcmd, char *opt);
-static void bam_error(char *format, ...);
static void bam_print(char *format, ...);
static void bam_exit(int excode);
static void bam_lock(void);
@@ -280,12 +219,13 @@ static error_t update_all(char *root, char *opt);
static error_t read_list(char *root, filelist_t *flistp);
static error_t set_global(menu_t *mp, char *globalcmd, int val);
static error_t set_option(menu_t *mp, char *globalcmd, char *opt);
+static error_t set_kernel(menu_t *mp, menu_cmd_t optnum, char *path,
+ char *buf, size_t bufsize);
+static char *expand_path(const char *partial_path);
static long s_strtol(char *str);
-static char *s_fgets(char *buf, int n, FILE *fp);
static int s_fputs(char *str, FILE *fp);
-static void *s_calloc(size_t nelem, size_t sz);
static char *s_strdup(char *str);
static int is_readonly(char *);
static int is_amd64(void);
@@ -302,6 +242,7 @@ static subcmd_defn_t menu_subcmds[] = {
"delete_all_entries", OPT_ABSENT, delete_all_entries, 0, /* PVT */
"update_entry", OPT_REQ, update_entry, 0, /* menu */
"update_temp", OPT_OPTIONAL, update_temp, 0, /* reboot */
+ "upgrade", OPT_ABSENT, upgrade_menu, 0, /* menu */
NULL, 0, NULL, 0 /* must be last */
};
@@ -325,7 +266,7 @@ struct safefile {
struct safefile *next;
};
-struct safefile *safefiles = NULL;
+static struct safefile *safefiles = NULL;
#define NEED_UPDATE_FILE "/etc/svc/volatile/boot_archive_needs_update"
static void
@@ -487,7 +428,7 @@ parse_args_internal(int argc, char *argv[])
opterr = 0;
error = 0;
- while ((c = getopt(argc, argv, "a:d:fm:no:vCR:")) != -1) {
+ while ((c = getopt(argc, argv, "a:d:fm:no:vCR:xX")) != -1) {
switch (c) {
case 'a':
if (bam_cmd) {
@@ -942,6 +883,7 @@ bam_menu(char *subcmd, char *opt, int largc, char *largv[])
{
error_t ret;
char menu_path[PATH_MAX];
+ char path[PATH_MAX];
menu_t *menu;
char *mntpt, *menu_root, *logslice, *fstype;
struct stat sb;
@@ -961,17 +903,26 @@ bam_menu(char *subcmd, char *opt, int largc, char *largv[])
logslice = fstype = NULL;
/*
- * If the user provides an alternate root, we
- * assume they know what they are doing and we
- * use it. Else we check if there is an
- * alternate location (other than /boot/grub)
- * for the GRUB menu
+ * Check for the menu.list file:
+ *
+ * 1. Check for a GRUB_slice file, be it on / or
+ * on the user-provided alternate root.
+ * 2. Use the alternate root, if given.
+ * 3. Check /stubboot
+ * 4. Use /
*/
if (bam_alt_root) {
- menu_root = bam_root;
- } else if (stat(GRUB_slice, &sb) == 0) {
+ (void) snprintf(path, sizeof (path), "%s%s", bam_root,
+ GRUB_slice);
+ } else {
+ (void) snprintf(path, sizeof (path), "%s", GRUB_slice);
+ }
+
+ if (stat(path, &sb) == 0) {
mntpt = mount_grub_slice(&mnted, NULL, &logslice, &fstype);
menu_root = mntpt;
+ } else if (bam_alt_root) {
+ menu_root = bam_root;
} else if (stat(STUBBOOT, &sb) == 0) {
menu_root = use_stubboot();
} else {
@@ -1015,11 +966,16 @@ bam_menu(char *subcmd, char *opt, int largc, char *largv[])
return (BAM_ERROR);
}
+ ret = dboot_or_multiboot(bam_root);
+ if (ret != BAM_SUCCESS)
+ return (ret);
+
/*
* Once the sub-cmd handler has run
* only the line field is guaranteed to have valid values
*/
- if (strcmp(subcmd, "update_entry") == 0)
+ if ((strcmp(subcmd, "update_entry") == 0) ||
+ (strcmp(subcmd, "upgrade") == 0))
ret = f(menu, bam_root, opt);
else
ret = f(menu, menu_path, opt);
@@ -1068,6 +1024,10 @@ bam_archive(
sparc_abort();
#endif
+ ret = dboot_or_multiboot(rootbuf);
+ if (ret != BAM_SUCCESS)
+ return (ret);
+
/*
* Check archive not supported with update_all
* since it is awkward to display out-of-sync
@@ -1089,7 +1049,7 @@ bam_archive(
}
/*PRINTFLIKE1*/
-static void
+void
bam_error(char *format, ...)
{
va_list ap;
@@ -1111,6 +1071,17 @@ bam_print(char *format, ...)
va_end(ap);
}
+/*PRINTFLIKE1*/
+void
+bam_print_stderr(char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ (void) vfprintf(stderr, format, ap);
+ va_end(ap);
+}
+
static void
bam_exit(int excode)
{
@@ -1501,13 +1472,24 @@ check_flags_and_files(char *root)
/*
* If archive is missing, create archive
*/
- (void) snprintf(path, sizeof (path), "%s%s", root, BOOT_ARCHIVE);
+ (void) snprintf(path, sizeof (path), "%s%s", root,
+ DIRECT_BOOT_ARCHIVE_32);
if (stat(path, &sb) != 0) {
if (bam_verbose && !bam_check)
bam_print(UPDATE_ARCH_MISS, path);
walk_arg.need_update = 1;
return;
}
+ if (bam_direct == BAM_DIRECT_DBOOT) {
+ (void) snprintf(path, sizeof (path), "%s%s", root,
+ DIRECT_BOOT_ARCHIVE_64);
+ if (stat(path, &sb) != 0) {
+ if (bam_verbose && !bam_check)
+ bam_print(UPDATE_ARCH_MISS, path);
+ walk_arg.need_update = 1;
+ return;
+ }
+ }
}
static error_t
@@ -1891,11 +1873,20 @@ create_ramdisk(char *root)
/*
* Verify that the archive has been created
*/
- (void) snprintf(path, sizeof (path), "%s%s", root, BOOT_ARCHIVE);
+ (void) snprintf(path, sizeof (path), "%s%s", root,
+ DIRECT_BOOT_ARCHIVE_32);
if (stat(path, &sb) != 0) {
bam_error(ARCHIVE_NOT_CREATED, path);
return (BAM_ERROR);
}
+ if (bam_direct == BAM_DIRECT_DBOOT) {
+ (void) snprintf(path, sizeof (path), "%s%s", root,
+ DIRECT_BOOT_ARCHIVE_64);
+ if (stat(path, &sb) != 0) {
+ bam_error(ARCHIVE_NOT_CREATED, path);
+ return (BAM_ERROR);
+ }
+ }
return (BAM_SUCCESS);
}
@@ -2248,7 +2239,13 @@ update_all(char *root, char *opt)
(void) snprintf(rootbuf, sizeof (rootbuf), "%s/",
mnt.mnt_mountp);
bam_rootlen = strlen(rootbuf);
- if (update_archive(rootbuf, opt) != BAM_SUCCESS)
+
+ /*
+ * It's possible that other mounts may be an alternate boot
+ * architecture, so check it again.
+ */
+ if ((dboot_or_multiboot(rootbuf) != BAM_SUCCESS) ||
+ (update_archive(rootbuf, opt) != BAM_SUCCESS))
ret = BAM_ERROR;
}
@@ -2352,6 +2349,7 @@ line_parser(menu_t *mp, char *str, int *lineNum, int *entryNum)
*/
static line_t *prev = NULL;
static entry_t *curr_ent = NULL;
+ static int in_liveupgrade = 0;
line_t *lp;
char *cmd, *sep, *arg;
@@ -2377,6 +2375,11 @@ line_parser(menu_t *mp, char *str, int *lineNum, int *entryNum)
sep = NULL;
arg = s_strdup(str + 1);
flag = BAM_COMMENT;
+ if (strstr(arg, BAM_LU_HDR) != NULL) {
+ in_liveupgrade = 1;
+ } else if (strstr(arg, BAM_LU_FTR) != NULL) {
+ in_liveupgrade = 0;
+ }
} else if (*str == '\0') { /* blank line */
cmd = sep = arg = NULL;
flag = BAM_EMPTY;
@@ -2429,12 +2432,17 @@ line_parser(menu_t *mp, char *str, int *lineNum, int *entryNum)
lp->entryNum = ++(*entryNum);
lp->flags = BAM_TITLE;
if (prev && prev->flags == BAM_COMMENT &&
- prev->arg && strcmp(prev->arg, BAM_HDR) == 0) {
+ prev->arg && strcmp(prev->arg, BAM_BOOTADM_HDR) == 0) {
prev->entryNum = lp->entryNum;
curr_ent = boot_entry_new(mp, prev, lp);
+ curr_ent->flags = BAM_ENTRY_BOOTADM;
} else {
curr_ent = boot_entry_new(mp, lp, lp);
+ if (in_liveupgrade) {
+ curr_ent->flags = BAM_ENTRY_LU;
+ }
}
+ curr_ent->entryNum = *entryNum;
} else if (flag != BAM_INVALID) {
/*
* For header comments, the entry# is "fixed up"
@@ -2444,7 +2452,29 @@ line_parser(menu_t *mp, char *str, int *lineNum, int *entryNum)
lp->flags = flag;
} else {
lp->entryNum = *entryNum;
- lp->flags = (*entryNum == ENTRY_INIT) ? BAM_GLOBAL : BAM_ENTRY;
+
+ if (*entryNum == ENTRY_INIT) {
+ lp->flags = BAM_GLOBAL;
+ } else {
+ lp->flags = BAM_ENTRY;
+
+ if (cmd && arg) {
+ /*
+ * We only compare for the length of "module"
+ * so that "module$" will also match.
+ */
+ if ((strncmp(cmd, menu_cmds[MODULE_CMD],
+ strlen(menu_cmds[MODULE_CMD])) == 0) &&
+ (strcmp(arg, MINIROOT) == 0))
+ curr_ent->flags |= BAM_ENTRY_MINIROOT;
+ else if (strcmp(cmd, menu_cmds[ROOT_CMD]) == 0)
+ curr_ent->flags |= BAM_ENTRY_ROOT;
+ else if (strcmp(cmd,
+ menu_cmds[CHAINLOADER_CMD]) == 0)
+ curr_ent->flags |=
+ BAM_ENTRY_CHAINLOADER;
+ }
+ }
}
/* record default, old default, and entry line ranges */
@@ -2454,8 +2484,12 @@ line_parser(menu_t *mp, char *str, int *lineNum, int *entryNum)
} else if (lp->flags == BAM_COMMENT &&
strncmp(lp->arg, BAM_OLDDEF, strlen(BAM_OLDDEF)) == 0) {
mp->olddefault = lp;
+ } else if (lp->flags == BAM_COMMENT &&
+ strncmp(lp->arg, BAM_OLD_RC_DEF, strlen(BAM_OLD_RC_DEF)) == 0) {
+ mp->old_rc_default = lp;
} else if (lp->flags == BAM_ENTRY ||
- (lp->flags == BAM_COMMENT && strcmp(lp->arg, BAM_FTR) == 0)) {
+ (lp->flags == BAM_COMMENT &&
+ strcmp(lp->arg, BAM_BOOTADM_FTR) == 0)) {
boot_entry_addline(curr_ent, lp);
}
append_line(mp, lp);
@@ -2522,7 +2556,8 @@ update_numbering(menu_t *mp)
lp->entryNum = ++entryNum;
/* fixup the bootadm header */
if (prev && prev->flags == BAM_COMMENT &&
- prev->arg && strcmp(prev->arg, BAM_HDR) == 0) {
+ prev->arg &&
+ strcmp(prev->arg, BAM_BOOTADM_HDR) == 0) {
prev->entryNum = lp->entryNum;
}
} else {
@@ -2727,6 +2762,7 @@ add_boot_entry(menu_t *mp,
{
int lineNum, entryNum;
char linebuf[BAM_MAXLINE];
+ menu_cmd_t k_cmd, m_cmd;
assert(mp);
@@ -2738,8 +2774,36 @@ add_boot_entry(menu_t *mp,
return (BAM_ERROR);
}
if (module == NULL) {
- bam_error(SUBOPT_MISS, menu_cmds[MODULE_CMD]);
- return (BAM_ERROR);
+ if (bam_direct != BAM_DIRECT_DBOOT) {
+ bam_error(SUBOPT_MISS, menu_cmds[MODULE_CMD]);
+ return (BAM_ERROR);
+ }
+
+ /* Figure the commands out from the kernel line */
+ if (strstr(kernel, "$ISADIR") != NULL) {
+ module = DIRECT_BOOT_ARCHIVE;
+ k_cmd = KERNEL_DOLLAR_CMD;
+ m_cmd = MODULE_DOLLAR_CMD;
+ } else if (strstr(kernel, "amd64") != NULL) {
+ module = DIRECT_BOOT_ARCHIVE_64;
+ k_cmd = KERNEL_CMD;
+ m_cmd = MODULE_CMD;
+ } else {
+ module = DIRECT_BOOT_ARCHIVE_32;
+ k_cmd = KERNEL_CMD;
+ m_cmd = MODULE_CMD;
+ }
+ } else if ((bam_direct == BAM_DIRECT_DBOOT) &&
+ (strstr(kernel, "$ISADIR") != NULL)) {
+ /*
+ * If it's a non-failsafe dboot kernel, use the "kernel$"
+ * command. Otherwise, use "kernel".
+ */
+ k_cmd = KERNEL_DOLLAR_CMD;
+ m_cmd = MODULE_DOLLAR_CMD;
+ } else {
+ k_cmd = KERNEL_CMD;
+ m_cmd = MODULE_CMD;
}
if (mp->start) {
@@ -2755,7 +2819,7 @@ add_boot_entry(menu_t *mp,
* The syntax for comments is #<comment>
*/
(void) snprintf(linebuf, sizeof (linebuf), "%s%s",
- menu_cmds[COMMENT_CMD], BAM_HDR);
+ menu_cmds[COMMENT_CMD], BAM_BOOTADM_HDR);
line_parser(mp, linebuf, &lineNum, &entryNum);
(void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
@@ -2769,15 +2833,15 @@ add_boot_entry(menu_t *mp,
}
(void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
- menu_cmds[KERNEL_CMD], menu_cmds[SEP_CMD], kernel);
+ menu_cmds[k_cmd], menu_cmds[SEP_CMD], kernel);
line_parser(mp, linebuf, &lineNum, &entryNum);
(void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
- menu_cmds[MODULE_CMD], menu_cmds[SEP_CMD], module);
+ menu_cmds[m_cmd], menu_cmds[SEP_CMD], module);
line_parser(mp, linebuf, &lineNum, &entryNum);
(void) snprintf(linebuf, sizeof (linebuf), "%s%s",
- menu_cmds[COMMENT_CMD], BAM_FTR);
+ menu_cmds[COMMENT_CMD], BAM_BOOTADM_FTR);
line_parser(mp, linebuf, &lineNum, &entryNum);
return (entryNum);
@@ -2797,7 +2861,7 @@ do_delete(menu_t *mp, int entryNum)
lp = ent->start;
/* check entry number and make sure it's a bootadm entry */
if (lp->flags != BAM_COMMENT ||
- strcmp(lp->arg, BAM_HDR) != 0 ||
+ strcmp(lp->arg, BAM_BOOTADM_HDR) != 0 ||
(entryNum != ALL_ENTRIES && lp->entryNum != entryNum)) {
ent = ent->next;
continue;
@@ -3003,7 +3067,7 @@ get_title(char *rootdir)
return (cp == NULL ? "Solaris" : cp);
}
-static char *
+char *
get_special(char *mountp)
{
FILE *mntfp;
@@ -3027,7 +3091,7 @@ get_special(char *mountp)
return (s_strdup(mp.mnt_special));
}
-static char *
+char *
os_to_grubdisk(char *osdisk, int on_bootdev)
{
FILE *fp;
@@ -3092,7 +3156,8 @@ find_boot_entry(menu_t *mp, char *title, char *root, char *module,
/* first line of entry must be bootadm comment */
lp = ent->start;
- if (lp->flags != BAM_COMMENT || strcmp(lp->arg, BAM_HDR) != 0) {
+ if (lp->flags != BAM_COMMENT ||
+ strcmp(lp->arg, BAM_BOOTADM_HDR) != 0) {
continue;
}
@@ -3125,8 +3190,9 @@ find_boot_entry(menu_t *mp, char *title, char *root, char *module,
/* check for matching module entry (failsafe or normal) */
lp = lp->next; /* advance to module line */
- if (strcmp(lp->cmd, menu_cmds[MODULE_CMD]) != 0 ||
- strcmp(lp->arg, module) != 0) {
+ if ((strncmp(lp->cmd, menu_cmds[MODULE_CMD],
+ strlen(menu_cmds[MODULE_CMD])) != 0) ||
+ (strcmp(lp->arg, module) != 0)) {
continue;
}
break; /* match found */
@@ -3140,13 +3206,24 @@ static int
update_boot_entry(menu_t *mp, char *title, char *root, char *kernel,
char *module, int root_opt)
{
- int i;
+ int i, change_kernel = 0;
entry_t *ent;
line_t *lp;
char linebuf[BAM_MAXLINE];
/* note: don't match on title, it's updated on upgrade */
ent = find_boot_entry(mp, NULL, root, module, root_opt, &i);
+ if ((ent == NULL) && (bam_direct == BAM_DIRECT_DBOOT)) {
+ /*
+ * We may be upgrading a kernel from multiboot to
+ * directboot. Look for a multiboot entry.
+ */
+ ent = find_boot_entry(mp, NULL, root, MULTI_BOOT_ARCHIVE,
+ root_opt, &i);
+ if (ent != NULL) {
+ change_kernel = 1;
+ }
+ }
if (ent == NULL)
return (add_boot_entry(mp, title, root_opt ? NULL : root,
kernel, module));
@@ -3171,6 +3248,32 @@ update_boot_entry(menu_t *mp, char *title, char *root, char *kernel,
} else
lp = lp->next;
}
+
+ if (change_kernel) {
+ /*
+ * We're upgrading from multiboot to directboot.
+ */
+ if (strcmp(lp->cmd, menu_cmds[KERNEL_CMD]) == 0) {
+ (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
+ menu_cmds[KERNEL_DOLLAR_CMD], menu_cmds[SEP_CMD],
+ kernel);
+ free(lp->arg);
+ free(lp->line);
+ lp->arg = s_strdup(kernel);
+ lp->line = s_strdup(linebuf);
+ lp = lp->next;
+ }
+ if (strcmp(lp->cmd, menu_cmds[MODULE_CMD]) == 0) {
+ (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
+ menu_cmds[MODULE_DOLLAR_CMD], menu_cmds[SEP_CMD],
+ module);
+ free(lp->arg);
+ free(lp->line);
+ lp->arg = s_strdup(module);
+ lp->line = s_strdup(linebuf);
+ lp = lp->next;
+ }
+ }
return (i);
}
@@ -3207,19 +3310,24 @@ update_entry(menu_t *mp, char *menu_root, char *opt)
}
/* add the entry for normal Solaris */
- entry = update_boot_entry(mp, title, grubdisk,
- "/platform/i86pc/multiboot",
- "/platform/i86pc/boot_archive",
- osroot == menu_root);
+ if (bam_direct == BAM_DIRECT_DBOOT) {
+ entry = update_boot_entry(mp, title, grubdisk,
+ DIRECT_BOOT_KERNEL, DIRECT_BOOT_ARCHIVE,
+ osroot == menu_root);
+ } else {
+ entry = update_boot_entry(mp, title, grubdisk,
+ MULTI_BOOT, MULTI_BOOT_ARCHIVE,
+ osroot == menu_root);
+ }
/* add the entry for failsafe archive */
- (void) snprintf(failsafe, sizeof (failsafe),
- "%s/boot/x86.miniroot-safe", osroot);
- if (stat(failsafe, &sbuf) == 0)
- (void) update_boot_entry(mp, "Solaris failsafe", grubdisk,
- "/boot/multiboot kernel/unix -s",
- "/boot/x86.miniroot-safe",
- osroot == menu_root);
+ (void) snprintf(failsafe, sizeof (failsafe), "%s%s", osroot, MINIROOT);
+ if (stat(failsafe, &sbuf) == 0) {
+ (void) update_boot_entry(mp, FAILSAFE_TITLE, grubdisk,
+ (bam_direct == BAM_DIRECT_DBOOT) ?
+ DIRECT_BOOT_FAILSAFE_LINE : MULTI_BOOT_FAILSAFE_LINE,
+ MINIROOT, osroot == menu_root);
+ }
free(grubdisk);
if (entry == BAM_ERROR) {
@@ -3276,7 +3384,7 @@ read_grub_root(void)
}
static void
-save_default_entry(menu_t *mp)
+save_default_entry(menu_t *mp, const char *which)
{
int lineNum, entryNum;
int entry = 0; /* default is 0 */
@@ -3294,26 +3402,24 @@ save_default_entry(menu_t *mp)
if (lp)
entry = s_strtol(lp->arg);
- (void) snprintf(linebuf, sizeof (linebuf), "#%s%d", BAM_OLDDEF, entry);
+ (void) snprintf(linebuf, sizeof (linebuf), "#%s%d", which, entry);
line_parser(mp, linebuf, &lineNum, &entryNum);
}
static void
-restore_default_entry(menu_t *mp)
+restore_default_entry(menu_t *mp, const char *which, line_t *lp)
{
int entry;
char *str;
- line_t *lp = mp->olddefault;
if (lp == NULL)
return; /* nothing to restore */
- str = lp->arg + strlen(BAM_OLDDEF);
+ str = lp->arg + strlen(which);
entry = s_strtol(str);
(void) set_global(mp, menu_cmds[DEFAULT_CMD], entry);
/* delete saved old default line */
- mp->olddefault = NULL;
unlink_line(mp, lp);
line_free(lp);
}
@@ -3333,8 +3439,9 @@ static error_t
update_temp(menu_t *mp, char *menupath, char *opt)
{
int entry;
- char *grubdisk, *rootdev;
- char kernbuf[1024];
+ char *grubdisk, *rootdev, *path;
+ char kernbuf[BUFSIZ];
+ char args_buf[BUFSIZ];
struct stat sb;
assert(mp);
@@ -3346,7 +3453,8 @@ update_temp(menu_t *mp, char *menupath, char *opt)
if (ent == NULL) /* not found is ok */
return (BAM_SUCCESS);
(void) do_delete(mp, entry);
- restore_default_entry(mp);
+ restore_default_entry(mp, BAM_OLDDEF, mp->olddefault);
+ mp->olddefault = NULL;
return (BAM_WRITE);
}
@@ -3385,10 +3493,47 @@ update_temp(menu_t *mp, char *menupath, char *opt)
}
/* add an entry for Solaris reboot */
- (void) snprintf(kernbuf, sizeof (kernbuf),
- "/platform/i86pc/multiboot %s", opt);
- entry = add_boot_entry(mp, REBOOT_TITLE, grubdisk, kernbuf,
- "/platform/i86pc/boot_archive");
+ if (bam_direct == BAM_DIRECT_DBOOT) {
+ if (opt[0] == '-') {
+ /* It's an option - first see if boot-file is set */
+ if (set_kernel(mp, KERNEL_CMD, NULL, kernbuf, BUFSIZ)
+ != BAM_SUCCESS)
+ return (BAM_ERROR);
+ if (kernbuf[0] == '\0')
+ (void) strncpy(kernbuf, DIRECT_BOOT_KERNEL,
+ BUFSIZ);
+ (void) strlcat(kernbuf, " ", BUFSIZ);
+ (void) strlcat(kernbuf, opt, BUFSIZ);
+ } else if (opt[0] == '/') {
+ /* It's a full path - write it out and go home */
+ (void) strlcpy(kernbuf, opt, BUFSIZ);
+ } else {
+ path = expand_path(opt);
+ if (path != NULL) {
+ (void) strlcpy(kernbuf, path, BUFSIZ);
+ free(path);
+ if (strcmp(opt, "kmdb") == 0) {
+ if (set_kernel(mp, ARGS_CMD, NULL,
+ args_buf, BUFSIZ) != BAM_SUCCESS)
+ return (BAM_ERROR);
+
+ if (args_buf[0] != '\0') {
+ (void) strlcat(kernbuf, " ",
+ BUFSIZ);
+ (void) strlcat(kernbuf,
+ args_buf, BUFSIZ);
+ }
+ }
+ }
+ }
+ entry = add_boot_entry(mp, REBOOT_TITLE, grubdisk, kernbuf,
+ NULL);
+ } else {
+ (void) snprintf(kernbuf, sizeof (kernbuf), "%s %s",
+ MULTI_BOOT, opt);
+ entry = add_boot_entry(mp, REBOOT_TITLE, grubdisk, kernbuf,
+ MULTI_BOOT_ARCHIVE);
+ }
free(grubdisk);
if (entry == BAM_ERROR) {
@@ -3396,7 +3541,7 @@ update_temp(menu_t *mp, char *menupath, char *opt)
return (BAM_ERROR);
}
- save_default_entry(mp);
+ save_default_entry(mp, BAM_OLDDEF);
(void) set_global(mp, menu_cmds[DEFAULT_CMD], entry);
return (BAM_WRITE);
}
@@ -3482,35 +3627,418 @@ set_global(menu_t *mp, char *globalcmd, int val)
return (BAM_WRITE); /* need a write to menu */
}
+/*
+ * partial_path may be anything like "kernel/unix" or "kmdb". Try to
+ * expand it to a full unix path.
+ */
+static char *
+expand_path(const char *partial_path)
+{
+ int new_path_len;
+ char *new_path, new_path2[PATH_MAX];
+ struct stat sb;
+
+ new_path_len = strlen(partial_path) + 64;
+ new_path = s_calloc(1, new_path_len);
+
+ /* First, try the simplest case - something like "kernel/unix" */
+ (void) snprintf(new_path, new_path_len, "/platform/i86pc/%s",
+ partial_path);
+ if (stat(new_path, &sb) == 0) {
+ return (new_path);
+ }
+
+ if (strcmp(partial_path, "kmdb") == 0) {
+ (void) snprintf(new_path, new_path_len, "%s -k",
+ DIRECT_BOOT_KERNEL);
+ return (new_path);
+ }
+
+ /*
+ * We've quickly reached unsupported usage. Try once more to
+ * see if we were just given a glom name.
+ */
+ (void) snprintf(new_path, new_path_len, "/platform/i86pc/%s/unix",
+ partial_path);
+ (void) snprintf(new_path2, PATH_MAX, "/platform/i86pc/%s/amd64/unix",
+ partial_path);
+ if (stat(new_path, &sb) == 0) {
+ if (stat(new_path2, &sb) == 0) {
+ /*
+ * We matched both, so we actually
+ * want to write the $ISADIR version.
+ */
+ (void) snprintf(new_path, new_path_len,
+ "/platform/i86pc/kernel/%s/$ISADIR/unix",
+ partial_path);
+ }
+ return (new_path);
+ }
+
+ bam_error(UNKNOWN_KERNEL, partial_path);
+ free(new_path);
+ return (NULL);
+}
+
+/*
+ * The kernel cmd and arg have been changed, so
+ * check whether the archive line needs to change.
+ */
+static void
+set_archive_line(entry_t *entryp, line_t *kernelp)
+{
+ line_t *lp = entryp->start;
+ char *new_archive;
+ menu_cmd_t m_cmd;
+
+ for (; lp != NULL; lp = lp->next) {
+ if (strncmp(lp->cmd, menu_cmds[MODULE_CMD],
+ sizeof (menu_cmds[MODULE_CMD]) - 1) == 0) {
+ break;
+ }
+ if (lp == entryp->end)
+ return;
+ }
+ if (lp == NULL)
+ return;
+
+ if (strstr(kernelp->arg, "$ISADIR") != NULL) {
+ new_archive = DIRECT_BOOT_ARCHIVE;
+ m_cmd = MODULE_DOLLAR_CMD;
+ } else if (strstr(kernelp->arg, "amd64") != NULL) {
+ new_archive = DIRECT_BOOT_ARCHIVE_64;
+ m_cmd = MODULE_CMD;
+ } else {
+ new_archive = DIRECT_BOOT_ARCHIVE_32;
+ m_cmd = MODULE_CMD;
+ }
+
+ if (strcmp(lp->arg, new_archive) == 0)
+ return;
+
+ if (strcmp(lp->cmd, menu_cmds[m_cmd]) != 0) {
+ free(lp->cmd);
+ lp->cmd = s_strdup(menu_cmds[m_cmd]);
+ }
+
+ free(lp->arg);
+ lp->arg = s_strdup(new_archive);
+ update_line(lp);
+}
+
+/*
+ * Title for an entry to set properties that once went in bootenv.rc.
+ */
+#define BOOTENV_RC_TITLE "Solaris bootenv rc"
+
+/*
+ * If path is NULL, return the kernel (optnum == KERNEL_CMD) or arguments
+ * (optnum == ARGS_CMD) in the argument buf. If path is a zero-length
+ * string, reset the value to the default. If path is a non-zero-length
+ * string, set the kernel or arguments.
+ */
+static error_t
+set_kernel(menu_t *mp, menu_cmd_t optnum, char *path, char *buf, size_t bufsize)
+{
+ int entryNum, rv = BAM_SUCCESS, free_new_path = 0;
+ entry_t *entryp;
+ line_t *ptr, *kernelp;
+ char *new_arg, *old_args, *space;
+ char *grubdisk, *rootdev, *new_path;
+ char old_space;
+ size_t old_kernel_len, new_str_len;
+ struct stat sb;
+
+ assert(bufsize > 0);
+
+ ptr = kernelp = NULL;
+ new_arg = old_args = space = NULL;
+ grubdisk = rootdev = new_path = NULL;
+ buf[0] = '\0';
+
+ if (bam_direct != BAM_DIRECT_DBOOT) {
+ bam_error(NOT_DBOOT, optnum == KERNEL_CMD ? "kernel" : "args");
+ return (BAM_ERROR);
+ }
+
+ /*
+ * If a user changed the default entry to a non-bootadm controlled
+ * one, we don't want to mess with it. Just print an error and
+ * return.
+ */
+ if (mp->curdefault) {
+ entryNum = s_strtol(mp->curdefault->arg);
+ for (entryp = mp->entries; entryp; entryp = entryp->next) {
+ if (entryp->entryNum == entryNum)
+ break;
+ }
+ if ((entryp != NULL) &&
+ ((entryp->flags & (BAM_ENTRY_BOOTADM|BAM_ENTRY_LU)) == 0)) {
+ bam_error(DEFAULT_NOT_BAM);
+ return (BAM_ERROR);
+ }
+ }
+
+ entryNum = -1;
+ entryp = find_boot_entry(mp, BOOTENV_RC_TITLE, NULL, NULL, 0,
+ &entryNum);
+
+ if (entryp != NULL) {
+ for (ptr = entryp->start; ptr && ptr != entryp->end;
+ ptr = ptr->next) {
+ if (strncmp(ptr->cmd, menu_cmds[KERNEL_CMD],
+ sizeof (menu_cmds[KERNEL_CMD]) - 1) == 0) {
+ kernelp = ptr;
+ break;
+ }
+ }
+ if (kernelp == NULL) {
+ bam_error(NO_KERNEL, entryNum);
+ return (BAM_ERROR);
+ }
+
+ old_kernel_len = strcspn(kernelp->arg, " \t");
+ space = old_args = kernelp->arg + old_kernel_len;
+ while ((*old_args == ' ') || (*old_args == '\t'))
+ old_args++;
+ }
+
+ if (path == NULL) {
+ /* Simply report what was found */
+ if (kernelp == NULL)
+ return (BAM_SUCCESS);
+
+ if (optnum == ARGS_CMD) {
+ if (old_args[0] != '\0')
+ (void) strlcpy(buf, old_args, bufsize);
+ } else {
+ /*
+ * We need to print the kernel, so we just turn the
+ * first space into a '\0' and print the beginning.
+ * We don't print anything if it's the default kernel.
+ */
+ old_space = *space;
+ *space = '\0';
+ if (strcmp(kernelp->arg, DIRECT_BOOT_KERNEL) != 0)
+ (void) strlcpy(buf, kernelp->arg, bufsize);
+ *space = old_space;
+ }
+ return (BAM_SUCCESS);
+ }
+
+ /*
+ * First, check if we're resetting an entry to the default.
+ */
+ if ((path[0] == '\0') ||
+ ((optnum == KERNEL_CMD) &&
+ (strcmp(path, DIRECT_BOOT_KERNEL) == 0))) {
+ if ((entryp == NULL) || (kernelp == NULL)) {
+ /* No previous entry, it's already the default */
+ return (BAM_SUCCESS);
+ }
+
+ /*
+ * Check if we can delete the entry. If we're resetting the
+ * kernel command, and the args is already empty, or if we're
+ * resetting the args command, and the kernel is already the
+ * default, we can restore the old default and delete the entry.
+ */
+ if (((optnum == KERNEL_CMD) &&
+ ((old_args == NULL) || (old_args[0] == '\0'))) ||
+ ((optnum == ARGS_CMD) &&
+ (strncmp(kernelp->arg, DIRECT_BOOT_KERNEL,
+ sizeof (DIRECT_BOOT_KERNEL) - 1) == 0))) {
+ kernelp = NULL;
+ (void) do_delete(mp, entryNum);
+ restore_default_entry(mp, BAM_OLD_RC_DEF,
+ mp->old_rc_default);
+ mp->old_rc_default = NULL;
+ rv = BAM_WRITE;
+ goto done;
+ }
+
+ if (optnum == KERNEL_CMD) {
+ /*
+ * At this point, we've already checked that old_args
+ * and entryp are valid pointers. The "+ 2" is for
+ * a space a the string termination character.
+ */
+ new_str_len = (sizeof (DIRECT_BOOT_KERNEL) - 1) +
+ strlen(old_args) + 2;
+ new_arg = s_calloc(1, new_str_len);
+ (void) snprintf(new_arg, new_str_len, "%s %s",
+ DIRECT_BOOT_KERNEL, old_args);
+ free(kernelp->arg);
+ kernelp->arg = new_arg;
+
+ /*
+ * We have changed the kernel line, so we may need
+ * to update the archive line as well.
+ */
+ set_archive_line(entryp, kernelp);
+ } else {
+ /*
+ * We're resetting the boot args to nothing, so
+ * we only need to copy the kernel. We've already
+ * checked that the kernel is not the default.
+ */
+ new_arg = s_calloc(1, old_kernel_len + 1);
+ (void) snprintf(new_arg, old_kernel_len + 1, "%s",
+ kernelp->arg);
+ free(kernelp->arg);
+ kernelp->arg = new_arg;
+ }
+ rv = BAM_WRITE;
+ goto done;
+ }
+
+ /*
+ * Expand the kernel file to a full path, if necessary
+ */
+ if ((optnum == KERNEL_CMD) && (path[0] != '/')) {
+ new_path = expand_path(path);
+ if (new_path == NULL) {
+ return (BAM_ERROR);
+ }
+ free_new_path = 1;
+ } else {
+ new_path = path;
+ free_new_path = 0;
+ }
+
+ /*
+ * At this point, we know we're setting a new value. First, take care
+ * of the case where there was no previous entry.
+ */
+ if (entryp == NULL) {
+ /* Similar to code in update_temp */
+ if (stat(GRUB_slice, &sb) != 0) {
+ /*
+ * 1. First get root disk name from mnttab
+ * 2. Translate disk name to grub name
+ * 3. Add the new menu entry
+ */
+ rootdev = get_special("/");
+ if (rootdev) {
+ grubdisk = os_to_grubdisk(rootdev, 1);
+ free(rootdev);
+ }
+ } else {
+ /*
+ * This is an LU BE. The GRUB_root file
+ * contains entry for GRUB's "root" cmd.
+ */
+ grubdisk = read_grub_root();
+ }
+ if (grubdisk == NULL) {
+ bam_error(REBOOT_WITH_ARGS_FAILED);
+ rv = BAM_ERROR;
+ goto done;
+ }
+ if (optnum == KERNEL_CMD) {
+ entryNum = add_boot_entry(mp, BOOTENV_RC_TITLE,
+ grubdisk, new_path, NULL);
+ } else {
+ new_str_len = strlen(DIRECT_BOOT_KERNEL) +
+ strlen(path) + 8;
+ new_arg = s_calloc(1, new_str_len);
+
+ (void) snprintf(new_arg, new_str_len, "%s %s",
+ DIRECT_BOOT_KERNEL, path);
+ entryNum = add_boot_entry(mp, BOOTENV_RC_TITLE,
+ grubdisk, new_arg, DIRECT_BOOT_ARCHIVE);
+ }
+ save_default_entry(mp, BAM_OLD_RC_DEF);
+ (void) set_global(mp, menu_cmds[DEFAULT_CMD], entryNum);
+ rv = BAM_WRITE;
+ goto done;
+ }
+
+ /*
+ * There was already an bootenv entry which we need to edit.
+ */
+ if (optnum == KERNEL_CMD) {
+ new_str_len = strlen(new_path) + strlen(old_args) + 2;
+ new_arg = s_calloc(1, new_str_len);
+ (void) snprintf(new_arg, new_str_len, "%s %s", new_path,
+ old_args);
+ free(kernelp->arg);
+ kernelp->arg = new_arg;
+
+ /*
+ * If we have changed the kernel line, we may need to update
+ * the archive line as well.
+ */
+ set_archive_line(entryp, kernelp);
+ } else {
+ new_str_len = old_kernel_len + strlen(path) + 8;
+ new_arg = s_calloc(1, new_str_len);
+ (void) strncpy(new_arg, kernelp->arg, old_kernel_len);
+ (void) strlcat(new_arg, " ", new_str_len);
+ (void) strlcat(new_arg, path, new_str_len);
+ free(kernelp->arg);
+ kernelp->arg = new_arg;
+ }
+ rv = BAM_WRITE;
+
+done:
+ if ((rv == BAM_WRITE) && kernelp)
+ update_line(kernelp);
+ if (free_new_path)
+ free(new_path);
+ return (rv);
+}
+
/*ARGSUSED*/
static error_t
set_option(menu_t *mp, char *menu_path, char *opt)
{
int optnum, optval;
char *val;
+ char buf[BUFSIZ] = "";
+ error_t rv;
assert(mp);
assert(opt);
val = strchr(opt, '=');
- if (val == NULL) {
- bam_error(INVALID_ENTRY, opt);
- return (BAM_ERROR);
+ if (val != NULL) {
+ *val = '\0';
}
- *val = '\0';
if (strcmp(opt, "default") == 0) {
optnum = DEFAULT_CMD;
} else if (strcmp(opt, "timeout") == 0) {
optnum = TIMEOUT_CMD;
+ } else if (strcmp(opt, menu_cmds[KERNEL_CMD]) == 0) {
+ optnum = KERNEL_CMD;
+ } else if (strcmp(opt, menu_cmds[ARGS_CMD]) == 0) {
+ optnum = ARGS_CMD;
} else {
bam_error(INVALID_ENTRY, opt);
return (BAM_ERROR);
}
- optval = s_strtol(val + 1);
- *val = '=';
- return (set_global(mp, menu_cmds[optnum], optval));
+ /*
+ * kernel and args are allowed without "=new_value" strings. All
+ * others cause errors
+ */
+ if ((val == NULL) && (optnum != KERNEL_CMD) && (optnum != ARGS_CMD)) {
+ bam_error(INVALID_ENTRY, opt);
+ return (BAM_ERROR);
+ } else if (val != NULL) {
+ *val = '=';
+ }
+
+ if ((optnum == KERNEL_CMD) || (optnum == ARGS_CMD)) {
+ rv = set_kernel(mp, optnum, val ? val + 1 : NULL, buf, BUFSIZ);
+ if ((rv == BAM_SUCCESS) && (buf[0] != '\0'))
+ (void) printf("%s\n", buf);
+ return (rv);
+ } else {
+ optval = s_strtol(val + 1);
+ return (set_global(mp, menu_cmds[optnum], optval));
+ }
}
/*
@@ -3766,7 +4294,7 @@ s_fputs(char *str, FILE *fp)
/*
* Wrapper around fgets, that strips newlines returned by fgets
*/
-static char *
+char *
s_fgets(char *buf, int buflen, FILE *fp)
{
int n;
@@ -3782,7 +4310,7 @@ s_fgets(char *buf, int buflen, FILE *fp)
return (buf);
}
-static void *
+void *
s_calloc(size_t nelem, size_t sz)
{
void *ptr;
@@ -3795,6 +4323,17 @@ s_calloc(size_t nelem, size_t sz)
return (ptr);
}
+void *
+s_realloc(void *ptr, size_t sz)
+{
+ ptr = realloc(ptr, sz);
+ if (ptr == NULL) {
+ bam_error(NO_MEM, sz);
+ bam_exit(1);
+ }
+ return (ptr);
+}
+
static char *
s_strdup(char *str)
{
diff --git a/usr/src/cmd/boot/bootadm/bootadm.h b/usr/src/cmd/boot/bootadm/bootadm.h
new file mode 100644
index 0000000000..80309501cb
--- /dev/null
+++ b/usr/src/cmd/boot/bootadm/bootadm.h
@@ -0,0 +1,184 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _BOOTADM_H
+#define _BOOTADM_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef TEXT_DOMAIN
+#define TEXT_DOMAIN "SUNW_OST_OSCMD"
+#endif /* TEXT_DOMAIN */
+
+/* Type definitions */
+
+/* GRUB menu per-line classification */
+typedef enum {
+ BAM_INVALID = 0,
+ BAM_EMPTY,
+ BAM_COMMENT,
+ BAM_GLOBAL,
+ BAM_ENTRY,
+ BAM_TITLE
+} menu_flag_t;
+
+/* struct for menu.lst contents */
+typedef struct line {
+ int lineNum; /* Line number in menu.lst */
+ int entryNum; /* menu boot entry #. ENTRY_INIT if not applicable */
+ char *cmd;
+ char *sep;
+ char *arg;
+ char *line;
+ menu_flag_t flags;
+ struct line *next;
+ struct line *prev;
+} line_t;
+
+typedef struct entry {
+ struct entry *next;
+ struct entry *prev;
+ line_t *start;
+ line_t *end;
+ int entryNum;
+ uint8_t flags;
+} entry_t;
+
+/* For flags value in entry_t */
+#define BAM_ENTRY_BOOTADM 0x01 /* entry created by bootadm */
+#define BAM_ENTRY_LU 0x02 /* entry created by Live Upgrade */
+#define BAM_ENTRY_CHAINLOADER 0x04 /* chainloader entry; do not disturb */
+#define BAM_ENTRY_ROOT 0x08 /* entry has a root line */
+#define BAM_ENTRY_MINIROOT 0x10 /* entry uses the failsafe miniroot */
+#define BAM_ENTRY_DBOOT 0x20 /* Is a dboot entry */
+#define BAM_ENTRY_32BIT 0x40 /* Is a 32-bit entry */
+
+typedef struct {
+ line_t *start;
+ line_t *end;
+ line_t *curdefault; /* line containing default */
+ line_t *olddefault; /* old default line (commented) */
+ line_t *old_rc_default; /* old default line for bootenv.rc */
+ entry_t *entries; /* os entries */
+} menu_t;
+
+typedef enum {
+ BAM_ERROR = -1, /* Must be negative. add_boot_entry() depends on it */
+ BAM_SUCCESS = 0,
+ BAM_WRITE = 2,
+ BAM_SKIP /* Used by upgrade_menu() */
+} error_t;
+
+/*
+ * Menu related
+ * menu_cmd_t and menu_cmds must be kept in sync
+ */
+typedef enum {
+ DEFAULT_CMD = 0,
+ TIMEOUT_CMD,
+ TITLE_CMD,
+ ROOT_CMD,
+ KERNEL_CMD,
+ KERNEL_DOLLAR_CMD,
+ MODULE_CMD,
+ MODULE_DOLLAR_CMD,
+ SEP_CMD,
+ COMMENT_CMD,
+ CHAINLOADER_CMD,
+ ARGS_CMD
+} menu_cmd_t;
+
+extern char *menu_cmds[];
+
+/* For multi- or direct-boot */
+typedef enum {
+ BAM_DIRECT_NOT_SET,
+ BAM_DIRECT_MULTIBOOT,
+ BAM_DIRECT_DBOOT
+} direct_or_multi_t;
+
+extern int bam_verbose;
+extern int bam_force;
+extern direct_or_multi_t bam_direct;
+
+extern error_t upgrade_menu(menu_t *, char *, char *);
+extern void *s_calloc(size_t, size_t);
+extern void *s_realloc(void *, size_t);
+extern char *s_fgets(char *buf, int n, FILE *fp);
+extern void bam_error(char *format, ...);
+extern void bam_print_stderr(char *format, ...);
+extern error_t dboot_or_multiboot(const char *);
+extern char *get_special(char *);
+extern char *os_to_grubdisk(char *, int);
+extern void update_line(line_t *);
+
+#define BAM_MAXLINE 8192
+
+/* menu.lst comments created by bootadm */
+#define BAM_BOOTADM_HDR "---------- ADDED BY BOOTADM - DO NOT EDIT ----------"
+#define BAM_BOOTADM_FTR "---------------------END BOOTADM--------------------"
+
+/*
+ * menu.lst comments create by Live Upgrade. Note that these are the end of
+ * the comment strings - there will be other text before them.
+ */
+#define BAM_LU_HDR " - ADDED BY LIVE UPGRADE - DO NOT EDIT -----"
+#define BAM_LU_FTR " -------------- END LIVE UPGRADE ------------"
+
+#define BAM_OLDDEF "BOOTADM SAVED DEFAULT: "
+#define BAM_OLD_RC_DEF "BOOTADM RC SAVED DEFAULT: "
+
+/* Title used for failsafe entries */
+#define FAILSAFE_TITLE "Solaris failsafe"
+
+/* multiboot */
+#define MULTI_BOOT "/platform/i86pc/multiboot"
+#define MULTI_BOOT_FAILSAFE "/boot/multiboot"
+#define MULTI_BOOT_FAILSAFE_UNIX "kernel/unix"
+#define MULTI_BOOT_FAILSAFE_LINE "/boot/multiboot kernel/unix -s"
+
+/* directboot kernels */
+#define DIRECT_BOOT_32 "/platform/i86pc/kernel/unix"
+#define DIRECT_BOOT_64 "/platform/i86pc/kernel/amd64/unix"
+#define DIRECT_BOOT_KERNEL "/platform/i86pc/kernel/$ISADIR/unix"
+#define DIRECT_BOOT_FAILSAFE_KERNEL "/boot/platform/i86pc/kernel/unix"
+#define DIRECT_BOOT_FAILSAFE_LINE DIRECT_BOOT_FAILSAFE_KERNEL " -s"
+
+/* Boot archives */
+#define DIRECT_BOOT_ARCHIVE "/platform/i86pc/$ISADIR/boot_archive"
+#define DIRECT_BOOT_ARCHIVE_32 "/platform/i86pc/boot_archive"
+#define DIRECT_BOOT_ARCHIVE_64 "/platform/i86pc/amd64/boot_archive"
+#define MULTI_BOOT_ARCHIVE DIRECT_BOOT_ARCHIVE_32
+#define MINIROOT "/boot/x86.miniroot-safe"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BOOTADM_H */
diff --git a/usr/src/cmd/boot/bootadm/bootadm_upgrade.c b/usr/src/cmd/boot/bootadm/bootadm_upgrade.c
new file mode 100644
index 0000000000..0b375b7fd0
--- /dev/null
+++ b/usr/src/cmd/boot/bootadm/bootadm_upgrade.c
@@ -0,0 +1,575 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <strings.h>
+
+#include <sys/mman.h>
+#include <sys/elf.h>
+#include <sys/multiboot.h>
+
+#include "message.h"
+#include "bootadm.h"
+
+direct_or_multi_t bam_direct = BAM_DIRECT_NOT_SET;
+
+error_t
+dboot_or_multiboot(const char *root)
+{
+ char fname[PATH_MAX];
+ char *image;
+ uchar_t *ident;
+ int fd, m;
+ multiboot_header_t *mbh;
+
+ (void) snprintf(fname, PATH_MAX, "%s/%s", root,
+ "platform/i86pc/kernel/unix");
+ fd = open(fname, O_RDONLY);
+ if (fd < 0) {
+ bam_error(OPEN_FAIL, fname, strerror(errno));
+ return (BAM_ERROR);
+ }
+
+ /*
+ * mmap the first 8K
+ */
+ image = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0);
+ if (image == MAP_FAILED) {
+ bam_error(MMAP_FAIL, fname, strerror(errno));
+ return (BAM_ERROR);
+ }
+
+ ident = (uchar_t *)image;
+ if (ident[EI_MAG0] != ELFMAG0 || ident[EI_MAG1] != ELFMAG1 ||
+ ident[EI_MAG2] != ELFMAG2 || ident[EI_MAG3] != ELFMAG3) {
+ bam_error(NOT_ELF_FILE, fname);
+ return (BAM_ERROR);
+ }
+ if (ident[EI_CLASS] != ELFCLASS32) {
+ bam_error(WRONG_ELF_CLASS, fname, ident[EI_CLASS]);
+ return (BAM_ERROR);
+ }
+
+ /*
+ * The GRUB multiboot header must be 32-bit aligned and completely
+ * contained in the 1st 8K of the file. If the unix binary has
+ * a multiboot header, then it is a 'dboot' kernel. Otherwise,
+ * this kernel must be booted via multiboot -- we call this a
+ * 'multiboot' kernel.
+ */
+ bam_direct = BAM_DIRECT_MULTIBOOT;
+ for (m = 0; m < 8192 - sizeof (multiboot_header_t); m += 4) {
+ mbh = (void *)(image + m);
+ if (mbh->magic == MB_HEADER_MAGIC) {
+ bam_direct = BAM_DIRECT_DBOOT;
+ break;
+ }
+ }
+ (void) munmap(image, 8192);
+ (void) close(fd);
+ return (BAM_SUCCESS);
+}
+
+#define INST_RELEASE "var/sadm/system/admin/INST_RELEASE"
+
+/*
+ * Return true if root has been bfu'ed. bfu will blow away
+ * var/sadm/system/admin/INST_RELEASE, so if it's still there, we can
+ * assume the system has not been bfu'ed.
+ */
+static int
+is_bfu_system(const char *root)
+{
+ static int is_bfu = -1;
+ char path[PATH_MAX];
+ struct stat sb;
+
+ if (is_bfu != -1)
+ return (is_bfu);
+
+ (void) snprintf(path, sizeof (path), "%s/%s", root, INST_RELEASE);
+ if (stat(path, &sb) != 0) {
+ is_bfu = 1;
+ } else {
+ is_bfu = 0;
+ }
+ return (is_bfu);
+}
+
+#define MENU_URL(root) (is_bfu_system(root) ? \
+ "http://www.sun.com/msg/SUNOS-8000-CF" : \
+ "http://www.sun.com/msg/SUNOS-8000-AK")
+
+/*
+ * Simply allocate a new line and copy in cmd + sep + arg
+ */
+void
+update_line(line_t *linep)
+{
+ size_t size;
+
+ free(linep->line);
+ size = strlen(linep->cmd) + strlen(linep->sep) + strlen(linep->arg) + 1;
+ linep->line = s_calloc(1, size);
+ (void) snprintf(linep->line, size, "%s%s%s", linep->cmd, linep->sep,
+ linep->arg);
+}
+
+/*
+ * The parse_kernel_line function examines a menu.lst kernel line. For
+ * multiboot, this is:
+ *
+ * kernel <multiboot path> <flags1> <kernel path> <flags2>
+ *
+ * <multiboot path> is either /platform/i86pc/multiboot or /boot/multiboot
+ *
+ * <kernel path> may be missing, or may be any full or relative path to unix.
+ * We check for it by looking for a word ending in "/unix". If it ends
+ * in "kernel/unix", we upgrade it to a 32-bit entry. If it ends in
+ * "kernel/amd64/unix", we upgrade it to the default entry. Otherwise,
+ * it's a custom kernel, and we skip it.
+ *
+ * <flags*> are anything that doesn't fit either of the above - these will be
+ * copied over.
+ *
+ * For direct boot, the defaults are
+ *
+ * kernel$ <kernel path> <flags>
+ *
+ * <kernel path> is one of:
+ * /platform/i86pc/kernel/$ISADIR/unix
+ * /platform/i86pc/kernel/unix
+ * /platform/i86pc/kernel/amd64/unix
+ * /boot/platform/i86pc/kernel/unix
+ *
+ * If <kernel path> is any of the last three, the command may also be "kernel".
+ *
+ * <flags> is anything that isn't <kernel path>.
+ *
+ * This function is only called if it applies to our target boot environment.
+ * If we can't make any sense of the kernel line, an error is printed and
+ * BAM_ERROR is returned.
+ *
+ * The desired install type is given in the global variable bam_direct.
+ * If the kernel line is of a different install type, we change it to the
+ * preferred type. If the kernel line is already of the correct install
+ * type, we do nothing. Either way, BAM_SUCCESS is returned.
+ *
+ * For safety, we do one more check: if the kernel path starts with /boot,
+ * we verify that the new kernel exists before changing it. This is mainly
+ * done for bfu, as it may cause the failsafe archives to be a different
+ * boot architecture from the newly bfu'ed system.
+ */
+static error_t
+parse_kernel_line(line_t *linep, const char *root, uint8_t *flags)
+{
+ char path[PATH_MAX];
+ int len, left, total_len;
+ struct stat sb;
+ char *new_ptr, *new_arg, *old_ptr;
+ menu_cmd_t which;
+
+ /* Used when changing a multiboot line to dboot */
+ char *unix_ptr, *flags1_ptr, *flags2_ptr;
+
+ /*
+ * Note that BAM_ENTRY_DBOOT refers to the entry we're looking at, not
+ * necessarily the system type.
+ */
+ if (strncmp(linep->arg, DIRECT_BOOT_32,
+ sizeof (DIRECT_BOOT_32) - 1) == 0) {
+ *flags |= BAM_ENTRY_DBOOT | BAM_ENTRY_32BIT;
+ } else if ((strncmp(linep->arg, DIRECT_BOOT_KERNEL,
+ sizeof (DIRECT_BOOT_KERNEL) - 1) == 0) ||
+ (strncmp(linep->arg, DIRECT_BOOT_64,
+ sizeof (DIRECT_BOOT_64) - 1) == 0) ||
+ (strncmp(linep->arg, DIRECT_BOOT_FAILSAFE_KERNEL,
+ sizeof (DIRECT_BOOT_FAILSAFE_KERNEL) - 1) == 0)) {
+ *flags |= BAM_ENTRY_DBOOT;
+ } else if ((strncmp(linep->arg, MULTI_BOOT,
+ sizeof (MULTI_BOOT) - 1) == 0) ||
+ (strncmp(linep->arg, MULTI_BOOT_FAILSAFE,
+ sizeof (MULTI_BOOT_FAILSAFE) - 1) == 0)) {
+ *flags &= ~BAM_ENTRY_DBOOT;
+ } else {
+ bam_error(NO_KERNEL_MATCH, linep->lineNum, MENU_URL(root));
+ return (BAM_ERROR);
+ }
+
+ if (((*flags & BAM_ENTRY_DBOOT) && (bam_direct == BAM_DIRECT_DBOOT)) ||
+ (((*flags & BAM_ENTRY_DBOOT) == 0) &&
+ (bam_direct == BAM_DIRECT_MULTIBOOT))) {
+
+ /* No action needed */
+ return (BAM_SUCCESS);
+ }
+
+ if (*flags & BAM_ENTRY_MINIROOT) {
+ /*
+ * We're changing boot architectures - make sure
+ * the multiboot failsafe still exists.
+ */
+ (void) snprintf(path, PATH_MAX, "%s%s", root,
+ (*flags & BAM_ENTRY_DBOOT) ? MULTI_BOOT_FAILSAFE :
+ DIRECT_BOOT_FAILSAFE_KERNEL);
+ if (stat(path, &sb) != 0) {
+ if (bam_verbose) {
+ bam_error(FAILSAFE_MISSING, linep->lineNum);
+ }
+ return (BAM_SUCCESS);
+ }
+ }
+
+ /*
+ * Make sure we have the correct cmd - either kernel or kernel$
+ * The failsafe entry should always be KERNEL_CMD.
+ */
+ which = ((bam_direct == BAM_DIRECT_MULTIBOOT) ||
+ (*flags & BAM_ENTRY_MINIROOT)) ? KERNEL_CMD : KERNEL_DOLLAR_CMD;
+ free(linep->cmd);
+ len = strlen(menu_cmds[which]) + 1;
+ linep->cmd = s_calloc(1, len);
+ (void) strncpy(linep->cmd, menu_cmds[which], len);
+
+ /*
+ * Since all arguments are copied, the new arg string should be close
+ * in size to the old one. Just add 32 to cover the difference in
+ * the boot path.
+ */
+ total_len = strlen(linep->arg) + 32;
+ new_arg = s_calloc(1, total_len);
+ old_ptr = strchr(linep->arg, ' ');
+ if (old_ptr != NULL)
+ old_ptr++;
+
+ /*
+ * Transitioning from dboot to multiboot is pretty simple. We
+ * copy in multiboot and any args.
+ */
+ if (bam_direct == BAM_DIRECT_MULTIBOOT) {
+ if (old_ptr == NULL) {
+ (void) snprintf(new_arg, total_len, "%s",
+ (*flags & BAM_ENTRY_MINIROOT) ?
+ MULTI_BOOT_FAILSAFE : MULTI_BOOT);
+ } else {
+ (void) snprintf(new_arg, total_len, "%s %s",
+ (*flags & BAM_ENTRY_MINIROOT) ?
+ MULTI_BOOT_FAILSAFE : MULTI_BOOT, old_ptr);
+ }
+ goto done;
+ }
+
+ /*
+ * Transitioning from multiboot to directboot is a bit more
+ * complicated, since we may have two sets of arguments to
+ * copy and a unix path to parse.
+ *
+ * First, figure out if there's a unix path.
+ */
+ if ((old_ptr != NULL) &&
+ ((unix_ptr = strstr(old_ptr, "/unix")) != NULL)) {
+ /* See if there's anything past unix */
+ flags2_ptr = unix_ptr + sizeof ("/unix");
+ if (*flags2_ptr == '\0') {
+ flags2_ptr = NULL;
+ }
+
+ while ((unix_ptr > old_ptr) && (*unix_ptr != ' '))
+ unix_ptr--;
+
+ if (unix_ptr == old_ptr) {
+ flags1_ptr = NULL;
+ } else {
+ flags1_ptr = old_ptr;
+ }
+
+ if (strstr(unix_ptr, "kernel/unix") != NULL) {
+ *flags |= BAM_ENTRY_32BIT;
+ } else if ((strstr(unix_ptr, "kernel/amd64/unix") == NULL) &&
+ (!bam_force)) {
+ /*
+ * If the above strstr returns NULL, but bam_force is
+ * set, we'll be upgrading an Install kernel. The
+ * result probably won't be what was intended, but we'll
+ * try it anyways.
+ */
+ return (BAM_SKIP);
+ }
+ } else if (old_ptr != NULL) {
+ flags1_ptr = old_ptr;
+ unix_ptr = flags1_ptr + strlen(old_ptr);
+ flags2_ptr = NULL;
+ } else {
+ unix_ptr = flags1_ptr = flags2_ptr = NULL;
+ }
+
+ if (*flags & BAM_ENTRY_MINIROOT) {
+ (void) snprintf(new_arg, total_len, "%s",
+ DIRECT_BOOT_FAILSAFE_KERNEL);
+ } else if (*flags & BAM_ENTRY_32BIT) {
+ (void) snprintf(new_arg, total_len, "%s", DIRECT_BOOT_32);
+ } else {
+ (void) snprintf(new_arg, total_len, "%s", DIRECT_BOOT_KERNEL);
+ }
+
+ /*
+ * We now want to copy flags1_ptr through unix_ptr, and
+ * flags2_ptr through the end of the string
+ */
+ if (flags1_ptr != NULL) {
+ len = strlcat(new_arg, " ", total_len);
+ left = total_len - len;
+ new_ptr = new_arg + len;
+
+ if ((unix_ptr - flags1_ptr) < left)
+ left = (unix_ptr - flags1_ptr) + 1;
+ (void) strlcpy(new_ptr, flags1_ptr, left);
+ }
+ if (flags2_ptr != NULL) {
+ (void) strlcat(new_arg, " ", total_len);
+ (void) strlcat(new_arg, flags2_ptr, total_len);
+ }
+
+done:
+ free(linep->arg);
+ linep->arg = new_arg;
+ update_line(linep);
+ return (BAM_SUCCESS);
+}
+
+/*
+ * Similar to above, except this time we're looking at a module line,
+ * which is quite a bit simpler.
+ *
+ * Under multiboot, the archive line is:
+ *
+ * module /platform/i86pc/boot_archive
+ *
+ * Under directboot, the archive line is:
+ *
+ * module$ /platform/i86pc/$ISADIR/boot_archive
+ *
+ * which may be specified exactly as either of:
+ *
+ * module /platform/i86pc/boot_archive
+ * module /platform/i86pc/amd64/boot_archive
+ *
+ * For either dboot or multiboot, the failsafe is:
+ *
+ * module /boot/x86.miniroot-safe
+ */
+static error_t
+parse_module_line(line_t *linep, const char *root, uint8_t flags)
+{
+ int len;
+ menu_cmd_t which;
+ char *new;
+
+ /*
+ * If necessary, BAM_ENTRY_MINIROOT was already set in flags
+ * in upgrade_menu(). We re-check BAM_ENTRY_DBOOT here in here
+ * in case the kernel and module lines differ.
+ */
+ if ((strcmp(linep->arg, DIRECT_BOOT_ARCHIVE) == 0) ||
+ (strcmp(linep->arg, DIRECT_BOOT_ARCHIVE_64) == 0)) {
+ flags |= BAM_ENTRY_DBOOT;
+ } else if ((strcmp(linep->arg, MULTI_BOOT_ARCHIVE) == 0) ||
+ (strcmp(linep->arg, MINIROOT) == 0)) {
+ flags &= ~BAM_ENTRY_DBOOT;
+ } else {
+ bam_error(NO_MODULE_MATCH, linep->lineNum, MENU_URL(root));
+ return (BAM_ERROR);
+ }
+
+ if (((flags & BAM_ENTRY_DBOOT) && (bam_direct == BAM_DIRECT_DBOOT)) ||
+ (((flags & BAM_ENTRY_DBOOT) == 0) &&
+ (bam_direct == BAM_DIRECT_MULTIBOOT)) ||
+ ((flags & BAM_ENTRY_MINIROOT) &&
+ (strcmp(linep->cmd, menu_cmds[MODULE_CMD]) == 0))) {
+
+ /* No action needed */
+ return (BAM_SUCCESS);
+ }
+
+ /*
+ * Make sure we have the correct cmd - either module or module$
+ * The failsafe entry should always be MODULE_CMD.
+ */
+ which = ((bam_direct == BAM_DIRECT_MULTIBOOT) ||
+ (flags & BAM_ENTRY_MINIROOT)) ? MODULE_CMD : MODULE_DOLLAR_CMD;
+ free(linep->cmd);
+ len = strlen(menu_cmds[which]) + 1;
+ linep->cmd = s_calloc(1, len);
+ (void) strncpy(linep->cmd, menu_cmds[which], len);
+
+ if (flags & BAM_ENTRY_MINIROOT) {
+ new = MINIROOT;
+ } else if ((bam_direct == BAM_DIRECT_DBOOT) &&
+ ((flags & BAM_ENTRY_32BIT) == 0)) {
+ new = DIRECT_BOOT_ARCHIVE;
+ } else {
+ new = MULTI_BOOT_ARCHIVE;
+ }
+
+ free(linep->arg);
+ len = strlen(new) + 1;
+ linep->arg = s_calloc(1, len);
+ (void) strncpy(linep->arg, new, len);
+ update_line(linep);
+
+ return (BAM_SUCCESS);
+}
+
+/*ARGSUSED*/
+error_t
+upgrade_menu(menu_t *mp, char *root, char *opt)
+{
+ entry_t *cur_entry;
+ line_t *cur_line;
+ int i, skipit = 0, num_entries = 0;
+ int *hand_entries = NULL;
+ boolean_t found_kernel = B_FALSE;
+ error_t rv;
+ char *rootdev, *grubdisk = NULL;
+
+ rootdev = get_special(root);
+ if (rootdev) {
+ grubdisk = os_to_grubdisk(rootdev, strlen(root) == 1);
+ free(rootdev);
+ rootdev = NULL;
+ }
+
+ /* Loop through all OS entries in the menu.lst file */
+ for (cur_entry = mp->entries; cur_entry != NULL;
+ cur_entry = cur_entry->next, skipit = 0) {
+
+ if ((cur_entry->flags & BAM_ENTRY_CHAINLOADER) ||
+ ((cur_entry->flags & BAM_ENTRY_MINIROOT) && !bam_force))
+ continue;
+
+ /*
+ * We only change entries added by bootadm and live upgrade,
+ * and warn on the rest, unless the -f flag was passed.
+ */
+ if ((!(cur_entry->flags & (BAM_ENTRY_BOOTADM|BAM_ENTRY_LU))) &&
+ !bam_force) {
+ if (num_entries == 0) {
+ hand_entries = s_calloc(1, sizeof (int));
+ } else {
+ hand_entries = s_realloc(hand_entries,
+ (num_entries + 1) * sizeof (int));
+ }
+ hand_entries[num_entries++] = cur_entry->entryNum;
+ continue;
+ }
+
+ /*
+ * We make two loops through the lines. First, we check if
+ * there is a root entry, and if so, whether we should be
+ * checking this entry.
+ */
+ if ((grubdisk != NULL) && (cur_entry->flags & BAM_ENTRY_ROOT)) {
+ for (cur_line = cur_entry->start; cur_line != NULL;
+ cur_line = cur_line->next) {
+ if ((cur_line->cmd == NULL) ||
+ (cur_line->arg == NULL))
+ continue;
+
+ if (strcmp(cur_line->cmd,
+ menu_cmds[ROOT_CMD]) == 0) {
+ if (strcmp(cur_line->arg,
+ grubdisk) != 0) {
+ /* A different slice */
+ skipit = 1;
+ }
+ break;
+ }
+ if (cur_line == cur_entry->end)
+ break;
+ }
+ }
+ if (skipit)
+ continue;
+
+ for (cur_line = cur_entry->start; cur_line != NULL;
+ cur_line = cur_line->next) {
+
+ /*
+ * We only compare for the length of KERNEL_CMD,
+ * so that KERNEL_DOLLAR_CMD will also match.
+ */
+ if (strncmp(cur_line->cmd, menu_cmds[KERNEL_CMD],
+ strlen(menu_cmds[KERNEL_CMD])) == 0) {
+ rv = parse_kernel_line(cur_line, root,
+ &(cur_entry->flags));
+ if (rv == BAM_SKIP) {
+ break;
+ } else if (rv != BAM_SUCCESS) {
+ return (rv);
+ }
+ found_kernel = B_TRUE;
+ } else if (strncmp(cur_line->cmd,
+ menu_cmds[MODULE_CMD],
+ strlen(menu_cmds[MODULE_CMD])) == 0) {
+ rv = parse_module_line(cur_line, root,
+ cur_entry->flags);
+ if (rv != BAM_SUCCESS) {
+ return (rv);
+ }
+ }
+ if (cur_line == cur_entry->end)
+ break;
+ }
+ }
+
+ /*
+ * We only want to output one error, to avoid confusing a user. We
+ * rank "No kernels changed" as a higher priority than "will not
+ * update hand-added entries", since the former implies the latter.
+ */
+ if (found_kernel == B_FALSE) {
+ bam_error(NO_KERNELS_FOUND, MENU_URL(root));
+ return (BAM_ERROR);
+ } else if (num_entries > 0) {
+ bam_error(HAND_ADDED_ENTRY, MENU_URL(root));
+ bam_print_stderr("Entry Number%s: ", (num_entries > 1) ?
+ "s" : "");
+ for (i = 0; i < num_entries; i++) {
+ bam_print_stderr("%d ", hand_entries[i]);
+ }
+ bam_print_stderr("\n");
+ }
+ return (BAM_WRITE);
+}
diff --git a/usr/src/cmd/boot/bootadm/message.h b/usr/src/cmd/boot/bootadm/message.h
index 0eb28e12b4..6d6dee45d2 100644
--- a/usr/src/cmd/boot/bootadm/message.h
+++ b/usr/src/cmd/boot/bootadm/message.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,6 +32,8 @@
extern "C" {
#endif
+#include <libintl.h>
+
#define FILE_MISS gettext("file not found: %s\n")
#define ARCH_EXEC_MISS gettext("archive creation file not found: %s: %s\n")
@@ -130,6 +132,8 @@ extern "C" {
#define INVALID_ROOT gettext("invalid root entry: %s\n")
+#define NO_KERNEL gettext("No kernel line found in entry %d\n")
+
#define INVALID_KERNEL gettext("invalid kernel entry: %s\n")
#define INVALID_MODULE gettext("invalid module entry: %s\n")
@@ -179,6 +183,8 @@ extern "C" {
#define UNLOCK_FAIL gettext("failed to unlock file: %s: %s\n")
+#define MMAP_FAIL gettext("failed to mmap file: %s: %s\n")
+
#define FILE_LOCKED gettext("Another instance of bootadm (pid %u) is running\n")
#define FLIST_FAIL \
@@ -198,7 +204,7 @@ extern "C" {
#define RDONLY_FS gettext("read-only filesystem: %s\n")
-#define ARCHIVE_FAIL gettext("failed to create boot archive: %s\n")
+#define ARCHIVE_FAIL gettext("Command '%s' failed to create boot archive\n")
#define ARCHIVE_NOT_CREATED gettext("couldn't create boot archive: %s\n")
@@ -321,6 +327,44 @@ the failsafe archive unbootable\n")
#define FILE_REMOVE_FAILED \
gettext("Failed to delete one or more of (%s,%s). Remove manually.\n")
+#define UNKNOWN_KERNEL gettext("Unable to expand %s to a full file path.\n")
+
+#define NOT_DBOOT \
+ gettext("bootadm set-menu %s may only be run on directboot kernels.\n")
+
+#define DEFAULT_NOT_BAM \
+gettext("Default menu.lst entry is not controlled by bootadm. Exiting\n")
+
+#define NO_KERNEL_MATCH \
+gettext("Unexpected kernel command on line %d.\n\
+** YOU MUST MANUALLY CORRECT menu.lst BEFORE REBOOT! **\n\
+For details, see %s\n")
+
+#define NO_MODULE_MATCH \
+gettext("Unexpected module command on line %d.\n\
+** YOU MUST MANUALLY CORRECT menu.lst BEFORE REBOOT! **\n\
+For details, see %s\n")
+
+#define NO_KERNELS_FOUND \
+gettext("Could not find any kernel lines to update. Only entries created by\n\
+bootadm(1M) and lu(1M) can be updated. All other must be manually changed.\n\
+** YOU MUST MANUALLY CORRECT menu.lst BEFORE REBOOT! **\n\
+For details on updating entries, see %s\n")
+
+#define HAND_ADDED_ENTRY \
+gettext("On upgrades, bootadm(1M) will only upgrade entries added by\n\
+bootadm(1M) or lu(1M). The following entry or entries in menu.lst will\n\
+not be upgraded. For details on updating entries, see\n\
+%s\n")
+
+#define NOT_ELF_FILE gettext("%s is not an ELF file.\n")
+
+#define WRONG_ELF_CLASS gettext("%s is wrong ELF class 0x%x\n")
+
+#define FAILSAFE_MISSING \
+gettext("bootadm -m upgrade run, but the failsafe archives have not been\n\
+updated. Not updating line %d\n")
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/boot/scripts/Makefile.com b/usr/src/cmd/boot/scripts/Makefile.com
index 8cd77a555d..b8fe31bc54 100644
--- a/usr/src/cmd/boot/scripts/Makefile.com
+++ b/usr/src/cmd/boot/scripts/Makefile.com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -30,7 +30,7 @@
MANIFEST= boot-archive-update.xml
SVCMETHOD= boot-archive-update
-PROG= create_ramdisk create_diskmap
+PROG= create_ramdisk create_diskmap update_grub
METHODPROG= boot-archive-update
SBINPROG= root_archive
diff --git a/usr/src/cmd/boot/scripts/create_ramdisk.ksh b/usr/src/cmd/boot/scripts/create_ramdisk.ksh
index f26dde26a1..85a5082780 100644
--- a/usr/src/cmd/boot/scripts/create_ramdisk.ksh
+++ b/usr/src/cmd/boot/scripts/create_ramdisk.ksh
@@ -20,33 +20,39 @@
# CDDL HEADER END
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
# ident "%Z%%M% %I% %E% SMI"
format=ufs
ALT_ROOT=
-NO_AMD64=
+compress=yes
+SPLIT=unknown
+ERROR=0
BOOT_ARCHIVE=platform/i86pc/boot_archive
+BOOT_ARCHIVE_64=platform/i86pc/amd64/boot_archive
export PATH=$PATH:/usr/sbin:/usr/bin:/sbin
#
# Parse options
#
-while getopts R: OPT 2> /dev/null
+while [ "$1" != "" ]
do
- case $OPT in
- R) ALT_ROOT="$OPTARG"
+ case $1 in
+ -R) shift
+ ALT_ROOT="$1"
if [ "$ALT_ROOT" != "/" ]; then
echo "Creating ram disk for $ALT_ROOT"
fi
;;
- ?) echo Usage: ${0##*/}: [-R \<root\>]
+ -n|--nocompress) compress=no ;;
+ *) echo Usage: ${0##*/}: [-R \<root\>] [--nocompress]
exit ;;
esac
+ shift
done
if [ -x /usr/bin/mkisofs -o -x /tmp/bfubin/mkisofs ] ; then
@@ -59,7 +65,7 @@ fi
#
release=`uname -r`
if [ "$release" = "5.8" ]; then
- format=ufs
+ format=ufs
fi
shift `expr $OPTIND - 1`
@@ -69,18 +75,34 @@ if [ $# -eq 1 ]; then
echo "Creating ram disk for $ALT_ROOT"
fi
+rundir=`dirname $0`
+if [ ! -x $rundir/symdef ]; then
+ # Shouldn't happen
+ echo "Warning: $rundir/symdef not present."
+ echo "Creating single archive at $ALT_ROOT/platform/i86pc/boot_archive"
+ SPLIT=no
+ compress=no
+elif $rundir/symdef "$ALT_ROOT"/platform/i86pc/kernel/unix \
+ dboot_image 2>/dev/null; then
+ SPLIT=yes
+else
+ SPLIT=no
+ compress=no
+fi
+
+[ -x /usr/bin/gzip ] || compress=no
+
function cleanup
{
- umount -f "$rdmnt" 2>/dev/null
- lofiadm -d "$rdfile" 2>/dev/null
+ umount -f "$rdmnt32" 2>/dev/null
+ umount -f "$rdmnt64" 2>/dev/null
+ lofiadm -d "$rdfile32" 2>/dev/null
+ lofiadm -d "$rdfile64" 2>/dev/null
rm -fr "$rddir" 2> /dev/null
}
function getsize
{
- # should we exclude amd64 binaries?
- [ $is_amd64 -eq 0 ] && NO_AMD64="-type d -name amd64 -prune -o"
-
# Estimate image size and add %10 overhead for ufs stuff.
# Note, we can't use du here in case we're on a filesystem, e.g. zfs,
# in which the disk usage is less than the sum of the file sizes.
@@ -93,87 +115,225 @@ function getsize
# with directories. This results in a total size that's slightly
# bigger than if du was called on a ufs directory.
total_size=$(cd "/$ALT_ROOT"
- find $filelist $NO_AMD64 -ls 2>/dev/null | nawk '
+ find $filelist -ls 2>/dev/null | nawk '
{t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
END {print int(t * 1.10 / 1024)}')
}
+#
+# The first argument can be:
+#
+# "both" - create an archive with both 32-bit and 64-bit binaries
+# "32-bit" - create an archive with only 32-bit binaries
+# "64-bit" - create an archive with only 64-bit binaries
+#
function create_ufs
{
+ which=$1
+ archive=$2
+ lofidev=$3
+
# should we exclude amd64 binaries?
- [ $is_amd64 -eq 0 ] && NO_AMD64="-type d -name amd64 -prune -o"
+ if [ "$which" = "32-bit" ]; then
+ NO_AMD64="-type d -name amd64 -prune -o"
+ rdfile="$rdfile32"
+ rdmnt="$rdmnt32"
+ elif [ "$which" = "64-bit" ]; then
+ NO_AMD64=""
+ rdfile="$rdfile64"
+ rdmnt="$rdmnt64"
+ else
+ NO_AMD64=""
+ rdfile="$rdfile32"
+ rdmnt="$rdmnt32"
+ fi
- mkfile ${total_size}k "$rdfile"
- lofidev=`lofiadm -a "$rdfile"`
newfs $lofidev < /dev/null 2> /dev/null
mkdir "$rdmnt"
mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1
mount -o nologging $lofidev "$rdmnt"
+ files=
# do the actual copy
cd "/$ALT_ROOT"
- find $filelist $NO_AMD64 -print 2> /dev/null | \
- cpio -pdum "$rdmnt" 2> /dev/null
+ for path in `find $filelist $NO_AMD64 -type f -print 2> /dev/null`
+ do
+ if [ "$which" = "both" ]; then
+ files="$files $path"
+ else
+ filetype=`file $path 2>/dev/null |\
+ awk '/ELF/ { print \$3 }'`
+ if [ -z "$filetype" ] || [ "$filetype" = "$which" ]
+ then
+ files="$files $path"
+ fi
+ fi
+ done
+ if [ $compress = yes ]; then
+ ls $files | while read path
+ do
+ dir="${path%/*}"
+ mkdir -p "$rdmnt/$dir"
+ /usr/bin/gzip -c "$path" > "$rdmnt/$path"
+ done
+ else
+ ls $files | cpio -pdum "$rdmnt" 2> /dev/null
+ fi
umount "$rdmnt"
- lofiadm -d "$rdfile"
rmdir "$rdmnt"
+ #
# Check if gzip exists in /usr/bin, so we only try to run gzip
# on systems that have gzip. Then run gzip out of the patch to
# pick it up from bfubin or something like that if needed.
#
- if [ -x /usr/bin/gzip ] ; then
- gzip -c "$rdfile" > "$ALT_ROOT/$BOOT_ARCHIVE-new"
+ # If compress is set, the individual files in the archive are
+ # compressed, and the final compression will accomplish very
+ # little. To save time, we skip the gzip in this case.
+ #
+ if [ $compress = no ] && [ -x /usr/bin/gzip ] ; then
+ gzip -c "$rdfile" > "${archive}-new"
else
- cat "$rdfile" > "$ALT_ROOT/$BOOT_ARCHIVE-new"
+ cat "$rdfile" > "${archive}-new"
fi
}
+#
+# The first argument can be:
+#
+# "both" - create an archive with both 32-bit and 64-bit binaries
+# "32-bit" - create an archive with only 32-bit binaries
+# "64-bit" - create an archive with only 64-bit binaries
+#
function create_isofs
{
+ which=$1
+ archive=$2
+
# should we exclude amd64 binaries?
- [ $is_amd64 = 0 ] && NO_AMD64="-m amd64"
+ if [ "$which" = "32-bit" ]; then
+ NO_AMD64="-type d -name amd64 -prune -o"
+ rdmnt="$rdmnt32"
+ errlog="$errlog32"
+ elif [ "$which" = "64-bit" ]; then
+ NO_AMD64=""
+ rdmnt="$rdmnt64"
+ errlog="$errlog64"
+ else
+ NO_AMD64=""
+ rdmnt="$rdmnt32"
+ errlog="$errlog32"
+ fi
# create image directory seed with graft points
mkdir "$rdmnt"
files=
- isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames $NO_AMD64"
- for path in $filelist
+ isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames"
+
+ cd "/$ALT_ROOT"
+ for path in `find $filelist $NO_AMD64 -type f -print 2> /dev/null`
do
- if [ -d "$ALT_ROOT/$path" ]; then
- isocmd="$isocmd $path/=\"$ALT_ROOT/$path\""
- mkdir -p "$rdmnt/$path"
- elif [ -f "$ALT_ROOT/$path" ]; then
+ if [ "$which" = "both" ]; then
files="$files $path"
+ else
+ filetype=`file $path 2>/dev/null |\
+ awk '/ELF/ { print \$3 }'`
+ if [ -z "$filetype" ] || [ "$filetype" = "$which" ]
+ then
+ files="$files $path"
+ fi
fi
done
- cd "/$ALT_ROOT"
- find $files 2> /dev/null | cpio -pdum "$rdmnt" 2> /dev/null
+ if [ $compress = yes ]; then
+ ls $files | while read path
+ do
+ dir="${path%/*}"
+ mkdir -p "$rdmnt/$dir"
+ /usr/bin/gzip -c "$path" > "$rdmnt/$path"
+ done
+ else
+ ls $files | cpio -pdum "$rdmnt" 2> /dev/null
+ fi
isocmd="$isocmd \"$rdmnt\""
rm -f "$errlog"
+ #
# Check if gzip exists in /usr/bin, so we only try to run gzip
# on systems that have gzip. Then run gzip out of the patch to
# pick it up from bfubin or something like that if needed.
#
- if [ -x /usr/bin/gzip ] ; then
+ # If compress is set, the individual files in the archive are
+ # compressed, and the final compression will accomplish very
+ # little. To save time, we skip the gzip in this case.
+ #
+ if [ $compress = no ] && [ -x /usr/bin/gzip ] ; then
ksh -c "$isocmd" 2> "$errlog" | \
- gzip > "$ALT_ROOT/$BOOT_ARCHIVE-new"
+ gzip > "${archive}-new"
else
- ksh -c "$isocmd" 2> "$errlog" > "$ALT_ROOT/$BOOT_ARCHIVE-new"
+ ksh -c "$isocmd" 2> "$errlog" > "${archive}-new"
fi
if [ -s "$errlog" ]; then
grep Error: "$errlog" >/dev/null 2>&1
if [ $? -eq 0 ]; then
grep Error: "$errlog"
- rm -f "$ALT_ROOT/$BOOT_ARCHIVE-new"
+ rm -f "${archive}-new"
fi
fi
rm -f "$errlog"
}
+function create_archive
+{
+ which=$1
+ archive=$2
+ lofidev=$3
+
+ echo "updating $archive...this may take a minute"
+
+ if [ "$format" = "ufs" ]; then
+ create_ufs "$which" "$archive" "$lofidev"
+ else
+ create_isofs "$which" "$archive"
+ fi
+
+ # sanity check the archive before moving it into place
+ #
+ ARCHIVE_SIZE=`du -k "${archive}-new" | cut -f 1`
+ if [ $compress = yes ]
+ then
+ #
+ # 'file' will report "English text" for uncompressed
+ # boot_archives. Checking for that doesn't seem stable,
+ # so we just check that the file exists.
+ #
+ ls "${archive}-new" >/dev/null 2>&1
+ else
+ #
+ # the file type check also establishes that the
+ # file exists at all
+ #
+ file "${archive}-new" | grep gzip > /dev/null
+ fi
+
+ if [ $? = 1 ] && [ -x /usr/bin/gzip ] || [ $ARCHIVE_SIZE -lt 5000 ]
+ then
+ #
+ # Two of these functions may be run in parallel. We
+ # need to allow the other to clean up, so we can't
+ # exit immediately. Instead, we set a flag.
+ #
+ echo "update of $archive failed"
+ ERROR=1
+ else
+ lockfs -f "/$ALT_ROOT" 2>/dev/null
+ mv "${archive}-new" "$archive"
+ lockfs -f "/$ALT_ROOT" 2>/dev/null
+ fi
+
+}
+
#
# get filelist
#
@@ -186,33 +346,35 @@ then
fi
filelist=$(sort -u $files)
-#
-# decide if cpu is amd64 capable
-#
-prtconf -v /devices | grep CPU_not_amd64 > /dev/null 2>&1
-is_amd64=$?
-
scratch=tmp
if [ $format = ufs ] ; then
# calculate image size
getsize
+ # We do two mkfile's of total_size, so double the space
+ (( tmp_needed = total_size * 2 ))
+
# check to see if there is sufficient space in tmpfs
#
tmp_free=`df -b /tmp | tail -1 | awk '{ printf ($2) }'`
(( tmp_free = tmp_free / 2 ))
- if [ $total_size -gt $tmp_free ] ; then
+ if [ $tmp_needed -gt $tmp_free ] ; then
# assumes we have enough scratch space on $ALT_ROOT
scratch="$ALT_ROOT"
fi
fi
rddir="/$scratch/create_ramdisk.$$.tmp"
-rdfile="$rddir/rd.file"
-rdmnt="$rddir/rd.mount"
-errlog="$rddir/rd.errlog"
+rdfile32="$rddir/rd.file.32"
+rdfile64="$rddir/rd.file.64"
+rdmnt32="$rddir/rd.mount.32"
+rdmnt64="$rddir/rd.mount.64"
+errlog32="$rddir/rd.errlog.32"
+errlog64="$rddir/rd.errlog.64"
+lofidev32=""
+lofidev64=""
# make directory for temp files safely
rm -rf "$rddir"
@@ -221,46 +383,46 @@ mkdir "$rddir"
# Clean up upon exit.
trap 'cleanup' EXIT
-echo "updating $ALT_ROOT/$BOOT_ARCHIVE...this may take a minute"
-
-if [ $format = "ufs" ]; then
- create_ufs
+if [ $SPLIT = yes ]; then
+ #
+ # We can't run lofiadm commands in parallel, so we have to do
+ # them here.
+ #
+ if [ "$format" = "ufs" ]; then
+ mkfile ${total_size}k "$rdfile32"
+ lofidev32=`lofiadm -a "$rdfile32"`
+ mkfile ${total_size}k "$rdfile64"
+ lofidev64=`lofiadm -a "$rdfile64"`
+ fi
+ create_archive "32-bit" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32 &
+ create_archive "64-bit" "$ALT_ROOT/$BOOT_ARCHIVE_64" $lofidev64
+ wait
+ if [ "$format" = "ufs" ]; then
+ lofiadm -d "$rdfile32"
+ lofiadm -d "$rdfile64"
+ fi
else
- create_isofs
+ if [ "$format" = "ufs" ]; then
+ mkfile ${total_size}k "$rdfile32"
+ lofidev32=`lofiadm -a "$rdfile32"`
+ fi
+ create_archive "both" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32
+ [ "$format" = "ufs" ] && lofiadm -d "$rdfile32"
fi
-
-# Make sure $BOOT_ARCHIVE-new created by either create_ufs or creat_isofs
-# above is flushed to the backing store before we do anything with it.
-lockfs -f "/$ALT_ROOT"
-
-# sanity check the archive before moving it into place
-# the file type check also establishes that the file exists at all
-#
-ARCHIVE_SIZE=$(/bin/ls -l "$ALT_ROOT/$BOOT_ARCHIVE-new" |
- nawk '{print int($5 / 1024)}')
-file "$ALT_ROOT/$BOOT_ARCHIVE-new" | grep gzip > /dev/null
-
-if [ $? = 1 ] && [ -x /usr/bin/gzip ] || [ $ARCHIVE_SIZE -lt 5000 ]; then
- echo "update of $ALT_ROOT/$BOOT_ARCHIVE failed"
- rm -rf "$rddir"
+if [ $ERROR = 1 ]; then
+ cleanup
exit 1
fi
#
# For the diskless case, hardlink archive to /boot to make it
# visible via tftp. /boot is lofs mounted under /tftpboot/<hostname>.
-# NOTE: this script must work on both client and server
+# NOTE: this script must work on both client and server.
#
grep "[ ]/[ ]*nfs[ ]" "$ALT_ROOT/etc/vfstab" > /dev/null
if [ $? = 0 ]; then
- mv "$ALT_ROOT/$BOOT_ARCHIVE-new" "$ALT_ROOT/$BOOT_ARCHIVE"
- rm -f "$ALT_ROOT/boot/boot_archive"
+ rm -f "$ALT_ROOT/boot/boot_archive" "$ALT_ROOT/boot/amd64/boot_archive"
ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive"
- rm -rf "$rddir"
- exit
+ ln "$ALT_ROOT/$BOOT_ARCHIVE_64" "$ALT_ROOT/boot/amd64/boot_archive"
fi
-
-mv "$ALT_ROOT/$BOOT_ARCHIVE-new" "$ALT_ROOT/$BOOT_ARCHIVE"
-lockfs -f "/$ALT_ROOT"
-
rm -rf "$rddir"
diff --git a/usr/src/cmd/boot/scripts/root_archive.ksh b/usr/src/cmd/boot/scripts/root_archive.ksh
index 40bd1cd755..7321c23e2c 100644
--- a/usr/src/cmd/boot/scripts/root_archive.ksh
+++ b/usr/src/cmd/boot/scripts/root_archive.ksh
@@ -20,7 +20,7 @@
# CDDL HEADER END
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -111,7 +111,7 @@ packmedia()
RELEASE=`basename "$RELEASE"`
mkdir -p "$MEDIA/$RELEASE/Tools/Boot"
- mkdir -p "$MEDIA/boot"
+ mkdir -p "$MEDIA/boot/platform/i86pc/kernel"
# archive package databases to conserve memory
#
@@ -134,6 +134,8 @@ packmedia()
archive_X "$MEDIA" "$MINIROOT"
cp "$MINIROOT/platform/i86pc/multiboot" "$MEDIA/boot"
+ cp "$MINIROOT/platform/i86pc/kernel/unix" \
+ "$MEDIA/boot/platform/i86pc/kernel/unix"
# copy the install menu to menu.lst so we have a menu
# on the install media
diff --git a/usr/src/cmd/boot/scripts/update_grub.ksh b/usr/src/cmd/boot/scripts/update_grub.ksh
new file mode 100644
index 0000000000..86a2ee65c8
--- /dev/null
+++ b/usr/src/cmd/boot/scripts/update_grub.ksh
@@ -0,0 +1,125 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+PATH="/usr/bin:/usr/sbin:${PATH}"; export PATH
+ALT_ROOT=
+
+while getopts R: OPT 2>/dev/null
+do
+ case $OPT in
+ R) ALT_ROOT="$OPTARG"
+ ;;
+ ?) echo "Usage: ${0##*/}: [-R \<root\>]"
+ ;;
+ esac
+done
+
+ARCH=`uname -p`
+
+is_pcfs_boot=yes
+
+check_pcfs_boot()
+{
+ bootdev=`grep -v "^#" "$ALT_ROOT"/etc/vfstab | grep pcfs \
+ | grep "[ ]/stubboot[ ]" | nawk '{print $1}'`
+ if [ X"$bootdev" = "X" ]; then
+ is_pcfs_boot=no
+ fi
+}
+
+#
+# Detect SVM root and return the list of raw devices under the mirror
+#
+get_rootdev_list()
+{
+ if [ -f "$ALT_ROOT"/etc/lu/GRUB_slice ]; then
+ grep '^PHYS_SLICE' "$ALT_ROOT"/etc/lu/GRUB_slice | cut -d= -f2
+ else
+ metadev=`grep -v "^#" "$ALT_ROOT"/etc/vfstab | \
+ grep "[ ]/[ ]" | nawk '{print $2}'`
+ if [[ $metadev = /dev/rdsk/* ]]; then
+ rootdevlist=`echo "$metadev" | sed -e "s#/dev/rdsk/##"`
+ elif [[ $metadev = /dev/md/rdsk/* ]]; then
+ metavol=`echo "$metadev" | sed -e "s#/dev/md/rdsk/##"`
+ rootdevlist=`metastat -p $metavol |\
+ grep -v "^$metavol[ ]" | nawk '{print $4}'`
+ fi
+ for rootdev in $rootdevlist
+ do
+ echo /dev/rdsk/$rootdev
+ done
+ fi
+}
+
+#
+# multiboot: install grub on the boot slice
+#
+install_grub()
+{
+ # Stage 2 blocks must remain untouched
+ STAGE1="$ALT_ROOT"/boot/grub/stage1
+ STAGE2="$ALT_ROOT"/boot/grub/stage2
+
+ if [ $is_pcfs_boot = yes ]; then
+ #
+ # Note: /stubboot/boot/grub/stage2 must stay untouched.
+ #
+ mkdir -p "$ALT_ROOT"/stubboot/boot/grub
+ cp "$ALT_ROOT"/boot/grub/menu.lst "$ALT_ROOT"/stubboot/boot/grub
+ bootdev=`grep -v "^#" "$ALT_ROOT"/etc/vfstab | grep pcfs | \
+ grep "[ ]/stubboot[ ]" | nawk '{print $1}'`
+ rpcfsdev=`echo "$bootdev" | sed -e "s/dev\/dsk/dev\/rdsk/"`
+ if [ X"$rpcfsdev" != X ]; then
+ print "Installing grub on $rpcfsdev"
+ "$ALT_ROOT"/sbin/installgrub $STAGE1 $STAGE2 $rpcfsdev
+ fi
+ fi
+
+ get_rootdev_list | while read rootdev
+ do
+ if [ X"$rpcfsdev" != X ]; then
+ echo "create GRUB menu in "$ALT_ROOT"/stubboot"
+ "$ALT_ROOT"/sbin/bootadm update-menu \
+ -R "$ALT_ROOT"/stubboot -o $rootdev,"$ALT_ROOT"
+ else
+ echo "Creating GRUB menu in ${ALT_ROOT:-/}"
+ $ALT_ROOT/sbin/bootadm update-menu -R ${ALT_ROOT:-/} \
+ -o $rootdev
+ fi
+ print "Installing grub on $rootdev"
+ "$ALT_ROOT"/sbin/installgrub $STAGE1 $STAGE2 $rootdev
+ done
+}
+
+if [ -f "$ALT_ROOT"/platform/i86pc/multiboot -a "$ARCH" = i386 ] ; then
+ check_pcfs_boot
+ install_grub
+fi
+
+exit 0
diff --git a/usr/src/cmd/boot/symdef/Makefile b/usr/src/cmd/boot/symdef/Makefile
new file mode 100644
index 0000000000..dba76dea89
--- /dev/null
+++ b/usr/src/cmd/boot/symdef/Makefile
@@ -0,0 +1,58 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG= symdef
+
+OBJS= symdef.o
+SRCS = $(OBJS:.o=.c)
+
+include ../Makefile.com
+
+.KEEP_STATE:
+
+LDLIBS += -lelf
+
+# Writing into string literals is incorrect. We need to match gcc's
+# behavior, which causes us to take SIGSEGV on such a write.
+CFLAGS += $(XSTRCONST)
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTBOOTSOLARISBINPROG)
+
+clean:
+ -$(RM) $(OBJS)
+
+_msg:
+
+lint: lint_SRCS
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/boot/symdef/symdef.c b/usr/src/cmd/boot/symdef/symdef.c
new file mode 100644
index 0000000000..4a0ddbc1a1
--- /dev/null
+++ b/usr/src/cmd/boot/symdef/symdef.c
@@ -0,0 +1,117 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <libelf.h>
+#include <gelf.h>
+#include <errno.h>
+
+/*
+ * symdef is a very simplified version of nm. It is used by upgrade and
+ * create_ramdisk in situations where we can't guarantee that nm will be around.
+ *
+ * Two arguments are expected: a binary and a symbol name. If the symbol is
+ * found in the name table of the binary, 0 is returned. If it is not found,
+ * 1 is returned. If an error occurs, a message is printed to stderr and -1
+ * is returned.
+ */
+
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr, "USAGE: symdef file_name symbol\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+ int fd = 0;
+ int rv = 1;
+ uint_t cnt, symcnt;
+ Elf *elfp = NULL;
+ Elf_Scn *scn = NULL;
+ size_t shstrndx;
+ GElf_Ehdr ehdr;
+ GElf_Shdr shdr;
+ GElf_Sym sym;
+ Elf32_Word shndx;
+ Elf_Data *symdata, *shndxdata;
+
+ if (argc != 3) {
+ usage();
+ return (-1);
+ }
+
+ fd = open(argv[1], O_RDONLY);
+ if (fd == -1) {
+ (void) fprintf(stderr, "%s\n", strerror(errno));
+ rv = -1;
+ goto done;
+ }
+ if (elf_version(EV_CURRENT) == EV_NONE) {
+ (void) fprintf(stderr, "Elf library version out of date\n");
+ rv = -1;
+ goto done;
+ }
+ elfp = elf_begin(fd, ELF_C_READ, NULL);
+ if ((elfp == NULL) || (elf_kind(elfp) != ELF_K_ELF) ||
+ ((gelf_getehdr(elfp, &ehdr)) == NULL) ||
+ (elf_getshstrndx(elfp, &shstrndx) == 0))
+ goto done;
+
+ while ((scn = elf_nextscn(elfp, scn)) != NULL) {
+ if ((gelf_getshdr(scn, &shdr) == NULL) ||
+ ((shdr.sh_type != SHT_SYMTAB) &&
+ (shdr.sh_type != SHT_DYNSYM)) ||
+ ((symdata = elf_getdata(scn, NULL)) == NULL))
+ continue;
+ symcnt = shdr.sh_size / shdr.sh_entsize;
+ shndxdata = NULL;
+ for (cnt = 0; cnt < symcnt; cnt++) {
+ if ((gelf_getsymshndx(symdata, shndxdata, cnt,
+ &sym, &shndx) != NULL) &&
+ (strcmp(argv[2], elf_strptr(elfp, shdr.sh_link,
+ sym.st_name)) == 0)) {
+ rv = 0;
+ goto done;
+ }
+ }
+ }
+done:
+ if (elfp)
+ (void) elf_end(elfp);
+ if (fd != -1)
+ (void) close(fd);
+ return (rv);
+}
diff --git a/usr/src/cmd/devfsadm/i386/misc_link_i386.c b/usr/src/cmd/devfsadm/i386/misc_link_i386.c
index f855486dee..95fb5895e8 100644
--- a/usr/src/cmd/devfsadm/i386/misc_link_i386.c
+++ b/usr/src/cmd/devfsadm/i386/misc_link_i386.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,6 +48,7 @@ static int smbios(di_minor_t minor, di_node_t node);
static int agp_process(di_minor_t minor, di_node_t node);
static int drm_node(di_minor_t minor, di_node_t node);
static int mc_node(di_minor_t minor, di_node_t node);
+static int xsvc(di_minor_t minor, di_node_t node);
static devfsadm_create_t misc_cbt[] = {
{ "vt00", "ddi_display", NULL,
@@ -89,6 +90,9 @@ static devfsadm_create_t misc_cbt[] = {
{ "agp", "ddi_agp:master", NULL,
TYPE_EXACT, ILEVEL_0, agp_process
},
+ { "pseudo", "ddi_pseudo", NULL,
+ TYPE_EXACT, ILEVEL_0, xsvc
+ },
{ "memory-controller", "ddi_mem_ctrl", NULL,
TYPE_EXACT, ILEVEL_0, mc_node
}
@@ -548,3 +552,22 @@ mc_node(di_minor_t minor, di_node_t node)
(void) devfsadm_mklink(linkpath, node, minor, 0);
return (DEVFSADM_CONTINUE);
}
+
+/*
+ * Creates \M0 devlink for xsvc node
+ */
+static int
+xsvc(di_minor_t minor, di_node_t node)
+{
+ char *mn;
+
+ if (strcmp(di_node_name(node), "xsvc") != 0)
+ return (DEVFSADM_CONTINUE);
+
+ mn = di_minor_name(minor);
+ if (mn == NULL)
+ return (DEVFSADM_CONTINUE);
+
+ (void) devfsadm_mklink(mn, node, minor, 0);
+ return (DEVFSADM_CONTINUE);
+}
diff --git a/usr/src/cmd/eeprom/Makefile b/usr/src/cmd/eeprom/Makefile
index 47011aeb75..9cda9fbd7b 100644
--- a/usr/src/cmd/eeprom/Makefile
+++ b/usr/src/cmd/eeprom/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -27,31 +27,18 @@
#
SUBDIRS= $(MACH)
-MANIFEST=eeprom.xml
-
include ../Makefile.cmd
-ROOTMANIFESTDIR = $(ROOTSVCPLATFORMI86PC)
-
-all:= TARGET= all
-install:= TARGET= install
-clean:= TARGET= clean
-clobber:= TARGET= clobber
-lint:= TARGET= lint
-
-PROG = eeprom
-FILEMODE = 555
-GROUP = sys
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+lint := TARGET= lint
+check := TARGET= check
.KEEP_STATE:
-all install clean clobber lint : $(SUBDIRS)
-
-install: $(SUBDIRS) $(ROOTMANIFEST)
- $(RM) $(ROOTUSRSBINPROG)
- $(LN) $(PLATEXEC) $(ROOTUSRSBINPROG)
-
-check: $(CHKMANIFEST)
+all install clean clobber lint check: $(SUBDIRS)
$(SUBDIRS): FRC
@cd $@; pwd; $(MAKE) $(TARGET)
diff --git a/usr/src/cmd/eeprom/Makefile.com b/usr/src/cmd/eeprom/Makefile.com
index cc5944fd6f..0cc0be6f29 100644
--- a/usr/src/cmd/eeprom/Makefile.com
+++ b/usr/src/cmd/eeprom/Makefile.com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -22,12 +21,10 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright (c) 1993,1998 by Sun Microsystems, Inc.
-# All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
-# cmd/eeprom/Makefile.com
-#
-
+
#
# Create default so empty rules don't
# confuse make
@@ -35,7 +32,6 @@
CLASS = 32
include $(SRCDIR)/../Makefile.cmd
-include $(SRCDIR)/../../Makefile.psm
PROG = eeprom
@@ -43,44 +39,15 @@ FILEMODE = 02555
DIRMODE = 755
GROUP = sys
-#
-# Sparc program implementation supports openprom machines. identical versions
-# are installed in /usr/platform for each machine type
-# because (at this point in time) we have no guarantee that a common version
-# will be available for all potential sparc machines (eg: ICL, solbourne ,...).
-#
-# The identical binary is installed several times (rather than linking them
-# together) because they will be in separate packages.
-#
-# Now that it should be obvious that little (if anything) was gained from
-# this `fix-impl' implementation style, maybe somebody will unroll this in
-# distinct, small and simpler versions for each PROM type.
-#
-IMPL = $(PLATFORM:sun%=sun)
+OBJS = error.o
-prep_OBJS = openprom.o loadlogo.o
-sun_OBJS = openprom.o loadlogo.o
-i86pc_OBJS = benv.o benv_kvm.o benv_sync.o
-OBJS = error.o
-OBJS += $($(IMPL)_OBJS)
LINT_OBJS = $(OBJS:%.o=%.ln)
-
-prep_SOURCES = openprom.c loadlogo.c
-sun_SOURCES = openprom.c loadlogo.c
-i86pc_SOURCES = benv.c benv_kvm.c benv_syn.c
-SOURCES = error.c
-SOURCES += $($(IMPL)_SOURCES)
+SOURCES = $(OBJS:%.o=%.c)
.PARALLEL: $(OBJS)
-%.o: ../common/%.c
- $(COMPILE.c) -o $@ $<
-
%.o: $(SRCDIR)/common/%.c
$(COMPILE.c) -o $@ $<
%.ln: ../common/%.c
$(LINT.c) -c $@ $<
-
-%.ln: $(SRCDIR)/common/%.c
- $(LINT.c) -c $@ $<
diff --git a/usr/src/cmd/eeprom/Makefile.targ b/usr/src/cmd/eeprom/Makefile.targ
index 538108a183..1d819bdabc 100644
--- a/usr/src/cmd/eeprom/Makefile.targ
+++ b/usr/src/cmd/eeprom/Makefile.targ
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -22,11 +21,13 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright (c) 1993 by Sun Microsystems, Inc.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
# cmd/eeprom/Makefile.targ
#
-install: all $(USR_PSM_SBIN_PROG) $(USR_PSM_SBIN_PROG_LINKS)
+
+install: all $(ROOTUSRSBIN) $(ROOTUSRSBINPROG)
$(PROG): $(OBJS)
$(LINK.c) -o $@ $(OBJS) $(LDLIBS)
@@ -35,9 +36,11 @@ $(PROG): $(OBJS)
clean:
-$(RM) $(OBJS)
-$(RM) $(LINT_OBJS)
+ -$(RM) $(PROG)
lint: $(LINT_OBJS)
$(LINT.c) $(LINT_OBJS)
+check:
+
include $(SRCDIR)/../Makefile.targ
-include $(SRCDIR)/../../Makefile.psm.targ
diff --git a/usr/src/cmd/eeprom/i386/Makefile b/usr/src/cmd/eeprom/i386/Makefile
index 33c7bc2ccf..4c28dce186 100644
--- a/usr/src/cmd/eeprom/i386/Makefile
+++ b/usr/src/cmd/eeprom/i386/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -22,23 +21,22 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright (c) 1993 by Sun Microsystems, Inc.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
-# cmd/eeprom/i386/Makefile
-#
-SUBDIRS= i86pc
-all:= TARGET= all
-install:= TARGET= install
-clean:= TARGET= clean
-clobber:= TARGET= clobber
-lint:= TARGET= lint
+SRCDIR = ..
-.KEEP_STATE:
+include $(SRCDIR)/Makefile.com
+
+# We "borrow" some error messages from bootadm. Add the path to pick these up
+CFLAGS += -I../../boot/bootadm
+LINTFLAGS += -I../../boot/bootadm
-all install clean clobber lint : $(SUBDIRS)
+OBJS += benv.o benv_kvm.o
+
+.KEEP_STATE:
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
+all: $(PROG)
-FRC:
+include $(SRCDIR)/Makefile.targ
diff --git a/usr/src/cmd/eeprom/i386/common/benv.c b/usr/src/cmd/eeprom/i386/benv.c
index a1d9809bcc..3e44469f9a 100644
--- a/usr/src/cmd/eeprom/i386/common/benv.c
+++ b/usr/src/cmd/eeprom/i386/benv.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,17 +19,20 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "benv.h"
+#include "message.h"
#include <ctype.h>
#include <stdarg.h>
#include <sys/mman.h>
#include <unistd.h>
+#include <signal.h>
+#include <sys/wait.h>
/*
* Usage: % eeprom [-v] [-f prom_dev] [-]
@@ -40,7 +42,6 @@
extern void get_kbenv(void);
extern void close_kbenv(void);
extern caddr_t get_propval(char *name, char *node);
-extern void sync_benv(void);
extern void setprogname(char *prog);
char *boottree;
@@ -48,7 +49,6 @@ struct utsname uts_buf;
static int test;
int verbose;
-static char *bootargs;
/*
* Concatenate a NULL terminated list of strings into
@@ -69,7 +69,7 @@ strcats(char *s, ...)
} else {
len += strlen(cp);
ret = realloc(ret, len);
- strcat(ret, cp);
+ (void) strcat(ret, cp);
}
}
va_end(ap);
@@ -187,15 +187,262 @@ get_var(char *name, eplist_t *list)
return (NULL);
}
+/*PRINTFLIKE1*/
+static void
+eeprom_error(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ (void) fprintf(stderr, "eeprom: ");
+ (void) vfprintf(stderr, format, ap);
+ va_end(ap);
+}
+
+static int
+exec_cmd(char *cmdline, char *output, int64_t osize)
+{
+ char buf[BUFSIZ];
+ int ret;
+ size_t len;
+ FILE *ptr;
+ sigset_t set;
+ void (*disp)(int);
+
+ if (output)
+ output[0] = '\0';
+
+ /*
+ * For security
+ * - only absolute paths are allowed
+ * - set IFS to space and tab
+ */
+ if (*cmdline != '/') {
+ eeprom_error(ABS_PATH_REQ, cmdline);
+ return (-1);
+ }
+ (void) putenv("IFS= \t");
+
+ /*
+ * We may have been exec'ed with SIGCHLD blocked
+ * unblock it here
+ */
+ (void) sigemptyset(&set);
+ (void) sigaddset(&set, SIGCHLD);
+ if (sigprocmask(SIG_UNBLOCK, &set, NULL) != 0) {
+ eeprom_error(FAILED_SIG, strerror(errno));
+ return (-1);
+ }
+
+ /*
+ * Set SIGCHLD disposition to SIG_DFL for popen/pclose
+ */
+ disp = sigset(SIGCHLD, SIG_DFL);
+ if (disp == SIG_ERR) {
+ eeprom_error(FAILED_SIG, strerror(errno));
+ return (-1);
+ }
+ if (disp == SIG_HOLD) {
+ eeprom_error(BLOCKED_SIG, cmdline);
+ return (-1);
+ }
+
+ ptr = popen(cmdline, "r");
+ if (ptr == NULL) {
+ eeprom_error(POPEN_FAIL, cmdline, strerror(errno));
+ return (-1);
+ }
+
+ /*
+ * If we simply do a pclose() following a popen(), pclose()
+ * will close the reader end of the pipe immediately even
+ * if the child process has not started/exited. pclose()
+ * does wait for cmd to terminate before returning though.
+ * When the executed command writes its output to the pipe
+ * there is no reader process and the command dies with
+ * SIGPIPE. To avoid this we read repeatedly until read
+ * terminates with EOF. This indicates that the command
+ * (writer) has closed the pipe and we can safely do a
+ * pclose().
+ *
+ * Since pclose() does wait for the command to exit,
+ * we can safely reap the exit status of the command
+ * from the value returned by pclose()
+ */
+ while (fgets(buf, sizeof (buf), ptr) != NULL) {
+ if (output && osize > 0) {
+ (void) snprintf(output, osize, "%s", buf);
+ len = strlen(buf);
+ output += len;
+ osize -= len;
+ }
+ }
+
+ /*
+ * If there's a "\n" at the end, we want to chop it off
+ */
+ if (output) {
+ len = strlen(output) - 1;
+ if (output[len] == '\n')
+ output[len] = '\0';
+ }
+
+ ret = pclose(ptr);
+ if (ret == -1) {
+ eeprom_error(PCLOSE_FAIL, cmdline, strerror(errno));
+ return (-1);
+ }
+
+ if (WIFEXITED(ret)) {
+ return (WEXITSTATUS(ret));
+ } else {
+ eeprom_error(EXEC_FAIL, cmdline, ret);
+ return (-1);
+ }
+}
+
+#define BOOTADM_STR "bootadm: "
+
+/*
+ * bootadm starts all error messages with "bootadm: ".
+ * Add a note so users don't get confused on how they ran bootadm.
+ */
+static void
+output_error_msg(const char *msg)
+{
+ size_t len = sizeof (BOOTADM_STR) - 1;
+
+ if (strncmp(msg, BOOTADM_STR, len) == 0) {
+ eeprom_error("error returned from %s\n", msg);
+ } else if (msg[0] != '\0') {
+ eeprom_error("%s\n", msg);
+ }
+}
+
+static char *
+get_bootadm_value(char *name)
+{
+ char *ptr, *ret_str, *end_ptr, *orig_ptr;
+ char output[BUFSIZ];
+ int is_console, is_kernel = 0;
+ size_t len;
+
+ is_console = (strcmp(name, "console") == 0);
+
+ if (strcmp(name, "boot-file") == 0) {
+ is_kernel = 1;
+ ptr = "/sbin/bootadm set-menu kernel 2>&1";
+ } else if (is_console || (strcmp(name, "boot-args") == 0)) {
+ ptr = "/sbin/bootadm set-menu args 2>&1";
+ } else {
+ eeprom_error("Unknown value in get_bootadm_value: %s\n", name);
+ return (NULL);
+ }
+
+ if (exec_cmd(ptr, output, BUFSIZ) != 0) {
+ output_error_msg(output);
+ return (NULL);
+ }
+
+ if (is_console) {
+ if ((ptr = strstr(output, "console=")) == NULL) {
+ return (NULL);
+ }
+ ptr += strlen("console=");
+
+ /*
+ * -B may have comma-separated values. It may also be
+ * followed by other flags.
+ */
+ len = strcspn(ptr, " \t,");
+ ret_str = calloc(len + 1, 1);
+ if (ret_str == NULL) {
+ eeprom_error(NO_MEM, len + 1);
+ return (NULL);
+ }
+ (void) strncpy(ret_str, ptr, len);
+ return (ret_str);
+ } else if (is_kernel) {
+ ret_str = strdup(output);
+ if (ret_str == NULL)
+ eeprom_error(NO_MEM, strlen(output) + 1);
+ return (ret_str);
+ } else {
+ /* If there's no console setting, we can return */
+ if ((orig_ptr = strstr(output, "console=")) == NULL) {
+ return (strdup(output));
+ }
+ len = strcspn(orig_ptr, " \t,");
+ ptr = orig_ptr;
+ end_ptr = orig_ptr + len + 1;
+
+ /* Eat up any white space */
+ while ((*end_ptr == ' ') || (*end_ptr == '\t'))
+ end_ptr++;
+
+ /*
+ * If there's data following the console string, copy it.
+ * If not, cut off the new string.
+ */
+ if (*end_ptr == '\0')
+ *ptr = '\0';
+
+ while (*end_ptr != '\0') {
+ *ptr = *end_ptr;
+ ptr++;
+ end_ptr++;
+ }
+ *ptr = '\0';
+ if ((strchr(output, '=') == NULL) &&
+ (strncmp(output, "-B ", 3) == 0)) {
+ /*
+ * Since we removed the console setting, we no
+ * longer need the initial "-B "
+ */
+ orig_ptr = output + 3;
+ } else {
+ orig_ptr = output;
+ }
+
+ ret_str = strdup(orig_ptr);
+ if (ret_str == NULL)
+ eeprom_error(NO_MEM, strlen(orig_ptr) + 1);
+ return (ret_str);
+ }
+}
+
+/*
+ * If quiet is 1, print nothing if there is no value. If quiet is 0, print
+ * a message.
+ */
+static void
+print_bootadm_value(char *name, int quiet)
+{
+ char *value = get_bootadm_value(name);
+
+ if ((value != NULL) && (value[0] != '\0')) {
+ (void) printf("%s=%s\n", name, value);
+ } else if (quiet == 0) {
+ (void) printf("%s: data not available.\n", name);
+ }
+
+ if (value != NULL)
+ free(value);
+}
+
static void
print_var(char *name, eplist_t *list)
{
benv_ent_t *p;
- if ((p = get_var(name, list)) == NULL)
- printf("%s: data not available.\n", name);
+ if ((strcmp(name, "boot-file") == 0) ||
+ (strcmp(name, "boot-args") == 0) ||
+ (strcmp(name, "console") == 0)) {
+ print_bootadm_value(name, 0);
+ } else if ((p = get_var(name, list)) == NULL)
+ (void) printf("%s: data not available.\n", name);
else
- printf("%s=%s\n", name, p->val ? p->val : "");
+ (void) printf("%s=%s\n", name, p->val ? p->val : "");
}
static void
@@ -206,9 +453,19 @@ print_vars(eplist_t *list)
for (e = list->next; e != list; e = e->next) {
p = (benv_ent_t *)e->item;
- if (p->name != NULL)
- printf("%s=%s\n", p->name, p->val ? p->val : "");
+ if (p->name != NULL) {
+ if ((strcmp(p->name, "boot-file") == 0) ||
+ (strcmp(p->name, "boot-args") == 0) ||
+ (strcmp(p->name, "console") == 0)) {
+ /* handle these separately */
+ continue;
+ }
+ (void) printf("%s=%s\n", p->name, p->val ? p->val : "");
+ }
}
+ print_bootadm_value("boot-file", 1);
+ print_bootadm_value("boot-args", 1);
+ print_bootadm_value("console", 1);
}
/*
@@ -219,35 +476,91 @@ print_vars(eplist_t *list)
static void
put_quoted(FILE *fp, char *val)
{
- putc('\'', fp);
+ (void) putc('\'', fp);
while (*val) {
switch (*val) {
case '\'':
case '\\':
- putc('\\', fp);
+ (void) putc('\\', fp);
/* FALLTHROUGH */
default:
- putc(*val, fp);
+ (void) putc(*val, fp);
break;
}
val++;
}
- putc('\'', fp);
+ (void) putc('\'', fp);
}
static void
-write_bargs(char *name, char *val)
+set_bootadm_var(char *name, char *value)
{
- FILE *fp;
+ char buf[BUFSIZ];
+ char output[BUFSIZ] = "";
+ char *ptr, *console, *args;
+ int is_console;
- if ((fp = fopen(bootargs, "w")) == NULL)
- exit(_error(PERROR, "cannot open %s", bootargs));
+ if (verbose) {
+ (void) printf("old:");
+ print_bootadm_value(name, 0);
+ }
- fprintf(fp, "setprop %s ", name);
- put_quoted(fp, val);
- fprintf(fp, "\n");
+ /*
+ * For security, we single-quote whatever we run on the command line,
+ * and we don't allow single quotes in the string.
+ */
+ if ((ptr = strchr(value, '\'')) != NULL) {
+ eeprom_error("Single quotes are not allowed "
+ "in the %s property.\n", name);
+ return;
+ }
- fclose(fp);
+ is_console = (strcmp(name, "console") == 0);
+ if (strcmp(name, "boot-file") == 0) {
+ (void) snprintf(buf, BUFSIZ, "/sbin/bootadm set-menu "
+ "kernel='%s' 2>&1", value);
+ } else if (is_console || (strcmp(name, "boot-args") == 0)) {
+ if (is_console) {
+ args = get_bootadm_value("boot-args");
+ console = value;
+ } else {
+ args = value;
+ console = get_bootadm_value("console");
+ }
+ if (((args == NULL) || (args[0] == '\0')) &&
+ ((console == NULL) || (console[0] == '\0'))) {
+ (void) snprintf(buf, BUFSIZ, "/sbin/bootadm set-menu "
+ "args= 2>&1");
+ } else if ((args == NULL) || (args[0] == '\0')) {
+ (void) snprintf(buf, BUFSIZ, "/sbin/bootadm "
+ "set-menu args='-B console=%s' 2>&1",
+ console);
+ } else if ((console == NULL) || (console[0] == '\0')) {
+ (void) snprintf(buf, BUFSIZ, "/sbin/bootadm "
+ "set-menu args='%s' 2>&1", args);
+ } else if (strncmp(args, "-B ", 3) != 0) {
+ (void) snprintf(buf, BUFSIZ, "/sbin/bootadm "
+ "set-menu args='-B console=%s %s' 2>&1",
+ console, args);
+ } else {
+ (void) snprintf(buf, BUFSIZ, "/sbin/bootadm "
+ "set-menu args='-B console=%s,%s' 2>&1",
+ console, args + 3);
+ }
+ } else {
+ eeprom_error("Unknown value in set_bootadm_value: %s\n", name);
+ return;
+ }
+
+ if (exec_cmd(buf, output, BUFSIZ) != 0) {
+ output_error_msg(output);
+ return;
+ }
+
+ if (verbose) {
+ (void) printf("new:");
+ print_bootadm_value(name, 0);
+ }
}
static void
@@ -255,8 +568,15 @@ set_var(char *name, char *val, eplist_t *list)
{
benv_ent_t *p;
+ if ((strcmp(name, "boot-file") == 0) ||
+ (strcmp(name, "boot-args") == 0) ||
+ (strcmp(name, "console") == 0)) {
+ set_bootadm_var(name, val);
+ return;
+ }
+
if (verbose) {
- printf("old:");
+ (void) printf("old:");
print_var(name, list);
}
@@ -267,7 +587,7 @@ set_var(char *name, char *val, eplist_t *list)
add_bent(list, NULL, "setprop", name, val);
if (verbose) {
- printf("new:");
+ (void) printf("new:");
print_var(name, list);
}
}
@@ -307,8 +627,6 @@ init_benv(benv_des_t *bd, char *file)
bd->name = file;
else
bd->name = strcats(boottree, "/solaris/bootenv.rc", NULL);
-
- bootargs = strcats(boottree, "/solaris/bootargs.rc", NULL);
}
static void
@@ -636,25 +954,22 @@ write_benv(benv_des_t *bd)
for (e = list->next; e != list; e = e->next) {
bent = (benv_ent_t *)e->item;
name = bent->name;
- if (name)
- if (strcmp(name, "bootargs") == 0) {
- /*
- * Write "bootargs" to bootargs.rc file.
- */
- write_bargs(name, bent->val);
- } else if (bent->val) {
- fprintf(fp, "%s %s ",
+ if (name) {
+ if (bent->val) {
+ (void) fprintf(fp, "%s %s ",
bent->cmd, bent->name);
put_quoted(fp, bent->val);
- fprintf(fp, "\n");
- } else
- fprintf(fp, "%s %s\n",
+ (void) fprintf(fp, "\n");
+ } else {
+ (void) fprintf(fp, "%s %s\n",
bent->cmd, bent->name);
- else
- fprintf(fp, "%s\n", bent->cmd);
+ }
+ } else {
+ (void) fprintf(fp, "%s\n", bent->cmd);
+ }
}
- fclose(fp);
+ (void) fclose(fp);
}
static char *
@@ -679,23 +994,12 @@ get_line(void)
return (NULL);
}
-void
-init_eeprom(void)
-{
-
- /* ignore truncate failure */
- (void) truncate(bootargs, 0);
-
- sync_benv();
-}
-
int
main(int argc, char **argv)
{
int c;
- int init = 0;
int updates = 0;
- char *usage = "Usage: %s [-I] [-v] [-f prom-device]"
+ char *usage = "Usage: %s [-v] [-f prom-device]"
" [variable[=value] ...]";
eplist_t *elist;
benv_des_t *bd;
@@ -705,9 +1009,6 @@ main(int argc, char **argv)
while ((c = getopt(argc, argv, "f:Itv")) != -1)
switch (c) {
- case 'I':
- init++;
- break;
case 'v':
verbose++;
break;
@@ -733,9 +1034,7 @@ main(int argc, char **argv)
elist = bd->elist;
- if (init)
- init_eeprom();
- else if (optind >= argc) {
+ if (optind >= argc) {
print_vars(elist);
return (0);
} else
@@ -761,7 +1060,7 @@ main(int argc, char **argv)
* don't write benv if we are processing delayed writes since
* it is likely that the delayed writes changes bootenv.rc anyway...
*/
- if (!init && updates)
+ if (updates)
write_benv(bd);
close_kbenv();
diff --git a/usr/src/cmd/eeprom/i386/common/benv.h b/usr/src/cmd/eeprom/i386/benv.h
index ec031e67c6..ec031e67c6 100644
--- a/usr/src/cmd/eeprom/i386/common/benv.h
+++ b/usr/src/cmd/eeprom/i386/benv.h
diff --git a/usr/src/cmd/eeprom/i386/common/benv_kvm.c b/usr/src/cmd/eeprom/i386/benv_kvm.c
index b7b912eb73..b7b912eb73 100644
--- a/usr/src/cmd/eeprom/i386/common/benv_kvm.c
+++ b/usr/src/cmd/eeprom/i386/benv_kvm.c
diff --git a/usr/src/cmd/eeprom/sparc/Makefile b/usr/src/cmd/eeprom/sparc/Makefile
index e3579bd4dc..7215f7466a 100644
--- a/usr/src/cmd/eeprom/sparc/Makefile
+++ b/usr/src/cmd/eeprom/sparc/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -22,26 +21,18 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# cmd/eeprom/sparc/Makefile
-#
-SRCDIR=..
-SUBDIRS= sun4u sun4v
+SRCDIR = ..
-all:= TARGET= all
-install:= TARGET= install
-clean:= TARGET= clean
-clobber:= TARGET= clobber
-lint:= TARGET= lint
+include $(SRCDIR)/Makefile.com
-.KEEP_STATE:
+OBJS += openprom.o loadlogo.o
-all install clean clobber lint : $(SUBDIRS)
+.KEEP_STATE:
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
+all: $(PROG)
-FRC:
+include $(SRCDIR)/Makefile.targ
diff --git a/usr/src/cmd/eeprom/common/loadlogo.c b/usr/src/cmd/eeprom/sparc/loadlogo.c
index ebd30f324e..ebd30f324e 100644
--- a/usr/src/cmd/eeprom/common/loadlogo.c
+++ b/usr/src/cmd/eeprom/sparc/loadlogo.c
diff --git a/usr/src/cmd/eeprom/common/openprom.c b/usr/src/cmd/eeprom/sparc/openprom.c
index 36bf325a62..36bf325a62 100644
--- a/usr/src/cmd/eeprom/common/openprom.c
+++ b/usr/src/cmd/eeprom/sparc/openprom.c
diff --git a/usr/src/cmd/mdb/common/kmdb/kaif_start.c b/usr/src/cmd/mdb/common/kmdb/kaif_start.c
index 17f136b307..6c0fc810bb 100644
--- a/usr/src/cmd/mdb/common/kmdb/kaif_start.c
+++ b/usr/src/cmd/mdb/common/kmdb/kaif_start.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -80,6 +80,13 @@ kaif_lock_exit(uintptr_t *lock)
membar_producer();
}
+static void
+kaif_start_slaves(int cmd)
+{
+ kaif_slave_cmd = cmd;
+ kmdb_kdi_start_slaves();
+}
+
static int
kaif_master_loop(kaif_cpusave_t *cpusave)
{
@@ -90,6 +97,12 @@ kaif_master_loop(kaif_cpusave_t *cpusave)
#endif
kaif_trap_set_debugger();
+ /*
+ * If we re-entered due to a ::switch, we need to tell the slave CPUs
+ * to sleep again.
+ */
+ kmdb_kdi_stop_slaves(cpusave->krs_cpu_id, 0);
+
master_loop:
switch (kmdb_dpi_reenter()) {
case KMDB_DPI_CMD_SWITCH_CPU:
@@ -112,7 +125,7 @@ master_loop:
*/
kaif_trap_set_saved(cpusave);
- kaif_slave_cmd = KAIF_SLAVE_CMD_SWITCH;
+ kaif_start_slaves(KAIF_SLAVE_CMD_SWITCH);
/* The new master is now awake */
return (KAIF_CPU_CMD_SWITCH);
@@ -124,7 +137,7 @@ master_loop:
*/
kaif_master_cpuid = KAIF_MASTER_CPUID_UNSET;
membar_producer();
- kaif_slave_cmd = KAIF_SLAVE_CMD_RESUME;
+ kaif_start_slaves(KAIF_SLAVE_CMD_RESUME);
if (kmdb_dpi_work_required())
kmdb_dpi_wrintr_fire();
@@ -141,7 +154,7 @@ master_loop:
return (KAIF_CPU_CMD_RESUME_MASTER);
case KMDB_DPI_CMD_FLUSH_CACHES:
- kaif_slave_cmd = KAIF_SLAVE_CMD_FLUSH;
+ kaif_start_slaves(KAIF_SLAVE_CMD_FLUSH);
/*
* Wait for the other cpus to finish flushing their caches.
@@ -170,9 +183,9 @@ master_loop:
* afraid that I don't want to know the answer.
*/
if (cpusave->krs_cpu_id == 0)
- return (KAIF_CPU_CMD_REBOOT);
+ kmdb_kdi_reboot();
- kaif_slave_cmd = KAIF_SLAVE_CMD_REBOOT;
+ kaif_start_slaves(KAIF_SLAVE_CMD_REBOOT);
/*
* Spin forever, waiting for CPU 0 (apparently a slave) to
@@ -223,7 +236,8 @@ kaif_slave_loop(kaif_cpusave_t *cpusave)
#if defined(__i386) || defined(__amd64)
} else if (slavecmd == KAIF_SLAVE_CMD_REBOOT &&
cpusave->krs_cpu_id == 0) {
- rv = KAIF_CPU_CMD_REBOOT;
+ rv = 0;
+ kmdb_kdi_reboot();
break;
#endif
@@ -238,6 +252,8 @@ kaif_slave_loop(kaif_cpusave_t *cpusave)
cpusave->krs_cpu_acked = 0;
#endif
}
+
+ kmdb_kdi_slave_wait();
}
#if defined(__sparc)
@@ -260,9 +276,7 @@ kaif_select_master(kaif_cpusave_t *cpusave)
membar_producer();
- kmdb_kdi_stop_other_cpus(cpusave->krs_cpu_id,
- kaif_slave_entry);
-
+ kmdb_kdi_stop_slaves(cpusave->krs_cpu_id, 1);
} else {
/* The master was already chosen - go be a slave */
cpusave->krs_cpu_state = KAIF_CPU_STATE_SLAVE;
@@ -405,7 +419,7 @@ kaif_slave_loop_barrier(void)
int not_acked;
int timeout_count = 0;
- kaif_slave_cmd = KAIF_SLAVE_CMD_ACK;
+ kaif_start_slaves(KAIF_SLAVE_CMD_ACK);
/*
* Wait for slave cpus to explicitly acknowledge
diff --git a/usr/src/cmd/mdb/common/kmdb/kaif_start.h b/usr/src/cmd/mdb/common/kmdb/kaif_start.h
index a0234cb493..40ddc252b5 100644
--- a/usr/src/cmd/mdb/common/kmdb/kaif_start.h
+++ b/usr/src/cmd/mdb/common/kmdb/kaif_start.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,7 +29,7 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/types.h>
-#include <kmdb/kaif_regs.h>
+#include <kmdb/kaif.h>
#ifdef __cplusplus
extern "C" {
@@ -40,6 +39,12 @@ extern int kaif_main_loop(kaif_cpusave_t *);
extern int kaif_master_cpuid;
+#define KAIF_MASTER_CPUID_UNSET -1
+
+#define KAIF_CPU_CMD_RESUME 0
+#define KAIF_CPU_CMD_RESUME_MASTER 1
+#define KAIF_CPU_CMD_SWITCH 2
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/mdb/common/kmdb/kctl/kctl.h b/usr/src/cmd/mdb/common/kmdb/kctl/kctl.h
index 612ed8db13..8c082d6649 100644
--- a/usr/src/cmd/mdb/common/kmdb/kctl/kctl.h
+++ b/usr/src/cmd/mdb/common/kmdb/kctl/kctl.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -49,7 +49,6 @@ typedef enum {
KCTL_ST_MOD_NOTIFIERS, /* krtld module notifiers registered */
KCTL_ST_THREAD_STARTED, /* WR queue thread started */
KCTL_ST_DBG_ACTIVATED, /* kmdb activated */
- KCTL_ST_KCTL_ACTIVATED, /* kctl activated */
KCTL_ST_ACTIVE, /* kernel is aware of kmdb activation */
KCTL_ST_DEACTIVATING /* debugger is being deactivated */
} kctl_state_t;
@@ -93,9 +92,8 @@ extern void kctl_dprintf(const char *, ...);
extern void kctl_warn(const char *, ...);
extern int kctl_preactivate_isadep(void);
-extern int kctl_activate_isadep(kdi_debugvec_t *);
+extern void kctl_activate_isadep(kdi_debugvec_t *);
extern void kctl_depreactivate_isadep(void);
-extern void kctl_deactivate_isadep(void);
extern void kctl_cleanup(void);
extern void *kctl_boot_tmpinit(void);
diff --git a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_auxv.c b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_auxv.c
index 1ea1216ae6..773a088783 100644
--- a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_auxv.c
+++ b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_auxv.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -83,28 +82,15 @@ kctl_auxv_init(kmdb_auxv_t *kav, const char *cfg, const char **argv, void *romp)
kav->kav_config = cfg;
kav->kav_argv = argv;
+ kav->kav_modpath = kobj_module_path;
- if (kctl.kctl_boot_loaded) {
- /*
- * default_path hasn't been set yet, so we have to fetch the
- * path from OBP.
- */
- ssize_t sz;
-
- if ((sz = BOP_GETPROPLEN(kctl.kctl_boot_ops,
- "module-path")) != -1) {
- kav->kav_modpath = kobj_alloc(sz, KM_TMP);
- (void) BOP_GETPROP(kctl.kctl_boot_ops, "module-path",
- (char *)kav->kav_modpath);
- }
+ kctl_dprintf("kctl_auxv_init: modpath '%s'", kav->kav_modpath);
+ if (kctl.kctl_boot_loaded) {
kav->kav_lookup_by_name = kctl_boot_lookup_by_name;
kav->kav_flags |= KMDB_AUXV_FL_NOUNLOAD;
- } else {
- kav->kav_modpath = default_path;
-
+ } else
kav->kav_lookup_by_name = kctl_lookup_by_name;
- }
if (kctl.kctl_flags & KMDB_F_TRAP_NOSWITCH)
kav->kav_flags |= KMDB_AUXV_FL_NOTRPSWTCH;
diff --git a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_dmod.c b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_dmod.c
index 76fc32bdc6..36a088e437 100644
--- a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_dmod.c
+++ b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_dmod.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -76,7 +76,7 @@ kctl_find_module(char *modname, char *fullname, size_t fullnamelen)
/* If they gave us an absolute path, we don't need to search */
if (modname[0] == '/') {
if (strlen(modname) + 1 > fullnamelen) {
- cmn_err(CE_WARN, "Can't load dmod %s - name too long\n",
+ cmn_err(CE_WARN, "Can't load dmod %s - name too long",
modname);
return (0);
}
@@ -343,7 +343,7 @@ kctl_dmod_unload(kmdb_wr_unload_t *dur)
int rc;
if ((rc = kctl_dmod_unload_common(dur->dur_modctl)) != 0) {
- cmn_err(CE_WARN, "unexpected dmod unload failure: %d\n", rc);
+ cmn_err(CE_WARN, "unexpected dmod unload failure: %d", rc);
dur->dur_errno = rc;
}
}
diff --git a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_main.c b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_main.c
index 13992c6ae2..11b6ec8231 100644
--- a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_main.c
+++ b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_main.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -192,17 +191,13 @@ kctl_memavail(void)
* If we're going to wedge the machine during debugger startup,
* at least let them know why it's going to wedge.
*/
- cmn_err(CE_WARN, "retrying of kmdb allocation of 0x%lx bytes\n",
+ cmn_err(CE_WARN, "retrying of kmdb allocation of 0x%lx bytes",
(ulong_t)needed);
base = kmem_zalloc(needed, KM_SLEEP);
}
- if (kdi_dvec->dv_memavail(base, needed) < 0) {
- cmn_err(CE_WARN, "failed to add memory to debugger\n");
- kmem_free(base, needed);
- }
-
+ kdi_dvec->dv_memavail(base, needed);
kctl.kctl_mrbase = base;
kctl.kctl_mrsize = needed;
}
@@ -223,10 +218,6 @@ kctl_cleanup(void)
kdi_dvec = NULL;
/*FALLTHROUGH*/
- case KCTL_ST_KCTL_ACTIVATED:
- kctl_deactivate_isadep();
- /*FALLTHROUGH*/
-
case KCTL_ST_DBG_ACTIVATED:
KCTL_PROM_LOCK;
kmdb_deactivate();
@@ -375,10 +366,7 @@ kctl_startup_activate(uint_t flags)
dvec->dv_kctl_thravail = kctl_startup_thread;
dvec->dv_kctl_memavail = kctl_memavail;
- if (kctl_activate_isadep(dvec) != 0)
- return (EIO);
-
- (void) kctl_set_state(KCTL_ST_KCTL_ACTIVATED);
+ kctl_activate_isadep(dvec);
kdi_dvec = dvec;
membar_producer();
@@ -425,7 +413,7 @@ kctl_deactivate(void)
goto deactivate_done;
kmdb_kdi_set_unload_request();
- kdi_dvec_enter();
+ kmdb_kdi_kmdb_enter();
/*
* The debugger will pass the request to the work thread, which will
@@ -487,13 +475,14 @@ kctl_boot_activate(struct bootops *ops, void *romp, size_t memsz,
if (memsz == 0)
memsz = KCTL_MEM_GOALSZ;
- kctl.kctl_dseg = (caddr_t)SEGDEBUGBASE;
- kctl.kctl_dseg_size = (memsz > SEGDEBUGSIZE ? SEGDEBUGSIZE : memsz);
+ kctl.kctl_dseg = kdi_segdebugbase;
+ kctl.kctl_dseg_size =
+ memsz > kdi_segdebugsize ? kdi_segdebugsize : memsz;
kctl.kctl_memgoalsz = memsz;
if (kctl_boot_dseg_alloc(kctl.kctl_dseg, kctl.kctl_dseg_size) < 0) {
- kctl_warn("kmdb: failed to allocate %d-byte debugger area at "
- "%x", kctl.kctl_dseg_size, kctl.kctl_dseg);
+ kctl_warn("kmdb: failed to allocate %lu-byte debugger area at "
+ "%p", kctl.kctl_dseg_size, (void *)kctl.kctl_dseg);
return (-1);
}
@@ -510,9 +499,10 @@ kctl_boot_activate(struct bootops *ops, void *romp, size_t memsz,
kctl_dprintf("finished with kmdb initialization");
- kctl.kctl_boot_ops = NULL;
kctl_boot_tmpfini(old);
+ kctl.kctl_boot_ops = NULL;
+
return (0);
}
@@ -525,7 +515,7 @@ kctl_modload_activate(size_t memsz, const char *cfg, uint_t flags)
if ((rc = kctl_state_check(kctl.kctl_state, KCTL_ST_INACTIVE)) != 0) {
if ((flags & KMDB_F_AUTO_ENTRY) && rc == EMDB_KACTIVE) {
- kdi_dvec_enter();
+ kmdb_kdi_kmdb_enter();
rc = 0;
}
@@ -538,8 +528,9 @@ kctl_modload_activate(size_t memsz, const char *cfg, uint_t flags)
if (memsz == 0)
memsz = KCTL_MEM_GOALSZ;
- kctl.kctl_dseg = (caddr_t)SEGDEBUGBASE;
- kctl.kctl_dseg_size = (memsz > SEGDEBUGSIZE ? SEGDEBUGSIZE : memsz);
+ kctl.kctl_dseg = kdi_segdebugbase;
+ kctl.kctl_dseg_size =
+ memsz > kdi_segdebugsize ? kdi_segdebugsize : memsz;
kctl.kctl_memgoalsz = memsz;
if ((rc = kctl_dseg_alloc(kctl.kctl_dseg, kctl.kctl_dseg_size)) != 0)
@@ -559,7 +550,7 @@ kctl_modload_activate(size_t memsz, const char *cfg, uint_t flags)
kctl_memavail(); /* Must be after kdi_dvec is set */
if (kctl.kctl_flags & KMDB_F_AUTO_ENTRY)
- kdi_dvec_enter();
+ kmdb_kdi_kmdb_enter();
mutex_exit(&kctl.kctl_lock);
return (0);
diff --git a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_wr.c b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_wr.c
index 0b8103ae70..b9d54edc02 100644
--- a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_wr.c
+++ b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_wr.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -256,7 +255,7 @@ kctl_wr_thread(void *arg)
* debugger for processing, so we need to wake the debugger up.
*/
if (kctl_wr_process() > 0)
- kdi_dvec_enter();
+ kmdb_kdi_kmdb_enter();
}
/*
diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_dpi_impl.h b/usr/src/cmd/mdb/common/kmdb/kmdb_dpi_impl.h
index fe4bd9458b..a94cfae990 100644
--- a/usr/src/cmd/mdb/common/kmdb/kmdb_dpi_impl.h
+++ b/usr/src/cmd/mdb/common/kmdb/kmdb_dpi_impl.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -95,10 +94,8 @@ struct dpi_ops {
void (*dpo_dump_crumbs)(uintptr_t, int);
- int (*dpo_memrange_add)(caddr_t, size_t);
-
#if defined(__i386) || defined(__amd64)
- void (*dpo_msr_add)(const kmdb_msr_t *);
+ void (*dpo_msr_add)(const kdi_msr_t *);
uint64_t (*dpo_msr_get)(int, uint_t);
#endif
diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.c b/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.c
index 7d2f674748..c9e3358af9 100644
--- a/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.c
+++ b/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -50,7 +49,7 @@
#include <sys/kdi_impl.h>
-#include <kmdb/kmdb_kdi_impl.h>
+#include <kmdb/kmdb_kdi.h>
#include <kmdb/kmdb_dpi.h>
#include <kmdb/kmdb_kvm.h>
#include <kmdb/kmdb_promif.h>
@@ -221,6 +220,12 @@ kmdb_kdi_get_polled_io(void)
return (mdb.m_kdi->kdi_get_polled_io());
}
+void
+kmdb_kdi_kmdb_enter(void)
+{
+ mdb.m_kdi->kdi_kmdb_enter();
+}
+
int
kmdb_kdi_vtop(uintptr_t va, physaddr_t *pap)
{
@@ -284,8 +289,6 @@ kmdb_kdi_init(kdi_t *kdi, kmdb_auxv_t *kav)
kdi_auxv = kav;
kmdb_kdi_init_isadep(kdi, kav);
-
- kdi_cpu_init();
}
void
diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.h b/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.h
index 8ffd0f2cab..28f047a33a 100644
--- a/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.h
+++ b/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -69,7 +68,10 @@ extern int kmdb_kdi_mod_haschanged(struct modctl *, struct module *,
struct modctl *, struct module *);
extern ssize_t kmdb_kdi_pread(void *, size_t, physaddr_t);
extern ssize_t kmdb_kdi_pwrite(void *, size_t, physaddr_t);
-extern void kmdb_kdi_stop_other_cpus(int, void (*)(void)); /* Driver OK */
+extern void kmdb_kdi_stop_slaves(int, int);
+extern void kmdb_kdi_start_slaves(void);
+extern void kmdb_kdi_slave_wait(void);
+extern void kmdb_kdi_kmdb_enter(void); /* Driver OK */
extern void kmdb_kdi_system_claim(void);
extern void kmdb_kdi_system_release(void);
extern size_t kmdb_kdi_range_is_nontoxic(uintptr_t, size_t, int);
diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c b/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c
index 18f0d4eb7c..a79d455af1 100644
--- a/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c
+++ b/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -977,7 +976,7 @@ kmt_lookup_by_name(mdb_tgt_t *t, const char *obj, const char *name,
break;
case (uintptr_t)MDB_TGT_OBJ_RTLD:
- obj = KMT_RTLD_NAME;
+ obj = kmt->kmt_rtld_name;
/*FALLTHROUGH*/
default:
@@ -1081,7 +1080,7 @@ kmt_symbol_iter(mdb_tgt_t *t, const char *obj, uint_t which, uint_t type,
return (0);
case (uintptr_t)MDB_TGT_OBJ_RTLD:
- obj = KMT_RTLD_NAME;
+ obj = kmt->kmt_rtld_name;
/*FALLTHROUGH*/
default:
@@ -1197,6 +1196,20 @@ kmt_addr_to_map(mdb_tgt_t *t, uintptr_t addr)
return (NULL);
}
+static kmt_module_t *
+kmt_module_by_name(kmt_data_t *kmt, const char *name)
+{
+ kmt_module_t *km;
+
+ for (km = mdb_list_next(&kmt->kmt_modlist); km != NULL;
+ km = mdb_list_next(km)) {
+ if (strcmp(name, km->km_name) == 0)
+ return (km);
+ }
+
+ return (NULL);
+}
+
static const mdb_map_t *
kmt_name_to_map(mdb_tgt_t *t, const char *name)
{
@@ -1214,13 +1227,10 @@ kmt_name_to_map(mdb_tgt_t *t, const char *name)
}
if (name == MDB_TGT_OBJ_RTLD)
- name = KMT_RTLD_NAME; /* replace MDB_TGT_OBJ_RTLD with krtld */
+ name = kmt->kmt_rtld_name;
- for (km = mdb_list_next(&kmt->kmt_modlist); km != NULL;
- km = mdb_list_next(km)) {
- if (strcmp(name, km->km_name) == 0)
- return (kmt_mod_to_map(km, &m));
- }
+ if ((km = kmt_module_by_name(kmt, name)) != NULL)
+ return (kmt_mod_to_map(km, &m));
(void) set_errno(EMDB_NOOBJ);
return (NULL);
@@ -1300,19 +1310,16 @@ kmt_name_to_ctf(mdb_tgt_t *t, const char *name)
kmt_module_t *km;
if (name == MDB_TGT_OBJ_EXEC) {
- name = KMT_CTFPARENT; /* base CTF data is kept in genunix */
+ name = KMT_CTFPARENT;
} else if (name == MDB_TGT_OBJ_RTLD) {
- name = KMT_RTLD_NAME; /* replace with krtld */
+ name = kt->kmt_rtld_name;
} else if (strncmp(name, "DMOD`", 5) == 0) {
/* Request for CTF data for a DMOD symbol */
return (kmdb_module_name_to_ctf(name + 5));
}
- for (km = mdb_list_next(&kt->kmt_modlist); km != NULL;
- km = mdb_list_next(km)) {
- if (strcmp(name, km->km_name) == 0)
- return (kmt_load_ctfdata(t, km));
- }
+ if ((km = kmt_module_by_name(kt, name)) != NULL)
+ return (kmt_load_ctfdata(t, km));
(void) set_errno(EMDB_NOOBJ);
return (NULL);
@@ -2344,6 +2351,12 @@ kmt_activate(mdb_tgt_t *t)
(void) mdb_tgt_register_dcmds(t, &kmt_dcmds[0], MDB_MOD_FORCE);
mdb_tgt_register_regvars(t, kmt->kmt_rds, &kmt_reg_disc, 0);
+
+ /*
+ * Force load of the MDB krtld module, in case it's been rolled into
+ * unix.
+ */
+ (void) mdb_module_load(KMT_RTLD_NAME, MDB_MOD_SILENT | MDB_MOD_DEFER);
}
static void
@@ -2525,6 +2538,8 @@ create_err:
void
kmdb_kvm_startup(void)
{
+ kmt_data_t *kmt = mdb.m_target->t_data;
+
mdb_dprintf(MDB_DBG_KMOD, "kmdb_kvm startup\n");
kmt_sync(mdb.m_target);
@@ -2538,6 +2553,11 @@ kmdb_kvm_startup(void)
* startup.
*/
(void) mdb_tgt_sespec_activate_all(mdb.m_target);
+
+ kmt->kmt_rtld_name = KMT_RTLD_NAME;
+
+ if (kmt_module_by_name(kmt, KMT_RTLD_NAME) == NULL)
+ kmt->kmt_rtld_name = "unix";
}
/*
diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_promif.c b/usr/src/cmd/mdb/common/kmdb/kmdb_promif.c
index 0757ccb48d..135a22e4d0 100644
--- a/usr/src/cmd/mdb/common/kmdb/kmdb_promif.c
+++ b/usr/src/cmd/mdb/common/kmdb/kmdb_promif.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -52,24 +52,31 @@ static char kmdb_prom_readbuf[KMDB_PROM_READBUF_SIZE];
static int kmdb_prom_readbuf_head;
static int kmdb_prom_readbuf_tail;
-static ssize_t
-kmdb_prom_polled_read(caddr_t buf, size_t len)
+static int
+kmdb_prom_getchar(int wait)
{
- uintptr_t arg = (uintptr_t)mdb.m_pio->cons_polledio_argument;
- uintptr_t ischar = (uintptr_t)mdb.m_pio->cons_polledio_ischar;
- int nread = 0;
- int c;
+ struct cons_polledio *pio = mdb.m_pio;
+ uintptr_t ischar;
+ uintptr_t getchar;
+ uintptr_t arg;
+
+ if (pio == NULL || pio->cons_polledio_getchar == NULL) {
+ int c;
+ while ((c = prom_mayget()) == -1) {
+ if (!wait)
+ return (-1);
+ }
+ return (c);
+ }
- while ((ischar == NULL || kmdb_dpi_call(ischar, 1, &arg)) &&
- nread < len) {
- c = kmdb_dpi_call((uintptr_t)mdb.m_pio->cons_polledio_getchar,
- 1, &arg);
+ ischar = (uintptr_t)pio->cons_polledio_ischar;
+ getchar = (uintptr_t)pio->cons_polledio_getchar;
+ arg = (uintptr_t)pio->cons_polledio_argument;
- *buf++ = (char)c;
- nread++;
- }
+ if (!wait && ischar != NULL && !kmdb_dpi_call(ischar, 1, &arg))
+ return (-1);
- return (nread);
+ return ((int)kmdb_dpi_call(getchar, 1, &arg));
}
static ssize_t
@@ -90,17 +97,18 @@ kmdb_prom_polled_write(caddr_t buf, size_t len)
}
static ssize_t
-kmdb_prom_reader(caddr_t buf, size_t len)
+kmdb_prom_reader(caddr_t buf, size_t len, int wait)
{
int nread = 0;
int c;
- if (mdb.m_pio != NULL && mdb.m_pio->cons_polledio_getchar != NULL)
- return (kmdb_prom_polled_read(buf, len));
+ while (nread < len) {
+ if ((c = kmdb_prom_getchar(wait)) == -1)
+ break;
- while (nread < len && (c = prom_mayget()) != -1) {
*buf++ = (char)c;
nread++;
+ wait = 0;
}
return (nread);
@@ -217,7 +225,7 @@ check_int(char *buf, size_t len)
* delivering an interrupt directly if we find one.
*/
static void
-kmdb_prom_fill_readbuf(int check_for_int)
+kmdb_prom_fill_readbuf(int check_for_int, int wait)
{
int oldhead, left, n;
@@ -238,7 +246,7 @@ kmdb_prom_fill_readbuf(int check_for_int)
* the common code handle the second.
*/
if ((n = kmdb_prom_reader(kmdb_prom_readbuf +
- kmdb_prom_readbuf_head, left)) <= 0)
+ kmdb_prom_readbuf_head, left, wait)) <= 0)
return;
oldhead = kmdb_prom_readbuf_head;
@@ -255,7 +263,7 @@ kmdb_prom_fill_readbuf(int check_for_int)
left = kmdb_prom_readbuf_tail - kmdb_prom_readbuf_head - 1;
if (left > 0) {
if ((n = kmdb_prom_reader(kmdb_prom_readbuf +
- kmdb_prom_readbuf_head, left)) <= 0)
+ kmdb_prom_readbuf_head, left, wait)) <= 0)
return;
oldhead = kmdb_prom_readbuf_head;
@@ -272,7 +280,7 @@ kmdb_prom_fill_readbuf(int check_for_int)
if (check_for_int) {
char c;
- while (kmdb_prom_reader(&c, 1) == 1)
+ while (kmdb_prom_reader(&c, 1, 0) == 1)
check_int(&c, 1);
}
}
@@ -280,7 +288,7 @@ kmdb_prom_fill_readbuf(int check_for_int)
void
kmdb_prom_check_interrupt(void)
{
- kmdb_prom_fill_readbuf(1);
+ kmdb_prom_fill_readbuf(1, 0);
}
/*
@@ -294,9 +302,10 @@ kmdb_prom_read(void *buf, size_t len, struct termios *tio)
size_t totread = 0;
size_t thisread;
char *c = (char *)buf;
+ int wait = 1;
for (;;) {
- kmdb_prom_fill_readbuf(0);
+ kmdb_prom_fill_readbuf(0, wait);
thisread = kmdb_prom_drain_readbuf(c, len);
len -= thisread;
totread += thisread;
@@ -306,6 +315,8 @@ kmdb_prom_read(void *buf, size_t len, struct termios *tio)
if (totread == 0)
continue;
+ wait = 0;
+
/*
* We're done if we've exhausted available input or if we've
* filled the provided buffer.
diff --git a/usr/src/cmd/mdb/common/kmdb/kvm.h b/usr/src/cmd/mdb/common/kmdb/kvm.h
index 4c1786dbf6..414a79eca9 100644
--- a/usr/src/cmd/mdb/common/kmdb/kvm.h
+++ b/usr/src/cmd/mdb/common/kmdb/kvm.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -80,6 +80,7 @@ typedef struct kmt_data {
const mdb_tgt_regdesc_t *kmt_rds; /* Register description table */
mdb_nv_t kmt_modules; /* Hash table of modules */
mdb_list_t kmt_modlist; /* List of mods in load order */
+ const char *kmt_rtld_name; /* Module containing krtld */
caddr_t kmt_writemap; /* Used to map PAs for writes */
size_t kmt_writemapsz; /* Size of same */
mdb_map_t kmt_map; /* Persistant map for callers */
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ks.h b/usr/src/cmd/mdb/common/mdb/mdb_ks.h
index bb3038dcd8..3ea1343492 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_ks.h
+++ b/usr/src/cmd/mdb/common/mdb/mdb_ks.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -65,7 +65,7 @@ extern int mdb_devinfo2statep(uintptr_t, char *, uintptr_t *);
extern int mdb_cpu2cpuid(uintptr_t);
-extern int mdb_cpuset_find(uintptr_t cpusetp);
+extern int mdb_cpuset_find(uintptr_t);
/*
* Returns a pointer to the top of the soft state struct for the instance
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_kvm.c b/usr/src/cmd/mdb/common/mdb/mdb_kvm.c
index c2e71bb643..853feb80d1 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_kvm.c
+++ b/usr/src/cmd/mdb/common/mdb/mdb_kvm.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -90,7 +89,6 @@ typedef struct kt_maparg {
void *map_data; /* Callback function argument */
} kt_maparg_t;
-static const char KT_RTLD_NAME[] = "krtld";
static const char KT_MODULE[] = "mdb_ks";
static const char KT_CTFPARENT[] = "genunix";
@@ -491,6 +489,19 @@ reg_disc_get(const mdb_var_t *v)
return (r);
}
+static kt_module_t *
+kt_module_by_name(kt_data_t *kt, const char *name)
+{
+ kt_module_t *km;
+
+ for (km = mdb_list_next(&kt->k_modlist); km; km = mdb_list_next(km)) {
+ if (strcmp(name, km->km_name) == 0)
+ return (km);
+ }
+
+ return (NULL);
+}
+
void
kt_activate(mdb_tgt_t *t)
{
@@ -546,9 +557,23 @@ kt_activate(mdb_tgt_t *t)
mdb_iob_flush(mdb.m_out);
}
- if (!(t->t_flags & MDB_TGT_F_NOLOAD))
+ if (!(t->t_flags & MDB_TGT_F_NOLOAD)) {
kt_load_modules(kt, t);
+ /*
+ * Determine where the CTF data for krtld is. If krtld
+ * is rolled into unix, force load the MDB krtld
+ * module.
+ */
+ kt->k_rtld_name = "krtld";
+
+ if (kt_module_by_name(kt, "krtld") == NULL) {
+ (void) mdb_module_load("krtld", MDB_MOD_SILENT);
+ kt->k_rtld_name = "unix";
+ }
+ }
+
+
if (t->t_flags & MDB_TGT_F_PRELOAD) {
mdb_iob_puts(mdb.m_out, " ]\n");
mdb_iob_setflags(mdb.m_out, oflag);
@@ -778,7 +803,7 @@ kt_lookup_by_name(mdb_tgt_t *t, const char *obj, const char *name,
break;
case (uintptr_t)MDB_TGT_OBJ_RTLD:
- obj = KT_RTLD_NAME;
+ obj = kt->k_rtld_name;
/*FALLTHRU*/
default:
@@ -964,7 +989,7 @@ kt_symbol_iter(mdb_tgt_t *t, const char *obj, uint_t which, uint_t type,
break;
case (uintptr_t)MDB_TGT_OBJ_RTLD:
- obj = KT_RTLD_NAME;
+ obj = kt->k_rtld_name;
/*FALLTHRU*/
default:
@@ -1092,12 +1117,10 @@ kt_name_to_map(mdb_tgt_t *t, const char *name)
return (kt_module_to_map(mdb_list_next(&kt->k_modlist), &m));
if (name == MDB_TGT_OBJ_RTLD)
- name = KT_RTLD_NAME; /* replace MDB_TGT_OBJ_RTLD with krtld */
+ name = kt->k_rtld_name;
- for (km = mdb_list_next(&kt->k_modlist); km; km = mdb_list_next(km)) {
- if (strcmp(name, km->km_name) == 0)
- return (kt_module_to_map(km, &m));
- }
+ if ((km = kt_module_by_name(kt, name)) != NULL)
+ return (kt_module_to_map(km, &m));
(void) set_errno(EMDB_NOOBJ);
return (NULL);
@@ -1200,14 +1223,12 @@ kt_name_to_ctf(mdb_tgt_t *t, const char *name)
kt_module_t *km;
if (name == MDB_TGT_OBJ_EXEC)
- name = KT_CTFPARENT; /* base CTF data is kept in genunix */
+ name = KT_CTFPARENT;
else if (name == MDB_TGT_OBJ_RTLD)
- name = KT_RTLD_NAME; /* replace MDB_TGT_OBJ_RTLD with krtld */
+ name = kt->k_rtld_name;
- for (km = mdb_list_next(&kt->k_modlist); km; km = mdb_list_next(km)) {
- if (strcmp(name, km->km_name) == 0)
- return (kt_load_ctfdata(t, km));
- }
+ if ((km = kt_module_by_name(kt, name)) != NULL)
+ return (kt_load_ctfdata(t, km));
(void) set_errno(EMDB_NOOBJ);
return (NULL);
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_kvm.h b/usr/src/cmd/mdb/common/mdb/mdb_kvm.h
index 9e4ca6f774..ef85d9179e 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_kvm.h
+++ b/usr/src/cmd/mdb/common/mdb/mdb_kvm.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -79,6 +78,7 @@ typedef struct kt_data {
int (*k_dump_find_curproc)(); /* mdb_ks dump_find_curproc routine */
char *k_symfile; /* Symbol table pathname */
char *k_kvmfile; /* Core file pathname */
+ const char *k_rtld_name; /* module containing krtld */
mdb_map_t k_map; /* Persistant map for callers */
kvm_t *k_cookie; /* Cookie for libkvm routines */
struct as *k_as; /* Kernel VA of kas struct */
diff --git a/usr/src/cmd/mdb/common/modules/genunix/Makefile.files b/usr/src/cmd/mdb/common/modules/genunix/Makefile.files
new file mode 100644
index 0000000000..b125e5f21b
--- /dev/null
+++ b/usr/src/cmd/mdb/common/modules/genunix/Makefile.files
@@ -0,0 +1,68 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+#
+# This file simply contains the list of sources files compiled together
+# to create the genunix mdb module. Having them in one place saves
+# a bunch of unnecessary replication.
+#
+GENUNIX_SRCS = \
+ avl.c \
+ bio.c \
+ contract.c \
+ cpupart.c \
+ ctxop.c \
+ cyclic.c \
+ devinfo.c \
+ findstack.c \
+ fm.c \
+ genunix.c \
+ group.c \
+ kgrep.c \
+ kmem.c \
+ ldi.c \
+ leaky.c \
+ leaky_subr.c \
+ lgrp.c \
+ list.c \
+ log.c \
+ mdi.c \
+ memory.c \
+ mmd.c \
+ modhash.c \
+ ndievents.c \
+ net.c \
+ nvpair.c \
+ pg.c \
+ rctl.c \
+ sobj.c \
+ streams.c \
+ sysevent.c \
+ thread.c \
+ tsd.c \
+ tsol.c \
+ vfs.c \
+ zone.c
diff --git a/usr/src/cmd/mdb/common/modules/libc/libc.c b/usr/src/cmd/mdb/common/modules/libc/libc.c
index a24a8bf6b4..acfa8ad884 100644
--- a/usr/src/cmd/mdb/common/modules/libc/libc.c
+++ b/usr/src/cmd/mdb/common/modules/libc/libc.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -566,13 +566,12 @@ d_ulwp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
prt_addr(ulwp.ul_schedctl_called, 1),
prt_addr((void *)ulwp.ul_schedctl, 0));
- HD("bindflags gs stsd &ftsd");
+ HD("bindflags pad2 stsd &ftsd");
mdb_printf(OFFSTR,
OFFSET(ul_bindflags));
mdb_printf(ulwp.ul_bindflags? "0x%-8x " : "%-10d ",
ulwp.ul_bindflags);
- mdb_printf(ulwp.ul_gs? "0x%-8x " : "%-10d ",
- ulwp.ul_gs);
+ mdb_printf("%-10d ", ulwp.ul_pad2);
mdb_printf("%s %s\n",
prt_addr(ulwp.ul_stsd, 1),
prt_addr((void *)(addr + OFFSET(ul_ftsd[0])), 0));
diff --git a/usr/src/cmd/mdb/i86pc/modules/uppc/intr_common.c b/usr/src/cmd/mdb/i86pc/modules/common/intr_common.c
index 9fb1f0e3d3..36f0f78bb7 100644
--- a/usr/src/cmd/mdb/i86pc/modules/uppc/intr_common.c
+++ b/usr/src/cmd/mdb/i86pc/modules/common/intr_common.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,12 +29,33 @@
#include <sys/multidata.h>
#include <sys/gld.h>
#include <sys/gldpriv.h>
-#include <sys/ddi_intr_impl.h>
-#include <sys/cpuvar.h>
-int option_flags;
-uintptr_t gld_intr_addr;
-static struct av_head softvec_tbl[LOCK_LEVEL + 1];
+int option_flags;
+uintptr_t gld_intr_addr;
+static struct av_head softvec_tbl[LOCK_LEVEL + 1];
+
+static char *businfo_array[] = {
+ " ",
+ "CBUS",
+ "CBUSII",
+ "EISA",
+ "FUTURE",
+ "INTERN",
+ "ISA",
+ "MBI",
+ "MBII",
+ "PCIe",
+ "MPI",
+ "MPSA",
+ "NUBUS",
+ "PCI",
+ "PCMCIA",
+ "TC",
+ "VL",
+ "VME",
+ "XPRESS",
+ " "
+};
void
interrupt_help(void)
@@ -55,42 +76,6 @@ soft_interrupt_help(void)
" -d instead of ISR, print <driver_name><instance#>\n");
}
-void
-interrupt_print_isr(uintptr_t vector, uintptr_t arg1, uintptr_t dip)
-{
- uintptr_t isr_addr = vector;
- struct dev_info dev_info;
-
- /*
- * figure out the real ISR function name from gld_intr()
- */
- if (isr_addr == gld_intr_addr) {
- gld_mac_info_t macinfo;
-
- if (mdb_vread(&macinfo, sizeof (gld_mac_info_t), arg1) != -1) {
- /* verify gld data structure and get the real ISR */
- if (macinfo.gldm_GLD_version == GLD_VERSION)
- isr_addr = (uintptr_t)macinfo.gldm_intr;
- }
- }
-
- if ((option_flags & INTR_DISPLAY_DRVR_INST) && dip) {
- char drvr_name[MODMAXNAMELEN + 1];
-
- if (dip && mdb_devinfo2driver(dip, drvr_name,
- sizeof (drvr_name)) == 0) {
- (void) mdb_vread(&dev_info, sizeof (dev_info), dip);
- mdb_printf("%s#%d", drvr_name, dev_info.devi_instance);
- } else {
- mdb_printf("%a", isr_addr);
- }
-
- } else {
- mdb_printf("%a", isr_addr);
- }
-}
-
-
/*
* This is copied from avintr.c
* NOTE: Ensure that this definition stays in sync
@@ -152,3 +137,164 @@ soft_interrupt_dump(uintptr_t addr, uint_t flags, int argc,
return (DCMD_OK);
}
+
+void
+interrupt_print_isr(uintptr_t vector, uintptr_t arg1, uintptr_t dip)
+{
+ uintptr_t isr_addr = vector;
+ struct dev_info dev_info;
+
+ /*
+ * figure out the real ISR function name from gld_intr()
+ */
+ if (isr_addr == gld_intr_addr) {
+ gld_mac_info_t macinfo;
+
+ if (mdb_vread(&macinfo, sizeof (gld_mac_info_t), arg1) != -1) {
+ /* verify gld data structure and get the real ISR */
+ if (macinfo.gldm_GLD_version == GLD_VERSION)
+ isr_addr = (uintptr_t)macinfo.gldm_intr;
+ }
+ }
+
+ if ((option_flags & INTR_DISPLAY_DRVR_INST) && dip) {
+ char drvr_name[MODMAXNAMELEN + 1];
+
+ if (dip && mdb_devinfo2driver(dip, drvr_name,
+ sizeof (drvr_name)) == 0) {
+ (void) mdb_vread(&dev_info, sizeof (dev_info), dip);
+ mdb_printf("%s#%d", drvr_name, dev_info.devi_instance);
+ } else {
+ mdb_printf("%a", isr_addr);
+ }
+
+ } else {
+ mdb_printf("%a", isr_addr);
+ }
+}
+
+/*
+ * get_interrupt_type:
+ *
+ * Get some interrupt related useful information
+ *
+ * NOTE: a0 is clock, c0/d0/e0 are x-calls, e1 is apic_error_intr
+ * d1/d3 are cbe_fire interrupts
+ */
+static char *
+get_interrupt_type(short index)
+{
+ if (index == RESERVE_INDEX)
+ return ("IPI");
+ else if (index == ACPI_INDEX)
+ return ("Fixed");
+ else if (index == MSI_INDEX)
+ return ("MSI");
+ else if (index == MSIX_INDEX)
+ return ("MSI-X");
+ else
+ return ("Fixed");
+}
+
+void
+apic_interrupt_dump(apic_irq_t *irqp, struct av_head *avp,
+ int i, ushort_t *evtchnp, char level)
+{
+ int bus_type;
+ int j;
+ char *intr_type;
+ char ioapic_iline[10];
+ char ipl[3];
+ char cpu_assigned[4];
+ char evtchn[8];
+ uchar_t assigned_cpu;
+ struct autovec avhp;
+
+ /* If invalid index; continue */
+ if (!irqp->airq_mps_intr_index ||
+ irqp->airq_mps_intr_index == FREE_INDEX)
+ return;
+
+ /* Figure out interrupt type and trigger information */
+ intr_type = get_interrupt_type(irqp->airq_mps_intr_index);
+
+ /* Figure out IOAPIC number and ILINE number */
+ if (APIC_IS_MSI_OR_MSIX_INDEX(irqp->airq_mps_intr_index))
+ (void) mdb_snprintf(ioapic_iline, 10, "- ");
+ else {
+ if (!irqp->airq_ioapicindex && !irqp->airq_intin_no) {
+ if (strcmp(intr_type, "Fixed") == 0)
+ (void) mdb_snprintf(ioapic_iline, 10,
+ "0x%x/0x%x", irqp->airq_ioapicindex,
+ irqp->airq_intin_no);
+ else if (irqp->airq_mps_intr_index == RESERVE_INDEX)
+ (void) mdb_snprintf(ioapic_iline, 10, "- ");
+ else
+ (void) mdb_snprintf(ioapic_iline, 10, " ");
+ } else
+ (void) mdb_snprintf(ioapic_iline, 10, "0x%x/0x%x",
+ irqp->airq_ioapicindex, irqp->airq_intin_no);
+ }
+
+ evtchn[0] = '\0';
+ if (evtchnp != NULL)
+ (void) mdb_snprintf(evtchn, 8, "%-7hd", *evtchnp);
+
+ assigned_cpu = irqp->airq_temp_cpu;
+ if (assigned_cpu == IRQ_UNINIT || assigned_cpu == IRQ_UNBOUND)
+ assigned_cpu = irqp->airq_cpu;
+ bus_type = irqp->airq_iflag.bustype;
+
+ if (irqp->airq_mps_intr_index == RESERVE_INDEX) {
+ (void) mdb_snprintf(cpu_assigned, 4, "all");
+ (void) mdb_snprintf(ipl, 3, "%d", avp->avh_hi_pri);
+ } else {
+ (void) mdb_snprintf(cpu_assigned, 4, "%d", assigned_cpu);
+ (void) mdb_snprintf(ipl, 3, "%d", irqp->airq_ipl);
+ }
+
+ /* Print each interrupt entry */
+ if (option_flags & INTR_DISPLAY_INTRSTAT)
+ mdb_printf("%-4s", cpu_assigned);
+ else
+ mdb_printf("%-3d 0x%x %s%-3s %-6s %-3s %-6s %-4s%-3d %-9s ",
+ i, irqp->airq_vector, evtchn, ipl,
+ (bus_type ? businfo_array[bus_type] : " "),
+ (level ? "Lvl" : "Edg"),
+ intr_type, cpu_assigned, irqp->airq_share, ioapic_iline);
+
+ /* If valid dip found; print driver name */
+ if (irqp->airq_dip) {
+ (void) mdb_vread(&avhp, sizeof (struct autovec),
+ (uintptr_t)avp->avh_link);
+
+ /*
+ * Loop thru all the shared IRQs
+ */
+ if (irqp->airq_share)
+ interrupt_print_isr((uintptr_t)avhp.av_vector,
+ (uintptr_t)avhp.av_intarg1, (uintptr_t)avhp.av_dip);
+
+ for (j = 1; irqp->airq_mps_intr_index != FREE_INDEX &&
+ j < irqp->airq_share; j++) {
+ if (mdb_vread(&avhp, sizeof (struct autovec),
+ (uintptr_t)avhp.av_link) != -1) {
+ mdb_printf(", ");
+ interrupt_print_isr((uintptr_t)avhp.av_vector,
+ (uintptr_t)avhp.av_intarg1,
+ (uintptr_t)avhp.av_dip);
+ } else {
+ break;
+ }
+ }
+
+ } else {
+ if (irqp->airq_mps_intr_index == RESERVE_INDEX &&
+ !irqp->airq_share)
+ mdb_printf("poke_cpu");
+ else if (mdb_vread(&avhp, sizeof (struct autovec),
+ (uintptr_t)avp->avh_link) != -1)
+ mdb_printf("%a", avhp.av_vector);
+ }
+ mdb_printf("\n");
+}
diff --git a/usr/src/cmd/mdb/i86pc/modules/uppc/intr_common.h b/usr/src/cmd/mdb/i86pc/modules/common/intr_common.h
index 74a0b44668..19c90f04bc 100644
--- a/usr/src/cmd/mdb/i86pc/modules/uppc/intr_common.h
+++ b/usr/src/cmd/mdb/i86pc/modules/common/intr_common.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,16 +39,18 @@ extern "C" {
#include <sys/avintr.h>
#include <sys/psm_common.h>
#include <sys/pic.h>
-#include <io/pcplusmp/apic.h>
+#include <sys/apic.h>
/*
* Function prototypes
*/
-void interrupt_help(void);
-void soft_interrupt_help(void);
-void interrupt_print_isr(uintptr_t vector, uintptr_t arg1, uintptr_t dip);
-int soft_interrupt_dump(uintptr_t addr, uint_t flags, int argc,
- const mdb_arg_t *argv);
+void interrupt_help(void);
+void interrupt_print_isr(uintptr_t, uintptr_t, uintptr_t);
+void apic_interrupt_dump(apic_irq_t *, struct av_head *, int i,
+ ushort_t *, char);
+
+void soft_interrupt_help(void);
+int soft_interrupt_dump(uintptr_t, uint_t, int, const mdb_arg_t *);
/*
* ::interrupts usage related defines and variables
diff --git a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/amd64/Makefile b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/amd64/Makefile
index fddfa8db13..88bf7fd4c8 100644
--- a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/amd64/Makefile
+++ b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/amd64/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -35,10 +35,10 @@ include ../../../../intel/Makefile.amd64
include ../../../Makefile.i86pc
include ../../../../Makefile.module
-MODSRCS_DIR = ../../uppc
+MODSRCS_DIR = ../../common
CPPFLAGS += -DMP -D_MACHDEP
CPPFLAGS += -I../../../../common
-CPPFLAGS += -I../../uppc
+CPPFLAGS += -I../../common
CPPFLAGS += -I$(SRC)/uts/intel
CPPFLAGS += -I$(SRC)/uts/i86pc
diff --git a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c
index c2c9b6538d..fb8824855a 100644
--- a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c
+++ b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,154 +30,9 @@
/*
* Globals
*/
-static char *businfo_array[] = {
- " ",
- "CBUS",
- "CBUSII",
- "EISA",
- "FUTURE",
- "INTERN",
- "ISA",
- "MBI",
- "MBII",
- "PCIe",
- "MPI",
- "MPSA",
- "NUBUS",
- "PCI",
- "PCMCIA",
- "TC",
- "VL",
- "VME",
- "XPRESS",
- " "
-};
-
static struct av_head avec_tbl[APIC_MAX_VECTOR+1];
-
-/*
- * get_interrupt_type:
- *
- * Get some interrupt related useful information
- *
- * NOTE: a0 is clock, c0/d0/e0 are x-calls, e1 is apic_error_intr
- * d1/d3 are cbe_fire interrupts
- */
-static char *
-get_interrupt_type(short index)
-{
- if (index == RESERVE_INDEX)
- return ("IPI");
- else if (index == ACPI_INDEX)
- return ("Fixed");
- else if (index == MSI_INDEX)
- return ("MSI");
- else if (index == MSIX_INDEX)
- return ("MSI-X");
- else
- return ("Fixed");
-}
-
-/*
- * interrupt_display_info:
- *
- * Dump interrupt information including shared interrupts.
- */
-static void
-interrupt_display_info(apic_irq_t irqp, int i)
-{
- int bus_type;
- int j;
- char *intr_type;
- char ioapic_iline[10];
- char ipl[3];
- char cpu_assigned[4];
- uchar_t assigned_cpu;
- struct autovec avhp;
-
- /* If invalid index; continue */
- if (!irqp.airq_mps_intr_index || irqp.airq_mps_intr_index == FREE_INDEX)
- return;
-
- /* Figure out interrupt type and trigger information */
- intr_type = get_interrupt_type(irqp.airq_mps_intr_index);
-
- /* Figure out IOAPIC number and ILINE number */
- if (APIC_IS_MSI_OR_MSIX_INDEX(irqp.airq_mps_intr_index))
- (void) mdb_snprintf(ioapic_iline, 10, "- ");
- else {
- if (!irqp.airq_ioapicindex && !irqp.airq_intin_no) {
- if (strcmp(intr_type, "Fixed") == 0)
- (void) mdb_snprintf(ioapic_iline, 10,
- "0x%x/0x%x", irqp.airq_ioapicindex,
- irqp.airq_intin_no);
- else if (irqp.airq_mps_intr_index == RESERVE_INDEX)
- (void) mdb_snprintf(ioapic_iline, 10, "- ");
- else
- (void) mdb_snprintf(ioapic_iline, 10, " ");
- } else
- (void) mdb_snprintf(ioapic_iline, 10, "0x%x/0x%x",
- irqp.airq_ioapicindex, irqp.airq_intin_no);
- }
-
- assigned_cpu = irqp.airq_temp_cpu;
- if (assigned_cpu == IRQ_UNINIT || assigned_cpu == IRQ_UNBOUND)
- assigned_cpu = irqp.airq_cpu;
- bus_type = irqp.airq_iflag.bustype;
-
- if (irqp.airq_mps_intr_index == RESERVE_INDEX) {
- (void) mdb_snprintf(cpu_assigned, 4, "ALL");
- (void) mdb_snprintf(ipl, 3, "%d", avec_tbl[i].avh_hi_pri);
- } else {
- (void) mdb_snprintf(cpu_assigned, 4, "%d", assigned_cpu);
- (void) mdb_snprintf(ipl, 3, "%d", irqp.airq_ipl);
- }
-
- /* Print each interrupt entry */
- if (option_flags & INTR_DISPLAY_INTRSTAT)
- mdb_printf("cpu%s\t", cpu_assigned);
- else
- mdb_printf("%-3d 0x%x %-3s %-5s %-6s%-4s%-3d %-9s ",
- i, irqp.airq_vector, ipl,
- (bus_type ? businfo_array[bus_type] : " "),
- intr_type, cpu_assigned, irqp.airq_share, ioapic_iline);
-
- /* If valid dip found; print driver name */
- if (irqp.airq_dip) {
- (void) mdb_vread(&avhp, sizeof (struct autovec),
- (uintptr_t)avec_tbl[i].avh_link);
-
- /*
- * Loop thru all the shared IRQs
- */
- if (irqp.airq_share)
- interrupt_print_isr((uintptr_t)avhp.av_vector,
- (uintptr_t)avhp.av_intarg1, (uintptr_t)avhp.av_dip);
-
- for (j = 1; irqp.airq_mps_intr_index != FREE_INDEX &&
- j < irqp.airq_share; j++) {
- if (mdb_vread(&avhp, sizeof (struct autovec),
- (uintptr_t)avhp.av_link) != -1) {
- mdb_printf(", ");
- interrupt_print_isr((uintptr_t)avhp.av_vector,
- (uintptr_t)avhp.av_intarg1,
- (uintptr_t)avhp.av_dip);
- } else {
- break;
- }
- }
-
- } else {
- if (irqp.airq_mps_intr_index == RESERVE_INDEX &&
- !irqp.airq_share)
- mdb_printf("poke_cpu");
- else if (mdb_vread(&avhp, sizeof (struct autovec),
- (uintptr_t)avec_tbl[i].avh_link) != -1)
- mdb_printf("%a", avhp.av_vector);
- }
- mdb_printf("\n");
-}
-
+static apic_irq_t *irq_tbl[APIC_MAX_VECTOR+1], airq;
+static char level_tbl[APIC_MAX_VECTOR+1];
/*
* interrupt_dump:
@@ -189,7 +44,6 @@ int
interrupt_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
int i;
- apic_irq_t *irq_tbl[APIC_MAX_VECTOR+1], irqp;
option_flags = 0;
if (mdb_getopts(argc, argv,
@@ -203,6 +57,11 @@ interrupt_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
return (DCMD_ERR);
}
+ if (mdb_readvar(&level_tbl, "apic_level_intr") == -1) {
+ mdb_warn("failed to read apic_level_intr");
+ return (DCMD_ERR);
+ }
+
if (mdb_readvar(&avec_tbl, "autovect") == -1) {
mdb_warn("failed to read autovect");
return (DCMD_ERR);
@@ -210,21 +69,21 @@ interrupt_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
/* Print the header first */
if (option_flags & INTR_DISPLAY_INTRSTAT)
- mdb_printf("%<u>CPU\t ");
+ mdb_printf("%<u>CPU ");
else
mdb_printf(
- "%<u>IRQ Vector IPL Bus Type CPU Share APIC/INT# ");
+ "%<u>IRQ Vect IPL Bus Trg Type CPU Share APIC/INT# ");
mdb_printf("%s %</u>\n", option_flags & INTR_DISPLAY_DRVR_INST ?
"Driver Name(s)" : "ISR(s)");
/* Walk all the entries */
for (i = 0; i < APIC_MAX_VECTOR + 1; i++) {
/* Read the entry */
- if (mdb_vread(&irqp, sizeof (apic_irq_t),
+ if (mdb_vread(&airq, sizeof (apic_irq_t),
(uintptr_t)irq_tbl[i]) == -1)
continue;
- interrupt_display_info(irqp, i);
+ apic_interrupt_dump(&airq, &avec_tbl[i], i, NULL, level_tbl[i]);
}
return (DCMD_OK);
diff --git a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/ia32/Makefile b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/ia32/Makefile
index 3964bf6bde..e0e8edc45b 100644
--- a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/ia32/Makefile
+++ b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/ia32/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -34,10 +34,10 @@ include ../../../../intel/Makefile.ia32
include ../../../Makefile.i86pc
include ../../../../Makefile.module
-MODSRCS_DIR = ../../uppc
+MODSRCS_DIR = ../../common
CPPFLAGS += -DMP -D_MACHDEP
CPPFLAGS += -I../../../../common
-CPPFLAGS += -I../../uppc
+CPPFLAGS += -I../../common
CPPFLAGS += -I$(SRC)/uts/intel
CPPFLAGS += -I$(SRC)/uts/i86pc
diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile b/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile
index 7ed692a12b..08cbabf3e1 100644
--- a/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile
+++ b/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -38,5 +37,5 @@ include ../../../../Makefile.module
CPPFLAGS += -DMP -D_MACHDEP
CPPFLAGS += -I../../../../common
-CPPFLAGS += -I$(SRC)/uts/intel
CPPFLAGS += -I$(SRC)/uts/i86pc
+CPPFLAGS += -I$(SRC)/uts/intel
diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.c b/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.c
index 05577a6cc8..161bd9d9a1 100644
--- a/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.c
+++ b/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.c
@@ -19,10 +19,9 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
#pragma ident "%Z%%M% %I% %E% SMI"
/*
@@ -37,6 +36,7 @@
#include <sys/types.h>
#include <sys/machparam.h>
#include <sys/controlregs.h>
+#include <sys/mach_mmu.h>
#include <vm/as.h>
#include <mdb/mdb_modapi.h>
@@ -50,7 +50,7 @@ struct pfn2pp {
page_t *pp;
};
-static int do_va2pfn(uintptr_t, struct as *, int, physaddr_t *);
+static int do_va2pa(uintptr_t, struct as *, int, physaddr_t *, pfn_t *);
static void get_mmu(void);
int
@@ -66,7 +66,7 @@ platform_vtop(uintptr_t addr, struct as *asp, physaddr_t *pap)
if (mmu.num_level == 0)
return (DCMD_ERR);
- return (do_va2pfn(addr, asp, 0, pap));
+ return (do_va2pa(addr, asp, 0, pap, NULL));
}
@@ -134,9 +134,6 @@ page_num2pp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
}
-
-
-
/*
* ::memseg_list dcmd and walker to implement it.
*/
@@ -221,20 +218,7 @@ memseg_walk_fini(mdb_walk_state_t *wsp)
}
/*
- * HAT related dcmds:
- *
- * ::pte [-p XXXXXXXX] [-l 0/1/2/3]
- *
- * dcmd that interprets the -p argument as a page table entry and
- * prints it in more human readable form. The PTE is assumed to be in
- * a level 0 page table, unless -l specifies another level.
- *
- * ::vatopfn [-v] [-a as]
- *
- * Given a virtual address, returns the PFN, if any, mapped at the address.
- * -v shows the intermediate htable/page table entries used to resolve the
- * mapping. By default the virtual address is assumed to be in the kernel's
- * address space. -a is used to specify a different address space.
+ * Now HAT related dcmds.
*/
struct hat *khat; /* value of kas.a_hat */
@@ -261,6 +245,21 @@ get_mmu(void)
khat = kas.a_hat;
}
+#define mdb_ma_to_pa(ma) (ma)
+#define mdb_mfn_to_pfn(mfn) (mfn)
+#define mdb_pfn_to_mfn(pfn) (pfn)
+
+static pfn_t
+pte2mfn(x86pte_t pte, uint_t level)
+{
+ pfn_t mfn;
+ if (level > 0 && (pte & PT_PAGESIZE))
+ mfn = mmu_btop(pte & PT_PADDR_LGPG);
+ else
+ mfn = mmu_btop(pte & PT_PADDR);
+ return (mfn);
+}
+
/*
* Print a PTE in more human friendly way. The PTE is assumed to be in
* a level 0 page table, unless -l specifies another level.
@@ -275,12 +274,14 @@ do_pte_dcmd(int level, uint64_t pte)
"wrback", "wrthru", "uncached", "uncached",
"wrback", "wrthru", "wrcombine", "uncached"};
int pat_index = 0;
+ pfn_t mfn;
- mdb_printf("PTE=%llx: ", pte);
+ mdb_printf("pte=%llr: ", pte);
if (PTE_GET(pte, mmu.pt_nx))
mdb_printf("noexec ");
- mdb_printf("page=0x%llx ", PTE2PFN(pte, level));
+ mfn = pte2mfn(pte, level);
+ mdb_printf("%s=0x%lr ", "pfn", mfn);
if (PTE_GET(pte, PT_NOCONSIST))
mdb_printf("noconsist ");
@@ -387,8 +388,43 @@ pte_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
return (do_pte_dcmd(level, pte));
}
+static size_t
+va2entry(htable_t *htable, uintptr_t addr)
+{
+ size_t entry = (addr - htable->ht_vaddr);
+
+ entry >>= mmu.level_shift[htable->ht_level];
+ return (entry & HTABLE_NUM_PTES(htable) - 1);
+}
+
+static x86pte_t
+get_pte(hat_t *hat, htable_t *htable, uintptr_t addr)
+{
+ x86pte_t buf;
+ x86pte32_t *pte32 = (x86pte32_t *)&buf;
+ size_t len;
+
+ if (htable->ht_flags & HTABLE_VLP) {
+ uintptr_t ptr = (uintptr_t)hat->hat_vlp_ptes;
+ ptr += va2entry(htable, addr) << mmu.pte_size_shift;
+ len = mdb_vread(&buf, mmu.pte_size, ptr);
+ } else {
+ paddr_t paddr = mmu_ptob((paddr_t)htable->ht_pfn);
+ paddr += va2entry(htable, addr) << mmu.pte_size_shift;
+ len = mdb_pread(&buf, mmu.pte_size, paddr);
+ }
+
+ if (len != mmu.pte_size)
+ return (0);
+
+ if (mmu.pte_size == sizeof (x86pte_t))
+ return (buf);
+ return (*pte32);
+}
+
static int
-do_va2pfn(uintptr_t addr, struct as *asp, int print_level, physaddr_t *pap)
+do_va2pa(uintptr_t addr, struct as *asp, int print_level, physaddr_t *pap,
+ pfn_t *mfnp)
{
struct as as;
struct hat *hatp;
@@ -400,10 +436,7 @@ do_va2pfn(uintptr_t addr, struct as *asp, int print_level, physaddr_t *pap)
int level;
int found = 0;
x86pte_t pte;
- x86pte_t buf;
- x86pte32_t *pte32 = (x86pte32_t *)&buf;
physaddr_t paddr;
- size_t len;
if (asp != NULL) {
if (mdb_vread(&as, sizeof (as), (uintptr_t)asp) == -1) {
@@ -426,9 +459,8 @@ do_va2pfn(uintptr_t addr, struct as *asp, int print_level, physaddr_t *pap)
/*
* read the htable hashtable
*/
- *pap = 0;
for (level = 0; level <= mmu.max_level; ++level) {
- if (level == mmu.max_level)
+ if (level == TOP_LEVEL(&hat))
base = 0;
else
base = addr & mmu.level_mask[level + 1];
@@ -445,38 +477,38 @@ do_va2pfn(uintptr_t addr, struct as *asp, int print_level, physaddr_t *pap)
mdb_warn("Couldn't read htable\n");
return (DCMD_ERR);
}
+
if (htable.ht_vaddr != base ||
htable.ht_level != level)
continue;
- /*
- * found - read the page table entry
- */
- paddr = htable.ht_pfn << MMU_PAGESHIFT;
- paddr += ((addr - base) >>
- mmu.level_shift[level]) <<
- mmu.pte_size_shift;
- len = mdb_pread(&buf, mmu.pte_size, paddr);
- if (len != mmu.pte_size)
- return (DCMD_ERR);
- if (mmu.pte_size == sizeof (x86pte_t))
- pte = buf;
- else
- pte = *pte32;
+ pte = get_pte(&hat, &htable, addr);
- if (!found) {
- if (PTE_IS_LGPG(pte, level))
- paddr = pte & PT_PADDR_LGPG;
- else
- paddr = pte & PT_PADDR;
- paddr += addr & mmu.level_offset[level];
- *pap = paddr;
- found = 1;
+ if (print_level) {
+ mdb_printf("\tlevel=%d htable=%p "
+ "pte=%llr\n", level, ht, pte);
}
- if (print_level == 0)
+
+ if (!PTE_ISVALID(pte)) {
+ mdb_printf("Address %p is unmapped.\n",
+ addr);
+ return (DCMD_ERR);
+ }
+
+ if (found)
continue;
- mdb_printf("\tlevel=%d htable=%p pte=%llx\n",
- level, ht, pte);
+
+ if (PTE_IS_LGPG(pte, level))
+ paddr = mdb_ma_to_pa(pte &
+ PT_PADDR_LGPG);
+ else
+ paddr = mdb_ma_to_pa(pte & PT_PADDR);
+ paddr += addr & mmu.level_offset[level];
+ if (pap != NULL)
+ *pap = paddr;
+ if (mfnp != NULL)
+ *mfnp = pte2mfn(pte, level);
+ found = 1;
}
}
}
@@ -492,7 +524,9 @@ va2pfn_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
uintptr_t addrspace;
char *addrspace_str = NULL;
- uint64_t physaddr;
+ int piped = flags & DCMD_PIPE_OUT;
+ pfn_t pfn;
+ pfn_t mfn;
int rc;
/*
@@ -517,12 +551,26 @@ va2pfn_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
else
addrspace = 0;
- rc = do_va2pfn(addr, (struct as *)addrspace, 1, &physaddr);
+ rc = do_va2pa(addr, (struct as *)addrspace, !piped, NULL, &mfn);
+
+ if (rc != DCMD_OK)
+ return (rc);
+
+ if ((pfn = mdb_mfn_to_pfn(mfn)) == -(pfn_t)1) {
+ mdb_warn("Invalid mfn %lr\n", mfn);
+ return (DCMD_ERR);
+ }
+
+ if (piped) {
+ mdb_printf("0x%lr\n", pfn);
+ return (DCMD_OK);
+ }
- if (rc == DCMD_OK)
- mdb_printf("Virtual %p maps Physical %llx\n", addr, physaddr);
+ mdb_printf("Virtual address 0x%p maps pfn 0x%lr", addr, pfn);
- return (rc);
+ mdb_printf("\n");
+
+ return (DCMD_OK);
}
/*
@@ -596,8 +644,9 @@ do_report_maps(pfn_t pfn)
level = htable.ht_level;
if (level > mmu.max_page_level)
continue;
- paddr = htable.ht_pfn << MMU_PAGESHIFT;
- for (entry = 0; entry < htable.ht_num_ptes;
+ paddr = mmu_ptob((physaddr_t)htable.ht_pfn);
+ for (entry = 0;
+ entry < HTABLE_NUM_PTES(&htable);
++entry) {
base = htable.ht_vaddr + entry *
@@ -625,7 +674,7 @@ do_report_maps(pfn_t pfn)
pte &= PT_PADDR;
else
pte &= PT_PADDR_LGPG;
- if ((pte >> MMU_PAGESHIFT) != pfn)
+ if (mmu_btop(mdb_ma_to_pa(pte)) != pfn)
continue;
mdb_printf("hat=%p maps addr=%p\n",
hatp, (caddr_t)base);
@@ -645,6 +694,9 @@ done:
int
report_maps_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
+ pfn_t pfn;
+ uint_t mflag = 0;
+
/*
* The kernel has to at least have made it thru mmu_init()
*/
@@ -655,12 +707,17 @@ report_maps_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
if ((flags & DCMD_ADDRSPEC) == 0)
return (DCMD_USAGE);
- return (do_report_maps((pfn_t)addr));
+ if (mdb_getopts(argc, argv,
+ 'm', MDB_OPT_SETBITS, TRUE, &mflag, NULL) != argc)
+ return (DCMD_USAGE);
+
+ pfn = (pfn_t)addr;
+ if (mflag)
+ pfn = mdb_mfn_to_pfn(pfn);
+
+ return (do_report_maps(pfn));
}
-/*
- * Dump the page table at the given PFN
- */
static int
do_ptable_dcmd(pfn_t pfn)
{
@@ -730,7 +787,7 @@ found_it:
pagesize = MMU_PAGESIZE;
}
- paddr = pfn << MMU_PAGESHIFT;
+ paddr = mmu_ptob((physaddr_t)pfn);
for (entry = 0; entry < mmu.ptes_per_table; ++entry) {
len = mdb_pread(&buf, mmu.pte_size,
paddr + entry * mmu.pte_size);
@@ -753,12 +810,82 @@ done:
}
/*
- * given a PFN as its address argument, prints out the uses of it
+ * Dump the page table at the given PFN
*/
/*ARGSUSED*/
int
ptable_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
+ pfn_t pfn;
+ uint_t mflag = 0;
+
+ /*
+ * The kernel has to at least have made it thru mmu_init()
+ */
+ get_mmu();
+ if (mmu.num_level == 0)
+ return (DCMD_ERR);
+
+ if ((flags & DCMD_ADDRSPEC) == 0)
+ return (DCMD_USAGE);
+
+ if (mdb_getopts(argc, argv,
+ 'm', MDB_OPT_SETBITS, TRUE, &mflag, NULL) != argc)
+ return (DCMD_USAGE);
+
+ pfn = (pfn_t)addr;
+ if (mflag)
+ pfn = mdb_mfn_to_pfn(pfn);
+
+ return (do_ptable_dcmd(pfn));
+}
+
+static int
+do_htables_dcmd(hat_t *hatp)
+{
+ struct hat hat;
+ htable_t *ht;
+ htable_t htable;
+ int h;
+
+ /*
+ * read the hat and its hash table
+ */
+ if (mdb_vread(&hat, sizeof (hat), (uintptr_t)hatp) == -1) {
+ mdb_warn("Couldn't read struct hat\n");
+ return (DCMD_ERR);
+ }
+
+ /*
+ * read the htable hashtable
+ */
+ for (h = 0; h < hat.hat_num_hash; ++h) {
+ if (mdb_vread(&ht, sizeof (htable_t *),
+ (uintptr_t)(hat.hat_ht_hash + h)) == -1) {
+ mdb_warn("Couldn't read htable ptr\\n");
+ return (DCMD_ERR);
+ }
+ for (; ht != NULL; ht = htable.ht_next) {
+ mdb_printf("%p\n", ht);
+ if (mdb_vread(&htable, sizeof (htable_t),
+ (uintptr_t)ht) == -1) {
+ mdb_warn("Couldn't read htable\n");
+ return (DCMD_ERR);
+ }
+ }
+ }
+ return (DCMD_OK);
+}
+
+/*
+ * Dump the htables for the given hat
+ */
+/*ARGSUSED*/
+int
+htables_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ hat_t *hat;
+
/*
* The kernel has to at least have made it thru mmu_init()
*/
@@ -769,5 +896,7 @@ ptable_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
if ((flags & DCMD_ADDRSPEC) == 0)
return (DCMD_USAGE);
- return (do_ptable_dcmd((pfn_t)addr));
+ hat = (hat_t *)addr;
+
+ return (do_htables_dcmd(hat));
}
diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.h b/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.h
index 6b01d31c47..5f86f0fd5e 100644
--- a/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.h
+++ b/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,6 +38,9 @@ extern int pte_dcmd(uintptr_t addr, uint_t flags, int argc,
extern int report_maps_dcmd(uintptr_t addr, uint_t flags, int argc,
const mdb_arg_t *argv);
+extern int htables_dcmd(uintptr_t addr, uint_t flags, int argc,
+ const mdb_arg_t *argv);
+
extern int ptable_dcmd(uintptr_t addr, uint_t flags, int argc,
const mdb_arg_t *argv);
diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/ia32/Makefile b/usr/src/cmd/mdb/i86pc/modules/unix/ia32/Makefile
index edb2d65a68..8121af9b49 100644
--- a/usr/src/cmd/mdb/i86pc/modules/unix/ia32/Makefile
+++ b/usr/src/cmd/mdb/i86pc/modules/unix/ia32/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -37,5 +36,5 @@ include ../../../../Makefile.module
CPPFLAGS += -DMP -D_MACHDEP
CPPFLAGS += -I../../../../common
-CPPFLAGS += -I$(SRC)/uts/intel
CPPFLAGS += -I$(SRC)/uts/i86pc
+CPPFLAGS += -I$(SRC)/uts/intel
diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/unix.c b/usr/src/cmd/mdb/i86pc/modules/unix/unix.c
index 21921df599..d251ee9e11 100644
--- a/usr/src/cmd/mdb/i86pc/modules/unix/unix.c
+++ b/usr/src/cmd/mdb/i86pc/modules/unix/unix.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,6 +30,7 @@
#include <sys/cpuvar.h>
#include <sys/systm.h>
#include <sys/traptrace.h>
+#include <sys/x_call.h>
#include <sys/avintr.h>
#include <sys/systm.h>
#include <sys/trap.h>
@@ -186,11 +186,10 @@ ttrace_syscall(trap_trace_rec_t *rec)
uintptr_t addr;
struct sysent sys;
- mdb_printf("%s%-*x", sysnum < 0x10 ? " " : "",
- sysnum < 0x10 ? 2 : 3, sysnum);
+ mdb_printf("%-3x", sysnum);
if (rec->ttr_sysnum > NSYSCALL) {
- mdb_printf("%-*d", TT_HDLR_WIDTH, rec->ttr_sysnum);
+ mdb_printf(" %-*d", TT_HDLR_WIDTH, rec->ttr_sysnum);
return (0);
}
@@ -211,7 +210,7 @@ ttrace_syscall(trap_trace_rec_t *rec)
return (-1);
}
- mdb_printf("%-*a", TT_HDLR_WIDTH, sys.sy_callc);
+ mdb_printf(" %-*a", TT_HDLR_WIDTH, sys.sy_callc);
return (0);
}
@@ -224,12 +223,15 @@ ttrace_interrupt(trap_trace_rec_t *rec)
struct av_head hd;
struct autovec av;
- if (rec->ttr_regs.r_trapno == T_SOFTINT) {
- mdb_printf("%2s %-*s", "-", TT_HDLR_WIDTH, "(fakesoftint)");
+ switch (rec->ttr_regs.r_trapno) {
+ case T_SOFTINT:
+ mdb_printf("%-3s %-*s", "-", TT_HDLR_WIDTH, "(fakesoftint)");
return (0);
+ default:
+ break;
}
- mdb_printf("%2x ", rec->ttr_vector);
+ mdb_printf("%-3x ", rec->ttr_vector);
if (mdb_lookup_by_name("autovect", &sym) == -1) {
mdb_warn("\ncouldn't find 'autovect'");
@@ -250,7 +252,10 @@ ttrace_interrupt(trap_trace_rec_t *rec)
}
if (hd.avh_link == NULL) {
- mdb_printf("%-*s", TT_HDLR_WIDTH, "(spurious)");
+ if (rec->ttr_ipl == XC_CPUPOKE_PIL)
+ mdb_printf("%-*s", TT_HDLR_WIDTH, "(cpupoke)");
+ else
+ mdb_printf("%-*s", TT_HDLR_WIDTH, "(spurious)");
} else {
if (mdb_vread(&av, sizeof (av), (uintptr_t)hd.avh_link) == -1) {
mdb_warn("couldn't read autovec at %p",
@@ -286,6 +291,17 @@ static struct {
{ T_ALIGNMENT, "alignment-check" },
{ T_MCE, "machine-check" },
{ T_SIMDFPE, "sse-exception" },
+
+ { T_DBGENTR, "debug-enter" },
+ { T_FASTTRAP, "fasttrap-0xd2" },
+ { T_SYSCALLINT, "syscall-0x91" },
+ { T_DTRACE_RET, "dtrace-ret" },
+ { T_SOFTINT, "softint" },
+ { T_INTERRUPT, "interrupt" },
+ { T_FAULT, "fault" },
+ { T_AST, "ast" },
+ { T_SYSCALL, "syscall" },
+
{ 0, NULL }
};
@@ -294,7 +310,10 @@ ttrace_trap(trap_trace_rec_t *rec)
{
int i;
- mdb_printf("%2x ", rec->ttr_regs.r_trapno);
+ if (rec->ttr_regs.r_trapno == T_AST)
+ mdb_printf("%-3s ", "-");
+ else
+ mdb_printf("%-3x ", rec->ttr_regs.r_trapno);
for (i = 0; ttrace_traps[i].tt_name != NULL; i++) {
if (rec->ttr_regs.r_trapno == ttrace_traps[i].tt_trapno)
@@ -310,6 +329,137 @@ ttrace_trap(trap_trace_rec_t *rec)
}
static struct {
+ int tt_type;
+ char *tt_name;
+} ttrace_xcalls[] = {
+ { TT_XC_SVC_BEGIN, "<svc-begin>" },
+ { TT_XC_SVC_END, "<svc-end>" },
+ { TT_XC_START, "<start>" },
+ { TT_XC_WAIT, "<wait>" },
+ { TT_XC_ACK, "<ack>" },
+ { TT_XC_CAPTURE, "<capture>" },
+ { TT_XC_RELEASE, "<release>" },
+ { TT_XC_POKE_CPU, "<poke-cpu>" },
+ { TT_XC_CBE_FIRE, "<cbe-fire>" },
+ { TT_XC_CBE_XCALL, "<cbe-xcall>" },
+ { 0, NULL }
+};
+
+static int
+ttrace_xcall(trap_trace_rec_t *rec)
+{
+ struct _xc_entry *xce = &(rec->ttr_info.xc_entry);
+ int i;
+
+ for (i = 0; ttrace_xcalls[i].tt_name != NULL; i++)
+ if (ttrace_xcalls[i].tt_type == xce->xce_marker)
+ break;
+
+ switch (xce->xce_marker) {
+ case TT_XC_SVC_BEGIN:
+ case TT_XC_SVC_END:
+ mdb_printf("%3s ", "-");
+ break;
+ default:
+ mdb_printf("%3x ", (int)xce->xce_arg);
+ break;
+ }
+
+ if (ttrace_xcalls[i].tt_name == NULL)
+ mdb_printf("%-*s", TT_HDLR_WIDTH, "(unknown)");
+ else
+ mdb_printf("%-*s", TT_HDLR_WIDTH, ttrace_xcalls[i].tt_name);
+ return (0);
+}
+
+static char *
+xc_pri_to_str(int pri)
+{
+ switch (pri) {
+ case X_CALL_LOPRI:
+ return (" low");
+ case X_CALL_MEDPRI:
+ return (" med");
+ case X_CALL_HIPRI:
+ return ("high");
+ default:
+ return ("bad?");
+ }
+}
+
+static char *
+xc_state_to_str(uint8_t state)
+{
+ switch (state) {
+ case XC_DONE:
+ return ("done");
+ case XC_HOLD:
+ return ("hold");
+ case XC_SYNC_OP:
+ return ("sync");
+ case XC_CALL_OP:
+ return ("call");
+ case XC_WAIT:
+ return ("wait");
+ default:
+ return ("bad?");
+ }
+}
+
+static void
+ttrace_intr_detail(trap_trace_rec_t *rec)
+{
+ mdb_printf("\tirq %x ipl %d oldpri %d basepri %d\n", rec->ttr_vector,
+ rec->ttr_ipl, rec->ttr_pri, rec->ttr_spl);
+}
+
+static void
+ttrace_xcall_detail(trap_trace_rec_t *rec)
+{
+ struct _xc_entry *xce = &(rec->ttr_info.xc_entry);
+
+ if ((uint_t)xce->xce_pri < X_CALL_LEVELS)
+ mdb_printf("\t%s pri [%s] ", xc_pri_to_str(xce->xce_pri),
+ xc_state_to_str(xce->xce_state));
+ else
+ mdb_printf("\t");
+
+ switch (xce->xce_marker) {
+ case TT_XC_SVC_BEGIN:
+ if (xce->xce_pri != X_CALL_MEDPRI && xce->xce_func != NULL)
+ mdb_printf("call %a() ..", xce->xce_func);
+ break;
+ case TT_XC_SVC_END:
+ if (xce->xce_arg == DDI_INTR_UNCLAIMED)
+ mdb_printf("[spurious]");
+ else if (xce->xce_pri != X_CALL_MEDPRI &&
+ xce->xce_func != NULL)
+ mdb_printf(".. called %a() returned %d",
+ xce->xce_func, xce->xce_retval);
+ break;
+ case TT_XC_START:
+ case TT_XC_CAPTURE:
+ mdb_printf("--> cpu%d", (int)xce->xce_arg);
+ break;
+ case TT_XC_RELEASE:
+ case TT_XC_WAIT:
+ case TT_XC_ACK:
+ mdb_printf("<-- cpu%d", (int)xce->xce_arg);
+ break;
+ case TT_XC_POKE_CPU:
+ case TT_XC_CBE_FIRE:
+ case TT_XC_CBE_XCALL:
+ mdb_printf("--> cpu%d", (int)xce->xce_arg);
+ break;
+ default:
+ mdb_printf("tag %d? arg 0x%lx",
+ xce->xce_marker, xce->xce_arg);
+ break;
+ }
+ mdb_printf("\n\n");
+}
+
+static struct {
uchar_t t_marker;
char *t_name;
int (*t_hdlr)(trap_trace_rec_t *);
@@ -320,6 +470,8 @@ static struct {
{ TT_SYSC64, "sc64", ttrace_syscall },
{ TT_INTERRUPT, "intr", ttrace_interrupt },
{ TT_TRAP, "trap", ttrace_trap },
+ { TT_EVENT, "evnt", ttrace_trap },
+ { TT_XCALL, "xcal", ttrace_xcall },
{ 0, NULL, NULL }
};
@@ -333,7 +485,6 @@ typedef struct ttrace_dcmd {
#define DUMP(reg) #reg, regs->r_##reg
#define THREEREGS " %3s: %16lx %3s: %16lx %3s: %16lx\n"
-#define TWOREGS " %3s: %16lx %3s: %16lx\n"
static void
ttrace_dumpregs(trap_trace_rec_t *rec)
@@ -345,12 +496,10 @@ ttrace_dumpregs(trap_trace_rec_t *rec)
mdb_printf(THREEREGS, DUMP(rax), DUMP(rbx), DUMP(rbp));
mdb_printf(THREEREGS, DUMP(r10), DUMP(r11), DUMP(r12));
mdb_printf(THREEREGS, DUMP(r13), DUMP(r14), DUMP(r15));
- mdb_printf(THREEREGS, "fsb", regs->r_fsbase, "gsb", regs->r_gsbase,
- DUMP(ds));
- mdb_printf(THREEREGS, DUMP(es), DUMP(fs), DUMP(gs));
- mdb_printf(THREEREGS, "trp", regs->r_trapno, DUMP(err), DUMP(rip));
- mdb_printf(THREEREGS, DUMP(cs), DUMP(rfl), DUMP(rsp));
- mdb_printf(TWOREGS, DUMP(ss), "cr2", rec->ttr_cr2);
+ mdb_printf(THREEREGS, DUMP(ds), DUMP(es), DUMP(fs));
+ mdb_printf(THREEREGS, DUMP(gs), "trp", regs->r_trapno, DUMP(err));
+ mdb_printf(THREEREGS, DUMP(rip), DUMP(cs), DUMP(rfl));
+ mdb_printf(THREEREGS, DUMP(rsp), DUMP(ss), "cr2", rec->ttr_cr2);
mdb_printf("\n");
}
@@ -408,12 +557,17 @@ ttrace_walk(uintptr_t addr, trap_trace_rec_t *rec, ttrace_dcmd_t *dcmd)
return (WALK_ERR);
}
- mdb_printf("%a\n", regs->r_pc);
+ mdb_printf(" %a\n", regs->r_pc);
if (dcmd->ttd_extended == FALSE)
return (WALK_NEXT);
- ttrace_dumpregs(rec);
+ if (rec->ttr_marker == TT_XCALL)
+ ttrace_xcall_detail(rec);
+ else if (rec->ttr_marker == TT_INTERRUPT)
+ ttrace_intr_detail(rec);
+ else
+ ttrace_dumpregs(rec);
if (rec->ttr_sdepth > 0) {
for (i = 0; i < rec->ttr_sdepth; i++) {
@@ -459,8 +613,8 @@ ttrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
if (DCMD_HDRSPEC(flags)) {
mdb_printf("%3s %15s %4s %2s %-*s%s\n", "CPU",
- "TIMESTAMP", "TYPE", "VC", TT_HDLR_WIDTH, "HANDLER",
- "EIP");
+ "TIMESTAMP", "TYPE", "Vec", TT_HDLR_WIDTH, "HANDLER",
+ " EIP");
}
if (flags & DCMD_ADDRSPEC) {
@@ -618,15 +772,47 @@ idt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
return (DCMD_OK);
}
+static void
+htables_help(void)
+{
+ mdb_printf(
+ "Given a (hat_t *), generates the list of all (htable_t *)s\n"
+ "that correspond to that address space\n");
+}
+
+static void
+report_maps_help(void)
+{
+ mdb_printf(
+ "Given a PFN, report HAT structures that map the page, or use\n"
+ "the page as a pagetable.\n"
+ "\n"
+ "-m Interpret the PFN as a Xen MFN (machine frame number)\n");
+}
+
+static void
+ptable_help(void)
+{
+ mdb_printf(
+ "Given a PFN holding a page table, print its contents, and\n"
+ "the address of the corresponding htable structure.\n"
+ "\n"
+ "-m Interpret the PFN as a Xen MFN (machine frame number)\n");
+}
+
static const mdb_dcmd_t dcmds[] = {
{ "gate_desc", ":", "dump a gate descriptor", gate_desc },
{ "idt", ":[-v]", "dump an IDT", idt },
{ "ttrace", "[-x]", "dump trap trace buffers", ttrace },
{ "vatopfn", ":[-a as]", "translate address to physical page",
va2pfn_dcmd },
- { "report_maps", "", "Given PFN, report mappings / page table usage",
- report_maps_dcmd },
- { "ptable", "", "Dump contents of a page table", ptable_dcmd },
+ { "report_maps", ":[-m]",
+ "Given PFN, report mappings / page table usage",
+ report_maps_dcmd, report_maps_help },
+ { "htables", "", "Given hat_t *, lists all its htable_t * values",
+ htables_dcmd, htables_help },
+ { "ptable", ":[-m]", "Given PFN, dump contents of a page table",
+ ptable_dcmd, ptable_help },
{ "pte", ":[-p XXXXX] [-l N]", "print human readable page table entry",
pte_dcmd },
{ "page_num2pp", ":", "page frame number to page structure",
diff --git a/usr/src/cmd/mdb/i86pc/modules/uppc/amd64/Makefile b/usr/src/cmd/mdb/i86pc/modules/uppc/amd64/Makefile
index 0bcf1cd107..501eecf8c5 100644
--- a/usr/src/cmd/mdb/i86pc/modules/uppc/amd64/Makefile
+++ b/usr/src/cmd/mdb/i86pc/modules/uppc/amd64/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -35,7 +35,10 @@ include ../../../../intel/Makefile.amd64
include ../../../Makefile.i86pc
include ../../../../Makefile.module
+MODSRCS_DIR = ../../common
+
CPPFLAGS += -DMP -D_MACHDEP
+CPPFLAGS += -I../../common
CPPFLAGS += -I../../../../common
CPPFLAGS += -I$(SRC)/uts/intel
CPPFLAGS += -I$(SRC)/uts/i86pc
diff --git a/usr/src/cmd/mdb/i86pc/modules/uppc/ia32/Makefile b/usr/src/cmd/mdb/i86pc/modules/uppc/ia32/Makefile
index e7778d3e05..f10ce9e177 100644
--- a/usr/src/cmd/mdb/i86pc/modules/uppc/ia32/Makefile
+++ b/usr/src/cmd/mdb/i86pc/modules/uppc/ia32/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -34,7 +34,10 @@ include ../../../../intel/Makefile.ia32
include ../../../Makefile.i86pc
include ../../../../Makefile.module
+MODSRCS_DIR = ../../common
+
CPPFLAGS += -DMP -D_MACHDEP
+CPPFLAGS += -I../../common
CPPFLAGS += -I../../../../common
CPPFLAGS += -I$(SRC)/uts/intel
CPPFLAGS += -I$(SRC)/uts/i86pc
diff --git a/usr/src/cmd/mdb/i86pc/modules/uppc/uppc.c b/usr/src/cmd/mdb/i86pc/modules/uppc/uppc.c
index be910bbcb7..fee48b58f5 100644
--- a/usr/src/cmd/mdb/i86pc/modules/uppc/uppc.c
+++ b/usr/src/cmd/mdb/i86pc/modules/uppc/uppc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -110,7 +110,7 @@ uppc_interrupt_dump(uintptr_t addr, uint_t flags, int argc,
/* Print the header first */
if (option_flags & INTR_DISPLAY_INTRSTAT)
- mdb_printf("%<u>CPU\t ");
+ mdb_printf("%<u>CPU ");
else
mdb_printf("%<u>IRQ Vector IPL(lo/hi) Bus Share ");
mdb_printf("%s %</u>\n", option_flags & INTR_DISPLAY_DRVR_INST ?
diff --git a/usr/src/cmd/mdb/intel/Makefile.kmdb b/usr/src/cmd/mdb/intel/Makefile.kmdb
index 67c6d7c92b..7026ef906c 100644
--- a/usr/src/cmd/mdb/intel/Makefile.kmdb
+++ b/usr/src/cmd/mdb/intel/Makefile.kmdb
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -34,9 +34,6 @@ PROMSRCS += \
KMDBSRCS += \
kaif.c \
- kaif_activate.c \
- kaif_idt.c \
- kaif_start_isadep.c \
kmdb_dpi_isadep.c \
kmdb_fault_isadep.c \
kmdb_kdi_isadep.c \
@@ -46,7 +43,6 @@ KMDBSRCS += \
kvm_isadep.c
KMDBML += \
- kaif_idthdl.s \
kmdb_asmutil.s \
kmdb_setcontext.s
diff --git a/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb b/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb
index 93e99f8aa6..324572a024 100644
--- a/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb
+++ b/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,27 +19,18 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
#
KMDBML += \
- kaif_asmutil.s \
kaif_invoke.s \
- kaif_resume.s \
- kaif_startup.s \
kmdb_start.s
KMDBSRCS += \
kmdb_makecontext.c \
mdb_amd64util.c
-REGOFFUSERS = \
- kaif_resume.o \
- kaif_startup.o
-
SACPPFLAGS = -D__$(MACH64) -U__$(MACH)
-
-$(REGOFFUSERS) $(REGOFFUSERS:%.o=%.ln): kaif_off.h
diff --git a/usr/src/cmd/mdb/intel/amd64/genunix/Makefile b/usr/src/cmd/mdb/intel/amd64/genunix/Makefile
index 801d16db46..980d83ae29 100644
--- a/usr/src/cmd/mdb/intel/amd64/genunix/Makefile
+++ b/usr/src/cmd/mdb/intel/amd64/genunix/Makefile
@@ -29,43 +29,10 @@
MODULE = genunix.so
MDBTGT = kvm
+include ../../../common/modules/genunix/Makefile.files
+
COMMONSRCS = \
- avl.c \
- bio.c \
- contract.c \
- cpupart.c \
- ctxop.c \
- cyclic.c \
- devinfo.c \
- findstack.c \
- fm.c \
- genunix.c \
- group.c \
- kgrep.c \
- kmem.c \
- ldi.c \
- leaky.c \
- leaky_subr.c \
- lgrp.c \
- list.c \
- log.c \
- mdi.c \
- memory.c \
- mmd.c \
- modhash.c \
- ndievents.c \
- net.c \
- nvpair.c \
- pg.c \
- rctl.c \
- sobj.c \
- streams.c \
- sysevent.c \
- thread.c \
- tsd.c \
- tsol.c \
- vfs.c \
- zone.c
+ $(GENUNIX_SRCS)
KMODSRCS = \
$(COMMONSRCS)
diff --git a/usr/src/cmd/mdb/intel/amd64/kmdb/Makefile b/usr/src/cmd/mdb/intel/amd64/kmdb/Makefile
index e5094fc27b..c22ed7a256 100644
--- a/usr/src/cmd/mdb/intel/amd64/kmdb/Makefile
+++ b/usr/src/cmd/mdb/intel/amd64/kmdb/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -88,9 +88,6 @@ lintprom: $(PROMOBJS:%.o=%.ln)
lintkctl: $(KCTLOBJS:%.o=%.ln)
$(LINT) $(ALLLINTFLAGS) $(KCTLOBJS:%.o=%.ln)
-kaif_off.h: ../../kmdb/kaif_off.in
- $(OFFSETS_CREATE) <../../kmdb/kaif_off.in >$@
-
kmdb_context_off.h: ../../kmdb/kmdb_context_off.in
$(OFFSETS_CREATE) <../../kmdb/kmdb_context_off.in >$@
diff --git a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_startup.s b/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_startup.s
deleted file mode 100644
index 658f564e02..0000000000
--- a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_startup.s
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Debugger entry for both master and slave CPUs
- */
-
-#if defined(__lint)
-#include <sys/types.h>
-#endif
-
-#include <sys/segments.h>
-#include <sys/asm_linkage.h>
-#include <sys/controlregs.h>
-#include <sys/x86_archext.h>
-
-#include <mdb/mdb_kreg.h>
-#include <kmdb/kaif.h>
-#include <kmdb/kaif_asmutil.h>
-#include <kmdb/kaif_regs.h>
-#include <kmdb/kaif_off.h>
-#include <kmdb/kmdb_dpi_isadep.h>
-
-#if !defined(__lint)
-
- /* XXX implement me */
- ENTRY_NP(kaif_nmiint)
- clrq %rcx
- movq (%rcx), %rcx
- SET_SIZE(kaif_nmiint)
-
- ENTRY_NP(kaif_save_common_state)
-
- /*
- * The state of the world:
- *
- * The stack has a complete set of saved registers and segment
- * selectors, arranged in the order given in mdb_kreg.h. It also has a
- * pointer to our cpusave area.
- *
- * We need to save, into the cpusave area, a pointer to these saved
- * registers. After that, we save a few more registers, ready the
- * machine for debugger entry, and enter the debugger.
- */
-
- popq %rax /* the cpusave area */
- movq %rsp, KRS_GREGS(%rax) /* save ptr to current saved regs */
-
- SAVE_IDTGDT
-
- /* Save off %cr0, and clear write protect */
- movq %cr0, %rcx
- movq %rcx, KRS_CR0(%rax)
- andq $_BITNOT(CR0_WP), %rcx
- movq %rcx, %cr0
-
- /* Save the debug registers and disable any active watchpoints */
- movq %dr7, %rcx
- movq %rcx, KRS_DRCTL(%rax)
- andq $_BITNOT(KREG_DRCTL_WPALLEN_MASK), %rcx
- movq %rcx, %dr7
-
- movq %dr6, %rcx
- movq %rcx, KRS_DRSTAT(%rax)
-
- movq %dr0, %rcx
- movq %rcx, KRS_DROFF(0)(%rax)
- movq %dr1, %rcx
- movq %rcx, KRS_DROFF(1)(%rax)
- movq %dr2, %rcx
- movq %rcx, KRS_DROFF(2)(%rax)
- movq %dr3, %rcx
- movq %rcx, KRS_DROFF(3)(%rax)
-
- /*
- * Save any requested MSRs.
- */
- movq KRS_MSR(%rax), %rcx
- cmpq $0, %rcx
- je no_msr
-
- pushq %rax /* rdmsr clobbers %eax */
- movq %rcx, %rbx
-
-1:
- movl MSR_NUM(%rbx), %ecx
- cmpl $0, %ecx
- je msr_done
-
- movl MSR_TYPE(%rbx), %edx
- cmpl $KMDB_MSR_READ, %edx
- jne msr_next
-
- rdmsr /* addr in %ecx, value into %edx:%eax */
- movl %eax, MSR_VAL(%rbx)
- movl %edx, _CONST(MSR_VAL + 4)(%rbx)
-
-msr_next:
- addq $MSR_SIZE, %rbx
- jmp 1b
-
-msr_done:
- popq %rax
-
-no_msr:
- clrq %rbp /* stack traces should end here */
-
- pushq %rax
- movq %rax, %rdi /* cpusave */
-
- call kaif_debugger_entry
-
- /* Pass cpusave and debugger return code for "call" to resume */
- popq %rdi
- movq %rax, %rsi
-
- jmp kaif_resume
-
- SET_SIZE(kaif_save_common_state)
-
-#endif /* !__lint */
-
-/*
- * The main entry point for master CPUs. It also serves as the trap handler
- * for all traps and interrupts taken during single-step.
- */
-#if defined(__lint)
-void
-kaif_cmnint(void)
-{
-}
-#else /* __lint */
-
- ENTRY_NP(kaif_cmnint)
- ALTENTRY(kaif_master_entry)
-
- cli
-
- /* Save current register state */
- subq $REG_OFF(KREG_TRAPNO), %rsp
- KAIF_SAVE_REGS(%rsp)
-
- /*
- * Switch to the kernel's GSBASE. Neither GSBASE nor the ill-named
- * KGSBASE can be trusted, as the kernel may or may not have already
- * done a swapgs. All is not lost, as the kernel can divine the correct
- * value for us.
- */
- movq mdb+MDB_KDI, %rax
- movq MKDI_GDT2GSBASE(%rax), %rax
- subq $10, %rsp
- sgdt (%rsp)
- movq 2(%rsp), %rdi /* gdt base now in %rdi */
- addq $10, %rsp
- call *%rax /* returns kernel's GSBASE in %rax */
-
- movq %rax, %rdx
- shrq $32, %rdx
- movl $MSR_AMD_GSBASE, %ecx
- wrmsr
-
- GET_CPUSAVE_ADDR /* %rax = cpusave, %rbx = CPU ID */
-
- ADVANCE_CRUMB_POINTER(%rax, %rcx, %rdx)
-
- ADD_CRUMB(%rax, KRM_CPU_STATE, $KAIF_CPU_STATE_MASTER, %rdx)
-
- movq REG_OFF(KREG_RIP)(%rsp), %rcx
- ADD_CRUMB(%rax, KRM_PC, %rcx, %rdx)
- ADD_CRUMB(%rax, KRM_SP, %rsp, %rdx)
- movq REG_OFF(KREG_TRAPNO)(%rsp), %rcx
- ADD_CRUMB(%rax, KRM_TRAPNO, %rcx, %rdx)
-
- movq %rsp, %rbp
- pushq %rax
-
- /*
- * Were we in the debugger when we took the trap (i.e. was %esp in one
- * of the debugger's memory ranges)?
- */
- leaq kaif_memranges, %rcx
- movl kaif_nmemranges, %edx
-1: cmpq MR_BASE(%rcx), %rsp
- jl 2f /* below this range -- try the next one */
- cmpq MR_LIM(%rcx), %rsp
- jg 2f /* above this range -- try the next one */
- jmp 3f /* matched within this range */
-
-2: decl %edx
- jz kaif_save_common_state /* %rsp not within debugger memory */
- addq $MR_SIZE, %rcx
- jmp 1b
-
-3: /*
- * The master is still set. That should only happen if we hit a trap
- * while running in the debugger. Note that it may be an intentional
- * fault. kmdb_dpi_handle_fault will sort it all out.
- */
-
- movq REG_OFF(KREG_TRAPNO)(%rbp), %rdi
- movq REG_OFF(KREG_RIP)(%rbp), %rsi
- movq REG_OFF(KREG_RSP)(%rbp), %rdx
- movq %rbx, %rcx /* cpuid */
-
- call kmdb_dpi_handle_fault
-
- /*
- * If we're here, we ran into a debugger problem, and the user
- * elected to solve it by having the debugger debug itself. The
- * state we're about to save is that of the debugger when it took
- * the fault.
- */
-
- jmp kaif_save_common_state
-
- SET_SIZE(kaif_master_entry)
- SET_SIZE(kaif_cmnint)
-
-#endif /* __lint */
-
-/*
- * The cross-call handler for slave CPUs.
- *
- * The debugger is single-threaded, so only one CPU, called the master, may be
- * running it at any given time. The other CPUs, known as slaves, spin in a
- * busy loop until there's something for them to do. This is the entry point
- * for the slaves - they'll be sent here in response to a cross-call sent by the
- * master.
- */
-
-#if defined(__lint)
-char kaif_slave_entry_patch;
-
-void
-kaif_slave_entry(void)
-{
-}
-#else /* __lint */
- .globl kaif_slave_entry_patch;
-
- ENTRY_NP(kaif_slave_entry)
-
- /* kaif_msr_add_clrentry knows where this is */
-kaif_slave_entry_patch:
- KAIF_MSR_PATCH;
-
- /*
- * Cross calls are implemented as function calls, so our stack currently
- * looks like one you'd get from a zero-argument function call. That
- * is, there's the return %rip at %rsp, and that's about it. We need
- * to make it look like an interrupt stack. When we first save, we'll
- * reverse the saved %ss and %rip, which we'll fix back up when we've
- * freed up some general-purpose registers. We'll also need to fix up
- * the saved %rsp.
- */
-
- pushq %rsp /* pushed value off by 8 */
- pushfq
- cli
- clrq %rax
- movw %cs, %ax
- pushq %rax
- movw %ss, %ax
- pushq %rax /* rip should be here */
- pushq $-1 /* phony trap error code */
- pushq $-1 /* phony trap number */
-
- subq $REG_OFF(KREG_TRAPNO), %rsp
- KAIF_SAVE_REGS(%rsp)
-
- movq REG_OFF(KREG_SS)(%rsp), %rax
- xchgq REG_OFF(KREG_RIP)(%rsp), %rax
- movq %rax, REG_OFF(KREG_SS)(%rsp)
-
- movq REG_OFF(KREG_RSP)(%rsp), %rax
- addq $8, %rax
- movq %rax, REG_OFF(KREG_RSP)(%rsp)
-
- /*
- * We've saved all of the general-purpose registers, and have a stack
- * that is irettable (after we strip down to the error code)
- */
-
- GET_CPUSAVE_ADDR /* %rax = cpusave, %rbx = CPU ID */
-
- ADVANCE_CRUMB_POINTER(%rax, %rcx, %rdx)
-
- ADD_CRUMB(%rax, KRM_CPU_STATE, $KAIF_CPU_STATE_SLAVE, %rdx)
-
- movq REG_OFF(KREG_RIP)(%rsp), %rcx
- ADD_CRUMB(%rax, KRM_PC, %rcx, %rdx)
-
- pushq %rax
- jmp kaif_save_common_state
-
- SET_SIZE(kaif_slave_entry)
-
-#endif /* __lint */
diff --git a/usr/src/cmd/mdb/intel/ia32/Makefile.kmdb b/usr/src/cmd/mdb/intel/ia32/Makefile.kmdb
index d9b792bc58..53b19b535d 100644
--- a/usr/src/cmd/mdb/intel/ia32/Makefile.kmdb
+++ b/usr/src/cmd/mdb/intel/ia32/Makefile.kmdb
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,17 +19,14 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
#
KMDBML += \
- kaif_asmutil.s \
kaif_invoke.s \
- kaif_resume.s \
- kaif_startup.s \
kmdb_start.s
KMDBSRCS += \
@@ -38,10 +34,4 @@ KMDBSRCS += \
kmdb_makecontext.c \
kvm_cpu_p6.c
-REGOFFUSERS = \
- kaif_resume.o \
- kaif_startup.o
-
SACPPFLAGS = -D__$(MACH)
-
-$(REGOFFUSERS) $(REGOFFUSERS:%.o=%.ln): kaif_off.h
diff --git a/usr/src/cmd/mdb/intel/ia32/genunix/Makefile b/usr/src/cmd/mdb/intel/ia32/genunix/Makefile
index 63609d42b2..7ca684b524 100644
--- a/usr/src/cmd/mdb/intel/ia32/genunix/Makefile
+++ b/usr/src/cmd/mdb/intel/ia32/genunix/Makefile
@@ -29,43 +29,10 @@
MODULE = genunix.so
MDBTGT = kvm
+include ../../../common/modules/genunix/Makefile.files
+
COMMONSRCS = \
- avl.c \
- bio.c \
- contract.c \
- cpupart.c \
- ctxop.c \
- cyclic.c \
- devinfo.c \
- findstack.c \
- fm.c \
- genunix.c \
- group.c \
- kgrep.c \
- kmem.c \
- ldi.c \
- leaky.c \
- leaky_subr.c \
- lgrp.c \
- list.c \
- log.c \
- mdi.c \
- memory.c \
- mmd.c \
- modhash.c \
- ndievents.c \
- net.c \
- nvpair.c \
- pg.c \
- rctl.c \
- sobj.c \
- streams.c \
- sysevent.c \
- thread.c \
- tsd.c \
- tsol.c \
- vfs.c \
- zone.c
+ $(GENUNIX_SRCS)
KMODSRCS = \
$(COMMONSRCS)
diff --git a/usr/src/cmd/mdb/intel/ia32/kmdb/Makefile b/usr/src/cmd/mdb/intel/ia32/kmdb/Makefile
index ccd4b446c4..594594ecb5 100644
--- a/usr/src/cmd/mdb/intel/ia32/kmdb/Makefile
+++ b/usr/src/cmd/mdb/intel/ia32/kmdb/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -79,9 +79,6 @@ lintprom: $(PROMOBJS:%.o=%.ln)
lintkctl: $(KCTLOBJS:%.o=%.ln)
$(LINT) $(ALLLINTFLAGS) $(KCTLOBJS:%.o=%.ln)
-kaif_off.h: ../../kmdb/kaif_off.in
- $(OFFSETS_CREATE) <../../kmdb/kaif_off.in >$@
-
kmdb_context_off.h: ../../kmdb/kmdb_context_off.in
$(OFFSETS_CREATE) <../../kmdb/kmdb_context_off.in >$@
diff --git a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_startup.s b/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_startup.s
deleted file mode 100644
index 196c3b26c4..0000000000
--- a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_startup.s
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Debugger entry for both master and slave CPUs
- */
-
-#if defined(__lint)
-#include <sys/types.h>
-#endif
-
-#include <sys/segments.h>
-#include <sys/asm_linkage.h>
-#include <sys/controlregs.h>
-#include <sys/x86_archext.h>
-
-#include <mdb/mdb_kreg.h>
-#include <kmdb/kaif.h>
-#include <kmdb/kaif_asmutil.h>
-#include <kmdb/kaif_regs.h>
-#include <kmdb/kaif_off.h>
-#include <kmdb/kmdb_dpi_isadep.h>
-
-#if !defined(__lint)
-
- /* XXX implement me */
- ENTRY_NP(kaif_nmiint)
- clr %ecx
- movl (%ecx), %ecx
- SET_SIZE(kaif_nmiint)
-
- ENTRY_NP(kaif_save_common_state)
-
- /*
- * The state of the world:
- *
- * The stack has a complete set of saved registers and segment
- * selectors, arranged in `struct regs' order (or vice-versa), up to
- * and including EFLAGS. It also has a pointer to our cpusave area.
- *
- * We need to save a pointer to these saved registers. We also want
- * to adjust the saved %esp - it should point just beyond the saved
- * registers to the last frame of the thread we interrupted. Finally,
- * we want to clear out bits 16-31 of the saved selectors, as the
- * selector pushls don't automatically clear them.
- */
- popl %eax /* the cpusave area */
-
- movl %esp, KRS_GREGS(%eax) /* save ptr to current saved regs */
-
- SAVE_IDTGDT
-
- addl $REG_OFF(KREG_EFLAGS - KREG_EAX), KREG_OFF(KREG_ESP)(%esp)
-
- andl $0xffff, KREG_OFF(KREG_SS)(%esp)
- andl $0xffff, KREG_OFF(KREG_GS)(%esp)
- andl $0xffff, KREG_OFF(KREG_FS)(%esp)
- andl $0xffff, KREG_OFF(KREG_ES)(%esp)
- andl $0xffff, KREG_OFF(KREG_DS)(%esp)
-
- /* Save off %cr0, and clear write protect */
- movl %cr0, %ecx
- movl %ecx, KRS_CR0(%eax)
- andl $_BITNOT(CR0_WP), %ecx
- movl %ecx, %cr0
-
- /* Save the debug registers and disable any active watchpoints */
- movl %dr7, %ecx
- movl %ecx, KRS_DRCTL(%eax)
- andl $_BITNOT(KREG_DRCTL_WPALLEN_MASK), %ecx
- movl %ecx, %dr7
-
- movl %dr6, %ecx
- movl %ecx, KRS_DRSTAT(%eax)
-
- movl %dr0, %ecx
- movl %ecx, KRS_DROFF(0)(%eax)
- movl %dr1, %ecx
- movl %ecx, KRS_DROFF(1)(%eax)
- movl %dr2, %ecx
- movl %ecx, KRS_DROFF(2)(%eax)
- movl %dr3, %ecx
- movl %ecx, KRS_DROFF(3)(%eax)
-
- /*
- * Save any requested MSRs.
- */
- movl KRS_MSR(%eax), %ecx
- cmpl $0, %ecx
- je no_msr
-
- pushl %eax /* rdmsr clobbers %eax */
- movl %ecx, %ebx
-
-1:
- movl MSR_NUM(%ebx), %ecx
- cmpl $0, %ecx
- je msr_done
-
- movl MSR_TYPE(%ebx), %edx
- cmpl $KMDB_MSR_READ, %edx
- jne msr_next
-
- rdmsr /* addr in %ecx, value into %edx:%eax */
- movl %eax, MSR_VAL(%ebx)
- movl %edx, _CONST(MSR_VAL + 4)(%ebx)
-
-msr_next:
- addl $MSR_SIZE, %ebx
- jmp 1b
-
-msr_done:
- popl %eax
-
-no_msr:
- clr %ebp /* stack traces should end here */
-
- pushl %eax
- call kaif_debugger_entry
- pushl %eax /* leave cpusave on the stack */
-
- jmp kaif_resume
-
- SET_SIZE(kaif_save_common_state)
-
-#endif /* !__lint */
-
-/*
- * The main entry point for master CPUs. It also serves as the trap handler
- * for all traps and interrupts taken during single-step.
- */
-#if defined(__lint)
-void
-kaif_cmnint(void)
-{
-}
-#else /* __lint */
-
- ENTRY_NP(kaif_cmnint)
- ALTENTRY(kaif_master_entry)
-
- cli
-
- /* Save all registers and selectors */
- pushal
- pushl %ds
- pushl %es
- pushl %fs
- pushl %gs
- pushl %ss
-
- subl $8, %esp
- movl %ebp, REG_OFF(KREG_SAVFP)(%esp)
- movl REG_OFF(KREG_EIP)(%esp), %eax
- movl %eax, REG_OFF(KREG_SAVPC)(%esp)
-
- /*
- * If the kernel has started using its own selectors, we should too.
- * Update our saved selectors if they haven't been updated already.
- */
- movw %cs, %ax
- cmpw $KCS_SEL, %ax
- jne 1f /* The kernel hasn't switched yet */
-
- movw $KDS_SEL, %ax
- movw %ax, %ds
- movw kaif_cs, %ax
- cmpw $KCS_SEL, %ax
- je 1f /* We already switched */
-
- /*
- * The kernel switched, but we haven't. Update our saved selectors
- * to match the kernel's copies for use below.
- */
- movl $KCS_SEL, kaif_cs
- movl $KDS_SEL, kaif_ds
- movl $KFS_SEL, kaif_fs
- movl $KGS_SEL, kaif_gs
-
-1:
- /*
- * Set the selectors to a known state. If we come in from kmdb's IDT,
- * we'll be on boot's %cs. This will cause GET_CPUSAVE_ADDR to return
- * CPU 0's cpusave, regardless of which CPU we're on, and chaos will
- * ensue. So, if we've got $KCSSEL in kaif_cs, switch to it. The other
- * selectors are restored normally.
- */
- movw %cs:kaif_cs, %ax
- cmpw $KCS_SEL, %ax
- jne 1f
- ljmp $KCS_SEL, $1f
-1:
- movw %cs:kaif_ds, %ds
- movw kaif_ds, %es
- movw kaif_fs, %fs
- movw kaif_gs, %gs
- movw kaif_ds, %ss
-
- GET_CPUSAVE_ADDR /* %eax = cpusave, %ebx = CPU ID */
-
- ADVANCE_CRUMB_POINTER(%eax, %ecx, %edx)
-
- ADD_CRUMB(%eax, KRM_CPU_STATE, $KAIF_CPU_STATE_MASTER, %edx)
-
- movl REG_OFF(KREG_EIP)(%esp), %ecx
- ADD_CRUMB(%eax, KRM_PC, %ecx, %edx)
- ADD_CRUMB(%eax, KRM_SP, %esp, %edx)
- movl REG_OFF(KREG_TRAPNO)(%esp), %ecx
- ADD_CRUMB(%eax, KRM_TRAPNO, %ecx, %edx)
-
- movl %esp, %ebp
- pushl %eax
-
- /*
- * Were we in the debugger when we took the trap (i.e. was %esp in one
- * of the debugger's memory ranges)?
- */
- leal kaif_memranges, %ecx
- movl kaif_nmemranges, %edx
-1: cmpl MR_BASE(%ecx), %esp
- jl 2f /* below this range -- try the next one */
- cmpl MR_LIM(%ecx), %esp
- jg 2f /* above this range -- try the next one */
- jmp 3f /* matched within this range */
-
-2: decl %edx
- jz kaif_save_common_state /* %esp not within debugger memory */
- addl $MR_SIZE, %ecx
- jmp 1b
-
-3: /*
- * %esp was within one of the debugger's memory ranges. This should only
- * happen when we take a trap while running in the debugger.
- * kmdb_dpi_handle_fault will determine whether or not it was an expected
- * trap, and will take the appropriate action.
- */
-
- pushl %ebx /* cpuid */
-
- movl REG_OFF(KREG_ESP)(%ebp), %ecx
- addl $REG_OFF(KREG_EFLAGS - KREG_EAX), %ecx
- pushl %ecx
-
- pushl REG_OFF(KREG_EIP)(%ebp)
- pushl REG_OFF(KREG_TRAPNO)(%ebp)
-
- call kmdb_dpi_handle_fault
- addl $16, %esp
-
- /*
- * If we're here, we ran into a debugger problem, and the user
- * elected to solve it by having the debugger debug itself. The
- * state we're about to save is that of the debugger when it took
- * the fault.
- */
-
- jmp kaif_save_common_state
-
- SET_SIZE(kaif_master_entry)
- SET_SIZE(kaif_cmnint)
-
-#endif /* __lint */
-
-/*
- * The cross-call handler for slave CPUs.
- *
- * The debugger is single-threaded, so only one CPU, called the master, may be
- * running it at any given time. The other CPUs, known as slaves, spin in a
- * busy loop until there's something for them to do. This is the entry point
- * for the slaves - they'll be sent here in response to a cross-call sent by the
- * master.
- */
-
-#if defined(__lint)
-char kaif_slave_entry_patch;
-
-void
-kaif_slave_entry(void)
-{
-}
-#else /* __lint */
- .globl kaif_slave_entry_patch;
-
- ENTRY_NP(kaif_slave_entry)
-
- /* kaif_msr_add_clrentry knows where this is */
-kaif_slave_entry_patch:
- KAIF_MSR_PATCH;
-
- /*
- * Cross calls are implemented as function calls, so our stack currently
- * looks like one you'd get from a zero-argument function call. There's
- * an %eip at %esp, and that's about it. We want to make it look like the
- * master CPU's stack. By doing this, we can use the same resume code for
- * both master and slave. We need to make our stack look like a `struct
- * regs' before we jump into the common save routine.
- */
-
- pushl %cs
- pushfl
- cli
- pushl $-1 /* A phony trap error code */
- pushl $-1 /* A phony trap number */
- pushal
- pushl %ds
- pushl %es
- pushl %fs
- pushl %gs
- pushl %ss
-
- subl $8, %esp
- movl %ebp, REG_OFF(KREG_SAVFP)(%esp)
- movl REG_OFF(KREG_EIP)(%esp), %eax
- movl %eax, REG_OFF(KREG_SAVPC)(%esp)
-
- /* Swap our saved EFLAGS and %eip. Each is where the other should be */
- movl REG_OFF(KREG_EFLAGS)(%esp), %eax
- xchgl REG_OFF(KREG_EIP)(%esp), %eax
- movl %eax, REG_OFF(KREG_EFLAGS)(%esp)
-
- /* Our stack now matches struct regs, and is irettable */
-
- /* Load sanitized segment selectors */
- movw kaif_ds, %ds
- movw kaif_ds, %es
- movw kaif_fs, %fs
- movw kaif_gs, %gs
- movw kaif_ds, %ss
-
- GET_CPUSAVE_ADDR /* %eax = cpusave, %ebx = CPU ID */
-
- ADVANCE_CRUMB_POINTER(%eax, %ecx, %edx)
-
- ADD_CRUMB(%eax, KRM_CPU_STATE, $KAIF_CPU_STATE_SLAVE, %edx)
-
- movl REG_OFF(KREG_EIP)(%esp), %ecx
- ADD_CRUMB(%eax, KRM_PC, %ecx, %edx)
-
- pushl %eax
- jmp kaif_save_common_state
-
- SET_SIZE(kaif_slave_entry)
-
-#endif /* __lint */
diff --git a/usr/src/cmd/mdb/intel/ia32/kmdb/kvm_cpu_p6.c b/usr/src/cmd/mdb/intel/ia32/kmdb/kvm_cpu_p6.c
index 732142e85a..b3c3982ca6 100644
--- a/usr/src/cmd/mdb/intel/ia32/kmdb/kvm_cpu_p6.c
+++ b/usr/src/cmd/mdb/intel/ia32/kmdb/kvm_cpu_p6.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -91,13 +90,13 @@ kmt_p6_branches(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
* MSRs that we want to track. These will be read each time the debugger is
* entered.
*/
-static const kmdb_msr_t kmt_p6_msr[] = {
- { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY },
- { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_p6.p6_debugctl },
- { MSR_LBR_TO, KMDB_MSR_READ },
- { MSR_LBR_FROM, KMDB_MSR_READ },
- { MSR_LEX_TO, KMDB_MSR_READ },
- { MSR_LEX_FROM, KMDB_MSR_READ },
+static const kdi_msr_t kmt_p6_msr[] = {
+ { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY },
+ { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_p6.p6_debugctl },
+ { MSR_LBR_TO, KDI_MSR_READ },
+ { MSR_LBR_FROM, KDI_MSR_READ },
+ { MSR_LEX_TO, KDI_MSR_READ },
+ { MSR_LEX_FROM, KDI_MSR_READ },
{ NULL }
};
diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif.c b/usr/src/cmd/mdb/intel/kmdb/kaif.c
index ceedccc96f..207ddca12a 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kaif.c
+++ b/usr/src/cmd/mdb/intel/kmdb/kaif.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,58 +28,43 @@
/*
* The debugger/"PROM" interface layer
*
- * (it makes more sense on SPARC)
+ * It makes more sense on SPARC. In reality, these interfaces deal with three
+ * things: setting break/watchpoints, stepping, and interfacing with the KDI to
+ * set up kmdb's IDT handlers.
*/
#include <kmdb/kmdb_dpi_impl.h>
#include <kmdb/kmdb_kdi.h>
#include <kmdb/kmdb_umemglue.h>
#include <kmdb/kaif.h>
-#include <kmdb/kaif_asmutil.h>
#include <kmdb/kmdb_io.h>
+#include <kmdb/kaif_start.h>
#include <mdb/mdb_err.h>
#include <mdb/mdb_debug.h>
#include <mdb/mdb_isautil.h>
#include <mdb/mdb_io_impl.h>
-#include <mdb/mdb_kreg.h>
+#include <mdb/mdb_kreg_impl.h>
#include <mdb/mdb.h>
#include <sys/types.h>
-#include <sys/segments.h>
#include <sys/bitmap.h>
#include <sys/termios.h>
+#include <sys/kdi_impl.h>
-kaif_cpusave_t *kaif_cpusave;
+/*
+ * This is the area containing the saved state when we enter
+ * via kmdb's IDT entries.
+ */
+kdi_cpusave_t *kaif_cpusave;
int kaif_ncpusave;
-
-kaif_drreg_t kaif_drreg;
+kdi_drreg_t kaif_drreg;
uint32_t kaif_waptmap;
-#ifndef __amd64
-/* Used to track the current set of valid kernel selectors. */
-uint32_t kaif_cs;
-uint32_t kaif_ds;
-uint32_t kaif_fs;
-uint32_t kaif_gs;
-#endif
-
-uint_t kaif_msr_wrexit_msr;
-uint64_t *kaif_msr_wrexit_valp;
-
-uintptr_t kaif_kernel_handler;
-uintptr_t kaif_sys_sysenter;
-uintptr_t kaif_brand_sys_sysenter;
-
int kaif_trap_switch;
void (*kaif_modchg_cb)(struct modctl *, int);
-#define KAIF_MEMRANGES_MAX 2
-
-kaif_memrange_t kaif_memranges[KAIF_MEMRANGES_MAX];
-int kaif_nmemranges;
-
enum {
M_SYSRET = 0x07, /* after M_ESC */
M_ESC = 0x0f,
@@ -181,15 +166,25 @@ kaif_get_master_cpuid(void)
return (kaif_master_cpuid);
}
-static const mdb_tgt_gregset_t *
-kaif_get_gregs(int cpuid)
+static mdb_tgt_gregset_t *
+kaif_kdi_to_gregs(int cpuid)
{
kaif_cpusave_t *save;
if ((save = kaif_cpuid2save(cpuid)) == NULL)
return (NULL); /* errno is set for us */
- return (save->krs_gregs);
+ /*
+ * The saved registers are actually identical to an mdb_tgt_gregset,
+ * so we can directly cast here.
+ */
+ return ((mdb_tgt_gregset_t *)save->krs_gregs);
+}
+
+static const mdb_tgt_gregset_t *
+kaif_get_gregs(int cpuid)
+{
+ return (kaif_kdi_to_gregs(cpuid));
}
typedef struct kaif_reg_synonyms {
@@ -212,11 +207,11 @@ kaif_find_regp(const char *regname)
#endif
{ "tt", "trapno" }
};
-
- kaif_cpusave_t *save;
+ mdb_tgt_gregset_t *regs;
int i;
- save = kaif_cpuid2save(DPI_MASTER_CPUID);
+ if ((regs = kaif_kdi_to_gregs(DPI_MASTER_CPUID)) == NULL)
+ return (NULL);
for (i = 0; i < sizeof (synonyms) / sizeof (synonyms[0]); i++) {
if (strcmp(synonyms[i].rs_syn, regname) == 0)
@@ -227,7 +222,7 @@ kaif_find_regp(const char *regname)
const mdb_tgt_regdesc_t *rd = &mdb_isa_kregs[i];
if (strcmp(rd->rd_name, regname) == 0)
- return (&save->krs_gregs->kregs[rd->rd_num]);
+ return (&regs->kregs[rd->rd_num]);
}
(void) set_errno(ENOENT);
@@ -361,7 +356,7 @@ kaif_wapt_reserve(kmdb_wapt_t *wp)
{
int id;
- for (id = 0; id <= KREG_MAXWPIDX; id++) {
+ for (id = 0; id <= KDI_MAXWPIDX; id++) {
if (!BT_TEST(&kaif_waptmap, id)) {
/* found one */
BT_SET(&kaif_waptmap, id);
@@ -405,6 +400,7 @@ kaif_wapt_arm(kmdb_wapt_t *wp)
kaif_drreg.dr_ctl &= ~KREG_DRCTL_WP_MASK(hwid);
kaif_drreg.dr_ctl |= KREG_DRCTL_WP_LENRW(hwid, wp->wp_size - 1, rw);
kaif_drreg.dr_ctl |= KREG_DRCTL_WPEN(hwid);
+ kmdb_kdi_update_drreg(&kaif_drreg);
}
/*ARGSUSED*/
@@ -418,6 +414,7 @@ kaif_wapt_disarm(kmdb_wapt_t *wp)
kaif_drreg.dr_addr[hwid] = 0;
kaif_drreg.dr_ctl &= ~(KREG_DRCTL_WP_MASK(hwid) |
KREG_DRCTL_WPEN_MASK(hwid));
+ kmdb_kdi_update_drreg(&kaif_drreg);
}
/*ARGSUSED*/
@@ -523,7 +520,7 @@ kaif_step(void)
case M_POPF:
/*
* popfl will restore a pushed EFLAGS from the stack, and could
- * in so doing cause IF to be turned on, if only for a a brief
+ * in so doing cause IF to be turned on, if only for a brief
* period. To avoid this, we'll secretly replace the stack's
* EFLAGS with our decaffeinated brand. We'll then manually
* load our EFLAGS copy with the real verion after the step.
@@ -646,12 +643,12 @@ kaif_call(uintptr_t funcva, uint_t argc, const uintptr_t argv[])
}
static void
-dump_crumb(kaif_crumb_t *krmp)
+dump_crumb(kdi_crumb_t *krmp)
{
- kaif_crumb_t krm;
+ kdi_crumb_t krm;
- if (mdb_vread(&krm, sizeof (kaif_crumb_t), (uintptr_t)krmp) !=
- sizeof (kaif_crumb_t)) {
+ if (mdb_vread(&krm, sizeof (kdi_crumb_t), (uintptr_t)krmp) !=
+ sizeof (kdi_crumb_t)) {
warn("failed to read crumb at %p", krmp);
return;
}
@@ -677,8 +674,8 @@ dump_crumbs(kaif_cpusave_t *save)
{
int i;
- for (i = KAIF_NCRUMBS; i > 0; i--) {
- uint_t idx = (save->krs_curcrumbidx + i) % KAIF_NCRUMBS;
+ for (i = KDI_NCRUMBS; i > 0; i--) {
+ uint_t idx = (save->krs_curcrumbidx + i) % KDI_NCRUMBS;
dump_crumb(&save->krs_crumbs[idx]);
}
}
@@ -690,7 +687,7 @@ kaif_dump_crumbs(uintptr_t addr, int cpuid)
if (addr != NULL) {
/* dump_crumb will protect us against bogus addresses */
- dump_crumb((kaif_crumb_t *)addr);
+ dump_crumb((kdi_crumb_t *)addr);
} else if (cpuid != -1) {
if (cpuid < 0 || cpuid >= kaif_ncpusave)
@@ -727,101 +724,32 @@ kaif_modchg_cancel(void)
kaif_modchg_cb = NULL;
}
-void
-kaif_mod_loaded(struct modctl *modp)
-{
- if (kaif_modchg_cb != NULL)
- kaif_modchg_cb(modp, 1);
-}
-
-void
-kaif_mod_unloading(struct modctl *modp)
-{
- if (kaif_modchg_cb != NULL)
- kaif_modchg_cb(modp, 0);
-}
-
-/*
- * On some processors, we'll need to clear a certain MSR before proceeding into
- * the debugger. Complicating matters, this MSR must be cleared before we take
- * any branches. We have patch points in every trap handler, which will cover
- * all entry paths for master CPUs. We also have a patch point in the slave
- * entry code.
- */
static void
-kaif_msr_add_clrentry(uint_t msr)
+kaif_msr_add(const kdi_msr_t *msrs)
{
-#ifdef __amd64
- uchar_t code[] = {
- 0x51, 0x50, 0x52, /* pushq %rcx, %rax, %rdx */
- 0xb9, 0x00, 0x00, 0x00, 0x00, /* movl $MSRNUM, %ecx */
- 0x31, 0xc0, /* clr %eax */
- 0x31, 0xd2, /* clr %edx */
- 0x0f, 0x30, /* wrmsr */
- 0x5a, 0x58, 0x59 /* popq %rdx, %rax, %rcx */
- };
- uchar_t *patch = &code[4];
-#else
- uchar_t code[] = {
- 0x60, /* pushal */
- 0xb9, 0x00, 0x00, 0x00, 0x00, /* movl $MSRNUM, %ecx */
- 0x31, 0xc0, /* clr %eax */
- 0x31, 0xd2, /* clr %edx */
- 0x0f, 0x30, /* wrmsr */
- 0x61 /* popal */
- };
- uchar_t *patch = &code[2];
-#endif
-
- bcopy(&msr, patch, sizeof (uint32_t));
-
- kaif_idt_patch((caddr_t)code, sizeof (code));
-
- bcopy(code, &kaif_slave_entry_patch, sizeof (code));
-}
-
-static void
-kaif_msr_add_wrexit(uint_t msr, uint64_t *valp)
-{
- kaif_msr_wrexit_msr = msr;
- kaif_msr_wrexit_valp = valp;
-}
-
-static void
-kaif_msr_add(const kmdb_msr_t *msrs)
-{
- kmdb_msr_t *save;
- int nmsrs, i;
-
- ASSERT(kaif_cpusave[0].krs_msr == NULL);
+ kdi_msr_t *save;
+ size_t nr_msrs = 0;
+ size_t i;
- for (i = 0; msrs[i].msr_num != 0; i++) {
- switch (msrs[i].msr_type) {
- case KMDB_MSR_CLEARENTRY:
- kaif_msr_add_clrentry(msrs[i].msr_num);
- break;
+ while (msrs[nr_msrs].msr_num != 0)
+ nr_msrs++;
+ /* we want to copy the terminating kdi_msr_t too */
+ nr_msrs++;
- case KMDB_MSR_WRITEDELAY:
- kaif_msr_add_wrexit(msrs[i].msr_num, msrs[i].msr_valp);
- break;
- }
- }
- nmsrs = i + 1; /* we want to copy the terminating kmdb_msr_t too */
-
- save = mdb_zalloc(sizeof (kmdb_msr_t) * nmsrs * kaif_ncpusave,
+ save = mdb_zalloc(sizeof (kdi_msr_t) * nr_msrs * kaif_ncpusave,
UM_SLEEP);
- for (i = 0; i < kaif_ncpusave; i++) {
- bcopy(msrs, &save[nmsrs * i], sizeof (kmdb_msr_t) * nmsrs);
- kaif_cpusave[i].krs_msr = &save[nmsrs * i];
- }
+ for (i = 0; i < kaif_ncpusave; i++)
+ bcopy(msrs, &save[nr_msrs * i], sizeof (kdi_msr_t) * nr_msrs);
+
+ kmdb_kdi_set_debug_msrs(save);
}
static uint64_t
kaif_msr_get(int cpuid, uint_t num)
{
- kaif_cpusave_t *save;
- kmdb_msr_t *msr;
+ kdi_cpusave_t *save;
+ kdi_msr_t *msr;
int i;
if ((save = kaif_cpuid2save(cpuid)) == NULL)
@@ -830,109 +758,115 @@ kaif_msr_get(int cpuid, uint_t num)
msr = save->krs_msr;
for (i = 0; msr[i].msr_num != 0; i++) {
- if (msr[i].msr_num == num &&
- (msr[i].msr_type & KMDB_MSR_READ))
- return (msr[i].msr_val);
+ if (msr[i].msr_num == num && (msr[i].msr_type & KDI_MSR_READ))
+ return (msr[i].kdi_msr_val);
}
return (0);
}
-int
-kaif_memrange_add(caddr_t base, size_t len)
+void
+kaif_trap_set_debugger(void)
{
- kaif_memrange_t *mr = &kaif_memranges[kaif_nmemranges];
+ kmdb_kdi_idt_switch(NULL);
+}
- if (kaif_nmemranges == KAIF_MEMRANGES_MAX)
- return (set_errno(ENOSPC));
+void
+kaif_trap_set_saved(kaif_cpusave_t *cpusave)
+{
+ kmdb_kdi_idt_switch(cpusave);
+}
+static void
+kaif_vmready(void)
+{
+}
+
+void
+kaif_memavail(caddr_t base, size_t len)
+{
+ int ret;
/*
* In the unlikely event that someone is stepping through this routine,
- * we need to make sure that kaif_memranges knows about the new range
- * before umem gets it. That way the entry code can recognize stacks
+ * we need to make sure that the KDI knows about the new range before
+ * umem gets it. That way the entry code can recognize stacks
* allocated from the new region.
*/
- mr->mr_base = base;
- mr->mr_lim = base + len - 1;
- kaif_nmemranges++;
+ kmdb_kdi_memrange_add(base, len);
+ ret = mdb_umem_add(base, len);
+ ASSERT(ret == 0);
+}
- if (mdb_umem_add(base, len) < 0) {
- kaif_nmemranges--;
- return (-1); /* errno is set for us */
- }
+void
+kaif_mod_loaded(struct modctl *modp)
+{
+ if (kaif_modchg_cb != NULL)
+ kaif_modchg_cb(modp, 1);
+}
- return (0);
+void
+kaif_mod_unloading(struct modctl *modp)
+{
+ if (kaif_modchg_cb != NULL)
+ kaif_modchg_cb(modp, 0);
}
void
-kaif_trap_set_debugger(void)
+kaif_handle_fault(greg_t trapno, greg_t pc, greg_t sp, int cpuid)
+{
+ kmdb_dpi_handle_fault((kreg_t)trapno, (kreg_t)pc,
+ (kreg_t)sp, cpuid);
+}
+
+static kdi_debugvec_t kaif_dvec = {
+ NULL, /* dv_kctl_vmready */
+ NULL, /* dv_kctl_memavail */
+ NULL, /* dv_kctl_modavail */
+ NULL, /* dv_kctl_thravail */
+ kaif_vmready,
+ kaif_memavail,
+ kaif_mod_loaded,
+ kaif_mod_unloading,
+ kaif_handle_fault
+};
+
+void
+kaif_kdi_entry(kdi_cpusave_t *cpusave)
{
- set_idt(&kaif_idtr);
+ int ret = kaif_main_loop(cpusave);
+ ASSERT(ret == KAIF_CPU_CMD_RESUME ||
+ ret == KAIF_CPU_CMD_RESUME_MASTER);
}
+/*ARGSUSED*/
void
-kaif_trap_set_saved(kaif_cpusave_t *cpusave)
+kaif_activate(kdi_debugvec_t **dvecp, uint_t flags)
{
- set_idt(&cpusave->krs_idtr);
+ kmdb_kdi_activate(kaif_kdi_entry, kaif_cpusave, kaif_ncpusave);
+ *dvecp = &kaif_dvec;
}
static int
kaif_init(kmdb_auxv_t *kav)
{
- int i;
-
/* Allocate the per-CPU save areas */
kaif_cpusave = mdb_zalloc(sizeof (kaif_cpusave_t) * kav->kav_ncpu,
UM_SLEEP);
kaif_ncpusave = kav->kav_ncpu;
- for (i = 0; i < kaif_ncpusave; i++) {
- kaif_cpusave_t *save = &kaif_cpusave[i];
-
- save->krs_cpu_id = i;
- save->krs_curcrumbidx = KAIF_NCRUMBS - 1;
- save->krs_curcrumb = &save->krs_crumbs[save->krs_curcrumbidx];
- }
-
- kaif_idt_init();
-
- /* The initial selector set. Updated by the debugger-entry code */
-#ifndef __amd64
- kaif_cs = BOOTCODE_SEL;
- kaif_ds = kaif_fs = kaif_gs = BOOTFLAT_SEL;
-#endif
-
- kaif_memranges[0].mr_base = kav->kav_dseg;
- kaif_memranges[0].mr_lim = kav->kav_dseg + kav->kav_dseg_size - 1;
- kaif_nmemranges = 1;
-
kaif_modchg_cb = NULL;
kaif_waptmap = 0;
- kaif_drreg.dr_ctl = KREG_DRCTL_RESERVED;
- kaif_drreg.dr_stat = KREG_DRSTAT_RESERVED;
-
- kaif_msr_wrexit_msr = 0;
- kaif_msr_wrexit_valp = NULL;
-
kaif_trap_switch = (kav->kav_flags & KMDB_AUXV_FL_NOTRPSWTCH) == 0;
- if ((kaif_sys_sysenter = kmdb_kdi_lookup_by_name("unix",
- "sys_sysenter")) == NULL)
- return (set_errno(ENOENT));
-
- if ((kaif_brand_sys_sysenter = kmdb_kdi_lookup_by_name("unix",
- "brand_sys_sysenter")) == NULL)
- return (set_errno(ENOENT));
-
return (0);
}
dpi_ops_t kmdb_dpi_ops = {
kaif_init,
kaif_activate,
- kaif_deactivate,
+ kmdb_kdi_deactivate,
kaif_enter_mon,
kaif_modchg_register,
kaif_modchg_cancel,
@@ -953,7 +887,6 @@ dpi_ops_t kmdb_dpi_ops = {
kaif_step_branch,
kaif_call,
kaif_dump_crumbs,
- kaif_memrange_add,
kaif_msr_add,
kaif_msr_get,
};
diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif.h b/usr/src/cmd/mdb/intel/kmdb/kaif.h
index c5392e7889..a7af3a6911 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kaif.h
+++ b/usr/src/cmd/mdb/intel/kmdb/kaif.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,84 +32,32 @@
#include <sys/kdi.h>
#include <sys/types.h>
#include <sys/segments.h>
-#include <kmdb/kaif_regs.h>
+#include <sys/kdi_machimpl.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
-#define KAIF_MASTER_CPUID_UNSET -1
+typedef kdi_cpusave_t kaif_cpusave_t;
-#define KAIF_CPU_CMD_RESUME 0
-#define KAIF_CPU_CMD_RESUME_MASTER 1
-#define KAIF_CPU_CMD_SWITCH 2
-#define KAIF_CPU_CMD_PASS_TO_KERNEL 3
-#define KAIF_CPU_CMD_REBOOT 4
-
-#define KAIF_CPU_STATE_NONE 0
-#define KAIF_CPU_STATE_MASTER 1
-#define KAIF_CPU_STATE_SLAVE 2
+#define KAIF_CPU_STATE_NONE KDI_CPU_STATE_NONE
+#define KAIF_CPU_STATE_MASTER KDI_CPU_STATE_MASTER
+#define KAIF_CPU_STATE_SLAVE KDI_CPU_STATE_SLAVE
#ifndef _ASM
-typedef struct kaif_memrange {
- caddr_t mr_base;
- caddr_t mr_lim;
-} kaif_memrange_t;
-
-extern kaif_memrange_t kaif_memranges[];
-extern int kaif_nmemranges;
-
-extern kaif_cpusave_t *kaif_cpusave;
+extern kdi_cpusave_t *kaif_cpusave;
extern int kaif_ncpusave;
extern int kaif_master_cpuid;
-extern uint32_t kaif_cs;
-extern uint32_t kaif_ds;
-extern uint32_t kaif_fs;
-extern uint32_t kaif_gs;
-
-extern char kaif_slave_entry_patch;
-
-extern struct gate_desc kaif_idt[];
-extern desctbr_t kaif_idtr;
-extern size_t kaif_ivct_size;
extern int kaif_trap_switch;
-extern uintptr_t kaif_kernel_handler;
-extern uintptr_t kaif_sys_sysenter;
-extern uintptr_t kaif_brand_sys_sysenter;
-
extern void kaif_trap_set_debugger(void);
-extern void kaif_trap_set_saved(kaif_cpusave_t *);
+extern void kaif_trap_set_saved(kdi_cpusave_t *);
extern uintptr_t kaif_invoke(uintptr_t, uint_t, const uintptr_t[]);
-extern void kaif_nmiint(void);
-extern void kaif_cmnint(void);
-extern void kaif_enter(void);
-extern void kaif_slave_entry(void);
-extern int kaif_debugger_entry(kaif_cpusave_t *);
-
-extern void kaif_mod_loaded(struct modctl *);
-extern void kaif_mod_unloading(struct modctl *);
-
-extern void kaif_cpu_debug_init(kaif_cpusave_t *);
-
-extern void kaif_idt_init(void);
-extern void kaif_idt_write(gate_desc_t *, uint_t);
-extern void kaif_idt_patch(caddr_t, size_t);
-extern uintptr_t kaif_kernel_trap2hdlr(int);
-
-extern void kaif_activate(kdi_debugvec_t **, uint_t);
-extern void kaif_deactivate(void);
-
-extern int kaif_memrange_add(caddr_t, size_t);
-
-extern void get_idt(desctbr_t *);
-extern void set_idt(desctbr_t *);
-
#endif
#ifdef __cplusplus
diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif_idt.c b/usr/src/cmd/mdb/intel/kmdb/kaif_idt.c
deleted file mode 100644
index 43e218e1a6..0000000000
--- a/usr/src/cmd/mdb/intel/kmdb/kaif_idt.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * kmdb's IDT
- */
-
-#include <sys/types.h>
-#include <sys/segments.h>
-#include <sys/trap.h>
-#include <strings.h>
-
-#include <kmdb/kaif.h>
-#include <mdb/mdb_debug.h>
-#include <kmdb/kaif_asmutil.h>
-
-#if defined(__amd64)
-#define KMDBCODE_SEL B64CODE_SEL
-#else
-#define KMDBCODE_SEL BOOTCODE_SEL
-#endif
-
-typedef void idt_hdlr_f(void);
-
-extern idt_hdlr_f kaif_trap0, kaif_trap1, kaif_int2, kaif_trap3, kaif_trap4;
-extern idt_hdlr_f kaif_trap5, kaif_trap6, kaif_trap7, kaif_traperr8, kaif_trap9;
-extern idt_hdlr_f kaif_traperr10, kaif_traperr11, kaif_traperr12;
-extern idt_hdlr_f kaif_traperr13, kaif_traperr14, kaif_trap16, kaif_trap17;
-extern idt_hdlr_f kaif_trap18, kaif_trap19, kaif_trap20, kaif_ivct32;
-extern idt_hdlr_f kaif_invaltrap;
-
-gate_desc_t kaif_idt[NIDT];
-desctbr_t kaif_idtr;
-
-struct idt_description {
- uint_t id_low;
- uint_t id_high;
- idt_hdlr_f *id_basehdlr;
- size_t *id_incrp;
- uint_t id_type;
-} idt_description[] = {
- { T_ZERODIV, 0, kaif_trap0, NULL, SDT_SYSIGT },
- { T_SGLSTP, 0, kaif_trap1, NULL, SDT_SYSIGT },
- { T_NMIFLT, 0, kaif_int2, NULL, SDT_SYSIGT },
- { T_BPTFLT, 0, kaif_trap3, NULL, SDT_SYSIGT },
- { T_OVFLW, 0, kaif_trap4, NULL, SDT_SYSIGT },
- { T_BOUNDFLT, 0, kaif_trap5, NULL, SDT_SYSIGT },
- { T_ILLINST, 0, kaif_trap6, NULL, SDT_SYSIGT },
- { T_NOEXTFLT, 0, kaif_trap7, NULL, SDT_SYSIGT },
- { T_DBLFLT, 0, kaif_traperr8, NULL, SDT_SYSIGT },
- { T_EXTOVRFLT, 0, kaif_trap9, NULL, SDT_SYSIGT },
- { T_TSSFLT, 0, kaif_traperr10, NULL, SDT_SYSIGT },
- { T_SEGFLT, 0, kaif_traperr11, NULL, SDT_SYSIGT },
- { T_STKFLT, 0, kaif_traperr12, NULL, SDT_SYSIGT },
- { T_GPFLT, 0, kaif_traperr13, NULL, SDT_SYSIGT },
- { T_PGFLT, 0, kaif_traperr14, NULL, SDT_SYSIGT },
- { 15, 0, kaif_invaltrap, NULL, SDT_SYSIGT },
- { T_EXTERRFLT, 0, kaif_trap16, NULL, SDT_SYSIGT },
- { T_ALIGNMENT, 0, kaif_trap17, NULL, SDT_SYSIGT },
- { T_MCE, 0, kaif_trap18, NULL, SDT_SYSIGT },
- { T_SIMDFPE, 0, kaif_trap19, NULL, SDT_SYSIGT },
- { T_DBGENTR, 0, kaif_trap20, NULL, SDT_SYSIGT },
- { 21, 31, kaif_invaltrap, NULL, SDT_SYSIGT },
- { 32, 255, kaif_ivct32, &kaif_ivct_size, SDT_SYSIGT },
- { 0, 0, NULL },
-};
-
-static void
-kaif_set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel,
- uint_t type)
-{
- bzero(dp, sizeof (gate_desc_t));
-
- dp->sgd_looffset = ((uintptr_t)func) & 0xffff;
- dp->sgd_hioffset = ((uintptr_t)func >> 16) & 0xffff;
-#ifdef __amd64
- dp->sgd_hi64offset = (uintptr_t)func >> 32;
-#endif
-
- dp->sgd_selector = (uint16_t)sel;
- dp->sgd_type = type;
- dp->sgd_dpl = SEL_KPL;
- dp->sgd_p = 1;
-
-#ifdef __amd64
- dp->sgd_ist = 0;
-#else
- dp->sgd_stkcpy = 0;
-#endif
-}
-
-void
-kaif_idt_init(void)
-{
- struct idt_description *id;
- int i;
-
- for (id = idt_description; id->id_basehdlr != NULL; id++) {
- uint_t high = id->id_high != 0 ? id->id_high : id->id_low;
- size_t incr = id->id_incrp != NULL ? *id->id_incrp : 0;
-
- for (i = id->id_low; i <= high; i++) {
- caddr_t hdlr = (caddr_t)id->id_basehdlr +
- incr * (i - id->id_low);
- kaif_set_gatesegd(&kaif_idt[i], (void (*)(void))hdlr,
- KMDBCODE_SEL, id->id_type);
- }
- }
-
- kaif_idtr.dtr_limit = sizeof (kaif_idt) - 1;
- kaif_idtr.dtr_base = (uint64_t)kaif_idt;
-}
-
-/*
- * Patch caller-provided code into the debugger's IDT handlers. This code is
- * used to save MSRs that must be saved before the first branch. All handlers
- * are essentially the same, and end with a branch to kaif_cmnint. To save the
- * MSR, we need to patch in before the branch. The handlers have the following
- * structure: KAIF_MSR_PATCHOFF bytes of code, KAIF_MSR_PATCHSZ bytes of
- * patchable space, followed by more code.
- */
-void
-kaif_idt_patch(caddr_t code, size_t sz)
-{
- int i;
-
- ASSERT(sz <= KAIF_MSR_PATCHSZ);
-
- for (i = 0; i < sizeof (kaif_idt) / sizeof (struct gate_desc); i++) {
- gate_desc_t *gd;
- uchar_t *patch;
-
- if (i == T_DBLFLT)
- continue; /* uses kernel's handler */
-
- gd = &kaif_idt[i];
- patch = (uchar_t *)GATESEG_GETOFFSET(gd) + KAIF_MSR_PATCHOFF;
-
- /*
- * We can't ASSERT that there's a nop here, because this may be
- * a debugger restart. In that case, we're copying the new
- * patch point over the old one.
- */
- bcopy(code, patch, sz);
-
- /* Fill the rest with nops to be sure */
- while (sz < KAIF_MSR_PATCHSZ)
- patch[sz++] = 0x90; /* nop */
- }
-}
-
-void
-kaif_idt_write(gate_desc_t *gate, uint_t vec)
-{
- kaif_idt[vec] = *gate;
-}
diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif_regs.h b/usr/src/cmd/mdb/intel/kmdb/kaif_regs.h
deleted file mode 100644
index 9d5b64a240..0000000000
--- a/usr/src/cmd/mdb/intel/kmdb/kaif_regs.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _KAIF_REGS_H
-#define _KAIF_REGS_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifndef _ASM
-#include <sys/types.h>
-#include <sys/segments.h>
-
-#include <mdb/mdb_kreg_impl.h>
-#include <mdb/mdb_target.h>
-#include <kmdb/kmdb_dpi.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define KAIF_NCRUMBS 5
-
-#ifndef _ASM
-
-/*
- * We maintain a ring buffer of bread crumbs for debugging purposes. The
- * current buffer pointer is advanced along the ring with each intercepted
- * trap (debugger entry, invalid memory access, fault during step, etc).
- * The macros used to populate the crumb buffers assume that all members are
- * 32 bits wide.
- */
-typedef struct kaif_crumb {
- kreg_t krm_cpu_state; /* This CPU's state at last entry */
- kreg_t krm_pc; /* Instruction pointer at trap */
- kreg_t krm_sp; /* Stack pointer at trap */
- kreg_t krm_trapno; /* The last trap number */
- kreg_t krm_flag; /* KAIF_CRUMB_F_* */
-} kaif_crumb_t;
-
-/*
- * Storage for %dr0-3, %dr6, and %dr7.
- */
-typedef struct kaif_drreg {
- kreg_t dr_ctl;
- kreg_t dr_stat;
- kreg_t dr_addr[KREG_MAXWPIDX + 1];
-} kaif_drreg_t;
-
-/*
- * Data structure used to hold all of the state for a given CPU.
- */
-typedef struct kaif_cpusave {
- mdb_tgt_gregset_t *krs_gregs; /* saved registers */
-
- kaif_drreg_t krs_dr; /* saved debug registers */
-
- desctbr_t krs_gdtr; /* saved GDT register */
- desctbr_t krs_idtr; /* saved IDT register */
- desctbr_t krs_tmpdesc; /* pre-save *DT comparisons */
-
- kreg_t krs_cr0; /* saved %cr0 */
-
- kmdb_msr_t *krs_msr; /* ptr to MSR save area */
-
- uint_t krs_cpu_state; /* KAIF_CPU_STATE_* mstr/slv */
- uint_t krs_cpu_flushed; /* Have caches been flushed? */
- uint_t krs_cpu_id; /* this CPU's ID */
-
- /* Bread crumb ring buffer */
- ulong_t krs_curcrumbidx; /* Current krs_crumbs idx */
- kaif_crumb_t *krs_curcrumb; /* Pointer to current crumb */
- kaif_crumb_t krs_crumbs[KAIF_NCRUMBS]; /* Crumbs */
-} kaif_cpusave_t;
-
-#endif /* !_ASM */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _KAIF_REGS_H */
diff --git a/usr/src/cmd/mdb/intel/kmdb/kctl/kctl_isadep.c b/usr/src/cmd/mdb/intel/kmdb/kctl/kctl_isadep.c
index 542b5b69e1..44b2248755 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kctl/kctl_isadep.c
+++ b/usr/src/cmd/mdb/intel/kmdb/kctl/kctl_isadep.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,16 +38,11 @@
#include <sys/controlregs.h>
#include <sys/archsystm.h>
-#if defined(__i386)
-/* Copied from stand/i386/sys/bootdef.h */
-#define GS_GDT 0x38 /* dummy cpu_t pointer descriptor */
-#endif
-
static int
kctl_boot_prop_read(char *pname, char *prop_buf, int buf_len)
{
- int len;
struct bootops *ops = kctl.kctl_boot_ops;
+ int len;
len = BOP_GETPROPLEN(ops, pname);
if (len > 0 && len <= buf_len) {
@@ -144,12 +139,6 @@ kctl_pcache_destroy(kmdb_auxv_nv_t *pnv)
kobj_free(pnv, sizeof (kmdb_auxv_nv_t) * KCTL_PROPNV_NENT);
}
-/*ARGSUSED*/
-static void
-kctl_cpu_init(void)
-{
-}
-
void
kctl_auxv_init_isadep(kmdb_auxv_t *kav, void *romp)
{
@@ -171,16 +160,13 @@ kctl_preactivate_isadep(void)
}
/*ARGSUSED*/
-int
+void
kctl_activate_isadep(kdi_debugvec_t *dvec)
{
- dvec->dv_kctl_cpu_init = kctl_cpu_init;
dvec->dv_kctl_vmready = hat_kdi_init;
if (!kctl.kctl_boot_loaded)
hat_kdi_init();
-
- return (0);
}
void
@@ -188,64 +174,20 @@ kctl_depreactivate_isadep(void)
{
}
-void
-kctl_deactivate_isadep(void)
-{
- hat_kdi_fini();
-}
-
-#if defined(__amd64)
-void *
-kctl_boot_tmpinit(void)
-{
- /*
- * Many common kernel functions assume that GSBASE has been initialized,
- * and fail horribly if it hasn't. We'll install a pointer to a dummy
- * cpu_t for use during our initialization.
- */
- cpu_t *old = (cpu_t *)rdmsr(MSR_AMD_GSBASE);
-
- wrmsr(MSR_AMD_GSBASE, (uint64_t)kobj_zalloc(sizeof (cpu_t), KM_TMP));
- return (old);
-}
-
-void
-kctl_boot_tmpfini(void *old)
-{
- wrmsr(MSR_AMD_GSBASE, (uint64_t)old);
-}
-
-#else
-
+/*
+ * Many common kernel functions assume that %gs can be deferenced, and
+ * fail horribly if it cannot. Ask the kernel to set up a temporary
+ * mapping to a fake cpu_t so that we can call such functions during
+ * initialization.
+ */
void *
kctl_boot_tmpinit(void)
{
- /*
- * Many common kernel functions assume that %gs has been initialized,
- * and fail horribly if it hasn't. Boot has reserved a descriptor for
- * us (GS_GDT) in its GDT, a descriptor which we'll use to describe our
- * dummy cpu_t. We then set %gs to refer to this descriptor.
- */
- cpu_t *cpu = kobj_zalloc(sizeof (cpu_t), KM_TMP);
- uintptr_t old;
- desctbr_t bgdt;
- user_desc_t *gsdesc;
-
- rd_gdtr(&bgdt);
- gsdesc = (user_desc_t *)(bgdt.dtr_base + GS_GDT);
-
- USEGD_SETBASE(gsdesc, (uintptr_t)cpu);
- USEGD_SETLIMIT(gsdesc, sizeof (cpu_t));
-
- old = getgs();
- setgs(GS_GDT);
-
- return ((void *)old);
+ return (boot_kdi_tmpinit());
}
void
kctl_boot_tmpfini(void *old)
{
- setgs((uintptr_t)old);
+ boot_kdi_tmpfini(old);
}
-#endif
diff --git a/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.c b/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.c
index f5b7a3a679..719e36b8dc 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.c
+++ b/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -145,7 +144,7 @@ kmdb_dpi_reboot(void)
}
void
-kmdb_dpi_msr_add(const kmdb_msr_t *msrs)
+kmdb_dpi_msr_add(const kdi_msr_t *msrs)
{
mdb.m_dpi->dpo_msr_add(msrs);
}
diff --git a/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.h b/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.h
index 952960060f..2565c1f843 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.h
+++ b/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,36 +30,20 @@
#ifndef _ASM
#include <mdb/mdb_isautil.h>
+#include <sys/kdi_machimpl.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
-#define KMDB_MSR_READ 0x1 /* read during entry (unlimited) */
-#define KMDB_MSR_WRITE 0x2 /* write during exit (unlimited) */
-#define KMDB_MSR_WRITEDELAY 0x4 /* write after last branch (<= 1) */
-#define KMDB_MSR_CLEARENTRY 0x3 /* clear before 1st branch (<= 1) */
-
#ifndef _ASM
-typedef struct kmdb_msr {
- uint_t msr_num;
- uint_t msr_type;
- union {
- uint64_t *_msr_valp;
- uint64_t _msr_val;
- } _u;
-} kmdb_msr_t;
-
-#define msr_val _u._msr_val
-#define msr_valp _u._msr_valp
-
extern void kmdb_dpi_handle_fault(kreg_t, kreg_t, kreg_t, int);
extern void kmdb_dpi_reboot(void) __NORETURN;
-extern void kmdb_dpi_msr_add(const kmdb_msr_t *);
+extern void kmdb_dpi_msr_add(const kdi_msr_t *);
extern uint64_t kmdb_dpi_msr_get(uint_t);
extern uint64_t kmdb_dpi_msr_get_by_cpu(int, uint_t);
diff --git a/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.c b/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.c
index ef001fff68..a556c90041 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.c
+++ b/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,30 +34,26 @@
#include <mdb/mdb_err.h>
#include <mdb/mdb_umem.h>
#include <kmdb/kmdb_dpi.h>
-#include <kmdb/kmdb_kdi_impl.h>
#include <mdb/mdb.h>
-void (**kmdb_kdi_shutdownp)(int, int);
-
-int
-kmdb_kdi_xc_initialized(void)
+/*ARGSUSED*/
+void
+kmdb_kdi_stop_slaves(int my_cpuid, int doxc)
{
- return (mdb.m_kdi->mkdi_xc_initialized());
+ /* Stop other CPUs if there are CPUs to stop */
+ mdb.m_kdi->mkdi_stop_slaves(my_cpuid, doxc);
}
-/*ARGSUSED*/
void
-kmdb_kdi_stop_other_cpus(int my_cpuid, void (*slave_saver)(void))
+kmdb_kdi_start_slaves(void)
{
- /* Stop other CPUs if there are CPUs to stop */
- if (mdb.m_kdi->mkdi_xc_initialized())
- mdb.m_kdi->mkdi_xc_others(my_cpuid, slave_saver);
+ mdb.m_kdi->mkdi_start_slaves();
}
void
-kmdb_kdi_cpu_iter(void (*iter)(struct cpu *, uint_t), uint_t arg)
+kmdb_kdi_slave_wait(void)
{
- mdb.m_kdi->mkdi_cpu_iter(iter, arg);
+ mdb.m_kdi->mkdi_slave_wait();
}
uintptr_t
@@ -67,51 +62,61 @@ kmdb_kdi_get_userlimit(void)
return (mdb.m_kdi->mkdi_get_userlimit());
}
-void
-kmdb_kdi_idt_init_gate(gate_desc_t *gate, void (*hdlr)(void), uint_t dpl,
- int useboot)
+int
+kmdb_kdi_get_cpuinfo(uint_t *vendorp, uint_t *familyp, uint_t *modelp)
{
- mdb.m_kdi->mkdi_idt_init_gate(gate, hdlr, dpl, useboot);
+ int err;
+
+ if ((err = mdb.m_kdi->mkdi_get_cpuinfo(vendorp, familyp, modelp)) != 0)
+ return (set_errno(err));
+
+ return (0);
}
+/*ARGSUSED*/
void
-kmdb_kdi_idt_read(gate_desc_t *idt, gate_desc_t *gatep, uint_t vec)
+kmdb_kdi_init_isadep(kdi_t *kdi, kmdb_auxv_t *kav)
{
- mdb.m_kdi->mkdi_idt_read(idt, gatep, vec);
}
void
-kmdb_kdi_idt_write(gate_desc_t *idt, gate_desc_t *gate, uint_t vec)
+kmdb_kdi_activate(kdi_main_t main, kdi_cpusave_t *cpusave, int ncpusave)
{
- mdb.m_kdi->mkdi_idt_write(idt, gate, vec);
+ mdb.m_kdi->mkdi_activate(main, cpusave, ncpusave);
}
-gate_desc_t *
-kmdb_kdi_cpu2idt(cpu_t *cp)
+void
+kmdb_kdi_deactivate(void)
{
- return (mdb.m_kdi->mkdi_cpu2idt(cp));
+ mdb.m_kdi->mkdi_deactivate();
}
-int
-kmdb_kdi_get_cpuinfo(uint_t *vendorp, uint_t *familyp, uint_t *modelp)
+void
+kmdb_kdi_idt_switch(kdi_cpusave_t *cpusave)
{
- int err;
+ mdb.m_kdi->mkdi_idt_switch(cpusave);
+}
- if ((err = mdb.m_kdi->mkdi_get_cpuinfo(vendorp, familyp, modelp)) != 0)
- return (set_errno(err));
+void
+kmdb_kdi_update_drreg(kdi_drreg_t *drreg)
+{
+ mdb.m_kdi->mkdi_update_drreg(drreg);
+}
- return (0);
+void
+kmdb_kdi_set_debug_msrs(kdi_msr_t *msrs)
+{
+ mdb.m_kdi->mkdi_set_debug_msrs(msrs);
}
-/*ARGSUSED*/
void
-kdi_cpu_init(void)
+kmdb_kdi_memrange_add(caddr_t base, size_t len)
{
+ mdb.m_kdi->mkdi_memrange_add(base, len);
}
-/*ARGSUSED1*/
void
-kmdb_kdi_init_isadep(kdi_t *kdi, kmdb_auxv_t *kav)
+kmdb_kdi_reboot(void)
{
- kmdb_kdi_shutdownp = kdi->mkdi_shutdownp;
+ mdb.m_kdi->mkdi_reboot();
}
diff --git a/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.h b/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.h
index 6807a4809c..1813b382e3 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.h
+++ b/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,6 +29,7 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/types.h>
+#include <sys/kdi_machimpl.h>
#include <mdb/mdb_target.h>
@@ -39,24 +39,21 @@ extern "C" {
struct gate_desc;
-extern void (**kdi_shutdownp)(int, int);
+extern void kmdb_kdi_activate(kdi_main_t, kdi_cpusave_t *, int);
+extern void kmdb_kdi_deactivate(void);
-extern uintptr_t kmdb_kdi_get_userlimit(void);
-extern int kmdb_kdi_xc_initialized(void);
+extern void kmdb_kdi_idt_switch(kdi_cpusave_t *);
+
+extern void kmdb_kdi_update_drreg(kdi_drreg_t *);
+extern void kmdb_kdi_set_debug_msrs(kdi_msr_t *);
-extern void kmdb_kdi_idt_init_gate(struct gate_desc *, void (*)(void), uint_t,
- int);
-extern void kmdb_kdi_idt_read(struct gate_desc *, struct gate_desc *, uint_t);
-extern void kmdb_kdi_idt_write(struct gate_desc *, struct gate_desc *, uint_t);
-extern struct gate_desc *kmdb_kdi_cpu2idt(struct cpu *);
+extern uintptr_t kmdb_kdi_get_userlimit(void);
extern int kmdb_kdi_get_cpuinfo(uint_t *, uint_t *, uint_t *);
-/*
- * To be used only when the kernel is running
- */
-extern void kmdb_kdi_cpu_iter(void (*)(struct cpu *, uint_t),
- uint_t);
+extern void kmdb_kdi_memrange_add(caddr_t, size_t);
+
+extern void kmdb_kdi_reboot(void);
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_amd.c b/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_amd.c
index 7d05c02265..6b67853220 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_amd.c
+++ b/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_amd.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,7 +40,7 @@
typedef struct kmt_cpu_amd {
uint64_t amd_debugctl; /* value for debugctl MSR */
- const kmdb_msr_t *amd_msrs; /* MSR r/w list */
+ const kdi_msr_t *amd_msrs; /* MSR r/w list */
uint_t amd_family; /* CPUID family */
uint_t amd_model; /* CPUID model */
} kmt_cpu_amd_t;
@@ -72,22 +71,22 @@ kmt_amd_branch(uint_t cpuid, const char *label, uint_t msr)
* MSRs for AMD processors with simple branch tracing facilities. We'll use
* this array if we can access listed LBR/LEX MSRs.
*/
-static const kmdb_msr_t kmt_amd_msrs[] = {
- { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY },
- { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_amd.amd_debugctl },
- { MSR_LBR_TO, KMDB_MSR_READ },
- { MSR_LBR_FROM, KMDB_MSR_READ },
- { MSR_LEX_TO, KMDB_MSR_READ },
- { MSR_LEX_FROM, KMDB_MSR_READ },
+static const kdi_msr_t kmt_amd_msrs[] = {
+ { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY },
+ { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_amd.amd_debugctl },
+ { MSR_LBR_TO, KDI_MSR_READ },
+ { MSR_LBR_FROM, KDI_MSR_READ },
+ { MSR_LEX_TO, KDI_MSR_READ },
+ { MSR_LEX_FROM, KDI_MSR_READ },
{ NULL }
};
/*
* Fallback MSR list for use if we can't read the LBR/LEX MSRs.
*/
-static const kmdb_msr_t kmt_amdunk_msrs[] = {
- { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY },
- { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_amd.amd_debugctl },
+static const kdi_msr_t kmt_amdunk_msrs[] = {
+ { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY },
+ { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_amd.amd_debugctl },
{ NULL }
};
diff --git a/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_p4.c b/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_p4.c
index 39d5ea175a..653b4a31f5 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_p4.c
+++ b/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_p4.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -51,7 +50,7 @@
*/
typedef struct kmt_p4_flavor {
const char *p4f_name; /* name for CPU support */
- const kmdb_msr_t *p4f_msrs; /* MSR r/w list */
+ const kdi_msr_t *p4f_msrs; /* MSR r/w list */
int (*p4f_branches)(const struct kmt_p4_flavor *, uint_t,
intptr_t, int); /* dumper for CPU branch stk */
uint_t p4f_msr_tos; /* branch stk index MSR */
@@ -164,14 +163,14 @@ kmt_p4_branches_split(const kmt_p4_flavor_t *p4f, uint_t tos, intptr_t cpuid,
}
#ifndef __amd64
-static const kmdb_msr_t kmt_p4orig_msrs[] = {
- { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY },
- { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl },
- { MSR_P4_LBSTK_TOS, KMDB_MSR_READ },
- { MSR_P4_LBSTK_0, KMDB_MSR_READ },
- { MSR_P4_LBSTK_1, KMDB_MSR_READ },
- { MSR_P4_LBSTK_2, KMDB_MSR_READ },
- { MSR_P4_LBSTK_3, KMDB_MSR_READ },
+static const kdi_msr_t kmt_p4orig_msrs[] = {
+ { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY },
+ { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl },
+ { MSR_P4_LBSTK_TOS, KDI_MSR_READ },
+ { MSR_P4_LBSTK_0, KDI_MSR_READ },
+ { MSR_P4_LBSTK_1, KDI_MSR_READ },
+ { MSR_P4_LBSTK_2, KDI_MSR_READ },
+ { MSR_P4_LBSTK_3, KDI_MSR_READ },
{ NULL }
};
@@ -181,18 +180,18 @@ static const kmt_p4_flavor_t kmt_p4_original = {
MSR_P4_LBSTK_0, MSR_P4_LBSTK_0, 4
};
-static const kmdb_msr_t kmt_p6m_msrs[] = {
- { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY },
- { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl },
- { MSR_P6M_LBSTK_TOS, KMDB_MSR_READ },
- { MSR_P6M_LBSTK_0, KMDB_MSR_READ },
- { MSR_P6M_LBSTK_1, KMDB_MSR_READ },
- { MSR_P6M_LBSTK_2, KMDB_MSR_READ },
- { MSR_P6M_LBSTK_3, KMDB_MSR_READ },
- { MSR_P6M_LBSTK_4, KMDB_MSR_READ },
- { MSR_P6M_LBSTK_5, KMDB_MSR_READ },
- { MSR_P6M_LBSTK_6, KMDB_MSR_READ },
- { MSR_P6M_LBSTK_7, KMDB_MSR_READ },
+static const kdi_msr_t kmt_p6m_msrs[] = {
+ { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY },
+ { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl },
+ { MSR_P6M_LBSTK_TOS, KDI_MSR_READ },
+ { MSR_P6M_LBSTK_0, KDI_MSR_READ },
+ { MSR_P6M_LBSTK_1, KDI_MSR_READ },
+ { MSR_P6M_LBSTK_2, KDI_MSR_READ },
+ { MSR_P6M_LBSTK_3, KDI_MSR_READ },
+ { MSR_P6M_LBSTK_4, KDI_MSR_READ },
+ { MSR_P6M_LBSTK_5, KDI_MSR_READ },
+ { MSR_P6M_LBSTK_6, KDI_MSR_READ },
+ { MSR_P6M_LBSTK_7, KDI_MSR_READ },
{ NULL }
};
@@ -203,42 +202,42 @@ static const kmt_p4_flavor_t kmt_p6_m = {
};
#endif /* __amd64 */
-static const kmdb_msr_t kmt_prp4_msrs[] = {
- { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY },
- { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl },
- { MSR_PRP4_LBSTK_TOS, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_0, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_1, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_2, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_3, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_4, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_5, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_6, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_7, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_8, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_9, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_10, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_11, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_12, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_13, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_14, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_FROM_15, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_0, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_1, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_2, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_3, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_4, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_5, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_6, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_7, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_8, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_9, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_10, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_11, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_12, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_13, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_14, KMDB_MSR_READ },
- { MSR_PRP4_LBSTK_TO_15, KMDB_MSR_READ },
+static const kdi_msr_t kmt_prp4_msrs[] = {
+ { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY },
+ { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl },
+ { MSR_PRP4_LBSTK_TOS, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_0, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_1, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_2, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_3, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_4, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_5, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_6, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_7, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_8, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_9, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_10, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_11, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_12, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_13, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_14, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_FROM_15, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_0, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_1, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_2, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_3, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_4, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_5, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_6, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_7, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_8, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_9, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_10, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_11, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_12, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_13, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_14, KDI_MSR_READ },
+ { MSR_PRP4_LBSTK_TO_15, KDI_MSR_READ },
{ NULL }
};
@@ -248,9 +247,9 @@ static const kmt_p4_flavor_t kmt_p4_prescott = {
MSR_PRP4_LBSTK_FROM_0, MSR_PRP4_LBSTK_TO_0, 16
};
-static const kmdb_msr_t kmt_p4unk_msrs[] = {
- { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY },
- { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl },
+static const kdi_msr_t kmt_p4unk_msrs[] = {
+ { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY },
+ { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl },
{ NULL }
};
diff --git a/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.c b/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.c
index e80b2243ef..3f32502080 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.c
+++ b/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -377,7 +377,7 @@ kmt_wrmsr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
}
int
-kmt_msr_validate(const kmdb_msr_t *msr)
+kmt_msr_validate(const kdi_msr_t *msr)
{
uint64_t val;
diff --git a/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.h b/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.h
index d03ae5eafa..e944c6ca8b 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.h
+++ b/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,8 +45,7 @@ extern int kmt_wrmsr(uintptr_t, uint_t, int, const mdb_arg_t *);
extern int kmt_rdpcicfg(uintptr_t, uint_t, int, const mdb_arg_t *);
extern int kmt_wrpcicfg(uintptr_t, uint_t, int, const mdb_arg_t *);
-
-extern int kmt_msr_validate(const kmdb_msr_t *);
+extern int kmt_msr_validate(const kdi_msr_t *);
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c b/usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c
index a2f965f424..43468af924 100644
--- a/usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c
+++ b/usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -320,8 +319,6 @@ kt_amd64_init(mdb_tgt_t *t)
kregs[KREG_R13] = regs.r_r13;
kregs[KREG_R14] = regs.r_r14;
kregs[KREG_R15] = regs.r_r15;
- kregs[KREG_FSBASE] = regs.r_fsbase;
- kregs[KREG_GSBASE] = regs.r_gsbase;
kregs[KREG_DS] = regs.r_ds;
kregs[KREG_ES] = regs.r_es;
kregs[KREG_FS] = regs.r_fs;
diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c b/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c
index 93ab6bf92b..303923f236 100644
--- a/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c
+++ b/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -64,9 +64,6 @@ const mdb_tgt_regdesc_t mdb_amd64_kregs[] = {
{ "r13", KREG_R13, MDB_TGT_R_EXPORT },
{ "r14", KREG_R14, MDB_TGT_R_EXPORT },
{ "r15", KREG_R15, MDB_TGT_R_EXPORT },
- { "fsbase", KREG_FSBASE, MDB_TGT_R_EXPORT | MDB_TGT_R_PRIV },
- { "gsbase", KREG_GSBASE, MDB_TGT_R_EXPORT | MDB_TGT_R_PRIV },
- { "kgsbase", KREG_KGSBASE, MDB_TGT_R_EXPORT | MDB_TGT_R_PRIV },
{ "ds", KREG_DS, MDB_TGT_R_EXPORT },
{ "es", KREG_ES, MDB_TGT_R_EXPORT },
{ "fs", KREG_FS, MDB_TGT_R_EXPORT },
@@ -134,10 +131,10 @@ mdb_amd64_printregs(const mdb_tgt_gregset_t *gregs)
mdb_printf("%24s%%cs = 0x%04x\t%%ds = 0x%04x\t%%es = 0x%04x\n",
" ", kregs[KREG_CS], kregs[KREG_DS], kregs[KREG_ES]);
- mdb_printf("%%trapno = 0x%x\t\t%%fs = 0x%04x\tfsbase = 0x%0?p\n",
- kregs[KREG_TRAPNO], (kregs[KREG_FS] & 0xffff), kregs[KREG_FSBASE]);
- mdb_printf(" %%err = 0x%x\t\t%%gs = 0x%04x\tgsbase = 0x%0?p\n",
- kregs[KREG_ERR], (kregs[KREG_GS] & 0xffff), kregs[KREG_GSBASE]);
+ mdb_printf("%%trapno = 0x%x\t\t%%fs = 0x%04x\t%%gs = 0x%04x\n",
+ kregs[KREG_TRAPNO], (kregs[KREG_FS] & 0xffff),
+ (kregs[KREG_GS] & 0xffff));
+ mdb_printf(" %%err = 0x%x\n", kregs[KREG_ERR]);
}
diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_kreg.h b/usr/src/cmd/mdb/intel/mdb/mdb_kreg.h
index 3e7d79f462..4ba5fb567c 100644
--- a/usr/src/cmd/mdb/intel/mdb/mdb_kreg.h
+++ b/usr/src/cmd/mdb/intel/mdb/mdb_kreg.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,6 +28,7 @@
#pragma ident "%Z%%M% %I% %E% SMI"
+#include <sys/kdi_regs.h>
#ifndef _ASM
#include <sys/types.h>
#endif
@@ -37,51 +37,51 @@
extern "C" {
#endif
-#ifdef __amd64
-#define KREG_NGREG 31
#ifndef _ASM
+#ifdef __amd64
typedef uint64_t kreg_t;
-#endif /* !_ASM */
#else /* __amd64 */
-#define KREG_NGREG 21
-#ifndef _ASM
typedef uint32_t kreg_t;
-#endif /* !_ASM */
#endif /* __amd64 */
+#endif /* !_ASM */
+
+#define KREG_NGREG KDIREG_NGREG
+
+/*
+ * The order of these registers corresponds to a slightly altered struct regs,
+ * in the order kmdb entry pushes onto the stack.
+ */
#ifdef __amd64
-#define KREG_SAVFP 0
-#define KREG_SAVPC 1
-#define KREG_RDI 2
-#define KREG_RSI 3
-#define KREG_RDX 4
-#define KREG_RCX 5
-#define KREG_R8 6
-#define KREG_R9 7
-#define KREG_RAX 8
-#define KREG_RBX 9
-#define KREG_RBP 10
-#define KREG_R10 11
-#define KREG_R11 12
-#define KREG_R12 13
-#define KREG_R13 14
-#define KREG_R14 15
-#define KREG_R15 16
-#define KREG_FSBASE 17
-#define KREG_GSBASE 18
-#define KREG_KGSBASE 19
-#define KREG_DS 20
-#define KREG_ES 21
-#define KREG_FS 22
-#define KREG_GS 23
-#define KREG_TRAPNO 24
-#define KREG_ERR 25
-#define KREG_RIP 26
-#define KREG_CS 27
-#define KREG_RFLAGS 28
-#define KREG_RSP 29
-#define KREG_SS 30
+#define KREG_SAVFP KDIREG_SAVFP
+#define KREG_SAVPC KDIREG_SAVPC
+#define KREG_RDI KDIREG_RDI
+#define KREG_RSI KDIREG_RSI
+#define KREG_RDX KDIREG_RDX
+#define KREG_RCX KDIREG_RCX
+#define KREG_R8 KDIREG_R8
+#define KREG_R9 KDIREG_R9
+#define KREG_RAX KDIREG_RAX
+#define KREG_RBX KDIREG_RBX
+#define KREG_RBP KDIREG_RBP
+#define KREG_R10 KDIREG_R10
+#define KREG_R11 KDIREG_R11
+#define KREG_R12 KDIREG_R12
+#define KREG_R13 KDIREG_R13
+#define KREG_R14 KDIREG_R14
+#define KREG_R15 KDIREG_R15
+#define KREG_DS KDIREG_DS
+#define KREG_ES KDIREG_ES
+#define KREG_FS KDIREG_FS
+#define KREG_GS KDIREG_GS
+#define KREG_TRAPNO KDIREG_TRAPNO
+#define KREG_ERR KDIREG_ERR
+#define KREG_RIP KDIREG_RIP
+#define KREG_CS KDIREG_CS
+#define KREG_RFLAGS KDIREG_RFLAGS
+#define KREG_RSP KDIREG_RSP
+#define KREG_SS KDIREG_SS
#define KREG_PC KREG_RIP
#define KREG_SP KREG_RSP
@@ -89,33 +89,27 @@ typedef uint32_t kreg_t;
#else /* __amd64 */
-/*
- * The order of these registers corresponds to a slightly altered struct regs.
- * %ss appears first, and is followed by the remainder of the struct regs. This
- * change is necessary to support kmdb state saving.
- */
-
-#define KREG_SAVFP 0
-#define KREG_SAVPC 1
-#define KREG_SS 2
-#define KREG_GS 3
-#define KREG_FS 4
-#define KREG_ES 5
-#define KREG_DS 6
-#define KREG_EDI 7
-#define KREG_ESI 8
-#define KREG_EBP 9
-#define KREG_ESP 10
-#define KREG_EBX 11
-#define KREG_EDX 12
-#define KREG_ECX 13
-#define KREG_EAX 14
-#define KREG_TRAPNO 15
-#define KREG_ERR 16
-#define KREG_EIP 17
-#define KREG_CS 18
-#define KREG_EFLAGS 19
-#define KREG_UESP 20
+#define KREG_SAVFP KDIREG_SAVFP
+#define KREG_SAVPC KDIREG_SAVPC
+#define KREG_SS KDIREG_SS
+#define KREG_GS KDIREG_GS
+#define KREG_FS KDIREG_FS
+#define KREG_ES KDIREG_ES
+#define KREG_DS KDIREG_DS
+#define KREG_EDI KDIREG_EDI
+#define KREG_ESI KDIREG_ESI
+#define KREG_EBP KDIREG_EBP
+#define KREG_ESP KDIREG_ESP
+#define KREG_EBX KDIREG_EBX
+#define KREG_EDX KDIREG_EDX
+#define KREG_ECX KDIREG_ECX
+#define KREG_EAX KDIREG_EAX
+#define KREG_TRAPNO KDIREG_TRAPNO
+#define KREG_ERR KDIREG_ERR
+#define KREG_EIP KDIREG_EIP
+#define KREG_CS KDIREG_CS
+#define KREG_EFLAGS KDIREG_EFLAGS
+#define KREG_UESP KDIREG_UESP
#define KREG_PC KREG_EIP
#define KREG_SP KREG_ESP
@@ -174,8 +168,6 @@ typedef uint32_t kreg_t;
#define KREG_EFLAGS_CF_MASK 0x00000001
#define KREG_EFLAGS_CF_SHIFT 0
-#define KREG_MAXWPIDX 3
-
/* %dr7 */
#define KREG_DRCTL_WP_BASESHIFT 16
#define KREG_DRCTL_WP_INCRSHIFT 4
@@ -199,12 +191,6 @@ typedef uint32_t kreg_t;
(3 << (KREG_DRCTL_WPEN_INCRSHIFT * (n)))
#define KREG_DRCTL_WPEN(n) KREG_DRCTL_WPEN_MASK(n)
-#define KREG_DRCTL_WPALLEN_MASK 0x000000ff
-
-#define KREG_DRCTL_GD_MASK 0x00002000
-
-#define KREG_DRCTL_RESERVED 0x00000700
-
/* %dr6 */
#define KREG_DRSTAT_BT_MASK 0x00008000
#define KREG_DRSTAT_BS_MASK 0x00004000
@@ -212,8 +198,6 @@ typedef uint32_t kreg_t;
#define KREG_DRSTAT_WP_MASK(n) (1 << (n))
-#define KREG_DRSTAT_RESERVED 0xffff0ff0
-
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/mdb/sparc/kmdb/kaif.c b/usr/src/cmd/mdb/sparc/kmdb/kaif.c
index 92eaec51f1..729d1fdd1d 100644
--- a/usr/src/cmd/mdb/sparc/kmdb/kaif.c
+++ b/usr/src/cmd/mdb/sparc/kmdb/kaif.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -875,14 +875,6 @@ kaif_mod_unloading(struct modctl *modp)
kaif_modchg_cb(modp, 0);
}
-/*ARGSUSED*/
-int
-kaif_memrange_add(caddr_t base, size_t len)
-{
- /* We don't support multiple memory ranges on SPARC */
- return (set_errno(ENOTSUP));
-}
-
void
kaif_trap_set_debugger(void)
{
@@ -1017,6 +1009,5 @@ dpi_ops_t kmdb_dpi_ops = {
kaif_step,
kaif_call,
kaif_dump_crumbs,
- kaif_memrange_add,
kaif_kernpanic
};
diff --git a/usr/src/cmd/mdb/sparc/kmdb/kaif.h b/usr/src/cmd/mdb/sparc/kmdb/kaif.h
index 98d196192c..50445df8a3 100644
--- a/usr/src/cmd/mdb/sparc/kmdb/kaif.h
+++ b/usr/src/cmd/mdb/sparc/kmdb/kaif.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,16 +41,10 @@
extern "C" {
#endif
-#define KAIF_MASTER_CPUID_UNSET -1
-
#define KAIF_CPU_STATE_NONE 0
#define KAIF_CPU_STATE_MASTER 1
#define KAIF_CPU_STATE_SLAVE 2
-#define KAIF_CPU_CMD_RESUME 0
-#define KAIF_CPU_CMD_RESUME_MASTER 1
-#define KAIF_CPU_CMD_SWITCH 2
-
#define KAIF_LSUCTL_VWAPT_MASK (LSU_VM|LSU_VR|LSU_VW)
#define KAIF_LSUCTL_PWAPT_MASK (LSU_PM|LSU_PR|LSU_PW)
#define KAIF_LSUCTL_WAPT_MASK (LSU_PM|LSU_VM|LSU_PR|LSU_PW|LSU_VR|LSU_VW)
@@ -111,8 +105,6 @@ extern void kaif_slave_entry(void);
extern void kaif_prom_rearm(void);
extern void kaif_debugger_entry(kaif_cpusave_t *);
-extern int kaif_memrange_add(caddr_t, size_t);
-
extern void kaif_slave_loop_barrier(void);
#endif
diff --git a/usr/src/cmd/mdb/sparc/kmdb/kaif_activate.c b/usr/src/cmd/mdb/sparc/kmdb/kaif_activate.c
index a17431d53f..e7bcf7e68f 100644
--- a/usr/src/cmd/mdb/sparc/kmdb/kaif_activate.c
+++ b/usr/src/cmd/mdb/sparc/kmdb/kaif_activate.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -278,18 +278,17 @@ kaif_cpr_restart(void)
}
static kdi_debugvec_t kaif_dvec = {
- kaif_enter,
- kaif_cpu_init,
- NULL, /* dv_kctl_cpu_init */
- kaif_vmready,
NULL, /* dv_kctl_vmready */
NULL, /* dv_kctl_memavail */
- kaif_memrange_add,
- kaif_cpr_restart,
NULL, /* dv_kctl_modavail */
NULL, /* dv_kctl_thravail */
+ kaif_vmready,
+ NULL, /* dv_memavail */
kaif_mod_loaded,
- kaif_mod_unloading
+ kaif_mod_unloading,
+ NULL, /* dv_kctl_cpu_init */
+ kaif_cpu_init,
+ kaif_cpr_restart
};
/*ARGSUSED1*/
diff --git a/usr/src/cmd/mdb/sparc/kmdb/kctl/kctl_isadep.c b/usr/src/cmd/mdb/sparc/kmdb/kctl/kctl_isadep.c
index 5ae674e26e..f50016389c 100644
--- a/usr/src/cmd/mdb/sparc/kmdb/kctl/kctl_isadep.c
+++ b/usr/src/cmd/mdb/sparc/kmdb/kctl/kctl_isadep.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -195,18 +195,11 @@ kctl_depreactivate_isadep(void)
kdi_watchdog_restore();
}
-int
+void
kctl_activate_isadep(kdi_debugvec_t *dvec)
{
dvec->dv_kctl_cpu_init = kctl_cpu_init;
dvec->dv_kctl_vmready = kctl_ttable_init;
-
- return (0);
-}
-
-void
-kctl_deactivate_isadep(void)
-{
}
void
diff --git a/usr/src/cmd/mdb/sparc/kmdb/kmdb_kdi_isadep.c b/usr/src/cmd/mdb/sparc/kmdb/kmdb_kdi_isadep.c
index c82095ada5..15ceeeff1f 100644
--- a/usr/src/cmd/mdb/sparc/kmdb/kmdb_kdi_isadep.c
+++ b/usr/src/cmd/mdb/sparc/kmdb/kmdb_kdi_isadep.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,7 +32,7 @@
#include <sys/types.h>
#include <sys/kdi_impl.h>
-#include <kmdb/kmdb_kdi_impl.h>
+#include <kmdb/kaif.h>
#include <kmdb/kmdb_dpi.h>
#include <kmdb/kmdb_promif.h>
#include <mdb/mdb_debug.h>
@@ -49,6 +49,8 @@ static size_t kdi_icache_linesize;
static uint_t kdi_max_cpu_freq;
static uint_t kdi_sticks_per_usec;
+/* XXX needs to go into a header */
+
void
kdi_usecwait(clock_t n)
{
@@ -139,36 +141,6 @@ kdi_init_cpus_cb(pnode_t node, void *arg, void *result)
return (0);
}
-void
-kdi_cpu_init(void)
-{
- kdi_dcache_size = kdi_dcache_linesize =
- kdi_icache_size = kdi_icache_linesize = 0;
-
- kdi_max_cpu_freq = kdi_sticks_per_usec = 0;
-
- mdb_dprintf(MDB_DBG_KDI, "Initializing CPUs\n");
-
- kmdb_prom_walk_cpus(kdi_init_cpus_cb, NULL, NULL);
-
- /*
- * If we can't find one, guess high. The CPU frequency is going to be
- * used to determine the length of various delays, such as the mondo
- * interrupt retry delay. Too long is generally better than too short.
- */
- if (kdi_max_cpu_freq == 0) {
- mdb_dprintf(MDB_DBG_KDI, "No CPU freq found - assuming "
- "500MHz\n");
- kdi_max_cpu_freq = 500 * MICROSEC;
- }
-
- kdi_sticks_per_usec =
- MAX((kdi_max_cpu_freq + (MICROSEC - 1)) / MICROSEC, 1);
-
- mdb.m_kdi->mkdi_cpu_init(kdi_dcache_size, kdi_dcache_linesize,
- kdi_icache_size, kdi_icache_linesize);
-}
-
/*
* Called on an individual CPU. Tries to send it off to the state saver if it
* hasn't already entered the debugger. Returns non-zero if it *fails* to stop
@@ -217,12 +189,13 @@ kdi_report_unhalted(int cpuid, void *junk)
/*ARGSUSED*/
void
-kmdb_kdi_stop_other_cpus(int my_cpuid, void (*slave_saver)(void))
+kmdb_kdi_stop_slaves(int my_cpuid, int doxc)
{
int i;
for (i = 0; i < KDI_XC_RETRIES; i++) {
- if (kdi_cpu_ready_iter(kdi_halt_cpu, (void *)slave_saver) == 0)
+ if (kdi_cpu_ready_iter(kdi_halt_cpu,
+ (void *)kaif_slave_entry) == 0)
break;
kdi_usecwait(2000);
@@ -230,6 +203,16 @@ kmdb_kdi_stop_other_cpus(int my_cpuid, void (*slave_saver)(void))
(void) kdi_cpu_ready_iter(kdi_report_unhalted, NULL);
}
+void
+kmdb_kdi_start_slaves(void)
+{
+}
+
+void
+kmdb_kdi_slave_wait(void)
+{
+}
+
int
kmdb_kdi_get_stick(uint64_t *stickp)
{
@@ -257,4 +240,29 @@ kmdb_kdi_kernpanic(struct regs *regs, uint_t tt)
void
kmdb_kdi_init_isadep(kdi_t *kdi, kmdb_auxv_t *kav)
{
+ kdi_dcache_size = kdi_dcache_linesize =
+ kdi_icache_size = kdi_icache_linesize = 0;
+
+ kdi_max_cpu_freq = kdi_sticks_per_usec = 0;
+
+ mdb_dprintf(MDB_DBG_KDI, "Initializing CPUs\n");
+
+ kmdb_prom_walk_cpus(kdi_init_cpus_cb, NULL, NULL);
+
+ /*
+ * If we can't find one, guess high. The CPU frequency is going to be
+ * used to determine the length of various delays, such as the mondo
+ * interrupt retry delay. Too long is generally better than too short.
+ */
+ if (kdi_max_cpu_freq == 0) {
+ mdb_dprintf(MDB_DBG_KDI, "No CPU freq found - assuming "
+ "500MHz\n");
+ kdi_max_cpu_freq = 500 * MICROSEC;
+ }
+
+ kdi_sticks_per_usec =
+ MAX((kdi_max_cpu_freq + (MICROSEC - 1)) / MICROSEC, 1);
+
+ mdb.m_kdi->mkdi_cpu_init(kdi_dcache_size, kdi_dcache_linesize,
+ kdi_icache_size, kdi_icache_linesize);
}
diff --git a/usr/src/cmd/mdb/sparc/v9/genunix/Makefile b/usr/src/cmd/mdb/sparc/v9/genunix/Makefile
index 2cf7038d9e..564244d298 100644
--- a/usr/src/cmd/mdb/sparc/v9/genunix/Makefile
+++ b/usr/src/cmd/mdb/sparc/v9/genunix/Makefile
@@ -29,43 +29,10 @@
MODULE = genunix.so
MDBTGT = kvm
+include ../../../common/modules/genunix/Makefile.files
+
COMMONSRCS = \
- avl.c \
- bio.c \
- contract.c \
- cpupart.c \
- ctxop.c \
- cyclic.c \
- devinfo.c \
- findstack.c \
- fm.c \
- genunix.c \
- group.c \
- kgrep.c \
- kmem.c \
- ldi.c \
- leaky.c \
- leaky_subr.c \
- lgrp.c \
- list.c \
- log.c \
- mdi.c \
- memory.c \
- mmd.c \
- modhash.c \
- ndievents.c \
- net.c \
- nvpair.c \
- pg.c \
- rctl.c \
- sobj.c \
- streams.c \
- sysevent.c \
- thread.c \
- tsd.c \
- tsol.c \
- vfs.c \
- zone.c
+ $(GENUNIX_SRCS)
KMODSRCS = \
$(COMMONSRCS)
diff --git a/usr/src/cmd/mdb/sun4u/Makefile.kmdb b/usr/src/cmd/mdb/sun4u/Makefile.kmdb
index 43471fe808..152e0e736b 100644
--- a/usr/src/cmd/mdb/sun4u/Makefile.kmdb
+++ b/usr/src/cmd/mdb/sun4u/Makefile.kmdb
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -63,7 +62,6 @@ KMDBSRCS += \
kvm_isadep.c
KMDBML += \
- kaif_enter.s \
kmdb_asmutil.s
KCTLSRCS += \
diff --git a/usr/src/cmd/mdb/sun4v/Makefile.kmdb b/usr/src/cmd/mdb/sun4v/Makefile.kmdb
index d307d5f6f8..52ea632d90 100644
--- a/usr/src/cmd/mdb/sun4v/Makefile.kmdb
+++ b/usr/src/cmd/mdb/sun4v/Makefile.kmdb
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -71,7 +71,6 @@ KMDBSRCS += \
kvm_isadep.c
KMDBML += \
- kaif_enter.s \
kmdb_asmutil.s
KCTLSRCS += \
diff --git a/usr/src/cmd/prtdiag/Makefile b/usr/src/cmd/prtdiag/Makefile
index 2265dbd099..5a094f0213 100644
--- a/usr/src/cmd/prtdiag/Makefile
+++ b/usr/src/cmd/prtdiag/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -42,10 +41,6 @@ _msg := TARGET = _msg
all install clean clobber lint _msg: $(SUBDIRS)
-install: $(SUBDIRS)
- $(RM) $(ROOTUSRSBINPROG)
- $(LN) $(PLATEXEC) $(ROOTUSRSBINPROG)
-
$(SUBDIRS): FRC
@cd $@; pwd; $(MAKE) $(TARGET)
diff --git a/usr/src/cmd/prtdiag/Makefile.com b/usr/src/cmd/prtdiag/Makefile.com
index 732ab9e7eb..46d21d2338 100644
--- a/usr/src/cmd/prtdiag/Makefile.com
+++ b/usr/src/cmd/prtdiag/Makefile.com
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -37,13 +37,13 @@ DIRMODE = 755
OWNER = root
GROUP = sys
-LINTFILES = $(OBJS:%.o=%.ln)
-POFILE = prtdiag_$(PLATFORM).po
+LINT_OBJS = $(OBJS:%.o=%.ln)
+POFILE = prtdiag.po
POFILES = $(OBJS:%.o=%.po)
LIBPRTDIAG = $(SRC)/lib/libprtdiag
-.PARALLEL: $(OBJS) $(LINTFILES)
+.PARALLEL: $(OBJS) $(LINT_OBJS)
%.o: %.c
$(COMPILE.c) -o $@ $<
diff --git a/usr/src/cmd/prtdiag/i386/Makefile b/usr/src/cmd/prtdiag/i386/Makefile
index 985fd3411a..10bbed0d40 100644
--- a/usr/src/cmd/prtdiag/i386/Makefile
+++ b/usr/src/cmd/prtdiag/i386/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -19,27 +18,22 @@
#
# CDDL HEADER END
#
-
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-SUBDIRS = i86pc
+SRCDIR = ..
-all := TARGET = all
-install := TARGET = install
-clean := TARGET = clean
-clobber := TARGET = clobber
-lint := TARGET = lint
-_msg := TARGET = _msg
+include $(SRCDIR)/Makefile.com
-.KEEP_STATE:
+OBJS += smbios.o
+LDLIBS += -lsmbios
-all install clean clobber lint _msg: $(SUBDIRS)
+.KEEP_STATE:
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
+all: $(PROG)
-FRC:
+include $(SRCDIR)/i386/Makefile.targ
diff --git a/usr/src/cmd/prtdiag/i386/Makefile.targ b/usr/src/cmd/prtdiag/i386/Makefile.targ
new file mode 100644
index 0000000000..61b0ad98da
--- /dev/null
+++ b/usr/src/cmd/prtdiag/i386/Makefile.targ
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+install: all $(ROOTUSRSBIN) $(ROOTUSRSBINPROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+clean:
+ -$(RM) $(OBJS)
+ -$(RM) $(LINT_OBJS)
+ -$(RM) $(PROG)
+
+lint: $(LINT_OBJS)
+ $(LINT.c) $(LINT_OBJS) $(LDLIBS)
+
+$(POFILE): $(POFILES)
+ $(RM) $@
+ cat $(POFILES) > $@
+
+include $(SRCDIR)/../Makefile.targ
diff --git a/usr/src/cmd/prtdiag/i386/i86pc/smbios.c b/usr/src/cmd/prtdiag/i386/smbios.c
index 819cd04551..819cd04551 100644
--- a/usr/src/cmd/prtdiag/i386/i86pc/smbios.c
+++ b/usr/src/cmd/prtdiag/i386/smbios.c
diff --git a/usr/src/cmd/prtdiag/Makefile.targ b/usr/src/cmd/prtdiag/sparc/Makefile.targ
index 4cc5938f24..19a930a8ec 100644
--- a/usr/src/cmd/prtdiag/Makefile.targ
+++ b/usr/src/cmd/prtdiag/sparc/Makefile.targ
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -21,22 +20,24 @@
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
install: all $(USR_PSM_SBIN_PROG) $(USR_PSM_SBIN_PROG_LINKS)
+ $(RM) $(ROOTUSRSBINPROG)
+ $(LN) $(PLATEXEC) $(ROOTUSRSBINPROG)
$(PROG): $(OBJS)
$(LINK.c) -o $@ $(OBJS) $(LDLIBS)
$(POST_PROCESS)
clean:
- -$(RM) $(OBJS) $(LINTFILES)
+ -$(RM) $(OBJS) $(LINT_OBJS) $(PROG)
-lint: $(LINTFILES)
- $(LINT) $(LINTFILES) $(LDLIBS)
+lint: $(LINT_OBJS)
+ $(LINT) $(LINT_OBJS) $(LDLIBS)
$(POFILE): $(POFILES)
$(RM) $@
diff --git a/usr/src/cmd/prtdiag/sparc/sun4u/Makefile b/usr/src/cmd/prtdiag/sparc/sun4u/Makefile
index 17f6f71ac7..c7c6157dad 100644
--- a/usr/src/cmd/prtdiag/sparc/sun4u/Makefile
+++ b/usr/src/cmd/prtdiag/sparc/sun4u/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -48,4 +47,4 @@ LINTFLAGS += -u
all: $(LIBPRTDIAG) $(PROG)
-include $(SRCDIR)/Makefile.targ
+include $(SRCDIR)/sparc/Makefile.targ
diff --git a/usr/src/cmd/prtdiag/sparc/sun4v/Makefile b/usr/src/cmd/prtdiag/sparc/sun4v/Makefile
index 04deb33a76..1da627801a 100644
--- a/usr/src/cmd/prtdiag/sparc/sun4v/Makefile
+++ b/usr/src/cmd/prtdiag/sparc/sun4v/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -48,4 +47,4 @@ LINTFLAGS += -u
all: $(LIBPRTDIAG) $(PROG)
-include $(SRCDIR)/Makefile.targ
+include $(SRCDIR)/sparc/Makefile.targ
diff --git a/usr/src/cmd/svc/profile/Makefile b/usr/src/cmd/svc/profile/Makefile
index d193399b68..18b1e40f87 100644
--- a/usr/src/cmd/svc/profile/Makefile
+++ b/usr/src/cmd/svc/profile/Makefile
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -50,7 +50,6 @@ PROFILESRCS = \
platform_SUNW,Sun-Fire.xml \
platform_SUNW,Ultra-Enterprise-10000.xml \
platform_SUNW,UltraSPARC-IIi-Netract.xml \
- platform_i86pc.xml \
platform_none.xml \
platform_sun4v.xml
diff --git a/usr/src/common/elfcap/elfcap.c b/usr/src/common/elfcap/elfcap.c
index 67be6eb882..f3262a2cc3 100644
--- a/usr/src/common/elfcap/elfcap.c
+++ b/usr/src/common/elfcap/elfcap.c
@@ -18,10 +18,12 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+
#pragma ident "%Z%%M% %I% %E% SMI"
/* LINTLIBRARY */
@@ -144,6 +146,8 @@ static const char Hw1_i_pause[] = "PAUSE";
static const char Hw1_i_sse3[] = "SSE3";
static const char Hw1_i_mon[] = "MON";
static const char Hw1_i_cx16[] = "CX16";
+static const char Hw1_i_ahf[] = "AHF";
+static const char Hw1_i_tscp[] = "TSCP";
#elif CAP_LOWERCASE
static const char Hw1_i_fpu[] = "fpu";
static const char Hw1_i_tsc[] = "tsc";
@@ -162,6 +166,8 @@ static const char Hw1_i_pause[] = "pause";
static const char Hw1_i_sse3[] = "sse3";
static const char Hw1_i_mon[] = "mon";
static const char Hw1_i_cx16[] = "cx16";
+static const char Hw1_i_ahf[] = "ahf";
+static const char Hw1_i_tscp[] = "tscp";
#else
#error "Hardware Capabilities (intel) - what case do you want?"
#endif
@@ -189,12 +195,14 @@ static const Cap_desc hw1_i[] = {
{ AV_386_PAUSE, Hw1_i_pause, sizeof (Hw1_i_pause) - 1 },
{ AV_386_SSE3, Hw1_i_sse3, sizeof (Hw1_i_sse3) - 1 },
{ AV_386_MON, Hw1_i_mon, sizeof (Hw1_i_mon) - 1 },
- { AV_386_CX16, Hw1_i_cx16, sizeof (Hw1_i_cx16) - 1 }
+ { AV_386_CX16, Hw1_i_cx16, sizeof (Hw1_i_cx16) - 1 },
+ { AV_386_AHF, Hw1_i_ahf, sizeof (Hw1_i_ahf) - 1 },
+ { AV_386_TSCP, Hw1_i_tscp, sizeof (Hw1_i_tscp) - 1 }
};
static const uint_t hw1_i_num = sizeof (hw1_i) / sizeof (Cap_desc);
/*
- * Concatenate a token to the string buffer. This can be a capailities token
+ * Concatenate a token to the string buffer. This can be a capabilities token
* or a separator token.
*/
static int
diff --git a/usr/src/common/fs/decompress.c b/usr/src/common/fs/decompress.c
new file mode 100644
index 0000000000..8c78302c6f
--- /dev/null
+++ b/usr/src/common/fs/decompress.c
@@ -0,0 +1,308 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Decompression module for stand alone file systems.
+ */
+
+#include <sys/param.h>
+#include <sys/sysmacros.h>
+#include <sys/vnode.h>
+#include <sys/bootvfs.h>
+#include <sys/filep.h>
+#include <zmod/zlib.h>
+
+#ifdef _BOOT
+#include "../common/util.h"
+#else
+#include <sys/sunddi.h>
+#endif
+
+#define MAX_DECOMP_BUFS 8
+#define GZIP_ID_BYTE_1 0x1f
+#define GZIP_ID_BYTE_2 0x8b
+#define GZIP_CM_DEFLATE 0x08
+#define SEEKBUFSIZE 8192
+
+#ifdef _BOOT
+#define dprintf if (cf_debug) printf
+#else
+#define dprintf if (cf_debug) printf
+
+#endif
+
+extern int bootrd_debug;
+extern void *bkmem_alloc(size_t);
+extern void bkmem_free(void *, size_t);
+
+caddr_t scratch_bufs[MAX_DECOMP_BUFS]; /* array of free scratch mem bufs */
+int decomp_bufcnt; /* total no, of allocated decomp bufs */
+int free_dcomp_bufs; /* no. of free decomp bufs */
+char seek_scrbuf[SEEKBUFSIZE]; /* buffer for seeking */
+int cf_debug; /* non-zero enables debug prints */
+
+void *
+cf_alloc(void *opaque, unsigned int items, unsigned int size)
+{
+ fileid_t *filep;
+ unsigned int nbytes;
+ caddr_t ptr;
+
+ filep = (fileid_t *)opaque;
+ nbytes = roundup(items * size, sizeof (long));
+ if (nbytes > (DECOMP_BUFSIZE - filep->fi_dcscrused)) {
+ ptr = bkmem_alloc(nbytes);
+ } else {
+ ptr = &filep->fi_dcscrbuf[filep->fi_dcscrused];
+ filep->fi_dcscrused += nbytes;
+ }
+ bzero(ptr, nbytes);
+ return (ptr);
+}
+
+/*
+ * Decompression scratch memory free routine, does nothing since we free
+ * the entire scratch area all at once on file close.
+ */
+/* ARGSUSED */
+void
+cf_free(void *opaque, void *addr)
+{
+}
+
+/*
+ * Read the first block of the file described by filep and determine if
+ * the file is gzip-compressed. If so, the compressed flag will be set
+ * in the fileid_t struct pointed to by filep and it will be initialized
+ * for doing decompression on reads to the file.
+ */
+int
+cf_check_compressed(fileid_t *filep)
+{
+ unsigned char *filebytes;
+ z_stream *zsp;
+
+ filep->fi_offset = 0;
+ if ((filep->fi_getblock)(filep) == -1)
+ return (-1);
+ filep->fi_offset = 0;
+ filep->fi_count = 0;
+ filep->fi_cfoff = 0;
+ filebytes = (unsigned char *)filep->fi_memp;
+ if (filebytes[0] != GZIP_ID_BYTE_1 || filebytes[1] != GZIP_ID_BYTE_2 ||
+ filebytes[2] != GZIP_CM_DEFLATE)
+ return (0); /* not compressed */
+ filep->fi_flags |= FI_COMPRESSED;
+
+ dprintf("file %s is compressed\n", filep->fi_path);
+
+ /*
+ * Allocate decompress scratch buffer
+ */
+ if (free_dcomp_bufs) {
+ filep->fi_dcscrbuf = scratch_bufs[--free_dcomp_bufs];
+ } else {
+ filep->fi_dcscrbuf = bkmem_alloc(DECOMP_BUFSIZE);
+ decomp_bufcnt++;
+ }
+ filep->fi_dcscrused = 0;
+ zsp = bkmem_alloc(sizeof (*zsp));
+ filep->fi_dcstream = zsp;
+ /*
+ * Initialize the decompression stream
+ */
+ bzero(zsp, sizeof (*zsp));
+ zsp->opaque = filep;
+ zsp->zalloc = cf_alloc;
+ zsp->zfree = cf_free;
+ zsp->avail_in = 0;
+ zsp->next_in = NULL;
+ zsp->avail_out = 0;
+ zsp->next_out = NULL;
+ if (inflateInit2(zsp, -MAX_WBITS) != Z_OK)
+ return (-1);
+ return (0);
+}
+
+/*
+ * If the file described by fileid_t struct at *filep is compressed
+ * free any resources associated with the decompression. (decompression
+ * buffer, etc.).
+ */
+void
+cf_close(fileid_t *filep)
+{
+ if ((filep->fi_flags & FI_COMPRESSED) == 0)
+ return;
+ dprintf("cf_close: %s\n", filep->fi_path);
+ (void) inflateEnd(filep->fi_dcstream);
+ bkmem_free(filep->fi_dcstream, sizeof (z_stream));
+ if (free_dcomp_bufs == MAX_DECOMP_BUFS) {
+ bkmem_free(filep->fi_dcscrbuf, DECOMP_BUFSIZE);
+ } else {
+ scratch_bufs[free_dcomp_bufs++] = filep->fi_dcscrbuf;
+ }
+}
+
+void
+cf_rewind(fileid_t *filep)
+{
+ z_stream *zsp;
+
+ dprintf("cf_rewind: %s\n", filep->fi_path);
+ zsp = filep->fi_dcstream;
+ zsp->avail_in = 0;
+ zsp->next_in = NULL;
+ (void) inflateReset(zsp);
+ filep->fi_cfoff = 0;
+}
+
+#define FLG_FHCRC 0x02 /* crc field present */
+#define FLG_FEXTRA 0x04 /* "extra" field present */
+#define FLG_FNAME 0x08 /* file name field present */
+#define FLG_FCOMMENT 0x10 /* comment field present */
+
+/*
+ * Calculate the header length of a gzip compressed file
+ */
+static int
+cf_headerlen(unsigned char *hp)
+{
+ unsigned char flag;
+ int xlen, hlen = 0;
+
+ hlen += 3; /* skip ID bytes and compression method */
+ flag = hp[hlen];
+ hlen += 7; /* skip flag, mtime(4 bytes), xfl, and os */
+ if (flag & FLG_FEXTRA) {
+ xlen = hp[hlen++];
+ xlen += hp[hlen++] << 8;
+ hlen += xlen; /* skip extra field */
+ }
+ if (flag & FLG_FNAME)
+ hlen += strlen((char *)&hp[hlen]) + 1; /* skip file name */
+ if (flag & FLG_FCOMMENT)
+ hlen += strlen((char *)&hp[hlen]) + 1; /* skip comment */
+ if (flag & FLG_FHCRC)
+ hlen += 2; /* skip crc */
+ return (hlen);
+}
+
+/*
+ * Read at the current uncompressed offset from the compressed file described
+ * by *filep. Will return decompressed data.
+ */
+int
+cf_read(fileid_t *filep, caddr_t buf, size_t count)
+{
+ z_stream *zsp;
+ struct inode *ip;
+ int err = Z_OK;
+ int hlen, infbytes;
+ off_t soff;
+ caddr_t smemp;
+
+ dprintf("cf_read: %s ", filep->fi_path);
+ dprintf("%lx bytes\n", count);
+ zsp = filep->fi_dcstream;
+ ip = filep->fi_inode;
+ dprintf(" reading at offset %lx\n", zsp->total_out);
+ zsp->next_out = (unsigned char *)buf;
+ zsp->avail_out = count;
+ while (zsp->avail_out != 0) {
+ if (zsp->avail_in == 0 && filep->fi_cfoff < ip->i_size) {
+ /*
+ * read a block of the file to inflate
+ */
+ soff = filep->fi_offset;
+ smemp = filep->fi_memp;
+ filep->fi_memp = NULL;
+ filep->fi_offset = filep->fi_cfoff;
+ filep->fi_count = 0;
+ if ((*filep->fi_getblock)(filep) == -1)
+ return (-1);
+ filep->fi_offset = soff;
+ zsp->next_in = (unsigned char *)filep->fi_memp;
+ zsp->avail_in = filep->fi_count;
+ filep->fi_memp = smemp;
+ /*
+ * If we are reading the first block of the file, we
+ * need to skip over the header bytes before inflating
+ */
+ if (filep->fi_cfoff == 0) {
+ hlen = cf_headerlen(zsp->next_in);
+ zsp->next_in += hlen;
+ zsp->avail_in -= hlen;
+ }
+ filep->fi_cfoff += filep->fi_count;
+ }
+ infbytes = zsp->avail_out;
+ dprintf("attempting inflate of %x bytes to buf at: %lx\n",
+ zsp->avail_out, (unsigned long)zsp->next_out);
+ err = inflate(zsp, Z_NO_FLUSH);
+ infbytes -= zsp->avail_out;
+ dprintf("inflated %x bytes, errcode=%d\n", infbytes, err);
+ /*
+ * break out if we hit end of the compressed file
+ * or the end of the compressed byte stream
+ */
+ if (filep->fi_cfoff >= ip->i_size || err == Z_STREAM_END)
+ break;
+ }
+ dprintf("cf_read: returned %lx bytes\n", count - zsp->avail_out);
+ return (count - zsp->avail_out);
+}
+
+/*
+ * Seek to the location specified by addr
+ */
+void
+cf_seek(fileid_t *filep, off_t addr, int whence)
+{
+ z_stream *zsp;
+ int readsz;
+
+ dprintf("cf_seek: %s ", filep->fi_path);
+ dprintf("to %lx\n", addr);
+ zsp = filep->fi_dcstream;
+ if (whence == SEEK_CUR)
+ addr += zsp->total_out;
+ /*
+ * To seek backwards, must rewind and seek forwards
+ */
+ if (addr < zsp->total_out) {
+ cf_rewind(filep);
+ filep->fi_offset = 0;
+ } else {
+ addr -= zsp->total_out;
+ }
+ while (addr > 0) {
+ readsz = MIN(addr, SEEKBUFSIZE);
+ (void) cf_read(filep, seek_scrbuf, readsz);
+ addr -= readsz;
+ }
+}
diff --git a/usr/src/common/fs/hsfs.c b/usr/src/common/fs/hsfs.c
index b625c0aba9..9efe265cfa 100644
--- a/usr/src/common/fs/hsfs.c
+++ b/usr/src/common/fs/hsfs.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -84,6 +84,10 @@ extern void kobj_printf(char *, ...);
extern int bootrd_debug;
extern void *bkmem_alloc(size_t);
extern void bkmem_free(void *, size_t);
+extern int cf_check_compressed(fileid_t *);
+extern void cf_close(fileid_t *);
+extern void cf_seek(fileid_t *, off_t, int);
+extern int cf_read(fileid_t *, caddr_t, size_t);
struct dirstuff {
int loc;
@@ -353,30 +357,39 @@ bhsfs_read(int fd, caddr_t buf, size_t count)
struct inode *ip;
caddr_t n;
- dprintf("bhsfs_read %d, count 0x%lx\n", fd, count);
+ dprintf("bhsfs_read %d, ", fd);
+ dprintf("count 0x%lx\n", count);
filep = find_fp(fd);
if (filep == NULL)
return (-1);
ip = filep->fi_inode;
n = buf;
- if (filep->fi_offset + count > ip->i_size)
+ if ((filep->fi_flags & FI_COMPRESSED) == 0 &&
+ filep->fi_offset + count > ip->i_size)
count = ip->i_size - filep->fi_offset;
if ((i = count) <= 0)
return (0);
while (i > 0) {
- if (filep->fi_count == 0) {
- if (getblock(filep) == -1)
- return (0);
+ if (filep->fi_flags & FI_COMPRESSED) {
+ if ((j = cf_read(filep, buf, count)) < 0)
+ return (0); /* encountered an error */
+ if (j < i)
+ i = j; /* short read, must have hit EOF */
+ } else {
+ if (filep->fi_count == 0) {
+ if (getblock(filep) == -1)
+ return (0);
+ }
+ j = MIN(i, filep->fi_count);
+ bcopy(filep->fi_memp, buf, (uint_t)j);
}
- j = MIN(i, filep->fi_count);
- bcopy(filep->fi_memp, buf, (uint_t)j);
- buf += j;
filep->fi_memp += j;
filep->fi_offset += j;
filep->fi_count -= j;
+ buf += j;
i -= j;
}
@@ -477,6 +490,8 @@ bhsfs_open(char *str, int flags)
(void) strcpy(filep->fi_path, str);
filep->fi_inode = NULL;
bzero(filep->fi_buf, MAXBSIZE);
+ filep->fi_getblock = getblock;
+ filep->fi_flags = 0;
ino = find(str, filep);
if (ino == 0) {
@@ -489,6 +504,8 @@ bhsfs_open(char *str, int flags)
filep->fi_count = 0;
filep->fi_memp = 0;
+ if (cf_check_compressed(filep) != 0)
+ return (-1);
dprintf("open done\n");
return (filep->fi_filedes);
}
@@ -503,10 +520,11 @@ bhsfs_close(int fd)
return (-1);
if (filep->fi_taken == 0 || filep == head) {
- printf("File descripter %d no allocated!\n", fd);
+ printf("File descripter %d not allocated!\n", fd);
return (-1);
}
+ cf_close(filep);
/* unlink and deallocate node */
filep->fi_forw->fi_back = filep->fi_back;
filep->fi_back->fi_forw = filep->fi_forw;
@@ -541,24 +559,29 @@ bhsfs_lseek(int fd, off_t addr, int whence)
{
fileid_t *filep;
- dprintf("lseek %d, off = %lx\n", fd, addr);
+ dprintf("lseek %d, ", fd);
+ dprintf("off = %lx\n", addr);
if (!(filep = find_fp(fd)))
return (-1);
- switch (whence) {
- case SEEK_CUR:
- filep->fi_offset += addr;
- break;
- case SEEK_SET:
- filep->fi_offset = addr;
- break;
- default:
- case SEEK_END:
- printf("lseek(): invalid whence value %d\n", whence);
- break;
+ if (filep->fi_flags & FI_COMPRESSED) {
+ cf_seek(filep, addr, whence);
+ } else {
+ switch (whence) {
+ case SEEK_CUR:
+ filep->fi_offset += addr;
+ break;
+ case SEEK_SET:
+ filep->fi_offset = addr;
+ break;
+ default:
+ case SEEK_END:
+ printf("lseek(): invalid whence value %d\n", whence);
+ break;
+ }
+ filep->fi_blocknum = addr / DEV_BSIZE;
}
- filep->fi_blocknum = addr / DEV_BSIZE;
filep->fi_count = 0;
return (0);
}
@@ -590,6 +613,11 @@ bhsfs_fstat(int fd, struct bootstat *stp)
default:
break;
}
+ /*
+ * NOTE: this size will be the compressed size for a compressed file
+ * This could confuse the caller since we decompress the file behind
+ * the scenes when the file is read.
+ */
stp->st_size = ip->i_size;
/* file times */
diff --git a/usr/src/common/fs/ufsops.c b/usr/src/common/fs/ufsops.c
index ba0a60dbdd..8cdd5d6e79 100644
--- a/usr/src/common/fs/ufsops.c
+++ b/usr/src/common/fs/ufsops.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -43,6 +43,10 @@
extern void *bkmem_alloc(size_t);
extern void bkmem_free(void *, size_t);
+extern int cf_check_compressed(fileid_t *);
+extern void cf_close(fileid_t *);
+extern void cf_seek(fileid_t *, off_t, int);
+extern int cf_read(fileid_t *, caddr_t, size_t);
int bootrd_debug;
#ifdef _BOOT
@@ -419,6 +423,59 @@ getblock(fileid_t *filep, caddr_t buf, int count, int *rcount)
return (0);
}
+/*
+ * Get the next block of data from the file. Don't attempt to go directly
+ * to user's buffer.
+ */
+static int
+getblock_noopt(fileid_t *filep)
+{
+ struct fs *fs;
+ caddr_t p;
+ int off, size, diff;
+ daddr32_t lbn;
+ devid_t *devp;
+
+ dprintf("getblock_noopt: start\n");
+
+ devp = filep->fi_devp;
+ p = filep->fi_memp;
+ if ((signed)filep->fi_count <= 0) {
+
+ /* find the amt left to be read in the file */
+ diff = filep->fi_inode->i_size - filep->fi_offset;
+ if (diff <= 0) {
+ printf("Short read\n");
+ return (-1);
+ }
+
+ fs = &devp->un_fs.di_fs;
+ /* which block (or frag) in the file do we read? */
+ lbn = lblkno(fs, filep->fi_offset);
+
+ /* which physical block on the device do we read? */
+ filep->fi_blocknum = fsbtodb(fs, sbmap(filep, lbn));
+
+ off = blkoff(fs, filep->fi_offset);
+
+ /* either blksize or fragsize */
+ size = blksize(fs, filep->fi_inode, lbn);
+ filep->fi_count = size;
+ /* reading on a ramdisk, just get a pointer to the data */
+ filep->fi_memp = NULL;
+
+ if (diskread(filep))
+ return (-1);
+
+ if (filep->fi_offset - off + size >= filep->fi_inode->i_size)
+ filep->fi_count = diff + off;
+ filep->fi_count -= off;
+ p = &filep->fi_memp[off];
+ }
+ filep->fi_memp = p;
+ return (0);
+}
+
/*
* This is the high-level read function. It works like this.
@@ -441,7 +498,8 @@ bufs_read(int fd, caddr_t buf, size_t count)
return (-1);
}
- if (filep->fi_offset + count > filep->fi_inode->i_size)
+ if ((filep->fi_flags & FI_COMPRESSED) == 0 &&
+ filep->fi_offset + count > filep->fi_inode->i_size)
count = filep->fi_inode->i_size - filep->fi_offset;
/* that was easy */
@@ -450,22 +508,30 @@ bufs_read(int fd, caddr_t buf, size_t count)
n = buf;
while (i > 0) {
- /* If we need to reload the buffer, do so */
- if ((j = filep->fi_count) == 0) {
- (void) getblock(filep, buf, i, &rcount);
- i -= rcount;
- buf += rcount;
- filep->fi_offset += rcount;
+ if (filep->fi_flags & FI_COMPRESSED) {
+ if ((j = cf_read(filep, buf, count)) < 0)
+ return (0); /* encountered an error */
+ if (j < i)
+ i = j; /* short read, must have hit EOF */
} else {
- /* else just bcopy from our buffer */
- j = MIN(i, j);
- bcopy(filep->fi_memp, buf, (unsigned)j);
- buf += j;
- filep->fi_memp += j;
- filep->fi_offset += j;
- filep->fi_count -= j;
- i -= j;
+ /* If we need to reload the buffer, do so */
+ if ((j = filep->fi_count) == 0) {
+ (void) getblock(filep, buf, i, &rcount);
+ i -= rcount;
+ buf += rcount;
+ filep->fi_offset += rcount;
+ continue;
+ } else {
+ /* else just bcopy from our buffer */
+ j = MIN(i, j);
+ bcopy(filep->fi_memp, buf, (unsigned)j);
+ }
}
+ buf += j;
+ filep->fi_memp += j;
+ filep->fi_offset += j;
+ filep->fi_count -= j;
+ i -= j;
}
return (buf - n);
}
@@ -564,6 +630,8 @@ bufs_open(char *filename, int flags)
filep->fi_devp = ufs_devp; /* dev is already "mounted" */
filep->fi_inode = NULL;
bzero(filep->fi_buf, MAXBSIZE);
+ filep->fi_getblock = getblock_noopt;
+ filep->fi_flags = 0;
inode = find(filep, (char *)filename);
if (inode == (ino_t)0) {
@@ -579,6 +647,8 @@ bufs_open(char *filename, int flags)
filep->fi_offset = filep->fi_count = 0;
+ if (cf_check_compressed(filep) != 0)
+ return (-1);
return (filep->fi_filedes);
}
@@ -596,20 +666,24 @@ bufs_lseek(int fd, off_t addr, int whence)
if (!(filep = find_fp(fd)))
return (-1);
- switch (whence) {
- case SEEK_CUR:
- filep->fi_offset += addr;
- break;
- case SEEK_SET:
- filep->fi_offset = addr;
- break;
- default:
- case SEEK_END:
- printf("lseek(): invalid whence value %d\n", whence);
- break;
+ if (filep->fi_flags & FI_COMPRESSED) {
+ cf_seek(filep, addr, whence);
+ } else {
+ switch (whence) {
+ case SEEK_CUR:
+ filep->fi_offset += addr;
+ break;
+ case SEEK_SET:
+ filep->fi_offset = addr;
+ break;
+ default:
+ case SEEK_END:
+ printf("lseek(): invalid whence value %d\n", whence);
+ break;
+ }
+ filep->fi_blocknum = addr / DEV_BSIZE;
}
- filep->fi_blocknum = addr / DEV_BSIZE;
filep->fi_count = 0;
return (0);
@@ -643,6 +717,11 @@ bufs_fstat(int fd, struct bootstat *stp)
default:
break;
}
+ /*
+ * NOTE: this size will be the compressed size for a compressed file
+ * This could confuse the caller since we decompress the file behind
+ * the scenes when the file is read.
+ */
stp->st_size = ip->i_size;
stp->st_atim.tv_sec = ip->i_atime.tv_sec;
stp->st_atim.tv_nsec = ip->i_atime.tv_usec * 1000;
@@ -675,6 +754,7 @@ bufs_close(int fd)
/* unlink and deallocate node */
filep->fi_forw->fi_back = filep->fi_back;
filep->fi_back->fi_forw = filep->fi_forw;
+ cf_close(filep);
bkmem_free((char *)filep, sizeof (fileid_t));
return (0);
diff --git a/usr/src/common/util/bzero.c b/usr/src/common/util/bzero.c
index a9d30adad1..3bd96aa029 100644
--- a/usr/src/common/util/bzero.c
+++ b/usr/src/common/util/bzero.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T
@@ -35,7 +34,7 @@
#if !defined(_KMDB) && !defined(_BOOT)
#include "synonyms.h"
-#endif /* !_KMDB || _BOOT */
+#endif /* !_KMDB && !_BOOT */
#include <sys/types.h>
#include <string.h>
diff --git a/usr/src/common/util/memcpy.c b/usr/src/common/util/memcpy.c
index a9051f3e84..9580401335 100644
--- a/usr/src/common/util/memcpy.c
+++ b/usr/src/common/util/memcpy.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -51,10 +51,12 @@
#if defined(_KERNEL)
#include <sys/systm.h>
-#else
+#elif !defined(_BOOT)
#include <stddef.h>
#include <string.h>
-#endif /* !_KERNEL */
+#endif
+
+#include "memcpy.h"
/*
* Copy s0 to s, always copy n bytes.
diff --git a/usr/src/common/util/memcpy.h b/usr/src/common/util/memcpy.h
new file mode 100644
index 0000000000..de7756825e
--- /dev/null
+++ b/usr/src/common/util/memcpy.h
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _COMMON_UTIL_MEMCPY_H
+#define _COMMON_UTIL_MEMCPY_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void *memcpy(void *, const void *, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COMMON_UTIL_MEMCPY_H */
diff --git a/usr/src/common/util/memset.c b/usr/src/common/util/memset.c
index f18f8cb0e3..9258a5fa0f 100644
--- a/usr/src/common/util/memset.c
+++ b/usr/src/common/util/memset.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -42,9 +41,11 @@
#if defined(_KERNEL)
#include <sys/systm.h>
-#else
+#elif !defined(_BOOT)
#include <string.h>
-#endif /* !_KERNEL */
+#endif
+
+#include "string.h"
/*
* Set an array of n chars starting at sp to the character c.
diff --git a/usr/src/common/util/memset.h b/usr/src/common/util/memset.h
new file mode 100644
index 0000000000..93436f2ac1
--- /dev/null
+++ b/usr/src/common/util/memset.h
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _COMMON_UTIL_MEMSET_H
+#define _COMMON_UTIL_MEMSET_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void *memset(void *, int, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COMMON_UTIL_MEMSET_H */
diff --git a/usr/src/common/util/sscanf.c b/usr/src/common/util/sscanf.c
new file mode 100644
index 0000000000..df800aaf87
--- /dev/null
+++ b/usr/src/common/util/sscanf.c
@@ -0,0 +1,633 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ * From: Id: vfscanf.c,v 1.13 1998/09/25 12:20:27 obrien Exp
+ * From: static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93";
+ * From: static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93";
+ */
+
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/ctype.h>
+#include <sys/sunddi.h>
+#include <util/sscanf.h>
+
+#define BUF 32 /* Maximum length of numeric string. */
+
+/*
+ * Flags used during conversion.
+ */
+#define LONG 0x01 /* l: long or double */
+#define SHORT 0x04 /* h: short */
+#define SUPPRESS 0x08 /* suppress assignment */
+#define POINTER 0x10 /* weird %p pointer (`fake hex') */
+#define NOSKIP 0x20 /* do not skip blanks */
+
+/*
+ * The following are used in numeric conversions only:
+ * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
+ * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
+ */
+#define SIGNOK 0x40 /* +/- is (still) legal */
+#define NDIGITS 0x80 /* no digits detected */
+
+#define DPTOK 0x100 /* (float) decimal point is still legal */
+#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
+
+#define PFXOK 0x100 /* 0x prefix is (still) legal */
+#define NZDIGITS 0x200 /* no zero digits detected */
+
+/*
+ * Conversion types.
+ */
+#define CT_CHAR 0 /* %c conversion */
+#define CT_CCL 1 /* %[...] conversion */
+#define CT_STRING 2 /* %s conversion */
+#define CT_INT 3 /* integer, i.e., strtoq or strtouq */
+
+static const uchar_t *set_ccl(char *, const uchar_t *);
+
+#define isspace(ch) (((ch) == ' ') || ((ch) == '\r') || ((ch) == '\n') || \
+ ((ch) == '\t') || ((ch) == '\f'))
+
+int
+vsscanf(const char *inp, char const *fmt0, va_list ap)
+{
+ int inr;
+ const uchar_t *fmt = (const uchar_t *)fmt0;
+ int c; /* character from format, or conversion */
+ size_t width; /* field width, or 0 */
+ char *p; /* points into all kinds of strings */
+ int n; /* handy integer */
+ int flags; /* flags as defined above */
+ char *p0; /* saves original value of p when necessary */
+ int nassigned; /* number of fields assigned */
+ int nconversions; /* number of conversions */
+ int nread; /* number of characters consumed from fp */
+ int base; /* base argument to strtoq/strtouq */
+ int sconv; /* do signed conversion */
+ char ccltab[256]; /* character class table for %[...] */
+ char buf[BUF]; /* buffer for numeric conversions */
+
+ /* `basefix' is used to avoid `if' tests in the integer scanner */
+ static short basefix[17] =
+ { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+
+ inr = strlen(inp);
+
+ sconv = 0;
+ nassigned = 0;
+ nconversions = 0;
+ nread = 0;
+ base = 0;
+ for (;;) {
+ c = *fmt++;
+ if (c == 0)
+ return (nassigned);
+ if (isspace(c)) {
+ while (inr > 0 && isspace(*inp))
+ nread++, inr--, inp++;
+ continue;
+ }
+ if (c != '%')
+ goto literal;
+ width = 0;
+ flags = 0;
+ /*
+ * switch on the format. continue if done;
+ * break once format type is derived.
+ */
+again: c = *fmt++;
+ switch (c) {
+ case '%':
+literal:
+ if (inr <= 0)
+ goto input_failure;
+ if (*inp != c)
+ goto match_failure;
+ inr--, inp++;
+ nread++;
+ continue;
+
+ case '*':
+ flags |= SUPPRESS;
+ goto again;
+ case 'l':
+ flags |= LONG;
+ goto again;
+ case 'h':
+ flags |= SHORT;
+ goto again;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ width = width * 10 + c - '0';
+ goto again;
+
+ /*
+ * Conversions.
+ *
+ */
+ case 'd':
+ c = CT_INT;
+ sconv = 1;
+ base = 10;
+ break;
+
+ case 'i':
+ c = CT_INT;
+ sconv = 1;
+ base = 0;
+ break;
+
+ case 'o':
+ c = CT_INT;
+ base = 8;
+ break;
+
+ case 'u':
+ c = CT_INT;
+ base = 10;
+ break;
+
+ case 'x':
+ flags |= PFXOK; /* enable 0x prefixing */
+ c = CT_INT;
+ base = 16;
+ break;
+
+ case 's':
+ c = CT_STRING;
+ break;
+
+ case '[':
+ fmt = set_ccl(ccltab, fmt);
+ flags |= NOSKIP;
+ c = CT_CCL;
+ break;
+
+ case 'c':
+ flags |= NOSKIP;
+ c = CT_CHAR;
+ break;
+
+ case 'p': /* pointer format is like hex */
+ flags |= POINTER | PFXOK;
+ c = CT_INT;
+ base = 16;
+ break;
+
+ case 'n':
+ nconversions++;
+ if (flags & SUPPRESS) /* ??? */
+ continue;
+ if (flags & SHORT)
+ *va_arg(ap, short *) = (short)nread;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = (long)nread;
+ else
+ *va_arg(ap, int *) = nread;
+ continue;
+ }
+
+ /*
+ * We have a conversion that requires input.
+ */
+ if (inr <= 0)
+ goto input_failure;
+
+ /*
+ * Consume leading white space, except for formats
+ * that suppress this.
+ */
+ if ((flags & NOSKIP) == 0) {
+ while (isspace(*inp)) {
+ nread++;
+ if (--inr > 0)
+ inp++;
+ else
+ goto input_failure;
+ }
+ /*
+ * Note that there is at least one character in
+ * the buffer, so conversions that do not set NOSKIP
+ * can no longer result in an input failure.
+ */
+ }
+
+ /*
+ * Do the conversion.
+ */
+ switch (c) {
+
+ case CT_CHAR:
+ /* scan arbitrary characters (sets NOSKIP) */
+ if (width == 0)
+ width = 1;
+ if (flags & SUPPRESS) {
+ size_t sum = 0;
+
+ if ((n = inr) < width) {
+ sum += n;
+ width -= n;
+ inp += n;
+ if (sum == 0)
+ goto input_failure;
+ } else {
+ sum += width;
+ inr -= width;
+ inp += width;
+ }
+ nread += sum;
+ } else {
+ bcopy(inp, va_arg(ap, char *), width);
+ inr -= width;
+ inp += width;
+ nread += width;
+ nassigned++;
+ }
+ nconversions++;
+ break;
+
+ case CT_CCL:
+ /* scan a (nonempty) character class (sets NOSKIP) */
+ if (width == 0)
+ width = (size_t)~0; /* `infinity' */
+ /* take only those things in the class */
+ if (flags & SUPPRESS) {
+ n = 0;
+ while (ccltab[(unsigned char)*inp]) {
+ n++, inr--, inp++;
+ if (--width == 0)
+ break;
+ if (inr <= 0) {
+ if (n == 0)
+ goto input_failure;
+ break;
+ }
+ }
+ if (n == 0)
+ goto match_failure;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (ccltab[(unsigned char)*inp]) {
+ inr--;
+ *p++ = *inp++;
+ if (--width == 0)
+ break;
+ if (inr <= 0) {
+ if (p == p0)
+ goto input_failure;
+ break;
+ }
+ }
+ n = p - p0;
+ if (n == 0)
+ goto match_failure;
+ *p = 0;
+ nassigned++;
+ }
+ nread += n;
+ nconversions++;
+ break;
+
+ case CT_STRING:
+ /* like CCL, but zero-length string OK, & no NOSKIP */
+ if (width == 0)
+ width = (size_t)~0;
+ if (flags & SUPPRESS) {
+ n = 0;
+ while (!isspace(*inp)) {
+ n++, inr--, inp++;
+ if (--width == 0)
+ break;
+ if (inr <= 0)
+ break;
+ }
+ nread += n;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (!isspace(*inp)) {
+ inr--;
+ *p++ = *inp++;
+ if (--width == 0)
+ break;
+ if (inr <= 0)
+ break;
+ }
+ *p = 0;
+ nread += p - p0;
+ nassigned++;
+ }
+ nconversions++;
+ continue;
+
+ case CT_INT:
+ /* scan an integer as if by strtoq/strtouq */
+ /* size_t is unsigned, hence this optimisation */
+ if (--width > sizeof (buf) - 2)
+ width = sizeof (buf) - 2;
+ width++;
+ flags |= SIGNOK | NDIGITS | NZDIGITS;
+ for (p = buf; width; width--) {
+ c = *inp;
+ /*
+ * Switch on the character; `goto ok'
+ * if we accept it as a part of number.
+ */
+ switch (c) {
+
+ /*
+ * The digit 0 is always legal, but is
+ * special. For %i conversions, if no
+ * digits (zero or nonzero) have been
+ * scanned (only signs), we will have
+ * base==0. In that case, we should set
+ * it to 8 and enable 0x prefixing.
+ * Also, if we have not scanned zero digits
+ * before this, do not turn off prefixing
+ * (someone else will turn it off if we
+ * have scanned any nonzero digits).
+ */
+ case '0':
+ if (base == 0) {
+ base = 8;
+ flags |= PFXOK;
+ }
+ if (flags & NZDIGITS)
+ flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
+ else
+ flags &= ~(SIGNOK|PFXOK|NDIGITS);
+ goto ok;
+
+ /* 1 through 7 always legal */
+ case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ base = basefix[base];
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* digits 8 and 9 ok iff decimal or hex */
+ case '8': case '9':
+ base = basefix[base];
+ if (base <= 8)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* letters ok iff hex */
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F':
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f':
+ /* no need to fix base here */
+ if (base <= 10)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* sign ok only as first character */
+ case '+': case '-':
+ if (flags & SIGNOK) {
+ flags &= ~SIGNOK;
+ goto ok;
+ }
+ break;
+
+ /* x ok iff flag still set & 2nd char */
+ case 'x': case 'X':
+ if (flags & PFXOK && p == buf + 1) {
+ base = 16; /* if %i */
+ flags &= ~PFXOK;
+ goto ok;
+ }
+ break;
+ }
+
+ /*
+ * If we got here, c is not a legal character
+ * for a number. Stop accumulating digits.
+ */
+ break;
+ ok:
+ /*
+ * c is legal: store it and look at the next.
+ */
+ *p++ = c;
+ if (--inr > 0)
+ inp++;
+ else
+ break; /* end of input */
+ }
+ /*
+ * If we had only a sign, it is no good; push
+ * back the sign. If the number ends in `x',
+ * it was [sign] '0' 'x', so push back the x
+ * and treat it as [sign] '0'.
+ */
+ if (flags & NDIGITS) {
+ if (p > buf) {
+ inp--;
+ inr++;
+ }
+ goto match_failure;
+ }
+ c = ((uchar_t *)p)[-1];
+ if (c == 'x' || c == 'X') {
+ --p;
+ inp--;
+ inr++;
+ }
+ if ((flags & SUPPRESS) == 0) {
+ ulong_t res;
+
+ *p = 0;
+ if (sconv)
+ (void) ddi_strtol(buf, (char **)NULL,
+ base, (long *)(&res));
+ else
+ (void) ddi_strtoul(buf, (char **)NULL,
+ base, &res);
+ if (flags & POINTER)
+ *va_arg(ap, void **) =
+ (void *)(uintptr_t)res;
+ else if (flags & SHORT)
+ *va_arg(ap, short *) = (short)res;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = (long)res;
+ else
+ *va_arg(ap, int *) = (int)res;
+ nassigned++;
+ }
+ nread += p - buf;
+ nconversions++;
+ break;
+
+ }
+ }
+input_failure:
+ return (nconversions != 0 ? nassigned : -1);
+match_failure:
+ return (nassigned);
+}
+
+/*
+ * Fill in the given table from the scanset at the given format
+ * (just after `['). Return a pointer to the character past the
+ * closing `]'. The table has a 1 wherever characters should be
+ * considered part of the scanset.
+ */
+static const uchar_t *
+set_ccl(char *tab, const uchar_t *fmt)
+{
+ int c, n, v;
+
+ /* first `clear' the whole table */
+ c = *fmt++; /* first char hat => negated scanset */
+ if (c == '^') {
+ v = 1; /* default => accept */
+ c = *fmt++; /* get new first char */
+ } else
+ v = 0; /* default => reject */
+
+ /* XXX: Will not work if sizeof(tab*) > sizeof(char) */
+ for (n = 0; n < 256; n++)
+ tab[n] = v; /* memset(tab, v, 256) */
+
+ if (c == 0)
+ return (fmt - 1); /* format ended before closing ] */
+
+ /*
+ * Now set the entries corresponding to the actual scanset
+ * to the opposite of the above.
+ *
+ * The first character may be ']' (or '-') without being special;
+ * the last character may be '-'.
+ */
+ v = 1 - v;
+ for (;;) {
+ tab[c] = v; /* take character c */
+doswitch:
+ n = *fmt++; /* and examine the next */
+ switch (n) {
+
+ case 0: /* format ended too soon */
+ return (fmt - 1);
+
+ case '-':
+ /*
+ * A scanset of the form
+ * [01+-]
+ * is defined as `the digit 0, the digit 1,
+ * the character +, the character -', but
+ * the effect of a scanset such as
+ * [a-zA-Z0-9]
+ * is implementation defined. The V7 Unix
+ * scanf treats `a-z' as `the letters a through
+ * z', but treats `a-a' as `the letter a, the
+ * character -, and the letter a'.
+ *
+ * For compatibility, the `-' is not considerd
+ * to define a range if the character following
+ * it is either a close bracket (required by ANSI)
+ * or is not numerically greater than the character
+ * we just stored in the table (c).
+ */
+ n = *fmt;
+ if (n == ']' || n < c) {
+ c = '-';
+ break; /* resume the for(;;) */
+ }
+ fmt++;
+ /* fill in the range */
+ do {
+ tab[++c] = v;
+ } while (c < n);
+ c = n;
+ /*
+ * Alas, the V7 Unix scanf also treats formats
+ * such as [a-c-e] as `the letters a through e'.
+ * This too is permitted by the standard....
+ */
+ goto doswitch;
+ /* NOTREACHED */
+
+ case ']': /* end of scanset */
+ return (fmt);
+
+ default: /* just another character */
+ c = n;
+ break;
+ }
+ }
+ /* NOTREACHED */
+}
+
+int
+sscanf(const char *ibuf, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = vsscanf(ibuf, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/usr/src/common/util/sscanf.h b/usr/src/common/util/sscanf.h
new file mode 100644
index 0000000000..8ca717b9c1
--- /dev/null
+++ b/usr/src/common/util/sscanf.h
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _COMMON_UTIL_SSCANF_H
+#define _COMMON_UTIL_SSCANF_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/varargs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*SCANFLIKE2*/
+extern int sscanf(const char *, const char *, ...);
+extern int vsscanf(const char *, const char *, va_list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COMMON_UTIL_SSCANF_H */
diff --git a/usr/src/common/util/string.c b/usr/src/common/util/string.c
index 59a6139324..94153d2db2 100644
--- a/usr/src/common/util/string.c
+++ b/usr/src/common/util/string.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,19 +33,25 @@
#include <sys/types.h>
#include <sys/varargs.h>
-#if defined(_BOOT) || defined(_KMDB)
-#include <string.h>
-#else
+
+#if defined(_KERNEL)
#include <sys/systm.h>
-#endif
-#ifdef _KERNEL
#include <sys/debug.h>
-#endif /* _KERNEL */
+#elif !defined(_BOOT)
+#include <string.h>
+#endif
+
+#ifndef NULL
+#define NULL 0l
+#endif
+
+#include "memcpy.h"
+#include "string.h"
/*
- * kmdb has its own *printf routines, and thus doesn't need these versions too.
+ * We don't need these for x86 boot or kmdb.
*/
-#if !defined(_KMDB)
+#if !defined(_KMDB) && (!defined(_BOOT) || defined(__sparc))
#define ADDCHAR(c) if (bufp++ - buf < buflen) bufp[-1] = (c)
@@ -322,7 +328,7 @@ snprintf(char *buf, size_t buflen, const char *fmt, ...)
return (buflen);
}
-#if defined(_BOOT)
+#if defined(_BOOT) && defined(__sparc)
/*
* The sprintf() and vsprintf() routines aren't shared with the kernel because
* the DDI mandates that they return the buffer rather than its length.
@@ -346,9 +352,9 @@ vsprintf(char *buf, const char *fmt, va_list args)
(void) vsnprintf(buf, INT_MAX, fmt, args);
return (strlen(buf));
}
-#endif
+#endif /* _BOOT && __sparc */
-#endif /* !_KMDB */
+#endif /* !_KMDB && (!_BOOT || __sparc) */
char *
strcat(char *s1, const char *s2)
@@ -571,7 +577,8 @@ strlcat(char *dst, const char *src, size_t dstsize)
while (left-- != 0 && *df != '\0')
df++;
- l1 = df - dst;
+ /*LINTED: possible ptrdiff_t overflow*/
+ l1 = (size_t)(df - dst);
if (dstsize == l1)
return (l1 + l2);
@@ -611,7 +618,8 @@ strspn(const char *string, const char *charset)
break;
}
- return (q - string);
+ /*LINTED: possible ptrdiff_t overflow*/
+ return ((size_t)(q - string));
}
/*
diff --git a/usr/src/common/util/string.h b/usr/src/common/util/string.h
new file mode 100644
index 0000000000..c7db1bf967
--- /dev/null
+++ b/usr/src/common/util/string.h
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _COMMON_UTIL_STRING_H
+#define _COMMON_UTIL_STRING_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_KMDB) && (!defined(_BOOT) || defined(__sparc))
+
+extern size_t vsnprintf(char *, size_t, const char *, va_list);
+/*PRINTFLIKE1*/
+extern size_t snprintf(char *, size_t, const char *, ...);
+
+#if defined(_BOOT) && defined(__sparc)
+
+/*PRINTFLIKE2*/
+extern int sprintf(char *, const char *, ...);
+extern int vsprintf(char *, const char *, va_list);
+
+#endif /* _BOOT && __sparc */
+#endif /* !_KMDB && (!_BOOT || __sparc) */
+
+extern char *strcat(char *, const char *);
+extern char *strchr(const char *, int);
+extern int strcmp(const char *, const char *);
+extern int strncmp(const char *, const char *, size_t);
+extern int strcasecmp(const char *, const char *);
+extern int strncasecmp(const char *, const char *, size_t);
+extern char *strcpy(char *, const char *);
+extern char *strncpy(char *, const char *, size_t);
+extern char *strrchr(const char *, int c);
+extern char *strstr(const char *, const char *);
+extern char *strpbrk(const char *, const char *);
+extern char *strncat(char *, const char *, size_t);
+extern size_t strlcat(char *, const char *, size_t);
+extern size_t strlcpy(char *, const char *, size_t);
+extern size_t strspn(const char *, const char *);
+
+#if defined(_BOOT) || defined(_KMDB)
+
+extern char *strtok(char *, const char *);
+extern size_t strlen(const char *);
+
+#endif /* _BOOT || _KMDB */
+
+#ifdef _KERNEL
+
+extern int strident_valid(const char *);
+extern void strident_canon(char *, size_t);
+
+#endif /* _KERNEL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COMMON_UTIL_STRING_H */
diff --git a/usr/src/grub/grub-0.95/grub/asmstub.c b/usr/src/grub/grub-0.95/grub/asmstub.c
index d71fe5c6f3..b7edddd52f 100644
--- a/usr/src/grub/grub-0.95/grub/asmstub.c
+++ b/usr/src/grub/grub-0.95/grub/asmstub.c
@@ -1281,3 +1281,30 @@ hercules_setcursor (int on)
{
return 1;
}
+
+uint32_t amd64_cpuid_supported(void)
+{
+ /* Nothing to do in the simulator. */
+ return (1);
+}
+
+void amd64_cpuid_insn(uint32_t i, void * r)
+{
+ /* Nothing to do in the simulator. */
+}
+
+void amd64_rdmsr(uint32_t i, uint64_t * p)
+{
+ /* Nothing to do in the simulator. */
+}
+
+void amd64_wrmsr(uint32_t i, const uint64_t * p)
+{
+ /* Nothing to do in the simulator. */
+}
+
+int get_target_operating_mode(void)
+{
+ /* Nothing to do in the simulator. */
+ return (1);
+}
diff --git a/usr/src/grub/grub-0.95/stage2/asm.S b/usr/src/grub/grub-0.95/stage2/asm.S
index 1aa6eaed06..1952421725 100644
--- a/usr/src/grub/grub-0.95/stage2/asm.S
+++ b/usr/src/grub/grub-0.95/stage2/asm.S
@@ -2595,7 +2595,81 @@ ENTRY(currticks)
popl %ebp
ret
-#endif /* STAGE1_5 */
+ENTRY(amd64_rdmsr)
+ movl 4(%esp), %ecx
+ rdmsr
+ movl 8(%esp), %ecx
+ movl %eax, (%ecx)
+ movl %edx, 4(%ecx)
+ ret
+
+ENTRY(amd64_wrmsr)
+ movl 8(%esp), %ecx
+ movl (%ecx), %eax
+ movl 4(%ecx), %edx
+ movl 4(%esp), %ecx
+ wrmsr
+ ret
+
+ENTRY(amd64_cpuid_insn)
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ebx
+ pushl %esi
+ movl 0x8(%ebp), %eax
+ movl 0xc(%ebp), %esi
+ cpuid
+ movl %eax, 0x0(%esi)
+ movl %ebx, 0x4(%esi)
+ movl %ecx, 0x8(%esi)
+ movl %edx, 0xc(%esi)
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+
+ /*
+ * Based on code from AMD64 Volume 3
+ */
+ENTRY(amd64_cpuid_supported)
+ pushf
+ popl %eax
+ mov %eax, %edx /* save %eax for later */
+ xorl %eax, 0x200000 /* toggle bit 21 */
+ pushl %eax
+ popf /* save new %eax to EFLAGS */
+ pushf /* save new EFLAGS */
+ popl %ecx /* copy EFLAGS to %eax */
+ xorl %eax, %eax
+ cmpl %ecx, %edx /* see if bit 21 has changes */
+ jne 1f
+ incl %eax
+1:
+ ret
+
+ENTRY(get_target_operating_mode)
+ pusha
+
+ call EXT_C(prot_to_real)
+ .code16
+
+ movw $0xec00, %ax
+ movw $0x03, %bx
+ int $0x15
+/* XXX still need to pass back return */
+
+ movw %ax, %cx
+
+ DATA32 call EXT_C(real_to_prot)
+ .code32
+
+ xorl %eax, %eax
+ movw %cx, %ax
+
+ popa
+ ret
+
+#endif /* ! STAGE1_5 */
/*
* This is the area for all of the special variables.
diff --git a/usr/src/grub/grub-0.95/stage2/builtins.c b/usr/src/grub/grub-0.95/stage2/builtins.c
index bdc3fe4e45..b7d0aaa00a 100644
--- a/usr/src/grub/grub-0.95/stage2/builtins.c
+++ b/usr/src/grub/grub-0.95/stage2/builtins.c
@@ -48,6 +48,8 @@
# include <md5.h>
#endif
+#include <cpu.h>
+
/* The type of kernel loaded. */
kernel_t kernel_type;
/* The boot device. */
@@ -989,7 +991,7 @@ static int verbose_func(char *arg, int flags) {
silent.status = VERBOSE;
- /* get back to text console XXX setje -- tty??? */
+ /* get back to text console */
if (current_term->shutdown) {
(*current_term->shutdown)();
current_term = term_table; /* assumption: console is first */
@@ -2716,6 +2718,280 @@ static struct builtin builtin_kernel =
" Linux's mem option automatically."
};
+
+static int detect_target_operating_mode();
+
+int
+amd64_config_cpu(void)
+{
+ struct amd64_cpuid_regs __vcr, *vcr = &__vcr;
+ uint32_t maxeax;
+ uint32_t max_maxeax = 0x100;
+ char vendor[13];
+ int isamd64 = 0;
+ uint32_t stdfeatures = 0, xtdfeatures = 0;
+ uint64_t efer;
+
+ /*
+ * This check may seem silly, but if the C preprocesor symbol __amd64
+ * is #defined during compilation, something that may outwardly seem
+ * like a good idea, uts/common/sys/isa_defs.h will #define _LP64,
+ * which will cause uts/common/sys/int_types.h to typedef uint64_t as
+ * an unsigned long - which is only 4 bytes in size when using a 32-bit
+ * compiler.
+ *
+ * If that happens, all the page table translation routines will fail
+ * horribly, so check the size of uint64_t just to insure some degree
+ * of sanity in future operations.
+ */
+ /*LINTED [sizeof result is invarient]*/
+ if (sizeof (uint64_t) != 8)
+ prom_panic("grub compiled improperly, unable to boot "
+ "64-bit AMD64 executables");
+
+ /*
+ * If the CPU doesn't support the CPUID instruction, it's definitely
+ * not an AMD64.
+ */
+ if (amd64_cpuid_supported() == 0)
+ return (0);
+
+ amd64_cpuid_insn(0, vcr);
+
+ maxeax = vcr->r_eax;
+ {
+ /*LINTED [vendor string from cpuid data]*/
+ uint32_t *iptr = (uint32_t *)vendor;
+
+ *iptr++ = vcr->r_ebx;
+ *iptr++ = vcr->r_edx;
+ *iptr++ = vcr->r_ecx;
+
+ vendor[12] = '\0';
+ }
+
+ if (maxeax > max_maxeax) {
+ grub_printf("cpu: warning, maxeax was 0x%x -> 0x%x\n",
+ maxeax, max_maxeax);
+ maxeax = max_maxeax;
+ }
+
+ if (maxeax < 1)
+ return (0); /* no additional functions, not an AMD64 */
+ else {
+ uint_t family, model, step;
+
+ amd64_cpuid_insn(1, vcr);
+
+ /*
+ * All AMD64/IA32e processors technically SHOULD report
+ * themselves as being in family 0xf, but for some reason
+ * Simics doesn't, and this may change in the future, so
+ * don't error out if it's not true.
+ */
+ if ((family = BITX(vcr->r_eax, 11, 8)) == 0xf)
+ family += BITX(vcr->r_eax, 27, 20);
+
+ if ((model = BITX(vcr->r_eax, 7, 4)) == 0xf)
+ model += BITX(vcr->r_eax, 19, 16) << 4;
+ step = BITX(vcr->r_eax, 3, 0);
+
+ grub_printf("cpu: '%s' family %d model %d step %d\n",
+ vendor, family, model, step);
+ stdfeatures = vcr->r_edx;
+ }
+
+ amd64_cpuid_insn(0x80000000, vcr);
+
+ if (vcr->r_eax & 0x80000000) {
+ uint32_t xmaxeax = vcr->r_eax;
+ const uint32_t max_xmaxeax = 0x80000100;
+
+ if (xmaxeax > max_xmaxeax) {
+ grub_printf("amd64: warning, xmaxeax was "
+ "0x%x -> 0x%x\n", xmaxeax, max_xmaxeax);
+ xmaxeax = max_xmaxeax;
+ }
+
+ if (xmaxeax >= 0x80000001) {
+ amd64_cpuid_insn(0x80000001, vcr);
+ xtdfeatures = vcr->r_edx;
+ }
+ }
+
+ if (BITX(xtdfeatures, 29, 29)) /* long mode */
+ isamd64++;
+ else
+ grub_printf("amd64: CPU does NOT support long mode\n");
+
+ if (!BITX(stdfeatures, 0, 0)) {
+ grub_printf("amd64: CPU does NOT support FPU\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 4, 4)) {
+ grub_printf("amd64: CPU does NOT support TSC\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 5, 5)) {
+ grub_printf("amd64: CPU does NOT support MSRs\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 6, 6)) {
+ grub_printf("amd64: CPU does NOT support PAE\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 8, 8)) {
+ grub_printf("amd64: CPU does NOT support CX8\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 13, 13)) {
+ grub_printf("amd64: CPU does NOT support PGE\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 17, 17)) {
+ grub_printf("amd64: CPU does NOT support PSE\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 19, 19)) {
+ grub_printf("amd64: CPU does NOT support CLFSH\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 23, 23)) {
+ grub_printf("amd64: CPU does NOT support MMX\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 24, 24)) {
+ grub_printf("amd64: CPU does NOT support FXSR\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 25, 25)) {
+ grub_printf("amd64: CPU does NOT support SSE\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 26, 26)) {
+ grub_printf("amd64: CPU does NOT support SSE2\n");
+ isamd64--;
+ }
+
+ if (isamd64 < 1) {
+ grub_printf("amd64: CPU does not support amd64 executables.\n");
+ return (0);
+ }
+
+ amd64_rdmsr(MSR_AMD_EFER, &efer);
+ if (efer & AMD_EFER_SCE)
+ grub_printf("amd64: EFER_SCE (syscall/sysret) already "
+ "enabled\n");
+ if (efer & AMD_EFER_NXE)
+ grub_printf("amd64: EFER_NXE (no-exec prot) already enabled\n");
+ if (efer & AMD_EFER_LME)
+ grub_printf("amd64: EFER_LME (long mode) already enabled\n");
+
+ return (detect_target_operating_mode());
+}
+
+static int
+detect_target_operating_mode()
+{
+ int ret, ah;
+
+ ah = get_target_operating_mode();
+
+ ah = ah >> 8;
+
+ /* XXX still need to pass back the return from the call */
+ ret = 0;
+
+ if (ah == 0x86 && (ret & CB) != 0) {
+ grub_printf("[BIOS 'Detect Target Operating Mode' "
+ "callback unsupported on this platform]\n");
+ return (1); /* unsupported, ignore */
+ }
+
+ if (ah == 0x0 && (ret & CB) == 0) {
+ grub_printf("[BIOS accepted mixed-mode target setting!]\n");
+ return (1); /* told the bios what we're up to */
+ }
+
+ if (ah == 0 && ret & CB) {
+ grub_printf("fatal: BIOS reports this machine CANNOT run in "
+ "mixed 32/64-bit mode!\n");
+ return (0);
+ }
+
+ grub_printf("warning: BIOS Detect Target Operating Mode callback "
+ "confused.\n %%ax >> 8 = 0x%x, carry = %d\n", ah,
+ ret & CB ? 1 : 0);
+
+ return (1);
+}
+
+
+int
+isamd64()
+{
+ static int ret = -1;
+
+ if (ret == -1)
+ ret = amd64_config_cpu();
+
+ return (ret);
+}
+
+static int
+expand_arch (char *arg, int flags, int func())
+{
+ char newarg[MAX_CMDLINE]; /* everything boils down to MAX_CMDLINE */
+ char *index;
+
+ newarg[0] = '\0';
+
+ while ((index = strstr(arg, "$ISADIR")) != NULL) {
+
+ index[0] = '\0';
+ strncat(newarg, arg, MAX_CMDLINE);
+ index[0] = '$';
+
+ if (isamd64())
+ strncat(newarg, "amd64", MAX_CMDLINE);
+
+ arg = index + 7;
+ }
+
+ strncat(newarg, arg, MAX_CMDLINE);
+
+ grub_printf("loading %s\n", newarg);
+
+ return (func(newarg, flags));
+}
+
+/* kernel$ */
+static int
+kernel_dollar_func (char *arg, int flags)
+{
+ return (expand_arch(arg, flags, (void *)&kernel_func));
+}
+
+static struct builtin builtin_kernel_dollar =
+{
+ "kernel$",
+ kernel_dollar_func,
+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+ "kernel$ [--no-mem-option] [--type=TYPE] FILE [ARG ...]",
+ " Just like kernel, but with $ISADIR expansion."
+};
+
/* lock */
static int
@@ -2931,6 +3207,22 @@ static struct builtin builtin_module =
" the `kernel' command."
};
+/* module$ */
+static int
+module_dollar_func (char *arg, int flags)
+{
+ return (expand_arch(arg, flags, (void *)&module_func));
+}
+
+static struct builtin builtin_module_dollar =
+{
+ "module$",
+ module_dollar_func,
+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+ "module FILE [ARG ...]",
+ " Just like module, but with $ISADIR expansion."
+};
+
/* modulenounzip */
static int
@@ -5148,6 +5440,7 @@ struct builtin *builtin_table[] =
&builtin_install,
&builtin_ioprobe,
&builtin_kernel,
+ &builtin_kernel_dollar,
&builtin_lock,
&builtin_makeactive,
&builtin_map,
@@ -5155,6 +5448,7 @@ struct builtin *builtin_table[] =
&builtin_md5crypt,
#endif /* USE_MD5_PASSWORDS */
&builtin_module,
+ &builtin_module_dollar,
&builtin_modulenounzip,
&builtin_pager,
&builtin_partnew,
diff --git a/usr/src/grub/grub-0.95/stage2/controlregs.h b/usr/src/grub/grub-0.95/stage2/controlregs.h
new file mode 100644
index 0000000000..dc675f603f
--- /dev/null
+++ b/usr/src/grub/grub-0.95/stage2/controlregs.h
@@ -0,0 +1,161 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_CONTROLREGS_H
+#define _SYS_CONTROLREGS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file describes the x86 architecture control registers which
+ * are part of the privileged architecture.
+ *
+ * Many of these definitions are shared between IA-32-style and
+ * AMD64-style processors.
+ */
+
+/* CR0 Register */
+
+#define CR0_PG 0x80000000 /* paging enabled */
+#define CR0_CD 0x40000000 /* cache disable */
+#define CR0_NW 0x20000000 /* not writethrough */
+#define CR0_AM 0x00040000 /* alignment mask */
+#define CR0_WP 0x00010000 /* write protect */
+#define CR0_NE 0x00000020 /* numeric error */
+#define CR0_ET 0x00000010 /* extension type */
+#define CR0_TS 0x00000008 /* task switch */
+#define CR0_EM 0x00000004 /* emulation */
+#define CR0_MP 0x00000002 /* monitor coprocessor */
+#define CR0_PE 0x00000001 /* protection enabled */
+
+/* XX64 eliminate these compatibility defines */
+
+#define CR0_CE CR0_CD
+#define CR0_WT CR0_NW
+
+#define FMT_CR0 \
+ "\20\40pg\37cd\36nw\35am\21wp\6ne\5et\4ts\3em\2mp\1pe"
+
+/* CR3 Register */
+
+#define CR3_PCD 0x00000010 /* cache disable */
+#define CR3_PWT 0x00000008 /* write through */
+
+#define FMT_CR3 "\20\5pcd\4pwt"
+
+/* CR4 Register */
+
+#define CR4_VME 0x0001 /* virtual-8086 mode extensions */
+#define CR4_PVI 0x0002 /* protected-mode virtual interrupts */
+#define CR4_TSD 0x0004 /* time stamp disable */
+#define CR4_DE 0x0008 /* debugging extensions */
+#define CR4_PSE 0x0010 /* page size extensions */
+#define CR4_PAE 0x0020 /* physical address extension */
+#define CR4_MCE 0x0040 /* machine check enable */
+#define CR4_PGE 0x0080 /* page global enable */
+#define CR4_PCE 0x0100 /* perf-monitoring counter enable */
+#define CR4_OSFXSR 0x0200 /* OS fxsave/fxrstor support */
+#define CR4_OSXMMEXCPT 0x0400 /* OS unmasked exception support */
+
+#define FMT_CR4 \
+ "\20\13xmme\12fxsr\11pce\10pge\7mce\6pae\5pse\4de\3tsd\2pvi\1vme"
+
+/* Intel's SYSENTER configuration registers */
+
+#define MSR_INTC_SEP_CS 0x174 /* kernel code selector MSR */
+#define MSR_INTC_SEP_ESP 0x175 /* kernel esp MSR */
+#define MSR_INTC_SEP_EIP 0x176 /* kernel eip MSR */
+
+/* AMD's EFER register */
+
+#define MSR_AMD_EFER 0xc0000080 /* extended feature enable MSR */
+
+#define AMD_EFER_NXE 0x800 /* no-execute enable */
+#define AMD_EFER_LMA 0x400 /* long mode active (read-only) */
+#define AMD_EFER_LME 0x100 /* long mode enable */
+#define AMD_EFER_SCE 0x001 /* system call extensions */
+
+#define FMT_AMD_EFER \
+ "\20\14nxe\13lma\11lme\1sce"
+
+/* AMD's SYSCFG register */
+
+#define MSR_AMD_SYSCFG 0xc0000010 /* system configuration MSR */
+
+#define AMD_SYSCFG_TOM2 0x200000 /* MtrrTom2En */
+#define AMD_SYSCFG_MVDM 0x100000 /* MtrrVarDramEn */
+#define AMD_SYSCFG_MFDM 0x080000 /* MtrrFixDramModEn */
+#define AMD_SYSCFG_MFDE 0x040000 /* MtrrFixDramEn */
+
+#define FMT_AMD_SYSCFG \
+ "\20\26tom2\25mvdm\24mfdm\23mfde"
+
+/* AMD's syscall/sysret MSRs */
+
+#define MSR_AMD_STAR 0xc0000081 /* %cs:%ss:%cs:%ss:%eip for syscall */
+#define MSR_AMD_LSTAR 0xc0000082 /* target %rip of 64-bit syscall */
+#define MSR_AMD_CSTAR 0xc0000083 /* target %rip of 32-bit syscall */
+#define MSR_AMD_SFMASK 0xc0000084 /* syscall flag mask */
+
+/* AMD's FS.base and GS.base MSRs */
+
+#define MSR_AMD_FSBASE 0xc0000100 /* 64-bit base address for %fs */
+#define MSR_AMD_GSBASE 0xc0000101 /* 64-bit base address for %gs */
+#define MSR_AMD_KGSBASE 0xc0000102 /* swapgs swaps this with gsbase */
+
+/* AMD's configuration MSRs, weakly documented in the revision guide */
+
+#define MSR_AMD_DC_CFG 0xc0011022
+
+#define AMD_DC_CFG_DIS_CNV_WC_SSO (UINT64_C(1) << 3)
+#define AMD_DC_CFG_DIS_SMC_CHK_BUF (UINT64_C(1) << 10)
+
+/* AMD's HWCR MSR */
+
+#define MSR_AMD_HWCR 0xc0010015
+
+#define AMD_HWCR_FFDIS 0x00040 /* disable TLB Flush Filter */
+#define AMD_HWCR_MCI_STATUS_WREN 0x40000 /* enable write of MCi_STATUS */
+
+/* AMD's NorthBridge Config MSR, SHOULD ONLY BE WRITTEN TO BY BIOS */
+
+#define MSR_AMD_NB_CFG 0xc001001f
+
+#define MSR_BU_CFG 0xc0011023
+
+#define AMD_NB_CFG_SRQ_HEARTBEAT (UINT64_C(1) << 20)
+#define AMD_NB_CFG_SRQ_SPR (UINT64_C(1) << 32)
+
+/* AMD */
+#define MSR_AMD_PATCHLEVEL 0x8b
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_SYS_CONTROLREGS_H */
diff --git a/usr/src/grub/grub-0.95/stage2/cpu.h b/usr/src/grub/grub-0.95/stage2/cpu.h
new file mode 100644
index 0000000000..34180727d9
--- /dev/null
+++ b/usr/src/grub/grub-0.95/stage2/cpu.h
@@ -0,0 +1,73 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _AMD64_CPU
+#define _AMD64_CPU
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned int uint_t;
+typedef unsigned long ulong_t;
+
+#define BITX(u, h, l) (((u) >> (l)) & ((1lu << ((h) - (l) + 1lu)) - 1lu))
+
+#include <controlregs.h>
+
+#define CB 0x0001
+
+extern void amd64_flush_tlb(void);
+extern void amd64_flush_tlbentry(caddr_t);
+
+extern ulong_t amd64_get_cr2(void);
+extern ulong_t amd64_get_cr0(void);
+extern ulong_t amd64_get_cr3(void);
+extern ulong_t amd64_get_cr4(void);
+
+extern ulong_t amd64_get_eflags(void);
+
+struct amd64_cpuid_regs {
+ uint32_t r_eax;
+ uint32_t r_ebx;
+ uint32_t r_ecx;
+ uint32_t r_edx;
+};
+
+#define AMD64_Auth 0x68747541
+#define AMD64_enti 0x69746e65
+#define AMD64_cAMD 0x444d4163
+
+extern uint32_t amd64_cpuid_supported(void);
+extern void amd64_cpuid_insn(uint32_t, struct amd64_cpuid_regs *);
+extern void amd64_rdmsr(uint32_t, uint64_t *);
+extern void amd64_wrmsr(uint32_t, const uint64_t *);
+extern int get_target_operating_mode(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _AMD64_CPU */
diff --git a/usr/src/grub/install_menu b/usr/src/grub/install_menu
index f856e75e07..d2f0c52204 100644
--- a/usr/src/grub/install_menu
+++ b/usr/src/grub/install_menu
@@ -4,14 +4,14 @@
default=0
timeout=60
title Solaris Express, Developer Edition
- kernel /boot/multiboot kernel/unix -B install_media=cdrom,soldevx=true
+ kernel /boot/platform/i86pc/kernel/unix -B install_media=cdrom,soldevx=true
module /boot/x86.miniroot
title Solaris Express
- kernel /boot/multiboot kernel/unix -B install_media=cdrom
+ kernel /boot/platform/i86pc/kernel/unix -B install_media=cdrom
module /boot/x86.miniroot
title Solaris Express Serial Console ttya
- kernel /boot/multiboot kernel/unix -B install_media=cdrom,console=ttya
+ kernel /boot/platform/i86pc/kernel/unix -B install_media=cdrom,console=ttya
module /boot/x86.miniroot
title Solaris Express Serial Console ttyb (for lx50, v60x and v65x)
- kernel /boot/multiboot kernel/unix -B install_media=cdrom,console=ttyb
+ kernel /boot/platform/i86pc/kernel/unix -B install_media=cdrom,console=ttyb
module /boot/x86.miniroot
diff --git a/usr/src/grub/menu.lst b/usr/src/grub/menu.lst
index 41105017e0..8225e83928 100644
--- a/usr/src/grub/menu.lst
+++ b/usr/src/grub/menu.lst
@@ -31,14 +31,17 @@ timeout 10
# makeactive
#
# To load a Solaris instance based on grub
+# If GRUB determines if the booting system is 64-bit capable,
+# the kernel$ and module$ commands expand $ISADIR to "amd64"
#
# title Solaris <version>
# root (hd<disk no>,<partition no>,x) --x = Solaris root slice
-# kernel /platform/i86pc/multiboot
-# module /platform/i86pc/boot_archive
+# kernel$ /platform/i86pc/kernel/$ISADIR/unix
+# module$ /platform/i86pc/$ISADIR/boot_archive
+
#
# To override Solaris boot args (see kernel(1M)), console device and
# properties set via eeprom(1M) edit the "kernel" line to:
#
-# kernel /platform/i86pc/multiboot <boot-args> -B prop1=val1,prop2=val2,...
+# kernel /platform/i86pc/kernel/unix <boot-args> -B prop1=val1,prop2=val2,...
#
diff --git a/usr/src/lib/libc/amd64/threads/amd64.il b/usr/src/lib/libc/amd64/threads/amd64.il
index fd1e080571..92b55caaad 100644
--- a/usr/src/lib/libc/amd64/threads/amd64.il
+++ b/usr/src/lib/libc/amd64/threads/amd64.il
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,12 +29,7 @@
.end
.inline __curthread, 0
- xorq %rax, %rax
- movw %fs, %ax
- andq %rax, %rax
- je 1f
movq %fs:0, %rax
-1:
.end
.inline stkptr, 0
diff --git a/usr/src/lib/libc/amd64/threads/machdep.c b/usr/src/lib/libc/amd64/threads/machdep.c
index dd8b7e3e3b..d600fb4cd5 100644
--- a/usr/src/lib/libc/amd64/threads/machdep.c
+++ b/usr/src/lib/libc/amd64/threads/machdep.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,8 +45,7 @@ setup_context(ucontext_t *ucp, void *(*func)(ulwp_t *),
/* setup to store the current thread pointer in %fs */
ucp->uc_mcontext.gregs[REG_FSBASE] = (greg_t)ulwp;
- ulwp->ul_gs = LWPFS_SEL;
- ucp->uc_mcontext.gregs[REG_FS] = (greg_t)ulwp->ul_gs;
+ ucp->uc_mcontext.gregs[REG_FS] = 0; /* null selector indicates fsbase */
/* all contexts should have a valid data segment descriptor for %ss */
ucp->uc_mcontext.gregs[REG_SS] = UDS_SEL;
diff --git a/usr/src/lib/libc/i386/threads/i386.il b/usr/src/lib/libc/i386/threads/i386.il
index f0606c7f79..e37be525e2 100644
--- a/usr/src/lib/libc/i386/threads/i386.il
+++ b/usr/src/lib/libc/i386/threads/i386.il
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,12 +30,7 @@
.end
.inline __curthread, 0
- xorl %eax, %eax
- movw %gs, %ax
- andl %eax, %eax
- je 1f
movl %gs:0, %eax
-1:
.end
.inline stkptr, 0
diff --git a/usr/src/lib/libc/i386/threads/machdep.c b/usr/src/lib/libc/i386/threads/machdep.c
index 9062a29d9b..56e7446924 100644
--- a/usr/src/lib/libc/i386/threads/machdep.c
+++ b/usr/src/lib/libc/i386/threads/machdep.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -74,8 +73,7 @@ setup_context(ucontext_t *ucp, void *(*func)(ulwp_t *),
* on the other side of __lwp_create().
*/
ucp->uc_mcontext.gregs[ESP] = (greg_t)ulwp;
- ulwp->ul_gs = LWPGS_SEL;
- ucp->uc_mcontext.gregs[GS] = (greg_t)ulwp->ul_gs;
+ ucp->uc_mcontext.gregs[GS] = (greg_t)LWPGS_SEL;
/* top-of-stack must be rounded down to STACK_ALIGN */
stack = (uint32_t *)(((uintptr_t)stk + stksize) & ~(STACK_ALIGN-1));
diff --git a/usr/src/lib/libc/inc/thr_inlines.h b/usr/src/lib/libc/inc/thr_inlines.h
index e49ac97501..4e2f469488 100644
--- a/usr/src/lib/libc/inc/thr_inlines.h
+++ b/usr/src/lib/libc/inc/thr_inlines.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -56,28 +56,14 @@ __curthread(void)
ulwp_t *__value;
__asm__ __volatile__(
#if defined(__amd64)
- "xorq %0, %0\n\t"
- "mov %%fs, %0\n\t"
- "andq %0, %0\n\t"
- "je 1f\n\t"
"movq %%fs:0, %0\n\t"
#elif defined(__i386)
- "xorl %0, %0\n\t"
- "mov %%gs, %0\n\t"
- "andl %0, %0\n\t"
- "je 1f\n\t"
"movl %%gs:0, %0\n\t"
#elif defined(__sparcv9)
".register %%g7, #scratch\n\t"
- "tst %%g7\n\t"
- "be,a,pn %%xcc, 1f\n\t"
- " mov %%g0, %0\n\t"
"ldx [%%g7 + 80], %0\n\t"
#elif defined(__sparc)
".register %%g7, #scratch\n\t"
- "tst %%g7\n\t"
- "be,a 1f\n\t"
- " mov %%g0, %0\n\t"
"ld [%%g7 + 80], %0\n\t"
#else
#error "port me"
diff --git a/usr/src/lib/libc/inc/thr_uberdata.h b/usr/src/lib/libc/inc/thr_uberdata.h
index b5ecc7a1be..4e14f05997 100644
--- a/usr/src/lib/libc/inc/thr_uberdata.h
+++ b/usr/src/lib/libc/inc/thr_uberdata.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -522,7 +522,7 @@ typedef struct ulwp {
uberflags_t *volatile ul_schedctl_called; /* ul_schedctl is set up */
volatile sc_shared_t *volatile ul_schedctl; /* schedctl data */
int ul_bindflags; /* bind_guard() interface to ld.so.1 */
- int ul_gs; /* x86 only: value of %gs/%fs */
+ int ul_pad2;
tsd_t *ul_stsd; /* slow TLS for keys >= TSD_NFAST */
void *ul_ftsd[TSD_NFAST]; /* fast TLS for keys < TSD_NFAST */
td_evbuf_t ul_td_evbuf; /* event buffer */
@@ -892,7 +892,7 @@ typedef struct ulwp32 {
caddr32_t ul_schedctl_called; /* ul_schedctl is set up */
caddr32_t ul_schedctl; /* schedctl data */
int ul_bindflags; /* bind_guard() interface to ld.so.1 */
- int ul_gs; /* x86 only: value of %gs/%fs */
+ int ul_pad2;
caddr32_t ul_stsd; /* slow TLS for keys >= TSD_NFAST */
caddr32_t ul_ftsd[TSD_NFAST]; /* fast TLS for keys < TSD_NFAST */
td_evbuf32_t ul_td_evbuf; /* event buffer */
diff --git a/usr/src/lib/libc/port/threads/sigaction.c b/usr/src/lib/libc/port/threads/sigaction.c
index 5f65435999..529530f2af 100644
--- a/usr/src/lib/libc/port/threads/sigaction.c
+++ b/usr/src/lib/libc/port/threads/sigaction.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -531,9 +531,9 @@ _private_setcontext(const ucontext_t *ucp)
#if defined(__sparc)
uc.uc_mcontext.gregs[REG_G7] = (greg_t)self;
#elif defined(__amd64)
- uc.uc_mcontext.gregs[REG_FS] = (greg_t)self->ul_gs;
+ uc.uc_mcontext.gregs[REG_FS] = (greg_t)0; /* null for fsbase */
#elif defined(__i386)
- uc.uc_mcontext.gregs[GS] = (greg_t)self->ul_gs;
+ uc.uc_mcontext.gregs[GS] = (greg_t)LWPGS_SEL;
#else
#error "none of __sparc, __amd64, __i386 defined"
#endif
diff --git a/usr/src/lib/libc/port/threads/thr.c b/usr/src/lib/libc/port/threads/thr.c
index ac023cf5aa..4df8a78ade 100644
--- a/usr/src/lib/libc/port/threads/thr.c
+++ b/usr/src/lib/libc/port/threads/thr.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -838,7 +838,6 @@ _thrp_exit()
int ix = self->ul_ix; /* the hash index */
(void) _private_memcpy(replace, self, REPLACEMENT_SIZE);
replace->ul_self = replace;
- replace->ul_gs = 0; /* clone does not carry %gs */
replace->ul_next = NULL; /* clone not on stack list */
replace->ul_mapsiz = 0; /* allows clone to be freed */
replace->ul_replace = 1; /* requires clone to be freed */
@@ -1417,9 +1416,9 @@ libc_init(void)
self->ul_nocancel = 1;
#if defined(__amd64)
- self->ul_gs = ___lwp_private(_LWP_SETPRIVATE, _LWP_FSBASE, self);
+ (void) ___lwp_private(_LWP_SETPRIVATE, _LWP_FSBASE, self);
#elif defined(__i386)
- self->ul_gs = ___lwp_private(_LWP_SETPRIVATE, _LWP_GSBASE, self);
+ (void) ___lwp_private(_LWP_SETPRIVATE, _LWP_GSBASE, self);
#endif /* __i386 || __amd64 */
set_curthread(self); /* redundant on i386 */
/*
diff --git a/usr/src/lib/libc/sparc/threads/sparc.il b/usr/src/lib/libc/sparc/threads/sparc.il
index ba0ff4a938..c3f81e69b3 100644
--- a/usr/src/lib/libc/sparc/threads/sparc.il
+++ b/usr/src/lib/libc/sparc/threads/sparc.il
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,11 +32,7 @@
.inline __curthread, 0
.register %g7, #scratch
- tst %g7
- be,a 1f
- mov %g0, %o0
ld [%g7 + 80], %o0 ! ul_self
-1:
.end
.inline stkptr, 0
diff --git a/usr/src/lib/libc/sparcv9/threads/sparcv9.il b/usr/src/lib/libc/sparcv9/threads/sparcv9.il
index d3fa907f8e..f84623f93c 100644
--- a/usr/src/lib/libc/sparcv9/threads/sparcv9.il
+++ b/usr/src/lib/libc/sparcv9/threads/sparcv9.il
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,11 +32,7 @@
.inline __curthread, 0
.register %g7, #scratch
- tst %g7
- be,a,pn %xcc, 1f
- mov %g0, %o0
ldx [%g7 + 80], %o0 ! ul_self
-1:
.end
.inline stkptr, 0
diff --git a/usr/src/lib/libdtrace/common/dt_module.c b/usr/src/lib/libdtrace/common/dt_module.c
index 46ad7c6529..54f6c87e11 100644
--- a/usr/src/lib/libdtrace/common/dt_module.c
+++ b/usr/src/lib/libdtrace/common/dt_module.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -927,11 +926,14 @@ dtrace_update(dtrace_hdl_t *dtp)
/*
* Cache the pointers to the modules representing the base executable
- * and the run-time linker in the dtrace client handle. We should
- * probably have a more generic way of inquiring as to their names.
+ * and the run-time linker in the dtrace client handle. Note that on
+ * x86 krtld is folded into unix, so if we don't find it, use unix
+ * instead.
*/
dtp->dt_exec = dt_module_lookup_by_name(dtp, "genunix");
dtp->dt_rtld = dt_module_lookup_by_name(dtp, "krtld");
+ if (dtp->dt_rtld == NULL)
+ dtp->dt_rtld = dt_module_lookup_by_name(dtp, "unix");
/*
* If this is the first time we are initializing the module list,
diff --git a/usr/src/pkgdefs/Makefile b/usr/src/pkgdefs/Makefile
index 6a8a27e0e9..7c229c9b37 100644
--- a/usr/src/pkgdefs/Makefile
+++ b/usr/src/pkgdefs/Makefile
@@ -121,9 +121,10 @@ i386_SUBDIRS= \
SUNWdrmr \
SUNWgrub \
SUNWgrubS \
- SUNWkvm.i \
+ SUNWkvm.i \
SUNWlxr \
SUNWlxu \
+ SUNWmv88sx \
SUNWonmtst.i \
SUNWos86r \
SUNWpsdcr \
@@ -134,7 +135,7 @@ i386_SUBDIRS= \
SUNWrtls \
SUNWsi3124 \
SUNWvia823x \
- SUNWmv88sx
+ SUNWxsvc
i386_XMODS= \
SUNWadpu320 \
diff --git a/usr/src/pkgdefs/SUNWagp/prototype_i386 b/usr/src/pkgdefs/SUNWagp/prototype_i386
index 8d6c472610..15be4c0023 100644
--- a/usr/src/pkgdefs/SUNWagp/prototype_i386
+++ b/usr/src/pkgdefs/SUNWagp/prototype_i386
@@ -1,5 +1,5 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -25,15 +25,13 @@
#
# SUNWagp
#
-d none platform 0755 root sys
-d none platform/i86pc 0755 root sys
-d none platform/i86pc/kernel 0755 root sys
-d none platform/i86pc/kernel/drv 0755 root sys
-f none platform/i86pc/kernel/drv/agpgart 0755 root sys
-f none platform/i86pc/kernel/drv/agpgart.conf 0644 root sys
-f none platform/i86pc/kernel/drv/amd64_gart 0755 root sys
-f none platform/i86pc/kernel/drv/agptarget 0755 root sys
-d none platform/i86pc/kernel/drv/amd64 0755 root sys
-f none platform/i86pc/kernel/drv/amd64/agpgart 0755 root sys
-f none platform/i86pc/kernel/drv/amd64/amd64_gart 0755 root sys
-f none platform/i86pc/kernel/drv/amd64/agptarget 0755 root sys
+d none kernel 0755 root sys
+d none kernel/drv 0755 root sys
+f none kernel/drv/agpgart 0755 root sys
+f none kernel/drv/agpgart.conf 0644 root sys
+f none kernel/drv/amd64_gart 0755 root sys
+f none kernel/drv/agptarget 0755 root sys
+d none kernel/drv/amd64 0755 root sys
+f none kernel/drv/amd64/agpgart 0755 root sys
+f none kernel/drv/amd64/amd64_gart 0755 root sys
+f none kernel/drv/amd64/agptarget 0755 root sys
diff --git a/usr/src/pkgdefs/SUNWcakr.i/prototype_com b/usr/src/pkgdefs/SUNWcakr.i/prototype_com
index 2f83aab47d..4c95f6f92f 100644
--- a/usr/src/pkgdefs/SUNWcakr.i/prototype_com
+++ b/usr/src/pkgdefs/SUNWcakr.i/prototype_com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -51,12 +51,17 @@ f none boot/solaris/bin/create_diskmap 0555 root sys
f none boot/solaris/bin/create_ramdisk 0555 root sys
f none boot/solaris/bin/mbr 0555 root sys
s none boot/solaris/bin/root_archive=../../../usr/sbin/root_archive
+f none boot/solaris/bin/symdef 0555 root sys
+f none boot/solaris/bin/update_grub 0555 root sys
f none boot/solaris/filelist.ramdisk 0644 root sys
f none boot/solaris/filelist.safe 0644 root sys
+d none boot/platform 755 root sys
+d none boot/platform/i86pc 755 root sys
+d none boot/platform/i86pc/kernel 755 root sys
+f none boot/platform/i86pc/kernel/unix 755 root sys
d none platform 755 root sys
d none platform/i86pc 755 root sys
-f none platform/i86pc/biosint 755 root sys
-f none platform/i86pc/multiboot 755 root sys
+d none platform/i86pc/amd64 755 root sys
d none platform/i86pc/kernel 755 root sys
d none platform/i86pc/kernel/amd64 755 root sys
f none platform/i86pc/kernel/amd64/unix 755 root sys
@@ -66,54 +71,34 @@ f none platform/i86pc/kernel/cpu/amd64/cpu.AuthenticAMD.15 755 root sys
f none platform/i86pc/kernel/cpu/amd64/cpu.generic 755 root sys
f none platform/i86pc/kernel/cpu/cpu.AuthenticAMD.15 755 root sys
f none platform/i86pc/kernel/cpu/cpu.generic 755 root sys
+d none platform/i86pc/kernel/dacf 755 root sys
+f none platform/i86pc/kernel/dacf/consconfig_dacf 755 root sys
+d none platform/i86pc/kernel/dacf/amd64 755 root sys
+f none platform/i86pc/kernel/dacf/amd64/consconfig_dacf 755 root sys
d none platform/i86pc/kernel/drv 755 root sys
d none platform/i86pc/kernel/drv/amd64 755 root sys
-f none platform/i86pc/kernel/drv/amd64/bmc 755 root sys
-f none platform/i86pc/kernel/drv/amd64/bscbus 755 root sys
-f none platform/i86pc/kernel/drv/amd64/bscv 755 root sys
f none platform/i86pc/kernel/drv/amd64/isa 755 root sys
-f none platform/i86pc/kernel/drv/amd64/kb8042 755 root sys
f none platform/i86pc/kernel/drv/amd64/mc-amd 755 root sys
f none platform/i86pc/kernel/drv/amd64/npe 755 root sys
f none platform/i86pc/kernel/drv/amd64/pci 755 root sys
-f none platform/i86pc/kernel/drv/amd64/pci_pci 755 root sys
-f none platform/i86pc/kernel/drv/amd64/pcie_pci 755 root sys
-f none platform/i86pc/kernel/drv/amd64/power 755 root sys
f none platform/i86pc/kernel/drv/amd64/rootnex 755 root sys
-f none platform/i86pc/kernel/drv/bmc 755 root sys
-f none platform/i86pc/kernel/drv/bmc.conf 644 root sys
-f none platform/i86pc/kernel/drv/bscbus 755 root sys
-f none platform/i86pc/kernel/drv/bscbus.conf 644 root sys
-f none platform/i86pc/kernel/drv/bscv 755 root sys
-f none platform/i86pc/kernel/drv/bscv.conf 644 root sys
f none platform/i86pc/kernel/drv/isa 755 root sys
-f none platform/i86pc/kernel/drv/kb8042 755 root sys
f none platform/i86pc/kernel/drv/mc-amd 755 root sys
f none platform/i86pc/kernel/drv/mc-amd.conf 644 root sys
f none platform/i86pc/kernel/drv/npe 755 root sys
f none platform/i86pc/kernel/drv/pci 755 root sys
-f none platform/i86pc/kernel/drv/pci_pci 755 root sys
-f none platform/i86pc/kernel/drv/pcie_pci 755 root sys
-f none platform/i86pc/kernel/drv/pcie_pci.conf 644 root sys
-f none platform/i86pc/kernel/drv/power 755 root sys
-f none platform/i86pc/kernel/drv/power.conf 644 root sys
f none platform/i86pc/kernel/drv/rootnex 755 root sys
d none platform/i86pc/kernel/mach 755 root sys
+f none platform/i86pc/kernel/mach/pcplusmp 755 root sys
d none platform/i86pc/kernel/mach/amd64 755 root sys
+f none platform/i86pc/kernel/mach/amd64/pcplusmp 755 root sys
f none platform/i86pc/kernel/mach/amd64/uppc 755 root sys
f none platform/i86pc/kernel/mach/uppc 755 root sys
d none platform/i86pc/kernel/misc 755 root sys
d none platform/i86pc/kernel/misc/amd64 755 root sys
-f none platform/i86pc/kernel/misc/amd64/agpmaster 755 root sys
-f none platform/i86pc/kernel/misc/amd64/bootdev 755 root sys
f none platform/i86pc/kernel/misc/amd64/gfx_private 755 root sys
-f none platform/i86pc/kernel/misc/amd64/pci_autoconfig 755 root sys
f none platform/i86pc/kernel/misc/amd64/pcie 755 root sys
-f none platform/i86pc/kernel/misc/amd64/pciehpc 755 root sys
-f none platform/i86pc/kernel/misc/agpmaster 755 root sys
-f none platform/i86pc/kernel/misc/bootdev 755 root sys
f none platform/i86pc/kernel/misc/gfx_private 755 root sys
-f none platform/i86pc/kernel/misc/pci_autoconfig 755 root sys
-f none platform/i86pc/kernel/misc/pciehpc 755 root sys
f none platform/i86pc/kernel/misc/pcie 755 root sys
f none platform/i86pc/kernel/unix 755 root sys
+f none platform/i86pc/multiboot 755 root sys
diff --git a/usr/src/pkgdefs/SUNWckr/prototype_i386 b/usr/src/pkgdefs/SUNWckr/prototype_i386
index 5197d98759..fba5fac922 100644
--- a/usr/src/pkgdefs/SUNWckr/prototype_i386
+++ b/usr/src/pkgdefs/SUNWckr/prototype_i386
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -56,11 +56,16 @@ f none kernel/crypto/rsa 755 root sys
f none kernel/crypto/sha1 755 root sys
f none kernel/crypto/sha2 755 root sys
f none kernel/crypto/swrand 755 root sys
-f none kernel/dacf/consconfig_dacf 755 root sys
f none kernel/devname/sdev_nsconfig_mod 755 root sys
f none kernel/drv/aggr 755 root sys
f none kernel/drv/arp 755 root sys
f none kernel/drv/bl 755 root sys
+f none kernel/drv/bmc 755 root sys
+f none kernel/drv/bmc.conf 644 root sys
+f none kernel/drv/bscbus 755 root sys
+f none kernel/drv/bscbus.conf 644 root sys
+f none kernel/drv/bscv 755 root sys
+f none kernel/drv/bscv.conf 644 root sys
f none kernel/drv/clone 755 root sys
f none kernel/drv/cn 755 root sys
f none kernel/drv/conskbd 755 root sys
@@ -83,6 +88,7 @@ f none kernel/drv/ippctl 755 root sys
f none kernel/drv/ipsecah 755 root sys
f none kernel/drv/ipsecesp 755 root sys
f none kernel/drv/iwscn 755 root sys
+f none kernel/drv/kb8042 755 root sys
f none kernel/drv/keysock 755 root sys
f none kernel/drv/kmdb 755 root sys
f none kernel/drv/kssl 755 root sys
@@ -95,10 +101,15 @@ f none kernel/drv/mpt.conf 644 root sys
f none kernel/drv/mouse8042 755 root sys
f none kernel/drv/openeepr 755 root sys
f none kernel/drv/options 755 root sys
+f none kernel/drv/pci_pci 755 root sys
f none kernel/drv/pci_to_i2o 755 root sys
f none kernel/drv/pci_to_i2o.conf 644 root sys
+f none kernel/drv/pcie_pci 755 root sys
+f none kernel/drv/pcie_pci.conf 644 root sys
f none kernel/drv/physmem 755 root sys
f none kernel/drv/poll 755 root sys
+f none kernel/drv/power 755 root sys
+f none kernel/drv/power.conf 644 root sys
f none kernel/drv/pseudo 755 root sys
f none kernel/drv/ptc 755 root sys
f none kernel/drv/ptsl 755 root sys
@@ -152,6 +163,8 @@ d none boot/acpi/tables 755 root sys
f none kernel/mac/mac_ether 755 root sys
f none kernel/mac/mac_wifi 755 root sys
f none kernel/misc/acpica 755 root sys
+f none kernel/misc/agpmaster 755 root sys
+f none kernel/misc/bootdev 755 root sys
f none kernel/misc/busra 755 root sys
f none kernel/misc/cardbus 755 root sys
f none kernel/misc/cmlb 755 root sys
@@ -168,13 +181,14 @@ f none kernel/misc/ipc 755 root sys
f none kernel/misc/kbtrans 755 root sys
f none kernel/misc/kcf 755 root sys
f none kernel/misc/kmdbmod 755 root sys
-f none kernel/misc/krtld 755 root sys
f none kernel/misc/mac 755 root sys
l none kernel/misc/md5=../../kernel/crypto/md5
f none kernel/misc/net80211 755 root sys
f none kernel/misc/neti 755 root sys
f none kernel/misc/pcicfg 755 root sys
+f none kernel/misc/pciehpc 755 root sys
f none kernel/misc/pcihp 755 root sys
+f none kernel/misc/pci_autoconfig 755 root sys
f none kernel/misc/pcmcia 755 root sys
f none kernel/misc/rpcsec 755 root sys
f none kernel/misc/sata 755 root sys
@@ -184,7 +198,6 @@ l none kernel/misc/sha2=../../kernel/crypto/sha2
f none kernel/misc/strplumb 755 root sys
f none kernel/misc/tem 755 root sys
f none kernel/misc/tlimod 755 root sys
-f none kernel/misc/zmod 755 root sys
f none kernel/sched/TS 755 root sys
f none kernel/sched/TS_DPTBL 755 root sys
f none kernel/strmod/6to4tun 755 root sys
@@ -238,14 +251,15 @@ f none kernel/crypto/amd64/rsa 755 root sys
f none kernel/crypto/amd64/sha1 755 root sys
f none kernel/crypto/amd64/sha2 755 root sys
f none kernel/crypto/amd64/swrand 755 root sys
-d none kernel/dacf/amd64 755 root sys
-f none kernel/dacf/amd64/consconfig_dacf 755 root sys
d none kernel/devname/amd64 755 root sys
f none kernel/devname/amd64/sdev_nsconfig_mod 755 root sys
d none kernel/drv/amd64 755 root sys
f none kernel/drv/amd64/aggr 755 root sys
f none kernel/drv/amd64/arp 755 root sys
f none kernel/drv/amd64/bl 755 root sys
+f none kernel/drv/amd64/bmc 755 root sys
+f none kernel/drv/amd64/bscbus 755 root sys
+f none kernel/drv/amd64/bscv 755 root sys
f none kernel/drv/amd64/clone 755 root sys
f none kernel/drv/amd64/cn 755 root sys
f none kernel/drv/amd64/conskbd 755 root sys
@@ -264,6 +278,7 @@ f none kernel/drv/amd64/ippctl 755 root sys
f none kernel/drv/amd64/ipsecah 755 root sys
f none kernel/drv/amd64/ipsecesp 755 root sys
f none kernel/drv/amd64/iwscn 755 root sys
+f none kernel/drv/amd64/kb8042 755 root sys
f none kernel/drv/amd64/keysock 755 root sys
f none kernel/drv/amd64/kmdb 755 root sys
f none kernel/drv/amd64/kssl 755 root sys
@@ -275,8 +290,11 @@ f none kernel/drv/amd64/mpt 755 root sys
f none kernel/drv/amd64/mouse8042 755 root sys
f none kernel/drv/amd64/openeepr 755 root sys
f none kernel/drv/amd64/options 755 root sys
+f none kernel/drv/amd64/pci_pci 755 root sys
+f none kernel/drv/amd64/pcie_pci 755 root sys
f none kernel/drv/amd64/physmem 755 root sys
f none kernel/drv/amd64/poll 755 root sys
+f none kernel/drv/amd64/power 755 root sys
f none kernel/drv/amd64/pseudo 755 root sys
f none kernel/drv/amd64/ptc 755 root sys
f none kernel/drv/amd64/ptsl 755 root sys
@@ -331,6 +349,8 @@ f none kernel/mac/amd64/mac_ether 755 root sys
f none kernel/mac/amd64/mac_wifi 755 root sys
d none kernel/misc/amd64 755 root sys
f none kernel/misc/amd64/acpica 755 root sys
+f none kernel/misc/amd64/agpmaster 755 root sys
+f none kernel/misc/amd64/bootdev 755 root sys
f none kernel/misc/amd64/busra 755 root sys
f none kernel/misc/amd64/cardbus 755 root sys
f none kernel/misc/amd64/cmlb 755 root sys
@@ -346,13 +366,14 @@ f none kernel/misc/amd64/ipc 755 root sys
f none kernel/misc/amd64/kbtrans 755 root sys
f none kernel/misc/amd64/kcf 755 root sys
f none kernel/misc/amd64/kmdbmod 755 root sys
-f none kernel/misc/amd64/krtld 755 root sys
f none kernel/misc/amd64/mac 755 root sys
l none kernel/misc/amd64/md5=../../../kernel/crypto/amd64/md5
f none kernel/misc/amd64/net80211 755 root sys
f none kernel/misc/amd64/neti 755 root sys
f none kernel/misc/amd64/pcicfg 755 root sys
+f none kernel/misc/amd64/pciehpc 755 root sys
f none kernel/misc/amd64/pcihp 755 root sys
+f none kernel/misc/amd64/pci_autoconfig 755 root sys
f none kernel/misc/amd64/pcmcia 755 root sys
f none kernel/misc/amd64/rpcsec 755 root sys
f none kernel/misc/amd64/sata 755 root sys
@@ -362,7 +383,6 @@ l none kernel/misc/amd64/sha2=../../../kernel/crypto/amd64/sha2
f none kernel/misc/amd64/strplumb 755 root sys
f none kernel/misc/amd64/tem 755 root sys
f none kernel/misc/amd64/tlimod 755 root sys
-f none kernel/misc/amd64/zmod 755 root sys
d none kernel/sched/amd64 755 root sys
f none kernel/sched/amd64/TS 755 root sys
f none kernel/sched/amd64/TS_DPTBL 755 root sys
diff --git a/usr/src/pkgdefs/SUNWckr/prototype_sparc b/usr/src/pkgdefs/SUNWckr/prototype_sparc
index 9050ad70bb..4d29d7f36e 100644
--- a/usr/src/pkgdefs/SUNWckr/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWckr/prototype_sparc
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -191,7 +191,6 @@ f none kernel/misc/sparcv9/strplumb 755 root sys
f none kernel/misc/sparcv9/swapgeneric 755 root sys
f none kernel/misc/sparcv9/tlimod 755 root sys
f none kernel/misc/sparcv9/tem 755 root sys
-f none kernel/misc/sparcv9/zmod 755 root sys
d none kernel/sched/sparcv9 755 root sys
f none kernel/sched/sparcv9/TS 755 root sys
f none kernel/sched/sparcv9/TS_DPTBL 755 root sys
diff --git a/usr/src/pkgdefs/SUNWcsr/postinstall b/usr/src/pkgdefs/SUNWcsr/postinstall
index 88fe03318b..8184b02a5a 100644
--- a/usr/src/pkgdefs/SUNWcsr/postinstall
+++ b/usr/src/pkgdefs/SUNWcsr/postinstall
@@ -124,6 +124,21 @@ if [ -x /usr/sbin/svcadm -a -x /usr/sbin/svccfg -a \
fi
#
+# If the eeprom service is present, remove it. We can't use
+# /var/svc/profile/upgrade as it runs before manifest-import.
+#
+/usr/sbin/svccfg -s svc:/platform/i86pc/eeprom:default end >/dev/null 2>&1
+if [ "$?" = 0 ]; then
+ if [ -r $PKG_INSTALL_ROOT/etc/svc/volatile/repository_door ]; then
+ svcadm disable -s svc:/platform/i86pc/eeprom:default \
+ >/dev/null 2>&1
+ fi
+ svccfg delete svc:/platform/i86pc/eeprom >/dev/null 2>&1
+ rm -f $PKG_INSTALL_ROOT/var/svc/profile/platform_i86pc.xml
+ rm -f $PKG_INSTALL_ROOT/var/svc/profile/platform.xml
+fi
+
+#
# svc:/network/rpc/keyserv is expected to be off on systems that don't
# set domainname. On systems that do define a default domain, leave the
# setting as previously set.
diff --git a/usr/src/pkgdefs/SUNWcsr/prototype_i386 b/usr/src/pkgdefs/SUNWcsr/prototype_i386
index 84084dd378..2cb46da075 100644
--- a/usr/src/pkgdefs/SUNWcsr/prototype_i386
+++ b/usr/src/pkgdefs/SUNWcsr/prototype_i386
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -40,7 +40,7 @@
#
!include prototype_com
#
-# List files which are I386 specific here
+# List files which are i386 specific here
#
# source locations relative to the prototype file
#
@@ -51,6 +51,4 @@ f none sbin/biosdev 555 root bin
f none sbin/installgrub 0555 root sys
d none var/ld/amd64 755 root bin
s none var/ld/64=amd64
-d none var/svc/manifest/platform/i86pc 755 root sys
f none var/svc/manifest/system/boot-archive-update.xml 0444 root sys
-f none var/svc/profile/platform_i86pc.xml 444 root sys
diff --git a/usr/src/pkgdefs/SUNWcsu/prototype_com b/usr/src/pkgdefs/SUNWcsu/prototype_com
index f369ae52cf..d5022de6ba 100644
--- a/usr/src/pkgdefs/SUNWcsu/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsu/prototype_com
@@ -733,7 +733,7 @@ f none usr/sbin/dminfo 555 root bin
l none usr/sbin/drvconfig=./devfsadm
f none usr/sbin/dumpadm 555 root bin
s none usr/sbin/edquota=../lib/fs/ufs/edquota
-l none usr/sbin/eeprom=../../usr/lib/platexec
+f none usr/sbin/eeprom 2555 root bin
s none usr/sbin/fdisk=../../sbin/fdisk
f none usr/sbin/ff 555 root bin
f none usr/sbin/fmthard 555 root sys
@@ -802,7 +802,6 @@ l none usr/sbin/ports=./devfsadm
l none usr/sbin/poweroff=./halt
f none usr/sbin/praudit 555 root bin
l none usr/sbin/prtconf=../../usr/lib/isaexec
-l none usr/sbin/prtdiag=../../usr/lib/platexec
f none usr/sbin/prtvtoc 555 root sys
f none usr/sbin/psradm 555 root sys
f none usr/sbin/psrinfo 555 root sys
diff --git a/usr/src/pkgdefs/SUNWcsu/prototype_i386 b/usr/src/pkgdefs/SUNWcsu/prototype_i386
index 7dffa22aad..2b7a59b851 100644
--- a/usr/src/pkgdefs/SUNWcsu/prototype_i386
+++ b/usr/src/pkgdefs/SUNWcsu/prototype_i386
@@ -80,8 +80,10 @@ f none usr/kernel/strmod/cryptmod 755 root sys
f none usr/kernel/sys/acctctl 755 root sys
f none usr/kernel/sys/exacctsys 755 root sys
f none usr/kernel/sys/sysacct 755 root sys
+f none usr/lib/devfsadm/linkmod/SUNW_ieee1394_link.so 755 root sys
f none usr/lib/devfsadm/linkmod/SUNW_misc_link_i386.so 755 root sys
s none usr/sbin/installgrub=../../sbin/installgrub
+f none usr/sbin/prtdiag 2755 root sys
f none usr/sbin/rtc 555 root bin
d none usr/sbin/i86 755 root bin
f none usr/sbin/i86/add_drv 555 root sys
@@ -138,7 +140,6 @@ d none usr/kernel/sys/amd64 755 root sys
f none usr/kernel/sys/amd64/acctctl 755 root sys
f none usr/kernel/sys/amd64/exacctsys 755 root sys
f none usr/kernel/sys/amd64/sysacct 755 root sys
-f none usr/lib/devfsadm/linkmod/SUNW_ieee1394_link.so 755 root sys
d none usr/lib/secure/amd64 755 root bin
s none usr/lib/secure/64=amd64
d none usr/lib/amd64 755 root bin
diff --git a/usr/src/pkgdefs/SUNWcsu/prototype_sparc b/usr/src/pkgdefs/SUNWcsu/prototype_sparc
index a53f2c1703..281413f974 100644
--- a/usr/src/pkgdefs/SUNWcsu/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWcsu/prototype_sparc
@@ -98,6 +98,7 @@ d none usr/lib/secure/sparcv9 755 root bin
s none usr/lib/secure/64=sparcv9
d none usr/lib/sparcv9 755 root bin
s none usr/lib/sparcv9/ld.so.1=../../../lib/sparcv9/ld.so.1
+l none usr/sbin/prtdiag=../../usr/lib/platexec
d none usr/sbin/sparcv9 755 root bin
f none usr/sbin/sparcv9/add_drv 555 root sys
f none usr/sbin/sparcv9/modinfo 555 root sys
diff --git a/usr/src/pkgdefs/SUNWdrmr/prototype_i386 b/usr/src/pkgdefs/SUNWdrmr/prototype_i386
index 972bf8af95..d7cfd7f00c 100755
--- a/usr/src/pkgdefs/SUNWdrmr/prototype_i386
+++ b/usr/src/pkgdefs/SUNWdrmr/prototype_i386
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -47,14 +47,11 @@
# SUNWdrmr
#
d none kernel 0755 root sys
+d none kernel/drv 0755 root sys
+f none kernel/drv/i915 0755 root sys
+d none kernel/drv/amd64 0755 root sys
+f none kernel/drv/amd64/i915 0755 root sys
d none kernel/misc 0755 root sys
f none kernel/misc/drm 0755 root sys
d none kernel/misc/amd64 0755 root sys
f none kernel/misc/amd64/drm 0755 root sys
-d none platform 0755 root sys
-d none platform/i86pc 0755 root sys
-d none platform/i86pc/kernel 0755 root sys
-d none platform/i86pc/kernel/drv 0755 root sys
-f none platform/i86pc/kernel/drv/i915 0755 root sys
-d none platform/i86pc/kernel/drv/amd64 0755 root sys
-f none platform/i86pc/kernel/drv/amd64/i915 0755 root sys
diff --git a/usr/src/pkgdefs/SUNWhea/prototype_i386 b/usr/src/pkgdefs/SUNWhea/prototype_i386
index 3d7a74517e..4fafdc6e72 100644
--- a/usr/src/pkgdefs/SUNWhea/prototype_i386
+++ b/usr/src/pkgdefs/SUNWhea/prototype_i386
@@ -58,12 +58,13 @@ f none usr/include/asm/htable.h 644 root bin
f none usr/include/asm/mmu.h 644 root bin
d none usr/include/amd64 755 root bin
d none usr/include/amd64/sys 755 root bin
+f none usr/include/amd64/sys/kdi_regs.h 644 root bin
f none usr/include/amd64/sys/privregs.h 644 root bin
d none usr/include/ia32 755 root bin
d none usr/include/ia32/sys 755 root bin
f none usr/include/ia32/sys/asm_linkage.h 644 root bin
+f none usr/include/ia32/sys/kdi_regs.h 644 root bin
f none usr/include/ia32/sys/machtypes.h 644 root bin
-f none usr/include/ia32/sys/mmu.h 644 root bin
f none usr/include/ia32/sys/privregs.h 644 root bin
f none usr/include/ia32/sys/psw.h 644 root bin
f none usr/include/ia32/sys/pte.h 644 root bin
@@ -71,6 +72,7 @@ f none usr/include/ia32/sys/reg.h 644 root bin
f none usr/include/ia32/sys/stack.h 644 root bin
f none usr/include/ia32/sys/trap.h 644 root bin
f none usr/include/ia32/sys/traptrace.h 644 root bin
+f none usr/include/sys/kdi_regs.h 644 root bin
f none usr/include/stack_unwind.h 644 root bin
f none usr/include/sys/bootregs.h 644 root bin
f none usr/include/sys/bootsvcs.h 644 root bin
@@ -91,19 +93,18 @@ f none usr/include/sys/i2o/i2oadptr.h 644 root bin
f none usr/include/sys/i2o/i2obscsi.h 644 root bin
f none usr/include/sys/i2o/i2omstr.h 644 root bin
f none usr/include/sys/i8272A.h 644 root bin
-f none usr/include/sys/immu.h 644 root bin
f none usr/include/sys/kd.h 644 root bin
f none usr/include/sys/mc.h 644 root bin
f none usr/include/sys/mc_amd.h 644 root bin
f none usr/include/sys/mca_amd.h 644 root bin
f none usr/include/sys/mca_x86.h 644 root bin
-f none usr/include/sys/mmu.h 644 root bin
f none usr/include/sys/mutex_impl.h 644 root bin
f none usr/include/sys/obpdefs.h 644 root bin
f none usr/include/sys/pcic_reg.h 644 root bin
f none usr/include/sys/pcic_var.h 644 root bin
f none usr/include/sys/pic.h 644 root bin
f none usr/include/sys/pit.h 644 root bin
+f none usr/include/sys/pmem.h 644 root bin
f none usr/include/sys/privregs.h 644 root bin
f none usr/include/sys/prom_emul.h 644 root bin
f none usr/include/sys/prom_isa.h 644 root bin
@@ -128,13 +129,15 @@ d none usr/platform/i86pc/include/sys 755 root bin
f none usr/platform/i86pc/include/sys/asm_misc.h 644 root bin
f none usr/platform/i86pc/include/sys/clock.h 644 root bin
f none usr/platform/i86pc/include/sys/cram.h 644 root bin
+f none usr/platform/i86pc/include/sys/debug_info.h 644 root bin
f none usr/platform/i86pc/include/sys/ddi_subrdefs.h 644 root bin
+f none usr/platform/i86pc/include/sys/mach_mmu.h 644 root bin
f none usr/platform/i86pc/include/sys/machcpuvar.h 644 root bin
f none usr/platform/i86pc/include/sys/machparam.h 644 root bin
f none usr/platform/i86pc/include/sys/machsystm.h 644 root bin
f none usr/platform/i86pc/include/sys/machthread.h 644 root bin
f none usr/platform/i86pc/include/sys/memnode.h 644 root bin
-f none usr/platform/i86pc/include/sys/pmem.h 644 root bin
+f none usr/platform/i86pc/include/sys/pc_mmu.h 644 root bin
f none usr/platform/i86pc/include/sys/psm.h 644 root bin
f none usr/platform/i86pc/include/sys/psm_defs.h 644 root bin
f none usr/platform/i86pc/include/sys/psm_modctl.h 644 root bin
@@ -142,6 +145,7 @@ f none usr/platform/i86pc/include/sys/psm_types.h 644 root bin
f none usr/platform/i86pc/include/sys/rm_platter.h 644 root bin
f none usr/platform/i86pc/include/sys/smp_impldefs.h 644 root bin
f none usr/platform/i86pc/include/sys/vm_machparam.h 644 root bin
+f none usr/platform/i86pc/include/sys/xsvc.h 644 root bin
f none usr/platform/i86pc/include/sys/x_call.h 644 root bin
f none usr/platform/i86pc/include/sys/xc_levels.h 644 root bin
d none usr/platform/i86pc/include/vm 755 root bin
@@ -149,6 +153,7 @@ f none usr/platform/i86pc/include/vm/hat_i86.h 644 root bin
f none usr/platform/i86pc/include/vm/hat_pte.h 644 root bin
f none usr/platform/i86pc/include/vm/htable.h 644 root bin
f none usr/platform/i86pc/include/vm/hment.h 644 root bin
+f none usr/platform/i86pc/include/vm/kboot_mmu.h 644 root bin
d none usr/share/src/uts/i86pc 755 root bin
s none usr/share/src/uts/i86pc/sys=../../../../platform/i86pc/include/sys
s none usr/share/src/uts/i86pc/vm=../../../../platform/i86pc/include/vm
diff --git a/usr/src/pkgdefs/SUNWkvm.i/prototype_com b/usr/src/pkgdefs/SUNWkvm.i/prototype_com
index c2e8d5e9f7..670d6aaae7 100644
--- a/usr/src/pkgdefs/SUNWkvm.i/prototype_com
+++ b/usr/src/pkgdefs/SUNWkvm.i/prototype_com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -46,11 +45,4 @@ i copyright
d none usr 755 root sys
d none usr/platform 755 root sys
d none usr/platform/i86pc 755 root sys
-d none usr/platform/i86pc/sbin 755 root bin
-f none usr/platform/i86pc/sbin/eeprom 2555 root sys
-f none usr/platform/i86pc/sbin/prtdiag 555 root sys
d none usr/platform/i86pc/lib 755 root bin
-#
-# make the links to other machine types
-#
-s none usr/platform/ncri86pc=i86pc
diff --git a/usr/src/pkgdefs/SUNWkvm.u/prototype_com b/usr/src/pkgdefs/SUNWkvm.u/prototype_com
index a2acd42082..04066f8be5 100644
--- a/usr/src/pkgdefs/SUNWkvm.u/prototype_com
+++ b/usr/src/pkgdefs/SUNWkvm.u/prototype_com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -97,24 +97,19 @@ s none usr/platform/SUNW,Sun-Blade-1500/sbin=../sun4u/sbin
s none usr/platform/SUNW,Sun-Blade-2500/sbin=../sun4u/sbin
s none usr/platform/SUNW,A70/sbin=../sun4u/sbin
d none usr/platform/SUNW,SPARC-Enterprise/sbin 755 root bin
-s none usr/platform/SUNW,SPARC-Enterprise/sbin/eeprom=../../sun4u/sbin/eeprom
s none usr/platform/SUNW,SPARC-Enterprise/sbin/prtdiag=../../sun4u/sbin/prtdiag
s none usr/platform/SUNW,SPARC-Enterprise/sbin/trapstat=../../sun4u/sbin/trapstat
d none usr/platform/SUNW,Sun-Fire-V445/sbin 755 root bin
-s none usr/platform/SUNW,Sun-Fire-V445/sbin/eeprom=../../sun4u/sbin/eeprom
s none usr/platform/SUNW,Sun-Fire-V445/sbin/prtdiag=../../sun4u/sbin/prtdiag
s none usr/platform/SUNW,Sun-Fire-V445/sbin/trapstat=../../sun4u/sbin/trapstat
d none usr/platform/SUNW,Sun-Fire-V215/sbin 755 root bin
-s none usr/platform/SUNW,Sun-Fire-V215/sbin/eeprom=../../sun4u/sbin/eeprom
s none usr/platform/SUNW,Sun-Fire-V215/sbin/prtdiag=../../sun4u/sbin/prtdiag
s none usr/platform/SUNW,Sun-Fire-V215/sbin/trapstat=../../sun4u/sbin/trapstat
s none usr/platform/SUNW,Sun-Fire/sbin=../sun4u/sbin
d none usr/platform/SUNW,Sun-Fire-V240/sbin 755 root bin
-s none usr/platform/SUNW,Sun-Fire-V240/sbin/eeprom=../../sun4u/sbin/eeprom
s none usr/platform/SUNW,Sun-Fire-V240/sbin/prtdiag=../../sun4u/sbin/prtdiag
s none usr/platform/SUNW,Sun-Fire-V240/sbin/trapstat=../../sun4u/sbin/trapstat
d none usr/platform/SUNW,Sun-Fire-V250/sbin 755 root bin
-s none usr/platform/SUNW,Sun-Fire-V250/sbin/eeprom=../../sun4u/sbin/eeprom
s none usr/platform/SUNW,Sun-Fire-V250/sbin/prtdiag=../../sun4u/sbin/prtdiag
s none usr/platform/SUNW,Sun-Fire-V250/sbin/trapstat=../../sun4u/sbin/trapstat
s none usr/platform/SUNW,Sun-Fire-V440/sbin=../SUNW,Sun-Fire-V240/sbin
@@ -131,15 +126,12 @@ s none usr/platform/SUNW,UltraSPARC-IIi-Netract/sbin=../sun4u/sbin
s none usr/platform/SUNW,UltraSPARC-IIe-NetraCT-40/sbin=../sun4u/sbin
s none usr/platform/SUNW,UltraSPARC-IIe-NetraCT-60/sbin=../sun4u/sbin
d none usr/platform/SUNW,Netra-CP2300/sbin 755 root bin
-s none usr/platform/SUNW,Netra-CP2300/sbin/eeprom=../../sun4u/sbin/eeprom
s none usr/platform/SUNW,Netra-CP2300/sbin/prtdiag=../../sun4u/sbin/prtdiag
s none usr/platform/SUNW,Netra-CP2300/sbin/trapstat=../../sun4u/sbin/trapstat
d none usr/platform/SUNW,Netra-CP3010/sbin 755 root bin
-s none usr/platform/SUNW,Netra-CP3010/sbin/eeprom=../../sun4u/sbin/eeprom
s none usr/platform/SUNW,Netra-CP3010/sbin/prtdiag=../../sun4u/sbin/prtdiag
s none usr/platform/SUNW,Netra-CP3010/sbin/trapstat=../../sun4u/sbin/trapstat
#
-f none usr/platform/sun4u/sbin/eeprom 2555 root sys
f none usr/platform/sun4u/sbin/trapstat 555 root bin
#
diff --git a/usr/src/pkgdefs/SUNWkvm.v/prototype_com b/usr/src/pkgdefs/SUNWkvm.v/prototype_com
index df2c3d72c7..0d388e4eff 100644
--- a/usr/src/pkgdefs/SUNWkvm.v/prototype_com
+++ b/usr/src/pkgdefs/SUNWkvm.v/prototype_com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -51,7 +51,6 @@ d none usr/platform/sun4v 755 root sys
d none usr/platform/sun4v/sbin 755 root bin
#
f none usr/platform/sun4v/sbin/trapstat 555 root bin
-f none usr/platform/sun4v/sbin/eeprom 2555 root sys
#
# create lib directory for sun4v
#
diff --git a/usr/src/pkgdefs/SUNWos86r/prototype_i386 b/usr/src/pkgdefs/SUNWos86r/prototype_i386
index fb8dc7c93a..fdb964123b 100644
--- a/usr/src/pkgdefs/SUNWos86r/prototype_i386
+++ b/usr/src/pkgdefs/SUNWos86r/prototype_i386
@@ -20,7 +20,7 @@
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -81,8 +81,6 @@ f none kernel/drv/elxl 755 root sys
f none kernel/drv/elxl.conf 644 root sys
f none kernel/drv/iprb 755 root sys
f none kernel/drv/iprb.conf 644 root sys
-f none kernel/drv/ncrs 755 root sys
-f none kernel/drv/ncrs.conf 644 root sys
f none kernel/drv/pcn 755 root sys
f none kernel/drv/pcn.conf 644 root sys
# EXPORT DELETE START
@@ -93,14 +91,3 @@ d none kernel/drv/amd64 755 root sys
f none kernel/drv/amd64/elxl 755 root sys
f none kernel/drv/amd64/iprb 755 root sys
f none kernel/drv/amd64/pcn 755 root sys
-d none kernel/mach 755 root sys
-f none kernel/mach/pcplusmp 755 root sys
-d none kernel/mach/amd64 755 root sys
-f none kernel/mach/amd64/pcplusmp 755 root sys
-d none kernel/misc 755 root sys
-d none var 755 root sys
-d none var/svc 755 root sys
-d none var/svc/manifest 755 root sys
-d none var/svc/manifest/platform 755 root sys
-d none var/svc/manifest/platform/i86pc 755 root sys
-f manifest var/svc/manifest/platform/i86pc/eeprom.xml 0444 root sys
diff --git a/usr/src/pkgdefs/SUNWpsdcr/prototype_i386 b/usr/src/pkgdefs/SUNWpsdcr/prototype_i386
index d147a9f963..345b187edd 100644
--- a/usr/src/pkgdefs/SUNWpsdcr/prototype_i386
+++ b/usr/src/pkgdefs/SUNWpsdcr/prototype_i386
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -19,7 +18,7 @@
#
# CDDL HEADER END
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -51,52 +50,47 @@ i preremove
#
d none kernel 755 root sys
d none kernel/drv 755 root sys
-# Following drv and misc modules are from SUNWcsr
f none kernel/drv/asy 755 root sys
f none kernel/drv/asy.conf 644 root sys
f none kernel/drv/cmdk 755 root sys
f none kernel/drv/cmdk.conf 644 root sys
f none kernel/drv/ecpp 755 root sys
f none kernel/drv/ecpp.conf 644 root sys
+f none kernel/drv/fd 755 root sys
+f none kernel/drv/fd.conf 644 root sys
+f none kernel/drv/fdc.conf 644 root sys
+f none kernel/drv/fdc 755 root sys
+f none kernel/drv/logi 755 root sys
+f none kernel/drv/msm 755 root sys
+f none kernel/drv/ncrs 755 root sys
+f none kernel/drv/ncrs.conf 644 root sys
d none kernel/misc 755 root sys
f none kernel/misc/dadk 755 root sys
f none kernel/misc/gda 755 root sys
f none kernel/misc/strategy 755 root sys
+d none kernel/strmod 755 root sys
+f none kernel/strmod/vuid2ps2 755 root sys
+f none kernel/strmod/vuid3ps2 755 root sys
+f none kernel/strmod/vuidm3p 755 root sys
+f none kernel/strmod/vuidm4p 755 root sys
+f none kernel/strmod/vuidm5p 755 root sys
d none kernel/drv/amd64 755 root sys
f none kernel/drv/amd64/asy 755 root sys
f none kernel/drv/amd64/cmdk 755 root sys
f none kernel/drv/amd64/ecpp 755 root sys
+f none kernel/drv/amd64/fd 755 root sys
+f none kernel/drv/amd64/fdc 755 root sys
+f none kernel/drv/amd64/logi 755 root sys
d none kernel/misc/amd64 755 root sys
f none kernel/misc/amd64/dadk 755 root sys
f none kernel/misc/amd64/gda 755 root sys
f none kernel/misc/amd64/strategy 755 root sys
+d none kernel/strmod/amd64 755 root sys
+f none kernel/strmod/amd64/vuid2ps2 755 root sys
+f none kernel/strmod/amd64/vuid3ps2 755 root sys
+f none kernel/strmod/amd64/vuidm3p 755 root sys
+f none kernel/strmod/amd64/vuidm4p 755 root sys
+f none kernel/strmod/amd64/vuidm5p 755 root sys
e preserve kernel/misc/sysinit 755 root sys
e preserve kernel/misc/amd64/sysinit 755 root sys
-# Following drivers are from SUNWcar.i
-d none platform 755 root sys
-d none platform/i86pc 755 root sys
-d none platform/i86pc/kernel 755 root sys
-d none platform/i86pc/kernel/drv 755 root sys
-f none platform/i86pc/kernel/drv/fd 755 root sys
-f none platform/i86pc/kernel/drv/fd.conf 644 root sys
-f none platform/i86pc/kernel/drv/fdc.conf 644 root sys
-f none platform/i86pc/kernel/drv/fdc 755 root sys
-f none platform/i86pc/kernel/drv/logi 755 root sys
-f none platform/i86pc/kernel/drv/msm 755 root sys
-d none platform/i86pc/kernel/drv/amd64 755 root sys
-f none platform/i86pc/kernel/drv/amd64/fd 755 root sys
-f none platform/i86pc/kernel/drv/amd64/fdc 755 root sys
-f none platform/i86pc/kernel/drv/amd64/logi 755 root sys
-d none platform/i86pc/kernel/misc 755 root sys
-d none platform/i86pc/kernel/strmod 755 root sys
-f none platform/i86pc/kernel/strmod/vuid2ps2 755 root sys
-f none platform/i86pc/kernel/strmod/vuid3ps2 755 root sys
-f none platform/i86pc/kernel/strmod/vuidm3p 755 root sys
-f none platform/i86pc/kernel/strmod/vuidm4p 755 root sys
-f none platform/i86pc/kernel/strmod/vuidm5p 755 root sys
-d none platform/i86pc/kernel/strmod/amd64 755 root sys
-f none platform/i86pc/kernel/strmod/amd64/vuid2ps2 755 root sys
-f none platform/i86pc/kernel/strmod/amd64/vuid3ps2 755 root sys
-f none platform/i86pc/kernel/strmod/amd64/vuidm3p 755 root sys
-f none platform/i86pc/kernel/strmod/amd64/vuidm4p 755 root sys
-f none platform/i86pc/kernel/strmod/amd64/vuidm5p 755 root sys
+
diff --git a/usr/src/pkgdefs/SUNWpsdir/prototype_i386 b/usr/src/pkgdefs/SUNWpsdir/prototype_i386
index 35bd862170..0ffb0c26ce 100644
--- a/usr/src/pkgdefs/SUNWpsdir/prototype_i386
+++ b/usr/src/pkgdefs/SUNWpsdir/prototype_i386
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -51,18 +50,22 @@ i preinstall
# SUNWpsdir
#
# Following drivers are from SUNWcar.i
+d none kernel 755 root sys
+d none kernel/drv 755 root sys
+f none kernel/drv/ata 755 root sys
+e ataconf kernel/drv/ata.conf 644 root sys
+f none kernel/drv/mscsi 755 root sys
+f none kernel/drv/mscsi.conf 644 root sys
+f none kernel/drv/sbpro 755 root sys
+f none kernel/drv/sbpro.conf 644 root sys
+d none kernel/drv/amd64 755 root sys
+f none kernel/drv/amd64/ata 755 root sys
+
d none platform 755 root sys
d none platform/i86pc 755 root sys
d none platform/i86pc/kernel 755 root sys
d none platform/i86pc/kernel/drv 755 root sys
-f none platform/i86pc/kernel/drv/ata 755 root sys
-e ataconf platform/i86pc/kernel/drv/ata.conf 644 root sys
-f none platform/i86pc/kernel/drv/mscsi 755 root sys
-f none platform/i86pc/kernel/drv/mscsi.conf 644 root sys
f none platform/i86pc/kernel/drv/pci-ide 755 root sys
f none platform/i86pc/kernel/drv/pci-ide.conf 644 root sys
-f none platform/i86pc/kernel/drv/sbpro 755 root sys
-f none platform/i86pc/kernel/drv/sbpro.conf 644 root sys
d none platform/i86pc/kernel/drv/amd64 755 root sys
-f none platform/i86pc/kernel/drv/amd64/ata 755 root sys
f none platform/i86pc/kernel/drv/amd64/pci-ide 755 root sys
diff --git a/usr/src/pkgdefs/SUNWxsvc/Makefile b/usr/src/pkgdefs/SUNWxsvc/Makefile
new file mode 100644
index 0000000000..0e03136b09
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWxsvc/Makefile
@@ -0,0 +1,37 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES +=
+CLOBBERFILES += $(MACHDATAFILES)
+
+.KEEP_STATE:
+
+all: $(FILES) $(MACHDATAFILES)
+install: all pkg
+
+include ../Makefile.targ
diff --git a/usr/src/pkgdefs/SUNWxsvc/depend b/usr/src/pkgdefs/SUNWxsvc/depend
new file mode 100644
index 0000000000..9d7e7d4f42
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWxsvc/depend
@@ -0,0 +1,52 @@
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This package information file defines software dependencies associated
+# with the pkg. You can define three types of pkg dependencies with this file:
+# P indicates a prerequisite for installation
+# I indicates an incompatible package
+# R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# (<arch>)<version>
+# (<arch>)<version>
+# ...
+# <type> <pkg.abbr> <name>
+# ...
+#
+
+# Required system dependencies
+P SUNWcar Core Architecture, (Root)
+P SUNWcakr Core Solaris Kernel Architecture (Root)
+P SUNWkvm Core Architecture, (Kvm)
+P SUNWcsr Core Solaris, (Root)
+P SUNWckr Core Solaris Kernel (Root)
+P SUNWcnetr Core Solaris Network Infrastructure (Root)
+P SUNWcsu Core Solaris, (Usr)
+P SUNWcsd Core Solaris Devices
+P SUNWcsl Core Solaris Libraries
diff --git a/usr/src/pkgdefs/SUNWxsvc/pkginfo.tmpl b/usr/src/pkgdefs/SUNWxsvc/pkginfo.tmpl
new file mode 100644
index 0000000000..70f40d326b
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWxsvc/pkginfo.tmpl
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWxsvc"
+NAME="Sun Xserver pseudo driver"
+ARCH="i386"
+CATEGORY="system"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKGTYPE="root"
+CLASSES="none"
+DESC="Sun Xserver pseudo driver"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+VERSION="ONVERS,REV=0.0.0"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+MAXINST="1000"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="true"
+SUNW_PKG_THISZONE="false"
diff --git a/usr/src/pkgdefs/SUNWxsvc/postinstall b/usr/src/pkgdefs/SUNWxsvc/postinstall
new file mode 100644
index 0000000000..bfd7363653
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWxsvc/postinstall
@@ -0,0 +1,46 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+PATH="/usr/bin:/usr/sbin:${PATH}"
+export PATH
+
+#
+# Driver info
+#
+ADD_DRV="add_drv -b ${BASEDIR}"
+
+DRV=xsvc
+grep "^${DRV} " $BASEDIR/etc/name_to_major > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+ ${ADD_DRV} ${DRV}
+ if [ $? -ne 0 ]; then
+ echo "\nFailed add_drv of ${DRV}!\n" >&2
+ exit 1
+ fi
+fi
+
+exit 0
diff --git a/usr/src/pkgdefs/SUNWxsvc/postremove b/usr/src/pkgdefs/SUNWxsvc/postremove
new file mode 100644
index 0000000000..9e98dbd5b5
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWxsvc/postremove
@@ -0,0 +1,35 @@
+#!/sbin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+BD=${BASEDIR:-/}
+if [ "$ACTIVE_PATCH" = "" ]
+then
+ if grep "\<xsvc\>" $BD/etc/name_to_major > /dev/null 2>&1
+ then
+ rem_drv -b ${BD} xsvc
+ fi
+fi
+exit 0
diff --git a/usr/src/pkgdefs/SUNWxsvc/prototype_i386 b/usr/src/pkgdefs/SUNWxsvc/prototype_i386
new file mode 100644
index 0000000000..910c7e56db
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWxsvc/prototype_i386
@@ -0,0 +1,57 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+# packaging files
+i copyright
+i depend
+i pkginfo
+i postinstall
+i postremove
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+#
+#
+# List files which are i386 specific here
+#
+# source locations relative to the prototype file
+#
+# SUNWxsvc
+#
+d none platform 0755 root sys
+d none platform/i86pc 0755 root sys
+d none platform/i86pc/kernel 0755 root sys
+d none platform/i86pc/kernel/drv 0755 root sys
+f none platform/i86pc/kernel/drv/xsvc 755 root sys
+f none platform/i86pc/kernel/drv/xsvc.conf 644 root sys
+d none platform/i86pc/kernel/drv/amd64 0755 root sys
+f none platform/i86pc/kernel/drv/amd64/xsvc 755 root sys
diff --git a/usr/src/pkgdefs/etc/exception_list_sparc b/usr/src/pkgdefs/etc/exception_list_sparc
index ddd59166e4..d8930e923a 100644
--- a/usr/src/pkgdefs/etc/exception_list_sparc
+++ b/usr/src/pkgdefs/etc/exception_list_sparc
@@ -635,9 +635,6 @@ usr/lib/sparcv9/librestart.so sparc
usr/include/librestart.h sparc
usr/include/librestart_priv.h sparc
usr/include/libcontract_priv.h sparc
-var/svc/manifest/platform/i86pc sparc
-var/svc/manifest/platform/i86pc/eeprom.xml sparc
-var/svc/profile/platform_i86pc.xml sparc
#
# Private libuutil files
#
diff --git a/usr/src/pkgdefs/etc/proto_list_ihv_i386 b/usr/src/pkgdefs/etc/proto_list_ihv_i386
index 0bc969214b..c4cba07150 100644
--- a/usr/src/pkgdefs/etc/proto_list_ihv_i386
+++ b/usr/src/pkgdefs/etc/proto_list_ihv_i386
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -32,13 +32,10 @@
#
f kernel/drv/adp - 755 root sys 0 1 - -
f kernel/drv/adp.conf - 644 root sys 0 1 - -
-f kernel/drv/amd64/xsvc - 755 root sys 0 1 - -
f kernel/drv/cadp - 755 root sys 0 1 - -
f kernel/drv/cadp.conf - 644 root sys 0 1 - -
f kernel/drv/cpqhpc - 755 root sys 0 1 - -
f kernel/drv/cpqhpc.conf - 644 root sys 0 1 - -
-f kernel/drv/xsvc - 755 root sys 0 1 - -
-f kernel/drv/xsvc.conf - 644 root sys 0 1 - -
f platform/i86pc/kernel/drv/amd64/cadp160 - 755 root sys 0 1 - -
f platform/i86pc/kernel/drv/cadp160 - 755 root sys 0 1 - -
f platform/i86pc/kernel/drv/cadp160.conf - 644 root sys 0 1 - -
diff --git a/usr/src/psm/stand/boot/Makefile b/usr/src/psm/stand/boot/Makefile
index cffc01d339..0964794481 100644
--- a/usr/src/psm/stand/boot/Makefile
+++ b/usr/src/psm/stand/boot/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -29,7 +29,6 @@ include ../../../Makefile.master
sparcv9_ARCHITECTURES = sparcv9
sparc_ARCHITECTURES = $(sparcv9_ARCHITECTURES)
-i386_ARCHITECTURES = i386
SUBDIRS = $($(MACH)_ARCHITECTURES)
@@ -56,7 +55,7 @@ UTSDIR = ../../../uts
UTSCLOSED = ../../../../closed/uts
STANDLIBDIR = ../../../stand/lib
STANDSYSDIRS = ../../../stand/sys
-PROMDIRS = ../../promif $(UTSDIR)/intel/promif
+PROMDIRS = ../../promif
NAMESDIRS = ../lib/names
XRDIRS += $(STANDLIBDIR) $(STANDSYSDIRS) $(PROMDIRS) $(NAMESDIRS)
@@ -64,8 +63,7 @@ XRDIRS += $(STANDLIBDIR) $(STANDSYSDIRS) $(PROMDIRS) $(NAMESDIRS)
# Components beginning with B! are in the open and closed trees; those
# beginning with O! are just in the open tree.
#
-XRINCCOMP = B!sun4u O!sfmmu O!sparc/v7 O!sparc/v9 B!sparc B!sun \
- B!common B!intel B!i86pc
+XRINCCOMP = B!sun4u O!sfmmu O!sparc/v7 O!sparc/v9 B!sparc B!sun B!common
XRINC_TMP = $(XRINCCOMP:B!%=$(UTSDIR)/%)
XRINCDIRS = $(XRINC_TMP:O!%=$(UTSDIR)/%)
$(CLOSED_BUILD)XRINC_TMP = $(XRINCCOMP:B!%=$(UTSDIR)/% $(UTSCLOSED)/%)
diff --git a/usr/src/psm/stand/boot/i386/common/console.c b/usr/src/psm/stand/boot/i386/common/console.c
deleted file mode 100644
index d6c40a83df..0000000000
--- a/usr/src/psm/stand/boot/i386/common/console.c
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/types.h>
-#include <sys/bootsvcs.h>
-#include <sys/varargs.h>
-#include <sys/promif.h>
-#include <sys/salib.h>
-#include <sys/psw.h>
-
-#include "util.h"
-#include "serial.h"
-#include "chario.h"
-#include "vga.h"
-#include "console.h"
-#include "debug.h"
-#include "bootprop.h"
-
-#include "biosint.h"
-
-#define dprintf if (debug & D_ALLOC) printf
-
-static int cons_color = CONS_COLOR;
-int console = CONS_SCREEN_TEXT;
-/* or CONS_SCREEN_GRAPHICS, CONS_TTYA, CONS_TTYB */
-static int serial_ischar(void);
-static int serial_getchar(void);
-static void serial_putchar(int);
-static void serial_adjust_prop(void);
-static int console_state = 0;
-
-/* Clear the screen and initialize VIDEO, XPOS and YPOS. */
-static void
-clear_screen(void)
-{
- /*
- * XXX should set vga mode so we don't depend on the
- * state left by the boot loader
- */
- vga_clear(cons_color);
- vga_setpos(0, 0);
-}
-
-/* Put the character C on the screen. */
-static void
-screen_putchar(int c)
-{
- int row, col;
-
- vga_getpos(&row, &col);
- switch (c) {
- case '\r':
- vga_setpos(row, 0);
- break;
-
- case '\b':
- if (col > 0)
- vga_setpos(row, col - 1);
- break;
-
- case '\n':
- if (row < VGA_TEXT_ROWS - 1)
- vga_setpos(row + 1, col);
- else
- vga_scroll(cons_color);
- break;
-
- default:
- vga_drawc(c, cons_color);
- if (col < VGA_TEXT_COLS -1)
- vga_setpos(row, col + 1);
- else if (row < VGA_TEXT_ROWS - 1)
- vga_setpos(row + 1, 0);
- else {
- vga_setpos(row, 0);
- vga_scroll(cons_color);
- }
- break;
- }
-}
-
-static int
-get_videomode(void)
-{
- struct int_pb ic = {0};
- int error;
-
- ic.ax = 0x0f00;
-
- if ((error = bios_doint(0x10, &ic)) & PS_C) {
- dprintf("get_videomode: bios_doint failed: %d\n", error);
- return (-1);
- }
-
- return (ic.ax & 0xFF);
-}
-
-/* serial port stuff */
-static int port;
-
-static void
-serial_init(void)
-{
- extern int bios_free;
- extern void mdelay();
-
- /* initialize only once */
- if (port != 0)
- return;
-
- /*
- * wait 2 seconds for serial console redirection to settle
- * NOTE we only need to wait if BIOS console redirection
- * is enabled, but we can't really tell without working
- * through a scary Microsoft license.
- */
- if (!bios_free)
- mdelay(2000);
-
- switch (console) {
- case CONS_TTYA:
- port = 0x3f8;
- break;
- case CONS_TTYB:
- port = 0x2f8;
- break;
- }
-
- outb(port + ISR, 0x20);
- if (inb(port + ISR) & 0x20) {
- /*
- * 82510 chip is present
- */
- outb(port + DAT+7, 0x04); /* clear status */
- outb(port + ISR, 0x40); /* set to bank 2 */
- outb(port + MCR, 0x08); /* IMD */
- outb(port + DAT, 0x21); /* FMD */
- outb(port + ISR, 0x00); /* set to bank 0 */
- } else {
- /*
- * set the UART in FIFO mode if it has FIFO buffers.
- * use 16550 fifo reset sequence specified in NS
- * application note. disable fifos until chip is
- * initialized.
- */
- outb(port + FIFOR, 0x00); /* clear */
- outb(port + FIFOR, FIFO_ON); /* enable */
- outb(port + FIFOR, FIFO_ON|FIFORXFLSH); /* reset */
- outb(port + FIFOR,
- FIFO_ON|FIFODMA|FIFOTXFLSH|FIFORXFLSH|0x80);
- if ((inb(port + ISR) & 0xc0) != 0xc0) {
- /*
- * no fifo buffers so disable fifos.
- * this is true for 8250's
- */
- outb(port + FIFOR, 0x00);
- }
- }
-
- /* disable interrupts */
- outb(port + ICR, 0);
-
- /* adjust setting based on tty properties */
- serial_adjust_prop();
-
- /*
- * Do a full reset to match console behavior.
- * In verbose mode (-V), we only reset ansi attributes,
- * leaving existing output on screen.
- * 0x1B + c - reset everything
- * 0x1B +
- * [ - attribute change (blick, inverse, color, etc.)
- * 0 - attribute value
- * m - terminate escape sequence
- *
- */
- if (verbosemode) {
- serial_putchar(0x1B);
- serial_putchar('[');
- serial_putchar('0');
- serial_putchar('m');
- } else {
- serial_putchar(0x1B);
- serial_putchar('c');
- }
-}
-
-/* adjust serial port based on properties */
-static void
-serial_adjust_prop(void)
-{
- int plen;
- char propname[20], propval[20];
-
- (void) snprintf(propname, sizeof (propname), "tty%c-mode",
- 'a' + console - CONS_TTYA);
- plen = bgetproplen(NULL, propname);
- if (plen > 0 && plen <= sizeof (propval)) {
- (void) bgetprop(NULL, propname, propval);
- } else {
- (void) strcpy(propval, "9600,8,n,1,-");
- }
-
- {
- char *p;
- ulong_t baud;
- uchar_t lcr = 0;
-
- /* property is of the form: "9600,8,n,1,-" */
- p = strtok(propval, ",");
- if (strcmp(p, "110") == 0)
- baud = ASY110;
- else if (strcmp(p, "150") == 0)
- baud = ASY150;
- else if (strcmp(p, "300") == 0)
- baud = ASY300;
- else if (strcmp(p, "600") == 0)
- baud = ASY600;
- else if (strcmp(p, "1200") == 0)
- baud = ASY1200;
- else if (strcmp(p, "2400") == 0)
- baud = ASY2400;
- else if (strcmp(p, "4800") == 0)
- baud = ASY4800;
- else if (strcmp(p, "19200") == 0)
- baud = ASY19200;
- else if (strcmp(p, "38400") == 0)
- baud = ASY38400;
- else if (strcmp(p, "57600") == 0)
- baud = ASY57600;
- else if (strcmp(p, "115200") == 0)
- baud = ASY115200;
- else
- baud = ASY9600;
-
- /* set baud */
- outb(port + LCR, DLAB);
- outb(port + DAT+DLL, baud & 0xff);
- outb(port + DAT+DLH, (baud >> 8) & 0xff);
-
- p = strtok(NULL, ",");
- if (p) {
- switch (*p) {
- case '5':
- lcr |= BITS5;
- break;
- case '6':
- lcr |= BITS6;
- break;
- case '7':
- lcr |= BITS7;
- break;
- case '8':
- default:
- lcr |= BITS8;
- break;
- }
- }
-
- p = strtok(NULL, ",");
- if (p) {
- switch (*p) {
- case 'n':
- lcr |= PARITY_NONE;
- break;
- case 'o':
- lcr |= PARITY_ODD;
- break;
- case 'e':
- default:
- lcr |= PARITY_EVEN;
- break;
- }
- }
-
- p = strtok(NULL, ",");
- if (p) {
- switch (*p) {
- case '1':
- /* STOP1 is 0 */
- break;
- default:
- lcr |= STOP2;
- break;
- }
- }
-
- /* set parity bits */
- outb(port + LCR, lcr);
- }
-
- (void) snprintf(propname, sizeof (propname),
- "tty%c-rts-dtr-off", 'a' + console - CONS_TTYA);
- plen = bgetproplen(NULL, propname);
- if (plen > 0 && plen <= sizeof (propval)) {
- (void) bgetprop(NULL, propname, propval);
- } else {
- (void) strcpy(propval, "false");
- }
-
- {
- uchar_t mcr = DTR | RTS;
- if (propval[0] != 'f' && propval[0] != 'F')
- mcr = 0;
- /* set modem control bits */
- outb(port + MCR, mcr | OUT2);
- }
-}
-
-/* For console=usb-serial, store early output in a buffer */
-static char *usbser_buf;
-static char *usbser_cur;
-
-static void
-usbser_init(void)
-{
- if (usbser_buf)
- return;
-
- usbser_cur = usbser_buf = bkmem_zalloc(MMU_PAGESIZE);
- (void) bsetprop(NULL, "usb-serial-buf", &usbser_buf, sizeof (char *));
-}
-
-static void
-usbser_putchar(int c)
-{
- if (usbser_buf == 0 || usbser_cur >= usbser_buf + MMU_PAGESIZE - 1)
- return;
-
- *usbser_cur++ = c;
-}
-
-char *
-console_init(char *bootstr)
-{
- char *cons;
-
- console = CONS_INVALID;
-
- cons = strstr(bootstr, "console=");
- if (cons)
- cons += strlen("console=");
- else {
- cons = strstr(bootstr, "output-device=");
- if (cons)
- cons += strlen("output-device=");
- }
-
- /* both "graphics" and "text" mean "detect graphics mode" now */
- if (cons) {
- if (strncmp(cons, "ttya", 4) == 0) {
- console = CONS_TTYA;
- cons = "ttya";
- } else if (strncmp(cons, "ttyb", 4) == 0) {
- console = CONS_TTYB;
- cons = "ttyb";
- } else if (strncmp(cons, "graphics", 9) == 0) {
- console = CONS_SCREEN_TEXT;
- cons = "graphics";
- } else if (strncmp(cons, "text", 4) == 0) {
- console = CONS_SCREEN_TEXT;
- cons = "text";
- } else if (strncmp(cons, "screen", 6) == 0) {
- console = CONS_SCREEN_TEXT;
- cons = "text";
- } else if (strncmp(cons, "usb-serial", 10) == 0) {
- console = CONS_USBSER;
- cons = "usb-serial";
- }
- }
-
- /*
- * If no console device specified, default to text.
- * Remember what was specified for second phase.
- */
- console_state = console;
- if (console == CONS_INVALID)
- console = CONS_SCREEN_TEXT;
-
- switch (console) {
- case CONS_TTYA:
- case CONS_TTYB:
- case CONS_USBSER:
- /* leave initialization till later, when we know tty mode */
- break;
- case CONS_SCREEN_TEXT:
- default:
- clear_screen();
- kb_init();
- break;
- }
-
- return (cons);
-}
-
-/*
- * Second phase of possible console redirection,
- * based on input-device & output-device eeprom(1M) properties.
- * Also support a unified "console" property.
- */
-void
-console_init2(char *inputdev, char *outputdev, char *consoledev)
-{
- int cons = CONS_INVALID;
-
- if (console_state == CONS_INVALID) {
-
- /* both "graphics" and "text" mean "detect graphics mode" now */
- if (consoledev) {
- if (strcmp(consoledev, "ttya") == 0)
- cons = CONS_TTYA;
- else if (strcmp(consoledev, "ttyb") == 0)
- cons = CONS_TTYB;
- else if (strcmp(consoledev, "usb-serial") == 0)
- cons = CONS_USBSER;
- else if (strcmp(consoledev, "text") == 0)
- cons = CONS_SCREEN_TEXT;
- else if (strcmp(consoledev, "graphics") == 0)
- cons = CONS_SCREEN_TEXT;
- else if (strcmp(consoledev, "screen") == 0)
- cons = CONS_SCREEN_TEXT;
- }
-
- if (cons == CONS_INVALID) {
- if (inputdev) {
- if (strcmp(inputdev, "ttya") == 0)
- cons = CONS_TTYA;
- else if (strcmp(inputdev, "ttyb") == 0)
- cons = CONS_TTYB;
- }
- if (outputdev) {
- if (strcmp(outputdev, "ttya") == 0)
- cons = CONS_TTYA;
- else if (strcmp(outputdev, "ttyb") == 0)
- cons = CONS_TTYB;
- }
- }
-
- if (cons == CONS_INVALID)
- cons = CONS_SCREEN_TEXT;
- console = cons;
-
- switch (console) {
- case CONS_TTYA:
- case CONS_TTYB:
- if (console_state != CONS_TTYA &&
- console_state != CONS_TTYB) {
- serial_init();
- }
- break;
- case CONS_USBSER:
- break;
- case CONS_SCREEN_TEXT:
- if (console_state != CONS_SCREEN_TEXT) {
- clear_screen();
- kb_init();
- }
- break;
- }
- }
-
- /* special handling for graphics boot and serial console */
- switch (console) {
- case CONS_TTYA:
- case CONS_TTYB:
- serial_init();
- break;
- case CONS_USBSER:
- usbser_init();
- break;
- default:
- if (get_videomode() == VGA_GRAPHICS) {
- console_state = CONS_SCREEN_GRAPHICS;
- (void) bsetprop(NULL, "console", "graphics",
- sizeof ("graphics"));
- } else {
- console_state = CONS_SCREEN_TEXT;
- (void) bsetprop(NULL, "console", "text",
- sizeof ("text"));
- }
- };
-}
-
-static void
-serial_putchar(int c)
-{
- int checks = 10000;
-
- while (((inb(port + LSR) & XHRE) == 0) && checks--)
- ;
- outb(port + DAT, (char)c);
-}
-
-static int
-serial_getchar(void)
-{
- uchar_t lsr;
-
- while (serial_ischar() == 0)
- ;
-
- lsr = inb(port + LSR);
- if (lsr & (SERIAL_BREAK | SERIAL_FRAME |
- SERIAL_PARITY | SERIAL_OVERRUN)) {
- if (lsr & SERIAL_OVERRUN) {
- printf("silo overflow\n");
- return (inb(port + DAT));
- } else {
- /* Toss the garbage */
- (void) inb(port + DAT);
- return (0);
- }
- }
- return (inb(port + DAT));
-}
-
-static int
-serial_ischar(void)
-{
- return (inb(port + LSR) & RCA);
-}
-
-static void
-_doputchar(int c)
-{
- switch (console) {
- case CONS_TTYA:
- case CONS_TTYB:
- serial_putchar(c);
- return;
- case CONS_USBSER:
- /*
- * usbser_putchar() prints to memory buffer.
- * The buffer is displayed after consconfig().
- */
- usbser_putchar(c);
- return;
- case CONS_SCREEN_TEXT:
- screen_putchar(c);
- return;
- }
-}
-
-void
-putchar(int c)
-{
- static int bhcharpos = 0;
-
- if (c == '\t') {
- do {
- _doputchar(' ');
- } while (++bhcharpos % 8);
- return;
- } else if (c == '\n' || c == '\r') {
- bhcharpos = 0;
- _doputchar('\r');
- _doputchar(c);
- return;
- } else if (c == '\b') {
- if (bhcharpos)
- bhcharpos--;
- _doputchar(c);
- return;
- }
-
- bhcharpos++;
- _doputchar(c);
-}
-
-
-int
-getchar(void)
-{
- switch (console) {
- case CONS_TTYA:
- case CONS_TTYB:
- return (serial_getchar());
- default:
- return (kb_getchar());
- }
-}
-
-int
-ischar(void)
-{
- switch (console) {
- case CONS_TTYA:
- case CONS_TTYB:
- return (serial_ischar());
- default:
- return (kb_ischar());
- }
-}
-
-/*
- * Read from the console (using getchar) into string str,
- * until a carriage return or until n-1 characters are read.
- * Null terminate the string, and return.
- * This all is made complicated by the fact that we must
- * do our own echoing during input.
- * N.B.: Returns the *number of characters in str*.
- */
-
-int
-cons_gets(char *str, int n)
-{
- int c;
- int t;
- char *p;
-
- p = str;
- c = 0;
-
- while ((t = getchar()) != '\r') {
- putchar(t);
- if (t == '\b') {
- if (c) {
- printf(" \b");
- c--; p--;
- } else
- putchar(' ');
- continue;
- }
- if (c < n - 1) {
- *p++ = t;
- c++;
- }
- }
- putchar('\n');
- *p = '\0';
-
- return (c);
-}
-
-/*PRINTFLIKE1*/
-void
-printf(const char *fmt, ...)
-{
- va_list adx;
-
- va_start(adx, fmt);
- prom_vprintf(fmt, adx);
- va_end(adx);
-}
-
-/* setup boot syscall fields needed by the kernel */
-static struct boot_syscalls sc = {
- getchar,
- putchar,
- ischar
-};
-
-struct boot_syscalls *sysp = &sc;
diff --git a/usr/src/psm/stand/boot/i386/common/serial.h b/usr/src/psm/stand/boot/i386/common/serial.h
deleted file mode 100644
index d63264fa74..0000000000
--- a/usr/src/psm/stand/boot/i386/common/serial.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 1997, Sun Microsystems, Inc. All Rights Reserved.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/* ---- ports on 16550 serial chips ---- */
-#define DAT 0 /* ... data */
-#define ICR 1 /* ... intr control reg */
-#define ISR 2 /* ... intr status reg */
-#define LCR 3 /* ... line control reg */
-#define MCR 4 /* ... modem control reg */
-#define LSR 5 /* ... line status reg */
-#define MSR 6 /* ... modem status reg */
-#define DLL 0 /* ... data latch low (used for baud rate) */
-#define DLH 1 /* ... data latch high (ditto) */
-#define FIFOR ISR /* ... fifo write reg */
-
-/* ---- convenant macros ---- */
-/* this macro uses the _chario_io_p structure */
-#define INB(a, off) \
- (inb((a) + off))
-#define OUTB(a, off, val) \
- (outb((a)+(off), (char)(val)))
-
-/* ---- LSR bits ---- */
-#define RCA 0x01 /* ... receive char avail */
-#define XHRE 0x20 /* ... xmit hold buffer empty */
-
-/* ---- Modem bits ---- */
-#define DTR 0x01
-#define RTS 0x02
-#define OUT2 0x08
-
-#define FIFO_ON 0x01
-#define FIFO_OFF 0x00
-#define FIFORXFLSH 0x02
-#define FIFOTXFLSH 0x04
-#define FIFODMA 0x08
-
-/* ---- LCR bits ---- */
-#define STOP1 00
-#define STOP2 0x04
-#define BITS5 0x00 /* 5 bits per char */
-#define BITS6 0x01 /* 6 bits per char */
-#define BITS7 0x02 /* 7 bits per char */
-#define BITS8 0x03 /* 8 bits per char */
-
-/* baud rate definitions */
-#define DLAB 0x80 /* divisor latch access bit */
-#define ASY110 1047 /* 110 baud rate for serial console */
-#define ASY150 768 /* 150 baud rate for serial console */
-#define ASY300 384 /* 300 baud rate for serial console */
-#define ASY600 192 /* 600 baud rate for serial console */
-#define ASY1200 96 /* 1200 baud rate for serial console */
-#define ASY2400 48 /* 2400 baud rate for serial console */
-#define ASY4800 24 /* 4800 baud rate for serial console */
-#define ASY9600 12 /* 9600 baud rate for serial console */
-#define ASY19200 6 /* 19200 baud rate for serial console */
-#define ASY38400 3 /* 38400 baud rate for serial console */
-#define ASY57600 2 /* 57600 baud rate for serial console */
-#define ASY115200 1 /* 115200 baud rate for serial console */
diff --git a/usr/src/psm/stand/cpr/common/Makefile.com b/usr/src/psm/stand/cpr/common/Makefile.com
index 033907f0c8..8d448c539f 100644
--- a/usr/src/psm/stand/cpr/common/Makefile.com
+++ b/usr/src/psm/stand/cpr/common/Makefile.com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -22,7 +21,7 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# psm/stand/cpr/common/Makefile.com
@@ -66,7 +65,8 @@ CPPINCS += -I$(SYSDIR)/sun4 -I$(SYSDIR)/common -I$(TOPDIR)/head
CPPFLAGS = $(CPPDEFS) $(CPPINCS) $(CPPFLAGS.master)
CPPFLAGS += $(CCYFLAG)$(SYSDIR)/common
-CFLAGS = $(CCVERBOSE) -O
+C99MODE = $(C99_ENABLE)
+CFLAGS = $(CCVERBOSE) -O $(C99MODE)
ASFLAGS = -P -D_ASM $(CPPDEFS) -DLOCORE -D_LOCORE -D__STDC__
AS_CPPFLAGS = $(CPPINCS) $(CPPFLAGS.master)
diff --git a/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.c b/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.c
index e2973d2fcb..5881aa2fca 100644
--- a/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.c
+++ b/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -363,7 +362,7 @@ cb_read_statefile(void)
cb_nbitmaps = cdump.cdd_bitmaprec;
cpr_test_mode = cdump.cdd_test_mode;
sfile.kpages = cdump.cdd_dumppgsize;
- DEBUG4(prom_printf("%s: total kpages %d\n", prog, sfile.kpages));
+ CPR_DEBUG(CPR_DEBUG4, "%s: total kpages %d\n", prog, sfile.kpages);
/*
* alloc virt and phys space with 512K alignment;
@@ -401,7 +400,7 @@ cb_read_statefile(void)
cnt = 0;
dtlb_index = cb_dents - 1;
(void) prom_seek(sfile.fd, specialstate ? CPR_SPEC_OFFSET : 0);
- DEBUG1(prom_printf("%s: reading statefile... ", prog));
+ CPR_DEBUG(CPR_DEBUG1, "%s: reading statefile... ", prog);
for (resid = cdump.cdd_filesize; resid; resid -= len) {
/*
* do a full spin (4 spin chars)
@@ -432,7 +431,7 @@ cb_read_statefile(void)
dst_virt += len;
dst_phys += len;
}
- DEBUG1(prom_printf(" \b\n"));
+ CPR_DEBUG(CPR_DEBUG1, " \b\n");
/*
* free up any unused phys pages trailing the statefile buffer;
diff --git a/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.h b/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.h
index 52807b6616..2102820146 100644
--- a/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.h
+++ b/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -81,7 +80,7 @@ extern "C" {
#define NULLP (char *)0
-#define CPR_DBG(n) (cpr_debug & LEVEL##n)
+#define CPR_DBG(n) (cpr_debug & CPR_DEBUG##n)
/*
diff --git a/usr/src/psm/stand/cpr/sparcv9/sun4u/pages.c b/usr/src/psm/stand/cpr/sparcv9/sun4u/pages.c
index e8781db864..a8513319e9 100644
--- a/usr/src/psm/stand/cpr/sparcv9/sun4u/pages.c
+++ b/usr/src/psm/stand/cpr/sparcv9/sun4u/pages.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -285,7 +284,7 @@ cb_restore_kpages(void)
str = "cb_restore_kpages";
CB_VPRINTF((ent_fmt, str, entry));
- DEBUG1(prom_printf("%s: restoring kpages... ", prog));
+ CPR_DEBUG(CPR_DEBUG1, "%s: restoring kpages... ", prog);
npages = compressed = regular = 0;
while (npages < sfile.kpages) {
get_phys_data(&desc, sizeof (desc));
@@ -310,7 +309,7 @@ cb_restore_kpages(void)
if ((sfile.ngroups++ & 0x1f) == 0)
cb_spin();
}
- DEBUG1(prom_printf(" \b\n"));
+ CPR_DEBUG(CPR_DEBUG1, " \b\n");
dtlb_cleanup();
@@ -322,9 +321,9 @@ cb_restore_kpages(void)
sfile.ngroups, sfile.recycle);
}
- DEBUG4(prom_printf(
+ CPR_DEBUG(CPR_DEBUG4,
"%s: total=%d, npages=%d, compressed=%d, regular=%d\n",
- str, sfile.kpages, npages, compressed, regular));
+ str, sfile.kpages, npages, compressed, regular);
/*
* sanity check
diff --git a/usr/src/tools/Makefile b/usr/src/tools/Makefile
index 3bf6dcf572..82af4e14a5 100644
--- a/usr/src/tools/Makefile
+++ b/usr/src/tools/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -60,8 +60,10 @@ sparc_SUBDIRS= \
stabs \
tokenize
-i386_SUBDIRS= \
- aw
+i386_SUBDIRS= \
+ aw \
+ elfextract \
+ mbh_patch
LINTSUBDIRS= \
codereview \
diff --git a/usr/src/tools/ctf/cvt/ctfmerge.c b/usr/src/tools/ctf/cvt/ctfmerge.c
index 3afea434de..70ca22c7fe 100644
--- a/usr/src/tools/ctf/cvt/ctfmerge.c
+++ b/usr/src/tools/ctf/cvt/ctfmerge.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -879,8 +878,16 @@ main(int argc, char **argv)
* don't need to specify labels.
*/
if (read_ctf(ifiles, nifiles, NULL, merge_ctf_cb,
- &wq, require_ctf) == 0)
+ &wq, require_ctf) == 0) {
+ /*
+ * If we're verifying that C files have CTF, it's safe to
+ * assume that in this case, we're building only from assembly
+ * inputs.
+ */
+ if (require_ctf)
+ exit(0);
terminate("No ctf sections found to merge\n");
+ }
pthread_mutex_lock(&wq.wq_queue_lock);
wq.wq_nomorefiles = 1;
diff --git a/usr/src/tools/ctf/cvt/dwarf.c b/usr/src/tools/ctf/cvt/dwarf.c
index 961f7e6610..a7e97dfb23 100644
--- a/usr/src/tools/ctf/cvt/dwarf.c
+++ b/usr/src/tools/ctf/cvt/dwarf.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -935,8 +935,11 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
(void) die_unsigned(dw, str, DW_AT_byte_size, &sz, DW_ATTR_REQ);
tdp->t_size = sz;
+ /*
+ * GCC allows empty SOUs as an extension.
+ */
if ((mem = die_child(dw, str)) == NULL)
- terminate("die %llu: %s has no members", off, typename);
+ goto out;
mlastp = &tdp->t_members;
@@ -1026,10 +1029,11 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
if (tdp->t_name != NULL)
free(tdp->t_name);
tdp->t_name = new;
-
+ return;
}
- if (tdp->t_name != NULL && tdp->t_members != NULL) {
+out:
+ if (tdp->t_name != NULL) {
ii = xcalloc(sizeof (iidesc_t));
ii->ii_type = II_SOU;
ii->ii_name = xstrdup(tdp->t_name);
@@ -1066,10 +1070,22 @@ die_sou_resolve(tdesc_t *tdp, tdesc_t **tdpp, void *private)
for (ml = tdp->t_members; ml != NULL; ml = ml->ml_next) {
if (ml->ml_size == 0) {
- if ((ml->ml_size = tdesc_bitsize(ml->ml_type)) == 0) {
- dw->dw_nunres++;
- return (1);
- }
+ mt = tdesc_basetype(ml->ml_type);
+
+ if ((ml->ml_size = tdesc_bitsize(mt)) != 0)
+ continue;
+
+ /*
+ * For empty members, or GCC/C99 flexible array
+ * members, a size of 0 is correct.
+ */
+ if (mt->t_members == NULL)
+ continue;
+ if (mt->t_type == ARRAY && mt->t_ardef->ad_nelems == 0)
+ continue;
+
+ dw->dw_nunres++;
+ return (1);
}
if ((mt = tdesc_basetype(ml->ml_type)) == NULL) {
diff --git a/usr/src/tools/elfextract/Makefile b/usr/src/tools/elfextract/Makefile
new file mode 100644
index 0000000000..7a3e6838d4
--- /dev/null
+++ b/usr/src/tools/elfextract/Makefile
@@ -0,0 +1,44 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+include ../Makefile.tools
+
+PROG = elfextract
+
+include ../Makefile.tools
+
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all .WAIT $(ROOTONBLDMACHPROG)
+
+clean:
+ $(RM) elfextract
+
+include ../Makefile.targ
diff --git a/usr/src/tools/elfextract/elfextract.c b/usr/src/tools/elfextract/elfextract.c
new file mode 100644
index 0000000000..71cd685888
--- /dev/null
+++ b/usr/src/tools/elfextract/elfextract.c
@@ -0,0 +1,274 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <strings.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/inttypes.h>
+#include <sys/elf.h>
+#include <sys/elf_notes.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+
+static char *pname;
+static char *fname;
+static char *image; /* pointer to the ELF file in memory */
+
+#define ELFSEEK(offset) ((void *)(image + offset))
+
+/*
+ * Extract the PT_LOAD bits and format them into a .s
+ */
+static void
+extract32(Elf32_Ehdr *eh)
+{
+ Elf32_Phdr *phdr;
+ caddr_t allphdrs;
+ int i;
+ int c;
+ unsigned char *bytes;
+ uint_t cnt = 10;
+
+ allphdrs = NULL;
+
+ if (eh->e_type != ET_EXEC) {
+ (void) fprintf(stderr, "%s: not ET_EXEC, e_type = 0x%x\n",
+ pname, eh->e_type);
+ exit(1);
+ }
+ if (eh->e_phnum == 0 || eh->e_phoff == 0) {
+ (void) fprintf(stderr, "%s: no program headers\n", pname);
+ exit(1);
+ }
+
+ /*
+ * Get the program headers.
+ */
+ allphdrs = ELFSEEK(eh->e_phoff);
+ if (allphdrs == NULL) {
+ (void) fprintf(stderr, "%s: Failed to get %d program hdrs\n",
+ pname, eh->e_phnum);
+ exit(1);
+ }
+
+ /*
+ * Find the PT_LOAD section
+ */
+ for (i = 0; i < eh->e_phnum; i++) {
+ /*LINTED [ELF program header alignment]*/
+ phdr = (Elf32_Phdr *)(allphdrs + eh->e_phentsize * i);
+
+ if (phdr->p_type != PT_LOAD)
+ continue;
+
+ if (phdr->p_memsz == 0)
+ continue;
+
+ bytes = ELFSEEK(phdr->p_offset);
+ for (c = 0; c < phdr->p_filesz; ++c) {
+ if (c % cnt == 0)
+ (void) printf("\n .byte ");
+ else
+ (void) printf(",");
+ (void) printf("0x%x", bytes[c]);
+ }
+ for (; c < phdr->p_memsz; ++c) {
+ if (c % cnt == 0) {
+ (void) printf("\n .byte ");
+ cnt = 20;
+ } else {
+ (void) printf(", ");
+ }
+ (void) printf("0");
+ }
+ (void) printf("\n");
+ return;
+ }
+
+ (void) fprintf(stderr, "%s: Failed finding PT_LOAD section\n", pname);
+ exit(1);
+}
+
+static void
+extract64(Elf64_Ehdr *eh)
+{
+ Elf64_Phdr *phdr;
+ caddr_t allphdrs;
+ int i;
+ int c;
+ unsigned char *bytes;
+ uint_t cnt = 10;
+
+ allphdrs = NULL;
+
+ if (eh->e_type != ET_EXEC) {
+ (void) fprintf(stderr, "%s: not ET_EXEC, e_type = 0x%x\n",
+ pname, eh->e_type);
+ exit(1);
+ }
+ if (eh->e_phnum == 0 || eh->e_phoff == 0) {
+ (void) fprintf(stderr, "%s: no program headers\n", pname);
+ exit(1);
+ }
+
+ /*
+ * Get the program headers.
+ */
+ allphdrs = ELFSEEK(eh->e_phoff);
+ if (allphdrs == NULL) {
+ (void) fprintf(stderr, "%s: Failed to get %d program hdrs\n",
+ pname, eh->e_phnum);
+ exit(1);
+ }
+
+ /*
+ * Find the PT_LOAD section
+ */
+ for (i = 0; i < eh->e_phnum; i++) {
+ /*LINTED [ELF program header alignment]*/
+ phdr = (Elf64_Phdr *)(allphdrs + eh->e_phentsize * i);
+
+ if (phdr->p_type != PT_LOAD)
+ continue;
+
+ if (phdr->p_memsz == 0)
+ continue;
+
+ bytes = ELFSEEK(phdr->p_offset);
+ for (c = 0; c < phdr->p_filesz; ++c) {
+ if (c % cnt == 0)
+ (void) printf("\n .byte ");
+ else
+ (void) printf(",");
+ (void) printf("0x%x", bytes[c]);
+ }
+ for (; c < phdr->p_memsz; ++c) {
+ if (c % cnt == 0) {
+ (void) printf("\n .byte ");
+ cnt = 20;
+ } else {
+ (void) printf(", ");
+ }
+ (void) printf("0");
+ }
+ (void) printf("\n");
+ return;
+ }
+
+ (void) fprintf(stderr, "%s: Failed finding PT_LOAD section\n", pname);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int fd;
+ uchar_t *ident;
+ void *hdr = NULL;
+ struct stat stats;
+ ssize_t r;
+ uint_t len;
+
+ /*
+ * we expect one argument -- the elf file
+ */
+ if (argc != 2) {
+ (void) fprintf(stderr, "usage: %s <unix-elf-file>\n", argv[0]);
+ exit(1);
+ }
+
+ pname = strrchr(argv[0], '/');
+ if (pname == NULL)
+ pname = argv[0];
+ else
+ ++pname;
+
+ fname = argv[1];
+ fd = open(fname, O_RDONLY);
+ if (fd < 0) {
+ (void) fprintf(stderr, "%s: open(%s, O_RDONLY) failed, %s\n",
+ pname, fname, strerror(errno));
+ exit(1);
+ }
+
+ if (stat(fname, &stats) < 0) {
+ (void) fprintf(stderr, "%s: stat(%s, ...) failed, %s\n",
+ pname, fname, strerror(errno));
+ exit(1);
+ }
+
+ len = stats.st_blocks * 512;
+ len += 0xfff;
+ len &= ~0xfff;
+
+#ifdef BUG_6491065_IS_FIXED
+ /*
+ * mmap the file
+ */
+ image = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
+ if (image == MAP_FAILED) {
+ (void) fprintf(stderr, "%s: mmap() of %s failed, %s\n",
+ pname, fname, strerror(errno));
+ exit(1);
+ }
+#else
+ if ((image = malloc(stats.st_size)) == NULL) {
+ (void) fprintf(stderr, "%s: out of memory\n", pname);
+ exit(1);
+ }
+ if ((r = read(fd, image, stats.st_size)) != stats.st_size) {
+ (void) fprintf(stderr, "%s: stat(%s, ...) failed, %s\n",
+ pname, fname, strerror(errno));
+ exit(1);
+ }
+#endif
+
+ ident = ELFSEEK(0);
+ if (ident[EI_MAG0] != ELFMAG0 || ident[EI_MAG1] != ELFMAG1 ||
+ ident[EI_MAG2] != ELFMAG2 || ident[EI_MAG3] != ELFMAG3) {
+ (void) fprintf(stderr, "%s: not an ELF file!\n", pname);
+ exit(1);
+ }
+
+ if (ident[EI_CLASS] == ELFCLASS32) {
+ hdr = ELFSEEK(0);
+ extract32(hdr);
+ } else if (ident[EI_CLASS] == ELFCLASS64) {
+ hdr = ELFSEEK(0);
+ extract64(hdr);
+ } else {
+ (void) fprintf(stderr, "%s: Wrong ELF class 0x%x\n", pname,
+ ident[EI_CLASS]);
+ exit(1);
+ }
+ return (0);
+}
diff --git a/usr/src/tools/findunref/exception_list b/usr/src/tools/findunref/exception_list
index de4da39448..e2db37045c 100644
--- a/usr/src/tools/findunref/exception_list
+++ b/usr/src/tools/findunref/exception_list
@@ -18,7 +18,7 @@
#
# CDDL HEADER END
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -112,7 +112,7 @@
./src/prototypes
*/tools
./src/cmd/pools/poold/com/sun/solaris/*/*/package.html
-./src/uts/i86pc/io/acpica/cmp_ca.sh
+./src/uts/intel/io/acpica/cmp_ca.sh
#
# Ignore files that are only used by internal packages.
diff --git a/usr/src/tools/mbh_patch/Makefile b/usr/src/tools/mbh_patch/Makefile
new file mode 100644
index 0000000000..68d2559864
--- /dev/null
+++ b/usr/src/tools/mbh_patch/Makefile
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+include ../Makefile.tools
+
+PROG = mbh_patch
+
+include ../Makefile.tools
+
+CPPFLAGS += -I../../uts/common
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all .WAIT $(ROOTONBLDMACHPROG)
+
+clean:
+ $(RM) mbh_patch
+
+include ../Makefile.targ
diff --git a/usr/src/tools/mbh_patch/mbh_patch.c b/usr/src/tools/mbh_patch/mbh_patch.c
new file mode 100644
index 0000000000..404b1f3871
--- /dev/null
+++ b/usr/src/tools/mbh_patch/mbh_patch.c
@@ -0,0 +1,213 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <strings.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/inttypes.h>
+#include <sys/elf.h>
+#include <sys/elf_notes.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include "sys/multiboot.h"
+
+static char *pname;
+static char *fname;
+static char *image; /* pointer to the ELF file in memory */
+
+#define ELFSEEK(offset) ((void *)(image + offset))
+
+/*
+ * patch the load address / entry address
+ * Find the physical load address of the 1st PT_LOAD segment.
+ * Find the amount that e_entry exceeds that amount.
+ * Now go back and subtract the excess from the p_paddr of the LOAD segment.
+ */
+static void
+patch64(Elf64_Ehdr *eh)
+{
+ Elf64_Phdr *phdr;
+ caddr_t allphdrs;
+ int i;
+ int m;
+ int extra;
+ multiboot_header_t *mbh;
+
+ allphdrs = NULL;
+
+ if (eh->e_type != ET_EXEC) {
+ (void) fprintf(stderr, "%s: not ET_EXEC, e_type = 0x%x\n",
+ pname, eh->e_type);
+ exit(1);
+ }
+ if (eh->e_phnum == 0 || eh->e_phoff == 0) {
+ (void) fprintf(stderr, "%s: no program headers\n", pname);
+ exit(1);
+ }
+
+ /*
+ * Get the program headers.
+ */
+ allphdrs = ELFSEEK(eh->e_phoff);
+ if (allphdrs == NULL) {
+ (void) fprintf(stderr, "%s: Failed to get %d program hdrs\n",
+ pname, eh->e_phnum);
+ exit(1);
+ }
+
+ /*
+ * Look for multiboot header. It must be 32-bit aligned and
+ * completely contained in the 1st 8K of the file.
+ */
+ for (m = 0; m < 8192 - sizeof (multiboot_header_t); m += 4) {
+ mbh = (void *)(image + m);
+ if (mbh->magic == MB_HEADER_MAGIC)
+ break;
+ }
+
+ if (m >= 8192 - sizeof (multiboot_header_t)) {
+ (void) fprintf(stderr, "%s: Didn't find multiboot header\n",
+ pname);
+ exit(1);
+ }
+
+ /*
+ * Find the 1:1 mapped PT_LOAD section
+ */
+ for (i = 0; i < eh->e_phnum; i++) {
+ /*LINTED [ELF program header alignment]*/
+ phdr = (Elf64_Phdr *)(allphdrs + eh->e_phentsize * i);
+
+ /*
+ * Find the low memory 1:1 PT_LOAD section!
+ */
+ if (phdr->p_type != PT_LOAD)
+ continue;
+
+ if (phdr->p_memsz == 0)
+ continue;
+
+ if (phdr->p_paddr != phdr->p_vaddr)
+ continue;
+
+ if (i != 0) {
+ (void) fprintf(stderr, "%s: identity mapped PT_LOAD"
+ " wasn't 1st\n", pname);
+ exit(1);
+ }
+
+ /*
+ * Patch the multiboot header fields to get entire
+ * file loaded, with entry aligned at extra.
+ */
+ if (eh->e_entry != phdr->p_paddr) {
+ (void) fprintf(stderr, "%s: entry != paddr\n", pname);
+ exit(1);
+ }
+
+ /*
+ * Grub uses the MB header for 64 bit loading.
+ */
+ mbh->load_addr = phdr->p_paddr - phdr->p_offset;
+ mbh->entry_addr = phdr->p_paddr;
+ mbh->header_addr = mbh->load_addr + m;
+#ifdef VERBOSE
+ (void) printf("%s ELF64 MB header patched by 0x%0x "
+ "bytes:\n", fname, extra);
+ (void) printf("\tload_addr now 0x%x\n", mbh->load_addr);
+ (void) printf("\tentry_addr now 0x%x\n", mbh->entry_addr);
+ (void) printf("\theader_addr now 0x%x\n", mbh->header_addr);
+#endif
+ exit(0);
+ }
+
+ (void) fprintf(stderr, "%s: Didn't find 1:1 mapped PT_LOAD section\n",
+ pname);
+ exit(1);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int fd;
+ uchar_t *ident;
+ void *hdr = NULL;
+
+ /*
+ * we expect one argument -- the elf file
+ */
+ if (argc != 2) {
+ (void) fprintf(stderr, "usage: %s <unix-elf-file>\n", argv[0]);
+ exit(1);
+ }
+
+ pname = strrchr(argv[0], '/');
+ if (pname == NULL)
+ pname = argv[0];
+ else
+ ++pname;
+
+ fname = argv[1];
+ fd = open(fname, O_RDWR);
+ if (fd < 0) {
+ (void) fprintf(stderr, "%s: open(%s, O_RDWR) failed\n",
+ pname, fname);
+ exit(1);
+ }
+
+ /*
+ * mmap just the 1st 8K -- since that's where the GRUB
+ * multiboot header must be located.
+ */
+ image = mmap(NULL, 8192, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (image == MAP_FAILED) {
+ (void) fprintf(stderr, "%s: mmap() of %s failed\n",
+ pname, fname);
+ exit(1);
+ }
+
+ ident = ELFSEEK(0);
+ if (ident[EI_MAG0] != ELFMAG0 || ident[EI_MAG1] != ELFMAG1 ||
+ ident[EI_MAG2] != ELFMAG2 || ident[EI_MAG3] != ELFMAG3) {
+ (void) fprintf(stderr, "%s: not an ELF file!\n", pname);
+ exit(1);
+ }
+
+ if (ident[EI_CLASS] == ELFCLASS64) {
+ hdr = ELFSEEK(0);
+ patch64(hdr);
+ } else if (ident[EI_CLASS] != ELFCLASS32) {
+ (void) fprintf(stderr, "%s: Unknown ELF class 0x%x\n", pname,
+ ident[EI_CLASS]);
+ exit(1);
+ }
+ return (0);
+}
diff --git a/usr/src/tools/protocmp/arch.c b/usr/src/tools/protocmp/arch.c
index 36ca0fb0aa..5d78c3b019 100644
--- a/usr/src/tools/protocmp/arch.c
+++ b/usr/src/tools/protocmp/arch.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,7 +36,7 @@ assign_arch(const char *architecture)
{
int arch = 0;
-#if defined(sparc)
+#if defined(__sparc)
if (strcmp(architecture, "sparc") == 0)
arch = P_SPARC;
else if (strcmp(architecture, "ISA") == 0)
@@ -58,7 +57,7 @@ assign_arch(const char *architecture)
arch = P_SUN4m;
else if (strcmp(architecture, "sparc.sun4v") == 0)
arch = P_SUN4v;
-#elif defined(i386)
+#elif defined(__i386)
if (strcmp(architecture, "i386") == 0)
arch = P_I386;
else if (strcmp(architecture, "ISA") == 0)
diff --git a/usr/src/tools/protocmp/list.h b/usr/src/tools/protocmp/list.h
index 0cbab88f61..497fd43650 100644
--- a/usr/src/tools/protocmp/list.h
+++ b/usr/src/tools/protocmp/list.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,13 +19,18 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+#ifndef _LIST_H
+#define _LIST_H
+#pragma ident "%Z%%M% %I% %E% SMI"
+#ifdef __cplusplus
+extern "C" {
+#endif
/*
* Constants
@@ -155,3 +159,9 @@ extern void print_type_list(elem_list *list, char file_type);
/* Global statistics */
extern int max_list_depth;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIST_H */
diff --git a/usr/src/tools/protocmp/proto_list.c b/usr/src/tools/protocmp/proto_list.c
index a4d995ff88..e09a8c03b7 100644
--- a/usr/src/tools/protocmp/proto_list.c
+++ b/usr/src/tools/protocmp/proto_list.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -195,7 +194,7 @@ parse_line(char **v, elem *e)
e->symsrc = malloc(strlen(v[SYM]) + 1);
(void) strcpy(e->symsrc, v[SYM]);
if (e->file_type != SYM_LINK_T)
-#if defined(sparc)
+#if defined(__sparc)
if (strncmp(e->symsrc, "sun4/", 5) == 0)
e->arch = P_SUN4;
else if (strncmp(e->symsrc, "sun4c/", 6) == 0)
@@ -210,7 +209,7 @@ parse_line(char **v, elem *e)
e->arch = P_SUN4m;
else if (strncmp(e->symsrc, "sun4v/", 6) == 0)
e->arch = P_SUN4v;
-#elif defined(i386)
+#elif defined(__i386)
if (strncmp(e->symsrc, "i86pc/", 6) == 0)
e->arch = P_I86PC;
#elif defined(__ppc)
diff --git a/usr/src/tools/scripts/Install.sh b/usr/src/tools/scripts/Install.sh
index 9d8f99a715..f491412c46 100644
--- a/usr/src/tools/scripts/Install.sh
+++ b/usr/src/tools/scripts/Install.sh
@@ -20,7 +20,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#From: "@(#)Install 1.56 96/10/11 SMI"
@@ -391,7 +391,7 @@ copy_kernel() {
case $KARCH in
sun4*) ISA=sparc; MACH=sparc ;;
- i86pc) ISA=intel; MACH=i386 ;;
+ i86*) ISA=intel; MACH=i386 ;;
*) fail "${KARCH}: invalid kernel architecture";;
esac
export MACH
@@ -491,7 +491,8 @@ copy_kernel() {
#
# on x86, add the glommed kernel name to the root archive
#
- if [[ $KARCH = "i86pc" && $GLOM == "yes" ]]; then
+ if [[ $MACH = "i386" && $GLOM == "yes" ]];
+ then
filelist="$INSTALL_FILES/etc/boot/solaris/filelist.ramdisk"
mkdir -p `dirname $filelist`
echo "platform/$KARCH/$GLOMNAME" >$filelist
diff --git a/usr/src/tools/scripts/bfu.sh b/usr/src/tools/scripts/bfu.sh
index 5712e4f5a6..08ba1a27b5 100644
--- a/usr/src/tools/scripts/bfu.sh
+++ b/usr/src/tools/scripts/bfu.sh
@@ -437,7 +437,6 @@ fail() {
print "$*" >& 2
print "bfu aborting" >& 2
rm -f "$local_zone_info_file"
- prun 1
exit 1
}
@@ -1394,6 +1393,54 @@ smf_bkbfu_repair_sysconfig() {
EOF
}
+#
+# Return true if $file exists in $archive. $file may also be a pattern.
+#
+archive_file_exists()
+{
+ archive=$1
+ file=$2
+
+ $ZCAT $cpiodir/${archive}${ZFIX} | cpio -it 2>/dev/null | \
+ egrep -s "$file"
+}
+
+#
+# If we're no longer delivering the eeprom service, remove it from the system,
+# as eeprom -I is removed as well.
+#
+smf_fix_i86pc_profile () {
+ mfst="var/svc/manifest/platform/i86pc/eeprom.xml"
+ profile="var/svc/profile/platform_i86pc.xml"
+
+ if [ ! "$karch" = "i86pc" ]; then
+ return
+ fi
+
+ if ! archive_file_exists generic.root "^$profile"; then
+ rm -f $rootprefix/$profile
+ fi
+
+ if [ ! -f $rootprefix/$mfst ]; then
+ return
+ fi
+
+ if archive_file_exists generic.root "^$mfst"; then
+ return
+ fi
+
+ rm -f $rootprefix/$mfst
+
+ #
+ # we must disable via svccfg directly, as manifest-import runs after
+ # this service tries to run
+ #
+ [[ -n "$rootprefix" ]] &&
+ export SVCCFG_REPOSITORY=$rootprefix/etc/svc/repository.db
+ /tmp/bfubin/svccfg delete -f platform/i86pc/eeprom
+ [[ -n "$rootprefix" ]] && unset SVCCFG_REPOSITORY
+}
+
smf_apply_conf () {
#
# Go thru the original manifests and move any that were unchanged
@@ -1854,6 +1901,7 @@ EOF
esac
EOF
+ smf_fix_i86pc_profile
}
EXTRACT_LOG=/tmp/bfu-extract-log.$$
@@ -1907,14 +1955,27 @@ while [ $# -gt 0 ]; do
shift
done
+# Variables for x86 platforms
boot_is_pcfs=no
have_realmode=no
-multiboot_archives=no
-dca_to_multi=no
is_pcfs_boot=no
need_datalink=no
new_dladm=no
+# Set when moving to either directboot or multiboot
+multi_or_direct=no
+
+#
+# Shows which type of archives we have, which type of system we are
+# running on (before the bfu), and what the failsafe archives are
+# (again, before the bfu). failsafe_type is only needed on diskful
+# bfu's, so it's not set in the diskless case.
+# Possible values: unknown, dca, multiboot, directboot
+#
+archive_type=unknown
+system_type=unknown
+failsafe_type=unknown
+
test $# -ge 1 || usage
if [ -x /usr/bin/ppriv ]; then
@@ -1952,6 +2013,27 @@ case `echo generic.root*` in
*) fail "generic.root missing or in unknown compression format";;
esac
+#
+# Determine what kind of archives we're installing, using the following rules:
+#
+# 1. If strap.com is present, the archives are pre-multiboot
+# 2. If symdef is present, the archives are directboot
+# 3. Otherwise, the archives are multiboot
+#
+if [ $target_isa = i386 ]; then
+ if [ -f $cpiodir/i86pc.boot$ZFIX ] && \
+ archive_file_exists i86pc.boot "strap.com"; then
+ archive_type=dca
+ elif [ -f $cpiodir/i86pc.root$ZFIX ] && \
+ archive_file_exists i86pc.boot symdef; then
+ archive_type=directboot
+ multi_or_direct=yes
+ else
+ archive_type=multiboot
+ multi_or_direct=yes
+ fi
+fi
+
if [ $diskless = no ]; then
root=${2:-/}
[[ "$root" = /* ]] || fail "root-dir must be an absolute path"
@@ -1962,6 +2044,12 @@ if [ $diskless = no ]; then
[[ -f $root/etc/system ]] || \
fail "$root/etc/system not found; local zone target not allowed"
+ if [ -f $root/boot/platform/i86pc/kernel/unix ]; then
+ failsafe_type=directboot
+ elif [ -f $root/boot/multiboot ]; then
+ failsafe_type=multiboot
+ fi
+
# Make sure we extract the sun4u-us3 libc_psr.so.1
if [ -d $root/platform/sun4u -a \
! -d $root/platform/sun4u-us3 ]
@@ -2116,10 +2204,12 @@ if [ ! -x $usr/lib/dbus-daemon ]; then
fail "Run $update_script to update D-Bus."
fi
-if [[ $target_isa = i386 && -f $cpiodir/i86pc.root$ZFIX ]] && \
- $ZCAT $cpiodir/i86pc.root$ZFIX | cpio -it 2>/dev/null | \
- grep multiboot >/dev/null 2>&1 ; then
- multiboot_archives=yes
+#
+# We need biosdev if we're moving from pre-multiboot to multiboot or directboot
+# kernels.
+#
+if [ $target_isa = i386 ] && [ $multi_or_direct = yes ] && [ $diskless = no ]
+then
prtconf -v | grep biosdev >/dev/null 2>&1
if [ $? -ne 0 ] && [ ! -f $rootprefix/platform/i86pc/multiboot ]; then
echo "biosdev cannot be run on this machine."
@@ -2199,9 +2289,7 @@ bfucmd="
/usr/bin/pkginfo
/usr/bin/pkill
/usr/bin/printf
- /usr/bin/prun
/usr/bin/ps
- /usr/bin/pstop
/usr/bin/ptree
/usr/bin/rm
/usr/bin/rmdir
@@ -2319,24 +2407,101 @@ do
done
#
-# set up installgrub and friends if transitioning to multiboot
+# set up installgrub and friends if transitioning to multiboot or directboot
# do this now so ldd can determine library dependencies
#
+# We split the binaries into two groups: the type where we want to make any
+# effort to get the newest version (like symdef and bootadm), and the type
+# where any old version will do (like installgrub and biosdev).
+#
+# If we're bfu'ing across the directboot/multiboot boundary, we need the new
+# bootadm and symdef to properly handle menu.lst changes. If the system is
+# directboot, we can use the local copies. If the system is multiboot but
+# the archives are directboot, we extract the binaries early. Otherwise,
+# we're not crossing the boundary, and which one we use doesn't matter.
+#
+# NB - if bootadm or symdef is ever changed to require a new library, the
+# early extraction will blow up horribly.
+#
+# For testing purposes, a user can set DIRECTBOOT_BIN_DIR in the environment,
+# and we'll use that instead.
+#
MULTIBOOT_BIN_DIR=${MULTIBOOT_BIN_DIR:=${GATE}/public/multiboot}
+have_new_bootadm=unknown
+
+if [ -x $root/boot/solaris/bin/symdef ] && \
+ $root/boot/solaris/bin/symdef $root/platform/i86pc/kernel/unix dboot_image
+then
+ root_is_directboot=yes
+else
+ root_is_directboot=no
+fi
+
+#
+# A comma-separated list of the command and the archive it's in
+#
+multiboot_new_cmds="
+ sbin/bootadm,generic.sbin
+ boot/solaris/bin/symdef,i86pc.boot
+"
+
+if [ $multi_or_direct = yes ]; then
+ for line in $multiboot_new_cmds
+ do
+ cmd=${line%,*}
+ file=${cmd##*/}
+ archive=${line#*,}
+ if [ -n "$DIRECTBOOT_BIN_DIR" ] && \
+ [ -f $DIRECTBOOT_BIN_DIR/$file ]; then
+ cp $DIRECTBOOT_BIN_DIR/$file /tmp/bfubin/
+ else
+ if [ $root_is_directboot = yes ]; then
+ cp $root/$cmd /tmp/bfubin/
+ have_new_bootadm=yes
+ elif [ $archive_type = directboot ]; then
+ DBOOT_TMPDIR=/tmp/dboot.$$
+ trap "rm -rf $DBOOT_TMPDIR" EXIT
+ OLD_PWD=$(pwd)
+ rm -rf $DBOOT_TMPDIR
+ mkdir $DBOOT_TMPDIR
+ cd $DBOOT_TMPDIR
+ $ZCAT $cpiodir/${archive}$ZFIX | \
+ cpio -id "$cmd" 2>/dev/null
+ if [ -x $cmd ]; then
+ cp $cmd /tmp/bfubin/
+ have_new_bootadm=yes
+ fi
+ cd $OLD_PWD
+ rm -rf $DBOOT_TMPDIR
+ trap - EXIT
+ fi
+ fi
+
+ #
+ # If all else fails, grab the local version
+ #
+ if [ ! -x /tmp/bfubin/$file ]; then
+ [ -x /$cmd ] && cp /$cmd /tmp/bfubin
+ fi
+ done
+fi
multiboot_cmds="
/sbin/biosdev
/sbin/installgrub
- /sbin/bootadm
"
copying_mboot_cmds=no
-if [ $multiboot_archives = yes ]; then
+if [ $multi_or_direct = yes ]; then
for cmd in $multiboot_cmds
do
+ file=`basename $cmd`
if [ -f $cmd ]; then
cp $cmd /tmp/bfubin
+ elif [ -n "$DIRECTBOOT_BIN_DIR" ] &&
+ [ -d $DIRECTBOOT_BIN_DIR ] &&
+ [ -x $DIRECTBOOT_BIN_DIR/$file ]; then
+ cp $DIRECTBOOT_BIN_DIR/$file /tmp/bfubin/
else
- file=`basename $cmd`
if [ ! -d $MULTIBOOT_BIN_DIR ]; then
echo "$MULTIBOOT_BIN_DIR: not found"
elif [ ! -f $MULTIBOOT_BIN_DIR/$file ]; then
@@ -2452,9 +2617,10 @@ multiboot_scr="
/boot/solaris/bin/root_archive
"
-if [ $multiboot_archives = yes ]; then
+if [ $multi_or_direct = yes ]; then
for cmd in $multiboot_scr
do
+ file=`basename $cmd`
if [ -f $cmd ]; then
cp $cmd /tmp/bfubin
else
@@ -2463,7 +2629,6 @@ if [ $multiboot_archives = yes ]; then
fail ""
fi
- file=`basename $cmd`
if [ ! -f $MULTIBOOT_BIN_DIR/$file ]; then
echo "$MULTIBOOT_BIN_DIR/$file: not found"
fail ""
@@ -2472,9 +2637,13 @@ if [ $multiboot_archives = yes ]; then
cp $MULTIBOOT_BIN_DIR/$file /tmp/bfubin
fi
- file=`basename $cmd`
+ #
+ # We do two substitutions here to replace references to
+ # both /usr/bin/ and /bin/ with /tmp/bfubin/
+ #
mv /tmp/bfubin/${file} /tmp/bfubin/${file}-
- sed 's/\/usr\/bin\//\/tmp\/bfubin\//g' \
+ sed -e 's/\/usr\/bin\//\/tmp\/bfubin\//g' \
+ -e 's/\/bin\//\/tmp\/bfubin\//g' \
< /tmp/bfubin/${file}- > /tmp/bfubin/${file}
chmod +x /tmp/bfubin/${file}
done
@@ -3702,7 +3871,7 @@ do
smf_check_repository
done
-MINIMUM_OS_REV=9
+MINIMUM_OS_REV=10
#
# Perform additional sanity checks if we are upgrading the live system.
@@ -3716,6 +3885,10 @@ then
if [ $os_rev -lt $MINIMUM_OS_REV -a "$force_override" = "no" ]; then
fail "Cannot bfu from pre-Solaris $MINIMUM_OS_REV"
fi
+ if [ ! -x /usr/sbin/svcadm ]; then
+ fail "This version of bfu cannot run on pre-Greenline " \
+ "(s10_64) systems"
+ fi
#
# Filesystem space checks
@@ -3748,12 +3921,6 @@ then
modload -p exec/intpexec >/dev/null 2>&1
modload -p sys/kaio >/dev/null 2>&1
- #
- # Stop init(1M) so extraction/manipulation of inittab is safe.
- #
- print "Quiescing init ..."
- pstop 1
-
# umount /lib/libc.so.1 if necessary
if [ -n "`mount | grep '^/lib/libc.so.1'`" ]
then
@@ -3929,6 +4096,10 @@ else
if [ $os_rev -lt $MINIMUM_OS_REV -a "$force_override" = "no" ]; then
fail "Cannot bfu from pre-Solaris $MINIMUM_OS_REV"
fi
+ if [ ! -x /usr/sbin/svcadm ]; then
+ fail "This version of bfu cannot run on pre-Greenline " \
+ "(s10_64) systems"
+ fi
fi
export PATH=/tmp/bfubin:$PATH
@@ -4163,6 +4334,15 @@ check_multi_to_dca_boot()
check_dca_to_multiboot()
{
+ bootdev=`grep p0:boot $rootprefix/etc/vfstab | \
+ grep pcfs | nawk '{print $1}'`
+ if [ "$bootdev" != "" ]; then
+ is_pcfs_boot=yes
+ fi
+ if [ $system_type != dca ]; then
+ return
+ fi
+
# ensure bootpath is in $rootprefix/boot/solaris/bootenv.rc
# It's ok to put a meta device path in there
bootenvrc=$rootprefix/boot/solaris/bootenv.rc
@@ -4175,36 +4355,52 @@ check_dca_to_multiboot()
echo "setprop bootpath '$bootpath'" >> $bootenvrc
fi
- bootdev=`grep p0:boot $rootprefix/etc/vfstab | \
- grep pcfs | nawk '{print $1}'`
- if [ "$bootdev" != "" ]; then
- is_pcfs_boot=yes
- fi
- if [ ! -f $rootprefix/boot/mdboot ]; then
- return
- fi
- dca_to_multi=yes
rm -f $rootprefix/boot/mdboot
}
#
+# Figure out the boot architecture of the current system:
+# 1. If dboot_image is in unix, it's a dboot system
+# 2. Otherwise, if multiboot is present, it's a multiboot system
+# 3. Otherwise, it's a pre-multiboot system
+#
+# This is called before we lay down the new archives.
+#
+check_system_type()
+{
+ if [ -x $root/boot/solaris/bin/symdef ] && \
+ $root/boot/solaris/bin/symdef $root/platform/i86pc/kernel/unix \
+ dboot_image; then
+ system_type=directboot
+ elif [ -x $root/platform/i86pc/multiboot ]; then
+ system_type=multiboot
+ else
+ system_type=dca
+ fi
+}
+
+#
# Detect SVM root and return the list of raw devices under the mirror
#
get_rootdev_list()
{
- metadev=`grep -v "^#" $rootprefix/etc/vfstab | \
- grep "[ ]/[ ]" | nawk '{print $2}'`
- if [[ $metadev = /dev/rdsk/* ]]; then
- rootdevlist=`echo "$metadev" | sed -e "s#/dev/rdsk/##"`
- elif [[ $metadev = /dev/md/rdsk/* ]]; then
- metavol=`echo "$metadev" | sed -e "s#/dev/md/rdsk/##"`
- rootdevlist=`metastat -p $metavol |\
- grep -v "^$metavol[ ]" | nawk '{print $4}'`
- fi
- for rootdev in $rootdevlist
- do
- echo /dev/rdsk/$rootdev
- done
+ if [ -f $rootprefix/etc/lu/GRUB_slice ]; then
+ grep '^PHYS_SLICE' $rootprefix/etc/lu/GRUB_slice | cut -d= -f2
+ else
+ metadev=`grep -v "^#" $rootprefix/etc/vfstab | \
+ grep "[ ]/[ ]" | nawk '{print $2}'`
+ if [[ $metadev = /dev/rdsk/* ]]; then
+ rootdevlist=`echo "$metadev" | sed -e "s#/dev/rdsk/##"`
+ elif [[ $metadev = /dev/md/rdsk/* ]]; then
+ metavol=`echo "$metadev" | sed -e "s#/dev/md/rdsk/##"`
+ rootdevlist=`metastat -p $metavol |\
+ grep -v "^$metavol[ ]" | nawk '{print $4}'`
+ fi
+ for rootdev in $rootdevlist
+ do
+ echo /dev/rdsk/$rootdev
+ done
+ fi
}
#
@@ -4256,10 +4452,13 @@ setup_stubboot()
#
install_grub()
{
- STAGE1=$root/boot/grub/stage1
- STAGE2=$root/boot/grub/stage2
+ STAGE1=$rootprefix/boot/grub/stage1
+ STAGE2=$rootprefix/boot/grub/stage2
- if [ $is_pcfs_boot = no ]; then
+ if [ -x $rootprefix/boot/solaris/bin/update_grub ]; then
+ /tmp/bfubin/ksh $rootprefix/boot/solaris/bin/update_grub \
+ -R $root
+ elif [ $is_pcfs_boot = no ]; then
get_rootdev_list | while read rootdev
do
print "Install grub on $rootdev"
@@ -4291,6 +4490,79 @@ install_grub()
fi
}
+#
+# We check for several possibilites of a bootenv.rc line:
+#
+# 1. setprop name 'value'
+# 2. setprop name "value"
+# 3. setprop name value
+#
+parse_bootenv_line()
+{
+ line=$1
+ value=`echo $line | grep "'" | cut -d\' -f2`
+ if [ -z "$value" ]; then
+ value=`echo $line | grep "\"" | cut -d\" -f2`
+ if [ -z "$value" ]; then
+ value=`echo $line | cut -d' ' -f3-`
+ fi
+ fi
+ echo $value
+}
+
+update_bootenv()
+{
+ bootenvrc=$rootprefix/boot/solaris/bootenv.rc
+ bootenvrc_updated=0
+
+ # Note: the big space below is actually a space and tab
+ boot_file=`grep '^setprop[ ]\{1,\}boot-file\>' $bootenvrc`
+ if [ -n "$boot_file" ]; then
+ file=`parse_bootenv_line "$boot_file"`
+ if [ -n "$file" ]; then
+ PATH=/tmp/bfubin /tmp/bfubin/bootadm set-menu kernel="$file"
+ bootenvrc_updated=1
+ fi
+ fi
+
+ console=`grep '^setprop[ ]\{1,\}console\>' $bootenvrc`
+ if [ -z "$console" ]; then
+ console=`grep '^setprop[ ]\{1,\}input-device\>' \
+ $bootenvrc`
+ fi
+ if [ -n "$console" ]; then
+ cons=`parse_bootenv_line "$console"`
+ fi
+ boot_args=`grep '^setprop[ ]\{1,\}boot-args\>' $bootenvrc`
+ if [ -n "boot_args" ]; then
+ args=`parse_bootenv_line "$boot_args"`
+ fi
+ if [ -n "$cons" ] && [ -n "$args" ]; then
+ # If args starts with a -B, remove it and add a comma instead
+ if echo $args | grep '^-B ' >/dev/null; then
+ new_args=`echo $args | sed 's/^-B //'`
+ args_line="-B console=$cons,$new_args"
+ else
+ args_line="-B console=$cons $args"
+ fi
+ elif [ -n "$cons" ]; then
+ args_line="-B console=$cons"
+ elif [ -n "$args" ]; then
+ args_line="$args"
+ else
+ args_line=""
+ fi
+ if [ -n "$args_line" ]; then
+ PATH=/tmp/bfubin /tmp/bfubin/bootadm set-menu args="$args_line"
+ bootenvrc_updated=1
+ fi
+
+ if [ $bootenvrc_updated = 1 ]; then
+ egrep -v '^setprop[ ]+(console|boot-file|boot-args|input-device)[ ]' $bootenvrc > ${bootenvrc}.new
+ [ -s ${bootenvrc}.new ] && mv ${bootenvrc}.new $bootenvrc
+ fi
+}
+
get_biosdisk()
{
rootdev=$1
@@ -4310,12 +4582,32 @@ get_biosdisk()
#
update_grub_menu()
{
- BOOT_PROG=/platform/i86pc/multiboot
- BOOT_ARCHIVE=/platform/i86pc/boot_archive
MENU=$rootprefix/boot/grub/menu.lst
grubhd=$1
+ if [ $archive_type = multiboot ]; then
+ BOOT_PROG="kernel /platform/i86pc/multiboot"
+ BOOT_ARCHIVE="module /platform/i86pc/boot_archive"
+ else
+ #
+ # directboot archives
+ #
+ BOOT_PROG="kernel\$ /platform/i86pc/kernel/\$ISADIR/unix"
+ BOOT_ARCHIVE="module\$ /platform/i86pc/\$ISADIR/boot_archive"
+ fi
+
+ #
+ # The failsafe archives may be different than the boot archives
+ #
+ if [ -x /boot/platform/i86pc/kernel/unix ]; then
+ BOOT_FAILSAFE_FILE="/boot/platform/i86pc/kernel/unix"
+ BOOT_FAILSAFE_SUFFIX=""
+ else
+ BOOT_FAILSAFE_FILE="/boot/multiboot"
+ BOOT_FAILSAFE_SUFFIX="kernel/unix"
+ fi
+
#
# Append some useful entries to the existing menu
#
@@ -4331,12 +4623,12 @@ update_grub_menu()
echo "#splashimage=$grubhd/boot/grub/splash.xpm.gz" >> $MENU
echo "title Solaris" >> $MENU
echo " root $grubhd" >> $MENU
- echo " kernel ${BOOT_PROG}" >> $MENU
- echo " module ${BOOT_ARCHIVE}" >> $MENU
+ echo " ${BOOT_PROG}" >> $MENU
+ echo " ${BOOT_ARCHIVE}" >> $MENU
echo "GRUB menu entry 'Solaris' boots to eeprom(1m) settings"
- if [ -f ${rootprefix}/boot/multiboot ] &&
+ if [ -f ${rootprefix}/$BOOT_FAILSAFE_FILE ] &&
[ -f ${rootprefix}/boot/x86.miniroot-safe ] ; then
TTY=`grep "^setprop input-device" \
@@ -4351,27 +4643,42 @@ update_grub_menu()
FS_CONSOLE="-B console=${TTY}"
fi
- echo "title Solaris failsafe" >> $MENU
- echo " root $grubhd" >> $MENU
- echo " kernel /boot/multiboot kernel/unix $FS_CONSOLE -s" \
- >> $MENU
- echo " module /boot/x86.miniroot-safe" >> $MENU
+cat >>$MENU <<EOF
+title Solaris failsafe
+ root $grubhd
+ kernel $BOOT_FAILSAFE_FILE $BOOT_FAILSAFE_SUFFIX $FS_CONSOLE -s
+ module /boot/x86.miniroot-safe
+EOF
fi
}
+bootadm_f_flag=""
+
install_failsafe()
{
- if [ ! -f /boot/multiboot -o ! -f /boot/x86.miniroot-safe ] && \
- [ -x ${GATEPATH}/public/bin/update_failsafe ] ; then
- echo Updating boot/multiboot and boot/x86.miniroot-safe
+ if [ "$root" != "/" ] || \
+ [ -f /boot/x86.miniroot-safe ] || \
+ [ -x ${GATEPATH}/public/bin/update_failsafe ]; then
+ #
+ # Either we're not bfu'ing /, or the failsafe archives were
+ # already installed, or update_failsafe is not available.
+ # If the old failsafe archives were multiboot, clear out the
+ # directboot kernel.
+ #
+ if [ $failsafe_type = multiboot ]; then
+ rm -f $rootprefix/boot/platform/i86pc/kernel/unix
+ fi
+ else
+ echo "Updating failsafe archives"
${GATEPATH}/public/bin/update_failsafe
+
+ # Force bootadm to update the failsafe entry
+ bootadm_f_flag="-f"
fi
}
setup_grub_menu()
{
- BOOT_PROG=/platform/i86pc/multiboot
- BOOT_ARCHIVE=/platform/i86pc/boot_archive
MENU=$rootprefix/boot/grub/menu.lst
get_rootdev_list | while read rootdev
@@ -4420,8 +4727,6 @@ setup_grub_menu()
#
build_boot_archive()
{
- echo "Create ${rootprefix}/platform/i86pc/boot_archive"
-
#
# We should be able to run bootadm here but that's a
# little more complicated than one would think
@@ -4430,7 +4735,7 @@ build_boot_archive()
cr_args=${rootprefix:+ -R $rootprefix}
LD_LIBRARY_PATH=/tmp/bfulib PATH=/tmp/bfubin \
- /tmp/bfubin/ksh /tmp/bfubin/create_ramdisk $cr_args
+ /tmp/bfubin/ksh $rootprefix/boot/solaris/bin/create_ramdisk $cr_args
#
# Disable the boot-archive service on the first boot
@@ -4484,6 +4789,58 @@ dir_is_inherited() {
[ "$3" = "/$dir" ] && return 0 || return 1
}
+check_boot_env()
+{
+ if [ $multi_or_direct = yes ]; then
+ if [ $archive_type != $system_type ]; then
+ install_failsafe
+ [ $system_type = dca ] && setup_grub_menu
+
+ if [ $have_new_bootadm = yes ] || \
+ [ -x /tmp/bfubin/symdef ] && \
+ [ -x /tmp/bfubin/bootadm ] && \
+ /tmp/bfubin/symdef /tmp/bfubin/bootadm \
+ dboot_or_multiboot; then
+ if [[ -z $rootprefix ]]; then
+ PATH=/tmp/bfubin /tmp/bfubin/bootadm \
+ -m upgrade $bootadm_f_flag
+ else
+ PATH=/tmp/bfubin /tmp/bfubin/bootadm \
+ -m upgrade -R $rootprefix \
+ $bootadm_f_flag
+ fi
+ install_grub
+ [ $archive_type = directboot ] && update_bootenv
+ else
+ install_grub
+ cat >&2 <<EOF
+
+WARNING: Cannot find new bootadm. If bfu'ing across the multiboot/directboot
+boundary, you will need to manually change menu.lst. See
+http://www.sun.com/msg/SUNOS-8000-CF for details.
+
+EOF
+ fi
+
+ #
+ # If we're going backwards, we need to remove the
+ # symdef binary.
+ #
+ if [ -f $rootprefix/boot/solaris/bin/symdef ] && \
+ [ $archive_type = multiboot ]
+ then
+ rm -f $rootprefix/boot/solaris/bin/symdef \
+ $rootprefix/boot/solaris/bin/update_grub
+ fi
+ elif [ $failsafe_type = multiboot ]; then
+ rm -f $rootprefix/boot/platform/i86pc/kernel/unix
+ fi
+ build_boot_archive
+ else
+ disable_boot_service
+ fi
+}
+
mondo_loop() {
typeset pkgroot
typeset pkg
@@ -4512,16 +4869,15 @@ mondo_loop() {
if [ "$karch" = "i86pc" -a "$diskless" = "no" -a "$zone" = "global" ]
then
remove_properties
+ check_system_type
if boot_is_upgradeable $root && \
- [ -f $cpiodir/i86pc.boot$ZFIX ] && \
- $ZCAT $cpiodir/i86pc.boot$ZFIX | cpio -it | \
- grep strap.com >/dev/null 2>&1 ; then
+ [ $archive_type = dca ]; then
check_multi_to_dca_boot
print "\nUpdating realmode boot loaders\n"
update_realmode_booters $root
setup_pboot
fi
- if [ $multiboot_archives = yes ]; then
+ if [ $multi_or_direct = yes ]; then
check_dca_to_multiboot
if [ $is_pcfs_boot = yes ]; then
setup_stubboot
@@ -6343,7 +6699,7 @@ mondo_loop() {
print "Restoring configuration files ... \c" >> $EXTRACT_LOG
filelist $zone | cpio -pdmu bfu.parent 2>>$EXTRACT_LOG || \
extraction_error "restoring configuration files"
- if [ $multiboot_archives = no ]; then
+ if [ $multi_or_direct = no ]; then
if [ $have_realmode = yes ]; then
if [ -d bfu.realmode ]; then
( cd bfu.realmode ; realmode_filelist | \
@@ -6508,16 +6864,7 @@ mondo_loop() {
if [ $target_isa = i386 ] && [[ $rootslice = /dev/rdsk/* || \
$rootslice = /dev/md/rdsk/* ]]; then
- if [ $multiboot_archives = yes ]; then
- if [ $dca_to_multi = yes ]; then
- install_failsafe
- setup_grub_menu
- install_grub
- fi
- build_boot_archive
- else
- disable_boot_service
- fi
+ check_boot_env
fi
# Check for damage due to CR 6379341. This was actually fixed
@@ -6575,7 +6922,7 @@ mondo_loop() {
print "\nFor each file in conflict, your version has been restored."
print "The new versions are under $rootprefix/bfu.conflicts."
print "\nMAKE SURE YOU RESOLVE ALL CONFLICTS BEFORE REBOOTING.\n"
- if [ $multiboot_archives = yes ]; then
+ if [ $multi_or_direct = yes ]; then
print "To install resolved changes required for reboot in the boot"
print "archive, invoke 'bootadm update-archive${cr_args}'\n"
fi
@@ -6707,8 +7054,4 @@ print "Exiting post-bfu protected environment. To reenter, type:"
print LD_NOAUXFLTR=1 LD_LIBRARY_PATH=/tmp/bfulib $ldlib64 PATH=/tmp/bfubin \
/tmp/bfubin/ksh
-# Allow init(1M) to continue, if we're leaving.
-print "Reactivating init ..."
-prun 1
-
exit 0
diff --git a/usr/src/uts/Makefile.targ b/usr/src/uts/Makefile.targ
index 5f898515f8..65efe774de 100644
--- a/usr/src/uts/Makefile.targ
+++ b/usr/src/uts/Makefile.targ
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -76,8 +76,8 @@ MOD_LINT_LIB = $(LINT_LIB_DIR)/llib-l$(LINT_MODULE).ln
$(MOD_LINT_LIB): $(LINT_LIB_DIR) $(LINTS)
@-$(ECHO) "\n$(OBJS_DIR)/$(MODULE): (library construction):"
- @$(LINT) -o $(LINT_MODULE) $(LINTFLAGS) $(LINTS)
- @$(MV) $(@F) $@
+ @$(LINT) -o $(LINT_MODULE)-$(OBJS_DIR) $(LINTFLAGS) $(LINTS)
+ @$(MV) llib-l$(LINT_MODULE)-$(OBJS_DIR).ln $@
$(LINT_MODULE).lint: $(MOD_LINT_LIB) $(LINT_LIB) $(GEN_LINT_LIB)
@-$(ECHO) "\n$(OBJS_DIR)/$(LINT_MODULE): global crosschecks:"
@@ -109,7 +109,7 @@ $(LINTS_DIR)/modstubs.ln: $(MODSTUBS)
#
# release: contents of $(RELEASE) (Spaces replaced by '_')
# version: contents of $(PATCHID) (Spaces replaced by '_')
-# machine: contents of $(PLATFORM)
+# machine: contents of $(UNAME_M)
#
# Build environment information is only contained in the comment section.
#
@@ -123,7 +123,7 @@ $(INTERNAL_RELEASE_BUILD)VERSION_STRING = $(ECHO) $(PATCHID)
$(OBJS_DIR)/vers.o: $(OBJECTS)
$(COMPILE.c) -DUTS_RELEASE=\"`$(ECHO) $(RELEASE) | sed -e 's/ /_/g'`\" \
-DUTS_VERSION=\"`$(VERSION_STRING) | sed -e 's/ /_/g'`\" \
- -DUTS_PLATFORM=\"$(PLATFORM)\" -o $@ $(SRC)/uts/common/os/vers.c
+ -DUTS_PLATFORM=\"$(UNAME_M)\" -o $@ $(SRC)/uts/common/os/vers.c
$(CTFCONVERT_O)
$(POST_PROCESS_O)
@@ -444,4 +444,5 @@ lint32:
@for file in $(LINT32_FILES); do \
if [ ! -f $$file ]; then touch $$file; fi \
done
+
FRC:
diff --git a/usr/src/uts/Makefile.uts b/usr/src/uts/Makefile.uts
index 508560c90e..af2765ac4d 100644
--- a/usr/src/uts/Makefile.uts
+++ b/usr/src/uts/Makefile.uts
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -213,6 +213,8 @@ AS_CPPFLAGS = $(ALWAYS_DEFS) $(ALL_DEFS) $(CONFIG_DEFS) $(AS_DEFS) \
# Override the default, the kernel is squeaky clean
CERRWARN = -errtags=yes -errwarn=%all
+C99MODE = $(C99_ENABLE)
+
CFLAGS_uts =
CFLAGS_uts += $(STAND_FLAGS_$(CLASS))
CFLAGS_uts += $(CCVERBOSE)
@@ -220,7 +222,6 @@ CFLAGS_uts += $(ILDOFF)
CFLAGS_uts += $(XAOPT)
CFLAGS_uts += $(CTF_FLAGS)
CFLAGS_uts += $(CERRWARN)
-CFLAGS_uts += $(C99_ENABLE)
CFLAGS_uts += $(CGLOBALSTATIC)
CFLAGS_uts += $(EXTRA_CFLAGS)
@@ -373,29 +374,12 @@ CTFMERGE_GENUNIX_MERGE = \
$$cmd $(OBJECTS) $(CTFEXTRAOBJS) $(IPCTF_TARGET)
#
-# Used to copy CTF data from the sun4u genunix to the sun4m genunix. While
-# we may lose some genunix-specific sun4m-only data, there really isn't any
-# other way, since individual ctfmerges on the sun4u and sun4m genunix
-# modules will result in differing type indices for the same types, and we
-# can't uniquify a given non-genunix module against two genunix modules.
-#
-CTFMERGE_COPY_CTF_DATA = \
- @if [ -f $(CTFMERGE_GENUNIX) ] ; then \
- cmd="$(CTFMERGE) $(CTFMRGFLAGS) -c $(CTFMERGE_GENUNIX) $@" ; \
- echo $$cmd ; \
- $$cmd ; \
- else \
- echo "WARNING: $(CTFMERGE_GENUNIX) not built. " \
- "CTF data will be incomplete" ; \
- fi
-
-#
# We ctfmerge the ip objects into genunix to maximize the number of common types
# found there, thus maximizing the effectiveness of uniquification. We don't
# want the genunix build to have to know about the individual ip objects, so we
# put them in an archive. The genunix ctfmerge then includes this archive.
#
-IPCTF = $(IPDRV_DIR)/$(OBJS_DIR)/ipctf.a
+IPCTF = $(IPDRV_DIR)/$(OBJS_DIR)/ipctf.a
#
# Rule for building fake shared libraries used for symbol resolution
@@ -578,15 +562,28 @@ USR_PLAT_LINKS = $(PLAT_LINKS:%=$(USR_PLAT_DIR)/%)
USR_PLAT_LINKS_2 = $(PLAT_LINKS_2:%=$(USR_PLAT_DIR)/%)
#
-# Collection of all relevant, delivered kernel modules.
+# Collection of all relevant, delivered kernel modules.
+#
+# Note that we insist on building genunix first, because everything else
+# uniquifies against it. When doing a 'make' from usr/src/uts/, we'll enter
+# the platform directories first. These will cd into the corresponding genunix
+# directory and build it. So genunix /shouldn't/ get rebuilt when we get to
+# building all the kernel modules. However, due to an as-yet-unexplained
+# problem with dependencies, sometimes it does get rebuilt, which then messes
+# up the other modules. So we always force the issue here rather than try to
+# build genunix in parallel with everything else.
#
-KMODS = $(DRV_KMODS) $(EXEC_KMODS) $(FS_KMODS) $(SCHED_KMODS) $(TOD_KMODS) \
- $(STRMOD_KMODS) $(SYS_KMODS) $(MISC_KMODS) $(NLMISC_KMODS) \
- $(MACH_KMODS) $(CPU_KMODS) $(GENUNIX_KMODS) \
- $(GSS_KMODS) $(MMU_KMODS) $(DACF_KMODS) $(EXPORT_KMODS) \
- $(IPP_KMODS) $(CRYPTO_KMODS) $(CRYPTO_EK_KMODS) $(PCBE_KMODS) \
- $(DRV_KMODS_$(CLASS)) $(MISC_KMODS_$(CLASS)) $(MAC_KMODS) \
- $(DEVNAME_KMODS)
+PARALLEL_KMODS = $(DRV_KMODS) $(EXEC_KMODS) $(FS_KMODS) $(SCHED_KMODS) \
+ $(TOD_KMODS) $(STRMOD_KMODS) $(SYS_KMODS) $(MISC_KMODS) \
+ $(NLMISC_KMODS) $(MACH_KMODS) $(CPU_KMODS) $(GSS_KMODS) \
+ $(MMU_KMODS) $(DACF_KMODS) $(EXPORT_KMODS) $(IPP_KMODS) \
+ $(CRYPTO_KMODS) $(CRYPTO_EK_KMODS) $(PCBE_KMODS) \
+ $(DRV_KMODS_$(CLASS)) $(MISC_KMODS_$(CLASS)) $(MAC_KMODS) \
+ $(DEVNAME_KMODS)
+
+KMODS = $(GENUNIX_KMODS) $(PARALLEL_KMODS)
+
+$(PARALLEL_KMODS): $(GENUNIX_KMODS)
$(CLOSED_BUILD)CLOSED_KMODS = $(CLOSED_DRV_KMODS) $(CLOSED_TOD_KMODS) \
$(CLOSED_MISC_KMODS) \
@@ -596,8 +593,7 @@ LINT_KMODS = $(DRV_KMODS) $(EXEC_KMODS) $(FS_KMODS) $(SCHED_KMODS) \
$(TOD_KMODS) $(STRMOD_KMODS) $(SYS_KMODS) $(MISC_KMODS) \
$(MACH_KMODS) $(GSS_KMODS) $(DACF_KMODS) $(IPP_KMODS) \
$(CRYPTO_KMODS) $(PCBE_KMODS) $(DEVNAME_KMODS) \
- $(DRV_KMODS_$(CLASS)) $(MISC_KMODS_$(CLASS)) $(MAC_KMODS) \
- $(DEVNAME_KMODS)
+ $(DRV_KMODS_$(CLASS)) $(MISC_KMODS_$(CLASS)) $(MAC_KMODS)
$(CLOSED_BUILD)CLOSED_LINT_KMODS = $(CLOSED_DRV_KMODS) $(CLOSED_TOD_KMODS) \
$(CLOSED_MISC_KMODS) $(CLOSED_DRV_KMODS_$(CLASS))
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index 946fececfa..927ded787f 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -31,10 +31,7 @@
i386_CORE_OBJS += \
avintr.o \
- pit.o \
- pic.o \
- hardclk.o \
- i8254.o
+ pic.o
sparc_CORE_OBJS +=
@@ -63,6 +60,7 @@ COMMON_CORE_OBJS += \
rctl_proc.o \
rwlock.o \
seg_kmem.o \
+ string.o \
thread_intr.o \
vm_page.o \
vm_pagelist.o
@@ -272,6 +270,7 @@ GENUNIX_OBJS += \
sleepq.o \
softint.o \
space.o \
+ sscanf.o \
ssig.o \
stat.o \
statfs.o \
@@ -281,7 +280,6 @@ GENUNIX_OBJS += \
stream.o \
streamio.o \
strext.o \
- string.o \
strsubr.o \
strsun.o \
subr.o \
@@ -356,7 +354,14 @@ GENUNIX_OBJS += \
#
# Stubs for the stand-alone linker/loader
#
-GENSTUBS_OBJS += kobj_stubs.o
+sparc_GENSTUBS_OBJS = \
+ kobj_stubs.o
+
+i386_GENSTUBS_OBJS =
+
+COMMON_GENSTUBS_OBJS =
+
+GENSTUBS_OBJS += $(COMMON_GENSTUBS_OBJS) $($(MACH)_GENSTUBS_OBJS)
#
# DTrace and DTrace Providers
@@ -1203,14 +1208,20 @@ DES_OBJS += des_crypt.o des_cbc_crypt.o des_impl.o des_ks.o des_soft.o
DLBOOT_OBJS += bootparam_xdr.o nfs_dlinet.o scan.o
-KRTLD_OBJS += \
- kobj_bootflags.o \
- getoptstr.o \
- kobj.o \
- kobj_kdi.o \
- kobj_lm.o \
+sparc_KRTLD_OBJS = \
kobj_subr.o
+i386_KRTLD_OBJS =
+
+COMMON_KRTLD_OBJS = \
+ kobj_bootflags.o \
+ getoptstr.o \
+ kobj.o \
+ kobj_kdi.o \
+ kobj_lm.o
+
+KRTLD_OBJS += $(COMMON_KRTLD_OBJS) $($(MACH)_KRTLD_OBJS)
+
MOD_OBJS += modctl.o modsubr.o modsysfile.o modconf.o modhash.o
STRPLUMB_OBJS += strplumb.o octet.o
diff --git a/usr/src/uts/common/cpr/cpr_driver.c b/usr/src/uts/common/cpr/cpr_driver.c
index deb6241319..a23a9cbf7c 100644
--- a/usr/src/uts/common/cpr/cpr_driver.c
+++ b/usr/src/uts/common/cpr/cpr_driver.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -67,7 +66,8 @@ cpr_suspend_devices(dev_info_t *dip)
return (ENXIO);
if (!cpr_is_real_device(dip))
continue;
- DEBUG2(errp("Suspending device %s\n", devi_string(dip, buf)));
+ CPR_DEBUG(CPR_DEBUG2, "Suspending device %s\n",
+ devi_string(dip, buf));
ASSERT((DEVI(dip)->devi_cpr_flags & DCF_CPR_SUSPENDED) == 0);
if (!i_ddi_devi_attached(dip))
@@ -78,8 +78,9 @@ cpr_suspend_devices(dev_info_t *dip)
if (error == DDI_SUCCESS)
DEVI(dip)->devi_cpr_flags |= DCF_CPR_SUSPENDED;
else {
- DEBUG2(errp("WARNING: Unable to suspend device %s\n",
- devi_string(dip, buf)));
+ CPR_DEBUG(CPR_DEBUG2,
+ "WARNING: Unable to suspend device %s\n",
+ devi_string(dip, buf));
cpr_err(CE_WARN, "Unable to suspend device %s.",
devi_string(dip, buf));
cpr_err(CE_WARN, "Device is busy or does not "
@@ -130,8 +131,8 @@ cpr_resume_devices(dev_info_t *start, int resume_failed)
* the entire tree to clear the suspend flag.
*/
if (did_suspend && !error) {
- DEBUG2(errp("Resuming device %s\n",
- devi_string(dip, buf)));
+ CPR_DEBUG(CPR_DEBUG2, "Resuming device %s\n",
+ devi_string(dip, buf));
/*
* If a device suspended by cpr gets detached during
* the resume process (for example, due to hotplugging)
@@ -139,17 +140,17 @@ cpr_resume_devices(dev_info_t *start, int resume_failed)
* we'll have problems.
*/
if (!i_ddi_devi_attached(dip)) {
- DEBUG2(errp("WARNING: Skipping %s, device "
- "not ready for resume\n",
- devi_string(dip, buf)));
+ CPR_DEBUG(CPR_DEBUG2, "WARNING: Skipping "
+ "%s, device not ready for resume\n",
+ devi_string(dip, buf));
cpr_err(CE_WARN, "Skipping %s, device "
"not ready for resume",
devi_string(dip, buf));
} else if (devi_attach(dip, DDI_RESUME) !=
DDI_SUCCESS) {
- DEBUG2(errp(
+ CPR_DEBUG(CPR_DEBUG2,
"WARNING: Unable to resume device %s\n",
- devi_string(dip, buf)));
+ devi_string(dip, buf));
cpr_err(CE_WARN, "Unable to resume device %s",
devi_string(dip, buf));
error = ENXIO;
@@ -243,6 +244,11 @@ cpr_is_real_device(dev_info_t *dip)
void
cpr_power_down(void)
{
+#if defined(__sparc)
+ /*
+ * XXX This platform firmware implementation dependency
+ * doesn't belong in common code!
+ */
int is_defined = 0;
char *wordexists = "p\" power-off\" find nip swap l! ";
char *req = "power-off";
@@ -252,7 +258,8 @@ cpr_power_down(void)
*/
prom_interpret(wordexists, (uintptr_t)&is_defined, 0, 0, 0, 0);
if (is_defined) {
- DEBUG1(errp("\ncpr: %s...\n", req));
+ CPR_DEBUG(CPR_DEBUG1, "\ncpr: %s...\n", req);
prom_interpret(req, 0, 0, 0, 0, 0);
}
+#endif
}
diff --git a/usr/src/uts/common/cpr/cpr_dump.c b/usr/src/uts/common/cpr/cpr_dump.c
index 46269c4955..99f5cea43d 100644
--- a/usr/src/uts/common/cpr/cpr_dump.c
+++ b/usr/src/uts/common/cpr/cpr_dump.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -214,9 +214,9 @@ cpr_write_header(vnode_t *vp)
upages = cpr_count_upages(REGULAR_BITMAP, cpr_setbit);
cdump.cdd_dumppgsize = kpages - vpages + upages;
cpr_pages_tobe_dumped = cdump.cdd_dumppgsize;
- DEBUG7(errp(
+ CPR_DEBUG(CPR_DEBUG7,
"\ncpr_write_header: kpages %ld - vpages %ld + upages %ld = %d\n",
- kpages, vpages, upages, cdump.cdd_dumppgsize));
+ kpages, vpages, upages, cdump.cdd_dumppgsize);
/*
* Some pages contain volatile data (cpr_buf and storage area for
@@ -247,8 +247,8 @@ cpr_write_header(vnode_t *vp)
*/
if (!(CPR->c_flags & C_COMPRESSING) &&
(STAT->cs_nocomp_statefsz > STAT->cs_est_statefsz)) {
- if (cpr_debug & (LEVEL1 | LEVEL7))
- errp("cpr_write_header: STAT->cs_nocomp_statefsz > "
+ if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG7))
+ prom_printf("cpr_write_header: STAT->cs_nocomp_statefsz > "
"STAT->cs_est_statefsz\n");
return (ENOSPC);
}
@@ -274,8 +274,8 @@ cpr_write_terminator(vnode_t *vp)
cpr_term.real_statef_size = STAT->cs_real_statefsz +
btod(cpr_wptr - cpr_buf) * DEV_BSIZE;
- DEBUG9(errp("cpr_dump: Real Statefile Size: %ld\n",
- STAT->cs_real_statefsz));
+ CPR_DEBUG(CPR_DEBUG9, "cpr_dump: Real Statefile Size: %ld\n",
+ STAT->cs_real_statefsz);
cpr_tod_get(&cpr_term.tm_shutdown);
@@ -338,7 +338,7 @@ cpr_write_statefile(vnode_t *vp)
*/
str = "cpr_write_statefile:";
spages = i_cpr_count_sensitive_kpages(REGULAR_BITMAP, cpr_clrbit);
- DEBUG7(errp("%s untag %ld sens pages\n", str, spages));
+ CPR_DEBUG(CPR_DEBUG7, "%s untag %ld sens pages\n", str, spages);
/*
* now it's OK to call a driver that makes allocations
@@ -351,7 +351,8 @@ cpr_write_statefile(vnode_t *vp)
*/
error = i_cpr_dump_sensitive_kpages(vp);
if (error) {
- DEBUG7(errp("%s cpr_dump_sensitive_kpages() failed!\n", str));
+ CPR_DEBUG(CPR_DEBUG7,
+ "%s cpr_dump_sensitive_kpages() failed!\n", str);
return (error);
}
@@ -360,7 +361,8 @@ cpr_write_statefile(vnode_t *vp)
*/
error = cpr_dump_regular_pages(vp);
if (error) {
- DEBUG7(errp("%s cpr_dump_regular_pages() failed!\n", str));
+ CPR_DEBUG(CPR_DEBUG7,
+ "%s cpr_dump_regular_pages() failed!\n", str);
return (error);
}
@@ -371,7 +373,7 @@ cpr_write_statefile(vnode_t *vp)
cpr_regular_pgs_dumped);
if (error) {
- errp("\n%s page count mismatch!\n", str);
+ prom_printf("\n%s page count mismatch!\n", str);
#ifdef DEBUG
if (cpr_test_mode)
debug_enter(NULL);
@@ -443,7 +445,8 @@ cpr_dump(vnode_t *vp)
* compressed before they are saved into the storage area.
*/
if (error = i_cpr_save_sensitive_kpages()) {
- DEBUG7(errp("cpr_dump: save_sensitive_kpages failed!\n"));
+ CPR_DEBUG(CPR_DEBUG7,
+ "cpr_dump: save_sensitive_kpages failed!\n");
return (error);
}
@@ -453,7 +456,8 @@ cpr_dump(vnode_t *vp)
* count regular and sensitive kpages.
*/
if (error = cpr_write_header(vp)) {
- DEBUG7(errp("cpr_dump: cpr_write_header() failed!\n"));
+ CPR_DEBUG(CPR_DEBUG7,
+ "cpr_dump: cpr_write_header() failed!\n");
return (error);
}
@@ -467,7 +471,8 @@ cpr_dump(vnode_t *vp)
return (error);
if (error = cpr_write_statefile(vp)) {
- DEBUG7(errp("cpr_dump: cpr_write_statefile() failed!\n"));
+ CPR_DEBUG(CPR_DEBUG7,
+ "cpr_dump: cpr_write_statefile() failed!\n");
return (error);
}
@@ -539,8 +544,8 @@ cpr_scan_kvseg(int mapflag, bitfunc_t bitfunc, struct seg *seg)
vmem_walk(heap_arena, VMEM_ALLOC, cpr_walk, &cwinfo);
- if (cpr_debug & LEVEL7) {
- errp("walked %d sub-ranges, total pages %ld\n",
+ if (cpr_debug & CPR_DEBUG7) {
+ prom_printf("walked %d sub-ranges, total pages %ld\n",
cwinfo.ranges, mmu_btop(cwinfo.size));
cpr_show_range(seg->s_base, seg->s_size,
mapflag, bitfunc, cwinfo.pages);
@@ -584,8 +589,8 @@ cpr_scan_segkpm(int mapflag, bitfunc_t bitfunc, struct seg *seg)
cwinfo.bitfunc = bitfunc;
hat_kpm_walk(cpr_walk_kpm, &cwinfo);
- if (cpr_debug & LEVEL7) {
- errp("walked %d sub-ranges, total pages %ld\n",
+ if (cpr_debug & CPR_DEBUG7) {
+ prom_printf("walked %d sub-ranges, total pages %ld\n",
cwinfo.ranges, mmu_btop(cwinfo.size));
cpr_show_range(segkpm->s_base, segkpm->s_size,
mapflag, bitfunc, cwinfo.pages);
@@ -683,9 +688,9 @@ cpr_count_kpages(int mapflag, bitfunc_t bitfunc)
kas_cnt = i_cpr_count_special_kpages(mapflag, bitfunc);
kas_cnt += cpr_count_seg_pages(mapflag, bitfunc);
- DEBUG9(errp("cpr_count_kpages: kas_cnt=%ld\n", kas_cnt));
- DEBUG7(errp("\ncpr_count_kpages: %ld pages, 0x%lx bytes\n",
- kas_cnt, mmu_ptob(kas_cnt)));
+ CPR_DEBUG(CPR_DEBUG9, "cpr_count_kpages: kas_cnt=%ld\n", kas_cnt);
+ CPR_DEBUG(CPR_DEBUG7, "\ncpr_count_kpages: %ld pages, 0x%lx bytes\n",
+ kas_cnt, mmu_ptob(kas_cnt));
return (kas_cnt);
}
@@ -807,10 +812,10 @@ cpr_count_upages(int mapflag, bitfunc_t bitfunc)
} while ((pp = page_next(pp)) != page0);
STAT->cs_upage2statef = dcnt;
- DEBUG9(errp("cpr_count_upages: dirty=%ld total=%ld\n",
- dcnt, tcnt));
- DEBUG7(errp("cpr_count_upages: %ld pages, 0x%lx bytes\n",
- dcnt, mmu_ptob(dcnt)));
+ CPR_DEBUG(CPR_DEBUG9, "cpr_count_upages: dirty=%ld total=%ld\n",
+ dcnt, tcnt);
+ CPR_DEBUG(CPR_DEBUG7, "cpr_count_upages: %ld pages, 0x%lx bytes\n",
+ dcnt, mmu_ptob(dcnt));
return (dcnt);
}
@@ -901,8 +906,8 @@ cpr_compress_and_write(vnode_t *vp, uint_t va, pfn_t pfn, pgcnt_t npg)
i_cpr_mapin(CPR->c_mapping_area, npg, pfn);
- DEBUG3(errp("mapped-in %ld pages, vaddr 0x%p, pfn 0x%lx\n",
- npg, CPR->c_mapping_area, pfn));
+ CPR_DEBUG(CPR_DEBUG3, "mapped-in %ld pages, vaddr 0x%p, pfn 0x%lx\n",
+ npg, CPR->c_mapping_area, pfn);
/*
* Fill cpr page descriptor.
@@ -927,10 +932,10 @@ cpr_compress_and_write(vnode_t *vp, uint_t va, pfn_t pfn, pgcnt_t npg)
i_cpr_mapout(CPR->c_mapping_area, npg);
if (error) {
- DEBUG1(errp("cpr_compress_and_write: vp 0x%p va 0x%x ",
- vp, va));
- DEBUG1(errp("pfn 0x%lx blk %d err %d\n",
- pfn, cpr_file_bn, error));
+ CPR_DEBUG(CPR_DEBUG1,
+ "cpr_compress_and_write: vp 0x%p va 0x%x ", vp, va);
+ CPR_DEBUG(CPR_DEBUG1, "pfn 0x%lx blk %d err %d\n",
+ pfn, cpr_file_bn, error);
} else {
cpr_regular_pgs_dumped += npg;
}
@@ -978,20 +983,21 @@ cpr_write(vnode_t *vp, caddr_t buffer, size_t size)
return (ENOSPC);
}
- DEBUG3(errp("cpr_write: frmp=%p wptr=%p cnt=%lx...",
- fromp, cpr_wptr, bytes));
+ CPR_DEBUG(CPR_DEBUG3,
+ "cpr_write: frmp=%p wptr=%p cnt=%lx...",
+ fromp, cpr_wptr, bytes);
/*
* cross check, this should not happen!
*/
if (cpr_disk_writes_ok == 0) {
- errp("cpr_write: disk write too early!\n");
+ prom_printf("cpr_write: disk write too early!\n");
return (EINVAL);
}
do_polled_io = 1;
error = VOP_DUMP(vp, cpr_buf, cpr_file_bn, cpr_buf_blocks);
do_polled_io = 0;
- DEBUG3(errp("done\n"));
+ CPR_DEBUG(CPR_DEBUG3, "done\n");
STAT->cs_real_statefsz += cpr_buf_size;
@@ -1024,7 +1030,8 @@ cpr_flush_write(vnode_t *vp)
cpr_file_bn += nblk;
if (error)
- DEBUG2(errp("cpr_flush_write: error (%d)\n", error));
+ CPR_DEBUG(CPR_DEBUG2, "cpr_flush_write: error (%d)\n",
+ error);
return (error);
}
@@ -1037,7 +1044,7 @@ cpr_clear_bitmaps(void)
bzero((void *)dp->cbd_reg_bitmap,
(size_t)dp->cbd_size * 2);
}
- DEBUG7(errp("\ncleared reg and vlt bitmaps\n"));
+ CPR_DEBUG(CPR_DEBUG7, "\ncleared reg and vlt bitmaps\n");
}
int
@@ -1113,7 +1120,7 @@ cpr_show_range(caddr_t vaddr, size_t size,
action = "untag";
else
action = "none";
- errp("range (0x%p, 0x%p), %s bitmap, %s %ld\n",
+ prom_printf("range (0x%p, 0x%p), %s bitmap, %s %ld\n",
vaddr, vaddr + size, bname, action, count);
}
@@ -1135,7 +1142,7 @@ cpr_count_pages(caddr_t sva, size_t size,
}
}
- if ((cpr_debug & LEVEL7) && showrange == DBG_SHOWRANGE)
+ if ((cpr_debug & CPR_DEBUG7) && showrange == DBG_SHOWRANGE)
cpr_show_range(sva, size, mapflag, bitfunc, count);
return (count);
@@ -1157,8 +1164,8 @@ cpr_count_volatile_pages(int mapflag, bitfunc_t bitfunc)
}
count += i_cpr_count_storage_pages(mapflag, bitfunc);
- DEBUG7(errp("cpr_count_vpages: %ld pages, 0x%lx bytes\n",
- count, mmu_ptob(count)));
+ CPR_DEBUG(CPR_DEBUG7, "cpr_count_vpages: %ld pages, 0x%lx bytes\n",
+ count, mmu_ptob(count));
return (count);
}
@@ -1171,6 +1178,6 @@ cpr_dump_regular_pages(vnode_t *vp)
cpr_regular_pgs_dumped = 0;
error = cpr_contig_pages(vp, WRITE_TO_STATEFILE);
if (!error)
- DEBUG7(errp("cpr_dump_regular_pages() done.\n"));
+ CPR_DEBUG(CPR_DEBUG7, "cpr_dump_regular_pages() done.\n");
return (error);
}
diff --git a/usr/src/uts/common/cpr/cpr_main.c b/usr/src/uts/common/cpr/cpr_main.c
index cd14998bee..6669469681 100644
--- a/usr/src/uts/common/cpr/cpr_main.c
+++ b/usr/src/uts/common/cpr/cpr_main.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -172,19 +171,20 @@ cpr_log_status(int enable, int *svstat, vnode_t *vp)
if (error = VOP_IOCTL(vp, _FIOISLOG,
(uintptr_t)&status, FKIOCTL, CRED(), NULL)) {
mntpt = vfs_getmntpoint(vp->v_vfsp);
- errp("%s: \"%s\", cant get logging status, error %d\n",
- str, refstr_value(mntpt), error);
+ prom_printf("%s: \"%s\", cant get logging "
+ "status, error %d\n", str, refstr_value(mntpt),
+ error);
refstr_rele(mntpt);
return;
}
*svstat = status;
- DEBUG5(
- {
+ if (cpr_debug & CPR_DEBUG5) {
mntpt = vfs_getmntpoint(vp->v_vfsp);
- errp("%s: \"%s\", logging status = %d\n",
+ CPR_DEBUG(CPR_DEBUG5,
+ "%s: \"%s\", logging status = %d\n",
str, refstr_value(mntpt), status);
refstr_rele(mntpt);
- });
+ };
able = "disable";
cmd = _FIOLOGDISABLE;
@@ -201,17 +201,17 @@ cpr_log_status(int enable, int *svstat, vnode_t *vp)
FKIOCTL, CRED(), NULL);
if (error) {
mntpt = vfs_getmntpoint(vp->v_vfsp);
- errp("%s: \"%s\", cant %s logging, error %d\n",
+ prom_printf("%s: \"%s\", cant %s logging, error %d\n",
str, refstr_value(mntpt), able, error);
refstr_rele(mntpt);
} else {
- DEBUG5(
- {
+ if (cpr_debug & CPR_DEBUG5) {
mntpt = vfs_getmntpoint(vp->v_vfsp);
- errp("%s: \"%s\", logging is now %sd\n",
+ CPR_DEBUG(CPR_DEBUG5,
+ "%s: \"%s\", logging is now %sd\n",
str, refstr_value(mntpt), able);
refstr_rele(mntpt);
- });
+ }
}
}
@@ -258,8 +258,8 @@ cpr_ufs_logging(int enable)
return (ENOENT);
if (error = vn_open(fname, UIO_SYSSPACE, FCREAT|FWRITE,
0600, &vp, CRCREAT, 0)) {
- errp("cpr_ufs_logging: cant open/create \"%s\", error %d\n",
- fname, error);
+ prom_printf("cpr_ufs_logging: cant open/create \"%s\", "
+ "error %d\n", fname, error);
return (error);
}
@@ -343,13 +343,13 @@ cpr_suspend(void)
* The 3 retry is not a random number because 2 is possible if
* a thread has been forked before the parent thread is stopped.
*/
- DEBUG1(errp("\nstopping user threads..."));
+ CPR_DEBUG(CPR_DEBUG1, "\nstopping user threads...");
CPR_STAT_EVENT_START(" stop users");
cpr_set_substate(C_ST_STOP_USER_THREADS);
if (rc = cpr_stop_user_threads())
return (rc);
CPR_STAT_EVENT_END(" stop users");
- DEBUG1(errp("done\n"));
+ CPR_DEBUG(CPR_DEBUG1, "done\n");
pm_save_direct_levels();
@@ -362,7 +362,7 @@ cpr_suspend(void)
cpr_send_notice();
if (cpr_debug)
- errp("\n");
+ prom_printf("\n");
(void) callb_execute_class(CB_CL_CPR_POST_USER, CB_CODE_CPR_CHKPT);
@@ -407,7 +407,7 @@ alloc_statefile:
cpr_set_substate(C_ST_STATEF_ALLOC);
if (rc = cpr_alloc_statefile(sf_realloc)) {
if (sf_realloc)
- errp("realloc failed\n");
+ prom_printf("realloc failed\n");
return (rc);
}
CPR_STAT_EVENT_END(" alloc statefile");
@@ -425,9 +425,9 @@ alloc_statefile:
* destroy all clean file mapped kernel pages
*/
CPR_STAT_EVENT_START(" clean pages");
- DEBUG1(errp("cleaning up mapped pages..."));
+ CPR_DEBUG(CPR_DEBUG1, "cleaning up mapped pages...");
(void) callb_execute_class(CB_CL_CPR_VM, CB_CODE_CPR_CHKPT);
- DEBUG1(errp("done\n"));
+ CPR_DEBUG(CPR_DEBUG1, "done\n");
CPR_STAT_EVENT_END(" clean pages");
@@ -441,14 +441,14 @@ alloc_statefile:
* Now suspend all the devices
*/
CPR_STAT_EVENT_START(" stop drivers");
- DEBUG1(errp("suspending drivers..."));
+ CPR_DEBUG(CPR_DEBUG1, "suspending drivers...");
cpr_set_substate(C_ST_SUSPEND_DEVICES);
pm_powering_down = 1;
rc = cpr_suspend_devices(ddi_root_node());
pm_powering_down = 0;
if (rc)
return (rc);
- DEBUG1(errp("done\n"));
+ CPR_DEBUG(CPR_DEBUG1, "done\n");
CPR_STAT_EVENT_END(" stop drivers");
/*
@@ -486,7 +486,7 @@ alloc_statefile:
mon_clock_start();
i_cpr_stop_intr();
- DEBUG1(errp("interrupt is stopped\n"));
+ CPR_DEBUG(CPR_DEBUG1, "interrupt is stopped\n");
/*
* Since we will now disable the mechanism that causes prom_printfs
@@ -569,7 +569,7 @@ cpr_resume(void)
* The following switch is used to resume the system
* that was suspended to a different level.
*/
- DEBUG1(errp("\nEntering cpr_resume...\n"));
+ CPR_DEBUG(CPR_DEBUG1, "\nEntering cpr_resume...\n");
/*
* Note:
@@ -730,7 +730,7 @@ rb_stop_kernel_threads:
cpr_start_kernel_threads();
rb_suspend_devices:
- DEBUG1(errp("resuming devices..."));
+ CPR_DEBUG(CPR_DEBUG1, "resuming devices...");
CPR_STAT_EVENT_START(" start drivers");
/*
@@ -748,7 +748,7 @@ rb_suspend_devices:
else if (rc)
cpr_err(CE_WARN, str);
CPR_STAT_EVENT_END(" start drivers");
- DEBUG1(errp("done\n"));
+ CPR_DEBUG(CPR_DEBUG1, "done\n");
/*
* If we had disabled modunloading in this cpr resume cycle (i.e. we
@@ -804,9 +804,9 @@ rb_pm_reattach_noinvol:
pm_restore_direct_levels();
rb_stop_user_threads:
- DEBUG1(errp("starting user threads..."));
+ CPR_DEBUG(CPR_DEBUG1, "starting user threads...");
cpr_start_user_threads();
- DEBUG1(errp("done\n"));
+ CPR_DEBUG(CPR_DEBUG1, "done\n");
rb_mp_offline:
if (cpr_mp_online())
@@ -832,16 +832,17 @@ rb_others:
if (!cpr_reusable_mode)
cpr_clear_definfo();
- DEBUG1(errp("Sending SIGTHAW..."));
+ CPR_DEBUG(CPR_DEBUG1, "Sending SIGTHAW...");
cpr_signal_user(SIGTHAW);
- DEBUG1(errp("done\n"));
+ CPR_DEBUG(CPR_DEBUG1, "done\n");
CPR_STAT_EVENT_END("Resume Total");
CPR_STAT_EVENT_START_TMZ("WHOLE CYCLE", &wholecycle_tv);
CPR_STAT_EVENT_END("WHOLE CYCLE");
- DEBUG1(cmn_err(CE_CONT, "\nThe system is back where you left!\n"));
+ if (cpr_debug & CPR_DEBUG1)
+ cmn_err(CE_CONT, "\nThe system is back where you left!\n");
CPR_STAT_EVENT_START("POST CPR DELAY");
diff --git a/usr/src/uts/common/cpr/cpr_misc.c b/usr/src/uts/common/cpr/cpr_misc.c
index 043219e77b..1632beb072 100644
--- a/usr/src/uts/common/cpr/cpr_misc.c
+++ b/usr/src/uts/common/cpr/cpr_misc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -123,8 +123,9 @@ cpr_init(int fcn)
mutex_exit(&cpr_slock);
return (EAGAIN);
}
- DEBUG3(cpr_err(CE_CONT, "Reserved virtual range from 0x%p for writing "
- "kas\n", (void *)CPR->c_mapping_area));
+ if (cpr_debug & CPR_DEBUG3)
+ cpr_err(CE_CONT, "Reserved virtual range from 0x%p for writing "
+ "kas\n", (void *)CPR->c_mapping_area);
return (0);
}
@@ -441,8 +442,8 @@ cpr_alloc_statefile(int alloc_retry)
*/
if (alloc_retry) {
str = "\n-->Retrying statefile allocation...";
- if (cpr_debug & (LEVEL1 | LEVEL7))
- errp(str);
+ if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG7))
+ prom_printf(str);
if (C_VP->v_type != VBLK)
(void) VOP_DUMPCTL(C_VP, DUMP_FREE, NULL);
} else {
@@ -598,13 +599,13 @@ cpr_statefile_ok(vnode_t *vp, int alloc_retry)
str = "cpr_statefile_ok:";
- DEBUG9(errp("Phys swap: max=%lu resv=%lu\n",
- k_anoninfo.ani_max, k_anoninfo.ani_phys_resv));
- DEBUG9(errp("Mem swap: max=%ld resv=%lu\n",
+ CPR_DEBUG(CPR_DEBUG9, "Phys swap: max=%lu resv=%lu\n",
+ k_anoninfo.ani_max, k_anoninfo.ani_phys_resv);
+ CPR_DEBUG(CPR_DEBUG9, "Mem swap: max=%ld resv=%lu\n",
MAX(availrmem - swapfs_minfree, 0),
- k_anoninfo.ani_mem_resv));
- DEBUG9(errp("Total available swap: %ld\n",
- CURRENT_TOTAL_AVAILABLE_SWAP));
+ k_anoninfo.ani_mem_resv);
+ CPR_DEBUG(CPR_DEBUG9, "Total available swap: %ld\n",
+ CURRENT_TOTAL_AVAILABLE_SWAP);
/*
* try increasing filesize by 15%
@@ -614,16 +615,17 @@ cpr_statefile_ok(vnode_t *vp, int alloc_retry)
* block device doesn't get any bigger
*/
if (vp->v_type == VBLK) {
- if (cpr_debug & (LEVEL1 | LEVEL6))
- errp("Retry statefile on special file\n");
+ if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6))
+ prom_printf(
+ "Retry statefile on special file\n");
return (ENOMEM);
} else {
rw_enter(&ip->i_contents, RW_READER);
size = (ip->i_size * SIZE_RATE) / INTEGRAL;
rw_exit(&ip->i_contents);
}
- if (cpr_debug & (LEVEL1 | LEVEL6))
- errp("Retry statefile size = %lld\n", size);
+ if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6))
+ prom_printf("Retry statefile size = %lld\n", size);
} else {
u_longlong_t cpd_size;
pgcnt_t npages, nback;
@@ -632,8 +634,8 @@ cpr_statefile_ok(vnode_t *vp, int alloc_retry)
ndvram = 0;
(void) callb_execute_class(CB_CL_CPR_FB,
(int)(uintptr_t)&ndvram);
- if (cpr_debug & (LEVEL1 | LEVEL6))
- errp("ndvram size = %d\n", ndvram);
+ if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6))
+ prom_printf("ndvram size = %d\n", ndvram);
/*
* estimate 1 cpd_t for every (CPR_MAXCONTIG / 2) pages
@@ -649,10 +651,11 @@ cpr_statefile_ok(vnode_t *vp, int alloc_retry)
if (CPR->c_flags & C_COMPRESSING) {
size = ((ksize * COMPRESS_PERCENT) / INTEGRAL) +
raw_data + ((nback * 10) / UCOMP_RATE);
- DEBUG1(errp(est_fmt, str, "", size, ksize));
+ CPR_DEBUG(CPR_DEBUG1, est_fmt, str, "", size, ksize);
} else {
size = ksize + raw_data + nback;
- DEBUG1(errp(est_fmt, str, "no ", size, ksize));
+ CPR_DEBUG(CPR_DEBUG1, est_fmt, str, "no ",
+ size, ksize);
}
}
@@ -661,8 +664,8 @@ cpr_statefile_ok(vnode_t *vp, int alloc_retry)
*/
if (vp->v_type == VBLK) {
space = cpr_get_devsize(vp->v_rdev);
- if (cpr_debug & (LEVEL1 | LEVEL6))
- errp("statefile dev size %lu\n", space);
+ if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6))
+ prom_printf("statefile dev size %lu\n", space);
/*
* Export the estimated filesize info, this value will be
@@ -670,9 +673,9 @@ cpr_statefile_ok(vnode_t *vp, int alloc_retry)
* no compression.
*/
STAT->cs_est_statefsz = size;
- if (cpr_debug & (LEVEL1 | LEVEL6))
- errp("%s Estimated statefile size %llu, space %lu\n",
- str, size, space);
+ if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6))
+ prom_printf("%s Estimated statefile size %llu, "
+ "space %lu\n", str, size, space);
if (size > space) {
cpr_err(CE_CONT, "Statefile partition too small.");
return (ENOMEM);
@@ -701,12 +704,12 @@ cpr_statefile_ok(vnode_t *vp, int alloc_retry)
*/
STAT->cs_est_statefsz = size;
error = cpr_grow_statefile(vp, size);
- if (cpr_debug & (LEVEL1 | LEVEL6)) {
+ if (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6)) {
rw_enter(&ip->i_contents, RW_READER);
isize = ip->i_size;
rw_exit(&ip->i_contents);
- errp("%s Estimated statefile size %lld, i_size %lld\n",
- str, size, isize);
+ prom_printf("%s Estimated statefile size %lld, "
+ "i_size %lld\n", str, size, isize);
}
return (error);
@@ -896,8 +899,9 @@ cpr_mp_offline(void)
return (rc);
}
} while ((cp = cp->cpu_next) != cpu_list);
- if (brought_up_boot && (cpr_debug & (LEVEL1 | LEVEL6)))
- errp("changed cpu %p to state %d\n", bootcpu, CPU_CPR_ONLINE);
+ if (brought_up_boot && (cpr_debug & (CPR_DEBUG1 | CPR_DEBUG6)))
+ prom_printf("changed cpu %p to state %d\n",
+ bootcpu, CPU_CPR_ONLINE);
mutex_exit(&cpu_lock);
return (rc);
diff --git a/usr/src/uts/common/cpr/cpr_mod.c b/usr/src/uts/common/cpr/cpr_mod.c
index 1cc09d48e1..365f102a2b 100644
--- a/usr/src/uts/common/cpr/cpr_mod.c
+++ b/usr/src/uts/common/cpr/cpr_mod.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -213,7 +212,7 @@ cpr(int fcn)
return (0);
case AD_CPR_DEBUG9:
- cpr_debug |= LEVEL6;
+ cpr_debug |= CPR_DEBUG6;
return (0);
default:
@@ -308,7 +307,7 @@ cpr(int fcn)
if (fcn != AD_CPR_TESTHALT)
cpr_power_down();
- errp("(Done. Please Switch Off)\n");
+ CPR_DEBUG(CPR_DEBUG1, "(Done. Please Switch Off)\n");
halt(NULL);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/cpr/cpr_stat.c b/usr/src/uts/common/cpr/cpr_stat.c
index e427a59c09..264bb4c9c7 100644
--- a/usr/src/uts/common/cpr/cpr_stat.c
+++ b/usr/src/uts/common/cpr/cpr_stat.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1993-2001 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -92,7 +91,7 @@ cpr_stat_event_end(char *name, cpr_time_t *ctp)
if ((cep = cpr_find_event(name, 0)) == NULL) {
#ifdef CPR_STAT
- errp("cpr_stat: event \"%s\" is not monitored\n", name);
+ prom_printf("cpr_stat: event \"%s\" is not monitored\n", name);
#endif /* CPR_STAT */
return;
}
diff --git a/usr/src/uts/common/cpr/cpr_uthread.c b/usr/src/uts/common/cpr/cpr_uthread.c
index a58b31c728..00d5e0e80b 100644
--- a/usr/src/uts/common/cpr/cpr_uthread.c
+++ b/usr/src/uts/common/cpr/cpr_uthread.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -193,8 +192,8 @@ cpr_check_user_threads()
mutex_exit(&pidlock);
if (count == CPR_UTSTOP_RETRY) {
- DEBUG1(errp("Suspend failed: cannt stop "
- "uthread\n"));
+ CPR_DEBUG(CPR_DEBUG1, "Suspend failed: "
+ "cannot stop uthread\n");
cpr_err(CE_WARN, "Suspend cannot stop "
"process %s (%p:%x).",
ttoproc(tp)->p_user.u_psargs, (void *)tp,
@@ -203,11 +202,12 @@ cpr_check_user_threads()
" network request, please try again.");
}
- DEBUG2(errp("cant stop t=%p state=%x pfg=%x sched=%x\n",
- tp, tp->t_state, tp->t_proc_flag, tp->t_schedflag));
- DEBUG2(errp("proc %p state=%x pid=%d\n",
- ttoproc(tp), ttoproc(tp)->p_stat,
- ttoproc(tp)->p_pidp->pid_id));
+ CPR_DEBUG(CPR_DEBUG2, "cant stop t=%p state=%x pfg=%x "
+ "sched=%x\n", tp, tp->t_state, tp->t_proc_flag,
+ tp->t_schedflag);
+ CPR_DEBUG(CPR_DEBUG2, "proc %p state=%x pid=%d\n",
+ ttoproc(tp), ttoproc(tp)->p_stat,
+ ttoproc(tp)->p_pidp->pid_id);
return (1);
}
thread_unlock(tp);
@@ -268,9 +268,9 @@ cpr_start_user_threads()
void
cpr_start_kernel_threads(void)
{
- DEBUG1(errp("starting kernel daemons..."));
+ CPR_DEBUG(CPR_DEBUG1, "starting kernel daemons...");
(void) callb_execute_class(CB_CL_CPR_DAEMON, CB_CODE_CPR_RESUME);
- DEBUG1(errp("done\n"));
+ CPR_DEBUG(CPR_DEBUG1, "done\n");
/* see table lock below */
callb_unlock_table();
@@ -290,7 +290,7 @@ cpr_stop_kernel_threads(void)
callb_lock_table(); /* Note: we unlock the table in resume. */
- DEBUG1(errp("stopping kernel daemons..."));
+ CPR_DEBUG(CPR_DEBUG1, "stopping kernel daemons...");
if ((name = callb_execute_class(CB_CL_CPR_DAEMON,
CB_CODE_CPR_CHKPT)) != (caddr_t)NULL) {
cpr_err(CE_WARN,
@@ -323,6 +323,6 @@ cpr_stop_kernel_threads(void)
} while ((tp = tp->t_next) != curthread);
mutex_exit(&pidlock);
- DEBUG1(errp("done\n"));
+ CPR_DEBUG(CPR_DEBUG1, "done\n");
return (0);
}
diff --git a/usr/src/uts/common/crypto/io/swrand.c b/usr/src/uts/common/crypto/io/swrand.c
index 63f30aa628..11b6778c21 100644
--- a/usr/src/uts/common/crypto/io/swrand.c
+++ b/usr/src/uts/common/crypto/io/swrand.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -55,6 +55,7 @@
#include <sys/sha1.h>
#include <sys/sunddi.h>
#include <sys/modctl.h>
+#include <sys/hold_page.h>
#define RNDPOOLSIZE 1024 /* Pool size in bytes */
#define HASHBUFSIZE 64 /* Buffer size used for pool mixing */
@@ -635,6 +636,7 @@ physmem_ent_gen(physmem_entsrc_t *entsrc)
hrtime_t ts1, ts2, diff, delta, delta2, delta3;
uint8_t digest[HASHSIZE];
HASH_CTX ctx;
+ page_t *pp;
/*
* Use each 32-bit quantity in the pool to pick a memory
@@ -678,6 +680,15 @@ physmem_ent_gen(physmem_entsrc_t *entsrc)
}
/*
+ * Do an initial check to see if the address is safe
+ */
+ if (plat_hold_page(offset >> PAGESHIFT, PLAT_HOLD_NO_LOCK, NULL)
+ == PLAT_HOLD_FAIL) {
+ memlist_read_unlock();
+ continue;
+ }
+
+ /*
* Figure out which page to load to read the
* memory block. Load the page and compute the
* hash of the memory block.
@@ -691,6 +702,15 @@ physmem_ent_gen(physmem_entsrc_t *entsrc)
nbytes = PAGESIZE - poffset < len ?
PAGESIZE - poffset : len;
+ /*
+ * Re-check the offset, and lock the frame. If the
+ * page was given away after the above check, we'll
+ * just bail out.
+ */
+ if (plat_hold_page(pfn, PLAT_HOLD_LOCK, &pp) ==
+ PLAT_HOLD_FAIL)
+ break;
+
hat_devload(kas.a_hat, entsrc->pmbuf,
PAGESIZE, pfn, PROT_READ,
HAT_LOAD_NOCONSIST | HAT_LOAD_LOCK);
@@ -701,12 +721,18 @@ physmem_ent_gen(physmem_entsrc_t *entsrc)
hat_unload(kas.a_hat, entsrc->pmbuf, PAGESIZE,
HAT_UNLOAD_UNLOCK);
+ plat_release_page(pp);
+
len -= nbytes;
offset += nbytes;
}
/* We got our pages. Let the DR roll */
memlist_read_unlock();
+ /* See if we had to bail out due to a page being given away */
+ if (len)
+ continue;
+
HashFinal(digest, &ctx);
ts2 = gethrtime();
diff --git a/usr/src/uts/common/dtrace/profile.c b/usr/src/uts/common/dtrace/profile.c
index 8452f03640..8de919a851 100644
--- a/usr/src/uts/common/dtrace/profile.c
+++ b/usr/src/uts/common/dtrace/profile.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -43,20 +43,18 @@ static dev_info_t *profile_devi;
static dtrace_provider_id_t profile_id;
/*
- * Regardless of platform, there are five artificial frames in the case of the
+ * Regardless of platform, the stack frames look like this in the case of the
* profile provider:
*
* profile_fire
* cyclic_expire
* cyclic_fire
* [ cbe ]
- * [ locore ]
+ * [ interrupt code ]
*
- * On amd64, there are two frames associated with locore: one in locore, and
- * another in common interrupt dispatch code. (i386 has not been modified to
- * use this common layer.) Further, on i386, the interrupted instruction
- * appears as its own stack frame. All of this means that we need to add one
- * frame for amd64, and then take one away for both amd64 and i386.
+ * On x86, there are five frames from the generic interrupt code; further, the
+ * interrupted instruction appears as its own stack frame, giving us a total of
+ * 10.
*
* On SPARC, the picture is further complicated because the compiler
* optimizes away tail-calls -- so the following frames are optimized away:
@@ -68,16 +66,13 @@ static dtrace_provider_id_t profile_id;
* frame cannot be tail-call eliminated, yielding four frames in this case.
*
* All of the above constraints lead to the mess below. Yes, the profile
- * provider should ideally figure this out on-the-fly by hiting one of its own
+ * provider should ideally figure this out on-the-fly by hitting one of its own
* probes and then walking its own stack trace. This is complicated, however,
* and the static definition doesn't seem to be overly brittle. Still, we
* allow for a manual override in case we get it completely wrong.
*/
-#ifdef __amd64
-#define PROF_ARTIFICIAL_FRAMES 7
-#else
-#ifdef __i386
-#define PROF_ARTIFICIAL_FRAMES 6
+#ifdef __x86
+#define PROF_ARTIFICIAL_FRAMES 10
#else
#ifdef __sparc
#ifdef DEBUG
@@ -87,7 +82,6 @@ static dtrace_provider_id_t profile_id;
#endif
#endif
#endif
-#endif
#define PROF_NAMELEN 15
@@ -164,6 +158,10 @@ static void
profile_create(hrtime_t interval, const char *name, int kind)
{
profile_probe_t *prof;
+ int nr_frames = PROF_ARTIFICIAL_FRAMES + dtrace_mach_aframes();
+
+ if (profile_aframes)
+ nr_frames = profile_aframes;
if (interval < profile_interval_min)
return;
@@ -183,8 +181,7 @@ profile_create(hrtime_t interval, const char *name, int kind)
prof->prof_cyclic = CYCLIC_NONE;
prof->prof_kind = kind;
prof->prof_id = dtrace_probe_create(profile_id,
- NULL, NULL, name,
- profile_aframes ? profile_aframes : PROF_ARTIFICIAL_FRAMES, prof);
+ NULL, NULL, name, nr_frames, prof);
}
/*ARGSUSED*/
diff --git a/usr/src/uts/common/fs/fsflush.c b/usr/src/uts/common/fs/fsflush.c
index 24b5ff8bbc..d7b3ae1071 100644
--- a/usr/src/uts/common/fs/fsflush.c
+++ b/usr/src/uts/common/fs/fsflush.c
@@ -23,7 +23,7 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -352,8 +352,8 @@ fsflush()
proc_fsflush->p_stime = 0;
proc_fsflush->p_cutime = 0;
proc_fsflush->p_utime = 0;
- bcopy("fsflush", u.u_psargs, 8);
- bcopy("fsflush", u.u_comm, 7);
+ bcopy("fsflush", curproc->p_user.u_psargs, 8);
+ bcopy("fsflush", curproc->p_user.u_comm, 7);
mutex_init(&fsflush_lock, NULL, MUTEX_DEFAULT, NULL);
sema_init(&fsflush_sema, 0, NULL, SEMA_DEFAULT, NULL);
diff --git a/usr/src/uts/common/fs/sockfs/socktpi.c b/usr/src/uts/common/fs/sockfs/socktpi.c
index 0e35cb7a46..fb862614e3 100644
--- a/usr/src/uts/common/fs/sockfs/socktpi.c
+++ b/usr/src/uts/common/fs/sockfs/socktpi.c
@@ -696,7 +696,7 @@ sotpi_bindlisten(struct sonode *so, struct sockaddr *name,
goto done;
}
vattr.va_type = VSOCK;
- vattr.va_mode = 0777 & ~u.u_cmask;
+ vattr.va_mode = 0777 & ~PTOU(curproc)->u_cmask;
vattr.va_mask = AT_TYPE|AT_MODE;
/* NOTE: holding so_lock */
error = vn_create(soun->sun_path, UIO_SYSSPACE, &vattr,
diff --git a/usr/src/uts/common/fs/specfs/specvnops.c b/usr/src/uts/common/fs/specfs/specvnops.c
index 24c7ffedab..1a6c40517a 100644
--- a/usr/src/uts/common/fs/specfs/specvnops.c
+++ b/usr/src/uts/common/fs/specfs/specvnops.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2179,7 +2179,7 @@ spec_map(
cvp = sp->s_commonvp;
ASSERT(cvp != NULL);
- if (off < 0 || (off + len) < 0)
+ if (off < 0 || ((offset_t)(off + len) < 0))
return (ENXIO);
as_rangelock(as);
diff --git a/usr/src/uts/common/fs/tmpfs/tmp_vnops.c b/usr/src/uts/common/fs/tmpfs/tmp_vnops.c
index aa870b124a..2f1e94a7c7 100644
--- a/usr/src/uts/common/fs/tmpfs/tmp_vnops.c
+++ b/usr/src/uts/common/fs/tmpfs/tmp_vnops.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2078,7 +2078,7 @@ tmp_map(
if (vp->v_flag & VNOMAP)
return (ENOSYS);
- if (off < 0 || (off + len) < 0 ||
+ if (off < 0 || (offset_t)(off + len) < 0 ||
off > MAXOFF_T || (off + len) > MAXOFF_T)
return (ENXIO);
diff --git a/usr/src/uts/common/fs/vfs.c b/usr/src/uts/common/fs/vfs.c
index 4cfe749214..b473706b8b 100644
--- a/usr/src/uts/common/fs/vfs.c
+++ b/usr/src/uts/common/fs/vfs.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -618,7 +618,7 @@ vfs_mountdevices(void)
* _init devfs module to fill in the vfssw
*/
if (modload("fs", "devfs") == -1)
- cmn_err(CE_PANIC, "Cannot _init devfs module\n");
+ panic("Cannot _init devfs module");
/*
* Hold vfs
@@ -632,13 +632,13 @@ vfs_mountdevices(void)
* Locate mount point
*/
if (lookupname("/devices", UIO_SYSSPACE, FOLLOW, NULLVPP, &mvp))
- cmn_err(CE_PANIC, "Cannot find /devices\n");
+ panic("Cannot find /devices");
/*
* Perform the mount of /devices
*/
if (VFS_MOUNT(&devices, mvp, &mounta, CRED()))
- cmn_err(CE_PANIC, "Cannot mount /devices\n");
+ panic("Cannot mount /devices");
RUNLOCK_VFSSW();
@@ -652,7 +652,7 @@ vfs_mountdevices(void)
* Hold the root of /devices so it won't go away
*/
if (VFS_ROOT(&devices, &devicesdir))
- cmn_err(CE_PANIC, "vfs_mountdevices: not devices root");
+ panic("vfs_mountdevices: not devices root");
if (vfs_lock(&devices) != 0) {
VN_RELE(devicesdir);
@@ -766,11 +766,11 @@ vfs_mountfs(char *module, char *spec, char *path)
mounta.spec = spec;
mounta.dir = path;
if (lookupname(path, UIO_SYSSPACE, FOLLOW, NULLVPP, &mvp)) {
- cmn_err(CE_WARN, "Cannot find %s\n", path);
+ cmn_err(CE_WARN, "Cannot find %s", path);
return;
}
if (domount(NULL, &mounta, mvp, CRED(), &vfsp))
- cmn_err(CE_WARN, "Cannot mount %s\n", path);
+ cmn_err(CE_WARN, "Cannot mount %s", path);
else
VFS_RELE(vfsp);
VN_RELE(mvp);
@@ -800,7 +800,7 @@ vfs_mountroot(void)
* file system type.
*/
if (rootconf())
- cmn_err(CE_PANIC, "vfs_mountroot: cannot mount root");
+ panic("vfs_mountroot: cannot mount root");
/*
* Get vnode for '/'. Set up rootdir, u.u_rdir and u.u_cdir
* to point to it. These are used by lookuppn() so that it
@@ -808,10 +808,10 @@ vfs_mountroot(void)
*/
vfs_setmntpoint(rootvfs, "/");
if (VFS_ROOT(rootvfs, &rootdir))
- cmn_err(CE_PANIC, "vfs_mountroot: no root vnode");
- u.u_cdir = rootdir;
- VN_HOLD(u.u_cdir);
- u.u_rdir = NULL;
+ panic("vfs_mountroot: no root vnode");
+ PTOU(curproc)->u_cdir = rootdir;
+ VN_HOLD(PTOU(curproc)->u_cdir);
+ PTOU(curproc)->u_rdir = NULL;
/*
* Setup the global zone's rootvp, now that it exists.
@@ -874,7 +874,7 @@ vfs_mountroot(void)
*/
if (root_is_svm) {
if (svm_rootconf()) {
- cmn_err(CE_PANIC, "vfs_mountroot: cannot remount root");
+ panic("vfs_mountroot: cannot remount root");
}
/*
@@ -1325,7 +1325,7 @@ domount(char *fsname, struct mounta *uap, vnode_t *vp, struct cred *credp,
if ((sema_tryp(&vfsp->vfs_reflock) == 0) &&
!(vfsp->vfs_flag & VFS_REMOUNT))
cmn_err(CE_WARN,
- "mount type %s couldn't get vfs_reflock\n", vswp->vsw_name);
+ "mount type %s couldn't get vfs_reflock", vswp->vsw_name);
/*
* Lock the vfs. If this is a remount we want to avoid spurious umount
@@ -2860,7 +2860,7 @@ vfs_remove(struct vfs *vfsp)
* be busy.
*/
if (vfsp == rootvfs)
- cmn_err(CE_PANIC, "vfs_remove: unmounting root");
+ panic("vfs_remove: unmounting root");
vfs_list_remove(vfsp);
@@ -4105,7 +4105,7 @@ rootconf()
return (error);
if (modload("fs", fstyp) == -1)
- cmn_err(CE_PANIC, "Cannot _init %s module\n", fstyp);
+ panic("Cannot _init %s module", fstyp);
RLOCK_VFSSW();
vsw = vfs_getvfsswbyname(fstyp);
@@ -4126,7 +4126,7 @@ rootconf()
rootdev = rootvfs->vfs_dev;
if (error)
- cmn_err(CE_PANIC, "cannot mount root path %s", svm_bootpath);
+ panic("cannot mount root path %s", rootfs.bo_name);
return (error);
}
@@ -4177,8 +4177,7 @@ getrootfs(void)
/* attempt to determine netdev_path via boot_mac address */
netdev_path = strplumb_get_netdev_path();
if (netdev_path == NULL)
- cmn_err(CE_PANIC,
- "Cannot find boot network interface\n");
+ panic("cannot find boot network interface");
(void) strncpy(rootfs.bo_name, netdev_path, BO_MAXOBJNAME);
}
return ("nfs");
diff --git a/usr/src/uts/common/io/audio/inc.flg b/usr/src/uts/common/io/audio/inc.flg
index a8e830ddc5..c05ee0f88d 100644
--- a/usr/src/uts/common/io/audio/inc.flg
+++ b/usr/src/uts/common/io/audio/inc.flg
@@ -21,7 +21,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -81,8 +81,8 @@ find_files "s.*" \
usr/src/uts/sparc/mixer \
usr/src/uts/sparc/amsrc2 \
usr/src/uts/sparc/diaudio \
- usr/src/uts/i86pc/audio810 \
- usr/src/uts/i86pc/audiohd \
+ usr/src/uts/intel/audio810 \
+ usr/src/uts/intel/audiohd \
usr/src/uts/intel/audiosup \
usr/src/uts/intel/mixer \
usr/src/uts/intel/diaudio
@@ -128,5 +128,3 @@ echo_file usr/src/uts/intel/Makefile.intel
echo_file usr/src/uts/intel/Makefile.intel.shared
echo_file usr/src/uts/intel/Makefile.targ
echo_file usr/src/uts/intel/Makefile.targ.shared
-echo_file usr/src/uts/intel/ia32/Makefile.rules
-echo_file usr/src/uts/intel/amd64/Makefile.rules
diff --git a/usr/src/uts/common/io/avintr.c b/usr/src/uts/common/io/avintr.c
index 9236b3f4f2..cd5d474731 100644
--- a/usr/src/uts/common/io/avintr.c
+++ b/usr/src/uts/common/io/avintr.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -570,7 +569,6 @@ av_dispatch_autovect(uint_t vec)
caddr_t arg2 = av->av_intarg2;
dev_info_t *dip = av->av_dip;
- numcalled++;
if (intr == NULL)
break;
@@ -579,6 +577,7 @@ av_dispatch_autovect(uint_t vec)
r = (*intr)(arg1, arg2);
DTRACE_PROBE4(interrupt__complete, dev_info_t *, dip,
void *, intr, caddr_t, arg1, uint_t, r);
+ numcalled++;
claimed |= r;
if (av->av_ticksp && av->av_prilevel <= LOCK_LEVEL)
atomic_add_64(av->av_ticksp, intr_get_time());
diff --git a/usr/src/uts/common/io/busra.c b/usr/src/uts/common/io/busra.c
index 9d0062f48e..1a3c49c666 100644
--- a/usr/src/uts/common/io/busra.c
+++ b/usr/src/uts/common/io/busra.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -141,7 +140,7 @@ static int ra_map_exist(dev_info_t *dip, char *type);
static struct modlmisc modlmisc = {
&mod_miscops, /* Type of module. This one is a module */
- "Bus Resource Allocator (BUSRA) 1.36", /* Name of the module. */
+ "Bus Resource Allocator (BUSRA) %I%", /* Name of the module. */
};
static struct modlinkage modlinkage = {
@@ -1022,7 +1021,7 @@ pci_resource_setup(dev_info_t *dip)
break;
}
}
- kmem_free((caddr_t)regs, rlen);
+ kmem_free(regs, rlen);
}
/*
diff --git a/usr/src/uts/common/io/consconfig_dacf.c b/usr/src/uts/common/io/consconfig_dacf.c
index f53ce5dbb6..99a43972de 100644
--- a/usr/src/uts/common/io/consconfig_dacf.c
+++ b/usr/src/uts/common/io/consconfig_dacf.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -209,12 +209,13 @@ static char *consconfig_usb_ms_path = NULL;
* Internal variables
*/
static dev_t stdoutdev;
+static cons_state_t *consconfig_sp;
/*
* consconfig_errlevel: debug verbosity; smaller numbers are more
* verbose.
*/
-static int consconfig_errlevel = DPRINT_L3;
+int consconfig_errlevel = DPRINT_L3;
/*
* Baud rate table
@@ -733,18 +734,20 @@ cons_build_upper_layer(cons_state_t *sp)
*/
/* open the console keyboard device. will never be closed */
- if (ldi_open_by_name(CONSKBD_PATH, FREAD|FWRITE|FNOCTTY, kcred,
- &sp->conskbd_lh, sp->cons_li) != 0)
- cmn_err(CE_PANIC, "consconfig: "
- "unable to open conskbd device");
+ if (ldi_open_by_name(CONSKBD_PATH, FREAD|FWRITE|FNOCTTY,
+ kcred, &sp->conskbd_lh, sp->cons_li) != 0) {
+ panic("consconfig: unable to open conskbd device");
+ /*NOTREACHED*/
+ }
DPRINTF(DPRINT_L0, "conskbd_lh = %p\n", sp->conskbd_lh);
/* open the console mouse device. will never be closed */
- if (ldi_open_by_name(CONSMS_PATH, FREAD|FWRITE|FNOCTTY, kcred,
- &sp->consms_lh, sp->cons_li) != 0)
- cmn_err(CE_PANIC, "consconfig: "
- "unable to open consms device");
+ if (ldi_open_by_name(CONSMS_PATH, FREAD|FWRITE|FNOCTTY,
+ kcred, &sp->consms_lh, sp->cons_li) != 0) {
+ panic("consconfig: unable to open consms device");
+ /*NOTREACHED*/
+ }
DPRINTF(DPRINT_L0, "consms_lh = %p\n", sp->consms_lh);
@@ -789,17 +792,19 @@ cons_build_upper_layer(cons_state_t *sp)
* here.)
*/
wsconsvp = i_consconfig_createvp(IWSCN_PATH);
- if (wsconsvp == NULL)
- cmn_err(CE_PANIC, "consconfig: "
- "unable to find iwscn device");
+ if (wsconsvp == NULL) {
+ panic("consconfig: unable to find iwscn device");
+ /*NOTREACHED*/
+ }
if (cons_tem_disable)
return;
if (sp->cons_fb_path == NULL) {
-#if defined(i386) || defined(__i386) || defined(__ia64)
- cmn_err(CE_WARN, "consconfig: no screen found");
-#endif /* defined(i386) || defined(__i386) || defined(__ia64) */
+#if defined(__x86)
+ if (plat_stdout_is_framebuffer())
+ cmn_err(CE_WARN, "consconfig: no screen found");
+#endif
return;
}
@@ -897,6 +902,17 @@ consconfig_load_drivers(cons_state_t *sp)
kbddev = ddi_pathname_to_dev_t(sp->cons_keyboard_path);
if (sp->cons_mouse_path != NULL)
mousedev = ddi_pathname_to_dev_t(sp->cons_mouse_path);
+
+ /*
+ * On x86, make sure the fb driver is loaded even if we don't use it
+ * for the console. This will ensure that we create a /dev/fb link
+ * which is required to start Xorg.
+ */
+#if defined(__x86)
+ if (sp->cons_fb_path != NULL)
+ fbdev = ddi_pathname_to_dev_t(sp->cons_fb_path);
+#endif
+
DPRINTF(DPRINT_L0, "stdindev %lx, stdoutdev %lx, kbddev %lx, "
"mousedev %lx\n", stdindev, stdoutdev, kbddev, mousedev);
}
@@ -1221,10 +1237,12 @@ consconfig_init_input(cons_state_t *sp)
* after being closed.
*/
rconsvp = i_consconfig_createvp(sp->cons_stdin_path);
- if (rconsvp == NULL)
- cmn_err(CE_PANIC, "consconfig_init_input: "
+ if (rconsvp == NULL) {
+ panic("consconfig_init_input: "
"unable to find stdin device (%s)",
sp->cons_stdin_path);
+ /*NOTREACHED*/
+ }
rconsdev = rconsvp->v_rdev;
ASSERT(rconsdev == stdindev);
@@ -1349,8 +1367,6 @@ consconfig_init_input(cons_state_t *sp)
void
dynamic_console_config(void)
{
- cons_state_t *sp;
-
/* initialize space.c globals */
stdindev = NODEV;
mousedev = NODEV;
@@ -1365,11 +1381,11 @@ dynamic_console_config(void)
rconsdev = NODEV;
/* Initialize cons_state_t structure and console device paths */
- sp = consconfig_state_init();
- ASSERT(sp);
+ consconfig_sp = consconfig_state_init();
+ ASSERT(consconfig_sp);
/* Build upper layer of console stream */
- cons_build_upper_layer(sp);
+ cons_build_upper_layer(consconfig_sp);
/*
* Load keyboard/mouse drivers. The dacf routines will
@@ -1379,16 +1395,16 @@ dynamic_console_config(void)
* and mouse drivers are linked into their respective console
* streams if the pathnames are valid.
*/
- consconfig_load_drivers(sp);
- sp->cons_input_type = cons_get_input_type();
+ consconfig_load_drivers(consconfig_sp);
+ consconfig_sp->cons_input_type = cons_get_input_type();
/*
* This is legacy special case code for the "cool" virtual console
* for the Starfire project. Starfire has a dummy "ssp-serial"
* node in the OBP device tree and cvc is a pseudo driver.
*/
- if (sp->cons_stdout_path != NULL && stdindev == NODEV &&
- strstr(sp->cons_stdout_path, "ssp-serial")) {
+ if (consconfig_sp->cons_stdout_path != NULL && stdindev == NODEV &&
+ strstr(consconfig_sp->cons_stdout_path, "ssp-serial")) {
/*
* Setup the virtual console driver for Starfire
* Note that console I/O will still go through prom for now
@@ -1405,13 +1421,13 @@ dynamic_console_config(void)
return;
}
- rwsconsvp = sp->cons_wc_vp;
- rwsconsdev = sp->cons_wc_vp->v_rdev;
+ rwsconsvp = consconfig_sp->cons_wc_vp;
+ rwsconsdev = consconfig_sp->cons_wc_vp->v_rdev;
/* initialize framebuffer, console input, and redirection device */
- consconfig_init_framebuffer(sp);
- consconfig_init_input(sp);
+ consconfig_init_framebuffer(consconfig_sp);
+ consconfig_init_input(consconfig_sp);
DPRINTF(DPRINT_L0,
"mousedev %lx, kbddev %lx, fbdev %lx, rconsdev %lx\n",
diff --git a/usr/src/uts/common/io/mem.c b/usr/src/uts/common/io/mem.c
index 1b0c925ff4..08d2ffba85 100644
--- a/usr/src/uts/common/io/mem.c
+++ b/usr/src/uts/common/io/mem.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -74,7 +74,7 @@ extern int cpu_get_mem_info(uint64_t, uint64_t, uint64_t *, uint64_t *,
extern size_t cpu_get_name_bufsize(void);
extern int cpu_get_mem_sid(char *, char *, int, int *);
extern int cpu_get_mem_addr(char *, char *, uint64_t, uint64_t *);
-#elif defined(__i386) || defined(__amd64)
+#elif defined(__x86)
#include <sys/cpu_module.h>
#endif /* __sparc */
@@ -262,6 +262,24 @@ mmio(struct uio *uio, enum uio_rw rw, pfn_t pfn, off_t pageoff, int allowio)
return (error);
}
+/*
+ * Some platforms have permanently-mapped areas without PFNs, so we check
+ * specially here.
+ */
+static int
+mmplatio(struct uio *uio, enum uio_rw rw)
+{
+ uintptr_t pageaddr = (uintptr_t)uio->uio_loffset & PAGEMASK;
+ off_t pageoff = uio->uio_loffset & PAGEOFFSET;
+ size_t nbytes = MIN((size_t)(PAGESIZE - pageoff),
+ (size_t)uio->uio_iov->iov_len);
+
+ if (!plat_mem_valid_page(pageaddr, rw))
+ return (ENOTSUP);
+
+ return (uiomove((void *)(pageaddr + pageoff), nbytes, rw, uio));
+}
+
#ifdef __sparc
static int
@@ -331,6 +349,9 @@ mmrw(dev_t dev, struct uio *uio, enum uio_rw rw, cred_t *cred)
int try_lock = NEED_LOCK_KVADDR(vaddr);
int locked = 0;
+ if ((error = mmplatio(uio, rw)) != ENOTSUP)
+ break;
+
/*
* If vaddr does not map a valid page, as_pagelock()
* will return failure. Hence we can't check the
@@ -1179,7 +1200,7 @@ mm_get_paddr(nvlist_t *nvl, uint64_t *paddr)
return (err);
}
}
-#elif defined(__i386) || defined(__amd64)
+#elif defined(__x86)
if (cmi_mc_unumtopa(NULL, nvl, &pa) == 0)
return (EINVAL);
#else
diff --git a/usr/src/uts/common/io/power.c b/usr/src/uts/common/io/power.c
index 83a0211102..e87922ce84 100644
--- a/usr/src/uts/common/io/power.c
+++ b/usr/src/uts/common/io/power.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -54,12 +54,15 @@
#include <sys/cmn_err.h>
#include <sys/errno.h>
#include <sys/modctl.h>
-#include <sys/machsystm.h>
#include <sys/open.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <sys/pbio.h>
+#if defined(__sparc)
+#include <sys/machsystm.h>
+#endif
+
#ifdef ACPI_POWER_BUTTON
#include <sys/acpi/acpi.h>
diff --git a/usr/src/uts/common/kmdb/kdrv.c b/usr/src/uts/common/kmdb/kdrv.c
index a2c5797371..2b8e4857b4 100644
--- a/usr/src/uts/common/kmdb/kdrv.c
+++ b/usr/src/uts/common/kmdb/kdrv.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -90,7 +90,7 @@ kdrv_activate(intptr_t arg)
size_t got;
int i, rc;
-#if defined(__i386) || defined(__amd64)
+#if defined(__x86)
if (cons_polledio == NULL) {
cmn_err(CE_NOTE, "kmdb not supported: no console polled I/O");
return (ENOTSUP);
diff --git a/usr/src/uts/common/krtld/bootrd.c b/usr/src/uts/common/krtld/bootrd.c
index 576b429c99..4d48f71673 100644
--- a/usr/src/uts/common/krtld/bootrd.c
+++ b/usr/src/uts/common/krtld/bootrd.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,9 +44,7 @@ static uint64_t rd_start, rd_end;
struct boot_fs_ops *bfs_ops;
struct boot_fs_ops *bfs_tab[] = {&bufs_ops, &bhsfs_ops, NULL};
-#ifdef DEBUG
-static uint64_t scratch_max;
-#endif
+static uintptr_t scratch_max;
#define _kmem_ready get_weakish_int(&kmem_ready)
@@ -115,12 +112,17 @@ kobj_boot_unmountroot()
{
#ifdef DEBUG
if (boothowto & RB_VERBOSE)
- _kobj_printf(ops, "boot scratch memory used: 0x%llx\n",
+ _kobj_printf(ops, "boot scratch memory used: 0x%lx\n",
scratch_max);
#endif
(void) BRD_UNMOUNTROOT(bfs_ops);
}
+/*
+ * Boot time wrappers for memory allocators. Called for both permanent
+ * and temporary boot memory allocations. We have to track which allocator
+ * (boot or kmem) was used so that we know how to free.
+ */
void *
bkmem_alloc(size_t size)
{
@@ -130,11 +132,13 @@ bkmem_alloc(size_t size)
if (_kmem_ready)
return (kobj_alloc(size, 0));
+ /*
+ * Remember the highest BOP_ALLOC allocated address and don't free
+ * anything below it.
+ */
addr = BOP_ALLOC(ops, 0, size, 0);
-#ifdef DEBUG
if (scratch_max < (uintptr_t)addr + size)
scratch_max = (uintptr_t)addr + size;
-#endif
return (addr);
}
@@ -143,12 +147,9 @@ void
bkmem_free(void *p, size_t size)
{
/*
- * Don't bother freeing scratch memory
- * Note that in amd64, BOP_ALLOC returns address
- * prepended with 0xffffffff, so we cast to 32-bit
- * before comparing.
+ * Free only if it's not boot scratch memory.
*/
- if ((uint32_t)(uintptr_t)p > MAGIC_PHYS)
+ if ((uintptr_t)p >= scratch_max)
kobj_free(p, size);
}
diff --git a/usr/src/uts/common/krtld/kobj.c b/usr/src/uts/common/krtld/kobj.c
index 01032117ec..87c66363c8 100644
--- a/usr/src/uts/common/krtld/kobj.c
+++ b/usr/src/uts/common/krtld/kobj.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -80,9 +80,10 @@
#define DOSYM_UNDEF -1 /* undefined symbol */
#define DOSYM_UNSAFE -2 /* MT-unsafe driver symbol */
-static struct module *load_exec(val_t *);
+static void synthetic_bootaux(char *, val_t *);
+static struct module *load_exec(val_t *, char *);
static void load_linker(val_t *);
-static struct modctl *add_primary(char *filename, int);
+static struct modctl *add_primary(const char *filename, int);
static int bind_primary(val_t *, int);
static int load_primary(struct module *, int);
static int load_kmdb(val_t *);
@@ -97,7 +98,7 @@ static int do_symbols(struct module *, Elf64_Addr);
static void module_assign(struct modctl *, struct module *);
static void free_module_data(struct module *);
static char *depends_on(struct module *);
-static char *getmodpath(void);
+static char *getmodpath(const char *);
static char *basename(char *);
static void attr_val(val_t *);
static char *find_libmacro(char *);
@@ -143,6 +144,11 @@ extern int last_module_id;
* is loaded.
*/
int kobj_debug = 0;
+
+#define KOBJ_MARK(s) if (kobj_debug & D_DEBUG) \
+ (_kobj_printf(ops, "%d", __LINE__), _kobj_printf(ops, ": %s\n", s))
+#else
+#define KOBJ_MARK(s) /* discard */
#endif
#define MODPATH_PROPNAME "module-path"
@@ -197,11 +203,11 @@ void sas_prisyms(struct modctl_list *);
void sas_syms(struct module *);
#endif
+char *kobj_module_path; /* module search path */
vmem_t *text_arena; /* module text arena */
static vmem_t *data_arena; /* module data & bss arena */
static vmem_t *ctf_arena; /* CTF debug data arena */
static struct modctl *kobj_modules = NULL; /* modules loaded */
-static char *module_path; /* module search path */
int kobj_mmu_pagesize; /* system pagesize */
static int lg_pagesize; /* "large" pagesize */
static int kobj_last_module_id = 0; /* id assignment */
@@ -262,12 +268,18 @@ const char *ultra_2 = "SUNW,UltraSPARC-II";
#endif
/*
- * Beginning and end of the kernel's
- * dynamic text/data segments.
+ * Beginning and end of the kernel's dynamic text/data segments.
*/
static caddr_t _text;
static caddr_t _etext;
-static caddr_t _data;
+static caddr_t _data;
+
+/*
+ * XXX Hmm. The sparc linker fails to define this symbol.
+ */
+#if !defined(__sparc)
+extern
+#endif
caddr_t _edata;
static Addr dynseg = 0; /* load address of "dynamic" segment */
@@ -337,6 +349,7 @@ kobj_init(
struct module *mp;
struct modctl *modp;
Addr entry;
+ char filename[MAXPATHLEN];
/*
* Save these to pass on to
@@ -351,6 +364,7 @@ kobj_init(
#else
_kobj_printf = (void (*)(void *, const char *, ...))bop_putsarg;
#endif
+ KOBJ_MARK("Entered kobj_init()");
#if defined(__sparc)
/* XXXQ should suppress this test on sun4v */
@@ -360,11 +374,6 @@ kobj_init(
}
}
#endif
- /*
- * Save the interesting attribute-values
- * (scanned by kobj_boot).
- */
- attr_val(bootaux);
/*
* Check bootops version.
@@ -374,6 +383,17 @@ kobj_init(
BOP_GETVERSION(ops));
_kobj_printf(ops, "expected %d\n", BO_VERSION);
}
+#ifdef KOBJ_DEBUG
+ else if (kobj_debug & D_DEBUG) {
+ /*
+ * Say -something- so we know we got this far ..
+ */
+ _kobj_printf(ops, "krtld: Using boot version %d.\n",
+ BOP_GETVERSION(ops));
+ }
+#endif
+
+ (void) BOP_GETPROP(ops, "whoami", filename);
/*
* We don't support standalone debuggers anymore. The use of kadb
@@ -395,13 +415,40 @@ kobj_init(
/* on x86, we always boot with a ramdisk */
extern int kobj_boot_mountroot(void);
(void) kobj_boot_mountroot();
+
+ /*
+ * Now that the ramdisk is mounted, finish boot property
+ * initialization.
+ */
+ boot_prop_finish();
}
#endif
+#if !defined(_UNIX_KRTLD)
+ /*
+ * If 'unix' is linked together with 'krtld' into one executable,
+ * the early boot code does -not- hand us any of the dynamic metadata
+ * about the executable. In particular, it does not read in, map or
+ * otherwise look at the program headers. We fake all that up now.
+ *
+ * We do this early as DTrace static probes and tnf probes both call
+ * undefined references. We have to process those relocations before
+ * calling any of them.
+ */
+ if (bootaux[BA_PHDR].ba_ptr == NULL)
+ synthetic_bootaux(filename, bootaux);
+#endif
+
+ /*
+ * Save the interesting attribute-values
+ * (scanned by kobj_boot).
+ */
+ attr_val(bootaux);
+
/*
* Set the module search path.
*/
- module_path = getmodpath();
+ kobj_module_path = getmodpath(filename);
boot_cpu_compatible_list = find_libmacro("CPU");
@@ -412,7 +459,7 @@ kobj_init(
* loadable modules.
*/
- mp = load_exec(bootaux);
+ mp = load_exec(bootaux, filename);
load_linker(bootaux);
/*
@@ -503,6 +550,72 @@ fail:
_kobj_printf(ops, "krtld: error during initial load/link phase\n");
}
+#if !defined(_UNIX_KRTLD)
+/*
+ * Synthesize additional metadata that describes the executable.
+ *
+ * (When the dynamic executable has an interpreter, the boot program
+ * does all this for us. Where we don't have an interpreter, (or a
+ * even a boot program, perhaps) we have to do this for ourselves.)
+ */
+static void
+synthetic_bootaux(char *filename, val_t *bootaux)
+{
+ Ehdr ehdr;
+ caddr_t phdrbase;
+ struct _buf *file;
+ int i, n;
+
+ /*
+ * Elf header
+ */
+ KOBJ_MARK("synthetic_bootaux()");
+ KOBJ_MARK(filename);
+ file = kobj_open_file(filename);
+ if (file == (struct _buf *)-1) {
+ _kobj_printf(ops, "krtld: failed to open '%s'\n", filename);
+ return;
+ }
+ KOBJ_MARK("reading program headers");
+ if (kobj_read_file(file, (char *)&ehdr, sizeof (ehdr), 0) < 0) {
+ _kobj_printf(ops, "krtld: %s: failed to read ehder\n",
+ filename);
+ return;
+ }
+
+ /*
+ * Program headers
+ */
+ bootaux[BA_PHNUM].ba_val = ehdr.e_phnum;
+ bootaux[BA_PHENT].ba_val = ehdr.e_phentsize;
+ n = ehdr.e_phentsize * ehdr.e_phnum;
+
+ phdrbase = kobj_alloc(n, KM_WAIT | KM_TMP);
+
+ if (kobj_read_file(file, phdrbase, n, ehdr.e_phoff) < 0) {
+ _kobj_printf(ops, "krtld: %s: failed to read phdrs\n",
+ filename);
+ return;
+ }
+ bootaux[BA_PHDR].ba_ptr = phdrbase;
+ kobj_close_file(file);
+ KOBJ_MARK("closed file");
+
+ /*
+ * Find the dynamic section address
+ */
+ for (i = 0; i < ehdr.e_phnum; i++) {
+ Phdr *phdr = (Phdr *)(phdrbase + ehdr.e_phentsize * i);
+
+ if (phdr->p_type == PT_DYNAMIC) {
+ bootaux[BA_DYNAMIC].ba_ptr = (void *)phdr->p_vaddr;
+ break;
+ }
+ }
+ KOBJ_MARK("synthetic_bootaux() done");
+}
+#endif
+
/*
* Set up any global information derived
* from attribute/values in the boot or
@@ -515,6 +628,7 @@ attr_val(val_t *bootaux)
int phnum, phsize;
int i;
+ KOBJ_MARK("attr_val()");
kobj_mmu_pagesize = bootaux[BA_PAGESZ].ba_val;
lg_pagesize = bootaux[BA_LPAGESZ].ba_val;
use_iflush = bootaux[BA_IFLUSH].ba_val;
@@ -531,11 +645,15 @@ attr_val(val_t *bootaux)
* Bounds of the various segments.
*/
if (!(phdr->p_flags & PF_X)) {
+#if defined(_UNIX_KRTLD)
dynseg = phdr->p_vaddr;
+#else
+ ASSERT(phdr->p_vaddr == 0);
+#endif
} else {
if (phdr->p_flags & PF_W) {
- _data = (caddr_t)phdr->p_vaddr;
- _edata = _data + phdr->p_memsz;
+ _data = (caddr_t)phdr->p_vaddr;
+ _edata = _data + phdr->p_memsz;
} else {
_text = (caddr_t)phdr->p_vaddr;
_etext = _text + phdr->p_memsz;
@@ -560,9 +678,8 @@ attr_val(val_t *bootaux)
* Set up the booted executable.
*/
static struct module *
-load_exec(val_t *bootaux)
+load_exec(val_t *bootaux, char *filename)
{
- char filename[MAXPATHLEN];
struct modctl *cp;
struct module *mp;
Dyn *dyn;
@@ -570,10 +687,20 @@ load_exec(val_t *bootaux)
int i, lsize, osize, nsize, allocsize;
char *libname, *tmp;
- (void) BOP_GETPROP(ops, "whoami", filename);
+ /*
+ * Set the module search path.
+ */
+ kobj_module_path = getmodpath(filename);
+#ifdef KOBJ_DEBUG
+ if (kobj_debug & D_DEBUG)
+ _kobj_printf(ops, "module path '%s'\n", kobj_module_path);
+#endif
+
+ KOBJ_MARK("add_primary");
cp = add_primary(filename, KOBJ_LM_PRIMARY);
+ KOBJ_MARK("struct module");
mp = kobj_zalloc(sizeof (struct module), KM_WAIT);
cp->mod_mp = mp;
@@ -590,7 +717,10 @@ load_exec(val_t *bootaux)
* Since this module is the only exception,
* we cons up some section headers.
*/
+ KOBJ_MARK("symhdr");
mp->symhdr = kobj_zalloc(sizeof (Shdr), KM_WAIT);
+
+ KOBJ_MARK("strhdr");
mp->strhdr = kobj_zalloc(sizeof (Shdr), KM_WAIT);
mp->symhdr->sh_type = SHT_SYMTAB;
@@ -631,6 +761,7 @@ load_exec(val_t *bootaux)
nsize = osize = 0;
allocsize = MAXPATHLEN;
+ KOBJ_MARK("depends_on");
mp->depends_on = kobj_alloc(allocsize, KM_WAIT);
for (dyn = (Dyn *) bootaux[BA_DYNAMIC].ba_ptr;
@@ -651,6 +782,7 @@ load_exec(val_t *bootaux)
lsize = strlen(libname);
nsize += lsize;
if (nsize + 1 > allocsize) {
+ KOBJ_MARK("grow depends_on");
tmp = kobj_alloc(allocsize + MAXPATHLEN,
KM_WAIT);
bcopy(mp->depends_on, tmp, osize);
@@ -668,6 +800,7 @@ load_exec(val_t *bootaux)
/*
* alloc with exact size and copy whatever it got over
*/
+ KOBJ_MARK("realloc depends_on");
tmp = kobj_alloc(nsize, KM_WAIT);
bcopy(mp->depends_on, tmp, nsize);
kobj_free(mp->depends_on, allocsize);
@@ -683,11 +816,17 @@ load_exec(val_t *bootaux)
* We allocate our own table since we don't
* hash undefined references.
*/
+ KOBJ_MARK("chains");
mp->chains = kobj_zalloc(mp->nsyms * sizeof (symid_t), KM_WAIT);
+ KOBJ_MARK("buckets");
mp->buckets = kobj_zalloc(mp->hashsize * sizeof (symid_t), KM_WAIT);
mp->text = _text;
mp->data = _data;
+
+ mp->text_size = _etext - _text;
+ mp->data_size = _edata - _data;
+
cp->mod_text = mp->text;
cp->mod_text_size = mp->text_size;
@@ -722,11 +861,12 @@ load_exec(val_t *bootaux)
sym_insert(mp, mp->strings + sp->st_name, i);
}
+ KOBJ_MARK("load_exec done");
return (mp);
}
/*
- * Set up the linker module.
+ * Set up the linker module (if it's compiled in, LDNAME is NULL)
*/
static void
load_linker(val_t *bootaux)
@@ -740,6 +880,12 @@ load_linker(val_t *bootaux)
int shsize;
char *dlname = (char *)bootaux[BA_LDNAME].ba_ptr;
+ /*
+ * On some architectures, krtld is compiled into the kernel.
+ */
+ if (dlname == NULL)
+ return;
+
cp = add_primary(dlname, KOBJ_LM_PRIMARY);
mp = kobj_zalloc(sizeof (struct module), KM_WAIT);
@@ -906,12 +1052,19 @@ kobj_notify(int type, struct modctl *modp)
/*
* Ask boot for the module path.
*/
+/*ARGSUSED*/
static char *
-getmodpath(void)
+getmodpath(const char *filename)
{
char *path;
int len;
+#if defined(_UNIX_KRTLD)
+ /*
+ * The boot program provides the module name when it detects
+ * that the executable has an interpreter, thus we can ask
+ * it directly in this case.
+ */
if ((len = BOP_GETPROPLEN(ops, MODPATH_PROPNAME)) == -1)
return (MOD_DEFPATH);
@@ -920,10 +1073,48 @@ getmodpath(void)
(void) BOP_GETPROP(ops, MODPATH_PROPNAME, path);
return (*path ? path : MOD_DEFPATH);
+
+#else
+
+ /*
+ * Construct the directory path from the filename.
+ */
+
+ char *p;
+ const char isastr[] = "/amd64";
+ size_t isalen = strlen(isastr);
+
+ if ((p = strrchr(filename, '/')) == NULL)
+ return (MOD_DEFPATH);
+
+ while (p > filename && *(p - 1) == '/')
+ p--; /* remove trailing '/' characters */
+ if (p == filename)
+ p++; /* so "/" -is- the modpath in this case */
+
+ /*
+ * Remove optional isa-dependent directory name - the module
+ * subsystem will put this back again (!)
+ */
+ len = p - filename;
+ if (len > isalen &&
+ strncmp(&filename[len - isalen], isastr, isalen) == 0)
+ p -= isalen;
+
+ /*
+ * "/platform/mumblefrotz" + " " + MOD_DEFPATH
+ */
+ len += (p - filename) + 1 + strlen(MOD_DEFPATH) + 1;
+
+ path = kobj_zalloc(len, KM_WAIT);
+ (void) strncpy(path, filename, p - filename);
+ (void) strcat(path, " ");
+ return (strcat(path, MOD_DEFPATH));
+#endif
}
static struct modctl *
-add_primary(char *filename, int lmid)
+add_primary(const char *filename, int lmid)
{
struct modctl *cp;
@@ -973,10 +1164,6 @@ bind_primary(val_t *bootaux, int lmid)
struct modctl_list *linkmap = kobj_lm_lookup(lmid);
struct modctl_list *lp;
struct module *mp;
- Dyn *dyn;
- Word relasz;
- Word relaent;
- char *rela;
/*
* Do common symbols.
@@ -1012,11 +1199,10 @@ bind_primary(val_t *bootaux, int lmid)
mp = mod(lp);
if (mp->flags & KOBJ_EXEC) {
- Word shtype;
-
- relasz = 0;
- relaent = 0;
- rela = NULL;
+ Dyn *dyn;
+ Word relasz = 0, relaent = 0;
+ Word shtype;
+ char *rela = NULL;
for (dyn = (Dyn *)bootaux[BA_DYNAMIC].ba_ptr;
dyn->d_tag != DT_NULL; dyn++) {
@@ -1048,7 +1234,6 @@ bind_primary(val_t *bootaux, int lmid)
"module %s\n", mp->filename);
return (-1);
}
-
#ifdef KOBJ_DEBUG
if (kobj_debug & D_RELOCATIONS)
_kobj_printf(ops, "krtld: relocating: file=%s "
@@ -1062,7 +1247,6 @@ bind_primary(val_t *bootaux, int lmid)
return (-1);
}
- /* sync_instruction_memory */
kobj_sync_instruction_memory(mp->text, mp->text_size);
}
@@ -1259,6 +1443,15 @@ load_kmdb(val_t *bootaux)
if ((sym = lookup_one(mctl->mod_mp, "kctl_boot_activate")) == NULL)
return (-1);
+#ifdef KOBJ_DEBUG
+ if (kobj_debug & D_DEBUG) {
+ _kobj_printf(ops, "calling kctl_boot_activate() @ 0x%lx\n",
+ sym->st_value);
+ _kobj_printf(ops, "\tops 0x%p\n", ops);
+ _kobj_printf(ops, "\tromp 0x%p\n", romp);
+ }
+#endif
+
if (((kctl_boot_activate_f *)sym->st_value)(ops, romp, 0,
(const char **)kobj_kmdb_argv) < 0)
return (-1);
@@ -2104,8 +2297,13 @@ get_progbits(struct module *mp, struct _buf *file)
mp->data_size = dp->size;
if (standalone) {
+ caddr_t limit = _data;
+
+ if (lg_pagesize && _text + lg_pagesize < limit)
+ limit = _text + lg_pagesize;
+
mp->text = kobj_segbrk(&_etext, mp->text_size,
- tp->align, _data);
+ tp->align, limit);
/*
* If we can't grow the text segment, try the
* data segment before failing.
@@ -2422,6 +2620,7 @@ get_syms(struct module *mp, struct _buf *file)
}
}
}
+
sym_insert(mp, symname, i);
}
@@ -3258,7 +3457,8 @@ kobj_open_path(char *name, int use_path, int use_moddir_suffix)
if (!use_path)
pathp = ""; /* use name as specified */
else
- pathp = module_path; /* use configured default path */
+ pathp = kobj_module_path;
+ /* use configured default path */
pathpsave = pathp; /* keep this for error reporting */
@@ -3701,7 +3901,7 @@ kobj_alloc(size_t size, int flag)
#ifdef KOBJ_DEBUG
if (kobj_debug & D_DEBUG) {
_kobj_printf(ops, "krtld: failed scratch alloc "
- "of %u bytes -- falling back\n", size);
+ "of %lu bytes -- falling back\n", size);
}
#endif
}
@@ -3730,15 +3930,13 @@ kobj_sync(void)
{
struct modctl_list *lp, **lpp;
- extern char *default_path;
-
/*
- * module_path can be set in /etc/system
+ * The module path can be set in /etc/system via 'moddir' commands
*/
if (default_path != NULL)
- module_path = default_path;
+ kobj_module_path = default_path;
else
- default_path = module_path;
+ default_path = kobj_module_path;
ksyms_arena = vmem_create("ksyms", NULL, 0, sizeof (uint64_t),
segkmem_alloc, segkmem_free, heap_arena, 0, VM_SLEEP);
@@ -3778,19 +3976,25 @@ kobj_segbrk(caddr_t *spp, size_t size, size_t align, caddr_t limit)
* Need more pages?
*/
if (va + size > pva) {
+ uintptr_t npva;
+
alloc_size = P2ROUNDUP(size - (pva - va), alloc_pgsz);
/*
* Check for overlapping segments.
*/
- if (limit && limit <= *spp + alloc_size)
+ if (limit && limit <= *spp + alloc_size) {
return ((caddr_t)0);
+ }
- pva = (uintptr_t)BOP_ALLOC(ops, (caddr_t)pva,
+ npva = (uintptr_t)BOP_ALLOC(ops, (caddr_t)pva,
alloc_size, alloc_align);
- if (pva == NULL) {
- _kobj_printf(ops, "BOP_ALLOC refused, 0x%x bytes ",
+
+ if (npva == NULL) {
+ _kobj_printf(ops, "BOP_ALLOC failed, 0x%lx bytes",
alloc_size);
+ _kobj_printf(ops, " aligned %lx", alloc_align);
_kobj_printf(ops, " at 0x%lx\n", pva);
+ return (NULL);
}
}
*spp = (caddr_t)(va + size);
diff --git a/usr/src/uts/common/krtld/kobj_kdi.c b/usr/src/uts/common/krtld/kobj_kdi.c
index 25d38e75b1..c094e30d06 100644
--- a/usr/src/uts/common/krtld/kobj_kdi.c
+++ b/usr/src/uts/common/krtld/kobj_kdi.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -239,6 +238,7 @@ kdi_t kobj_kdi = {
* plat_kdi_init.
*/
NULL, /* kdi_plat_call */
+ NULL, /* kdi_kmdb_enter */
{ NULL }, /* kdi_arch */
{ NULL } /* kdi_plat */
};
diff --git a/usr/src/uts/common/os/acct.c b/usr/src/uts/common/os/acct.c
index f442a30ae3..c596ce45f3 100644
--- a/usr/src/uts/common/os/acct.c
+++ b/usr/src/uts/common/os/acct.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -380,6 +379,7 @@ acct(char st)
struct vnode *vp;
struct cred *cr;
struct proc *p;
+ user_t *ua;
struct vattr va;
ssize_t resid = 0;
int error;
@@ -398,13 +398,14 @@ acct(char st)
* cred locking is needed.
*/
p = curproc;
- bcopy(u.u_comm, ag->acctbuf.ac_comm, sizeof (ag->acctbuf.ac_comm));
- ag->acctbuf.ac_btime = u.u_start.tv_sec;
+ ua = PTOU(p);
+ bcopy(ua->u_comm, ag->acctbuf.ac_comm, sizeof (ag->acctbuf.ac_comm));
+ ag->acctbuf.ac_btime = ua->u_start.tv_sec;
ag->acctbuf.ac_utime = acct_compress(NSEC_TO_TICK(p->p_acct[LMS_USER]));
ag->acctbuf.ac_stime = acct_compress(
NSEC_TO_TICK(p->p_acct[LMS_SYSTEM] + p->p_acct[LMS_TRAP]));
- ag->acctbuf.ac_etime = acct_compress(lbolt - u.u_ticks);
- ag->acctbuf.ac_mem = acct_compress((ulong_t)u.u_mem);
+ ag->acctbuf.ac_etime = acct_compress(lbolt - ua->u_ticks);
+ ag->acctbuf.ac_mem = acct_compress((ulong_t)ua->u_mem);
ag->acctbuf.ac_io = acct_compress((ulong_t)p->p_ru.ioch);
ag->acctbuf.ac_rw = acct_compress((ulong_t)(p->p_ru.inblock +
p->p_ru.oublock));
@@ -413,7 +414,7 @@ acct(char st)
ag->acctbuf.ac_gid = crgetrgid(cr);
(void) cmpldev(&ag->acctbuf.ac_tty, cttydev(p));
ag->acctbuf.ac_stat = st;
- ag->acctbuf.ac_flag = (u.u_acflag | AEXPND);
+ ag->acctbuf.ac_flag = (ua->u_acflag | AEXPND);
/*
* Save the size. If the write fails, reset the size to avoid
diff --git a/usr/src/uts/common/os/clock.c b/usr/src/uts/common/os/clock.c
index a1040f1270..4eff816e48 100644
--- a/usr/src/uts/common/os/clock.c
+++ b/usr/src/uts/common/os/clock.c
@@ -450,8 +450,17 @@ clock(void)
nrunnable += cpu_nrunnable;
cpupart = cp->cpu_part;
cpupart->cp_nrunnable_cum += cpu_nrunnable;
- if (one_sec)
+ if (one_sec) {
cpupart->cp_nrunnable += cpu_nrunnable;
+ /*
+ * w_io is used to update sysinfo.waiting during
+ * one_second processing below. Only gather w_io
+ * information when we walk the list of cpus if we're
+ * going to perform one_second processing.
+ */
+ w_io += CPU_STATS(cp, sys.iowait);
+
+ }
if (do_lgrp_load &&
(cp->cpu_flags & CPU_EXISTS)) {
/*
diff --git a/usr/src/uts/common/os/core.c b/usr/src/uts/common/os/core.c
index 5e64bdda97..e833022e2b 100644
--- a/usr/src/uts/common/os/core.c
+++ b/usr/src/uts/common/os/core.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -256,7 +255,7 @@ create_core_file(char *fp, enum core_types core_type, vnode_t **vpp)
file = pn.pn_path;
}
error = vn_openat(file, UIO_SYSSPACE, FWRITE | FTRUNC | FEXCL |
- FCREAT | FOFFMAX, perms, &vp, CRCREAT, u.u_cmask, dvp);
+ FCREAT | FOFFMAX, perms, &vp, CRCREAT, PTOU(curproc)->u_cmask, dvp);
if (core_type != CORE_PROC) {
VN_RELE(dvp);
pn_free(&pn);
@@ -438,9 +437,9 @@ do_core(char *fp, int sig, enum core_types core_type, struct core_globals *cg)
(void) flush_user_windows_to_stack(NULL);
#endif
#ifdef SUN_SRC_COMPAT
- u.u_acflag |= ACORE;
+ PTOU(curproc)->u_acflag |= ACORE;
#endif
- if ((eswp = u.u_execsw) == NULL ||
+ if ((eswp = PTOU(curproc)->u_execsw) == NULL ||
(eswp = findexec_by_magic(eswp->exec_magic)) == NULL) {
error = ENOSYS;
} else {
diff --git a/usr/src/uts/common/os/cpu.c b/usr/src/uts/common/os/cpu.c
index 9237517a69..849cdabc49 100644
--- a/usr/src/uts/common/os/cpu.c
+++ b/usr/src/uts/common/os/cpu.c
@@ -58,7 +58,7 @@
#include <sys/msacct.h>
#include <sys/time.h>
#include <sys/archsystm.h>
-#if defined(__i386) || defined(__amd64)
+#if defined(__x86)
#include <sys/x86_archext.h>
#endif
@@ -145,15 +145,6 @@ cpu_t *cpu_inmotion;
int weakbindingbarrier;
/*
- * values for safe_list. Pause state that CPUs are in.
- */
-#define PAUSE_IDLE 0 /* normal state */
-#define PAUSE_READY 1 /* paused thread ready to spl */
-#define PAUSE_WAIT 2 /* paused thread is spl-ed high */
-#define PAUSE_DIE 3 /* tell pause thread to leave */
-#define PAUSE_DEAD 4 /* pause thread has left */
-
-/*
* Variables used in pause_cpus().
*/
static volatile char safe_list[NCPU];
@@ -770,18 +761,8 @@ cpu_pause(volatile char *safe)
* setbackdq/setfrontdq.
*/
s = splhigh();
- /*
- * This cpu is now safe.
- */
- *safe = PAUSE_WAIT;
- membar_enter(); /* make sure stores are flushed */
- /*
- * Now we wait. When we are allowed to continue, safe will
- * be set to PAUSE_IDLE.
- */
- while (*safe != PAUSE_IDLE)
- ;
+ mach_cpu_pause(safe);
splx(s);
/*
@@ -1198,6 +1179,7 @@ cpu_online(cpu_t *cp)
lgrp_kstat_create(cp);
cpu_state_change_notify(cp->cpu_id, CPU_ON);
cpu_intr_enable(cp); /* arch-dep hook */
+ cpu_set_state(cp);
cyclic_online(cp);
poke_cpu(cp->cpu_id);
}
@@ -2093,7 +2075,7 @@ static struct {
kstat_named_t ci_device_ID;
kstat_named_t ci_cpu_fru;
#endif
-#if defined(__i386) || defined(__amd64)
+#if defined(__x86)
kstat_named_t ci_vendorstr;
kstat_named_t ci_family;
kstat_named_t ci_model;
@@ -2114,7 +2096,7 @@ static struct {
{ "device_ID", KSTAT_DATA_UINT64 },
{ "cpu_fru", KSTAT_DATA_STRING },
#endif
-#if defined(__i386) || defined(__amd64)
+#if defined(__x86)
{ "vendor_id", KSTAT_DATA_STRING },
{ "family", KSTAT_DATA_INT32 },
{ "model", KSTAT_DATA_INT32 },
@@ -2175,7 +2157,7 @@ cpu_info_kstat_update(kstat_t *ksp, int rw)
cpunodes[cp->cpu_id].device_id;
kstat_named_setstr(&cpu_info_template.ci_cpu_fru, cpu_fru_fmri(cp));
#endif
-#if defined(__i386) || defined(__amd64)
+#if defined(__x86)
kstat_named_setstr(&cpu_info_template.ci_vendorstr,
cpuid_getvendorstr(cp));
cpu_info_template.ci_family.value.l = cpuid_getfamily(cp);
@@ -2207,7 +2189,7 @@ cpu_info_kstat_create(cpu_t *cp)
cp->cpu_info_kstat->ks_data_size +=
strlen(cpu_fru_fmri(cp)) + 1;
#endif
-#if defined(__i386) || defined(__amd64)
+#if defined(__x86)
cp->cpu_info_kstat->ks_data_size += X86_VENDOR_STRLEN;
#endif
cp->cpu_info_kstat->ks_lock = &cpu_info_template_lock;
@@ -3020,7 +3002,7 @@ cpu_sys_stats_ks_update(kstat_t *ksp, int rw)
csskd->modload.value.ui64 = css->modload;
csskd->modunload.value.ui64 = css->modunload;
csskd->bawrite.value.ui64 = css->bawrite;
- csskd->iowait.value.ui64 = 0;
+ csskd->iowait.value.ui64 = css->iowait;
return (0);
}
@@ -3166,7 +3148,7 @@ cpu_stat_ks_update(kstat_t *ksp, int rw)
cso->cpu_sysinfo.win_su_cnt = 0;
cso->cpu_sysinfo.win_suo_cnt = 0;
- cso->cpu_syswait.iowait = 0;
+ cso->cpu_syswait.iowait = CPU_STATS(cp, sys.iowait);
cso->cpu_syswait.swap = 0;
cso->cpu_syswait.physio = 0;
diff --git a/usr/src/uts/common/os/dumpsubr.c b/usr/src/uts/common/os/dumpsubr.c
index d5b55a8842..9a6aca6965 100644
--- a/usr/src/uts/common/os/dumpsubr.c
+++ b/usr/src/uts/common/os/dumpsubr.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -637,6 +636,7 @@ dumpsys(void)
*/
dumphdr->dump_map = dumpvp_flush();
dump_as(&kas);
+ dumphdr->dump_nvtop += dump_plat_addr();
/*
* call into hat, which may have unmapped pages that also need to
@@ -704,6 +704,7 @@ dumpsys(void)
ASSERT(pfn != PFN_INVALID);
dumpvp_write(&pfn, sizeof (pfn_t));
}
+ dump_plat_pfn();
/*
* Write out all the pages.
@@ -741,6 +742,7 @@ dumpsys(void)
delay(1); /* let the output be sent */
}
}
+ dumphdr->dump_npages += dump_plat_data(dump_cbuf);
(void) dumpvp_flush();
diff --git a/usr/src/uts/common/os/fork.c b/usr/src/uts/common/os/fork.c
index 177c28316b..76c11663fd 100644
--- a/usr/src/uts/common/os/fork.c
+++ b/usr/src/uts/common/os/fork.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -687,15 +687,15 @@ fork_fail(proc_t *cp)
kmem_free(fip->fi_list, fip->fi_nfiles * sizeof (uf_entry_t));
- VN_RELE(u.u_cdir);
- if (u.u_rdir)
- VN_RELE(u.u_rdir);
+ VN_RELE(PTOU(curproc)->u_cdir);
+ if (PTOU(curproc)->u_rdir)
+ VN_RELE(PTOU(curproc)->u_rdir);
if (cp->p_exec)
VN_RELE(cp->p_exec);
if (cp->p_execdir)
VN_RELE(cp->p_execdir);
- if (u.u_cwd)
- refstr_rele(u.u_cwd);
+ if (PTOU(curproc)->u_cwd)
+ refstr_rele(PTOU(curproc)->u_cwd);
}
/*
@@ -1086,17 +1086,17 @@ getproc(proc_t **cpp, int kernel)
*/
fcnt_add(P_FINFO(pp), 1);
- VN_HOLD(u.u_cdir);
- if (u.u_rdir)
- VN_HOLD(u.u_rdir);
- if (u.u_cwd)
- refstr_hold(u.u_cwd);
+ VN_HOLD(PTOU(pp)->u_cdir);
+ if (PTOU(pp)->u_rdir)
+ VN_HOLD(PTOU(pp)->u_rdir);
+ if (PTOU(pp)->u_cwd)
+ refstr_hold(PTOU(pp)->u_cwd);
/*
* copy the parent's uarea.
*/
uarea = PTOU(cp);
- bcopy(PTOU(pp), uarea, sizeof (user_t));
+ bcopy(PTOU(pp), uarea, sizeof (*uarea));
flist_fork(P_FINFO(pp), P_FINFO(cp));
gethrestime(&uarea->u_start);
diff --git a/usr/src/uts/common/os/grow.c b/usr/src/uts/common/os/grow.c
index 115a1312fa..e463b97004 100644
--- a/usr/src/uts/common/os/grow.c
+++ b/usr/src/uts/common/os/grow.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -480,7 +480,7 @@ grow_internal(caddr_t sp, uint_t growszc)
segvn_create, &crargs)) != 0) {
if (error == EAGAIN) {
cmn_err(CE_WARN, "Sorry, no swap space to grow stack "
- "for pid %d (%s)", p->p_pid, u.u_comm);
+ "for pid %d (%s)", p->p_pid, PTOU(p)->u_comm);
}
return (error);
}
diff --git a/usr/src/uts/common/os/kdi.c b/usr/src/uts/common/os/kdi.c
index ef548e38d0..20eed5a16f 100644
--- a/usr/src/uts/common/os/kdi.c
+++ b/usr/src/uts/common/os/kdi.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,30 +38,6 @@ struct modctl *kdi_dmods;
static kdi_dtrace_state_t kdi_dtrace_state = KDI_DTSTATE_IDLE;
void
-kdi_dvec_enter(void)
-{
- kdi_dvec->dv_enter();
-}
-
-/*
- * Called on the CPU being initialized
- */
-void
-kdi_dvec_cpu_init(struct cpu *cp)
-{
- kdi_dvec->dv_kctl_cpu_init();
- kdi_dvec->dv_cpu_init(cp);
-}
-
-#if defined(__i386) || defined(__amd64)
-void
-kdi_dvec_idt_sync(gate_desc_t *idt)
-{
- kdi_dvec->dv_idt_sync(idt);
-}
-#endif /* __i386 || __amd64 */
-
-void
kdi_dvec_vmready(void)
{
kdi_dvec->dv_kctl_vmready();
@@ -79,7 +54,25 @@ kdi_dvec_memavail(void)
kdi_dvec->dv_kctl_memavail();
}
+#if defined(__x86)
+void
+kdi_dvec_handle_fault(greg_t trapno, greg_t pc, greg_t sp, int cpuid)
+{
+ kdi_dvec->dv_handle_fault(trapno, pc, sp, cpuid);
+}
+#endif
+
#if defined(__sparc)
+/*
+ * Called on the CPU being initialized
+ */
+void
+kdi_dvec_cpu_init(struct cpu *cp)
+{
+ kdi_dvec->dv_kctl_cpu_init();
+ kdi_dvec->dv_cpu_init(cp);
+}
+
void
kdi_dvec_cpr_restart(void)
{
diff --git a/usr/src/uts/common/os/main.c b/usr/src/uts/common/os/main.c
index 1f4fbbf877..85882b45c6 100644
--- a/usr/src/uts/common/os/main.c
+++ b/usr/src/uts/common/os/main.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -394,6 +394,15 @@ main(void)
clock_init();
/*
+ * On some platforms, clkinitf() changes the timing source that
+ * gethrtime_unscaled() uses to generate timestamps. cbe_init() calls
+ * clkinitf(), so re-initialize the microstate counters after the
+ * timesource has been chosen.
+ */
+ init_mstate(&t0, LMS_SYSTEM);
+ init_cpu_mstate(CPU, CMS_SYSTEM);
+
+ /*
* May need to probe to determine latencies from CPU 0 after
* gethrtime() comes alive in cbe_init() and before enabling interrupts
*/
@@ -447,8 +456,8 @@ main(void)
if (netboot == 0)
(void) strplumb();
- gethrestime(&u.u_start);
- curthread->t_start = u.u_start.tv_sec;
+ gethrestime(&PTOU(curproc)->u_start);
+ curthread->t_start = PTOU(curproc)->u_start.tv_sec;
p->p_mstart = gethrtime();
/*
@@ -577,8 +586,8 @@ main(void)
pid_setmin();
- bcopy("sched", u.u_psargs, 6);
- bcopy("sched", u.u_comm, 5);
+ bcopy("sched", PTOU(curproc)->u_psargs, 6);
+ bcopy("sched", PTOU(curproc)->u_comm, 5);
sched();
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/os/mem_config.c b/usr/src/uts/common/os/mem_config.c
index 8d8b978513..64bbc4b5ad 100644
--- a/usr/src/uts/common/os/mem_config.c
+++ b/usr/src/uts/common/os/mem_config.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -59,11 +59,6 @@
#include <sys/ddi.h>
#include <sys/modctl.h>
-extern void memlist_read_lock(void);
-extern void memlist_read_unlock(void);
-extern void memlist_write_lock(void);
-extern void memlist_write_unlock(void);
-
extern struct memlist *phys_avail;
extern void mem_node_add(pfn_t, pfn_t);
@@ -3128,60 +3123,6 @@ kphysm_split_memseg(
}
/*
- * The memsegs lock is only taken when modifying the memsegs list
- * and rebuilding the pfn hash table (after boot).
- * No lock is needed for read as memseg structure are never de-allocated
- * and the pointer linkage is never updated until the memseg is ready.
- */
-krwlock_t memsegslock;
-
-void
-memsegs_lock(int writer)
-{
- rw_enter(&memsegslock, writer ? RW_WRITER : RW_READER);
-}
-
-/*ARGSUSED*/
-void
-memsegs_unlock(int writer)
-{
- rw_exit(&memsegslock);
-}
-
-/*
- * memlist (phys_install, phys_avail) locking.
- */
-
-/*
- * A read/write lock might be better here.
- */
-static kmutex_t memlists_mutex;
-
-void
-memlist_read_lock()
-{
- mutex_enter(&memlists_mutex);
-}
-
-void
-memlist_read_unlock()
-{
- mutex_exit(&memlists_mutex);
-}
-
-void
-memlist_write_lock()
-{
- mutex_enter(&memlists_mutex);
-}
-
-void
-memlist_write_unlock()
-{
- mutex_exit(&memlists_mutex);
-}
-
-/*
* The sfmmu hat layer (e.g.) accesses some parts of the memseg
* structure using physical addresses. Therefore a kmem_cache is
* used with KMC_NOHASH to avoid page crossings within a memseg
diff --git a/usr/src/uts/common/os/mem_config_stubs.c b/usr/src/uts/common/os/mem_config_stubs.c
index 7129b4e62b..d3226ff633 100644
--- a/usr/src/uts/common/os/mem_config_stubs.c
+++ b/usr/src/uts/common/os/mem_config_stubs.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -65,18 +64,6 @@ kcage_create_throttle(pgcnt_t npages, int flags)
return (0);
}
-/*ARGSUSED*/
-void
-memsegs_lock(int x)
-{
-}
-
-/*ARGSUSED*/
-void
-memsegs_unlock(int x)
-{
-}
-
void
kcage_cageout_init(void)
{
@@ -86,15 +73,6 @@ void
kcage_cageout_wakeup()
{
}
-void
-memlist_read_lock()
-{
-}
-
-void
-memlist_read_unlock()
-{
-}
void
kcage_tick()
diff --git a/usr/src/uts/common/os/policy.c b/usr/src/uts/common/os/policy.c
index 59795156bf..8ea071b09b 100644
--- a/usr/src/uts/common/os/policy.c
+++ b/usr/src/uts/common/os/policy.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -342,7 +342,7 @@ priv_policy(const cred_t *cr, int priv, boolean_t allzone, int err,
if ((allzone || priv == PRIV_ALL ||
!PRIV_ISASSERT(priv_basic, priv)) &&
!servicing_interrupt()) {
- u.u_acflag |= ASU; /* Needed for SVVS */
+ PTOU(curproc)->u_acflag |= ASU; /* Needed for SVVS */
#ifdef C2_AUDIT
if (audit_active)
audit_priv(priv,
diff --git a/usr/src/uts/common/os/shm.c b/usr/src/uts/common/os/shm.c
index 49da2f5757..687759018f 100644
--- a/usr/src/uts/common/os/shm.c
+++ b/usr/src/uts/common/os/shm.c
@@ -317,18 +317,11 @@ shmat(int shmid, caddr_t uaddr, int uflags, uintptr_t *rvp)
/*
* Handle ISM
*/
- uint_t n, share_szc;
+ uint_t share_szc;
size_t share_size;
struct shm_data ssd;
uintptr_t align_hint;
- n = page_num_pagesizes();
- if (n < 2) { /* large pages aren't supported */
- as_rangeunlock(as);
- error = EINVAL;
- goto errret;
- }
-
/*
* Pick a share pagesize to use, if (!isspt(sp)).
* Otherwise use the already chosen page size.
@@ -357,15 +350,22 @@ shmat(int shmid, caddr_t uaddr, int uflags, uintptr_t *rvp)
align_hint = share_size;
#if defined(__i386) || defined(__amd64)
/*
- * For 64 bit amd64, we want to share an entire page table
- * if possible. We know (ugh) that there are 512 entries in
- * in a page table. The number for 32 bit non-PAE should be
- * 1024, but I'm not going to special case that. Note using 512
- * won't cause a failure below. It retries with align_hint set
- * to share_size
+ * For x86, we want to share as much of the page table tree
+ * as possible. We use a large align_hint at first, but
+ * if that fails, then the code below retries with align_hint
+ * set to share_size.
+ *
+ * The explicit extern here is due to the difficulties
+ * of getting to platform dependent includes. When/if the
+ * platform dependent bits of this function are cleaned up,
+ * another way of doing this should found.
*/
- while (size >= 512 * (uint64_t)align_hint)
- align_hint *= 512;
+ {
+ extern uint_t ptes_per_table;
+
+ while (size >= ptes_per_table * (uint64_t)align_hint)
+ align_hint *= ptes_per_table;
+ }
#endif /* __i386 || __amd64 */
#if defined(__sparcv9)
diff --git a/usr/src/uts/common/os/sig.c b/usr/src/uts/common/os/sig.c
index 8d46a3405f..808e5d2095 100644
--- a/usr/src/uts/common/os/sig.c
+++ b/usr/src/uts/common/os/sig.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -346,7 +346,8 @@ isjobstop(int sig)
ASSERT(MUTEX_HELD(&p->p_lock));
- if (u.u_signal[sig-1] == SIG_DFL && sigismember(&stopdefault, sig)) {
+ if (PTOU(curproc)->u_signal[sig-1] == SIG_DFL &&
+ sigismember(&stopdefault, sig)) {
/*
* If SIGCONT has been posted since we promoted this signal
* from pending to current, then don't do a jobcontrol stop.
@@ -476,7 +477,7 @@ issig_justlooking(void)
* the process when lwp_nostop is set.
*/
if (!lwp->lwp_nostop ||
- u.u_signal[sig-1] != SIG_DFL ||
+ PTOU(curproc)->u_signal[sig-1] != SIG_DFL ||
!sigismember(&stopdefault, sig))
return (1);
}
@@ -768,7 +769,8 @@ issig_forreal(void)
* signal() interface for setting the signal handler.
*/
if (sigcld_found &&
- (sig != SIGCLD || !sigismember(&u.u_sigresethand, SIGCLD)))
+ (sig != SIGCLD || !sigismember(&PTOU(curproc)->u_sigresethand,
+ SIGCLD)))
sigcld_repost();
if (sig != 0)
@@ -1295,7 +1297,7 @@ psig(void)
mutex_exit(&p->p_lock);
return;
}
- func = u.u_signal[sig-1];
+ func = PTOU(curproc)->u_signal[sig-1];
/*
* The signal disposition could have changed since we promoted
@@ -1386,10 +1388,10 @@ psig(void)
t->t_flag &= ~T_TOMASK;
else
lwp->lwp_sigoldmask = t->t_hold;
- sigorset(&t->t_hold, &u.u_sigmask[sig-1]);
- if (!sigismember(&u.u_signodefer, sig))
+ sigorset(&t->t_hold, &PTOU(curproc)->u_sigmask[sig-1]);
+ if (!sigismember(&PTOU(curproc)->u_signodefer, sig))
sigaddset(&t->t_hold, sig);
- if (sigismember(&u.u_sigresethand, sig))
+ if (sigismember(&PTOU(curproc)->u_sigresethand, sig))
setsigact(sig, SIG_DFL, nullsmask, 0);
DTRACE_PROC3(signal__handle, int, sig, k_siginfo_t *,
@@ -1526,7 +1528,7 @@ setsigact(int sig, void (*disp)(), k_sigset_t mask, int flags)
ASSERT(MUTEX_HELD(&p->p_lock));
- u.u_signal[sig - 1] = disp;
+ PTOU(curproc)->u_signal[sig - 1] = disp;
/*
* Honor the SA_SIGINFO flag if the signal is being caught.
@@ -1542,25 +1544,25 @@ setsigact(int sig, void (*disp)(), k_sigset_t mask, int flags)
if (disp != SIG_DFL && disp != SIG_IGN) {
sigdelset(&p->p_ignore, sig);
- u.u_sigmask[sig - 1] = mask;
+ PTOU(curproc)->u_sigmask[sig - 1] = mask;
if (!sigismember(&cantreset, sig)) {
if (flags & SA_RESETHAND)
- sigaddset(&u.u_sigresethand, sig);
+ sigaddset(&PTOU(curproc)->u_sigresethand, sig);
else
- sigdelset(&u.u_sigresethand, sig);
+ sigdelset(&PTOU(curproc)->u_sigresethand, sig);
}
if (flags & SA_NODEFER)
- sigaddset(&u.u_signodefer, sig);
+ sigaddset(&PTOU(curproc)->u_signodefer, sig);
else
- sigdelset(&u.u_signodefer, sig);
+ sigdelset(&PTOU(curproc)->u_signodefer, sig);
if (flags & SA_RESTART)
- sigaddset(&u.u_sigrestart, sig);
+ sigaddset(&PTOU(curproc)->u_sigrestart, sig);
else
- sigdelset(&u.u_sigrestart, sig);
+ sigdelset(&PTOU(curproc)->u_sigrestart, sig);
if (flags & SA_ONSTACK)
- sigaddset(&u.u_sigonstack, sig);
+ sigaddset(&PTOU(curproc)->u_sigonstack, sig);
else
- sigdelset(&u.u_sigonstack, sig);
+ sigdelset(&PTOU(curproc)->u_sigonstack, sig);
} else if (disp == SIG_IGN ||
(disp == SIG_DFL && sigismember(&ignoredefault, sig))) {
diff --git a/usr/src/uts/common/os/vm_pageout.c b/usr/src/uts/common/os/vm_pageout.c
index 53676cbaeb..6a514e0174 100644
--- a/usr/src/uts/common/os/vm_pageout.c
+++ b/usr/src/uts/common/os/vm_pageout.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -652,8 +652,8 @@ pageout()
proc_pageout->p_stime = 0;
proc_pageout->p_cutime = 0;
proc_pageout->p_utime = 0;
- bcopy("pageout", u.u_psargs, 8);
- bcopy("pageout", u.u_comm, 7);
+ bcopy("pageout", PTOU(curproc)->u_psargs, 8);
+ bcopy("pageout", PTOU(curproc)->u_comm, 7);
/*
* Create pageout scanner thread
diff --git a/usr/src/uts/common/os/zone.c b/usr/src/uts/common/os/zone.c
index 19ea8b31f1..da658c8a48 100644
--- a/usr/src/uts/common/os/zone.c
+++ b/usr/src/uts/common/os/zone.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2661,11 +2661,11 @@ zsched(void *arg)
nvlist_t *nvl = za->nvlist;
nvpair_t *nvp = NULL;
- bcopy("zsched", u.u_psargs, sizeof ("zsched"));
- bcopy("zsched", u.u_comm, sizeof ("zsched"));
- u.u_argc = 0;
- u.u_argv = NULL;
- u.u_envp = NULL;
+ bcopy("zsched", PTOU(pp)->u_psargs, sizeof ("zsched"));
+ bcopy("zsched", PTOU(pp)->u_comm, sizeof ("zsched"));
+ PTOU(pp)->u_argc = 0;
+ PTOU(pp)->u_argv = NULL;
+ PTOU(pp)->u_envp = NULL;
closeall(P_FINFO(pp));
/*
diff --git a/usr/src/uts/common/sys/auxv_386.h b/usr/src/uts/common/sys/auxv_386.h
index 85d4dc5f86..88fe720e8c 100644
--- a/usr/src/uts/common/sys/auxv_386.h
+++ b/usr/src/uts/common/sys/auxv_386.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -60,10 +59,12 @@ extern "C" {
#define AV_386_SSE3 0x04000 /* SSE3 insns and regs */
#define AV_386_MON 0x08000 /* monitor/mwait insns */
#define AV_386_CX16 0x10000 /* cmpxchg16b insn */
+#define AV_386_AHF 0x20000 /* lahf/sahf insns */
+#define AV_386_TSCP 0x40000 /* rdtscp instruction */
#define FMT_AV_386 \
"\20" \
- "\21cx16" \
+ "\23tscp\22ahf\21cx16" \
"\20mon\17sse3\16pause\15sse2\14sse\13fxsr\12amd3dx\11amd3d" \
"\10amdmmx\7mmx\6cmov\5amdsysc\4sep\3cx8\2tsc\1fpu"
diff --git a/usr/src/uts/common/sys/bootprops.h b/usr/src/uts/common/sys/bootprops.h
index 2f7360ec52..f337777172 100644
--- a/usr/src/uts/common/sys/bootprops.h
+++ b/usr/src/uts/common/sys/bootprops.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -47,6 +46,7 @@ extern "C" {
#define BP_SERVER_PATH "server-path"
#define BP_SERVER_ROOTOPTS "server-rootopts"
#define BP_BOOTP_RESPONSE "bootp-response"
+#define BP_NETWORK_INTERFACE "network-interface"
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/sys/cpr.h b/usr/src/uts/common/sys/cpr.h
index bfdd868e14..337cbf9986 100644
--- a/usr/src/uts/common/sys/cpr.h
+++ b/usr/src/uts/common/sys/cpr.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,6 +37,7 @@ extern "C" {
#include <sys/mutex.h>
#include <sys/uadmin.h>
#include <sys/compress.h>
+#include <sys/archsystm.h>
/*
* definitions for kernel, cprboot, pmconfig
@@ -178,36 +178,27 @@ struct cprconfig {
extern int cpr_debug;
-#define errp prom_printf
-#define DPRINT
-
/*
- * DEBUG1 displays the main flow of CPR. Use it to identify which sub-module
- * of CPR causes problems.
- * DEBUG2 displays minor stuff that normally won't matter.
- * DEBUG3 displays some big loops (cpr_dump); requires much longer runtime.
- * DEBUG4 displays lots of cprboot output, cpr_read and page handling.
- * DEBUG5 various, mostly unique stuff
- * DEBUG9 displays statistical data for CPR on console (by using printf),
+ * CPR_DEBUG1 displays the main flow of CPR. Use it to identify which
+ * sub-module of CPR causes problems.
+ * CPR_DEBUG2 displays minor stuff that normally won't matter.
+ * CPR_DEBUG3 displays some big loops (cpr_dump); requires much longer runtime.
+ * CPR_DEBUG4 displays lots of cprboot output, cpr_read and page handling.
+ * CPR_DEBUG5 various, mostly unique stuff
+ * CPR_DEBUG9 displays statistical data for CPR on console (by using printf),
* such as num page invalidated, etc.
*/
-#define LEVEL1 0x1
-#define LEVEL2 0x2
-#define LEVEL3 0x4
-#define LEVEL4 0x8
-#define LEVEL5 0x10
-#define LEVEL6 0x20
-#define LEVEL7 0x40
-#define LEVEL8 0x80
-
-#define DEBUG1(p) {if (cpr_debug & LEVEL1) p; }
-#define DEBUG2(p) {if (cpr_debug & LEVEL2) p; }
-#define DEBUG3(p) {if (cpr_debug & LEVEL3) p; }
-#define DEBUG4(p) {if (cpr_debug & LEVEL4) p; }
-#define DEBUG5(p) {if (cpr_debug & LEVEL5) p; }
-#define DEBUG7(p) {if (cpr_debug & LEVEL7) p; }
-#define DEBUG8(p) {if (cpr_debug & LEVEL8) p; }
-#define DEBUG9(p) {if (cpr_debug & LEVEL6) p; }
+#define CPR_DEBUG1 0x1
+#define CPR_DEBUG2 0x2
+#define CPR_DEBUG3 0x4
+#define CPR_DEBUG4 0x8
+#define CPR_DEBUG5 0x10
+#define CPR_DEBUG6 0x20
+#define CPR_DEBUG7 0x40
+#define CPR_DEBUG8 0x80
+#define CPR_DEBUG9 CPR_DEBUG6
+
+#define CPR_DEBUG(level, ...) if (cpr_debug & level) cpr_dprintf(__VA_ARGS__)
#define CPR_DEBUG_BIT(dval) (1 << (dval - AD_CPR_DEBUG0 - 1))
#define DBG_DONTSHOWRANGE 0
diff --git a/usr/src/uts/common/sys/cpuvar.h b/usr/src/uts/common/sys/cpuvar.h
index 1e467e4b64..0af0d086a9 100644
--- a/usr/src/uts/common/sys/cpuvar.h
+++ b/usr/src/uts/common/sys/cpuvar.h
@@ -301,6 +301,10 @@ extern cpu_core_t cpu_core[];
#define CPU_SPARE 0x100 /* CPU offline available for use */
#define CPU_FAULTED 0x200 /* CPU offline diagnosed faulty */
+#define FMT_CPU_FLAGS \
+ "\20\12fault\11spare\10frozen" \
+ "\7poweroff\6offline\5enable\4exist\3quiesced\2ready\1run"
+
#define CPU_ACTIVE(cpu) (((cpu)->cpu_flags & CPU_OFFLINE) == 0)
/*
@@ -575,6 +579,17 @@ void mbox_lock_init(void); /* initialize cross-call locks */
void mbox_init(int cpun); /* initialize cross-calls */
void poke_cpu(int cpun); /* interrupt another CPU (to preempt) */
+/*
+ * values for safe_list. Pause state that CPUs are in.
+ */
+#define PAUSE_IDLE 0 /* normal state */
+#define PAUSE_READY 1 /* paused thread ready to spl */
+#define PAUSE_WAIT 2 /* paused thread is spl-ed high */
+#define PAUSE_DIE 3 /* tell pause thread to leave */
+#define PAUSE_DEAD 4 /* pause thread has left */
+
+void mach_cpu_pause(volatile char *);
+
void pause_cpus(cpu_t *off_cp);
void start_cpus(void);
int cpus_paused(void);
diff --git a/usr/src/uts/common/sys/dtrace.h b/usr/src/uts/common/sys/dtrace.h
index d53b88ab82..1c76417830 100644
--- a/usr/src/uts/common/sys/dtrace.h
+++ b/usr/src/uts/common/sys/dtrace.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2196,6 +2196,8 @@ extern void dtrace_panic(const char *, ...);
extern int dtrace_safe_defer_signal(void);
extern void dtrace_safe_synchronous_signal(void);
+extern int dtrace_mach_aframes(void);
+
#if defined(__i386) || defined(__amd64)
extern int dtrace_instr_size(uchar_t *instr);
extern int dtrace_instr_size_isa(uchar_t *, model_t, int *);
diff --git a/usr/src/uts/common/sys/dumphdr.h b/usr/src/uts/common/sys/dumphdr.h
index 5949b218c8..dc450713de 100644
--- a/usr/src/uts/common/sys/dumphdr.h
+++ b/usr/src/uts/common/sys/dumphdr.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -134,6 +133,9 @@ extern void dumpsys(void);
extern void dump_messages(void);
extern void dump_ereports(void);
extern void dumpvp_write(const void *, size_t);
+extern int dump_plat_addr(void);
+extern void dump_plat_pfn(void);
+extern int dump_plat_data(void *);
#endif /* _KERNEL */
diff --git a/usr/src/uts/common/sys/filep.h b/usr/src/uts/common/sys/filep.h
index d68fab846b..0cd2b0734e 100644
--- a/usr/src/uts/common/sys/filep.h
+++ b/usr/src/uts/common/sys/filep.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -58,6 +57,9 @@ typedef struct dev_ident { /* device identifier block */
#define FI_PARTIAL_CACHE 0x200000
#define FI_NOCACHE 0x400000
+#define FI_COMPRESSED 0x8 /* File compressed in ramdisk */
+#define DECOMP_BUFSIZE (512 * 1024) /* size of decompress buffer */
+
typedef struct file_ident { /* file identifier block */
uint_t fi_filedes;
char *fi_path;
@@ -69,9 +71,14 @@ typedef struct file_ident { /* file identifier block */
char fi_flags;
devid_t *fi_devp;
char fi_buf[MAXBSIZE];
+ int (*fi_getblock)(struct file_ident *);
struct inode *fi_inode;
struct file_ident *fi_forw;
struct file_ident *fi_back;
+ off_t fi_cfoff; /* compressed file offset */
+ caddr_t fi_dcscrbuf; /* decomp scratch buffer */
+ size_t fi_dcscrused; /* used bytes in scratch buf */
+ struct z_stream_s *fi_dcstream; /* decompression stream */
} fileid_t;
extern int diskread(fileid_t *);
diff --git a/usr/src/uts/common/sys/hold_page.h b/usr/src/uts/common/sys/hold_page.h
new file mode 100644
index 0000000000..0f73e22646
--- /dev/null
+++ b/usr/src/uts/common/sys/hold_page.h
@@ -0,0 +1,76 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_HOLD_PAGE_H
+#define _SYS_HOLD_PAGE_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <vm/page.h>
+
+/*
+ * swrand generates entropy by mapping different pages in the system. This
+ * can create problems for some hypervisors, as certain pages may be removed
+ * from the system at any time. The following interfaces allow swrand to
+ * check the validity and make sure a page is not given away while it is mapped.
+ *
+ * int plat_hold_page(pfn_t pfn, int lock, page_t **pp_ret)
+ *
+ * If lock is PLAT_HOLD_NO_LOCK, simply check if the page pfn is valid
+ * in the system. If the page is valid, PLAT_HOLD_OK will be returned.
+ * pp_ret is ignored if lock is PLAT_HOLD_NO_LOCK.
+ *
+ * If lock is PLAT_HOLD_LOCK, in addition to the above, attempt to lock
+ * the page exclusively. Again, if the lock is successful, the page
+ * pointer will be put in pp, and PLAT_HOLD_OK will be returned. pp_ret
+ * must be passed to a later call to plat_release_page. If the page
+ * wasn't found, or the lock couldn't be grabbed, the return value will
+ * be PLAT_HOLD_FAIL.
+ *
+ * void plat_release_page(page_t *pp)
+ *
+ * Unlock the page pp. Should only be called after a previous,
+ * successful call to plat_release_page(pfn, PLAT_HOLD_LOCK, &pp);
+ */
+
+#define PLAT_HOLD_NO_LOCK 0
+#define PLAT_HOLD_LOCK 1
+
+#define PLAT_HOLD_OK 0
+#define PLAT_HOLD_FAIL 1
+
+extern int plat_hold_page(pfn_t, int, page_t **);
+extern void plat_release_page(page_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_HOLD_PAGE_H */
diff --git a/usr/src/uts/common/sys/isa_defs.h b/usr/src/uts/common/sys/isa_defs.h
index b045eb02d8..08fcbd02e5 100644
--- a/usr/src/uts/common/sys/isa_defs.h
+++ b/usr/src/uts/common/sys/isa_defs.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -201,6 +201,11 @@
* _RTC_CONFIG
* This indicates whether or not the implementation uses /etc/rtc_config
* to configure the real-time clock in the kernel.
+ *
+ * _UNIX_KRTLD
+ * This indicates that the implementation uses a dynamically
+ * linked unix + krtld to form the core kernel image at boot
+ * time, or (in the absence of this symbol) a prelinked kernel image.
*/
#ifdef __cplusplus
@@ -397,6 +402,7 @@ extern "C" {
#define _DMA_USES_VIRTADDR
#define _NO_FDISK_PRESENT
#define _HAVE_TEM_FIRMWARE
+#define _UNIX_KRTLD
/*
* The following set of definitions characterize the implementation of
diff --git a/usr/src/uts/common/sys/kdi.h b/usr/src/uts/common/sys/kdi.h
index 64f2b7b7cf..6959aef7d2 100644
--- a/usr/src/uts/common/sys/kdi.h
+++ b/usr/src/uts/common/sys/kdi.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,6 +28,8 @@
#pragma ident "%Z%%M% %I% %E% SMI"
+#include <sys/types.h>
+
/*
* The Kernel/Debugger interface.
*
@@ -45,17 +46,11 @@
extern "C" {
#endif
-/* The VA range reserved for the debugger. */
-#if defined(__sparc)
-#define SEGDEBUGBASE 0xedd00000
-#define SEGDEBUGSIZE (0xf0000000 - SEGDEBUGBASE)
-#elif defined(__amd64)
-#define SEGDEBUGBASE 0xffffffffff800000
-#define SEGDEBUGSIZE 0x400000
-#else
-#define SEGDEBUGBASE 0xff800000
-#define SEGDEBUGSIZE 0x400000
-#endif
+/*
+ * The VA range reserved for the debugger; used by kmdb.
+ */
+extern const caddr_t kdi_segdebugbase;
+extern const size_t kdi_segdebugsize;
struct cpu;
struct modctl;
@@ -68,16 +63,12 @@ typedef struct kdi kdi_t;
extern kdi_debugvec_t *kdi_dvec;
extern struct modctl *kdi_dmods;
-#define KDI_VERSION 6
+#define KDI_VERSION 7
-extern void kdi_dvec_enter(void);
-extern void kdi_dvec_cpu_init(struct cpu *);
-#if defined(__i386) || defined(__amd64)
-extern void kdi_dvec_idt_sync(struct gate_desc *);
-#endif /* __i386 || __amd64 */
extern void kdi_dvec_vmready(void);
extern void kdi_dvec_memavail(void);
#if defined(__sparc)
+extern void kdi_dvec_cpu_init(struct cpu *);
extern void kdi_dvec_cpr_restart(void);
#endif
extern void kdi_dvec_modavail(void);
diff --git a/usr/src/uts/common/sys/kdi_impl.h b/usr/src/uts/common/sys/kdi_impl.h
index ce605c1815..e488ae6b14 100644
--- a/usr/src/uts/common/sys/kdi_impl.h
+++ b/usr/src/uts/common/sys/kdi_impl.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,6 +30,7 @@
#include <sys/kdi.h>
#include <sys/kdi_machimpl.h>
+#include <sys/privregs.h>
#ifdef __cplusplus
extern "C" {
@@ -43,29 +43,24 @@ struct gdscr;
* The debugvec is used by the kernel to interact with the debugger.
*/
struct kdi_debugvec {
- void (*dv_enter)(void);
-
- void (*dv_cpu_init)(struct cpu *);
- void (*dv_kctl_cpu_init)(void);
-
-#if defined(__i386) || defined(__amd64)
- void (*dv_idt_sync)(gate_desc_t *);
-#endif /* __i386 || __amd64 */
-
- void (*dv_vmready)(void);
void (*dv_kctl_vmready)(void);
-
void (*dv_kctl_memavail)(void);
- int (*dv_memavail)(caddr_t, size_t);
-
-#if defined(__sparc)
- void (*dv_cpr_restart)(void);
-#endif
-
void (*dv_kctl_modavail)(void);
void (*dv_kctl_thravail)(void);
+
+ void (*dv_vmready)(void);
+ void (*dv_memavail)(caddr_t, size_t);
void (*dv_mod_loaded)(struct modctl *);
void (*dv_mod_unloading)(struct modctl *);
+
+#if defined(__i386) || defined(__amd64)
+ void (*dv_handle_fault)(greg_t, greg_t, greg_t, int);
+#endif
+#if defined(__sparc)
+ void (*dv_kctl_cpu_init)(void);
+ void (*dv_cpu_init)(struct cpu *);
+ void (*dv_cpr_restart)(void);
+#endif
};
typedef struct kdi_plat {
@@ -88,6 +83,7 @@ typedef struct kdi_plat {
* have been stopped. In such an environment, blocking services such as memory
* allocation or synchronization primitives are not available.
*/
+
struct kdi {
int kdi_version;
@@ -139,6 +135,8 @@ struct kdi {
void (*kdi_plat_call)(void (*)(void));
+ void (*kdi_kmdb_enter)(void);
+
kdi_mach_t kdi_mach;
kdi_plat_t kdi_plat;
};
@@ -155,6 +153,9 @@ extern void cpu_kdi_init(kdi_t *);
extern void mach_kdi_init(kdi_t *);
extern void plat_kdi_init(kdi_t *);
+extern void *boot_kdi_tmpinit(void);
+extern void boot_kdi_tmpfini(void *);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/sys/mem.h b/usr/src/uts/common/sys/mem.h
index d1307589a1..31cf613939 100644
--- a/usr/src/uts/common/sys/mem.h
+++ b/usr/src/uts/common/sys/mem.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +33,7 @@ extern "C" {
#endif
#include <sys/types.h>
+#include <sys/uio.h>
/*
* Memory Device Minor Numbers
@@ -142,6 +142,8 @@ typedef struct mem_info {
extern pfn_t impl_obmem_pfnum(pfn_t);
+extern int plat_mem_valid_page(uintptr_t, uio_rw_t);
+
#endif /* _KERNEL */
#ifdef __cplusplus
diff --git a/usr/src/uts/common/sys/mem_config.h b/usr/src/uts/common/sys/mem_config.h
index 151d5a4438..31ea4059d1 100644
--- a/usr/src/uts/common/sys/mem_config.h
+++ b/usr/src/uts/common/sys/mem_config.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1997-2001 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ifndef _SYS_MEM_CONFIG_H
@@ -144,9 +143,6 @@ extern int arch_kphysm_del_supported(void);
extern int pfn_is_being_deleted(pfn_t);
-extern void memsegs_lock(int);
-extern void memsegs_unlock(int);
-
#endif /* _KERNEL */
#ifdef __cplusplus
diff --git a/usr/src/uts/common/sys/memlist.h b/usr/src/uts/common/sys/memlist.h
index 10ad8237e6..371ecc522d 100644
--- a/usr/src/uts/common/sys/memlist.h
+++ b/usr/src/uts/common/sys/memlist.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1991-1998 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ifndef _SYS_MEMLIST_H
@@ -59,8 +58,6 @@ extern int address_in_memlist(struct memlist *, uint64_t, size_t);
* to protect reading this list.
*/
extern struct memlist *phys_install;
-extern void memlist_read_lock(void);
-extern void memlist_read_unlock(void);
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/sys/multiboot.h b/usr/src/uts/common/sys/multiboot.h
new file mode 100644
index 0000000000..1118aa9f53
--- /dev/null
+++ b/usr/src/uts/common/sys/multiboot.h
@@ -0,0 +1,174 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _MULTIBOOT_H
+#define _MULTIBOOT_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Definitions of structures/data for using a multiboot compliant OS loader.
+ */
+#define MB_HEADER_MAGIC 0x1BADB002 /* magic */
+#define MB_HEADER_FLAGS 0x00010003 /* flags we use */
+#define MB_HEADER_CHECKSUM -0x1BAEB005 /* -(magic + flag) */
+
+/*
+ * passed by boot loader to kernel
+ */
+#define MB_BOOTLOADER_MAGIC 0x2BADB002
+
+#ifndef _ASM /* excluded from assembly routines */
+
+#include <sys/types.h>
+#include <sys/types32.h>
+
+/*
+ * The Multiboot header must be somewhere in the 1st 8K of the image that
+ * the loader loads into memory.
+ */
+typedef struct multiboot_header {
+ uint32_t magic;
+ uint32_t flags;
+ uint32_t checksum;
+ caddr32_t header_addr; /* use as (mutliboot_header_t *) */
+ caddr32_t load_addr;
+ caddr32_t load_end_addr;
+ caddr32_t bss_end_addr;
+ caddr32_t entry_addr;
+} multiboot_header_t;
+
+/* The section header table for ELF. */
+typedef struct mb_elf_shtable {
+ uint32_t num;
+ uint32_t size;
+ uint32_t addr;
+ uint32_t shndx;
+} mb_elf_shtable_t;
+
+/* The module structure. */
+typedef struct mb_module {
+ caddr32_t mod_start;
+ caddr32_t mod_end;
+ caddr32_t mod_name; /* use as (char *) */
+ uint32_t reserved;
+} mb_module_t;
+
+/*
+ * Memory map data structure. Walked in a bizarre way - see mutltiboot
+ * documentation for example.
+ */
+typedef struct mb_memory_map {
+ uint32_t size;
+ uint32_t base_addr_low;
+ uint32_t base_addr_high;
+ uint32_t length_low;
+ uint32_t length_high;
+ uint32_t type; /* only value of 1 is RAM */
+} mb_memory_map_t;
+
+
+/*
+ * The Multiboot information. This is supplied by the multiboot loader
+ * for the OS.
+ *
+ * The flag bit fields defined what multiboot info the boot
+ * loader (see struct multiboot_info below) supplied:
+ * flag[0] mem_upper, mem_loader
+ * flag[1] boot_device
+ * flag[2] cmdline (for launching kernel)
+ * flag[3] mods_count, mods_addr
+ * flag[4] symbol table for a.out
+ * flag[5] symbol table for elf
+ * flag[6] mmap_length, mmap_addr
+ * flag[7] drives_length, drivers_addr
+ * flag[8] config_table
+ * flag[9] boot_loader_name
+ * flag[10] apm_table
+ * flag[11] vbe_control_info
+ * vbe_mode_info
+ * vbe_mode
+ * vbe_interface_seg
+ * vbe_interface_off
+ * vbe_interface_len
+ */
+typedef struct multiboot_info {
+ uint32_t flags;
+ uint32_t mem_lower; /* # of pages below 1Meg */
+ uint32_t mem_upper; /* # of pages above 1Meg */
+ uint32_t boot_device;
+ caddr32_t cmdline; /* use as (char *) */
+ uint32_t mods_count;
+ caddr32_t mods_addr; /* use as (mb_module_t *) */
+ mb_elf_shtable_t elf_sec;
+ uint32_t mmap_length;
+ caddr32_t mmap_addr; /* use as (mb_memory_map_t *) */
+ uint32_t drives_length;
+ caddr32_t drives_addr;
+ caddr32_t config_table;
+ caddr32_t boot_loader_name;
+ caddr32_t apm_table;
+ uint32_t vbe_control_info;
+ uint32_t vbe_mode_info;
+ uint16_t vbe_mode;
+ uint16_t vbe_interface_seg;
+ uint16_t vbe_interface_off;
+ uint16_t vbe_interface_len;
+} multiboot_info_t;
+
+/*
+ * netinfo for Solaris diskless booting
+ * XXX - not part of multiboot spec
+ */
+struct sol_netinfo {
+ uint8_t sn_infotype;
+ uint8_t sn_mactype;
+ uint8_t sn_maclen;
+ uint8_t sn_padding;
+ ulong_t sn_ciaddr;
+ ulong_t sn_siaddr;
+ ulong_t sn_giaddr;
+ ulong_t sn_netmask;
+ uint8_t sn_macaddr[1];
+};
+
+/* identify bootp/dhcp reply or rarp/ifconfig */
+#define SN_TYPE_BOOTP 2
+#define SN_TYPE_RARP 0xf0
+
+
+#endif /* _ASM */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MULTIBOOT_H */
diff --git a/usr/src/uts/common/sys/ontrap.h b/usr/src/uts/common/sys/ontrap.h
index 5b19af9d74..a7718848a1 100644
--- a/usr/src/uts/common/sys/ontrap.h
+++ b/usr/src/uts/common/sys/ontrap.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -87,6 +86,10 @@ extern "C" {
#define OT_DATA_ACCESS 0x01 /* data access exception protection */
#define OT_DATA_EC 0x02 /* error correction trap protection */
+#if defined(__x86)
+#define OT_SEGMENT_ACCESS 0x03 /* segmentation exception */
+#endif
+
#if !defined(_ASM)
typedef struct on_trap_data {
diff --git a/usr/src/uts/common/sys/param.h b/usr/src/uts/common/sys/param.h
index 4103fde786..cb7ab43c2f 100644
--- a/usr/src/uts/common/sys/param.h
+++ b/usr/src/uts/common/sys/param.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -420,6 +419,12 @@ extern const int _clsize;
#define dtopt(DD) ((DD) >> (PAGESHIFT - DEV_BSHIFT))
/*
+ * kB to pages and back
+ */
+#define kbtop(x) ((x) >> (PAGESHIFT - 10))
+#define ptokb(x) ((x) << (PAGESHIFT - 10))
+
+/*
* POSIX.4 related configuration parameters
*/
#define _AIO_LISTIO_MAX (4096)
diff --git a/usr/src/uts/common/sys/systm.h b/usr/src/uts/common/sys/systm.h
index ac465ad49f..5f1b4ee211 100644
--- a/usr/src/uts/common/sys/systm.h
+++ b/usr/src/uts/common/sys/systm.h
@@ -23,7 +23,7 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -168,64 +168,6 @@ dev_t expldev(dev32_t);
int bcmp(const void *, const void *, size_t) __PURE;
int stoi(char **);
void numtos(ulong_t, char *);
-size_t strlen(const char *) __PURE;
-char *strcat(char *, const char *);
-char *strncat(char *, const char *, size_t);
-char *strcpy(char *, const char *);
-char *strncpy(char *, const char *, size_t);
-/* Need to be consistent with <string.h> C++ definitions */
-#if __cplusplus >= 199711L
-extern const char *strchr(const char *, int);
-#ifndef _STRCHR_INLINE
-#define _STRCHR_INLINE
-extern "C++" {
- inline char *strchr(char *__s, int __c) {
- return (char *)strchr((const char *)__s, __c);
- }
-}
-#endif /* _STRCHR_INLINE */
-extern const char *strrchr(const char *, int);
-#ifndef _STRRCHR_INLINE
-#define _STRRCHR_INLINE
-extern "C++" {
- inline char *strrchr(char *__s, int __c) {
- return (char *)strrchr((const char *)__s, __c);
- }
-}
-#endif /* _STRRCHR_INLINE */
-extern const char *strstr(const char *, const char *);
-#ifndef _STRSTR_INLINE
-#define _STRSTR_INLINE
-extern "C++" {
- inline char *strstr(char *__s1, const char *__s2) {
- return (char *)strstr((const char *)__s1, __s2);
- }
-}
-#endif /* _STRSTR_INLINE */
-#else /* __cplusplus >= 199711L */
-char *strchr(const char *, int);
-char *strrchr(const char *, int);
-char *strstr(const char *, const char *);
-#endif /* __cplusplus >= 199711L */
-char *strnrchr(const char *, int, size_t);
-int strcmp(const char *, const char *) __PURE;
-int strncmp(const char *, const char *, size_t) __PURE;
-int strcasecmp(const char *, const char *) __PURE;
-int strncasecmp(const char *, const char *, size_t) __PURE;
-/* Need to be consistent with <string.h> C++ definitions */
-#if __cplusplus >= 199711L
-extern const char *strpbrk(const char *, const char *);
-#ifndef _STRPBRK_INLINE
-#define _STRPBRK_INLINE
-extern "C++" {
- inline char *strpbrk(char *__s1, const char *__s2) {
- return (char *)strpbrk((const char *)__s1, __s2);
- }
-}
-#endif /* _STRPBRK_INLINE */
-#else /* __cplusplus >= 199711L */
-char *strpbrk(const char *, const char *);
-#endif /* __cplusplus >= 199711L */
int strident_valid(const char *);
void strident_canon(char *, size_t);
int getsubopt(char **optionsp, char * const *tokens, char **valuep);
@@ -244,22 +186,15 @@ int copyinstr_noerr(const char *, char *, size_t, size_t *);
int copyoutstr(const char *, char *, size_t, size_t *);
int copyoutstr_noerr(const char *, char *, size_t, size_t *);
int copystr(const char *, char *, size_t, size_t *);
-void bcopy(const void *, void *, size_t);
void ucopy(const void *, void *, size_t);
void ucopystr(const char *, char *, size_t, size_t *);
void pgcopy(const void *, void *, size_t);
void ovbcopy(const void *, void *, size_t);
-void bzero(void *, size_t);
void uzero(void *, size_t);
int kcopy(const void *, void *, size_t);
int kcopy_nta(const void *, void *, size_t, int);
int kzero(void *, size_t);
-extern void *memset(void *, int, size_t);
-extern void *memcpy(void *, const void *, size_t);
-extern void *memmove(void *, const void *, size_t);
-extern int memcmp(const void *, const void *, size_t);
-
int fuword8(const void *, uint8_t *);
int fuword16(const void *, uint16_t *);
int fuword32(const void *, uint32_t *);
@@ -441,11 +376,6 @@ extern void swtch(void);
extern uint_t kcpc_key; /* TSD key for performance counter context */
-#ifdef __lint
-extern int __lintzero; /* for spoofing lint */
-#endif
-
-
/*
* initname holds the path to init and is used as a point of rendezvous
* between krtld (which processes the boot arguments) and the kernel.
@@ -465,6 +395,82 @@ extern int start_init_common(void);
#endif /* _KERNEL */
+#if defined(_KERNEL) || defined(_BOOT)
+
+size_t strlcat(char *, const char *, size_t);
+size_t strlen(const char *) __PURE;
+char *strcat(char *, const char *);
+char *strncat(char *, const char *, size_t);
+char *strcpy(char *, const char *);
+char *strncpy(char *, const char *, size_t);
+/* Need to be consistent with <string.h> C++ definitions */
+#if __cplusplus >= 199711L
+extern const char *strchr(const char *, int);
+#ifndef _STRCHR_INLINE
+#define _STRCHR_INLINE
+extern "C++" {
+ inline char *strchr(char *__s, int __c) {
+ return (char *)strchr((const char *)__s, __c);
+ }
+}
+#endif /* _STRCHR_INLINE */
+extern const char *strrchr(const char *, int);
+#ifndef _STRRCHR_INLINE
+#define _STRRCHR_INLINE
+extern "C++" {
+ inline char *strrchr(char *__s, int __c) {
+ return (char *)strrchr((const char *)__s, __c);
+ }
+}
+#endif /* _STRRCHR_INLINE */
+extern const char *strstr(const char *, const char *);
+#ifndef _STRSTR_INLINE
+#define _STRSTR_INLINE
+extern "C++" {
+ inline char *strstr(char *__s1, const char *__s2) {
+ return (char *)strstr((const char *)__s1, __s2);
+ }
+}
+#endif /* _STRSTR_INLINE */
+#else /* __cplusplus >= 199711L */
+char *strchr(const char *, int);
+char *strrchr(const char *, int);
+char *strstr(const char *, const char *);
+#endif /* __cplusplus >= 199711L */
+char *strnrchr(const char *, int, size_t);
+int strcmp(const char *, const char *) __PURE;
+int strncmp(const char *, const char *, size_t) __PURE;
+int strcasecmp(const char *, const char *) __PURE;
+int strncasecmp(const char *, const char *, size_t) __PURE;
+/* Need to be consistent with <string.h> C++ definitions */
+#if __cplusplus >= 199711L
+extern const char *strpbrk(const char *, const char *);
+#ifndef _STRPBRK_INLINE
+#define _STRPBRK_INLINE
+extern "C++" {
+ inline char *strpbrk(char *__s1, const char *__s2) {
+ return (char *)strpbrk((const char *)__s1, __s2);
+ }
+}
+#endif /* _STRPBRK_INLINE */
+#else /* __cplusplus >= 199711L */
+char *strpbrk(const char *, const char *);
+#endif /* __cplusplus >= 199711L */
+void bcopy(const void *, void *, size_t);
+void bzero(void *, size_t);
+
+extern void *memset(void *, int, size_t);
+extern void *memcpy(void *, const void *, size_t);
+extern void *memmove(void *, const void *, size_t);
+extern int memcmp(const void *, const void *, size_t);
+
+#ifdef __lint
+extern int __lintzero; /* for spoofing lint */
+#else /* __lint */
+#define __lintzero 0
+#endif /* __lint */
+#endif /* _KERNEL || _BOOT */
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/sys/time.h b/usr/src/uts/common/sys/time.h
index ab74c47d5f..ffc2c7dcfb 100644
--- a/usr/src/uts/common/sys/time.h
+++ b/usr/src/uts/common/sys/time.h
@@ -9,7 +9,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -411,7 +411,8 @@ int gettimeofday();
* non-X/Open applications, including this header will still make
* visible these definitions.
*/
-#if !defined(_KERNEL) && !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__)
+#if !defined(_BOOT) && !defined(_KERNEL) && \
+ !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__)
#include <time.h>
#endif
diff --git a/usr/src/uts/common/sys/types.h b/usr/src/uts/common/sys/types.h
index b38a5d1e13..ac5de5d5c0 100644
--- a/usr/src/uts/common/sys/types.h
+++ b/usr/src/uts/common/sys/types.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -24,7 +23,7 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -235,7 +234,7 @@ typedef longlong_t offset_t;
typedef u_longlong_t u_offset_t;
typedef u_longlong_t len_t;
typedef u_longlong_t diskaddr_t;
-#if (defined(_KERNEL) || defined(_KMEMUSER))
+#if (defined(_KERNEL) || defined(_KMEMUSER) || defined(_BOOT))
typedef uint64_t paddr_t;
#endif
diff --git a/usr/src/uts/common/sys/user.h b/usr/src/uts/common/sys/user.h
index 7d58d69e8c..9061fa5a23 100644
--- a/usr/src/uts/common/sys/user.h
+++ b/usr/src/uts/common/sys/user.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -246,7 +246,6 @@ typedef struct user {
#include <sys/proc.h> /* cannot include before user defined */
#ifdef _KERNEL
-#define u (curproc->p_user) /* user is now part of proc structure */
#define P_FINFO(p) (&(p)->p_user.u_finfo)
#endif /* _KERNEL */
diff --git a/usr/src/uts/common/syscall/mkdir.c b/usr/src/uts/common/syscall/mkdir.c
index fc9262b0a3..ef50e5a99d 100644
--- a/usr/src/uts/common/syscall/mkdir.c
+++ b/usr/src/uts/common/syscall/mkdir.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,11 +18,13 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
@@ -32,7 +33,7 @@
* under license from the Regents of the University of California.
*/
-#ident "%Z%%M% %I% %E% SMI"
+#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/param.h>
#include <sys/isa_defs.h>
@@ -59,7 +60,7 @@ mkdir(char *dname, int dmode)
vattr.va_mode = dmode & PERMMASK;
vattr.va_mask = AT_TYPE|AT_MODE;
error = vn_create(dname, UIO_USERSPACE, &vattr, EXCL, 0, &vp, CRMKDIR,
- 0, u.u_cmask);
+ 0, PTOU(curproc)->u_cmask);
if (error)
return (set_errno(error));
VN_RELE(vp);
diff --git a/usr/src/uts/common/syscall/mknod.c b/usr/src/uts/common/syscall/mknod.c
index 26250387e4..2b61dac506 100644
--- a/usr/src/uts/common/syscall/mknod.c
+++ b/usr/src/uts/common/syscall/mknod.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -90,7 +89,7 @@ mknod(char *fname, mode_t fmode, dev_t dev)
}
why = ((fmode & S_IFMT) == S_IFDIR) ? CRMKDIR : CRMKNOD;
if (error = vn_create(fname, UIO_USERSPACE, &vattr, EXCL, 0, &vp,
- why, 0, u.u_cmask))
+ why, 0, PTOU(curproc)->u_cmask))
return (set_errno(error));
VN_RELE(vp);
return (0);
diff --git a/usr/src/uts/common/syscall/open.c b/usr/src/uts/common/syscall/open.c
index 40e7faa097..f5b873bdb7 100644
--- a/usr/src/uts/common/syscall/open.c
+++ b/usr/src/uts/common/syscall/open.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -160,7 +159,7 @@ copen(int startfd, char *fname, int filemode, int createmode)
*/
error = vn_openat(fname, UIO_USERSPACE, filemode,
(int)(createmode & MODEMASK), &vp, CRCREAT,
- u.u_cmask, startvp);
+ PTOU(curproc)->u_cmask, startvp);
if (startvp != NULL)
VN_RELE(startvp);
diff --git a/usr/src/uts/common/syscall/sigaction.c b/usr/src/uts/common/syscall/sigaction.c
index cc9850229e..0ed2022fd8 100644
--- a/usr/src/uts/common/syscall/sigaction.c
+++ b/usr/src/uts/common/syscall/sigaction.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -50,6 +49,7 @@ sigaction(int sig, struct sigaction *actp, struct sigaction *oactp)
struct sigaction oact;
k_sigset_t set;
proc_t *p;
+ user_t *ua;
int sigcld_look = 0;
if (sig <= 0 || sig >= NSIG ||
@@ -77,26 +77,27 @@ sigaction(int sig, struct sigaction *actp, struct sigaction *oactp)
}
p = curproc;
+ ua = PTOU(p);
mutex_enter(&p->p_lock);
if (oactp) {
int flags;
void (*disp)();
- disp = u.u_signal[sig - 1];
+ disp = ua->u_signal[sig - 1];
flags = 0;
if (disp != SIG_DFL && disp != SIG_IGN) {
- set = u.u_sigmask[sig-1];
+ set = ua->u_sigmask[sig-1];
if (sigismember(&p->p_siginfo, sig))
flags |= SA_SIGINFO;
- if (sigismember(&u.u_sigrestart, sig))
+ if (sigismember(&ua->u_sigrestart, sig))
flags |= SA_RESTART;
- if (sigismember(&u.u_sigonstack, sig))
+ if (sigismember(&ua->u_sigonstack, sig))
flags |= SA_ONSTACK;
- if (sigismember(&u.u_sigresethand, sig))
+ if (sigismember(&ua->u_sigresethand, sig))
flags |= SA_RESETHAND;
- if (sigismember(&u.u_signodefer, sig))
+ if (sigismember(&ua->u_signodefer, sig))
flags |= SA_NODEFER;
} else
sigemptyset(&set);
@@ -144,6 +145,7 @@ sigaction32(int sig, struct sigaction32 *actp, struct sigaction32 *oactp)
struct sigaction32 oact32;
k_sigset_t set;
proc_t *p;
+ user_t *ua;
int sigcld_look = 0;
if (sig <= 0 || sig >= NSIG ||
@@ -171,26 +173,27 @@ sigaction32(int sig, struct sigaction32 *actp, struct sigaction32 *oactp)
}
p = curproc;
+ ua = PTOU(p);
mutex_enter(&p->p_lock);
if (oactp) {
int flags;
void (*disp)();
- disp = u.u_signal[sig - 1];
+ disp = ua->u_signal[sig - 1];
flags = 0;
if (disp != SIG_DFL && disp != SIG_IGN) {
- set = u.u_sigmask[sig-1];
+ set = ua->u_sigmask[sig-1];
if (sigismember(&p->p_siginfo, sig))
flags |= SA_SIGINFO;
- if (sigismember(&u.u_sigrestart, sig))
+ if (sigismember(&ua->u_sigrestart, sig))
flags |= SA_RESTART;
- if (sigismember(&u.u_sigonstack, sig))
+ if (sigismember(&ua->u_sigonstack, sig))
flags |= SA_ONSTACK;
- if (sigismember(&u.u_sigresethand, sig))
+ if (sigismember(&ua->u_sigresethand, sig))
flags |= SA_RESETHAND;
- if (sigismember(&u.u_signodefer, sig))
+ if (sigismember(&ua->u_signodefer, sig))
flags |= SA_NODEFER;
} else
sigemptyset(&set);
diff --git a/usr/src/uts/common/syscall/ssig.c b/usr/src/uts/common/syscall/ssig.c
index e0998f474b..946e2f5cac 100644
--- a/usr/src/uts/common/syscall/ssig.c
+++ b/usr/src/uts/common/syscall/ssig.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -24,7 +23,7 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -107,7 +106,7 @@ ssig(int signo, void (*func)())
if (sigismember(&curthread->t_hold, sig))
retval = (int)SIG_HOLD;
else
- retval = (int)(uintptr_t)u.u_signal[sig-1];
+ retval = (int)(uintptr_t)PTOU(curproc)->u_signal[sig-1];
if (func == SIG_HOLD) {
sigaddset(&curthread->t_hold, sig);
mutex_exit(&p->p_lock);
@@ -140,7 +139,7 @@ ssig(int signo, void (*func)())
return (set_errno(EINVAL));
}
#endif
- retval = (int)(uintptr_t)u.u_signal[sig-1];
+ retval = (int)(uintptr_t)PTOU(curproc)->u_signal[sig-1];
flags = SA_RESETHAND|SA_NODEFER;
break;
diff --git a/usr/src/uts/common/syscall/uadmin.c b/usr/src/uts/common/syscall/uadmin.c
index 3b9833088e..cb71c07b9a 100644
--- a/usr/src/uts/common/syscall/uadmin.c
+++ b/usr/src/uts/common/syscall/uadmin.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -217,15 +217,15 @@ kadmin(int cmd, int fcn, void *mdep, cred_t *credp)
* do not release these resources.
*/
if (ttoproc(curthread) != &p0) {
- VN_RELE(u.u_cdir);
- if (u.u_rdir)
- VN_RELE(u.u_rdir);
- if (u.u_cwd)
- refstr_rele(u.u_cwd);
-
- u.u_cdir = rootdir;
- u.u_rdir = NULL;
- u.u_cwd = NULL;
+ VN_RELE(PTOU(curproc)->u_cdir);
+ if (PTOU(curproc)->u_rdir)
+ VN_RELE(PTOU(curproc)->u_rdir);
+ if (PTOU(curproc)->u_cwd)
+ refstr_rele(PTOU(curproc)->u_cwd);
+
+ PTOU(curproc)->u_cdir = rootdir;
+ PTOU(curproc)->u_rdir = NULL;
+ PTOU(curproc)->u_cwd = NULL;
}
/*
diff --git a/usr/src/uts/common/syscall/umask.c b/usr/src/uts/common/syscall/umask.c
index e80d1de9a6..b753269afc 100644
--- a/usr/src/uts/common/syscall/umask.c
+++ b/usr/src/uts/common/syscall/umask.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,11 +18,16 @@
*
* CDDL HEADER END
*/
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
-#ident "%Z%%M% %I% %E% SMI" /* from SVr4.0 1.78 */
+#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/param.h>
#include <sys/types.h>
@@ -41,9 +45,9 @@
int
umask(int mask)
{
- register mode_t t;
+ mode_t t;
- t = u.u_cmask;
- u.u_cmask = (mode_t)(mask & PERMMASK);
+ t = PTOU(curproc)->u_cmask;
+ PTOU(curproc)->u_cmask = (mode_t)(mask & PERMMASK);
return ((int)t);
}
diff --git a/usr/src/uts/common/vm/page.h b/usr/src/uts/common/vm/page.h
index 733e4574c2..5824f1ef9e 100644
--- a/usr/src/uts/common/vm/page.h
+++ b/usr/src/uts/common/vm/page.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -872,6 +872,7 @@ int page_szc_user_filtered(size_t);
#define P_NORELOC 0x40 /* Page is non-relocatable */
#define P_MIGRATE 0x20 /* Migrate page on next touch */
#define P_SWAP 0x10 /* belongs to vnode that is V_ISSWAP */
+#define P_BOOTPAGES 0x08 /* member of bootpages list */
#define PP_ISFREE(pp) ((pp)->p_state & P_FREE)
#define PP_ISAGED(pp) (((pp)->p_state & P_FREE) && \
@@ -882,6 +883,7 @@ int page_szc_user_filtered(size_t);
#define PP_ISNORELOCKERNEL(pp) (PP_ISNORELOC(pp) && PP_ISKAS(pp))
#define PP_ISMIGRATE(pp) ((pp)->p_state & P_MIGRATE)
#define PP_ISSWAP(pp) ((pp)->p_state & P_SWAP)
+#define PP_ISBOOTPAGES(pp) ((pp)->p_state & P_BOOTPAGES)
#define PP_SETFREE(pp) ((pp)->p_state = ((pp)->p_state & ~P_MIGRATE) \
| P_FREE)
@@ -889,12 +891,14 @@ int page_szc_user_filtered(size_t);
#define PP_SETNORELOC(pp) ((pp)->p_state |= P_NORELOC)
#define PP_SETMIGRATE(pp) ((pp)->p_state |= P_MIGRATE)
#define PP_SETSWAP(pp) ((pp)->p_state |= P_SWAP)
+#define PP_SETBOOTPAGES(pp) ((pp)->p_state |= P_BOOTPAGES)
#define PP_CLRFREE(pp) ((pp)->p_state &= ~P_FREE)
#define PP_CLRAGED(pp) ASSERT(!PP_ISAGED(pp))
#define PP_CLRNORELOC(pp) ((pp)->p_state &= ~P_NORELOC)
#define PP_CLRMIGRATE(pp) ((pp)->p_state &= ~P_MIGRATE)
#define PP_CLRSWAP(pp) ((pp)->p_state &= ~P_SWAP)
+#define PP_CLRBOOTPAGES(pp) ((pp)->p_state &= ~P_BOOTPAGES)
/*
* Flags for page_t p_toxic, for tracking memory hardware errors.
@@ -1133,6 +1137,14 @@ int page_trycapture(page_t *pp, uint_t szc, uint_t flags, void *datap);
void page_unlock_capture(page_t *pp);
int page_capture_unretire_pp(page_t *);
+extern void memsegs_lock(int);
+extern void memsegs_unlock(int);
+extern int memsegs_lock_held(void);
+extern void memlist_read_lock(void);
+extern void memlist_read_unlock(void);
+extern void memlist_write_lock(void);
+extern void memlist_write_unlock(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/vm/page_lock.c b/usr/src/uts/common/vm/page_lock.c
index 4dab7c8bc7..9b00532b01 100644
--- a/usr/src/uts/common/vm/page_lock.c
+++ b/usr/src/uts/common/vm/page_lock.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -983,3 +983,56 @@ page_szc_lock_assert(page_t *pp)
return (MUTEX_HELD(mtx));
}
+
+/*
+ * memseg locking
+ */
+static krwlock_t memsegslock;
+
+/*
+ * memlist (phys_install, phys_avail) locking.
+ */
+static krwlock_t memlists_lock;
+
+void
+memsegs_lock(int writer)
+{
+ rw_enter(&memsegslock, writer ? RW_WRITER : RW_READER);
+}
+
+/*ARGSUSED*/
+void
+memsegs_unlock(int writer)
+{
+ rw_exit(&memsegslock);
+}
+
+int
+memsegs_lock_held(void)
+{
+ return (RW_LOCK_HELD(&memsegslock));
+}
+
+void
+memlist_read_lock(void)
+{
+ rw_enter(&memlists_lock, RW_READER);
+}
+
+void
+memlist_read_unlock(void)
+{
+ rw_exit(&memlists_lock);
+}
+
+void
+memlist_write_lock(void)
+{
+ rw_enter(&memlists_lock, RW_WRITER);
+}
+
+void
+memlist_write_unlock(void)
+{
+ rw_exit(&memlists_lock);
+}
diff --git a/usr/src/uts/common/zmod/zmod.c b/usr/src/uts/common/zmod/zmod.c
index 48383db9dc..677505f5d0 100644
--- a/usr/src/uts/common/zmod/zmod.c
+++ b/usr/src/uts/common/zmod/zmod.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -88,29 +87,3 @@ z_strerror(int err)
return (z_errmsg[i]);
}
-
-static struct modlmisc modlmisc = {
- &mod_miscops, "RFC 1950 decompression routines"
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1, &modlmisc, NULL
-};
-
-int
-_init(void)
-{
- return (mod_install(&modlinkage));
-}
-
-int
-_info(struct modinfo *mip)
-{
- return (mod_info(&modlinkage, mip));
-}
-
-int
-_fini(void)
-{
- return (mod_remove(&modlinkage));
-}
diff --git a/usr/src/uts/i86pc/Makefile b/usr/src/uts/i86pc/Makefile
index cfd649a46b..aa3fb7f1f2 100644
--- a/usr/src/uts/i86pc/Makefile
+++ b/usr/src/uts/i86pc/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -43,7 +43,8 @@ INTEL_LIB_DIR = $(UTSBASE)/intel/lint-libs/$(OBJS_DIR)
INTEL_LINTS = genunix
LINT_LIBS = $(LINT_LIB) \
- $(KMODS:%=$(LINT_LIB_DIR)/llib-l%.ln) \
+ $(GENUNIX_KMODS:%=$(LINT_LIB_DIR)/llib-l%.ln) \
+ $(PARALLEL_KMODS:%=$(LINT_LIB_DIR)/llib-l%.ln) \
$(CLOSED_KMODS:%=$(LINT_LIB_DIR)/llib-l%.ln) \
$(INTEL_LINTS:%=$(INTEL_LIB_DIR)/llib-l%.ln)
@@ -65,7 +66,7 @@ check := TARGET= check
.KEEP_STATE:
-.PARALLEL: $(KMODS) $(CLOSED_KMODS) $(XMODS) $(CLOSED_XMODS) \
+.PARALLEL: $(PARALLEL_KMODS) $(CLOSED_KMODS) $(XMODS) $(CLOSED_XMODS) \
modlist modlist.intel
INITIAL_TARGETS = \
@@ -120,18 +121,6 @@ install_h check: FRC
@cd sys; pwd; $(MAKE) $(TARGET)
#
-# For some x86 OEMs that deliver their own platform kernel modules but
-# will not deliver anything in usr/platform, they should add their platforms
-# here so a symlink will be created to the standard usr/platform/i86pc.
-#
-OEM_LINKS = ncri86pc
-
-OEM_USR_PLAT_LINKS = $(OEM_LINKS:%=$(USR_PLAT_DIR)/%)
-
-$(OEM_USR_PLAT_LINKS):
- $(INS.slink1)
-
-#
# Definitions for the /platform directory aliases.
# Currently none for i86pc.
#
@@ -148,11 +137,6 @@ install_platforms: $(ROOT_PSM_DIR) $(USR_PSM_DIR) \
$(OEM_USR_PLAT_LINKS)
#
-# Work-around to disable acpica global crosscheck lint warnings
-#
-LGREP.i86pc = grep -v 'i86pc/io/acpica'
-
-#
# Full kernel lint target.
#
LINT_TARGET = globallint
@@ -162,15 +146,13 @@ globallint := LINTFLAGS += -erroff=E_NAME_MULTIPLY_DEF2
globallint:
@-$(ECHO) "\nFULL KERNEL: global crosschecks:"
- @-$(LINT) $(LINTFLAGS) $(LINT_LIBS) 2>&1 | $(LGREP.i86pc) | $(LGREP.2)
+ @-$(LINT) $(LINTFLAGS) $(LINT_LIBS) 2>&1 | $(LGREP.2)
lint: lintlib .WAIT modlintlib .WAIT $(INTEL_LINTS) $(LINT_DEPS)
$(INTEL_LINTS): FRC
@cd $(UTSBASE)/intel/$@; pwd; $(MAKE) modlintlib
-FRC:
-
include ../Makefile.targ
#
diff --git a/usr/src/uts/i86pc/Makefile.files b/usr/src/uts/i86pc/Makefile.files
index ebbb9934aa..927f65344c 100644
--- a/usr/src/uts/i86pc/Makefile.files
+++ b/usr/src/uts/i86pc/Makefile.files
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -36,6 +36,7 @@
CORE_OBJS += \
beeper.o \
biosdisk.o \
+ bios_call.o \
cbe.o \
cmi.o \
confunix.o \
@@ -44,16 +45,26 @@ CORE_OBJS += \
ddi_impl.o \
dtrace_subr.o \
dvma.o \
+ fpu_subr.o \
+ fakebop.o \
graphics.o \
+ hardclk.o \
hat_i86.o \
hat_kdi.o \
hment.o \
+ hold_page.o \
hrtimers.o \
htable.o \
+ i8254.o \
+ i86_mmu.o \
instr_size.o \
intr.o \
+ kboot_mmu.o \
+ kdi_subr.o \
+ kdi_idt.o \
+ kdi_idthdl.o \
+ kdi_asm.o \
lgrpplat.o \
- mach_i86mmu.o \
mach_kdi.o \
mach_sysconfig.o \
machdep.o \
@@ -63,6 +74,7 @@ CORE_OBJS += \
mp_call.o \
mp_implfuncs.o \
mp_machdep.o \
+ mp_pc.o \
mp_startup.o \
memscrub.o \
mpcore.o \
@@ -77,6 +89,7 @@ CORE_OBJS += \
ppage.o \
startup.o \
timestamp.o \
+ todpc_subr.o \
trap.o \
vm_machdep.o \
x_call.o
@@ -88,6 +101,20 @@ CORE_OBJS += \
CORE_OBJS += $(SMBIOS_OBJS)
#
+# These get compiled twice:
+# - once in the dboot (direct boot) identity mapped code
+# - once for use during early startup in unix
+#
+BOOT_DRIVER_OBJS = \
+ boot_console.o \
+ boot_keyboard.o \
+ boot_keyboard_table.o \
+ boot_vga.o \
+ boot_mmu.o
+
+CORE_OBJS += $(BOOT_DRIVER_OBJS)
+
+#
# locore.o is special. It must be the first file relocated so that it
# it is relocated just where its name implies.
#
@@ -106,37 +133,35 @@ SPECIAL_OBJS_64 += \
SPECIAL_OBJS += $(SPECIAL_OBJS_$(CLASS))
#
-# driver modules
+# Objects that get compiled into the identity mapped PT_LOAD section of unix
+# to handle the earliest part of booting.
#
-ROOTNEX_OBJS += rootnex.o
-ISANEXUS_OBJS += isa.o dma_engine.o i8237A.o
-PCINEXUS_OBJS += pci.o pci_common.o pci_kstats.o pci_tools.o
-PCI_PCINEXUS_OBJS += pci_pci.o
-
-TCIC_OBJS += tcic.o
+DBOOT_OBJS_32 =
-FD_OBJS += fd.o
+DBOOT_OBJS_64 += dboot_elfload.o
-PCN_OBJS += mii.o
-
-DNET_OBJS += dnet.o mii.o
-LOGI_OBJS += logi.o
-MSCSI_OBJS += mscsi.o
-MSMOUSE_OBJS += msm.o
-PCPLUSMP_OBJS += apic.o psm_common.o apic_introp.o
-RTLS_OBJS += rtls.o
-AGPGART_OBJS += agpgart.o \
- agp_kstat.o
-AGPTARGET_OBJS += agptarget.o
-AMD64GART_OBJS += amd64_gart.o
-TZMON_OBJS += tzmon.o
+DBOOT_OBJS += \
+ dboot_grub.o \
+ dboot_startkern.o \
+ dboot_printf.o \
+ memcpy.o \
+ memset.o \
+ muldiv.o \
+ string.o \
+ $(BOOT_DRIVER_OBJS) \
+ $(DBOOT_OBJS_$(CLASS))
-GHD_OBJS += ghd.o ghd_debug.o ghd_dma.o ghd_queue.o ghd_scsa.o \
- ghd_scsi.o ghd_timer.o ghd_waitq.o ghd_gcmd.o
-
-ATA_OBJS += $(GHD_OBJS) ata_blacklist.o ata_common.o ata_disk.o \
- ata_dma.o atapi.o atapi_fsm.o ata_debug.o \
- sil3xxx.o
+#
+# driver and misc modules
+#
+GFX_PRIVATE_OBJS += gfx_private.o gfxp_pci.o gfxp_segmap.o \
+ gfxp_devmap.o gfxp_vgatext.o gfxp_vm.o vgasubr.o
+ISANEXUS_OBJS += isa.o dma_engine.o i8237A.o
+PCI_E_MISC_OBJS += pcie_error.o
+PCI_E_NEXUS_OBJS += npe.o npe_misc.o
+PCI_E_NEXUS_OBJS += pci_common.o pci_kstats.o pci_tools.o
+PCINEXUS_OBJS += pci.o pci_common.o pci_kstats.o pci_tools.o
+PCPLUSMP_OBJS += apic.o psm_common.o apic_introp.o mp_platform_common.o
include $(SRC)/common/mc/mc-amd/Makefile.mcamd
MCAMD_OBJS += \
@@ -146,77 +171,25 @@ MCAMD_OBJS += \
mcamd_subr.o \
mcamd_pcicfg.o
-#
-# PCI-Express driver modules
-#
-PCI_E_MISC_OBJS += pcie_error.o
-PCI_E_NEXUS_OBJS += npe.o npe_misc.o
-PCI_E_NEXUS_OBJS += pci_common.o pci_kstats.o pci_tools.o
-PCI_E_PCINEXUS_OBJS += pcie_pci.o
-PCIEHPCNEXUS_OBJS += pciehpc_x86.o pciehpc_acpi.o pciehpc_nvidia.o
-
-#
-# platform specific modules
-#
+ROOTNEX_OBJS += rootnex.o
+TZMON_OBJS += tzmon.o
UPPC_OBJS += uppc.o psm_common.o
-PCI_AUTOCONFIG_OBJS += \
- pci_autoconfig.o \
- pci_boot.o \
- pcie_nvidia.o \
- pci_memlist.o \
- pci_resource.o
-
-ACPICA_OBJS += dbcmds.o dbdisply.o \
- dbexec.o dbfileio.o dbhistry.o dbinput.o dbstats.o \
- dbutils.o dbxface.o evevent.o evgpe.o evgpeblk.o \
- evmisc.o evregion.o evrgnini.o evsci.o evxface.o \
- evxfevnt.o evxfregn.o hwacpi.o hwgpe.o hwregs.o \
- hwsleep.o hwtimer.o dsfield.o dsinit.o dsmethod.o \
- dsmthdat.o dsobject.o dsopcode.o dsutils.o dswexec.o \
- dswload.o dswscope.o dswstate.o exconfig.o exconvrt.o \
- excreate.o exdump.o exfield.o exfldio.o exmisc.o \
- exmutex.o exnames.o exoparg1.o exoparg2.o exoparg3.o \
- exoparg6.o exprep.o exregion.o exresnte.o exresolv.o \
- exresop.o exstore.o exstoren.o exstorob.o exsystem.o \
- exutils.o psargs.o psopcode.o psparse.o psscope.o \
- pstree.o psutils.o pswalk.o psxface.o nsaccess.o \
- nsalloc.o nsdump.o nsdumpdv.o nseval.o nsinit.o \
- nsload.o nsnames.o nsobject.o nsparse.o nssearch.o \
- nsutils.o nswalk.o nsxfeval.o nsxfname.o nsxfobj.o \
- rsaddr.o rscalc.o rscreate.o rsdump.o \
- rsinfo.o rsio.o rsirq.o rslist.o rsmemory.o rsmisc.o \
- rsutils.o rsxface.o tbconvrt.o tbget.o tbgetall.o \
- tbinstal.o tbrsdt.o tbutils.o tbxface.o tbxfroot.o \
- utalloc.o utclib.o utcopy.o utdebug.o utdelete.o \
- uteval.o utglobal.o utinit.o utmath.o utmisc.o \
- utobject.o utresrc.o utxface.o acpica.o acpi_enum.o \
- master_ops.o osl.o osl_ml.o acpica_ec.o utcache.o \
- utmutex.o utstate.o dmbuffer.o dmnames.o dmobject.o \
- dmopcode.o dmresrc.o dmresrcl.o dmresrcs.o dmutils.o \
- dmwalk.o psloop.o uttrack.o
-
-POWER_OBJS += power.o
-
-GFX_PRIVATE_OBJS += gfx_private.o gfxp_pci.o gfxp_segmap.o \
- gfxp_devmap.o gfxp_vgatext.o gfxp_vm.o vgasubr.o
-AGP_OBJS += agpmaster.o
-
-# DRM Intel integrated chipsets (i915) codes
-I915_OBJS += i915_sundrv.o i915_dma.o i915_drv.o i915_irq.o i915_mem.o
+XSVC_OBJS += xsvc.o
#
# Build up defines and paths.
#
ALL_DEFS += -Di86pc
-INC_PATH += -I$(UTSBASE)/i86pc
+INC_PATH += -I$(UTSBASE)/i86pc -I$(SRC)/common
#
-# Since assym.h is a derived file, the dependency must be explicit for
+# Since the assym files are derived, the dependencies must be explicit for
# all files including this file. (This is only actually required in the
# instance when the .nse_depinfo file does not exist.) It may seem that
# the lint targets should also have a similar dependency, but they don't
# since only C headers are included when #defined(__lint) is true.
#
+
ASSYM_DEPS += \
copy.o \
desctbls_asm.o \
@@ -233,3 +206,7 @@ ASSYM_DEPS += \
swtch.o \
syscall_asm.o \
syscall_asm_amd64.o
+
+$(KDI_ASSYM_DEPS:%=$(OBJS_DIR)/%): $(DSF_DIR)/$(OBJS_DIR)/kdi_assym.h
+
+ASSYM_DEPS += kdi_asm.o
diff --git a/usr/src/uts/i86pc/Makefile.i86pc.shared b/usr/src/uts/i86pc/Makefile.i86pc.shared
index aae56c8ea4..73ef283182 100644
--- a/usr/src/uts/i86pc/Makefile.i86pc.shared
+++ b/usr/src/uts/i86pc/Makefile.i86pc.shared
@@ -22,7 +22,7 @@
#
# uts/i86pc/Makefile.i86pc
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -37,6 +37,11 @@
PLATFORM = i86pc
#
+# uname -m value
+#
+UNAME_M = $(PLATFORM)
+
+#
# Everybody needs to know how to build modstubs.o and to locate unix.o
#
UNIX_DIR = $(UTSBASE)/$(PLATFORM)/unix
@@ -56,6 +61,7 @@ UNIX_O = $(UNIX_DIR)/$(OBJS_DIR)/unix.o
MODSTUBS_O = $(MODSTUBS_DIR)/$(OBJS_DIR)/modstubs.o
GENLIB = $(GENLIB_DIR)/$(OBJS_DIR)/libgenunix.so
LINT_LIB = $(LINT_LIB_DIR)/llib-lunix.ln
+DBOOT_LINT_LIB = $(LINT_LIB_DIR)/llib-ldboot.ln
GEN_LINT_LIB = $(GEN_LINT_LIB_DIR)/llib-lgenunix.ln
#
@@ -89,8 +95,10 @@ ALL_BUILDS = $(ALL_BUILDS64) $(ALL_BUILDS32)
#
# x86 or amd64 inline templates
#
-INLINES_32 = $(UTSBASE)/intel/ia32/ml/ia32.il
-INLINES_64 = $(UTSBASE)/intel/amd64/ml/amd64.il
+INLINES_32 = $(UTSBASE)/intel/ia32/ml/ia32.il \
+ $(UTSBASE)/$(PLATFORM)/ml/ia32.il
+INLINES_64 = $(UTSBASE)/intel/amd64/ml/amd64.il \
+ $(UTSBASE)/$(PLATFORM)/ml/amd64.il
INLINES += $(INLINES_$(CLASS))
#
@@ -135,6 +143,7 @@ OFFSETS_SRC = $(UTSBASE)/$(PLATFORM)/ml/offsets.in
PLATFORM_OFFSETS_32 = $(UTSBASE)/$(PLATFORM)/ml/mach_offsets.in
PLATFORM_OFFSETS_64 = $(UTSBASE)/intel/amd64/ml/mach_offsets.in
PLATFORM_OFFSETS_SRC = $(PLATFORM_OFFSETS_$(CLASS))
+KDI_OFFSETS_SRC = $(UTSBASE)/intel/kdi/kdi_offsets.in
#
# Define the actual specific platforms
@@ -148,14 +157,6 @@ MACHINE_DEFS = -D$(PLATFORM) -D_MACHDEP
include $(UTSBASE)/$(PLATFORM)/Makefile.workarounds
#
-# Simulator flag
-#
-i386_SIMULATOR = -D_SIMULATOR_SUPPORT
-amd64_SIMULATOR = -D_SIMULATOR_SUPPORT
-
-SIMULATOR = $($(MACH)_SIMULATOR)
-
-#
# Debugging level
#
# Special knowledge of which special debugging options effect which
@@ -167,10 +168,8 @@ SIMULATOR = $($(MACH)_SIMULATOR)
#
DEBUG_DEFS_OBJ32 =
DEBUG_DEFS_DBG32 = -DDEBUG
-DEBUG_DEFS_DBG32 += $(SIMULATOR)
DEBUG_DEFS_OBJ64 =
DEBUG_DEFS_DBG64 = -DDEBUG
-DEBUG_DEFS_DBG64 += $(SIMULATOR)
DEBUG_DEFS = $(DEBUG_DEFS_$(BUILD_TYPE))
DEBUG_COND_OBJ32 :sh = echo \\043
@@ -184,10 +183,14 @@ $(IF_DEBUG_OBJ)syscall_asm.o := DEBUG_DEFS += -DSYSCALLTRACE -DTRAPTRACE
$(IF_DEBUG_OBJ)syscall_asm_amd64.o := DEBUG_DEFS += -DSYSCALLTRACE -DTRAPTRACE
$(IF_DEBUG_OBJ)fast_trap_asm.o := DEBUG_DEFS += -DTRAPTRACE
$(IF_DEBUG_OBJ)interrupt.o := DEBUG_DEFS += -DTRAPTRACE
+$(IF_DEBUG_OBJ)intr.o := DEBUG_DEFS += -DTRAPTRACE
$(IF_DEBUG_OBJ)locore.o := DEBUG_DEFS += -DTRAPTRACE
$(IF_DEBUG_OBJ)mp_startup.o := DEBUG_DEFS += -DTRAPTRACE
$(IF_DEBUG_OBJ)machdep.o := DEBUG_DEFS += -DTRAPTRACE
$(IF_DEBUG_OBJ)exception.o := DEBUG_DEFS += -DTRAPTRACE
+$(IF_DEBUG_OBJ)x_call.o := DEBUG_DEFS += -DTRAPTRACE
+$(IF_DEBUG_OBJ)mp_call.o := DEBUG_DEFS += -DTRAPTRACE
+$(IF_DEBUG_OBJ)cbe.o := DEBUG_DEFS += -DTRAPTRACE
#
# Build `options'. These are historical and the need for these
@@ -237,52 +240,18 @@ MACH_NOT_YET_KMODS = $(AUTOCONF_OBJS)
# DRV_KMODS_32 are built only 32-bit
# DRV_KMODS_64 are built only 64-bit
#
-# XXX: How many of these are really machine specific?
-#
DRV_KMODS += rootnex
DRV_KMODS += isa
+DRV_KMODS += pcplusmp
+DRV_KMODS += cpc
DRV_KMODS += pci
-DRV_KMODS += pci_pci
-DRV_KMODS += pcie_pci
DRV_KMODS += npe
-
-DRV_KMODS += ata
-DRV_KMODS += fd
-DRV_KMODS += fdc
-DRV_KMODS += kb8042
DRV_KMODS += pci-ide
-DRV_KMODS += audio810
-DRV_KMODS += audiohd
-DRV_KMODS += audioixp
-
-DRV_KMODS_32 += dnet
-DRV_KMODS += logi
-DRV_KMODS_32 += mscsi
-DRV_KMODS_32 += msm
-DRV_KMODS += pcplusmp
-DRV_KMODS += agpgart
-DRV_KMODS += agptarget
-DRV_KMODS += amd64_gart
-DRV_KMODS += i915
-
-DRV_KMODS += cpc
+DRV_KMODS += xsvc
DRV_KMODS += mc-amd
-DRV_KMODS += power
DRV_KMODS += tzmon
-DRV_KMODS += pcic
-
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += audiovia823x
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += audioens
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += bmc
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += bscbus
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += bscv
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += elxl
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += iprb
+
$(CLOSED_BUILD)CLOSED_DRV_KMODS += memtest
-$(CLOSED_BUILD)CLOSED_DRV_KMODS_32 += ncrs
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += pcn
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += rtls
-$(CLOSED_BUILD)CLOSED_DRV_KMODS_32 += sbpro
#
# CPU Modules
@@ -308,11 +277,7 @@ FS_KMODS +=
#
# Streams Modules (/kernel/strmod):
#
-STRMOD_KMODS += vuid2ps2
-STRMOD_KMODS += vuid3ps2
-STRMOD_KMODS += vuidm3p
-STRMOD_KMODS += vuidm4p
-STRMOD_KMODS += vuidm5p
+STRMOD_KMODS +=
#
# 'System' Modules (/kernel/sys):
@@ -322,15 +287,14 @@ SYS_KMODS +=
#
# 'Misc' Modules (/kernel/misc):
#
-MISC_KMODS += pci_autoconfig bootdev acpica pcie pciehpc gfx_private \
- agpmaster drm
+MISC_KMODS += gfx_private pcie
#
-# 'Mach' Modules (/kernel/mach):
+# 'Dacf' modules (/kernel/dacf)
#
-MACH_KMODS += uppc
+DACF_KMODS += consconfig_dacf
#
-# Modules excluded from the product:
+# 'Mach' Modules (/kernel/mach):
#
-$(CLOSED_BUILD)CLOSED_XMODS += spwr
+MACH_KMODS += uppc
diff --git a/usr/src/uts/i86pc/Makefile.rules b/usr/src/uts/i86pc/Makefile.rules
index fc4d4e6dbd..4891b73ee8 100644
--- a/usr/src/uts/i86pc/Makefile.rules
+++ b/usr/src/uts/i86pc/Makefile.rules
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -75,10 +75,6 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/pciex/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/pciex/hotplug/pciehpc/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/pcplusmp/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
@@ -104,6 +100,10 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/os/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
+$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/boot/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/vm/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
@@ -120,91 +120,85 @@ $(OBJS_DIR)/%.o: $(SRC)/common/dis/i386/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/agpgart/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/gfx_private/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/agpmaster/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/drm/%.c
+$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/xsvc/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/drm/%.s
- $(COMPILE.s) -o $@ $<
-
-# ridiculous contortions ---
-ATOMIC_SUBDIR_32 = i386
-ATOMIC_SUBDIR_64 = amd64
-ATOMIC_SUBDIR = $(ATOMIC_SUBDIR_$(CLASS))
-
-$(OBJS_DIR)/%.o: $(SRC)/common/atomic/$(ATOMIC_SUBDIR)/%.s
- $(COMPILE.s) -o $@ $<
-
-$(OBJS_DIR)/%.o: $(UTSBASE)/common/io/power/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+#
+# dboot stuff is always 32 bit, linked to run with phys_addr == virt_addr
+#
+DBOOT_OBJS_DIR = dboot/$(OBJS_DIR)
+DBOOT_MACH_32 = -D_BOOT_TARGET_i386
+DBOOT_MACH_64 = -D_BOOT_TARGET_amd64
+DBOOT_DEFS = -D_BOOT $(DBOOT_MACH_$(CLASS))
+DBOOT_DEFS += -D_MACHDEP -D_KMEMUSER -U_KERNEL -D_I32LPx
-$(OBJS_DIR)/%.o: $(SRC)/common/mc/mc-amd/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+DBOOT_CC_INCL = -I$(SRC)/common $(INCLUDE_PATH)
+DBOOT_AS_INCL = $(AS_INC_PATH)
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+DBOOT_AS = $(ONBLD_TOOLS)/bin/$(MACH)/aw
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/%.s
- $(COMPILE.s) -o $@ $<
+DBOOT_LINTS_DIR = $(DBOOT_OBJS_DIR)
+DBOOT_LINTFLAGS_i86pc = $(LINTFLAGS_i386_32) $(LINTTAGS_i386_32)
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/debugger/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+DBOOT_LINTFLAGS = $(DBOOT_LINTFLAGS_$(PLATFORM)) $(C99LMODE) $(CPPFLAGS) \
+ $(DBOOT_DEFS)
+DBOOT_LOCAL_LINTFLAGS = -c -dirout=$(DBOOT_LINTS_DIR) -I$(SRC)/common \
+ $(DBOOT_LINTFLAGS)
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/events/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+$(DBOOT_OBJS_DIR)/%.o: $(UTSBASE)/i86pc/boot/%.c
+ $(i386_CC) $(CERRWARN) -O $(DBOOT_DEFS) $(DBOOT_CC_INCL) -c -o $@ $<
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/hardware/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+$(DBOOT_OBJS_DIR)/%.o: $(UTSBASE)/i86pc/dboot/%.c
+ $(i386_CC) $(CERRWARN) -O $(DBOOT_DEFS) $(DBOOT_CC_INCL) -c -o $@ $<
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/interpreter/dispatcher/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+$(DBOOT_OBJS_DIR)/%.o: $(COMMONBASE)/util/%.c
+ $(i386_CC) $(CERRWARN) -O $(DBOOT_DEFS) $(DBOOT_CC_INCL) -c -o $@ $<
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/interpreter/executer/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+$(DBOOT_OBJS_DIR)/%.o: $(COMMONBASE)/util/i386/%.s
+ $(DBOOT_AS) -P -D_ASM $(DBOOT_DEFS) $(DBOOT_AS_INCL) -o $@ $<
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/interpreter/parser/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+$(DBOOT_OBJS_DIR)/%.o: $(UTSBASE)/i86pc/dboot/%.s
+ $(DBOOT_AS) -P -D_ASM $(DBOOT_DEFS) $(DBOOT_AS_INCL) -o $@ $<
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/namespace/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+#
+# Stuff to build bios_call.o for the kernel.
+#
+MAPFILE_BIOS = $(UTSBASE)/i86pc/conf/Mapfile.bios
+$(OBJS_DIR)/bios_call.o: $(UTSBASE)/i86pc/ml/bios_call_src.s
+ $(COMPILE.s) -o $(OBJS_DIR)/bios_call_src.o \
+ $(UTSBASE)/i86pc/ml/bios_call_src.s
+ $(LD) -dn -M $(MAPFILE_BIOS) \
+ -o $(OBJS_DIR)/bios_call_src $(OBJS_DIR)/bios_call_src.o
+ @echo " .data" > $(OBJS_DIR)/bios_call.s
+ @echo " .globl bios_image" >> $(OBJS_DIR)/bios_call.s
+ @echo "bios_image:" >> $(OBJS_DIR)/bios_call.s
+ $(ELFEXTRACT) $(OBJS_DIR)/bios_call_src >> $(OBJS_DIR)/bios_call.s
+ @echo " .align 4" >> $(OBJS_DIR)/bios_call.s
+ @echo " .globl bios_size" >> $(OBJS_DIR)/bios_call.s
+ @echo "bios_size:" >> $(OBJS_DIR)/bios_call.s
+ @echo " .long . - bios_image" >> $(OBJS_DIR)/bios_call.s
+ $(COMPILE.s) -o $@ $(OBJS_DIR)/bios_call.s
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/resources/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+# ridiculous contortions ---
+ATOMIC_SUBDIR_32 = i386
+ATOMIC_SUBDIR_64 = amd64
+ATOMIC_SUBDIR = $(ATOMIC_SUBDIR_$(CLASS))
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/tables/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+$(OBJS_DIR)/%.o: $(SRC)/common/atomic/$(ATOMIC_SUBDIR)/%.s
+ $(COMPILE.s) -o $@ $<
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/utilities/%.c
+$(OBJS_DIR)/%.o: $(SRC)/common/mc/mc-amd/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
-$(OBJS_DIR)/%.o: $(UTSBASE)/i86pc/io/acpica/disassembler/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
+#
+# dtrace stubs
+#
$(OBJS_DIR)/dtracestubs.s: $(UNIX_O) $(LIBS)
nm -u $(UNIX_O) $(LIBS) | grep __dtrace_probe_ | sort | uniq | nawk '{ \
@@ -244,9 +238,6 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/pci/%.c
$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/pciex/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/pciex/hotplug/pciehpc/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/pcplusmp/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
@@ -268,6 +259,9 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/ml/%.s
$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/os/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
+$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/boot/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/vm/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
@@ -280,63 +274,40 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/common/os/%.c
$(LINTS_DIR)/%.ln: $(SRC)/common/dis/i386/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/agpgart/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
$(LINTS_DIR)/%.ln: $(SRC)/common/atomic/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
$(LINTS_DIR)/%.ln: $(SRC)/common/mc/mc-amd/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/%.s
- @($(LHEAD) $(LINT.s) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/debugger/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/events/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/hardware/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/interpreter/dispatcher/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/interpreter/executer/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/interpreter/parser/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/namespace/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/resources/%.c
+$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/gfx_private/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/tables/%.c
+$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/xsvc/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/utilities/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
+#
+# bios call has a funky name change while building
+#
+$(LINTS_DIR)/bios_call.ln: $(UTSBASE)/i86pc/ml/bios_call_src.s
+ @($(LHEAD) $(LINT.s) $(UTSBASE)/i86pc/ml/bios_call_src.s $(LTAIL))
+ @mv $(LINTS_DIR)/bios_call_src.ln $(LINTS_DIR)/bios_call.ln
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/acpica/disassembler/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
+#
+# dboot always compiles in 32-bit mode, so force lint to be 32-bit mode too.
+#
+$(DBOOT_LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/dboot/%.c
+ @($(LHEAD) $(DBOOT_LINT) $(DBOOT_LOCAL_LINTFLAGS) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/gfx_private/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
+$(DBOOT_LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/dboot/%.s
+ @($(LHEAD) $(DBOOT_LINT) $(DBOOT_LOCAL_LINTFLAGS) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/agpmaster/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
+$(DBOOT_LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/boot/%.c
+ @($(LHEAD) $(DBOOT_LINT) $(DBOOT_LOCAL_LINTFLAGS) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/drm/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
+$(DBOOT_LINTS_DIR)/%.ln: $(COMMONBASE)/util/%.c
+ @($(LHEAD) $(DBOOT_LINT) $(DBOOT_LOCAL_LINTFLAGS) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(UTSBASE)/i86pc/io/drm/%.s
- @($(LHEAD) $(LINT.s) $< $(LTAIL))
+$(DBOOT_LINTS_DIR)/%.ln: $(COMMONBASE)/util/i386/%.s
+ @($(LHEAD) $(DBOOT_LINT) $(DBOOT_LOCAL_LINTFLAGS) $< $(LTAIL))
diff --git a/usr/src/uts/i86pc/Makefile.workarounds b/usr/src/uts/i86pc/Makefile.workarounds
index 54e82c9abf..cdc555b44b 100644
--- a/usr/src/uts/i86pc/Makefile.workarounds
+++ b/usr/src/uts/i86pc/Makefile.workarounds
@@ -18,7 +18,7 @@
#
# CDDL HEADER END
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -87,9 +87,9 @@ WORKAROUND_DEFS += -DOPTERON_ERRATUM_122
# Processors
#
# Solaris does not currently support PowerNow which is required for this
-# Erratum. Disable for now.
+# Erratum. Check anyway.
#
-#WORKAROUND_DEFS += -DOPTERON_ERRATUM_123
+WORKAROUND_DEFS += -DOPTERON_ERRATUM_123
#
# Multiprocessor Systems with Four or More Cores May Deadlock Waiting for a
diff --git a/usr/src/uts/i86pc/boot/boot_console.c b/usr/src/uts/i86pc/boot/boot_console.c
new file mode 100644
index 0000000000..71134377ec
--- /dev/null
+++ b/usr/src/uts/i86pc/boot/boot_console.c
@@ -0,0 +1,556 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/archsystm.h>
+#include <sys/boot_console.h>
+
+#include "boot_serial.h"
+#include "boot_vga.h"
+
+#if defined(_BOOT)
+#include "../dboot/dboot_xboot.h"
+#include <util/string.h>
+#else
+#include <sys/bootconf.h>
+static char *usbser_buf;
+static char *usbser_cur;
+#endif
+
+static int cons_color = CONS_COLOR;
+int console = CONS_SCREEN_TEXT;
+/* or CONS_TTYA, CONS_TTYB */
+static int serial_ischar(void);
+static int serial_getchar(void);
+static void serial_putchar(int);
+static void serial_adjust_prop(void);
+
+static char *boot_line = NULL;
+
+/* Clear the screen and initialize VIDEO, XPOS and YPOS. */
+static void
+clear_screen(void)
+{
+ /*
+ * XXX should set vga mode so we don't depend on the
+ * state left by the boot loader
+ */
+ vga_clear(cons_color);
+ vga_setpos(0, 0);
+}
+
+/* Put the character C on the screen. */
+static void
+screen_putchar(int c)
+{
+ int row, col;
+
+ vga_getpos(&row, &col);
+ switch (c) {
+ case '\t':
+ col += 8 - (col % 8);
+ if (col == VGA_TEXT_COLS)
+ col = 79;
+ vga_setpos(row, col);
+ break;
+
+ case '\r':
+ vga_setpos(row, 0);
+ break;
+
+ case '\b':
+ if (col > 0)
+ vga_setpos(row, col - 1);
+ break;
+
+ case '\n':
+ if (row < VGA_TEXT_ROWS - 1)
+ vga_setpos(row + 1, col);
+ else
+ vga_scroll(cons_color);
+ break;
+
+ default:
+ vga_drawc(c, cons_color);
+ if (col < VGA_TEXT_COLS -1)
+ vga_setpos(row, col + 1);
+ else if (row < VGA_TEXT_ROWS - 1)
+ vga_setpos(row + 1, 0);
+ else {
+ vga_setpos(row, 0);
+ vga_scroll(cons_color);
+ }
+ break;
+ }
+}
+
+/* serial port stuff */
+static int port;
+
+static void
+serial_init(void)
+{
+ switch (console) {
+ case CONS_TTYA:
+ port = 0x3f8;
+ break;
+ case CONS_TTYB:
+ port = 0x2f8;
+ break;
+ }
+
+ outb(port + ISR, 0x20);
+ if (inb(port + ISR) & 0x20) {
+ /*
+ * 82510 chip is present
+ */
+ outb(port + DAT+7, 0x04); /* clear status */
+ outb(port + ISR, 0x40); /* set to bank 2 */
+ outb(port + MCR, 0x08); /* IMD */
+ outb(port + DAT, 0x21); /* FMD */
+ outb(port + ISR, 0x00); /* set to bank 0 */
+ } else {
+ /*
+ * set the UART in FIFO mode if it has FIFO buffers.
+ * use 16550 fifo reset sequence specified in NS
+ * application note. disable fifos until chip is
+ * initialized.
+ */
+ outb(port + FIFOR, 0x00); /* clear */
+ outb(port + FIFOR, FIFO_ON); /* enable */
+ outb(port + FIFOR, FIFO_ON|FIFORXFLSH); /* reset */
+ outb(port + FIFOR,
+ FIFO_ON|FIFODMA|FIFOTXFLSH|FIFORXFLSH|0x80);
+ if ((inb(port + ISR) & 0xc0) != 0xc0) {
+ /*
+ * no fifo buffers so disable fifos.
+ * this is true for 8250's
+ */
+ outb(port + FIFOR, 0x00);
+ }
+ }
+
+ /* disable interrupts */
+ outb(port + ICR, 0);
+
+ /* adjust setting based on tty properties */
+ serial_adjust_prop();
+
+#if defined(_BOOT)
+ /*
+ * Do a full reset to match console behavior.
+ * 0x1B + c - reset everything
+ */
+ serial_putchar(0x1B);
+ serial_putchar('c');
+#endif
+}
+
+
+#define MATCHES(p, pat) \
+ (strncmp(p, pat, strlen(pat)) == 0 ? (p += strlen(pat), 1) : 0)
+
+#define SKIP(p, c) \
+ while (*(p) != 0 && *p != (c)) \
+ ++(p); \
+ if (*(p) == (c)) \
+ ++(p);
+
+/*
+ * find a tty mode property either from cmdline or from boot properties
+ */
+static char *
+get_mode_value(char *name)
+{
+ char *p;
+
+ /*
+ * when specified on boot line it looks like "name" "="....
+ */
+ if (boot_line != NULL) {
+ p = strstr(boot_line, name);
+ if (p == NULL)
+ return (NULL);
+ SKIP(p, '=');
+ return (p);
+ }
+
+#if defined(_BOOT)
+ return (NULL);
+#else
+ /*
+ * if we're running in the full kernel we check the bootenv.rc settings
+ */
+ {
+ static char propval[20];
+
+ propval[0] = 0;
+ if (bootops == NULL || BOP_GETPROPLEN(bootops, name) == 0)
+ return (NULL);
+ (void) BOP_GETPROP(bootops, name, propval);
+ return (propval);
+ }
+#endif
+}
+
+/*
+ * adjust serial port based on properties
+ * These come either from the cmdline or from boot properties.
+ */
+static void
+serial_adjust_prop(void)
+{
+ char propname[20];
+ char *propval;
+ char *p;
+ ulong_t baud;
+ uchar_t lcr = 0;
+ uchar_t mcr = DTR | RTS;
+
+ (void) strcpy(propname, "ttyX-mode");
+ propname[3] = 'a' + console - CONS_TTYA;
+ propval = get_mode_value(propname);
+ if (propval == NULL)
+ propval = "9600,8,n,1,-";
+
+ /* property is of the form: "9600,8,n,1,-" */
+ p = propval;
+ if (MATCHES(p, "110,"))
+ baud = ASY110;
+ else if (MATCHES(p, "150,"))
+ baud = ASY150;
+ else if (MATCHES(p, "300,"))
+ baud = ASY300;
+ else if (MATCHES(p, "600,"))
+ baud = ASY600;
+ else if (MATCHES(p, "1200,"))
+ baud = ASY1200;
+ else if (MATCHES(p, "2400,"))
+ baud = ASY2400;
+ else if (MATCHES(p, "4800,"))
+ baud = ASY4800;
+ else if (MATCHES(p, "19200,"))
+ baud = ASY19200;
+ else if (MATCHES(p, "38400,"))
+ baud = ASY38400;
+ else if (MATCHES(p, "57600,"))
+ baud = ASY57600;
+ else if (MATCHES(p, "115200,"))
+ baud = ASY115200;
+ else {
+ baud = ASY9600;
+ SKIP(p, ',');
+ }
+ outb(port + LCR, DLAB);
+ outb(port + DAT + DLL, baud & 0xff);
+ outb(port + DAT + DLH, (baud >> 8) & 0xff);
+
+ switch (*p) {
+ case '5':
+ lcr |= BITS5;
+ ++p;
+ break;
+ case '6':
+ lcr |= BITS6;
+ ++p;
+ break;
+ case '7':
+ lcr |= BITS7;
+ ++p;
+ break;
+ case '8':
+ ++p;
+ default:
+ lcr |= BITS8;
+ break;
+ }
+
+ SKIP(p, ',');
+
+ switch (*p) {
+ case 'n':
+ lcr |= PARITY_NONE;
+ ++p;
+ break;
+ case 'o':
+ lcr |= PARITY_ODD;
+ ++p;
+ break;
+ case 'e':
+ ++p;
+ default:
+ lcr |= PARITY_EVEN;
+ break;
+ }
+
+
+ SKIP(p, ',');
+
+ switch (*p) {
+ case '1':
+ /* STOP1 is 0 */
+ ++p;
+ break;
+ default:
+ lcr |= STOP2;
+ break;
+ }
+ /* set parity bits */
+ outb(port + LCR, lcr);
+
+ (void) strcpy(propname, "ttyX-rts-dtr-off");
+ propname[3] = 'a' + console - CONS_TTYA;
+ propval = get_mode_value(propname);
+ if (propval == NULL)
+ propval = "false";
+ if (propval[0] != 'f' && propval[0] != 'F')
+ mcr = 0;
+ /* set modem control bits */
+ outb(port + MCR, mcr | OUT2);
+}
+
+void
+bcons_init(char *bootstr)
+{
+ boot_line = bootstr;
+ console = CONS_INVALID;
+
+ if (strstr(bootstr, "console=ttya") != 0)
+ console = CONS_TTYA;
+ else if (strstr(bootstr, "console=ttyb") != 0)
+ console = CONS_TTYB;
+ else if (strstr(bootstr, "console=text") != 0)
+ console = CONS_SCREEN_TEXT;
+
+ /*
+ * If no console device specified, default to text.
+ * Remember what was specified for second phase.
+ */
+ if (console == CONS_INVALID)
+ console = CONS_SCREEN_TEXT;
+
+ switch (console) {
+ case CONS_TTYA:
+ case CONS_TTYB:
+ serial_init();
+ break;
+
+ case CONS_SCREEN_TEXT:
+ default:
+#if defined(_BOOT)
+ clear_screen(); /* clears the grub screen */
+#endif
+ kb_init();
+ break;
+ }
+ boot_line = NULL;
+}
+
+/*
+ * 2nd part of console initialization.
+ * In the kernel (ie. fakebop), this can be used only to switch to
+ * using a serial port instead of screen based on the contents
+ * of the bootenv.rc file.
+ */
+/*ARGSUSED*/
+void
+bcons_init2(char *inputdev, char *outputdev, char *consoledev)
+{
+#if !defined(_BOOT)
+ int cons = CONS_INVALID;
+
+ if (consoledev) {
+ if (strstr(consoledev, "ttya") != 0)
+ cons = CONS_TTYA;
+ else if (strstr(consoledev, "ttyb") != 0)
+ cons = CONS_TTYB;
+ else if (strstr(consoledev, "usb-serial") != 0)
+ cons = CONS_USBSER;
+ }
+
+ if (cons == CONS_INVALID && inputdev) {
+ if (strstr(inputdev, "ttya") != 0)
+ cons = CONS_TTYA;
+ else if (strstr(inputdev, "ttyb") != 0)
+ cons = CONS_TTYB;
+ else if (strstr(inputdev, "usb-serial") != 0)
+ cons = CONS_USBSER;
+ }
+
+ if (cons == CONS_INVALID && outputdev) {
+ if (strstr(outputdev, "ttya") != 0)
+ cons = CONS_TTYA;
+ else if (strstr(outputdev, "ttyb") != 0)
+ cons = CONS_TTYB;
+ else if (strstr(outputdev, "usb-serial") != 0)
+ cons = CONS_USBSER;
+ }
+
+ if (cons == CONS_INVALID)
+ return;
+ if (cons == console)
+ return;
+
+ console = cons;
+ if (cons == CONS_TTYA || cons == CONS_TTYB) {
+ serial_init();
+ return;
+ }
+
+ /*
+ * USB serial -- we just collect data into a buffer
+ */
+ if (cons == CONS_USBSER) {
+ extern void *usbser_init(size_t);
+ usbser_buf = usbser_cur = usbser_init(MMU_PAGESIZE);
+ }
+#endif /* _BOOT */
+}
+
+#if !defined(_BOOT)
+static void
+usbser_putchar(int c)
+{
+ if (usbser_cur - usbser_buf < MMU_PAGESIZE)
+ *usbser_cur++ = c;
+}
+#endif /* _BOOT */
+
+static void
+serial_putchar(int c)
+{
+ int checks = 10000;
+
+ while (((inb(port + LSR) & XHRE) == 0) && checks--)
+ ;
+ outb(port + DAT, (char)c);
+}
+
+static int
+serial_getchar(void)
+{
+ uchar_t lsr;
+
+ while (serial_ischar() == 0)
+ ;
+
+ lsr = inb(port + LSR);
+ if (lsr & (SERIAL_BREAK | SERIAL_FRAME |
+ SERIAL_PARITY | SERIAL_OVERRUN)) {
+ if (lsr & SERIAL_OVERRUN) {
+ return (inb(port + DAT));
+ } else {
+ /* Toss the garbage */
+ (void) inb(port + DAT);
+ return (0);
+ }
+ }
+ return (inb(port + DAT));
+}
+
+static int
+serial_ischar(void)
+{
+ return (inb(port + LSR) & RCA);
+}
+
+static void
+_doputchar(int c)
+{
+ switch (console) {
+ case CONS_TTYA:
+ case CONS_TTYB:
+ serial_putchar(c);
+ return;
+ case CONS_SCREEN_TEXT:
+ screen_putchar(c);
+ return;
+#if !defined(_BOOT)
+ case CONS_USBSER:
+ usbser_putchar(c);
+ return;
+#endif /* _BOOT */
+ }
+}
+
+void
+bcons_putchar(int c)
+{
+ static int bhcharpos = 0;
+
+ if (c == '\t') {
+ do {
+ _doputchar(' ');
+ } while (++bhcharpos % 8);
+ return;
+ } else if (c == '\n' || c == '\r') {
+ bhcharpos = 0;
+ _doputchar('\r');
+ _doputchar(c);
+ return;
+ } else if (c == '\b') {
+ if (bhcharpos)
+ bhcharpos--;
+ _doputchar(c);
+ return;
+ }
+
+ bhcharpos++;
+ _doputchar(c);
+}
+
+/*
+ * kernel character input functions
+ */
+int
+bcons_getchar(void)
+{
+ switch (console) {
+ case CONS_TTYA:
+ case CONS_TTYB:
+ return (serial_getchar());
+ default:
+ return (kb_getchar());
+ }
+}
+
+#if !defined(_BOOT)
+
+int
+bcons_ischar(void)
+{
+ switch (console) {
+ case CONS_TTYA:
+ case CONS_TTYB:
+ return (serial_ischar());
+ default:
+ return (kb_ischar());
+ }
+}
+
+#endif /* _BOOT */
diff --git a/usr/src/uts/i86pc/boot/boot_gdt.s b/usr/src/uts/i86pc/boot/boot_gdt.s
new file mode 100644
index 0000000000..99875989ee
--- /dev/null
+++ b/usr/src/uts/i86pc/boot/boot_gdt.s
@@ -0,0 +1,108 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#if defined(__lint)
+
+int global_descriptor_table[0x10];
+
+#else /* __lint */
+
+ .align 16
+
+ /*
+ * This must remain in sync with the entries in intel/sys/gdt.h; in
+ * particular kmdb uses B64CODE_SEL or B32CODE_SEL in perpetuity for
+ * its IDT entries (they're copied to the kernel's GDT in init_idt()).
+ */
+
+global_descriptor_table:
+ .long 0
+ .long 0
+
+ /* GDT_B32DATA: 32 bit flat data descriptor */
+ .value 0xFFFF /* segment limit 0..15 */
+ .value 0x0000 /* segment base 0..15 */
+ .byte 0x0 /* segment base 16..23 */
+ .byte 0x92 /* P = 1, read/write data */
+ .byte 0xCF /* G=1, B=1, Limit (16..19)=1111 */
+ .byte 0x0 /* segment base 24..32 */
+
+ /* GDT_B32CODE 32 bit flat code descriptor */
+ .value 0xFFFF /* segment limit 0..15 */
+ .value 0x0000 /* segment base 0..15 */
+ .byte 0x0 /* segment base 16..23 */
+ .byte 0x9E /* P=1, code, exec, readable */
+ .byte 0xCF /* G=1, D=1, Limit (16..19)=1111 */
+ .byte 0x0 /* segment base 24..32 */
+
+ /*
+ * GDT_B16CODE 16 bit code descriptor for doing BIOS calls
+ */
+ .value 0xFFFF /* segment limit 0..15 */
+ .value 0x0000 /* segment base 0..15 */
+ .byte 0x0 /* segment base 16..23 */
+ .byte 0x9E /* P=1, code, exec, readable */
+ .byte 0x0F /* G=0, D=0, Limit (16..19)=1111 */
+ .byte 0x0 /* segment base 24..32 */
+
+ /*
+ * GDT_B16DATA 16 bit data descriptor for doing BIOS calls
+ */
+ .value 0xFFFF /* segment limit 0..15 */
+ .value 0x0000 /* segment base 0..15 */
+ .byte 0x0 /* segment base 16..23 */
+ .byte 0x92 /* P = 1, read/write data */
+ .byte 0x4F /* G=0, D=1, Limit (16..19)=1111 */
+ .byte 0x0 /* segment base 24..32 */
+
+ /* GDT_B64CODE: 64 bit flat code descriptor - only L bit has meaning */
+ .value 0xFFFF /* segment limit 0..15 */
+ .value 0x0000 /* segment base 0..15 */
+ .byte 0x0 /* segment base 16..23 */
+ .byte 0x9E /* P=1, code, exec, readable */
+ .byte 0xAF /* G=1, D=0, L=1, Limit (16..19)=1111 */
+ .byte 0x0 /* segment base 24..32 */
+
+ /*
+ * unused
+ */
+ .long 0
+ .long 0
+
+ /*
+ * GDT_BGSTMP -- an entry for kmdb to use during boot
+ */
+ .long 0
+ .long 0
+
+gdt_info:
+ .value gdt_info - global_descriptor_table - 1
+ .long global_descriptor_table
+ .long 0 /* needed for 64 bit */
+
+#endif /* __lint */
diff --git a/usr/src/psm/stand/boot/i386/common/keyboard.c b/usr/src/uts/i86pc/boot/boot_keyboard.c
index dc3f09d68c..7f362b648f 100644
--- a/usr/src/psm/stand/boot/i386/common/keyboard.c
+++ b/usr/src/uts/i86pc/boot/boot_keyboard.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,11 +32,13 @@
*/
#include <sys/types.h>
-#include "chario.h"
-#include "keyboard_table.h"
-#include "console.h"
-#include "util.h"
-#include "debug.h"
+#include <sys/archsystm.h>
+#include <sys/boot_console.h>
+#include "boot_keyboard_table.h"
+
+#if defined(_BOOT)
+#include "dboot/dboot_xboot.h"
+#endif
/*
* Definitions for BIOS keyboard state. We use BIOS's variable to store
@@ -98,8 +100,6 @@
#define peek8(p) (*(p))
#define poke8(p, val) (*(p) = (val))
-#define peeks(p) (*(p))
-#define pokes(p, val) (*(p) = (val))
static struct {
boolean_t initialized;
@@ -123,8 +123,6 @@ static struct {
-1, /* pending */
};
-#define kb_debug (debug & D_KEYBOARD)
-
static int kb_translate(unsigned char code);
static void kb_send(unsigned char cmd);
static void kb_update_leds(void);
@@ -135,9 +133,6 @@ kb_getchar(void)
{
int ret;
- if (kb_debug)
- printf(" getchar()");
-
while (!kb_ischar())
/* LOOP */;
@@ -155,9 +150,6 @@ kb_getchar(void)
kb.pending = -1;
}
- if (kb_debug)
- printf("=0x%x ", ret);
-
return (ret);
}
@@ -167,16 +159,12 @@ kb_ischar(void)
unsigned char buffer_stat;
unsigned char code;
unsigned char leds;
- static int cnt = 0;
if (!kb.initialized) {
kb_init();
kb.initialized = B_TRUE;
}
- if (kb_debug)
- printf("%c\b", "/-\\|"[cnt++ % 4]);
-
if (kb.pending >= 0)
return (1);
@@ -200,9 +188,6 @@ kb_ischar(void)
code = inb(I8042_DATA);
- if (kb_debug)
- printf("0x%x->", code);
-
switch (code) {
/*
* case 0xAA:
@@ -219,8 +204,6 @@ kb_ischar(void)
* in this mini-driver.
*/
case 0xFA:
- if (kb_debug)
- printf("ack ");
switch (kb.led_state) {
case KB_LED_IDLE:
@@ -253,80 +236,53 @@ kb_ischar(void)
* We don't care, and the codes are carefully arranged
* so that we don't have to.
*/
- if (kb_debug)
- printf("ignored ");
continue;
default:
if (code & 0x80) {
- if (kb_debug)
- printf("release->");
/* Release */
code &= 0x7f;
switch (keyboard_translate[code].normal) {
case KBTYPE_SPEC_LSHIFT:
poke8(kb_flag, peek8(kb_flag) &
~BIOS_LEFT_SHIFT);
- if (kb_debug)
- printf("lshift ");
break;
case KBTYPE_SPEC_RSHIFT:
poke8(kb_flag, peek8(kb_flag) &
~BIOS_RIGHT_SHIFT);
- if (kb_debug)
- printf("rshift ");
break;
case KBTYPE_SPEC_CTRL:
poke8(kb_flag, peek8(kb_flag) &
~BIOS_CTL_SHIFT);
- if (kb_debug)
- printf("ctrl ");
break;
case KBTYPE_SPEC_ALT:
poke8(kb_flag, peek8(kb_flag) &
~BIOS_ALT_SHIFT);
- if (kb_debug)
- printf("alt ");
break;
case KBTYPE_SPEC_CAPS_LOCK:
poke8(kb_flag_1, peek8(kb_flag_1) &
~BIOS_CAPS_SHIFT);
- if (kb_debug)
- printf("caps ");
break;
case KBTYPE_SPEC_NUM_LOCK:
poke8(kb_flag_1, peek8(kb_flag_1) &
~BIOS_NUM_SHIFT);
- if (kb_debug)
- printf("num ");
break;
case KBTYPE_SPEC_SCROLL_LOCK:
poke8(kb_flag_1, peek8(kb_flag_1) &
~BIOS_SCROLL_SHIFT);
- if (kb_debug)
- printf("scroll ");
break;
default:
/*
* Ignore all other releases.
*/
- if (kb_debug)
- printf("ignored ");
break;
}
} else {
/* Press */
- if (kb_debug)
- printf("press->");
kb.pending = kb_translate(code);
if (kb.pending >= 0) {
- if (kb_debug)
- printf("0x%x ", kb.pending);
return (1);
- } else {
- if (kb_debug)
- printf("ignored ");
}
}
}
@@ -430,11 +386,13 @@ kb_translate(unsigned char code)
break;
case KBTYPE_SPEC_MAYBE_REBOOT:
+#if 0 /* Solaris doesn't reboot via ctrl-alt-del */
if ((peek8(kb_flag) & (BIOS_CTL_SHIFT|BIOS_ALT_SHIFT)) ==
(BIOS_CTL_SHIFT|BIOS_ALT_SHIFT)) {
reset();
/* NOTREACHED */
}
+#endif
break;
default:
@@ -560,5 +518,5 @@ kb_calculate_leds(void)
if (peek8(kb_flag) & BIOS_SCROLL_STATE)
res |= KB_LED_SCROLL_LOCK;
- return (res);
+ return ((char)res);
}
diff --git a/usr/src/uts/i86pc/boot/boot_keyboard.h b/usr/src/uts/i86pc/boot/boot_keyboard.h
new file mode 100644
index 0000000000..390bb1f4fe
--- /dev/null
+++ b/usr/src/uts/i86pc/boot/boot_keyboard.h
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _BOOT_KEYBOARD_H
+#define _BOOT_KEYBOARD_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Interfaces to the simple keyboard driver.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int kb_ischar(void);
+char kb_getchar(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BOOT_KEYBOARD_H */
diff --git a/usr/src/psm/stand/boot/i386/common/keyboard_table.c b/usr/src/uts/i86pc/boot/boot_keyboard_table.c
index 64d57720df..6c352001f7 100644
--- a/usr/src/psm/stand/boot/i386/common/keyboard_table.c
+++ b/usr/src/uts/i86pc/boot/boot_keyboard_table.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,17 +19,17 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1999 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
- * Keyboard table for bootstrap's miniature keyboard driver.
+ * Keyboard table for bootstrap's simple keyboard driver.
*/
-#include "keyboard_table.h"
+#include "boot_keyboard_table.h"
#define A | KBTYPE_ALPHA
#define C & 0x1f
diff --git a/usr/src/psm/stand/boot/i386/common/keyboard_table.h b/usr/src/uts/i86pc/boot/boot_keyboard_table.h
index 2b72bdc0a3..4720d688a7 100644
--- a/usr/src/psm/stand/boot/i386/common/keyboard_table.h
+++ b/usr/src/uts/i86pc/boot/boot_keyboard_table.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,17 +19,17 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1999 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
-#ifndef _KEYBOARD_TABLE_H
-#define _KEYBOARD_TABLE_H
+#ifndef _BOOT_KEYBOARD_TABLE_H
+#define _BOOT_KEYBOARD_TABLE_H
#pragma ident "%Z%%M% %I% %E% SMI"
/*
- * Structure of the keyboard table for the bootstrap miniature
+ * Structure of the keyboard table for the bootstrap simple
* keyboard driver.
*/
@@ -48,16 +47,16 @@ extern "C" {
#define KBTYPE_FUNC 0x300 /* Extended Function. Send this code, */
/* prefixed with zero. */
#define KBTYPE_SPEC 0x400 /* One-of-a-kind codes. Self-explanatory. */
-#define KBTYPE_SPEC_NOP (KBTYPE_SPEC | 0x00)
-#define KBTYPE_SPEC_UNDEF (KBTYPE_SPEC | 0x01)
-#define KBTYPE_SPEC_LSHIFT (KBTYPE_SPEC | 0x02)
-#define KBTYPE_SPEC_RSHIFT (KBTYPE_SPEC | 0x03)
-#define KBTYPE_SPEC_CTRL (KBTYPE_SPEC | 0x04)
-#define KBTYPE_SPEC_ALT (KBTYPE_SPEC | 0x05)
-#define KBTYPE_SPEC_CAPS_LOCK (KBTYPE_SPEC | 0x06)
-#define KBTYPE_SPEC_NUM_LOCK (KBTYPE_SPEC | 0x07)
-#define KBTYPE_SPEC_SCROLL_LOCK (KBTYPE_SPEC | 0x08)
-#define KBTYPE_SPEC_MAYBE_REBOOT (KBTYPE_SPEC | 0x09)
+#define KBTYPE_SPEC_NOP (KBTYPE_SPEC | 0x00)
+#define KBTYPE_SPEC_UNDEF (KBTYPE_SPEC | 0x01)
+#define KBTYPE_SPEC_LSHIFT (KBTYPE_SPEC | 0x02)
+#define KBTYPE_SPEC_RSHIFT (KBTYPE_SPEC | 0x03)
+#define KBTYPE_SPEC_CTRL (KBTYPE_SPEC | 0x04)
+#define KBTYPE_SPEC_ALT (KBTYPE_SPEC | 0x05)
+#define KBTYPE_SPEC_CAPS_LOCK (KBTYPE_SPEC | 0x06)
+#define KBTYPE_SPEC_NUM_LOCK (KBTYPE_SPEC | 0x07)
+#define KBTYPE_SPEC_SCROLL_LOCK (KBTYPE_SPEC | 0x08)
+#define KBTYPE_SPEC_MAYBE_REBOOT (KBTYPE_SPEC | 0x09)
struct keyboard_translate {
unsigned short normal;
@@ -72,4 +71,4 @@ extern struct keyboard_translate keyboard_translate[128];
}
#endif
-#endif /* _KEYBOARD_TABLE_H */
+#endif /* _BOOT_KEYBOARD_TABLE_H */
diff --git a/usr/src/uts/i86pc/boot/boot_mmu.c b/usr/src/uts/i86pc/boot/boot_mmu.c
new file mode 100644
index 0000000000..6c7622f4e1
--- /dev/null
+++ b/usr/src/uts/i86pc/boot/boot_mmu.c
@@ -0,0 +1,121 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * WARNING: This file is used by both dboot and the kernel.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/param.h>
+#include <sys/machparam.h>
+#include <sys/mach_mmu.h>
+
+#ifdef _BOOT
+#include <dboot/dboot_printf.h>
+#define bop_panic dboot_panic
+#else
+#include <sys/bootconf.h>
+#endif
+
+uint_t shift_amt_nopae[] = {12, 22};
+uint_t shift_amt_pae[] = {12, 21, 30, 39};
+uint_t *shift_amt;
+uint_t ptes_per_table;
+uint_t pte_size;
+uint32_t lpagesize;
+paddr_t top_page_table;
+uint_t top_level;
+
+/*
+ * Return the index corresponding to a virt address at a given page table level.
+ */
+static uint_t
+vatoindex(uint64_t va, uint_t level)
+{
+ return ((va >> shift_amt[level]) & (ptes_per_table - 1));
+}
+
+/*
+ * Return a pointer to the page table entry that maps a virtual address.
+ * If there is no page table and probe_only is not set, one is created.
+ */
+x86pte_t *
+find_pte(uint64_t va, paddr_t *pa, uint_t level, uint_t probe_only)
+{
+ uint_t l;
+ uint_t index;
+ paddr_t table;
+
+ if (pa)
+ *pa = 0;
+
+#ifndef _BOOT
+ if (IN_HYPERVISOR_VA(va))
+ return (NULL);
+#endif
+
+ /*
+ * Walk down the page tables creating any needed intermediate tables.
+ */
+ table = top_page_table;
+ for (l = top_level; l != level; --l) {
+ uint64_t pteval;
+ paddr_t new_table;
+
+ index = vatoindex(va, l);
+ pteval = get_pteval(table, index);
+
+ /*
+ * Life is easy if we find the pagetable. We just use it.
+ */
+ if (pteval & PT_VALID) {
+ table = ma_to_pa(pteval & MMU_PAGEMASK);
+ if (table == -1) {
+ if (probe_only)
+ return (NULL);
+ bop_panic("find_pte(): phys not found!");
+ }
+ continue;
+ }
+
+ if (probe_only)
+ return (NULL);
+
+ new_table = make_ptable(&pteval, l);
+ set_pteval(table, index, l, pteval);
+
+ table = new_table;
+ }
+
+ /*
+ * Return a pointer into the current pagetable.
+ */
+ index = vatoindex(va, l);
+ if (pa)
+ *pa = table + index * pte_size;
+ return (map_pte(table, index));
+}
diff --git a/usr/src/uts/i86pc/boot/boot_serial.h b/usr/src/uts/i86pc/boot/boot_serial.h
new file mode 100644
index 0000000000..dd031f4f9a
--- /dev/null
+++ b/usr/src/uts/i86pc/boot/boot_serial.h
@@ -0,0 +1,148 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _BOOT_SERIAL_H
+#define _BOOT_SERIAL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ---- ports on 16550 serial chips ---- */
+#define DAT 0 /* ... data */
+#define ICR 1 /* ... intr control reg */
+#define ISR 2 /* ... intr status reg */
+#define LCR 3 /* ... line control reg */
+#define MCR 4 /* ... modem control reg */
+#define LSR 5 /* ... line status reg */
+#define MSR 6 /* ... modem status reg */
+#define DLL 0 /* ... data latch low (used for baud rate) */
+#define DLH 1 /* ... data latch high (ditto) */
+#define FIFOR ISR /* ... fifo write reg */
+
+/* ---- LSR bits ---- */
+#define RCA 0x01 /* ... receive char avail */
+#define XHRE 0x20 /* ... xmit hold buffer empty */
+
+/* ---- Modem bits ---- */
+#define DTR 0x01
+#define RTS 0x02
+#define OUT2 0x08
+
+#define FIFO_ON 0x01
+#define FIFO_OFF 0x00
+#define FIFORXFLSH 0x02
+#define FIFOTXFLSH 0x04
+#define FIFODMA 0x08
+
+/* ---- LCR bits ---- */
+#define STOP1 00
+#define STOP2 0x04
+#define BITS5 0x00 /* 5 bits per char */
+#define BITS6 0x01 /* 6 bits per char */
+#define BITS7 0x02 /* 7 bits per char */
+#define BITS8 0x03 /* 8 bits per char */
+
+/* baud rate definitions */
+#define DLAB 0x80 /* divisor latch access bit */
+#define ASY110 1047 /* 110 baud rate for serial console */
+#define ASY150 768 /* 150 baud rate for serial console */
+#define ASY300 384 /* 300 baud rate for serial console */
+#define ASY600 192 /* 600 baud rate for serial console */
+#define ASY1200 96 /* 1200 baud rate for serial console */
+#define ASY2400 48 /* 2400 baud rate for serial console */
+#define ASY4800 24 /* 4800 baud rate for serial console */
+#define ASY9600 12 /* 9600 baud rate for serial console */
+#define ASY19200 6 /* 19200 baud rate for serial console */
+#define ASY38400 3 /* 38400 baud rate for serial console */
+#define ASY57600 2 /* 57600 baud rate for serial console */
+#define ASY115200 1 /* 115200 baud rate for serial console */
+
+
+/*
+ * Defines for the serial port
+ */
+
+#define SERIAL_FIFO_FLUSH 16 /* maximum number of chars to flush */
+
+/* ---- Bit 11 defines direct serial port ---- */
+#define SDIRECT 0x1000
+
+/* ---- Bits 9-10 define flow control ---- */
+#define SSOFT 0x800
+#define SHARD 0x400
+
+/* ---- Bits 5-8 define baud rate ---- */
+#define S110 0x00
+#define S150 0x20
+#define S300 0x40
+#define S600 0x60
+#define S1200 0x80
+#define S2400 0xa0
+#define S4800 0xc0
+#define S9600 0xe0
+#define S19200 0x100
+#define S38400 0x120
+#define S57600 0x140
+#define S76800 0x160
+#define S115200 0x180
+#define S153600 0x1a0
+#define S230400 0x1c0
+#define S307200 0x1e0
+#define S460800 0x200
+
+/* ---- Bits 3 & 4 are parity ---- */
+#define PARITY_NONE 0x10
+#define PARITY_ODD 0x08
+#define PARITY_EVEN 0x18
+
+/* ---- Bit 2 is stop bit ---- */
+#define STOP_1 0x00
+#define STOP_2 0x04
+
+/* ---- Bits 0 & 1 are data bits ---- */
+#define DATA_8 0x03
+#define DATA_7 0x02
+#define DATA_6 0x01
+#define DATA_5 0x00
+
+/* ---- Line Status ---- */
+#define SERIAL_TIMEOUT 0x80
+#define SERIAL_XMITSHFT 0x40
+#define SERIAL_XMITHOLD 0x20
+#define SERIAL_BREAK 0x10
+#define SERIAL_FRAME 0x08
+#define SERIAL_PARITY 0x04
+#define SERIAL_OVERRUN 0x02
+#define SERIAL_DATA 0x01
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BOOT_SERIAL_H */
diff --git a/usr/src/psm/stand/boot/i386/common/vga.c b/usr/src/uts/i86pc/boot/boot_vga.c
index d534894cc3..7de0682776 100644
--- a/usr/src/psm/stand/boot/i386/common/vga.c
+++ b/usr/src/uts/i86pc/boot/boot_vga.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,8 +32,12 @@
#include <sys/archsystm.h>
#include <sys/vgareg.h>
-#include "util.h"
-#include "vga.h"
+
+#include "boot_vga.h"
+
+#if defined(_BOOT)
+#include "../dboot/dboot_xboot.h"
+#endif
#define VGA_COLOR_CRTC_INDEX 0x3d4
#define VGA_COLOR_CRTC_DATA 0x3d5
diff --git a/usr/src/psm/stand/boot/i386/common/vga.h b/usr/src/uts/i86pc/boot/boot_vga.h
index ec7fd2c371..87f818fc41 100644
--- a/usr/src/psm/stand/boot/i386/common/vga.h
+++ b/usr/src/uts/i86pc/boot/boot_vga.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,12 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#ifndef _VGA_H
-#define _VGA_H
+#ifndef _BOOT_VGA_H
+#define _BOOT_VGA_H
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -54,4 +53,4 @@ extern void vga_drawc(int, int);
}
#endif
-#endif /* _VGA_H */
+#endif /* _BOOT_VGA_H */
diff --git a/usr/src/uts/i86pc/conf/Mapfile b/usr/src/uts/i86pc/conf/Mapfile
index 73b304e07c..b822134be1 100644
--- a/usr/src/uts/i86pc/conf/Mapfile
+++ b/usr/src/uts/i86pc/conf/Mapfile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -19,21 +18,28 @@
#
# CDDL HEADER END
#
-# Copyright 2000 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
-text = LOAD ?RXN V0xFE800000;
+#
+# this is the 32 bit 1:1 mapped code to which grub jumps.
+#
+dboot = LOAD ?RWXN P0xC00000 V0xC00000;
+dboot : $PROGBITS ?AW : *dboot.o;
+
+#
+# this is the kernel text
+#
+text = LOAD ?RXN P0x400000 V0xFE800000;
text | .text;
text : $PROGBITS ?A!W;
#
# start the data segment on a new 4MB page boundary
-# Not all x86 machines support 4MB pages so startup()
-# has to deal with that edge case.
#
-data = LOAD ?RWX V0xFEc00000 A0x1000;
+data = LOAD ?RWX P0x800000 V0xFEc00000;
data | .data;
data : $PROGBITS ?AW;
data : $NOBITS ?AW;
diff --git a/usr/src/uts/i86pc/conf/Mapfile.amd64 b/usr/src/uts/i86pc/conf/Mapfile.amd64
index 6afe016b73..fca1e493c3 100644
--- a/usr/src/uts/i86pc/conf/Mapfile.amd64
+++ b/usr/src/uts/i86pc/conf/Mapfile.amd64
@@ -1,13 +1,12 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -27,16 +26,20 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#
-text = LOAD ?RXN V0xFFFFFFFFFB800000;
+#
+# this is the 32 bit 1:1 mapped code to which grub jumps.
+#
+dboot = LOAD ?RWXN P0xC00000 V0xC00000;
+dboot : $PROGBITS ?AW : *dboot.o;
+
+text = LOAD ?RXN P0x400000 V0xFFFFFFFFFB800000;
text | .text;
text : $PROGBITS ?A!W;
#
-# start the data segment on a new 4MB page boundary
-# Not all x86 machines support 4MB pages so startup()
-# has to deal with that edge case.
+# kernel data
#
-data = LOAD ?RWX V0xFFFFFFFFFBc00000 A0x1000;
+data = LOAD ?RWX P0x800000 V0xFFFFFFFFFBc00000;
data | .data;
data : $PROGBITS ?AW;
data : $NOBITS ?AW;
diff --git a/usr/src/uts/i86pc/conf/Mapfile.bios b/usr/src/uts/i86pc/conf/Mapfile.bios
new file mode 100644
index 0000000000..18aa3ef9fc
--- /dev/null
+++ b/usr/src/uts/i86pc/conf/Mapfile.bios
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+bios = LOAD ?NRWX V0x5000 P0x5000 A0x1000;
+bios : ?A;
diff --git a/usr/src/uts/intel/consconfig_dacf/Makefile b/usr/src/uts/i86pc/consconfig_dacf/Makefile
index a9c1c27c38..3867201c6b 100644
--- a/usr/src/uts/intel/consconfig_dacf/Makefile
+++ b/usr/src/uts/i86pc/consconfig_dacf/Makefile
@@ -19,9 +19,9 @@
# CDDL HEADER END
#
#
-# uts/intel/consconfig_dacf/Makefile
+# uts/i86pc/consconfig_dacf/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -39,12 +39,12 @@ UTSBASE = ../..
MODULE = consconfig_dacf
OBJECTS = $(CONSCONFIG_DACF_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(CONSCONFIG_DACF_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_DACF_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_PSM_DACF_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/intel/Makefile.intel
+include $(UTSBASE)/i86pc/Makefile.i86pc
#
# Define targets
@@ -79,4 +79,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/intel/Makefile.targ
+include $(UTSBASE)/i86pc/Makefile.targ
diff --git a/usr/src/uts/i86pc/dboot/dboot_elfload.c b/usr/src/uts/i86pc/dboot/dboot_elfload.c
new file mode 100644
index 0000000000..5260d2d405
--- /dev/null
+++ b/usr/src/uts/i86pc/dboot/dboot_elfload.c
@@ -0,0 +1,168 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/inttypes.h>
+#include <sys/systm.h>
+#include <sys/elf.h>
+#include <sys/elf_notes.h>
+
+#include <util/memcpy.h>
+
+#include "dboot_xboot.h"
+#include "dboot_elfload.h"
+#include "dboot_printf.h"
+
+static caddr_t elf_file = 0;
+
+#define PGETBYTES(offset) ((void *)(elf_file + (offset)))
+
+static void *
+getehdr(void)
+{
+ uchar_t *ident;
+ void *hdr = NULL;
+
+ ident = PGETBYTES(0);
+ if (ident == NULL)
+ dboot_panic("Cannot read kernel ELF header\n");
+
+ if (ident[EI_MAG0] != ELFMAG0 || ident[EI_MAG1] != ELFMAG1 ||
+ ident[EI_MAG2] != ELFMAG2 || ident[EI_MAG3] != ELFMAG3)
+ dboot_panic("not an ELF file!\n");
+
+ if (ident[EI_CLASS] == ELFCLASS32)
+ hdr = PGETBYTES(0);
+ else if (ident[EI_CLASS] == ELFCLASS64)
+ hdr = PGETBYTES(0);
+ else
+ dboot_panic("Unknown ELF class\n");
+
+ return (hdr);
+}
+
+
+/*
+ * parse the elf file for program information
+ */
+int
+dboot_elfload64(uintptr_t file_image)
+{
+ Elf64_Ehdr *eh;
+ Elf64_Phdr *phdr;
+ caddr_t allphdrs;
+ int i;
+ paddr_t src;
+ paddr_t dst;
+
+ elf_file = (caddr_t)file_image;
+
+ allphdrs = NULL;
+
+ eh = getehdr();
+ if (eh == NULL)
+ dboot_panic("getehdr() failed\n");
+
+ if (eh->e_type != ET_EXEC)
+ dboot_panic("not ET_EXEC, e_type = 0x%x\n", eh->e_type);
+
+ if (eh->e_phnum == 0 || eh->e_phoff == 0)
+ dboot_panic("no program headers\n");
+
+ /*
+ * Get the program headers.
+ */
+ allphdrs = PGETBYTES(eh->e_phoff);
+ if (allphdrs == NULL)
+ dboot_panic("Failed to get program headers e_phnum = %d\n",
+ eh->e_phnum);
+
+ /*
+ * Next look for interesting program headers.
+ */
+ for (i = 0; i < eh->e_phnum; i++) {
+ /*LINTED [ELF program header alignment]*/
+ phdr = (Elf64_Phdr *)(allphdrs + eh->e_phentsize * i);
+
+ /*
+ * Dynamically-linked executable.
+ * Complain.
+ */
+ if (phdr->p_type == PT_INTERP) {
+ dboot_printf("warning: PT_INTERP section\n");
+ continue;
+ }
+
+ /*
+ * at this point we only care about PT_LOAD segments
+ */
+ if (phdr->p_type != PT_LOAD)
+ continue;
+
+ if (phdr->p_flags == (PF_R | PF_W) && phdr->p_vaddr == 0) {
+ dboot_printf("warning: krtld reloc info?\n");
+ continue;
+ }
+
+ /*
+ * If memory size is zero just ignore this header.
+ */
+ if (phdr->p_memsz == 0)
+ continue;
+
+ /*
+ * If load address 1:1 then ignore this header.
+ */
+ if (phdr->p_paddr == phdr->p_vaddr) {
+ if (prom_debug)
+ dboot_printf("Skipping PT_LOAD segment for "
+ "paddr = 0x%lx\n", (ulong_t)phdr->p_paddr);
+ continue;
+ }
+
+ /*
+ * copy the data to kernel area
+ */
+ if (phdr->p_paddr != FOUR_MEG && phdr->p_paddr != 2 * FOUR_MEG)
+ dboot_panic("Bad paddr for kernel nucleus segment\n");
+ src = (uintptr_t)PGETBYTES(phdr->p_offset);
+ dst = ktext_phys + phdr->p_paddr - FOUR_MEG;
+ if (prom_debug)
+ dboot_printf("copying %lu bytes from ELF offset 0x%lx "
+ "to physaddr 0x%lx (va=0x%lx)\n",
+ (ulong_t)phdr->p_filesz, (ulong_t)phdr->p_offset,
+ (ulong_t)dst, (ulong_t)phdr->p_vaddr);
+ (void) memcpy((void *)(uintptr_t)dst,
+ (void *)(uintptr_t)src, (size_t)phdr->p_filesz);
+ }
+
+ /*
+ * Ignore the intepreter (or should we die if there is one??)
+ */
+ return (0);
+}
diff --git a/usr/src/uts/i86pc/dboot/dboot_elfload.h b/usr/src/uts/i86pc/dboot/dboot_elfload.h
new file mode 100644
index 0000000000..16b7a16011
--- /dev/null
+++ b/usr/src/uts/i86pc/dboot/dboot_elfload.h
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ELFLOAD_H
+#define _ELFLOAD_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dboot_elfload64(uintptr_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ELFLOAD_H */
diff --git a/usr/src/uts/i86pc/dboot/dboot_grub.s b/usr/src/uts/i86pc/dboot/dboot_grub.s
new file mode 100644
index 0000000000..503e1fd31c
--- /dev/null
+++ b/usr/src/uts/i86pc/dboot/dboot_grub.s
@@ -0,0 +1,283 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#if defined(__lint)
+
+int silence_lint_warnings = 0;
+
+#else /* __lint */
+
+#include <sys/multiboot.h>
+#include <sys/asm_linkage.h>
+#include <sys/segments.h>
+#include <sys/controlregs.h>
+
+#include "dboot_xboot.h"
+
+ .text
+ .globl _start
+_start:
+ jmp code_start
+
+ /*
+ * The multiboot header has to be at the start of the file
+ *
+ * The 32 bit kernel is ELF32, so the MB header is mostly ignored.
+ *
+ * The 64 bit kernel is ELF64, so we get grub to load the entire
+ * ELF file into memory and trick it into jumping into this code.
+ * The trick is done by a binary utility run after unix is linked,
+ * that rewrites the mb_header.
+ */
+ .align 4
+ .globl mb_header
+mb_header:
+ .long MB_HEADER_MAGIC /* magic number */
+ .long MB_HEADER_FLAGS /* flags */
+ .long MB_HEADER_CHECKSUM /* checksum */
+ .long 0x11111111 /* header_addr: patched by elfpatch */
+ .long 0x100000 /* load_addr: patched by elfpatch */
+ .long 0 /* load_end_addr - 0 means entire file */
+ .long 0 /* bss_end_addr */
+ .long 0x2222222 /* entry_addr: patched by elfpatch */
+ .long 0 /* video mode.. */
+ .long 0 /* width 0 == don't care */
+ .long 0 /* height 0 == don't care */
+ .long 0 /* depth 0 == don't care */
+
+ /*
+ * At entry we are in protected mode, 32 bit execution, paging and
+ * interrupts are disabled.
+ *
+ * EAX == 0x2BADB002
+ * EBX points to multiboot information
+ * segment registers all have segments with base 0, limit == 0xffffffff
+ */
+code_start:
+ movl %ebx, mb_info
+
+ movl $stack_space, %esp /* load my stack pointer */
+ addl $STACK_SIZE, %esp
+
+ pushl $0x0 /* push a dead-end frame */
+ pushl $0x0
+ movl %esp, %ebp
+
+ pushl $0x0 /* clear all processor flags */
+ popf
+
+ /*
+ * setup a global descriptor table with known contents
+ */
+ lgdt gdt_info
+ movw $B32DATA_SEL, %ax
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %fs
+ movw %ax, %gs
+ movw %ax, %ss
+ ljmp $B32CODE_SEL, $newgdt
+newgdt:
+ nop
+
+ /*
+ * go off and determine memory config, build page tables, etc.
+ */
+ call startup_kernel
+
+ /*
+ * On amd64 we'll want the stack pointer to be 16 byte aligned.
+ */
+ andl $0xfffffff0, %esp
+
+ /*
+ * Enable PGE, PAE and large pages
+ */
+ movl %cr4, %eax
+ testl $1, pge_support
+ jz 1f
+ orl $CR4_PGE, %eax
+1:
+ testl $1, pae_support
+ jz 1f
+ orl $CR4_PAE, %eax
+1:
+ testl $1, largepage_support
+ jz 1f
+ orl $CR4_PSE, %eax
+1:
+ movl %eax, %cr4
+
+ /*
+ * enable NX protection if processor supports it
+ */
+ testl $1, NX_support
+ jz 1f
+ movl $MSR_AMD_EFER, %ecx
+ rdmsr
+ orl $AMD_EFER_NXE, %eax
+ wrmsr
+1:
+
+
+ /*
+ * load the pagetable base address into cr3
+ */
+ movl top_page_table, %eax
+ movl %eax, %cr3
+
+#if defined(_BOOT_TARGET_amd64)
+ /*
+ * enable long mode
+ */
+ movl $MSR_AMD_EFER, %ecx
+ rdmsr
+ orl $AMD_EFER_LME, %eax
+ wrmsr
+#endif
+
+ /*
+ * enable paging
+ */
+ movl %cr0, %eax
+ orl $CR0_PG, %eax
+ movl %eax, %cr0
+ jmp paging_on
+paging_on:
+
+ /*
+ * The xboot_info ptr gets passed to the kernel as its argument
+ */
+ movl bi, %edi
+ movl entry_addr_low, %esi
+
+#if defined(_BOOT_TARGET_i386)
+
+ pushl %edi
+ call *%esi
+
+#elif defined(_BOOT_TARGET_amd64)
+
+ /*
+ * We're still in compatibility mode with 32 bit execution.
+ * Switch to 64 bit mode now by switching to a 64 bit code segment.
+ * then set up and do a lret to get into 64 bit execution.
+ */
+ pushl $B64CODE_SEL
+ pushl $longmode
+ lret
+longmode:
+ .code64
+ movq $0xffffffff00000000,%rdx
+ orq %rdx, %rsi /* set upper bits of entry addr */
+ notq %rdx
+ andq %rdx, %rdi /* clean %rdi for passing arg */
+ call *%rsi
+
+#else
+#error "undefined target"
+#endif
+
+ .code32
+
+ /*
+ * uint8_t inb(int port)
+ */
+ ENTRY_NP(inb)
+ movl 4(%esp), %edx
+ inb (%dx)
+ andl $0xff, %eax
+ ret
+ SET_SIZE(inb)
+
+ /*
+ * void outb(int port, uint8_t value)
+ */
+ ENTRY_NP(outb)
+ movl 4(%esp), %edx
+ movl 8(%esp), %eax
+ outb (%dx)
+ ret
+ SET_SIZE(outb)
+
+ /*
+ * if reset fails halt the system
+ */
+ ENTRY_NP(dboot_halt)
+ hlt
+ SET_SIZE(dboot_halt)
+
+ /*
+ * flush the TLB
+ */
+ ENTRY_NP(reload_cr3)
+ movl %cr3, %eax
+ movl %eax, %cr3
+ ret
+ SET_SIZE(reload_cr3)
+
+ /*
+ * do a cpuid instruction, returning the eax/edx values
+ */
+ ENTRY_NP(get_cpuid_edx)
+ movl 4(%esp), %ecx
+ movl (%ecx), %eax
+ pushl %ebx
+ cpuid
+ popl %ebx
+ movl 4(%esp), %ecx
+ movl %eax, (%ecx)
+ movl %edx, %eax
+ ret
+ SET_SIZE(get_cpuid_edx)
+
+ /*
+ * Detect if we can do cpuid, see if we can change bit 21 of eflags.
+ * Note we don't do the bizarre tests for Cyrix CPUs in ml/locore.s.
+ * If you're on such a CPU, you're stuck with non-PAE 32 bit kernels.
+ */
+ ENTRY_NP(have_cpuid)
+ pushf
+ pushf
+ xorl %eax, %eax
+ popl %ecx
+ movl %ecx, %edx
+ xorl $0x200000, %ecx
+ pushl %ecx
+ popf
+ pushf
+ popl %ecx
+ cmpl %ecx, %edx
+ setne %al
+ popf
+ ret
+ SET_SIZE(have_cpuid)
+
+#include "../boot/boot_gdt.s"
+
+#endif /* __lint */
diff --git a/usr/src/uts/i86pc/dboot/dboot_printf.c b/usr/src/uts/i86pc/dboot/dboot_printf.c
new file mode 100644
index 0000000000..44450a8c2d
--- /dev/null
+++ b/usr/src/uts/i86pc/dboot/dboot_printf.c
@@ -0,0 +1,205 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/machparam.h>
+#include <sys/archsystm.h>
+
+#include <sys/boot_console.h>
+
+#include "dboot_printf.h"
+
+#include "dboot_xboot.h"
+#include <sys/varargs.h>
+
+/*
+ * This file provides simple output formatting via dboot_printf()
+ */
+
+static void do_dboot_printf(char *fmt, va_list args);
+
+static char digits[] = "0123456789abcdef";
+
+/*
+ * Primitive version of panic, prints a message then resets the system
+ */
+void
+dboot_panic(char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ do_dboot_printf(fmt, args);
+
+ if (console == CONS_SCREEN_TEXT) {
+ dboot_printf("Press any key to reboot\n");
+ (void) bcons_getchar();
+ }
+
+ outb(0x64, 0xfe); /* this resets the system, see pc_reset() */
+ dboot_halt(); /* just in case */
+}
+
+/*
+ * printf for boot code
+ */
+void
+dboot_printf(char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ do_dboot_printf(fmt, args);
+}
+
+
+/*
+ * output a string
+ */
+static void
+dboot_puts(char *s)
+{
+ while (*s != 0) {
+ bcons_putchar(*s);
+ ++s;
+ }
+}
+
+static void
+dboot_putnum(uint64_t x, uint_t is_signed, uint8_t base)
+{
+ char buffer[64]; /* digits in reverse order */
+ int i;
+
+ if (is_signed && (int64_t)x < 0) {
+ bcons_putchar('-');
+ x = -x;
+ }
+
+ for (i = -1; x != 0 && i <= 63; x /= base)
+ buffer[++i] = digits[x - ((x / base) * base)];
+
+ if (i < 0)
+ buffer[++i] = '0';
+
+ while (i >= 0)
+ bcons_putchar(buffer[i--]);
+}
+
+/*
+ * very primitive printf - only does %s, %d, %x, %lx, or %%
+ */
+static void
+do_dboot_printf(char *fmt, va_list args)
+{
+ char *s;
+ uint64_t x;
+ uint8_t base;
+ uint8_t size;
+ uint_t is_signed = 1;
+
+ if (fmt == NULL) {
+ dboot_puts("dboot_printf(): 1st arg is NULL\n");
+ return;
+ }
+ for (; *fmt; ++fmt) {
+ if (*fmt != '%') {
+ bcons_putchar(*fmt);
+ continue;
+ }
+
+ size = 0;
+again:
+ ++fmt;
+ switch (*fmt) {
+
+ case '%':
+ bcons_putchar(*fmt);
+ break;
+
+ case 'c':
+ x = va_arg(args, int);
+ bcons_putchar(x);
+ break;
+
+ case 's':
+ s = va_arg(args, char *);
+ if (s == NULL)
+ dboot_puts("*NULL*");
+ else
+ dboot_puts(s);
+ break;
+
+ case 'p':
+ x = va_arg(args, ulong_t);
+ dboot_putnum(x, !is_signed, 16);
+ break;
+
+ case 'l':
+ if (size == 0)
+ size = sizeof (long);
+ else if (size == sizeof (long))
+ size = sizeof (long long);
+ goto again;
+
+ case 'd':
+ if (size == 0)
+ x = va_arg(args, int);
+ else if (size == sizeof (long))
+ x = va_arg(args, long);
+ else
+ x = va_arg(args, long long);
+ dboot_putnum(x, is_signed, 10);
+ break;
+
+ case 'b':
+ base = 2;
+ goto unsigned_num;
+
+ case 'o':
+ base = 8;
+ goto unsigned_num;
+
+ case 'x':
+ base = 16;
+unsigned_num:
+ if (size == 0)
+ x = va_arg(args, uint_t);
+ else if (size == sizeof (long))
+ x = va_arg(args, ulong_t);
+ else
+ x = va_arg(args, unsigned long long);
+ dboot_putnum(x, !is_signed, base);
+ break;
+
+ default:
+ dboot_puts("dboot_printf(): unknown % escape\n");
+ }
+ }
+}
diff --git a/usr/src/uts/i86pc/dboot/dboot_printf.h b/usr/src/uts/i86pc/dboot/dboot_printf.h
new file mode 100644
index 0000000000..22cf561e51
--- /dev/null
+++ b/usr/src/uts/i86pc/dboot/dboot_printf.h
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DBOOT_PRINTF_H
+#define _DBOOT_PRINTF_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Very primitive printf. This only understands the following simple formats:
+ * %%, %c, %s, %d, %ld, %lld, %x, %lx, %llx, %p
+ */
+/*PRINTFLIKE1*/
+extern void dboot_printf(char *fmt, ...)
+ __KPRINTFLIKE(1);
+
+/*
+ * Primitive version of panic, prints a message, waits for a keystroke,
+ * then resets the system
+ */
+/*PRINTFLIKE1*/
+extern void dboot_panic(char *fmt, ...)
+ __KPRINTFLIKE(1);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DBOOT_PRINTF_H */
diff --git a/usr/src/uts/i86pc/dboot/dboot_startkern.c b/usr/src/uts/i86pc/dboot/dboot_startkern.c
new file mode 100644
index 0000000000..ba336c0e9b
--- /dev/null
+++ b/usr/src/uts/i86pc/dboot/dboot_startkern.c
@@ -0,0 +1,827 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/machparam.h>
+#include <sys/x86_archext.h>
+#include <sys/systm.h>
+#include <sys/mach_mmu.h>
+
+#include <sys/multiboot.h>
+
+extern multiboot_header_t mb_header;
+extern int have_cpuid(void);
+extern uint32_t get_cpuid_edx(uint32_t *eax);
+
+#include <sys/inttypes.h>
+#include <sys/bootinfo.h>
+#include <sys/mach_mmu.h>
+#include <sys/boot_console.h>
+
+#include "dboot_printf.h"
+#include "dboot_xboot.h"
+#include "dboot_elfload.h"
+
+/*
+ * This file contains code that runs to transition us from either a multiboot
+ * compliant loader (32 bit non-paging) or Xen domain loader to regular kernel
+ * execution. Its task is to setup the kernel memory image and page tables.
+ *
+ * The code executes as:
+ * - 32 bits under GRUB (for 32 or 64 bit Solaris)
+ * - 32 bit program for Xen 32 bit
+ * - 64 bit program for Xen 64 bit (at least that's my assumption for now)
+ *
+ * Under Xen, we must create mappings for any memory beyond the initial
+ * start of day allocation (such as the kernel itself).
+ *
+ * When not under Xen, the mapping between maddr_t and paddr_t is 1:1.
+ * Since we are running in real mode, so all such memory is accessible.
+ */
+
+/*
+ * Standard bits used in PTE (page level) and PTP (internal levels)
+ */
+x86pte_t ptp_bits = PT_VALID | PT_REF | PT_USER | PT_WRITABLE | PT_USER;
+x86pte_t pte_bits = PT_VALID | PT_REF | PT_MOD | PT_NOCONSIST | PT_WRITABLE;
+
+/*
+ * This is the target addresses (physical) where the kernel text and data
+ * nucleus pages will be unpacked. On Xen this is actually a virtual address.
+ */
+paddr_t ktext_phys;
+uint32_t ksize = 2 * FOUR_MEG; /* kernel nucleus is 8Meg */
+
+static uint64_t target_kernel_text; /* value to use for KERNEL_TEXT */
+
+/*
+ * The stack is setup in assembler before entering startup_kernel()
+ */
+char stack_space[STACK_SIZE];
+
+/*
+ * Used to track physical memory allocation
+ */
+static paddr_t next_avail_addr = 0;
+
+multiboot_info_t *mb_info;
+
+/*
+ * This contains information passed to the kernel
+ */
+struct xboot_info boot_info[2]; /* extra space to fix alignement for amd64 */
+struct xboot_info *bi;
+
+/*
+ * Page table and memory stuff.
+ */
+static uint64_t max_mem; /* maximum memory address */
+
+/*
+ * Information about processor MMU
+ */
+int amd64_support = 0;
+int largepage_support = 0;
+int pae_support = 0;
+int pge_support = 0;
+int NX_support = 0;
+
+/*
+ * Low 32 bits of kernel entry address passed back to assembler.
+ * When running a 64 bit kernel, the high 32 bits are 0xffffffff.
+ */
+uint32_t entry_addr_low;
+
+/*
+ * Memlists for the kernel. We shouldn't need a lot of these.
+ */
+#define MAX_MEMLIST (10)
+struct boot_memlist memlists[MAX_MEMLIST];
+uint_t memlists_used = 0;
+
+#define MAX_MODULES (10)
+struct boot_modules modules[MAX_MODULES];
+uint_t modules_used = 0;
+
+/*
+ * Debugging macros
+ */
+uint_t prom_debug = 0;
+uint_t map_debug = 0;
+
+/*
+ * The Xen/Grub specific code builds the initial memlists. This code does
+ * sort/merge/link for final use.
+ */
+static void
+sort_physinstall(void)
+{
+ int i;
+ int j;
+ struct boot_memlist tmp;
+
+ /*
+ * Now sort the memlists, in case they weren't in order.
+ * Yeah, this is a bubble sort; small, simple and easy to get right.
+ */
+ DBG_MSG("Sorting phys-installed list\n");
+ for (j = memlists_used - 1; j > 0; --j) {
+ for (i = 0; i < j; ++i) {
+ if (memlists[i].addr < memlists[i + 1].addr)
+ continue;
+ tmp = memlists[i];
+ memlists[i] = memlists[i + 1];
+ memlists[i + 1] = tmp;
+ }
+ }
+
+ /*
+ * Merge any memlists that don't have holes between them.
+ */
+ for (i = 0; i <= memlists_used - 1; ++i) {
+ if (memlists[i].addr + memlists[i].size != memlists[i + 1].addr)
+ continue;
+
+ if (prom_debug)
+ dboot_printf(
+ "merging mem segs %" PRIx64 "...%" PRIx64
+ " w/ %" PRIx64 "...%" PRIx64 "\n",
+ memlists[i].addr,
+ memlists[i].addr + memlists[i].size,
+ memlists[i + 1].addr,
+ memlists[i + 1].addr + memlists[i + 1].size);
+
+ memlists[i].size += memlists[i + 1].size;
+ for (j = i + 1; j < memlists_used - 1; ++j)
+ memlists[j] = memlists[j + 1];
+ --memlists_used;
+ DBG(memlists_used);
+ --i; /* after merging we need to reexamine, so do this */
+ }
+
+ if (prom_debug) {
+ dboot_printf("\nFinal memlists:\n");
+ for (i = 0; i < memlists_used; ++i) {
+ dboot_printf("\t%d: addr=%" PRIx64 " size=%"
+ PRIx64 "\n", i, memlists[i].addr, memlists[i].size);
+ }
+ }
+
+ /*
+ * link together the memlists with native size pointers
+ */
+ memlists[0].next = 0;
+ memlists[0].prev = 0;
+ for (i = 1; i < memlists_used; ++i) {
+ memlists[i].prev = (native_ptr_t)(uintptr_t)(memlists + i - 1);
+ memlists[i].next = 0;
+ memlists[i - 1].next = (native_ptr_t)(uintptr_t)(memlists + i);
+ }
+ bi->bi_phys_install = (native_ptr_t)memlists;
+ DBG(bi->bi_phys_install);
+}
+
+x86pte_t
+get_pteval(paddr_t table, uint_t index)
+{
+ if (pae_support)
+ return (((x86pte_t *)(uintptr_t)table)[index]);
+ return (((x86pte32_t *)(uintptr_t)table)[index]);
+}
+
+/*ARGSUSED*/
+void
+set_pteval(paddr_t table, uint_t index, uint_t level, x86pte_t pteval)
+{
+ uintptr_t tab_addr = (uintptr_t)table;
+
+ if (pae_support)
+ ((x86pte_t *)tab_addr)[index] = pteval;
+ else
+ ((x86pte32_t *)tab_addr)[index] = (x86pte32_t)pteval;
+ if (level == top_level && level == 2)
+ reload_cr3();
+}
+
+paddr_t
+make_ptable(x86pte_t *pteval, uint_t level)
+{
+ paddr_t new_table = (paddr_t)(uintptr_t)mem_alloc(MMU_PAGESIZE);
+
+ if (level == top_level && level == 2)
+ *pteval = pa_to_ma((uintptr_t)new_table) | PT_VALID;
+ else
+ *pteval = pa_to_ma((uintptr_t)new_table) | ptp_bits;
+
+ if (map_debug)
+ dboot_printf("new page table lvl=%d paddr=0x%lx ptp=0x%"
+ PRIx64 "\n", level, (ulong_t)new_table, *pteval);
+ return (new_table);
+}
+
+x86pte_t *
+map_pte(paddr_t table, uint_t index)
+{
+ return ((x86pte_t *)(uintptr_t)(table + index * pte_size));
+}
+
+#if 0 /* useful if debugging */
+/*
+ * dump out the contents of page tables...
+ */
+static void
+dump_tables(void)
+{
+ uint_t save_index[4]; /* for recursion */
+ char *save_table[4]; /* for recursion */
+ uint_t l;
+ uint64_t va;
+ uint64_t pgsize;
+ int index;
+ int i;
+ x86pte_t pteval;
+ char *table;
+ static char *tablist = "\t\t\t";
+ char *tabs = tablist + 3 - top_level;
+ uint_t pa, pa1;
+
+ dboot_printf("Finished pagetables:\n");
+ table = (char *)top_page_table;
+ l = top_level;
+ va = 0;
+ for (index = 0; index < ptes_per_table; ++index) {
+ pgsize = 1ull << shift_amt[l];
+ if (pae_support)
+ pteval = ((x86pte_t *)table)[index];
+ else
+ pteval = ((x86pte32_t *)table)[index];
+ if (pteval == 0)
+ goto next_entry;
+
+ dboot_printf("%s %lx[0x%x] = %" PRIx64 ", va=%" PRIx64,
+ tabs + l, table, index, (uint64_t)pteval, va);
+ pa = ma_to_pa(pteval & MMU_PAGEMASK);
+ dboot_printf(" physaddr=%" PRIx64 "\n", pa);
+
+ /*
+ * Don't try to walk hypervisor private pagetables
+ */
+ if ((l > 1 || (l == 1 && (pteval & PT_PAGESIZE) == 0))) {
+ save_table[l] = table;
+ save_index[l] = index;
+ --l;
+ index = -1;
+ table = (char *)(uintptr_t)
+ ma_to_pa(pteval & MMU_PAGEMASK);
+ goto recursion;
+ }
+
+ /*
+ * shorten dump for consecutive mappings
+ */
+ for (i = 1; index + i < ptes_per_table; ++i) {
+ if (pae_support)
+ pteval = ((x86pte_t *)table)[index + i];
+ else
+ pteval = ((x86pte32_t *)table)[index + i];
+ if (pteval == 0)
+ break;
+ pa1 = ma_to_pa(pteval & MMU_PAGEMASK);
+ if (pa1 != pa + i * pgsize)
+ break;
+ }
+ if (i > 2) {
+ dboot_printf("%s...\n", tabs + l);
+ va += pgsize * (i - 2);
+ index += i - 2;
+ }
+next_entry:
+ va += pgsize;
+ if (l == 3 && index == 256) /* VA hole */
+ va = 0xffff800000000000ull;
+recursion:
+ ;
+ }
+ if (l < top_level) {
+ ++l;
+ index = save_index[l];
+ table = save_table[l];
+ goto recursion;
+ }
+}
+#endif
+
+/*
+ * Add a mapping for the physical page at the given virtual address.
+ */
+static void
+map_pa_at_va(paddr_t pa, native_ptr_t va, uint_t level)
+{
+ x86pte_t *ptep;
+ x86pte_t pteval;
+
+ pteval = pa_to_ma(pa) | pte_bits;
+ if (level > 0)
+ pteval |= PT_PAGESIZE;
+ if (va >= target_kernel_text && pge_support)
+ pteval |= PT_GLOBAL;
+
+ if (map_debug && pa != va)
+ dboot_printf("mapping pa=0x%" PRIx64 " va=0x%" PRIx64
+ " pte=0x%" PRIx64 " l=%d\n",
+ (uint64_t)pa, (uint64_t)va, pteval, level);
+
+ /*
+ * Find the pte that will map this address. This creates any
+ * missing intermediate level page tables
+ */
+ ptep = find_pte(va, NULL, level, 0);
+
+ /*
+ * On Xen we must use hypervisor calls to modify the PTE, since
+ * paging is active. On real hardware we just write to the pagetables
+ * which aren't in use yet.
+ */
+ if (va < 1024 * 1024)
+ pteval |= PT_NOCACHE; /* for video RAM */
+ if (pae_support)
+ *ptep = pteval;
+ else
+ *((x86pte32_t *)ptep) = (x86pte32_t)pteval;
+}
+
+/*
+ * During memory allocation, find the highest address not used yet.
+ */
+static void
+check_higher(paddr_t a)
+{
+ if (a < next_avail_addr)
+ return;
+ next_avail_addr = RNDUP(a + 1, MMU_PAGESIZE);
+ DBG(next_avail_addr);
+}
+
+/*
+ * Walk through the module information finding the last used address.
+ * The first available address will become the top level page table.
+ *
+ * We then build the phys_install memlist from the multiboot information.
+ */
+static void
+init_mem_alloc(void)
+{
+ mb_memory_map_t *mmap;
+ mb_module_t *mod;
+ uint64_t start;
+ uint64_t end;
+ uint64_t page_offset = MMU_PAGEOFFSET; /* needs to be 64 bits */
+ extern char _end[];
+ int i;
+
+ DBG_MSG("Entered init_mem_alloc()\n");
+ DBG((uintptr_t)mb_info);
+
+ /*
+ * search the modules to find the last used address
+ * we'll build the module list while we're walking through here
+ */
+ DBG_MSG("\nFinding Modules\n");
+ check_higher((paddr_t)&_end);
+ for (mod = (mb_module_t *)(mb_info->mods_addr), i = 0;
+ i < mb_info->mods_count;
+ ++mod, ++i) {
+ if (prom_debug) {
+ dboot_printf("\tmodule #%d: %s at: 0x%lx, len 0x%lx\n",
+ i, (char *)(mod->mod_name),
+ (ulong_t)mod->mod_start, (ulong_t)mod->mod_end);
+ }
+ modules[i].bm_addr = mod->mod_start;
+ modules[i].bm_size = mod->mod_end;
+
+ check_higher(mod->mod_end);
+ }
+ bi->bi_modules = (native_ptr_t)modules;
+ DBG(bi->bi_modules);
+ bi->bi_module_cnt = mb_info->mods_count;
+ DBG(bi->bi_module_cnt);
+
+ /*
+ * Walk through the memory map from multiboot and build our memlist
+ * structures. Note these will have native format pointers.
+ */
+ DBG_MSG("\nFinding Memory Map\n");
+ DBG(mb_info->flags);
+ max_mem = 0;
+ if (mb_info->flags & 0x40) {
+ DBG(mb_info->mmap_addr);
+ DBG(mb_info->mmap_length);
+ check_higher(mb_info->mmap_addr + mb_info->mmap_length);
+
+ for (mmap = (mb_memory_map_t *)mb_info->mmap_addr;
+ (uint32_t)mmap < mb_info->mmap_addr + mb_info->mmap_length;
+ mmap = (mb_memory_map_t *)((uint32_t)mmap + mmap->size
+ + sizeof (mmap->size))) {
+
+ start = ((uint64_t)mmap->base_addr_high << 32) +
+ mmap->base_addr_low;
+ end = start + ((uint64_t)mmap->length_high << 32) +
+ mmap->length_low;
+
+ if (prom_debug) {
+ dboot_printf("\ttype: %d %" PRIx64 "..%"
+ PRIx64 "\n", mmap->type, start, end);
+ }
+
+ /*
+ * only type 1 is usable RAM
+ */
+ if (mmap->type != 1)
+ continue;
+
+ /*
+ * page align start and end
+ */
+ start = (start + page_offset) & ~page_offset;
+ end &= ~page_offset;
+ if (end <= start)
+ continue;
+
+ if (end > max_mem)
+ max_mem = end;
+
+ memlists[memlists_used].addr = start;
+ memlists[memlists_used].size = end - start;
+ ++memlists_used; /* no overflow check */
+ }
+ } else if (mb_info->flags & 0x01) {
+ DBG(mb_info->mem_lower);
+ memlists[memlists_used].addr = 0;
+ memlists[memlists_used].size = mb_info->mem_lower * 1024;
+ ++memlists_used;
+ DBG(mb_info->mem_upper);
+ memlists[memlists_used].addr = 1024 * 1024;
+ memlists[memlists_used].size = mb_info->mem_upper * 1024;
+ ++memlists_used;
+ } else {
+ dboot_panic("No memory info from boot loader!!!\n");
+ }
+
+ check_higher(bi->bi_cmdline);
+
+ /*
+ * finish processing the physinstall list
+ */
+ sort_physinstall();
+}
+
+/*
+ * Simple memory allocator, allocates aligned physical memory.
+ * Note that startup_kernel() only allocates memory, never frees.
+ * Memory usage just grows in an upward direction.
+ */
+static void *
+do_mem_alloc(uint32_t size, uint32_t align)
+{
+ uint_t i;
+ uint64_t best;
+ uint64_t start;
+ uint64_t end;
+
+ /*
+ * make sure size is a multiple of pagesize
+ */
+ size = RNDUP(size, MMU_PAGESIZE);
+ next_avail_addr = RNDUP(next_avail_addr, align);
+
+ /*
+ * a really large bootarchive that causes you to run out of memory
+ * may cause this to blow up
+ */
+ /* LINTED E_UNEXPECTED_UINT_PROMOTION */
+ best = (uint64_t)-size;
+ for (i = 0; i < memlists_used; ++i) {
+ start = memlists[i].addr;
+ end = start + memlists[i].size;
+
+ /*
+ * did we find the desired address?
+ */
+ if (start <= next_avail_addr && next_avail_addr + size <= end) {
+ best = next_avail_addr;
+ goto done;
+ }
+
+ /*
+ * if not is this address the best so far?
+ */
+ if (start > next_avail_addr && start < best &&
+ RNDUP(start, align) + size <= end)
+ best = RNDUP(start, align);
+ }
+
+ /*
+ * We didn't find exactly the address we wanted, due to going off the
+ * end of a memory region. Return the best found memory address.
+ */
+done:
+ next_avail_addr = best + size;
+ (void) memset((void *)(uintptr_t)best, 0, size);
+ return ((void *)(uintptr_t)best);
+}
+
+void *
+mem_alloc(uint32_t size)
+{
+ return (do_mem_alloc(size, MMU_PAGESIZE));
+}
+
+
+/*
+ * Build page tables to map all of memory used so far as well as the kernel.
+ */
+static void
+build_page_tables(void)
+{
+ uint32_t psize;
+ uint32_t level;
+ uint32_t off;
+ uint32_t i;
+ uint64_t start;
+ uint64_t end;
+ uint64_t next_mapping;
+
+ /*
+ * If we're not using Xen, we need to create the top level pagetable.
+ */
+ top_page_table = (paddr_t)(uintptr_t)mem_alloc(MMU_PAGESIZE);
+ DBG((uintptr_t)top_page_table);
+
+ /*
+ * Determine if we'll use large mappings for kernel, then map it.
+ */
+ if (largepage_support) {
+ psize = lpagesize;
+ level = 1;
+ } else {
+ psize = MMU_PAGESIZE;
+ level = 0;
+ }
+
+ DBG_MSG("Mapping kernel\n");
+ DBG(ktext_phys);
+ DBG(target_kernel_text);
+ DBG(ksize);
+ DBG(psize);
+ for (off = 0; off < ksize; off += psize)
+ map_pa_at_va(ktext_phys + off, target_kernel_text + off, level);
+
+ /*
+ * The kernel will need a 1 page window to work with page tables
+ */
+ bi->bi_pt_window = (uintptr_t)mem_alloc(MMU_PAGESIZE);
+ DBG(bi->bi_pt_window);
+ bi->bi_pte_to_pt_window =
+ (uintptr_t)find_pte(bi->bi_pt_window, NULL, 0, 0);
+ DBG(bi->bi_pte_to_pt_window);
+
+ /*
+ * Under multiboot we need 1:1 mappings for all of low memory, which
+ * includes our pagetables. The following code works because our
+ * simple memory allocator only grows usage in an upwards direction.
+ *
+ * We map *all* possible addresses below 1 Meg, since things like
+ * the video RAM are down there.
+ *
+ * Skip memory between 1M and _start, this acts as a reserve
+ * of memory usable for DMA.
+ */
+ next_mapping = (uintptr_t)_start & MMU_PAGEMASK;
+ if (map_debug)
+ dboot_printf("1:1 map pa=0..1Meg\n");
+ for (start = 0; start < 1024 * 1024; start += MMU_PAGESIZE)
+ map_pa_at_va(start, start, 0);
+
+ for (i = 0; i < memlists_used; ++i) {
+ start = memlists[i].addr;
+ if (start < next_mapping)
+ start = next_mapping;
+
+ end = start + memlists[i].size;
+
+ if (map_debug)
+ dboot_printf("1:1 map pa=%" PRIx64 "..%" PRIx64 "\n",
+ start, end);
+ while (start < end && start < next_avail_addr) {
+ map_pa_at_va(start, start, 0);
+ start += MMU_PAGESIZE;
+ }
+ }
+
+ DBG_MSG("\nPage tables constructed\n");
+}
+
+#define NO_MULTIBOOT \
+"multiboot is no longer used to boot the Solaris Operating System.\n\
+The grub entry should be changed to:\n\
+kernel$ /platform/i86pc/kernel/$ISADIR/unix\n\
+module$ /platform/i86pc/$ISADIR/boot_archive\n\
+See http://www.sun.com/msg/SUNOS-8000-AK for details.\n"
+
+/*
+ * startup_kernel has a pretty simple job. It builds pagetables which reflect
+ * 1:1 mappings for all memory in use. It then also adds mappings for
+ * the kernel nucleus at virtual address of target_kernel_text using large page
+ * mappings. The page table pages are also accessible at 1:1 mapped
+ * virtual addresses.
+ */
+/*ARGSUSED*/
+void
+startup_kernel(void)
+{
+ char *cmdline;
+ uintptr_t addr;
+
+ /*
+ * At this point we are executing in a 32 bit real mode.
+ */
+ cmdline = (char *)mb_info->cmdline;
+ prom_debug = (strstr(cmdline, "prom_debug") != NULL);
+ map_debug = (strstr(cmdline, "map_debug") != NULL);
+ bcons_init(cmdline);
+ DBG_MSG("\n\nSolaris prekernel set: ");
+ DBG_MSG(cmdline);
+ DBG_MSG("\n");
+
+ if (strstr(cmdline, "multiboot") != NULL) {
+ dboot_panic(NO_MULTIBOOT);
+ }
+
+ /*
+ * boot info must be 16 byte aligned for 64 bit kernel ABI
+ */
+ addr = (uintptr_t)boot_info;
+ addr = (addr + 0xf) & ~0xf;
+ bi = (struct xboot_info *)addr;
+ DBG((uintptr_t)bi);
+ bi->bi_cmdline = (native_ptr_t)(uintptr_t)cmdline;
+
+ /*
+ * Need correct target_kernel_text value
+ */
+#if defined(_BOOT_TARGET_amd64)
+ target_kernel_text = KERNEL_TEXT_amd64;
+#else
+ target_kernel_text = KERNEL_TEXT_i386;
+#endif
+ DBG(target_kernel_text);
+
+ /*
+ * use cpuid to enable MMU features
+ */
+ if (have_cpuid()) {
+ uint32_t eax, edx;
+
+ eax = 1;
+ edx = get_cpuid_edx(&eax);
+ if (edx & CPUID_INTC_EDX_PSE)
+ largepage_support = 1;
+ if (edx & CPUID_INTC_EDX_PGE)
+ pge_support = 1;
+ if (edx & CPUID_INTC_EDX_PAE)
+ pae_support = 1;
+
+ eax = 0x80000000;
+ edx = get_cpuid_edx(&eax);
+ if (eax >= 0x80000001) {
+ eax = 0x80000001;
+ edx = get_cpuid_edx(&eax);
+ if (edx & CPUID_AMD_EDX_LM)
+ amd64_support = 1;
+ if (edx & CPUID_AMD_EDX_NX)
+ NX_support = 1;
+ }
+ } else {
+ dboot_printf("cpuid not supported\n");
+ }
+
+#if defined(_BOOT_TARGET_amd64)
+ if (amd64_support == 0)
+ dboot_panic("long mode not supported, rebooting\n");
+ else if (pae_support == 0)
+ dboot_panic("long mode, but no PAE; rebooting\n");
+#endif
+
+ /*
+ * initialize our memory allocator
+ */
+ init_mem_alloc();
+
+ /*
+ * configure mmu information
+ */
+#if !defined(_BOOT_TARGET_amd64)
+ if (pae_support && (max_mem > FOUR_GIG || NX_support)) {
+#endif
+ shift_amt = shift_amt_pae;
+ ptes_per_table = 512;
+ pte_size = 8;
+ lpagesize = TWO_MEG;
+#if defined(_BOOT_TARGET_amd64)
+ top_level = 3;
+#else
+ top_level = 2;
+#endif
+#if !defined(_BOOT_TARGET_amd64)
+ } else {
+ pae_support = 0;
+ NX_support = 0;
+ shift_amt = shift_amt_nopae;
+ ptes_per_table = 1024;
+ pte_size = 4;
+ lpagesize = FOUR_MEG;
+ top_level = 1;
+ }
+#endif
+
+ DBG(pge_support);
+ DBG(NX_support);
+ DBG(largepage_support);
+ DBG(amd64_support);
+ DBG(top_level);
+ DBG(pte_size);
+ DBG(ptes_per_table);
+ DBG(lpagesize);
+
+ ktext_phys = FOUR_MEG; /* from UNIX Mapfile */
+
+#if defined(_BOOT_TARGET_amd64)
+ /*
+ * For grub, copy kernel bits from the ELF64 file to final place.
+ */
+ DBG_MSG("\nAllocating nucleus pages.\n");
+ ktext_phys = (uintptr_t)do_mem_alloc(ksize, FOUR_MEG);
+ if (ktext_phys == 0)
+ dboot_panic("failed to allocate aligned kernel memory\n");
+ if (dboot_elfload64(mb_header.load_addr) != 0)
+ dboot_panic("failed to parse kernel ELF image, rebooting\n");
+
+#endif
+ DBG(ktext_phys);
+
+ /*
+ * Allocate page tables.
+ */
+ build_page_tables();
+
+ /*
+ * return to assembly code to switch to running kernel
+ */
+ entry_addr_low = (uint32_t)target_kernel_text;
+ DBG(entry_addr_low);
+ bi->bi_use_largepage = largepage_support;
+ bi->bi_use_pae = pae_support;
+ bi->bi_use_pge = pge_support;
+ bi->bi_use_nx = NX_support;
+ bi->bi_next_paddr = next_avail_addr;
+ DBG(bi->bi_next_paddr);
+ bi->bi_next_vaddr = (uintptr_t)next_avail_addr;
+ DBG(bi->bi_next_vaddr);
+ bi->bi_mb_info = (uintptr_t)mb_info;
+ bi->bi_top_page_table = (uintptr_t)top_page_table;
+
+ bi->bi_kseg_size = FOUR_MEG;
+ DBG(bi->bi_kseg_size);
+
+#if 0 /* useful if debugging initial page tables */
+ if (prom_debug)
+ dump_tables();
+#endif
+
+ DBG_MSG("\n\n*** DBOOT DONE -- back to asm to jump to kernel\n\n");
+}
diff --git a/usr/src/uts/i86pc/dboot/dboot_xboot.h b/usr/src/uts/i86pc/dboot/dboot_xboot.h
new file mode 100644
index 0000000000..fac4ee9c74
--- /dev/null
+++ b/usr/src/uts/i86pc/dboot/dboot_xboot.h
@@ -0,0 +1,83 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DBOOT_XBOOT_H
+#define _DBOOT_XBOOT_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/mach_mmu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/note.h>
+
+/*
+ * Stack used by xboot
+ */
+#define STACK_SIZE 0x8000
+
+#ifndef _ASM
+
+extern paddr_t ktext_phys;
+extern struct xboot_info *bi;
+
+/*
+ * Debugging macros
+ */
+extern uint_t prom_debug;
+
+#define DBG_MSG(s) do { if (prom_debug) \
+ dboot_printf(s); \
+ _NOTE(CONSTANTCONDITION) \
+ } while (0)
+
+#define DBG(x) do { if (prom_debug) { \
+ dboot_printf("%s is 0x%" PRIx64 "\n", #x, (uint64_t)(x)); \
+ _NOTE(CONSTANTCONDITION) \
+ } } while (0)
+
+extern void dboot_halt(void);
+extern void *mem_alloc(uint32_t size);
+
+#define RNDUP(x, y) ((x) + ((y) - 1ul) & ~((y) - 1ul))
+
+/*
+ * this is gross too, but archsystm.h is under a #ifdef _KERNEL
+ */
+extern uint8_t inb(int port);
+extern void outb(int port, uint8_t value);
+
+#endif /* _ASM */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DBOOT_XBOOT_H */
diff --git a/usr/src/uts/i86pc/genassym/Makefile b/usr/src/uts/i86pc/genassym/Makefile
index 96e0a20169..55425ce673 100644
--- a/usr/src/uts/i86pc/genassym/Makefile
+++ b/usr/src/uts/i86pc/genassym/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -37,6 +36,7 @@
UTSBASE = ../..
ASSYM_H = $(DSF_DIR)/$(OBJS_DIR)/assym.h
+KDI_ASSYM_H = $(DSF_DIR)/$(OBJS_DIR)/kdi_assym.h
GENASSYM = $(DSF_DIR)/$(OBJS_DIR)/genassym
#
@@ -47,7 +47,7 @@ include $(UTSBASE)/i86pc/Makefile.i86pc
#
# Define targets
#
-ALL_TARGET = $(ASSYM_H)
+ALL_TARGET = $(ASSYM_H) $(KDI_ASSYM_H)
#
# This is DSF_DIR. Use a short path.
@@ -59,7 +59,7 @@ DSF_DIR = .
# Overrides
#
CLEANFILES = $(GENASSYM) Nothing_to_remove
-CLOBBERFILES = $(ASSYM_H) $(CLEANFILES) Nothing_to_remove
+CLOBBERFILES = $(ASSYM_H) $(KDI_ASSYM.H) $(CLEANFILES) Nothing_to_remove
#
# Default build targets.
@@ -90,6 +90,10 @@ $(ASSYM_H): $(OFFSETS_SRC) $(PLATFORM_OFFSETS_SRC) $(GENASSYM)
$(OFFSETS_CREATE) <$(PLATFORM_OFFSETS_SRC) >>$@
$(GENASSYM) >>$@
+$(KDI_ASSYM_H): $(KDI_OFFSETS_SRC) $(GENASSYM)
+ $(OFFSETS_CREATE) <$(KDI_OFFSETS_SRC) >$@
+ $(GENASSYM) >>$@
+
#
# Include common targets.
#
diff --git a/usr/src/uts/i86pc/io/cbe.c b/usr/src/uts/i86pc/io/cbe.c
index 2863b289ae..7667bb2219 100644
--- a/usr/src/uts/i86pc/io/cbe.c
+++ b/usr/src/uts/i86pc/io/cbe.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,10 +18,12 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/systm.h>
@@ -34,6 +35,7 @@
#include <sys/machsystm.h>
#include <sys/smp_impldefs.h>
#include <sys/psm_types.h>
+#include <sys/psm.h>
#include <sys/atomic.h>
#include <sys/clock.h>
#include <sys/ddi_impldefs.h>
@@ -79,7 +81,6 @@ cbe_low_level(void)
* to the timer firing at level-14. Because cyclic_fire() can tolerate
* spurious calls, it would not matter if we called cyclic_fire() in both
* cases.
- *
*/
int
cbe_fire(void)
@@ -92,8 +93,10 @@ cbe_fire(void)
if (cbe_psm_timer_mode != TIMER_ONESHOT && me == 0 && !cross_call) {
for (i = 1; i < NCPU; i++) {
- if (CPU_IN_SET(cbe_enabled, i))
+ if (CPU_IN_SET(cbe_enabled, i)) {
+ XC_TRACE(TT_XC_CBE_FIRE, -1, i);
send_dirint(i, CBE_HIGH_PIL);
+ }
}
}
@@ -180,6 +183,7 @@ cbe_xcall(void *arg, cpu_t *dest, cyc_func_t func, void *farg)
cbe_xcall_cpu = dest;
cbe_xcall_func = func;
+ XC_TRACE(TT_XC_CBE_XCALL, -1, dest->cpu_id);
send_dirint(dest->cpu_id, CBE_HIGH_PIL);
while (cbe_xcall_func != NULL || cbe_xcall_cpu != NULL)
@@ -312,5 +316,4 @@ cbe_init(void)
(*psm_post_cyclic_setup)(NULL);
mutex_exit(&cpu_lock);
-
}
diff --git a/usr/src/uts/intel/io/consplat.c b/usr/src/uts/i86pc/io/consplat.c
index 78500fce34..78500fce34 100644
--- a/usr/src/uts/intel/io/consplat.c
+++ b/usr/src/uts/i86pc/io/consplat.c
diff --git a/usr/src/uts/common/io/pit.c b/usr/src/uts/i86pc/io/hardclk.c
index 6a69ca2d19..05961429c8 100644
--- a/usr/src/uts/common/io/pit.c
+++ b/usr/src/uts/i86pc/io/hardclk.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,7 @@
#include <sys/time.h>
#include <sys/systm.h>
#include <sys/archsystm.h>
+#include <sys/lockstat.h>
#include <sys/clock.h>
#include <sys/debug.h>
@@ -42,18 +43,15 @@
/*
* This file contains all generic part of clock and timer handling.
- * Specifics are now in a seperate file and may be overridden by OEM
- * modules which get loaded. Defaults come from i8254.c and hardclk.c
+ * Specifics are now in separate files and may be overridden by TOD
+ * modules.
*/
unsigned int microdata = 50; /* loop count for 10 microsecond wait. */
/* MUST be initialized for those who */
/* insist on calling "tenmicrosec" before */
/* the clock has been initialized. */
-timestruc_t (*todgetf)(void) = pc_tod_get;
-void (*todsetf)(timestruc_t) = pc_tod_set;
-
-long gmt_lag; /* offset in seconds of gmt to local time */
+char *tod_module_name; /* Settable in /etc/system */
/*
* Write the specified time into the clock chip.
@@ -68,7 +66,7 @@ tod_set(timestruc_t ts)
* Prevent false alarm in tod_validate() due to tod value change.
*/
tod_fault_reset();
- (*todsetf)(ts);
+ TODOP_SET(tod_ops, ts);
}
/*
@@ -83,18 +81,44 @@ tod_get(void)
ASSERT(MUTEX_HELD(&tod_lock));
- ts = (*todgetf)();
+ ts = TODOP_GET(tod_ops);
ts.tv_sec = tod_validate(ts.tv_sec);
return (ts);
}
+/*
+ * The following wrappers have been added so that locking
+ * can be exported to platform-independent clock routines
+ * (ie adjtime(), clock_setttime()), via a functional interface.
+ */
+int
+hr_clock_lock(void)
+{
+ ushort_t s;
+
+ CLOCK_LOCK(&s);
+ return (s);
+}
+
+void
+hr_clock_unlock(int s)
+{
+ CLOCK_UNLOCK(s);
+}
+
+/*
+ * Support routines for horrid GMT lag handling
+ */
+
+static time_t gmt_lag; /* offset in seconds of gmt to local time */
+
void
-sgmtl(long arg)
+sgmtl(time_t arg)
{
gmt_lag = arg;
}
-long
+time_t
ggmtl(void)
{
return (gmt_lag);
@@ -108,7 +132,7 @@ rtcsync(void)
timestruc_t ts;
mutex_enter(&tod_lock);
- ts = (*todgetf)();
+ ts = TODOP_GET(tod_ops);
set_hrestime(&ts);
mutex_exit(&tod_lock);
}
diff --git a/usr/src/uts/i86pc/io/mp_platform_common.c b/usr/src/uts/i86pc/io/mp_platform_common.c
new file mode 100644
index 0000000000..b032ec1b7c
--- /dev/null
+++ b/usr/src/uts/i86pc/io/mp_platform_common.c
@@ -0,0 +1,3736 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * PSMI 1.1 extensions are supported only in 2.6 and later versions.
+ * PSMI 1.2 extensions are supported only in 2.7 and later versions.
+ * PSMI 1.3 and 1.4 extensions are supported in Solaris 10.
+ * PSMI 1.5 extensions are supported in Solaris Nevada.
+ */
+#define PSMI_1_5
+
+#include <sys/processor.h>
+#include <sys/time.h>
+#include <sys/psm.h>
+#include <sys/smp_impldefs.h>
+#include <sys/cram.h>
+#include <sys/acpi/acpi.h>
+#include <sys/acpica.h>
+#include <sys/psm_common.h>
+#include <sys/apic.h>
+#include <sys/pit.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/ddi_impldefs.h>
+#include <sys/pci.h>
+#include <sys/promif.h>
+#include <sys/x86_archext.h>
+#include <sys/cpc_impl.h>
+#include <sys/uadmin.h>
+#include <sys/panic.h>
+#include <sys/debug.h>
+#include <sys/archsystm.h>
+#include <sys/trap.h>
+#include <sys/machsystm.h>
+#include <sys/cpuvar.h>
+#include <sys/rm_platter.h>
+#include <sys/privregs.h>
+#include <sys/cyclic.h>
+#include <sys/note.h>
+#include <sys/pci_intr_lib.h>
+#include <sys/sunndi.h>
+
+
+/*
+ * Local Function Prototypes
+ */
+static int apic_handle_defconf();
+static int apic_parse_mpct(caddr_t mpct, int bypass);
+static struct apic_mpfps_hdr *apic_find_fps_sig(caddr_t fptr, int size);
+static int apic_checksum(caddr_t bptr, int len);
+static int apic_find_bus_type(char *bus);
+static int apic_find_bus(int busid);
+static int apic_find_bus_id(int bustype);
+static struct apic_io_intr *apic_find_io_intr(int irqno);
+static int apic_find_free_irq(int start, int end);
+static void apic_mark_vector(uchar_t oldvector, uchar_t newvector);
+static void apic_xlate_vector_free_timeout_handler(void *arg);
+static void apic_reprogram_timeout_handler(void *arg);
+static int apic_check_stuck_interrupt(apic_irq_t *irq_ptr, int old_bind_cpu,
+ int new_bind_cpu, int apicindex, int intin_no, int which_irq,
+ struct ioapic_reprogram_data *drep);
+static void apic_record_rdt_entry(apic_irq_t *irqptr, int irq);
+static struct apic_io_intr *apic_find_io_intr_w_busid(int irqno, int busid);
+static int apic_find_intin(uchar_t ioapic, uchar_t intin);
+static int apic_handle_pci_pci_bridge(dev_info_t *idip, int child_devno,
+ int child_ipin, struct apic_io_intr **intrp);
+static int apic_setup_irq_table(dev_info_t *dip, int irqno,
+ struct apic_io_intr *intrp, struct intrspec *ispec, iflag_t *intr_flagp,
+ int type);
+static int apic_setup_sci_irq_table(int irqno, uchar_t ipl,
+ iflag_t *intr_flagp);
+static void apic_set_pwroff_method_from_mpcnfhdr(struct apic_mp_cnf_hdr *hdrp);
+static void apic_try_deferred_reprogram(int ipl, int vect);
+static void delete_defer_repro_ent(int which_irq);
+static void apic_ioapic_wait_pending_clear(int ioapicindex,
+ int intin_no);
+
+int apic_debug_mps_id = 0; /* 1 - print MPS ID strings */
+
+/* ACPI SCI interrupt configuration; -1 if SCI not used */
+int apic_sci_vect = -1;
+iflag_t apic_sci_flags;
+
+/*
+ * psm name pointer
+ */
+static char *psm_name;
+
+/* ACPI support routines */
+static int acpi_probe(char *);
+static int apic_acpi_irq_configure(acpi_psm_lnk_t *acpipsmlnkp, dev_info_t *dip,
+ int *pci_irqp, iflag_t *intr_flagp);
+
+static int apic_acpi_translate_pci_irq(dev_info_t *dip, int busid, int devid,
+ int ipin, int *pci_irqp, iflag_t *intr_flagp);
+static uchar_t acpi_find_ioapic(int irq);
+static int acpi_intr_compatible(iflag_t iflag1, iflag_t iflag2);
+
+
+/*
+ * number of bits per byte, from <sys/param.h>
+ */
+#define UCHAR_MAX ((1 << NBBY) - 1)
+
+/* Max wait time (in repetitions) for flags to clear in an RDT entry. */
+int apic_max_reps_clear_pending = 1000;
+
+/* The irq # is implicit in the array index: */
+struct ioapic_reprogram_data apic_reprogram_info[APIC_MAX_VECTOR+1];
+/*
+ * APIC_MAX_VECTOR + 1 is the maximum # of IRQs as well. ioapic_reprogram_info
+ * is indexed by IRQ number, NOT by vector number.
+ */
+
+int apic_intr_policy = INTR_ROUND_ROBIN_WITH_AFFINITY;
+
+int apic_next_bind_cpu = 1; /* For round robin assignment */
+ /* start with cpu 1 */
+
+/*
+ * If enabled, the distribution works as follows:
+ * On every interrupt entry, the current ipl for the CPU is set in cpu_info
+ * and the irq corresponding to the ipl is also set in the aci_current array.
+ * interrupt exit and setspl (due to soft interrupts) will cause the current
+ * ipl to be be changed. This is cache friendly as these frequently used
+ * paths write into a per cpu structure.
+ *
+ * Sampling is done by checking the structures for all CPUs and incrementing
+ * the busy field of the irq (if any) executing on each CPU and the busy field
+ * of the corresponding CPU.
+ * In periodic mode this is done on every clock interrupt.
+ * In one-shot mode, this is done thru a cyclic with an interval of
+ * apic_redistribute_sample_interval (default 10 milli sec).
+ *
+ * Every apic_sample_factor_redistribution times we sample, we do computations
+ * to decide which interrupt needs to be migrated (see comments
+ * before apic_intr_redistribute().
+ */
+
+/*
+ * Following 3 variables start as % and can be patched or set using an
+ * API to be defined in future. They will be scaled to
+ * sample_factor_redistribution which is in turn set to hertz+1 (in periodic
+ * mode), or 101 in one-shot mode to stagger it away from one sec processing
+ */
+
+int apic_int_busy_mark = 60;
+int apic_int_free_mark = 20;
+int apic_diff_for_redistribution = 10;
+
+/* sampling interval for interrupt redistribution for dynamic migration */
+int apic_redistribute_sample_interval = NANOSEC / 100; /* 10 millisec */
+
+/*
+ * number of times we sample before deciding to redistribute interrupts
+ * for dynamic migration
+ */
+int apic_sample_factor_redistribution = 101;
+
+/* timeout for xlate_vector, mark_vector */
+int apic_revector_timeout = 16 * 10000; /* 160 millisec */
+
+int apic_redist_cpu_skip = 0;
+int apic_num_imbalance = 0;
+int apic_num_rebind = 0;
+
+int apic_nproc = 0;
+size_t apic_cpus_size = 0;
+int apic_defconf = 0;
+int apic_irq_translate = 0;
+int apic_spec_rev = 0;
+int apic_imcrp = 0;
+
+int apic_use_acpi = 1; /* 1 = use ACPI, 0 = don't use ACPI */
+int apic_use_acpi_madt_only = 0; /* 1=ONLY use MADT from ACPI */
+
+/*
+ * For interrupt link devices, if apic_unconditional_srs is set, an irq resource
+ * will be assigned (via _SRS). If it is not set, use the current
+ * irq setting (via _CRS), but only if that irq is in the set of possible
+ * irqs (returned by _PRS) for the device.
+ */
+int apic_unconditional_srs = 1;
+
+/*
+ * For interrupt link devices, if apic_prefer_crs is set when we are
+ * assigning an IRQ resource to a device, prefer the current IRQ setting
+ * over other possible irq settings under same conditions.
+ */
+
+int apic_prefer_crs = 1;
+
+uchar_t apic_io_id[MAX_IO_APIC];
+volatile uint32_t *apicioadr[MAX_IO_APIC];
+static uchar_t apic_io_ver[MAX_IO_APIC];
+static uchar_t apic_io_vectbase[MAX_IO_APIC];
+static uchar_t apic_io_vectend[MAX_IO_APIC];
+uchar_t apic_reserved_irqlist[MAX_ISA_IRQ + 1];
+uint32_t apic_physaddr[MAX_IO_APIC];
+
+/*
+ * First available slot to be used as IRQ index into the apic_irq_table
+ * for those interrupts (like MSI/X) that don't have a physical IRQ.
+ */
+int apic_first_avail_irq = APIC_FIRST_FREE_IRQ;
+
+/*
+ * apic_ioapic_lock protects the ioapics (reg select), the status, temp_bound
+ * and bound elements of cpus_info and the temp_cpu element of irq_struct
+ */
+lock_t apic_ioapic_lock;
+
+/*
+ * apic_defer_reprogram_lock ensures that only one processor is handling
+ * deferred interrupt programming at apic_intr_exit time.
+ */
+static lock_t apic_defer_reprogram_lock;
+
+/*
+ * The current number of deferred reprogrammings outstanding
+ */
+uint_t apic_reprogram_outstanding = 0;
+
+#ifdef DEBUG
+/*
+ * Counters that keep track of deferred reprogramming stats
+ */
+uint_t apic_intr_deferrals = 0;
+uint_t apic_intr_deliver_timeouts = 0;
+uint_t apic_last_ditch_reprogram_failures = 0;
+uint_t apic_deferred_setup_failures = 0;
+uint_t apic_defer_repro_total_retries = 0;
+uint_t apic_defer_repro_successes = 0;
+uint_t apic_deferred_spurious_enters = 0;
+#endif
+
+static int apic_io_max = 0; /* no. of i/o apics enabled */
+
+static struct apic_io_intr *apic_io_intrp = 0;
+static struct apic_bus *apic_busp;
+
+uchar_t apic_vector_to_irq[APIC_MAX_VECTOR+1];
+uchar_t apic_resv_vector[MAXIPL+1];
+
+char apic_level_intr[APIC_MAX_VECTOR+1];
+
+static uint32_t eisa_level_intr_mask = 0;
+ /* At least MSB will be set if EISA bus */
+
+static int apic_pci_bus_total = 0;
+static uchar_t apic_single_pci_busid = 0;
+
+/*
+ * airq_mutex protects additions to the apic_irq_table - the first
+ * pointer and any airq_nexts off of that one. It also protects
+ * apic_max_device_irq & apic_min_device_irq. It also guarantees
+ * that share_id is unique as new ids are generated only when new
+ * irq_t structs are linked in. Once linked in the structs are never
+ * deleted. temp_cpu & mps_intr_index field indicate if it is programmed
+ * or allocated. Note that there is a slight gap between allocating in
+ * apic_introp_xlate and programming in addspl.
+ */
+kmutex_t airq_mutex;
+apic_irq_t *apic_irq_table[APIC_MAX_VECTOR+1];
+int apic_max_device_irq = 0;
+int apic_min_device_irq = APIC_MAX_VECTOR;
+
+/*
+ * Following declarations are for revectoring; used when ISRs at different
+ * IPLs share an irq.
+ */
+static lock_t apic_revector_lock;
+int apic_revector_pending = 0;
+static uchar_t *apic_oldvec_to_newvec;
+static uchar_t *apic_newvec_to_oldvec;
+
+typedef struct prs_irq_list_ent {
+ int list_prio;
+ int32_t irq;
+ iflag_t intrflags;
+ acpi_prs_private_t prsprv;
+ struct prs_irq_list_ent *next;
+} prs_irq_list_t;
+
+
+/*
+ * ACPI variables
+ */
+/* 1 = acpi is enabled & working, 0 = acpi is not enabled or not there */
+int apic_enable_acpi = 0;
+
+/* ACPI Multiple APIC Description Table ptr */
+static MULTIPLE_APIC_TABLE *acpi_mapic_dtp = NULL;
+
+/* ACPI Interrupt Source Override Structure ptr */
+static MADT_INTERRUPT_OVERRIDE *acpi_isop = NULL;
+static int acpi_iso_cnt = 0;
+
+/* ACPI Non-maskable Interrupt Sources ptr */
+static MADT_NMI_SOURCE *acpi_nmi_sp = NULL;
+static int acpi_nmi_scnt = 0;
+static MADT_LOCAL_APIC_NMI *acpi_nmi_cp = NULL;
+static int acpi_nmi_ccnt = 0;
+
+extern int apic_pci_msi_enable_vector(dev_info_t *, int, int,
+ int, int, int);
+extern apic_irq_t *apic_find_irq(dev_info_t *, struct intrspec *, int);
+
+/*
+ * The following added to identify a software poweroff method if available.
+ */
+
+static struct {
+ int poweroff_method;
+ char oem_id[APIC_MPS_OEM_ID_LEN + 1]; /* MAX + 1 for NULL */
+ char prod_id[APIC_MPS_PROD_ID_LEN + 1]; /* MAX + 1 for NULL */
+} apic_mps_ids[] = {
+ { APIC_POWEROFF_VIA_RTC, "INTEL", "ALDER" }, /* 4300 */
+ { APIC_POWEROFF_VIA_RTC, "NCR", "AMC" }, /* 4300 */
+ { APIC_POWEROFF_VIA_ASPEN_BMC, "INTEL", "A450NX" }, /* 4400? */
+ { APIC_POWEROFF_VIA_ASPEN_BMC, "INTEL", "AD450NX" }, /* 4400 */
+ { APIC_POWEROFF_VIA_ASPEN_BMC, "INTEL", "AC450NX" }, /* 4400R */
+ { APIC_POWEROFF_VIA_SITKA_BMC, "INTEL", "S450NX" }, /* S50 */
+ { APIC_POWEROFF_VIA_SITKA_BMC, "INTEL", "SC450NX" } /* S50? */
+};
+
+int apic_poweroff_method = APIC_POWEROFF_NONE;
+
+/*
+ * Auto-configuration routines
+ */
+
+/*
+ * Look at MPSpec 1.4 (Intel Order # 242016-005) for details of what we do here
+ * May work with 1.1 - but not guaranteed.
+ * According to the MP Spec, the MP floating pointer structure
+ * will be searched in the order described below:
+ * 1. In the first kilobyte of Extended BIOS Data Area (EBDA)
+ * 2. Within the last kilobyte of system base memory
+ * 3. In the BIOS ROM address space between 0F0000h and 0FFFFh
+ * Once we find the right signature with proper checksum, we call
+ * either handle_defconf or parse_mpct to get all info necessary for
+ * subsequent operations.
+ */
+int
+apic_probe_common(char *modname)
+{
+ uint32_t mpct_addr, ebda_start = 0, base_mem_end;
+ caddr_t biosdatap;
+ caddr_t mpct;
+ caddr_t fptr;
+ int i, mpct_size, mapsize, retval = PSM_FAILURE;
+ ushort_t ebda_seg, base_mem_size;
+ struct apic_mpfps_hdr *fpsp;
+ struct apic_mp_cnf_hdr *hdrp;
+ int bypass_cpu_and_ioapics_in_mptables;
+ int acpi_user_options;
+
+ if (apic_forceload < 0)
+ return (retval);
+
+ /*
+ * Remember who we are
+ */
+ psm_name = modname;
+
+ /* Allow override for MADT-only mode */
+ acpi_user_options = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_root_node(), 0,
+ "acpi-user-options", 0);
+ apic_use_acpi_madt_only = ((acpi_user_options & ACPI_OUSER_MADT) != 0);
+
+ /* Allow apic_use_acpi to override MADT-only mode */
+ if (!apic_use_acpi)
+ apic_use_acpi_madt_only = 0;
+
+ retval = acpi_probe(modname);
+
+ /*
+ * mapin the bios data area 40:0
+ * 40:13h - two-byte location reports the base memory size
+ * 40:0Eh - two-byte location for the exact starting address of
+ * the EBDA segment for EISA
+ */
+ biosdatap = psm_map_phys(0x400, 0x20, PROT_READ);
+ if (!biosdatap)
+ return (retval);
+ fpsp = (struct apic_mpfps_hdr *)NULL;
+ mapsize = MPFPS_RAM_WIN_LEN;
+ /*LINTED: pointer cast may result in improper alignment */
+ ebda_seg = *((ushort_t *)(biosdatap+0xe));
+ /* check the 1k of EBDA */
+ if (ebda_seg) {
+ ebda_start = ((uint32_t)ebda_seg) << 4;
+ fptr = psm_map_phys(ebda_start, MPFPS_RAM_WIN_LEN, PROT_READ);
+ if (fptr) {
+ if (!(fpsp =
+ apic_find_fps_sig(fptr, MPFPS_RAM_WIN_LEN)))
+ psm_unmap_phys(fptr, MPFPS_RAM_WIN_LEN);
+ }
+ }
+ /* If not in EBDA, check the last k of system base memory */
+ if (!fpsp) {
+ /*LINTED: pointer cast may result in improper alignment */
+ base_mem_size = *((ushort_t *)(biosdatap + 0x13));
+
+ if (base_mem_size > 512)
+ base_mem_end = 639 * 1024;
+ else
+ base_mem_end = 511 * 1024;
+ /* if ebda == last k of base mem, skip to check BIOS ROM */
+ if (base_mem_end != ebda_start) {
+
+ fptr = psm_map_phys(base_mem_end, MPFPS_RAM_WIN_LEN,
+ PROT_READ);
+
+ if (fptr) {
+ if (!(fpsp = apic_find_fps_sig(fptr,
+ MPFPS_RAM_WIN_LEN)))
+ psm_unmap_phys(fptr, MPFPS_RAM_WIN_LEN);
+ }
+ }
+ }
+ psm_unmap_phys(biosdatap, 0x20);
+
+ /* If still cannot find it, check the BIOS ROM space */
+ if (!fpsp) {
+ mapsize = MPFPS_ROM_WIN_LEN;
+ fptr = psm_map_phys(MPFPS_ROM_WIN_START,
+ MPFPS_ROM_WIN_LEN, PROT_READ);
+ if (fptr) {
+ if (!(fpsp =
+ apic_find_fps_sig(fptr, MPFPS_ROM_WIN_LEN))) {
+ psm_unmap_phys(fptr, MPFPS_ROM_WIN_LEN);
+ return (retval);
+ }
+ }
+ }
+
+ if (apic_checksum((caddr_t)fpsp, fpsp->mpfps_length * 16) != 0) {
+ psm_unmap_phys(fptr, MPFPS_ROM_WIN_LEN);
+ return (retval);
+ }
+
+ apic_spec_rev = fpsp->mpfps_spec_rev;
+ if ((apic_spec_rev != 04) && (apic_spec_rev != 01)) {
+ psm_unmap_phys(fptr, MPFPS_ROM_WIN_LEN);
+ return (retval);
+ }
+
+ /* check IMCR is present or not */
+ apic_imcrp = fpsp->mpfps_featinfo2 & MPFPS_FEATINFO2_IMCRP;
+
+ /* check default configuration (dual CPUs) */
+ if ((apic_defconf = fpsp->mpfps_featinfo1) != 0) {
+ psm_unmap_phys(fptr, mapsize);
+ return (apic_handle_defconf());
+ }
+
+ /* MP Configuration Table */
+ mpct_addr = (uint32_t)(fpsp->mpfps_mpct_paddr);
+
+ psm_unmap_phys(fptr, mapsize); /* unmap floating ptr struct */
+
+ /*
+ * Map in enough memory for the MP Configuration Table Header.
+ * Use this table to read the total length of the BIOS data and
+ * map in all the info
+ */
+ /*LINTED: pointer cast may result in improper alignment */
+ hdrp = (struct apic_mp_cnf_hdr *)psm_map_phys(mpct_addr,
+ sizeof (struct apic_mp_cnf_hdr), PROT_READ);
+ if (!hdrp)
+ return (retval);
+
+ /* check mp configuration table signature PCMP */
+ if (hdrp->mpcnf_sig != 0x504d4350) {
+ psm_unmap_phys((caddr_t)hdrp, sizeof (struct apic_mp_cnf_hdr));
+ return (retval);
+ }
+ mpct_size = (int)hdrp->mpcnf_tbl_length;
+
+ apic_set_pwroff_method_from_mpcnfhdr(hdrp);
+
+ psm_unmap_phys((caddr_t)hdrp, sizeof (struct apic_mp_cnf_hdr));
+
+ if ((retval == PSM_SUCCESS) && !apic_use_acpi_madt_only) {
+ /* This is an ACPI machine No need for further checks */
+ return (retval);
+ }
+
+ /*
+ * Map in the entries for this machine, ie. Processor
+ * Entry Tables, Bus Entry Tables, etc.
+ * They are in fixed order following one another
+ */
+ mpct = psm_map_phys(mpct_addr, mpct_size, PROT_READ);
+ if (!mpct)
+ return (retval);
+
+ if (apic_checksum(mpct, mpct_size) != 0)
+ goto apic_fail1;
+
+
+ /*LINTED: pointer cast may result in improper alignment */
+ hdrp = (struct apic_mp_cnf_hdr *)mpct;
+ apicadr = (uint32_t *)mapin_apic((uint32_t)hdrp->mpcnf_local_apic,
+ APIC_LOCAL_MEMLEN, PROT_READ | PROT_WRITE);
+ if (!apicadr)
+ goto apic_fail1;
+
+ /* Parse all information in the tables */
+ bypass_cpu_and_ioapics_in_mptables = (retval == PSM_SUCCESS);
+ if (apic_parse_mpct(mpct, bypass_cpu_and_ioapics_in_mptables) ==
+ PSM_SUCCESS)
+ return (PSM_SUCCESS);
+
+ for (i = 0; i < apic_io_max; i++)
+ mapout_ioapic((caddr_t)apicioadr[i], APIC_IO_MEMLEN);
+ if (apic_cpus)
+ kmem_free(apic_cpus, apic_cpus_size);
+ if (apicadr)
+ mapout_apic((caddr_t)apicadr, APIC_LOCAL_MEMLEN);
+apic_fail1:
+ psm_unmap_phys(mpct, mpct_size);
+ return (retval);
+}
+
+static void
+apic_set_pwroff_method_from_mpcnfhdr(struct apic_mp_cnf_hdr *hdrp)
+{
+ int i;
+
+ for (i = 0; i < (sizeof (apic_mps_ids) / sizeof (apic_mps_ids[0]));
+ i++) {
+ if ((strncmp(hdrp->mpcnf_oem_str, apic_mps_ids[i].oem_id,
+ strlen(apic_mps_ids[i].oem_id)) == 0) &&
+ (strncmp(hdrp->mpcnf_prod_str, apic_mps_ids[i].prod_id,
+ strlen(apic_mps_ids[i].prod_id)) == 0)) {
+
+ apic_poweroff_method = apic_mps_ids[i].poweroff_method;
+ break;
+ }
+ }
+
+ if (apic_debug_mps_id != 0) {
+ cmn_err(CE_CONT, "%s: MPS OEM ID = '%c%c%c%c%c%c%c%c'"
+ "Product ID = '%c%c%c%c%c%c%c%c%c%c%c%c'\n",
+ psm_name,
+ hdrp->mpcnf_oem_str[0],
+ hdrp->mpcnf_oem_str[1],
+ hdrp->mpcnf_oem_str[2],
+ hdrp->mpcnf_oem_str[3],
+ hdrp->mpcnf_oem_str[4],
+ hdrp->mpcnf_oem_str[5],
+ hdrp->mpcnf_oem_str[6],
+ hdrp->mpcnf_oem_str[7],
+ hdrp->mpcnf_prod_str[0],
+ hdrp->mpcnf_prod_str[1],
+ hdrp->mpcnf_prod_str[2],
+ hdrp->mpcnf_prod_str[3],
+ hdrp->mpcnf_prod_str[4],
+ hdrp->mpcnf_prod_str[5],
+ hdrp->mpcnf_prod_str[6],
+ hdrp->mpcnf_prod_str[7],
+ hdrp->mpcnf_prod_str[8],
+ hdrp->mpcnf_prod_str[9],
+ hdrp->mpcnf_prod_str[10],
+ hdrp->mpcnf_prod_str[11]);
+ }
+}
+
+static int
+acpi_probe(char *modname)
+{
+ int i, intmax, index, rv;
+ uint32_t id, ver;
+ int acpi_verboseflags = 0;
+ int madt_seen, madt_size;
+ APIC_HEADER *ap;
+ MADT_PROCESSOR_APIC *mpa;
+ MADT_IO_APIC *mia;
+ MADT_IO_SAPIC *misa;
+ MADT_INTERRUPT_OVERRIDE *mio;
+ MADT_NMI_SOURCE *mns;
+ MADT_INTERRUPT_SOURCE *mis;
+ MADT_LOCAL_APIC_NMI *mlan;
+ MADT_ADDRESS_OVERRIDE *mao;
+ ACPI_OBJECT_LIST arglist;
+ ACPI_OBJECT arg;
+ int sci;
+ iflag_t sci_flags;
+ volatile uint32_t *ioapic;
+ int apic_ix;
+ char local_ids[NCPU];
+ char proc_ids[NCPU];
+ uchar_t hid;
+
+ if (!apic_use_acpi)
+ return (PSM_FAILURE);
+
+ if (AcpiGetFirmwareTable(APIC_SIG, 1, ACPI_LOGICAL_ADDRESSING,
+ (ACPI_TABLE_HEADER **) &acpi_mapic_dtp) != AE_OK)
+ return (PSM_FAILURE);
+
+ apicadr = mapin_apic((uint32_t)acpi_mapic_dtp->LocalApicAddress,
+ APIC_LOCAL_MEMLEN, PROT_READ | PROT_WRITE);
+ if (!apicadr)
+ return (PSM_FAILURE);
+
+ id = apicadr[APIC_LID_REG];
+ local_ids[0] = (uchar_t)(id >> 24);
+ apic_nproc = index = 1;
+ CPUSET_ONLY(apic_cpumask, 0);
+ apic_io_max = 0;
+
+ ap = (APIC_HEADER *) (acpi_mapic_dtp + 1);
+ madt_size = acpi_mapic_dtp->Length;
+ madt_seen = sizeof (*acpi_mapic_dtp);
+
+ while (madt_seen < madt_size) {
+ switch (ap->Type) {
+ case APIC_PROCESSOR:
+ mpa = (MADT_PROCESSOR_APIC *) ap;
+ if (mpa->ProcessorEnabled) {
+ if (mpa->LocalApicId == local_ids[0])
+ proc_ids[0] = mpa->ProcessorId;
+ else if (apic_nproc < NCPU) {
+ local_ids[index] = mpa->LocalApicId;
+ proc_ids[index] = mpa->ProcessorId;
+ CPUSET_ADD(apic_cpumask, index);
+ index++;
+ apic_nproc++;
+ } else
+ cmn_err(CE_WARN, "%s: exceeded "
+ "maximum no. of CPUs (= %d)",
+ psm_name, NCPU);
+ }
+ break;
+
+ case APIC_IO:
+ mia = (MADT_IO_APIC *) ap;
+ if (apic_io_max < MAX_IO_APIC) {
+ apic_ix = apic_io_max;
+ apic_io_id[apic_io_max] = mia->IoApicId;
+ apic_io_vectbase[apic_io_max] =
+ mia->Interrupt;
+ apic_physaddr[apic_io_max] =
+ (uint32_t)mia->Address;
+ ioapic = apicioadr[apic_io_max] =
+ mapin_ioapic((uint32_t)mia->Address,
+ APIC_IO_MEMLEN, PROT_READ | PROT_WRITE);
+ if (!ioapic)
+ goto cleanup;
+ apic_io_max++;
+ }
+ break;
+
+ case APIC_XRUPT_OVERRIDE:
+ mio = (MADT_INTERRUPT_OVERRIDE *) ap;
+ if (acpi_isop == NULL)
+ acpi_isop = mio;
+ acpi_iso_cnt++;
+ break;
+
+ case APIC_NMI:
+ /* UNIMPLEMENTED */
+ mns = (MADT_NMI_SOURCE *) ap;
+ if (acpi_nmi_sp == NULL)
+ acpi_nmi_sp = mns;
+ acpi_nmi_scnt++;
+
+ cmn_err(CE_NOTE, "!apic: nmi source: %d %d %d\n",
+ mns->Interrupt, mns->Polarity,
+ mns->TriggerMode);
+ break;
+
+ case APIC_LOCAL_NMI:
+ /* UNIMPLEMENTED */
+ mlan = (MADT_LOCAL_APIC_NMI *) ap;
+ if (acpi_nmi_cp == NULL)
+ acpi_nmi_cp = mlan;
+ acpi_nmi_ccnt++;
+
+ cmn_err(CE_NOTE, "!apic: local nmi: %d %d %d %d\n",
+ mlan->ProcessorId, mlan->Polarity,
+ mlan->TriggerMode, mlan->Lint);
+ break;
+
+ case APIC_ADDRESS_OVERRIDE:
+ /* UNIMPLEMENTED */
+ mao = (MADT_ADDRESS_OVERRIDE *) ap;
+ cmn_err(CE_NOTE, "!apic: address override: %lx\n",
+ (long)mao->Address);
+ break;
+
+ case APIC_IO_SAPIC:
+ /* UNIMPLEMENTED */
+ misa = (MADT_IO_SAPIC *) ap;
+
+ cmn_err(CE_NOTE, "!apic: io sapic: %d %d %lx\n",
+ misa->IoSapicId, misa->InterruptBase,
+ (long)misa->Address);
+ break;
+
+ case APIC_XRUPT_SOURCE:
+ /* UNIMPLEMENTED */
+ mis = (MADT_INTERRUPT_SOURCE *) ap;
+
+ cmn_err(CE_NOTE,
+ "!apic: irq source: %d %d %d %d %d %d %d\n",
+ mis->ProcessorId, mis->ProcessorEid,
+ mis->Interrupt, mis->Polarity,
+ mis->TriggerMode, mis->InterruptType,
+ mis->IoSapicVector);
+ break;
+ default:
+ break;
+ }
+
+ /* advance to next entry */
+ madt_seen += ap->Length;
+ ap = (APIC_HEADER *)(((char *)ap) + ap->Length);
+ }
+
+ apic_cpus_size = apic_nproc * sizeof (*apic_cpus);
+ if ((apic_cpus = kmem_zalloc(apic_cpus_size, KM_NOSLEEP)) == NULL)
+ goto cleanup;
+
+ /*
+ * ACPI doesn't provide the local apic ver, get it directly from the
+ * local apic
+ */
+ ver = apicadr[APIC_VERS_REG];
+ for (i = 0; i < apic_nproc; i++) {
+ apic_cpus[i].aci_local_id = local_ids[i];
+ apic_cpus[i].aci_local_ver = (uchar_t)(ver & 0xFF);
+ }
+ for (i = 0; i < apic_io_max; i++) {
+ apic_ix = i;
+
+ /*
+ * need to check Sitka on the following acpi problem
+ * On the Sitka, the ioapic's apic_id field isn't reporting
+ * the actual io apic id. We have reported this problem
+ * to Intel. Until they fix the problem, we will get the
+ * actual id directly from the ioapic.
+ */
+ id = ioapic_read(apic_ix, APIC_ID_CMD);
+ hid = (uchar_t)(id >> 24);
+
+ if (hid != apic_io_id[i]) {
+ if (apic_io_id[i] == 0)
+ apic_io_id[i] = hid;
+ else { /* set ioapic id to whatever reported by ACPI */
+ id = ((uint32_t)apic_io_id[i]) << 24;
+ ioapic_write(apic_ix, APIC_ID_CMD, id);
+ }
+ }
+ ver = ioapic_read(apic_ix, APIC_VERS_CMD);
+ apic_io_ver[i] = (uchar_t)(ver & 0xff);
+ intmax = (ver >> 16) & 0xff;
+ apic_io_vectend[i] = apic_io_vectbase[i] + intmax;
+ if (apic_first_avail_irq <= apic_io_vectend[i])
+ apic_first_avail_irq = apic_io_vectend[i] + 1;
+ }
+
+
+ /*
+ * Process SCI configuration here
+ * An error may be returned here if
+ * acpi-user-options specifies legacy mode
+ * (no SCI, no ACPI mode)
+ */
+ if (acpica_get_sci(&sci, &sci_flags) != AE_OK)
+ sci = -1;
+
+ /*
+ * Now call acpi_init() to generate namespaces
+ * If this fails, we don't attempt to use ACPI
+ * even if we were able to get a MADT above
+ */
+ if (acpica_init() != AE_OK)
+ goto cleanup;
+
+ /*
+ * Squirrel away the SCI and flags for later on
+ * in apic_picinit() when we're ready
+ */
+ apic_sci_vect = sci;
+ apic_sci_flags = sci_flags;
+
+ if (apic_verbose & APIC_VERBOSE_IRQ_FLAG)
+ acpi_verboseflags |= PSM_VERBOSE_IRQ_FLAG;
+
+ if (apic_verbose & APIC_VERBOSE_POWEROFF_FLAG)
+ acpi_verboseflags |= PSM_VERBOSE_POWEROFF_FLAG;
+
+ if (apic_verbose & APIC_VERBOSE_POWEROFF_PAUSE_FLAG)
+ acpi_verboseflags |= PSM_VERBOSE_POWEROFF_PAUSE_FLAG;
+
+ if (acpi_psm_init(modname, acpi_verboseflags) == ACPI_PSM_FAILURE)
+ goto cleanup;
+
+ /* Enable ACPI APIC interrupt routing */
+ arglist.Count = 1;
+ arglist.Pointer = &arg;
+ arg.Type = ACPI_TYPE_INTEGER;
+ arg.Integer.Value = ACPI_APIC_MODE; /* 1 */
+ rv = AcpiEvaluateObject(NULL, "\\_PIC", &arglist, NULL);
+ if (rv == AE_OK) {
+ build_reserved_irqlist((uchar_t *)apic_reserved_irqlist);
+ apic_enable_acpi = 1;
+ if (apic_use_acpi_madt_only) {
+ cmn_err(CE_CONT,
+ "?Using ACPI for CPU/IOAPIC information ONLY\n");
+ }
+ return (PSM_SUCCESS);
+ }
+ /* if setting APIC mode failed above, we fall through to cleanup */
+
+cleanup:
+ if (apicadr != NULL) {
+ mapout_apic((caddr_t)apicadr, APIC_LOCAL_MEMLEN);
+ apicadr = NULL;
+ }
+ apic_nproc = 0;
+ for (i = 0; i < apic_io_max; i++) {
+ mapout_ioapic((caddr_t)apicioadr[i], APIC_IO_MEMLEN);
+ apicioadr[i] = NULL;
+ }
+ apic_io_max = 0;
+ acpi_isop = NULL;
+ acpi_iso_cnt = 0;
+ acpi_nmi_sp = NULL;
+ acpi_nmi_scnt = 0;
+ acpi_nmi_cp = NULL;
+ acpi_nmi_ccnt = 0;
+ return (PSM_FAILURE);
+}
+
+/*
+ * Handle default configuration. Fill in reqd global variables & tables
+ * Fill all details as MP table does not give any more info
+ */
+static int
+apic_handle_defconf()
+{
+ uint_t lid;
+
+ /*LINTED: pointer cast may result in improper alignment */
+ apicioadr[0] = mapin_ioapic(APIC_IO_ADDR,
+ APIC_IO_MEMLEN, PROT_READ | PROT_WRITE);
+ /*LINTED: pointer cast may result in improper alignment */
+ apicadr = (uint32_t *)psm_map_phys(APIC_LOCAL_ADDR,
+ APIC_LOCAL_MEMLEN, PROT_READ);
+ apic_cpus_size = 2 * sizeof (*apic_cpus);
+ apic_cpus = (apic_cpus_info_t *)
+ kmem_zalloc(apic_cpus_size, KM_NOSLEEP);
+ if ((!apicadr) || (!apicioadr[0]) || (!apic_cpus))
+ goto apic_handle_defconf_fail;
+ CPUSET_ONLY(apic_cpumask, 0);
+ CPUSET_ADD(apic_cpumask, 1);
+ apic_nproc = 2;
+ lid = apicadr[APIC_LID_REG];
+ apic_cpus[0].aci_local_id = (uchar_t)(lid >> APIC_ID_BIT_OFFSET);
+ /*
+ * According to the PC+MP spec 1.1, the local ids
+ * for the default configuration has to be 0 or 1
+ */
+ if (apic_cpus[0].aci_local_id == 1)
+ apic_cpus[1].aci_local_id = 0;
+ else if (apic_cpus[0].aci_local_id == 0)
+ apic_cpus[1].aci_local_id = 1;
+ else
+ goto apic_handle_defconf_fail;
+
+ apic_io_id[0] = 2;
+ apic_io_max = 1;
+ if (apic_defconf >= 5) {
+ apic_cpus[0].aci_local_ver = APIC_INTEGRATED_VERS;
+ apic_cpus[1].aci_local_ver = APIC_INTEGRATED_VERS;
+ apic_io_ver[0] = APIC_INTEGRATED_VERS;
+ } else {
+ apic_cpus[0].aci_local_ver = 0; /* 82489 DX */
+ apic_cpus[1].aci_local_ver = 0;
+ apic_io_ver[0] = 0;
+ }
+ if (apic_defconf == 2 || apic_defconf == 3 || apic_defconf == 6)
+ eisa_level_intr_mask = (inb(EISA_LEVEL_CNTL + 1) << 8) |
+ inb(EISA_LEVEL_CNTL) | ((uint_t)INT32_MAX + 1);
+ return (PSM_SUCCESS);
+
+apic_handle_defconf_fail:
+ if (apic_cpus)
+ kmem_free(apic_cpus, apic_cpus_size);
+ if (apicadr)
+ mapout_apic((caddr_t)apicadr, APIC_LOCAL_MEMLEN);
+ if (apicioadr[0])
+ mapout_ioapic((caddr_t)apicioadr[0], APIC_IO_MEMLEN);
+ return (PSM_FAILURE);
+}
+
+/* Parse the entries in MP configuration table and collect info that we need */
+static int
+apic_parse_mpct(caddr_t mpct, int bypass_cpus_and_ioapics)
+{
+ struct apic_procent *procp;
+ struct apic_bus *busp;
+ struct apic_io_entry *ioapicp;
+ struct apic_io_intr *intrp;
+ int apic_ix;
+ uint_t lid;
+ uint32_t id;
+ uchar_t hid;
+
+ /*LINTED: pointer cast may result in improper alignment */
+ procp = (struct apic_procent *)(mpct + sizeof (struct apic_mp_cnf_hdr));
+
+ /* No need to count cpu entries if we won't use them */
+ if (!bypass_cpus_and_ioapics) {
+
+ /* Find max # of CPUS and allocate structure accordingly */
+ apic_nproc = 0;
+ CPUSET_ZERO(apic_cpumask);
+ while (procp->proc_entry == APIC_CPU_ENTRY) {
+ if (procp->proc_cpuflags & CPUFLAGS_EN) {
+ if (apic_nproc < NCPU)
+ CPUSET_ADD(apic_cpumask, apic_nproc);
+ apic_nproc++;
+ }
+ procp++;
+ }
+ if (apic_nproc > NCPU)
+ cmn_err(CE_WARN, "%s: exceeded "
+ "maximum no. of CPUs (= %d)", psm_name, NCPU);
+ apic_cpus_size = apic_nproc * sizeof (*apic_cpus);
+ if (!apic_nproc || !(apic_cpus = (apic_cpus_info_t *)
+ kmem_zalloc(apic_cpus_size, KM_NOSLEEP)))
+ return (PSM_FAILURE);
+ }
+
+ /*LINTED: pointer cast may result in improper alignment */
+ procp = (struct apic_procent *)(mpct + sizeof (struct apic_mp_cnf_hdr));
+
+ /*
+ * start with index 1 as 0 needs to be filled in with Boot CPU, but
+ * if we're bypassing this information, it has already been filled
+ * in by acpi_probe(), so don't overwrite it.
+ */
+ if (!bypass_cpus_and_ioapics)
+ apic_nproc = 1;
+
+ while (procp->proc_entry == APIC_CPU_ENTRY) {
+ /* check whether the cpu exists or not */
+ if (!bypass_cpus_and_ioapics &&
+ procp->proc_cpuflags & CPUFLAGS_EN) {
+ if (procp->proc_cpuflags & CPUFLAGS_BP) { /* Boot CPU */
+ lid = apicadr[APIC_LID_REG];
+ apic_cpus[0].aci_local_id = procp->proc_apicid;
+ if (apic_cpus[0].aci_local_id !=
+ (uchar_t)(lid >> APIC_ID_BIT_OFFSET)) {
+ return (PSM_FAILURE);
+ }
+ apic_cpus[0].aci_local_ver =
+ procp->proc_version;
+ } else {
+
+ apic_cpus[apic_nproc].aci_local_id =
+ procp->proc_apicid;
+ apic_cpus[apic_nproc].aci_local_ver =
+ procp->proc_version;
+ apic_nproc++;
+
+ }
+ }
+ procp++;
+ }
+
+ /*
+ * Save start of bus entries for later use.
+ * Get EISA level cntrl if EISA bus is present.
+ * Also get the CPI bus id for single CPI bus case
+ */
+ apic_busp = busp = (struct apic_bus *)procp;
+ while (busp->bus_entry == APIC_BUS_ENTRY) {
+ lid = apic_find_bus_type((char *)&busp->bus_str1);
+ if (lid == BUS_EISA) {
+ eisa_level_intr_mask = (inb(EISA_LEVEL_CNTL + 1) << 8) |
+ inb(EISA_LEVEL_CNTL) | ((uint_t)INT32_MAX + 1);
+ } else if (lid == BUS_PCI) {
+ /*
+ * apic_single_pci_busid will be used only if
+ * apic_pic_bus_total is equal to 1
+ */
+ apic_pci_bus_total++;
+ apic_single_pci_busid = busp->bus_id;
+ }
+ busp++;
+ }
+
+ ioapicp = (struct apic_io_entry *)busp;
+
+ if (!bypass_cpus_and_ioapics)
+ apic_io_max = 0;
+ do {
+ if (!bypass_cpus_and_ioapics && apic_io_max < MAX_IO_APIC) {
+ if (ioapicp->io_flags & IOAPIC_FLAGS_EN) {
+ apic_io_id[apic_io_max] = ioapicp->io_apicid;
+ apic_io_ver[apic_io_max] = ioapicp->io_version;
+ /*LINTED: pointer cast may result in improper alignment */
+ apicioadr[apic_io_max] =
+ mapin_ioapic(
+ (uint32_t)ioapicp->io_apic_addr,
+ APIC_IO_MEMLEN, PROT_READ | PROT_WRITE);
+
+ if (!apicioadr[apic_io_max])
+ return (PSM_FAILURE);
+
+ apic_ix = apic_io_max;
+ id = ioapic_read(apic_ix, APIC_ID_CMD);
+ hid = (uchar_t)(id >> 24);
+
+ if (hid != apic_io_id[apic_io_max]) {
+ if (apic_io_id[apic_io_max] == 0)
+ apic_io_id[apic_io_max] = hid;
+ else {
+ /*
+ * set ioapic id to whatever
+ * reported by MPS
+ *
+ * may not need to set index
+ * again ???
+ * take it out and try
+ */
+
+ id = ((uint32_t)
+ apic_io_id[apic_io_max]) <<
+ 24;
+
+ ioapic_write(apic_ix,
+ APIC_ID_CMD, id);
+ }
+ }
+ apic_io_max++;
+ }
+ }
+ ioapicp++;
+ } while (ioapicp->io_entry == APIC_IO_ENTRY);
+
+ apic_io_intrp = (struct apic_io_intr *)ioapicp;
+
+ intrp = apic_io_intrp;
+ while (intrp->intr_entry == APIC_IO_INTR_ENTRY) {
+ if ((intrp->intr_irq > APIC_MAX_ISA_IRQ) ||
+ (apic_find_bus(intrp->intr_busid) == BUS_PCI)) {
+ apic_irq_translate = 1;
+ break;
+ }
+ intrp++;
+ }
+
+ return (PSM_SUCCESS);
+}
+
+boolean_t
+apic_cpu_in_range(int cpu)
+{
+ return ((cpu & ~IRQ_USER_BOUND) < apic_nproc);
+}
+
+static struct apic_mpfps_hdr *
+apic_find_fps_sig(caddr_t cptr, int len)
+{
+ int i;
+
+ /* Look for the pattern "_MP_" */
+ for (i = 0; i < len; i += 16) {
+ if ((*(cptr+i) == '_') &&
+ (*(cptr+i+1) == 'M') &&
+ (*(cptr+i+2) == 'P') &&
+ (*(cptr+i+3) == '_'))
+ /*LINTED: pointer cast may result in improper alignment */
+ return ((struct apic_mpfps_hdr *)(cptr + i));
+ }
+ return (NULL);
+}
+
+static int
+apic_checksum(caddr_t bptr, int len)
+{
+ int i;
+ uchar_t cksum;
+
+ cksum = 0;
+ for (i = 0; i < len; i++)
+ cksum += *bptr++;
+ return ((int)cksum);
+}
+
+
+/*
+ * Initialise vector->ipl and ipl->pri arrays. level_intr and irqtable
+ * are also set to NULL. vector->irq is set to a value which cannot map
+ * to a real irq to show that it is free.
+ */
+void
+apic_init_common()
+{
+ int i;
+ int *iptr;
+
+ /* cpu 0 is always up */
+ apic_cpus[0].aci_status = APIC_CPU_ONLINE | APIC_CPU_INTR_ENABLE;
+
+ iptr = (int *)&apic_irq_table[0];
+ for (i = 0; i <= APIC_MAX_VECTOR; i++) {
+ apic_level_intr[i] = 0;
+ *iptr++ = NULL;
+ apic_vector_to_irq[i] = APIC_RESV_IRQ;
+
+ /* These *must* be initted to B_TRUE! */
+ apic_reprogram_info[i].done = B_TRUE;
+ apic_reprogram_info[i].irqp = NULL;
+ apic_reprogram_info[i].tries = 0;
+ apic_reprogram_info[i].bindcpu = 0;
+ }
+
+ /*
+ * Allocate a dummy irq table entry for the reserved entry.
+ * This takes care of the race between removing an irq and
+ * clock detecting a CPU in that irq during interrupt load
+ * sampling.
+ */
+ apic_irq_table[APIC_RESV_IRQ] =
+ kmem_zalloc(sizeof (apic_irq_t), KM_NOSLEEP);
+
+ mutex_init(&airq_mutex, NULL, MUTEX_DEFAULT, NULL);
+}
+
+void
+ioapic_init_intr(int mask_apic)
+{
+ int apic_ix;
+ struct intrspec ispec;
+ apic_irq_t *irqptr;
+ int i, j;
+ ulong_t iflag;
+
+ LOCK_INIT_CLEAR(&apic_revector_lock);
+ LOCK_INIT_CLEAR(&apic_defer_reprogram_lock);
+
+ /* mask interrupt vectors */
+ for (j = 0; j < apic_io_max && mask_apic; j++) {
+ int intin_max;
+
+ apic_ix = j;
+ /* Bits 23-16 define the maximum redirection entries */
+ intin_max = (ioapic_read(apic_ix, APIC_VERS_CMD) >> 16) & 0xff;
+ for (i = 0; i < intin_max; i++)
+ ioapic_write(apic_ix, APIC_RDT_CMD + 2 * i, AV_MASK);
+ }
+
+ /*
+ * Hack alert: deal with ACPI SCI interrupt chicken/egg here
+ */
+ if (apic_sci_vect > 0) {
+ /*
+ * acpica has already done add_avintr(); we just
+ * to finish the job by mimicing translate_irq()
+ *
+ * Fake up an intrspec and setup the tables
+ */
+ ispec.intrspec_vec = apic_sci_vect;
+ ispec.intrspec_pri = SCI_IPL;
+
+ if (apic_setup_irq_table(NULL, apic_sci_vect, NULL,
+ &ispec, &apic_sci_flags, DDI_INTR_TYPE_FIXED) < 0) {
+ cmn_err(CE_WARN, "!apic: SCI setup failed");
+ return;
+ }
+ irqptr = apic_irq_table[apic_sci_vect];
+
+ iflag = intr_clear();
+ lock_set(&apic_ioapic_lock);
+
+ /* Program I/O APIC */
+ (void) apic_setup_io_intr(irqptr, apic_sci_vect, B_FALSE);
+
+ lock_clear(&apic_ioapic_lock);
+ intr_restore(iflag);
+
+ irqptr->airq_share++;
+ }
+}
+
+/*
+ * Add mask bits to disable interrupt vector from happening
+ * at or above IPL. In addition, it should remove mask bits
+ * to enable interrupt vectors below the given IPL.
+ *
+ * Both add and delspl are complicated by the fact that different interrupts
+ * may share IRQs. This can happen in two ways.
+ * 1. The same H/W line is shared by more than 1 device
+ * 1a. with interrupts at different IPLs
+ * 1b. with interrupts at same IPL
+ * 2. We ran out of vectors at a given IPL and started sharing vectors.
+ * 1b and 2 should be handled gracefully, except for the fact some ISRs
+ * will get called often when no interrupt is pending for the device.
+ * For 1a, we just hope that the machine blows up with the person who
+ * set it up that way!. In the meantime, we handle it at the higher IPL.
+ */
+/*ARGSUSED*/
+int
+apic_addspl_common(int irqno, int ipl, int min_ipl, int max_ipl)
+{
+ uchar_t vector;
+ ulong_t iflag;
+ apic_irq_t *irqptr, *irqheadptr;
+ int irqindex;
+
+ ASSERT(max_ipl <= UCHAR_MAX);
+ irqindex = IRQINDEX(irqno);
+
+ if ((irqindex == -1) || (!apic_irq_table[irqindex]))
+ return (PSM_FAILURE);
+
+ mutex_enter(&airq_mutex);
+ irqptr = irqheadptr = apic_irq_table[irqindex];
+
+ DDI_INTR_IMPLDBG((CE_CONT, "apic_addspl: dip=0x%p type=%d irqno=0x%x "
+ "vector=0x%x\n", (void *)irqptr->airq_dip,
+ irqptr->airq_mps_intr_index, irqno, irqptr->airq_vector));
+
+ while (irqptr) {
+ if (VIRTIRQ(irqindex, irqptr->airq_share_id) == irqno)
+ break;
+ irqptr = irqptr->airq_next;
+ }
+ irqptr->airq_share++;
+
+ mutex_exit(&airq_mutex);
+
+ /* return if it is not hardware interrupt */
+ if (irqptr->airq_mps_intr_index == RESERVE_INDEX)
+ return (PSM_SUCCESS);
+
+ /* Or if there are more interupts at a higher IPL */
+ if (ipl != max_ipl)
+ return (PSM_SUCCESS);
+
+ /*
+ * if apic_picinit() has not been called yet, just return.
+ * At the end of apic_picinit(), we will call setup_io_intr().
+ */
+
+ if (!apic_flag)
+ return (PSM_SUCCESS);
+
+ /*
+ * Upgrade vector if max_ipl is not earlier ipl. If we cannot allocate,
+ * return failure. Not very elegant, but then we hope the
+ * machine will blow up with ...
+ */
+ if (irqptr->airq_ipl != max_ipl) {
+ vector = apic_allocate_vector(max_ipl, irqindex, 1);
+ if (vector == 0) {
+ irqptr->airq_share--;
+ return (PSM_FAILURE);
+ }
+ irqptr = irqheadptr;
+ apic_mark_vector(irqptr->airq_vector, vector);
+ while (irqptr) {
+ irqptr->airq_vector = vector;
+ irqptr->airq_ipl = (uchar_t)max_ipl;
+ /*
+ * reprogram irq being added and every one else
+ * who is not in the UNINIT state
+ */
+ if ((VIRTIRQ(irqindex, irqptr->airq_share_id) ==
+ irqno) || (irqptr->airq_temp_cpu != IRQ_UNINIT)) {
+ apic_record_rdt_entry(irqptr, irqindex);
+
+ iflag = intr_clear();
+ lock_set(&apic_ioapic_lock);
+
+ (void) apic_setup_io_intr(irqptr, irqindex,
+ B_FALSE);
+
+ lock_clear(&apic_ioapic_lock);
+ intr_restore(iflag);
+ }
+ irqptr = irqptr->airq_next;
+ }
+ return (PSM_SUCCESS);
+ }
+
+ ASSERT(irqptr);
+
+ iflag = intr_clear();
+ lock_set(&apic_ioapic_lock);
+
+ (void) apic_setup_io_intr(irqptr, irqindex, B_FALSE);
+
+ lock_clear(&apic_ioapic_lock);
+ intr_restore(iflag);
+
+ return (PSM_SUCCESS);
+}
+
+/*
+ * Recompute mask bits for the given interrupt vector.
+ * If there is no interrupt servicing routine for this
+ * vector, this function should disable interrupt vector
+ * from happening at all IPLs. If there are still
+ * handlers using the given vector, this function should
+ * disable the given vector from happening below the lowest
+ * IPL of the remaining hadlers.
+ */
+/*ARGSUSED*/
+int
+apic_delspl_common(int irqno, int ipl, int min_ipl, int max_ipl)
+{
+ uchar_t vector, bind_cpu;
+ int intin, irqindex;
+ int apic_ix;
+ apic_irq_t *irqptr, *irqheadptr;
+ ulong_t iflag;
+
+ mutex_enter(&airq_mutex);
+ irqindex = IRQINDEX(irqno);
+ irqptr = irqheadptr = apic_irq_table[irqindex];
+
+ DDI_INTR_IMPLDBG((CE_CONT, "apic_delspl: dip=0x%p type=%d irqno=0x%x "
+ "vector=0x%x\n", (void *)irqptr->airq_dip,
+ irqptr->airq_mps_intr_index, irqno, irqptr->airq_vector));
+
+ while (irqptr) {
+ if (VIRTIRQ(irqindex, irqptr->airq_share_id) == irqno)
+ break;
+ irqptr = irqptr->airq_next;
+ }
+ ASSERT(irqptr);
+
+ irqptr->airq_share--;
+
+ mutex_exit(&airq_mutex);
+
+ if (ipl < max_ipl)
+ return (PSM_SUCCESS);
+
+ /* return if it is not hardware interrupt */
+ if (irqptr->airq_mps_intr_index == RESERVE_INDEX)
+ return (PSM_SUCCESS);
+
+ if (!apic_flag) {
+ /*
+ * Clear irq_struct. If two devices shared an intpt
+ * line & 1 unloaded before picinit, we are hosed. But, then
+ * we hope the machine will ...
+ */
+ irqptr->airq_mps_intr_index = FREE_INDEX;
+ irqptr->airq_temp_cpu = IRQ_UNINIT;
+ apic_free_vector(irqptr->airq_vector);
+ return (PSM_SUCCESS);
+ }
+ /*
+ * Downgrade vector to new max_ipl if needed.If we cannot allocate,
+ * use old IPL. Not very elegant, but then we hope ...
+ */
+ if ((irqptr->airq_ipl != max_ipl) && (max_ipl != PSM_INVALID_IPL)) {
+ apic_irq_t *irqp;
+ if (vector = apic_allocate_vector(max_ipl, irqno, 1)) {
+ apic_mark_vector(irqheadptr->airq_vector, vector);
+ irqp = irqheadptr;
+ while (irqp) {
+ irqp->airq_vector = vector;
+ irqp->airq_ipl = (uchar_t)max_ipl;
+ if (irqp->airq_temp_cpu != IRQ_UNINIT) {
+ apic_record_rdt_entry(irqp, irqindex);
+
+ iflag = intr_clear();
+ lock_set(&apic_ioapic_lock);
+
+ (void) apic_setup_io_intr(irqp,
+ irqindex, B_FALSE);
+
+ lock_clear(&apic_ioapic_lock);
+ intr_restore(iflag);
+ }
+ irqp = irqp->airq_next;
+ }
+ }
+ }
+
+ if (irqptr->airq_share)
+ return (PSM_SUCCESS);
+
+ iflag = intr_clear();
+ lock_set(&apic_ioapic_lock);
+
+ /* Disable the MSI/X vector */
+ if (APIC_IS_MSI_OR_MSIX_INDEX(irqptr->airq_mps_intr_index)) {
+ int type = (irqptr->airq_mps_intr_index == MSI_INDEX) ?
+ DDI_INTR_TYPE_MSI : DDI_INTR_TYPE_MSIX;
+
+ /*
+ * Make sure we only disable on the last
+ * of the multi-MSI support
+ */
+ if (i_ddi_intr_get_current_nintrs(irqptr->airq_dip) == 1) {
+ (void) apic_pci_msi_unconfigure(irqptr->airq_dip,
+ type, irqptr->airq_ioapicindex);
+
+ (void) apic_pci_msi_disable_mode(irqptr->airq_dip,
+ type, irqptr->airq_ioapicindex);
+ }
+ } else {
+ apic_ix = irqptr->airq_ioapicindex;
+ intin = irqptr->airq_intin_no;
+ ioapic_write(apic_ix, APIC_RDT_CMD + 2 * intin, AV_MASK);
+ }
+
+ if (max_ipl == PSM_INVALID_IPL) {
+ ASSERT(irqheadptr == irqptr);
+ bind_cpu = irqptr->airq_temp_cpu;
+ if (((uchar_t)bind_cpu != IRQ_UNBOUND) &&
+ ((uchar_t)bind_cpu != IRQ_UNINIT)) {
+ ASSERT((bind_cpu & ~IRQ_USER_BOUND) < apic_nproc);
+ if (bind_cpu & IRQ_USER_BOUND) {
+ /* If hardbound, temp_cpu == cpu */
+ bind_cpu &= ~IRQ_USER_BOUND;
+ apic_cpus[bind_cpu].aci_bound--;
+ } else
+ apic_cpus[bind_cpu].aci_temp_bound--;
+ }
+ irqptr->airq_temp_cpu = IRQ_UNINIT;
+ irqptr->airq_mps_intr_index = FREE_INDEX;
+ lock_clear(&apic_ioapic_lock);
+ intr_restore(iflag);
+ apic_free_vector(irqptr->airq_vector);
+ return (PSM_SUCCESS);
+ }
+ lock_clear(&apic_ioapic_lock);
+ intr_restore(iflag);
+
+ mutex_enter(&airq_mutex);
+ if ((irqptr == apic_irq_table[irqindex])) {
+ apic_irq_t *oldirqptr;
+ /* Move valid irq entry to the head */
+ irqheadptr = oldirqptr = irqptr;
+ irqptr = irqptr->airq_next;
+ ASSERT(irqptr);
+ while (irqptr) {
+ if (irqptr->airq_mps_intr_index != FREE_INDEX)
+ break;
+ oldirqptr = irqptr;
+ irqptr = irqptr->airq_next;
+ }
+ /* remove all invalid ones from the beginning */
+ apic_irq_table[irqindex] = irqptr;
+ /*
+ * and link them back after the head. The invalid ones
+ * begin with irqheadptr and end at oldirqptr
+ */
+ oldirqptr->airq_next = irqptr->airq_next;
+ irqptr->airq_next = irqheadptr;
+ }
+ mutex_exit(&airq_mutex);
+
+ irqptr->airq_temp_cpu = IRQ_UNINIT;
+ irqptr->airq_mps_intr_index = FREE_INDEX;
+
+ return (PSM_SUCCESS);
+}
+
+/*
+ * apic_introp_xlate() replaces apic_translate_irq() and is
+ * called only from apic_intr_ops(). With the new ADII framework,
+ * the priority can no longer be retrieved through i_ddi_get_intrspec().
+ * It has to be passed in from the caller.
+ */
+int
+apic_introp_xlate(dev_info_t *dip, struct intrspec *ispec, int type)
+{
+ char dev_type[16];
+ int dev_len, pci_irq, newirq, bustype, devid, busid, i;
+ int irqno = ispec->intrspec_vec;
+ ddi_acc_handle_t cfg_handle;
+ uchar_t ipin;
+ struct apic_io_intr *intrp;
+ iflag_t intr_flag;
+ APIC_HEADER *hp;
+ MADT_INTERRUPT_OVERRIDE *isop;
+ apic_irq_t *airqp;
+ int parent_is_pci_or_pciex = 0;
+ int child_is_pciex = 0;
+
+ DDI_INTR_IMPLDBG((CE_CONT, "apic_introp_xlate: dip=0x%p name=%s "
+ "type=%d irqno=0x%x\n", (void *)dip, ddi_get_name(dip), type,
+ irqno));
+
+ dev_len = sizeof (dev_type);
+ if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ddi_get_parent(dip),
+ DDI_PROP_DONTPASS, "device_type", (caddr_t)dev_type,
+ &dev_len) == DDI_PROP_SUCCESS) {
+ if ((strcmp(dev_type, "pci") == 0) ||
+ (strcmp(dev_type, "pciex") == 0))
+ parent_is_pci_or_pciex = 1;
+ }
+
+ if (parent_is_pci_or_pciex && ddi_prop_get_int(DDI_DEV_T_ANY, dip,
+ DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL) !=
+ PCI_CAP_NEXT_PTR_NULL) {
+ child_is_pciex = 1;
+ }
+
+ if (DDI_INTR_IS_MSI_OR_MSIX(type)) {
+ if ((airqp = apic_find_irq(dip, ispec, type)) != NULL) {
+ airqp->airq_iflag.bustype =
+ child_is_pciex ? BUS_PCIE : BUS_PCI;
+ return (apic_vector_to_irq[airqp->airq_vector]);
+ }
+ return (apic_setup_irq_table(dip, irqno, NULL, ispec,
+ NULL, type));
+ }
+
+ bustype = 0;
+
+ /* check if we have already translated this irq */
+ mutex_enter(&airq_mutex);
+ newirq = apic_min_device_irq;
+ for (; newirq <= apic_max_device_irq; newirq++) {
+ airqp = apic_irq_table[newirq];
+ while (airqp) {
+ if ((airqp->airq_dip == dip) &&
+ (airqp->airq_origirq == irqno) &&
+ (airqp->airq_mps_intr_index != FREE_INDEX)) {
+
+ mutex_exit(&airq_mutex);
+ return (VIRTIRQ(newirq, airqp->airq_share_id));
+ }
+ airqp = airqp->airq_next;
+ }
+ }
+ mutex_exit(&airq_mutex);
+
+ if (apic_defconf)
+ goto defconf;
+
+ if ((dip == NULL) || (!apic_irq_translate && !apic_enable_acpi))
+ goto nonpci;
+
+ if (parent_is_pci_or_pciex) {
+ /* pci device */
+ if (acpica_get_bdf(dip, &busid, &devid, NULL) != 0)
+ goto nonpci;
+ if (busid == 0 && apic_pci_bus_total == 1)
+ busid = (int)apic_single_pci_busid;
+
+ if (pci_config_setup(dip, &cfg_handle) != DDI_SUCCESS)
+ goto nonpci;
+ ipin = pci_config_get8(cfg_handle, PCI_CONF_IPIN) - PCI_INTA;
+ pci_config_teardown(&cfg_handle);
+ if (apic_enable_acpi && !apic_use_acpi_madt_only) {
+ if (apic_acpi_translate_pci_irq(dip, busid, devid,
+ ipin, &pci_irq, &intr_flag) != ACPI_PSM_SUCCESS)
+ goto nonpci;
+
+ intr_flag.bustype = child_is_pciex ? BUS_PCIE : BUS_PCI;
+ if ((newirq = apic_setup_irq_table(dip, pci_irq, NULL,
+ ispec, &intr_flag, type)) == -1)
+ goto nonpci;
+ return (newirq);
+ } else {
+ pci_irq = ((devid & 0x1f) << 2) | (ipin & 0x3);
+ if ((intrp = apic_find_io_intr_w_busid(pci_irq, busid))
+ == NULL) {
+ if ((pci_irq = apic_handle_pci_pci_bridge(dip,
+ devid, ipin, &intrp)) == -1)
+ goto nonpci;
+ }
+ if ((newirq = apic_setup_irq_table(dip, pci_irq, intrp,
+ ispec, NULL, type)) == -1)
+ goto nonpci;
+ return (newirq);
+ }
+ } else if (strcmp(dev_type, "isa") == 0)
+ bustype = BUS_ISA;
+ else if (strcmp(dev_type, "eisa") == 0)
+ bustype = BUS_EISA;
+
+nonpci:
+ if (apic_enable_acpi && !apic_use_acpi_madt_only) {
+ /* search iso entries first */
+ if (acpi_iso_cnt != 0) {
+ hp = (APIC_HEADER *)acpi_isop;
+ i = 0;
+ while (i < acpi_iso_cnt) {
+ if (hp->Type == APIC_XRUPT_OVERRIDE) {
+ isop = (MADT_INTERRUPT_OVERRIDE *)hp;
+ if (isop->Bus == 0 &&
+ isop->Source == irqno) {
+ newirq = isop->Interrupt;
+ intr_flag.intr_po =
+ isop->Polarity;
+ intr_flag.intr_el =
+ isop->TriggerMode;
+ intr_flag.bustype = BUS_ISA;
+
+ return (apic_setup_irq_table(
+ dip, newirq, NULL, ispec,
+ &intr_flag, type));
+
+ }
+ i++;
+ }
+ hp = (APIC_HEADER *)(((char *)hp) +
+ hp->Length);
+ }
+ }
+ intr_flag.intr_po = INTR_PO_ACTIVE_HIGH;
+ intr_flag.intr_el = INTR_EL_EDGE;
+ intr_flag.bustype = BUS_ISA;
+ return (apic_setup_irq_table(dip, irqno, NULL, ispec,
+ &intr_flag, type));
+ } else {
+ if (bustype == 0)
+ bustype = eisa_level_intr_mask ? BUS_EISA : BUS_ISA;
+ for (i = 0; i < 2; i++) {
+ if (((busid = apic_find_bus_id(bustype)) != -1) &&
+ ((intrp = apic_find_io_intr_w_busid(irqno, busid))
+ != NULL)) {
+ if ((newirq = apic_setup_irq_table(dip, irqno,
+ intrp, ispec, NULL, type)) != -1) {
+ return (newirq);
+ }
+ goto defconf;
+ }
+ bustype = (bustype == BUS_EISA) ? BUS_ISA : BUS_EISA;
+ }
+ }
+
+/* MPS default configuration */
+defconf:
+ newirq = apic_setup_irq_table(dip, irqno, NULL, ispec, NULL, type);
+ if (newirq == -1)
+ return (newirq);
+ ASSERT(IRQINDEX(newirq) == irqno);
+ ASSERT(apic_irq_table[irqno]);
+ return (newirq);
+}
+
+
+
+
+
+
+/*
+ * On machines with PCI-PCI bridges, a device behind a PCI-PCI bridge
+ * needs special handling. We may need to chase up the device tree,
+ * using the PCI-PCI Bridge specification's "rotating IPIN assumptions",
+ * to find the IPIN at the root bus that relates to the IPIN on the
+ * subsidiary bus (for ACPI or MP). We may, however, have an entry
+ * in the MP table or the ACPI namespace for this device itself.
+ * We handle both cases in the search below.
+ */
+/* this is the non-acpi version */
+static int
+apic_handle_pci_pci_bridge(dev_info_t *idip, int child_devno, int child_ipin,
+ struct apic_io_intr **intrp)
+{
+ dev_info_t *dipp, *dip;
+ int pci_irq;
+ ddi_acc_handle_t cfg_handle;
+ int bridge_devno, bridge_bus;
+ int ipin;
+
+ dip = idip;
+
+ /*CONSTCOND*/
+ while (1) {
+ if ((dipp = ddi_get_parent(dip)) == (dev_info_t *)NULL)
+ return (-1);
+ if ((pci_config_setup(dipp, &cfg_handle) == DDI_SUCCESS) &&
+ (pci_config_get8(cfg_handle, PCI_CONF_BASCLASS) ==
+ PCI_CLASS_BRIDGE) && (pci_config_get8(cfg_handle,
+ PCI_CONF_SUBCLASS) == PCI_BRIDGE_PCI)) {
+ pci_config_teardown(&cfg_handle);
+ if (acpica_get_bdf(dipp, &bridge_bus, &bridge_devno,
+ NULL) != 0)
+ return (-1);
+ /*
+ * This is the rotating scheme that Compaq is using
+ * and documented in the pci to pci spec. Also, if
+ * the pci to pci bridge is behind another pci to
+ * pci bridge, then it need to keep transversing
+ * up until an interrupt entry is found or reach
+ * the top of the tree
+ */
+ ipin = (child_devno + child_ipin) % PCI_INTD;
+ if (bridge_bus == 0 && apic_pci_bus_total == 1)
+ bridge_bus = (int)apic_single_pci_busid;
+ pci_irq = ((bridge_devno & 0x1f) << 2) |
+ (ipin & 0x3);
+ if ((*intrp = apic_find_io_intr_w_busid(pci_irq,
+ bridge_bus)) != NULL) {
+ return (pci_irq);
+ }
+ dip = dipp;
+ child_devno = bridge_devno;
+ child_ipin = ipin;
+ } else
+ return (-1);
+ }
+ /*LINTED: function will not fall off the bottom */
+}
+
+
+
+
+static uchar_t
+acpi_find_ioapic(int irq)
+{
+ int i;
+
+ for (i = 0; i < apic_io_max; i++) {
+ if (irq >= apic_io_vectbase[i] && irq <= apic_io_vectend[i])
+ return (i);
+ }
+ return (0xFF); /* shouldn't happen */
+}
+
+/*
+ * See if two irqs are compatible for sharing a vector.
+ * Currently we only support sharing of PCI devices.
+ */
+static int
+acpi_intr_compatible(iflag_t iflag1, iflag_t iflag2)
+{
+ uint_t level1, po1;
+ uint_t level2, po2;
+
+ /* Assume active high by default */
+ po1 = 0;
+ po2 = 0;
+
+ if (iflag1.bustype != iflag2.bustype || iflag1.bustype != BUS_PCI)
+ return (0);
+
+ if (iflag1.intr_el == INTR_EL_CONFORM)
+ level1 = AV_LEVEL;
+ else
+ level1 = (iflag1.intr_el == INTR_EL_LEVEL) ? AV_LEVEL : 0;
+
+ if (level1 && ((iflag1.intr_po == INTR_PO_ACTIVE_LOW) ||
+ (iflag1.intr_po == INTR_PO_CONFORM)))
+ po1 = AV_ACTIVE_LOW;
+
+ if (iflag2.intr_el == INTR_EL_CONFORM)
+ level2 = AV_LEVEL;
+ else
+ level2 = (iflag2.intr_el == INTR_EL_LEVEL) ? AV_LEVEL : 0;
+
+ if (level2 && ((iflag2.intr_po == INTR_PO_ACTIVE_LOW) ||
+ (iflag2.intr_po == INTR_PO_CONFORM)))
+ po2 = AV_ACTIVE_LOW;
+
+ if ((level1 == level2) && (po1 == po2))
+ return (1);
+
+ return (0);
+}
+
+/*
+ * Attempt to share vector with someone else
+ */
+static int
+apic_share_vector(int irqno, iflag_t *intr_flagp, short intr_index, int ipl,
+ uchar_t ioapicindex, uchar_t ipin, apic_irq_t **irqptrp)
+{
+#ifdef DEBUG
+ apic_irq_t *tmpirqp = NULL;
+#endif /* DEBUG */
+ apic_irq_t *irqptr, dummyirq;
+ int newirq, chosen_irq = -1, share = 127;
+ int lowest, highest, i;
+ uchar_t share_id;
+
+ DDI_INTR_IMPLDBG((CE_CONT, "apic_share_vector: irqno=0x%x "
+ "intr_index=0x%x ipl=0x%x\n", irqno, intr_index, ipl));
+
+ highest = apic_ipltopri[ipl] + APIC_VECTOR_MASK;
+ lowest = apic_ipltopri[ipl-1] + APIC_VECTOR_PER_IPL;
+
+ if (highest < lowest) /* Both ipl and ipl-1 map to same pri */
+ lowest -= APIC_VECTOR_PER_IPL;
+ dummyirq.airq_mps_intr_index = intr_index;
+ dummyirq.airq_ioapicindex = ioapicindex;
+ dummyirq.airq_intin_no = ipin;
+ if (intr_flagp)
+ dummyirq.airq_iflag = *intr_flagp;
+ apic_record_rdt_entry(&dummyirq, irqno);
+ for (i = lowest; i <= highest; i++) {
+ newirq = apic_vector_to_irq[i];
+ if (newirq == APIC_RESV_IRQ)
+ continue;
+ irqptr = apic_irq_table[newirq];
+
+ if ((dummyirq.airq_rdt_entry & 0xFF00) !=
+ (irqptr->airq_rdt_entry & 0xFF00))
+ /* not compatible */
+ continue;
+
+ if (irqptr->airq_share < share) {
+ share = irqptr->airq_share;
+ chosen_irq = newirq;
+ }
+ }
+ if (chosen_irq != -1) {
+ /*
+ * Assign a share id which is free or which is larger
+ * than the largest one.
+ */
+ share_id = 1;
+ mutex_enter(&airq_mutex);
+ irqptr = apic_irq_table[chosen_irq];
+ while (irqptr) {
+ if (irqptr->airq_mps_intr_index == FREE_INDEX) {
+ share_id = irqptr->airq_share_id;
+ break;
+ }
+ if (share_id <= irqptr->airq_share_id)
+ share_id = irqptr->airq_share_id + 1;
+#ifdef DEBUG
+ tmpirqp = irqptr;
+#endif /* DEBUG */
+ irqptr = irqptr->airq_next;
+ }
+ if (!irqptr) {
+ irqptr = kmem_zalloc(sizeof (apic_irq_t), KM_SLEEP);
+ irqptr->airq_temp_cpu = IRQ_UNINIT;
+ irqptr->airq_next =
+ apic_irq_table[chosen_irq]->airq_next;
+ apic_irq_table[chosen_irq]->airq_next = irqptr;
+#ifdef DEBUG
+ tmpirqp = apic_irq_table[chosen_irq];
+#endif /* DEBUG */
+ }
+ irqptr->airq_mps_intr_index = intr_index;
+ irqptr->airq_ioapicindex = ioapicindex;
+ irqptr->airq_intin_no = ipin;
+ if (intr_flagp)
+ irqptr->airq_iflag = *intr_flagp;
+ irqptr->airq_vector = apic_irq_table[chosen_irq]->airq_vector;
+ irqptr->airq_share_id = share_id;
+ apic_record_rdt_entry(irqptr, irqno);
+ *irqptrp = irqptr;
+#ifdef DEBUG
+ /* shuffle the pointers to test apic_delspl path */
+ if (tmpirqp) {
+ tmpirqp->airq_next = irqptr->airq_next;
+ irqptr->airq_next = apic_irq_table[chosen_irq];
+ apic_irq_table[chosen_irq] = irqptr;
+ }
+#endif /* DEBUG */
+ mutex_exit(&airq_mutex);
+ return (VIRTIRQ(chosen_irq, share_id));
+ }
+ return (-1);
+}
+
+/*
+ *
+ */
+static int
+apic_setup_irq_table(dev_info_t *dip, int irqno, struct apic_io_intr *intrp,
+ struct intrspec *ispec, iflag_t *intr_flagp, int type)
+{
+ int origirq = ispec->intrspec_vec;
+ uchar_t ipl = ispec->intrspec_pri;
+ int newirq, intr_index;
+ uchar_t ipin, ioapic, ioapicindex, vector;
+ apic_irq_t *irqptr;
+ major_t major;
+ dev_info_t *sdip;
+
+ DDI_INTR_IMPLDBG((CE_CONT, "apic_setup_irq_table: dip=0x%p type=%d "
+ "irqno=0x%x origirq=0x%x\n", (void *)dip, type, irqno, origirq));
+
+ ASSERT(ispec != NULL);
+
+ major = (dip != NULL) ? ddi_name_to_major(ddi_get_name(dip)) : 0;
+
+ if (DDI_INTR_IS_MSI_OR_MSIX(type)) {
+ /* MSI/X doesn't need to setup ioapic stuffs */
+ ioapicindex = 0xff;
+ ioapic = 0xff;
+ ipin = (uchar_t)0xff;
+ intr_index = (type == DDI_INTR_TYPE_MSI) ? MSI_INDEX :
+ MSIX_INDEX;
+ mutex_enter(&airq_mutex);
+ if ((irqno = apic_allocate_irq(apic_first_avail_irq)) == -1) {
+ mutex_exit(&airq_mutex);
+ /* need an irq for MSI/X to index into autovect[] */
+ cmn_err(CE_WARN, "No interrupt irq: %s instance %d",
+ ddi_get_name(dip), ddi_get_instance(dip));
+ return (-1);
+ }
+ mutex_exit(&airq_mutex);
+
+ } else if (intrp != NULL) {
+ intr_index = (int)(intrp - apic_io_intrp);
+ ioapic = intrp->intr_destid;
+ ipin = intrp->intr_destintin;
+ /* Find ioapicindex. If destid was ALL, we will exit with 0. */
+ for (ioapicindex = apic_io_max - 1; ioapicindex; ioapicindex--)
+ if (apic_io_id[ioapicindex] == ioapic)
+ break;
+ ASSERT((ioapic == apic_io_id[ioapicindex]) ||
+ (ioapic == INTR_ALL_APIC));
+
+ /* check whether this intin# has been used by another irqno */
+ if ((newirq = apic_find_intin(ioapicindex, ipin)) != -1) {
+ return (newirq);
+ }
+
+ } else if (intr_flagp != NULL) {
+ /* ACPI case */
+ intr_index = ACPI_INDEX;
+ ioapicindex = acpi_find_ioapic(irqno);
+ ASSERT(ioapicindex != 0xFF);
+ ioapic = apic_io_id[ioapicindex];
+ ipin = irqno - apic_io_vectbase[ioapicindex];
+ if (apic_irq_table[irqno] &&
+ apic_irq_table[irqno]->airq_mps_intr_index == ACPI_INDEX) {
+ ASSERT(apic_irq_table[irqno]->airq_intin_no == ipin &&
+ apic_irq_table[irqno]->airq_ioapicindex ==
+ ioapicindex);
+ return (irqno);
+ }
+
+ } else {
+ /* default configuration */
+ ioapicindex = 0;
+ ioapic = apic_io_id[ioapicindex];
+ ipin = (uchar_t)irqno;
+ intr_index = DEFAULT_INDEX;
+ }
+
+ if (ispec == NULL) {
+ APIC_VERBOSE_IOAPIC((CE_WARN, "No intrspec for irqno = %x\n",
+ irqno));
+ } else if ((vector = apic_allocate_vector(ipl, irqno, 0)) == 0) {
+ if ((newirq = apic_share_vector(irqno, intr_flagp, intr_index,
+ ipl, ioapicindex, ipin, &irqptr)) != -1) {
+ irqptr->airq_ipl = ipl;
+ irqptr->airq_origirq = (uchar_t)origirq;
+ irqptr->airq_dip = dip;
+ irqptr->airq_major = major;
+ sdip = apic_irq_table[IRQINDEX(newirq)]->airq_dip;
+ /* This is OK to do really */
+ if (sdip == NULL) {
+ cmn_err(CE_WARN, "Sharing vectors: %s"
+ " instance %d and SCI",
+ ddi_get_name(dip), ddi_get_instance(dip));
+ } else {
+ cmn_err(CE_WARN, "Sharing vectors: %s"
+ " instance %d and %s instance %d",
+ ddi_get_name(sdip), ddi_get_instance(sdip),
+ ddi_get_name(dip), ddi_get_instance(dip));
+ }
+ return (newirq);
+ }
+ /* try high priority allocation now that share has failed */
+ if ((vector = apic_allocate_vector(ipl, irqno, 1)) == 0) {
+ cmn_err(CE_WARN, "No interrupt vector: %s instance %d",
+ ddi_get_name(dip), ddi_get_instance(dip));
+ return (-1);
+ }
+ }
+
+ mutex_enter(&airq_mutex);
+ if (apic_irq_table[irqno] == NULL) {
+ irqptr = kmem_zalloc(sizeof (apic_irq_t), KM_SLEEP);
+ irqptr->airq_temp_cpu = IRQ_UNINIT;
+ apic_irq_table[irqno] = irqptr;
+ } else {
+ irqptr = apic_irq_table[irqno];
+ if (irqptr->airq_mps_intr_index != FREE_INDEX) {
+ /*
+ * The slot is used by another irqno, so allocate
+ * a free irqno for this interrupt
+ */
+ newirq = apic_allocate_irq(apic_first_avail_irq);
+ if (newirq == -1) {
+ mutex_exit(&airq_mutex);
+ return (-1);
+ }
+ irqno = newirq;
+ irqptr = apic_irq_table[irqno];
+ if (irqptr == NULL) {
+ irqptr = kmem_zalloc(sizeof (apic_irq_t),
+ KM_SLEEP);
+ irqptr->airq_temp_cpu = IRQ_UNINIT;
+ apic_irq_table[irqno] = irqptr;
+ }
+ vector = apic_modify_vector(vector, newirq);
+ }
+ }
+ apic_max_device_irq = max(irqno, apic_max_device_irq);
+ apic_min_device_irq = min(irqno, apic_min_device_irq);
+ mutex_exit(&airq_mutex);
+ irqptr->airq_ioapicindex = ioapicindex;
+ irqptr->airq_intin_no = ipin;
+ irqptr->airq_ipl = ipl;
+ irqptr->airq_vector = vector;
+ irqptr->airq_origirq = (uchar_t)origirq;
+ irqptr->airq_share_id = 0;
+ irqptr->airq_mps_intr_index = (short)intr_index;
+ irqptr->airq_dip = dip;
+ irqptr->airq_major = major;
+ irqptr->airq_cpu = apic_bind_intr(dip, irqno, ioapic, ipin);
+ if (intr_flagp)
+ irqptr->airq_iflag = *intr_flagp;
+
+ if (!DDI_INTR_IS_MSI_OR_MSIX(type)) {
+ /* setup I/O APIC entry for non-MSI/X interrupts */
+ apic_record_rdt_entry(irqptr, irqno);
+ }
+ return (irqno);
+}
+
+/*
+ * return the cpu to which this intr should be bound.
+ * Check properties or any other mechanism to see if user wants it
+ * bound to a specific CPU. If so, return the cpu id with high bit set.
+ * If not, use the policy to choose a cpu and return the id.
+ */
+uchar_t
+apic_bind_intr(dev_info_t *dip, int irq, uchar_t ioapicid, uchar_t intin)
+{
+ int instance, instno, prop_len, bind_cpu, count;
+ uint_t i, rc;
+ uchar_t cpu;
+ major_t major;
+ char *name, *drv_name, *prop_val, *cptr;
+ char prop_name[32];
+
+
+ if (apic_intr_policy == INTR_LOWEST_PRIORITY)
+ return (IRQ_UNBOUND);
+
+ drv_name = NULL;
+ rc = DDI_PROP_NOT_FOUND;
+ major = (major_t)-1;
+ if (dip != NULL) {
+ name = ddi_get_name(dip);
+ major = ddi_name_to_major(name);
+ drv_name = ddi_major_to_name(major);
+ instance = ddi_get_instance(dip);
+ if (apic_intr_policy == INTR_ROUND_ROBIN_WITH_AFFINITY) {
+ i = apic_min_device_irq;
+ for (; i <= apic_max_device_irq; i++) {
+
+ if ((i == irq) || (apic_irq_table[i] == NULL) ||
+ (apic_irq_table[i]->airq_mps_intr_index
+ == FREE_INDEX))
+ continue;
+
+ if ((apic_irq_table[i]->airq_major == major) &&
+ (!(apic_irq_table[i]->airq_cpu &
+ IRQ_USER_BOUND))) {
+
+ cpu = apic_irq_table[i]->airq_cpu;
+
+ cmn_err(CE_CONT,
+ "!%s: %s (%s) instance #%d "
+ "vector 0x%x ioapic 0x%x "
+ "intin 0x%x is bound to cpu %d\n",
+ psm_name,
+ name, drv_name, instance, irq,
+ ioapicid, intin, cpu);
+ return (cpu);
+ }
+ }
+ }
+ /*
+ * search for "drvname"_intpt_bind_cpus property first, the
+ * syntax of the property should be "a[,b,c,...]" where
+ * instance 0 binds to cpu a, instance 1 binds to cpu b,
+ * instance 3 binds to cpu c...
+ * ddi_getlongprop() will search /option first, then /
+ * if "drvname"_intpt_bind_cpus doesn't exist, then find
+ * intpt_bind_cpus property. The syntax is the same, and
+ * it applies to all the devices if its "drvname" specific
+ * property doesn't exist
+ */
+ (void) strcpy(prop_name, drv_name);
+ (void) strcat(prop_name, "_intpt_bind_cpus");
+ rc = ddi_getlongprop(DDI_DEV_T_ANY, dip, 0, prop_name,
+ (caddr_t)&prop_val, &prop_len);
+ if (rc != DDI_PROP_SUCCESS) {
+ rc = ddi_getlongprop(DDI_DEV_T_ANY, dip, 0,
+ "intpt_bind_cpus", (caddr_t)&prop_val, &prop_len);
+ }
+ }
+ if (rc == DDI_PROP_SUCCESS) {
+ for (i = count = 0; i < (prop_len - 1); i++)
+ if (prop_val[i] == ',')
+ count++;
+ if (prop_val[i-1] != ',')
+ count++;
+ /*
+ * if somehow the binding instances defined in the
+ * property are not enough for this instno., then
+ * reuse the pattern for the next instance until
+ * it reaches the requested instno
+ */
+ instno = instance % count;
+ i = 0;
+ cptr = prop_val;
+ while (i < instno)
+ if (*cptr++ == ',')
+ i++;
+ bind_cpu = stoi(&cptr);
+ kmem_free(prop_val, prop_len);
+ /* if specific cpu is bogus, then default to cpu 0 */
+ if (bind_cpu >= apic_nproc) {
+ cmn_err(CE_WARN, "%s: %s=%s: CPU %d not present",
+ psm_name, prop_name, prop_val, bind_cpu);
+ bind_cpu = 0;
+ } else {
+ /* indicate that we are bound at user request */
+ bind_cpu |= IRQ_USER_BOUND;
+ }
+ /*
+ * no need to check apic_cpus[].aci_status, if specific cpu is
+ * not up, then post_cpu_start will handle it.
+ */
+ } else {
+ bind_cpu = apic_next_bind_cpu++;
+ if (bind_cpu >= apic_nproc) {
+ apic_next_bind_cpu = 1;
+ bind_cpu = 0;
+ }
+ }
+ if (drv_name != NULL)
+ cmn_err(CE_CONT, "!%s: %s (%s) instance %d "
+ "vector 0x%x ioapic 0x%x intin 0x%x is bound to cpu %d\n",
+ psm_name, name, drv_name, instance,
+ irq, ioapicid, intin, bind_cpu & ~IRQ_USER_BOUND);
+ else
+ cmn_err(CE_CONT, "!%s: "
+ "vector 0x%x ioapic 0x%x intin 0x%x is bound to cpu %d\n",
+ psm_name, irq, ioapicid, intin, bind_cpu & ~IRQ_USER_BOUND);
+
+ return ((uchar_t)bind_cpu);
+}
+
+static struct apic_io_intr *
+apic_find_io_intr_w_busid(int irqno, int busid)
+{
+ struct apic_io_intr *intrp;
+
+ /*
+ * It can have more than 1 entry with same source bus IRQ,
+ * but unique with the source bus id
+ */
+ intrp = apic_io_intrp;
+ if (intrp != NULL) {
+ while (intrp->intr_entry == APIC_IO_INTR_ENTRY) {
+ if (intrp->intr_irq == irqno &&
+ intrp->intr_busid == busid &&
+ intrp->intr_type == IO_INTR_INT)
+ return (intrp);
+ intrp++;
+ }
+ }
+ APIC_VERBOSE_IOAPIC((CE_NOTE, "Did not find io intr for irqno:"
+ "busid %x:%x\n", irqno, busid));
+ return ((struct apic_io_intr *)NULL);
+}
+
+
+struct mps_bus_info {
+ char *bus_name;
+ int bus_id;
+} bus_info_array[] = {
+ "ISA ", BUS_ISA,
+ "PCI ", BUS_PCI,
+ "EISA ", BUS_EISA,
+ "XPRESS", BUS_XPRESS,
+ "PCMCIA", BUS_PCMCIA,
+ "VL ", BUS_VL,
+ "CBUS ", BUS_CBUS,
+ "CBUSII", BUS_CBUSII,
+ "FUTURE", BUS_FUTURE,
+ "INTERN", BUS_INTERN,
+ "MBI ", BUS_MBI,
+ "MBII ", BUS_MBII,
+ "MPI ", BUS_MPI,
+ "MPSA ", BUS_MPSA,
+ "NUBUS ", BUS_NUBUS,
+ "TC ", BUS_TC,
+ "VME ", BUS_VME,
+ "PCI-E ", BUS_PCIE
+};
+
+static int
+apic_find_bus_type(char *bus)
+{
+ int i = 0;
+
+ for (; i < sizeof (bus_info_array)/sizeof (struct mps_bus_info); i++)
+ if (strncmp(bus, bus_info_array[i].bus_name,
+ strlen(bus_info_array[i].bus_name)) == 0)
+ return (bus_info_array[i].bus_id);
+ APIC_VERBOSE_IOAPIC((CE_WARN, "Did not find bus type for bus %s", bus));
+ return (0);
+}
+
+static int
+apic_find_bus(int busid)
+{
+ struct apic_bus *busp;
+
+ busp = apic_busp;
+ while (busp->bus_entry == APIC_BUS_ENTRY) {
+ if (busp->bus_id == busid)
+ return (apic_find_bus_type((char *)&busp->bus_str1));
+ busp++;
+ }
+ APIC_VERBOSE_IOAPIC((CE_WARN, "Did not find bus for bus id %x", busid));
+ return (0);
+}
+
+static int
+apic_find_bus_id(int bustype)
+{
+ struct apic_bus *busp;
+
+ busp = apic_busp;
+ while (busp->bus_entry == APIC_BUS_ENTRY) {
+ if (apic_find_bus_type((char *)&busp->bus_str1) == bustype)
+ return (busp->bus_id);
+ busp++;
+ }
+ APIC_VERBOSE_IOAPIC((CE_WARN, "Did not find bus id for bustype %x",
+ bustype));
+ return (-1);
+}
+
+/*
+ * Check if a particular irq need to be reserved for any io_intr
+ */
+static struct apic_io_intr *
+apic_find_io_intr(int irqno)
+{
+ struct apic_io_intr *intrp;
+
+ intrp = apic_io_intrp;
+ if (intrp != NULL) {
+ while (intrp->intr_entry == APIC_IO_INTR_ENTRY) {
+ if (intrp->intr_irq == irqno &&
+ intrp->intr_type == IO_INTR_INT)
+ return (intrp);
+ intrp++;
+ }
+ }
+ return ((struct apic_io_intr *)NULL);
+}
+
+/*
+ * Check if the given ioapicindex intin combination has already been assigned
+ * an irq. If so return irqno. Else -1
+ */
+static int
+apic_find_intin(uchar_t ioapic, uchar_t intin)
+{
+ apic_irq_t *irqptr;
+ int i;
+
+ /* find ioapic and intin in the apic_irq_table[] and return the index */
+ for (i = apic_min_device_irq; i <= apic_max_device_irq; i++) {
+ irqptr = apic_irq_table[i];
+ while (irqptr) {
+ if ((irqptr->airq_mps_intr_index >= 0) &&
+ (irqptr->airq_intin_no == intin) &&
+ (irqptr->airq_ioapicindex == ioapic)) {
+ APIC_VERBOSE_IOAPIC((CE_NOTE, "!Found irq "
+ "entry for ioapic:intin %x:%x "
+ "shared interrupts ?", ioapic, intin));
+ return (i);
+ }
+ irqptr = irqptr->airq_next;
+ }
+ }
+ return (-1);
+}
+
+int
+apic_allocate_irq(int irq)
+{
+ int freeirq, i;
+
+ if ((freeirq = apic_find_free_irq(irq, (APIC_RESV_IRQ - 1))) == -1)
+ if ((freeirq = apic_find_free_irq(APIC_FIRST_FREE_IRQ,
+ (irq - 1))) == -1) {
+ /*
+ * if BIOS really defines every single irq in the mps
+ * table, then don't worry about conflicting with
+ * them, just use any free slot in apic_irq_table
+ */
+ for (i = APIC_FIRST_FREE_IRQ; i < APIC_RESV_IRQ; i++) {
+ if ((apic_irq_table[i] == NULL) ||
+ apic_irq_table[i]->airq_mps_intr_index ==
+ FREE_INDEX) {
+ freeirq = i;
+ break;
+ }
+ }
+ if (freeirq == -1) {
+ /* This shouldn't happen, but just in case */
+ cmn_err(CE_WARN, "%s: NO available IRQ", psm_name);
+ return (-1);
+ }
+ }
+ if (apic_irq_table[freeirq] == NULL) {
+ apic_irq_table[freeirq] =
+ kmem_zalloc(sizeof (apic_irq_t), KM_NOSLEEP);
+ if (apic_irq_table[freeirq] == NULL) {
+ cmn_err(CE_WARN, "%s: NO memory to allocate IRQ",
+ psm_name);
+ return (-1);
+ }
+ apic_irq_table[freeirq]->airq_mps_intr_index = FREE_INDEX;
+ }
+ return (freeirq);
+}
+
+static int
+apic_find_free_irq(int start, int end)
+{
+ int i;
+
+ for (i = start; i <= end; i++)
+ /* Check if any I/O entry needs this IRQ */
+ if (apic_find_io_intr(i) == NULL) {
+ /* Then see if it is free */
+ if ((apic_irq_table[i] == NULL) ||
+ (apic_irq_table[i]->airq_mps_intr_index ==
+ FREE_INDEX)) {
+ return (i);
+ }
+ }
+ return (-1);
+}
+
+
+/*
+ * Mark vector as being in the process of being deleted. Interrupts
+ * may still come in on some CPU. The moment an interrupt comes with
+ * the new vector, we know we can free the old one. Called only from
+ * addspl and delspl with interrupts disabled. Because an interrupt
+ * can be shared, but no interrupt from either device may come in,
+ * we also use a timeout mechanism, which we arbitrarily set to
+ * apic_revector_timeout microseconds.
+ */
+static void
+apic_mark_vector(uchar_t oldvector, uchar_t newvector)
+{
+ ulong_t iflag;
+
+ iflag = intr_clear();
+ lock_set(&apic_revector_lock);
+ if (!apic_oldvec_to_newvec) {
+ apic_oldvec_to_newvec =
+ kmem_zalloc(sizeof (newvector) * APIC_MAX_VECTOR * 2,
+ KM_NOSLEEP);
+
+ if (!apic_oldvec_to_newvec) {
+ /*
+ * This failure is not catastrophic.
+ * But, the oldvec will never be freed.
+ */
+ apic_error |= APIC_ERR_MARK_VECTOR_FAIL;
+ lock_clear(&apic_revector_lock);
+ intr_restore(iflag);
+ return;
+ }
+ apic_newvec_to_oldvec = &apic_oldvec_to_newvec[APIC_MAX_VECTOR];
+ }
+
+ /* See if we already did this for drivers which do double addintrs */
+ if (apic_oldvec_to_newvec[oldvector] != newvector) {
+ apic_oldvec_to_newvec[oldvector] = newvector;
+ apic_newvec_to_oldvec[newvector] = oldvector;
+ apic_revector_pending++;
+ }
+ lock_clear(&apic_revector_lock);
+ intr_restore(iflag);
+ (void) timeout(apic_xlate_vector_free_timeout_handler,
+ (void *)(uintptr_t)oldvector, drv_usectohz(apic_revector_timeout));
+}
+
+/*
+ * xlate_vector is called from intr_enter if revector_pending is set.
+ * It will xlate it if needed and mark the old vector as free.
+ */
+uchar_t
+apic_xlate_vector(uchar_t vector)
+{
+ uchar_t newvector, oldvector = 0;
+
+ lock_set(&apic_revector_lock);
+ /* Do we really need to do this ? */
+ if (!apic_revector_pending) {
+ lock_clear(&apic_revector_lock);
+ return (vector);
+ }
+ if ((newvector = apic_oldvec_to_newvec[vector]) != 0)
+ oldvector = vector;
+ else {
+ /*
+ * The incoming vector is new . See if a stale entry is
+ * remaining
+ */
+ if ((oldvector = apic_newvec_to_oldvec[vector]) != 0)
+ newvector = vector;
+ }
+
+ if (oldvector) {
+ apic_revector_pending--;
+ apic_oldvec_to_newvec[oldvector] = 0;
+ apic_newvec_to_oldvec[newvector] = 0;
+ apic_free_vector(oldvector);
+ lock_clear(&apic_revector_lock);
+ /* There could have been more than one reprogramming! */
+ return (apic_xlate_vector(newvector));
+ }
+ lock_clear(&apic_revector_lock);
+ return (vector);
+}
+
+void
+apic_xlate_vector_free_timeout_handler(void *arg)
+{
+ ulong_t iflag;
+ uchar_t oldvector, newvector;
+
+ oldvector = (uchar_t)(uintptr_t)arg;
+ iflag = intr_clear();
+ lock_set(&apic_revector_lock);
+ if ((newvector = apic_oldvec_to_newvec[oldvector]) != 0) {
+ apic_free_vector(oldvector);
+ apic_oldvec_to_newvec[oldvector] = 0;
+ apic_newvec_to_oldvec[newvector] = 0;
+ apic_revector_pending--;
+ }
+
+ lock_clear(&apic_revector_lock);
+ intr_restore(iflag);
+}
+
+
+/*
+ * compute the polarity, trigger mode and vector for programming into
+ * the I/O apic and record in airq_rdt_entry.
+ */
+static void
+apic_record_rdt_entry(apic_irq_t *irqptr, int irq)
+{
+ int ioapicindex, bus_type, vector;
+ short intr_index;
+ uint_t level, po, io_po;
+ struct apic_io_intr *iointrp;
+
+ intr_index = irqptr->airq_mps_intr_index;
+ DDI_INTR_IMPLDBG((CE_CONT, "apic_record_rdt_entry: intr_index=%d "
+ "irq = 0x%x dip = 0x%p vector = 0x%x\n", intr_index, irq,
+ (void *)irqptr->airq_dip, irqptr->airq_vector));
+
+ if (intr_index == RESERVE_INDEX) {
+ apic_error |= APIC_ERR_INVALID_INDEX;
+ return;
+ } else if (APIC_IS_MSI_OR_MSIX_INDEX(intr_index)) {
+ return;
+ }
+
+ vector = irqptr->airq_vector;
+ ioapicindex = irqptr->airq_ioapicindex;
+ /* Assume edge triggered by default */
+ level = 0;
+ /* Assume active high by default */
+ po = 0;
+
+ if (intr_index == DEFAULT_INDEX || intr_index == FREE_INDEX) {
+ ASSERT(irq < 16);
+ if (eisa_level_intr_mask & (1 << irq))
+ level = AV_LEVEL;
+ if (intr_index == FREE_INDEX && apic_defconf == 0)
+ apic_error |= APIC_ERR_INVALID_INDEX;
+ } else if (intr_index == ACPI_INDEX) {
+ bus_type = irqptr->airq_iflag.bustype;
+ if (irqptr->airq_iflag.intr_el == INTR_EL_CONFORM) {
+ if (bus_type == BUS_PCI)
+ level = AV_LEVEL;
+ } else
+ level = (irqptr->airq_iflag.intr_el == INTR_EL_LEVEL) ?
+ AV_LEVEL : 0;
+ if (level &&
+ ((irqptr->airq_iflag.intr_po == INTR_PO_ACTIVE_LOW) ||
+ (irqptr->airq_iflag.intr_po == INTR_PO_CONFORM &&
+ bus_type == BUS_PCI)))
+ po = AV_ACTIVE_LOW;
+ } else {
+ iointrp = apic_io_intrp + intr_index;
+ bus_type = apic_find_bus(iointrp->intr_busid);
+ if (iointrp->intr_el == INTR_EL_CONFORM) {
+ if ((irq < 16) && (eisa_level_intr_mask & (1 << irq)))
+ level = AV_LEVEL;
+ else if (bus_type == BUS_PCI)
+ level = AV_LEVEL;
+ } else
+ level = (iointrp->intr_el == INTR_EL_LEVEL) ?
+ AV_LEVEL : 0;
+ if (level && ((iointrp->intr_po == INTR_PO_ACTIVE_LOW) ||
+ (iointrp->intr_po == INTR_PO_CONFORM &&
+ bus_type == BUS_PCI)))
+ po = AV_ACTIVE_LOW;
+ }
+ if (level)
+ apic_level_intr[irq] = 1;
+ /*
+ * The 82489DX External APIC cannot do active low polarity interrupts.
+ */
+ if (po && (apic_io_ver[ioapicindex] != IOAPIC_VER_82489DX))
+ io_po = po;
+ else
+ io_po = 0;
+
+ if (apic_verbose & APIC_VERBOSE_IOAPIC_FLAG)
+ printf("setio: ioapic=%x intin=%x level=%x po=%x vector=%x\n",
+ ioapicindex, irqptr->airq_intin_no, level, io_po, vector);
+
+ irqptr->airq_rdt_entry = level|io_po|vector;
+}
+
+/*
+ * Bind interrupt corresponding to irq_ptr to bind_cpu.
+ * Must be called with interrupts disabled and apic_ioapic_lock held
+ */
+int
+apic_rebind(apic_irq_t *irq_ptr, int bind_cpu,
+ struct ioapic_reprogram_data *drep)
+{
+ int ioapicindex, intin_no;
+ uchar_t airq_temp_cpu;
+ apic_cpus_info_t *cpu_infop;
+ uint32_t rdt_entry;
+ int which_irq;
+
+ which_irq = apic_vector_to_irq[irq_ptr->airq_vector];
+
+ intin_no = irq_ptr->airq_intin_no;
+ ioapicindex = irq_ptr->airq_ioapicindex;
+ airq_temp_cpu = irq_ptr->airq_temp_cpu;
+ if (airq_temp_cpu != IRQ_UNINIT && airq_temp_cpu != IRQ_UNBOUND) {
+ if (airq_temp_cpu & IRQ_USER_BOUND)
+ /* Mask off high bit so it can be used as array index */
+ airq_temp_cpu &= ~IRQ_USER_BOUND;
+
+ ASSERT(airq_temp_cpu < apic_nproc);
+ }
+
+ /*
+ * Can't bind to a CPU that's not accepting interrupts:
+ */
+ cpu_infop = &apic_cpus[bind_cpu & ~IRQ_USER_BOUND];
+ if (!(cpu_infop->aci_status & APIC_CPU_INTR_ENABLE))
+ return (1);
+
+ /*
+ * If we are about to change the interrupt vector for this interrupt,
+ * and this interrupt is level-triggered, attached to an IOAPIC,
+ * has been delivered to a CPU and that CPU has not handled it
+ * yet, we cannot reprogram the IOAPIC now.
+ */
+ if (!APIC_IS_MSI_OR_MSIX_INDEX(irq_ptr->airq_mps_intr_index)) {
+
+ rdt_entry = READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapicindex,
+ intin_no);
+
+ if ((irq_ptr->airq_vector != RDT_VECTOR(rdt_entry)) &&
+ apic_check_stuck_interrupt(irq_ptr, airq_temp_cpu,
+ bind_cpu, ioapicindex, intin_no, which_irq, drep) != 0) {
+
+ return (0);
+ }
+ }
+
+ /*
+ * NOTE: We do not unmask the RDT here, as an interrupt MAY still
+ * come in before we have a chance to reprogram it below. The
+ * reprogramming below will simultaneously change and unmask the
+ * RDT entry.
+ */
+
+ if ((uchar_t)bind_cpu == IRQ_UNBOUND) {
+
+ rdt_entry = AV_LDEST | AV_LOPRI | irq_ptr->airq_rdt_entry;
+
+ /* Write the RDT entry -- no specific CPU binding */
+ WRITE_IOAPIC_RDT_ENTRY_HIGH_DWORD(ioapicindex, intin_no,
+ AV_TOALL);
+
+ if (airq_temp_cpu != IRQ_UNINIT && airq_temp_cpu != IRQ_UNBOUND)
+ apic_cpus[airq_temp_cpu].aci_temp_bound--;
+
+ /* Write the vector, trigger, and polarity portion of the RDT */
+ WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapicindex, intin_no,
+ rdt_entry);
+
+ irq_ptr->airq_temp_cpu = IRQ_UNBOUND;
+ return (0);
+ }
+
+ if (bind_cpu & IRQ_USER_BOUND) {
+ cpu_infop->aci_bound++;
+ } else {
+ cpu_infop->aci_temp_bound++;
+ }
+ ASSERT((bind_cpu & ~IRQ_USER_BOUND) < apic_nproc);
+ if (!APIC_IS_MSI_OR_MSIX_INDEX(irq_ptr->airq_mps_intr_index)) {
+ /* Write the RDT entry -- bind to a specific CPU: */
+ WRITE_IOAPIC_RDT_ENTRY_HIGH_DWORD(ioapicindex, intin_no,
+ cpu_infop->aci_local_id << APIC_ID_BIT_OFFSET);
+ }
+ if ((airq_temp_cpu != IRQ_UNBOUND) && (airq_temp_cpu != IRQ_UNINIT)) {
+ apic_cpus[airq_temp_cpu].aci_temp_bound--;
+ }
+ if (!APIC_IS_MSI_OR_MSIX_INDEX(irq_ptr->airq_mps_intr_index)) {
+
+ rdt_entry = AV_PDEST | AV_FIXED | irq_ptr->airq_rdt_entry;
+
+ /* Write the vector, trigger, and polarity portion of the RDT */
+ WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapicindex, intin_no,
+ rdt_entry);
+
+ } else {
+ int type = (irq_ptr->airq_mps_intr_index == MSI_INDEX) ?
+ DDI_INTR_TYPE_MSI : DDI_INTR_TYPE_MSIX;
+ (void) apic_pci_msi_disable_mode(irq_ptr->airq_dip, type,
+ ioapicindex);
+ if (ioapicindex == irq_ptr->airq_origirq) {
+ /* first one */
+ DDI_INTR_IMPLDBG((CE_CONT, "apic_rebind: call "
+ "apic_pci_msi_enable_vector\n"));
+ if (apic_pci_msi_enable_vector(irq_ptr->airq_dip, type,
+ which_irq, irq_ptr->airq_vector,
+ irq_ptr->airq_intin_no,
+ cpu_infop->aci_local_id) != PSM_SUCCESS) {
+ cmn_err(CE_WARN, "pcplusmp: "
+ "apic_pci_msi_enable_vector "
+ "returned PSM_FAILURE");
+ }
+ }
+ if ((ioapicindex + irq_ptr->airq_intin_no - 1) ==
+ irq_ptr->airq_origirq) { /* last one */
+ DDI_INTR_IMPLDBG((CE_CONT, "apic_rebind: call "
+ "pci_msi_enable_mode\n"));
+ if (apic_pci_msi_enable_mode(irq_ptr->airq_dip,
+ type, which_irq) != PSM_SUCCESS) {
+ DDI_INTR_IMPLDBG((CE_CONT, "pcplusmp: "
+ "pci_msi_enable failed\n"));
+ (void) apic_pci_msi_unconfigure(
+ irq_ptr->airq_dip, type, which_irq);
+ }
+ }
+ }
+ irq_ptr->airq_temp_cpu = (uchar_t)bind_cpu;
+ apic_redist_cpu_skip &= ~(1 << (bind_cpu & ~IRQ_USER_BOUND));
+ return (0);
+}
+
+static void
+apic_last_ditch_clear_remote_irr(int ioapic_ix, int intin_no)
+{
+ if ((READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix, intin_no)
+ & AV_REMOTE_IRR) != 0) {
+ /*
+ * Trying to clear the bit through normal
+ * channels has failed. So as a last-ditch
+ * effort, try to set the trigger mode to
+ * edge, then to level. This has been
+ * observed to work on many systems.
+ */
+ WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix,
+ intin_no,
+ READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix,
+ intin_no) & ~AV_LEVEL);
+
+ WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix,
+ intin_no,
+ READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix,
+ intin_no) | AV_LEVEL);
+
+ /*
+ * If the bit's STILL set, this interrupt may
+ * be hosed.
+ */
+ if ((READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix,
+ intin_no) & AV_REMOTE_IRR) != 0) {
+
+ prom_printf("%s: Remote IRR still "
+ "not clear for IOAPIC %d intin %d.\n"
+ "\tInterrupts to this pin may cease "
+ "functioning.\n", psm_name, ioapic_ix,
+ intin_no);
+#ifdef DEBUG
+ apic_last_ditch_reprogram_failures++;
+#endif
+ }
+ }
+}
+
+/*
+ * This function is protected by apic_ioapic_lock coupled with the
+ * fact that interrupts are disabled.
+ */
+static void
+delete_defer_repro_ent(int which_irq)
+{
+ ASSERT(which_irq >= 0);
+ ASSERT(which_irq <= 255);
+
+ if (apic_reprogram_info[which_irq].done)
+ return;
+
+ apic_reprogram_info[which_irq].done = B_TRUE;
+
+#ifdef DEBUG
+ apic_defer_repro_total_retries +=
+ apic_reprogram_info[which_irq].tries;
+
+ apic_defer_repro_successes++;
+#endif
+
+ if (--apic_reprogram_outstanding == 0) {
+
+ setlvlx = apic_intr_exit;
+ }
+}
+
+
+/*
+ * Interrupts must be disabled during this function to prevent
+ * self-deadlock. Interrupts are disabled because this function
+ * is called from apic_check_stuck_interrupt(), which is called
+ * from apic_rebind(), which requires its caller to disable interrupts.
+ */
+static void
+add_defer_repro_ent(apic_irq_t *irq_ptr, int which_irq, int new_bind_cpu)
+{
+ ASSERT(which_irq >= 0);
+ ASSERT(which_irq <= 255);
+
+ /*
+ * On the off-chance that there's already a deferred
+ * reprogramming on this irq, check, and if so, just update the
+ * CPU and irq pointer to which the interrupt is targeted, then return.
+ */
+ if (!apic_reprogram_info[which_irq].done) {
+ apic_reprogram_info[which_irq].bindcpu = new_bind_cpu;
+ apic_reprogram_info[which_irq].irqp = irq_ptr;
+ return;
+ }
+
+ apic_reprogram_info[which_irq].irqp = irq_ptr;
+ apic_reprogram_info[which_irq].bindcpu = new_bind_cpu;
+ apic_reprogram_info[which_irq].tries = 0;
+ /*
+ * This must be the last thing set, since we're not
+ * grabbing any locks, apic_try_deferred_reprogram() will
+ * make its decision about using this entry iff done
+ * is false.
+ */
+ apic_reprogram_info[which_irq].done = B_FALSE;
+
+ /*
+ * If there were previously no deferred reprogrammings, change
+ * setlvlx to call apic_try_deferred_reprogram()
+ */
+ if (++apic_reprogram_outstanding == 1) {
+
+ setlvlx = apic_try_deferred_reprogram;
+ }
+}
+
+static void
+apic_try_deferred_reprogram(int prev_ipl, int irq)
+{
+ int reproirq, iflag;
+ struct ioapic_reprogram_data *drep;
+
+ apic_intr_exit(prev_ipl, irq);
+
+ if (!lock_try(&apic_defer_reprogram_lock)) {
+ return;
+ }
+
+ /*
+ * Acquire the apic_ioapic_lock so that any other operations that
+ * may affect the apic_reprogram_info state are serialized.
+ * It's still possible for the last deferred reprogramming to clear
+ * between the time we entered this function and the time we get to
+ * the for loop below. In that case, *setlvlx will have been set
+ * back to apic_intr_exit and drep will be NULL. (There's no way to
+ * stop that from happening -- we would need to grab a lock before
+ * calling *setlvlx, which is neither realistic nor prudent).
+ */
+ iflag = intr_clear();
+ lock_set(&apic_ioapic_lock);
+
+ /*
+ * For each deferred RDT entry, try to reprogram it now. Note that
+ * there is no lock acquisition to read apic_reprogram_info because
+ * '.done' is set only after the other fields in the structure are set.
+ */
+
+ drep = NULL;
+ for (reproirq = 0; reproirq <= APIC_MAX_VECTOR; reproirq++) {
+ if (apic_reprogram_info[reproirq].done == B_FALSE) {
+ drep = &apic_reprogram_info[reproirq];
+ break;
+ }
+ }
+
+ /*
+ * Either we found a deferred action to perform, or
+ * we entered this function spuriously, after *setlvlx
+ * was restored to point to apic_intr_enter. Any other
+ * permutation is invalid.
+ */
+ ASSERT(drep != NULL || *setlvlx == apic_intr_exit);
+
+ /*
+ * Though we can't really do anything about errors
+ * at this point, keep track of them for reporting.
+ * Note that it is very possible for apic_setup_io_intr
+ * to re-register this very timeout if the Remote IRR bit
+ * has not yet cleared.
+ */
+
+#ifdef DEBUG
+ if (drep != NULL) {
+ if (apic_setup_io_intr(drep, reproirq, B_TRUE) != 0) {
+ apic_deferred_setup_failures++;
+ }
+ } else {
+ apic_deferred_spurious_enters++;
+ }
+#else
+ if (drep != NULL)
+ (void) apic_setup_io_intr(drep, reproirq, B_TRUE);
+#endif
+
+ lock_clear(&apic_ioapic_lock);
+ intr_restore(iflag);
+
+ lock_clear(&apic_defer_reprogram_lock);
+}
+
+static void
+apic_ioapic_wait_pending_clear(int ioapic_ix, int intin_no)
+{
+ int waited;
+
+ /*
+ * Wait for the delivery pending bit to clear.
+ */
+ if ((READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix, intin_no) &
+ (AV_LEVEL|AV_PENDING)) == (AV_LEVEL|AV_PENDING)) {
+
+ /*
+ * If we're still waiting on the delivery of this interrupt,
+ * continue to wait here until it is delivered (this should be
+ * a very small amount of time, but include a timeout just in
+ * case).
+ */
+ for (waited = 0; waited < apic_max_reps_clear_pending;
+ waited++) {
+ if ((READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix,
+ intin_no) & AV_PENDING) == 0) {
+ break;
+ }
+ }
+ }
+}
+
+
+/*
+ * Checks to see if the IOAPIC interrupt entry specified has its Remote IRR
+ * bit set. Calls functions that modify the function that setlvlx points to,
+ * so that the reprogramming can be retried very shortly.
+ *
+ * This function will mask the RDT entry if the interrupt is level-triggered.
+ * (The caller is responsible for unmasking the RDT entry.)
+ *
+ * Returns non-zero if the caller should defer IOAPIC reprogramming.
+ */
+static int
+apic_check_stuck_interrupt(apic_irq_t *irq_ptr, int old_bind_cpu,
+ int new_bind_cpu, int ioapic_ix, int intin_no, int which_irq,
+ struct ioapic_reprogram_data *drep)
+{
+ int32_t rdt_entry;
+ int waited;
+ int reps = 0;
+
+ /*
+ * Wait for the delivery pending bit to clear.
+ */
+ do {
+ ++reps;
+
+ apic_ioapic_wait_pending_clear(ioapic_ix, intin_no);
+
+ /*
+ * Mask the RDT entry, but only if it's a level-triggered
+ * interrupt
+ */
+ rdt_entry = READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix,
+ intin_no);
+ if ((rdt_entry & (AV_LEVEL|AV_MASK)) == AV_LEVEL) {
+
+ /* Mask it */
+ WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix, intin_no,
+ AV_MASK | rdt_entry);
+ }
+
+ if ((rdt_entry & AV_LEVEL) == AV_LEVEL) {
+ /*
+ * If there was a race and an interrupt was injected
+ * just before we masked, check for that case here.
+ * Then, unmask the RDT entry and try again. If we're
+ * on our last try, don't unmask (because we want the
+ * RDT entry to remain masked for the rest of the
+ * function).
+ */
+ rdt_entry = READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix,
+ intin_no);
+ if ((rdt_entry & AV_PENDING) &&
+ (reps < apic_max_reps_clear_pending)) {
+ /* Unmask it */
+ WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix,
+ intin_no, rdt_entry & ~AV_MASK);
+ }
+ }
+
+ } while ((rdt_entry & AV_PENDING) &&
+ (reps < apic_max_reps_clear_pending));
+
+#ifdef DEBUG
+ if (rdt_entry & AV_PENDING)
+ apic_intr_deliver_timeouts++;
+#endif
+
+ /*
+ * If the remote IRR bit is set, then the interrupt has been sent
+ * to a CPU for processing. We have no choice but to wait for
+ * that CPU to process the interrupt, at which point the remote IRR
+ * bit will be cleared.
+ */
+ if ((READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix, intin_no) &
+ (AV_LEVEL|AV_REMOTE_IRR)) == (AV_LEVEL|AV_REMOTE_IRR)) {
+
+ /*
+ * If the CPU that this RDT is bound to is NOT the current
+ * CPU, wait until that CPU handles the interrupt and ACKs
+ * it. If this interrupt is not bound to any CPU (that is,
+ * if it's bound to the logical destination of "anyone"), it
+ * may have been delivered to the current CPU so handle that
+ * case by deferring the reprogramming (below).
+ */
+ if ((old_bind_cpu != IRQ_UNBOUND) &&
+ (old_bind_cpu != IRQ_UNINIT) &&
+ (old_bind_cpu != psm_get_cpu_id())) {
+ for (waited = 0; waited < apic_max_reps_clear_pending;
+ waited++) {
+ if ((READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix,
+ intin_no) & AV_REMOTE_IRR) == 0) {
+
+ delete_defer_repro_ent(which_irq);
+
+ /* Remote IRR has cleared! */
+ return (0);
+ }
+ }
+ }
+
+ /*
+ * If we waited and the Remote IRR bit is still not cleared,
+ * AND if we've invoked the timeout APIC_REPROGRAM_MAX_TIMEOUTS
+ * times for this interrupt, try the last-ditch workaround:
+ */
+ if (drep && drep->tries >= APIC_REPROGRAM_MAX_TRIES) {
+
+ apic_last_ditch_clear_remote_irr(ioapic_ix, intin_no);
+
+ /* Mark this one as reprogrammed: */
+ delete_defer_repro_ent(which_irq);
+
+ return (0);
+ } else {
+#ifdef DEBUG
+ apic_intr_deferrals++;
+#endif
+
+ /*
+ * If waiting for the Remote IRR bit (above) didn't
+ * allow it to clear, defer the reprogramming.
+ * Add a new deferred-programming entry if the
+ * caller passed a NULL one (and update the existing one
+ * in case anything changed).
+ */
+ add_defer_repro_ent(irq_ptr, which_irq, new_bind_cpu);
+ if (drep)
+ drep->tries++;
+
+ /* Inform caller to defer IOAPIC programming: */
+ return (1);
+ }
+
+ }
+
+ /* Remote IRR is clear */
+ delete_defer_repro_ent(which_irq);
+
+ return (0);
+}
+
+/*
+ * Called to migrate all interrupts at an irq to another cpu.
+ * Must be called with interrupts disabled and apic_ioapic_lock held
+ */
+int
+apic_rebind_all(apic_irq_t *irq_ptr, int bind_cpu)
+{
+ apic_irq_t *irqptr = irq_ptr;
+ int retval = 0;
+
+ while (irqptr) {
+ if (irqptr->airq_temp_cpu != IRQ_UNINIT)
+ retval |= apic_rebind(irqptr, bind_cpu, NULL);
+ irqptr = irqptr->airq_next;
+ }
+
+ return (retval);
+}
+
+/*
+ * apic_intr_redistribute does all the messy computations for identifying
+ * which interrupt to move to which CPU. Currently we do just one interrupt
+ * at a time. This reduces the time we spent doing all this within clock
+ * interrupt. When it is done in idle, we could do more than 1.
+ * First we find the most busy and the most free CPU (time in ISR only)
+ * skipping those CPUs that has been identified as being ineligible (cpu_skip)
+ * Then we look for IRQs which are closest to the difference between the
+ * most busy CPU and the average ISR load. We try to find one whose load
+ * is less than difference.If none exists, then we chose one larger than the
+ * difference, provided it does not make the most idle CPU worse than the
+ * most busy one. In the end, we clear all the busy fields for CPUs. For
+ * IRQs, they are cleared as they are scanned.
+ */
+void
+apic_intr_redistribute()
+{
+ int busiest_cpu, most_free_cpu;
+ int cpu_free, cpu_busy, max_busy, min_busy;
+ int min_free, diff;
+ int average_busy, cpus_online;
+ int i, busy, iflag;
+ apic_cpus_info_t *cpu_infop;
+ apic_irq_t *min_busy_irq = NULL;
+ apic_irq_t *max_busy_irq = NULL;
+
+ busiest_cpu = most_free_cpu = -1;
+ cpu_free = cpu_busy = max_busy = average_busy = 0;
+ min_free = apic_sample_factor_redistribution;
+ cpus_online = 0;
+ /*
+ * Below we will check for CPU_INTR_ENABLE, bound, temp_bound, temp_cpu
+ * without ioapic_lock. That is OK as we are just doing statistical
+ * sampling anyway and any inaccuracy now will get corrected next time
+ * The call to rebind which actually changes things will make sure
+ * we are consistent.
+ */
+ for (i = 0; i < apic_nproc; i++) {
+ if (!(apic_redist_cpu_skip & (1 << i)) &&
+ (apic_cpus[i].aci_status & APIC_CPU_INTR_ENABLE)) {
+
+ cpu_infop = &apic_cpus[i];
+ /*
+ * If no unbound interrupts or only 1 total on this
+ * CPU, skip
+ */
+ if (!cpu_infop->aci_temp_bound ||
+ (cpu_infop->aci_bound + cpu_infop->aci_temp_bound)
+ == 1) {
+ apic_redist_cpu_skip |= 1 << i;
+ continue;
+ }
+
+ busy = cpu_infop->aci_busy;
+ average_busy += busy;
+ cpus_online++;
+ if (max_busy < busy) {
+ max_busy = busy;
+ busiest_cpu = i;
+ }
+ if (min_free > busy) {
+ min_free = busy;
+ most_free_cpu = i;
+ }
+ if (busy > apic_int_busy_mark) {
+ cpu_busy |= 1 << i;
+ } else {
+ if (busy < apic_int_free_mark)
+ cpu_free |= 1 << i;
+ }
+ }
+ }
+ if ((cpu_busy && cpu_free) ||
+ (max_busy >= (min_free + apic_diff_for_redistribution))) {
+
+ apic_num_imbalance++;
+#ifdef DEBUG
+ if (apic_verbose & APIC_VERBOSE_IOAPIC_FLAG) {
+ prom_printf(
+ "redistribute busy=%x free=%x max=%x min=%x",
+ cpu_busy, cpu_free, max_busy, min_free);
+ }
+#endif /* DEBUG */
+
+
+ average_busy /= cpus_online;
+
+ diff = max_busy - average_busy;
+ min_busy = max_busy; /* start with the max possible value */
+ max_busy = 0;
+ min_busy_irq = max_busy_irq = NULL;
+ i = apic_min_device_irq;
+ for (; i < apic_max_device_irq; i++) {
+ apic_irq_t *irq_ptr;
+ /* Change to linked list per CPU ? */
+ if ((irq_ptr = apic_irq_table[i]) == NULL)
+ continue;
+ /* Check for irq_busy & decide which one to move */
+ /* Also zero them for next round */
+ if ((irq_ptr->airq_temp_cpu == busiest_cpu) &&
+ irq_ptr->airq_busy) {
+ if (irq_ptr->airq_busy < diff) {
+ /*
+ * Check for least busy CPU,
+ * best fit or what ?
+ */
+ if (max_busy < irq_ptr->airq_busy) {
+ /*
+ * Most busy within the
+ * required differential
+ */
+ max_busy = irq_ptr->airq_busy;
+ max_busy_irq = irq_ptr;
+ }
+ } else {
+ if (min_busy > irq_ptr->airq_busy) {
+ /*
+ * least busy, but more than
+ * the reqd diff
+ */
+ if (min_busy <
+ (diff + average_busy -
+ min_free)) {
+ /*
+ * Making sure new cpu
+ * will not end up
+ * worse
+ */
+ min_busy =
+ irq_ptr->airq_busy;
+
+ min_busy_irq = irq_ptr;
+ }
+ }
+ }
+ }
+ irq_ptr->airq_busy = 0;
+ }
+
+ if (max_busy_irq != NULL) {
+#ifdef DEBUG
+ if (apic_verbose & APIC_VERBOSE_IOAPIC_FLAG) {
+ prom_printf("rebinding %x to %x",
+ max_busy_irq->airq_vector, most_free_cpu);
+ }
+#endif /* DEBUG */
+ iflag = intr_clear();
+ if (lock_try(&apic_ioapic_lock)) {
+ if (apic_rebind_all(max_busy_irq,
+ most_free_cpu) == 0) {
+ /* Make change permenant */
+ max_busy_irq->airq_cpu =
+ (uchar_t)most_free_cpu;
+ }
+ lock_clear(&apic_ioapic_lock);
+ }
+ intr_restore(iflag);
+
+ } else if (min_busy_irq != NULL) {
+#ifdef DEBUG
+ if (apic_verbose & APIC_VERBOSE_IOAPIC_FLAG) {
+ prom_printf("rebinding %x to %x",
+ min_busy_irq->airq_vector, most_free_cpu);
+ }
+#endif /* DEBUG */
+
+ iflag = intr_clear();
+ if (lock_try(&apic_ioapic_lock)) {
+ if (apic_rebind_all(min_busy_irq,
+ most_free_cpu) == 0) {
+ /* Make change permenant */
+ min_busy_irq->airq_cpu =
+ (uchar_t)most_free_cpu;
+ }
+ lock_clear(&apic_ioapic_lock);
+ }
+ intr_restore(iflag);
+
+ } else {
+ if (cpu_busy != (1 << busiest_cpu)) {
+ apic_redist_cpu_skip |= 1 << busiest_cpu;
+ /*
+ * We leave cpu_skip set so that next time we
+ * can choose another cpu
+ */
+ }
+ }
+ apic_num_rebind++;
+ } else {
+ /*
+ * found nothing. Could be that we skipped over valid CPUs
+ * or we have balanced everything. If we had a variable
+ * ticks_for_redistribution, it could be increased here.
+ * apic_int_busy, int_free etc would also need to be
+ * changed.
+ */
+ if (apic_redist_cpu_skip)
+ apic_redist_cpu_skip = 0;
+ }
+ for (i = 0; i < apic_nproc; i++) {
+ apic_cpus[i].aci_busy = 0;
+ }
+}
+
+void
+apic_cleanup_busy()
+{
+ int i;
+ apic_irq_t *irq_ptr;
+
+ for (i = 0; i < apic_nproc; i++) {
+ apic_cpus[i].aci_busy = 0;
+ }
+
+ for (i = apic_min_device_irq; i < apic_max_device_irq; i++) {
+ if ((irq_ptr = apic_irq_table[i]) != NULL)
+ irq_ptr->airq_busy = 0;
+ }
+}
+
+
+static int
+apic_acpi_translate_pci_irq(dev_info_t *dip, int busid, int devid,
+ int ipin, int *pci_irqp, iflag_t *intr_flagp)
+{
+
+ int status;
+ acpi_psm_lnk_t acpipsmlnk;
+
+ if ((status = acpi_get_irq_cache_ent(busid, devid, ipin, pci_irqp,
+ intr_flagp)) == ACPI_PSM_SUCCESS) {
+ APIC_VERBOSE_IRQ((CE_CONT, "!%s: Found irqno %d "
+ "from cache for device %s, instance #%d\n", psm_name,
+ *pci_irqp, ddi_get_name(dip), ddi_get_instance(dip)));
+ return (status);
+ }
+
+ bzero(&acpipsmlnk, sizeof (acpi_psm_lnk_t));
+
+ if ((status = acpi_translate_pci_irq(dip, ipin, pci_irqp, intr_flagp,
+ &acpipsmlnk)) == ACPI_PSM_FAILURE) {
+ APIC_VERBOSE_IRQ((CE_WARN, "%s: "
+ " acpi_translate_pci_irq failed for device %s, instance"
+ " #%d", psm_name, ddi_get_name(dip),
+ ddi_get_instance(dip)));
+ return (status);
+ }
+
+ if (status == ACPI_PSM_PARTIAL && acpipsmlnk.lnkobj != NULL) {
+ status = apic_acpi_irq_configure(&acpipsmlnk, dip, pci_irqp,
+ intr_flagp);
+ if (status != ACPI_PSM_SUCCESS) {
+ status = acpi_get_current_irq_resource(&acpipsmlnk,
+ pci_irqp, intr_flagp);
+ }
+ }
+
+ if (status == ACPI_PSM_SUCCESS) {
+ acpi_new_irq_cache_ent(busid, devid, ipin, *pci_irqp,
+ intr_flagp, &acpipsmlnk);
+
+ APIC_VERBOSE_IRQ((CE_CONT, "%s: [ACPI] "
+ "new irq %d for device %s, instance #%d\n", psm_name,
+ *pci_irqp, ddi_get_name(dip), ddi_get_instance(dip)));
+ }
+
+ return (status);
+}
+
+/*
+ * Adds an entry to the irq list passed in, and returns the new list.
+ * Entries are added in priority order (lower numerical priorities are
+ * placed closer to the head of the list)
+ */
+static prs_irq_list_t *
+acpi_insert_prs_irq_ent(prs_irq_list_t *listp, int priority, int irq,
+ iflag_t *iflagp, acpi_prs_private_t *prsprvp)
+{
+ struct prs_irq_list_ent *newent, *prevp = NULL, *origlistp;
+
+ newent = kmem_zalloc(sizeof (struct prs_irq_list_ent), KM_SLEEP);
+
+ newent->list_prio = priority;
+ newent->irq = irq;
+ newent->intrflags = *iflagp;
+ newent->prsprv = *prsprvp;
+ /* ->next is NULL from kmem_zalloc */
+
+ /*
+ * New list -- return the new entry as the list.
+ */
+ if (listp == NULL)
+ return (newent);
+
+ /*
+ * Save original list pointer for return (since we're not modifying
+ * the head)
+ */
+ origlistp = listp;
+
+ /*
+ * Insertion sort, with entries with identical keys stored AFTER
+ * existing entries (the less-than-or-equal test of priority does
+ * this for us).
+ */
+ while (listp != NULL && listp->list_prio <= priority) {
+ prevp = listp;
+ listp = listp->next;
+ }
+
+ newent->next = listp;
+
+ if (prevp == NULL) { /* Add at head of list (newent is the new head) */
+ return (newent);
+ } else {
+ prevp->next = newent;
+ return (origlistp);
+ }
+}
+
+/*
+ * Frees the list passed in, deallocating all memory and leaving *listpp
+ * set to NULL.
+ */
+static void
+acpi_destroy_prs_irq_list(prs_irq_list_t **listpp)
+{
+ struct prs_irq_list_ent *nextp;
+
+ ASSERT(listpp != NULL);
+
+ while (*listpp != NULL) {
+ nextp = (*listpp)->next;
+ kmem_free(*listpp, sizeof (struct prs_irq_list_ent));
+ *listpp = nextp;
+ }
+}
+
+/*
+ * apic_choose_irqs_from_prs returns a list of irqs selected from the list of
+ * irqs returned by the link device's _PRS method. The irqs are chosen
+ * to minimize contention in situations where the interrupt link device
+ * can be programmed to steer interrupts to different interrupt controller
+ * inputs (some of which may already be in use). The list is sorted in order
+ * of irqs to use, with the highest priority given to interrupt controller
+ * inputs that are not shared. When an interrupt controller input
+ * must be shared, apic_choose_irqs_from_prs adds the possible irqs to the
+ * returned list in the order that minimizes sharing (thereby ensuring lowest
+ * possible latency from interrupt trigger time to ISR execution time).
+ */
+static prs_irq_list_t *
+apic_choose_irqs_from_prs(acpi_irqlist_t *irqlistent, dev_info_t *dip,
+ int crs_irq)
+{
+ int32_t irq;
+ int i;
+ prs_irq_list_t *prsirqlistp = NULL;
+ iflag_t iflags;
+
+ while (irqlistent != NULL) {
+ irqlistent->intr_flags.bustype = BUS_PCI;
+
+ for (i = 0; i < irqlistent->num_irqs; i++) {
+
+ irq = irqlistent->irqs[i];
+
+ if (irq <= 0) {
+ /* invalid irq number */
+ continue;
+ }
+
+ if ((irq < 16) && (apic_reserved_irqlist[irq]))
+ continue;
+
+ if ((apic_irq_table[irq] == NULL) ||
+ (apic_irq_table[irq]->airq_dip == dip)) {
+
+ prsirqlistp = acpi_insert_prs_irq_ent(
+ prsirqlistp, 0 /* Highest priority */, irq,
+ &irqlistent->intr_flags,
+ &irqlistent->acpi_prs_prv);
+
+ /*
+ * If we do not prefer the current irq from _CRS
+ * or if we do and this irq is the same as the
+ * current irq from _CRS, this is the one
+ * to pick.
+ */
+ if (!(apic_prefer_crs) || (irq == crs_irq)) {
+ return (prsirqlistp);
+ }
+ continue;
+ }
+
+ /*
+ * Edge-triggered interrupts cannot be shared
+ */
+ if (irqlistent->intr_flags.intr_el == INTR_EL_EDGE)
+ continue;
+
+ /*
+ * To work around BIOSes that contain incorrect
+ * interrupt polarity information in interrupt
+ * descriptors returned by _PRS, we assume that
+ * the polarity of the other device sharing this
+ * interrupt controller input is compatible.
+ * If it's not, the caller will catch it when
+ * the caller invokes the link device's _CRS method
+ * (after invoking its _SRS method).
+ */
+ iflags = irqlistent->intr_flags;
+ iflags.intr_po =
+ apic_irq_table[irq]->airq_iflag.intr_po;
+
+ if (!acpi_intr_compatible(iflags,
+ apic_irq_table[irq]->airq_iflag)) {
+ APIC_VERBOSE_IRQ((CE_CONT, "!%s: irq %d "
+ "not compatible [%x:%x:%x !~ %x:%x:%x]",
+ psm_name, irq,
+ iflags.intr_po,
+ iflags.intr_el,
+ iflags.bustype,
+ apic_irq_table[irq]->airq_iflag.intr_po,
+ apic_irq_table[irq]->airq_iflag.intr_el,
+ apic_irq_table[irq]->airq_iflag.bustype));
+ continue;
+ }
+
+ /*
+ * If we prefer the irq from _CRS, no need
+ * to search any further (and make sure
+ * to add this irq with the highest priority
+ * so it's tried first).
+ */
+ if (crs_irq == irq && apic_prefer_crs) {
+
+ return (acpi_insert_prs_irq_ent(
+ prsirqlistp,
+ 0 /* Highest priority */,
+ irq, &iflags,
+ &irqlistent->acpi_prs_prv));
+ }
+
+ /*
+ * Priority is equal to the share count (lower
+ * share count is higher priority). Note that
+ * the intr flags passed in here are the ones we
+ * changed above -- if incorrect, it will be
+ * caught by the caller's _CRS flags comparison.
+ */
+ prsirqlistp = acpi_insert_prs_irq_ent(
+ prsirqlistp,
+ apic_irq_table[irq]->airq_share, irq,
+ &iflags, &irqlistent->acpi_prs_prv);
+ }
+
+ /* Go to the next irqlist entry */
+ irqlistent = irqlistent->next;
+ }
+
+ return (prsirqlistp);
+}
+
+/*
+ * Configures the irq for the interrupt link device identified by
+ * acpipsmlnkp.
+ *
+ * Gets the current and the list of possible irq settings for the
+ * device. If apic_unconditional_srs is not set, and the current
+ * resource setting is in the list of possible irq settings,
+ * current irq resource setting is passed to the caller.
+ *
+ * Otherwise, picks an irq number from the list of possible irq
+ * settings, and sets the irq of the device to this value.
+ * If prefer_crs is set, among a set of irq numbers in the list that have
+ * the least number of devices sharing the interrupt, we pick current irq
+ * resource setting if it is a member of this set.
+ *
+ * Passes the irq number in the value pointed to by pci_irqp, and
+ * polarity and sensitivity in the structure pointed to by dipintrflagp
+ * to the caller.
+ *
+ * Note that if setting the irq resource failed, but successfuly obtained
+ * the current irq resource settings, passes the current irq resources
+ * and considers it a success.
+ *
+ * Returns:
+ * ACPI_PSM_SUCCESS on success.
+ *
+ * ACPI_PSM_FAILURE if an error occured during the configuration or
+ * if a suitable irq was not found for this device, or if setting the
+ * irq resource and obtaining the current resource fails.
+ *
+ */
+static int
+apic_acpi_irq_configure(acpi_psm_lnk_t *acpipsmlnkp, dev_info_t *dip,
+ int *pci_irqp, iflag_t *dipintr_flagp)
+{
+ int32_t irq;
+ int cur_irq = -1;
+ acpi_irqlist_t *irqlistp;
+ prs_irq_list_t *prs_irq_listp, *prs_irq_entp;
+ boolean_t found_irq = B_FALSE;
+
+ dipintr_flagp->bustype = BUS_PCI;
+
+ if ((acpi_get_possible_irq_resources(acpipsmlnkp, &irqlistp))
+ == ACPI_PSM_FAILURE) {
+ APIC_VERBOSE_IRQ((CE_WARN, "!%s: Unable to determine "
+ "or assign IRQ for device %s, instance #%d: The system was "
+ "unable to get the list of potential IRQs from ACPI.",
+ psm_name, ddi_get_name(dip), ddi_get_instance(dip)));
+
+ return (ACPI_PSM_FAILURE);
+ }
+
+ if ((acpi_get_current_irq_resource(acpipsmlnkp, &cur_irq,
+ dipintr_flagp) == ACPI_PSM_SUCCESS) && (!apic_unconditional_srs) &&
+ (cur_irq > 0)) {
+ /*
+ * If an IRQ is set in CRS and that IRQ exists in the set
+ * returned from _PRS, return that IRQ, otherwise print
+ * a warning
+ */
+
+ if (acpi_irqlist_find_irq(irqlistp, cur_irq, NULL)
+ == ACPI_PSM_SUCCESS) {
+
+ ASSERT(pci_irqp != NULL);
+ *pci_irqp = cur_irq;
+ acpi_free_irqlist(irqlistp);
+ return (ACPI_PSM_SUCCESS);
+ }
+
+ APIC_VERBOSE_IRQ((CE_WARN, "!%s: Could not find the "
+ "current irq %d for device %s, instance #%d in ACPI's "
+ "list of possible irqs for this device. Picking one from "
+ " the latter list.", psm_name, cur_irq, ddi_get_name(dip),
+ ddi_get_instance(dip)));
+ }
+
+ if ((prs_irq_listp = apic_choose_irqs_from_prs(irqlistp, dip,
+ cur_irq)) == NULL) {
+
+ APIC_VERBOSE_IRQ((CE_WARN, "!%s: Could not find a "
+ "suitable irq from the list of possible irqs for device "
+ "%s, instance #%d in ACPI's list of possible irqs",
+ psm_name, ddi_get_name(dip), ddi_get_instance(dip)));
+
+ acpi_free_irqlist(irqlistp);
+ return (ACPI_PSM_FAILURE);
+ }
+
+ acpi_free_irqlist(irqlistp);
+
+ for (prs_irq_entp = prs_irq_listp;
+ prs_irq_entp != NULL && found_irq == B_FALSE;
+ prs_irq_entp = prs_irq_entp->next) {
+
+ acpipsmlnkp->acpi_prs_prv = prs_irq_entp->prsprv;
+ irq = prs_irq_entp->irq;
+
+ APIC_VERBOSE_IRQ((CE_CONT, "!%s: Setting irq %d for "
+ "device %s instance #%d\n", psm_name, irq,
+ ddi_get_name(dip), ddi_get_instance(dip)));
+
+ if ((acpi_set_irq_resource(acpipsmlnkp, irq))
+ == ACPI_PSM_SUCCESS) {
+ /*
+ * setting irq was successful, check to make sure CRS
+ * reflects that. If CRS does not agree with what we
+ * set, return the irq that was set.
+ */
+
+ if (acpi_get_current_irq_resource(acpipsmlnkp, &cur_irq,
+ dipintr_flagp) == ACPI_PSM_SUCCESS) {
+
+ if (cur_irq != irq)
+ APIC_VERBOSE_IRQ((CE_WARN,
+ "!%s: IRQ resource set "
+ "(irqno %d) for device %s "
+ "instance #%d, differs from "
+ "current setting irqno %d",
+ psm_name, irq, ddi_get_name(dip),
+ ddi_get_instance(dip), cur_irq));
+ } else {
+ /*
+ * On at least one system, there was a bug in
+ * a DSDT method called by _STA, causing _STA to
+ * indicate that the link device was disabled
+ * (when, in fact, it was enabled). Since _SRS
+ * succeeded, assume that _CRS is lying and use
+ * the iflags from this _PRS interrupt choice.
+ * If we're wrong about the flags, the polarity
+ * will be incorrect and we may get an interrupt
+ * storm, but there's not much else we can do
+ * at this point.
+ */
+ *dipintr_flagp = prs_irq_entp->intrflags;
+ }
+
+ /*
+ * Return the irq that was set, and not what _CRS
+ * reports, since _CRS has been seen to return
+ * different IRQs than what was passed to _SRS on some
+ * systems (and just not return successfully on others).
+ */
+ cur_irq = irq;
+ found_irq = B_TRUE;
+ } else {
+ APIC_VERBOSE_IRQ((CE_WARN, "!%s: set resource "
+ "irq %d failed for device %s instance #%d",
+ psm_name, irq, ddi_get_name(dip),
+ ddi_get_instance(dip)));
+
+ if (cur_irq == -1) {
+ acpi_destroy_prs_irq_list(&prs_irq_listp);
+ return (ACPI_PSM_FAILURE);
+ }
+ }
+ }
+
+ acpi_destroy_prs_irq_list(&prs_irq_listp);
+
+ if (!found_irq)
+ return (ACPI_PSM_FAILURE);
+
+ ASSERT(pci_irqp != NULL);
+ *pci_irqp = cur_irq;
+ return (ACPI_PSM_SUCCESS);
+}
+
+void
+ioapic_disable_redirection()
+{
+ int ioapic_ix;
+ int intin_max;
+ int intin_ix;
+
+ /* Disable the I/O APIC redirection entries */
+ for (ioapic_ix = 0; ioapic_ix < apic_io_max; ioapic_ix++) {
+
+ /* Bits 23-16 define the maximum redirection entries */
+ intin_max = (ioapic_read(ioapic_ix, APIC_VERS_CMD) >> 16)
+ & 0xff;
+
+ for (intin_ix = 0; intin_ix < intin_max; intin_ix++)
+ ioapic_write(ioapic_ix, APIC_RDT_CMD + 2 * intin_ix,
+ AV_MASK);
+ }
+}
diff --git a/usr/src/uts/i86pc/io/pci/pci_common.c b/usr/src/uts/i86pc/io/pci/pci_common.c
index f97c7539d4..f432b85130 100644
--- a/usr/src/uts/i86pc/io/pci/pci_common.c
+++ b/usr/src/uts/i86pc/io/pci/pci_common.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,7 +45,7 @@
#include <sys/policy.h>
#include <sys/sysmacros.h>
#include <sys/clock.h>
-#include <io/pcplusmp/apic.h>
+#include <sys/apic.h>
#include <sys/pci_tools.h>
#include <io/pci/pci_var.h>
#include <io/pci/pci_tools_ext.h>
diff --git a/usr/src/uts/i86pc/io/pci/pci_kstats.c b/usr/src/uts/i86pc/io/pci/pci_kstats.c
index ce0780bf34..c8032f1286 100644
--- a/usr/src/uts/i86pc/io/pci/pci_kstats.c
+++ b/usr/src/uts/i86pc/io/pci/pci_kstats.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,7 +33,7 @@
#include <sys/mach_intr.h>
#include <sys/psm.h>
#include <sys/clock.h>
-#include <io/pcplusmp/apic.h>
+#include <sys/apic.h>
#include <io/pci/pci_var.h>
typedef struct pci_kstat_private {
diff --git a/usr/src/uts/i86pc/io/pci/pci_tools.c b/usr/src/uts/i86pc/io/pci/pci_tools.c
index a08bfc9b91..7e4c90c432 100644
--- a/usr/src/uts/i86pc/io/pci/pci_tools.c
+++ b/usr/src/uts/i86pc/io/pci/pci_tools.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,7 +39,7 @@
#include <sys/pci_cfgspace.h>
#include <sys/pci_tools.h>
#include <io/pci/pci_tools_ext.h>
-#include <io/pcplusmp/apic.h>
+#include <sys/apic.h>
#include <io/pci/pci_var.h>
#include <sys/promif.h>
#include <sys/x86_archext.h>
@@ -741,6 +741,7 @@ pcitool_map(uint64_t phys_addr, size_t size, size_t *num_pages)
uint64_t offset = phys_addr & MMU_PAGEOFFSET;
void *virt_base;
uint64_t returned_addr;
+ pfn_t pfn;
if (pcitool_debug)
prom_printf("pcitool_map: Called with PA:0x%p\n",
@@ -771,9 +772,11 @@ pcitool_map(uint64_t phys_addr, size_t size, size_t *num_pages)
if (pcitool_debug)
prom_printf("Got base virtual address:0x%p\n", virt_base);
+ pfn = btop(page_base);
+
/* Now map the allocated virtual space to the physical address. */
- hat_devload(kas.a_hat, virt_base, mmu_ptob(*num_pages),
- mmu_btop(page_base), PROT_READ | PROT_WRITE | HAT_STRICTORDER,
+ hat_devload(kas.a_hat, virt_base, mmu_ptob(*num_pages), pfn,
+ PROT_READ | PROT_WRITE | HAT_STRICTORDER,
HAT_LOAD_LOCK);
returned_addr = ((uintptr_t)(virt_base)) + offset;
diff --git a/usr/src/uts/i86pc/io/pciex/inc.flg b/usr/src/uts/i86pc/io/pciex/inc.flg
index 4379616c55..7d4ab20ccf 100644
--- a/usr/src/uts/i86pc/io/pciex/inc.flg
+++ b/usr/src/uts/i86pc/io/pciex/inc.flg
@@ -3,9 +3,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -56,9 +55,9 @@ find_files "s.*" \
# to compile the drivers/modules
find_files "s.*" \
usr/src/uts/i86pc/npe \
- usr/src/uts/i86pc/pcie_pci \
- usr/src/uts/i86pc/pciehpc \
- usr/src/uts/i86pc/pci_autoconfig \
+ usr/src/uts/intel/pci_autoconfig \
+ usr/src/uts/intel/pcie_pci \
+ usr/src/uts/intel/pciehpc \
usr/src/uts/intel/pcicfg
# packaging files
@@ -75,9 +74,11 @@ find_files "s.*" \
usr/src/uts/common/rpc \
usr/src/uts/intel/asm \
usr/src/uts/intel/amd64 \
+ usr/src/uts/intel/io/pci \
+ usr/src/uts/intel/io/pciex \
usr/src/uts/i86pc/io/pci \
usr/src/uts/i86pc/io/pcplusmp \
- usr/src/uts/i86pc/io/acpica
+ usr/src/uts/intel/io/acpica
# makefiles
echo_file usr/src/Makefile.master
diff --git a/usr/src/uts/i86pc/io/pcplusmp/apic.c b/usr/src/uts/i86pc/io/pcplusmp/apic.c
index 1305e8ccde..0f30ffa9c8 100644
--- a/usr/src/uts/i86pc/io/pcplusmp/apic.c
+++ b/usr/src/uts/i86pc/io/pcplusmp/apic.c
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,7 +42,7 @@
#include <sys/acpi/acpi.h>
#include <sys/acpica.h>
#include <sys/psm_common.h>
-#include "apic.h"
+#include <sys/apic.h>
#include <sys/pit.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
@@ -56,78 +57,23 @@
#include <sys/archsystm.h>
#include <sys/trap.h>
#include <sys/machsystm.h>
+#include <sys/sysmacros.h>
#include <sys/cpuvar.h>
#include <sys/rm_platter.h>
#include <sys/privregs.h>
#include <sys/cyclic.h>
#include <sys/note.h>
#include <sys/pci_intr_lib.h>
-#include <sys/sunndi.h>
-
-struct ioapic_reprogram_data;
+#include <sys/spl.h>
/*
* Local Function Prototypes
*/
static void apic_init_intr();
static void apic_ret();
-static int apic_handle_defconf();
-static int apic_parse_mpct(caddr_t mpct, int bypass);
-static struct apic_mpfps_hdr *apic_find_fps_sig(caddr_t fptr, int size);
-static int apic_checksum(caddr_t bptr, int len);
static int get_apic_cmd1();
static int get_apic_pri();
-static int apic_find_bus_type(char *bus);
-static int apic_find_bus(int busid);
-static int apic_find_bus_id(int bustype);
-static struct apic_io_intr *apic_find_io_intr(int irqno);
-int apic_allocate_irq(int irq);
-static int apic_find_free_irq(int start, int end);
-static uchar_t apic_allocate_vector(int ipl, int irq, int pri);
-static void apic_modify_vector(uchar_t vector, int irq);
-static void apic_mark_vector(uchar_t oldvector, uchar_t newvector);
-static uchar_t apic_xlate_vector(uchar_t oldvector);
-static void apic_xlate_vector_free_timeout_handler(void *arg);
-static void apic_free_vector(uchar_t vector);
-static void apic_reprogram_timeout_handler(void *arg);
-static int apic_check_stuck_interrupt(apic_irq_t *irq_ptr, int old_bind_cpu,
- int new_bind_cpu, volatile int32_t *ioapic, int intin_no, int which_irq,
- struct ioapic_reprogram_data *drep);
-static int apic_setup_io_intr(void *p, int irq, boolean_t deferred);
-static void apic_record_rdt_entry(apic_irq_t *irqptr, int irq);
-static struct apic_io_intr *apic_find_io_intr_w_busid(int irqno, int busid);
-static int apic_find_intin(uchar_t ioapic, uchar_t intin);
-static int apic_handle_pci_pci_bridge(dev_info_t *idip, int child_devno,
- int child_ipin, struct apic_io_intr **intrp);
-static int apic_setup_irq_table(dev_info_t *dip, int irqno,
- struct apic_io_intr *intrp, struct intrspec *ispec, iflag_t *intr_flagp,
- int type);
-static int apic_setup_sci_irq_table(int irqno, uchar_t ipl,
- iflag_t *intr_flagp);
static void apic_nmi_intr(caddr_t arg);
-uchar_t apic_bind_intr(dev_info_t *dip, int irq, uchar_t ioapicid,
- uchar_t intin);
-static int apic_rebind(apic_irq_t *irq_ptr, int bind_cpu,
- struct ioapic_reprogram_data *drep);
-int apic_rebind_all(apic_irq_t *irq_ptr, int bind_cpu);
-static void apic_intr_redistribute();
-static void apic_cleanup_busy();
-static void apic_set_pwroff_method_from_mpcnfhdr(struct apic_mp_cnf_hdr *hdrp);
-int apic_introp_xlate(dev_info_t *dip, struct intrspec *ispec, int type);
-static void apic_try_deferred_reprogram(int ipl, int vect);
-static void delete_defer_repro_ent(int which_irq);
-static void apic_ioapic_wait_pending_clear(volatile int32_t *ioapic,
- int intin_no);
-
-/* ACPI support routines */
-static int acpi_probe(void);
-static int apic_acpi_irq_configure(acpi_psm_lnk_t *acpipsmlnkp, dev_info_t *dip,
- int *pci_irqp, iflag_t *intr_flagp);
-
-static int apic_acpi_translate_pci_irq(dev_info_t *dip, int busid, int devid,
- int ipin, int *pci_irqp, iflag_t *intr_flagp);
-static uchar_t acpi_find_ioapic(int irq);
-static int acpi_intr_compatible(iflag_t iflag1, iflag_t iflag2);
/*
* standard MP entries
@@ -141,7 +87,7 @@ static hrtime_t apic_gettime();
static hrtime_t apic_gethrtime();
static void apic_init();
static void apic_picinit(void);
-static void apic_cpu_start(processorid_t cpun, caddr_t rm_code);
+static int apic_cpu_start(processorid_t, caddr_t);
static int apic_post_cpu_start(void);
static void apic_send_ipi(int cpun, int ipl);
static void apic_set_softintr(int softintr);
@@ -149,7 +95,6 @@ static void apic_set_idlecpu(processorid_t cpun);
static void apic_unset_idlecpu(processorid_t cpun);
static int apic_softlvl_to_irq(int ipl);
static int apic_intr_enter(int ipl, int *vect);
-static void apic_intr_exit(int ipl, int vect);
static void apic_setspl(int ipl);
static int apic_addspl(int ipl, int vector, int min_ipl, int max_ipl);
static int apic_delspl(int ipl, int vector, int min_ipl, int max_ipl);
@@ -163,12 +108,14 @@ static void apic_timer_reprogram(hrtime_t time);
static void apic_timer_enable(void);
static void apic_timer_disable(void);
static void apic_post_cyclic_setup(void *arg);
-extern int apic_intr_ops(dev_info_t *, ddi_intr_handle_impl_t *,
- psm_intr_op_t, int *);
static int apic_oneshot = 0;
int apic_oneshot_enable = 1; /* to allow disabling one-shot capability */
+/* Now the ones for Dynamic Interrupt distribution */
+int apic_enable_dynamic_migration = 0;
+
+
/*
* These variables are frequently accessed in apic_intr_enter(),
* apic_intr_exit and apic_setspl, so group them together
@@ -177,10 +124,6 @@ volatile uint32_t *apicadr = NULL; /* virtual addr of local APIC */
int apic_setspl_delay = 1; /* apic_setspl - delay enable */
int apic_clkvect;
-/* ACPI SCI interrupt configuration; -1 if SCI not used */
-int apic_sci_vect = -1;
-iflag_t apic_sci_flags;
-
/* vector at which error interrupts come in */
int apic_errvect;
int apic_enable_error_intr = 1;
@@ -190,19 +133,6 @@ int apic_error_display_delay = 100;
int apic_cpcovf_vect;
int apic_enable_cpcovf_intr = 1;
-/* Max wait time (in repetitions) for flags to clear in an RDT entry. */
-static int apic_max_reps_clear_pending = 1000;
-
-/* Maximum number of times to retry reprogramming at apic_intr_exit time */
-#define APIC_REPROGRAM_MAX_TRIES 10000
-
-/*
- * number of bits per byte, from <sys/param.h>
- */
-#define UCHAR_MAX ((1 << NBBY) - 1)
-
-uchar_t apic_reserved_irqlist[MAX_ISA_IRQ + 1];
-
/*
* The following vector assignments influence the value of ipltopri and
* vectortoipl. Note that vectors 0 - 0x1f are not used. We can program
@@ -243,15 +173,6 @@ uchar_t apic_cr8pri[MAXIPL + 1]; /* unix ipl to cr8 pri */
*/
int apic_forceload = 0;
-#define INTR_ROUND_ROBIN_WITH_AFFINITY 0
-#define INTR_ROUND_ROBIN 1
-#define INTR_LOWEST_PRIORITY 2
-
-int apic_intr_policy = INTR_ROUND_ROBIN_WITH_AFFINITY;
-
-static int apic_next_bind_cpu = 1; /* For round robin assignment */
- /* start with cpu 1 */
-
int apic_coarse_hrtime = 1; /* 0 - use accurate slow gethrtime() */
/* 1 - use gettime() for performance */
int apic_flat_model = 0; /* 0 - clustered. 1 - flat */
@@ -262,102 +183,6 @@ int apic_panic_on_apic_error = 0;
int apic_verbose = 0;
-/* Flag definitions for apic_verbose */
-#define APIC_VERBOSE_IOAPIC_FLAG 0x00000001
-#define APIC_VERBOSE_IRQ_FLAG 0x00000002
-#define APIC_VERBOSE_POWEROFF_FLAG 0x00000004
-#define APIC_VERBOSE_POWEROFF_PAUSE_FLAG 0x00000008
-
-
-#define APIC_VERBOSE_IOAPIC(fmt) \
- if (apic_verbose & APIC_VERBOSE_IOAPIC_FLAG) \
- cmn_err fmt;
-
-#define APIC_VERBOSE_IRQ(fmt) \
- if (apic_verbose & APIC_VERBOSE_IRQ_FLAG) \
- cmn_err fmt;
-
-#define APIC_VERBOSE_POWEROFF(fmt) \
- if (apic_verbose & APIC_VERBOSE_POWEROFF_FLAG) \
- prom_printf fmt;
-
-
-/* Now the ones for Dynamic Interrupt distribution */
-int apic_enable_dynamic_migration = 0;
-
-/*
- * If enabled, the distribution works as follows:
- * On every interrupt entry, the current ipl for the CPU is set in cpu_info
- * and the irq corresponding to the ipl is also set in the aci_current array.
- * interrupt exit and setspl (due to soft interrupts) will cause the current
- * ipl to be be changed. This is cache friendly as these frequently used
- * paths write into a per cpu structure.
- *
- * Sampling is done by checking the structures for all CPUs and incrementing
- * the busy field of the irq (if any) executing on each CPU and the busy field
- * of the corresponding CPU.
- * In periodic mode this is done on every clock interrupt.
- * In one-shot mode, this is done thru a cyclic with an interval of
- * apic_redistribute_sample_interval (default 10 milli sec).
- *
- * Every apic_sample_factor_redistribution times we sample, we do computations
- * to decide which interrupt needs to be migrated (see comments
- * before apic_intr_redistribute().
- */
-
-/*
- * Following 3 variables start as % and can be patched or set using an
- * API to be defined in future. They will be scaled to
- * sample_factor_redistribution which is in turn set to hertz+1 (in periodic
- * mode), or 101 in one-shot mode to stagger it away from one sec processing
- */
-
-int apic_int_busy_mark = 60;
-int apic_int_free_mark = 20;
-int apic_diff_for_redistribution = 10;
-
-/* sampling interval for interrupt redistribution for dynamic migration */
-int apic_redistribute_sample_interval = NANOSEC / 100; /* 10 millisec */
-
-/*
- * number of times we sample before deciding to redistribute interrupts
- * for dynamic migration
- */
-int apic_sample_factor_redistribution = 101;
-
-/* timeout for xlate_vector, mark_vector */
-int apic_revector_timeout = 16 * 10000; /* 160 millisec */
-
-int apic_redist_cpu_skip = 0;
-int apic_num_imbalance = 0;
-int apic_num_rebind = 0;
-
-int apic_nproc = 0;
-int apic_defconf = 0;
-int apic_irq_translate = 0;
-int apic_spec_rev = 0;
-int apic_imcrp = 0;
-
-int apic_use_acpi = 1; /* 1 = use ACPI, 0 = don't use ACPI */
-int apic_use_acpi_madt_only = 0; /* 1=ONLY use MADT from ACPI */
-
-/*
- * For interrupt link devices, if apic_unconditional_srs is set, an irq resource
- * will be assigned (via _SRS). If it is not set, use the current
- * irq setting (via _CRS), but only if that irq is in the set of possible
- * irqs (returned by _PRS) for the device.
- */
-int apic_unconditional_srs = 1;
-
-/*
- * For interrupt link devices, if apic_prefer_crs is set when we are
- * assigning an IRQ resource to a device, prefer the current IRQ setting
- * over other possible irq settings under same conditions.
- */
-
-int apic_prefer_crs = 1;
-
-
/* minimum number of timer ticks to program to */
int apic_min_timer_ticks = 1;
/*
@@ -394,8 +219,6 @@ static struct psm_ops apic_ops = {
apic_send_ipi,
(int (*)(dev_info_t *, int))NULL, /* psm_translate_irq */
- (int (*)(todinfo_t *))NULL, /* psm_tod_get */
- (int (*)(todinfo_t *))NULL, /* psm_tod_set */
(void (*)(int, char *))NULL, /* psm_notify_error */
(void (*)(int))NULL, /* psm_notify_func */
apic_timer_reprogram,
@@ -418,33 +241,18 @@ static struct psm_info apic_psm_info = {
static void *apic_hdlp;
#ifdef DEBUG
-#define DENT 0x0001
int apic_debug = 0;
-/*
- * set apic_restrict_vector to the # of vectors we want to allow per range
- * useful in testing shared interrupt logic by setting it to 2 or 3
- */
int apic_restrict_vector = 0;
-#define APIC_DEBUG_MSGBUFSIZE 2048
int apic_debug_msgbuf[APIC_DEBUG_MSGBUFSIZE];
int apic_debug_msgbufindex = 0;
-/*
- * Put "int" info into debug buffer. No MP consistency, but light weight.
- * Good enough for most debugging.
- */
-#define APIC_DEBUG_BUF_PUT(x) \
- apic_debug_msgbuf[apic_debug_msgbufindex++] = x; \
- if (apic_debug_msgbufindex >= (APIC_DEBUG_MSGBUFSIZE - NCPU)) \
- apic_debug_msgbufindex = 0;
-
#endif /* DEBUG */
apic_cpus_info_t *apic_cpus;
-static cpuset_t apic_cpumask;
-static uint_t apic_flag;
+cpuset_t apic_cpumask;
+uint_t apic_flag;
/* Flag to indicate that we need to shut down all processors */
static uint_t apic_shutdown_processors;
@@ -482,148 +290,14 @@ int apic_apic_error = 0;
int apic_num_apic_errors = 0;
int apic_num_cksum_errors = 0;
-static uchar_t apic_io_id[MAX_IO_APIC];
-static uchar_t apic_io_ver[MAX_IO_APIC];
-static uchar_t apic_io_vectbase[MAX_IO_APIC];
-static uchar_t apic_io_vectend[MAX_IO_APIC];
-volatile int32_t *apicioadr[MAX_IO_APIC];
-
-/*
- * First available slot to be used as IRQ index into the apic_irq_table
- * for those interrupts (like MSI/X) that don't have a physical IRQ.
- */
-int apic_first_avail_irq = APIC_FIRST_FREE_IRQ;
-
-/*
- * apic_ioapic_lock protects the ioapics (reg select), the status, temp_bound
- * and bound elements of cpus_info and the temp_cpu element of irq_struct
- */
-lock_t apic_ioapic_lock;
-
-/*
- * apic_defer_reprogram_lock ensures that only one processor is handling
- * deferred interrupt programming at apic_intr_exit time.
- */
-static lock_t apic_defer_reprogram_lock;
-
-/*
- * The current number of deferred reprogrammings outstanding
- */
-uint_t apic_reprogram_outstanding = 0;
-
-#ifdef DEBUG
-/*
- * Counters that keep track of deferred reprogramming stats
- */
-uint_t apic_intr_deferrals = 0;
-uint_t apic_intr_deliver_timeouts = 0;
-uint_t apic_last_ditch_reprogram_failures = 0;
-uint_t apic_deferred_setup_failures = 0;
-uint_t apic_defer_repro_total_retries = 0;
-uint_t apic_defer_repro_successes = 0;
-uint_t apic_deferred_spurious_enters = 0;
-#endif
-
-static int apic_io_max = 0; /* no. of i/o apics enabled */
-
-static struct apic_io_intr *apic_io_intrp = 0;
-static struct apic_bus *apic_busp;
-
-uchar_t apic_vector_to_irq[APIC_MAX_VECTOR+1];
-static uchar_t apic_resv_vector[MAXIPL+1];
-
-static char apic_level_intr[APIC_MAX_VECTOR+1];
-static int apic_error = 0;
-/* values which apic_error can take. Not catastrophic, but may help debug */
-#define APIC_ERR_BOOT_EOI 0x1
-#define APIC_ERR_GET_IPIVECT_FAIL 0x2
-#define APIC_ERR_INVALID_INDEX 0x4
-#define APIC_ERR_MARK_VECTOR_FAIL 0x8
-#define APIC_ERR_APIC_ERROR 0x40000000
-#define APIC_ERR_NMI 0x80000000
-
+int apic_error = 0;
static int apic_cmos_ssb_set = 0;
-static uint32_t eisa_level_intr_mask = 0;
- /* At least MSB will be set if EISA bus */
-
-static int apic_pci_bus_total = 0;
-static uchar_t apic_single_pci_busid = 0;
-
-
-/*
- * airq_mutex protects additions to the apic_irq_table - the first
- * pointer and any airq_nexts off of that one. It also protects
- * apic_max_device_irq & apic_min_device_irq. It also guarantees
- * that share_id is unique as new ids are generated only when new
- * irq_t structs are linked in. Once linked in the structs are never
- * deleted. temp_cpu & mps_intr_index field indicate if it is programmed
- * or allocated. Note that there is a slight gap between allocating in
- * apic_introp_xlate and programming in addspl.
- */
-kmutex_t airq_mutex;
-apic_irq_t *apic_irq_table[APIC_MAX_VECTOR+1];
-int apic_max_device_irq = 0;
-int apic_min_device_irq = APIC_MAX_VECTOR;
-
/* use to make sure only one cpu handles the nmi */
static lock_t apic_nmi_lock;
/* use to make sure only one cpu handles the error interrupt */
static lock_t apic_error_lock;
-/*
- * Following declarations are for revectoring; used when ISRs at different
- * IPLs share an irq.
- */
-static lock_t apic_revector_lock;
-static int apic_revector_pending = 0;
-static uchar_t *apic_oldvec_to_newvec;
-static uchar_t *apic_newvec_to_oldvec;
-
-static struct ioapic_reprogram_data {
- boolean_t done;
- apic_irq_t *irqp;
- /* The CPU to which the int will be bound */
- int bindcpu;
- /* # times the reprogram timeout was called */
- unsigned tries;
-
-/* The irq # is implicit in the array index: */
-} apic_reprogram_info[APIC_MAX_VECTOR + 1];
-
-/*
- * APIC_MAX_VECTOR + 1 is the maximum # of IRQs as well. apic_reprogram_info
- * is indexed by IRQ number, NOT by vector number.
- */
-
-typedef struct prs_irq_list_ent {
- int list_prio;
- int32_t irq;
- iflag_t intrflags;
- acpi_prs_private_t prsprv;
- struct prs_irq_list_ent *next;
-} prs_irq_list_t;
-
-/*
- * The following added to identify a software poweroff method if available.
- */
-
-static struct {
- int poweroff_method;
- char oem_id[APIC_MPS_OEM_ID_LEN + 1]; /* MAX + 1 for NULL */
- char prod_id[APIC_MPS_PROD_ID_LEN + 1]; /* MAX + 1 for NULL */
-} apic_mps_ids[] = {
- { APIC_POWEROFF_VIA_RTC, "INTEL", "ALDER" }, /* 4300 */
- { APIC_POWEROFF_VIA_RTC, "NCR", "AMC" }, /* 4300 */
- { APIC_POWEROFF_VIA_ASPEN_BMC, "INTEL", "A450NX" }, /* 4400? */
- { APIC_POWEROFF_VIA_ASPEN_BMC, "INTEL", "AD450NX" }, /* 4400 */
- { APIC_POWEROFF_VIA_ASPEN_BMC, "INTEL", "AC450NX" }, /* 4400R */
- { APIC_POWEROFF_VIA_SITKA_BMC, "INTEL", "S450NX" }, /* S50 */
- { APIC_POWEROFF_VIA_SITKA_BMC, "INTEL", "SC450NX" } /* S50? */
-};
-
-int apic_poweroff_method = APIC_POWEROFF_NONE;
-
static struct {
uchar_t cntl;
uchar_t data;
@@ -662,60 +336,11 @@ static struct {
{ SMS_DATA_REGISTER, 0x22 } /* Cmd RESET_WATCHDOG_TIMER */
};
-
/* Patchable global variables. */
int apic_kmdb_on_nmi = 0; /* 0 - no, 1 - yes enter kmdb */
-int apic_debug_mps_id = 0; /* 1 - print MPS ID strings */
uint32_t apic_divide_reg_init = 0; /* 0 - divide by 2 */
/*
- * ACPI definitions
- */
-/* _PIC method arguments */
-#define ACPI_PIC_MODE 0
-#define ACPI_APIC_MODE 1
-
-/* APIC error flags we care about */
-#define APIC_SEND_CS_ERROR 0x01
-#define APIC_RECV_CS_ERROR 0x02
-#define APIC_CS_ERRORS (APIC_SEND_CS_ERROR|APIC_RECV_CS_ERROR)
-
-/*
- * ACPI variables
- */
-/* 1 = acpi is enabled & working, 0 = acpi is not enabled or not there */
-static int apic_enable_acpi = 0;
-
-/* ACPI Multiple APIC Description Table ptr */
-static MULTIPLE_APIC_TABLE *acpi_mapic_dtp = NULL;
-
-/* ACPI Interrupt Source Override Structure ptr */
-static MADT_INTERRUPT_OVERRIDE *acpi_isop = NULL;
-static int acpi_iso_cnt = 0;
-
-/* ACPI Non-maskable Interrupt Sources ptr */
-static MADT_NMI_SOURCE *acpi_nmi_sp = NULL;
-static int acpi_nmi_scnt = 0;
-static MADT_LOCAL_APIC_NMI *acpi_nmi_cp = NULL;
-static int acpi_nmi_ccnt = 0;
-
-/*
- * extern declarations
- */
-extern int intr_clear(void);
-extern void intr_restore(uint_t);
-#if defined(__amd64)
-extern int intpri_use_cr8;
-#endif /* __amd64 */
-
-extern int apic_pci_msi_enable_vector(dev_info_t *, int, int,
- int, int, int);
-extern apic_irq_t *apic_find_irq(dev_info_t *, struct intrspec *, int);
-extern int apic_pci_msi_unconfigure(dev_info_t *, int, int);
-extern int apic_pci_msi_disable_mode(dev_info_t *, int, int);
-extern int apic_pci_msi_enable_mode(dev_info_t *, int, int);
-
-/*
* This is the loadable module wrapper
*/
@@ -739,788 +364,19 @@ _info(struct modinfo *modinfop)
return (psm_mod_info(&apic_hdlp, &apic_psm_info, modinfop));
}
-/*
- * Auto-configuration routines
- */
-/*
- * Look at MPSpec 1.4 (Intel Order # 242016-005) for details of what we do here
- * May work with 1.1 - but not guaranteed.
- * According to the MP Spec, the MP floating pointer structure
- * will be searched in the order described below:
- * 1. In the first kilobyte of Extended BIOS Data Area (EBDA)
- * 2. Within the last kilobyte of system base memory
- * 3. In the BIOS ROM address space between 0F0000h and 0FFFFh
- * Once we find the right signature with proper checksum, we call
- * either handle_defconf or parse_mpct to get all info necessary for
- * subsequent operations.
- */
static int
apic_probe()
{
- uint32_t mpct_addr, ebda_start = 0, base_mem_end;
- caddr_t biosdatap;
- caddr_t mpct;
- caddr_t fptr;
- int i, mpct_size, mapsize, retval = PSM_FAILURE;
- ushort_t ebda_seg, base_mem_size;
- struct apic_mpfps_hdr *fpsp;
- struct apic_mp_cnf_hdr *hdrp;
- int bypass_cpu_and_ioapics_in_mptables;
- int acpi_user_options;
-
- if (apic_forceload < 0)
- return (retval);
-
- /* Allow override for MADT-only mode */
- acpi_user_options = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_root_node(), 0,
- "acpi-user-options", 0);
- apic_use_acpi_madt_only = ((acpi_user_options & ACPI_OUSER_MADT) != 0);
-
- /* Allow apic_use_acpi to override MADT-only mode */
- if (!apic_use_acpi)
- apic_use_acpi_madt_only = 0;
-
- retval = acpi_probe();
-
- /*
- * mapin the bios data area 40:0
- * 40:13h - two-byte location reports the base memory size
- * 40:0Eh - two-byte location for the exact starting address of
- * the EBDA segment for EISA
- */
- biosdatap = psm_map_phys(0x400, 0x20, PROT_READ);
- if (!biosdatap)
- return (retval);
- fpsp = (struct apic_mpfps_hdr *)NULL;
- mapsize = MPFPS_RAM_WIN_LEN;
- /*LINTED: pointer cast may result in improper alignment */
- ebda_seg = *((ushort_t *)(biosdatap+0xe));
- /* check the 1k of EBDA */
- if (ebda_seg) {
- ebda_start = ((uint32_t)ebda_seg) << 4;
- fptr = psm_map_phys(ebda_start, MPFPS_RAM_WIN_LEN, PROT_READ);
- if (fptr) {
- if (!(fpsp =
- apic_find_fps_sig(fptr, MPFPS_RAM_WIN_LEN)))
- psm_unmap_phys(fptr, MPFPS_RAM_WIN_LEN);
- }
- }
- /* If not in EBDA, check the last k of system base memory */
- if (!fpsp) {
- /*LINTED: pointer cast may result in improper alignment */
- base_mem_size = *((ushort_t *)(biosdatap + 0x13));
-
- if (base_mem_size > 512)
- base_mem_end = 639 * 1024;
- else
- base_mem_end = 511 * 1024;
- /* if ebda == last k of base mem, skip to check BIOS ROM */
- if (base_mem_end != ebda_start) {
-
- fptr = psm_map_phys(base_mem_end, MPFPS_RAM_WIN_LEN,
- PROT_READ);
-
- if (fptr) {
- if (!(fpsp = apic_find_fps_sig(fptr,
- MPFPS_RAM_WIN_LEN)))
- psm_unmap_phys(fptr, MPFPS_RAM_WIN_LEN);
- }
- }
- }
- psm_unmap_phys(biosdatap, 0x20);
-
- /* If still cannot find it, check the BIOS ROM space */
- if (!fpsp) {
- mapsize = MPFPS_ROM_WIN_LEN;
- fptr = psm_map_phys(MPFPS_ROM_WIN_START,
- MPFPS_ROM_WIN_LEN, PROT_READ);
- if (fptr) {
- if (!(fpsp =
- apic_find_fps_sig(fptr, MPFPS_ROM_WIN_LEN))) {
- psm_unmap_phys(fptr, MPFPS_ROM_WIN_LEN);
- return (retval);
- }
- }
- }
-
- if (apic_checksum((caddr_t)fpsp, fpsp->mpfps_length * 16) != 0) {
- psm_unmap_phys(fptr, MPFPS_ROM_WIN_LEN);
- return (retval);
- }
-
- apic_spec_rev = fpsp->mpfps_spec_rev;
- if ((apic_spec_rev != 04) && (apic_spec_rev != 01)) {
- psm_unmap_phys(fptr, MPFPS_ROM_WIN_LEN);
- return (retval);
- }
-
- /* check IMCR is present or not */
- apic_imcrp = fpsp->mpfps_featinfo2 & MPFPS_FEATINFO2_IMCRP;
-
- /* check default configuration (dual CPUs) */
- if ((apic_defconf = fpsp->mpfps_featinfo1) != 0) {
- psm_unmap_phys(fptr, mapsize);
- return (apic_handle_defconf());
- }
-
- /* MP Configuration Table */
- mpct_addr = (uint32_t)(fpsp->mpfps_mpct_paddr);
-
- psm_unmap_phys(fptr, mapsize); /* unmap floating ptr struct */
-
- /*
- * Map in enough memory for the MP Configuration Table Header.
- * Use this table to read the total length of the BIOS data and
- * map in all the info
- */
- /*LINTED: pointer cast may result in improper alignment */
- hdrp = (struct apic_mp_cnf_hdr *)psm_map_phys(mpct_addr,
- sizeof (struct apic_mp_cnf_hdr), PROT_READ);
- if (!hdrp)
- return (retval);
-
- /* check mp configuration table signature PCMP */
- if (hdrp->mpcnf_sig != 0x504d4350) {
- psm_unmap_phys((caddr_t)hdrp, sizeof (struct apic_mp_cnf_hdr));
- return (retval);
- }
- mpct_size = (int)hdrp->mpcnf_tbl_length;
-
- apic_set_pwroff_method_from_mpcnfhdr(hdrp);
-
- psm_unmap_phys((caddr_t)hdrp, sizeof (struct apic_mp_cnf_hdr));
-
- if ((retval == PSM_SUCCESS) && !apic_use_acpi_madt_only) {
- /* This is an ACPI machine No need for further checks */
- return (retval);
- }
-
- /*
- * Map in the entries for this machine, ie. Processor
- * Entry Tables, Bus Entry Tables, etc.
- * They are in fixed order following one another
- */
- mpct = psm_map_phys(mpct_addr, mpct_size, PROT_READ);
- if (!mpct)
- return (retval);
-
- if (apic_checksum(mpct, mpct_size) != 0)
- goto apic_fail1;
-
-
- /*LINTED: pointer cast may result in improper alignment */
- hdrp = (struct apic_mp_cnf_hdr *)mpct;
- /*LINTED: pointer cast may result in improper alignment */
- apicadr = (uint32_t *)psm_map_phys((uint32_t)hdrp->mpcnf_local_apic,
- APIC_LOCAL_MEMLEN, PROT_READ | PROT_WRITE);
- if (!apicadr)
- goto apic_fail1;
-
- /* Parse all information in the tables */
- bypass_cpu_and_ioapics_in_mptables = (retval == PSM_SUCCESS);
- if (apic_parse_mpct(mpct, bypass_cpu_and_ioapics_in_mptables) ==
- PSM_SUCCESS)
- return (PSM_SUCCESS);
-
- for (i = 0; i < apic_io_max; i++)
- psm_unmap_phys((caddr_t)apicioadr[i], APIC_IO_MEMLEN);
- if (apic_cpus)
- kmem_free(apic_cpus, sizeof (*apic_cpus) * apic_nproc);
- if (apicadr)
- psm_unmap_phys((caddr_t)apicadr, APIC_LOCAL_MEMLEN);
-apic_fail1:
- psm_unmap_phys(mpct, mpct_size);
- return (retval);
-}
-
-static void
-apic_set_pwroff_method_from_mpcnfhdr(struct apic_mp_cnf_hdr *hdrp)
-{
- int i;
-
- for (i = 0; i < (sizeof (apic_mps_ids) / sizeof (apic_mps_ids[0]));
- i++) {
- if ((strncmp(hdrp->mpcnf_oem_str, apic_mps_ids[i].oem_id,
- strlen(apic_mps_ids[i].oem_id)) == 0) &&
- (strncmp(hdrp->mpcnf_prod_str, apic_mps_ids[i].prod_id,
- strlen(apic_mps_ids[i].prod_id)) == 0)) {
-
- apic_poweroff_method = apic_mps_ids[i].poweroff_method;
- break;
- }
- }
-
- if (apic_debug_mps_id != 0) {
- cmn_err(CE_CONT, "pcplusmp: MPS OEM ID = '%c%c%c%c%c%c%c%c'"
- "Product ID = '%c%c%c%c%c%c%c%c%c%c%c%c'\n",
- hdrp->mpcnf_oem_str[0],
- hdrp->mpcnf_oem_str[1],
- hdrp->mpcnf_oem_str[2],
- hdrp->mpcnf_oem_str[3],
- hdrp->mpcnf_oem_str[4],
- hdrp->mpcnf_oem_str[5],
- hdrp->mpcnf_oem_str[6],
- hdrp->mpcnf_oem_str[7],
- hdrp->mpcnf_prod_str[0],
- hdrp->mpcnf_prod_str[1],
- hdrp->mpcnf_prod_str[2],
- hdrp->mpcnf_prod_str[3],
- hdrp->mpcnf_prod_str[4],
- hdrp->mpcnf_prod_str[5],
- hdrp->mpcnf_prod_str[6],
- hdrp->mpcnf_prod_str[7],
- hdrp->mpcnf_prod_str[8],
- hdrp->mpcnf_prod_str[9],
- hdrp->mpcnf_prod_str[10],
- hdrp->mpcnf_prod_str[11]);
- }
-}
-
-static int
-acpi_probe(void)
-{
- int i, id, intmax, ver, index, rv;
- int acpi_verboseflags = 0;
- int madt_seen, madt_size;
- APIC_HEADER *ap;
- MADT_PROCESSOR_APIC *mpa;
- MADT_IO_APIC *mia;
- MADT_IO_SAPIC *misa;
- MADT_INTERRUPT_OVERRIDE *mio;
- MADT_NMI_SOURCE *mns;
- MADT_INTERRUPT_SOURCE *mis;
- MADT_LOCAL_APIC_NMI *mlan;
- MADT_ADDRESS_OVERRIDE *mao;
- ACPI_OBJECT_LIST arglist;
- ACPI_OBJECT arg;
- int sci;
- iflag_t sci_flags;
- volatile int32_t *ioapic;
- char local_ids[NCPU];
- char proc_ids[NCPU];
- uchar_t hid;
-
- if (!apic_use_acpi)
- return (PSM_FAILURE);
-
- if (AcpiGetFirmwareTable(APIC_SIG, 1, ACPI_LOGICAL_ADDRESSING,
- (ACPI_TABLE_HEADER **) &acpi_mapic_dtp) != AE_OK)
- return (PSM_FAILURE);
-
- apicadr = (uint32_t *)psm_map_phys(
- (uint32_t)acpi_mapic_dtp->LocalApicAddress,
- APIC_LOCAL_MEMLEN, PROT_READ | PROT_WRITE);
- if (!apicadr)
- return (PSM_FAILURE);
-
- id = apicadr[APIC_LID_REG];
- local_ids[0] = (uchar_t)(((uint_t)id) >> 24);
- apic_nproc = index = 1;
- CPUSET_ONLY(apic_cpumask, 0);
- apic_io_max = 0;
-
- ap = (APIC_HEADER *) (acpi_mapic_dtp + 1);
- madt_size = acpi_mapic_dtp->Length;
- madt_seen = sizeof (*acpi_mapic_dtp);
-
- while (madt_seen < madt_size) {
- switch (ap->Type) {
- case APIC_PROCESSOR:
- mpa = (MADT_PROCESSOR_APIC *) ap;
- if (mpa->ProcessorEnabled) {
- if (mpa->LocalApicId == local_ids[0])
- proc_ids[0] = mpa->ProcessorId;
- else if (apic_nproc < NCPU) {
- local_ids[index] = mpa->LocalApicId;
- proc_ids[index] = mpa->ProcessorId;
- CPUSET_ADD(apic_cpumask, index);
- index++;
- apic_nproc++;
- } else
- cmn_err(CE_WARN, "pcplusmp: exceeded "
- "maximum no. of CPUs (= %d)", NCPU);
- }
- break;
-
- case APIC_IO:
- mia = (MADT_IO_APIC *) ap;
- if (apic_io_max < MAX_IO_APIC) {
- apic_io_id[apic_io_max] = mia->IoApicId;
- apic_io_vectbase[apic_io_max] =
- mia->Interrupt;
- ioapic = apicioadr[apic_io_max] =
- (int32_t *)psm_map_phys(
- (uint32_t)mia->Address,
- APIC_IO_MEMLEN, PROT_READ | PROT_WRITE);
- if (!ioapic)
- goto cleanup;
- apic_io_max++;
- }
- break;
-
- case APIC_XRUPT_OVERRIDE:
- mio = (MADT_INTERRUPT_OVERRIDE *) ap;
- if (acpi_isop == NULL)
- acpi_isop = mio;
- acpi_iso_cnt++;
- break;
-
- case APIC_NMI:
- /* UNIMPLEMENTED */
- mns = (MADT_NMI_SOURCE *) ap;
- if (acpi_nmi_sp == NULL)
- acpi_nmi_sp = mns;
- acpi_nmi_scnt++;
-
- cmn_err(CE_NOTE, "!apic: nmi source: %d %d %d\n",
- mns->Interrupt, mns->Polarity,
- mns->TriggerMode);
- break;
-
- case APIC_LOCAL_NMI:
- /* UNIMPLEMENTED */
- mlan = (MADT_LOCAL_APIC_NMI *) ap;
- if (acpi_nmi_cp == NULL)
- acpi_nmi_cp = mlan;
- acpi_nmi_ccnt++;
-
- cmn_err(CE_NOTE, "!apic: local nmi: %d %d %d %d\n",
- mlan->ProcessorId, mlan->Polarity,
- mlan->TriggerMode, mlan->Lint);
- break;
-
- case APIC_ADDRESS_OVERRIDE:
- /* UNIMPLEMENTED */
- mao = (MADT_ADDRESS_OVERRIDE *) ap;
- cmn_err(CE_NOTE, "!apic: address override: %lx\n",
- (long)mao->Address);
- break;
-
- case APIC_IO_SAPIC:
- /* UNIMPLEMENTED */
- misa = (MADT_IO_SAPIC *) ap;
-
- cmn_err(CE_NOTE, "!apic: io sapic: %d %d %lx\n",
- misa->IoSapicId, misa->InterruptBase,
- (long)misa->Address);
- break;
-
- case APIC_XRUPT_SOURCE:
- /* UNIMPLEMENTED */
- mis = (MADT_INTERRUPT_SOURCE *) ap;
-
- cmn_err(CE_NOTE,
- "!apic: irq source: %d %d %d %d %d %d %d\n",
- mis->ProcessorId, mis->ProcessorEid,
- mis->Interrupt, mis->Polarity,
- mis->TriggerMode, mis->InterruptType,
- mis->IoSapicVector);
- break;
- case APIC_RESERVED:
- default:
- break; /* ignore unknown items as per ACPI spec */
- }
-
- /* advance to next entry */
- madt_seen += ap->Length;
- ap = (APIC_HEADER *)(((char *)ap) + ap->Length);
- }
-
- if ((apic_cpus = kmem_zalloc(sizeof (*apic_cpus) * apic_nproc,
- KM_NOSLEEP)) == NULL)
- goto cleanup;
-
- /*
- * ACPI doesn't provide the local apic ver, get it directly from the
- * local apic
- */
- ver = apicadr[APIC_VERS_REG];
- for (i = 0; i < apic_nproc; i++) {
- apic_cpus[i].aci_local_id = local_ids[i];
- apic_cpus[i].aci_local_ver = (uchar_t)(ver & 0xFF);
- }
- for (i = 0; i < apic_io_max; i++) {
- ioapic = apicioadr[i];
-
- /*
- * need to check Sitka on the following acpi problem
- * On the Sitka, the ioapic's apic_id field isn't reporting
- * the actual io apic id. We have reported this problem
- * to Intel. Until they fix the problem, we will get the
- * actual id directly from the ioapic.
- */
- ioapic[APIC_IO_REG] = APIC_ID_CMD;
- id = ioapic[APIC_IO_DATA];
- hid = (uchar_t)(((uint_t)id) >> 24);
-
- if (hid != apic_io_id[i]) {
- if (apic_io_id[i] == 0)
- apic_io_id[i] = hid;
- else { /* set ioapic id to whatever reported by ACPI */
- id = ((int32_t)apic_io_id[i]) << 24;
- ioapic[APIC_IO_REG] = APIC_ID_CMD;
- ioapic[APIC_IO_DATA] = id;
- }
- }
- ioapic[APIC_IO_REG] = APIC_VERS_CMD;
- ver = ioapic[APIC_IO_DATA];
- apic_io_ver[i] = (uchar_t)(ver & 0xff);
- intmax = (ver >> 16) & 0xff;
- apic_io_vectend[i] = apic_io_vectbase[i] + intmax;
- if (apic_first_avail_irq <= apic_io_vectend[i])
- apic_first_avail_irq = apic_io_vectend[i] + 1;
- }
-
-
- /*
- * Process SCI configuration here
- * An error may be returned here if
- * acpi-user-options specifies legacy mode
- * (no SCI, no ACPI mode)
- */
- if (acpica_get_sci(&sci, &sci_flags) != AE_OK)
- sci = -1;
-
- /*
- * Now call acpi_init() to generate namespaces
- * If this fails, we don't attempt to use ACPI
- * even if we were able to get a MADT above
- */
- if (acpica_init() != AE_OK)
- goto cleanup;
-
- /*
- * Squirrel away the SCI and flags for later on
- * in apic_picinit() when we're ready
- */
- apic_sci_vect = sci;
- apic_sci_flags = sci_flags;
-
- if (apic_verbose & APIC_VERBOSE_IRQ_FLAG)
- acpi_verboseflags |= PSM_VERBOSE_IRQ_FLAG;
-
- if (apic_verbose & APIC_VERBOSE_POWEROFF_FLAG)
- acpi_verboseflags |= PSM_VERBOSE_POWEROFF_FLAG;
-
- if (apic_verbose & APIC_VERBOSE_POWEROFF_PAUSE_FLAG)
- acpi_verboseflags |= PSM_VERBOSE_POWEROFF_PAUSE_FLAG;
-
- if (acpi_psm_init(apic_psm_info.p_mach_idstring, acpi_verboseflags) ==
- ACPI_PSM_FAILURE)
- goto cleanup;
-
- /* Enable ACPI APIC interrupt routing */
- arglist.Count = 1;
- arglist.Pointer = &arg;
- arg.Type = ACPI_TYPE_INTEGER;
- arg.Integer.Value = ACPI_APIC_MODE; /* 1 */
- rv = AcpiEvaluateObject(NULL, "\\_PIC", &arglist, NULL);
- if (rv == AE_OK) {
- build_reserved_irqlist((uchar_t *)apic_reserved_irqlist);
- apic_enable_acpi = 1;
- if (apic_use_acpi_madt_only) {
- cmn_err(CE_CONT,
- "?Using ACPI for CPU/IOAPIC information ONLY\n");
- }
- return (PSM_SUCCESS);
- }
- /* if setting APIC mode failed above, we fall through to cleanup */
-
-cleanup:
- if (apicadr != NULL) {
- psm_unmap_phys((caddr_t)apicadr, APIC_LOCAL_MEMLEN);
- apicadr = NULL;
- }
- apic_nproc = 0;
- for (i = 0; i < apic_io_max; i++) {
- psm_unmap_phys((caddr_t)apicioadr[i], APIC_IO_MEMLEN);
- apicioadr[i] = NULL;
- }
- apic_io_max = 0;
- acpi_isop = NULL;
- acpi_iso_cnt = 0;
- acpi_nmi_sp = NULL;
- acpi_nmi_scnt = 0;
- acpi_nmi_cp = NULL;
- acpi_nmi_ccnt = 0;
- return (PSM_FAILURE);
+ return (apic_probe_common(apic_psm_info.p_mach_idstring));
}
-/*
- * Handle default configuration. Fill in reqd global variables & tables
- * Fill all details as MP table does not give any more info
- */
-static int
-apic_handle_defconf()
-{
- uint_t lid;
-
- /*LINTED: pointer cast may result in improper alignment */
- apicioadr[0] = (int32_t *)psm_map_phys(APIC_IO_ADDR,
- APIC_IO_MEMLEN, PROT_READ | PROT_WRITE);
- /*LINTED: pointer cast may result in improper alignment */
- apicadr = (uint32_t *)psm_map_phys(APIC_LOCAL_ADDR,
- APIC_LOCAL_MEMLEN, PROT_READ | PROT_WRITE);
- apic_cpus = (apic_cpus_info_t *)
- kmem_zalloc(sizeof (*apic_cpus) * 2, KM_NOSLEEP);
- if ((!apicadr) || (!apicioadr[0]) || (!apic_cpus))
- goto apic_handle_defconf_fail;
- CPUSET_ONLY(apic_cpumask, 0);
- CPUSET_ADD(apic_cpumask, 1);
- apic_nproc = 2;
- lid = apicadr[APIC_LID_REG];
- apic_cpus[0].aci_local_id = (uchar_t)(lid >> APIC_ID_BIT_OFFSET);
- /*
- * According to the PC+MP spec 1.1, the local ids
- * for the default configuration has to be 0 or 1
- */
- if (apic_cpus[0].aci_local_id == 1)
- apic_cpus[1].aci_local_id = 0;
- else if (apic_cpus[0].aci_local_id == 0)
- apic_cpus[1].aci_local_id = 1;
- else
- goto apic_handle_defconf_fail;
-
- apic_io_id[0] = 2;
- apic_io_max = 1;
- if (apic_defconf >= 5) {
- apic_cpus[0].aci_local_ver = APIC_INTEGRATED_VERS;
- apic_cpus[1].aci_local_ver = APIC_INTEGRATED_VERS;
- apic_io_ver[0] = APIC_INTEGRATED_VERS;
- } else {
- apic_cpus[0].aci_local_ver = 0; /* 82489 DX */
- apic_cpus[1].aci_local_ver = 0;
- apic_io_ver[0] = 0;
- }
- if (apic_defconf == 2 || apic_defconf == 3 || apic_defconf == 6)
- eisa_level_intr_mask = (inb(EISA_LEVEL_CNTL + 1) << 8) |
- inb(EISA_LEVEL_CNTL) | ((uint_t)INT32_MAX + 1);
- return (PSM_SUCCESS);
-
-apic_handle_defconf_fail:
- if (apic_cpus)
- kmem_free(apic_cpus, sizeof (*apic_cpus) * 2);
- if (apicadr)
- psm_unmap_phys((caddr_t)apicadr, APIC_LOCAL_MEMLEN);
- if (apicioadr[0])
- psm_unmap_phys((caddr_t)apicioadr[0], APIC_IO_MEMLEN);
- return (PSM_FAILURE);
-}
-
-/* Parse the entries in MP configuration table and collect info that we need */
-static int
-apic_parse_mpct(caddr_t mpct, int bypass_cpus_and_ioapics)
-{
- struct apic_procent *procp;
- struct apic_bus *busp;
- struct apic_io_entry *ioapicp;
- struct apic_io_intr *intrp;
- volatile int32_t *ioapic;
- uint_t lid;
- int id;
- uchar_t hid;
-
- /*LINTED: pointer cast may result in improper alignment */
- procp = (struct apic_procent *)(mpct + sizeof (struct apic_mp_cnf_hdr));
-
- /* No need to count cpu entries if we won't use them */
- if (!bypass_cpus_and_ioapics) {
-
- /* Find max # of CPUS and allocate structure accordingly */
- apic_nproc = 0;
- CPUSET_ZERO(apic_cpumask);
- while (procp->proc_entry == APIC_CPU_ENTRY) {
- if (procp->proc_cpuflags & CPUFLAGS_EN) {
- if (apic_nproc < NCPU)
- CPUSET_ADD(apic_cpumask, apic_nproc);
- apic_nproc++;
- }
- procp++;
- }
- if (apic_nproc > NCPU)
- cmn_err(CE_WARN, "pcplusmp: exceeded "
- "maximum no. of CPUs (= %d)", NCPU);
- if (!apic_nproc || !(apic_cpus = (apic_cpus_info_t *)
- kmem_zalloc(sizeof (*apic_cpus)*apic_nproc, KM_NOSLEEP)))
- return (PSM_FAILURE);
- }
-
- /*LINTED: pointer cast may result in improper alignment */
- procp = (struct apic_procent *)(mpct + sizeof (struct apic_mp_cnf_hdr));
-
- /*
- * start with index 1 as 0 needs to be filled in with Boot CPU, but
- * if we're bypassing this information, it has already been filled
- * in by acpi_probe(), so don't overwrite it.
- */
- if (!bypass_cpus_and_ioapics)
- apic_nproc = 1;
-
- while (procp->proc_entry == APIC_CPU_ENTRY) {
- /* check whether the cpu exists or not */
- if (!bypass_cpus_and_ioapics &&
- procp->proc_cpuflags & CPUFLAGS_EN) {
- if (procp->proc_cpuflags & CPUFLAGS_BP) { /* Boot CPU */
- lid = apicadr[APIC_LID_REG];
- apic_cpus[0].aci_local_id = procp->proc_apicid;
- if (apic_cpus[0].aci_local_id !=
- (uchar_t)(lid >> APIC_ID_BIT_OFFSET)) {
- return (PSM_FAILURE);
- }
- apic_cpus[0].aci_local_ver =
- procp->proc_version;
- } else {
-
- apic_cpus[apic_nproc].aci_local_id =
- procp->proc_apicid;
- apic_cpus[apic_nproc].aci_local_ver =
- procp->proc_version;
- apic_nproc++;
-
- }
- }
- procp++;
- }
-
- /*
- * Save start of bus entries for later use.
- * Get EISA level cntrl if EISA bus is present.
- * Also get the CPI bus id for single CPI bus case
- */
- apic_busp = busp = (struct apic_bus *)procp;
- while (busp->bus_entry == APIC_BUS_ENTRY) {
- lid = apic_find_bus_type((char *)&busp->bus_str1);
- if (lid == BUS_EISA) {
- eisa_level_intr_mask = (inb(EISA_LEVEL_CNTL + 1) << 8) |
- inb(EISA_LEVEL_CNTL) | ((uint_t)INT32_MAX + 1);
- } else if (lid == BUS_PCI) {
- /*
- * apic_single_pci_busid will be used only if
- * apic_pic_bus_total is equal to 1
- */
- apic_pci_bus_total++;
- apic_single_pci_busid = busp->bus_id;
- }
- busp++;
- }
-
- ioapicp = (struct apic_io_entry *)busp;
-
- if (!bypass_cpus_and_ioapics)
- apic_io_max = 0;
- do {
- if (!bypass_cpus_and_ioapics && apic_io_max < MAX_IO_APIC) {
- if (ioapicp->io_flags & IOAPIC_FLAGS_EN) {
- apic_io_id[apic_io_max] = ioapicp->io_apicid;
- apic_io_ver[apic_io_max] = ioapicp->io_version;
- /*LINTED: pointer cast may result in improper alignment */
- apicioadr[apic_io_max] =
- (int32_t *)psm_map_phys(
- (uint32_t)ioapicp->io_apic_addr,
- APIC_IO_MEMLEN, PROT_READ | PROT_WRITE);
-
- if (!apicioadr[apic_io_max])
- return (PSM_FAILURE);
-
- ioapic = apicioadr[apic_io_max];
- ioapic[APIC_IO_REG] = APIC_ID_CMD;
- id = ioapic[APIC_IO_DATA];
- hid = (uchar_t)(((uint_t)id) >> 24);
-
- if (hid != apic_io_id[apic_io_max]) {
- if (apic_io_id[apic_io_max] == 0)
- apic_io_id[apic_io_max] = hid;
- else {
- /*
- * set ioapic id to whatever
- * reported by MPS
- *
- * may not need to set index
- * again ???
- * take it out and try
- */
-
- id = ((int32_t)
- apic_io_id[apic_io_max]) <<
- 24;
-
- ioapic[APIC_IO_REG] =
- APIC_ID_CMD;
-
- ioapic[APIC_IO_DATA] = id;
-
- }
- }
- apic_io_max++;
- }
- }
- ioapicp++;
- } while (ioapicp->io_entry == APIC_IO_ENTRY);
-
- apic_io_intrp = (struct apic_io_intr *)ioapicp;
-
- intrp = apic_io_intrp;
- while (intrp->intr_entry == APIC_IO_INTR_ENTRY) {
- if ((intrp->intr_irq > APIC_MAX_ISA_IRQ) ||
- (apic_find_bus(intrp->intr_busid) == BUS_PCI)) {
- apic_irq_translate = 1;
- break;
- }
- intrp++;
- }
-
- return (PSM_SUCCESS);
-}
-
-boolean_t
-apic_cpu_in_range(int cpu)
-{
- return ((cpu & ~IRQ_USER_BOUND) < apic_nproc);
-}
-
-static struct apic_mpfps_hdr *
-apic_find_fps_sig(caddr_t cptr, int len)
-{
- int i;
-
- /* Look for the pattern "_MP_" */
- for (i = 0; i < len; i += 16) {
- if ((*(cptr+i) == '_') &&
- (*(cptr+i+1) == 'M') &&
- (*(cptr+i+2) == 'P') &&
- (*(cptr+i+3) == '_'))
- /*LINTED: pointer cast may result in improper alignment */
- return ((struct apic_mpfps_hdr *)(cptr + i));
- }
- return (NULL);
-}
-
-static int
-apic_checksum(caddr_t bptr, int len)
-{
- int i;
- uchar_t cksum;
-
- cksum = 0;
- for (i = 0; i < len; i++)
- cksum += *bptr++;
- return ((int)cksum);
-}
-
-
-/*
- * Initialise vector->ipl and ipl->pri arrays. level_intr and irqtable
- * are also set to NULL. vector->irq is set to a value which cannot map
- * to a real irq to show that it is free.
- */
void
apic_init()
{
- int i;
- int *iptr;
-
+ int i;
int j = 1;
+
apic_ipltopri[0] = APIC_VECTOR_PER_IPL; /* leave 0 for idle */
for (i = 0; i < (APIC_AVAIL_VECTOR / APIC_VECTOR_PER_IPL); i++) {
if ((i < ((APIC_AVAIL_VECTOR / APIC_VECTOR_PER_IPL) - 1)) &&
@@ -1535,33 +391,7 @@ apic_init()
for (; j < MAXIPL + 1; j++)
/* fill up any empty ipltopri slots */
apic_ipltopri[j] = (i << APIC_IPL_SHIFT) + APIC_BASE_VECT;
-
- /* cpu 0 is always up */
- apic_cpus[0].aci_status = APIC_CPU_ONLINE | APIC_CPU_INTR_ENABLE;
-
- iptr = (int *)&apic_irq_table[0];
- for (i = 0; i <= APIC_MAX_VECTOR; i++) {
- apic_level_intr[i] = 0;
- *iptr++ = NULL;
- apic_vector_to_irq[i] = APIC_RESV_IRQ;
-
- /* These *must* be initted to B_TRUE! */
- apic_reprogram_info[i].done = B_TRUE;
- apic_reprogram_info[i].irqp = NULL;
- apic_reprogram_info[i].tries = 0;
- apic_reprogram_info[i].bindcpu = 0;
- }
-
- /*
- * Allocate a dummy irq table entry for the reserved entry.
- * This takes care of the race between removing an irq and
- * clock detecting a CPU in that irq during interrupt load
- * sampling.
- */
- apic_irq_table[APIC_RESV_IRQ] =
- kmem_zalloc(sizeof (apic_irq_t), KM_NOSLEEP);
-
- mutex_init(&airq_mutex, NULL, MUTEX_DEFAULT, NULL);
+ apic_init_common();
#if defined(__amd64)
/*
* Make cpu-specific interrupt info point to cr8pri vector
@@ -1569,7 +399,6 @@ apic_init()
for (i = 0; i <= MAXIPL; i++)
apic_cr8pri[i] = apic_ipltopri[i] >> APIC_IPL_SHIFT;
CPU->cpu_pri_data = apic_cr8pri;
- intpri_use_cr8 = 1;
#endif /* __amd64 */
}
@@ -1750,11 +579,8 @@ apic_disable_local_apic()
static void
apic_picinit(void)
{
- int i, j, iflag;
+ int i, j;
uint_t isr;
- volatile int32_t *ioapic;
- apic_irq_t *irqptr;
- struct intrspec ispec;
/*
* On UniSys Model 6520, the BIOS leaves vector 0x20 isr
@@ -1778,8 +604,6 @@ apic_picinit(void)
apic_flag = 1;
LOCK_INIT_CLEAR(&apic_gethrtime_lock);
LOCK_INIT_CLEAR(&apic_ioapic_lock);
- LOCK_INIT_CLEAR(&apic_revector_lock);
- LOCK_INIT_CLEAR(&apic_defer_reprogram_lock);
LOCK_INIT_CLEAR(&apic_error_lock);
picsetup(); /* initialise the 8259 */
@@ -1799,59 +623,18 @@ apic_picinit(void)
outb(APIC_IMCR_P2, (uchar_t)APIC_IMCR_APIC);
}
- /* mask interrupt vectors */
- for (j = 0; j < apic_io_max; j++) {
- int intin_max;
- ioapic = apicioadr[j];
- ioapic[APIC_IO_REG] = APIC_VERS_CMD;
- /* Bits 23-16 define the maximum redirection entries */
- intin_max = (ioapic[APIC_IO_DATA] >> 16) & 0xff;
- for (i = 0; i < intin_max; i++) {
- ioapic[APIC_IO_REG] = APIC_RDT_CMD + 2 * i;
- ioapic[APIC_IO_DATA] = AV_MASK;
- }
- }
-
- /*
- * Hack alert: deal with ACPI SCI interrupt chicken/egg here
- */
- if (apic_sci_vect > 0) {
- /*
- * acpica has already done add_avintr(); we just
- * to finish the job by mimicing translate_irq()
- *
- * Fake up an intrspec and setup the tables
- */
- ispec.intrspec_vec = apic_sci_vect;
- ispec.intrspec_pri = SCI_IPL;
-
- if (apic_setup_irq_table(NULL, apic_sci_vect, NULL,
- &ispec, &apic_sci_flags, DDI_INTR_TYPE_FIXED) < 0) {
- cmn_err(CE_WARN, "!apic: SCI setup failed");
- return;
- }
- irqptr = apic_irq_table[apic_sci_vect];
-
- iflag = intr_clear();
- lock_set(&apic_ioapic_lock);
-
- /* Program I/O APIC */
- (void) apic_setup_io_intr(irqptr, apic_sci_vect, B_FALSE);
-
- lock_clear(&apic_ioapic_lock);
- intr_restore(iflag);
-
- irqptr->airq_share++;
- }
+ ioapic_init_intr(IOAPIC_MASK);
}
-static void
-apic_cpu_start(processorid_t cpun, caddr_t rm_code)
+/*ARGSUSED1*/
+static int
+apic_cpu_start(processorid_t cpun, caddr_t arg)
{
int loop_count;
uint32_t vector;
- uint_t cpu_id, iflag;
+ uint_t cpu_id;
+ ulong_t iflag;
cpu_id = apic_cpus[cpun].aci_local_id;
@@ -1890,7 +673,6 @@ apic_cpu_start(processorid_t cpun, caddr_t rm_code)
if (apic_cpus[cpun].aci_local_ver >= APIC_INTEGRATED_VERS) {
/* integrated apic */
- rm_code = (caddr_t)(uintptr_t)rm_platter_pa;
vector = (rm_platter_pa >> MMU_PAGESHIFT) &
(APIC_VECTOR_MASK | APIC_IPL_MASK);
@@ -1906,6 +688,7 @@ apic_cpu_start(processorid_t cpun, caddr_t rm_code)
drv_usecwait(200); /* 20 micro sec */
}
intr_restore(iflag);
+ return (0);
}
@@ -1937,7 +720,8 @@ apic_intr_enter(int ipl, int *vectorp)
{
uchar_t vector;
int nipl;
- int irq, iflag;
+ int irq;
+ ulong_t iflag;
apic_cpus_info_t *cpu_infop;
/*
@@ -2029,7 +813,7 @@ apic_intr_enter(int ipl, int *vectorp)
return (nipl);
}
-static void
+void
apic_intr_exit(int prev_ipl, int irq)
{
apic_cpus_info_t *cpu_infop;
@@ -2080,7 +864,7 @@ static void
apic_set_softintr(int ipl)
{
int vector;
- uint_t flag;
+ ulong_t flag;
vector = apic_resv_vector[ipl];
@@ -2102,7 +886,7 @@ static void
apic_send_ipi(int cpun, int ipl)
{
int vector;
- uint_t flag;
+ ulong_t flag;
vector = apic_resv_vector[ipl];
@@ -2196,11 +980,11 @@ gettime_again:
static hrtime_t
apic_gethrtime()
{
- int curr_timeval, countval, elapsed_ticks, oflags;
+ int curr_timeval, countval, elapsed_ticks;
int old_hrtime_stamp, status;
hrtime_t temp;
uchar_t cpun;
-
+ ulong_t oflags;
/*
* In one-shot mode, we do not keep time, so if anyone
@@ -2326,283 +1110,17 @@ apic_nmi_intr(caddr_t arg)
}
}
-/*
- * Add mask bits to disable interrupt vector from happening
- * at or above IPL. In addition, it should remove mask bits
- * to enable interrupt vectors below the given IPL.
- *
- * Both add and delspl are complicated by the fact that different interrupts
- * may share IRQs. This can happen in two ways.
- * 1. The same H/W line is shared by more than 1 device
- * 1a. with interrupts at different IPLs
- * 1b. with interrupts at same IPL
- * 2. We ran out of vectors at a given IPL and started sharing vectors.
- * 1b and 2 should be handled gracefully, except for the fact some ISRs
- * will get called often when no interrupt is pending for the device.
- * For 1a, we just hope that the machine blows up with the person who
- * set it up that way!. In the meantime, we handle it at the higher IPL.
- */
/*ARGSUSED*/
static int
apic_addspl(int irqno, int ipl, int min_ipl, int max_ipl)
{
- uchar_t vector;
- int iflag;
- apic_irq_t *irqptr, *irqheadptr;
- int irqindex;
-
- ASSERT(max_ipl <= UCHAR_MAX);
- irqindex = IRQINDEX(irqno);
-
- if ((irqindex == -1) || (!apic_irq_table[irqindex]))
- return (PSM_FAILURE);
-
- mutex_enter(&airq_mutex);
- irqptr = irqheadptr = apic_irq_table[irqindex];
-
- DDI_INTR_IMPLDBG((CE_CONT, "apic_addspl: dip=0x%p type=%d irqno=0x%x "
- "vector=0x%x\n", (void *)irqptr->airq_dip,
- irqptr->airq_mps_intr_index, irqno, irqptr->airq_vector));
-
- while (irqptr) {
- if (VIRTIRQ(irqindex, irqptr->airq_share_id) == irqno)
- break;
- irqptr = irqptr->airq_next;
- }
- irqptr->airq_share++;
-
- mutex_exit(&airq_mutex);
-
- /* return if it is not hardware interrupt */
- if (irqptr->airq_mps_intr_index == RESERVE_INDEX)
- return (PSM_SUCCESS);
-
- /* Or if there are more interupts at a higher IPL */
- if (ipl != max_ipl)
- return (PSM_SUCCESS);
-
- /*
- * if apic_picinit() has not been called yet, just return.
- * At the end of apic_picinit(), we will call setup_io_intr().
- */
-
- if (!apic_flag)
- return (PSM_SUCCESS);
-
- /*
- * Upgrade vector if max_ipl is not earlier ipl. If we cannot allocate,
- * return failure. Not very elegant, but then we hope the
- * machine will blow up with ...
- */
- if (irqptr->airq_ipl != max_ipl) {
- vector = apic_allocate_vector(max_ipl, irqindex, 1);
- if (vector == 0) {
- irqptr->airq_share--;
- return (PSM_FAILURE);
- }
- irqptr = irqheadptr;
- apic_mark_vector(irqptr->airq_vector, vector);
- while (irqptr) {
- irqptr->airq_vector = vector;
- irqptr->airq_ipl = (uchar_t)max_ipl;
- /*
- * reprogram irq being added and every one else
- * who is not in the UNINIT state
- */
- if ((VIRTIRQ(irqindex, irqptr->airq_share_id) ==
- irqno) || (irqptr->airq_temp_cpu != IRQ_UNINIT)) {
- apic_record_rdt_entry(irqptr, irqindex);
-
- iflag = intr_clear();
- lock_set(&apic_ioapic_lock);
-
- (void) apic_setup_io_intr(irqptr, irqindex,
- B_FALSE);
-
- lock_clear(&apic_ioapic_lock);
- intr_restore(iflag);
- }
- irqptr = irqptr->airq_next;
- }
- return (PSM_SUCCESS);
- }
-
- ASSERT(irqptr);
-
- iflag = intr_clear();
- lock_set(&apic_ioapic_lock);
-
- (void) apic_setup_io_intr(irqptr, irqindex, B_FALSE);
-
- lock_clear(&apic_ioapic_lock);
- intr_restore(iflag);
-
- return (PSM_SUCCESS);
+ return (apic_addspl_common(irqno, ipl, min_ipl, max_ipl));
}
-/*
- * Recompute mask bits for the given interrupt vector.
- * If there is no interrupt servicing routine for this
- * vector, this function should disable interrupt vector
- * from happening at all IPLs. If there are still
- * handlers using the given vector, this function should
- * disable the given vector from happening below the lowest
- * IPL of the remaining hadlers.
- */
-/*ARGSUSED*/
static int
apic_delspl(int irqno, int ipl, int min_ipl, int max_ipl)
{
- uchar_t vector, bind_cpu;
- int iflag, intin, irqindex;
- volatile int32_t *ioapic;
- apic_irq_t *irqptr, *irqheadptr;
-
- mutex_enter(&airq_mutex);
- irqindex = IRQINDEX(irqno);
- irqptr = irqheadptr = apic_irq_table[irqindex];
-
- DDI_INTR_IMPLDBG((CE_CONT, "apic_delspl: dip=0x%p type=%d irqno=0x%x "
- "vector=0x%x\n", (void *)irqptr->airq_dip,
- irqptr->airq_mps_intr_index, irqno, irqptr->airq_vector));
-
- while (irqptr) {
- if (VIRTIRQ(irqindex, irqptr->airq_share_id) == irqno)
- break;
- irqptr = irqptr->airq_next;
- }
- ASSERT(irqptr);
-
- irqptr->airq_share--;
-
- mutex_exit(&airq_mutex);
-
- if (ipl < max_ipl)
- return (PSM_SUCCESS);
-
- /* return if it is not hardware interrupt */
- if (irqptr->airq_mps_intr_index == RESERVE_INDEX)
- return (PSM_SUCCESS);
-
- if (!apic_flag) {
- /*
- * Clear irq_struct. If two devices shared an intpt
- * line & 1 unloaded before picinit, we are hosed. But, then
- * we hope the machine will ...
- */
- irqptr->airq_mps_intr_index = FREE_INDEX;
- irqptr->airq_temp_cpu = IRQ_UNINIT;
- apic_free_vector(irqptr->airq_vector);
- return (PSM_SUCCESS);
- }
- /*
- * Downgrade vector to new max_ipl if needed.If we cannot allocate,
- * use old IPL. Not very elegant, but then we hope ...
- */
- if ((irqptr->airq_ipl != max_ipl) && (max_ipl != PSM_INVALID_IPL)) {
- apic_irq_t *irqp;
- if (vector = apic_allocate_vector(max_ipl, irqno, 1)) {
- apic_mark_vector(irqheadptr->airq_vector, vector);
- irqp = irqheadptr;
- while (irqp) {
- irqp->airq_vector = vector;
- irqp->airq_ipl = (uchar_t)max_ipl;
- if (irqp->airq_temp_cpu != IRQ_UNINIT) {
- apic_record_rdt_entry(irqp, irqindex);
-
- iflag = intr_clear();
- lock_set(&apic_ioapic_lock);
-
- (void) apic_setup_io_intr(irqp,
- irqindex, B_FALSE);
-
- lock_clear(&apic_ioapic_lock);
- intr_restore(iflag);
- }
- irqp = irqp->airq_next;
- }
- }
- }
-
- if (irqptr->airq_share)
- return (PSM_SUCCESS);
-
- iflag = intr_clear();
- lock_set(&apic_ioapic_lock);
-
- /* Disable the MSI/X vector */
- if (APIC_IS_MSI_OR_MSIX_INDEX(irqptr->airq_mps_intr_index)) {
- int type = (irqptr->airq_mps_intr_index == MSI_INDEX) ?
- DDI_INTR_TYPE_MSI : DDI_INTR_TYPE_MSIX;
-
- /*
- * Make sure we only disable on the last
- * of the multi-MSI support
- */
- if (i_ddi_intr_get_current_nintrs(irqptr->airq_dip) == 1) {
- (void) apic_pci_msi_unconfigure(irqptr->airq_dip,
- type, irqptr->airq_ioapicindex);
- (void) apic_pci_msi_disable_mode(irqptr->airq_dip,
- type, irqptr->airq_ioapicindex);
- }
- } else {
- ioapic = apicioadr[irqptr->airq_ioapicindex];
- intin = irqptr->airq_intin_no;
- ioapic[APIC_IO_REG] = APIC_RDT_CMD + 2 * intin;
- ioapic[APIC_IO_DATA] = AV_MASK;
- }
-
- if (max_ipl == PSM_INVALID_IPL) {
- ASSERT(irqheadptr == irqptr);
- bind_cpu = irqptr->airq_temp_cpu;
- if (((uchar_t)bind_cpu != IRQ_UNBOUND) &&
- ((uchar_t)bind_cpu != IRQ_UNINIT)) {
- ASSERT((bind_cpu & ~IRQ_USER_BOUND) < apic_nproc);
- if (bind_cpu & IRQ_USER_BOUND) {
- /* If hardbound, temp_cpu == cpu */
- bind_cpu &= ~IRQ_USER_BOUND;
- apic_cpus[bind_cpu].aci_bound--;
- } else
- apic_cpus[bind_cpu].aci_temp_bound--;
- }
- irqptr->airq_temp_cpu = IRQ_UNINIT;
- irqptr->airq_mps_intr_index = FREE_INDEX;
- lock_clear(&apic_ioapic_lock);
- intr_restore(iflag);
- apic_free_vector(irqptr->airq_vector);
- return (PSM_SUCCESS);
- }
- lock_clear(&apic_ioapic_lock);
- intr_restore(iflag);
-
- mutex_enter(&airq_mutex);
- if ((irqptr == apic_irq_table[irqindex])) {
- apic_irq_t *oldirqptr;
- /* Move valid irq entry to the head */
- irqheadptr = oldirqptr = irqptr;
- irqptr = irqptr->airq_next;
- ASSERT(irqptr);
- while (irqptr) {
- if (irqptr->airq_mps_intr_index != FREE_INDEX)
- break;
- oldirqptr = irqptr;
- irqptr = irqptr->airq_next;
- }
- /* remove all invalid ones from the beginning */
- apic_irq_table[irqindex] = irqptr;
- /*
- * and link them back after the head. The invalid ones
- * begin with irqheadptr and end at oldirqptr
- */
- oldirqptr->airq_next = irqptr->airq_next;
- irqptr->airq_next = irqheadptr;
- }
- mutex_exit(&airq_mutex);
-
- irqptr->airq_temp_cpu = IRQ_UNINIT;
- irqptr->airq_mps_intr_index = FREE_INDEX;
-
- return (PSM_SUCCESS);
+ return (apic_delspl_common(irqno, ipl, min_ipl, max_ipl));
}
/*
@@ -2627,22 +1145,23 @@ apic_softlvl_to_irq(int ipl)
static int
apic_post_cpu_start()
{
- int i, cpun, iflag;
+ int i, cpun;
+ ulong_t iflag;
apic_irq_t *irq_ptr;
+ splx(ipltospl(LOCK_LEVEL));
apic_init_intr();
/*
* since some systems don't enable the internal cache on the non-boot
* cpus, so we have to enable them here
*/
- setcr0(getcr0() & ~(0x60000000));
+ setcr0(getcr0() & ~(CR0_CD | CR0_NW));
while (get_apic_cmd1() & AV_PENDING)
apic_ret();
cpun = psm_get_cpu_id();
-
apic_cpus[cpun].aci_status = APIC_CPU_ONLINE | APIC_CPU_INTR_ENABLE;
for (i = apic_min_device_irq; i <= apic_max_device_irq; i++) {
@@ -2665,7 +1184,6 @@ apic_post_cpu_start()
}
}
-
apicadr[APIC_DIVIDE_REG] = apic_divide_reg_init;
return (PSM_SUCCESS);
}
@@ -2740,7 +1258,7 @@ apic_calibrate(volatile uint32_t *addr, uint16_t *pit_ticks_adj)
uint8_t pit_tick_lo;
uint16_t pit_tick, target_pit_tick;
uint32_t start_apic_tick, end_apic_tick;
- int iflag;
+ ulong_t iflag;
addr += APIC_CURR_COUNT;
@@ -2813,7 +1331,7 @@ apic_clkinit(int hertz)
/* first time calibrate on CPU0 only */
apicadr[APIC_DIVIDE_REG] = apic_divide_reg_init;
- apicadr[APIC_INIT_COUNT] = APIC_MAXVAL; /* start counting */
+ apicadr[APIC_INIT_COUNT] = APIC_MAXVAL;
apic_ticks = apic_calibrate(apicadr, &pit_ticks_adj);
/* total number of PIT ticks corresponding to apic_ticks */
@@ -2826,7 +1344,7 @@ apic_clkinit(int hertz)
* apic_ticks / (pitticks / PIT_HZ) = apic_ticks_per_s
* (apic_ticks * PIT_HZ) / pitticks = apic_ticks_per_s
* apic_ticks_per_ns = (apic_ticks * PIT_HZ) / (pitticks * 10^9)
- * apic_ticks_per_SFns =
+ * pic_ticks_per_SFns =
* (SF * apic_ticks * PIT_HZ) / (pitticks * 10^9)
*/
apic_ticks_per_SFnsecs =
@@ -2890,10 +1408,10 @@ apic_preshutdown(int cmd, int fcn)
static void
apic_shutdown(int cmd, int fcn)
{
- int iflag, restarts, attempts;
- int i, j;
- volatile int32_t *ioapic;
+ int restarts, attempts;
+ int i;
uchar_t byte;
+ ulong_t iflag;
/* Send NMI to all CPUs except self to do per processor shutdown */
iflag = intr_clear();
@@ -2907,18 +1425,8 @@ apic_shutdown(int cmd, int fcn)
outb(CMOS_ADDR, SSB);
outb(CMOS_DATA, 0);
}
- /* Disable the I/O APIC redirection entries */
- for (j = 0; j < apic_io_max; j++) {
- int intin_max;
- ioapic = apicioadr[j];
- ioapic[APIC_IO_REG] = APIC_VERS_CMD;
- /* Bits 23-16 define the maximum redirection entries */
- intin_max = (ioapic[APIC_IO_DATA] >> 16) & 0xff;
- for (i = 0; i < intin_max; i++) {
- ioapic[APIC_IO_REG] = APIC_RDT_CMD + 2 * i;
- ioapic[APIC_IO_DATA] = AV_MASK;
- }
- }
+
+ ioapic_disable_redirection();
/* disable apic mode if imcr present */
if (apic_imcrp) {
@@ -3077,8 +1585,9 @@ restart_sitka_bmc:
static int
apic_disable_intr(processorid_t cpun)
{
- int bind_cpu = 0, i, hardbound = 0, iflag;
+ int bind_cpu = 0, i, hardbound = 0;
apic_irq_t *irq_ptr;
+ ulong_t iflag;
iflag = intr_clear();
lock_set(&apic_ioapic_lock);
@@ -3120,8 +1629,7 @@ apic_disable_intr(processorid_t cpun)
if (irq_ptr->airq_temp_cpu == cpun) {
do {
- apic_next_bind_cpu += 2;
- bind_cpu = apic_next_bind_cpu / 2;
+ bind_cpu = apic_next_bind_cpu++;
if (bind_cpu >= apic_nproc) {
apic_next_bind_cpu = 1;
bind_cpu = 0;
@@ -3147,8 +1655,9 @@ apic_disable_intr(processorid_t cpun)
static void
apic_enable_intr(processorid_t cpun)
{
- int i, iflag;
+ int i;
apic_irq_t *irq_ptr;
+ ulong_t iflag;
iflag = intr_clear();
lock_set(&apic_ioapic_lock);
@@ -3169,1912 +1678,6 @@ apic_enable_intr(processorid_t cpun)
intr_restore(iflag);
}
-/*
- * apic_introp_xlate() replaces apic_translate_irq() and is
- * called only from apic_intr_ops(). With the new ADII framework,
- * the priority can no longer be retrieved through i_ddi_get_intrspec().
- * It has to be passed in from the caller.
- */
-int
-apic_introp_xlate(dev_info_t *dip, struct intrspec *ispec, int type)
-{
- char dev_type[16];
- int dev_len, pci_irq, newirq, bustype, devid, busid, i;
- int irqno = ispec->intrspec_vec;
- ddi_acc_handle_t cfg_handle;
- uchar_t ipin;
- struct apic_io_intr *intrp;
- iflag_t intr_flag;
- APIC_HEADER *hp;
- MADT_INTERRUPT_OVERRIDE *isop;
- apic_irq_t *airqp;
- int parent_is_pci_or_pciex = 0;
- int child_is_pciex = 0;
-
- DDI_INTR_IMPLDBG((CE_CONT, "apic_introp_xlate: dip=0x%p name=%s "
- "type=%d irqno=0x%x\n", (void *)dip, ddi_get_name(dip), type,
- irqno));
-
- dev_len = sizeof (dev_type);
- if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ddi_get_parent(dip),
- DDI_PROP_DONTPASS, "device_type", (caddr_t)dev_type,
- &dev_len) == DDI_PROP_SUCCESS) {
- if ((strcmp(dev_type, "pci") == 0) ||
- (strcmp(dev_type, "pciex") == 0))
- parent_is_pci_or_pciex = 1;
- }
-
- if (parent_is_pci_or_pciex && ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL) !=
- PCI_CAP_NEXT_PTR_NULL) {
- child_is_pciex = 1;
- }
-
- if (DDI_INTR_IS_MSI_OR_MSIX(type)) {
- if ((airqp = apic_find_irq(dip, ispec, type)) != NULL) {
- airqp->airq_iflag.bustype =
- child_is_pciex ? BUS_PCIE : BUS_PCI;
- return (apic_vector_to_irq[airqp->airq_vector]);
- }
- return (apic_setup_irq_table(dip, irqno, NULL, ispec,
- NULL, type));
- }
-
- bustype = 0;
-
- /* check if we have already translated this irq */
- mutex_enter(&airq_mutex);
- newirq = apic_min_device_irq;
- for (; newirq <= apic_max_device_irq; newirq++) {
- airqp = apic_irq_table[newirq];
- while (airqp) {
- if ((airqp->airq_dip == dip) &&
- (airqp->airq_origirq == irqno) &&
- (airqp->airq_mps_intr_index != FREE_INDEX)) {
-
- mutex_exit(&airq_mutex);
- return (VIRTIRQ(newirq, airqp->airq_share_id));
- }
- airqp = airqp->airq_next;
- }
- }
- mutex_exit(&airq_mutex);
-
- if (apic_defconf)
- goto defconf;
-
- if ((dip == NULL) || (!apic_irq_translate && !apic_enable_acpi))
- goto nonpci;
-
- if (parent_is_pci_or_pciex) {
- /* pci device */
- if (acpica_get_bdf(dip, &busid, &devid, NULL) != 0)
- goto nonpci;
- if (busid == 0 && apic_pci_bus_total == 1)
- busid = (int)apic_single_pci_busid;
-
- if (pci_config_setup(dip, &cfg_handle) != DDI_SUCCESS)
- goto nonpci;
- ipin = pci_config_get8(cfg_handle, PCI_CONF_IPIN) - PCI_INTA;
- pci_config_teardown(&cfg_handle);
- if (apic_enable_acpi && !apic_use_acpi_madt_only) {
- if (apic_acpi_translate_pci_irq(dip, busid, devid,
- ipin, &pci_irq, &intr_flag) != ACPI_PSM_SUCCESS)
- goto nonpci;
-
- intr_flag.bustype = child_is_pciex ? BUS_PCIE : BUS_PCI;
- if ((newirq = apic_setup_irq_table(dip, pci_irq, NULL,
- ispec, &intr_flag, type)) == -1)
- goto nonpci;
- return (newirq);
- } else {
- pci_irq = ((devid & 0x1f) << 2) | (ipin & 0x3);
- if ((intrp = apic_find_io_intr_w_busid(pci_irq, busid))
- == NULL) {
- if ((pci_irq = apic_handle_pci_pci_bridge(dip,
- devid, ipin, &intrp)) == -1)
- goto nonpci;
- }
- if ((newirq = apic_setup_irq_table(dip, pci_irq, intrp,
- ispec, NULL, type)) == -1)
- goto nonpci;
- return (newirq);
- }
- } else if (strcmp(dev_type, "isa") == 0)
- bustype = BUS_ISA;
- else if (strcmp(dev_type, "eisa") == 0)
- bustype = BUS_EISA;
-
-nonpci:
- if (apic_enable_acpi && !apic_use_acpi_madt_only) {
- /* search iso entries first */
- if (acpi_iso_cnt != 0) {
- hp = (APIC_HEADER *)acpi_isop;
- i = 0;
- while (i < acpi_iso_cnt) {
- if (hp->Type == APIC_XRUPT_OVERRIDE) {
- isop = (MADT_INTERRUPT_OVERRIDE *)hp;
- if (isop->Bus == 0 &&
- isop->Source == irqno) {
- newirq = isop->Interrupt;
- intr_flag.intr_po =
- isop->Polarity;
- intr_flag.intr_el =
- isop->TriggerMode;
- intr_flag.bustype = BUS_ISA;
-
- return (apic_setup_irq_table(
- dip, newirq, NULL, ispec,
- &intr_flag, type));
-
- }
- i++;
- }
- hp = (APIC_HEADER *)(((char *)hp) +
- hp->Length);
- }
- }
- intr_flag.intr_po = INTR_PO_ACTIVE_HIGH;
- intr_flag.intr_el = INTR_EL_EDGE;
- intr_flag.bustype = BUS_ISA;
- return (apic_setup_irq_table(dip, irqno, NULL, ispec,
- &intr_flag, type));
- } else {
- if (bustype == 0)
- bustype = eisa_level_intr_mask ? BUS_EISA : BUS_ISA;
- for (i = 0; i < 2; i++) {
- if (((busid = apic_find_bus_id(bustype)) != -1) &&
- ((intrp = apic_find_io_intr_w_busid(irqno, busid))
- != NULL)) {
- if ((newirq = apic_setup_irq_table(dip, irqno,
- intrp, ispec, NULL, type)) != -1) {
- return (newirq);
- }
- goto defconf;
- }
- bustype = (bustype == BUS_EISA) ? BUS_ISA : BUS_EISA;
- }
- }
-
-/* MPS default configuration */
-defconf:
- newirq = apic_setup_irq_table(dip, irqno, NULL, ispec, NULL, type);
- if (newirq == -1)
- return (newirq);
- ASSERT(IRQINDEX(newirq) == irqno);
- ASSERT(apic_irq_table[irqno]);
- return (newirq);
-}
-
-
-
-
-
-
-/*
- * On machines with PCI-PCI bridges, a device behind a PCI-PCI bridge
- * needs special handling. We may need to chase up the device tree,
- * using the PCI-PCI Bridge specification's "rotating IPIN assumptions",
- * to find the IPIN at the root bus that relates to the IPIN on the
- * subsidiary bus (for ACPI or MP). We may, however, have an entry
- * in the MP table or the ACPI namespace for this device itself.
- * We handle both cases in the search below.
- */
-/* this is the non-acpi version */
-static int
-apic_handle_pci_pci_bridge(dev_info_t *idip, int child_devno, int child_ipin,
- struct apic_io_intr **intrp)
-{
- dev_info_t *dipp, *dip;
- int pci_irq;
- ddi_acc_handle_t cfg_handle;
- int bridge_devno, bridge_bus;
- int ipin;
-
- dip = idip;
-
- /*CONSTCOND*/
- while (1) {
- if ((dipp = ddi_get_parent(dip)) == (dev_info_t *)NULL)
- return (-1);
- if ((pci_config_setup(dipp, &cfg_handle) == DDI_SUCCESS) &&
- (pci_config_get8(cfg_handle, PCI_CONF_BASCLASS) ==
- PCI_CLASS_BRIDGE) && (pci_config_get8(cfg_handle,
- PCI_CONF_SUBCLASS) == PCI_BRIDGE_PCI)) {
- pci_config_teardown(&cfg_handle);
- if (acpica_get_bdf(dipp, &bridge_bus, &bridge_devno,
- NULL) != 0)
- return (-1);
- /*
- * This is the rotating scheme that Compaq is using
- * and documented in the pci to pci spec. Also, if
- * the pci to pci bridge is behind another pci to
- * pci bridge, then it need to keep transversing
- * up until an interrupt entry is found or reach
- * the top of the tree
- */
- ipin = (child_devno + child_ipin) % PCI_INTD;
- if (bridge_bus == 0 && apic_pci_bus_total == 1)
- bridge_bus = (int)apic_single_pci_busid;
- pci_irq = ((bridge_devno & 0x1f) << 2) |
- (ipin & 0x3);
- if ((*intrp = apic_find_io_intr_w_busid(pci_irq,
- bridge_bus)) != NULL) {
- return (pci_irq);
- }
- dip = dipp;
- child_devno = bridge_devno;
- child_ipin = ipin;
- } else
- return (-1);
- }
- /*LINTED: function will not fall off the bottom */
-}
-
-
-
-
-static uchar_t
-acpi_find_ioapic(int irq)
-{
- int i;
-
- for (i = 0; i < apic_io_max; i++) {
- if (irq >= apic_io_vectbase[i] && irq <= apic_io_vectend[i])
- return (i);
- }
- return (0xFF); /* shouldn't happen */
-}
-
-/*
- * See if two irqs are compatible for sharing a vector.
- * Currently we only support sharing of PCI devices.
- */
-static int
-acpi_intr_compatible(iflag_t iflag1, iflag_t iflag2)
-{
- uint_t level1, po1;
- uint_t level2, po2;
-
- /* Assume active high by default */
- po1 = 0;
- po2 = 0;
-
- if (iflag1.bustype != iflag2.bustype || iflag1.bustype != BUS_PCI)
- return (0);
-
- if (iflag1.intr_el == INTR_EL_CONFORM)
- level1 = AV_LEVEL;
- else
- level1 = (iflag1.intr_el == INTR_EL_LEVEL) ? AV_LEVEL : 0;
-
- if (level1 && ((iflag1.intr_po == INTR_PO_ACTIVE_LOW) ||
- (iflag1.intr_po == INTR_PO_CONFORM)))
- po1 = AV_ACTIVE_LOW;
-
- if (iflag2.intr_el == INTR_EL_CONFORM)
- level2 = AV_LEVEL;
- else
- level2 = (iflag2.intr_el == INTR_EL_LEVEL) ? AV_LEVEL : 0;
-
- if (level2 && ((iflag2.intr_po == INTR_PO_ACTIVE_LOW) ||
- (iflag2.intr_po == INTR_PO_CONFORM)))
- po2 = AV_ACTIVE_LOW;
-
- if ((level1 == level2) && (po1 == po2))
- return (1);
-
- return (0);
-}
-
-/*
- * Attempt to share vector with someone else
- */
-static int
-apic_share_vector(int irqno, iflag_t *intr_flagp, short intr_index, int ipl,
- uchar_t ioapicindex, uchar_t ipin, apic_irq_t **irqptrp)
-{
-#ifdef DEBUG
- apic_irq_t *tmpirqp = NULL;
-#endif /* DEBUG */
- apic_irq_t *irqptr, dummyirq;
- int newirq, chosen_irq = -1, share = 127;
- int lowest, highest, i;
- uchar_t share_id;
-
- DDI_INTR_IMPLDBG((CE_CONT, "apic_share_vector: irqno=0x%x "
- "intr_index=0x%x ipl=0x%x\n", irqno, intr_index, ipl));
-
- highest = apic_ipltopri[ipl] + APIC_VECTOR_MASK;
- lowest = apic_ipltopri[ipl-1] + APIC_VECTOR_PER_IPL;
-
- if (highest < lowest) /* Both ipl and ipl-1 map to same pri */
- lowest -= APIC_VECTOR_PER_IPL;
- dummyirq.airq_mps_intr_index = intr_index;
- dummyirq.airq_ioapicindex = ioapicindex;
- dummyirq.airq_intin_no = ipin;
- if (intr_flagp)
- dummyirq.airq_iflag = *intr_flagp;
- apic_record_rdt_entry(&dummyirq, irqno);
- for (i = lowest; i <= highest; i++) {
- newirq = apic_vector_to_irq[i];
- if (newirq == APIC_RESV_IRQ)
- continue;
- irqptr = apic_irq_table[newirq];
-
- if ((dummyirq.airq_rdt_entry & 0xFF00) !=
- (irqptr->airq_rdt_entry & 0xFF00))
- /* not compatible */
- continue;
-
- if (irqptr->airq_share < share) {
- share = irqptr->airq_share;
- chosen_irq = newirq;
- }
- }
- if (chosen_irq != -1) {
- /*
- * Assign a share id which is free or which is larger
- * than the largest one.
- */
- share_id = 1;
- mutex_enter(&airq_mutex);
- irqptr = apic_irq_table[chosen_irq];
- while (irqptr) {
- if (irqptr->airq_mps_intr_index == FREE_INDEX) {
- share_id = irqptr->airq_share_id;
- break;
- }
- if (share_id <= irqptr->airq_share_id)
- share_id = irqptr->airq_share_id + 1;
-#ifdef DEBUG
- tmpirqp = irqptr;
-#endif /* DEBUG */
- irqptr = irqptr->airq_next;
- }
- if (!irqptr) {
- irqptr = kmem_zalloc(sizeof (apic_irq_t), KM_SLEEP);
- irqptr->airq_temp_cpu = IRQ_UNINIT;
- irqptr->airq_next =
- apic_irq_table[chosen_irq]->airq_next;
- apic_irq_table[chosen_irq]->airq_next = irqptr;
-#ifdef DEBUG
- tmpirqp = apic_irq_table[chosen_irq];
-#endif /* DEBUG */
- }
- irqptr->airq_mps_intr_index = intr_index;
- irqptr->airq_ioapicindex = ioapicindex;
- irqptr->airq_intin_no = ipin;
- if (intr_flagp)
- irqptr->airq_iflag = *intr_flagp;
- irqptr->airq_vector = apic_irq_table[chosen_irq]->airq_vector;
- irqptr->airq_share_id = share_id;
- apic_record_rdt_entry(irqptr, irqno);
- *irqptrp = irqptr;
-#ifdef DEBUG
- /* shuffle the pointers to test apic_delspl path */
- if (tmpirqp) {
- tmpirqp->airq_next = irqptr->airq_next;
- irqptr->airq_next = apic_irq_table[chosen_irq];
- apic_irq_table[chosen_irq] = irqptr;
- }
-#endif /* DEBUG */
- mutex_exit(&airq_mutex);
- return (VIRTIRQ(chosen_irq, share_id));
- }
- return (-1);
-}
-
-/*
- *
- */
-static int
-apic_setup_irq_table(dev_info_t *dip, int irqno, struct apic_io_intr *intrp,
- struct intrspec *ispec, iflag_t *intr_flagp, int type)
-{
- int origirq = ispec->intrspec_vec;
- uchar_t ipl = ispec->intrspec_pri;
- int newirq, intr_index;
- uchar_t ipin, ioapic, ioapicindex, vector;
- apic_irq_t *irqptr;
- major_t major;
- dev_info_t *sdip;
-
- DDI_INTR_IMPLDBG((CE_CONT, "apic_setup_irq_table: dip=0x%p type=%d "
- "irqno=0x%x origirq=0x%x\n", (void *)dip, type, irqno, origirq));
-
- ASSERT(ispec != NULL);
-
- major = (dip != NULL) ? ddi_name_to_major(ddi_get_name(dip)) : 0;
-
- if (DDI_INTR_IS_MSI_OR_MSIX(type)) {
- /* MSI/X doesn't need to setup ioapic stuffs */
- ioapicindex = 0xff;
- ioapic = 0xff;
- ipin = (uchar_t)0xff;
- intr_index = (type == DDI_INTR_TYPE_MSI) ? MSI_INDEX :
- MSIX_INDEX;
- mutex_enter(&airq_mutex);
- if ((irqno = apic_allocate_irq(apic_first_avail_irq)) == -1) {
- mutex_exit(&airq_mutex);
- /* need an irq for MSI/X to index into autovect[] */
- cmn_err(CE_WARN, "No interrupt irq: %s instance %d",
- ddi_get_name(dip), ddi_get_instance(dip));
- return (-1);
- }
- mutex_exit(&airq_mutex);
-
- } else if (intrp != NULL) {
- intr_index = (int)(intrp - apic_io_intrp);
- ioapic = intrp->intr_destid;
- ipin = intrp->intr_destintin;
- /* Find ioapicindex. If destid was ALL, we will exit with 0. */
- for (ioapicindex = apic_io_max - 1; ioapicindex; ioapicindex--)
- if (apic_io_id[ioapicindex] == ioapic)
- break;
- ASSERT((ioapic == apic_io_id[ioapicindex]) ||
- (ioapic == INTR_ALL_APIC));
-
- /* check whether this intin# has been used by another irqno */
- if ((newirq = apic_find_intin(ioapicindex, ipin)) != -1) {
- return (newirq);
- }
-
- } else if (intr_flagp != NULL) {
- /* ACPI case */
- intr_index = ACPI_INDEX;
- ioapicindex = acpi_find_ioapic(irqno);
- ASSERT(ioapicindex != 0xFF);
- ioapic = apic_io_id[ioapicindex];
- ipin = irqno - apic_io_vectbase[ioapicindex];
- if (apic_irq_table[irqno] &&
- apic_irq_table[irqno]->airq_mps_intr_index == ACPI_INDEX) {
- ASSERT(apic_irq_table[irqno]->airq_intin_no == ipin &&
- apic_irq_table[irqno]->airq_ioapicindex ==
- ioapicindex);
- return (irqno);
- }
-
- } else {
- /* default configuration */
- ioapicindex = 0;
- ioapic = apic_io_id[ioapicindex];
- ipin = (uchar_t)irqno;
- intr_index = DEFAULT_INDEX;
- }
-
- if (ispec == NULL) {
- APIC_VERBOSE_IOAPIC((CE_WARN, "No intrspec for irqno = %x\n",
- irqno));
- } else if ((vector = apic_allocate_vector(ipl, irqno, 0)) == 0) {
- if ((newirq = apic_share_vector(irqno, intr_flagp, intr_index,
- ipl, ioapicindex, ipin, &irqptr)) != -1) {
- irqptr->airq_ipl = ipl;
- irqptr->airq_origirq = (uchar_t)origirq;
- irqptr->airq_dip = dip;
- irqptr->airq_major = major;
- sdip = apic_irq_table[IRQINDEX(newirq)]->airq_dip;
- /* This is OK to do really */
- if (sdip == NULL) {
- cmn_err(CE_WARN, "Sharing vectors: %s"
- " instance %d and SCI",
- ddi_get_name(dip), ddi_get_instance(dip));
- } else {
- cmn_err(CE_WARN, "Sharing vectors: %s"
- " instance %d and %s instance %d",
- ddi_get_name(sdip), ddi_get_instance(sdip),
- ddi_get_name(dip), ddi_get_instance(dip));
- }
- return (newirq);
- }
- /* try high priority allocation now that share has failed */
- if ((vector = apic_allocate_vector(ipl, irqno, 1)) == 0) {
- cmn_err(CE_WARN, "No interrupt vector: %s instance %d",
- ddi_get_name(dip), ddi_get_instance(dip));
- return (-1);
- }
- }
-
- mutex_enter(&airq_mutex);
- if (apic_irq_table[irqno] == NULL) {
- irqptr = kmem_zalloc(sizeof (apic_irq_t), KM_SLEEP);
- irqptr->airq_temp_cpu = IRQ_UNINIT;
- apic_irq_table[irqno] = irqptr;
- } else {
- irqptr = apic_irq_table[irqno];
- if (irqptr->airq_mps_intr_index != FREE_INDEX) {
- /*
- * The slot is used by another irqno, so allocate
- * a free irqno for this interrupt
- */
- newirq = apic_allocate_irq(apic_first_avail_irq);
- if (newirq == -1) {
- mutex_exit(&airq_mutex);
- return (-1);
- }
- irqno = newirq;
- irqptr = apic_irq_table[irqno];
- if (irqptr == NULL) {
- irqptr = kmem_zalloc(sizeof (apic_irq_t),
- KM_SLEEP);
- irqptr->airq_temp_cpu = IRQ_UNINIT;
- apic_irq_table[irqno] = irqptr;
- }
- apic_modify_vector(vector, newirq);
- }
- }
- apic_max_device_irq = max(irqno, apic_max_device_irq);
- apic_min_device_irq = min(irqno, apic_min_device_irq);
- mutex_exit(&airq_mutex);
- irqptr->airq_ioapicindex = ioapicindex;
- irqptr->airq_intin_no = ipin;
- irqptr->airq_ipl = ipl;
- irqptr->airq_vector = vector;
- irqptr->airq_origirq = (uchar_t)origirq;
- irqptr->airq_share_id = 0;
- irqptr->airq_mps_intr_index = (short)intr_index;
- irqptr->airq_dip = dip;
- irqptr->airq_major = major;
- irqptr->airq_cpu = apic_bind_intr(dip, irqno, ioapic, ipin);
- if (intr_flagp)
- irqptr->airq_iflag = *intr_flagp;
-
- if (!DDI_INTR_IS_MSI_OR_MSIX(type)) {
- /* setup I/O APIC entry for non-MSI/X interrupts */
- apic_record_rdt_entry(irqptr, irqno);
- }
- return (irqno);
-}
-
-/*
- * return the cpu to which this intr should be bound.
- * Check properties or any other mechanism to see if user wants it
- * bound to a specific CPU. If so, return the cpu id with high bit set.
- * If not, use the policy to choose a cpu and return the id.
- */
-uchar_t
-apic_bind_intr(dev_info_t *dip, int irq, uchar_t ioapicid, uchar_t intin)
-{
- int instance, instno, prop_len, bind_cpu, count;
- uint_t i, rc;
- uchar_t cpu;
- major_t major;
- char *name, *drv_name, *prop_val, *cptr;
- char prop_name[32];
-
-
- if (apic_intr_policy == INTR_LOWEST_PRIORITY)
- return (IRQ_UNBOUND);
-
- drv_name = NULL;
- rc = DDI_PROP_NOT_FOUND;
- major = (major_t)-1;
- if (dip != NULL) {
- name = ddi_get_name(dip);
- major = ddi_name_to_major(name);
- drv_name = ddi_major_to_name(major);
- instance = ddi_get_instance(dip);
- if (apic_intr_policy == INTR_ROUND_ROBIN_WITH_AFFINITY) {
- i = apic_min_device_irq;
- for (; i <= apic_max_device_irq; i++) {
-
- if ((i == irq) || (apic_irq_table[i] == NULL) ||
- (apic_irq_table[i]->airq_mps_intr_index
- == FREE_INDEX))
- continue;
-
- if ((apic_irq_table[i]->airq_major == major) &&
- (!(apic_irq_table[i]->airq_cpu &
- IRQ_USER_BOUND))) {
-
- cpu = apic_irq_table[i]->airq_cpu;
-
- cmn_err(CE_CONT,
- "!pcplusmp: %s (%s) instance #%d "
- "vector 0x%x ioapic 0x%x "
- "intin 0x%x is bound to cpu %d\n",
- name, drv_name, instance, irq,
- ioapicid, intin, cpu);
- return (cpu);
- }
- }
- }
- /*
- * search for "drvname"_intpt_bind_cpus property first, the
- * syntax of the property should be "a[,b,c,...]" where
- * instance 0 binds to cpu a, instance 1 binds to cpu b,
- * instance 3 binds to cpu c...
- * ddi_getlongprop() will search /option first, then /
- * if "drvname"_intpt_bind_cpus doesn't exist, then find
- * intpt_bind_cpus property. The syntax is the same, and
- * it applies to all the devices if its "drvname" specific
- * property doesn't exist
- */
- (void) strcpy(prop_name, drv_name);
- (void) strcat(prop_name, "_intpt_bind_cpus");
- rc = ddi_getlongprop(DDI_DEV_T_ANY, dip, 0, prop_name,
- (caddr_t)&prop_val, &prop_len);
- if (rc != DDI_PROP_SUCCESS) {
- rc = ddi_getlongprop(DDI_DEV_T_ANY, dip, 0,
- "intpt_bind_cpus", (caddr_t)&prop_val, &prop_len);
- }
- }
- if (rc == DDI_PROP_SUCCESS) {
- for (i = count = 0; i < (prop_len - 1); i++)
- if (prop_val[i] == ',')
- count++;
- if (prop_val[i-1] != ',')
- count++;
- /*
- * if somehow the binding instances defined in the
- * property are not enough for this instno., then
- * reuse the pattern for the next instance until
- * it reaches the requested instno
- */
- instno = instance % count;
- i = 0;
- cptr = prop_val;
- while (i < instno)
- if (*cptr++ == ',')
- i++;
- bind_cpu = stoi(&cptr);
- kmem_free(prop_val, prop_len);
- /* if specific cpu is bogus, then default to cpu 0 */
- if (bind_cpu >= apic_nproc) {
- cmn_err(CE_WARN, "pcplusmp: %s=%s: CPU %d not present",
- prop_name, prop_val, bind_cpu);
- bind_cpu = 0;
- } else {
- /* indicate that we are bound at user request */
- bind_cpu |= IRQ_USER_BOUND;
- }
- /*
- * no need to check apic_cpus[].aci_status, if specific cpu is
- * not up, then post_cpu_start will handle it.
- */
- } else {
- bind_cpu = apic_next_bind_cpu++;
- if (bind_cpu >= apic_nproc) {
- apic_next_bind_cpu = 1;
- bind_cpu = 0;
- }
- }
- if (drv_name != NULL)
- cmn_err(CE_CONT, "!pcplusmp: %s (%s) instance %d "
- "vector 0x%x ioapic 0x%x intin 0x%x is bound to cpu %d\n",
- name, drv_name, instance,
- irq, ioapicid, intin, bind_cpu & ~IRQ_USER_BOUND);
- else
- cmn_err(CE_CONT, "!pcplusmp: "
- "vector 0x%x ioapic 0x%x intin 0x%x is bound to cpu %d\n",
- irq, ioapicid, intin, bind_cpu & ~IRQ_USER_BOUND);
-
- return ((uchar_t)bind_cpu);
-}
-
-static struct apic_io_intr *
-apic_find_io_intr_w_busid(int irqno, int busid)
-{
- struct apic_io_intr *intrp;
-
- /*
- * It can have more than 1 entry with same source bus IRQ,
- * but unique with the source bus id
- */
- intrp = apic_io_intrp;
- if (intrp != NULL) {
- while (intrp->intr_entry == APIC_IO_INTR_ENTRY) {
- if (intrp->intr_irq == irqno &&
- intrp->intr_busid == busid &&
- intrp->intr_type == IO_INTR_INT)
- return (intrp);
- intrp++;
- }
- }
- APIC_VERBOSE_IOAPIC((CE_NOTE, "Did not find io intr for irqno:"
- "busid %x:%x\n", irqno, busid));
- return ((struct apic_io_intr *)NULL);
-}
-
-
-struct mps_bus_info {
- char *bus_name;
- int bus_id;
-} bus_info_array[] = {
- "ISA ", BUS_ISA,
- "PCI ", BUS_PCI,
- "EISA ", BUS_EISA,
- "XPRESS", BUS_XPRESS,
- "PCMCIA", BUS_PCMCIA,
- "VL ", BUS_VL,
- "CBUS ", BUS_CBUS,
- "CBUSII", BUS_CBUSII,
- "FUTURE", BUS_FUTURE,
- "INTERN", BUS_INTERN,
- "MBI ", BUS_MBI,
- "MBII ", BUS_MBII,
- "MPI ", BUS_MPI,
- "MPSA ", BUS_MPSA,
- "NUBUS ", BUS_NUBUS,
- "TC ", BUS_TC,
- "VME ", BUS_VME,
- "PCI-E ", BUS_PCIE
-};
-
-static int
-apic_find_bus_type(char *bus)
-{
- int i = 0;
-
- for (; i < sizeof (bus_info_array)/sizeof (struct mps_bus_info); i++)
- if (strncmp(bus, bus_info_array[i].bus_name,
- strlen(bus_info_array[i].bus_name)) == 0)
- return (bus_info_array[i].bus_id);
- APIC_VERBOSE_IOAPIC((CE_WARN, "Did not find bus type for bus %s", bus));
- return (0);
-}
-
-static int
-apic_find_bus(int busid)
-{
- struct apic_bus *busp;
-
- busp = apic_busp;
- while (busp->bus_entry == APIC_BUS_ENTRY) {
- if (busp->bus_id == busid)
- return (apic_find_bus_type((char *)&busp->bus_str1));
- busp++;
- }
- APIC_VERBOSE_IOAPIC((CE_WARN, "Did not find bus for bus id %x", busid));
- return (0);
-}
-
-static int
-apic_find_bus_id(int bustype)
-{
- struct apic_bus *busp;
-
- busp = apic_busp;
- while (busp->bus_entry == APIC_BUS_ENTRY) {
- if (apic_find_bus_type((char *)&busp->bus_str1) == bustype)
- return (busp->bus_id);
- busp++;
- }
- APIC_VERBOSE_IOAPIC((CE_WARN, "Did not find bus id for bustype %x",
- bustype));
- return (-1);
-}
-
-/*
- * Check if a particular irq need to be reserved for any io_intr
- */
-static struct apic_io_intr *
-apic_find_io_intr(int irqno)
-{
- struct apic_io_intr *intrp;
-
- intrp = apic_io_intrp;
- if (intrp != NULL) {
- while (intrp->intr_entry == APIC_IO_INTR_ENTRY) {
- if (intrp->intr_irq == irqno &&
- intrp->intr_type == IO_INTR_INT)
- return (intrp);
- intrp++;
- }
- }
- return ((struct apic_io_intr *)NULL);
-}
-
-/*
- * Check if the given ioapicindex intin combination has already been assigned
- * an irq. If so return irqno. Else -1
- */
-static int
-apic_find_intin(uchar_t ioapic, uchar_t intin)
-{
- apic_irq_t *irqptr;
- int i;
-
- /* find ioapic and intin in the apic_irq_table[] and return the index */
- for (i = apic_min_device_irq; i <= apic_max_device_irq; i++) {
- irqptr = apic_irq_table[i];
- while (irqptr) {
- if ((irqptr->airq_mps_intr_index >= 0) &&
- (irqptr->airq_intin_no == intin) &&
- (irqptr->airq_ioapicindex == ioapic)) {
- APIC_VERBOSE_IOAPIC((CE_NOTE, "!Found irq "
- "entry for ioapic:intin %x:%x "
- "shared interrupts ?", ioapic, intin));
- return (i);
- }
- irqptr = irqptr->airq_next;
- }
- }
- return (-1);
-}
-
-int
-apic_allocate_irq(int irq)
-{
- int freeirq, i;
-
- if ((freeirq = apic_find_free_irq(irq, (APIC_RESV_IRQ - 1))) == -1)
- if ((freeirq = apic_find_free_irq(APIC_FIRST_FREE_IRQ,
- (irq - 1))) == -1) {
- /*
- * if BIOS really defines every single irq in the mps
- * table, then don't worry about conflicting with
- * them, just use any free slot in apic_irq_table
- */
- for (i = APIC_FIRST_FREE_IRQ; i < APIC_RESV_IRQ; i++) {
- if ((apic_irq_table[i] == NULL) ||
- apic_irq_table[i]->airq_mps_intr_index ==
- FREE_INDEX) {
- freeirq = i;
- break;
- }
- }
- if (freeirq == -1) {
- /* This shouldn't happen, but just in case */
- cmn_err(CE_WARN, "pcplusmp: NO available IRQ");
- return (-1);
- }
- }
- if (apic_irq_table[freeirq] == NULL) {
- apic_irq_table[freeirq] =
- kmem_zalloc(sizeof (apic_irq_t), KM_NOSLEEP);
- if (apic_irq_table[freeirq] == NULL) {
- cmn_err(CE_WARN, "pcplusmp: NO memory to allocate IRQ");
- return (-1);
- }
- apic_irq_table[freeirq]->airq_mps_intr_index = FREE_INDEX;
- }
- return (freeirq);
-}
-
-static int
-apic_find_free_irq(int start, int end)
-{
- int i;
-
- for (i = start; i <= end; i++)
- /* Check if any I/O entry needs this IRQ */
- if (apic_find_io_intr(i) == NULL) {
- /* Then see if it is free */
- if ((apic_irq_table[i] == NULL) ||
- (apic_irq_table[i]->airq_mps_intr_index ==
- FREE_INDEX)) {
- return (i);
- }
- }
- return (-1);
-}
-
-/*
- * Allocate a free vector for irq at ipl. Takes care of merging of multiple
- * IPLs into a single APIC level as well as stretching some IPLs onto multiple
- * levels. APIC_HI_PRI_VECTS interrupts are reserved for high priority
- * requests and allocated only when pri is set.
- */
-static uchar_t
-apic_allocate_vector(int ipl, int irq, int pri)
-{
- int lowest, highest, i;
-
- highest = apic_ipltopri[ipl] + APIC_VECTOR_MASK;
- lowest = apic_ipltopri[ipl - 1] + APIC_VECTOR_PER_IPL;
-
- if (highest < lowest) /* Both ipl and ipl - 1 map to same pri */
- lowest -= APIC_VECTOR_PER_IPL;
-
-#ifdef DEBUG
- if (apic_restrict_vector) /* for testing shared interrupt logic */
- highest = lowest + apic_restrict_vector + APIC_HI_PRI_VECTS;
-#endif /* DEBUG */
- if (pri == 0)
- highest -= APIC_HI_PRI_VECTS;
-
- for (i = lowest; i < highest; i++) {
- if (APIC_CHECK_RESERVE_VECTORS(i))
- continue;
- if (apic_vector_to_irq[i] == APIC_RESV_IRQ) {
- apic_vector_to_irq[i] = (uchar_t)irq;
- return (i);
- }
- }
-
- return (0);
-}
-
-static void
-apic_modify_vector(uchar_t vector, int irq)
-{
- apic_vector_to_irq[vector] = (uchar_t)irq;
-}
-
-/*
- * Mark vector as being in the process of being deleted. Interrupts
- * may still come in on some CPU. The moment an interrupt comes with
- * the new vector, we know we can free the old one. Called only from
- * addspl and delspl with interrupts disabled. Because an interrupt
- * can be shared, but no interrupt from either device may come in,
- * we also use a timeout mechanism, which we arbitrarily set to
- * apic_revector_timeout microseconds.
- */
-static void
-apic_mark_vector(uchar_t oldvector, uchar_t newvector)
-{
- int iflag = intr_clear();
- lock_set(&apic_revector_lock);
- if (!apic_oldvec_to_newvec) {
- apic_oldvec_to_newvec =
- kmem_zalloc(sizeof (newvector) * APIC_MAX_VECTOR * 2,
- KM_NOSLEEP);
-
- if (!apic_oldvec_to_newvec) {
- /*
- * This failure is not catastrophic.
- * But, the oldvec will never be freed.
- */
- apic_error |= APIC_ERR_MARK_VECTOR_FAIL;
- lock_clear(&apic_revector_lock);
- intr_restore(iflag);
- return;
- }
- apic_newvec_to_oldvec = &apic_oldvec_to_newvec[APIC_MAX_VECTOR];
- }
-
- /* See if we already did this for drivers which do double addintrs */
- if (apic_oldvec_to_newvec[oldvector] != newvector) {
- apic_oldvec_to_newvec[oldvector] = newvector;
- apic_newvec_to_oldvec[newvector] = oldvector;
- apic_revector_pending++;
- }
- lock_clear(&apic_revector_lock);
- intr_restore(iflag);
- (void) timeout(apic_xlate_vector_free_timeout_handler,
- (void *)(uintptr_t)oldvector, drv_usectohz(apic_revector_timeout));
-}
-
-/*
- * xlate_vector is called from intr_enter if revector_pending is set.
- * It will xlate it if needed and mark the old vector as free.
- */
-static uchar_t
-apic_xlate_vector(uchar_t vector)
-{
- uchar_t newvector, oldvector = 0;
-
- lock_set(&apic_revector_lock);
- /* Do we really need to do this ? */
- if (!apic_revector_pending) {
- lock_clear(&apic_revector_lock);
- return (vector);
- }
- if ((newvector = apic_oldvec_to_newvec[vector]) != 0)
- oldvector = vector;
- else {
- /*
- * The incoming vector is new . See if a stale entry is
- * remaining
- */
- if ((oldvector = apic_newvec_to_oldvec[vector]) != 0)
- newvector = vector;
- }
-
- if (oldvector) {
- apic_revector_pending--;
- apic_oldvec_to_newvec[oldvector] = 0;
- apic_newvec_to_oldvec[newvector] = 0;
- apic_free_vector(oldvector);
- lock_clear(&apic_revector_lock);
- /* There could have been more than one reprogramming! */
- return (apic_xlate_vector(newvector));
- }
- lock_clear(&apic_revector_lock);
- return (vector);
-}
-
-void
-apic_xlate_vector_free_timeout_handler(void *arg)
-{
- int iflag;
- uchar_t oldvector, newvector;
-
- oldvector = (uchar_t)(uintptr_t)arg;
- iflag = intr_clear();
- lock_set(&apic_revector_lock);
- if ((newvector = apic_oldvec_to_newvec[oldvector]) != 0) {
- apic_free_vector(oldvector);
- apic_oldvec_to_newvec[oldvector] = 0;
- apic_newvec_to_oldvec[newvector] = 0;
- apic_revector_pending--;
- }
-
- lock_clear(&apic_revector_lock);
- intr_restore(iflag);
-}
-
-
-/* Mark vector as not being used by any irq */
-static void
-apic_free_vector(uchar_t vector)
-{
- apic_vector_to_irq[vector] = APIC_RESV_IRQ;
-}
-
-/*
- * compute the polarity, trigger mode and vector for programming into
- * the I/O apic and record in airq_rdt_entry.
- */
-static void
-apic_record_rdt_entry(apic_irq_t *irqptr, int irq)
-{
- int ioapicindex, bus_type, vector;
- short intr_index;
- uint_t level, po, io_po;
- struct apic_io_intr *iointrp;
-
- intr_index = irqptr->airq_mps_intr_index;
- DDI_INTR_IMPLDBG((CE_CONT, "apic_record_rdt_entry: intr_index=%d "
- "irq = 0x%x dip = 0x%p vector = 0x%x\n", intr_index, irq,
- (void *)irqptr->airq_dip, irqptr->airq_vector));
-
- if (intr_index == RESERVE_INDEX) {
- apic_error |= APIC_ERR_INVALID_INDEX;
- return;
- } else if (APIC_IS_MSI_OR_MSIX_INDEX(intr_index)) {
- return;
- }
-
- vector = irqptr->airq_vector;
- ioapicindex = irqptr->airq_ioapicindex;
- /* Assume edge triggered by default */
- level = 0;
- /* Assume active high by default */
- po = 0;
-
- if (intr_index == DEFAULT_INDEX || intr_index == FREE_INDEX) {
- ASSERT(irq < 16);
- if (eisa_level_intr_mask & (1 << irq))
- level = AV_LEVEL;
- if (intr_index == FREE_INDEX && apic_defconf == 0)
- apic_error |= APIC_ERR_INVALID_INDEX;
- } else if (intr_index == ACPI_INDEX) {
- bus_type = irqptr->airq_iflag.bustype;
- if (irqptr->airq_iflag.intr_el == INTR_EL_CONFORM) {
- if (bus_type == BUS_PCI)
- level = AV_LEVEL;
- } else
- level = (irqptr->airq_iflag.intr_el == INTR_EL_LEVEL) ?
- AV_LEVEL : 0;
- if (level &&
- ((irqptr->airq_iflag.intr_po == INTR_PO_ACTIVE_LOW) ||
- (irqptr->airq_iflag.intr_po == INTR_PO_CONFORM &&
- bus_type == BUS_PCI)))
- po = AV_ACTIVE_LOW;
- } else {
- iointrp = apic_io_intrp + intr_index;
- bus_type = apic_find_bus(iointrp->intr_busid);
- if (iointrp->intr_el == INTR_EL_CONFORM) {
- if ((irq < 16) && (eisa_level_intr_mask & (1 << irq)))
- level = AV_LEVEL;
- else if (bus_type == BUS_PCI)
- level = AV_LEVEL;
- } else
- level = (iointrp->intr_el == INTR_EL_LEVEL) ?
- AV_LEVEL : 0;
- if (level && ((iointrp->intr_po == INTR_PO_ACTIVE_LOW) ||
- (iointrp->intr_po == INTR_PO_CONFORM &&
- bus_type == BUS_PCI)))
- po = AV_ACTIVE_LOW;
- }
- if (level)
- apic_level_intr[irq] = 1;
- /*
- * The 82489DX External APIC cannot do active low polarity interrupts.
- */
- if (po && (apic_io_ver[ioapicindex] != IOAPIC_VER_82489DX))
- io_po = po;
- else
- io_po = 0;
-
- if (apic_verbose & APIC_VERBOSE_IOAPIC_FLAG)
- printf("setio: ioapic=%x intin=%x level=%x po=%x vector=%x\n",
- ioapicindex, irqptr->airq_intin_no, level, io_po, vector);
-
- irqptr->airq_rdt_entry = level|io_po|vector;
-}
-
-static processorid_t
-apic_find_cpu(int flag)
-{
- processorid_t acid = 0;
- int i;
-
- /* Find the first CPU with the passed-in flag set */
- for (i = 0; i < apic_nproc; i++) {
- if (apic_cpus[i].aci_status & flag) {
- acid = i;
- break;
- }
- }
-
- ASSERT((apic_cpus[acid].aci_status & flag) != 0);
- return (acid);
-}
-
-/*
- * Call rebind to do the actual programming.
- * Must be called with interrupts disabled and apic_ioapic_lock held
- * 'p' is polymorphic -- if this function is called to process a deferred
- * reprogramming, p is of type 'struct ioapic_reprogram_data *', from which
- * the irq pointer is retrieved. If not doing deferred reprogramming,
- * p is of the type 'apic_irq_t *'.
- *
- * apic_ioapic_lock must be held across this call, as it protects apic_rebind
- * and it protects apic_find_cpu() from a race in which a CPU can be taken
- * offline after a cpu is selected, but before apic_rebind is called to
- * bind interrupts to it.
- */
-static int
-apic_setup_io_intr(void *p, int irq, boolean_t deferred)
-{
- apic_irq_t *irqptr;
- struct ioapic_reprogram_data *drep = NULL;
- int rv;
-
- if (deferred) {
- drep = (struct ioapic_reprogram_data *)p;
- ASSERT(drep != NULL);
- irqptr = drep->irqp;
- } else
- irqptr = (apic_irq_t *)p;
-
- ASSERT(irqptr != NULL);
-
- rv = apic_rebind(irqptr, apic_irq_table[irq]->airq_cpu, drep);
- if (rv) {
- /*
- * CPU is not up or interrupts are disabled. Fall back to
- * the first available CPU
- */
- rv = apic_rebind(irqptr, apic_find_cpu(APIC_CPU_INTR_ENABLE),
- drep);
- }
-
- return (rv);
-}
-
-/*
- * Bind interrupt corresponding to irq_ptr to bind_cpu.
- * Must be called with interrupts disabled and apic_ioapic_lock held
- */
-static int
-apic_rebind(apic_irq_t *irq_ptr, int bind_cpu,
- struct ioapic_reprogram_data *drep)
-{
- int ioapicindex, intin_no;
- volatile int32_t *ioapic;
- uchar_t airq_temp_cpu;
- apic_cpus_info_t *cpu_infop;
- uint32_t rdt_entry;
- int which_irq;
-
- which_irq = apic_vector_to_irq[irq_ptr->airq_vector];
-
- intin_no = irq_ptr->airq_intin_no;
- ioapicindex = irq_ptr->airq_ioapicindex;
- ioapic = apicioadr[ioapicindex];
- airq_temp_cpu = irq_ptr->airq_temp_cpu;
- if (airq_temp_cpu != IRQ_UNINIT && airq_temp_cpu != IRQ_UNBOUND) {
- if (airq_temp_cpu & IRQ_USER_BOUND)
- /* Mask off high bit so it can be used as array index */
- airq_temp_cpu &= ~IRQ_USER_BOUND;
-
- ASSERT(airq_temp_cpu < apic_nproc);
- }
-
- /*
- * Can't bind to a CPU that's not accepting interrupts:
- */
- cpu_infop = &apic_cpus[bind_cpu & ~IRQ_USER_BOUND];
- if (!(cpu_infop->aci_status & APIC_CPU_INTR_ENABLE))
- return (1);
-
- /*
- * If we are about to change the interrupt vector for this interrupt,
- * and this interrupt is level-triggered, attached to an IOAPIC,
- * has been delivered to a CPU and that CPU has not handled it
- * yet, we cannot reprogram the IOAPIC now.
- */
- if (!APIC_IS_MSI_OR_MSIX_INDEX(irq_ptr->airq_mps_intr_index)) {
-
- rdt_entry = READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no);
-
- if ((irq_ptr->airq_vector != RDT_VECTOR(rdt_entry)) &&
- apic_check_stuck_interrupt(irq_ptr, airq_temp_cpu,
- bind_cpu, ioapic, intin_no, which_irq, drep) != 0) {
-
- return (0);
- }
- }
-
- /*
- * NOTE: We do not unmask the RDT here, as an interrupt MAY still
- * come in before we have a chance to reprogram it below. The
- * reprogramming below will simultaneously change and unmask the
- * RDT entry.
- */
-
- if ((uchar_t)bind_cpu == IRQ_UNBOUND) {
-
- rdt_entry = AV_LDEST | AV_LOPRI | irq_ptr->airq_rdt_entry;
-
- /* Write the RDT entry -- no specific CPU binding */
- WRITE_IOAPIC_RDT_ENTRY_HIGH_DWORD(ioapic, intin_no, AV_TOALL);
-
- if (airq_temp_cpu != IRQ_UNINIT && airq_temp_cpu != IRQ_UNBOUND)
- apic_cpus[airq_temp_cpu].aci_temp_bound--;
-
- /* Write the vector, trigger, and polarity portion of the RDT */
- WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no, rdt_entry);
-
- irq_ptr->airq_temp_cpu = IRQ_UNBOUND;
- return (0);
- }
-
- if (bind_cpu & IRQ_USER_BOUND) {
- cpu_infop->aci_bound++;
- } else {
- cpu_infop->aci_temp_bound++;
- }
- ASSERT((bind_cpu & ~IRQ_USER_BOUND) < apic_nproc);
- if (!APIC_IS_MSI_OR_MSIX_INDEX(irq_ptr->airq_mps_intr_index)) {
- /* Write the RDT entry -- bind to a specific CPU: */
- WRITE_IOAPIC_RDT_ENTRY_HIGH_DWORD(ioapic, intin_no,
- cpu_infop->aci_local_id << APIC_ID_BIT_OFFSET);
- }
- if ((airq_temp_cpu != IRQ_UNBOUND) && (airq_temp_cpu != IRQ_UNINIT)) {
- apic_cpus[airq_temp_cpu].aci_temp_bound--;
- }
- if (!APIC_IS_MSI_OR_MSIX_INDEX(irq_ptr->airq_mps_intr_index)) {
-
- rdt_entry = AV_PDEST | AV_FIXED | irq_ptr->airq_rdt_entry;
-
- /* Write the vector, trigger, and polarity portion of the RDT */
- WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no, rdt_entry);
-
- } else {
- int type = (irq_ptr->airq_mps_intr_index == MSI_INDEX) ?
- DDI_INTR_TYPE_MSI : DDI_INTR_TYPE_MSIX;
- (void) apic_pci_msi_disable_mode(irq_ptr->airq_dip, type,
- ioapicindex);
- if (ioapicindex == irq_ptr->airq_origirq) {
- /* first one */
- DDI_INTR_IMPLDBG((CE_CONT, "apic_rebind: call "
- "apic_pci_msi_enable_vector\n"));
- if (apic_pci_msi_enable_vector(irq_ptr->airq_dip, type,
- which_irq, irq_ptr->airq_vector,
- irq_ptr->airq_intin_no,
- cpu_infop->aci_local_id) != PSM_SUCCESS) {
- cmn_err(CE_WARN, "pcplusmp: "
- "apic_pci_msi_enable_vector "
- "returned PSM_FAILURE");
- }
- }
- if ((ioapicindex + irq_ptr->airq_intin_no - 1) ==
- irq_ptr->airq_origirq) { /* last one */
- DDI_INTR_IMPLDBG((CE_CONT, "apic_rebind: call "
- "pci_msi_enable_mode\n"));
- if (apic_pci_msi_enable_mode(irq_ptr->airq_dip,
- type, which_irq) != PSM_SUCCESS) {
- DDI_INTR_IMPLDBG((CE_CONT, "pcplusmp: "
- "pci_msi_enable failed\n"));
- (void) apic_pci_msi_unconfigure(
- irq_ptr->airq_dip, type, which_irq);
- }
- }
- }
- irq_ptr->airq_temp_cpu = (uchar_t)bind_cpu;
- apic_redist_cpu_skip &= ~(1 << (bind_cpu & ~IRQ_USER_BOUND));
- return (0);
-}
-
-static void
-apic_last_ditch_clear_remote_irr(volatile int32_t *ioapic, int intin_no)
-{
- if ((READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no)
- & AV_REMOTE_IRR) != 0) {
- /*
- * Trying to clear the bit through normal
- * channels has failed. So as a last-ditch
- * effort, try to set the trigger mode to
- * edge, then to level. This has been
- * observed to work on many systems.
- */
- WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic,
- intin_no,
- READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic,
- intin_no) & ~AV_LEVEL);
-
- WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic,
- intin_no,
- READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic,
- intin_no) | AV_LEVEL);
-
- /*
- * If the bit's STILL set, this interrupt may
- * be hosed.
- */
- if ((READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic,
- intin_no) & AV_REMOTE_IRR) != 0) {
-
- prom_printf("pcplusmp: Remote IRR still "
- "not clear for IOAPIC %p intin %d.\n"
- "\tInterrupts to this pin may cease "
- "functioning.\n", ioapic, intin_no);
-#ifdef DEBUG
- apic_last_ditch_reprogram_failures++;
-#endif
- }
- }
-}
-
-/*
- * This function is protected by apic_ioapic_lock coupled with the
- * fact that interrupts are disabled.
- */
-static void
-delete_defer_repro_ent(int which_irq)
-{
- ASSERT(which_irq >= 0);
- ASSERT(which_irq <= 255);
-
- if (apic_reprogram_info[which_irq].done)
- return;
-
- apic_reprogram_info[which_irq].done = B_TRUE;
-
-#ifdef DEBUG
- apic_defer_repro_total_retries +=
- apic_reprogram_info[which_irq].tries;
-
- apic_defer_repro_successes++;
-#endif
-
- if (--apic_reprogram_outstanding == 0) {
-
- setlvlx = apic_intr_exit;
- }
-}
-
-
-/*
- * Interrupts must be disabled during this function to prevent
- * self-deadlock. Interrupts are disabled because this function
- * is called from apic_check_stuck_interrupt(), which is called
- * from apic_rebind(), which requires its caller to disable interrupts.
- */
-static void
-add_defer_repro_ent(apic_irq_t *irq_ptr, int which_irq, int new_bind_cpu)
-{
- ASSERT(which_irq >= 0);
- ASSERT(which_irq <= 255);
-
- /*
- * On the off-chance that there's already a deferred
- * reprogramming on this irq, check, and if so, just update the
- * CPU and irq pointer to which the interrupt is targeted, then return.
- */
- if (!apic_reprogram_info[which_irq].done) {
- apic_reprogram_info[which_irq].bindcpu = new_bind_cpu;
- apic_reprogram_info[which_irq].irqp = irq_ptr;
- return;
- }
-
- apic_reprogram_info[which_irq].irqp = irq_ptr;
- apic_reprogram_info[which_irq].bindcpu = new_bind_cpu;
- apic_reprogram_info[which_irq].tries = 0;
- /*
- * This must be the last thing set, since we're not
- * grabbing any locks, apic_try_deferred_reprogram() will
- * make its decision about using this entry iff done
- * is false.
- */
- apic_reprogram_info[which_irq].done = B_FALSE;
-
- /*
- * If there were previously no deferred reprogrammings, change
- * setlvlx to call apic_try_deferred_reprogram()
- */
- if (++apic_reprogram_outstanding == 1) {
-
- setlvlx = apic_try_deferred_reprogram;
- }
-}
-
-static void
-apic_try_deferred_reprogram(int prev_ipl, int irq)
-{
- int reproirq, iflag;
- struct ioapic_reprogram_data *drep;
-
- apic_intr_exit(prev_ipl, irq);
-
- if (!lock_try(&apic_defer_reprogram_lock)) {
- return;
- }
-
- /*
- * Acquire the apic_ioapic_lock so that any other operations that
- * may affect the apic_reprogram_info state are serialized.
- * It's still possible for the last deferred reprogramming to clear
- * between the time we entered this function and the time we get to
- * the for loop below. In that case, *setlvlx will have been set
- * back to apic_intr_exit and drep will be NULL. (There's no way to
- * stop that from happening -- we would need to grab a lock before
- * calling *setlvlx, which is neither realistic nor prudent).
- */
- iflag = intr_clear();
- lock_set(&apic_ioapic_lock);
-
- /*
- * For each deferred RDT entry, try to reprogram it now. Note that
- * there is no lock acquisition to read apic_reprogram_info because
- * '.done' is set only after the other fields in the structure are set.
- */
-
- drep = NULL;
- for (reproirq = 0; reproirq <= APIC_MAX_VECTOR; reproirq++) {
- if (apic_reprogram_info[reproirq].done == B_FALSE) {
- drep = &apic_reprogram_info[reproirq];
- break;
- }
- }
-
- /*
- * Either we found a deferred action to perform, or
- * we entered this function spuriously, after *setlvlx
- * was restored to point to apic_intr_enter. Any other
- * permutation is invalid.
- */
- ASSERT(drep != NULL || *setlvlx == apic_intr_exit);
-
- /*
- * Though we can't really do anything about errors
- * at this point, keep track of them for reporting.
- * Note that it is very possible for apic_setup_io_intr
- * to re-register this very timeout if the Remote IRR bit
- * has not yet cleared.
- */
-
-#ifdef DEBUG
- if (drep != NULL) {
- if (apic_setup_io_intr(drep, reproirq, B_TRUE) != 0) {
- apic_deferred_setup_failures++;
- }
- } else {
- apic_deferred_spurious_enters++;
- }
-#else
- if (drep != NULL)
- (void) apic_setup_io_intr(drep, reproirq, B_TRUE);
-#endif
-
- lock_clear(&apic_ioapic_lock);
- intr_restore(iflag);
-
- lock_clear(&apic_defer_reprogram_lock);
-}
-
-static void
-apic_ioapic_wait_pending_clear(volatile int32_t *ioapic, int intin_no)
-{
- int waited;
-
- /*
- * Wait for the delivery pending bit to clear.
- */
- if ((READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no) &
- (AV_LEVEL|AV_PENDING)) == (AV_LEVEL|AV_PENDING)) {
-
- /*
- * If we're still waiting on the delivery of this interrupt,
- * continue to wait here until it is delivered (this should be
- * a very small amount of time, but include a timeout just in
- * case).
- */
- for (waited = 0; waited < apic_max_reps_clear_pending;
- waited++) {
- if ((READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no)
- & AV_PENDING) == 0) {
- break;
- }
- }
- }
-}
-
-/*
- * Checks to see if the IOAPIC interrupt entry specified has its Remote IRR
- * bit set. Calls functions that modify the function that setlvlx points to,
- * so that the reprogramming can be retried very shortly.
- *
- * This function will mask the RDT entry if the interrupt is level-triggered.
- * (The caller is responsible for unmasking the RDT entry.)
- *
- * Returns non-zero if the caller should defer IOAPIC reprogramming.
- */
-static int
-apic_check_stuck_interrupt(apic_irq_t *irq_ptr, int old_bind_cpu,
- int new_bind_cpu, volatile int32_t *ioapic, int intin_no, int which_irq,
- struct ioapic_reprogram_data *drep)
-{
- int32_t rdt_entry;
- int waited;
- int reps = 0;
-
- /*
- * Wait for the delivery pending bit to clear.
- */
- do {
- ++reps;
-
- apic_ioapic_wait_pending_clear(ioapic, intin_no);
-
- /*
- * Mask the RDT entry, but only if it's a level-triggered
- * interrupt
- */
- rdt_entry = READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no);
- if ((rdt_entry & (AV_LEVEL|AV_MASK)) == AV_LEVEL) {
-
- /* Mask it */
- WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no,
- AV_MASK | rdt_entry);
- }
-
- if ((rdt_entry & AV_LEVEL) == AV_LEVEL) {
- /*
- * If there was a race and an interrupt was injected
- * just before we masked, check for that case here.
- * Then, unmask the RDT entry and try again. If we're
- * on our last try, don't unmask (because we want the
- * RDT entry to remain masked for the rest of the
- * function).
- */
- rdt_entry = READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic,
- intin_no);
- if ((rdt_entry & AV_PENDING) &&
- (reps < apic_max_reps_clear_pending)) {
- /* Unmask it */
- WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic,
- intin_no, rdt_entry & ~AV_MASK);
- }
- }
-
- } while ((rdt_entry & AV_PENDING) &&
- (reps < apic_max_reps_clear_pending));
-
-#ifdef DEBUG
- if (rdt_entry & AV_PENDING)
- apic_intr_deliver_timeouts++;
-#endif
-
- /*
- * If the remote IRR bit is set, then the interrupt has been sent
- * to a CPU for processing. We have no choice but to wait for
- * that CPU to process the interrupt, at which point the remote IRR
- * bit will be cleared.
- */
- if ((READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no) &
- (AV_LEVEL|AV_REMOTE_IRR)) == (AV_LEVEL|AV_REMOTE_IRR)) {
-
- /*
- * If the CPU that this RDT is bound to is NOT the current
- * CPU, wait until that CPU handles the interrupt and ACKs
- * it. If this interrupt is not bound to any CPU (that is,
- * if it's bound to the logical destination of "anyone"), it
- * may have been delivered to the current CPU so handle that
- * case by deferring the reprogramming (below).
- */
- if ((old_bind_cpu != IRQ_UNBOUND) &&
- (old_bind_cpu != IRQ_UNINIT) &&
- (old_bind_cpu != psm_get_cpu_id())) {
- for (waited = 0; waited < apic_max_reps_clear_pending;
- waited++) {
- if ((READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic,
- intin_no) & AV_REMOTE_IRR) == 0) {
-
- delete_defer_repro_ent(which_irq);
-
- /* Remote IRR has cleared! */
- return (0);
- }
- }
- }
-
- /*
- * If we waited and the Remote IRR bit is still not cleared,
- * AND if we've invoked the timeout APIC_REPROGRAM_MAX_TIMEOUTS
- * times for this interrupt, try the last-ditch workaround:
- */
- if (drep && drep->tries >= APIC_REPROGRAM_MAX_TRIES) {
-
- apic_last_ditch_clear_remote_irr(ioapic, intin_no);
-
- /* Mark this one as reprogrammed: */
- delete_defer_repro_ent(which_irq);
-
- return (0);
- } else {
-#ifdef DEBUG
- apic_intr_deferrals++;
-#endif
-
- /*
- * If waiting for the Remote IRR bit (above) didn't
- * allow it to clear, defer the reprogramming.
- * Add a new deferred-programming entry if the
- * caller passed a NULL one (and update the existing one
- * in case anything changed).
- */
- add_defer_repro_ent(irq_ptr, which_irq, new_bind_cpu);
- if (drep)
- drep->tries++;
-
- /* Inform caller to defer IOAPIC programming: */
- return (1);
- }
-
- }
-
- /* Remote IRR is clear */
- delete_defer_repro_ent(which_irq);
-
- return (0);
-}
-
-/*
- * Called to migrate all interrupts at an irq to another cpu.
- * Must be called with interrupts disabled and apic_ioapic_lock held
- */
-int
-apic_rebind_all(apic_irq_t *irq_ptr, int bind_cpu)
-{
- apic_irq_t *irqptr = irq_ptr;
- int retval = 0;
-
- while (irqptr) {
- if (irqptr->airq_temp_cpu != IRQ_UNINIT)
- retval |= apic_rebind(irqptr, bind_cpu, NULL);
- irqptr = irqptr->airq_next;
- }
-
- return (retval);
-}
-
-/*
- * apic_intr_redistribute does all the messy computations for identifying
- * which interrupt to move to which CPU. Currently we do just one interrupt
- * at a time. This reduces the time we spent doing all this within clock
- * interrupt. When it is done in idle, we could do more than 1.
- * First we find the most busy and the most free CPU (time in ISR only)
- * skipping those CPUs that has been identified as being ineligible (cpu_skip)
- * Then we look for IRQs which are closest to the difference between the
- * most busy CPU and the average ISR load. We try to find one whose load
- * is less than difference.If none exists, then we chose one larger than the
- * difference, provided it does not make the most idle CPU worse than the
- * most busy one. In the end, we clear all the busy fields for CPUs. For
- * IRQs, they are cleared as they are scanned.
- */
-static void
-apic_intr_redistribute()
-{
- int busiest_cpu, most_free_cpu;
- int cpu_free, cpu_busy, max_busy, min_busy;
- int min_free, diff;
- int average_busy, cpus_online;
- int i, busy, iflag;
- apic_cpus_info_t *cpu_infop;
- apic_irq_t *min_busy_irq = NULL;
- apic_irq_t *max_busy_irq = NULL;
-
- busiest_cpu = most_free_cpu = -1;
- cpu_free = cpu_busy = max_busy = average_busy = 0;
- min_free = apic_sample_factor_redistribution;
- cpus_online = 0;
- /*
- * Below we will check for CPU_INTR_ENABLE, bound, temp_bound, temp_cpu
- * without ioapic_lock. That is OK as we are just doing statistical
- * sampling anyway and any inaccuracy now will get corrected next time
- * The call to rebind which actually changes things will make sure
- * we are consistent.
- */
- for (i = 0; i < apic_nproc; i++) {
- if (!(apic_redist_cpu_skip & (1 << i)) &&
- (apic_cpus[i].aci_status & APIC_CPU_INTR_ENABLE)) {
-
- cpu_infop = &apic_cpus[i];
- /*
- * If no unbound interrupts or only 1 total on this
- * CPU, skip
- */
- if (!cpu_infop->aci_temp_bound ||
- (cpu_infop->aci_bound + cpu_infop->aci_temp_bound)
- == 1) {
- apic_redist_cpu_skip |= 1 << i;
- continue;
- }
-
- busy = cpu_infop->aci_busy;
- average_busy += busy;
- cpus_online++;
- if (max_busy < busy) {
- max_busy = busy;
- busiest_cpu = i;
- }
- if (min_free > busy) {
- min_free = busy;
- most_free_cpu = i;
- }
- if (busy > apic_int_busy_mark) {
- cpu_busy |= 1 << i;
- } else {
- if (busy < apic_int_free_mark)
- cpu_free |= 1 << i;
- }
- }
- }
- if ((cpu_busy && cpu_free) ||
- (max_busy >= (min_free + apic_diff_for_redistribution))) {
-
- apic_num_imbalance++;
-#ifdef DEBUG
- if (apic_verbose & APIC_VERBOSE_IOAPIC_FLAG) {
- prom_printf(
- "redistribute busy=%x free=%x max=%x min=%x",
- cpu_busy, cpu_free, max_busy, min_free);
- }
-#endif /* DEBUG */
-
-
- average_busy /= cpus_online;
-
- diff = max_busy - average_busy;
- min_busy = max_busy; /* start with the max possible value */
- max_busy = 0;
- min_busy_irq = max_busy_irq = NULL;
- i = apic_min_device_irq;
- for (; i < apic_max_device_irq; i++) {
- apic_irq_t *irq_ptr;
- /* Change to linked list per CPU ? */
- if ((irq_ptr = apic_irq_table[i]) == NULL)
- continue;
- /* Check for irq_busy & decide which one to move */
- /* Also zero them for next round */
- if ((irq_ptr->airq_temp_cpu == busiest_cpu) &&
- irq_ptr->airq_busy) {
- if (irq_ptr->airq_busy < diff) {
- /*
- * Check for least busy CPU,
- * best fit or what ?
- */
- if (max_busy < irq_ptr->airq_busy) {
- /*
- * Most busy within the
- * required differential
- */
- max_busy = irq_ptr->airq_busy;
- max_busy_irq = irq_ptr;
- }
- } else {
- if (min_busy > irq_ptr->airq_busy) {
- /*
- * least busy, but more than
- * the reqd diff
- */
- if (min_busy <
- (diff + average_busy -
- min_free)) {
- /*
- * Making sure new cpu
- * will not end up
- * worse
- */
- min_busy =
- irq_ptr->airq_busy;
-
- min_busy_irq = irq_ptr;
- }
- }
- }
- }
- irq_ptr->airq_busy = 0;
- }
-
- if (max_busy_irq != NULL) {
-#ifdef DEBUG
- if (apic_verbose & APIC_VERBOSE_IOAPIC_FLAG) {
- prom_printf("rebinding %x to %x",
- max_busy_irq->airq_vector, most_free_cpu);
- }
-#endif /* DEBUG */
- iflag = intr_clear();
- if (lock_try(&apic_ioapic_lock)) {
- if (apic_rebind_all(max_busy_irq,
- most_free_cpu) == 0) {
- /* Make change permenant */
- max_busy_irq->airq_cpu =
- (uchar_t)most_free_cpu;
- }
- lock_clear(&apic_ioapic_lock);
- }
- intr_restore(iflag);
-
- } else if (min_busy_irq != NULL) {
-#ifdef DEBUG
- if (apic_verbose & APIC_VERBOSE_IOAPIC_FLAG) {
- prom_printf("rebinding %x to %x",
- min_busy_irq->airq_vector, most_free_cpu);
- }
-#endif /* DEBUG */
-
- iflag = intr_clear();
- if (lock_try(&apic_ioapic_lock)) {
- if (apic_rebind_all(min_busy_irq,
- most_free_cpu) == 0) {
- /* Make change permenant */
- min_busy_irq->airq_cpu =
- (uchar_t)most_free_cpu;
- }
- lock_clear(&apic_ioapic_lock);
- }
- intr_restore(iflag);
-
- } else {
- if (cpu_busy != (1 << busiest_cpu)) {
- apic_redist_cpu_skip |= 1 << busiest_cpu;
- /*
- * We leave cpu_skip set so that next time we
- * can choose another cpu
- */
- }
- }
- apic_num_rebind++;
- } else {
- /*
- * found nothing. Could be that we skipped over valid CPUs
- * or we have balanced everything. If we had a variable
- * ticks_for_redistribution, it could be increased here.
- * apic_int_busy, int_free etc would also need to be
- * changed.
- */
- if (apic_redist_cpu_skip)
- apic_redist_cpu_skip = 0;
- }
- for (i = 0; i < apic_nproc; i++) {
- apic_cpus[i].aci_busy = 0;
- }
-}
-
-static void
-apic_cleanup_busy()
-{
- int i;
- apic_irq_t *irq_ptr;
-
- for (i = 0; i < apic_nproc; i++) {
- apic_cpus[i].aci_busy = 0;
- }
-
- for (i = apic_min_device_irq; i < apic_max_device_irq; i++) {
- if ((irq_ptr = apic_irq_table[i]) != NULL)
- irq_ptr->airq_busy = 0;
- }
- apic_skipped_redistribute = 0;
-}
-
/*
* This function will reprogram the timer.
@@ -5091,7 +1694,7 @@ apic_timer_reprogram(hrtime_t time)
{
hrtime_t now;
uint_t ticks;
- int64_t delta;
+ int64_t delta;
/*
* We should be called from high PIL context (CBE_HIGH_PIL),
@@ -5253,10 +1856,12 @@ apic_redistribute_compute(void)
* more empirical data to decide if that is a
* good strategy. Punt for now.
*/
- if (apic_skipped_redistribute)
+ if (apic_skipped_redistribute) {
apic_cleanup_busy();
- else
+ apic_skipped_redistribute = 0;
+ } else {
apic_intr_redistribute();
+ }
} else
apic_skipped_redistribute++;
}
@@ -5264,402 +1869,268 @@ apic_redistribute_compute(void)
}
-static int
-apic_acpi_translate_pci_irq(dev_info_t *dip, int busid, int devid,
- int ipin, int *pci_irqp, iflag_t *intr_flagp)
-{
-
- int status;
- acpi_psm_lnk_t acpipsmlnk;
-
- if ((status = acpi_get_irq_cache_ent(busid, devid, ipin, pci_irqp,
- intr_flagp)) == ACPI_PSM_SUCCESS) {
- APIC_VERBOSE_IRQ((CE_CONT, "!pcplusmp: Found irqno %d "
- "from cache for device %s, instance #%d\n", *pci_irqp,
- ddi_get_name(dip), ddi_get_instance(dip)));
- return (status);
- }
-
- bzero(&acpipsmlnk, sizeof (acpi_psm_lnk_t));
-
- if ((status = acpi_translate_pci_irq(dip, ipin, pci_irqp, intr_flagp,
- &acpipsmlnk)) == ACPI_PSM_FAILURE) {
- APIC_VERBOSE_IRQ((CE_WARN, "pcplusmp: "
- " acpi_translate_pci_irq failed for device %s, instance"
- " #%d", ddi_get_name(dip), ddi_get_instance(dip)));
- return (status);
- }
-
- if (status == ACPI_PSM_PARTIAL && acpipsmlnk.lnkobj != NULL) {
- status = apic_acpi_irq_configure(&acpipsmlnk, dip, pci_irqp,
- intr_flagp);
- if (status != ACPI_PSM_SUCCESS) {
- status = acpi_get_current_irq_resource(&acpipsmlnk,
- pci_irqp, intr_flagp);
- }
- }
-
- if (status == ACPI_PSM_SUCCESS) {
- acpi_new_irq_cache_ent(busid, devid, ipin, *pci_irqp,
- intr_flagp, &acpipsmlnk);
-
- APIC_VERBOSE_IRQ((CE_CONT, "pcplusmp: [ACPI] "
- "new irq %d for device %s, instance #%d\n",
- *pci_irqp, ddi_get_name(dip), ddi_get_instance(dip)));
- }
-
- return (status);
-}
+/*
+ * The following functions are in the platform specific file so that they
+ * can be different functions depending on whether we are running on
+ * bare metal or a hypervisor.
+ */
/*
- * Adds an entry to the irq list passed in, and returns the new list.
- * Entries are added in priority order (lower numerical priorities are
- * placed closer to the head of the list)
+ * map an apic for memory-mapped access
*/
-static prs_irq_list_t *
-acpi_insert_prs_irq_ent(prs_irq_list_t *listp, int priority, int irq,
- iflag_t *iflagp, acpi_prs_private_t *prsprvp)
+uint32_t *
+mapin_apic(uint32_t addr, size_t len, int flags)
{
- struct prs_irq_list_ent *newent, *prevp = NULL, *origlistp;
-
- newent = kmem_zalloc(sizeof (struct prs_irq_list_ent), KM_SLEEP);
-
- newent->list_prio = priority;
- newent->irq = irq;
- newent->intrflags = *iflagp;
- newent->prsprv = *prsprvp;
- /* ->next is NULL from kmem_zalloc */
-
- /*
- * New list -- return the new entry as the list.
- */
- if (listp == NULL)
- return (newent);
-
- /*
- * Save original list pointer for return (since we're not modifying
- * the head)
- */
- origlistp = listp;
-
- /*
- * Insertion sort, with entries with identical keys stored AFTER
- * existing entries (the less-than-or-equal test of priority does
- * this for us).
- */
- while (listp != NULL && listp->list_prio <= priority) {
- prevp = listp;
- listp = listp->next;
- }
-
- newent->next = listp;
+ /*LINTED: pointer cast may result in improper alignment */
+ return ((uint32_t *)psm_map_phys(addr, len, flags));
+}
- if (prevp == NULL) { /* Add at head of list (newent is the new head) */
- return (newent);
- } else {
- prevp->next = newent;
- return (origlistp);
- }
+uint32_t *
+mapin_ioapic(uint32_t addr, size_t len, int flags)
+{
+ return (mapin_apic(addr, len, flags));
}
/*
- * Frees the list passed in, deallocating all memory and leaving *listpp
- * set to NULL.
+ * unmap an apic
*/
-static void
-acpi_destroy_prs_irq_list(prs_irq_list_t **listpp)
+void
+mapout_apic(caddr_t addr, size_t len)
{
- struct prs_irq_list_ent *nextp;
-
- ASSERT(listpp != NULL);
+ psm_unmap_phys(addr, len);
+}
- while (*listpp != NULL) {
- nextp = (*listpp)->next;
- kmem_free(*listpp, sizeof (struct prs_irq_list_ent));
- *listpp = nextp;
- }
+void
+mapout_ioapic(caddr_t addr, size_t len)
+{
+ mapout_apic(addr, len);
}
/*
- * apic_choose_irqs_from_prs returns a list of irqs selected from the list of
- * irqs returned by the link device's _PRS method. The irqs are chosen
- * to minimize contention in situations where the interrupt link device
- * can be programmed to steer interrupts to different interrupt controller
- * inputs (some of which may already be in use). The list is sorted in order
- * of irqs to use, with the highest priority given to interrupt controller
- * inputs that are not shared. When an interrupt controller input
- * must be shared, apic_choose_irqs_from_prs adds the possible irqs to the
- * returned list in the order that minimizes sharing (thereby ensuring lowest
- * possible latency from interrupt trigger time to ISR execution time).
+ * This function allocate "count" vector(s) for the given "dip/pri/type"
*/
-static prs_irq_list_t *
-apic_choose_irqs_from_prs(acpi_irqlist_t *irqlistent, dev_info_t *dip,
- int crs_irq)
+int
+apic_alloc_vectors(dev_info_t *dip, int inum, int count, int pri, int type,
+ int behavior)
{
- int32_t irq;
- int i;
- prs_irq_list_t *prsirqlistp = NULL;
- iflag_t iflags;
-
- while (irqlistent != NULL) {
- irqlistent->intr_flags.bustype = BUS_PCI;
-
- for (i = 0; i < irqlistent->num_irqs; i++) {
-
- irq = irqlistent->irqs[i];
-
- if (irq <= 0) {
- /* invalid irq number */
- continue;
- }
+ int rcount, i;
+ uchar_t start, irqno, cpu;
+ major_t major;
+ apic_irq_t *irqptr;
- if ((irq < 16) && (apic_reserved_irqlist[irq]))
- continue;
+ /* only supports MSI at the moment, will add MSI-X support later */
+ if (type != DDI_INTR_TYPE_MSI)
+ return (0);
- if ((apic_irq_table[irq] == NULL) ||
- (apic_irq_table[irq]->airq_dip == dip)) {
+ DDI_INTR_IMPLDBG((CE_CONT, "apic_alloc_vectors: dip=0x%p type=%d "
+ "inum=0x%x pri=0x%x count=0x%x behavior=%d\n",
+ (void *)dip, type, inum, pri, count, behavior));
- prsirqlistp = acpi_insert_prs_irq_ent(
- prsirqlistp, 0 /* Highest priority */, irq,
- &irqlistent->intr_flags,
- &irqlistent->acpi_prs_prv);
+ if (count > 1) {
+ if (behavior == DDI_INTR_ALLOC_STRICT &&
+ (apic_multi_msi_enable == 0 || count > apic_multi_msi_max))
+ return (0);
- /*
- * If we do not prefer the current irq from _CRS
- * or if we do and this irq is the same as the
- * current irq from _CRS, this is the one
- * to pick.
- */
- if (!(apic_prefer_crs) || (irq == crs_irq)) {
- return (prsirqlistp);
- }
- continue;
- }
+ if (apic_multi_msi_enable == 0)
+ count = 1;
+ else if (count > apic_multi_msi_max)
+ count = apic_multi_msi_max;
+ }
- /*
- * Edge-triggered interrupts cannot be shared
- */
- if (irqlistent->intr_flags.intr_el == INTR_EL_EDGE)
- continue;
+ if ((rcount = apic_navail_vector(dip, pri)) > count)
+ rcount = count;
+ else if (rcount == 0 || (rcount < count &&
+ behavior == DDI_INTR_ALLOC_STRICT))
+ return (0);
- /*
- * To work around BIOSes that contain incorrect
- * interrupt polarity information in interrupt
- * descriptors returned by _PRS, we assume that
- * the polarity of the other device sharing this
- * interrupt controller input is compatible.
- * If it's not, the caller will catch it when
- * the caller invokes the link device's _CRS method
- * (after invoking its _SRS method).
- */
- iflags = irqlistent->intr_flags;
- iflags.intr_po =
- apic_irq_table[irq]->airq_iflag.intr_po;
+ /* if not ISP2, then round it down */
+ if (!ISP2(rcount))
+ rcount = 1 << (highbit(rcount) - 1);
- if (!acpi_intr_compatible(iflags,
- apic_irq_table[irq]->airq_iflag))
- continue;
+ mutex_enter(&airq_mutex);
- /*
- * If we prefer the irq from _CRS, no need
- * to search any further (and make sure
- * to add this irq with the highest priority
- * so it's tried first).
- */
- if (crs_irq == irq && apic_prefer_crs) {
+ for (start = 0; rcount > 0; rcount >>= 1) {
+ if ((start = apic_find_multi_vectors(pri, rcount)) != 0 ||
+ behavior == DDI_INTR_ALLOC_STRICT)
+ break;
+ }
- return (acpi_insert_prs_irq_ent(
- prsirqlistp,
- 0 /* Highest priority */,
- irq, &iflags,
- &irqlistent->acpi_prs_prv));
- }
+ if (start == 0) {
+ /* no vector available */
+ mutex_exit(&airq_mutex);
+ return (0);
+ }
- /*
- * Priority is equal to the share count (lower
- * share count is higher priority). Note that
- * the intr flags passed in here are the ones we
- * changed above -- if incorrect, it will be
- * caught by the caller's _CRS flags comparison.
- */
- prsirqlistp = acpi_insert_prs_irq_ent(
- prsirqlistp,
- apic_irq_table[irq]->airq_share, irq,
- &iflags, &irqlistent->acpi_prs_prv);
+ major = (dip != NULL) ? ddi_name_to_major(ddi_get_name(dip)) : 0;
+ for (i = 0; i < rcount; i++) {
+ if ((irqno = apic_allocate_irq(apic_first_avail_irq)) ==
+ (uchar_t)-1) {
+ mutex_exit(&airq_mutex);
+ DDI_INTR_IMPLDBG((CE_CONT, "apic_alloc_vectors: "
+ "apic_allocate_irq failed\n"));
+ return (i);
}
-
- /* Go to the next irqlist entry */
- irqlistent = irqlistent->next;
+ apic_max_device_irq = max(irqno, apic_max_device_irq);
+ apic_min_device_irq = min(irqno, apic_min_device_irq);
+ irqptr = apic_irq_table[irqno];
+#ifdef DEBUG
+ if (apic_vector_to_irq[start + i] != APIC_RESV_IRQ)
+ DDI_INTR_IMPLDBG((CE_CONT, "apic_alloc_vectors: "
+ "apic_vector_to_irq is not APIC_RESV_IRQ\n"));
+#endif
+ apic_vector_to_irq[start + i] = (uchar_t)irqno;
+
+ irqptr->airq_vector = (uchar_t)(start + i);
+ irqptr->airq_ioapicindex = (uchar_t)inum; /* start */
+ irqptr->airq_intin_no = (uchar_t)rcount;
+ irqptr->airq_ipl = pri;
+ irqptr->airq_vector = start + i;
+ irqptr->airq_origirq = (uchar_t)(inum + i);
+ irqptr->airq_share_id = 0;
+ irqptr->airq_mps_intr_index = MSI_INDEX;
+ irqptr->airq_dip = dip;
+ irqptr->airq_major = major;
+ if (i == 0) /* they all bound to the same cpu */
+ cpu = irqptr->airq_cpu = apic_bind_intr(dip, irqno,
+ 0xff, 0xff);
+ else
+ irqptr->airq_cpu = cpu;
+ DDI_INTR_IMPLDBG((CE_CONT, "apic_alloc_vectors: irq=0x%x "
+ "dip=0x%p vector=0x%x origirq=0x%x pri=0x%x\n", irqno,
+ (void *)irqptr->airq_dip, irqptr->airq_vector,
+ irqptr->airq_origirq, pri));
}
-
- return (prsirqlistp);
+ mutex_exit(&airq_mutex);
+ return (rcount);
}
/*
- * Configures the irq for the interrupt link device identified by
- * acpipsmlnkp.
- *
- * Gets the current and the list of possible irq settings for the
- * device. If apic_unconditional_srs is not set, and the current
- * resource setting is in the list of possible irq settings,
- * current irq resource setting is passed to the caller.
- *
- * Otherwise, picks an irq number from the list of possible irq
- * settings, and sets the irq of the device to this value.
- * If prefer_crs is set, among a set of irq numbers in the list that have
- * the least number of devices sharing the interrupt, we pick current irq
- * resource setting if it is a member of this set.
- *
- * Passes the irq number in the value pointed to by pci_irqp, and
- * polarity and sensitivity in the structure pointed to by dipintrflagp
- * to the caller.
- *
- * Note that if setting the irq resource failed, but successfuly obtained
- * the current irq resource settings, passes the current irq resources
- * and considers it a success.
- *
- * Returns:
- * ACPI_PSM_SUCCESS on success.
- *
- * ACPI_PSM_FAILURE if an error occured during the configuration or
- * if a suitable irq was not found for this device, or if setting the
- * irq resource and obtaining the current resource fails.
- *
+ * Allocate a free vector for irq at ipl. Takes care of merging of multiple
+ * IPLs into a single APIC level as well as stretching some IPLs onto multiple
+ * levels. APIC_HI_PRI_VECTS interrupts are reserved for high priority
+ * requests and allocated only when pri is set.
*/
-static int
-apic_acpi_irq_configure(acpi_psm_lnk_t *acpipsmlnkp, dev_info_t *dip,
- int *pci_irqp, iflag_t *dipintr_flagp)
+uchar_t
+apic_allocate_vector(int ipl, int irq, int pri)
{
+ int lowest, highest, i;
- int32_t irq;
- int cur_irq = -1;
- acpi_irqlist_t *irqlistp;
- prs_irq_list_t *prs_irq_listp, *prs_irq_entp;
- boolean_t found_irq = B_FALSE;
+ highest = apic_ipltopri[ipl] + APIC_VECTOR_MASK;
+ lowest = apic_ipltopri[ipl - 1] + APIC_VECTOR_PER_IPL;
- dipintr_flagp->bustype = BUS_PCI;
+ if (highest < lowest) /* Both ipl and ipl - 1 map to same pri */
+ lowest -= APIC_VECTOR_PER_IPL;
- if ((acpi_get_possible_irq_resources(acpipsmlnkp, &irqlistp))
- == ACPI_PSM_FAILURE) {
- APIC_VERBOSE_IRQ((CE_WARN, "!pcplusmp: Unable to determine "
- "or assign IRQ for device %s, instance #%d: The system was "
- "unable to get the list of potential IRQs from ACPI.",
- ddi_get_name(dip), ddi_get_instance(dip)));
+#ifdef DEBUG
+ if (apic_restrict_vector) /* for testing shared interrupt logic */
+ highest = lowest + apic_restrict_vector + APIC_HI_PRI_VECTS;
+#endif /* DEBUG */
+ if (pri == 0)
+ highest -= APIC_HI_PRI_VECTS;
- return (ACPI_PSM_FAILURE);
+ for (i = lowest; i < highest; i++) {
+ if (APIC_CHECK_RESERVE_VECTORS(i))
+ continue;
+ if (apic_vector_to_irq[i] == APIC_RESV_IRQ) {
+ apic_vector_to_irq[i] = (uchar_t)irq;
+ return (i);
+ }
}
- if ((acpi_get_current_irq_resource(acpipsmlnkp, &cur_irq,
- dipintr_flagp) == ACPI_PSM_SUCCESS) && (!apic_unconditional_srs) &&
- (cur_irq > 0)) {
- /*
- * If an IRQ is set in CRS and that IRQ exists in the set
- * returned from _PRS, return that IRQ, otherwise print
- * a warning
- */
-
- if (acpi_irqlist_find_irq(irqlistp, cur_irq, NULL)
- == ACPI_PSM_SUCCESS) {
-
- ASSERT(pci_irqp != NULL);
- *pci_irqp = cur_irq;
- acpi_free_irqlist(irqlistp);
- return (ACPI_PSM_SUCCESS);
- }
+ return (0);
+}
- APIC_VERBOSE_IRQ((CE_WARN, "!pcplusmp: Could not find the "
- "current irq %d for device %s, instance #%d in ACPI's "
- "list of possible irqs for this device. Picking one from "
- " the latter list.", cur_irq, ddi_get_name(dip),
- ddi_get_instance(dip)));
- }
+/* Mark vector as not being used by any irq */
+void
+apic_free_vector(uchar_t vector)
+{
+ apic_vector_to_irq[vector] = APIC_RESV_IRQ;
+}
- if ((prs_irq_listp = apic_choose_irqs_from_prs(irqlistp, dip,
- cur_irq)) == NULL) {
+uint32_t
+ioapic_read(int ioapic_ix, uint32_t reg)
+{
+ volatile uint32_t *ioapic;
- APIC_VERBOSE_IRQ((CE_WARN, "!pcplusmp: Could not find a "
- "suitable irq from the list of possible irqs for device "
- "%s, instance #%d in ACPI's list of possible irqs",
- ddi_get_name(dip), ddi_get_instance(dip)));
+ ioapic = apicioadr[ioapic_ix];
+ ioapic[APIC_IO_REG] = reg;
+ return (ioapic[APIC_IO_DATA]);
+}
- acpi_free_irqlist(irqlistp);
- return (ACPI_PSM_FAILURE);
- }
+void
+ioapic_write(int ioapic_ix, uint32_t reg, uint32_t value)
+{
+ volatile uint32_t *ioapic;
- acpi_free_irqlist(irqlistp);
+ ioapic = apicioadr[ioapic_ix];
+ ioapic[APIC_IO_REG] = reg;
+ ioapic[APIC_IO_DATA] = value;
+}
- for (prs_irq_entp = prs_irq_listp;
- prs_irq_entp != NULL && found_irq == B_FALSE;
- prs_irq_entp = prs_irq_entp->next) {
+static processorid_t
+apic_find_cpu(int flag)
+{
+ processorid_t acid = 0;
+ int i;
- acpipsmlnkp->acpi_prs_prv = prs_irq_entp->prsprv;
- irq = prs_irq_entp->irq;
+ /* Find the first CPU with the passed-in flag set */
+ for (i = 0; i < apic_nproc; i++) {
+ if (apic_cpus[i].aci_status & flag) {
+ acid = i;
+ break;
+ }
+ }
- APIC_VERBOSE_IRQ((CE_CONT, "!pcplusmp: Setting irq %d for "
- "device %s instance #%d\n", irq, ddi_get_name(dip),
- ddi_get_instance(dip)));
+ ASSERT((apic_cpus[acid].aci_status & flag) != 0);
+ return (acid);
+}
- if ((acpi_set_irq_resource(acpipsmlnkp, irq))
- == ACPI_PSM_SUCCESS) {
- /*
- * setting irq was successful, check to make sure CRS
- * reflects that. If CRS does not agree with what we
- * set, return the irq that was set.
- */
+/*
+ * Call rebind to do the actual programming.
+ * Must be called with interrupts disabled and apic_ioapic_lock held
+ * 'p' is polymorphic -- if this function is called to process a deferred
+ * reprogramming, p is of type 'struct ioapic_reprogram_data *', from which
+ * the irq pointer is retrieved. If not doing deferred reprogramming,
+ * p is of the type 'apic_irq_t *'.
+ *
+ * apic_ioapic_lock must be held across this call, as it protects apic_rebind
+ * and it protects apic_find_cpu() from a race in which a CPU can be taken
+ * offline after a cpu is selected, but before apic_rebind is called to
+ * bind interrupts to it.
+ */
+int
+apic_setup_io_intr(void *p, int irq, boolean_t deferred)
+{
+ apic_irq_t *irqptr;
+ struct ioapic_reprogram_data *drep = NULL;
+ int rv;
- if (acpi_get_current_irq_resource(acpipsmlnkp, &cur_irq,
- dipintr_flagp) == ACPI_PSM_SUCCESS) {
-
- if (cur_irq != irq)
- APIC_VERBOSE_IRQ((CE_WARN,
- "!pcplusmp: IRQ resource set "
- "(irqno %d) for device %s "
- "instance #%d, differs from "
- "current setting irqno %d",
- irq, ddi_get_name(dip),
- ddi_get_instance(dip), cur_irq));
- } else {
- /*
- * On at least one system, there was a bug in
- * a DSDT method called by _STA, causing _STA to
- * indicate that the link device was disabled
- * (when, in fact, it was enabled). Since _SRS
- * succeeded, assume that _CRS is lying and use
- * the iflags from this _PRS interrupt choice.
- * If we're wrong about the flags, the polarity
- * will be incorrect and we may get an interrupt
- * storm, but there's not much else we can do
- * at this point.
- */
- *dipintr_flagp = prs_irq_entp->intrflags;
- }
+ if (deferred) {
+ drep = (struct ioapic_reprogram_data *)p;
+ ASSERT(drep != NULL);
+ irqptr = drep->irqp;
+ } else
+ irqptr = (apic_irq_t *)p;
- /*
- * Return the irq that was set, and not what _CRS
- * reports, since _CRS has been seen to return
- * different IRQs than what was passed to _SRS on some
- * systems (and just not return successfully on others).
- */
- cur_irq = irq;
- found_irq = B_TRUE;
- } else {
- APIC_VERBOSE_IRQ((CE_WARN, "!pcplusmp: set resource "
- "irq %d failed for device %s instance #%d",
- irq, ddi_get_name(dip), ddi_get_instance(dip)));
+ ASSERT(irqptr != NULL);
- if (cur_irq == -1) {
- acpi_destroy_prs_irq_list(&prs_irq_listp);
- return (ACPI_PSM_FAILURE);
- }
- }
+ rv = apic_rebind(irqptr, apic_irq_table[irq]->airq_cpu, drep);
+ if (rv) {
+ /*
+ * CPU is not up or interrupts are disabled. Fall back to
+ * the first available CPU
+ */
+ rv = apic_rebind(irqptr, apic_find_cpu(APIC_CPU_INTR_ENABLE),
+ drep);
}
- acpi_destroy_prs_irq_list(&prs_irq_listp);
+ return (rv);
+}
- if (!found_irq)
- return (ACPI_PSM_FAILURE);
- ASSERT(pci_irqp != NULL);
- *pci_irqp = cur_irq;
- return (ACPI_PSM_SUCCESS);
+uchar_t
+apic_modify_vector(uchar_t vector, int irq)
+{
+ apic_vector_to_irq[vector] = (uchar_t)irq;
+ return (vector);
}
diff --git a/usr/src/uts/i86pc/io/pcplusmp/apic_introp.c b/usr/src/uts/i86pc/io/pcplusmp/apic_introp.c
index 742779383a..02617ae071 100644
--- a/usr/src/uts/i86pc/io/pcplusmp/apic_introp.c
+++ b/usr/src/uts/i86pc/io/pcplusmp/apic_introp.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,7 +32,8 @@
#include <sys/cpuvar.h>
#include <sys/psm.h>
-#include "apic.h"
+#include <sys/archsystm.h>
+#include <sys/apic.h>
#include <sys/sunddi.h>
#include <sys/ddi_impldefs.h>
#include <sys/mach_intr.h>
@@ -52,15 +53,6 @@ apic_irq_t *apic_find_irq(dev_info_t *, struct intrspec *, int);
static int apic_get_pending(apic_irq_t *, int);
static void apic_clear_mask(apic_irq_t *);
static void apic_set_mask(apic_irq_t *);
-static uchar_t apic_find_multi_vectors(int, int);
-int apic_navail_vector(dev_info_t *, int);
-int apic_alloc_vectors(dev_info_t *, int, int, int, int, int);
-void apic_free_vectors(dev_info_t *, int, int, int, int);
-int apic_intr_ops(dev_info_t *, ddi_intr_handle_impl_t *,
- psm_intr_op_t, int *);
-
-extern int intr_clear(void);
-extern void intr_restore(uint_t);
/*
* MSI support flag:
@@ -78,19 +70,6 @@ int apic_support_msi = 0;
int apic_multi_msi_enable = 1;
int apic_multi_msi_max = 2;
-extern uchar_t apic_ipltopri[MAXIPL+1];
-extern uchar_t apic_vector_to_irq[APIC_MAX_VECTOR+1];
-extern int apic_max_device_irq;
-extern int apic_min_device_irq;
-extern apic_irq_t *apic_irq_table[APIC_MAX_VECTOR+1];
-extern volatile uint32_t *apicadr; /* virtual addr of local APIC */
-extern volatile int32_t *apicioadr[MAX_IO_APIC];
-extern lock_t apic_ioapic_lock;
-extern kmutex_t airq_mutex;
-extern apic_cpus_info_t *apic_cpus;
-extern int apic_first_avail_irq;
-
-
/*
* apic_pci_msi_enable_vector:
* Set the address/data fields in the MSI/X capability structure
@@ -202,7 +181,7 @@ apic_navail_vector(dev_info_t *dip, int pri)
* Caller needs to make sure that count has to be power of 2 and should not
* be < 1.
*/
-static uchar_t
+uchar_t
apic_find_multi_vectors(int pri, int count)
{
int lowest, highest, i, navail, start, msibits;
@@ -245,6 +224,7 @@ apic_find_multi_vectors(int pri, int count)
return (0);
}
+
/*
* It finds the apic_irq_t associates with the dip, ispec and type.
*/
@@ -288,7 +268,7 @@ apic_get_pending(apic_irq_t *irqp, int type)
{
int bit, index, irr, pending;
int intin_no;
- volatile int32_t *ioapic;
+ int apic_ix;
DDI_INTR_IMPLDBG((CE_CONT, "apic_get_pending: irqp: %p, cpuid: %x "
"type: %x\n", (void *)irqp, irqp->airq_cpu & ~IRQ_USER_BOUND,
@@ -309,8 +289,8 @@ apic_get_pending(apic_irq_t *irqp, int type)
if (!pending && (type == DDI_INTR_TYPE_FIXED)) {
/* check I/O APIC for fixed interrupt */
intin_no = irqp->airq_intin_no;
- ioapic = apicioadr[irqp->airq_ioapicindex];
- pending = (READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no) &
+ apic_ix = irqp->airq_ioapicindex;
+ pending = (READ_IOAPIC_RDT_ENTRY_LOW_DWORD(apic_ix, intin_no) &
AV_PENDING) ? 1 : 0;
}
return (pending);
@@ -324,23 +304,23 @@ static void
apic_clear_mask(apic_irq_t *irqp)
{
int intin_no;
- int iflag;
+ ulong_t iflag;
int32_t rdt_entry;
- volatile int32_t *ioapic;
+ int apic_ix;
DDI_INTR_IMPLDBG((CE_CONT, "apic_clear_mask: irqp: %p\n",
(void *)irqp));
intin_no = irqp->airq_intin_no;
- ioapic = apicioadr[irqp->airq_ioapicindex];
+ apic_ix = irqp->airq_ioapicindex;
iflag = intr_clear();
lock_set(&apic_ioapic_lock);
- rdt_entry = READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no);
+ rdt_entry = READ_IOAPIC_RDT_ENTRY_LOW_DWORD(apic_ix, intin_no);
/* clear mask */
- WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no,
+ WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(apic_ix, intin_no,
((~AV_MASK) & rdt_entry));
lock_clear(&apic_ioapic_lock);
@@ -355,23 +335,23 @@ static void
apic_set_mask(apic_irq_t *irqp)
{
int intin_no;
- volatile int32_t *ioapic;
- int iflag;
+ int apic_ix;
+ ulong_t iflag;
int32_t rdt_entry;
DDI_INTR_IMPLDBG((CE_CONT, "apic_set_mask: irqp: %p\n", (void *)irqp));
intin_no = irqp->airq_intin_no;
- ioapic = apicioadr[irqp->airq_ioapicindex];
+ apic_ix = irqp->airq_ioapicindex;
iflag = intr_clear();
lock_set(&apic_ioapic_lock);
- rdt_entry = READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no);
+ rdt_entry = READ_IOAPIC_RDT_ENTRY_LOW_DWORD(apic_ix, intin_no);
/* mask it */
- WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic, intin_no,
+ WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(apic_ix, intin_no,
(AV_MASK | rdt_entry));
lock_clear(&apic_ioapic_lock);
@@ -379,105 +359,6 @@ apic_set_mask(apic_irq_t *irqp)
}
-/*
- * This function allocate "count" vector(s) for the given "dip/pri/type"
- */
-int
-apic_alloc_vectors(dev_info_t *dip, int inum, int count, int pri, int type,
- int behavior)
-{
- int rcount, i;
- uchar_t start, irqno, cpu;
- major_t major;
- apic_irq_t *irqptr;
-
- /* only supports MSI at the moment, will add MSI-X support later */
- if (type != DDI_INTR_TYPE_MSI)
- return (0);
-
- DDI_INTR_IMPLDBG((CE_CONT, "apic_alloc_vectors: dip=0x%p type=%d "
- "inum=0x%x pri=0x%x count=0x%x behavior=%d\n",
- (void *)dip, type, inum, pri, count, behavior));
-
- if (count > 1) {
- if (behavior == DDI_INTR_ALLOC_STRICT &&
- (apic_multi_msi_enable == 0 || count > apic_multi_msi_max))
- return (0);
-
- if (apic_multi_msi_enable == 0)
- count = 1;
- else if (count > apic_multi_msi_max)
- count = apic_multi_msi_max;
- }
-
- if ((rcount = apic_navail_vector(dip, pri)) > count)
- rcount = count;
- else if (rcount == 0 || (rcount < count &&
- behavior == DDI_INTR_ALLOC_STRICT))
- return (0);
-
- /* if not ISP2, then round it down */
- if (!ISP2(rcount))
- rcount = 1 << (highbit(rcount) - 1);
-
- mutex_enter(&airq_mutex);
-
- for (start = 0; rcount > 0; rcount >>= 1) {
- if ((start = apic_find_multi_vectors(pri, rcount)) != 0 ||
- behavior == DDI_INTR_ALLOC_STRICT)
- break;
- }
-
- if (start == 0) {
- /* no vector available */
- mutex_exit(&airq_mutex);
- return (0);
- }
-
- major = (dip != NULL) ? ddi_name_to_major(ddi_get_name(dip)) : 0;
- for (i = 0; i < rcount; i++) {
- if ((irqno = apic_allocate_irq(apic_first_avail_irq)) ==
- (uchar_t)-1) {
- mutex_exit(&airq_mutex);
- DDI_INTR_IMPLDBG((CE_CONT, "apic_alloc_vectors: "
- "apic_allocate_irq failed\n"));
- return (i);
- }
- apic_max_device_irq = max(irqno, apic_max_device_irq);
- apic_min_device_irq = min(irqno, apic_min_device_irq);
- irqptr = apic_irq_table[irqno];
-#ifdef DEBUG
- if (apic_vector_to_irq[start + i] != APIC_RESV_IRQ)
- DDI_INTR_IMPLDBG((CE_CONT, "apic_alloc_vectors: "
- "apic_vector_to_irq is not APIC_RESV_IRQ\n"));
-#endif
- apic_vector_to_irq[start + i] = (uchar_t)irqno;
-
- irqptr->airq_vector = (uchar_t)(start + i);
- irqptr->airq_ioapicindex = (uchar_t)inum; /* start */
- irqptr->airq_intin_no = (uchar_t)rcount;
- irqptr->airq_ipl = pri;
- irqptr->airq_vector = start + i;
- irqptr->airq_origirq = (uchar_t)(inum + i);
- irqptr->airq_share_id = 0;
- irqptr->airq_mps_intr_index = MSI_INDEX;
- irqptr->airq_dip = dip;
- irqptr->airq_major = major;
- if (i == 0) /* they all bound to the same cpu */
- cpu = irqptr->airq_cpu = apic_bind_intr(dip, irqno,
- 0xff, 0xff);
- else
- irqptr->airq_cpu = cpu;
- DDI_INTR_IMPLDBG((CE_CONT, "apic_alloc_vectors: irq=0x%x "
- "dip=0x%p vector=0x%x origirq=0x%x pri=0x%x\n", irqno,
- (void *)irqptr->airq_dip, irqptr->airq_vector,
- irqptr->airq_origirq, pri));
- }
- mutex_exit(&airq_mutex);
- return (rcount);
-}
-
-
void
apic_free_vectors(dev_info_t *dip, int inum, int count, int pri, int type)
{
@@ -794,6 +675,7 @@ apic_pci_msi_disable_mode(dev_info_t *rdip, int type, int inum)
return (PSM_SUCCESS);
}
+
/*
* This function provides external interface to the nexus for all
* functionalities related to the new DDI interrupt framework.
@@ -920,7 +802,7 @@ apic_intr_ops(dev_info_t *dip, ddi_intr_handle_impl_t *hdlp,
hdlp->ih_scratch1, new_priority, hdlp->ih_type,
DDI_INTR_ALLOC_STRICT);
- /* Did we get the new vectors? */
+ /* Did we get new vectors? */
if (!count_vec)
return (PSM_FAILURE);
diff --git a/usr/src/uts/i86pc/io/psm/uppc.c b/usr/src/uts/i86pc/io/psm/uppc.c
index 6556f3eec4..ac7fb4f399 100644
--- a/usr/src/uts/i86pc/io/psm/uppc.c
+++ b/usr/src/uts/i86pc/io/psm/uppc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,16 +38,11 @@
#include <sys/pit.h>
#include <sys/psm_common.h>
#include <sys/atomic.h>
+#include <sys/archsystm.h>
#define NSEC_IN_SEC 1000000000
/*
- * External References
- */
-extern int intr_clear(void);
-extern void intr_restore(uint_t);
-
-/*
* Local Function Prototypes
*/
static void uppc_softinit(void);
@@ -158,7 +153,7 @@ static struct psm_ops uppc_ops = {
uppc_gethrtime, /* psm_gethrtime */
uppc_get_next_processorid, /* psm_get_next_processorid */
- (void (*)(processorid_t, caddr_t))NULL, /* psm_cpu_start */
+ (int (*)(processorid_t, caddr_t))NULL, /* psm_cpu_start */
(int (*)(void))NULL, /* psm_post_cpu_start */
uppc_shutdown, /* psm_shutdown */
(int (*)(int, int))NULL, /* psm_get_ipivect */
@@ -166,9 +161,6 @@ static struct psm_ops uppc_ops = {
uppc_translate_irq, /* psm_translate_irq */
- (int (*)(todinfo_t *))NULL, /* psm_tod_get */
- (int (*)(todinfo_t *))NULL, /* psm_tod_set */
-
(void (*)(int, char *))NULL, /* psm_notify_error */
(void (*)(int msg))NULL, /* psm_notify_func */
(void (*)(hrtime_t time))NULL, /* psm_timer_reprogram */
@@ -801,7 +793,6 @@ uppc_translate_irq(dev_info_t *dip, int irqno)
UPPC_VERBOSE_IRQ((CE_CONT, "!uppc: non-pci,"
"irqno %d device %s instance %d\n", irqno,
ddi_get_name(dip), ddi_get_instance(dip)));
-
}
return (irqno);
@@ -922,7 +913,8 @@ static hrtime_t
uppc_gethrtime()
{
hrtime_t timeval, temp;
- unsigned int oflags, ctr0;
+ unsigned int ctr0;
+ ulong_t oflags;
oflags = intr_clear(); /* disable ints */
lock_set(&uppc_gethrtime_lock);
diff --git a/usr/src/uts/common/io/hardclk.c b/usr/src/uts/i86pc/io/todpc_subr.c
index c1dedf6801..7e55876af3 100644
--- a/usr/src/uts/common/io/hardclk.c
+++ b/usr/src/uts/i86pc/io/todpc_subr.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -47,32 +47,27 @@
#include <sys/stat.h>
#include <sys/sunddi.h>
-static int pc_rtcget(unsigned char *buf);
-static void pc_rtcput(unsigned char *buf);
-
-#define CLOCK_RES 1000 /* 1 microsec in nanosecs */
-
-int clock_res = CLOCK_RES;
+static int todpc_rtcget(unsigned char *buf);
+static void todpc_rtcput(unsigned char *buf);
/*
* Machine-dependent clock routines.
*/
-extern long gmt_lag;
-
/*
* Write the specified time into the clock chip.
* Must be called with tod_lock held.
*/
-void
-pc_tod_set(timestruc_t ts)
+/*ARGSUSED*/
+static void
+todpc_set(tod_ops_t *top, timestruc_t ts)
{
- todinfo_t tod = utc_to_tod(ts.tv_sec - gmt_lag);
+ todinfo_t tod = utc_to_tod(ts.tv_sec - ggmtl());
struct rtc_t rtc;
ASSERT(MUTEX_HELD(&tod_lock));
- if (pc_rtcget((unsigned char *)&rtc))
+ if (todpc_rtcget((unsigned char *)&rtc))
return;
/*
@@ -95,7 +90,7 @@ pc_tod_set(timestruc_t ts)
rtc.rtc_min = BYTE_TO_BCD(tod.tod_min);
rtc.rtc_sec = BYTE_TO_BCD(tod.tod_sec);
- pc_rtcput((unsigned char *)&rtc);
+ todpc_rtcput((unsigned char *)&rtc);
}
/*
@@ -103,8 +98,9 @@ pc_tod_set(timestruc_t ts)
* Assumes that the year in the clock chip is valid.
* Must be called with tod_lock held.
*/
-timestruc_t
-pc_tod_get(void)
+/*ARGSUSED*/
+static timestruc_t
+todpc_get(tod_ops_t *top)
{
timestruc_t ts;
todinfo_t tod;
@@ -115,7 +111,7 @@ pc_tod_get(void)
ASSERT(MUTEX_HELD(&tod_lock));
- if (pc_rtcget((unsigned char *)&rtc)) {
+ if (todpc_rtcget((unsigned char *)&rtc)) {
ts.tv_sec = 0;
ts.tv_nsec = 0;
tod_fault_reset();
@@ -154,7 +150,7 @@ pc_tod_get(void)
tod.tod_min = BCD_TO_BYTE(rtc.rtc_min);
tod.tod_sec = BCD_TO_BYTE(rtc.rtc_sec);
- ts.tv_sec = tod_to_utc(tod) + gmt_lag;
+ ts.tv_sec = tod_to_utc(tod) + ggmtl();
ts.tv_nsec = 0;
return (ts);
@@ -162,7 +158,7 @@ pc_tod_get(void)
/*
* Routine to read contents of real time clock to the specified buffer.
- * Returns -1 if clock not valid, or -2 if clock data cannot be read
+ * Returns ENXIO if clock not valid, or EAGAIN if clock data cannot be read
* else 0.
* The routine will busy wait for the Update-In-Progress flag to clear.
* On completion of the reads the Seconds register is re-read and the
@@ -174,7 +170,7 @@ pc_tod_get(void)
*/
static int
-pc_rtcget(unsigned char *buf)
+todpc_rtcget(unsigned char *buf)
{
unsigned char reg;
int i;
@@ -186,11 +182,11 @@ pc_rtcget(unsigned char *buf)
outb(RTC_ADDR, RTC_D); /* check if clock valid */
reg = inb(RTC_DATA);
if ((reg & RTC_VRT) == 0)
- return (-1);
+ return (ENXIO);
checkuip:
if (retries-- < 0)
- return (-2);
+ return (EAGAIN);
outb(RTC_ADDR, RTC_A); /* check if update in progress */
reg = inb(RTC_DATA);
if (reg & RTC_UIP) {
@@ -221,7 +217,7 @@ checkuip:
* raised to 5.
*/
static void
-pc_rtcput(unsigned char *buf)
+todpc_rtcput(unsigned char *buf)
{
unsigned char reg;
int i;
@@ -240,22 +236,15 @@ pc_rtcput(unsigned char *buf)
outb(RTC_DATA, reg & ~RTC_SET); /* allow time update */
}
+static tod_ops_t todpc_ops = {
+ TOD_OPS_VERSION,
+ todpc_get,
+ todpc_set,
+ NULL
+};
+
/*
- * The following wrappers have been added so that locking
- * can be exported to platform-independent clock routines
- * (ie adjtime(), clock_setttime()), via a functional interface.
+ * Initialize for the default TOD ops vector for use on hardware.
*/
-int
-hr_clock_lock(void)
-{
- ushort_t s;
-
- CLOCK_LOCK(&s);
- return (s);
-}
-void
-hr_clock_unlock(int s)
-{
- CLOCK_UNLOCK(s);
-}
+tod_ops_t *tod_ops = &todpc_ops;
diff --git a/usr/src/uts/i86pc/io/xsvc/xsvc.c b/usr/src/uts/i86pc/io/xsvc/xsvc.c
new file mode 100644
index 0000000000..2b797dc904
--- /dev/null
+++ b/usr/src/uts/i86pc/io/xsvc/xsvc.c
@@ -0,0 +1,974 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/kmem.h>
+#include <sys/ddi.h>
+#include <sys/stat.h>
+#include <sys/sunddi.h>
+#include <sys/file.h>
+#include <sys/open.h>
+#include <sys/modctl.h>
+#include <sys/ddi_impldefs.h>
+#include <vm/seg_kmem.h>
+#include <sys/vmsystm.h>
+#include <sys/sysmacros.h>
+#include <sys/ddidevmap.h>
+#include <sys/avl.h>
+
+#include <sys/xsvc.h>
+
+/* total max memory which can be alloced with ioctl interface */
+uint64_t xsvc_max_memory = 10 * 1024 * 1024;
+
+extern void i86_va_map(caddr_t vaddr, struct as *asp, caddr_t kaddr);
+
+
+static int xsvc_open(dev_t *devp, int flag, int otyp, cred_t *cred);
+static int xsvc_close(dev_t devp, int flag, int otyp, cred_t *cred);
+static int xsvc_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred,
+ int *rval);
+static int xsvc_devmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t len,
+ size_t *maplen, uint_t model);
+static int xsvc_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);
+static int xsvc_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
+static int xsvc_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
+ void **result);
+
+static struct cb_ops xsvc_cb_ops = {
+ xsvc_open, /* cb_open */
+ xsvc_close, /* cb_close */
+ nodev, /* cb_strategy */
+ nodev, /* cb_print */
+ nodev, /* cb_dump */
+ nodev, /* cb_read */
+ nodev, /* cb_write */
+ xsvc_ioctl, /* cb_ioctl */
+ xsvc_devmap, /* cb_devmap */
+ NULL, /* cb_mmap */
+ NULL, /* cb_segmap */
+ nochpoll, /* cb_chpoll */
+ ddi_prop_op, /* cb_prop_op */
+ NULL, /* cb_stream */
+ D_NEW | D_MP | D_64BIT | D_DEVMAP, /* cb_flag */
+ CB_REV
+};
+
+static struct dev_ops xsvc_dev_ops = {
+ DEVO_REV, /* devo_rev */
+ 0, /* devo_refcnt */
+ xsvc_getinfo, /* devo_getinfo */
+ nulldev, /* devo_identify */
+ nulldev, /* devo_probe */
+ xsvc_attach, /* devo_attach */
+ xsvc_detach, /* devo_detach */
+ nodev, /* devo_reset */
+ &xsvc_cb_ops, /* devo_cb_ops */
+ NULL, /* devo_bus_ops */
+ NULL /* power */
+};
+
+static struct modldrv xsvc_modldrv = {
+ &mod_driverops, /* Type of module. This one is a driver */
+ "xsvc driver v%I%", /* Name of the module. */
+ &xsvc_dev_ops, /* driver ops */
+};
+
+static struct modlinkage xsvc_modlinkage = {
+ MODREV_1,
+ (void *) &xsvc_modldrv,
+ NULL
+};
+
+
+static int xsvc_ioctl_alloc_memory(xsvc_state_t *state, void *arg, int mode);
+static int xsvc_ioctl_flush_memory(xsvc_state_t *state, void *arg, int mode);
+static int xsvc_ioctl_free_memory(xsvc_state_t *state, void *arg, int mode);
+static int xsvc_mem_alloc(xsvc_state_t *state, uint64_t key,
+ xsvc_mem_t **mp);
+static void xsvc_mem_free(xsvc_state_t *state, xsvc_mem_t *mp);
+static xsvc_mem_t *xsvc_mem_lookup(xsvc_state_t *state,
+ uint64_t key);
+static int xsvc_mnode_key_compare(const void *q, const void *e);
+static int xsvc_umem_cookie_alloc(caddr_t kva, size_t size, int flags,
+ ddi_umem_cookie_t *cookiep);
+static void xsvc_umem_cookie_free(ddi_umem_cookie_t *cookiep);
+static void xsvc_devmap_unmap(devmap_cookie_t dhp, void *pvtp, offset_t off,
+ size_t len, devmap_cookie_t new_dhp1, void **new_pvtp1,
+ devmap_cookie_t new_dhp2, void **new_pvtp2);
+
+
+void *xsvc_statep;
+
+static ddi_device_acc_attr_t xsvc_device_attr = {
+ DDI_DEVICE_ATTR_V0,
+ DDI_NEVERSWAP_ACC,
+ DDI_STRICTORDER_ACC
+};
+
+static struct devmap_callback_ctl xsvc_callbk = {
+ DEVMAP_OPS_REV,
+ NULL,
+ NULL,
+ NULL,
+ xsvc_devmap_unmap
+};
+
+
+/*
+ * _init()
+ *
+ */
+int
+_init(void)
+{
+ int err;
+
+ err = ddi_soft_state_init(&xsvc_statep, sizeof (xsvc_state_t), 1);
+ if (err != 0) {
+ return (err);
+ }
+
+ err = mod_install(&xsvc_modlinkage);
+ if (err != 0) {
+ ddi_soft_state_fini(&xsvc_statep);
+ return (err);
+ }
+
+ return (0);
+}
+
+/*
+ * _info()
+ *
+ */
+int
+_info(struct modinfo *modinfop)
+{
+ return (mod_info(&xsvc_modlinkage, modinfop));
+}
+
+/*
+ * _fini()
+ *
+ */
+int
+_fini(void)
+{
+ int err;
+
+ err = mod_remove(&xsvc_modlinkage);
+ if (err != 0) {
+ return (err);
+ }
+
+ ddi_soft_state_fini(&xsvc_statep);
+
+ return (0);
+}
+
+/*
+ * xsvc_attach()
+ *
+ */
+static int
+xsvc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
+{
+ xsvc_state_t *state;
+ int maxallocmem;
+ int instance;
+ int err;
+
+
+ switch (cmd) {
+ case DDI_ATTACH:
+ break;
+
+ case DDI_RESUME:
+ return (DDI_SUCCESS);
+
+ default:
+ return (DDI_FAILURE);
+ }
+
+ instance = ddi_get_instance(dip);
+ err = ddi_soft_state_zalloc(xsvc_statep, instance);
+ if (err != DDI_SUCCESS) {
+ return (DDI_FAILURE);
+ }
+ state = ddi_get_soft_state(xsvc_statep, instance);
+ if (state == NULL) {
+ goto attachfail_get_soft_state;
+ }
+
+ state->xs_dip = dip;
+ state->xs_instance = instance;
+
+ /* Initialize allocation count */
+ mutex_init(&state->xs_mutex, NULL, MUTEX_DRIVER, NULL);
+ state->xs_currently_alloced = 0;
+
+ /* create the minor node (for the ioctl) */
+ err = ddi_create_minor_node(dip, "xsvc", S_IFCHR, instance, DDI_PSEUDO,
+ 0);
+ if (err != DDI_SUCCESS) {
+ goto attachfail_minor_node;
+ }
+
+ /*
+ * the maxallocmem property will override the default (xsvc_max_memory).
+ * This is the maximum total memory the ioctl will allow to be alloced.
+ */
+ maxallocmem = ddi_prop_get_int(DDI_DEV_T_ANY, state->xs_dip,
+ DDI_PROP_DONTPASS, "maxallocmem", -1);
+ if (maxallocmem >= 0) {
+ xsvc_max_memory = maxallocmem * 1024;
+ }
+
+ /* Initialize list of memory allocs */
+ mutex_init(&state->xs_mlist.ml_mutex, NULL, MUTEX_DRIVER, NULL);
+ avl_create(&state->xs_mlist.ml_avl, xsvc_mnode_key_compare,
+ sizeof (xsvc_mnode_t), offsetof(xsvc_mnode_t, mn_link));
+
+ /* Report that driver was loaded */
+ ddi_report_dev(dip);
+
+ return (DDI_SUCCESS);
+
+attachfail_minor_node:
+ mutex_destroy(&state->xs_mutex);
+attachfail_get_soft_state:
+ (void) ddi_soft_state_free(xsvc_statep, instance);
+
+ return (err);
+}
+
+/*
+ * xsvc_detach()
+ *
+ */
+static int
+xsvc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
+{
+ xsvc_state_t *state;
+ xsvc_mnode_t *mnode;
+ xsvc_mem_t *mp;
+ int instance;
+
+
+ instance = ddi_get_instance(dip);
+ state = ddi_get_soft_state(xsvc_statep, instance);
+ if (state == NULL) {
+ return (DDI_FAILURE);
+ }
+
+ switch (cmd) {
+ case DDI_DETACH:
+ break;
+
+ case DDI_SUSPEND:
+ return (DDI_SUCCESS);
+
+ default:
+ return (DDI_FAILURE);
+ }
+
+ ddi_remove_minor_node(dip, NULL);
+
+ /* Free any memory on list */
+ while ((mnode = avl_first(&state->xs_mlist.ml_avl)) != NULL) {
+ mp = mnode->mn_home;
+ xsvc_mem_free(state, mp);
+ }
+
+ /* remove list */
+ avl_destroy(&state->xs_mlist.ml_avl);
+ mutex_destroy(&state->xs_mlist.ml_mutex);
+
+ mutex_destroy(&state->xs_mutex);
+ (void) ddi_soft_state_free(xsvc_statep, state->xs_instance);
+ return (DDI_SUCCESS);
+}
+
+/*
+ * xsvc_getinfo()
+ *
+ */
+/*ARGSUSED*/
+static int
+xsvc_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
+{
+ xsvc_state_t *state;
+ int instance;
+ dev_t dev;
+ int err;
+
+
+ dev = (dev_t)arg;
+ instance = getminor(dev);
+
+ switch (cmd) {
+ case DDI_INFO_DEVT2DEVINFO:
+ state = ddi_get_soft_state(xsvc_statep, instance);
+ if (state == NULL) {
+ return (DDI_FAILURE);
+ }
+ *result = (void *)state->xs_dip;
+ err = DDI_SUCCESS;
+ break;
+
+ case DDI_INFO_DEVT2INSTANCE:
+ *result = (void *)(uintptr_t)instance;
+ err = DDI_SUCCESS;
+ break;
+
+ default:
+ err = DDI_FAILURE;
+ break;
+ }
+
+ return (err);
+}
+
+
+/*
+ * xsvc_open()
+ *
+ */
+/*ARGSUSED*/
+static int
+xsvc_open(dev_t *devp, int flag, int otyp, cred_t *cred)
+{
+ xsvc_state_t *state;
+ int instance;
+
+ instance = getminor(*devp);
+ state = ddi_get_soft_state(xsvc_statep, instance);
+ if (state == NULL) {
+ return (ENXIO);
+ }
+
+ return (0);
+}
+
+/*
+ * xsvc_close()
+ *
+ */
+/*ARGSUSED*/
+static int
+xsvc_close(dev_t devp, int flag, int otyp, cred_t *cred)
+{
+ return (0);
+}
+
+/*
+ * xsvc_ioctl()
+ *
+ */
+/*ARGSUSED*/
+static int
+xsvc_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred, int *rval)
+{
+ xsvc_state_t *state;
+ int instance;
+ int err;
+
+
+ err = drv_priv(cred);
+ if (err != 0) {
+ return (EPERM);
+ }
+ instance = getminor(dev);
+ if (instance == -1) {
+ return (EBADF);
+ }
+ state = ddi_get_soft_state(xsvc_statep, instance);
+ if (state == NULL) {
+ return (EBADF);
+ }
+
+ switch (cmd) {
+ case XSVC_ALLOC_MEM:
+ err = xsvc_ioctl_alloc_memory(state, (void *)arg, mode);
+ break;
+
+ case XSVC_FREE_MEM:
+ err = xsvc_ioctl_free_memory(state, (void *)arg, mode);
+ break;
+
+ case XSVC_FLUSH_MEM:
+ err = xsvc_ioctl_flush_memory(state, (void *)arg, mode);
+ break;
+
+ default:
+ err = ENXIO;
+ }
+
+ return (err);
+}
+
+/*
+ * xsvc_ioctl_alloc_memory()
+ *
+ */
+static int
+xsvc_ioctl_alloc_memory(xsvc_state_t *state, void *arg, int mode)
+{
+ xsvc_mem_req_32 params32;
+ xsvc_mloc_32 *usgl32;
+ xsvc_mem_req params;
+ xsvc_mloc_32 sgl32;
+ xsvc_mloc *usgl;
+ xsvc_mem_t *mp;
+ xsvc_mloc sgl;
+ uint64_t key;
+ size_t size;
+ int err;
+ int i;
+
+
+ /* Copy in the params, then get the size and key */
+ if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
+ err = ddi_copyin(arg, &params32, sizeof (xsvc_mem_req_32),
+ mode);
+ if (err != 0) {
+ return (EFAULT);
+ }
+
+ key = (uint64_t)params32.xsvc_mem_reqid;
+ size = P2ROUNDUP((size_t)params32.xsvc_mem_size, PAGESIZE);
+ } else {
+ err = ddi_copyin(arg, &params, sizeof (xsvc_mem_req), mode);
+ if (err != 0) {
+ return (EFAULT);
+ }
+ key = (uint64_t)params.xsvc_mem_reqid;
+ size = P2ROUNDUP(params.xsvc_mem_size, PAGESIZE);
+ }
+
+ /*
+ * make sure this doesn't put us over the maximum allowed to be
+ * allocated
+ */
+ mutex_enter(&state->xs_mutex);
+ if ((state->xs_currently_alloced + size) > xsvc_max_memory) {
+ mutex_exit(&state->xs_mutex);
+ return (EAGAIN);
+ }
+ state->xs_currently_alloced += size;
+ mutex_exit(&state->xs_mutex);
+
+ /* get state to track this memory */
+ err = xsvc_mem_alloc(state, key, &mp);
+ if (err != 0) {
+ return (err);
+ }
+ mp->xm_size = size;
+
+ /* allocate and bind the memory */
+ mp->xm_dma_attr.dma_attr_version = DMA_ATTR_V0;
+ mp->xm_dma_attr.dma_attr_count_max = (uint64_t)0xFFFFFFFF;
+ mp->xm_dma_attr.dma_attr_burstsizes = 1;
+ mp->xm_dma_attr.dma_attr_minxfer = 1;
+ mp->xm_dma_attr.dma_attr_maxxfer = (uint64_t)0xFFFFFFFF;
+ mp->xm_dma_attr.dma_attr_seg = (uint64_t)0xFFFFFFFF;
+ mp->xm_dma_attr.dma_attr_granular = 1;
+ mp->xm_dma_attr.dma_attr_flags = 0;
+
+ /* Finish converting params */
+ if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
+ mp->xm_dma_attr.dma_attr_addr_lo = params32.xsvc_mem_addr_lo;
+ mp->xm_dma_attr.dma_attr_addr_hi = params32.xsvc_mem_addr_hi;
+ mp->xm_dma_attr.dma_attr_sgllen = params32.xsvc_mem_sgllen;
+ usgl32 = (xsvc_mloc_32 *)(uintptr_t)params32.xsvc_sg_list;
+ mp->xm_dma_attr.dma_attr_align = P2ROUNDUP(
+ params32.xsvc_mem_align, PAGESIZE);
+ } else {
+ mp->xm_dma_attr.dma_attr_addr_lo = params.xsvc_mem_addr_lo;
+ mp->xm_dma_attr.dma_attr_addr_hi = params.xsvc_mem_addr_hi;
+ mp->xm_dma_attr.dma_attr_sgllen = params.xsvc_mem_sgllen;
+ usgl = (xsvc_mloc *)(uintptr_t)params.xsvc_sg_list;
+ mp->xm_dma_attr.dma_attr_align = P2ROUNDUP(
+ params.xsvc_mem_align, PAGESIZE);
+ }
+
+ mp->xm_device_attr = xsvc_device_attr;
+
+ err = ddi_dma_alloc_handle(state->xs_dip, &mp->xm_dma_attr,
+ DDI_DMA_SLEEP, NULL, &mp->xm_dma_handle);
+ if (err != DDI_SUCCESS) {
+ err = EINVAL;
+ goto allocfail_alloc_handle;
+ }
+
+ /* don't sleep here so we don't get stuck in contig alloc */
+ err = ddi_dma_mem_alloc(mp->xm_dma_handle, mp->xm_size,
+ &mp->xm_device_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL,
+ &mp->xm_addr, &mp->xm_real_length, &mp->xm_mem_handle);
+ if (err != DDI_SUCCESS) {
+ err = EINVAL;
+ goto allocfail_alloc_mem;
+ }
+
+ err = ddi_dma_addr_bind_handle(mp->xm_dma_handle, NULL, mp->xm_addr,
+ mp->xm_size, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
+ NULL, &mp->xm_cookie, &mp->xm_cookie_count);
+ if (err != DDI_DMA_MAPPED) {
+ err = EFAULT;
+ goto allocfail_bind;
+ }
+
+ /* return sgl */
+ for (i = 0; i < mp->xm_cookie_count; i++) {
+ if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
+ sgl32.mloc_addr = mp->xm_cookie.dmac_laddress;
+ sgl32.mloc_size = mp->xm_cookie.dmac_size;
+ err = ddi_copyout(&sgl32, &usgl32[i],
+ sizeof (xsvc_mloc_32), mode);
+ if (err != 0) {
+ err = EFAULT;
+ goto allocfail_copyout;
+ }
+ } else {
+ sgl.mloc_addr = mp->xm_cookie.dmac_laddress;
+ sgl.mloc_size = mp->xm_cookie.dmac_size;
+ err = ddi_copyout(&sgl, &usgl[i], sizeof (xsvc_mloc),
+ mode);
+ if (err != 0) {
+ err = EFAULT;
+ goto allocfail_copyout;
+ }
+ }
+ ddi_dma_nextcookie(mp->xm_dma_handle, &mp->xm_cookie);
+ }
+
+ /* set the last sgl entry to 0 to indicate cookie count */
+ if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
+ sgl32.mloc_addr = 0;
+ sgl32.mloc_size = 0;
+ err = ddi_copyout(&sgl32, &usgl32[i], sizeof (xsvc_mloc_32),
+ mode);
+ if (err != 0) {
+ err = EFAULT;
+ goto allocfail_copyout;
+ }
+ } else {
+ sgl.mloc_addr = 0;
+ sgl.mloc_size = 0;
+ err = ddi_copyout(&sgl, &usgl[i], sizeof (xsvc_mloc), mode);
+ if (err != 0) {
+ err = EFAULT;
+ goto allocfail_copyout;
+ }
+ }
+
+ return (0);
+
+allocfail_copyout:
+ (void) ddi_dma_unbind_handle(mp->xm_dma_handle);
+allocfail_bind:
+ ddi_dma_mem_free(&mp->xm_mem_handle);
+allocfail_alloc_mem:
+ ddi_dma_free_handle(&mp->xm_dma_handle);
+allocfail_alloc_handle:
+ mp->xm_dma_handle = NULL;
+ xsvc_mem_free(state, mp);
+
+ mutex_enter(&state->xs_mutex);
+ state->xs_currently_alloced = state->xs_currently_alloced - size;
+ mutex_exit(&state->xs_mutex);
+
+ return (err);
+}
+
+/*
+ * xsvc_ioctl_flush_memory()
+ *
+ */
+static int
+xsvc_ioctl_flush_memory(xsvc_state_t *state, void *arg, int mode)
+{
+ xsvc_mem_req_32 params32;
+ xsvc_mem_req params;
+ xsvc_mem_t *mp;
+ uint64_t key;
+ int err;
+
+
+ if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
+ err = ddi_copyin(arg, &params32, sizeof (xsvc_mem_req_32),
+ mode);
+ if (err != 0) {
+ return (EFAULT);
+ }
+ key = (uint64_t)params32.xsvc_mem_reqid;
+ } else {
+ err = ddi_copyin(arg, &params, sizeof (xsvc_mem_req), mode);
+ if (err != 0) {
+ return (EFAULT);
+ }
+ key = (uint64_t)params.xsvc_mem_reqid;
+ }
+
+ /* find the memory */
+ mp = xsvc_mem_lookup(state, key);
+ if (mp == NULL) {
+ return (EINVAL);
+ }
+
+ (void) ddi_dma_sync(mp->xm_dma_handle, 0, 0, DDI_DMA_SYNC_FORCPU);
+
+ return (0);
+}
+
+
+/*
+ * xsvc_ioctl_free_memory()
+ *
+ */
+static int
+xsvc_ioctl_free_memory(xsvc_state_t *state, void *arg, int mode)
+{
+ xsvc_mem_req_32 params32;
+ xsvc_mem_req params;
+ xsvc_mem_t *mp;
+ uint64_t key;
+ int err;
+
+
+ if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
+ err = ddi_copyin(arg, &params32, sizeof (xsvc_mem_req_32),
+ mode);
+ if (err != 0) {
+ return (EFAULT);
+ }
+ key = (uint64_t)params32.xsvc_mem_reqid;
+ } else {
+ err = ddi_copyin(arg, &params, sizeof (xsvc_mem_req), mode);
+ if (err != 0) {
+ return (EFAULT);
+ }
+ key = (uint64_t)params.xsvc_mem_reqid;
+ }
+
+ /* find the memory */
+ mp = xsvc_mem_lookup(state, key);
+ if (mp == NULL) {
+ return (EINVAL);
+ }
+
+ xsvc_mem_free(state, mp);
+
+ return (0);
+}
+
+/*
+ * xsvc_mem_alloc()
+ *
+ */
+static int
+xsvc_mem_alloc(xsvc_state_t *state, uint64_t key, xsvc_mem_t **mp)
+{
+ xsvc_mem_t *mem;
+
+ mem = xsvc_mem_lookup(state, key);
+ if (mem != NULL) {
+ xsvc_mem_free(state, mem);
+ }
+
+ *mp = kmem_alloc(sizeof (xsvc_mem_t), KM_SLEEP);
+ (*mp)->xm_mnode.mn_home = *mp;
+ (*mp)->xm_mnode.mn_key = key;
+
+ mutex_enter(&state->xs_mlist.ml_mutex);
+ avl_add(&state->xs_mlist.ml_avl, &(*mp)->xm_mnode);
+ mutex_exit(&state->xs_mlist.ml_mutex);
+
+ return (0);
+}
+
+/*
+ * xsvc_mem_free()
+ *
+ */
+static void
+xsvc_mem_free(xsvc_state_t *state, xsvc_mem_t *mp)
+{
+ if (mp->xm_dma_handle != NULL) {
+ (void) ddi_dma_unbind_handle(mp->xm_dma_handle);
+ ddi_dma_mem_free(&mp->xm_mem_handle);
+ ddi_dma_free_handle(&mp->xm_dma_handle);
+
+ mutex_enter(&state->xs_mutex);
+ state->xs_currently_alloced = state->xs_currently_alloced -
+ mp->xm_size;
+ mutex_exit(&state->xs_mutex);
+ }
+
+ mutex_enter(&state->xs_mlist.ml_mutex);
+ avl_remove(&state->xs_mlist.ml_avl, &mp->xm_mnode);
+ mutex_exit(&state->xs_mlist.ml_mutex);
+
+ kmem_free(mp, sizeof (*mp));
+}
+
+/*
+ * xsvc_mem_lookup()
+ *
+ */
+static xsvc_mem_t *
+xsvc_mem_lookup(xsvc_state_t *state, uint64_t key)
+{
+ xsvc_mnode_t mnode;
+ xsvc_mnode_t *mnp;
+ avl_index_t where;
+ xsvc_mem_t *mp;
+
+ mnode.mn_key = key;
+ mutex_enter(&state->xs_mlist.ml_mutex);
+ mnp = avl_find(&state->xs_mlist.ml_avl, &mnode, &where);
+ mutex_exit(&state->xs_mlist.ml_mutex);
+
+ if (mnp != NULL) {
+ mp = mnp->mn_home;
+ } else {
+ mp = NULL;
+ }
+
+ return (mp);
+}
+
+/*
+ * xsvc_mnode_key_compare()
+ *
+ */
+static int
+xsvc_mnode_key_compare(const void *q, const void *e)
+{
+ xsvc_mnode_t *n1;
+ xsvc_mnode_t *n2;
+
+ n1 = (xsvc_mnode_t *)q;
+ n2 = (xsvc_mnode_t *)e;
+
+ if (n1->mn_key < n2->mn_key) {
+ return (-1);
+ } else if (n1->mn_key > n2->mn_key) {
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+/*
+ * xsvc_devmap()
+ *
+ */
+/*ARGSUSED*/
+static int
+xsvc_devmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t len,
+ size_t *maplen, uint_t model)
+{
+ ddi_umem_cookie_t cookie;
+ xsvc_state_t *state;
+ offset_t off_align;
+ size_t npages;
+ caddr_t kvai;
+ size_t psize;
+ int instance;
+ caddr_t kva;
+ pfn_t pfn;
+ int err;
+ int i;
+
+
+ instance = getminor(dev);
+ state = ddi_get_soft_state(xsvc_statep, instance);
+ if (state == NULL) {
+ return (ENXIO);
+ }
+
+ /*
+ * On 64-bit kernels, if we have a 32-bit application doing a mmap(),
+ * smmap32 will sign extend the offset. We need to undo that since
+ * we are passed a physical address in off, not a offset.
+ */
+#if defined(__amd64)
+ if (((model & DDI_MODEL_MASK) == DDI_MODEL_ILP32) &&
+ ((off & ~0xFFFFFFFFll) == ~0xFFFFFFFFll)) {
+ off = off & 0xFFFFFFFF;
+ }
+#endif
+
+ pfn = btop(off);
+
+ /* always work with whole pages */
+ off_align = P2ALIGN(off, PAGESIZE);
+ psize = P2ROUNDUP(off + len, PAGESIZE) - off_align;
+
+ /*
+ * if this is memory we're trying to map into user space, we first
+ * need to map the PFNs into KVA, then build up a umem cookie, and
+ * finally do a umem_setup to map it in.
+ */
+ if (pf_is_memory(pfn)) {
+ npages = btop(psize);
+
+ kva = vmem_alloc(heap_arena, psize, VM_SLEEP);
+ if (kva == NULL) {
+ return (-1);
+ }
+
+ kvai = kva;
+ for (i = 0; i < npages; i++) {
+ hat_devload(kas.a_hat, kvai, PAGESIZE, pfn,
+ PROT_READ | PROT_WRITE, HAT_LOAD_LOCK);
+ pfn++;
+ kvai = (caddr_t)((uintptr_t)kvai + PAGESIZE);
+ }
+
+ err = xsvc_umem_cookie_alloc(kva, psize, KM_SLEEP, &cookie);
+ if (err != 0) {
+ goto devmapfail_cookie_alloc;
+ }
+
+ if ((err = devmap_umem_setup(dhp, state->xs_dip, &xsvc_callbk,
+ cookie, 0, psize, PROT_ALL, 0, &xsvc_device_attr)) < 0) {
+ goto devmapfail_umem_setup;
+ }
+ *maplen = psize;
+
+ /* Is this is not memory, go through devmem_setup */
+ } else {
+ if ((err = devmap_devmem_setup(dhp, state->xs_dip, NULL, 0,
+ off_align, psize, PROT_ALL, 0, &xsvc_device_attr)) < 0) {
+ return (err);
+ }
+ *maplen = psize;
+ }
+
+ return (0);
+
+devmapfail_umem_setup:
+ xsvc_umem_cookie_free(&cookie);
+
+devmapfail_cookie_alloc:
+ kvai = kva;
+ for (i = 0; i < npages; i++) {
+ hat_unload(kas.a_hat, kvai, PAGESIZE,
+ HAT_UNLOAD_UNLOCK);
+ kvai = (caddr_t)((uintptr_t)kvai + PAGESIZE);
+ }
+ vmem_free(heap_arena, kva, psize);
+
+ return (err);
+}
+
+/*
+ * xsvc_umem_cookie_alloc()
+ *
+ * allocate a umem cookie to be used in devmap_umem_setup using KVA already
+ * allocated.
+ */
+int
+xsvc_umem_cookie_alloc(caddr_t kva, size_t size, int flags,
+ ddi_umem_cookie_t *cookiep)
+{
+ struct ddi_umem_cookie *umem_cookiep;
+
+ umem_cookiep = kmem_zalloc(sizeof (struct ddi_umem_cookie), flags);
+ if (umem_cookiep == NULL) {
+ *cookiep = NULL;
+ return (-1);
+ }
+
+ umem_cookiep->cvaddr = kva;
+ umem_cookiep->type = KMEM_NON_PAGEABLE;
+ umem_cookiep->size = size;
+ *cookiep = (ddi_umem_cookie_t *)umem_cookiep;
+
+ return (0);
+}
+
+/*
+ * xsvc_umem_cookie_free()
+ *
+ */
+static void
+xsvc_umem_cookie_free(ddi_umem_cookie_t *cookiep)
+{
+ kmem_free(*cookiep, sizeof (struct ddi_umem_cookie));
+ *cookiep = NULL;
+}
+
+/*
+ * xsvc_devmap_unmap()
+ *
+ * This routine is only call if we were mapping in memory in xsvc_devmap().
+ * i.e. we only pass in xsvc_callbk to devmap_umem_setup if pf_is_memory()
+ * was true. It would have been nice if devmap_callback_ctl had an args param.
+ * We wouldn't have had to look into the devmap_handle and into the umem
+ * cookie.
+ */
+/*ARGSUSED*/
+static void
+xsvc_devmap_unmap(devmap_cookie_t dhc, void *pvtp, offset_t off, size_t len,
+ devmap_cookie_t new_dhp1, void **new_pvtp1, devmap_cookie_t new_dhp2,
+ void **new_pvtp2)
+{
+ struct ddi_umem_cookie *cp;
+ devmap_handle_t *dhp;
+ size_t npages;
+ caddr_t kvai;
+ caddr_t kva;
+ size_t size;
+ int i;
+
+
+ /* peek into the umem cookie to figure out what we need to free up */
+ dhp = (devmap_handle_t *)dhc;
+ cp = (struct ddi_umem_cookie *)dhp->dh_cookie;
+ kva = cp->cvaddr;
+ size = cp->size;
+
+ /*
+ * free up the umem cookie, then unmap all the pages what we mapped
+ * in during devmap, then free up the kva space.
+ */
+ npages = btop(size);
+ xsvc_umem_cookie_free(&dhp->dh_cookie);
+ kvai = kva;
+ for (i = 0; i < npages; i++) {
+ hat_unload(kas.a_hat, kvai, PAGESIZE, HAT_UNLOAD_UNLOCK);
+ kvai = (caddr_t)((uintptr_t)kvai + PAGESIZE);
+ }
+ vmem_free(heap_arena, kva, size);
+}
diff --git a/usr/src/uts/i86pc/io/xsvc/xsvc.conf b/usr/src/uts/i86pc/io/xsvc/xsvc.conf
new file mode 100644
index 0000000000..c41d589972
--- /dev/null
+++ b/usr/src/uts/i86pc/io/xsvc/xsvc.conf
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+# Driver.conf file for xsvc Pseudo-driver.
+#
+# The reg property defines the physical range that the xsvc driver can
+# map into user space.
+#
+name="xsvc" class="root" reg=0x0,0,0xffffffff;
+maxallocmem=10240;
diff --git a/usr/src/uts/i86pc/ml/amd64.il b/usr/src/uts/i86pc/ml/amd64.il
new file mode 100644
index 0000000000..4405e60e0d
--- /dev/null
+++ b/usr/src/uts/i86pc/ml/amd64.il
@@ -0,0 +1,183 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/
+/ Inline functions specific to the i86pc kernel running on bare metal.
+/
+
+/
+/ return value of cr3 register
+/
+ .inline getcr3,0
+ movq %cr3, %rax
+ .end
+
+/
+/ reload cr3 register with its current value
+/
+ .inline reload_cr3,0
+ movq %cr3, %rdi
+ movq %rdi, %cr3
+ .end
+
+/
+/ return value of cr8 register
+/
+ .inline getcr8,0
+ movq %cr8, %rax
+ .end
+
+/
+/ set cr8 register
+/
+ .inline setcr8,0
+ movq %rdi, %cr8
+ .end
+
+/
+/ enable interrupts
+/
+ .inline sti,0
+ sti
+ .end
+
+/
+/ disable interrupts
+/
+ .inline cli,0
+ cli
+ .end
+
+/
+/ disable interrupts and return value describing if interrupts were enabled
+/
+ .inline clear_int_flag,0
+ pushfq
+ cli
+ popq %rax
+ .end
+
+ .inline intr_clear,0
+ pushfq
+ cli
+ popq %rax
+ .end
+
+/
+/ return the value of the flags register
+/
+ .inline getflags,0
+ pushfq
+ popq %rax
+ .end
+
+/
+/ restore interrupt enable flag to value returned from 'clear_int_flag' above
+/
+ .inline restore_int_flag,4
+ pushq %rdi
+ popfq
+ .end
+
+ .inline intr_restore,4
+ pushq %rdi
+ popfq
+ .end
+
+/
+/ in and out
+/
+ .inline inb,4
+ movq %rdi, %rdx
+ xorq %rax, %rax
+ inb (%dx)
+ .end
+
+ .inline inw,4
+ movq %rdi, %rdx
+ xorq %rax, %rax
+ inw (%dx)
+ .end
+
+ .inline inl,4
+ movq %rdi, %rdx
+ xorq %rax, %rax
+ inl (%dx)
+ .end
+
+ .inline outb,8
+ movq %rdi, %rdx
+ movq %rsi, %rax
+ outb (%dx)
+ .end
+
+ .inline outw,8
+ movq %rdi, %rdx
+ movq %rsi, %rax
+ outw (%dx)
+ .end
+
+ .inline outl,8
+ movq %rdi, %rdx
+ movq %rsi, %rax
+ outl (%dx)
+ .end
+
+/*
+ * Read Time Stamp Counter
+ * uint64_t tsc_read();
+ *
+ * usage:
+ * uint64_t cycles = tsc_read();
+ */
+ .inline tsc_read, 0
+ rdtsc / %edx:%eax = RDTSC
+ shlq $32, %rdx
+ orq %rdx, %rax
+ .end
+
+/*
+ * Call the halt instruction. This will put the CPU to sleep until
+ * it is again awoken via an interrupt.
+ * This function should be called with interrupts already disabled
+ * for the CPU.
+ * Note that "sti" will only enable interrupts at the end of the
+ * subsequent instruction...in this case: "hlt".
+ */
+ .inline i86_halt,0
+ sti
+ hlt
+ .end
+/
+/ execute the bsrw instruction
+/
+ .inline bsrw_insn,4
+ xorl %eax, %eax
+ bsrw %di, %ax
+ .end
+
diff --git a/usr/src/uts/i86pc/ml/bios_call_src.s b/usr/src/uts/i86pc/ml/bios_call_src.s
new file mode 100644
index 0000000000..a587929066
--- /dev/null
+++ b/usr/src/uts/i86pc/ml/bios_call_src.s
@@ -0,0 +1,565 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#if defined(__lint)
+
+int silence_lint = 0;
+
+#else
+
+#include <sys/segments.h>
+#include <sys/controlregs.h>
+
+/*
+ * Do a call into BIOS. This goes down to 16 bit real mode and back again.
+ */
+
+/*
+ * instruction prefix to change operand size in instruction
+ */
+#define DATASZ .byte 0x66;
+
+#if defined(__amd64)
+#define MOVCR(x, y) movq x,%rax; movq %rax, y
+#define LOAD_XAX(sym) leaq sym, %rax
+#elif defined(__i386)
+#define MOVCR(x, y) movl x,%eax; movl %eax, y
+#define LOAD_XAX(sym) leal sym, %eax
+#endif
+
+ .globl _start
+_start:
+
+#if defined(__i386)
+
+ /*
+ * Save caller registers
+ */
+ movl %ebp, save_ebp
+ movl %esp, save_esp
+ movl %ebx, save_ebx
+ movl %esi, save_esi
+ movl %edi, save_edi
+
+ /* get registers argument into esi */
+ movl 8(%esp), %esi
+
+ /* put interrupt number in %bl */
+ movl 4(%esp), %ebx
+
+ /* Switch to a low memory stack */
+ movl $_start, %esp
+
+ /* allocate space for args on stack */
+ subl $18, %esp
+ movl %esp, %edi
+
+#elif defined(__amd64)
+
+ /*
+ * Save caller registers
+ */
+ movq %rbp, save_rbp
+ movq %rsp, save_rsp
+ movq %rbx, save_rbx
+ movq %rsi, save_rsi
+ movq %r12, save_r12
+ movq %r13, save_r13
+ movq %r14, save_r14
+ movq %r15, save_r15
+
+ /* Switch to a low memory stack */
+ movq $_start, %rsp
+
+ /* put interrupt number in %bl */
+ movq %rdi, %rbx
+
+ /* allocate space for args on stack */
+ subq $18, %rsp
+ movq %rsp, %rdi
+
+#endif
+
+ /* copy args from high memory to stack in low memory */
+ cld
+ movl $18, %ecx
+ rep
+ movsb
+
+ /*
+ * Save system registers
+ */
+ sidt save_idt
+ sgdt save_gdt
+ str save_tr
+ movw %cs, save_cs
+ movw %ds, save_ds
+ movw %ss, save_ss
+ movw %es, save_es
+ movw %fs, save_fs
+ movw %gs, save_gs
+ MOVCR( %cr4, save_cr4)
+ MOVCR( %cr3, save_cr3)
+ MOVCR( %cr0, save_cr0)
+
+#if defined(__amd64)
+ /*
+ * save/clear the extension parts of the fs/gs base registers and cr8
+ */
+ movl $MSR_AMD_FSBASE, %ecx
+ rdmsr
+ movl %eax, save_fsbase
+ movl %edx, save_fsbase + 4
+ xorl %eax, %eax
+ xorl %edx, %edx
+ wrmsr
+
+ movl $MSR_AMD_GSBASE, %ecx
+ rdmsr
+ movl %eax, save_gsbase
+ movl %edx, save_gsbase + 4
+ xorl %eax, %eax
+ xorl %edx, %edx
+ wrmsr
+
+ movl $MSR_AMD_KGSBASE, %ecx
+ rdmsr
+ movl %eax, save_kgsbase
+ movl %edx, save_kgsbase + 4
+ xorl %eax, %eax
+ xorl %edx, %edx
+ wrmsr
+
+ movq %cr8, %rax
+ movq %rax, save_cr8
+#endif
+
+ /*
+ * set offsets in 16 bit ljmp instructions below
+ */
+ LOAD_XAX(enter_real)
+ movw %ax, enter_real_ljmp
+
+ LOAD_XAX(enter_protected)
+ movw %ax, enter_protected_ljmp
+
+ LOAD_XAX(gdt_info)
+ movw %ax, gdt_info_load
+
+ /*
+ * insert BIOS interrupt number into later instruction
+ */
+ movb %bl, int_instr+1
+ jmp 1f
+1:
+
+ /*
+ * zero out all the registers to make sure they're 16 bit clean
+ */
+#if defined(__amd64)
+ xorq %r8, %r8
+ xorq %r9, %r9
+ xorq %r10, %r10
+ xorq %r11, %r11
+ xorq %r12, %r12
+ xorq %r13, %r13
+ xorq %r14, %r14
+ xorq %r15, %r15
+#endif
+ xorl %eax, %eax
+ xorl %ebx, %ebx
+ xorl %ecx, %ecx
+ xorl %edx, %edx
+ xorl %ebp, %ebp
+ xorl %esi, %esi
+ xorl %edi, %edi
+
+ /*
+ * Load our own GDT/IDT
+ */
+ lgdt gdt_info
+ lidt idt_info
+
+#if defined(__amd64)
+ /*
+ * Shut down 64 bit mode. First get into compatiblity mode.
+ */
+ movq %rsp, %rax
+ pushq $B32DATA_SEL
+ pushq %rax
+ pushf
+ pushq $B32CODE_SEL
+ pushq $1f
+ iretq
+1:
+ .code32
+
+ /*
+ * disable long mode by:
+ * - shutting down paging (bit 31 of cr0)
+ * - flushing the TLB
+ * - disabling LME (long made enable) in EFER (extended feature reg)
+ */
+ movl %cr0, %eax
+ btcl $31, %eax /* disable paging */
+ movl %eax, %cr0
+ ljmp $B32CODE_SEL, $1f
+1:
+
+ xorl %eax, %eax
+ movl %eax, %cr3 /* flushes TLB */
+
+ movl $MSR_AMD_EFER, %ecx /* Extended Feature Enable */
+ rdmsr
+ btcl $8, %eax /* bit 8 Long Mode Enable bit */
+ wrmsr
+#endif
+
+ /*
+ * ok.. now enter 16 bit mode, so we can shut down protected mode
+ *
+ * We'll have to act like we're still in a 32 bit section.
+ * So the code from this point has DATASZ in front of it to get 32 bit
+ * operands. If DATASZ is missing the operands will be 16 bit.
+ *
+ * Now shut down paging and protected (ie. segmentation) modes.
+ */
+ ljmp $B16CODE_SEL, $enter_16_bit
+enter_16_bit:
+
+ /*
+ * Make sure hidden parts of segment registers are 16 bit clean
+ */
+ DATASZ movl $B16DATA_SEL, %eax
+ movw %ax, %ss
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %fs
+ movw %ax, %gs
+
+
+ DATASZ movl $0x0, %eax /* put us in real mode */
+ DATASZ movl %eax, %cr0
+ .byte 0xea /* ljmp */
+enter_real_ljmp:
+ .value 0 /* addr (16 bit) */
+ .value 0x0 /* value for %cs */
+enter_real:
+
+ /*
+ * zero out the remaining segment registers
+ */
+ DATASZ xorl %eax, %eax
+ movw %ax, %ss
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %fs
+ movw %ax, %gs
+
+ /*
+ * load the arguments to the BIOS call from the stack
+ */
+ popl %eax /* really executes a 16 bit pop */
+ popl %ebx
+ popl %ecx
+ popl %edx
+ popl %esi
+ popl %edi
+ popl %ebp
+ pop %es
+ pop %ds
+
+ /*
+ * do the actual BIOS call
+ */
+ sti
+int_instr:
+ int $0x10 /* this int number is overwritten */
+ cli /* ensure interrupts remain disabled */
+
+ /*
+ * save results of the BIOS call
+ */
+ pushf
+ push %ds
+ push %es
+ pushl %ebp /* still executes as 16 bit */
+ pushl %edi
+ pushl %esi
+ pushl %edx
+ pushl %ecx
+ pushl %ebx
+ pushl %eax
+
+ /*
+ * Restore protected mode and 32 bit execution
+ */
+ push $0 /* make sure %ds is zero before lgdt */
+ pop %ds
+ .byte 0x0f, 0x01, 0x16 /* lgdt */
+gdt_info_load:
+ .value 0 /* temp GDT in currently addressible mem */
+
+ DATASZ movl $0x1, %eax
+ DATASZ movl %eax, %cr0
+
+ .byte 0xea /* ljmp */
+enter_protected_ljmp:
+ .value 0 /* addr (still in 16 bit) */
+ .value B32CODE_SEL /* %cs value */
+enter_protected:
+
+ /*
+ * We are now back in a 32 bit code section, fix data/stack segments
+ */
+ .code32
+ movw $B32DATA_SEL, %ax
+ movw %ax, %ds
+ movw %ax, %ss
+
+ /*
+ * Re-enable paging. Note we only use 32 bit mov's to restore these
+ * control registers. That's OK as the upper 32 bits are always zero.
+ */
+ movl save_cr4, %eax
+ movl %eax, %cr4
+ movl save_cr3, %eax
+ movl %eax, %cr3
+
+#if defined(__amd64)
+ /*
+ * re-enable long mode
+ */
+ movl $MSR_AMD_EFER, %ecx
+ rdmsr
+ btsl $8, %eax
+ wrmsr
+#endif
+
+ movl save_cr0, %eax
+ movl %eax, %cr0
+ jmp enter_paging
+enter_paging:
+
+
+#if defined(__amd64)
+ /*
+ * transition back to 64 bit mode
+ */
+ pushl $B64CODE_SEL
+ pushl $longmode
+ lret
+longmode:
+ .code64
+#endif
+ /*
+ * restore caller frame pointer and segment registers
+ */
+ lgdt save_gdt
+ lidt save_idt
+
+ /*
+ * Before loading the task register we need to reset the busy bit
+ * in its corresponding GDT selector. The busy bit is the 2nd bit in
+ * the 5th byte of the selector.
+ */
+#if defined(__i386)
+ movzwl save_tr, %eax
+ addl save_gdt+2, %eax
+ btcl $1, 5(%eax)
+#elif defined(__amd64)
+ movzwq save_tr, %rax
+ addq save_gdt+2, %rax
+ btcl $1, 5(%rax)
+#endif
+ ltr save_tr
+ movw save_ds, %ds
+ movw save_ss, %ss
+ movw save_es, %es
+ movw save_fs, %fs
+ movw save_gs, %gs
+
+#if defined(__i386)
+ pushl save_cs
+ pushl $.newcs
+ lret
+#elif defined(__amd64)
+ pushq save_cs
+ pushq $.newcs
+ lretq
+#endif
+.newcs:
+
+#if defined(__amd64)
+ /*
+ * restore the hidden kernel segment base register values
+ */
+ movl save_fsbase, %eax
+ movl save_fsbase + 4, %edx
+ movl $MSR_AMD_FSBASE, %ecx
+ wrmsr
+
+ movl save_gsbase, %eax
+ movl save_gsbase + 4, %edx
+ movl $MSR_AMD_GSBASE, %ecx
+ wrmsr
+
+ movl save_kgsbase, %eax
+ movl save_kgsbase + 4, %edx
+ movl $MSR_AMD_KGSBASE, %ecx
+ wrmsr
+
+ movq save_cr8, %rax
+ cmpq $0, %rax
+ je 1f
+ movq %rax, %cr8
+1:
+#endif
+
+ /*
+ * copy results to caller's location, then restore remaining registers
+ */
+#if defined(__i386)
+ movl save_esp, %edi
+ movl 8(%edi), %edi
+ movl %esp, %esi
+ movl $18, %ecx
+ rep
+ movsb
+ movw 18(%esp), %ax
+ andl $0xffff, %eax
+ movl save_ebx, %ebx
+ movl save_esi, %esi
+ movl save_edi, %edi
+ movl save_esp, %esp
+ movl save_ebp, %ebp
+ movl save_esp, %esp
+ ret
+
+#elif defined(__amd64)
+ movq save_rsi, %rdi
+ movq %rsp, %rsi
+ movq $18, %rcx
+ rep
+ movsb
+ movw 18(%rsp), %ax
+ andq $0xffff, %rax
+ movq save_r12, %r12
+ movq save_r13, %r13
+ movq save_r14, %r14
+ movq save_r15, %r15
+ movq save_rbx, %rbx
+ movq save_rbp, %rbp
+ movq save_rsp, %rsp
+ ret
+
+#endif
+
+
+/*
+ * Caller's registers to restore
+ */
+ .align 4
+save_esi:
+ .long 0
+save_edi:
+ .long 0
+save_ebx:
+ .long 0
+save_ebp:
+ .long 0
+save_esp:
+ .long 0
+
+ .align 8
+#if defined(__amd64)
+save_rsi:
+ .quad 0
+save_rbx:
+ .quad 0
+save_rbp:
+ .quad 0
+save_rsp:
+ .quad 0
+save_r12:
+ .quad 0
+save_r13:
+ .quad 0
+save_r14:
+ .quad 0
+save_r15:
+ .quad 0
+save_kgsbase:
+ .quad 0
+save_gsbase:
+ .quad 0
+save_fsbase:
+ .quad 0
+save_cr8:
+ .quad 0
+#endif /* __amd64 */
+
+save_idt:
+ .quad 0
+ .quad 0
+
+save_gdt:
+ .quad 0
+ .quad 0
+
+save_cr0:
+ .quad 0
+save_cr3:
+ .quad 0
+save_cr4:
+ .quad 0
+save_cs:
+ .quad 0
+save_ss:
+ .value 0
+save_ds:
+ .value 0
+save_es:
+ .value 0
+save_fs:
+ .value 0
+save_gs:
+ .value 0
+save_tr:
+ .value 0
+
+idt_info:
+ .value 0x3ff
+ .quad 0
+
+
+/*
+ * We need to trampoline thru a gdt we have in low memory.
+ */
+#include "../boot/boot_gdt.s"
+#endif /* __lint */
diff --git a/usr/src/uts/i86pc/ml/genassym.c b/usr/src/uts/i86pc/ml/genassym.c
index a346a8f59b..cda4acb3a3 100644
--- a/usr/src/uts/i86pc/ml/genassym.c
+++ b/usr/src/uts/i86pc/ml/genassym.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,8 +48,11 @@
#include <sys/pic.h>
#include <sys/pit.h>
#include <sys/fp.h>
+#include <sys/disp.h>
#include <sys/archsystm.h>
+#include <sys/x86_archext.h>
#include <sys/sunddi.h>
+#include <sys/mach_mmu.h>
#undef exit /* unhide exit, see comment above */
extern void exit(int);
@@ -111,9 +114,6 @@ main(int argc, char *argv[])
printf("#define\tFPU_EN 0x%x\n", FPU_EN);
printf("#define\tFPU_VALID 0x%x\n", FPU_VALID);
- printf("#define\tELF_NOTE_PAGESIZE_HINT 0x%x\n",
- ELF_NOTE_PAGESIZE_HINT);
-
printf("#define\tFP_NO 0x%x\n", FP_NO);
printf("#define\tFP_SW 0x%x\n", FP_SW);
printf("#define\tFP_HW 0x%x\n", FP_HW);
@@ -162,15 +162,8 @@ main(int argc, char *argv[])
printf("#define\tDDI_DEV_AUTOINCR 0x%x\n", DDI_DEV_AUTOINCR);
printf("#define\tMMU_STD_PAGESIZE 0x%x\n", (uint_t)MMU_STD_PAGESIZE);
- printf("#define\tMMU_STD_PAGESHIFT 0x%x\n", (uint_t)MMU_STD_PAGESHIFT);
printf("#define\tMMU_STD_PAGEMASK 0x%x\n", (uint_t)MMU_STD_PAGEMASK);
- printf("#define\tMMU_L2_MASK 0x%x\n", (uint_t)(NPTEPERPT - 1));
- printf("#define\tNPTESHIFT 0x%x\n", (uint_t)NPTESHIFT);
- printf("#define\tFOURMB_PAGEOFFSET 0x%x\n", (uint_t)FOURMB_PAGEOFFSET);
- printf("#define\tFOURMB_PAGESIZE 0x%x\n", (uint_t)FOURMB_PAGESIZE);
- printf("#define\tPTE_LARGEPAGE 0x%x\n", (uint_t)PTE_LARGEPAGE);
- printf("#define\tPTE_VALID 0x%x\n", (uint_t)PTE_VALID);
- printf("#define\tPTE_SRWX 0x%x\n", (uint_t)PTE_SRWX);
+ printf("#define\tFOUR_MEG 0x%x\n", (uint_t)FOUR_MEG);
printf("#define\tTRAPTR_NENT 0x%x\n", TRAPTR_NENT);
@@ -182,5 +175,7 @@ main(int argc, char *argv[])
printf("#define\tMODS_WEAK 0x%x\n", MODS_WEAK);
printf("#define\tMODS_INSTALLED 0x%x\n", MODS_INSTALLED);
+ printf("#define\tKPREEMPT_SYNC 0x%x\n", KPREEMPT_SYNC);
+
return (0);
}
diff --git a/usr/src/uts/i86pc/ml/ia32.il b/usr/src/uts/i86pc/ml/ia32.il
new file mode 100644
index 0000000000..4a7be58bd7
--- /dev/null
+++ b/usr/src/uts/i86pc/ml/ia32.il
@@ -0,0 +1,187 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/
+/ Inline functions specific to the i86pc kernel running on bare metal.
+/
+
+/
+/ return value of cr3 register
+/
+ .inline getcr3,0
+ movl %cr3, %eax
+ .end
+
+/
+/ reload cr3 register with its current value
+/
+ .inline reload_cr3,0
+ movl %cr3, %eax
+ movl %eax, %cr3
+ .end
+
+/*
+ * Put a new value into cr3 (page table base register
+ * void setcr3(void *value)
+ */
+ .inline setcr3,4
+ movl (%esp), %eax
+ movl %eax, %cr3
+ .end
+
+/
+/ enable interrupts
+/
+ .inline sti,0
+ sti
+ .end
+
+/
+/ disable interrupts
+/
+ .inline cli,0
+ cli
+ .end
+
+/
+/ disable interrupts and return value describing if interrupts were enabled
+/
+ .inline clear_int_flag,0
+ pushfl
+ cli
+ popl %eax
+ .end
+
+ .inline intr_clear,0
+ pushfl
+ cli
+ popl %eax
+ .end
+
+/
+/ return the flags register
+/
+ .inline getflags,0
+ pushfl
+ popl %eax
+ .end
+
+/
+/ restore interrupt enable flag to value returned from 'clear_int_flag' above
+/
+ .inline restore_int_flag,4
+ pushl (%esp)
+ popfl
+ .end
+
+ .inline intr_restore,4
+ pushl (%esp)
+ popfl
+ .end
+
+/
+/ in and out
+/
+ .inline inb,4
+ movl (%esp), %edx
+ xorl %eax, %eax
+ inb (%dx)
+ .end
+
+ .inline inw,4
+ movl (%esp), %edx
+ xorl %eax, %eax
+ inw (%dx)
+ .end
+
+ .inline inl,4
+ movl (%esp), %edx
+ xorl %eax, %eax
+ inl (%dx)
+ .end
+
+ .inline outb,8
+ movl (%esp), %edx
+ movl 4(%esp), %eax
+ outb (%dx)
+ .end
+
+ .inline outw,8
+ movl (%esp), %edx
+ movl 4(%esp), %eax
+ outw (%dx)
+ .end
+
+ .inline outl,8
+ movl (%esp), %edx
+ movl 4(%esp), %eax
+ outl (%dx)
+ .end
+
+/*
+ * Invalidate TLB translation to 1 page.
+ * void mmu_tlbflush_entry(void *addr)
+ */
+ .inline mmu_tlbflush_entry,4
+ movl (%esp), %eax
+ invlpg (%eax)
+ .end
+
+/*
+ * Read Time Stamp Counter
+ * uint64_t tsc_read();
+ *
+ * usage:
+ * uint64_t cycles = tsc_read();
+ */
+ .inline tsc_read, 0
+ rdtsc / %edx:%eax = RDTSC
+ .end
+
+/*
+ * Call the halt instruction. This will put the CPU to sleep until
+ * it is again awoken via an interrupt.
+ * This function should be called with interrupts already disabled
+ * for the CPU.
+ * Note that "sti" will only enable interrupts at the end of the
+ * subsequent instruction...in this case: "hlt".
+ */
+ .inline i86_halt,0
+ sti
+ hlt
+ .end
+
+/*
+ * execute the bsrw instruction
+ * int bsrw_insn(uint16_t)
+ */
+ .inline bsrw_insn,4
+ xorl %eax, %eax
+ movw (%esp), %cx
+ bsrw %cx, %ax
+ .end
diff --git a/usr/src/uts/i86pc/ml/interrupt.s b/usr/src/uts/i86pc/ml/interrupt.s
index 69e990674d..da1348ecbd 100644
--- a/usr/src/uts/i86pc/ml/interrupt.s
+++ b/usr/src/uts/i86pc/ml/interrupt.s
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -55,9 +55,6 @@
#include <sys/panic.h>
#include "assym.h"
-_ftrace_intr_thread_fmt:
- .string "intr_thread(): regs=0x%lx, int=0x%x, pil=0x%x"
-
#endif /* lint */
#if defined(__i386)
@@ -79,23 +76,8 @@ patch_tsc(void)
*/
ENTRY_NP(patch_tsc)
movw _rdtsc_insn, %cx
- movw %cx, _tsc_patch1
- movw %cx, _tsc_patch2
- movw %cx, _tsc_patch3
- movw %cx, _tsc_patch4
- movw %cx, _tsc_patch5
- movw %cx, _tsc_patch6
- movw %cx, _tsc_patch7
- movw %cx, _tsc_patch8
- movw %cx, _tsc_patch9
- movw %cx, _tsc_patch10
- movw %cx, _tsc_patch11
- movw %cx, _tsc_patch12
- movw %cx, _tsc_patch13
- movw %cx, _tsc_patch14
movw %cx, _tsc_patch15
movw %cx, _tsc_patch16
- movw %cx, _tsc_patch17
ret
_rdtsc_insn:
rdtsc
@@ -119,16 +101,12 @@ _interrupt(void)
/*
* Common register usage:
*
- * %rbx cpu pointer
- * %r12 trap trace pointer -and- stash of
- * vec across intr_thread dispatch.
- * %r13d ipl of isr
- * %r14d old ipl (ipl level we entered on)
- * %r15 interrupted thread stack pointer
+ * %r12 trap trace pointer
*/
ENTRY_NP2(cmnint, _interrupt)
INTR_PUSH
+ INTGATE_INIT_KERNEL_FLAGS /* (set kernel rflags values) */
/*
* At the end of TRACE_PTR %r12 points to the current TRAPTRACE entry
@@ -138,404 +116,36 @@ _interrupt(void)
TRACE_REGS(%r12, %rsp, %rax, %rbx) /* Uses label 9 */
TRACE_STAMP(%r12) /* Clobbers %eax, %edx, uses 9 */
- DISABLE_INTR_FLAGS /* (and set kernel flag values) */
-
movq %rsp, %rbp
TRACE_STACK(%r12)
+#ifdef TRAPTRACE
LOADCPU(%rbx) /* &cpu */
- leaq REGOFF_TRAPNO(%rbp), %rsi /* &vector */
movl CPU_PRI(%rbx), %r14d /* old ipl */
- movl CPU_SOFTINFO(%rbx), %edx
-
-#ifdef TRAPTRACE
movl $255, TTR_IPL(%r12)
movl %r14d, %edi
movb %dil, TTR_PRI(%r12)
movl CPU_BASE_SPL(%rbx), %edi
movb %dil, TTR_SPL(%r12)
movb $255, TTR_VECTOR(%r12)
+ movq %r12, %rsi /* pass traptrace record pointer */
#endif
- /*
- * Check to see if the trap number is T_SOFTINT; if it is,
- * jump straight to dosoftint now.
- */
- cmpq $T_SOFTINT, (%rsi)
- je dosoftint
-
- /*
- * Raise the interrupt priority level, returns newpil.
- * (The vector address is in %rsi so setlvl can update it.)
- */
- movl %r14d, %edi /* old ipl */
- /* &vector */
- call *setlvl(%rip)
-
-#ifdef TRAPTRACE
- movb %al, TTR_IPL(%r12)
-#endif
- /*
- * check for spurious interrupt
- */
- cmpl $-1, %eax
- je _sys_rtt
-
-#ifdef TRAPTRACE
- movl %r14d, %edx
- movb %dl, TTR_PRI(%r12)
- movl CPU_BASE_SPL(%rbx), %edx
- movb %dl, TTR_SPL(%r12)
-#endif
- movl %eax, CPU_PRI(%rbx) /* update ipl */
-
-#ifdef TRAPTRACE
- movl REGOFF_TRAPNO(%rbp), %edx
- movb %dl, TTR_VECTOR(%r12)
-#endif
- movl %eax, %r13d /* ipl of isr */
-
- /*
- * At this point we can take one of two paths.
- * If the new level is at or below lock level, we will
- * run this interrupt in a separate thread.
- */
- cmpl $LOCK_LEVEL, %eax
- jbe intr_thread
-
- movq %rbx, %rdi /* &cpu */
- movl %r13d, %esi /* ipl */
- movl %r14d, %edx /* old ipl */
- movq %rbp, %rcx /* &regs */
- call hilevel_intr_prolog
- orl %eax, %eax /* zero if need to switch stack */
- jnz 1f
-
- /*
- * Save the thread stack and get on the cpu's interrupt stack
- */
- movq %rsp, %r15
- movq CPU_INTR_STACK(%rbx), %rsp
-1:
-
- sti
-
- /*
- * Walk the list of handlers for this vector, calling
- * them as we go until no more interrupts are claimed.
- */
- movl REGOFF_TRAPNO(%rbp), %edi
- call av_dispatch_autovect
-
- cli
-
- movq %rbx, %rdi /* &cpu */
- movl %r13d, %esi /* ipl */
- movl %r14d, %edx /* oldipl */
- movl REGOFF_TRAPNO(%rbp), %ecx /* vec */
- call hilevel_intr_epilog
- orl %eax, %eax /* zero if need to switch stack */
- jnz 2f
- movq %r15, %rsp
-2: /*
- * Check for, and execute, softints before we iret.
- *
- * (dosoftint expects oldipl in %r14d (which is where it is)
- * the cpu pointer in %rbx (which is where it is) and the
- * softinfo in %edx (which is where we'll put it right now))
- */
- movl CPU_SOFTINFO(%rbx), %edx
- orl %edx, %edx
- jz _sys_rtt
- jmp dosoftint
+ movq %rsp, %rdi /* pass struct regs pointer */
+ call do_interrupt
+ jmp _sys_rtt
/*NOTREACHED*/
SET_SIZE(cmnint)
SET_SIZE(_interrupt)
-/*
- * Handle an interrupt in a new thread
- *
- * As we branch here, interrupts are still masked,
- * %rbx still contains the cpu pointer,
- * %r14d contains the old ipl that we came in on, and
- * %eax contains the new ipl that we got from the setlvl routine
- */
-
- ENTRY_NP(intr_thread)
-
- movq %rbx, %rdi /* &cpu */
- movq %rbp, %rsi /* &regs = stack pointer for _sys_rtt */
- movl REGOFF_TRAPNO(%rbp), %r12d /* stash the vec */
- movl %eax, %edx /* new pil from setlvlx() */
- call intr_thread_prolog
- movq %rsp, %r15
- movq %rax, %rsp /* t_stk from interrupt thread */
- movq %rsp, %rbp
-
- sti
-
- testl $FTRACE_ENABLED, CPU_FTRACE_STATE(%rbx)
- jz 1f
- /*
- * ftracing support. do we need this on x86?
- */
- leaq _ftrace_intr_thread_fmt(%rip), %rdi
- movq %rbp, %rsi /* &regs */
- movl %r12d, %edx /* vec */
- movq CPU_THREAD(%rbx), %r11 /* (the interrupt thread) */
- movzbl T_PIL(%r11), %ecx /* newipl */
- call ftrace_3_notick
-1:
- movl %r12d, %edi /* vec */
- call av_dispatch_autovect
-
- cli
-
- movq %rbx, %rdi /* &cpu */
- movl %r12d, %esi /* vec */
- movl %r14d, %edx /* oldpil */
- call intr_thread_epilog
- /*
- * If we return from here (we might not if the interrupted thread
- * has exited or blocked, in which case we'll have quietly swtch()ed
- * away) then we need to switch back to our old %rsp
- */
- movq %r15, %rsp
- movq %rsp, %rbp
- /*
- * Check for, and execute, softints before we iret.
- *
- * (dosoftint expects oldpil in %r14d, the cpu pointer in %rbx and
- * the mcpu_softinfo.st_pending field in %edx.
- */
- movl CPU_SOFTINFO(%rbx), %edx
- orl %edx, %edx
- jz _sys_rtt
- /*FALLTHROUGH*/
-
-/*
- * Process soft interrupts.
- * Interrupts are masked, and we have a minimal frame on the stack.
- * %edx should contain the mcpu_softinfo.st_pending field
- */
-
- ALTENTRY(dosoftint)
-
- movq %rbx, %rdi /* &cpu */
- movq %rbp, %rsi /* &regs = stack pointer for _sys_rtt */
- /* cpu->cpu_m.mcpu_softinfo.st_pending */
- movl %r14d, %ecx /* oldipl */
- call dosoftint_prolog
- /*
- * dosoftint_prolog() usually returns a stack pointer for the
- * interrupt thread that we must switch to. However, if the
- * returned stack pointer is NULL, then the software interrupt was
- * too low in priority to run now; we'll catch it another time.
- */
- orq %rax, %rax
- jz _sys_rtt
- movq %rsp, %r15
- movq %rax, %rsp /* t_stk from interrupt thread */
- movq %rsp, %rbp
-
- sti
-
- /*
- * Enabling interrupts (above) could raise the current ipl
- * and base spl. But, we continue processing the current soft
- * interrupt and we will check the base spl next time around
- * so that blocked interrupt threads get a chance to run.
- */
- movq CPU_THREAD(%rbx), %r11 /* now an interrupt thread */
- movzbl T_PIL(%r11), %edi
- call av_dispatch_softvect
-
- cli
-
- movq %rbx, %rdi /* &cpu */
- movl %r14d, %esi /* oldpil */
- call dosoftint_epilog
- movq %r15, %rsp /* back on old stack pointer */
- movq %rsp, %rbp
- movl CPU_SOFTINFO(%rbx), %edx
- orl %edx, %edx
- jz _sys_rtt
- jmp dosoftint
-
- SET_SIZE(dosoftint)
- SET_SIZE(intr_thread)
-
#elif defined(__i386)
-/*
- * One day, this should just invoke the C routines that know how to
- * do all the interrupt bookkeeping. In the meantime, try
- * and make the assembler a little more comprehensible.
- */
-
-#define INC64(basereg, offset) \
- addl $1, offset(basereg); \
- adcl $0, offset + 4(basereg)
-
-#define TSC_CLR(basereg, offset) \
- movl $0, offset(basereg); \
- movl $0, offset + 4(basereg)
-
-/*
- * The following macros assume the time value is in %edx:%eax
- * e.g. from a rdtsc instruction.
- */
-#define TSC_STORE(reg, offset) \
- movl %eax, offset(reg); \
- movl %edx, offset + 4(reg)
-
-#define TSC_LOAD(reg, offset) \
- movl offset(reg), %eax; \
- movl offset + 4(reg), %edx
-
-#define TSC_ADD_TO(reg, offset) \
- addl %eax, offset(reg); \
- adcl %edx, offset + 4(reg)
-
-#define TSC_SUB_FROM(reg, offset) \
- subl offset(reg), %eax; \
- sbbl offset + 4(reg), %edx /* interval in edx:eax */
-
-/*
- * basereg - pointer to cpu struct
- * pilreg - pil or converted pil (pil - (LOCK_LEVEL + 1))
- *
- * Returns (base + pil * 8) in pilreg
- */
-#define PILBASE(basereg, pilreg) \
- lea (basereg, pilreg, 8), pilreg
-
-/*
- * Returns (base + (pil - (LOCK_LEVEL + 1)) * 8) in pilreg
- */
-#define HIGHPILBASE(basereg, pilreg) \
- subl $LOCK_LEVEL + 1, pilreg; \
- PILBASE(basereg, pilreg)
-
-/*
- * Returns (base + pil * 16) in pilreg
- */
-#define PILBASE_INTRSTAT(basereg, pilreg) \
- shl $4, pilreg; \
- addl basereg, pilreg;
-
-/*
- * Returns (cpu + cpu_mstate * 8) in tgt
- */
-#define INTRACCTBASE(cpureg, tgtreg) \
- movzwl CPU_MSTATE(cpureg), tgtreg; \
- lea (cpureg, tgtreg, 8), tgtreg
-
-/*
- * cpu_stats.sys.intr[PIL]++
- */
-#define INC_CPU_STATS_INTR(pilreg, tmpreg, tmpreg_32, basereg) \
- movl pilreg, tmpreg_32; \
- PILBASE(basereg, tmpreg); \
- INC64(tmpreg, _CONST(CPU_STATS_SYS_INTR - 8))
-
-/*
- * Unlink thread from CPU's list
- */
-#define UNLINK_INTR_THREAD(cpureg, ithread, tmpreg) \
- mov CPU_INTR_THREAD(cpureg), ithread; \
- mov T_LINK(ithread), tmpreg; \
- mov tmpreg, CPU_INTR_THREAD(cpureg)
-
-/*
- * Link a thread into CPU's list
- */
-#define LINK_INTR_THREAD(cpureg, ithread, tmpreg) \
- mov CPU_INTR_THREAD(cpureg), tmpreg; \
- mov tmpreg, T_LINK(ithread); \
- mov ithread, CPU_INTR_THREAD(cpureg)
-
-#if defined(DEBUG)
-
-/*
- * Do not call panic, if panic is already in progress.
- */
-#define __PANIC(msg, label) \
- cmpl $0, panic_quiesce; \
- jne label; \
- pushl $msg; \
- call panic
-
-#define __CMP64_JNE(basereg, offset, label) \
- cmpl $0, offset(basereg); \
- jne label; \
- cmpl $0, offset + 4(basereg); \
- jne label
-
-/*
- * ASSERT(!(CPU->cpu_intr_actv & (1 << PIL)))
- */
-#define ASSERT_NOT_CPU_INTR_ACTV(pilreg, basereg, msg) \
- btl pilreg, CPU_INTR_ACTV(basereg); \
- jnc 4f; \
- __PANIC(msg, 4f); \
-4:
-
-/*
- * ASSERT(CPU->cpu_intr_actv & (1 << PIL))
- */
-#define ASSERT_CPU_INTR_ACTV(pilreg, basereg, msg) \
- btl pilreg, CPU_INTR_ACTV(basereg); \
- jc 5f; \
- __PANIC(msg, 5f); \
-5:
-
-/*
- * ASSERT(CPU->cpu_pil_high_start != 0)
- */
-#define ASSERT_CPU_PIL_HIGH_START_NZ(basereg) \
- __CMP64_JNE(basereg, CPU_PIL_HIGH_START, 6f); \
- __PANIC(_interrupt_timestamp_zero, 6f); \
-6:
-
-/*
- * ASSERT(t->t_intr_start != 0)
- */
-#define ASSERT_T_INTR_START_NZ(basereg) \
- __CMP64_JNE(basereg, T_INTR_START, 7f); \
- __PANIC(_intr_thread_t_intr_start_zero, 7f); \
-7:
-
-_interrupt_actv_bit_set:
- .string "_interrupt(): cpu_intr_actv bit already set for PIL"
-_interrupt_actv_bit_not_set:
- .string "_interrupt(): cpu_intr_actv bit not set for PIL"
-_interrupt_timestamp_zero:
- .string "_interrupt(): timestamp zero upon handler return"
-_intr_thread_actv_bit_not_set:
- .string "intr_thread(): cpu_intr_actv bit not set for PIL"
-_intr_thread_t_intr_start_zero:
- .string "intr_thread(): t_intr_start zero upon handler return"
-_dosoftint_actv_bit_set:
- .string "dosoftint(): cpu_intr_actv bit already set for PIL"
-_dosoftint_actv_bit_not_set:
- .string "dosoftint(): cpu_intr_actv bit not set for PIL"
-
- DGDEF(intr_thread_cnt)
- .4byte 0
-
-#else
-#define ASSERT_NOT_CPU_INTR_ACTV(pilreg, basereg, msg)
-#define ASSERT_CPU_INTR_ACTV(pilreg, basereg, msg)
-#define ASSERT_CPU_PIL_HIGH_START_NZ(basereg)
-#define ASSERT_T_INTR_START_NZ(basereg)
-#endif
-
ENTRY_NP2(cmnint, _interrupt)
INTR_PUSH
+ INTGATE_INIT_KERNEL_FLAGS
/*
* At the end of TRACE_PTR %esi points to the current TRAPTRACE entry
@@ -546,298 +156,15 @@ _dosoftint_actv_bit_not_set:
TRACE_STAMP(%esi) /* Clobbers %eax, %edx, uses 9 */
movl %esp, %ebp
- DISABLE_INTR_FLAGS
- LOADCPU(%ebx) /* get pointer to CPU struct. Avoid gs refs */
- leal REGOFF_TRAPNO(%ebp), %ecx /* get address of vector */
- movl CPU_PRI(%ebx), %edi /* get ipl */
- movl CPU_SOFTINFO(%ebx), %edx
- /
- / Check to see if the trap number is T_SOFTINT; if it is, we'll
- / jump straight to dosoftint now.
- /
- cmpl $T_SOFTINT, (%ecx)
- je dosoftint
+ TRACE_STACK(%esi)
- / raise interrupt priority level
- / oldipl is in %edi, vectorp is in %ecx
- / newipl is returned in %eax
- pushl %ecx
- pushl %edi
- call *setlvl
- popl %edi /* save oldpil in %edi */
- popl %ecx
+ pushl %esi /* pass traptrace record pointer */
+ pushl %ebp /* pass struct regs pointer */
+ call do_interrupt /* interrupt service routine */
+ addl $8, %esp /* pop args off of stack */
-#ifdef TRAPTRACE
- movb %al, TTR_IPL(%esi)
-#endif
-
- / check for spurious interrupt
- cmp $-1, %eax
- je _sys_rtt
-
-#ifdef TRAPTRACE
- movl CPU_PRI(%ebx), %edx
- movb %dl, TTR_PRI(%esi)
- movl CPU_BASE_SPL(%ebx), %edx
- movb %dl, TTR_SPL(%esi)
-#endif
-
- movl %eax, CPU_PRI(%ebx) /* update ipl */
- movl REGOFF_TRAPNO(%ebp), %ecx /* reload the interrupt vector */
-
-#ifdef TRAPTRACE
- movb %cl, TTR_VECTOR(%esi)
-#endif
-
- / At this point we can take one of two paths. If the new priority
- / level is less than or equal to LOCK LEVEL then we jump to code that
- / will run this interrupt as a separate thread. Otherwise the
- / interrupt is NOT run as a separate thread.
-
- / %edi - old priority level
- / %ebp - pointer to REGS
- / %ecx - translated vector
- / %eax - ipl of isr
- / %ebx - cpu pointer
-
- cmpl $LOCK_LEVEL, %eax /* compare to highest thread level */
- jbe intr_thread /* process as a separate thread */
-
- cmpl $CBE_HIGH_PIL, %eax /* Is this a CY_HIGH_LEVEL interrupt? */
- jne 2f
-
- movl REGOFF_PC(%ebp), %esi
- movl %edi, CPU_PROFILE_PIL(%ebx) /* record interrupted PIL */
- testw $CPL_MASK, REGOFF_CS(%ebp) /* trap from supervisor mode? */
- jz 1f
- movl %esi, CPU_PROFILE_UPC(%ebx) /* record user PC */
- movl $0, CPU_PROFILE_PC(%ebx) /* zero kernel PC */
- jmp 2f
-
-1:
- movl %esi, CPU_PROFILE_PC(%ebx) /* record kernel PC */
- movl $0, CPU_PROFILE_UPC(%ebx) /* zero user PC */
-
-2:
- pushl %ecx /* vec */
- pushl %eax /* newpil */
-
- /
- / See if we are interrupting another high-level interrupt.
- /
- movl CPU_INTR_ACTV(%ebx), %eax
- andl $CPU_INTR_ACTV_HIGH_LEVEL_MASK, %eax
- jz 0f
- /
- / We have interrupted another high-level interrupt.
- / Load starting timestamp, compute interval, update cumulative counter.
- /
- bsrl %eax, %ecx /* find PIL of interrupted handler */
- movl %ecx, %esi /* save PIL for later */
- HIGHPILBASE(%ebx, %ecx)
-_tsc_patch1:
- nop; nop /* patched to rdtsc if available */
- TSC_SUB_FROM(%ecx, CPU_PIL_HIGH_START)
-
- PILBASE_INTRSTAT(%ebx, %esi)
- TSC_ADD_TO(%esi, CPU_INTRSTAT)
- INTRACCTBASE(%ebx, %ecx)
- TSC_ADD_TO(%ecx, CPU_INTRACCT) /* cpu_intracct[cpu_mstate] += tsc */
- /
- / Another high-level interrupt is active below this one, so
- / there is no need to check for an interrupt thread. That will be
- / done by the lowest priority high-level interrupt active.
- /
- jmp 1f
-0:
- /
- / See if we are interrupting a low-level interrupt thread.
- /
- movl CPU_THREAD(%ebx), %esi
- testw $T_INTR_THREAD, T_FLAGS(%esi)
- jz 1f
- /
- / We have interrupted an interrupt thread. Account for its time slice
- / only if its time stamp is non-zero.
- /
- cmpl $0, T_INTR_START+4(%esi)
- jne 0f
- cmpl $0, T_INTR_START(%esi)
- je 1f
-0:
- movzbl T_PIL(%esi), %ecx /* %ecx has PIL of interrupted handler */
- PILBASE_INTRSTAT(%ebx, %ecx)
-_tsc_patch2:
- nop; nop /* patched to rdtsc if available */
- TSC_SUB_FROM(%esi, T_INTR_START)
- TSC_CLR(%esi, T_INTR_START)
- TSC_ADD_TO(%ecx, CPU_INTRSTAT)
- INTRACCTBASE(%ebx, %ecx)
- TSC_ADD_TO(%ecx, CPU_INTRACCT) /* cpu_intracct[cpu_mstate] += tsc */
-1:
- / Store starting timestamp in CPU structure for this PIL.
- popl %ecx /* restore new PIL */
- pushl %ecx
- HIGHPILBASE(%ebx, %ecx)
-_tsc_patch3:
- nop; nop /* patched to rdtsc if available */
- TSC_STORE(%ecx, CPU_PIL_HIGH_START)
-
- popl %eax /* restore new pil */
- popl %ecx /* vec */
- /
- / Set bit for this PIL in CPU's interrupt active bitmask.
- /
-
- ASSERT_NOT_CPU_INTR_ACTV(%eax, %ebx, _interrupt_actv_bit_set)
-
- / Save old CPU_INTR_ACTV
- movl CPU_INTR_ACTV(%ebx), %esi
-
- cmpl $15, %eax
- jne 0f
- / PIL-15 interrupt. Increment nest-count in upper 16 bits of intr_actv
- incw CPU_INTR_ACTV_REF(%ebx) /* increment ref count */
-0:
- btsl %eax, CPU_INTR_ACTV(%ebx)
- /
- / Handle high-level nested interrupt on separate interrupt stack
- /
- testl $CPU_INTR_ACTV_HIGH_LEVEL_MASK, %esi
- jnz onstack /* already on interrupt stack */
- movl %esp, %eax
- movl CPU_INTR_STACK(%ebx), %esp /* get on interrupt stack */
- pushl %eax /* save the thread stack pointer */
-onstack:
- movl $autovect, %esi /* get autovect structure before */
- /* sti to save on AGI later */
- sti /* enable interrupts */
- pushl %ecx /* save interrupt vector */
- /
- / Get handler address
- /
-pre_loop1:
- movl AVH_LINK(%esi, %ecx, 8), %esi
- xorl %ebx, %ebx /* bh is no. of intpts in chain */
- /* bl is DDI_INTR_CLAIMED status of chain */
- testl %esi, %esi /* if pointer is null */
- jz .intr_ret /* then skip */
-loop1:
- incb %bh
- movl AV_VECTOR(%esi), %edx /* get the interrupt routine */
- testl %edx, %edx /* if func is null */
- jz .intr_ret /* then skip */
- pushl $0
- pushl AV_INTARG2(%esi)
- pushl AV_INTARG1(%esi)
- pushl AV_VECTOR(%esi)
- pushl AV_DIP(%esi)
- call __dtrace_probe_interrupt__start
- pushl AV_INTARG2(%esi) /* get 2nd arg to interrupt routine */
- pushl AV_INTARG1(%esi) /* get first arg to interrupt routine */
- call *%edx /* call interrupt routine with arg */
- addl $8, %esp
- movl %eax, 16(%esp)
- call __dtrace_probe_interrupt__complete
- addl $20, %esp
- orb %al, %bl /* see if anyone claims intpt. */
- movl AV_LINK(%esi), %esi /* get next routine on list */
- testl %esi, %esi /* if pointer is non-null */
- jnz loop1 /* then continue */
-
-.intr_ret:
- cmpb $1, %bh /* if only 1 intpt in chain, it is OK */
- je .intr_ret1
- orb %bl, %bl /* If no one claims intpt, then it is OK */
- jz .intr_ret1
- movl (%esp), %ecx /* else restore intr vector */
- movl $autovect, %esi /* get autovect structure */
- jmp pre_loop1 /* and try again. */
-
-.intr_ret1:
- LOADCPU(%ebx) /* get pointer to cpu struct */
-
- cli
- movl CPU_PRI(%ebx), %esi
-
- / cpu_stats.sys.intr[PIL]++
- INC_CPU_STATS_INTR(%esi, %eax, %eax, %ebx)
-
- /
- / Clear bit for this PIL in CPU's interrupt active bitmask.
- /
-
- ASSERT_CPU_INTR_ACTV(%esi, %ebx, _interrupt_actv_bit_not_set)
-
- cmpl $15, %esi
- jne 0f
- / Only clear bit if reference count is now zero.
- decw CPU_INTR_ACTV_REF(%ebx)
- jnz 1f
-0:
- btrl %esi, CPU_INTR_ACTV(%ebx)
-1:
- /
- / Take timestamp, compute interval, update cumulative counter.
- / esi = PIL
-_tsc_patch4:
- nop; nop /* patched to rdtsc if available */
- movl %esi, %ecx /* save for later */
- HIGHPILBASE(%ebx, %esi)
-
- ASSERT_CPU_PIL_HIGH_START_NZ(%esi)
-
- TSC_SUB_FROM(%esi, CPU_PIL_HIGH_START)
-
- PILBASE_INTRSTAT(%ebx, %ecx)
- TSC_ADD_TO(%ecx, CPU_INTRSTAT)
- INTRACCTBASE(%ebx, %esi)
- TSC_ADD_TO(%esi, CPU_INTRACCT) /* cpu_intracct[cpu_mstate] += tsc */
- /
- / Check for lower-PIL nested high-level interrupt beneath current one
- / If so, place a starting timestamp in its pil_high_start entry.
- /
- movl CPU_INTR_ACTV(%ebx), %eax
- movl %eax, %esi
- andl $CPU_INTR_ACTV_HIGH_LEVEL_MASK, %eax
- jz 0f
- bsrl %eax, %ecx /* find PIL of nested interrupt */
- HIGHPILBASE(%ebx, %ecx)
-_tsc_patch5:
- nop; nop /* patched to rdtsc if available */
- TSC_STORE(%ecx, CPU_PIL_HIGH_START)
- /
- / Another high-level interrupt is active below this one, so
- / there is no need to check for an interrupt thread. That will be
- / done by the lowest priority high-level interrupt active.
- /
- jmp 1f
-0:
- / Check to see if there is a low-level interrupt active. If so,
- / place a starting timestamp in the thread structure.
- movl CPU_THREAD(%ebx), %esi
- testw $T_INTR_THREAD, T_FLAGS(%esi)
- jz 1f
-_tsc_patch6:
- nop; nop /* patched to rdtsc if available */
- TSC_STORE(%esi, T_INTR_START)
-1:
- movl %edi, CPU_PRI(%ebx)
- /* interrupt vector already on stack */
- pushl %edi /* old ipl */
- call *setlvlx
- addl $8, %esp /* eax contains the current ipl */
-
- movl CPU_INTR_ACTV(%ebx), %esi /* reset stack pointer if no more */
- shrl $LOCK_LEVEL + 1, %esi /* HI PRI intrs. */
- jnz .intr_ret2
- popl %esp /* restore the thread stack pointer */
-.intr_ret2:
- movl CPU_SOFTINFO(%ebx), %edx /* any pending software interrupts */
- orl %edx, %edx
- jz _sys_rtt
- jmp dosoftint /* check for softints before we return. */
+ jmp _sys_rtt
SET_SIZE(cmnint)
SET_SIZE(_interrupt)
@@ -855,388 +182,6 @@ _interrupt_size:
#endif /* __lint */
-#if defined(__i386)
-
-/*
- * Handle an interrupt in a new thread.
- * Entry: traps disabled.
- * %edi - old priority level
- * %ebp - pointer to REGS
- * %ecx - translated vector
- * %eax - ipl of isr.
- * %ebx - pointer to CPU struct
- * Uses:
- */
-
-#if !defined(__lint)
-
- ENTRY_NP(intr_thread)
- /
- / Set bit for this PIL in CPU's interrupt active bitmask.
- /
-
- ASSERT_NOT_CPU_INTR_ACTV(%eax, %ebx, _interrupt_actv_bit_set)
-
- btsl %eax, CPU_INTR_ACTV(%ebx)
-
- / Get set to run interrupt thread.
- / There should always be an interrupt thread since we allocate one
- / for each level on the CPU.
- /
- / Note that the code in kcpc_overflow_intr -relies- on the ordering
- / of events here - in particular that t->t_lwp of the interrupt
- / thread is set to the pinned thread *before* curthread is changed
- /
- movl CPU_THREAD(%ebx), %edx /* cur thread in edx */
-
- /
- / Are we interrupting an interrupt thread? If so, account for it.
- /
- testw $T_INTR_THREAD, T_FLAGS(%edx)
- jz 0f
- /
- / We have interrupted an interrupt thread. Account for its time slice
- / only if its time stamp is non-zero. t_intr_start may be zero due to
- / cpu_intr_swtch_enter.
- /
- cmpl $0, T_INTR_START+4(%edx)
- jne 1f
- cmpl $0, T_INTR_START(%edx)
- je 0f
-1:
- pushl %ecx
- pushl %eax
- movl %edx, %esi
-_tsc_patch7:
- nop; nop /* patched to rdtsc if available */
- TSC_SUB_FROM(%esi, T_INTR_START)
- TSC_CLR(%esi, T_INTR_START)
- movzbl T_PIL(%esi), %ecx
- PILBASE_INTRSTAT(%ebx, %ecx)
- TSC_ADD_TO(%ecx, CPU_INTRSTAT)
- INTRACCTBASE(%ebx, %ecx)
- TSC_ADD_TO(%ecx, CPU_INTRACCT) /* cpu_intracct[cpu_mstate] += tsc */
- movl %esi, %edx
- popl %eax
- popl %ecx
-0:
- movl %esp, T_SP(%edx) /* mark stack in curthread for resume */
- pushl %edi /* get a temporary register */
- UNLINK_INTR_THREAD(%ebx, %esi, %edi)
-
- movl T_LWP(%edx), %edi
- movl %edx, T_INTR(%esi) /* push old thread */
- movl %edi, T_LWP(%esi)
- /
- / Threads on the interrupt thread free list could have state already
- / set to TS_ONPROC, but it helps in debugging if they're TS_FREE
- /
- movl $ONPROC_THREAD, T_STATE(%esi)
- /
- / chain the interrupted thread onto list from the interrupt thread.
- / Set the new interrupt thread as the current one.
- /
- popl %edi /* Don't need a temp reg anymore */
- movl T_STACK(%esi), %esp /* interrupt stack pointer */
- movl %esp, %ebp
- movl %esi, CPU_THREAD(%ebx) /* set new thread */
- pushl %eax /* save the ipl */
- /
- / Initialize thread priority level from intr_pri
- /
- movb %al, T_PIL(%esi) /* store pil */
- movzwl intr_pri, %ebx /* XXX Can cause probs if new class */
- /* is loaded on some other cpu. */
- addl %ebx, %eax /* convert level to dispatch priority */
- movw %ax, T_PRI(%esi)
-
- /
- / Take timestamp and store it in the thread structure.
- /
- movl %eax, %ebx /* save priority over rdtsc */
-_tsc_patch8:
- nop; nop /* patched to rdtsc if available */
- TSC_STORE(%esi, T_INTR_START)
- movl %ebx, %eax /* restore priority */
-
- / The following 3 instructions need not be in cli.
- / Putting them here only to avoid the AGI penalty on Pentiums.
-
- pushl %ecx /* save interrupt vector. */
- pushl %esi /* save interrupt thread */
- movl $autovect, %esi /* get autovect structure */
- sti /* enable interrupts */
-
- / Fast event tracing.
- LOADCPU(%ebx)
- movl CPU_FTRACE_STATE(%ebx), %ebx
- testl $FTRACE_ENABLED, %ebx
- jz 1f
-
- movl 8(%esp), %ebx
- pushl %ebx /* ipl */
- pushl %ecx /* int vector */
- movl T_SP(%edx), %ebx
- pushl %ebx /* &regs */
- pushl $_ftrace_intr_thread_fmt
- call ftrace_3_notick
- addl $8, %esp
- popl %ecx /* restore int vector */
- addl $4, %esp
-1:
-pre_loop2:
- movl AVH_LINK(%esi, %ecx, 8), %esi
- xorl %ebx, %ebx /* bh is cno. of intpts in chain */
- /* bl is DDI_INTR_CLAIMED status of * chain */
- testl %esi, %esi /* if pointer is null */
- jz loop_done2 /* we're done */
-loop2:
- movl AV_VECTOR(%esi), %edx /* get the interrupt routine */
- testl %edx, %edx /* if pointer is null */
- jz loop_done2 /* we're done */
- incb %bh
- pushl $0
- pushl AV_INTARG2(%esi)
- pushl AV_INTARG1(%esi)
- pushl AV_VECTOR(%esi)
- pushl AV_DIP(%esi)
- call __dtrace_probe_interrupt__start
- pushl AV_INTARG2(%esi) /* get 2nd arg to interrupt routine */
- pushl AV_INTARG1(%esi) /* get first arg to interrupt routine */
- call *%edx /* call interrupt routine with arg */
- addl $8, %esp
- movl %eax, 16(%esp)
- call __dtrace_probe_interrupt__complete
- addl $20, %esp
- orb %al, %bl /* see if anyone claims intpt. */
- movl AV_TICKSP(%esi), %ecx
- testl %ecx, %ecx
- jz no_time
- call intr_get_time
- movl AV_TICKSP(%esi), %ecx
- TSC_ADD_TO(%ecx, 0)
-no_time:
- movl AV_LINK(%esi), %esi /* get next routine on list */
- testl %esi, %esi /* if pointer is non-null */
- jnz loop2 /* continue */
-loop_done2:
- cmpb $1, %bh /* if only 1 intpt in chain, it is OK */
- je .loop_done2_1
- orb %bl, %bl /* If no one claims intpt, then it is OK */
- jz .loop_done2_1
- movl $autovect, %esi /* else get autovect structure */
- movl 4(%esp), %ecx /* restore intr vector */
- jmp pre_loop2 /* and try again. */
-.loop_done2_1:
- popl %esi /* restore intr thread pointer */
-
- LOADCPU(%ebx)
-
- cli /* protect interrupt thread pool and intr_actv */
- movzbl T_PIL(%esi), %eax
-
- / Save value in regs
- pushl %eax /* current pil */
- pushl %edx /* (huh?) */
- pushl %edi /* old pil */
-
- / cpu_stats.sys.intr[PIL]++
- INC_CPU_STATS_INTR(%eax, %edx, %edx, %ebx)
-
- /
- / Take timestamp, compute interval, and update cumulative counter.
- / esi = thread pointer, ebx = cpu pointer, eax = PIL
- /
- movl %eax, %edi
-
- ASSERT_T_INTR_START_NZ(%esi)
-
-_tsc_patch9:
- nop; nop /* patched to rdtsc if available */
- TSC_SUB_FROM(%esi, T_INTR_START)
- PILBASE_INTRSTAT(%ebx, %edi)
- TSC_ADD_TO(%edi, CPU_INTRSTAT)
- INTRACCTBASE(%ebx, %edi)
- TSC_ADD_TO(%edi, CPU_INTRACCT) /* cpu_intracct[cpu_mstate] += tsc */
- popl %edi
- popl %edx
- popl %eax
-
- /
- / Clear bit for this PIL in CPU's interrupt active bitmask.
- /
-
- ASSERT_CPU_INTR_ACTV(%eax, %ebx, _intr_thread_actv_bit_not_set)
-
- btrl %eax, CPU_INTR_ACTV(%ebx)
-
- / if there is still an interrupted thread underneath this one
- / then the interrupt was never blocked and the return is fairly
- / simple. Otherwise jump to intr_thread_exit
- cmpl $0, T_INTR(%esi)
- je intr_thread_exit
-
- /
- / link the thread back onto the interrupt thread pool
- LINK_INTR_THREAD(%ebx, %esi, %edx)
-
- movl CPU_BASE_SPL(%ebx), %eax /* used below. */
- / set the thread state to free so kmdb doesn't see it
- movl $FREE_THREAD, T_STATE(%esi)
-
- cmpl %eax, %edi /* if (oldipl >= basespl) */
- jae intr_restore_ipl /* then use oldipl */
- movl %eax, %edi /* else use basespl */
-intr_restore_ipl:
- movl %edi, CPU_PRI(%ebx)
- /* intr vector already on stack */
- pushl %edi /* old ipl */
- call *setlvlx /* eax contains the current ipl */
- /
- / Switch back to the interrupted thread
- movl T_INTR(%esi), %ecx
-
- / Place starting timestamp in interrupted thread's thread structure.
-_tsc_patch10:
- nop; nop /* patched to rdtsc if available */
- TSC_STORE(%ecx, T_INTR_START)
-
- movl T_SP(%ecx), %esp /* restore stack pointer */
- movl %esp, %ebp
- movl %ecx, CPU_THREAD(%ebx)
-
- movl CPU_SOFTINFO(%ebx), %edx /* any pending software interrupts */
- orl %edx, %edx
- jz _sys_rtt
- jmp dosoftint /* check for softints before we return. */
-
- /
- / An interrupt returned on what was once (and still might be)
- / an interrupt thread stack, but the interrupted process is no longer
- / there. This means the interrupt must have blocked.
- /
- / There is no longer a thread under this one, so put this thread back
- / on the CPU's free list and resume the idle thread which will dispatch
- / the next thread to run.
- /
- / All interrupts are disabled here
- /
-
-intr_thread_exit:
-#ifdef DEBUG
- incl intr_thread_cnt
-#endif
- INC64(%ebx, CPU_STATS_SYS_INTRBLK) /* cpu_stats.sys.intrblk++ */
- /
- / Put thread back on the interrupt thread list.
- / As a reminder, the regs at this point are
- / esi interrupt thread
- / edi old ipl
- / ebx ptr to CPU struct
-
- / Set CPU's base SPL level based on active interrupts bitmask
- call set_base_spl
-
- movl CPU_BASE_SPL(%ebx), %edi
- movl %edi, CPU_PRI(%ebx)
- /* interrupt vector already on stack */
- pushl %edi
- call *setlvlx
- addl $8, %esp /* XXX - don't need to pop since */
- /* we are ready to switch */
- call splhigh /* block all intrs below lock level */
- /
- / Set the thread state to free so kmdb doesn't see it
- /
- movl $FREE_THREAD, T_STATE(%esi)
- /
- / Put thread on either the interrupt pool or the free pool and
- / call swtch() to resume another thread.
- /
- LINK_INTR_THREAD(%ebx, %esi, %edx)
- call swtch
- / swtch() shouldn't return
-
- SET_SIZE(intr_thread)
-
-#endif /* __lint */
-#endif /* __i386 */
-
-/*
- * Set Cpu's base SPL level, base on which interrupt levels are active
- * Called at spl7 or above.
- */
-
-#if defined(__lint)
-
-void
-set_base_spl(void)
-{}
-
-#else /* __lint */
-
- ENTRY_NP(set_base_spl)
- movl %gs:CPU_INTR_ACTV, %eax /* load active interrupts mask */
- testl %eax, %eax /* is it zero? */
- jz setbase
- testl $0xff00, %eax
- jnz ah_set
- shl $24, %eax /* shift 'em over so we can find */
- /* the 1st bit faster */
- bsrl %eax, %eax
- subl $24, %eax
-setbase:
- movl %eax, %gs:CPU_BASE_SPL /* store base priority */
- ret
-ah_set:
- shl $16, %eax
- bsrl %eax, %eax
- subl $16, %eax
- jmp setbase
- SET_SIZE(set_base_spl)
-
-#endif /* __lint */
-
-#if defined(__i386)
-
-/*
- * int
- * intr_passivate(from, to)
- * thread_id_t from; interrupt thread
- * thread_id_t to; interrupted thread
- *
- * intr_passivate(t, itp) makes the interrupted thread "t" runnable.
- *
- * Since t->t_sp has already been saved, t->t_pc is all that needs
- * set in this function.
- *
- * Returns interrupt level of the thread.
- */
-
-#if defined(__lint)
-
-/* ARGSUSED */
-int
-intr_passivate(kthread_id_t from, kthread_id_t to)
-{ return (0); }
-
-#else /* __lint */
-
- ENTRY(intr_passivate)
- movl 8(%esp), %eax /* interrupted thread */
- movl $_sys_rtt, T_PC(%eax) /* set T_PC for interrupted thread */
-
- movl 4(%esp), %eax /* interrupt thread */
- movl T_STACK(%eax), %eax /* get the pointer to the start of */
- /* of the interrupt thread stack */
- movl -4(%eax), %eax /* interrupt level was the first */
- /* thing pushed onto the stack */
- ret
- SET_SIZE(intr_passivate)
-
-#endif /* __lint */
-#endif /* __i386 */
-
#if defined(__lint)
void
@@ -1274,412 +219,24 @@ fakesoftint(void)
pushq $0 /* err */
pushq $T_SOFTINT /* trap */
jmp cmnint
+ ALTENTRY(fakesoftint_return)
+ ret
+ SET_SIZE(fakesoftint_return)
SET_SIZE(fakesoftint)
#elif defined(__i386)
ENTRY_NP(fakesoftint)
- pushf
- push %cs
- push $fakesoftint_return
- push $0
- push $T_SOFTINT
+ pushfl
+ pushl %cs
+ pushl $fakesoftint_return
+ pushl $0
+ pushl $T_SOFTINT
jmp cmnint
+ ALTENTRY(fakesoftint_return)
+ ret
+ SET_SIZE(fakesoftint_return)
SET_SIZE(fakesoftint)
#endif /* __i386 */
-
- .align CPTRSIZE
- .globl _fakesoftint_size
- .type _fakesoftint_size, @object
-_fakesoftint_size:
- .NWORD . - fakesoftint
- SET_SIZE(_fakesoftint_size)
-
-/*
- * dosoftint(old_pil in %edi, softinfo in %edx, CPU pointer in %ebx)
- * Process software interrupts
- * Interrupts are disabled here.
- */
-#if defined(__i386)
-
- ENTRY_NP(dosoftint)
-
- bsrl %edx, %edx /* find highest pending interrupt */
- cmpl %edx, %edi /* if curipl >= pri soft pending intr */
- jae _sys_rtt /* skip */
-
- movl %gs:CPU_BASE_SPL, %eax /* check for blocked intr threads */
- cmpl %edx, %eax /* if basespl >= pri soft pending */
- jae _sys_rtt /* skip */
-
- lock /* MP protect */
- btrl %edx, CPU_SOFTINFO(%ebx) /* clear the selected interrupt bit */
- jnc dosoftint_again
-
- movl %edx, CPU_PRI(%ebx) /* set IPL to sofint level */
- pushl %edx
- call *setspl /* mask levels upto the softint level */
- popl %eax /* priority we are at in %eax */
-
- / Get set to run interrupt thread.
- / There should always be an interrupt thread since we allocate one
- / for each level on the CPU.
- UNLINK_INTR_THREAD(%ebx, %esi, %edx)
-
- /
- / Note that the code in kcpc_overflow_intr -relies- on the ordering
- / of events here - in particular that t->t_lwp of the interrupt
- / thread is set to the pinned thread *before* curthread is changed
- /
- movl CPU_THREAD(%ebx), %ecx
-
- / If we are interrupting an interrupt thread, account for it.
- testw $T_INTR_THREAD, T_FLAGS(%ecx)
- jz 0f
- /
- / We have interrupted an interrupt thread. Account for its time slice
- / only if its time stamp is non-zero. t_intr_start may be zero due to
- / cpu_intr_swtch_enter.
- /
- cmpl $0, T_INTR_START+4(%ecx)
- jne 1f
- cmpl $0, T_INTR_START(%ecx)
- je 0f
-1:
- pushl %eax
- movl %eax, %ebp
-_tsc_patch11:
- nop; nop /* patched to rdtsc if available */
- PILBASE_INTRSTAT(%ebx, %ebp)
- TSC_SUB_FROM(%ecx, T_INTR_START)
- TSC_ADD_TO(%ebp, CPU_INTRSTAT)
- INTRACCTBASE(%ebx, %ebp)
- TSC_ADD_TO(%ebp, CPU_INTRACCT) /* cpu_intracct[cpu_mstate] += tsc */
- popl %eax
-0:
- movl T_LWP(%ecx), %ebp
- movl %ebp, T_LWP(%esi)
- /
- / Threads on the interrupt thread free list could have state already
- / set to TS_ONPROC, but it helps in debugging if they're TS_FREE
- / Could eliminate the next two instructions with a little work.
- /
- movl $ONPROC_THREAD, T_STATE(%esi)
- /
- / Push interrupted thread onto list from new thread.
- / Set the new thread as the current one.
- / Set interrupted thread's T_SP because if it is the idle thread,
- / Resume() may use that stack between threads.
- /
- movl %esp, T_SP(%ecx) /* mark stack for resume */
- movl %ecx, T_INTR(%esi) /* push old thread */
- movl %esi, CPU_THREAD(%ebx) /* set new thread */
- movl T_STACK(%esi), %esp /* interrupt stack pointer */
- movl %esp, %ebp
-
- pushl %eax /* push ipl as first element in stack */
- /* see intr_passivate() */
- /
- / Set bit for this PIL in CPU's interrupt active bitmask.
- /
-
- ASSERT_NOT_CPU_INTR_ACTV(%eax, %ebx, _dosoftint_actv_bit_set)
-
- btsl %eax, CPU_INTR_ACTV(%ebx)
-
- /
- / Initialize thread priority level from intr_pri
- /
- movb %al, T_PIL(%esi) /* store pil */
- movzwl intr_pri, %ecx
- addl %eax, %ecx /* convert level to dispatch priority */
- movw %cx, T_PRI(%esi)
-
- /
- / Store starting timestamp in thread structure.
- / esi = thread, ebx = cpu pointer, eax = PIL
- /
- movl %eax, %ecx /* save PIL from rdtsc clobber */
-_tsc_patch12:
- nop; nop /* patched to rdtsc if available */
- TSC_STORE(%esi, T_INTR_START)
-
- sti /* enable interrupts */
-
- /
- / Enabling interrupts (above) could raise the current
- / IPL and base SPL. But, we continue processing the current soft
- / interrupt and we will check the base SPL next time in the loop
- / so that blocked interrupt thread would get a chance to run.
- /
-
- /
- / dispatch soft interrupts
- /
- pushl %ecx
- call av_dispatch_softvect
- addl $4, %esp
-
- cli /* protect interrupt thread pool */
- /* and softinfo & sysinfo */
- movl CPU_THREAD(%ebx), %esi /* restore thread pointer */
- movzbl T_PIL(%esi), %ecx
-
- / cpu_stats.sys.intr[PIL]++
- INC_CPU_STATS_INTR(%ecx, %edx, %edx, %ebx)
-
- /
- / Clear bit for this PIL in CPU's interrupt active bitmask.
- /
-
- ASSERT_CPU_INTR_ACTV(%ecx, %ebx, _dosoftint_actv_bit_not_set)
-
- btrl %ecx, CPU_INTR_ACTV(%ebx)
-
- /
- / Take timestamp, compute interval, update cumulative counter.
- / esi = thread, ebx = cpu, ecx = PIL
- /
- PILBASE_INTRSTAT(%ebx, %ecx)
-_tsc_patch13:
- nop; nop /* patched to rdtsc if available */
- TSC_SUB_FROM(%esi, T_INTR_START)
- TSC_ADD_TO(%ecx, CPU_INTRSTAT)
- INTRACCTBASE(%ebx, %ecx)
- TSC_ADD_TO(%ecx, CPU_INTRACCT) /* cpu_intracct[cpu_mstate] += tsc */
-
- / if there is still an interrupt thread underneath this one
- / then the interrupt was never blocked and the return is fairly
- / simple. Otherwise jump to softintr_thread_exit.
- / softintr_thread_exit expect esi to be curthread & ebx to be ipl.
- cmpl $0, T_INTR(%esi)
- je softintr_thread_exit
-
- /
- / link the thread back onto the interrupt thread pool
- LINK_INTR_THREAD(%ebx, %esi, %edx)
-
- / set the thread state to free so kmdb doesn't see it
- movl $FREE_THREAD, T_STATE(%esi)
- /
- / Switch back to the interrupted thread
- movl T_INTR(%esi), %ecx
- movl %ecx, CPU_THREAD(%ebx)
- movl T_SP(%ecx), %esp /* restore stack pointer */
- movl %esp, %ebp
-
- / If we are returning to an interrupt thread, store a starting
- / timestamp in the thread structure.
- testw $T_INTR_THREAD, T_FLAGS(%ecx)
- jz 0f
-_tsc_patch14:
- nop; nop /* patched to rdtsc if available */
- TSC_STORE(%ecx, T_INTR_START)
-0:
- movl CPU_BASE_SPL(%ebx), %eax
- cmpl %eax, %edi /* if (oldipl >= basespl) */
- jae softintr_restore_ipl /* then use oldipl */
- movl %eax, %edi /* else use basespl */
-softintr_restore_ipl:
- movl %edi, CPU_PRI(%ebx) /* set IPL to old level */
- pushl %edi
- call *setspl
- popl %eax
-dosoftint_again:
- movl CPU_SOFTINFO(%ebx), %edx /* any pending software interrupts */
- orl %edx, %edx
- jz _sys_rtt
- jmp dosoftint /* process more software interrupts */
-
-softintr_thread_exit:
- /
- / Put thread back on the interrupt thread list.
- / As a reminder, the regs at this point are
- / %esi interrupt thread
-
- /
- / This was an interrupt thread, so set CPU's base SPL level
- / set_base_spl only uses %eax.
- /
- call set_base_spl /* interrupt vector already on stack */
- /
- / Set the thread state to free so kmdb doesn't see it
- /
- movl $FREE_THREAD, T_STATE(%esi)
- /
- / Put thread on either the interrupt pool or the free pool and
- / call swtch() to resume another thread.
- /
- LOADCPU(%ebx)
- LINK_INTR_THREAD(%ebx, %esi, %edx)
- call splhigh /* block all intrs below lock lvl */
- call swtch
- / swtch() shouldn't return
- SET_SIZE(dosoftint)
-
-#endif /* __i386 */
#endif /* __lint */
-
-#if defined(lint)
-
-/*
- * intr_get_time() is a resource for interrupt handlers to determine how
- * much time has been spent handling the current interrupt. Such a function
- * is needed because higher level interrupts can arrive during the
- * processing of an interrupt, thus making direct comparisons of %tick by
- * the handler inaccurate. intr_get_time() only returns time spent in the
- * current interrupt handler.
- *
- * The caller must be calling from an interrupt handler running at a pil
- * below or at lock level. Timings are not provided for high-level
- * interrupts.
- *
- * The first time intr_get_time() is called while handling an interrupt,
- * it returns the time since the interrupt handler was invoked. Subsequent
- * calls will return the time since the prior call to intr_get_time(). Time
- * is returned as ticks. Use tsc_scalehrtime() to convert ticks to nsec.
- *
- * Theory Of Intrstat[][]:
- *
- * uint64_t intrstat[pil][0..1] is an array indexed by pil level, with two
- * uint64_ts per pil.
- *
- * intrstat[pil][0] is a cumulative count of the number of ticks spent
- * handling all interrupts at the specified pil on this CPU. It is
- * exported via kstats to the user.
- *
- * intrstat[pil][1] is always a count of ticks less than or equal to the
- * value in [0]. The difference between [1] and [0] is the value returned
- * by a call to intr_get_time(). At the start of interrupt processing,
- * [0] and [1] will be equal (or nearly so). As the interrupt consumes
- * time, [0] will increase, but [1] will remain the same. A call to
- * intr_get_time() will return the difference, then update [1] to be the
- * same as [0]. Future calls will return the time since the last call.
- * Finally, when the interrupt completes, [1] is updated to the same as [0].
- *
- * Implementation:
- *
- * intr_get_time() works much like a higher level interrupt arriving. It
- * "checkpoints" the timing information by incrementing intrstat[pil][0]
- * to include elapsed running time, and by setting t_intr_start to rdtsc.
- * It then sets the return value to intrstat[pil][0] - intrstat[pil][1],
- * and updates intrstat[pil][1] to be the same as the new value of
- * intrstat[pil][0].
- *
- * In the normal handling of interrupts, after an interrupt handler returns
- * and the code in intr_thread() updates intrstat[pil][0], it then sets
- * intrstat[pil][1] to the new value of intrstat[pil][0]. When [0] == [1],
- * the timings are reset, i.e. intr_get_time() will return [0] - [1] which
- * is 0.
- *
- * Whenever interrupts arrive on a CPU which is handling a lower pil
- * interrupt, they update the lower pil's [0] to show time spent in the
- * handler that they've interrupted. This results in a growing discrepancy
- * between [0] and [1], which is returned the next time intr_get_time() is
- * called. Time spent in the higher-pil interrupt will not be returned in
- * the next intr_get_time() call from the original interrupt, because
- * the higher-pil interrupt's time is accumulated in intrstat[higherpil][].
- */
-
-/*ARGSUSED*/
-uint64_t
-intr_get_time(void)
-{ return 0; }
-#else /* lint */
-
-
-#if defined(__amd64)
- ENTRY_NP(intr_get_time)
- cli /* make this easy -- block intrs */
- LOADCPU(%rdi)
- call intr_thread_get_time
- sti
- ret
- SET_SIZE(intr_get_time)
-
-#elif defined(__i386)
-
-#ifdef DEBUG
-
-
-_intr_get_time_high_pil:
- .string "intr_get_time(): %pil > LOCK_LEVEL"
-_intr_get_time_not_intr:
- .string "intr_get_time(): not called from an interrupt thread"
-_intr_get_time_no_start_time:
- .string "intr_get_time(): t_intr_start == 0"
-
-/*
- * ASSERT(%pil <= LOCK_LEVEL)
- */
-#define ASSERT_PIL_BELOW_LOCK_LEVEL(cpureg) \
- testl $CPU_INTR_ACTV_HIGH_LEVEL_MASK, CPU_INTR_ACTV(cpureg); \
- jz 0f; \
- __PANIC(_intr_get_time_high_pil, 0f); \
-0:
-
-/*
- * ASSERT((t_flags & T_INTR_THREAD) != 0 && t_pil > 0)
- */
-#define ASSERT_NO_PIL_0_INTRS(thrreg) \
- testw $T_INTR_THREAD, T_FLAGS(thrreg); \
- jz 1f; \
- cmpb $0, T_PIL(thrreg); \
- jne 0f; \
-1: \
- __PANIC(_intr_get_time_not_intr, 0f); \
-0:
-
-/*
- * ASSERT(t_intr_start != 0)
- */
-#define ASSERT_INTR_START_NOT_0(thrreg) \
- cmpl $0, T_INTR_START(thrreg); \
- jnz 0f; \
- cmpl $0, T_INTR_START+4(thrreg); \
- jnz 0f; \
- __PANIC(_intr_get_time_no_start_time, 0f); \
-0:
-
-#endif /* DEBUG */
-
- ENTRY_NP(intr_get_time)
-
- cli /* make this easy -- block intrs */
- pushl %esi /* and free up some registers */
- pushl %ebx
-
- LOADCPU(%esi)
- movl CPU_THREAD(%esi), %ecx
-
-#ifdef DEBUG
- ASSERT_PIL_BELOW_LOCK_LEVEL(%esi)
- ASSERT_NO_PIL_0_INTRS(%ecx)
- ASSERT_INTR_START_NOT_0(%ecx)
-#endif /* DEBUG */
-
-_tsc_patch17:
- nop; nop /* patched to rdtsc if available */
- TSC_SUB_FROM(%ecx, T_INTR_START) /* get elapsed time */
- TSC_ADD_TO(%ecx, T_INTR_START) /* T_INTR_START = rdtsc */
-
- INTRACCTBASE(%esi, %ebx) /* %ebx = CPU + cpu_mstate*8 */
- TSC_ADD_TO(%ebx, CPU_INTRACCT); /* intracct[ms] += elapsed */
- movzbl T_PIL(%ecx), %ecx /* %ecx = pil */
- PILBASE_INTRSTAT(%esi, %ecx) /* %ecx = CPU + pil*16 */
- TSC_ADD_TO(%ecx, CPU_INTRSTAT) /* intrstat[0] += elapsed */
- TSC_LOAD(%ecx, CPU_INTRSTAT) /* get new intrstat[0] */
- TSC_SUB_FROM(%ecx, CPU_INTRSTAT+8) /* diff with intrstat[1] */
- TSC_ADD_TO(%ecx, CPU_INTRSTAT+8) /* intrstat[1] = intrstat[0] */
-
- /* %edx/%eax contain difference between old and new intrstat[1] */
-
- popl %ebx
- popl %esi
- sti
- ret
- SET_SIZE(intr_get_time)
-#endif /* __i386 */
-
-#endif /* lint */
diff --git a/usr/src/uts/i86pc/ml/kdi_subr.s b/usr/src/uts/i86pc/ml/kdi_subr.s
new file mode 100644
index 0000000000..8ed90ed410
--- /dev/null
+++ b/usr/src/uts/i86pc/ml/kdi_subr.s
@@ -0,0 +1,160 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/asm_linkage.h>
+#include <sys/asm_misc.h>
+#include <sys/regset.h>
+#include <sys/privregs.h>
+#include <sys/psw.h>
+
+#if defined(__lint)
+#include <sys/types.h>
+#include <sys/segments.h>
+#endif
+
+#if defined(__lint)
+
+ulong_t
+kdi_getdr0(void)
+{
+ return (0);
+}
+
+ulong_t
+kdi_getdr1(void)
+{
+ return (0);
+}
+
+ulong_t
+kdi_getdr2(void)
+{
+ return (0);
+}
+
+ulong_t
+kdi_getdr3(void)
+{
+ return (0);
+}
+
+ulong_t
+kdi_getdr6(void)
+{
+ return (0);
+}
+
+ulong_t
+kdi_getdr7(void)
+{
+ return (0);
+}
+
+/*ARGSUSED*/
+void
+kdi_setdr0(ulong_t value)
+{}
+
+/*ARGSUSED*/
+void
+kdi_setdr1(ulong_t value)
+{}
+
+/*ARGSUSED*/
+void
+kdi_setdr2(ulong_t value)
+{}
+
+/*ARGSUSED*/
+void
+kdi_setdr3(ulong_t value)
+{}
+
+/*ARGSUSED*/
+void
+kdi_setdr4(ulong_t value)
+{}
+
+/*ARGSUSED*/
+void
+kdi_setdr6(ulong_t value)
+{}
+
+/*ARGSUSED*/
+void
+kdi_setdr7(ulong_t value)
+{}
+
+#else
+
+#if defined(__amd64)
+
+#define GETDREG(name, r) \
+ ENTRY_NP(name); \
+ movq r, %rax; \
+ ret; \
+ SET_SIZE(name)
+
+#define SETDREG(name, r) \
+ ENTRY_NP(name); \
+ movq %rdi, r; \
+ ret; \
+ SET_SIZE(name)
+
+#elif defined(__i386)
+
+#define GETDREG(name, r) \
+ ENTRY_NP(name); \
+ movl r, %eax; \
+ ret; \
+ SET_SIZE(name)
+
+#define SETDREG(name, r) \
+ ENTRY_NP(name); \
+ movl 4(%esp), %eax; \
+ movl %eax, r; \
+ ret; \
+ SET_SIZE(name)
+
+#endif
+
+ GETDREG(kdi_getdr0, %dr0)
+ GETDREG(kdi_getdr1, %dr1)
+ GETDREG(kdi_getdr2, %dr2)
+ GETDREG(kdi_getdr3, %dr3)
+ GETDREG(kdi_getdr6, %dr6)
+ GETDREG(kdi_getdr7, %dr7)
+
+ SETDREG(kdi_setdr0, %dr0)
+ SETDREG(kdi_setdr1, %dr1)
+ SETDREG(kdi_setdr2, %dr2)
+ SETDREG(kdi_setdr3, %dr3)
+ SETDREG(kdi_setdr6, %dr6)
+ SETDREG(kdi_setdr7, %dr7)
+
+#endif /* __lint */
diff --git a/usr/src/uts/i86pc/ml/locore.s b/usr/src/uts/i86pc/ml/locore.s
index bc88297503..c3da3b99bc 100644
--- a/usr/src/uts/i86pc/ml/locore.s
+++ b/usr/src/uts/i86pc/ml/locore.s
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -63,6 +64,7 @@
#include <sys/cmn_err.h>
#include <sys/pit.h>
#include <sys/panic.h>
+
#include "assym.h"
/*
@@ -93,11 +95,17 @@
*
* NOW, the real code!
*/
+ /*
+ * The very first thing in the kernel's text segment must be a jump
+ * to the os/fakebop.c startup code.
+ */
+ .text
+ jmp _start
/*
* Globals:
*/
- .globl _start
+ .globl _locore_start
.globl mlsetup
.globl main
.globl panic
@@ -143,32 +151,32 @@
/*
* Enough padding for 31 more CPUs (no .skip on x86 -- grrrr).
*/
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0
#if defined(__amd64)
#if NCPU != 64
-#error "NCPU != 64, Expand padding for trap_trace_ctl"
+#error "NCPU != 64, Expand padding for trap_trace_ctl"
#endif
/*
* Enough padding for 32 more CPUs (no .skip on x86 -- grrrr).
*/
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- .NWORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ .NWORD 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
#else /* __amd64 */
@@ -200,12 +208,16 @@
/* ARGSUSED */
void
-_start(struct boot_syscalls *sysp, struct bootops *bop, Elf64_Boot *ebp)
+_locore_start(struct boot_syscalls *sysp, ulong_t rsi, struct bootops *bop)
{}
#else /* __lint */
- ENTRY_NP(_start)
+ /*
+ * kobj_init() vectors us back to here with (note) a slightly different
+ * set of arguments than _start is given (see lint prototypes above).
+ */
+ ENTRY_NP(_locore_start)
/*
* %rdi = boot services (should die someday)
@@ -249,8 +261,6 @@ _start(struct boot_syscalls *sysp, struct bootops *bop, Elf64_Boot *ebp)
popq %r11
movq %r11, REGOFF_RFL(%rsp)
- DISABLE_INTR_FLAGS
-
/*
* Enable write protect and alignment check faults.
*/
@@ -279,35 +289,7 @@ _start(struct boot_syscalls *sysp, struct bootops *bop, Elf64_Boot *ebp)
leaq __return_from_main(%rip), %rdi
xorl %eax, %eax
call panic
- SET_SIZE(_start)
-
- /*
- * Kernel's handler to switch stacks before invoking
- * vmx's putchar handler.
- *
- * This is needed because we use the boot program for
- * console services for a -long- time before consconfig
- * takes them over. In an ideal world, we'd have a console
- * configured earlier.
- *
- * We use this stack to execute bsys->putchar on, because
- * we may be asking vmx/boot to print something using a stack
- * that only exists in the 64-bit MMU e.g. a trapping thread.
- */
- .data
- .comm _safe_putchar_stack, DEFAULTSTKSZ, 32
-
- ENTRY_NP(_stack_safe_putchar)
- .globl _vmx_sysp
- movq %rsp, %r11
- leaq _safe_putchar_stack+DEFAULTSTKSZ(%rip), %rsp
- pushq %r11
- movq _vmx_sysp(%rip), %r10
- call *BOOTSVCS_PUTCHAR(%r10)
- popq %r11
- movq %r11, %rsp
- ret
- SET_SIZE(_stack_safe_putchar)
+ SET_SIZE(_locore_start)
#endif /* __amd64 */
#endif /* __lint */
@@ -325,93 +307,20 @@ __unsupported_cpu:
#if defined(__lint)
-/*ARGSUSED*/
+/* ARGSUSED */
void
-_start(struct boot_syscalls *sysp, struct bootops *bop, Elf32_Boot * ebp)
+_locore_start(struct boot_syscalls *sysp, struct bootops *bop)
{}
#else /* __lint */
- ENTRY_NP(_start)
/*
- * We jump to __start to make sure the function
- * enable_big_page_support does not span multiple 4K pages. This
- * is essential, since we need to turn paging off in
- * enable_big_page_support
+ * kobj_init() vectors us back to here with (note) a slightly different
+ * set of arguments than _start is given (see lint prototypes above).
*/
- jmp __start
-
- /*
- * It is very important that this function sit right here in the file
- * This function should not span multiple pages. This function has
- * to be executed from an address such that we have 1-1 mapping.
- * First we disable paging, then we load %cr4 with %edx and then
- * enable paging. We return to 0xe00xxxx with paging enabled.
- */
-
- ENTRY_NP(enable_big_page_support)
- movl %cr0, %eax
- and $_BITNOT(CR0_PG), %eax
- movl %eax, %cr0 / disable paging
- movl %cr3, %eax
- movl %eax, %cr3
- movl %cr4, %eax
- orl %ebx, %eax
- movl %eax, %cr4
- nop
- movl %cr0, %eax
- orl $CR0_PG, %eax / enable paging
- movl %eax, %cr0
- jmp enable_big_page_support_done
-enable_big_page_support_done:
- xorl %eax, %eax
- ret
- SET_SIZE(enable_big_page_support)
- /*
- * This function enables physical address extension thereby
- * switching from 32 bit pte's to 64 bit pte's
- *
- * It loads the argument that it received in %ebx into cr3
- *
- * XXX is there some reason why this routine -can't- use
- * normal C parameter passing conventions??
- */
- ENTRY_NP(enable_pae)
- /*
- * disable paging
- */
- movl %cr0, %eax
- andl $_BITNOT(CR0_PG), %eax
- movl %eax, %cr0
- /*
- * enable physical address extension
- */
- movl %cr4, %eax
- orl $CR4_PAE, %eax
- movl %eax, %cr4
- /*
- * set new page table base
- */
- movl %ebx, %cr3
- /*
- * restart paging
- */
- movl %cr0, %eax
- orl $CR0_PG, %eax
- movl %eax, %cr0
- jmp enable_pae_done / jmp required after enabling paging
-enable_pae_done:
- /*
- * flush TLBs just in case and return
- */
- movl %cr3, %eax
- movl %eax, %cr3
- orl $CR4_PAE, cr4_value
- ret
- SET_SIZE(enable_pae)
+ ENTRY_NP(_locore_start)
-__start:
/*
* %ecx = boot services (should die someday)
* %ebx = bootops
@@ -433,7 +342,7 @@ __start:
mov %ebx, bootops / save bootops
movl $bootops, bootopsp
- DISABLE_INTR_FLAGS
+
/*
* Save all registers and flags
*/
@@ -453,6 +362,7 @@ __start:
andl $_BITNOT(CR0_WT|CR0_CE), %eax
movl %eax, %cr0 / set the cr0 register correctly and
/ override the BIOS setup
+
/*
* If bit 21 of eflags can be flipped, then cpuid is present
* and enabled.
@@ -1193,6 +1103,7 @@ coma_bug:
jmp cpu_done
cpu_done:
+
popfl /* Restore original FLAGS */
popal /* Restore all registers */
@@ -1217,15 +1128,16 @@ cpu_done:
cpu_486:
pushl $__unsupported_cpu
call panic
- SET_SIZE(_start)
+ SET_SIZE(_locore_start)
#endif /* __lint */
#endif /* !__amd64 */
/*
- * For stack layout, see reg.h
+ * For stack layout, see privregs.h
* When cmntrap gets called, the error code and trap number have been pushed.
+ * When cmntrap_pushed gets called, the entire struct regs has been pushed.
*/
#if defined(__lint)
@@ -1243,14 +1155,28 @@ cmntrap()
ENTRY_NP2(cmntrap, _cmntrap)
- TRAP_PUSH
+ INTR_PUSH
+ ALTENTRY(cmntrap_pushed)
+
+ movq %rsp, %rbp
+
+ /*
+ * - if this is a #pf i.e. T_PGFLT, %r15 is live
+ * and contains the faulting address i.e. a copy of %cr2
+ *
+ * - if this is a #db i.e. T_SGLSTP, %r15 is live
+ * and contains the value of %db6
+ */
+
+ TRACE_PTR(%rdi, %rbx, %ebx, %rcx, $TT_TRAP) /* Uses labels 8 and 9 */
+ TRACE_REGS(%rdi, %rsp, %rbx, %rcx) /* Uses label 9 */
+ TRACE_STAMP(%rdi) /* Clobbers %eax, %edx, uses 9 */
/*
* We must first check if DTrace has set its NOFAULT bit. This
- * regrettably must happen before the TRAPTRACE data is recorded,
- * because recording the TRAPTRACE data includes obtaining a stack
- * trace -- which requires a call to getpcstack() and may induce
- * recursion if an fbt::getpcstack: enabling is inducing the bad load.
+ * regrettably must happen before the trap stack is recorded, because
+ * this requires a call to getpcstack() and may induce recursion if an
+ * fbt::getpcstack: enabling is inducing the bad load.
*/
movl %gs:CPU_ID, %eax
shlq $CPU_CORE_SHIFT, %rax
@@ -1260,60 +1186,31 @@ cmntrap()
testw $CPU_DTRACE_NOFAULT, %cx
jnz .dtrace_induced
- TRACE_PTR(%rdi, %rbx, %ebx, %rcx, $TT_TRAP) /* Uses labels 8 and 9 */
- TRACE_REGS(%rdi, %rsp, %rbx, %rcx) /* Uses label 9 */
- TRACE_STAMP(%rdi) /* Clobbers %eax, %edx, uses 9 */
-
- /*
- * Getting a stack trace as part of TRACE_STACK() requires a call to
- * getpcstack(). Before we can do this, we must move our stack pointer
- * into the base pointer, and we must save the value of %cr2. %cr2
- * must be saved before the call because getpcstack() may be
- * instrumented by DTrace -- and any invalid load in the DTrace
- * enabling will clobber %cr2.
- */
- movq %rsp, %rbp
- movq %cr2, %r12
-
TRACE_STACK(%rdi)
-/ XXX - check for NMIs????
-
- / If this is a debug trap, save %dr6 in the pcb
- cmpl $T_SGLSTP, REGOFF_TRAPNO(%rbp)
- jne .L11
- movq %gs:CPU_LWP, %rax
- orq %rax, %rax
- jz .L11 /* null lwp pointer; can't happen? */
- movq %db6, %rcx
- movq %rcx, LWP_PCB_DRSTAT(%rax)
- movl $0, %ecx
- movq %rcx, %db6 /* clear debug status register */
-.L11:
movq %rbp, %rdi
- movq %r12, %rsi
+ movq %r15, %rsi
movl %gs:CPU_ID, %edx
- /
- / We know that this isn't a DTrace non-faulting load; we can now safely
- / reenable interrupts. (In the case of pagefaults, we enter through an
- / interrupt gate.)
- /
+ /*
+ * We know that this isn't a DTrace non-faulting load; we can now safely
+ * reenable interrupts. (In the case of pagefaults, we enter through an
+ * interrupt gate.)
+ */
ENABLE_INTR_FLAGS
call trap /* trap(rp, addr, cpuid) handles all traps */
-
jmp _sys_rtt
+
.dtrace_induced:
- movq %rsp, %rbp
- testw $CPL_MASK, REGOFF_CS(%rbp) /* test CS for user-mode trap */
- jnz 2f /* if from user, panic */
+ cmpw $KCS_SEL, REGOFF_CS(%rbp) /* test CS for user-mode trap */
+ jne 2f /* if from user, panic */
cmpl $T_PGFLT, REGOFF_TRAPNO(%rbp)
- je 0f /* if not a pagefault, panic */
+ je 0f
cmpl $T_GPFLT, REGOFF_TRAPNO(%rbp)
- jne 3f
+ jne 3f /* if not PF or GP, panic */
/*
* If we've taken a GPF, we don't (unfortunately) have the address that
@@ -1326,8 +1223,7 @@ cmntrap()
0:
orw $CPU_DTRACE_BADADDR, %cx
movw %cx, CPUC_DTRACE_FLAGS(%rax) /* set fault to bad addr */
- movq %cr2, %rcx
- movq %rcx, CPUC_DTRACE_ILLVAL(%rax)
+ movq %r15, CPUC_DTRACE_ILLVAL(%rax)
/* fault addr is illegal value */
1:
movq REGOFF_RIP(%rbp), %rdi
@@ -1336,7 +1232,8 @@ cmntrap()
addq %rax, %r12
movq %r12, REGOFF_RIP(%rbp)
INTR_POP
- iretq
+ IRET
+ /*NOTREACHED*/
2:
leaq dtrace_badflags(%rip), %rdi
xorl %eax, %eax
@@ -1345,49 +1242,50 @@ cmntrap()
leaq dtrace_badtrap(%rip), %rdi
xorl %eax, %eax
call panic
-
SET_SIZE(cmntrap)
SET_SIZE(_cmntrap)
#elif defined(__i386)
+
ENTRY_NP2(cmntrap, _cmntrap)
INTR_PUSH
- TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP) /* Uses labels 8 and 9 */
- TRACE_REGS(%edi, %esp, %ebx, %ecx) /* Uses label 9 */
- TRACE_STAMP(%edi) /* Clobbers %eax, %edx, uses 9 */
+ ALTENTRY(cmntrap_pushed)
movl %esp, %ebp
-/ XXX - check for NMIs????
-
- / If this is a debug trap, save %dr6 in the pcb
- cmpl $T_SGLSTP, REGOFF_TRAPNO(%ebp)
- jne .L11
- movl %gs:CPU_LWP, %eax
- orl %eax, %eax
- jz .L11 /* null lwp pointer; can't happen? */
- movl %db6, %ecx
- movl %ecx, LWP_PCB_DRSTAT(%eax)
- movl $0, %ecx
- movl %ecx, %db6 /* clear debug status register */
-.L11:
- pushl %gs:CPU_ID
- movl %cr2, %eax / fault address for PGFLTs
- pushl %eax
- pushl %ebp
+ /*
+ * - if this is a #pf i.e. T_PGFLT, %esi is live
+ * and contains the faulting address i.e. a copy of %cr2
+ *
+ * - if this is a #db i.e. T_SGLSTP, %esi is live
+ * and contains the value of %db6
+ */
+
+ TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP) /* Uses labels 8 and 9 */
+ TRACE_REGS(%edi, %esp, %ebx, %ecx) /* Uses label 9 */
+ TRACE_STAMP(%edi) /* Clobbers %eax, %edx, uses 9 */
/*
- * We must now check if DTrace has set its NOFAULT bit.
+ * We must first check if DTrace has set its NOFAULT bit. This
+ * regrettably must happen before the trap stack is recorded, because
+ * this requires a call to getpcstack() and may induce recursion if an
+ * fbt::getpcstack: enabling is inducing the bad load.
*/
movl %gs:CPU_ID, %eax
shll $CPU_CORE_SHIFT, %eax
addl $cpu_core, %eax
movw CPUC_DTRACE_FLAGS(%eax), %cx
testw $CPU_DTRACE_NOFAULT, %cx
- jnz 0f
+ jnz .dtrace_induced
+
+ TRACE_STACK(%edi)
+
+ pushl %gs:CPU_ID
+ pushl %esi /* fault address for PGFLTs */
+ pushl %ebp /* &regs */
/*
* We know that this isn't a DTrace non-faulting load; we can now safely
@@ -1398,18 +1296,17 @@ cmntrap()
call trap /* trap(rp, addr, cpuid) handles all traps */
addl $12, %esp /* get argument off stack */
-
jmp _sys_rtt
-0:
- testw $CPL_MASK, REGOFF_CS(%ebp) /* test CS for user-mode trap */
- jnz 2f /* if from user, panic */
+.dtrace_induced:
+ cmpw $KCS_SEL, REGOFF_CS(%ebp) /* test CS for user-mode trap */
+ jne 2f /* if from user, panic */
cmpl $T_PGFLT, REGOFF_TRAPNO(%ebp)
- je 0f /* if not a pagefault, panic */
+ je 0f
cmpl $T_GPFLT, REGOFF_TRAPNO(%ebp)
- jne 3f
+ jne 3f /* if not PF or GP, panic */
/*
* If we've taken a GPF, we don't (unfortunately) have the address that
@@ -1419,30 +1316,26 @@ cmntrap()
orw $CPU_DTRACE_ILLOP, %cx
movw %cx, CPUC_DTRACE_FLAGS(%eax)
jmp 1f
-
0:
orw $CPU_DTRACE_BADADDR, %cx
movw %cx, CPUC_DTRACE_FLAGS(%eax) /* set fault to bad addr */
- movl %cr2, %ecx
- movl %ecx, CPUC_DTRACE_ILLVAL(%eax)
+ movl %esi, CPUC_DTRACE_ILLVAL(%eax)
/* fault addr is illegal value */
1:
pushl REGOFF_EIP(%ebp)
call dtrace_instr_size
- addl $16, %esp
+ addl $4, %esp
movl REGOFF_EIP(%ebp), %ecx
addl %eax, %ecx
movl %ecx, REGOFF_EIP(%ebp)
INTR_POP_KERNEL
- iret
+ IRET
2:
pushl $dtrace_badflags
call panic
-
3:
pushl $dtrace_badtrap
call panic
-
SET_SIZE(cmntrap)
SET_SIZE(_cmntrap)
@@ -1473,6 +1366,10 @@ void
cmninttrap()
{}
+void
+bop_trap_handler(void)
+{}
+
#else /* __lint */
.globl trap /* C handler called below */
@@ -1482,42 +1379,63 @@ cmninttrap()
ENTRY_NP(cmninttrap)
INTR_PUSH
+ INTGATE_INIT_KERNEL_FLAGS
TRACE_PTR(%rdi, %rbx, %ebx, %rcx, $TT_TRAP) /* Uses labels 8 and 9 */
TRACE_REGS(%rdi, %rsp, %rbx, %rcx) /* Uses label 9 */
TRACE_STAMP(%rdi) /* Clobbers %eax, %edx, uses 9 */
- DISABLE_INTR_FLAGS
-
movq %rsp, %rbp
movl %gs:CPU_ID, %edx
xorl %esi, %esi
movq %rsp, %rdi
call trap /* trap(rp, addr, cpuid) handles all traps */
-
jmp _sys_rtt
SET_SIZE(cmninttrap)
+ /*
+ * Handle traps early in boot. Just revectors into C quickly as
+ * these are always fatal errors.
+ */
+ ENTRY(bop_trap_handler)
+ movq %rsp, %rdi
+ call bop_trap
+ SET_SIZE(bop_trap_handler)
+
#elif defined(__i386)
ENTRY_NP(cmninttrap)
INTR_PUSH
- DISABLE_INTR_FLAGS
+ INTGATE_INIT_KERNEL_FLAGS
+
+ TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP) /* Uses labels 8 and 9 */
+ TRACE_REGS(%edi, %esp, %ebx, %ecx) /* Uses label 9 */
+ TRACE_STAMP(%edi) /* Clobbers %eax, %edx, uses 9 */
movl %esp, %ebp
- movl %esp, %ecx
+ TRACE_STACK(%edi)
+
pushl %gs:CPU_ID
- pushl $0 /* fake cr2 (cmntrap is used for page faults) */
- pushl %ecx
+ pushl $0
+ pushl %ebp
call trap /* trap(rp, addr, cpuid) handles all traps */
- addl $12, %esp /* get argument off stack */
-
+ addl $12, %esp
jmp _sys_rtt
SET_SIZE(cmninttrap)
+ /*
+ * Handle traps early in boot. Just revectors into C quickly as
+ * these are always fatal errors.
+ */
+ ENTRY(bop_trap_handler)
+ movl %esp, %eax
+ pushl %eax
+ call bop_trap
+ SET_SIZE(bop_trap_handler)
+
#endif /* __i386 */
#endif /* __lint */
@@ -1573,8 +1491,7 @@ dtrace_trap()
pushl %eax
pushl %ebp
- pushl $F_ON
- popfl
+ ENABLE_INTR_FLAGS
call dtrace_user_probe /* dtrace_user_probe(rp, addr, cpuid) */
addl $12, %esp /* get argument off stack */
@@ -1649,7 +1566,7 @@ _lwp_rtt:
xorl %eax, %eax
call panic
_no_pending_updates:
- .string "%M%:%d lwp_rtt(lwp %p) but no RUPDATE_PENDING"
+ .string "locore.s:%d lwp_rtt(lwp %p) but no RUPDATE_PENDING"
1:
#endif
@@ -1668,228 +1585,58 @@ _no_pending_updates:
movq REGOFF_RDX(%rsp), %rsi
movq REGOFF_RAX(%rsp), %rdi
call post_syscall /* post_syscall(rval1, rval2) */
- movq %cr0, %rax
- orq $CR0_TS, %rax
- movq %rax, %cr0 /* set up to take fault */
- /* on first use of fp */
+
+ /*
+ * set up to take fault on first use of fp
+ */
+ STTS(%rdi)
+
+ /*
+ * XXX - may want a fast path that avoids sys_rtt_common in the
+ * most common case.
+ */
ALTENTRY(_sys_rtt)
- testw $CPL_MASK, REGOFF_CS(%rsp) /* test %cs for user mode return */
+ CLI(%rax) /* disable interrupts */
+ movq %rsp, %rdi /* pass rp to sys_rtt_common */
+ call sys_rtt_common /* do common sys_rtt tasks */
+ testq %rax, %rax /* returning to userland? */
jz sr_sup
/*
* Return to user
*/
+ ASSERT_UPCALL_MASK_IS_SET
cmpw $UCS_SEL, REGOFF_CS(%rsp) /* test for native (64-bit) lwp? */
je sys_rtt_syscall
/*
- * Return to 32-bit userland, checking for an AST, and (optionally)
- * twerking any changing segment registers on the way out.
+ * Return to 32-bit userland
*/
ALTENTRY(sys_rtt_syscall32)
- movq %gs:CPU_THREAD, %rax
- cli /* disable interrupts */
- cmpb $0, T_ASTFLAG(%rax) /* test for signal or AST flag */
- jne _handle_ast
-
- movq T_LWP(%rax), %r14
- movl PCB_FLAGS(%r14), %edx
- testl $RUPDATE_PENDING, %edx
- jne _update_sregs
-
- /*
- * The following label is branched to by sys_syscall32 handler
- * so if iretq below #gp faults kern_gpfault can detect and
- * handle it.
- */
- ALTENTRY(_set_user32_regs)
USER32_POP
- iretq
+ IRET
/*NOTREACHED*/
-
+ ALTENTRY(sys_rtt_syscall)
/*
- * Return to 64-bit userland, checking for an AST, and (optionally)
- * twerking any changing segment registers on the way out.
+ * Return to 64-bit userland
*/
- ALTENTRY(sys_rtt_syscall)
- movq %gs:CPU_THREAD, %rax
- cli /* disable interrupts */
- cmpb $0, T_ASTFLAG(%rax) /* test for signal or AST flag */
- jne _handle_ast
-
- movq T_LWP(%rax), %r14
- movl PCB_FLAGS(%r14), %edx
- testl $RUPDATE_PENDING, %edx
- jne _update_sregs
-_set_user_regs:
USER_POP
- iretq
+ IRET
/*NOTREACHED*/
/*
- * XX64 Don't understand why we ever come here.
- * If we do come here then we can probably recover by just
- * branching straight to _sys_rtt
- */
-bad_set_user_regs:
- leaq __bad_set_user_regs_msg(%rip), %rdi
- movq %rsp, %rsi
- movq REGOFF_CS(%rsp), %rdx
- xorl %eax, %eax
- call panic
-__bad_set_user_regs_msg:
- .string "bad_set_user_regs: rp=%lx rp->r_cs=%lx; how did that happen?"
-
- /*
- * Update the segment registers with new values from the pcb
- *
- * We have to do this carefully, and in the following order,
- * in case any of the selectors points at a bogus descriptor.
- * If they do, we'll take a trap that will end in delivering
- * the application a weird SIGSEGV via kern_gpfault().
- *
- * This is particularly tricky for %gs.
- *
- * Note also the slightly brittle nature of the dependencies
- * between this code and kern_gpfault().
- */
- ENTRY_NP(_update_sregs)
- movw LWP_PCB_GS(%r14), %bx
- movl $MSR_AMD_GSBASE, %ecx
- rdmsr
- movw %bx, %gs
- /*
- * If that instruction failed because the new %gs is a bad %gs,
- * we'll be taking a trap but with the original %gs and %gsbase
- * undamaged (i.e. pointing at curcpu). Otherwise, we've just
- * mucked up the kernel's gsbase. Oops. Make the newly computed
- * gsbase be the hidden gs, and fix the kernel's gsbase back again.
- */
-#if defined(OPTERON_ERRATUM_88)
- mfence
-#endif
- swapgs
- wrmsr /* repair kernel gsbase */
- movw %bx, REGOFF_GS(%rsp)
- /*
- * Only override the descriptor base address if r_gs == LWPGS_SEL
- * or if r_gs == NULL.
- *
- * A note on NULL descriptors -- 32-bit programs take faults if
- * they deference NULL descriptors; however, when 64-bit programs
- * load them into %fs or %gs, they DONT fault -- only the base
- * address remains whatever it was from the last load. Urk.
- *
- * Avoid any leakage by setting the base address to an inaccessible
- * region.
- */
- cmpw $0, %bx
- jne 0f
- movl $0x80000000, LWP_PCB_GSBASE(%r14)
- movl $0xffffffff, LWP_PCB_GSBASE+4(%r14)
- jmp _set_gsbase
-0: cmpw $LWPGS_SEL, %bx
- jne 1f
-_set_gsbase:
- movl $MSR_AMD_KGSBASE, %ecx
- movl LWP_PCB_GSBASE(%r14), %eax
- movl LWP_PCB_GSBASE+4(%r14), %edx
- wrmsr /* update hidden gsbase for userland */
- movl %eax, REGOFF_GSBASE(%rsp)
- movl %edx, REGOFF_GSBASE+4(%rsp)
-1: movw LWP_PCB_FS(%r14), %bx
- movw %bx, %fs
- movw %bx, REGOFF_FS(%rsp)
- /*
- * Only override the descriptor base address if r_fs == LWPFS_SEL
- * or if r_fs == NULL.
- */
- cmpw $0, %bx
- jne 2f
- movl $0x80000000, LWP_PCB_FSBASE(%r14)
- movl $0xffffffff, LWP_PCB_FSBASE+4(%r14)
- jmp _set_fsbase
-2: cmpw $LWPFS_SEL, %bx
- jne 3f
-_set_fsbase:
- movl $MSR_AMD_FSBASE, %ecx
- movl LWP_PCB_FSBASE(%r14), %eax
- movl LWP_PCB_FSBASE+4(%r14), %edx
- wrmsr /* update fsbase for userland */
- movl %eax, REGOFF_FSBASE(%rsp)
- movl %edx, REGOFF_FSBASE+4(%rsp)
-3:
- movw LWP_PCB_ES(%r14), %bx
- movw %bx, %es
- movw %bx, REGOFF_ES(%rsp)
- movw LWP_PCB_DS(%r14), %bx
- movw %bx, %ds
- movw %bx, REGOFF_DS(%rsp)
- andl $_BITNOT(RUPDATE_PENDING), PCB_FLAGS(%r14)
- jmp _set_user_regs
- .globl _update_sregs_done
-_update_sregs_done:
- /*NOTREACHED*/
- SET_SIZE(_update_sregs)
-
-_handle_ast:
- /* Let trap() handle the AST */
- sti /* enable interrupts */
- movl $T_AST, REGOFF_TRAPNO(%rsp) /* set trap type to AST */
- movq %rsp, %rdi
- xorl %esi, %esi
- movl %gs:CPU_ID, %edx
- call trap /* trap(rp, 0, cpuid) */
- jmp _sys_rtt
- /*NOTREACHED*/
-
- /*
* Return to supervisor
+ * NOTE: to make the check in trap() that tests if we are executing
+ * segment register fixup/restore code work properly, sr_sup MUST be
+ * after _sys_rtt .
*/
ALTENTRY(sr_sup)
-
- /* Check for a kernel preemption request */
- cmpb $0, %gs:CPU_KPRUNRUN
- jne sr_sup_preempt /* preemption */
-
/*
* Restore regs before doing iretq to kernel mode
*/
-set_sup_regs:
- cmpw $KCS_SEL, REGOFF_CS(%rsp) /* test %cs for return to user mode */
- jne bad_set_user_regs /* ... (this should not be necessary) */
-
- /*
- * If we interrupted the mutex_exit() critical region we must
- * reset the PC back to the beginning to prevent missed wakeups.
- * See the comments in mutex_exit() for details.
- */
- movq REGOFF_PC(%rsp), %rdx
- leaq mutex_exit_critical_start(%rip), %r8
- subq %r8, %rdx
- cmpq mutex_exit_critical_size(%rip), %rdx
- jae .mutex_exit_check_done
- movq %r8, REGOFF_PC(%rsp)
- /* restart mutex_exit() */
-.mutex_exit_check_done:
INTR_POP
- iretq
-
-sr_sup_preempt:
- movq %gs:CPU_THREAD, %rbx
- cmpb $0, T_PREEMPT_LK(%rbx) /* Already in kpreempt? */
- jne set_sup_regs /* if so, get out of here */
- movb $1, T_PREEMPT_LK(%rbx) /* otherwise, set t_preempt_lk */
-
- sti /* it's now safe to unmask interrupts */
-
- movl $1, %edi /* indicate asynchronous call */
- call kpreempt /* kpreempt(1) */
-
- cli /* re-mask interrupts */
- movb $0, T_PREEMPT_LK(%rbx) /* clear t_preempt_lk */
-
- jmp set_sup_regs
+ IRET
+ /*NOTREACHED*/
SET_SIZE(sr_sup)
SET_SIZE(lwp_rtt)
SET_SIZE(lwp_rtt_initial)
@@ -1929,94 +1676,42 @@ _lwp_rtt:
pushl %eax
call post_syscall /* post_syscall(rval1, rval2) */
addl $8, %esp
- movl %cr0, %eax
- orl $CR0_TS, %eax
- movl %eax, %cr0 /* set up to take fault */
- /* on first use of fp */
+ /*
+ * set up to take fault on first use of fp
+ */
+ STTS(%eax)
+
+ /*
+ * XXX - may want a fast path that avoids sys_rtt_common in the
+ * most common case.
+ */
ALTENTRY(_sys_rtt)
- testw $CPL_MASK, REGOFF_CS(%esp) /* test CS for return to user mode */
+ CLI(%eax) /* disable interrupts */
+ pushl %esp /* pass rp to sys_rtt_common */
+ call sys_rtt_common
+ addl $4, %esp /* pop arg */
+ testl %eax, %eax /* test for return to user mode */
jz sr_sup
/*
* Return to User.
*/
-
ALTENTRY(sys_rtt_syscall)
- /* check for an AST that's posted to the lwp */
- movl %gs:CPU_THREAD, %eax
- cli /* disable interrupts */
- cmpb $0, T_ASTFLAG(%eax) /* test for signal or AST flag */
- jne handle_ast
-
-
- /*
- * Restore user regs before returning to user mode.
- */
- ALTENTRY(set_user_regs)
INTR_POP_USER
- iret
- SET_SIZE(set_user_regs)
-
-handle_ast:
- /* Let trap() handle the AST */
- sti /* enable interrupts */
- movl $T_AST, REGOFF_TRAPNO(%esp) /* set trap type to AST */
- movl %esp, %eax
- pushl %gs:CPU_ID
- pushl $0
- pushl %eax
- call trap /* trap(rp, 0, cpuid) */
- addl $12, %esp
- jmp _sys_rtt
+ IRET
/*
* Return to supervisor
*/
ALTENTRY(sr_sup)
- /* Check for a kernel preemption request */
- cmpb $0, %gs:CPU_KPRUNRUN
- jne sr_sup_preempt /* preemption */
-
/*
* Restore regs before doing iret to kernel mode
*/
-set_sup_regs:
- cmpw $KGS_SEL, REGOFF_GS(%esp) /* test GS for return to user mode */
- jne set_user_regs /* ... (this should not be necessary) */
-
- /*
- * If we interrupted the mutex_exit() critical region we must
- * reset the PC back to the beginning to prevent missed wakeups.
- * See the comments in mutex_exit() for details.
- */
- movl REGOFF_PC(%esp), %edx
- subl $mutex_exit_critical_start, %edx
- cmpl mutex_exit_critical_size, %edx
- jae .mutex_exit_check_done
- movl $mutex_exit_critical_start, REGOFF_PC(%esp)
- /* restart mutex_exit() */
-.mutex_exit_check_done:
INTR_POP_KERNEL
- iret
-
-sr_sup_preempt:
- movl %gs:CPU_THREAD, %ebx
- cmpb $0, T_PREEMPT_LK(%ebx) /* Already in kpreempt? */
- jne set_sup_regs /* if so, get out of here */
- movb $1, T_PREEMPT_LK(%ebx) /* otherwise, set t_preempt_lk */
+ IRET
- sti /* it's now safe to unmask interrupts */
-
- pushl $1 /* indicate asynchronous call */
- call kpreempt /* kpreempt(1) */
- addl $4, %esp
-
- cli /* re-mask interrupts */
- movb $0, T_PREEMPT_LK(%ebx) /* clear t_preempt_lk */
-
- jmp set_sup_regs
SET_SIZE(sr_sup)
SET_SIZE(lwp_rtt)
SET_SIZE(lwp_rtt_initial)
@@ -2062,9 +1757,6 @@ freq_tsc(uint32_t *pit_counter)
movq %rdi, %r9 /* save pit_counter */
pushq %rbx
- pushfq
- cli
-
/ We have a TSC, but we have no way in general to know how reliable it is.
/ Usually a marginal TSC behaves appropriately unless not enough time
/ elapses between reads. A reliable TSC can be read as often and as rapidly
@@ -2253,8 +1945,6 @@ freq_tsc_too_fast:
freq_tsc_end:
shlq $32, %rdx
orq %rdx, %rax
- / restore state of the interrupt flag
- popfq
popq %rbx
leaveq
@@ -2270,9 +1960,6 @@ freq_tsc_end:
pushl %esi
pushl %ebx
- pushfl
- cli
-
/ We have a TSC, but we have no way in general to know how reliable it is.
/ Usually a marginal TSC behaves appropriately unless not enough time
/ elapses between reads. A reliable TSC can be read as often and as rapidly
@@ -2460,14 +2147,10 @@ freq_tsc_too_fast:
xorl %edx, %edx
freq_tsc_end:
- / restore state of the interrupt flag
- popfl
-
popl %ebx
popl %esi
popl %edi
popl %ebp
-
ret
SET_SIZE(freq_tsc)
@@ -2497,9 +2180,6 @@ freq_notsc(uint32_t *pit_counter)
pushl %esi
pushl %ebx
- pushfl
- cli
-
/ initial count for the idivl loop
movl $0x1000, %ecx
@@ -2652,9 +2332,6 @@ freq_notsc_too_fast:
xorl %edx, %edx
freq_notsc_end:
- / restore state of the interrupt flag
- popfl
-
popl %ebx
popl %esi
popl %edi
@@ -2663,128 +2340,6 @@ freq_notsc_end:
ret
SET_SIZE(freq_notsc)
- /
- / setup_121_andcall(funcp, argument)
- /
- / invokes funcp(argument) after having setup one to one mapping
- / for the virtual address funcp to its physical address.
- / This function cannot be invoked with PAE enabled, this could
- / be used to enable PAE
- /
- ENTRY_NP(setup_121_andcall)
- pushl %ebp
- movl %esp, %ebp
- pushl %ebx
- movl 8(%ebp), %ecx / funcp
- movl %ecx, %edx
- shrl $MMU_STD_PAGESHIFT, %ecx
- andl $MMU_L2_MASK, %ecx / pagetable index
- movl %cr3, %eax
- andl $MMU_STD_PAGEMASK, %eax / pagedirectory pointer
- pushl %eax
- shrl $MMU_STD_PAGESHIFT+NPTESHIFT, %edx
- movl (%eax, %edx, 4), %eax / funcp's pagetable
- testl $PTE_LARGEPAGE, %eax
- je not_a_large_page
- shrl $MMU_STD_PAGESHIFT, %eax
- addl %eax, %ecx
- movl %ecx, %edx
- shll $MMU_STD_PAGESHIFT, %edx
- orl $_CONST(PTE_SRWX|PTE_VALID), %edx
- jmp got_pfn
-
-not_a_large_page:
- andl $MMU_STD_PAGEMASK, %eax / ignore ref and other bits
- movl (%eax, %ecx, 4), %ecx / pte entry
- movl %ecx, %edx
- shrl $MMU_STD_PAGESHIFT, %ecx /pfnum of funcp
-got_pfn:
- movl %ecx, %ebx
- andl $MMU_L2_MASK, %ecx
- shrl $NPTESHIFT, %ebx
- movl 0(%esp), %eax
- leal (%eax, %ebx, 4), %eax / new pde entry for the function
- pushl %eax
- movl (%eax), %eax
- testl $PTE_VALID, %eax / is the pde entry valid
- jne pagetable_isvalid
- movl $one2one_pagetable, %ebx
- addl $MMU_STD_PAGESIZE, %ebx / move to next 4k
- shrl $MMU_STD_PAGESHIFT+NPTESHIFT, %ebx
- movl 4(%esp), %eax
- movl (%eax, %ebx, 4), %eax
- testl $PTE_LARGEPAGE, %eax
- je not_a_large_page1
- shrl $MMU_STD_PAGESHIFT, %eax
- movl $one2one_pagetable, %ebx
- addl $MMU_STD_PAGESIZE, %ebx / move to next 4k
- shrl $MMU_STD_PAGESHIFT, %ebx
- andl $MMU_L2_MASK, %ebx
- addl %ebx, %eax
- shll $MMU_STD_PAGESHIFT, %eax
- orl $_CONST(PTE_SRWX|PTE_VALID), %eax
- jmp got_pfn1
-not_a_large_page1:
- andl $MMU_STD_PAGEMASK, %eax / ignore ref and other bits
- movl $one2one_pagetable, %ebx
- addl $MMU_STD_PAGESIZE, %ebx / move to next 4k
- shrl $MMU_STD_PAGESHIFT, %ebx
- andl $MMU_L2_MASK, %ebx
- movl (%eax, %ebx, 4), %eax / pte entry for one2one_pagetable
-got_pfn1:
- movl 0(%esp), %ebx
- movl %eax, (%ebx) / point pde entry at one2one_pagetable
- movl $one2one_pagetable, %eax / load pagetable ptr
- addl $MMU_STD_PAGESIZE, %eax / 4K aligned virtual address
- andl $MMU_STD_PAGEMASK, %eax
- movl $0, 4(%esp) / previous pde is invalid
- jmp pagetable_madevalid
-pagetable_isvalid:
- movl %eax, 4(%esp) / save pde
-pagetable_madevalid:
- andl $MMU_STD_PAGEMASK, %eax / ignore lower 12 bits
-
- pushl (%eax, %ecx, 4) / save the old pagetable entry that
- / belongs to boot
-
- movl %edx, (%eax, %ecx, 4) / We now have a 1-1 mapping for the
- / function funcp
- leal (%eax, %ecx, 4), %eax
- pushl %eax / save the address of pagetable entry
- / we patched above
-
- movl 8(%ebp), %eax / funcp
- andl $MMU_PAGEOFFSET, %eax / pick the 4k offset
- andl $MMU_STD_PAGEMASK, %edx
- addl %edx, %eax
- movl 12(%ebp), %ebx / argument
- movl %cr3, %ecx
- movl %ecx, %cr3
- call *%eax / jump to funcp(%eax)
- / we have 1-1 mapping
- / for this particular page, ret address
- / still points to space in 0xe00xxxxx
-
- testl %eax, %eax
- jne cr3_changed
- popl %eax / pop the pagetable entry address
- popl %ecx / pop the pagetable entry
- movl %ecx, (%eax) / restore the pte that we destroyed
- popl %eax / pop the pagedirectory address
- popl %ecx / pop pde
- movl %ecx, (%eax) / restore pde
- movl %cr3, %eax
- movl %eax, %cr3
- popl %ebx
- popl %ebp
- ret
-cr3_changed:
- addl $16, %esp / we had saved 4 arguments
- popl %ebx
- popl %ebp
- ret
- SET_SIZE(setup_121_andcall)
-
#endif /* __lint */
#endif /* !__amd64 */
@@ -2801,14 +2356,5 @@ cpu_vendor:
.globl x86_type
.globl x86_vendor
#endif
- .globl cr4_value
-
- /*
- * pagetable that would allow a one to one mapping of the
- * first 4K of kernel text.
- * we allocate 8K so that we have a 4K pagetable aligned
- * across 4K boundary
- */
- .comm one2one_pagetable, 8192
#endif /* __lint */
diff --git a/usr/src/uts/i86pc/ml/mpcore.s b/usr/src/uts/i86pc/ml/mpcore.s
index f1717a73f0..721761f01d 100644
--- a/usr/src/uts/i86pc/ml/mpcore.s
+++ b/usr/src/uts/i86pc/ml/mpcore.s
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,6 +29,7 @@
#include <sys/asm_misc.h>
#include <sys/regset.h>
#include <sys/privregs.h>
+#include <sys/x86_archext.h>
#if !defined(__lint)
#include <sys/segments.h>
@@ -53,13 +54,13 @@
*
*/
-#if defined(lint) || defined(__lint)
+#if defined(__lint)
void
real_mode_start(void)
{}
-#else /* lint */
+#else /* __lint */
#if defined(__amd64)
@@ -299,10 +300,17 @@ kernel_cs_code:
movq %rax, %cr0 /* set machine status word */
/*
- * Before proceeding, enable usage of the page table NX bit if that's
- * how the page tables are set up.
+ * Before going any further, enable usage of page table NX bit if
+ * that's how our page tables are set up.
*/
- call *set_nxe_func
+ movl x86_feature, %ecx
+ andl $X86_NX, %ecx
+ jz 1f
+ movl $MSR_AMD_EFER, %ecx
+ rdmsr
+ orl $AMD_EFER_NXE, %eax
+ wrmsr
+1:
/*
* Complete the rest of the setup and call mp_startup().
@@ -546,10 +554,17 @@ kernel_cs_code:
movq %rax, %cr0 /* set machine status word */
/*
- * Before proceeding, enable usage of the page table NX bit if that's
- * how the page tables are set up.
+ * Before going any further, enable usage of page table NX bit if
+ * that's how our page tables are set up.
*/
- call *set_nxe_func
+ movl x86_feature, %ecx
+ andl $X86_NX, %ecx
+ jz 1f
+ movl $MSR_AMD_EFER, %ecx
+ rdmsr
+ orl $AMD_EFER_NXE, %eax
+ wrmsr
+1:
/*
* Complete the rest of the setup and call mp_startup().
@@ -643,7 +658,17 @@ kernel_cs_code:
* Before going any further, enable usage of page table NX bit if
* that's how our page tables are set up.
*/
- call *set_nxe_func
+ movl x86_feature, %ecx
+ andl $X86_NX, %ecx
+ jz 1f
+ movl %cr4, %ecx
+ andl $CR4_PAE, %ecx
+ jz 1f
+ movl $MSR_AMD_EFER, %ecx
+ rdmsr
+ orl $AMD_EFER_NXE, %eax
+ wrmsr
+1:
movl %gs:CPU_THREAD, %eax /* get thread ptr */
call *T_PC(%eax) /* call mp_startup */
/* not reached */
@@ -725,7 +750,17 @@ kernel_cs_code:
* Before going any farther, enable usage of page table NX bit if
* that's how our page tables are set up.
*/
- call *set_nxe_func
+ movl x86_feature, %ecx
+ andl $X86_NX, %ecx
+ jz 1f
+ movl %cr4, %ecx
+ andl $CR4_PAE, %ecx
+ jz 1f
+ movl $MSR_AMD_EFER, %ecx
+ rdmsr
+ orl $AMD_EFER_NXE, %eax
+ wrmsr
+1:
mov %gs:CPU_THREAD, %eax /* get thread ptr */
call *T_PC(%eax) /* call mp_startup */
/* not reached */
@@ -735,48 +770,4 @@ kernel_cs_code:
SET_SIZE(real_mode_start)
#endif /* __amd64 */
-
-#endif /* lint */
-
-
-#if defined(lint) || defined(__lint)
-
-void
-return_instr(void)
-{}
-
-/*ARGSUSED*/
-void
-send_dirint(int cpuix, int int_level)
-{}
-
-#else /* lint */
-
- /*
- * Same for amd64 and i386.
- */
- ENTRY_NP(return_instr)
- rep; ret /* use 2 byte return instruction when branch target */
- /* AMD Software Optimization Guide - Section 6.2 */
- SET_SIZE(return_instr)
-
-#if defined(__amd64)
-
- /*
- * jump indirect to the send_dirint
- * function. Set to return if machine
- * type module doesnt redirect it.
- */
- ENTRY_NP(send_dirint)
- jmp *send_dirintf(%rip)
- SET_SIZE(send_dirint)
-
-#elif defined(__i386)
-
- ENTRY_NP(send_dirint)
- jmp *send_dirintf
- SET_SIZE(send_dirint)
-
-#endif /* __amd64 */
-
-#endif /* lint */
+#endif /* __lint */
diff --git a/usr/src/uts/i86pc/ml/notes.s b/usr/src/uts/i86pc/ml/notes.s
index 8212394028..72ae373813 100644
--- a/usr/src/uts/i86pc/ml/notes.s
+++ b/usr/src/uts/i86pc/ml/notes.s
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,7 +18,7 @@
*
* CDDL HEADER END
*
- * Copyright 2000 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,7 +29,8 @@
#if defined(lint)
#include <sys/types.h>
#else
-#include <sys/mmu.h>
+
+#include "assym.h"
/
/ Tell the booter that we'd like to load unix on a large page
@@ -46,7 +46,7 @@
.name1_end:
.align 4
.desc1_begin:
- .4byte FOURMB_PAGESIZE
+ .4byte FOUR_MEG
.desc1_end:
.align 4
#endif
diff --git a/usr/src/uts/i86pc/ml/offsets.in b/usr/src/uts/i86pc/ml/offsets.in
index 2ed5b03b74..1c51a7c7d5 100644
--- a/usr/src/uts/i86pc/ml/offsets.in
+++ b/usr/src/uts/i86pc/ml/offsets.in
@@ -1,5 +1,5 @@
\
-\ Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+\ Copyright 2007 Sun Microsystems, Inc. All rights reserved.
\ Use is subject to license terms.
\
\ CDDL HEADER START
@@ -166,6 +166,7 @@ fpu_ctx
fpu_flags FPU_CTX_FPU_FLAGS
fxsave_state FXSAVE_STATE_SIZE
+ fx_fsw FXSAVE_STATE_FSW
fx_mxcsr_mask FXSAVE_STATE_MXCSR_MASK
@@ -290,10 +291,6 @@ rm_platter
rm_cr4 CR4OFF
rm_x86feature X86FEATURE
-cpu_tables
- ct_stack
- ct_gdt
-
ddi_acc_impl
ahi_acc_attr ACC_ATTR
ahi_get8 ACC_GETB
diff --git a/usr/src/uts/i86pc/ml/syscall_asm.s b/usr/src/uts/i86pc/ml/syscall_asm.s
index 530cfcaf56..f43b9702d6 100644
--- a/usr/src/uts/i86pc/ml/syscall_asm.s
+++ b/usr/src/uts/i86pc/ml/syscall_asm.s
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,6 +38,7 @@
#include <sys/psw.h>
#include <sys/x86_archext.h>
#include <sys/machbrand.h>
+#include <sys/privregs.h>
#if defined(__lint)
@@ -383,20 +384,23 @@ size_t _allsyscalls_size;
_watch_do_syscall:
movl %esp, %ebp
- pushl %eax / preserve across mstate call
- MSTATE_TRANSITION(LMS_USER, LMS_SYSTEM)
- popl %eax
-
+ / Interrupts may be enabled here, so we must make sure this thread
+ / doesn't migrate off the CPU while it updates the CPU stats.
+ /
+ / XXX This is only true if we got here via call gate thru the LDT for
+ / old style syscalls. Perhaps this preempt++-- will go away soon?
movl %gs:CPU_THREAD, %ebx
-
- / Interrupts are enabled here, so we must make sure this thread doesn't
- / migrate off the CPU while it updates the CPU stats.
addb $1, T_PREEMPT(%ebx)
CPU_STATS_SYS_SYSCALL_INC
subb $1, T_PREEMPT(%ebx)
- / Set EFLAGS to standard kernel settings.
ENABLE_INTR_FLAGS
+
+ pushl %eax / preserve across mstate call
+ MSTATE_TRANSITION(LMS_USER, LMS_SYSTEM)
+ popl %eax
+
+ movl %gs:CPU_THREAD, %ebx
ASSERT_LWPTOREGS(%ebx, %esp)
@@ -419,8 +423,8 @@ _syslcall_done:
/
/ get back via iret
/
- cli
- jmp set_user_regs
+ CLI(%edx)
+ jmp sys_rtt_syscall
_full_syscall_presys:
movl T_LWP(%ebx), %esi
@@ -440,7 +444,7 @@ _full_syscall_postsys:
call syscall_exit
addl $12, %esp
MSTATE_TRANSITION(LMS_SYSTEM, LMS_USER)
- jmp sys_rtt_syscall
+ jmp _sys_rtt
_syscall_fault:
push $0xe / EFAULT
@@ -729,6 +733,7 @@ watch_syscall(void)
#else /* __lint */
ENTRY_NP(watch_syscall)
+ CLI(%eax)
movl %gs:CPU_THREAD, %ebx
movl T_STACK(%ebx), %esp / switch to the thread stack
movl REGOFF_EAX(%esp), %eax / recover original syscall#
diff --git a/usr/src/uts/i86pc/ml/syscall_asm_amd64.s b/usr/src/uts/i86pc/ml/syscall_asm_amd64.s
index ce2f08f807..95f86bee20 100644
--- a/usr/src/uts/i86pc/ml/syscall_asm_amd64.s
+++ b/usr/src/uts/i86pc/ml/syscall_asm_amd64.s
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,6 +28,7 @@
#include <sys/asm_linkage.h>
#include <sys/asm_misc.h>
#include <sys/regset.h>
+#include <sys/privregs.h>
#include <sys/psw.h>
#include <sys/machbrand.h>
@@ -354,12 +355,12 @@ size_t _allsyscalls_size;
#else /* __lint */
ENTRY_NP2(brand_sys_syscall,_allsyscalls)
- swapgs
+ SWAPGS
BRAND_CALLBACK(BRAND_CB_SYSCALL)
- swapgs
+ SWAPGS
ALTENTRY(sys_syscall)
- swapgs
+ SWAPGS
movq %rsp, %gs:CPU_RTMP_RSP
movq %r15, %gs:CPU_RTMP_R15
movq %gs:CPU_THREAD, %r15
@@ -428,7 +429,6 @@ size_t _allsyscalls_size;
movq T_LWP(%r15), %r14
ASSERT_NO_RUPDATE_PENDING(%r14)
-
ENABLE_INTR_FLAGS
MSTATE_TRANSITION(LMS_USER, LMS_SYSTEM)
@@ -489,7 +489,7 @@ _syscall_invoke:
* lwp got in ahead of us, it could change the segment
* registers without us noticing before we return to userland.
*/
- cli
+ CLI(%r14)
CHECK_POSTSYS_NE(%r15, %r14, %ebx)
jne _syscall_post
SIMPLE_SYSCALL_POSTSYS(%r15, %r14, %bx)
@@ -524,7 +524,7 @@ _syscall_invoke:
movq REGOFF_RIP(%rsp), %rcx
movl REGOFF_RFL(%rsp), %r11d
movq REGOFF_RSP(%rsp), %rsp
- swapgs
+ SWAPGS
sysretq
_syscall_pre:
@@ -545,7 +545,7 @@ _syscall_ill:
jmp _syscall_post_call
_syscall_post:
- sti
+ STI
/*
* Sigh, our optimism wasn't justified, put it back to LMS_SYSTEM
* so that we can account for the extra work it takes us to finish.
@@ -556,7 +556,7 @@ _syscall_post_call:
movq %r13, %rsi
call post_syscall
MSTATE_TRANSITION(LMS_SYSTEM, LMS_USER)
- jmp sys_rtt_syscall
+ jmp _sys_rtt
SET_SIZE(sys_syscall)
SET_SIZE(brand_sys_syscall)
@@ -572,12 +572,12 @@ sys_syscall32()
#else /* __lint */
ENTRY_NP(brand_sys_syscall32)
- swapgs
+ SWAPGS
BRAND_CALLBACK(BRAND_CB_SYSCALL32)
- swapgs
+ SWAPGS
ALTENTRY(sys_syscall32)
- swapgs
+ SWAPGS
movl %esp, %r10d
movq %gs:CPU_THREAD, %r15
movq T_STACK(%r15), %rsp
@@ -590,7 +590,6 @@ sys_syscall32()
movl $UDS_SEL, REGOFF_SS(%rsp)
_syscall32_save:
-
movl %edi, REGOFF_RDI(%rsp)
movl %esi, REGOFF_RSI(%rsp)
movl %ebp, REGOFF_RBP(%rsp)
@@ -711,7 +710,7 @@ _syscall32_save:
* lwp got in ahead of us, it could change the segment
* registers without us noticing before we return to userland.
*/
- cli
+ CLI(%r14)
CHECK_POSTSYS_NE(%r15, %r14, %ebx)
jne _full_syscall_postsys32
SIMPLE_SYSCALL_POSTSYS(%r15, %r14, %bx)
@@ -738,7 +737,7 @@ _syscall32_save:
sysretl
_full_syscall_postsys32:
- sti
+ STI
/*
* Sigh, our optimism wasn't justified, put it back to LMS_SYSTEM
* so that we can account for the extra work it takes us to finish.
@@ -749,7 +748,7 @@ _full_syscall_postsys32:
movq %r13, %rdx /* rval2 - %edx */
call syscall_exit
MSTATE_TRANSITION(LMS_SYSTEM, LMS_USER)
- jmp sys_rtt_syscall32
+ jmp _sys_rtt
SET_SIZE(sys_syscall32)
SET_SIZE(brand_sys_syscall32)
@@ -805,7 +804,7 @@ sys_sysenter()
#else /* __lint */
ENTRY_NP(brand_sys_sysenter)
- swapgs
+ SWAPGS
ALTENTRY(_brand_sys_sysenter_post_swapgs)
BRAND_CALLBACK(BRAND_CB_SYSENTER)
@@ -816,7 +815,7 @@ sys_sysenter()
jmp _sys_sysenter_post_swapgs
ALTENTRY(sys_sysenter)
- swapgs
+ SWAPGS
ALTENTRY(_sys_sysenter_post_swapgs)
movq %gs:CPU_THREAD, %r15
@@ -1052,7 +1051,7 @@ sys_syscall_int()
#else /* __lint */
ENTRY_NP(brand_sys_syscall_int)
- swapgs
+ SWAPGS
BRAND_CALLBACK(BRAND_CB_INT91)
swapgs
@@ -1067,6 +1066,7 @@ sys_syscall_int()
* and use a faster return mechanism.
*/
movb $1, T_POST_SYS(%r15)
+ CLEAN_CS
jmp _syscall32_save
SET_SIZE(sys_syscall_int)
SET_SIZE(brand_sys_syscall_int)
@@ -1097,7 +1097,7 @@ sys_lcall32()
#else /* __lint */
ENTRY_NP(sys_lcall32)
- swapgs
+ SWAPGS
pushq $0
pushq %rbp
movq %rsp, %rbp
diff --git a/usr/src/uts/i86pc/os/acpi_fw.h b/usr/src/uts/i86pc/os/acpi_fw.h
new file mode 100644
index 0000000000..aead3dec37
--- /dev/null
+++ b/usr/src/uts/i86pc/os/acpi_fw.h
@@ -0,0 +1,148 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ACPI_FW_H
+#define _ACPI_FW_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void process_acpi_properties();
+
+#define ACPI_RSDP_SIG "RSD PTR "
+#define ACPI_RSDP_SIG_LEN (8)
+#define ACPI_TABLE_SIG_LEN (4)
+#define ACPI_EBDA_SEG_ADDR (0x40e)
+#define ACPI_EBDA_LEN (1024)
+
+#pragma pack(1)
+
+struct rsdp_v1 {
+ char sig[8];
+ uint8_t checksum;
+ char oem_id[6];
+ char revision;
+ uint32_t rsdt;
+};
+
+struct rsdp {
+ struct rsdp_v1 v1;
+ uint32_t len;
+ uint64_t xsdt;
+ uint8_t ext_checksum;
+ char reserved[3];
+};
+
+struct table_header {
+ char sig[4];
+ uint32_t len;
+ uint8_t revision;
+ uint8_t checksum;
+ char oem_id[6];
+ char oem_table_id[8];
+ uint32_t oem_revision;
+ uint32_t creator_id;
+ uint32_t creator_revision;
+};
+
+struct xsdt {
+ struct table_header hdr;
+ union {
+ uint32_t r[1];
+ uint64_t x[1];
+ } p;
+};
+
+
+#define MADT_PROCESSOR 0
+
+struct madt_processor {
+ uint8_t type;
+ uint8_t len;
+ uint8_t acpi_processor_id;
+ uint8_t apic_id;
+ uint32_t flags;
+};
+
+struct madt {
+ struct table_header hdr;
+ uint32_t lapic_addr;
+ uint32_t flags;
+ struct madt_processor list[1];
+};
+
+struct srat_processor {
+ uint8_t domain1;
+ uint8_t apic_id;
+ uint32_t flags;
+ uint8_t local_sapic_eid;
+ uint8_t domain2[3];
+ uint8_t reserved[4];
+};
+
+struct srat_memory {
+ uint32_t domain;
+ uint8_t reserved1[2];
+ uint64_t base_addr;
+ uint64_t len;
+ uint8_t reserved2[4];
+ uint32_t flags;
+ uint8_t reserved3[8];
+};
+
+struct srat_item {
+ uint8_t type;
+ uint8_t len;
+ union {
+ struct srat_processor p;
+ struct srat_memory m;
+ } i;
+};
+
+struct srat {
+ struct table_header hdr;
+ uint32_t reserved1;
+ uint8_t reserved2[8];
+ struct srat_item list[1];
+};
+
+#define SRAT_PROCESSOR (0)
+#define SRAT_MEMORY (1)
+
+#define SRAT_ENABLED (1)
+#define SRAT_HOT_PLUG (2)
+#define SRAT_NON_VOLATILE (4)
+
+
+#pragma pack()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ACPI_FW_H */
diff --git a/usr/src/uts/i86pc/os/cmi.c b/usr/src/uts/i86pc/os/cmi.c
index fb1c494565..0e5129ebdc 100644
--- a/usr/src/uts/i86pc/os/cmi.c
+++ b/usr/src/uts/i86pc/os/cmi.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -87,8 +87,8 @@ cmi_load_modctl(modctl_t *modp)
}
if ((ops = modlookup_by_modctl(modp, "_cmi_ops")) == NULL) {
- cmn_err(CE_WARN, "CPU module %s is invalid: no _cmi_ops "
- "found\n", modp->mod_modname);
+ cmn_err(CE_WARN, "cpu module '%s' is invalid: no _cmi_ops "
+ "found", modp->mod_modname);
return (NULL);
}
@@ -197,8 +197,9 @@ cmi_load(cpu_t *cp)
((cmi = cmi_load_module(cp)) == NULL) ||
((err = cmi->cmi_ops->cmi_init(cp, &data)) != 0 &&
err != ENOTSUP))) {
- cmn_err(CE_WARN, "CPU module %s failed to init CPU %d: err=%d",
- cmi ? cmi->cmi_modp->mod_modname : "<>", cp->cpu_id, err);
+ cmn_err(CE_WARN,
+ "cpu%d: failed to init cpu module '%s': err=%d",
+ cp->cpu_id, cmi ? cmi->cmi_modp->mod_modname : "<>", err);
mutex_exit(&cmi_load_lock);
return (-1);
}
@@ -206,8 +207,9 @@ cmi_load(cpu_t *cp)
if ((cmi_force_generic || err != 0) &&
((cmi = cmi_load_generic()) == NULL ||
(err = cmi->cmi_ops->cmi_init(cp, &data)) != 0)) {
- cmn_err(CE_WARN, "CPU module %s failed to init CPU %d: err=%d",
- cmi ? cmi->cmi_modp->mod_modname : "<>", cp->cpu_id, err);
+ cmn_err(CE_WARN,
+ "cpu%d: failed to init cpu module '%s': err=%d",
+ cp->cpu_id, cmi ? cmi->cmi_modp->mod_modname : "<>", err);
mutex_exit(&cmi_load_lock);
return (-1);
}
@@ -220,7 +222,7 @@ cmi_load(cpu_t *cp)
mutex_exit(&cmi_load_lock);
if (boothowto & RB_VERBOSE) {
- printf("cpuid %d: initialized cpumod: %s\n",
+ printf("cpu%d: initialized cpu module '%s'\n",
cp->cpu_id, cmi->cmi_modp->mod_modname);
}
@@ -231,7 +233,7 @@ void
cmi_init(void)
{
if (cmi_load(CPU) < 0)
- panic("failed to load module for CPU %u", CPU->cpu_id);
+ panic("failed to load module for cpu%d", CPU->cpu_id);
}
void
diff --git a/usr/src/uts/i86pc/os/cpuid.c b/usr/src/uts/i86pc/os/cpuid.c
index 094092ed0b..df93dde5e7 100644
--- a/usr/src/uts/i86pc/os/cpuid.c
+++ b/usr/src/uts/i86pc/os/cpuid.c
@@ -45,7 +45,6 @@
#include <sys/controlregs.h>
#include <sys/auxv_386.h>
#include <sys/bitmap.h>
-#include <sys/controlregs.h>
#include <sys/memnode.h>
/*
@@ -104,7 +103,6 @@ uint_t x86_feature = 0;
uint_t x86_vendor = X86_VENDOR_IntelClone;
uint_t x86_type = X86_TYPE_OTHER;
-ulong_t cr4_value;
uint_t pentiumpro_bug4046376;
uint_t pentiumpro_bug4064495;
@@ -158,12 +156,12 @@ struct cpuid_info {
/*
* supported feature information
*/
- uint32_t cpi_support[4];
+ uint32_t cpi_support[5];
#define STD_EDX_FEATURES 0
#define AMD_EDX_FEATURES 1
#define TM_EDX_FEATURES 2
#define STD_ECX_FEATURES 3
-
+#define AMD_ECX_FEATURES 4
/*
* Synthesized information, where known.
*/
@@ -342,6 +340,14 @@ synth_info(struct cpuid_info *cpi)
}
/*
+ * Apply up various platform-dependent restrictions where the
+ * underlying platform restrictions mean the CPU can be marked
+ * as less capable than its cpuid instruction would imply.
+ */
+
+#define platform_cpuid_mangle(vendor, eax, cp) /* nothing */
+
+/*
* Some undocumented ways of patching the results of the cpuid
* instruction to permit running Solaris 10 on future cpus that
* we don't currently support. Could be set to non-zero values
@@ -353,6 +359,26 @@ uint32_t cpuid_feature_ecx_exclude;
uint32_t cpuid_feature_edx_include;
uint32_t cpuid_feature_edx_exclude;
+void
+cpuid_alloc_space(cpu_t *cpu)
+{
+ /*
+ * By convention, cpu0 is the boot cpu, which is set up
+ * before memory allocation is available. All other cpus get
+ * their cpuid_info struct allocated here.
+ */
+ ASSERT(cpu->cpu_id != 0);
+ cpu->cpu_m.mcpu_cpi =
+ kmem_zalloc(sizeof (*cpu->cpu_m.mcpu_cpi), KM_SLEEP);
+}
+
+void
+cpuid_free_space(cpu_t *cpu)
+{
+ ASSERT(cpu->cpu_id != 0);
+ kmem_free(cpu->cpu_m.mcpu_cpi, sizeof (*cpu->cpu_m.mcpu_cpi));
+}
+
uint_t
cpuid_pass1(cpu_t *cpu)
{
@@ -362,17 +388,14 @@ cpuid_pass1(cpu_t *cpu)
struct cpuid_regs *cp;
int xcpuid;
+
/*
- * By convention, cpu0 is the boot cpu, which is called
- * before memory allocation is available. Other cpus are
- * initialized when memory becomes available.
+ * Space statically allocated for cpu0, ensure pointer is set
*/
if (cpu->cpu_id == 0)
- cpu->cpu_m.mcpu_cpi = cpi = &cpuid_info0;
- else
- cpu->cpu_m.mcpu_cpi = cpi =
- kmem_zalloc(sizeof (*cpi), KM_SLEEP);
-
+ cpu->cpu_m.mcpu_cpi = &cpuid_info0;
+ cpi = cpu->cpu_m.mcpu_cpi;
+ ASSERT(cpi != NULL);
cp = &cpi->cpi_std[0];
cp->cp_eax = 0;
cpi->cpi_maxeax = __cpuid_insn(cp);
@@ -615,13 +638,18 @@ cpuid_pass1(cpu_t *cpu)
cp->cp_ecx &= mask_ecx;
/*
- * fold in fix ups
+ * apply any platform restrictions (we don't call this
+ * immediately after __cpuid_insn here, because we need the
+ * workarounds applied above first)
*/
+ platform_cpuid_mangle(cpi->cpi_vendor, 1, cp);
+ /*
+ * fold in overrides from the "eeprom" mechanism
+ */
cp->cp_edx |= cpuid_feature_edx_include;
cp->cp_edx &= ~cpuid_feature_edx_exclude;
-
cp->cp_ecx |= cpuid_feature_ecx_include;
cp->cp_ecx &= ~cpuid_feature_ecx_exclude;
@@ -646,10 +674,6 @@ cpuid_pass1(cpu_t *cpu)
feature |= X86_PAE;
if (cp->cp_edx & CPUID_INTC_EDX_CX8)
feature |= X86_CX8;
- /*
- * Once this bit was thought questionable, but it looks like it's
- * back, as of Application Note 485 March 2005 (24161829.pdf)
- */
if (cp->cp_ecx & CPUID_INTC_ECX_CX16)
feature |= X86_CX16;
if (cp->cp_edx & CPUID_INTC_EDX_PAT)
@@ -670,7 +694,7 @@ cpuid_pass1(cpu_t *cpu)
feature |= X86_SSE3;
}
if (cp->cp_edx & CPUID_INTC_EDX_DE)
- cr4_value |= CR4_DE;
+ feature |= X86_DE;
if (feature & X86_PAE)
cpi->cpi_pabits = 36;
@@ -682,7 +706,7 @@ cpuid_pass1(cpu_t *cpu)
* (AMD chose to set the HTT bit on their CMP processors,
* even though they're not actually hyperthreaded. Thus it
* takes a bit more work to figure out what's really going
- * on ... see the handling of the CMP_LEGACY bit below)
+ * on ... see the handling of the CMP_LGCY bit below)
*/
if (cp->cp_edx & CPUID_INTC_EDX_HTT) {
cpi->cpi_ncpu_per_chip = CPI_CPU_COUNT(cpi);
@@ -742,6 +766,7 @@ cpuid_pass1(cpu_t *cpu)
cp = &cpi->cpi_extd[1];
cp->cp_eax = 0x80000001;
(void) __cpuid_insn(cp);
+
if (cpi->cpi_vendor == X86_VENDOR_AMD &&
cpi->cpi_family == 5 &&
cpi->cpi_model == 6 &&
@@ -756,6 +781,8 @@ cpuid_pass1(cpu_t *cpu)
}
}
+ platform_cpuid_mangle(cpi->cpi_vendor, 0x80000001, cp);
+
/*
* Compute the additions to the kernel's feature word.
*/
@@ -763,17 +790,17 @@ cpuid_pass1(cpu_t *cpu)
feature |= X86_NX;
/*
- * If both the HTT and CMP_LEGACY bits are set,
+ * If both the HTT and CMP_LGCY bits are set,
* then we're not actually HyperThreaded. Read
* "AMD CPUID Specification" for more details.
*/
if (cpi->cpi_vendor == X86_VENDOR_AMD &&
(feature & X86_HTT) &&
- (cp->cp_ecx & CPUID_AMD_ECX_CMP_LEGACY)) {
+ (cp->cp_ecx & CPUID_AMD_ECX_CMP_LGCY)) {
feature &= ~X86_HTT;
feature |= X86_CMP;
}
-#if defined(_LP64)
+#if defined(__amd64)
/*
* It's really tricky to support syscall/sysret in
* the i386 kernel; we rely on sysenter/sysexit
@@ -791,6 +818,8 @@ cpuid_pass1(cpu_t *cpu)
if (x86_vendor == X86_VENDOR_AMD)
feature &= ~X86_SEP;
#endif
+ if (cp->cp_edx & CPUID_AMD_EDX_TSCP)
+ feature |= X86_TSCP;
break;
default:
break;
@@ -806,6 +835,7 @@ cpuid_pass1(cpu_t *cpu)
cp->cp_eax = 4;
cp->cp_ecx = 0;
(void) __cpuid_insn(cp);
+ platform_cpuid_mangle(cpi->cpi_vendor, 4, cp);
}
/*FALLTHROUGH*/
case X86_VENDOR_AMD:
@@ -814,6 +844,8 @@ cpuid_pass1(cpu_t *cpu)
cp = &cpi->cpi_extd[8];
cp->cp_eax = 0x80000008;
(void) __cpuid_insn(cp);
+ platform_cpuid_mangle(cpi->cpi_vendor, 0x80000008, cp);
+
/*
* Virtual and physical address limits from
* cpuid override previously guessed values.
@@ -848,7 +880,6 @@ cpuid_pass1(cpu_t *cpu)
cpi->cpi_ncore_per_chip = 1;
break;
}
-
}
/*
@@ -856,6 +887,7 @@ cpuid_pass1(cpu_t *cpu)
*/
if (cpi->cpi_ncore_per_chip > 1)
feature |= X86_CMP;
+
/*
* If the number of cores is the same as the number
* of CPUs, then we cannot have HyperThreading.
@@ -980,6 +1012,7 @@ cpuid_pass2(cpu_t *cpu)
for (n = 2, cp = &cpi->cpi_std[2]; n < nmax; n++, cp++) {
cp->cp_eax = n;
(void) __cpuid_insn(cp);
+ platform_cpuid_mangle(cpi->cpi_vendor, n, cp);
switch (n) {
case 2:
/*
@@ -1052,6 +1085,7 @@ cpuid_pass2(cpu_t *cpu)
for (n = 2, cp = &cpi->cpi_extd[2]; n < nmax; cp++, n++) {
cp->cp_eax = 0x80000000 + n;
(void) __cpuid_insn(cp);
+ platform_cpuid_mangle(cpi->cpi_vendor, 0x80000000 + n, cp);
switch (n) {
case 2:
case 3:
@@ -1641,10 +1675,8 @@ cpuid_pass4(cpu_t *cpu)
hwcap_flags |= AV_386_CMOV;
if (*ecx & CPUID_INTC_ECX_MON)
hwcap_flags |= AV_386_MON;
-#if defined(CPUID_INTC_ECX_CX16)
if (*ecx & CPUID_INTC_ECX_CX16)
hwcap_flags |= AV_386_CX16;
-#endif
}
if (x86_feature & X86_HTT)
@@ -1655,13 +1687,39 @@ cpuid_pass4(cpu_t *cpu)
switch (cpi->cpi_vendor) {
struct cpuid_regs cp;
- uint32_t *edx;
+ uint32_t *edx, *ecx;
+
+ case X86_VENDOR_Intel:
+ /*
+ * Seems like Intel duplicated what we necessary
+ * here to make the initial crop of 64-bit OS's work.
+ * Hopefully, those are the only "extended" bits
+ * they'll add.
+ */
+ /*FALLTHROUGH*/
- case X86_VENDOR_Intel: /* sigh */
case X86_VENDOR_AMD:
edx = &cpi->cpi_support[AMD_EDX_FEATURES];
+ ecx = &cpi->cpi_support[AMD_ECX_FEATURES];
*edx = CPI_FEATURES_XTD_EDX(cpi);
+ *ecx = CPI_FEATURES_XTD_ECX(cpi);
+
+ /*
+ * [these features require explicit kernel support]
+ */
+ switch (cpi->cpi_vendor) {
+ case X86_VENDOR_Intel:
+ break;
+
+ case X86_VENDOR_AMD:
+ if ((x86_feature & X86_TSCP) == 0)
+ *edx &= ~CPUID_AMD_EDX_TSCP;
+ break;
+
+ default:
+ break;
+ }
/*
* [no explicit support required beyond
@@ -1671,25 +1729,46 @@ cpuid_pass4(cpu_t *cpu)
*edx &= ~(CPUID_AMD_EDX_MMXamd |
CPUID_AMD_EDX_3DNow | CPUID_AMD_EDX_3DNowx);
- if ((x86_feature & X86_ASYSC) == 0)
- *edx &= ~CPUID_AMD_EDX_SYSC;
if ((x86_feature & X86_NX) == 0)
*edx &= ~CPUID_AMD_EDX_NX;
-#if !defined(_LP64)
+#if !defined(__amd64)
*edx &= ~CPUID_AMD_EDX_LM;
#endif
/*
* Now map the supported feature vector to
* things that we think userland will care about.
*/
+#if defined(__amd64)
if (*edx & CPUID_AMD_EDX_SYSC)
hwcap_flags |= AV_386_AMD_SYSC;
+#endif
if (*edx & CPUID_AMD_EDX_MMXamd)
hwcap_flags |= AV_386_AMD_MMX;
if (*edx & CPUID_AMD_EDX_3DNow)
hwcap_flags |= AV_386_AMD_3DNow;
if (*edx & CPUID_AMD_EDX_3DNowx)
hwcap_flags |= AV_386_AMD_3DNowx;
+
+ switch (cpi->cpi_vendor) {
+ case X86_VENDOR_AMD:
+ if (*edx & CPUID_AMD_EDX_TSCP)
+ hwcap_flags |= AV_386_TSCP;
+ if (*ecx & CPUID_AMD_ECX_AHF64)
+ hwcap_flags |= AV_386_AHF;
+ break;
+
+ case X86_VENDOR_Intel:
+ /*
+ * Aarrgh.
+ * Intel uses a different bit in the same word.
+ */
+ if (*ecx & CPUID_INTC_ECX_AHF64)
+ hwcap_flags |= AV_386_AHF;
+ break;
+
+ default:
+ break;
+ }
break;
case X86_VENDOR_TM:
@@ -1790,8 +1869,18 @@ cpuid_syscall32_insn(cpu_t *cpu)
{
ASSERT(cpuid_checkpass((cpu == NULL ? CPU : cpu), 1));
- if (x86_feature & X86_ASYSC)
- return (x86_vendor != X86_VENDOR_Intel);
+ if (cpu == NULL)
+ cpu = CPU;
+
+ /*CSTYLED*/
+ {
+ struct cpuid_info *cpi = cpu->cpu_m.mcpu_cpi;
+
+ if (cpi->cpi_vendor == X86_VENDOR_AMD &&
+ cpi->cpi_xmaxeax >= 0x80000001 &&
+ (CPI_FEATURES_XTD_EDX(cpi) & CPUID_AMD_EDX_SYSC))
+ return (1);
+ }
return (0);
}
@@ -2226,6 +2315,7 @@ add_cache_prop(dev_info_t *devi, const char *label, const char *type,
static const char l1_icache_str[] = "l1-icache";
static const char l1_dcache_str[] = "l1-dcache";
static const char l2_cache_str[] = "l2-cache";
+static const char l3_cache_str[] = "l3-cache";
static const char itlb4k_str[] = "itlb-4K";
static const char dtlb4k_str[] = "dtlb-4K";
static const char itlb4M_str[] = "itlb-4M";
@@ -2245,6 +2335,7 @@ static const struct cachetab {
const char *ct_label;
} intel_ctab[] = {
/* maintain descending order! */
+ { 0xb4, 4, 0, 256, dtlb4k_str },
{ 0xb3, 4, 0, 128, dtlb4k_str },
{ 0xb0, 4, 0, 128, itlb4k_str },
{ 0x87, 8, 64, 1024*1024, l2_cache_str},
@@ -2253,7 +2344,6 @@ static const struct cachetab {
{ 0x84, 8, 32, 1024*1024, l2_cache_str},
{ 0x83, 8, 32, 512*1024, l2_cache_str},
{ 0x82, 8, 32, 256*1024, l2_cache_str},
- { 0x81, 8, 32, 128*1024, l2_cache_str}, /* suspect! */
{ 0x7f, 2, 64, 512*1024, l2_cache_str},
{ 0x7d, 8, 64, 2*1024*1024, sl2_cache_str},
{ 0x7c, 8, 64, 1024*1024, sl2_cache_str},
@@ -2261,6 +2351,7 @@ static const struct cachetab {
{ 0x7a, 8, 64, 256*1024, sl2_cache_str},
{ 0x79, 8, 64, 128*1024, sl2_cache_str},
{ 0x78, 8, 64, 1024*1024, l2_cache_str},
+ { 0x73, 8, 0, 64*1024, itrace_str},
{ 0x72, 8, 0, 32*1024, itrace_str},
{ 0x71, 8, 0, 16*1024, itrace_str},
{ 0x70, 8, 0, 12*1024, itrace_str},
@@ -2274,13 +2365,23 @@ static const struct cachetab {
{ 0x52, 0, 0, 256, itlb424_str},
{ 0x51, 0, 0, 128, itlb424_str},
{ 0x50, 0, 0, 64, itlb424_str},
+ { 0x4d, 16, 64, 16*1024*1024, l3_cache_str},
+ { 0x4c, 12, 64, 12*1024*1024, l3_cache_str},
+ { 0x4b, 16, 64, 8*1024*1024, l3_cache_str},
+ { 0x4a, 12, 64, 6*1024*1024, l3_cache_str},
+ { 0x49, 16, 64, 4*1024*1024, l3_cache_str},
+ { 0x47, 8, 64, 8*1024*1024, l3_cache_str},
+ { 0x46, 4, 64, 4*1024*1024, l3_cache_str},
{ 0x45, 4, 32, 2*1024*1024, l2_cache_str},
{ 0x44, 4, 32, 1024*1024, l2_cache_str},
{ 0x43, 4, 32, 512*1024, l2_cache_str},
{ 0x42, 4, 32, 256*1024, l2_cache_str},
{ 0x41, 4, 32, 128*1024, l2_cache_str},
+ { 0x3e, 4, 64, 512*1024, sl2_cache_str},
+ { 0x3d, 6, 64, 384*1024, sl2_cache_str},
{ 0x3c, 4, 64, 256*1024, sl2_cache_str},
{ 0x3b, 2, 64, 128*1024, sl2_cache_str},
+ { 0x3a, 6, 64, 192*1024, sl2_cache_str},
{ 0x39, 4, 64, 128*1024, sl2_cache_str},
{ 0x30, 8, 64, 32*1024, l1_icache_str},
{ 0x2c, 8, 64, 32*1024, l1_dcache_str},
@@ -2289,6 +2390,7 @@ static const struct cachetab {
{ 0x23, 8, 64, 1024*1024, sl3_cache_str},
{ 0x22, 4, 64, 512*1024, sl3_cache_str},
{ 0x0c, 4, 32, 16*1024, l1_dcache_str},
+ { 0x0b, 4, 0, 4, itlb4M_str},
{ 0x0a, 2, 32, 8*1024, l1_dcache_str},
{ 0x08, 4, 32, 16*1024, l1_icache_str},
{ 0x06, 4, 32, 8*1024, l1_icache_str},
diff --git a/usr/src/uts/i86pc/os/dtrace_subr.c b/usr/src/uts/i86pc/os/dtrace_subr.c
index 00da457012..7e369be269 100644
--- a/usr/src/uts/i86pc/os/dtrace_subr.c
+++ b/usr/src/uts/i86pc/os/dtrace_subr.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -373,3 +373,13 @@ dtrace_safe_defer_signal(void)
return (1);
}
+
+/*
+ * Additional artificial frames for the machine type. For i86pc, we're already
+ * accounted for, so return 0.
+ */
+int
+dtrace_mach_aframes(void)
+{
+ return (0);
+}
diff --git a/usr/src/uts/i86pc/os/fakebop.c b/usr/src/uts/i86pc/os/fakebop.c
new file mode 100644
index 0000000000..06b308e6e6
--- /dev/null
+++ b/usr/src/uts/i86pc/os/fakebop.c
@@ -0,0 +1,1503 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * This file contains the functionality that mimics the boot operations
+ * on SPARC systems or the old boot.bin/multiboot programs on x86 systems.
+ * The x86 kernel now does everything on its own.
+ */
+
+#include <sys/types.h>
+#include <sys/bootconf.h>
+#include <sys/bootsvcs.h>
+#include <sys/bootinfo.h>
+#include <sys/multiboot.h>
+#include <sys/bootvfs.h>
+#include <sys/bootprops.h>
+#include <sys/varargs.h>
+#include <sys/param.h>
+#include <sys/machparam.h>
+#include <sys/archsystm.h>
+#include <sys/boot_console.h>
+#include <sys/cmn_err.h>
+#include <sys/systm.h>
+#include <sys/promif.h>
+#include <sys/archsystm.h>
+#include <sys/x86_archext.h>
+#include <sys/kobj.h>
+#include <sys/privregs.h>
+#include <sys/sysmacros.h>
+#include <sys/ctype.h>
+#include <vm/kboot_mmu.h>
+#include <vm/hat_pte.h>
+#include "acpi_fw.h"
+
+static int have_console = 0; /* set once primitive console is initialized */
+static char *boot_args = "";
+
+/*
+ * Debugging macros
+ */
+static uint_t kbm_debug = 0;
+#define DBG_MSG(s) { if (kbm_debug) bop_printf(NULL, "%s", s); }
+#define DBG(x) { if (kbm_debug) \
+ bop_printf(NULL, "%s is %" PRIx64 "\n", #x, (uint64_t)(x)); \
+ }
+
+#define PUT_STRING(s) { \
+ char *cp; \
+ for (cp = (s); *cp; ++cp) \
+ bcons_putchar(*cp); \
+ }
+
+struct xboot_info *xbootp; /* boot info from "glue" code in low memory */
+bootops_t bootop; /* simple bootops we'll pass on to kernel */
+struct bsys_mem bm;
+
+static uintptr_t next_virt; /* next available virtual address */
+static paddr_t next_phys; /* next available physical address from dboot */
+static paddr_t high_phys = -(paddr_t)1; /* last used physical address */
+
+/*
+ * buffer for vsnprintf for console I/O
+ */
+#define BUFFERSIZE 256
+static char buffer[BUFFERSIZE];
+/*
+ * stuff to store/report/manipulate boot property settings.
+ */
+typedef struct bootprop {
+ struct bootprop *bp_next;
+ char *bp_name;
+ uint_t bp_vlen;
+ char *bp_value;
+} bootprop_t;
+
+static bootprop_t *bprops = NULL;
+static char *curr_page = NULL; /* ptr to avail bprop memory */
+static int curr_space = 0; /* amount of memory at curr_page */
+
+/*
+ * some allocator statistics
+ */
+static ulong_t total_bop_alloc_scratch = 0;
+static ulong_t total_bop_alloc_kernel = 0;
+
+static void build_firmware_properties(void);
+
+/*
+ * Allocate aligned physical memory at boot time. This allocator allocates
+ * from the highest possible addresses. This avoids exhausting memory that
+ * would be useful for DMA buffers.
+ */
+paddr_t
+do_bop_phys_alloc(uint64_t size, uint64_t align)
+{
+ paddr_t pa = 0;
+ paddr_t start;
+ paddr_t end;
+ struct memlist *ml = (struct memlist *)xbootp->bi_phys_install;
+
+ /*
+ * Be careful if high memory usage is limited in startup.c
+ * Since there are holes in the low part of the physical address
+ * space we can treat physmem as a pfn (not just a pgcnt) and
+ * get a conservative upper limit.
+ */
+ extern pgcnt_t physmem;
+ if (physmem != 0 && high_phys > pfn_to_pa(physmem))
+ high_phys = pfn_to_pa(physmem);
+
+ /*
+ * find the highest available memory in physinstalled
+ */
+ size = P2ROUNDUP(size, align);
+ for (; ml; ml = ml->next) {
+ start = ml->address;
+ end = P2ALIGN(start + ml->size, align);
+ if (start < next_phys)
+ start = next_phys;
+ if (end > high_phys)
+ end = P2ALIGN(high_phys, align);
+
+ if (end <= start)
+ continue;
+ if (end - start < size)
+ continue;
+
+ if (end - size > pa)
+ pa = end - size;
+ }
+ if (pa != 0) {
+ high_phys = pa;
+ return (pa);
+ }
+ panic("do_bop_phys_alloc(0x%" PRIx64 ", 0x%" PRIx64 ") Out of memory\n",
+ size, align);
+ /*NOTREACHED*/
+}
+
+static uintptr_t
+alloc_vaddr(size_t size, paddr_t align)
+{
+ uintptr_t rv;
+
+ next_virt = P2ROUNDUP(next_virt, (uintptr_t)align);
+ rv = (uintptr_t)next_virt;
+ next_virt += size;
+ return (rv);
+}
+
+/*
+ * Allocate virtual memory. The size is always rounded up to a multiple
+ * of base pagesize.
+ */
+
+/*ARGSUSED*/
+static caddr_t
+do_bsys_alloc(bootops_t *bop, caddr_t virthint, size_t size, int align)
+{
+ paddr_t a = align; /* same type as pa for masking */
+ uint_t pgsize;
+ paddr_t pa;
+ uintptr_t va;
+ ssize_t s; /* the aligned size */
+ uint_t level;
+ uint_t is_kernel = (virthint != 0);
+
+ if (a < MMU_PAGESIZE)
+ a = MMU_PAGESIZE;
+ else if (!ISP2(a))
+ prom_panic("do_bsys_alloc() incorrect alignment");
+ size = P2ROUNDUP(size, MMU_PAGESIZE);
+
+ /*
+ * Use the next aligned virtual address if we weren't given one.
+ */
+ if (virthint == NULL) {
+ virthint = (caddr_t)alloc_vaddr(size, a);
+ total_bop_alloc_scratch += size;
+ } else {
+ total_bop_alloc_kernel += size;
+ }
+
+ /*
+ * allocate the physical memory
+ */
+ pa = do_bop_phys_alloc(size, a);
+
+ /*
+ * Add the mappings to the page tables, try large pages first.
+ */
+ va = (uintptr_t)virthint;
+ s = size;
+ level = 1;
+ pgsize = xbootp->bi_use_pae ? TWO_MEG : FOUR_MEG;
+ if (xbootp->bi_use_largepage && a == pgsize) {
+ while (IS_P2ALIGNED(pa, pgsize) && IS_P2ALIGNED(va, pgsize) &&
+ s >= pgsize) {
+ kbm_map(va, pa, level, is_kernel);
+ va += pgsize;
+ pa += pgsize;
+ s -= pgsize;
+ }
+ }
+
+ /*
+ * Map remaining pages use small mappings
+ */
+ level = 0;
+ pgsize = MMU_PAGESIZE;
+ while (s > 0) {
+ kbm_map(va, pa, level, is_kernel);
+ va += pgsize;
+ pa += pgsize;
+ s -= pgsize;
+ }
+ return (virthint);
+}
+
+/*
+ * Free virtual memory - we'll just ignore these.
+ */
+/*ARGSUSED*/
+static void
+do_bsys_free(bootops_t *bop, caddr_t virt, size_t size)
+{
+ bop_printf(NULL, "do_bsys_free(virt=0x%p, size=0x%lx) ignored\n",
+ (void *)virt, size);
+}
+
+/*
+ * Old interface
+ */
+/*ARGSUSED*/
+static caddr_t
+do_bsys_ealloc(
+ bootops_t *bop,
+ caddr_t virthint,
+ size_t size,
+ int align,
+ int flags)
+{
+ prom_panic("unsupported call to BOP_EALLOC()\n");
+ return (0);
+}
+
+
+static void
+bsetprop(char *name, int nlen, void *value, int vlen)
+{
+ uint_t size;
+ uint_t need_size;
+ bootprop_t *b;
+
+ /*
+ * align the size to 16 byte boundary
+ */
+ size = sizeof (bootprop_t) + nlen + 1 + vlen;
+ size = (size + 0xf) & ~0xf;
+ if (size > curr_space) {
+ need_size = (size + (MMU_PAGEOFFSET)) & MMU_PAGEMASK;
+ curr_page = do_bsys_alloc(NULL, 0, need_size, MMU_PAGESIZE);
+ curr_space = need_size;
+ }
+
+ /*
+ * use a bootprop_t at curr_page and link into list
+ */
+ b = (bootprop_t *)curr_page;
+ curr_page += sizeof (bootprop_t);
+ curr_space -= sizeof (bootprop_t);
+ b->bp_next = bprops;
+ bprops = b;
+
+ /*
+ * follow by name and ending zero byte
+ */
+ b->bp_name = curr_page;
+ bcopy(name, curr_page, nlen);
+ curr_page += nlen;
+ *curr_page++ = 0;
+ curr_space -= nlen + 1;
+
+ /*
+ * copy in value, but no ending zero byte
+ */
+ b->bp_value = curr_page;
+ b->bp_vlen = vlen;
+ if (vlen > 0) {
+ bcopy(value, curr_page, vlen);
+ curr_page += vlen;
+ curr_space -= vlen;
+ }
+
+ /*
+ * align new values of curr_page, curr_space
+ */
+ while (curr_space & 0xf) {
+ ++curr_page;
+ --curr_space;
+ }
+}
+
+static void
+bsetprops(char *name, char *value)
+{
+ bsetprop(name, strlen(name), value, strlen(value) + 1);
+}
+
+static void
+bsetprop64(char *name, uint64_t value)
+{
+ bsetprop(name, strlen(name), (void *)&value, sizeof (value));
+}
+
+static void
+bsetpropsi(char *name, int value)
+{
+ char prop_val[32];
+
+ (void) snprintf(prop_val, sizeof (prop_val), "%d", value);
+ bsetprops(name, prop_val);
+}
+
+/*
+ * to find the size of the buffer to allocate
+ */
+/*ARGSUSED*/
+static int
+do_bsys_getproplen(bootops_t *bop, char *name)
+{
+ bootprop_t *b;
+
+ for (b = bprops; b; b = b->bp_next) {
+ if (strcmp(name, b->bp_name) != 0)
+ continue;
+ return (b->bp_vlen);
+ }
+ return (-1);
+}
+
+/*
+ * get the value associated with this name
+ */
+/*ARGSUSED*/
+static int
+do_bsys_getprop(bootops_t *bop, char *name, void *value)
+{
+ bootprop_t *b;
+
+ for (b = bprops; b; b = b->bp_next) {
+ if (strcmp(name, b->bp_name) != 0)
+ continue;
+ bcopy(b->bp_value, value, b->bp_vlen);
+ return (0);
+ }
+ return (-1);
+}
+
+/*
+ * get the name of the next property in succession from the standalone
+ */
+/*ARGSUSED*/
+static char *
+do_bsys_nextprop(bootops_t *bop, char *name)
+{
+ bootprop_t *b;
+
+ /*
+ * A null name is a special signal for the 1st boot property
+ */
+ if (name == NULL || strlen(name) == 0) {
+ if (bprops == NULL)
+ return (NULL);
+ return (bprops->bp_name);
+ }
+
+ for (b = bprops; b; b = b->bp_next) {
+ if (name != b->bp_name)
+ continue;
+ b = b->bp_next;
+ if (b == NULL)
+ return (NULL);
+ return (b->bp_name);
+ }
+ return (NULL);
+}
+
+/*
+ * 2nd part of building the table of boot properties. This includes:
+ * - values from /boot/solaris/bootenv.rc (ie. eeprom(1m) values)
+ *
+ * lines look like one of:
+ * ^$
+ * ^# comment till end of line
+ * setprop name 'value'
+ * setprop name value
+ * setprop name "value"
+ *
+ * we do single character I/O since this is really just looking at memory
+ */
+void
+boot_prop_finish(void)
+{
+ int fd;
+ char *line;
+ int c;
+ int bytes_read;
+ char *name;
+ int n_len;
+ char *value;
+ int v_len;
+ char *inputdev; /* these override the comand line if serial ports */
+ char *outputdev;
+ char *consoledev;
+
+ DBG_MSG("Opening /boot/solaris/bootenv.rc\n");
+ fd = BRD_OPEN(bfs_ops, "/boot/solaris/bootenv.rc", 0);
+ DBG(fd);
+
+ line = do_bsys_alloc(NULL, NULL, MMU_PAGESIZE, MMU_PAGESIZE);
+ while (fd >= 0) {
+
+ /*
+ * get a line
+ */
+ for (c = 0; ; ++c) {
+ bytes_read = BRD_READ(bfs_ops, fd, line + c, 1);
+ if (bytes_read == 0) {
+ if (c == 0)
+ goto done;
+ break;
+ }
+ if (line[c] == '\n')
+ break;
+ }
+ line[c] = 0;
+
+ /*
+ * ignore comment lines
+ */
+ c = 0;
+ while (ISSPACE(line[c]))
+ ++c;
+ if (line[c] == '#' || line[c] == 0)
+ continue;
+
+ /*
+ * must have "setprop " or "setprop\t"
+ */
+ if (strncmp(line + c, "setprop ", 8) != 0 &&
+ strncmp(line + c, "setprop\t", 8) != 0)
+ continue;
+ c += 8;
+ while (ISSPACE(line[c]))
+ ++c;
+ if (line[c] == 0)
+ continue;
+
+ /*
+ * gather up the property name
+ */
+ name = line + c;
+ n_len = 0;
+ while (line[c] && !ISSPACE(line[c]))
+ ++n_len, ++c;
+
+ /*
+ * gather up the value, if any
+ */
+ value = "";
+ v_len = 0;
+ while (ISSPACE(line[c]))
+ ++c;
+ if (line[c] != 0) {
+ value = line + c;
+ while (line[c] && !ISSPACE(line[c]))
+ ++v_len, ++c;
+ }
+
+ if (v_len >= 2 && value[0] == value[v_len - 1] &&
+ (value[0] == '\'' || value[0] == '"')) {
+ ++value;
+ v_len -= 2;
+ }
+ name[n_len] = 0;
+ if (v_len > 0)
+ value[v_len] = 0;
+ else
+ continue;
+
+ /*
+ * ignore "boot-file" property, it's now meaningless
+ */
+ if (strcmp(name, "boot-file") == 0)
+ continue;
+ if (strcmp(name, "boot-args") == 0 &&
+ strlen(boot_args) > 0)
+ continue;
+
+ /*
+ * If console was explicitly set on the command line it will
+ * override a setting in bootenv.rc
+ */
+ if (strcmp(name, "console") == 0 &&
+ do_bsys_getproplen(NULL, "console") > 0)
+ continue;
+
+ bsetprop(name, n_len, value, v_len + 1);
+ }
+done:
+ if (fd >= 0)
+ BRD_CLOSE(bfs_ops, fd);
+
+ /*
+ * check to see if we have to override the default value of the console
+ */
+ inputdev = line;
+ v_len = do_bsys_getproplen(NULL, "input-device");
+ if (v_len > 0)
+ (void) do_bsys_getprop(NULL, "input-device", inputdev);
+ else
+ v_len = 0;
+ inputdev[v_len] = 0;
+
+ outputdev = inputdev + v_len + 1;
+ v_len = do_bsys_getproplen(NULL, "output-device");
+ if (v_len > 0)
+ (void) do_bsys_getprop(NULL, "output-device", outputdev);
+ else
+ v_len = 0;
+ outputdev[v_len] = 0;
+
+ consoledev = outputdev + v_len + 1;
+ v_len = do_bsys_getproplen(NULL, "console");
+ if (v_len > 0)
+ (void) do_bsys_getprop(NULL, "console", consoledev);
+ else
+ v_len = 0;
+ consoledev[v_len] = 0;
+ bcons_init2(inputdev, outputdev, consoledev);
+
+ if (strstr((char *)xbootp->bi_cmdline, "prom_debug") || kbm_debug) {
+ value = line;
+ bop_printf(NULL, "\nBoot properties:\n");
+ name = "";
+ while ((name = do_bsys_nextprop(NULL, name)) != NULL) {
+ bop_printf(NULL, "\t0x%p %s = ", (void *)name, name);
+ (void) do_bsys_getprop(NULL, name, value);
+ v_len = do_bsys_getproplen(NULL, name);
+ bop_printf(NULL, "len=%d ", v_len);
+ value[v_len] = 0;
+ bop_printf(NULL, "%s\n", value);
+ }
+ }
+}
+
+/*
+ * print formatted output
+ */
+/*PRINTFLIKE2*/
+/*ARGSUSED*/
+void
+bop_printf(bootops_t *bop, char *fmt, ...)
+{
+ va_list ap;
+
+ if (have_console == 0)
+ return;
+
+ va_start(ap, fmt);
+ (void) vsnprintf(buffer, BUFFERSIZE, fmt, ap);
+ va_end(ap);
+ PUT_STRING(buffer);
+}
+
+/*
+ * Another panic() variant; this one can be used even earlier during boot than
+ * prom_panic().
+ */
+/*PRINTFLIKE1*/
+void
+bop_panic(char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ bop_printf(NULL, fmt, ap);
+ va_end(ap);
+
+ bop_printf(NULL, "\nPress any key to reboot.\n");
+ (void) bcons_getchar();
+ bop_printf(NULL, "Resetting...\n");
+ reset();
+}
+
+/*
+ * Do a real mode interrupt BIOS call
+ */
+typedef struct bios_regs {
+ unsigned short ax, bx, cx, dx, si, di, bp, es, ds;
+} bios_regs_t;
+typedef int (*bios_func_t)(int, bios_regs_t *);
+
+/*ARGSUSED*/
+static void
+do_bsys_doint(bootops_t *bop, int intnum, struct bop_regs *rp)
+{
+ static int firsttime = 1;
+ bios_func_t bios_func = (bios_func_t)(void *)(uintptr_t)0x5000;
+ bios_regs_t br;
+
+ /*
+ * The first time we do this, we have to copy the pre-packaged
+ * low memory bios call code image into place.
+ */
+ if (firsttime) {
+ extern char bios_image[];
+ extern uint32_t bios_size;
+
+ bcopy(bios_image, (void *)bios_func, bios_size);
+ firsttime = 0;
+ }
+
+ br.ax = rp->eax.word.ax;
+ br.bx = rp->ebx.word.bx;
+ br.cx = rp->ecx.word.cx;
+ br.dx = rp->edx.word.dx;
+ br.bp = rp->ebp.word.bp;
+ br.si = rp->esi.word.si;
+ br.di = rp->edi.word.di;
+ br.ds = rp->ds;
+ br.es = rp->es;
+
+ DBG_MSG("Doing BIOS call...");
+ rp->eflags = bios_func(intnum, &br);
+ DBG_MSG("done\n");
+
+ rp->eax.word.ax = br.ax;
+ rp->ebx.word.bx = br.bx;
+ rp->ecx.word.cx = br.cx;
+ rp->edx.word.dx = br.dx;
+ rp->ebp.word.bp = br.bp;
+ rp->esi.word.si = br.si;
+ rp->edi.word.di = br.di;
+ rp->ds = br.ds;
+ rp->es = br.es;
+}
+
+static struct boot_syscalls bop_sysp = {
+ bcons_getchar,
+ bcons_putchar,
+ bcons_ischar,
+};
+
+static char *whoami;
+
+#define BUFLEN 64
+
+static void
+setup_rarp_props(struct sol_netinfo *sip)
+{
+ char buf[BUFLEN]; /* to hold ip/mac addrs */
+ uint8_t *val;
+
+ val = (uint8_t *)&sip->sn_ciaddr;
+ (void) snprintf(buf, BUFLEN, "%d.%d.%d.%d",
+ val[0], val[1], val[2], val[3]);
+ bsetprops(BP_HOST_IP, buf);
+
+ val = (uint8_t *)&sip->sn_siaddr;
+ (void) snprintf(buf, BUFLEN, "%d.%d.%d.%d",
+ val[0], val[1], val[2], val[3]);
+ bsetprops(BP_SERVER_IP, buf);
+
+ if (sip->sn_giaddr != 0) {
+ val = (uint8_t *)&sip->sn_giaddr;
+ (void) snprintf(buf, BUFLEN, "%d.%d.%d.%d",
+ val[0], val[1], val[2], val[3]);
+ bsetprops(BP_ROUTER_IP, buf);
+ }
+
+ if (sip->sn_netmask != 0) {
+ val = (uint8_t *)&sip->sn_netmask;
+ (void) snprintf(buf, BUFLEN, "%d.%d.%d.%d",
+ val[0], val[1], val[2], val[3]);
+ bsetprops(BP_SUBNET_MASK, buf);
+ }
+
+ if (sip->sn_mactype != 4 || sip->sn_maclen != 6) {
+ bop_printf(NULL, "unsupported mac type %d, mac len %d\n",
+ sip->sn_mactype, sip->sn_maclen);
+ } else {
+ val = sip->sn_macaddr;
+ (void) snprintf(buf, BUFLEN, "%x:%x:%x:%x:%x:%x",
+ val[0], val[1], val[2], val[3], val[4], val[5]);
+ bsetprops(BP_BOOT_MAC, buf);
+ }
+}
+
+/*
+ * 1st pass at building the table of boot properties. This includes:
+ * - values set on the command line: -B a=x,b=y,c=z ....
+ * - known values we just compute (ie. from xbootp)
+ * - values from /boot/solaris/bootenv.rc (ie. eeprom(1m) values)
+ *
+ * the grub command line looked like:
+ * kernel boot-file [-B prop=value[,prop=value]...] [boot-args]
+ *
+ * whoami is the same as boot-file
+ */
+static void
+build_boot_properties(void)
+{
+ char *name;
+ int name_len;
+ char *value;
+ int value_len;
+ static int stdout_val = 0;
+ struct boot_modules *bm;
+ char *propbuf;
+ int quoted = 0;
+ int boot_arg_len;
+ uchar_t boot_device;
+ char str[3];
+ multiboot_info_t *mbi;
+ int netboot;
+ struct sol_netinfo *sip;
+
+ /*
+ * These have to be done first, so that kobj_mount_root() works
+ */
+ DBG_MSG("Building boot properties\n");
+ propbuf = do_bsys_alloc(NULL, NULL, MMU_PAGESIZE, 0);
+ DBG((uintptr_t)propbuf);
+ if (xbootp->bi_module_cnt > 0) {
+ bm = xbootp->bi_modules;
+ bsetprop64("ramdisk_start", (uint64_t)(uintptr_t)bm->bm_addr);
+ bsetprop64("ramdisk_end", (uint64_t)(uintptr_t)bm->bm_addr +
+ bm->bm_size);
+ }
+
+ DBG_MSG("Parsing command line for boot properties\n");
+ value = xbootp->bi_cmdline;
+
+ /*
+ * allocate memory to collect boot_args into
+ */
+ boot_arg_len = strlen(xbootp->bi_cmdline) + 1;
+ boot_args = do_bsys_alloc(NULL, NULL, boot_arg_len, MMU_PAGESIZE);
+ boot_args[0] = 0;
+ boot_arg_len = 0;
+
+ while (ISSPACE(*value))
+ ++value;
+ /*
+ * value now points at the boot-file
+ */
+ value_len = 0;
+ while (value[value_len] && !ISSPACE(value[value_len]))
+ ++value_len;
+ if (value_len > 0) {
+ whoami = propbuf;
+ bcopy(value, whoami, value_len);
+ whoami[value_len] = 0;
+ bsetprops("boot-file", whoami);
+ /*
+ * strip leading path stuff from whoami, so running from
+ * PXE/miniroot makes sense.
+ */
+ if (strstr(whoami, "/platform/") != NULL)
+ whoami = strstr(whoami, "/platform/");
+ bsetprops("whoami", whoami);
+ }
+
+ /*
+ * Values forcibly set boot propertiex on the command line via -B.
+ * Allow use of quotes in values. Other stuff goes on kernel
+ * command line.
+ */
+ name = value + value_len;
+ while (*name != 0) {
+ /*
+ * anything not " -B" is copied to the command line
+ */
+ if (!ISSPACE(name[0]) || name[1] != '-' || name[2] != 'B') {
+ boot_args[boot_arg_len++] = *name;
+ boot_args[boot_arg_len] = 0;
+ ++name;
+ continue;
+ }
+
+ /*
+ * skip the " -B" and following white space
+ */
+ name += 3;
+ while (ISSPACE(*name))
+ ++name;
+ while (*name && !ISSPACE(*name)) {
+ value = strstr(name, "=");
+ if (value == NULL)
+ break;
+ name_len = value - name;
+ ++value;
+ value_len = 0;
+ quoted = 0;
+ for (; ; ++value_len) {
+ if (!value[value_len])
+ break;
+
+ /*
+ * is this value quoted?
+ */
+ if (value_len == 0 &&
+ (value[0] == '\'' || value[0] == '"')) {
+ quoted = value[0];
+ ++value_len;
+ }
+
+ /*
+ * In the quote accept any character,
+ * but look for ending quote.
+ */
+ if (quoted) {
+ if (value[value_len] == quoted)
+ quoted = 0;
+ continue;
+ }
+
+ /*
+ * a comma or white space ends the value
+ */
+ if (value[value_len] == ',' ||
+ ISSPACE(value[value_len]))
+ break;
+ }
+
+ if (value_len == 0) {
+ bsetprop(name, name_len, "true", 5);
+ } else {
+ char *v = value;
+ int l = value_len;
+ if (v[0] == v[l - 1] &&
+ (v[0] == '\'' || v[0] == '"')) {
+ ++v;
+ l -= 2;
+ }
+ bcopy(v, propbuf, l);
+ propbuf[l] = '\0';
+ bsetprop(name, name_len, propbuf,
+ l + 1);
+ }
+ name = value + value_len;
+ while (*name == ',')
+ ++name;
+ }
+ }
+
+ /*
+ * set boot-args property
+ */
+ bsetprops("boot-args", boot_args);
+
+ /*
+ * set the BIOS boot device from GRUB
+ */
+ netboot = 0;
+ mbi = xbootp->bi_mb_info;
+ if (mbi != NULL && mbi->flags & 0x2) {
+ boot_device = mbi->boot_device >> 24;
+ if (boot_device == 0x20)
+ netboot++;
+ str[0] = (boot_device >> 4) + '0';
+ str[1] = (boot_device & 0xf) + '0';
+ str[2] = 0;
+ bsetprops("bios-boot-device", str);
+ } else {
+ netboot = 1;
+ }
+
+ /*
+ * In the netboot case, drives_info is overloaded with the dhcp ack.
+ * This is not multiboot compliant and requires special pxegrub!
+ */
+ if (netboot && mbi->drives_length != 0) {
+ sip = (struct sol_netinfo *)(uintptr_t)mbi->drives_addr;
+ if (sip->sn_infotype == SN_TYPE_BOOTP)
+ bsetprop("bootp-response", sizeof ("bootp-response"),
+ (void *)(uintptr_t)mbi->drives_addr,
+ mbi->drives_length);
+ else if (sip->sn_infotype == SN_TYPE_BOOTP)
+ setup_rarp_props(sip);
+ }
+ bsetprop("stdout", strlen("stdout"),
+ &stdout_val, sizeof (stdout_val));
+
+ /*
+ * more conjured up values for made up things....
+ */
+ bsetprops("mfg-name", "i86pc");
+ bsetprops("impl-arch-name", "i86pc");
+
+ /*
+ * Build firmware-provided system properties
+ */
+ build_firmware_properties();
+
+ /*
+ * Find out what these are:
+ * - cpuid_feature_ecx_include
+ * - cpuid_feature_ecx_exclude
+ * - cpuid_feature_edx_include
+ * - cpuid_feature_edx_exclude
+ *
+ * Find out what these are in multiboot:
+ * - bootp-response
+ * - netdev-path
+ * - fstype
+ */
+}
+
+/*
+ * Install a temporary IDT that lets us catch errors in the boot time code.
+ * We shouldn't get any faults at all while this is installed, so we'll
+ * just generate a traceback and exit.
+ */
+#ifdef __amd64
+static const int bcode_sel = B64CODE_SEL;
+#else
+static const int bcode_sel = B32CODE_SEL;
+#endif
+
+/*
+ * simple description of a stack frame (args are 32 bit only currently)
+ */
+typedef struct bop_frame {
+ struct bop_frame *old_frame;
+ pc_t retaddr;
+ long arg[1];
+} bop_frame_t;
+
+void
+bop_traceback(bop_frame_t *frame)
+{
+ pc_t pc;
+ int cnt;
+ int a;
+ char *ksym;
+ ulong_t off;
+
+ bop_printf(NULL, "Stack traceback:\n");
+ for (cnt = 0; cnt < 30; ++cnt) { /* up to 30 frames */
+ pc = frame->retaddr;
+ if (pc == 0)
+ break;
+ ksym = kobj_getsymname(pc, &off);
+ if (ksym)
+ bop_printf(NULL, " %s+%lx", ksym, off);
+ else
+ bop_printf(NULL, " 0x%lx", pc);
+
+ frame = frame->old_frame;
+ if (frame == 0) {
+ bop_printf(NULL, "\n");
+ break;
+ }
+ for (a = 0; a < 6; ++a) { /* try for 6 args */
+#if defined(__i386)
+ if ((void *)&frame->arg[a] == (void *)frame->old_frame)
+ break;
+ if (a == 0)
+ bop_printf(NULL, "(");
+ else
+ bop_printf(NULL, ",");
+ bop_printf(NULL, "0x%lx", frame->arg[a]);
+#endif
+ }
+ bop_printf(NULL, ")\n");
+ }
+}
+
+struct trapframe {
+ ulong_t frame_ptr; /* %[er]bp pushed by our code */
+ ulong_t error_code; /* optional */
+ ulong_t inst_ptr;
+ ulong_t code_seg;
+ ulong_t flags_reg;
+#ifdef __amd64
+ ulong_t stk_ptr;
+ ulong_t stk_seg;
+#endif
+};
+
+void
+bop_trap(struct trapframe *tf)
+{
+ bop_frame_t fakeframe;
+ static int depth = 0;
+
+ /*
+ * Check for an infinite loop of traps. Avoid bop_printf() here to
+ * reduce code path and further possibility of failure.
+ */
+ if (++depth > 2) {
+ PUT_STRING("Nested trap, calling reset()\n");
+ reset();
+ }
+
+ /*
+ * adjust the tf for optional error_code by detecting the code selector
+ */
+ if (tf->code_seg != bcode_sel)
+ tf = (struct trapframe *)((uintptr_t)tf - sizeof (ulong_t));
+
+ bop_printf(NULL, "Unexpected trap\n");
+ bop_printf(NULL, "instruction pointer 0x%lx\n", tf->inst_ptr);
+ bop_printf(NULL, "error code, optional 0x%lx\n",
+ tf->error_code & 0xffffffff);
+ bop_printf(NULL, "code segment 0x%lx\n", tf->code_seg & 0xffff);
+ bop_printf(NULL, "flags register 0x%lx\n", tf->flags_reg);
+#ifdef __amd64
+ bop_printf(NULL, "return %%rsp 0x%lx\n", tf->stk_ptr);
+ bop_printf(NULL, "return %%ss 0x%lx\n", tf->stk_seg & 0xffff);
+#endif
+ fakeframe.old_frame = (bop_frame_t *)tf->frame_ptr;
+ fakeframe.retaddr = (pc_t)tf->inst_ptr;
+ bop_printf(NULL, "Attempting stack backtrace:\n");
+ bop_traceback(&fakeframe);
+ bop_panic("unexpected trap in early boot");
+}
+
+extern void bop_trap_handler(void);
+
+static gate_desc_t bop_idt[NIDT];
+
+static desctbr_t bop_idt_info;
+
+static void
+bop_idt_init(void)
+{
+ int t;
+
+ bzero(&bop_idt, sizeof (bop_idt));
+ for (t = 0; t < NIDT; ++t) {
+ set_gatesegd(&bop_idt[t], &bop_trap_handler, bcode_sel,
+ SDT_SYSIGT, SEL_KPL);
+ }
+ bop_idt_info.dtr_limit = sizeof (bop_idt) - 1;
+ bop_idt_info.dtr_base = (uintptr_t)&bop_idt;
+ wr_idtr(&bop_idt_info);
+}
+
+/*
+ * This is where we enter the kernel. It dummies up the boot_ops and
+ * boot_syscalls vectors and jumps off to _kobj_boot()
+ */
+void
+_start(struct xboot_info *xbp)
+{
+ bootops_t *bops = &bootop;
+ extern void _kobj_boot();
+
+ /*
+ * 1st off - initialize the console for any error messages
+ */
+ xbootp = xbp;
+ bcons_init((void *)xbootp->bi_cmdline);
+ have_console = 1;
+
+ /*
+ * enable debugging
+ */
+ if (strstr((char *)xbootp->bi_cmdline, "kbm_debug"))
+ kbm_debug = 1;
+
+ DBG_MSG("\n\n*** Entered Solaris in _start() cmdline is: ");
+ DBG_MSG((char *)xbootp->bi_cmdline);
+ DBG_MSG("\n\n\n");
+
+ /*
+ * Install an IDT to catch early pagefaults (shouldn't have any).
+ * Also needed for kmdb.
+ */
+ bop_idt_init();
+
+ /*
+ * only physinstalled is still used by startup.
+ */
+ bm.physinstalled = xbp->bi_phys_install;
+ bm.physavail = NULL;
+
+ /*
+ * initialize the boot time allocator
+ */
+ next_phys = xbootp->bi_next_paddr;
+ DBG(next_phys);
+ next_virt = (uintptr_t)xbootp->bi_next_vaddr;
+ DBG(next_virt);
+ DBG_MSG("Initializing boot time memory management...");
+ kbm_init(xbootp);
+ DBG_MSG("done\n");
+
+ /*
+ * Fill in the bootops vector
+ */
+ bops->bsys_version = BO_VERSION;
+ bops->boot_mem = &bm;
+ bops->bsys_alloc = do_bsys_alloc;
+ bops->bsys_free = do_bsys_free;
+ bops->bsys_getproplen = do_bsys_getproplen;
+ bops->bsys_getprop = do_bsys_getprop;
+ bops->bsys_nextprop = do_bsys_nextprop;
+ bops->bsys_printf = bop_printf;
+ bops->bsys_doint = do_bsys_doint;
+
+ /*
+ * BOP_EALLOC() is no longer needed
+ */
+ bops->bsys_ealloc = do_bsys_ealloc;
+
+ /*
+ *
+ */
+ DBG_MSG("Initializing boot properties:\n");
+ build_boot_properties();
+
+ if (strstr((char *)xbootp->bi_cmdline, "prom_debug") || kbm_debug) {
+ char *name;
+ char *value;
+ int len;
+
+ value = do_bsys_alloc(NULL, NULL, MMU_PAGESIZE, MMU_PAGESIZE);
+ bop_printf(NULL, "\nBoot properties:\n");
+ name = "";
+ while ((name = do_bsys_nextprop(NULL, name)) != NULL) {
+ bop_printf(NULL, "\t0x%p %s = ", (void *)name, name);
+ (void) do_bsys_getprop(NULL, name, value);
+ len = do_bsys_getproplen(NULL, name);
+ bop_printf(NULL, "len=%d ", len);
+ value[len] = 0;
+ bop_printf(NULL, "%s\n", value);
+ }
+ }
+
+ /*
+ * jump into krtld...
+ */
+ _kobj_boot(&bop_sysp, NULL, bops, NULL);
+}
+
+
+/*ARGSUSED*/
+static caddr_t
+no_more_alloc(bootops_t *bop, caddr_t virthint, size_t size, int align)
+{
+ panic("Attempt to bsys_alloc() too late\n");
+ return (NULL);
+}
+
+/*ARGSUSED*/
+static void
+no_more_free(bootops_t *bop, caddr_t virt, size_t size)
+{
+ panic("Attempt to bsys_free() too late\n");
+}
+
+void
+bop_no_more_mem(void)
+{
+ DBG(total_bop_alloc_scratch);
+ DBG(total_bop_alloc_kernel);
+ bootops->bsys_alloc = no_more_alloc;
+ bootops->bsys_free = no_more_free;
+}
+
+
+/*
+ * Set ACPI firmware properties
+ */
+
+static caddr_t
+vmap_phys(size_t length, paddr_t pa)
+{
+ paddr_t start, end;
+ caddr_t va;
+ size_t len, page;
+
+ start = P2ALIGN(pa, MMU_PAGESIZE);
+ end = P2ROUNDUP(pa + length, MMU_PAGESIZE);
+ len = end - start;
+ va = (caddr_t)alloc_vaddr(len, MMU_PAGESIZE);
+ for (page = 0; page < len; page += MMU_PAGESIZE)
+ kbm_map((uintptr_t)va + page, start + page, 0, 0);
+ return (va + (pa & MMU_PAGEOFFSET));
+}
+
+static uint8_t
+checksum_table(uint8_t *tp, size_t len)
+{
+ uint8_t sum = 0;
+
+ while (len-- > 0)
+ sum += *tp++;
+
+ return (sum);
+}
+
+static int
+valid_rsdp(struct rsdp *rp)
+{
+
+ /* validate the V1.x checksum */
+ if (checksum_table((uint8_t *)&rp->v1, sizeof (struct rsdp_v1)) != 0)
+ return (0);
+
+ /* If pre-ACPI 2.0, this is a valid RSDP */
+ if (rp->v1.revision < 2)
+ return (1);
+
+ /* validate the V2.x checksum */
+ if (checksum_table((uint8_t *)rp, sizeof (struct rsdp)) != 0)
+ return (0);
+
+ return (1);
+}
+
+/*
+ * Scan memory range for an RSDP;
+ * see ACPI 3.0 Spec, 5.2.5.1
+ */
+static struct rsdp *
+scan_rsdp(paddr_t start, paddr_t end)
+{
+ size_t len = end - start + 1;
+ caddr_t ptr;
+
+ ptr = vmap_phys(len, start);
+ while (len > 0) {
+ if (strncmp(ptr, ACPI_RSDP_SIG, ACPI_RSDP_SIG_LEN) == 0)
+ if (valid_rsdp((struct rsdp *)ptr))
+ return ((struct rsdp *)ptr);
+ ptr += 16;
+ len -= 16;
+ }
+
+ return (NULL);
+}
+
+/*
+ * Refer to ACPI 3.0 Spec, section 5.2.5.1 to understand this function
+ */
+static struct rsdp *
+find_rsdp() {
+ struct rsdp *rsdp;
+ uint16_t *ebda_seg;
+ paddr_t ebda_addr;
+
+ /*
+ * Get the EBDA segment and scan the first 1K
+ */
+ ebda_seg = (uint16_t *)vmap_phys(sizeof (uint16_t), ACPI_EBDA_SEG_ADDR);
+ ebda_addr = *ebda_seg << 4;
+ rsdp = scan_rsdp(ebda_addr, ebda_addr + ACPI_EBDA_LEN - 1);
+ if (rsdp == NULL)
+ /* if EBDA doesn't contain RSDP, look in BIOS memory */
+ rsdp = scan_rsdp(0xe0000, 0xfffff);
+ return (rsdp);
+}
+
+static struct table_header *
+map_fw_table(paddr_t table_addr)
+{
+ struct table_header *tp;
+ size_t len = MAX(sizeof (struct table_header), MMU_PAGESIZE);
+
+ /*
+ * Map at least a page; if the table is larger than this, remap it
+ */
+ tp = (struct table_header *)vmap_phys(len, table_addr);
+ if (tp->len > len)
+ tp = (struct table_header *)vmap_phys(tp->len, table_addr);
+ return (tp);
+}
+
+static struct table_header *
+find_fw_table(char *signature)
+{
+ static int revision = 0;
+ static struct xsdt *xsdt;
+ static int len;
+ paddr_t xsdt_addr;
+ struct rsdp *rsdp;
+ struct table_header *tp;
+ paddr_t table_addr;
+ int n;
+
+ if (strlen(signature) != ACPI_TABLE_SIG_LEN)
+ return (NULL);
+
+ /*
+ * Reading the ACPI 3.0 Spec, section 5.2.5.3 will help
+ * understand this code. If we haven't already found the RSDT/XSDT,
+ * revision will be 0. Find the RSDP and check the revision
+ * to find out whether to use the RSDT or XSDT. If revision is
+ * 0 or 1, use the RSDT and set internal revision to 1; if it is 2,
+ * use the XSDT. If the XSDT address is 0, though, fall back to
+ * revision 1 and use the RSDT.
+ */
+ if (revision == 0) {
+ if ((rsdp = (struct rsdp *)find_rsdp()) != NULL) {
+ revision = rsdp->v1.revision;
+ switch (revision) {
+ case 2:
+ /*
+ * Use the XSDT unless BIOS is buggy and
+ * claims to be rev 2 but has a null XSDT
+ * address
+ */
+ xsdt_addr = rsdp->xsdt;
+ if (xsdt_addr != 0)
+ break;
+ /* FALLTHROUGH */
+ case 0:
+ /* treat RSDP rev 0 as revision 1 internally */
+ revision = 1;
+ /* FALLTHROUGH */
+ case 1:
+ /* use the RSDT for rev 0/1 */
+ xsdt_addr = rsdp->v1.rsdt;
+ break;
+ default:
+ /* unknown revision */
+ revision = 0;
+ break;
+ }
+ }
+ if (revision == 0)
+ return (NULL);
+
+ /* cache the XSDT info */
+ xsdt = (struct xsdt *)map_fw_table(xsdt_addr);
+ len = (xsdt->hdr.len - sizeof (xsdt->hdr)) /
+ ((revision == 1) ? sizeof (uint32_t) : sizeof (uint64_t));
+ }
+
+ /*
+ * Scan the table headers looking for a signature match
+ */
+ for (n = 0; n < len; n++) {
+ table_addr = (revision == 1) ? xsdt->p.r[n] : xsdt->p.x[n];
+ if (table_addr == 0)
+ continue;
+ tp = map_fw_table(table_addr);
+ if (strncmp(tp->sig, signature, ACPI_TABLE_SIG_LEN) == 0) {
+ return (tp);
+ }
+ }
+ return (NULL);
+}
+
+static void
+process_madt(struct madt *tp)
+{
+ struct madt_processor *cpu, *end;
+ uint32_t cpu_count = 0;
+
+ /*
+ * User-set boot-ncpus overrides firmware count
+ */
+ if (do_bsys_getproplen(NULL, "boot-ncpus") >= 0)
+ return;
+
+ if (tp != NULL) {
+ end = (struct madt_processor *)(tp->hdr.len + (uintptr_t)tp);
+ cpu = tp->list;
+ while (cpu < end) {
+ if (cpu->type == MADT_PROCESSOR)
+ if (cpu->flags & 1)
+ cpu_count++;
+
+ cpu = (struct madt_processor *)
+ (cpu->len + (uintptr_t)cpu);
+ }
+ bsetpropsi("boot-ncpus", cpu_count);
+ }
+
+}
+
+static void
+process_srat(struct srat *tp)
+{
+ struct srat_item *item, *end;
+ int i;
+ int proc_num, mem_num;
+#pragma pack(1)
+ struct {
+ uint32_t domain;
+ uint32_t apic_id;
+ uint32_t sapic_id;
+ } processor;
+ struct {
+ uint32_t domain;
+ uint64_t addr;
+ uint64_t length;
+ uint32_t flags;
+ } memory;
+#pragma pack()
+ char prop_name[30];
+
+ if (tp == NULL)
+ return;
+
+ proc_num = mem_num = 0;
+ end = (struct srat_item *)(tp->hdr.len + (uintptr_t)tp);
+ item = tp->list;
+ while (item < end) {
+ switch (item->type) {
+ case SRAT_PROCESSOR:
+ if (!(item->i.p.flags & SRAT_ENABLED))
+ break;
+ processor.domain = item->i.p.domain1;
+ for (i = 0; i < 3; i++)
+ processor.domain +=
+ item->i.p.domain2[i] << ((i + 1) * 8);
+ processor.apic_id = item->i.p.apic_id;
+ processor.sapic_id = item->i.p.local_sapic_eid;
+ (void) snprintf(prop_name, 30, "acpi-srat-processor-%d",
+ proc_num);
+ bsetprop(prop_name, strlen(prop_name), &processor,
+ sizeof (processor));
+ proc_num++;
+ break;
+ case SRAT_MEMORY:
+ if (!(item->i.m.flags & SRAT_ENABLED))
+ break;
+ memory.domain = item->i.m.domain;
+ memory.addr = item->i.m.base_addr;
+ memory.length = item->i.m.len;
+ memory.flags = item->i.m.flags;
+ (void) snprintf(prop_name, 30, "acpi-srat-memory-%d",
+ mem_num);
+ bsetprop(prop_name, strlen(prop_name), &memory,
+ sizeof (memory));
+ mem_num++;
+ break;
+ }
+
+ item = (struct srat_item *)
+ (item->len + (caddr_t)item);
+ }
+}
+
+static void
+build_firmware_properties(void)
+{
+ struct table_header *tp;
+
+ if (tp = find_fw_table("APIC"))
+ process_madt((struct madt *)tp);
+
+ if (tp = find_fw_table("SRAT"))
+ process_srat((struct srat *)tp);
+}
+
+/*
+ * fake up a boot property for USB serial console early boot output
+ */
+void *
+usbser_init(size_t size)
+{
+ static char *p = NULL;
+
+ p = do_bsys_alloc(NULL, NULL, size, MMU_PAGESIZE);
+ *p = 0;
+ bsetprop("usb-serial-buf", strlen("usb-serial-buf") + 1,
+ &p, sizeof (p));
+ return (p);
+}
diff --git a/usr/src/uts/i86pc/os/fpu_subr.c b/usr/src/uts/i86pc/os/fpu_subr.c
new file mode 100644
index 0000000000..dee40885e7
--- /dev/null
+++ b/usr/src/uts/i86pc/os/fpu_subr.c
@@ -0,0 +1,193 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Floating point configuration.
+ */
+
+#include <sys/types.h>
+#include <sys/regset.h>
+#include <sys/privregs.h>
+#include <sys/x86_archext.h>
+#include <sys/archsystm.h>
+#include <sys/fp.h>
+#include <sys/cmn_err.h>
+
+#define XMM_ALIGN 16
+
+/*
+ * If fpu_exists is non-zero, fpu_probe will attempt to use any
+ * hardware FPU (subject to other constraints, see below). If
+ * fpu_exists is zero, fpu_probe will report that there is no
+ * FPU even if there is one.
+ */
+int fpu_exists = 1;
+
+int fp_kind = FP_387;
+
+/*
+ * The variable fpu_ignored is provided to allow other code to
+ * determine whether emulation is being done because there is
+ * no FPU or because of an override requested via /etc/system.
+ */
+int fpu_ignored = 0;
+
+/*
+ * Used by ppcopy and ppzero to determine whether or not to use the
+ * SSE-based pagecopy and pagezero routines
+ */
+int use_sse_pagecopy = 0;
+int use_sse_pagezero = 0;
+int use_sse_copy = 0;
+
+#if defined(__i386)
+
+/*
+ * The variable fpu_pentium_fdivbug is provided to allow other code to
+ * determine whether the system contains a Pentium with the FDIV problem.
+ */
+int fpu_pentium_fdivbug = 0;
+
+#endif
+
+
+#define ENABLE_SSE() setcr4(CR4_ENABLE_SSE_FLAGS(getcr4()))
+#define DISABLE_SSE() setcr4(CR4_DISABLE_SSE_FLAGS(getcr4()))
+
+/*
+ * Try and figure out what kind of FP capabilities we have, and
+ * set up the control registers accordingly.
+ */
+void
+fpu_probe(void)
+{
+ do {
+ if (fpu_initial_probe() != 0)
+ continue;
+
+ if (fpu_exists == 0) {
+ fpu_ignored = 1;
+ continue;
+ }
+
+#if defined(__i386)
+ fpu_pentium_fdivbug = fpu_probe_pentium_fdivbug();
+ /*
+ * The test does some real floating point operations.
+ * Reset it back to previous state.
+ */
+ (void) fpu_initial_probe();
+
+ if (fpu_pentium_fdivbug != 0) {
+ fpu_ignored = 1;
+ continue;
+ }
+#endif
+
+ /*
+ * Check and see if the fpu is present by looking
+ * at the "extension type" bit. (While this used to
+ * indicate a 387DX coprocessor in days gone by,
+ * it's forced on by modern implementations for
+ * compatibility.)
+ */
+ if ((getcr0() & CR0_ET) == 0)
+ continue;
+
+#if defined(__amd64)
+ /*
+ * SSE and SSE2 are required for the 64-bit ABI.
+ *
+ * If they're not present, we can in principal run
+ * 32-bit userland, though 64-bit processes will be hosed.
+ *
+ * (Perhaps we should complain more about this case!)
+ */
+ if ((x86_feature & X86_SSE|X86_SSE2) == (X86_SSE|X86_SSE2)) {
+ fp_kind = __FP_SSE;
+ ENABLE_SSE();
+ }
+#elif defined(__i386)
+ /*
+ * SSE and SSE2 are both optional, and we patch kernel
+ * code to exploit it when present.
+ */
+ if (x86_feature & X86_SSE) {
+ fp_kind = __FP_SSE;
+ fpsave_ctxt = fpxsave_ctxt;
+ patch_sse();
+ if (x86_feature & X86_SSE2)
+ patch_sse2();
+ ENABLE_SSE();
+ } else {
+ x86_feature &= ~X86_SSE2;
+ /*
+ * (Just in case the BIOS decided we wanted SSE
+ * enabled when we didn't. See 4965674.)
+ */
+ DISABLE_SSE();
+ }
+#endif
+ if (x86_feature & X86_SSE2) {
+ use_sse_pagecopy = use_sse_pagezero = use_sse_copy = 1;
+ }
+
+ if (fp_kind == __FP_SSE) {
+ struct fxsave_state *fx;
+ uint8_t fxsave_state[sizeof (struct fxsave_state) +
+ XMM_ALIGN];
+
+ /*
+ * Extract the mxcsr mask from our first fxsave
+ */
+ fx = (void *)(((uintptr_t)(&fxsave_state[0]) +
+ XMM_ALIGN) & ~(XMM_ALIGN - 1ul));
+
+ fx->fx_mxcsr_mask = 0;
+ fxsave_insn(fx);
+ if (fx->fx_mxcsr_mask != 0) {
+ /*
+ * Override default mask initialized in fpu.c
+ */
+ sse_mxcsr_mask = fx->fx_mxcsr_mask;
+ }
+ }
+
+ setcr0(CR0_ENABLE_FPU_FLAGS(getcr0()));
+ return;
+ /*CONSTANTCONDITION*/
+ } while (0);
+
+ /*
+ * No FPU hardware present
+ */
+ setcr0(CR0_DISABLE_FPU_FLAGS(getcr0()));
+ DISABLE_SSE();
+ fp_kind = FP_NO;
+ fpu_exists = 0;
+}
diff --git a/usr/src/uts/i86pc/os/hold_page.c b/usr/src/uts/i86pc/os/hold_page.c
new file mode 100644
index 0000000000..1c11bc80f1
--- /dev/null
+++ b/usr/src/uts/i86pc/os/hold_page.c
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/hold_page.h>
+
+/*ARGSUSED*/
+int
+plat_hold_page(pfn_t pfn, int lock, page_t **pp_ret)
+{
+ return (PLAT_HOLD_OK);
+}
+
+/*ARGSUSED*/
+void
+plat_release_page(page_t *pp)
+{
+}
diff --git a/usr/src/uts/i86pc/os/intr.c b/usr/src/uts/i86pc/os/intr.c
index 30352a3908..598d608f1a 100644
--- a/usr/src/uts/i86pc/os/intr.c
+++ b/usr/src/uts/i86pc/os/intr.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,49 +48,23 @@
#include <sys/pool_pset.h>
#include <sys/zone.h>
#include <sys/bitmap.h>
+#include <sys/archsystm.h>
+#include <sys/machsystm.h>
+#include <sys/ontrap.h>
+#include <sys/x86_archext.h>
+#include <sys/promif.h>
-#if defined(__amd64)
-#if defined(__lint)
/*
- * atomic_btr32() is a gcc __inline__ function, defined in <asm/bitmap.h>
- * For lint purposes, define it here.
+ * Set cpu's base SPL level to the highest active interrupt level
*/
-uint_t
-atomic_btr32(uint32_t *pending, uint_t pil)
-{
- return (*pending &= ~(1 << pil));
-}
-#else
-
-extern uint_t atomic_btr32(uint32_t *pending, uint_t pil);
-
-#endif
-
-/*
- * This code is amd64-only for now, but as time permits, we should
- * use this on i386 too.
- */
-
-/*
- * Some questions to ponder:
- * - in several of these routines, we make multiple calls to tsc_read()
- * without invoking functions .. couldn't we just reuse the same
- * timestamp sometimes?
- * - if we have the inline, we can probably make set_base_spl be a
- * C routine too.
- */
-
-static uint_t
-bsrw_insn(uint16_t mask)
+void
+set_base_spl(void)
{
- uint_t index = sizeof (mask) * NBBY - 1;
+ struct cpu *cpu = CPU;
+ uint16_t active = (uint16_t)cpu->cpu_intr_actv;
- ASSERT(mask != 0);
-
- while ((mask & (1 << index)) == 0)
- index--;
- return (index);
+ cpu->cpu_base_spl = active == 0 ? 0 : bsrw_insn(active);
}
/*
@@ -103,12 +77,13 @@ bsrw_insn(uint16_t mask)
* Called with interrupts masked.
* The 'pil' is already set to the appropriate level for rp->r_trapno.
*/
-int
+static int
hilevel_intr_prolog(struct cpu *cpu, uint_t pil, uint_t oldpil, struct regs *rp)
{
struct machcpu *mcpu = &cpu->cpu_m;
uint_t mask;
hrtime_t intrtime;
+ hrtime_t now = tsc_read();
ASSERT(pil > LOCK_LEVEL);
@@ -134,7 +109,7 @@ hilevel_intr_prolog(struct cpu *cpu, uint_t pil, uint_t oldpil, struct regs *rp)
*/
nestpil = bsrw_insn((uint16_t)mask);
ASSERT(nestpil < pil);
- intrtime = tsc_read() -
+ intrtime = now -
mcpu->pil_high_start[nestpil - (LOCK_LEVEL + 1)];
mcpu->intrstat[nestpil][0] += intrtime;
cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;
@@ -153,7 +128,7 @@ hilevel_intr_prolog(struct cpu *cpu, uint_t pil, uint_t oldpil, struct regs *rp)
* is non-zero.
*/
if ((t->t_flag & T_INTR_THREAD) != 0 && t->t_intr_start != 0) {
- intrtime = tsc_read() - t->t_intr_start;
+ intrtime = now - t->t_intr_start;
mcpu->intrstat[t->t_pil][0] += intrtime;
cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;
t->t_intr_start = 0;
@@ -163,7 +138,7 @@ hilevel_intr_prolog(struct cpu *cpu, uint_t pil, uint_t oldpil, struct regs *rp)
/*
* Store starting timestamp in CPU structure for this PIL.
*/
- mcpu->pil_high_start[pil - (LOCK_LEVEL + 1)] = tsc_read();
+ mcpu->pil_high_start[pil - (LOCK_LEVEL + 1)] = now;
ASSERT((cpu->cpu_intr_actv & (1 << pil)) == 0);
@@ -194,12 +169,13 @@ hilevel_intr_prolog(struct cpu *cpu, uint_t pil, uint_t oldpil, struct regs *rp)
*
* Called with interrupts masked
*/
-int
+static int
hilevel_intr_epilog(struct cpu *cpu, uint_t pil, uint_t oldpil, uint_t vecnum)
{
struct machcpu *mcpu = &cpu->cpu_m;
uint_t mask;
hrtime_t intrtime;
+ hrtime_t now = tsc_read();
ASSERT(mcpu->mcpu_pri == pil);
@@ -226,7 +202,7 @@ hilevel_intr_epilog(struct cpu *cpu, uint_t pil, uint_t oldpil, uint_t vecnum)
ASSERT(mcpu->pil_high_start[pil - (LOCK_LEVEL + 1)] != 0);
- intrtime = tsc_read() - mcpu->pil_high_start[pil - (LOCK_LEVEL + 1)];
+ intrtime = now - mcpu->pil_high_start[pil - (LOCK_LEVEL + 1)];
mcpu->intrstat[pil][0] += intrtime;
cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;
@@ -244,7 +220,7 @@ hilevel_intr_epilog(struct cpu *cpu, uint_t pil, uint_t oldpil, uint_t vecnum)
*/
nestpil = bsrw_insn((uint16_t)mask);
ASSERT(nestpil < pil);
- mcpu->pil_high_start[nestpil - (LOCK_LEVEL + 1)] = tsc_read();
+ mcpu->pil_high_start[nestpil - (LOCK_LEVEL + 1)] = now;
/*
* (Another high-level interrupt is active below this one,
* so there is no need to check for an interrupt
@@ -260,7 +236,7 @@ hilevel_intr_epilog(struct cpu *cpu, uint_t pil, uint_t oldpil, uint_t vecnum)
kthread_t *t = cpu->cpu_thread;
if (t->t_flag & T_INTR_THREAD)
- t->t_intr_start = tsc_read();
+ t->t_intr_start = now;
}
mcpu->mcpu_pri = oldpil;
@@ -274,11 +250,12 @@ hilevel_intr_epilog(struct cpu *cpu, uint_t pil, uint_t oldpil, uint_t vecnum)
* executing an interrupt thread. The new stack pointer of the
* interrupt thread (which *must* be switched to) is returned.
*/
-caddr_t
+static caddr_t
intr_thread_prolog(struct cpu *cpu, caddr_t stackptr, uint_t pil)
{
struct machcpu *mcpu = &cpu->cpu_m;
kthread_t *t, *volatile it;
+ hrtime_t now = tsc_read();
ASSERT(pil > 0);
ASSERT((cpu->cpu_intr_actv & (1 << pil)) == 0);
@@ -293,7 +270,7 @@ intr_thread_prolog(struct cpu *cpu, caddr_t stackptr, uint_t pil)
*/
t = cpu->cpu_thread;
if ((t->t_flag & T_INTR_THREAD) && t->t_intr_start != 0) {
- hrtime_t intrtime = tsc_read() - t->t_intr_start;
+ hrtime_t intrtime = now - t->t_intr_start;
mcpu->intrstat[t->t_pil][0] += intrtime;
cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;
t->t_intr_start = 0;
@@ -326,7 +303,7 @@ intr_thread_prolog(struct cpu *cpu, caddr_t stackptr, uint_t pil)
cpu->cpu_thread = it; /* new curthread on this cpu */
it->t_pil = (uchar_t)pil;
it->t_pri = intr_pri + (pri_t)pil;
- it->t_intr_start = tsc_read();
+ it->t_intr_start = now;
return (it->t_stk);
}
@@ -339,7 +316,7 @@ int intr_thread_cnt;
/*
* Called with interrupts disabled
*/
-void
+static void
intr_thread_epilog(struct cpu *cpu, uint_t vec, uint_t oldpil)
{
struct machcpu *mcpu = &cpu->cpu_m;
@@ -347,12 +324,13 @@ intr_thread_epilog(struct cpu *cpu, uint_t vec, uint_t oldpil)
kthread_t *it = cpu->cpu_thread; /* curthread */
uint_t pil, basespl;
hrtime_t intrtime;
+ hrtime_t now = tsc_read();
pil = it->t_pil;
cpu->cpu_stats.sys.intr[pil - 1]++;
ASSERT(it->t_intr_start != 0);
- intrtime = tsc_read() - it->t_intr_start;
+ intrtime = now - it->t_intr_start;
mcpu->intrstat[pil][0] += intrtime;
cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;
@@ -389,6 +367,7 @@ intr_thread_epilog(struct cpu *cpu, uint_t vec, uint_t oldpil)
mcpu->mcpu_pri = basespl;
(*setlvlx)(basespl, vec);
(void) splhigh();
+ sti();
it->t_state = TS_FREE;
/*
* Return interrupt thread to pool
@@ -396,6 +375,7 @@ intr_thread_epilog(struct cpu *cpu, uint_t vec, uint_t oldpil)
it->t_link = cpu->cpu_intr_thread;
cpu->cpu_intr_thread = it;
swtch();
+ panic("intr_thread_epilog: swtch returned");
/*NOTREACHED*/
}
@@ -410,23 +390,81 @@ intr_thread_epilog(struct cpu *cpu, uint_t vec, uint_t oldpil)
pil = MAX(oldpil, basespl);
mcpu->mcpu_pri = pil;
(*setlvlx)(pil, vec);
- t->t_intr_start = tsc_read();
+ t->t_intr_start = now;
cpu->cpu_thread = t;
}
/*
- * Called with interrupts disabled by an interrupt thread to determine
- * how much time has elapsed. See interrupt.s:intr_get_time() for detailed
- * theory of operation.
+ * intr_get_time() is a resource for interrupt handlers to determine how
+ * much time has been spent handling the current interrupt. Such a function
+ * is needed because higher level interrupts can arrive during the
+ * processing of an interrupt. intr_get_time() only returns time spent in the
+ * current interrupt handler.
+ *
+ * The caller must be calling from an interrupt handler running at a pil
+ * below or at lock level. Timings are not provided for high-level
+ * interrupts.
+ *
+ * The first time intr_get_time() is called while handling an interrupt,
+ * it returns the time since the interrupt handler was invoked. Subsequent
+ * calls will return the time since the prior call to intr_get_time(). Time
+ * is returned as ticks. Use tsc_scalehrtime() to convert ticks to nsec.
+ *
+ * Theory Of Intrstat[][]:
+ *
+ * uint64_t intrstat[pil][0..1] is an array indexed by pil level, with two
+ * uint64_ts per pil.
+ *
+ * intrstat[pil][0] is a cumulative count of the number of ticks spent
+ * handling all interrupts at the specified pil on this CPU. It is
+ * exported via kstats to the user.
+ *
+ * intrstat[pil][1] is always a count of ticks less than or equal to the
+ * value in [0]. The difference between [1] and [0] is the value returned
+ * by a call to intr_get_time(). At the start of interrupt processing,
+ * [0] and [1] will be equal (or nearly so). As the interrupt consumes
+ * time, [0] will increase, but [1] will remain the same. A call to
+ * intr_get_time() will return the difference, then update [1] to be the
+ * same as [0]. Future calls will return the time since the last call.
+ * Finally, when the interrupt completes, [1] is updated to the same as [0].
+ *
+ * Implementation:
+ *
+ * intr_get_time() works much like a higher level interrupt arriving. It
+ * "checkpoints" the timing information by incrementing intrstat[pil][0]
+ * to include elapsed running time, and by setting t_intr_start to rdtsc.
+ * It then sets the return value to intrstat[pil][0] - intrstat[pil][1],
+ * and updates intrstat[pil][1] to be the same as the new value of
+ * intrstat[pil][0].
+ *
+ * In the normal handling of interrupts, after an interrupt handler returns
+ * and the code in intr_thread() updates intrstat[pil][0], it then sets
+ * intrstat[pil][1] to the new value of intrstat[pil][0]. When [0] == [1],
+ * the timings are reset, i.e. intr_get_time() will return [0] - [1] which
+ * is 0.
+ *
+ * Whenever interrupts arrive on a CPU which is handling a lower pil
+ * interrupt, they update the lower pil's [0] to show time spent in the
+ * handler that they've interrupted. This results in a growing discrepancy
+ * between [0] and [1], which is returned the next time intr_get_time() is
+ * called. Time spent in the higher-pil interrupt will not be returned in
+ * the next intr_get_time() call from the original interrupt, because
+ * the higher-pil interrupt's time is accumulated in intrstat[higherpil][].
*/
uint64_t
-intr_thread_get_time(struct cpu *cpu)
+intr_get_time(void)
{
- struct machcpu *mcpu = &cpu->cpu_m;
- kthread_t *t = cpu->cpu_thread;
+ struct cpu *cpu;
+ struct machcpu *mcpu;
+ kthread_t *t;
uint64_t time, delta, ret;
- uint_t pil = t->t_pil;
+ uint_t pil;
+ cli();
+ cpu = CPU;
+ mcpu = &cpu->cpu_m;
+ t = cpu->cpu_thread;
+ pil = t->t_pil;
ASSERT((cpu->cpu_intr_actv & CPU_INTR_ACTV_HIGH_LEVEL_MASK) == 0);
ASSERT(t->t_flag & T_INTR_THREAD);
ASSERT(pil != 0);
@@ -442,10 +480,11 @@ intr_thread_get_time(struct cpu *cpu)
mcpu->intrstat[pil][1] = time;
cpu->cpu_intracct[cpu->cpu_mstate] += delta;
+ sti();
return (ret);
}
-caddr_t
+static caddr_t
dosoftint_prolog(
struct cpu *cpu,
caddr_t stackptr,
@@ -455,6 +494,7 @@ dosoftint_prolog(
kthread_t *t, *volatile it;
struct machcpu *mcpu = &cpu->cpu_m;
uint_t pil;
+ hrtime_t now;
top:
ASSERT(st_pending == mcpu->mcpu_softinfo.st_pending);
@@ -489,8 +529,8 @@ top:
* but at this point, correctness is critical, so we slavishly
* emulate the i386 port.
*/
- if (atomic_btr32((uint32_t *)&mcpu->mcpu_softinfo.st_pending, pil)
- == 0) {
+ if (atomic_btr32((uint32_t *)
+ &mcpu->mcpu_softinfo.st_pending, pil) == 0) {
st_pending = mcpu->mcpu_softinfo.st_pending;
goto top;
}
@@ -498,6 +538,8 @@ top:
mcpu->mcpu_pri = pil;
(*setspl)(pil);
+ now = tsc_read();
+
/*
* Get set to run interrupt thread.
* There should always be an interrupt thread since we
@@ -509,7 +551,7 @@ top:
/* t_intr_start could be zero due to cpu_intr_swtch_enter. */
t = cpu->cpu_thread;
if ((t->t_flag & T_INTR_THREAD) && t->t_intr_start != 0) {
- hrtime_t intrtime = tsc_read() - t->t_intr_start;
+ hrtime_t intrtime = now - t->t_intr_start;
mcpu->intrstat[pil][0] += intrtime;
cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;
t->t_intr_start = 0;
@@ -548,18 +590,19 @@ top:
*/
it->t_pil = (uchar_t)pil;
it->t_pri = (pri_t)pil + intr_pri;
- it->t_intr_start = tsc_read();
+ it->t_intr_start = now;
return (it->t_stk);
}
-void
+static void
dosoftint_epilog(struct cpu *cpu, uint_t oldpil)
{
struct machcpu *mcpu = &cpu->cpu_m;
kthread_t *t, *it;
uint_t pil, basespl;
hrtime_t intrtime;
+ hrtime_t now = tsc_read();
it = cpu->cpu_thread;
pil = it->t_pil;
@@ -568,7 +611,7 @@ dosoftint_epilog(struct cpu *cpu, uint_t oldpil)
ASSERT(cpu->cpu_intr_actv & (1 << pil));
cpu->cpu_intr_actv &= ~(1 << pil);
- intrtime = tsc_read() - it->t_intr_start;
+ intrtime = now - it->t_intr_start;
mcpu->intrstat[pil][0] += intrtime;
cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;
@@ -587,21 +630,24 @@ dosoftint_epilog(struct cpu *cpu, uint_t oldpil)
it->t_link = cpu->cpu_intr_thread;
cpu->cpu_intr_thread = it;
(void) splhigh();
+ sti();
swtch();
/*NOTREACHED*/
+ panic("dosoftint_epilog: swtch returned");
}
it->t_link = cpu->cpu_intr_thread;
cpu->cpu_intr_thread = it;
it->t_state = TS_FREE;
cpu->cpu_thread = t;
if (t->t_flag & T_INTR_THREAD)
- t->t_intr_start = tsc_read();
+ t->t_intr_start = now;
basespl = cpu->cpu_base_spl;
pil = MAX(oldpil, basespl);
mcpu->mcpu_pri = pil;
(*setspl)(pil);
}
+
/*
* Make the interrupted thread 'to' be runnable.
*
@@ -624,8 +670,6 @@ intr_passivate(
return (it->t_pil);
}
-#endif /* __amd64 */
-
/*
* Create interrupt kstats for this CPU.
*/
@@ -758,3 +802,341 @@ cpu_intr_swtch_exit(kthread_id_t t)
ts = t->t_intr_start;
} while (cas64(&t->t_intr_start, ts, tsc_read()) != ts);
}
+
+/*
+ * Dispatch a hilevel interrupt (one above LOCK_LEVEL)
+ */
+/*ARGSUSED*/
+static void
+dispatch_hilevel(uint_t vector, uint_t arg2)
+{
+ sti();
+ av_dispatch_autovect(vector);
+ cli();
+}
+
+/*
+ * Dispatch a soft interrupt
+ */
+/*ARGSUSED*/
+static void
+dispatch_softint(uint_t oldpil, uint_t arg2)
+{
+ struct cpu *cpu = CPU;
+
+ sti();
+ av_dispatch_softvect((int)cpu->cpu_thread->t_pil);
+ cli();
+
+ /*
+ * Must run softint_epilog() on the interrupt thread stack, since
+ * there may not be a return from it if the interrupt thread blocked.
+ */
+ dosoftint_epilog(cpu, oldpil);
+}
+
+/*
+ * Dispatch a normal interrupt
+ */
+static void
+dispatch_hardint(uint_t vector, uint_t oldipl)
+{
+ struct cpu *cpu = CPU;
+
+ sti();
+ av_dispatch_autovect(vector);
+ cli();
+
+ /*
+ * Must run intr_thread_epilog() on the interrupt thread stack, since
+ * there may not be a return from it if the interrupt thread blocked.
+ */
+ intr_thread_epilog(cpu, vector, oldipl);
+}
+
+/*
+ * Deliver any softints the current interrupt priority allows.
+ * Called with interrupts disabled.
+ */
+void
+dosoftint(struct regs *regs)
+{
+ struct cpu *cpu = CPU;
+ int oldipl;
+ caddr_t newsp;
+
+ while (cpu->cpu_softinfo.st_pending) {
+ oldipl = cpu->cpu_pri;
+ newsp = dosoftint_prolog(cpu, (caddr_t)regs,
+ cpu->cpu_softinfo.st_pending, oldipl);
+ /*
+ * If returned stack pointer is NULL, priority is too high
+ * to run any of the pending softints now.
+ * Break out and they will be run later.
+ */
+ if (newsp == NULL)
+ break;
+ switch_sp_and_call(newsp, dispatch_softint, oldipl, 0);
+ }
+}
+
+/*
+ * Interrupt service routine, called with interrupts disabled.
+ */
+/*ARGSUSED*/
+void
+do_interrupt(struct regs *rp, trap_trace_rec_t *ttp)
+{
+ struct cpu *cpu = CPU;
+ int newipl, oldipl = cpu->cpu_pri;
+ uint_t vector;
+ caddr_t newsp;
+
+#ifdef TRAPTRACE
+ ttp->ttr_marker = TT_INTERRUPT;
+ ttp->ttr_ipl = 0xff;
+ ttp->ttr_pri = oldipl;
+ ttp->ttr_spl = cpu->cpu_base_spl;
+ ttp->ttr_vector = 0xff;
+#endif /* TRAPTRACE */
+
+ /*
+ * If it's a softint go do it now.
+ */
+ if (rp->r_trapno == T_SOFTINT) {
+ dosoftint(rp);
+ ASSERT(!interrupts_enabled());
+ return;
+ }
+
+ /*
+ * Raise the interrupt priority.
+ */
+ newipl = (*setlvl)(oldipl, (int *)&rp->r_trapno);
+#ifdef TRAPTRACE
+ ttp->ttr_ipl = newipl;
+#endif /* TRAPTRACE */
+
+ /*
+ * Bail if it is a spurious interrupt
+ */
+ if (newipl == -1)
+ return;
+ cpu->cpu_pri = newipl;
+ vector = rp->r_trapno;
+#ifdef TRAPTRACE
+ ttp->ttr_vector = vector;
+#endif /* TRAPTRACE */
+ if (newipl > LOCK_LEVEL) {
+ /*
+ * High priority interrupts run on this cpu's interrupt stack.
+ */
+ if (hilevel_intr_prolog(cpu, newipl, oldipl, rp) == 0) {
+ newsp = cpu->cpu_intr_stack;
+ switch_sp_and_call(newsp, dispatch_hilevel, vector, 0);
+ } else { /* already on the interrupt stack */
+ dispatch_hilevel(vector, 0);
+ }
+ (void) hilevel_intr_epilog(cpu, newipl, oldipl, vector);
+ } else {
+ /*
+ * Run this interrupt in a separate thread.
+ */
+ newsp = intr_thread_prolog(cpu, (caddr_t)rp, newipl);
+ switch_sp_and_call(newsp, dispatch_hardint, vector, oldipl);
+ }
+
+ /*
+ * Deliver any pending soft interrupts.
+ */
+ if (cpu->cpu_softinfo.st_pending)
+ dosoftint(rp);
+}
+
+/*
+ * Common tasks always done by _sys_rtt, called with interrupts disabled.
+ * Returns 1 if returning to userland, 0 if returning to system mode.
+ */
+int
+sys_rtt_common(struct regs *rp)
+{
+ kthread_t *tp;
+ extern void mutex_exit_critical_start();
+ extern long mutex_exit_critical_size;
+
+loop:
+
+ /*
+ * Check if returning to user
+ */
+ tp = CPU->cpu_thread;
+ if (USERMODE(rp->r_cs)) {
+ /*
+ * Check if AST pending.
+ */
+ if (tp->t_astflag) {
+ /*
+ * Let trap() handle the AST
+ */
+ sti();
+ rp->r_trapno = T_AST;
+ trap(rp, (caddr_t)0, CPU->cpu_id);
+ cli();
+ goto loop;
+ }
+
+#if defined(__amd64)
+ /*
+ * We are done if segment registers do not need updating.
+ */
+ if ((tp->t_lwp->lwp_pcb.pcb_flags & RUPDATE_PENDING) == 0)
+ return (1);
+
+ if (update_sregs(rp, tp->t_lwp)) {
+ /*
+ * 1 or more of the selectors is bad.
+ * Deliver a SIGSEGV.
+ */
+ proc_t *p = ttoproc(tp);
+
+ sti();
+ mutex_enter(&p->p_lock);
+ tp->t_lwp->lwp_cursig = SIGSEGV;
+ mutex_exit(&p->p_lock);
+ psig();
+ tp->t_sig_check = 1;
+ cli();
+ }
+ tp->t_lwp->lwp_pcb.pcb_flags &= ~RUPDATE_PENDING;
+
+#endif /* __amd64 */
+ return (1);
+ }
+
+ /*
+ * Here if we are returning to supervisor mode.
+ * Check for a kernel preemption request.
+ */
+ if (CPU->cpu_kprunrun && (rp->r_ps & PS_IE)) {
+
+ /*
+ * Do nothing if already in kpreempt
+ */
+ if (!tp->t_preempt_lk) {
+ tp->t_preempt_lk = 1;
+ sti();
+ kpreempt(1); /* asynchronous kpreempt call */
+ cli();
+ tp->t_preempt_lk = 0;
+ }
+ }
+
+ /*
+ * If we interrupted the mutex_exit() critical region we must
+ * reset the PC back to the beginning to prevent missed wakeups
+ * See the comments in mutex_exit() for details.
+ */
+ if ((uintptr_t)rp->r_pc - (uintptr_t)mutex_exit_critical_start <
+ mutex_exit_critical_size) {
+ rp->r_pc = (greg_t)mutex_exit_critical_start;
+ }
+ return (0);
+}
+
+void
+send_dirint(int cpuid, int int_level)
+{
+ (*send_dirintf)(cpuid, int_level);
+}
+
+/*
+ * do_splx routine, takes new ipl to set
+ * returns the old ipl.
+ * We are careful not to set priority lower than CPU->cpu_base_pri,
+ * even though it seems we're raising the priority, it could be set
+ * higher at any time by an interrupt routine, so we must block interrupts
+ * and look at CPU->cpu_base_pri
+ */
+int
+do_splx(int newpri)
+{
+ ulong_t flag;
+ cpu_t *cpu;
+ int curpri, basepri;
+
+ flag = intr_clear();
+ cpu = CPU; /* ints are disabled, now safe to cache cpu ptr */
+ curpri = cpu->cpu_m.mcpu_pri;
+ basepri = cpu->cpu_base_spl;
+ if (newpri < basepri)
+ newpri = basepri;
+ cpu->cpu_m.mcpu_pri = newpri;
+ (*setspl)(newpri);
+ /*
+ * If we are going to reenable interrupts see if new priority level
+ * allows pending softint delivery.
+ */
+ if ((flag & PS_IE) &&
+ bsrw_insn((uint16_t)cpu->cpu_softinfo.st_pending) > newpri)
+ fakesoftint();
+ ASSERT(!interrupts_enabled());
+ intr_restore(flag);
+ return (curpri);
+}
+
+/*
+ * Common spl raise routine, takes new ipl to set
+ * returns the old ipl, will not lower ipl.
+ */
+int
+splr(int newpri)
+{
+ ulong_t flag;
+ cpu_t *cpu;
+ int curpri, basepri;
+
+ flag = intr_clear();
+ cpu = CPU; /* ints are disabled, now safe to cache cpu ptr */
+ curpri = cpu->cpu_m.mcpu_pri;
+ /*
+ * Only do something if new priority is larger
+ */
+ if (newpri > curpri) {
+ basepri = cpu->cpu_base_spl;
+ if (newpri < basepri)
+ newpri = basepri;
+ cpu->cpu_m.mcpu_pri = newpri;
+ (*setspl)(newpri);
+ /*
+ * See if new priority level allows pending softint delivery
+ */
+ if ((flag & PS_IE) &&
+ bsrw_insn((uint16_t)cpu->cpu_softinfo.st_pending) > newpri)
+ fakesoftint();
+ }
+ intr_restore(flag);
+ return (curpri);
+}
+
+int
+getpil(void)
+{
+ return (CPU->cpu_m.mcpu_pri);
+}
+
+int
+interrupts_enabled(void)
+{
+ ulong_t flag;
+
+ flag = getflags();
+ return ((flag & PS_IE) == PS_IE);
+}
+
+#ifdef DEBUG
+void
+assert_ints_enabled(void)
+{
+ ASSERT(!interrupts_unleashed || interrupts_enabled());
+}
+#endif /* DEBUG */
diff --git a/usr/src/uts/i86pc/os/mach_kdi.c b/usr/src/uts/i86pc/os/mach_kdi.c
index c07ec41f92..ce8255cdd8 100644
--- a/usr/src/uts/i86pc/os/mach_kdi.c
+++ b/usr/src/uts/i86pc/os/mach_kdi.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -40,173 +39,172 @@
#include <sys/smp_impldefs.h>
#include <sys/psm_types.h>
#include <sys/segments.h>
+#include <sys/archsystm.h>
+#include <sys/controlregs.h>
+#include <sys/trap.h>
+#include <sys/kobj.h>
+#include <sys/kobj_impl.h>
+#include <sys/mach_mmu.h>
-static void
-kdi_system_claim(void)
-{
- psm_notifyf(PSM_DEBUG_ENTER);
-}
-
-static void
-kdi_system_release(void)
-{
- psm_notifyf(PSM_DEBUG_EXIT);
-}
-
-static cpu_t *
-kdi_gdt2cpu(uintptr_t gdtbase)
+void
+kdi_idt_write(gate_desc_t *gate, uint_t vec)
{
- cpu_t *cp = cpu_list;
+ gate_desc_t *idt = CPU->cpu_m.mcpu_idt;
- if (cp == NULL)
- return (NULL);
+ /*
+ * See kdi_idtr_set().
+ */
+ if (idt == NULL) {
+ desctbr_t idtr;
+ rd_idtr(&idtr);
+ idt = (gate_desc_t *)idtr.dtr_base;
+ }
- do {
- if (gdtbase == (uintptr_t)cp->cpu_gdt)
- return (cp);
- } while ((cp = cp->cpu_next) != cpu_list);
+ idt[vec] = *gate;
+}
- return (NULL);
+ulong_t
+kdi_dreg_get(int reg)
+{
+ switch (reg) {
+ case 0:
+ return (kdi_getdr0());
+ case 1:
+ return (kdi_getdr1());
+ case 2:
+ return (kdi_getdr2());
+ case 3:
+ return (kdi_getdr3());
+ case 6:
+ return (kdi_getdr6());
+ case 7:
+ return (kdi_getdr7());
+ default:
+ panic("invalid debug register dr%d", reg);
+ /*NOTREACHED*/
+ }
}
-#if defined(__amd64)
-static uintptr_t
-kdi_gdt2gsbase(uintptr_t gdtbase)
-{
- return ((uintptr_t)kdi_gdt2cpu(gdtbase));
+void
+kdi_dreg_set(int reg, ulong_t value)
+{
+ switch (reg) {
+ case 0:
+ kdi_setdr0(value);
+ break;
+ case 1:
+ kdi_setdr1(value);
+ break;
+ case 2:
+ kdi_setdr2(value);
+ break;
+ case 3:
+ kdi_setdr3(value);
+ break;
+ case 6:
+ kdi_setdr6(value);
+ break;
+ case 7:
+ kdi_setdr7(value);
+ break;
+ default:
+ panic("invalid debug register dr%d", reg);
+ /*NOTREACHED*/
+ }
}
-#endif
-static void
-kdi_cpu_iter(void (*iter)(cpu_t *, uint_t), uint_t arg)
+void
+kdi_flush_caches(void)
{
- cpu_t *cp;
-
- mutex_enter(&cpu_lock);
+ reload_cr3();
+}
- cp = cpu_list;
- do {
- iter(cp, arg);
- } while ((cp = cp->cpu_next) != cpu_list);
+extern void kdi_slave_entry(void);
- mutex_exit(&cpu_lock);
+void
+kdi_stop_slaves(int cpu, int doxc)
+{
+ if (doxc)
+ kdi_xc_others(cpu, kdi_slave_entry);
}
-static gate_desc_t *
-curidt(void)
+/*
+ * On i86pc, slaves busy-loop, so we don't need to do anything here.
+ */
+void
+kdi_start_slaves(void)
{
- desctbr_t idtdesc;
- rd_idtr(&idtdesc);
- return ((gate_desc_t *)idtdesc.dtr_base);
}
-static void
-kdi_idt_init_gate(gate_desc_t *gate, void (*hdlr)(void), uint_t dpl,
- int useboot)
+void
+kdi_slave_wait(void)
{
- bzero(gate, sizeof (gate_desc_t));
+}
+
+/*
+ * Caution.
+ * These routines are called -extremely- early, during kmdb initialization.
+ *
+ * Many common kernel functions assume that %gs has been initialized,
+ * and fail horribly if it hasn't. At this point, the boot code has
+ * reserved a descriptor for us (KMDBGS_SEL) in it's GDT; arrange for it
+ * to point at a dummy cpu_t, temporarily at least.
+ *
+ * Note that kmdb entry relies on the fake cpu_t having zero cpu_idt/cpu_id.
+ */
#if defined(__amd64)
- set_gatesegd(gate, hdlr, (useboot ? B64CODE_SEL : KCS_SEL), 0,
- SDT_SYSIGT, dpl);
-#else
- set_gatesegd(gate, hdlr, (useboot ? BOOTCODE_SEL : KCS_SEL), 0,
- SDT_SYSIGT, dpl);
-#endif
-}
-static void
-kdi_idt_read(gate_desc_t *idt, gate_desc_t *gatep, uint_t vec)
+void *
+boot_kdi_tmpinit(void)
{
- if (idt == NULL)
- idt = curidt();
- *gatep = idt[vec];
-}
+ cpu_t *cpu = kobj_zalloc(sizeof (*cpu), KM_TMP);
+ uintptr_t old;
-static void
-kdi_idt_write(gate_desc_t *idt, gate_desc_t *gate, uint_t vec)
-{
- if (idt == NULL)
- idt = curidt();
- idt[vec] = *gate;
-}
+ cpu->cpu_self = cpu;
-static gate_desc_t *
-kdi_cpu2idt(cpu_t *cp)
-{
- if (cp == NULL)
- cp = CPU;
- return (cp->cpu_idt);
+ old = (uintptr_t)rdmsr(MSR_AMD_GSBASE);
+ wrmsr(MSR_AMD_GSBASE, (uint64_t)cpu);
+ return ((void *)old);
}
void
-kdi_flush_caches(void)
+boot_kdi_tmpfini(void *old)
{
- reload_cr3();
+ wrmsr(MSR_AMD_GSBASE, (uint64_t)old);
}
-static int
-kdi_get_cpuinfo(uint_t *vendorp, uint_t *familyp, uint_t *modelp)
-{
- desctbr_t gdtr;
- cpu_t *cpu;
+#elif defined(__i386)
- /*
- * CPU doesn't work until the GDT and gs/GSBASE have been set up.
- * Boot-loaded kmdb will call us well before then, so we have to
- * find the current cpu_t the hard way.
- */
- rd_gdtr(&gdtr);
- if ((cpu = kdi_gdt2cpu(gdtr.dtr_base)) == NULL ||
- !cpuid_checkpass(cpu, 1))
- return (EAGAIN); /* cpuid isn't done yet */
+void *
+boot_kdi_tmpinit(void)
+{
+ cpu_t *cpu = kobj_zalloc(sizeof (*cpu), KM_TMP);
+ uintptr_t old;
+ desctbr_t b_gdtr;
+ user_desc_t *bgdt;
- *vendorp = cpuid_getvendor(cpu);
- *familyp = cpuid_getfamily(cpu);
- *modelp = cpuid_getmodel(cpu);
+ cpu->cpu_self = cpu;
- return (0);
-}
+ rd_gdtr(&b_gdtr);
+ bgdt = (user_desc_t *)(b_gdtr.dtr_base);
-static void
-kdi_plat_call(void (*platfn)(void))
-{
- if (platfn != NULL)
- platfn();
-}
+ set_usegd(&bgdt[GDT_BGSTMP],
+ cpu, sizeof (*cpu), SDT_MEMRWA, SEL_KPL, SDP_BYTES, SDP_OP32);
-void
-mach_kdi_init(kdi_t *kdi)
-{
- kdi->kdi_plat_call = kdi_plat_call;
- kdi->mkdi_get_cpuinfo = kdi_get_cpuinfo;
- kdi->mkdi_xc_initialized = kdi_xc_initialized;
- kdi->mkdi_xc_others = kdi_xc_others;
- kdi->mkdi_get_userlimit = kdi_get_userlimit;
-
- kdi->mkdi_idt_init_gate = kdi_idt_init_gate;
- kdi->mkdi_idt_read = kdi_idt_read;
- kdi->mkdi_idt_write = kdi_idt_write;
- kdi->mkdi_cpu2idt = kdi_cpu2idt;
-
- kdi->mkdi_shutdownp = &psm_shutdownf;
-#if defined(__amd64)
- kdi->mkdi_gdt2gsbase = &kdi_gdt2gsbase;
-#endif
+ /*
+ * Now switch %gs to point at it.
+ */
+ old = getgs();
+ setgs(KMDBGS_SEL);
- kdi->mkdi_cpu_iter = kdi_cpu_iter;
+ return ((void *)old);
}
-/*ARGSUSED*/
void
-mach_kdi_fini(kdi_t *kdi)
+boot_kdi_tmpfini(void *old)
{
- hat_kdi_fini();
+ setgs((uintptr_t)old);
}
-void
-plat_kdi_init(kdi_t *kdi)
-{
- kdi->pkdi_system_claim = kdi_system_claim;
- kdi->pkdi_system_release = kdi_system_release;
-}
+#endif /* __i386 */
diff --git a/usr/src/uts/i86pc/os/machdep.c b/usr/src/uts/i86pc/os/machdep.c
index 3a84df1063..bc2da7f363 100644
--- a/usr/src/uts/i86pc/os/machdep.c
+++ b/usr/src/uts/i86pc/os/machdep.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -60,7 +60,6 @@
#include <sys/cmn_err.h>
#include <sys/utsname.h>
#include <sys/debug.h>
-#include <sys/kdi_impl.h>
#include <sys/dumphdr.h>
#include <sys/bootconf.h>
@@ -82,7 +81,6 @@
#include <sys/stack.h>
#include <sys/trap.h>
#include <sys/pic.h>
-#include <sys/mmu.h>
#include <vm/hat.h>
#include <vm/anon.h>
#include <vm/as.h>
@@ -115,7 +113,9 @@
#include <sys/x86_archext.h>
#include <sys/pool_pset.h>
#include <sys/autoconf.h>
-#include <sys/kdi.h>
+#include <sys/mem.h>
+#include <sys/dumphdr.h>
+#include <sys/compress.h>
#ifdef TRAPTRACE
#include <sys/traptrace.h>
@@ -264,8 +264,6 @@ resume_other_cpus()
xc_release_cpus();
}
-extern void mp_halt(char *);
-
void
stop_other_cpus()
{
@@ -275,12 +273,12 @@ stop_other_cpus()
ASSERT(cpuid < NCPU);
/*
- * xc_trycall will attempt to make all other CPUs execute mp_halt,
+ * xc_trycall will attempt to make all other CPUs execute mach_cpu_halt,
* and will return immediately regardless of whether or not it was
* able to make them do it.
*/
CPUSET_ALL_BUT(xcset, cpuid);
- xc_trycall(NULL, NULL, NULL, xcset, (int (*)())mp_halt);
+ xc_trycall(NULL, NULL, NULL, xcset, (int (*)())mach_cpu_halt);
}
/*
@@ -322,7 +320,7 @@ debug_enter(
prom_printf("%s\n", msg);
if (boothowto & RB_DEBUG)
- kdi_dvec_enter();
+ kmdb_enter();
if (dtrace_debugger_fini != NULL)
(*dtrace_debugger_fini)();
@@ -363,20 +361,6 @@ halt(char *s)
}
/*
- * Enter monitor. Called via cross-call from stop_other_cpus().
- */
-void
-mp_halt(char *msg)
-{
- if (msg)
- prom_printf("%s\n", msg);
-
- /*CONSTANTCONDITION*/
- while (1)
- ;
-}
-
-/*
* Initiate interrupt redistribution.
*/
void
@@ -431,7 +415,7 @@ int
sysp_getchar()
{
int i;
- int s;
+ ulong_t s;
if (cons_polledio == NULL) {
/* Uh oh */
@@ -450,7 +434,7 @@ sysp_getchar()
void
sysp_putchar(int c)
{
- int s;
+ ulong_t s;
/*
* We have no alternative but to drop the output on the floor.
@@ -469,7 +453,7 @@ int
sysp_ischar()
{
int i;
- int s;
+ ulong_t s;
if (cons_polledio == NULL ||
cons_polledio->cons_polledio_ischar == NULL)
@@ -759,7 +743,8 @@ panic_idle(void)
splx(ipltospl(CLOCK_LEVEL));
(void) setjmp(&curthread->t_pcb);
- for (;;);
+ for (;;)
+ ;
}
/*
@@ -826,8 +811,7 @@ panic_dump_hw(int spl)
/*ARGSUSED*/
void
plat_tod_fault(enum tod_fault_type tod_bad)
-{
-}
+{}
/*ARGSUSED*/
int
@@ -874,7 +858,6 @@ void
tenmicrosec(void)
{
extern int tsc_gethrtime_initted;
- int i;
if (tsc_gethrtime_initted) {
hrtime_t start, end;
@@ -884,6 +867,8 @@ tenmicrosec(void)
end = gethrtime();
}
} else {
+ int i;
+
/*
* Artificial loop to induce delay.
*/
@@ -979,3 +964,58 @@ get_cpu_mstate(cpu_t *cpu, hrtime_t *times)
}
scalehrtime(&times[CMS_SYSTEM]);
}
+
+
+/*
+ * This is a version of the rdmsr instruction that allows
+ * an error code to be returned in the case of failure.
+ */
+int
+checked_rdmsr(uint_t msr, uint64_t *value)
+{
+ if ((x86_feature & X86_MSR) == 0)
+ return (ENOTSUP);
+ *value = rdmsr(msr);
+ return (0);
+}
+
+/*
+ * This is a version of the wrmsr instruction that allows
+ * an error code to be returned in the case of failure.
+ */
+int
+checked_wrmsr(uint_t msr, uint64_t value)
+{
+ if ((x86_feature & X86_MSR) == 0)
+ return (ENOTSUP);
+ wrmsr(msr, value);
+ return (0);
+}
+
+/*
+ * Return true if the given page VA can be read via /dev/kmem.
+ */
+/*ARGSUSED*/
+int
+plat_mem_valid_page(uintptr_t pageaddr, uio_rw_t rw)
+{
+ return (0);
+}
+
+int
+dump_plat_addr()
+{
+ return (0);
+}
+
+void
+dump_plat_pfn()
+{
+}
+
+/*ARGSUSED*/
+int
+dump_plat_data(void *dump_cbuf)
+{
+ return (0);
+}
diff --git a/usr/src/uts/i86pc/os/memscrub.c b/usr/src/uts/i86pc/os/memscrub.c
index 2e73a2a694..322573ff91 100644
--- a/usr/src/uts/i86pc/os/memscrub.c
+++ b/usr/src/uts/i86pc/os/memscrub.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -101,7 +100,7 @@
#include <vm/hat_i86.h>
static caddr_t memscrub_window;
-static void *memscrub_pte;
+static hat_mempte_t memscrub_pte;
/*
* Global Data:
diff --git a/usr/src/uts/i86pc/os/mlsetup.c b/usr/src/uts/i86pc/os/mlsetup.c
index 067f417551..f946ed2f5a 100644
--- a/usr/src/uts/i86pc/os/mlsetup.c
+++ b/usr/src/uts/i86pc/os/mlsetup.c
@@ -26,6 +26,7 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/types.h>
+#include <sys/sysmacros.h>
#include <sys/disp.h>
#include <sys/promif.h>
#include <sys/clock.h>
@@ -50,31 +51,13 @@
#include <sys/machsystm.h>
#include <sys/ontrap.h>
#include <sys/bootconf.h>
-#include <sys/kdi.h>
+#include <sys/kdi_machimpl.h>
#include <sys/archsystm.h>
#include <sys/promif.h>
#include <sys/bootconf.h>
#include <sys/kobj.h>
#include <sys/kobj_lex.h>
#include <sys/pci_cfgspace.h>
-#if defined(__amd64)
-#include <sys/bootsvcs.h>
-
-/*
- * XX64 This stuff deals with switching stacks in case a trapping
- * thread wants to call back into boot -after- boot has lost track
- * of the mappings but before the kernel owns the console.
- *
- * (A better way to hide this would be to add a 'this' pointer to
- * every boot syscall so that vmx could get at the resulting save
- * area.)
- */
-
-struct boot_syscalls *_vmx_sysp;
-static struct boot_syscalls __kbootsvcs;
-extern struct boot_syscalls *sysp;
-extern void _stack_safe_putchar(int c);
-#endif
/*
* some globals for patching the result of cpuid
@@ -89,17 +72,11 @@ extern uint32_t cpuid_feature_edx_exclude;
/*
* Dummy spl priority masks
*/
-static unsigned char dummy_cpu_pri[MAXIPL + 1] = {
+static unsigned char dummy_cpu_pri[MAXIPL + 1] = {
0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf
};
-/*
- * External Routines:
- */
-
-extern void init_tables(void);
-
static uint32_t
bootprop_getval(char *name)
@@ -128,29 +105,6 @@ mlsetup(struct regs *rp)
ASSERT_STACK_ALIGNED();
-#if defined(__amd64)
-
-#if (BS_VERSION > 4)
- /*
- * When new boot_syscalls are added to the vector, this routine
- * must be modified to copy them into the kernel's copy of the
- * vector.
- */
-#error mlsetup() must be updated for amd64 to support new boot_syscalls
-#endif /* (BS_VERSION > 4) */
-
- /*
- * XX64 This remaps vmx's putchar to use the kernel's version
- * that switches stacks before diving into vmx
- * See explanation/complaints in commentary above.
- */
- _vmx_sysp = sysp;
- sysp = &__kbootsvcs;
-
- sysp->bsvc_getchar = _vmx_sysp->bsvc_getchar;
- sysp->bsvc_putchar = _stack_safe_putchar;
- sysp->bsvc_ischar = _vmx_sysp->bsvc_ischar;
-#endif
/*
* initialize cpu_self
*/
@@ -188,46 +142,15 @@ mlsetup(struct regs *rp)
* want to set the feature bits to correspond to the feature
* minimum) this value may be altered.
*/
-
x86_feature = cpuid_pass1(cpu[0]);
/*
* Initialize idt0, gdt0, ldt0_default, ktss0 and dftss.
*/
- init_tables();
-
-#if defined(__amd64)
- /*CSTYLED*/
- {
- /*
- * setup %gs for the kernel
- */
- wrmsr(MSR_AMD_GSBASE, (uint64_t)&cpus[0]);
- /*
- * XX64 We should never dereference off "other gsbase" or
- * "fsbase". So, we should arrange to point FSBASE and
- * KGSBASE somewhere truly awful e.g. point it at the last
- * valid address below the hole so that any attempts to index
- * off them cause an exception.
- *
- * For now, point it at 8G -- at least it should be unmapped
- * until some 64-bit processes run.
- */
- wrmsr(MSR_AMD_FSBASE, 0x200000000UL);
- wrmsr(MSR_AMD_KGSBASE, 0x200000000UL);
- }
+ init_desctbls();
-#elif defined(__i386)
- /*
- * enable large page support right here.
- */
- if (x86_feature & X86_LARGEPAGE) {
- cr4_value |= CR4_PSE;
- if (x86_feature & X86_PGE)
- cr4_value |= CR4_PGE;
- setup_121_andcall(enable_big_page_support, cr4_value);
- }
+#if defined(__i386)
/*
* Some i386 processors do not implement the rdtsc instruction,
* or at least they do not implement it correctly.
@@ -238,7 +161,22 @@ mlsetup(struct regs *rp)
*/
if (x86_feature & X86_TSC)
patch_tsc();
-#endif
+#endif /* __i386 */
+
+ /*
+ * While we're thinking about the TSC, let's set up %cr4 so that
+ * userland can issue rdtsc, and initialize the TSC_AUX value
+ * (the cpuid) for the rdtscp instruction on appropriately
+ * capable hardware.
+ */
+ if (x86_feature & X86_TSC)
+ setcr4(getcr4() & ~CR4_TSD);
+
+ if (x86_feature & X86_TSCP)
+ (void) wrmsr(MSR_AMD_TSCAUX, 0);
+
+ if (x86_feature & X86_DE)
+ setcr4(getcr4() | CR4_DE);
/*
* initialize t0
@@ -264,7 +202,7 @@ mlsetup(struct regs *rp)
THREAD_ONPROC(&t0, CPU);
lwp0.lwp_thread = &t0;
- lwp0.lwp_regs = (void *) rp;
+ lwp0.lwp_regs = (void *)rp;
lwp0.lwp_procp = &p0;
t0.t_tid = p0.p_lwpcnt = p0.p_lwprcnt = p0.p_lwpid = 1;
@@ -290,24 +228,15 @@ mlsetup(struct regs *rp)
CPU->cpu_id = 0;
- CPU->cpu_tss = &ktss0;
-
CPU->cpu_pri = 12; /* initial PIL for the boot CPU */
- CPU->cpu_gdt = gdt0;
-
/*
* The kernel doesn't use LDTs unless a process explicitly requests one.
*/
p0.p_ldt_desc = zero_sdesc;
/*
- * Kernel IDT.
- */
- CPU->cpu_idt = idt0;
-
- /*
- * Initialize thread/cpu microstate accounting here
+ * Initialize thread/cpu microstate accounting
*/
init_mstate(&t0, LMS_SYSTEM);
init_cpu_mstate(CPU, CMS_SYSTEM);
@@ -317,6 +246,23 @@ mlsetup(struct regs *rp)
*/
cpu_list_init(CPU);
+ /*
+ * Now that we have taken over the GDT, IDT and have initialized
+ * active CPU list it's time to inform kmdb if present.
+ */
+ if (boothowto & RB_DEBUG)
+ kdi_idt_sync();
+
+ /*
+ * If requested (boot -d) drop into kmdb.
+ *
+ * This must be done after cpu_list_init() on the 64-bit kernel
+ * since taking a trap requires that we re-compute gsbase based
+ * on the cpu list.
+ */
+ if (boothowto & RB_DEBUGENTER)
+ kmdb_enter();
+
cpu_vm_data_init(CPU);
/* lgrp_init() needs PCI config space access */
@@ -333,16 +279,8 @@ mlsetup(struct regs *rp)
boot_ncpus = bootprop_getval("boot-ncpus");
- /*
- * To avoid wasting kernel memory, we're temporarily limiting the
- * total number of processors to 32 by default until we get the
- * capability to scan ACPI tables early on boot to detect how many
- * processors are actually present. However, 64-bit systems
- * can be booted with up to 64 processors by setting "boot-ncpus"
- * boot property to 64.
- */
if (boot_ncpus <= 0 || boot_ncpus > NCPU)
- boot_ncpus = 32;
+ boot_ncpus = NCPU;
max_ncpus = boot_max_ncpus = boot_ncpus;
diff --git a/usr/src/uts/i86pc/os/mp_call.c b/usr/src/uts/i86pc/os/mp_call.c
index 0dd9e9db4c..581dcbd631 100644
--- a/usr/src/uts/i86pc/os/mp_call.c
+++ b/usr/src/uts/i86pc/os/mp_call.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,9 +18,10 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright (c) 1990-1993, 1999 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -32,6 +32,8 @@
#include <sys/cpuvar.h>
#include <sys/machsystm.h>
#include <sys/systm.h>
+#include <sys/promif.h>
+#include <sys/x_call.h>
/*
* Interrupt another CPU.
@@ -46,10 +48,12 @@
void
poke_cpu(int cpun)
{
+ if (panicstr)
+ return;
/*
* We don't need to receive an ACK from the CPU being poked,
* so just send out a directed interrupt.
*/
- if (!panicstr)
- send_dirint(cpun, XC_CPUPOKE_PIL);
+ XC_TRACE(TT_XC_POKE_CPU, -1, cpun);
+ send_dirint(cpun, XC_CPUPOKE_PIL);
}
diff --git a/usr/src/uts/i86pc/os/mp_implfuncs.c b/usr/src/uts/i86pc/os/mp_implfuncs.c
index 5032c16b20..cad5365b08 100644
--- a/usr/src/uts/i86pc/os/mp_implfuncs.c
+++ b/usr/src/uts/i86pc/os/mp_implfuncs.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -212,7 +211,7 @@ psm_map_phys_new(paddr_t addr, size_t len, int prot)
return (0);
pgoffset = addr & MMU_PAGEOFFSET;
- base = addr - pgoffset;
+ base = addr;
npages = mmu_btopr(len + pgoffset);
cvaddr = device_arena_alloc(ptob(npages), VM_NOSLEEP);
if (cvaddr == NULL)
@@ -331,12 +330,14 @@ mod_infopsm(struct modlpsm *modl, struct modlinkage *modlp, int *p0)
return (0);
}
+#define DEFAULT_PSM_MODULE "uppc"
+
static char *
psm_get_impl_module(int first)
{
static char **pnamep;
static char *psm_impl_module_list[] = {
- "uppc",
+ DEFAULT_PSM_MODULE,
(char *)0
};
static void *mhdl = NULL;
diff --git a/usr/src/uts/i86pc/os/mp_machdep.c b/usr/src/uts/i86pc/os/mp_machdep.c
index c2e3123a24..f7d3a802f7 100644
--- a/usr/src/uts/i86pc/os/mp_machdep.c
+++ b/usr/src/uts/i86pc/os/mp_machdep.c
@@ -40,8 +40,10 @@
#include <sys/cpuvar.h>
#include <sys/pghw.h>
#include <sys/disp.h>
-#include <sys/cpu.h>
#include <sys/archsystm.h>
+#include <sys/machsystm.h>
+#include <sys/param.h>
+#include <sys/promif.h>
#include <sys/mach_intr.h>
#define OFFSETOF(s, m) (size_t)(&(((s *)0)->m))
@@ -60,27 +62,21 @@ static void mach_fixcpufreq(void);
static int mach_clkinit(int, int *);
static void mach_smpinit(void);
static void mach_set_softintr(int ipl, struct av_softinfo *);
-static void mach_cpu_start(int cpun);
static int mach_softlvl_to_vect(int ipl);
static void mach_get_platform(int owner);
static void mach_construct_info();
static int mach_translate_irq(dev_info_t *dip, int irqno);
static int mach_intr_ops(dev_info_t *, ddi_intr_handle_impl_t *,
psm_intr_op_t, int *);
-static timestruc_t mach_tod_get(void);
-static void mach_tod_set(timestruc_t ts);
static void mach_notify_error(int level, char *errmsg);
static hrtime_t dummy_hrtime(void);
static void dummy_scalehrtime(hrtime_t *);
-static void cpu_halt(void);
+static void cpu_idle(void);
static void cpu_wakeup(cpu_t *, int);
/*
* External reference functions
*/
extern void return_instr();
-extern timestruc_t (*todgetf)(void);
-extern void (*todsetf)(timestruc_t);
-extern long gmt_lag;
extern uint64_t freq_tsc(uint32_t *);
#if defined(__i386)
extern uint64_t freq_notsc(uint32_t *);
@@ -92,18 +88,17 @@ extern int cpuid_get_chipid(cpu_t *);
/*
* PSM functions initialization
*/
-void (*psm_shutdownf)(int, int) = return_instr;
-void (*psm_preshutdownf)(int, int) = return_instr;
-void (*psm_notifyf)(int) = return_instr;
-void (*psm_set_idle_cpuf)(int) = return_instr;
-void (*psm_unset_idle_cpuf)(int) = return_instr;
+void (*psm_shutdownf)(int, int) = (void (*)(int, int))return_instr;
+void (*psm_preshutdownf)(int, int) = (void (*)(int, int))return_instr;
+void (*psm_notifyf)(int) = (void (*)(int))return_instr;
+void (*psm_set_idle_cpuf)(int) = (void (*)(int))return_instr;
+void (*psm_unset_idle_cpuf)(int) = (void (*)(int))return_instr;
void (*psminitf)() = mach_init;
void (*picinitf)() = return_instr;
int (*clkinitf)(int, int *) = (int (*)(int, int *))return_instr;
-void (*cpu_startf)() = return_instr;
int (*ap_mlsetup)() = (int (*)(void))return_instr;
void (*send_dirintf)() = return_instr;
-void (*setspl)(int) = return_instr;
+void (*setspl)(int) = (void (*)(int))return_instr;
int (*addspl)(int, int, int, int) = (int (*)(int, int, int, int))return_instr;
int (*delspl)(int, int, int, int) = (int (*)(int, int, int, int))return_instr;
void (*setsoftint)(int, struct av_softinfo *)=
@@ -118,8 +113,6 @@ hrtime_t (*gethrtimeunscaledf)(void) = dummy_hrtime;
void (*scalehrtimef)(hrtime_t *) = dummy_scalehrtime;
int (*psm_translate_irq)(dev_info_t *, int) = mach_translate_irq;
void (*gethrestimef)(timestruc_t *) = pc_gethrestime;
-int (*psm_todgetf)(todinfo_t *) = (int (*)(todinfo_t *))return_instr;
-int (*psm_todsetf)(todinfo_t *) = (int (*)(todinfo_t *))return_instr;
void (*psm_notify_error)(int, char *) = (void (*)(int, char *))NULL;
int (*psm_get_clockirq)(int) = NULL;
int (*psm_get_ipivect)(int, int) = NULL;
@@ -146,25 +139,10 @@ static struct psm_ops *mach_set[4] = {&mach_ops, NULL, NULL, NULL};
static ushort_t mach_ver[4] = {0, 0, 0, 0};
/*
- * If non-zero, idle cpus will "halted" when there's
+ * If non-zero, idle cpus will become "halted" when there's
* no work to do.
*/
-int halt_idle_cpus = 1;
-
-#if defined(__amd64)
-/*
- * If non-zero, will use cr8 for interrupt priority masking
- * We declare this here since install_spl is called from here
- * (where this is checked).
- */
-int intpri_use_cr8 = 0;
-#endif /* __amd64 */
-
-#ifdef _SIMULATOR_SUPPORT
-
-int simulator_run = 0; /* patch to non-zero if running under simics */
-
-#endif /* _SIMULATOR_SUPPORT */
+int idle_cpu_use_hlt = 1;
/*ARGSUSED*/
@@ -271,10 +249,10 @@ dummy_scalehrtime(hrtime_t *ticks)
{}
/*
- * Halt the present CPU until awoken via an interrupt
+ * Idle the present CPU until awoken via an interrupt
*/
static void
-cpu_halt(void)
+cpu_idle(void)
{
cpu_t *cpup = CPU;
processorid_t cpun = cpup->cpu_id;
@@ -339,7 +317,7 @@ cpu_halt(void)
* This means that the ordering of the poke and the clearing
* of the bit by cpu_wakeup is important.
* cpu_wakeup() must clear, then poke.
- * cpu_halt() must disable interrupts, then check for the bit.
+ * cpu_idle() must disable interrupts, then check for the bit.
*/
cli();
@@ -364,12 +342,7 @@ cpu_halt(void)
return;
}
- /*
- * Call the halt sequence:
- * sti
- * hlt
- */
- i86_halt();
+ mach_cpu_idle();
/*
* We're no longer halted
@@ -404,7 +377,7 @@ cpu_wakeup(cpu_t *cpu, int bound)
/*
* We may find the current CPU present in the halted cpuset
* if we're in the context of an interrupt that occurred
- * before we had a chance to clear our bit in cpu_halt().
+ * before we had a chance to clear our bit in cpu_idle().
* Poking ourself is obviously unnecessary, since if
* we're here, we're not halted.
*/
@@ -449,6 +422,8 @@ cpu_wakeup(cpu_t *cpu, int bound)
poke_cpu(cpu_found);
}
+void (*cpu_pause_handler)(volatile char *) = NULL;
+
static int
mp_disable_intr(int cpun)
{
@@ -533,7 +508,7 @@ mach_get_platform(int owner)
static void
mach_construct_info()
{
- register struct psm_sw *swp;
+ struct psm_sw *swp;
int mach_cnt[PSM_OWN_OVERRIDE+1] = {0};
int conflict_owner = 0;
@@ -584,7 +559,7 @@ mach_construct_info()
static void
mach_init()
{
- register struct psm_ops *pops;
+ struct psm_ops *pops;
mach_construct_info();
@@ -604,14 +579,22 @@ mach_init()
psm_translate_irq = pops->psm_translate_irq;
if (pops->psm_intr_ops)
psm_intr_ops = pops->psm_intr_ops;
- if (pops->psm_tod_get) {
- todgetf = mach_tod_get;
- psm_todgetf = pops->psm_tod_get;
- }
- if (pops->psm_tod_set) {
- todsetf = mach_tod_set;
- psm_todsetf = pops->psm_tod_set;
- }
+
+#if defined(PSMI_1_2) || defined(PSMI_1_3) || defined(PSMI_1_4)
+ /*
+ * Time-of-day functionality now handled in TOD modules.
+ * (Warn about PSM modules that think that we're going to use
+ * their ops vectors.)
+ */
+ if (pops->psm_tod_get)
+ cmn_err(CE_WARN, "obsolete psm_tod_get op %p",
+ (void *)pops->psm_tod_get);
+
+ if (pops->psm_tod_set)
+ cmn_err(CE_WARN, "obsolete psm_tod_set op %p",
+ (void *)pops->psm_tod_set);
+#endif
+
if (pops->psm_notify_error) {
psm_notify_error = mach_notify_error;
notify_error = pops->psm_notify_error;
@@ -623,13 +606,8 @@ mach_init()
* Initialize the dispatcher's function hooks
* to enable CPU halting when idle
*/
-#if defined(_SIMULATOR_SUPPORT)
- if (halt_idle_cpus && !simulator_run)
- idle_cpu = cpu_halt;
-#else
- if (halt_idle_cpus)
- idle_cpu = cpu_halt;
-#endif /* _SIMULATOR_SUPPORT */
+ if (idle_cpu_use_hlt)
+ idle_cpu = cpu_idle;
mach_smpinit();
}
@@ -654,7 +632,6 @@ mach_smpinit(void)
mp_cpus = cpumask;
/* MP related routines */
- cpu_startf = mach_cpu_start;
ap_mlsetup = pops->psm_post_cpu_start;
send_dirintf = pops->psm_send_ipi;
@@ -696,15 +673,8 @@ mach_smpinit(void)
* Set the dispatcher hook to enable cpu "wake up"
* when a thread becomes runnable.
*/
-#if defined(_SIMULATOR_SUPPORT)
- if (halt_idle_cpus && !simulator_run) {
- disp_enq_thread = cpu_wakeup;
- }
-#else
- if (halt_idle_cpus) {
+ if (idle_cpu_use_hlt)
disp_enq_thread = cpu_wakeup;
- }
-#endif /* _SIMULATOR_SUPPORT */
if (pops->psm_disable_intr)
psm_disable_intr = pops->psm_disable_intr;
@@ -727,10 +697,6 @@ static void
mach_picinit()
{
struct psm_ops *pops;
- extern void install_spl(void); /* XXX: belongs in a header file */
-#if defined(__amd64) && defined(DEBUG)
- extern void *spl_patch, *slow_spl, *setsplhi_patch, *slow_setsplhi;
-#endif
pops = mach_set[0];
@@ -743,17 +709,8 @@ mach_picinit()
/* set interrupt mask for current ipl */
setspl = pops->psm_setspl;
+ cli();
setspl(CPU->cpu_pri);
-
- /* Install proper spl routine now that we can Program the PIC */
-#if defined(__amd64)
- /*
- * It would be better if we could check this at compile time
- */
- ASSERT(((uintptr_t)&slow_setsplhi - (uintptr_t)&setsplhi_patch < 128) &&
- ((uintptr_t)&slow_spl - (uintptr_t)&spl_patch < 128));
-#endif
- install_spl();
}
uint_t cpu_freq; /* MHz */
@@ -786,7 +743,9 @@ mach_getcpufreq(void)
* We have a TSC. freq_tsc() knows how to measure the number
* of clock cycles sampled against the PIT.
*/
+ ulong_t flags = clear_int_flag();
processor_clks = freq_tsc(&pit_counter);
+ restore_int_flag(flags);
return (mach_calchz(pit_counter, &processor_clks));
} else if (x86_vendor == X86_VENDOR_Cyrix || x86_type == X86_TYPE_P5) {
#if defined(__amd64)
@@ -797,7 +756,9 @@ mach_getcpufreq(void)
* for which freq_notsc() knows how to measure the number of
* elapsed clock cycles sampled against the PIT
*/
+ ulong_t flags = clear_int_flag();
processor_clks = freq_notsc(&pit_counter);
+ restore_int_flag(flags);
return (mach_calchz(pit_counter, &processor_clks));
#endif /* __i386 */
}
@@ -939,19 +900,12 @@ machhztomhz(uint64_t cpu_freq_hz)
static int
mach_clkinit(int preferred_mode, int *set_mode)
{
- register struct psm_ops *pops;
+ struct psm_ops *pops;
int resolution;
pops = mach_set[0];
-#ifdef _SIMULATOR_SUPPORT
- if (!simulator_run)
- cpu_freq_hz = mach_getcpufreq();
- else
- cpu_freq_hz = 40000000; /* use 40 Mhz (hack for simulator) */
-#else
cpu_freq_hz = mach_getcpufreq();
-#endif /* _SIMULATOR_SUPPORT */
cpu_freq = machhztomhz(cpu_freq_hz);
@@ -1013,7 +967,7 @@ mach_clkinit(int preferred_mode, int *set_mode)
static void
mach_psm_set_softintr(int ipl, struct av_softinfo *pending)
{
- register struct psm_ops *pops;
+ struct psm_ops *pops;
/* invoke hardware interrupt */
pops = mach_set[0];
@@ -1021,10 +975,10 @@ mach_psm_set_softintr(int ipl, struct av_softinfo *pending)
}
static int
-mach_softlvl_to_vect(register int ipl)
+mach_softlvl_to_vect(int ipl)
{
- register int softvect;
- register struct psm_ops *pops;
+ int softvect;
+ struct psm_ops *pops;
pops = mach_set[0];
@@ -1050,9 +1004,9 @@ mach_softlvl_to_vect(register int ipl)
}
static void
-mach_set_softintr(register int ipl, struct av_softinfo *pending)
+mach_set_softintr(int ipl, struct av_softinfo *pending)
{
- register struct psm_ops *pops;
+ struct psm_ops *pops;
/* set software pending bits */
av_set_softint_pending(ipl, pending);
@@ -1066,14 +1020,24 @@ mach_set_softintr(register int ipl, struct av_softinfo *pending)
(*pops->psm_set_softintr)(ipl);
}
-static void
-mach_cpu_start(register int cpun)
-{
- struct psm_ops *pops;
+#ifdef DEBUG
+/*
+ * This is here to allow us to simulate cpus that refuse to start.
+ */
+cpuset_t cpufailset;
+#endif
- pops = mach_set[0];
+int
+mach_cpu_start(struct cpu *cp, void *ctx)
+{
+ struct psm_ops *pops = mach_set[0];
+ processorid_t id = cp->cpu_id;
- (*pops->psm_cpu_start)(cpun, rm_platter_va);
+#ifdef DEBUG
+ if (CPU_IN_SET(cpufailset, id))
+ return (0);
+#endif
+ return ((*pops->psm_cpu_start)(id, ctx));
}
/*ARGSUSED*/
@@ -1083,53 +1047,6 @@ mach_translate_irq(dev_info_t *dip, int irqno)
return (irqno); /* default to NO translation */
}
-static timestruc_t
-mach_tod_get(void)
-{
- timestruc_t ts;
- todinfo_t tod;
- static int mach_range_warn = 1; /* warn only once */
-
- ASSERT(MUTEX_HELD(&tod_lock));
-
- /* The year returned from is the last 2 digit only */
- if ((*psm_todgetf)(&tod)) {
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
- tod_fault_reset();
- return (ts);
- }
-
- /* assume that we wrap the rtc year back to zero at 2000 */
- if (tod.tod_year < 69) {
- if (mach_range_warn && tod.tod_year > 38) {
- cmn_err(CE_WARN, "hardware real-time clock is out "
- "of range -- time needs to be reset");
- mach_range_warn = 0;
- }
- tod.tod_year += 100;
- }
-
- /* tod_to_utc uses 1900 as base for the year */
- ts.tv_sec = tod_to_utc(tod) + gmt_lag;
- ts.tv_nsec = 0;
-
- return (ts);
-}
-
-static void
-mach_tod_set(timestruc_t ts)
-{
- todinfo_t tod = utc_to_tod(ts.tv_sec - gmt_lag);
-
- ASSERT(MUTEX_HELD(&tod_lock));
-
- if (tod.tod_year >= 100)
- tod.tod_year -= 100;
-
- (*psm_todsetf)(&tod);
-}
-
static void
mach_notify_error(int level, char *errmsg)
{
diff --git a/usr/src/uts/i86pc/os/mp_pc.c b/usr/src/uts/i86pc/os/mp_pc.c
new file mode 100644
index 0000000000..293750e1ec
--- /dev/null
+++ b/usr/src/uts/i86pc/os/mp_pc.c
@@ -0,0 +1,287 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Welcome to the world of the "real mode platter".
+ * See also startup.c, mpcore.s and apic.c for related routines.
+ */
+
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/cpuvar.h>
+#include <sys/kmem.h>
+#include <sys/archsystm.h>
+#include <sys/machsystm.h>
+#include <sys/controlregs.h>
+#include <sys/x86_archext.h>
+#include <sys/smp_impldefs.h>
+#include <sys/sysmacros.h>
+#include <sys/mach_mmu.h>
+#include <sys/promif.h>
+#include <sys/cpu.h>
+
+extern void real_mode_start(void);
+extern void real_mode_end(void);
+
+/*
+ * Fill up the real mode platter to make it easy for real mode code to
+ * kick it off. This area should really be one passed by boot to kernel
+ * and guaranteed to be below 1MB and aligned to 16 bytes. Should also
+ * have identical physical and virtual address in paged mode.
+ */
+static ushort_t *warm_reset_vector = NULL;
+
+int
+mach_cpucontext_init(void)
+{
+ ushort_t *vec;
+
+ if (!(vec = (ushort_t *)psm_map_phys(WARM_RESET_VECTOR,
+ sizeof (vec), PROT_READ | PROT_WRITE)))
+ return (-1);
+ /*
+ * setup secondary cpu bios boot up vector
+ */
+ *vec = (ushort_t)((caddr_t)
+ ((struct rm_platter *)rm_platter_va)->rm_code - rm_platter_va
+ + ((ulong_t)rm_platter_va & 0xf));
+ vec[1] = (ushort_t)(rm_platter_pa >> 4);
+ warm_reset_vector = vec;
+
+ bcopy((caddr_t)real_mode_start,
+ (caddr_t)((rm_platter_t *)rm_platter_va)->rm_code,
+ (size_t)real_mode_end - (size_t)real_mode_start);
+
+ return (0);
+}
+
+void
+mach_cpucontext_fini(void)
+{
+ if (warm_reset_vector)
+ psm_unmap_phys((caddr_t)warm_reset_vector,
+ sizeof (warm_reset_vector));
+ hat_unload(kas.a_hat, (caddr_t)(uintptr_t)rm_platter_pa, MMU_PAGESIZE,
+ HAT_UNLOAD);
+}
+
+#if defined(__amd64)
+extern void *long_mode_64(void);
+#endif /* __amd64 */
+
+void *
+mach_cpucontext_alloc(struct cpu *cp)
+{
+ rm_platter_t *rm = (rm_platter_t *)rm_platter_va;
+ struct cpu_tables *ct;
+ struct tss *ntss;
+
+ /*
+ * Allocate space for page directory, stack, tss, gdt and idt.
+ * The page directory has to be page aligned
+ */
+ ct = kmem_zalloc(sizeof (*ct), KM_SLEEP);
+ if ((uintptr_t)ct & ~MMU_STD_PAGEMASK)
+ panic("mp_startup_init: cpu%d misaligned tables", cp->cpu_id);
+
+ ntss = cp->cpu_tss = &ct->ct_tss;
+
+#if defined(__amd64)
+
+ /*
+ * #DF (double fault).
+ */
+ ntss->tss_ist1 = (uint64_t)&ct->ct_stack[sizeof (ct->ct_stack)];
+
+#elif defined(__i386)
+
+ ntss->tss_esp0 = ntss->tss_esp1 = ntss->tss_esp2 = ntss->tss_esp =
+ (uint32_t)&ct->ct_stack[sizeof (ct->ct_stack)];
+
+ ntss->tss_ss0 = ntss->tss_ss1 = ntss->tss_ss2 = ntss->tss_ss = KDS_SEL;
+
+ ntss->tss_eip = (uint32_t)cp->cpu_thread->t_pc;
+
+ ntss->tss_cs = KCS_SEL;
+ ntss->tss_ds = ntss->tss_es = KDS_SEL;
+ ntss->tss_fs = KFS_SEL;
+ ntss->tss_gs = KGS_SEL;
+
+#endif /* __i386 */
+
+ /*
+ * Set I/O bit map offset equal to size of TSS segment limit
+ * for no I/O permission map. This will cause all user I/O
+ * instructions to generate #gp fault.
+ */
+ ntss->tss_bitmapbase = sizeof (*ntss);
+
+ /*
+ * Setup kernel tss.
+ */
+ set_syssegd((system_desc_t *)&cp->cpu_gdt[GDT_KTSS], cp->cpu_tss,
+ sizeof (*cp->cpu_tss) -1, SDT_SYSTSS, SEL_KPL);
+
+ /*
+ * Now copy all that we've set up onto the real mode platter
+ * for the real mode code to digest as part of starting the cpu.
+ */
+
+ rm->rm_idt_base = cp->cpu_idt;
+ rm->rm_idt_lim = sizeof (idt0) - 1;
+ rm->rm_gdt_base = cp->cpu_gdt;
+ rm->rm_gdt_lim = ((sizeof (*cp->cpu_gdt) * NGDT)) -1;
+
+ rm->rm_pdbr = getcr3();
+ rm->rm_cpu = cp->cpu_id;
+ rm->rm_x86feature = x86_feature;
+ rm->rm_cr4 = getcr4();
+
+#if defined(__amd64)
+
+ if (getcr3() > 0xffffffffUL)
+ panic("Cannot initialize CPUs; kernel's 64-bit page tables\n"
+ "located above 4G in physical memory (@ 0x%lx)", getcr3());
+
+ /*
+ * Setup pseudo-descriptors for temporary GDT and IDT for use ONLY
+ * by code in real_mode_start():
+ *
+ * GDT[0]: NULL selector
+ * GDT[1]: 64-bit CS: Long = 1, Present = 1, bits 12, 11 = 1
+ *
+ * Clear the IDT as interrupts will be off and a limit of 0 will cause
+ * the CPU to triple fault and reset on an NMI, seemingly as reasonable
+ * a course of action as any other, though it may cause the entire
+ * platform to reset in some cases...
+ */
+ rm->rm_temp_gdt[0] = 0;
+ rm->rm_temp_gdt[TEMPGDT_KCODE64] = 0x20980000000000ULL;
+
+ rm->rm_temp_gdt_lim = (ushort_t)(sizeof (rm->rm_temp_gdt) - 1);
+ rm->rm_temp_gdt_base = rm_platter_pa +
+ (uint32_t)offsetof(rm_platter_t, rm_temp_gdt);
+ rm->rm_temp_idt_lim = 0;
+ rm->rm_temp_idt_base = 0;
+
+ /*
+ * Since the CPU needs to jump to protected mode using an identity
+ * mapped address, we need to calculate it here.
+ */
+ rm->rm_longmode64_addr = rm_platter_pa +
+ ((uint32_t)long_mode_64 - (uint32_t)real_mode_start);
+#endif /* __amd64 */
+
+ return (ct);
+}
+
+/*ARGSUSED*/
+void
+mach_cpucontext_free(struct cpu *cp, void *arg, int err)
+{
+ struct cpu_tables *ct = arg;
+
+ ASSERT(&ct->ct_tss == cp->cpu_tss);
+
+ switch (err) {
+ case 0:
+ break;
+ case ETIMEDOUT:
+ /*
+ * The processor was poked, but failed to start before
+ * we gave up waiting for it. In case it starts later,
+ * don't free anything.
+ */
+ break;
+ default:
+ /*
+ * Some other, passive, error occurred.
+ */
+ kmem_free(ct, sizeof (*ct));
+ cp->cpu_tss = NULL;
+ break;
+ }
+}
+
+/*
+ * "Enter monitor." Called via cross-call from stop_other_cpus().
+ */
+void
+mach_cpu_halt(char *msg)
+{
+ if (msg)
+ prom_printf("%s\n", msg);
+
+ /*CONSTANTCONDITION*/
+ while (1)
+ ;
+}
+
+void
+mach_cpu_idle(void)
+{
+ i86_halt();
+}
+
+void
+mach_cpu_pause(volatile char *safe)
+{
+ /*
+ * This cpu is now safe.
+ */
+ *safe = PAUSE_WAIT;
+ membar_enter(); /* make sure stores are flushed */
+
+ /*
+ * Now we wait. When we are allowed to continue, safe
+ * will be set to PAUSE_IDLE.
+ */
+ while (*safe != PAUSE_IDLE)
+ SMT_PAUSE();
+}
+
+/*
+ * Power on CPU.
+ */
+/*ARGSUSED*/
+int
+mp_cpu_poweron(struct cpu *cp)
+{
+ ASSERT(MUTEX_HELD(&cpu_lock));
+ return (ENOTSUP); /* not supported */
+}
+
+/*
+ * Power off CPU.
+ */
+/*ARGSUSED*/
+int
+mp_cpu_poweroff(struct cpu *cp)
+{
+ ASSERT(MUTEX_HELD(&cpu_lock));
+ return (ENOTSUP); /* not supported */
+}
diff --git a/usr/src/uts/i86pc/os/mp_startup.c b/usr/src/uts/i86pc/os/mp_startup.c
index 5fd2325888..96a3a1e628 100644
--- a/usr/src/uts/i86pc/os/mp_startup.c
+++ b/usr/src/uts/i86pc/os/mp_startup.c
@@ -18,6 +18,7 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
@@ -32,7 +33,6 @@
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/disp.h>
-#include <sys/mmu.h>
#include <sys/class.h>
#include <sys/cmn_err.h>
#include <sys/debug.h>
@@ -42,9 +42,9 @@
#include <sys/var.h>
#include <sys/vtrace.h>
#include <vm/hat.h>
-#include <sys/mmu.h>
#include <vm/as.h>
#include <vm/seg_kmem.h>
+#include <vm/seg_kp.h>
#include <sys/segments.h>
#include <sys/kmem.h>
#include <sys/stack.h>
@@ -60,10 +60,12 @@
#include <sys/archsystm.h>
#include <sys/fp.h>
#include <sys/reboot.h>
-#include <sys/kdi.h>
+#include <sys/kdi_machimpl.h>
#include <vm/hat_i86.h>
#include <sys/memnode.h>
#include <sys/pci_cfgspace.h>
+#include <sys/mach_mmu.h>
+#include <sys/sysmacros.h>
#include <sys/cpu_module.h>
struct cpu cpus[1]; /* CPU data */
@@ -71,15 +73,15 @@ struct cpu *cpu[NCPU] = {&cpus[0]}; /* pointers to all CPUs */
cpu_core_t cpu_core[NCPU]; /* cpu_core structures */
/*
- * Useful for disabling MP bring-up for an MP capable kernel
- * (a kernel that was built with MP defined)
+ * Useful for disabling MP bring-up on a MP capable system.
*/
int use_mp = 1;
/*
- * To be set by a PSM to indicate what CPUs are available on the system.
+ * to be set by a PSM to indicate what cpus
+ * are sitting around on the system.
*/
-cpuset_t mp_cpus = 1;
+cpuset_t mp_cpus;
/*
* This variable is used by the hat layer to decide whether or not
@@ -87,11 +89,9 @@ cpuset_t mp_cpus = 1;
* this variable is set once enough MP initialization has been done in
* order to allow cross calls.
*/
-int flushes_require_xcalls = 0;
-cpuset_t cpu_ready_set = 1;
+int flushes_require_xcalls;
+cpuset_t cpu_ready_set = 1;
-extern void real_mode_start(void);
-extern void real_mode_end(void);
static void mp_startup(void);
static void cpu_sep_enable(void);
@@ -143,7 +143,7 @@ init_cpu_syscall(struct cpu *cp)
kpreempt_disable();
#if defined(__amd64)
- if (x86_feature & X86_ASYSC) {
+ if ((x86_feature & (X86_MSR | X86_ASYSC)) == (X86_MSR | X86_ASYSC)) {
#if !defined(__lint)
/*
@@ -163,8 +163,8 @@ init_cpu_syscall(struct cpu *cp)
/*
* Program the magic registers ..
*/
- wrmsr(MSR_AMD_STAR, ((uint64_t)(U32CS_SEL << 16 | KCS_SEL)) <<
- 32);
+ wrmsr(MSR_AMD_STAR,
+ ((uint64_t)(U32CS_SEL << 16 | KCS_SEL)) << 32);
wrmsr(MSR_AMD_LSTAR, (uint64_t)(uintptr_t)sys_syscall);
wrmsr(MSR_AMD_CSTAR, (uint64_t)(uintptr_t)sys_syscall32);
@@ -183,7 +183,7 @@ init_cpu_syscall(struct cpu *cp)
* On 64-bit kernels on Nocona machines, the 32-bit syscall
* variant isn't available to 32-bit applications, but sysenter is.
*/
- if (x86_feature & X86_SEP) {
+ if ((x86_feature & (X86_MSR | X86_SEP)) == (X86_MSR | X86_SEP)) {
#if !defined(__lint)
/*
@@ -208,7 +208,7 @@ init_cpu_syscall(struct cpu *cp)
* resume() sets this value to the base of the threads stack
* via a context handler.
*/
- wrmsr(MSR_INTC_SEP_ESP, 0ULL);
+ wrmsr(MSR_INTC_SEP_ESP, 0);
wrmsr(MSR_INTC_SEP_EIP, (uint64_t)(uintptr_t)sys_sysenter);
}
@@ -221,35 +221,22 @@ init_cpu_syscall(struct cpu *cp)
* Allocate and initialize the cpu structure, TRAPTRACE buffer, and the
* startup and idle threads for the specified CPU.
*/
-static void
+struct cpu *
mp_startup_init(int cpun)
{
-#if defined(__amd64)
-extern void *long_mode_64(void);
-#endif /* __amd64 */
-
struct cpu *cp;
- struct tss *ntss;
kthread_id_t tp;
caddr_t sp;
- int size;
proc_t *procp;
extern void idle();
- struct cpu_tables *tablesp;
- rm_platter_t *real_mode_platter = (rm_platter_t *)rm_platter_va;
-
#ifdef TRAPTRACE
trap_trace_ctl_t *ttc = &trap_trace_ctl[cpun];
#endif
ASSERT(cpun < NCPU && cpu[cpun] == NULL);
- if ((cp = kmem_zalloc(sizeof (*cp), KM_NOSLEEP)) == NULL) {
- panic("mp_startup_init: cpu%d: "
- "no memory for cpu structure", cpun);
- /*NOTREACHED*/
- }
+ cp = kmem_zalloc(sizeof (*cp), KM_SLEEP);
procp = curthread->t_procp;
mutex_enter(&cpu_lock);
@@ -289,6 +276,9 @@ extern void *long_mode_64(void);
sp = tp->t_stk;
tp->t_pc = (uintptr_t)mp_startup;
tp->t_sp = (uintptr_t)(sp - MINFRAME);
+#if defined(__amd64)
+ tp->t_sp -= STACK_ENTRY_ALIGN; /* fake a call */
+#endif
cp->cpu_id = cpun;
cp->cpu_self = cp;
@@ -327,7 +317,7 @@ extern void *long_mode_64(void);
pg_cpu_bootstrap(cp);
/*
- * Perform CPC intialization on the new CPU.
+ * Perform CPC initialization on the new CPU.
*/
kcpc_hw_init(cp);
@@ -335,77 +325,25 @@ extern void *long_mode_64(void);
* Allocate virtual addresses for cpu_caddr1 and cpu_caddr2
* for each CPU.
*/
-
setup_vaddr_for_ppcopy(cp);
/*
- * Allocate space for page directory, stack, tss, gdt and idt.
- * This assumes that kmem_alloc will return memory which is aligned
- * to the next higher power of 2 or a page(if size > MAXABIG)
- * If this assumption goes wrong at any time due to change in
- * kmem alloc, things may not work as the page directory has to be
- * page aligned
+ * Allocate page for new GDT and initialize from current GDT.
*/
- if ((tablesp = kmem_zalloc(sizeof (*tablesp), KM_NOSLEEP)) == NULL)
- panic("mp_startup_init: cpu%d cannot allocate tables", cpun);
-
- if ((uintptr_t)tablesp & ~MMU_STD_PAGEMASK) {
- kmem_free(tablesp, sizeof (struct cpu_tables));
- size = sizeof (struct cpu_tables) + MMU_STD_PAGESIZE;
- tablesp = kmem_zalloc(size, KM_NOSLEEP);
- tablesp = (struct cpu_tables *)
- (((uintptr_t)tablesp + MMU_STD_PAGESIZE) &
- MMU_STD_PAGEMASK);
- }
-
- ntss = cp->cpu_tss = &tablesp->ct_tss;
-
- if ((tablesp->ct_gdt = kmem_zalloc(PAGESIZE, KM_NOSLEEP)) == NULL)
- panic("mp_startup_init: cpu%d cannot allocate GDT", cpun);
- cp->cpu_gdt = tablesp->ct_gdt;
- bcopy(CPU->cpu_gdt, cp->cpu_gdt, NGDT * (sizeof (user_desc_t)));
-
-#if defined(__amd64)
-
- /*
- * #DF (double fault).
- */
- ntss->tss_ist1 =
- (uint64_t)&tablesp->ct_stack[sizeof (tablesp->ct_stack)];
-
-#elif defined(__i386)
-
- ntss->tss_esp0 = ntss->tss_esp1 = ntss->tss_esp2 = ntss->tss_esp =
- (uint32_t)&tablesp->ct_stack[sizeof (tablesp->ct_stack)];
-
- ntss->tss_ss0 = ntss->tss_ss1 = ntss->tss_ss2 = ntss->tss_ss = KDS_SEL;
-
- ntss->tss_eip = (uint32_t)mp_startup;
-
- ntss->tss_cs = KCS_SEL;
- ntss->tss_fs = KFS_SEL;
- ntss->tss_gs = KGS_SEL;
+#if !defined(__lint)
+ ASSERT((sizeof (*cp->cpu_gdt) * NGDT) <= PAGESIZE);
+#endif
+ cp->cpu_m.mcpu_gdt = kmem_zalloc(PAGESIZE, KM_SLEEP);
+ bcopy(CPU->cpu_m.mcpu_gdt, cp->cpu_m.mcpu_gdt,
+ (sizeof (*cp->cpu_m.mcpu_gdt) * NGDT));
+#if defined(__i386)
/*
* setup kernel %gs.
*/
set_usegd(&cp->cpu_gdt[GDT_GS], cp, sizeof (struct cpu) -1, SDT_MEMRWA,
SEL_KPL, 0, 1);
-
-#endif /* __i386 */
-
- /*
- * Set I/O bit map offset equal to size of TSS segment limit
- * for no I/O permission map. This will cause all user I/O
- * instructions to generate #gp fault.
- */
- ntss->tss_bitmapbase = sizeof (*ntss);
-
- /*
- * setup kernel tss.
- */
- set_syssegd((system_desc_t *)&cp->cpu_gdt[GDT_KTSS], cp->cpu_tss,
- sizeof (*cp->cpu_tss) -1, SDT_SYSTSS, SEL_KPL);
+#endif
/*
* If we have more than one node, each cpu gets a copy of IDT
@@ -413,83 +351,35 @@ extern void *long_mode_64(void);
* IDT. cpu 0's IDT has been made read-only to workaround the
* cmpxchgl register bug
*/
- cp->cpu_idt = CPU->cpu_idt;
if (system_hardware.hd_nodes && x86_type != X86_TYPE_P5) {
- cp->cpu_idt = kmem_alloc(sizeof (idt0), KM_SLEEP);
- bcopy(idt0, cp->cpu_idt, sizeof (idt0));
+ struct machcpu *mcpu = &cp->cpu_m;
+
+ mcpu->mcpu_idt = kmem_alloc(sizeof (idt0), KM_SLEEP);
+ bcopy(idt0, mcpu->mcpu_idt, sizeof (idt0));
+ } else {
+ cp->cpu_m.mcpu_idt = CPU->cpu_m.mcpu_idt;
}
/*
- * Get interrupt priority data from cpu 0
+ * Get interrupt priority data from cpu 0.
*/
cp->cpu_pri_data = CPU->cpu_pri_data;
- hat_cpu_online(cp);
-
- /* Should remove all entries for the current process/thread here */
-
/*
- * Fill up the real mode platter to make it easy for real mode code to
- * kick it off. This area should really be one passed by boot to kernel
- * and guaranteed to be below 1MB and aligned to 16 bytes. Should also
- * have identical physical and virtual address in paged mode.
+ * alloc space for cpuid info
*/
- real_mode_platter->rm_idt_base = cp->cpu_idt;
- real_mode_platter->rm_idt_lim = sizeof (idt0) - 1;
- real_mode_platter->rm_gdt_base = cp->cpu_gdt;
- real_mode_platter->rm_gdt_lim = sizeof (gdt0) -1;
- real_mode_platter->rm_pdbr = getcr3();
- real_mode_platter->rm_cpu = cpun;
- real_mode_platter->rm_x86feature = x86_feature;
- real_mode_platter->rm_cr4 = cr4_value;
-
-#if defined(__amd64)
- if (getcr3() > 0xffffffffUL)
- panic("Cannot initialize CPUs; kernel's 64-bit page tables\n"
- "located above 4G in physical memory (@ 0x%llx).",
- (unsigned long long)getcr3());
+ cpuid_alloc_space(cp);
- /*
- * Setup pseudo-descriptors for temporary GDT and IDT for use ONLY
- * by code in real_mode_start():
- *
- * GDT[0]: NULL selector
- * GDT[1]: 64-bit CS: Long = 1, Present = 1, bits 12, 11 = 1
- *
- * Clear the IDT as interrupts will be off and a limit of 0 will cause
- * the CPU to triple fault and reset on an NMI, seemingly as reasonable
- * a course of action as any other, though it may cause the entire
- * platform to reset in some cases...
- */
- real_mode_platter->rm_temp_gdt[0] = 0ULL;
- real_mode_platter->rm_temp_gdt[TEMPGDT_KCODE64] = 0x20980000000000ULL;
-
- real_mode_platter->rm_temp_gdt_lim = (ushort_t)
- (sizeof (real_mode_platter->rm_temp_gdt) - 1);
- real_mode_platter->rm_temp_gdt_base = rm_platter_pa +
- (uint32_t)(&((rm_platter_t *)0)->rm_temp_gdt);
-
- real_mode_platter->rm_temp_idt_lim = 0;
- real_mode_platter->rm_temp_idt_base = 0;
-
- /*
- * Since the CPU needs to jump to protected mode using an identity
- * mapped address, we need to calculate it here.
- */
- real_mode_platter->rm_longmode64_addr = rm_platter_pa +
- ((uint32_t)long_mode_64 - (uint32_t)real_mode_start);
-#endif /* __amd64 */
+ hat_cpu_online(cp);
#ifdef TRAPTRACE
/*
- * If this is a TRAPTRACE kernel, allocate TRAPTRACE buffers for this
- * CPU.
+ * If this is a TRAPTRACE kernel, allocate TRAPTRACE buffers
*/
ttc->ttc_first = (uintptr_t)kmem_zalloc(trap_trace_bufsize, KM_SLEEP);
ttc->ttc_next = ttc->ttc_first;
ttc->ttc_limit = ttc->ttc_first + trap_trace_bufsize;
#endif
-
/*
* Record that we have another CPU.
*/
@@ -504,6 +394,92 @@ extern void *long_mode_64(void);
*/
cpu_add_unit(cp);
mutex_exit(&cpu_lock);
+
+ return (cp);
+}
+
+/*
+ * Undo what was done in mp_startup_init
+ */
+static void
+mp_startup_fini(struct cpu *cp, int error)
+{
+ mutex_enter(&cpu_lock);
+
+ /*
+ * Remove the CPU from the list of available CPUs.
+ */
+ cpu_del_unit(cp->cpu_id);
+
+ if (error == ETIMEDOUT) {
+ /*
+ * The cpu was started, but never *seemed* to run any
+ * code in the kernel; it's probably off spinning in its
+ * own private world, though with potential references to
+ * our kmem-allocated IDTs and GDTs (for example).
+ *
+ * Worse still, it may actually wake up some time later,
+ * so rather than guess what it might or might not do, we
+ * leave the fundamental data structures intact.
+ */
+ cp->cpu_flags = 0;
+ mutex_exit(&cpu_lock);
+ return;
+ }
+
+ /*
+ * At this point, the only threads bound to this CPU should
+ * special per-cpu threads: it's idle thread, it's pause threads,
+ * and it's interrupt threads. Clean these up.
+ */
+ cpu_destroy_bound_threads(cp);
+ cp->cpu_idle_thread = NULL;
+
+ /*
+ * Free the interrupt stack.
+ */
+ segkp_release(segkp,
+ cp->cpu_intr_stack - (INTR_STACK_SIZE - SA(MINFRAME)));
+
+ mutex_exit(&cpu_lock);
+
+#ifdef TRAPTRACE
+ /*
+ * Discard the trap trace buffer
+ */
+ {
+ trap_trace_ctl_t *ttc = &trap_trace_ctl[cp->cpu_id];
+
+ kmem_free((void *)ttc->ttc_first, trap_trace_bufsize);
+ ttc->ttc_first = NULL;
+ }
+#endif
+
+ hat_cpu_offline(cp);
+
+ cpuid_free_space(cp);
+
+ if (cp->cpu_m.mcpu_idt != CPU->cpu_m.mcpu_idt)
+ kmem_free(cp->cpu_m.mcpu_idt, sizeof (idt0));
+ cp->cpu_m.mcpu_idt = NULL;
+
+ kmem_free(cp->cpu_m.mcpu_gdt, PAGESIZE);
+ cp->cpu_m.mcpu_gdt = NULL;
+
+ teardown_vaddr_for_ppcopy(cp);
+
+ kcpc_hw_fini(cp);
+
+ cp->cpu_dispthread = NULL;
+ cp->cpu_thread = NULL; /* discarded by cpu_destroy_bound_threads() */
+
+ cpu_vm_data_destroy(cp);
+
+ mutex_enter(&cpu_lock);
+ disp_cpu_fini(cp);
+ mutex_exit(&cpu_lock);
+
+ kmem_free(cp, sizeof (*cp));
}
/*
@@ -528,6 +504,10 @@ extern void *long_mode_64(void);
* AMD Athlon(tm) 64 and AMD Opteron(tm) Processors, August 2005.
*/
+#if defined(OPTERON_ERRATUM_88)
+int opteron_erratum_88; /* if non-zero -> at least one cpu has it */
+#endif
+
#if defined(OPTERON_ERRATUM_91)
int opteron_erratum_91; /* if non-zero -> at least one cpu has it */
#endif
@@ -536,10 +516,18 @@ int opteron_erratum_91; /* if non-zero -> at least one cpu has it */
int opteron_erratum_93; /* if non-zero -> at least one cpu has it */
#endif
+#if defined(OPTERON_ERRATUM_95)
+int opteron_erratum_95; /* if non-zero -> at least one cpu has it */
+#endif
+
#if defined(OPTERON_ERRATUM_100)
int opteron_erratum_100; /* if non-zero -> at least one cpu has it */
#endif
+#if defined(OPTERON_ERRATUM_108)
+int opteron_erratum_108; /* if non-zero -> at least one cpu has it */
+#endif
+
#if defined(OPTERON_ERRATUM_109)
int opteron_erratum_109; /* if non-zero -> at least one cpu has it */
#endif
@@ -569,9 +557,30 @@ int opteron_workaround_6336786_UP = 0; /* Not needed for UP */
int opteron_workaround_6323525; /* if non-zero -> at least one cpu has it */
#endif
-#define WARNING(cpu, n) \
- cmn_err(CE_WARN, "cpu%d: no workaround for erratum %d", \
- (cpu)->cpu_id, (n))
+static void
+workaround_warning(cpu_t *cp, uint_t erratum)
+{
+ cmn_err(CE_WARN, "cpu%d: no workaround for erratum %u",
+ cp->cpu_id, erratum);
+}
+
+static void
+workaround_applied(uint_t erratum)
+{
+ if (erratum > 1000000)
+ cmn_err(CE_CONT, "?workaround applied for cpu issue #%d\n",
+ erratum);
+ else
+ cmn_err(CE_CONT, "?workaround applied for cpu erratum #%d\n",
+ erratum);
+}
+
+static void
+msr_warning(cpu_t *cp, const char *rw, uint_t msr, int error)
+{
+ cmn_err(CE_WARN, "cpu%d: couldn't %smsr 0x%x, error %d",
+ cp->cpu_id, rw, msr, error);
+}
uint_t
workaround_errata(struct cpu *cpu)
@@ -589,8 +598,9 @@ workaround_errata(struct cpu *cpu)
/*
* The workaround is an mfence in the relevant assembler code
*/
+ opteron_erratum_88++;
#else
- WARNING(cpu, 88);
+ workaround_warning(cpu, 88);
missing++;
#endif
}
@@ -605,7 +615,7 @@ workaround_errata(struct cpu *cpu)
*/
opteron_erratum_91++;
#else
- WARNING(cpu, 91);
+ workaround_warning(cpu, 91);
missing++;
#endif
}
@@ -620,7 +630,7 @@ workaround_errata(struct cpu *cpu)
*/
opteron_erratum_93++;
#else
- WARNING(cpu, 93);
+ workaround_warning(cpu, 93);
missing++;
#endif
}
@@ -642,11 +652,12 @@ workaround_errata(struct cpu *cpu)
/*LINTED*/
ASSERT((uint32_t)COREHEAP_BASE == 0xc0000000u);
+ opteron_erratum_95++;
#endif /* _LP64 */
#else
- WARNING(cpu, 95);
+ workaround_warning(cpu, 95);
missing++;
-#endif /* OPTERON_ERRATUM_95 */
+#endif
}
if (cpuid_opteron_erratum(cpu, 100) > 0) {
@@ -659,7 +670,7 @@ workaround_errata(struct cpu *cpu)
*/
opteron_erratum_100++;
#else
- WARNING(cpu, 100);
+ workaround_warning(cpu, 100);
missing++;
#endif
}
@@ -676,26 +687,38 @@ workaround_errata(struct cpu *cpu)
* those processors)
*/
#else
- WARNING(cpu, 108);
+ workaround_warning(cpu, 108);
missing++;
#endif
}
/*LINTED*/
- if (cpuid_opteron_erratum(cpu, 109) > 0) {
+ if (cpuid_opteron_erratum(cpu, 109) > 0) do {
/*
* Certain Reverse REP MOVS May Produce Unpredictable Behaviour
*/
#if defined(OPTERON_ERRATUM_109)
-
- /* workaround is to print a warning to upgrade BIOS */
- if (rdmsr(MSR_AMD_PATCHLEVEL) == 0)
+ /*
+ * The "workaround" is to print a warning to upgrade the BIOS
+ */
+ uint64_t value;
+ const uint_t msr = MSR_AMD_PATCHLEVEL;
+ int err;
+
+ if ((err = checked_rdmsr(msr, &value)) != 0) {
+ msr_warning(cpu, "rd", msr, err);
+ workaround_warning(cpu, 109);
+ missing++;
+ }
+ if (value == 0)
opteron_erratum_109++;
#else
- WARNING(cpu, 109);
+ workaround_warning(cpu, 109);
missing++;
#endif
- }
+ /*CONSTANTCONDITION*/
+ } while (0);
+
/*LINTED*/
if (cpuid_opteron_erratum(cpu, 121) > 0) {
/*
@@ -703,132 +726,160 @@ workaround_errata(struct cpu *cpu)
* Processor Hang
*/
#if defined(OPTERON_ERRATUM_121)
- static int lma;
-
- if (opteron_erratum_121)
- opteron_erratum_121++;
-
+#if defined(_LP64)
/*
* Erratum 121 is only present in long (64 bit) mode.
* Workaround is to include the page immediately before the
* va hole to eliminate the possibility of system hangs due to
* sequential execution across the va hole boundary.
*/
- if (lma == 0) {
- /*
- * check LMA once: assume all cpus are in long mode
- * or not.
- */
- lma = 1;
-
- if (rdmsr(MSR_AMD_EFER) & AMD_EFER_LMA) {
- if (hole_start) {
- hole_start -= PAGESIZE;
- } else {
- /*
- * hole_start not yet initialized by
- * mmu_init. Initialize hole_start
- * with value to be subtracted.
- */
- hole_start = PAGESIZE;
- }
- opteron_erratum_121++;
+ if (opteron_erratum_121)
+ opteron_erratum_121++;
+ else {
+ if (hole_start) {
+ hole_start -= PAGESIZE;
+ } else {
+ /*
+ * hole_start not yet initialized by
+ * mmu_init. Initialize hole_start
+ * with value to be subtracted.
+ */
+ hole_start = PAGESIZE;
}
+ opteron_erratum_121++;
}
+#endif /* _LP64 */
#else
- WARNING(cpu, 121);
+ workaround_warning(cpu, 121);
missing++;
#endif
}
/*LINTED*/
- if (cpuid_opteron_erratum(cpu, 122) > 0) {
+ if (cpuid_opteron_erratum(cpu, 122) > 0) do {
/*
- * TLB Flush Filter May Cause Cohenrency Problem in
+ * TLB Flush Filter May Cause Coherency Problem in
* Multiprocessor Systems
*/
#if defined(OPTERON_ERRATUM_122)
+ uint64_t value;
+ const uint_t msr = MSR_AMD_HWCR;
+ int error;
+
/*
* Erratum 122 is only present in MP configurations (multi-core
* or multi-processor).
*/
-
- if (opteron_erratum_122 || lgrp_plat_node_cnt > 1 ||
- cpuid_get_ncpu_per_chip(cpu) > 1) {
- /* disable TLB Flush Filter */
- wrmsr(MSR_AMD_HWCR, rdmsr(MSR_AMD_HWCR) |
- (uint64_t)(uintptr_t)AMD_HWCR_FFDIS);
- opteron_erratum_122++;
+ if (!opteron_erratum_122 && lgrp_plat_node_cnt == 1 &&
+ cpuid_get_ncpu_per_chip(cpu) == 1)
+ break;
+
+ /* disable TLB Flush Filter */
+
+ if ((error = checked_rdmsr(msr, &value)) != 0) {
+ msr_warning(cpu, "rd", msr, error);
+ workaround_warning(cpu, 122);
+ missing++;
+ } else {
+ value |= (uint64_t)AMD_HWCR_FFDIS;
+ if ((error = checked_wrmsr(msr, value)) != 0) {
+ msr_warning(cpu, "wr", msr, error);
+ workaround_warning(cpu, 122);
+ missing++;
+ }
}
-
+ opteron_erratum_122++;
#else
- WARNING(cpu, 122);
+ workaround_warning(cpu, 122);
missing++;
#endif
- }
+ /*CONSTANTCONDITION*/
+ } while (0);
-#if defined(OPTERON_ERRATUM_123)
/*LINTED*/
- if (cpuid_opteron_erratum(cpu, 123) > 0) {
+ if (cpuid_opteron_erratum(cpu, 123) > 0) do {
/*
* Bypassed Reads May Cause Data Corruption of System Hang in
* Dual Core Processors
*/
+#if defined(OPTERON_ERRATUM_123)
+ uint64_t value;
+ const uint_t msr = MSR_AMD_PATCHLEVEL;
+ int err;
+
/*
* Erratum 123 applies only to multi-core cpus.
*/
+ if (cpuid_get_ncpu_per_chip(cpu) < 2)
+ break;
- if (cpuid_get_ncpu_per_chip(cpu) > 1) {
- /* workaround is to print a warning to upgrade BIOS */
- if (rdmsr(MSR_AMD_PATCHLEVEL) == 0)
- opteron_erratum_123++;
+ /*
+ * The "workaround" is to print a warning to upgrade the BIOS
+ */
+ if ((err = checked_rdmsr(msr, &value)) != 0) {
+ msr_warning(cpu, "rd", msr, err);
+ workaround_warning(cpu, 123);
+ missing++;
}
- }
+ if (value == 0)
+ opteron_erratum_123++;
+#else
+ workaround_warning(cpu, 123);
+ missing++;
+
#endif
+ /*CONSTANTCONDITION*/
+ } while (0);
-#if defined(OPTERON_ERRATUM_131)
/*LINTED*/
- if (cpuid_opteron_erratum(cpu, 131) > 0) {
+ if (cpuid_opteron_erratum(cpu, 131) > 0) do {
/*
* Multiprocessor Systems with Four or More Cores May Deadlock
* Waiting for a Probe Response
*/
+#if defined(OPTERON_ERRATUM_131)
+ uint64_t nbcfg;
+ const uint_t msr = MSR_AMD_NB_CFG;
+ const uint64_t wabits =
+ AMD_NB_CFG_SRQ_HEARTBEAT | AMD_NB_CFG_SRQ_SPR;
+ int error;
+
/*
* Erratum 131 applies to any system with four or more cores.
*/
- if ((opteron_erratum_131 == 0) && ((lgrp_plat_node_cnt *
- cpuid_get_ncpu_per_chip(cpu)) >= 4)) {
- uint64_t nbcfg;
- uint64_t wabits;
+ if (opteron_erratum_131)
+ break;
- /*
- * Print a warning if neither of the workarounds
- * for Erratum 131 is present.
- */
+ if (lgrp_plat_node_cnt * cpuid_get_ncpu_per_chip(cpu) < 4)
+ break;
- wabits = AMD_NB_CFG_SRQ_HEARTBEAT |
- AMD_NB_CFG_SRQ_SPR;
-
- nbcfg = rdmsr(MSR_AMD_NB_CFG);
- if ((nbcfg & wabits) == 0) {
- opteron_erratum_131++;
- } else {
- /* cannot have both workarounds set */
- ASSERT((nbcfg & wabits) != wabits);
- }
+ /*
+ * Print a warning if neither of the workarounds for
+ * erratum 131 is present.
+ */
+ if ((error = checked_rdmsr(msr, &nbcfg)) != 0) {
+ msr_warning(cpu, "rd", msr, error);
+ workaround_warning(cpu, 131);
+ missing++;
+ } else if ((nbcfg & wabits) == 0) {
+ opteron_erratum_131++;
+ } else {
+ /* cannot have both workarounds set */
+ ASSERT((nbcfg & wabits) != wabits);
}
- }
+#else
+ workaround_warning(cpu, 131);
+ missing++;
#endif
+ /*CONSTANTCONDITION*/
+ } while (0);
-#if defined(OPTERON_WORKAROUND_6336786)
/*
- * This isn't really erratum, but for convenience the
+ * This isn't really an erratum, but for convenience the
* detection/workaround code lives here and in cpuid_opteron_erratum.
*/
if (cpuid_opteron_erratum(cpu, 6336786) > 0) {
- int node;
- uint8_t data;
-
+#if defined(OPTERON_WORKAROUND_6336786)
/*
* Disable C1-Clock ramping on multi-core/multi-processor
* K8 platforms to guard against TSC drift.
@@ -836,8 +887,11 @@ workaround_errata(struct cpu *cpu)
if (opteron_workaround_6336786) {
opteron_workaround_6336786++;
} else if ((lgrp_plat_node_cnt *
- cpuid_get_ncpu_per_chip(cpu) >= 2) ||
+ cpuid_get_ncpu_per_chip(cpu) > 1) ||
opteron_workaround_6336786_UP) {
+ int node;
+ uint8_t data;
+
for (node = 0; node < lgrp_plat_node_cnt; node++) {
/*
* Clear PMM7[1:0] (function 3, offset 0x87)
@@ -849,18 +903,20 @@ workaround_errata(struct cpu *cpu)
}
opteron_workaround_6336786++;
}
- }
+#else
+ workaround_warning(cpu, 6336786);
+ missing++;
#endif
+ }
-#if defined(OPTERON_WORKAROUND_6323525)
/*LINTED*/
/*
* Mutex primitives don't work as expected.
*/
if (cpuid_opteron_erratum(cpu, 6323525) > 0) {
-
+#if defined(OPTERON_WORKAROUND_6323525)
/*
- * problem only occurs with 2 or more cores. If bit in
+ * This problem only occurs with 2 or more cores. If bit in
* MSR_BU_CFG set, then not applicable. The workaround
* is to patch the semaphone routines with the lfence
* instruction to provide necessary load memory barrier with
@@ -872,18 +928,46 @@ workaround_errata(struct cpu *cpu)
if (opteron_workaround_6323525) {
opteron_workaround_6323525++;
} else if ((x86_feature & X86_SSE2) && ((lgrp_plat_node_cnt *
- cpuid_get_ncpu_per_chip(cpu)) >= 2)) {
+ cpuid_get_ncpu_per_chip(cpu)) > 1)) {
if ((xrdmsr(MSR_BU_CFG) & 0x02) == 0)
opteron_workaround_6323525++;
}
- }
+#else
+ workaround_warning(cpu, 6323525);
+ missing++;
#endif
+ }
+
return (missing);
}
void
workaround_errata_end()
{
+#if defined(OPTERON_ERRATUM_88)
+ if (opteron_erratum_88)
+ workaround_applied(88);
+#endif
+#if defined(OPTERON_ERRATUM_91)
+ if (opteron_erratum_91)
+ workaround_applied(91);
+#endif
+#if defined(OPTERON_ERRATUM_93)
+ if (opteron_erratum_93)
+ workaround_applied(93);
+#endif
+#if defined(OPTERON_ERRATUM_95)
+ if (opteron_erratum_95)
+ workaround_applied(95);
+#endif
+#if defined(OPTERON_ERRATUM_100)
+ if (opteron_erratum_100)
+ workaround_applied(100);
+#endif
+#if defined(OPTERON_ERRATUM_108)
+ if (opteron_erratum_108)
+ workaround_applied(108);
+#endif
#if defined(OPTERON_ERRATUM_109)
if (opteron_erratum_109) {
cmn_err(CE_WARN,
@@ -893,7 +977,15 @@ workaround_errata_end()
" microcode patch is HIGHLY recommended or erroneous"
" system\noperation may occur.\n");
}
-#endif /* OPTERON_ERRATUM_109 */
+#endif
+#if defined(OPTERON_ERRATUM_121)
+ if (opteron_erratum_121)
+ workaround_applied(121);
+#endif
+#if defined(OPTERON_ERRATUM_122)
+ if (opteron_erratum_122)
+ workaround_applied(122);
+#endif
#if defined(OPTERON_ERRATUM_123)
if (opteron_erratum_123) {
cmn_err(CE_WARN,
@@ -903,7 +995,7 @@ workaround_errata_end()
" microcode patch is HIGHLY recommended or erroneous"
" system\noperation may occur.\n");
}
-#endif /* OPTERON_ERRATUM_123 */
+#endif
#if defined(OPTERON_ERRATUM_131)
if (opteron_erratum_131) {
cmn_err(CE_WARN,
@@ -913,24 +1005,125 @@ workaround_errata_end()
" microcode patch is HIGHLY recommended or erroneous"
" system\noperation may occur.\n");
}
-#endif /* OPTERON_ERRATUM_131 */
+#endif
+#if defined(OPTERON_WORKAROUND_6336786)
+ if (opteron_workaround_6336786)
+ workaround_applied(6336786);
+#endif
+#if defined(OPTERON_WORKAROUND_6323525)
+ if (opteron_workaround_6323525)
+ workaround_applied(6323525);
+#endif
}
-static ushort_t *mp_map_warm_reset_vector();
-static void mp_unmap_warm_reset_vector(ushort_t *warm_reset_vector);
+static cpuset_t procset;
+
+/*
+ * Start a single cpu, assuming that the kernel context is available
+ * to successfully start another cpu.
+ *
+ * (For example, real mode code is mapped into the right place
+ * in memory and is ready to be run.)
+ */
+int
+start_cpu(processorid_t who)
+{
+ void *ctx;
+ cpu_t *cp;
+ int delays;
+ int error = 0;
+
+ ASSERT(who != 0);
+
+ /*
+ * Check if there's at least a Mbyte of kmem available
+ * before attempting to start the cpu.
+ */
+ if (kmem_avail() < 1024 * 1024) {
+ /*
+ * Kick off a reap in case that helps us with
+ * later attempts ..
+ */
+ kmem_reap();
+ return (ENOMEM);
+ }
+
+ cp = mp_startup_init(who);
+ if ((ctx = mach_cpucontext_alloc(cp)) == NULL ||
+ (error = mach_cpu_start(cp, ctx)) != 0) {
+
+ /*
+ * Something went wrong before we even started it
+ */
+ if (ctx)
+ cmn_err(CE_WARN,
+ "cpu%d: failed to start error %d",
+ cp->cpu_id, error);
+ else
+ cmn_err(CE_WARN,
+ "cpu%d: failed to allocate context", cp->cpu_id);
+
+ if (ctx)
+ mach_cpucontext_free(cp, ctx, error);
+ else
+ error = EAGAIN; /* hmm. */
+ mp_startup_fini(cp, error);
+ return (error);
+ }
+
+ for (delays = 0; !CPU_IN_SET(procset, who); delays++) {
+ if (delays == 500) {
+ /*
+ * After five seconds, things are probably looking
+ * a bit bleak - explain the hang.
+ */
+ cmn_err(CE_NOTE, "cpu%d: started, "
+ "but not running in the kernel yet", who);
+ } else if (delays > 2000) {
+ /*
+ * We waited at least 20 seconds, bail ..
+ */
+ error = ETIMEDOUT;
+ cmn_err(CE_WARN, "cpu%d: timed out", who);
+ mach_cpucontext_free(cp, ctx, error);
+ mp_startup_fini(cp, error);
+ return (error);
+ }
+
+ /*
+ * wait at least 10ms, then check again..
+ */
+ delay(USEC_TO_TICK_ROUNDUP(10000));
+ }
+
+ mach_cpucontext_free(cp, ctx, 0);
+
+ if (tsc_gethrtime_enable)
+ tsc_sync_master(who);
+
+ if (dtrace_cpu_init != NULL) {
+ /*
+ * DTrace CPU initialization expects cpu_lock to be held.
+ */
+ mutex_enter(&cpu_lock);
+ (*dtrace_cpu_init)(who);
+ mutex_exit(&cpu_lock);
+ }
+
+ while (!CPU_IN_SET(cpu_ready_set, who))
+ delay(1);
+
+ return (0);
+}
-static cpuset_t procset = 1;
/*ARGSUSED*/
void
start_other_cpus(int cprboot)
{
- unsigned int who;
- int skipped = 0;
- int cpuid = 0;
- int delays = 0;
- int started_cpu;
- ushort_t *warm_reset_vector = NULL;
+ uint_t who;
+ uint_t skipped = 0;
+ uint_t bootcpuid = 0;
/*
* Initialize our own cpu_info.
@@ -943,9 +1136,17 @@ start_other_cpus(int cprboot)
init_cpu_syscall(CPU);
/*
+ * Take the boot cpu out of the mp_cpus set because we know
+ * it's already running. Add it to the cpu_ready_set for
+ * precisely the same reason.
+ */
+ CPUSET_DEL(mp_cpus, bootcpuid);
+ CPUSET_ADD(cpu_ready_set, bootcpuid);
+
+ /*
* if only 1 cpu or not using MP, skip the rest of this
*/
- if (CPUSET_ISEQUAL(mp_cpus, cpu_ready_set) || use_mp == 0) {
+ if (CPUSET_ISNULL(mp_cpus) || use_mp == 0) {
if (use_mp == 0)
cmn_err(CE_CONT, "?***** Not in MP mode\n");
goto done;
@@ -959,23 +1160,11 @@ start_other_cpus(int cprboot)
xc_init(); /* initialize processor crosscalls */
- /*
- * Copy the real mode code at "real_mode_start" to the
- * page at rm_platter_va.
- */
- warm_reset_vector = mp_map_warm_reset_vector();
- if (warm_reset_vector == NULL)
+ if (mach_cpucontext_init() != 0)
goto done;
- bcopy((caddr_t)real_mode_start,
- (caddr_t)((rm_platter_t *)rm_platter_va)->rm_code,
- (size_t)real_mode_end - (size_t)real_mode_start);
-
flushes_require_xcalls = 1;
- ASSERT(CPU_IN_SET(procset, cpuid));
- ASSERT(CPU_IN_SET(cpu_ready_set, cpuid));
-
/*
* We lock our affinity to the master CPU to ensure that all slave CPUs
* do their TSC syncs with the same CPU.
@@ -983,67 +1172,24 @@ start_other_cpus(int cprboot)
affinity_set(CPU_CURRENT);
for (who = 0; who < NCPU; who++) {
- if (who == cpuid)
- continue;
-
- delays = 0;
if (!CPU_IN_SET(mp_cpus, who))
continue;
-
+ ASSERT(who != bootcpuid);
if (ncpus >= max_ncpus) {
skipped = who;
continue;
}
-
- mp_startup_init(who);
- started_cpu = 1;
- (*cpu_startf)(who, rm_platter_pa);
-
- while (!CPU_IN_SET(procset, who)) {
- delay(1);
- if (++delays > (20 * hz)) {
-
- cmn_err(CE_WARN,
- "cpu%d failed to start", who);
-
- mutex_enter(&cpu_lock);
- cpu[who]->cpu_flags = 0;
- cpu_vm_data_destroy(cpu[who]);
- cpu_del_unit(who);
- mutex_exit(&cpu_lock);
-
- started_cpu = 0;
- break;
- }
- }
- if (!started_cpu)
- continue;
- if (tsc_gethrtime_enable)
- tsc_sync_master(who);
-
+ if (start_cpu(who) != 0)
+ CPUSET_DEL(mp_cpus, who);
}
affinity_clear();
- /*
- * Wait for all CPUs that booted (have presence in procset)
- * to come online (have presence in cpu_ready_set). Note
- * that the start CPU already satisfies both of these, so no
- * special case is needed.
- */
- for (who = 0; who < NCPU; who++) {
- if (!CPU_IN_SET(procset, who))
- continue;
-
- while (!CPU_IN_SET(cpu_ready_set, who))
- delay(1);
- }
-
if (skipped) {
cmn_err(CE_NOTE,
- "System detected %d CPU(s), but "
- "only %d CPU(s) were enabled during boot.",
+ "System detected %d cpus, but "
+ "only %d cpu(s) were enabled during boot.",
skipped + 1, ncpus);
cmn_err(CE_NOTE,
"Use \"boot-ncpus\" parameter to enable more CPU(s). "
@@ -1052,11 +1198,7 @@ start_other_cpus(int cprboot)
done:
workaround_errata_end();
-
- if (warm_reset_vector != NULL)
- mp_unmap_warm_reset_vector(warm_reset_vector);
- hat_unload(kas.a_hat, (caddr_t)(uintptr_t)rm_platter_pa, MMU_PAGESIZE,
- HAT_UNLOAD);
+ mach_cpucontext_fini();
cmi_post_mpstartup();
}
@@ -1124,6 +1266,13 @@ mp_startup(void)
mtrr_sync();
/*
+ * Set up TSC_AUX to contain the cpuid for this processor
+ * for the rdtscp instruction.
+ */
+ if (x86_feature & X86_TSCP)
+ (void) wrmsr(MSR_AMD_TSCAUX, cp->cpu_id);
+
+ /*
* Initialize this CPU's syscall handlers
*/
init_cpu_syscall(cp);
@@ -1136,7 +1285,8 @@ mp_startup(void)
* device interrupts that may end up in the hat layer issuing cross
* calls before CPU_READY is set.
*/
- (void) splx(ipltospl(LOCK_LEVEL));
+ splx(ipltospl(LOCK_LEVEL));
+ sti();
/*
* Do a sanity check to make sure this new CPU is a sane thing
@@ -1218,7 +1368,7 @@ mp_startup(void)
cmi_mca_init();
if (boothowto & RB_DEBUG)
- kdi_dvec_cpu_init(cp);
+ kdi_cpu_init();
/*
* Setting the bit in cpu_ready_set must be the last operation in
@@ -1277,29 +1427,6 @@ mp_cpu_stop(struct cpu *cp)
}
/*
- * Power on CPU.
- */
-/* ARGSUSED */
-int
-mp_cpu_poweron(struct cpu *cp)
-{
- ASSERT(MUTEX_HELD(&cpu_lock));
- return (ENOTSUP); /* not supported */
-}
-
-/*
- * Power off CPU.
- */
-/* ARGSUSED */
-int
-mp_cpu_poweroff(struct cpu *cp)
-{
- ASSERT(MUTEX_HELD(&cpu_lock));
- return (ENOTSUP); /* not supported */
-}
-
-
-/*
* Take the specified CPU out of participation in interrupts.
*/
int
@@ -1325,34 +1452,6 @@ cpu_enable_intr(struct cpu *cp)
-static ushort_t *
-mp_map_warm_reset_vector()
-{
- ushort_t *warm_reset_vector;
-
- if (!(warm_reset_vector = (ushort_t *)psm_map_phys(WARM_RESET_VECTOR,
- sizeof (ushort_t *), PROT_READ|PROT_WRITE)))
- return (NULL);
-
- /*
- * setup secondary cpu bios boot up vector
- */
- *warm_reset_vector = (ushort_t)((caddr_t)
- ((struct rm_platter *)rm_platter_va)->rm_code - rm_platter_va
- + ((ulong_t)rm_platter_va & 0xf));
- warm_reset_vector++;
- *warm_reset_vector = (ushort_t)(rm_platter_pa >> 4);
-
- --warm_reset_vector;
- return (warm_reset_vector);
-}
-
-static void
-mp_unmap_warm_reset_vector(ushort_t *warm_reset_vector)
-{
- psm_unmap_phys((caddr_t)warm_reset_vector, sizeof (ushort_t *));
-}
-
void
mp_cpu_faulted_enter(struct cpu *cp)
{
@@ -1379,9 +1478,9 @@ mp_cpu_faulted_exit(struct cpu *cp)
void
cpu_fast_syscall_disable(void *arg)
{
- if (x86_feature & X86_SEP)
+ if ((x86_feature & (X86_MSR | X86_SEP)) == (X86_MSR | X86_SEP))
cpu_sep_disable();
- if (x86_feature & X86_ASYSC)
+ if ((x86_feature & (X86_MSR | X86_ASYSC)) == (X86_MSR | X86_ASYSC))
cpu_asysc_disable();
}
@@ -1389,9 +1488,9 @@ cpu_fast_syscall_disable(void *arg)
void
cpu_fast_syscall_enable(void *arg)
{
- if (x86_feature & X86_SEP)
+ if ((x86_feature & (X86_MSR | X86_SEP)) == (X86_MSR | X86_SEP))
cpu_sep_enable();
- if (x86_feature & X86_ASYSC)
+ if ((x86_feature & (X86_MSR | X86_ASYSC)) == (X86_MSR | X86_ASYSC))
cpu_asysc_enable();
}
@@ -1414,7 +1513,7 @@ cpu_sep_disable(void)
* Setting the SYSENTER_CS_MSR register to 0 causes software executing
* the sysenter or sysexit instruction to trigger a #gp fault.
*/
- wrmsr(MSR_INTC_SEP_CS, 0ULL);
+ wrmsr(MSR_INTC_SEP_CS, 0);
}
static void
diff --git a/usr/src/uts/i86pc/os/startup.c b/usr/src/uts/i86pc/os/startup.c
index 6d7954db30..d082635a8d 100644
--- a/usr/src/uts/i86pc/os/startup.c
+++ b/usr/src/uts/i86pc/os/startup.c
@@ -46,6 +46,7 @@
#include <sys/proc.h>
#include <sys/buf.h>
#include <sys/kmem.h>
+#include <sys/mem.h>
#include <sys/kstat.h>
#include <sys/reboot.h>
@@ -111,6 +112,11 @@
#include <sys/x86_archext.h>
#include <sys/cpu_module.h>
#include <sys/smbios.h>
+#include <sys/debug_info.h>
+
+
+#include <sys/bootinfo.h>
+#include <vm/kboot_mmu.h>
extern void progressbar_init(void);
extern void progressbar_start(void);
@@ -130,8 +136,8 @@ extern int segkp_fromheap;
static void kvm_init(void);
static void startup_init(void);
static void startup_memlist(void);
+static void startup_kmem(void);
static void startup_modules(void);
-static void startup_bop_gone(void);
static void startup_vm(void);
static void startup_end(void);
@@ -187,14 +193,6 @@ size_t kpm_size;
static int kpm_desired = 0; /* Do we want to try to use segkpm? */
/*
- * VA range that must be preserved for boot until we release all of its
- * mappings.
- */
-#if defined(__amd64)
-static void *kmem_setaside;
-#endif
-
-/*
* Configuration parameters set at boot time.
*/
@@ -241,6 +239,8 @@ struct seg kmapseg; /* Segment used for generic kernel mappings */
struct seg kdebugseg; /* Segment used for the kernel debugger */
struct seg *segkmap = &kmapseg; /* Kernel generic mapping segment */
+static struct seg *segmap = &kmapseg; /* easier to use name for in here */
+
struct seg *segkp = &kpseg; /* Pageable kernel virtual memory segment */
#if defined(__amd64)
@@ -260,6 +260,12 @@ pgcnt_t segkpsize = 0;
#endif
pgcnt_t segziosize = 0; /* size of zio segment in pages */
+/*
+ * VA range available to the debugger
+ */
+const caddr_t kdi_segdebugbase = (const caddr_t)SEGDEBUGBASE;
+const size_t kdi_segdebugsize = SEGDEBUGSIZE;
+
struct memseg *memseg_base;
struct vnode unused_pages_vp;
@@ -279,13 +285,10 @@ caddr_t e_moddata; /* end of loadable module data reserved */
struct memlist *phys_install; /* Total installed physical memory */
struct memlist *phys_avail; /* Total available physical memory */
-static void memlist_add(uint64_t, uint64_t, struct memlist *,
- struct memlist **);
-
/*
* kphysm_init returns the number of pages that were processed
*/
-static pgcnt_t kphysm_init(page_t *, struct memseg *, pgcnt_t, pgcnt_t);
+static pgcnt_t kphysm_init(page_t *, pgcnt_t);
#define IO_PROP_SIZE 64 /* device property size */
@@ -297,15 +300,14 @@ static pgcnt_t kphysm_init(page_t *, struct memseg *, pgcnt_t, pgcnt_t);
#define ROUND_UP_LPAGE(x) \
((uintptr_t)P2ROUNDUP((uintptr_t)(x), mmu.level_size[1]))
#define ROUND_UP_4MEG(x) \
- ((uintptr_t)P2ROUNDUP((uintptr_t)(x), (uintptr_t)FOURMB_PAGESIZE))
+ ((uintptr_t)P2ROUNDUP((uintptr_t)(x), (uintptr_t)FOUR_MEG))
#define ROUND_UP_TOPLEVEL(x) \
((uintptr_t)P2ROUNDUP((uintptr_t)(x), mmu.level_size[mmu.max_level]))
/*
* 32-bit Kernel's Virtual memory layout.
* +-----------------------+
- * | psm 1-1 map |
- * | exec args area |
+ * | |
* 0xFFC00000 -|-----------------------|- ARGSBASE
* | debugger |
* 0xFF800000 -|-----------------------|- SEGDEBUGBASE
@@ -313,23 +315,21 @@ static pgcnt_t kphysm_init(page_t *, struct memseg *, pgcnt_t, pgcnt_t);
* 0xFEC00000 -|-----------------------|
* | Kernel Text |
* 0xFE800000 -|-----------------------|- KERNEL_TEXT
- * | LUFS sinkhole |
- * 0xFE000000 -|-----------------------|- lufs_addr
- * --- -|-----------------------|- valloc_base + valloc_sz
- * | early pp structures |
+ * |--- GDT ---|- GDT page (GDT_VA)
+ * |--- debug info ---|- debug info (DEBUG_INFO_VA)
+ * | |
+ * | page_t structures |
* | memsegs, memlists, |
* | page hash, etc. |
- * --- -|-----------------------|- valloc_base (floating)
- * | ptable_va |
- * 0xFDFFE000 -|-----------------------|- ekernelheap, ptable_va
- * | | (segkp is an arena under the heap)
+ * --- -|-----------------------|- ekernelheap, valloc_base (floating)
+ * | | (segkp is just an arena in the heap)
* | |
* | kvseg |
* | |
* | |
* --- -|-----------------------|- kernelheap (floating)
* | Segkmap |
- * 0xC3002000 -|-----------------------|- segkmap_start (floating)
+ * 0xC3002000 -|-----------------------|- segmap_start (floating)
* | Red Zone |
* 0xC3000000 -|-----------------------|- kernelbase / userlimit (floating)
* | | ||
@@ -348,8 +348,7 @@ static pgcnt_t kphysm_init(page_t *, struct memseg *, pgcnt_t, pgcnt_t);
*
* 64-bit Kernel's Virtual memory layout. (assuming 64 bit app)
* +-----------------------+
- * | psm 1-1 map |
- * | exec args area |
+ * | |
* 0xFFFFFFFF.FFC00000 |-----------------------|- ARGSBASE
* | debugger (?) |
* 0xFFFFFFFF.FF800000 |-----------------------|- SEGDEBUGBASE
@@ -359,28 +358,26 @@ static pgcnt_t kphysm_init(page_t *, struct memseg *, pgcnt_t, pgcnt_t);
* 0xFFFFFFFF.FBC00000 |-----------------------|
* | Kernel Text |
* 0xFFFFFFFF.FB800000 |-----------------------|- KERNEL_TEXT
- * | LUFS sinkhole |
- * 0xFFFFFFFF.FB000000 -|-----------------------|- lufs_addr
- * --- |-----------------------|- valloc_base + valloc_sz
- * | early pp structures |
- * | memsegs, memlists, |
- * | page hash, etc. |
- * --- |-----------------------|- valloc_base
- * | ptable_va |
- * --- |-----------------------|- ptable_va
+ * |--- GDT ---|- GDT page (GDT_VA)
+ * |--- debug info ---|- debug info (DEBUG_INFO_VA)
+ * | |
* | Core heap | (used for loadable modules)
* 0xFFFFFFFF.C0000000 |-----------------------|- core_base / ekernelheap
* | Kernel |
* | heap |
* 0xFFFFFXXX.XXX00000 |-----------------------|- kernelheap (floating)
- * | segkmap |
- * 0xFFFFFXXX.XXX00000 |-----------------------|- segkmap_start (floating)
+ * | segmap |
+ * 0xFFFFFXXX.XXX00000 |-----------------------|- segmap_start (floating)
* | device mappings |
* 0xFFFFFXXX.XXX00000 |-----------------------|- toxic_addr (floating)
* | segzio |
* 0xFFFFFXXX.XXX00000 |-----------------------|- segzio_base (floating)
* | segkp |
- * --- |-----------------------|- segkp_base
+ * --- |-----------------------|- segkp_base (floating)
+ * | page_t structures | valloc_base + valloc_sz
+ * | memsegs, memlists, |
+ * | page hash, etc. |
+ * 0xFFFFFF00.00000000 |-----------------------|- valloc_base
* | segkpm |
* 0xFFFFFE00.00000000 |-----------------------|
* | Red Zone |
@@ -413,8 +410,8 @@ static pgcnt_t kphysm_init(page_t *, struct memseg *, pgcnt_t, pgcnt_t);
* Floating values:
*
* valloc_base: start of the kernel's memory management/tracking data
- * structures. This region contains page_t structures for the lowest 4GB
- * of physical memory, memsegs, memlists, and the page hash.
+ * structures. This region contains page_t structures for
+ * physical memory, memsegs, memlists, and the page hash.
*
* core_base: start of the kernel's "core" heap area on 64-bit systems.
* This area is intended to be used for global data as well as for module
@@ -428,7 +425,7 @@ static pgcnt_t kphysm_init(page_t *, struct memseg *, pgcnt_t, pgcnt_t);
* above a red zone that separates the user's address space from the
* kernel's. On 64-bit systems, it sits above segkp and segkpm.
*
- * segkmap_start: start of segmap. The length of segmap can be modified
+ * segmap_start: start of segmap. The length of segmap can be modified
* by changing segmapsize in /etc/system (preferred) or eeprom (deprecated).
* The default length is 16MB on 32-bit systems and 64MB on 64-bit systems.
*
@@ -459,19 +456,19 @@ static pgcnt_t kphysm_init(page_t *, struct memseg *, pgcnt_t, pgcnt_t);
*/
/* real-time-clock initialization parameters */
-long gmt_lag; /* offset in seconds of gmt to local time */
-extern long process_rtc_config_file(void);
+extern time_t process_rtc_config_file(void);
char *final_kernelheap;
char *boot_kernelheap;
uintptr_t kernelbase;
+uintptr_t postbootkernelbase; /* not set till boot loader is gone */
uintptr_t eprom_kernelbase;
size_t segmapsize;
static uintptr_t segmap_reserved;
-uintptr_t segkmap_start;
+uintptr_t segmap_start;
int segmapfreelists;
-pgcnt_t boot_npages;
pgcnt_t npages;
+pgcnt_t orig_npages;
size_t core_size; /* size of "core" heap */
uintptr_t core_base; /* base address of "core" heap */
@@ -480,30 +477,20 @@ uintptr_t core_base; /* base address of "core" heap */
* release_bootstrap() will free them when we're completely done with
* the bootstrap.
*/
-static page_t *bootpages, *rd_pages;
+static page_t *bootpages;
+
+/*
+ * boot time pages that have a vnode from the ramdisk will keep that forever.
+ */
+static page_t *rd_pages;
struct system_hardware system_hardware;
/*
* Enable some debugging messages concerning memory usage...
- *
- * XX64 There should only be one print routine once memlist usage between
- * vmx and the kernel is cleaned up and there is a single memlist structure
- * shared between kernel and boot.
*/
static void
-print_boot_memlist(char *title, struct memlist *mp)
-{
- prom_printf("MEMLIST: %s:\n", title);
- while (mp != NULL) {
- prom_printf("\tAddress 0x%" PRIx64 ", size 0x%" PRIx64 "\n",
- mp->address, mp->size);
- mp = mp->next;
- }
-}
-
-static void
-print_kernel_memlist(char *title, struct memlist *mp)
+print_memlist(char *title, struct memlist *mp)
{
prom_printf("MEMLIST: %s:\n", title);
while (mp != NULL) {
@@ -529,7 +516,7 @@ int l2cache_assoc = 1;
vmem_t *device_arena;
uintptr_t toxic_addr = (uintptr_t)NULL;
-size_t toxic_size = 1 * 1024 * 1024 * 1024; /* Sparc uses 1 gig too */
+size_t toxic_size = 1024 * 1024 * 1024; /* Sparc uses 1 gig too */
#else /* __i386 */
@@ -566,8 +553,6 @@ struct {
} allocations[NUM_ALLOCATIONS];
size_t valloc_sz = 0;
uintptr_t valloc_base;
-extern uintptr_t ptable_va;
-extern size_t ptable_sz;
#define ADD_TO_ALLOCATIONS(ptr, size) { \
size = ROUND_UP_PAGE(size); \
@@ -579,13 +564,20 @@ extern size_t ptable_sz;
++num_allocations; \
}
+/*
+ * Allocate all the initial memory needed by the page allocator.
+ */
static void
perform_allocations(void)
{
caddr_t mem;
int i;
+ int valloc_align;
- mem = BOP_ALLOC(bootops, (caddr_t)valloc_base, valloc_sz, BO_NO_ALIGN);
+ PRM_DEBUG(valloc_base);
+ PRM_DEBUG(valloc_sz);
+ valloc_align = mmu.level_size[mmu.max_page_level > 0];
+ mem = BOP_ALLOC(bootops, (caddr_t)valloc_base, valloc_sz, valloc_align);
if (mem != (caddr_t)valloc_base)
panic("BOP_ALLOC() failed");
bzero(mem, valloc_sz);
@@ -607,9 +599,8 @@ perform_allocations(void)
* unix/genunix/krtld/module text loads.
*
* On the data page:
- * unix/genunix/krtld/module data loads and space for page_t's.
- */
-/*
+ * unix/genunix/krtld/module data loads.
+ *
* Machine-dependent startup code
*/
void
@@ -629,10 +620,10 @@ startup(void)
progressbar_init();
startup_init();
startup_memlist();
+ startup_kmem();
startup_pci_bios();
startup_modules();
startup_bios_disk();
- startup_bop_gone();
startup_vm();
startup_end();
progressbar_start();
@@ -707,7 +698,7 @@ avail_filter(uint64_t *addr, uint64_t *size)
}
/*
- * First we trim from the front of the range. Since hat_boot_probe()
+ * First we trim from the front of the range. Since kbm_probe()
* walks ranges in virtual order, but addr/size are physical, we need
* to the list until no changes are seen. This deals with the case
* where page "p" is mapped at v, page "p + PAGESIZE" is mapped at w
@@ -716,11 +707,11 @@ avail_filter(uint64_t *addr, uint64_t *size)
do {
change = 0;
for (va = KERNEL_TEXT;
- *size > 0 && hat_boot_probe(&va, &len, &pfn, &prot) != 0;
+ *size > 0 && kbm_probe(&va, &len, &pfn, &prot) != 0;
va = next_va) {
next_va = va + len;
- pfn_addr = ptob((uint64_t)pfn);
+ pfn_addr = pfn_to_pa(pfn);
pfn_eaddr = pfn_addr + len;
if (pfn_addr <= *addr && pfn_eaddr > *addr) {
@@ -741,11 +732,11 @@ avail_filter(uint64_t *addr, uint64_t *size)
* Trim pages from the end of the range.
*/
for (va = KERNEL_TEXT;
- *size > 0 && hat_boot_probe(&va, &len, &pfn, &prot) != 0;
+ *size > 0 && kbm_probe(&va, &len, &pfn, &prot) != 0;
va = next_va) {
next_va = va + len;
- pfn_addr = ptob((uint64_t)pfn);
+ pfn_addr = pfn_to_pa(pfn);
if (pfn_addr >= *addr && pfn_addr < *addr + *size)
*size = pfn_addr - *addr;
@@ -760,8 +751,6 @@ static void
kpm_init()
{
struct segkpm_crargs b;
- uintptr_t start, end;
- struct memlist *pmem;
/*
* These variables were all designed for sfmmu in which segkpm is
@@ -792,53 +781,39 @@ kpm_init()
panic("segkpm_create segkpm");
rw_exit(&kas.a_lock);
+}
- /*
- * Map each of the memsegs into the kpm segment, coalesing adjacent
- * memsegs to allow mapping with the largest possible pages.
- */
- pmem = phys_install;
- start = pmem->address;
- end = start + pmem->size;
- for (;;) {
- if (pmem == NULL || pmem->address > end) {
- hat_devload(kas.a_hat, kpm_vbase + start,
- end - start, mmu_btop(start),
- PROT_READ | PROT_WRITE,
- HAT_LOAD | HAT_LOAD_LOCK | HAT_LOAD_NOCONSIST);
- if (pmem == NULL)
- break;
- start = pmem->address;
- }
- end = pmem->address + pmem->size;
- pmem = pmem->next;
- }
+/*
+ * The debug info page provides enough information to allow external
+ * inspectors (e.g. when running under a hypervisor) to bootstrap
+ * themselves into allowing full-blown kernel debugging.
+ */
+static void
+init_debug_info(void)
+{
+ caddr_t mem;
+ debug_info_t *di;
+
+#ifndef __lint
+ ASSERT(sizeof (debug_info_t) < MMU_PAGESIZE);
+#endif
+
+ mem = BOP_ALLOC(bootops, (caddr_t)DEBUG_INFO_VA, MMU_PAGESIZE,
+ MMU_PAGESIZE);
+
+ if (mem != (caddr_t)DEBUG_INFO_VA)
+ panic("BOP_ALLOC() failed");
+ bzero(mem, MMU_PAGESIZE);
+
+ di = (debug_info_t *)mem;
+
+ di->di_magic = DEBUG_INFO_MAGIC;
+ di->di_version = DEBUG_INFO_VERSION;
}
/*
- * The purpose of startup memlist is to get the system to the
- * point where it can use kmem_alloc()'s that operate correctly
- * relying on BOP_ALLOC(). This includes allocating page_ts,
- * page hash table, vmem initialized, etc.
- *
- * Boot's versions of physinstalled and physavail are insufficient for
- * the kernel's purposes. Specifically we don't know which pages that
- * are not in physavail can be reclaimed after boot is gone.
- *
- * This code solves the problem by dividing the address space
- * into 3 regions as it takes over the MMU from the booter.
- *
- * 1) Any (non-nucleus) pages that are mapped at addresses above KERNEL_TEXT
- * can not be used by the kernel.
- *
- * 2) Any free page that happens to be mapped below kernelbase
- * is protected until the boot loader is released, but will then be reclaimed.
- *
- * 3) Boot shouldn't use any address in the remaining area between kernelbase
- * and KERNEL_TEXT.
- *
- * In the case of multiple mappings to the same page, region 1 has precedence
- * over region 2.
+ * Build the memlists and other kernel essential memory system data structures.
+ * This is everything at valloc_base.
*/
static void
startup_memlist(void)
@@ -857,55 +832,31 @@ startup_memlist(void)
caddr_t page_ctrs_mem;
size_t page_ctrs_size;
struct memlist *current;
- pgcnt_t orig_npages = 0;
extern void startup_build_mem_nodes(struct memlist *);
/* XX64 fix these - they should be in include files */
- extern ulong_t cr4_value;
extern size_t page_coloring_init(uint_t, int, int);
extern void page_coloring_setup(caddr_t);
PRM_POINT("startup_memlist() starting...");
/*
- * Take the most current snapshot we can by calling mem-update.
- * For this to work properly, we first have to ask boot for its
- * end address.
- */
- if (BOP_GETPROPLEN(bootops, "memory-update") == 0)
- (void) BOP_GETPROP(bootops, "memory-update", NULL);
-
- /*
- * find if the kernel is mapped on a large page
- */
- va = KERNEL_TEXT;
- if (hat_boot_probe(&va, &len, &pfn, &prot) == 0)
- panic("Couldn't find kernel text boot mapping");
-
- /*
* Use leftover large page nucleus text/data space for loadable modules.
* Use at most MODTEXT/MODDATA.
*/
- if (len > MMU_PAGESIZE) {
-
- moddata = (caddr_t)ROUND_UP_PAGE(e_data);
- e_moddata = (caddr_t)ROUND_UP_4MEG(e_data);
- if (e_moddata - moddata > MODDATA)
- e_moddata = moddata + MODDATA;
+ len = kbm_nucleus_size;
+ ASSERT(len > MMU_PAGESIZE);
- modtext = (caddr_t)ROUND_UP_PAGE(e_text);
- e_modtext = (caddr_t)ROUND_UP_4MEG(e_text);
- if (e_modtext - modtext > MODTEXT)
- e_modtext = modtext + MODTEXT;
+ moddata = (caddr_t)ROUND_UP_PAGE(e_data);
+ e_moddata = (caddr_t)P2ROUNDUP((uintptr_t)e_data, (uintptr_t)len);
+ if (e_moddata - moddata > MODDATA)
+ e_moddata = moddata + MODDATA;
+ modtext = (caddr_t)ROUND_UP_PAGE(e_text);
+ e_modtext = (caddr_t)P2ROUNDUP((uintptr_t)e_text, (uintptr_t)len);
+ if (e_modtext - modtext > MODTEXT)
+ e_modtext = modtext + MODTEXT;
- } else {
-
- PRM_POINT("Kernel NOT loaded on Large Page!");
- e_moddata = moddata = (caddr_t)ROUND_UP_PAGE(e_data);
- e_modtext = modtext = (caddr_t)ROUND_UP_PAGE(e_text);
-
- }
econtig = e_moddata;
PRM_DEBUG(modtext);
@@ -915,21 +866,13 @@ startup_memlist(void)
PRM_DEBUG(econtig);
/*
- * For MP machines cr4_value must be set or the non-boot
- * CPUs will not be able to start.
- */
- if (x86_feature & X86_LARGEPAGE)
- cr4_value = getcr4();
- PRM_DEBUG(cr4_value);
-
- /*
- * Examine the boot loaders physical memory map to find out:
+ * Examine the boot loader physical memory map to find out:
* - total memory in system - physinstalled
* - the max physical address - physmax
- * - the number of segments the intsalled memory comes in
+ * - the number of discontiguous segments of memory.
*/
if (prom_debug)
- print_boot_memlist("boot physinstalled",
+ print_memlist("boot physinstalled",
bootops->boot_mem->physinstalled);
installed_top_size(bootops->boot_mem->physinstalled, &physmax,
&physinstalled, &memblocks);
@@ -937,10 +880,6 @@ startup_memlist(void)
PRM_DEBUG(physinstalled);
PRM_DEBUG(memblocks);
- if (prom_debug)
- print_boot_memlist("boot physavail",
- bootops->boot_mem->physavail);
-
/*
* Initialize hat's mmu parameters.
* Check for enforce-prot-exec in boot environment. It's used to
@@ -992,7 +931,7 @@ startup_memlist(void)
npages = physinstalled - 1; /* avail_filter() skips page 0, so "- 1" */
obp_pages = 0;
va = KERNEL_TEXT;
- while (hat_boot_probe(&va, &len, &pfn, &prot) != 0) {
+ while (kbm_probe(&va, &len, &pfn, &prot) != 0) {
npages -= len >> MMU_PAGESHIFT;
if (va >= (uintptr_t)e_moddata)
obp_pages += len >> MMU_PAGESHIFT;
@@ -1029,9 +968,8 @@ startup_memlist(void)
PRM_DEBUG(memseg_sz);
/*
- * Reserve space for phys_avail/phys_install memlists.
- * There's no real good way to know exactly how much room we'll need,
- * but this should be a good upper bound.
+ * Reserve space for memlists. There's no real good way to know exactly
+ * how much room we'll need, but this should be a good upper bound.
*/
memlist_sz = ROUND_UP_PAGE(2 * sizeof (struct memlist) *
(memblocks + POSS_NEW_FRAGMENTS));
@@ -1049,23 +987,10 @@ startup_memlist(void)
PRM_DEBUG(pagehash_sz);
/*
- * Set aside room for the page structures themselves. Note: on
- * 64-bit systems we don't allocate page_t's for every page here.
- * We just allocate enough to map the lowest 4GB of physical
- * memory, minus those pages that are used for the "nucleus" kernel
- * text and data. The remaining pages are allocated once we can
- * map around boot.
- *
- * boot_npages is used to allocate an area big enough for our
- * initial page_t's. kphym_init may use less than that.
+ * Set aside room for the page structures themselves.
*/
- boot_npages = npages;
-#if defined(__amd64)
- if (npages > mmu_btop(FOURGB - (econtig - s_text)))
- boot_npages = mmu_btop(FOURGB - (econtig - s_text));
-#endif
- PRM_DEBUG(boot_npages);
- pp_sz = sizeof (struct page) * boot_npages;
+ PRM_DEBUG(npages);
+ pp_sz = sizeof (struct page) * npages;
ADD_TO_ALLOCATIONS(pp_base, pp_sz);
PRM_DEBUG(pp_sz);
@@ -1083,14 +1008,83 @@ startup_memlist(void)
ADD_TO_ALLOCATIONS(page_ctrs_mem, page_ctrs_size);
PRM_DEBUG(page_ctrs_size);
- /*
- * valloc_base will be below kernel text
- * The extra pages are for the HAT and kmdb to map page tables.
- */
+#if defined(__amd64)
valloc_sz = ROUND_UP_LPAGE(valloc_sz);
- valloc_base = KERNEL_TEXT - valloc_sz;
+ valloc_base = VALLOC_BASE;
+#else /* __i386 */
+ valloc_base = (uintptr_t)(MISC_VA_BASE - valloc_sz);
+ valloc_base = P2ALIGN(valloc_base, mmu.level_size[1]);
+#endif /* __i386 */
PRM_DEBUG(valloc_base);
- ptable_va = valloc_base - ptable_sz;
+
+ /*
+ * do all the initial allocations
+ */
+ perform_allocations();
+
+ /*
+ * Build phys_install and phys_avail in kernel memspace.
+ * - phys_install should be all memory in the system.
+ * - phys_avail is phys_install minus any memory mapped before this
+ * point above KERNEL_TEXT.
+ */
+ current = phys_install = memlist;
+ copy_memlist_filter(bootops->boot_mem->physinstalled, &current, NULL);
+ if ((caddr_t)current > (caddr_t)memlist + memlist_sz)
+ panic("physinstalled was too big!");
+ if (prom_debug)
+ print_memlist("phys_install", phys_install);
+
+ phys_avail = current;
+ PRM_POINT("Building phys_avail:\n");
+ copy_memlist_filter(bootops->boot_mem->physinstalled, &current,
+ avail_filter);
+ if ((caddr_t)current > (caddr_t)memlist + memlist_sz)
+ panic("physavail was too big!");
+ if (prom_debug)
+ print_memlist("phys_avail", phys_avail);
+
+ /*
+ * setup page coloring
+ */
+ page_coloring_setup(pagecolor_mem);
+ page_lock_init(); /* currently a no-op */
+
+ /*
+ * free page list counters
+ */
+ (void) page_ctrs_alloc(page_ctrs_mem);
+
+ /*
+ * Initialize the page structures from the memory lists.
+ */
+ availrmem_initial = availrmem = freemem = 0;
+ PRM_POINT("Calling kphysm_init()...");
+ npages = kphysm_init(pp_base, npages);
+ PRM_POINT("kphysm_init() done");
+ PRM_DEBUG(npages);
+
+ init_debug_info();
+
+ /*
+ * Now that page_t's have been initialized, remove all the
+ * initial allocation pages from the kernel free page lists.
+ */
+ boot_mapin((caddr_t)valloc_base, valloc_sz);
+ boot_mapin((caddr_t)GDT_VA, MMU_PAGESIZE);
+ boot_mapin((caddr_t)DEBUG_INFO_VA, MMU_PAGESIZE);
+ PRM_POINT("startup_memlist() done");
+
+ PRM_DEBUG(valloc_sz);
+}
+
+/*
+ * Layout the kernel's part of address space and initialize kmem allocator.
+ */
+static void
+startup_kmem(void)
+{
+ PRM_POINT("startup_kmem() starting...");
#if defined(__amd64)
if (eprom_kernelbase && eprom_kernelbase != KERNELBASE)
@@ -1098,7 +1092,7 @@ startup_memlist(void)
"systems.");
kernelbase = (uintptr_t)KERNELBASE;
core_base = (uintptr_t)COREHEAP_BASE;
- core_size = ptable_va - core_base;
+ core_size = (size_t)MISC_VA_BASE - COREHEAP_BASE;
#else /* __i386 */
/*
* We configure kernelbase based on:
@@ -1121,48 +1115,43 @@ startup_memlist(void)
kernelbase -= ROUND_UP_4MEG(2 * valloc_sz);
}
ASSERT((kernelbase & mmu.level_offset[1]) == 0);
- core_base = ptable_va;
+ core_base = valloc_base;
core_size = 0;
-#endif
+#endif /* __i386 */
- PRM_DEBUG(kernelbase);
PRM_DEBUG(core_base);
PRM_DEBUG(core_size);
+ PRM_DEBUG(kernelbase);
/*
* At this point, we can only use a portion of the kernelheap that
- * will be available after we boot. Both 32-bit and 64-bit systems
- * have this limitation, although the reasons are completely
- * different.
- *
- * On 64-bit systems, the booter only supports allocations in the
- * upper 4GB of memory, so we have to work with a reduced kernel
- * heap until we take over all allocations. The booter also sits
- * in the lower portion of that 4GB range, so we have to raise the
- * bottom of the heap even further.
+ * will be available after we boot. 32-bit systems have this
+ * limitation.
*
* On 32-bit systems we have to leave room to place segmap below
* the heap. We don't yet know how large segmap will be, so we
* have to be very conservative.
+ *
+ * On 64 bit systems there should be LOTS of room so just use
+ * the next 4Gig below core_base.
*/
#if defined(__amd64)
- /*
- * XX64: For now, we let boot have the lower 2GB of the top 4GB
- * address range. In the long run, that should be fixed. It's
- * insane for a booter to need 2 2GB address ranges.
- */
- boot_kernelheap = (caddr_t)(BOOT_DOUBLEMAP_BASE + BOOT_DOUBLEMAP_SIZE);
+
+ boot_kernelheap = (caddr_t)core_base - FOURGB;
segmap_reserved = 0;
#else /* __i386 */
+
segkp_fromheap = 1;
segmap_reserved = ROUND_UP_LPAGE(MAX(segmapsize, SEGMAPMAX));
- boot_kernelheap = (caddr_t)(ROUND_UP_LPAGE(kernelbase) +
- segmap_reserved);
-#endif
+ boot_kernelheap =
+ (caddr_t)ROUND_UP_LPAGE(kernelbase) + segmap_reserved;
+
+#endif /* __i386 */
PRM_DEBUG(boot_kernelheap);
- kernelheap = boot_kernelheap;
ekernelheap = (char *)core_base;
+ PRM_DEBUG(ekernelheap);
+ kernelheap = boot_kernelheap;
/*
* If segmap is too large we can push the bottom of the kernel heap
@@ -1187,11 +1176,6 @@ startup_memlist(void)
#if defined(__amd64)
ASSERT(_kernelbase == KERNELBASE);
ASSERT(_userlimit == USERLIMIT);
- /*
- * As one final sanity check, verify that the "red zone" between
- * kernel and userspace is exactly the size we expected.
- */
- ASSERT(_kernelbase == (_userlimit + (2 * 1024 * 1024)));
#else
*(uintptr_t *)&_kernelbase = kernelbase;
*(uintptr_t *)&_userlimit = kernelbase;
@@ -1202,63 +1186,11 @@ startup_memlist(void)
PRM_DEBUG(_userlimit32);
/*
- * do all the initial allocations
- */
- perform_allocations();
-
- /*
* Initialize the kernel heap. Note 3rd argument must be > 1st.
*/
- kernelheap_init(kernelheap, ekernelheap, kernelheap + MMU_PAGESIZE,
- (void *)core_base, (void *)ptable_va);
-
- /*
- * Build phys_install and phys_avail in kernel memspace.
- * - phys_install should be all memory in the system.
- * - phys_avail is phys_install minus any memory mapped before this
- * point above KERNEL_TEXT.
- */
- current = phys_install = memlist;
- copy_memlist_filter(bootops->boot_mem->physinstalled, &current, NULL);
- if ((caddr_t)current > (caddr_t)memlist + memlist_sz)
- panic("physinstalled was too big!");
- if (prom_debug)
- print_kernel_memlist("phys_install", phys_install);
-
- phys_avail = current;
- PRM_POINT("Building phys_avail:\n");
- copy_memlist_filter(bootops->boot_mem->physinstalled, &current,
- avail_filter);
- if ((caddr_t)current > (caddr_t)memlist + memlist_sz)
- panic("physavail was too big!");
- if (prom_debug)
- print_kernel_memlist("phys_avail", phys_avail);
-
- /*
- * setup page coloring
- */
- page_coloring_setup(pagecolor_mem);
- page_lock_init(); /* currently a no-op */
-
- /*
- * free page list counters
- */
- (void) page_ctrs_alloc(page_ctrs_mem);
-
- /*
- * Initialize the page structures from the memory lists.
- */
- availrmem_initial = availrmem = freemem = 0;
- PRM_POINT("Calling kphysm_init()...");
- boot_npages = kphysm_init(pp_base, memseg_base, 0, boot_npages);
- PRM_POINT("kphysm_init() done");
- PRM_DEBUG(boot_npages);
-
- /*
- * Now that page_t's have been initialized, remove all the
- * initial allocation pages from the kernel free page lists.
- */
- boot_mapin((caddr_t)valloc_base, valloc_sz);
+ kernelheap_init(boot_kernelheap, ekernelheap,
+ boot_kernelheap + MMU_PAGESIZE,
+ (void *)core_base, (void *)(core_base + core_size));
/*
* Initialize kernel memory allocator.
@@ -1286,7 +1218,7 @@ startup_memlist(void)
* modified via /etc/system in kmem_init/mod_read_system_file.
*/
if (npages == PHYSMEM32) {
- cmn_err(CE_WARN, "!Due to 32 bit virtual"
+ cmn_err(CE_WARN, "!Due to 32-bit virtual"
" address space limitations, limiting"
" physmem to 0x%lx of 0x%lx available pages",
npages, orig_npages);
@@ -1313,7 +1245,7 @@ startup_memlist(void)
}
#endif
- PRM_POINT("startup_memlist() done");
+ PRM_POINT("startup_kmem() done");
}
static void
@@ -1334,7 +1266,7 @@ startup_modules(void)
/*
* Read the GMT lag from /etc/rtc_config.
*/
- gmt_lag = process_rtc_config_file();
+ sgmtl(process_rtc_config_file());
/*
* Calculate default settings of system parameters based upon
@@ -1414,34 +1346,46 @@ startup_modules(void)
/*
* Fake a prom tree such that /dev/openprom continues to work
*/
+ PRM_POINT("startup_modules: calling prom_setup...");
prom_setup();
+ PRM_POINT("startup_modules: done");
/*
* Load all platform specific modules
*/
+ PRM_POINT("startup_modules: calling psm_modload...");
psm_modload();
PRM_POINT("startup_modules() done");
}
-static void
-startup_bop_gone(void)
+/*
+ * claim a "setaside" boot page for use in the kernel
+ */
+page_t *
+boot_claim_page(pfn_t pfn)
{
- PRM_POINT("startup_bop_gone() starting...");
+ page_t *pp;
- /*
- * Do final allocations of HAT data structures that need to
- * be allocated before quiescing the boot loader.
- */
- PRM_POINT("Calling hat_kern_alloc()...");
- hat_kern_alloc();
- PRM_POINT("hat_kern_alloc() done");
+ pp = page_numtopp_nolock(pfn);
+ ASSERT(pp != NULL);
- /*
- * Setup MTRR (Memory type range registers)
- */
- setup_mtrr();
- PRM_POINT("startup_bop_gone() done");
+ if (PP_ISBOOTPAGES(pp)) {
+ if (pp->p_next != NULL)
+ pp->p_next->p_prev = pp->p_prev;
+ if (pp->p_prev == NULL)
+ bootpages = pp->p_next;
+ else
+ pp->p_prev->p_next = pp->p_next;
+ } else {
+ /*
+ * htable_attach() expects a base pagesize page
+ */
+ if (pp->p_szc != 0)
+ page_boot_demote(pp);
+ pp = page_numtopp(pfn, SE_EXCL);
+ }
+ return (pp);
}
/*
@@ -1459,7 +1403,7 @@ protect_boot_range(uintptr_t low, uintptr_t high, int setaside)
page_t *pp;
pgcnt_t boot_protect_cnt = 0;
- while (hat_boot_probe(&va, &len, &pfn, &prot) != 0 && va < high) {
+ while (kbm_probe(&va, &len, &pfn, &prot) != 0 && va < high) {
if (va + len >= high)
panic("0x%lx byte mapping at 0x%p exceeds boot's "
"legal range.", len, (void *)va);
@@ -1473,6 +1417,11 @@ protect_boot_range(uintptr_t low, uintptr_t high, int setaside)
(void *)va, pfn);
pp->p_next = bootpages;
+ pp->p_prev = NULL;
+ PP_SETBOOTPAGES(pp);
+ if (bootpages != NULL) {
+ bootpages->p_prev = pp;
+ }
bootpages = pp;
++boot_protect_cnt;
}
@@ -1485,87 +1434,53 @@ protect_boot_range(uintptr_t low, uintptr_t high, int setaside)
PRM_DEBUG(boot_protect_cnt);
}
+/*
+ * Finish initializing the VM system, now that we are no longer
+ * relying on the boot time memory allocators.
+ */
static void
startup_vm(void)
{
struct segmap_crargs a;
- extern void hat_kern_setup(void);
- pgcnt_t pages_left;
extern int use_brk_lpg, use_stk_lpg;
PRM_POINT("startup_vm() starting...");
/*
- * The next two loops are done in distinct steps in order
- * to be sure that any page that is doubly mapped (both above
- * KERNEL_TEXT and below kernelbase) is dealt with correctly.
- * Note this may never happen, but it might someday.
- */
-
- bootpages = NULL;
- PRM_POINT("Protecting boot pages");
- /*
- * Protect any pages mapped above KERNEL_TEXT that somehow have
- * page_t's. This can only happen if something weird allocated
- * in this range (like kadb/kmdb).
+ * Establish the final size of the kernel's heap, size of segmap,
+ * segkp, etc.
*/
- protect_boot_range(KERNEL_TEXT, (uintptr_t)-1, 0);
- /*
- * Before we can take over memory allocation/mapping from the boot
- * loader we must remove from our free page lists any boot pages that
- * will stay mapped until release_bootstrap().
- */
- protect_boot_range(0, kernelbase, 1);
#if defined(__amd64)
- protect_boot_range(BOOT_DOUBLEMAP_BASE,
- BOOT_DOUBLEMAP_BASE + BOOT_DOUBLEMAP_SIZE, 0);
-#endif
-
- /*
- * Copy in boot's page tables, set up extra page tables for the kernel,
- * and switch to the kernel's context.
- */
- PRM_POINT("Calling hat_kern_setup()...");
- hat_kern_setup();
/*
- * It is no longer safe to call BOP_ALLOC(), so make sure we don't.
+ * Check if there is enough virtual address space in KPM region to
+ * map physmax.
*/
- bootops->bsys_alloc = NULL;
- PRM_POINT("hat_kern_setup() done");
+ kpm_vbase = (caddr_t)(uintptr_t)SEGKPM_BASE;
+ kpm_size = 0;
+ if (kpm_desired) {
+ kpm_size = ROUND_UP_LPAGE(mmu_ptob(physmax + 1));
+ if ((uintptr_t)kpm_vbase + kpm_size > (uintptr_t)VALLOC_BASE) {
+ kpm_size = 0;
+ kpm_desired = 0;
+ }
+ }
- hat_cpu_online(CPU);
+ PRM_DEBUG(kpm_size);
+ PRM_DEBUG(kpm_vbase);
/*
- * Before we call kvm_init(), we need to establish the final size
- * of the kernel's heap. So, we need to figure out how much space
- * to set aside for segkp, segkpm, and segmap.
+ * By default we create a seg_kp in 64 bit kernels, it's a little
+ * faster to access than embedding it in the heap.
*/
- final_kernelheap = (caddr_t)ROUND_UP_LPAGE(kernelbase);
-#if defined(__amd64)
- if (kpm_desired) {
- /*
- * Segkpm appears at the bottom of the kernel's address
- * range. To detect accidental overruns of the user
- * address space, we leave a "red zone" of unmapped memory
- * between kernelbase and the beginning of segkpm.
- */
- kpm_vbase = final_kernelheap + KERNEL_REDZONE_SIZE;
- kpm_size = mmu_ptob(physmax + 1);
- PRM_DEBUG(kpm_vbase);
- PRM_DEBUG(kpm_size);
- final_kernelheap =
- (caddr_t)ROUND_UP_TOPLEVEL(kpm_vbase + kpm_size);
- }
-
+ segkp_base = (caddr_t)valloc_base + valloc_sz;
if (!segkp_fromheap) {
size_t sz = mmu_ptob(segkpsize);
/*
- * determine size of segkp and adjust the bottom of the
- * kernel's heap.
+ * determine size of segkp
*/
if (sz < SEGKPMINSIZE || sz > SEGKPMAXSIZE) {
sz = SEGKPDEFSIZE;
@@ -1576,14 +1491,14 @@ startup_vm(void)
sz = MIN(sz, MAX(SEGKPMINSIZE, mmu_ptob(physmem)));
segkpsize = mmu_btop(ROUND_UP_LPAGE(sz));
- segkp_base = final_kernelheap;
- PRM_DEBUG(segkpsize);
- PRM_DEBUG(segkp_base);
- final_kernelheap = segkp_base + mmu_ptob(segkpsize);
- PRM_DEBUG(final_kernelheap);
}
+ PRM_DEBUG(segkp_base);
+ PRM_DEBUG(segkpsize);
- if (!segzio_fromheap) {
+ segzio_base = segkp_base + mmu_ptob(segkpsize);
+ if (segzio_fromheap) {
+ segziosize = 0;
+ } else {
size_t size;
size_t maxsize;
@@ -1603,22 +1518,23 @@ startup_vm(void)
size = maxsize;
}
segziosize = mmu_btop(ROUND_UP_LPAGE(size));
- segzio_base = final_kernelheap;
- PRM_DEBUG(segziosize);
- PRM_DEBUG(segzio_base);
- final_kernelheap = segzio_base + mmu_ptob(segziosize);
- PRM_DEBUG(final_kernelheap);
}
+ PRM_DEBUG(segziosize);
+ PRM_DEBUG(segzio_base);
/*
- * put the range of VA for device mappings next
+ * Put the range of VA for device mappings next, kmdb knows to not
+ * grep in this range of addresses.
*/
- toxic_addr = (uintptr_t)final_kernelheap;
+ toxic_addr =
+ ROUND_UP_LPAGE((uintptr_t)segzio_base + mmu_ptob(segziosize));
PRM_DEBUG(toxic_addr);
- final_kernelheap = (char *)toxic_addr + toxic_size;
-#endif
- PRM_DEBUG(final_kernelheap);
- ASSERT(final_kernelheap < boot_kernelheap);
+ segmap_start = ROUND_UP_LPAGE(toxic_addr + toxic_size);
+#else /* __i386 */
+ segmap_start = ROUND_UP_LPAGE(kernelbase);
+#endif /* __i386 */
+ PRM_DEBUG(segmap_start);
+ ASSERT((caddr_t)segmap_start < boot_kernelheap);
/*
* Users can change segmapsize through eeprom or /etc/system.
@@ -1628,7 +1544,6 @@ startup_vm(void)
* planned for in startup_memlist().
*/
segmapsize = MAX(ROUND_UP_LPAGE(segmapsize), SEGMAPDEFAULT);
- segkmap_start = ROUND_UP_LPAGE((uintptr_t)final_kernelheap);
#if defined(__i386)
if (segmapsize > segmap_reserved) {
@@ -1639,18 +1554,69 @@ startup_vm(void)
/*
* 32-bit systems don't have segkpm or segkp, so segmap appears at
* the bottom of the kernel's address range. Set aside space for a
- * red zone just below the start of segmap.
+ * small red zone just below the start of segmap.
*/
- segkmap_start += KERNEL_REDZONE_SIZE;
+ segmap_start += KERNEL_REDZONE_SIZE;
segmapsize -= KERNEL_REDZONE_SIZE;
#endif
- final_kernelheap = (char *)(segkmap_start + segmapsize);
- PRM_DEBUG(segkmap_start);
+ PRM_DEBUG(segmap_start);
PRM_DEBUG(segmapsize);
+ final_kernelheap = (caddr_t)ROUND_UP_LPAGE(segmap_start + segmapsize);
PRM_DEBUG(final_kernelheap);
/*
+ * Do final allocations of HAT data structures that need to
+ * be allocated before quiescing the boot loader.
+ */
+ PRM_POINT("Calling hat_kern_alloc()...");
+ hat_kern_alloc((caddr_t)segmap_start, segmapsize, ekernelheap);
+ PRM_POINT("hat_kern_alloc() done");
+
+ /*
+ * Setup MTRR (Memory type range registers)
+ */
+ setup_mtrr();
+
+ /*
+ * The next two loops are done in distinct steps in order
+ * to be sure that any page that is doubly mapped (both above
+ * KERNEL_TEXT and below kernelbase) is dealt with correctly.
+ * Note this may never happen, but it might someday.
+ */
+ bootpages = NULL;
+ PRM_POINT("Protecting boot pages");
+
+ /*
+ * Protect any pages mapped above KERNEL_TEXT that somehow have
+ * page_t's. This can only happen if something weird allocated
+ * in this range (like kadb/kmdb).
+ */
+ protect_boot_range(KERNEL_TEXT, (uintptr_t)-1, 0);
+
+ /*
+ * Before we can take over memory allocation/mapping from the boot
+ * loader we must remove from our free page lists any boot allocated
+ * pages that stay mapped until release_bootstrap().
+ */
+ protect_boot_range(0, kernelbase, 1);
+
+ /*
+ * Switch to running on regular HAT (not boot_mmu)
+ */
+ PRM_POINT("Calling hat_kern_setup()...");
+ hat_kern_setup();
+
+ /*
+ * It is no longer safe to call BOP_ALLOC(), so make sure we don't.
+ */
+ bop_no_more_mem();
+
+ PRM_POINT("hat_kern_setup() done");
+
+ hat_cpu_online(CPU);
+
+ /*
* Initialize VM system
*/
PRM_POINT("Calling kvm_init()...");
@@ -1668,37 +1634,16 @@ startup_vm(void)
*/
cpuid_pass3(CPU);
- PRM_DEBUG(final_kernelheap);
-
/*
* Now that we can use memory outside the top 4GB (on 64-bit
* systems) and we know the size of segmap, we can set the final
- * size of the kernel's heap. Note: on 64-bit systems we still
- * can't touch anything in the bottom half of the top 4GB range
- * because boot still has pages mapped there.
+ * size of the kernel's heap.
*/
if (final_kernelheap < boot_kernelheap) {
+ PRM_POINT("kernelheap_extend()");
+ PRM_DEBUG(boot_kernelheap);
+ PRM_DEBUG(final_kernelheap);
kernelheap_extend(final_kernelheap, boot_kernelheap);
-#if defined(__amd64)
- kmem_setaside = vmem_xalloc(heap_arena, BOOT_DOUBLEMAP_SIZE,
- MMU_PAGESIZE, 0, 0, (void *)(BOOT_DOUBLEMAP_BASE),
- (void *)(BOOT_DOUBLEMAP_BASE + BOOT_DOUBLEMAP_SIZE),
- VM_NOSLEEP | VM_BESTFIT | VM_PANIC);
- PRM_DEBUG(kmem_setaside);
- if (kmem_setaside == NULL)
- panic("Could not protect boot's memory");
-#endif
- }
- /*
- * Now that the kernel heap may have grown significantly, we need
- * to make all the remaining page_t's available to back that memory.
- *
- * XX64 this should probably wait till after release boot-strap too.
- */
- pages_left = npages - boot_npages;
- if (pages_left > 0) {
- PRM_DEBUG(pages_left);
- (void) kphysm_init(NULL, memseg_base, boot_npages, pages_left);
}
#if defined(__amd64)
@@ -1714,7 +1659,7 @@ startup_vm(void)
/*
* allocate the bit map that tracks toxic pages
*/
- toxic_bit_map_len = btop((ulong_t)(ptable_va - kernelbase));
+ toxic_bit_map_len = btop((ulong_t)(valloc_base - kernelbase));
PRM_DEBUG(toxic_bit_map_len);
toxic_bit_map =
kmem_zalloc(BT_SIZEOFMAP(toxic_bit_map_len), KM_NOSLEEP);
@@ -1737,23 +1682,24 @@ startup_vm(void)
*/
#if !defined(__amd64)
if (x86_type == X86_TYPE_P5) {
+ desctbr_t idtr;
gate_desc_t *newidt;
- desctbr_t newidt_r;
+ struct machcpu *mcpu = &CPU->cpu_m;
if ((newidt = kmem_zalloc(MMU_PAGESIZE, KM_NOSLEEP)) == NULL)
panic("failed to install pentium_pftrap");
bcopy(idt0, newidt, sizeof (idt0));
set_gatesegd(&newidt[T_PGFLT], &pentium_pftrap,
- KCS_SEL, 0, SDT_SYSIGT, SEL_KPL);
+ KCS_SEL, SDT_SYSIGT, SEL_KPL);
(void) as_setprot(&kas, (caddr_t)newidt, MMU_PAGESIZE,
PROT_READ|PROT_EXEC);
- newidt_r.dtr_limit = sizeof (idt0) - 1;
- newidt_r.dtr_base = (uintptr_t)newidt;
- CPU->cpu_idt = newidt;
- wr_idtr(&newidt_r);
+ mcpu->mcpu_idt = newidt;
+ idtr.dtr_base = (uintptr_t)mcpu->mcpu_idt;
+ idtr.dtr_limit = sizeof (idt0) - 1;
+ wr_idtr(&idtr);
}
#endif /* !__amd64 */
@@ -1797,20 +1743,15 @@ startup_vm(void)
* Initialize the segkp segment type.
*/
rw_enter(&kas.a_lock, RW_WRITER);
- if (!segkp_fromheap) {
- if (seg_attach(&kas, (caddr_t)segkp_base, mmu_ptob(segkpsize),
- segkp) < 0) {
- panic("startup: cannot attach segkp");
- /*NOTREACHED*/
- }
- } else {
- /*
- * For 32 bit x86 systems, we will have segkp under the heap.
- * There will not be a segkp segment. We do, however, need
- * to fill in the seg structure.
- */
+ PRM_POINT("Attaching segkp");
+ if (segkp_fromheap) {
segkp->s_as = &kas;
+ } else if (seg_attach(&kas, (caddr_t)segkp_base, mmu_ptob(segkpsize),
+ segkp) < 0) {
+ panic("startup: cannot attach segkp");
+ /*NOTREACHED*/
}
+ PRM_POINT("Doing segkp_create()");
if (segkp_create(segkp) != 0) {
panic("startup: segkp_create failed");
/*NOTREACHED*/
@@ -1832,38 +1773,38 @@ startup_vm(void)
* Now create segmap segment.
*/
rw_enter(&kas.a_lock, RW_WRITER);
- if (seg_attach(&kas, (caddr_t)segkmap_start, segmapsize, segkmap) < 0) {
- panic("cannot attach segkmap");
+ if (seg_attach(&kas, (caddr_t)segmap_start, segmapsize, segmap) < 0) {
+ panic("cannot attach segmap");
/*NOTREACHED*/
}
- PRM_DEBUG(segkmap);
-
- /*
- * The 64 bit HAT permanently maps only segmap's page tables.
- * The 32 bit HAT maps the heap's page tables too.
- */
-#if defined(__amd64)
- hat_kmap_init(segkmap_start, segmapsize);
-#else /* __i386 */
- ASSERT(segkmap_start + segmapsize == (uintptr_t)final_kernelheap);
- hat_kmap_init(segkmap_start, (uintptr_t)ekernelheap - segkmap_start);
-#endif /* __i386 */
+ PRM_DEBUG(segmap);
a.prot = PROT_READ | PROT_WRITE;
a.shmsize = 0;
a.nfreelist = segmapfreelists;
- if (segmap_create(segkmap, (caddr_t)&a) != 0)
- panic("segmap_create segkmap");
+ if (segmap_create(segmap, (caddr_t)&a) != 0)
+ panic("segmap_create segmap");
rw_exit(&kas.a_lock);
setup_vaddr_for_ppcopy(CPU);
segdev_init();
pmem_init();
+
PRM_POINT("startup_vm() done");
}
+/*
+ * Load a tod module for the non-standard tod part found on this system.
+ */
+static void
+load_tod_module(char *todmod)
+{
+ if (modload("tod", todmod) == -1)
+ halt("Can't load TOD module");
+}
+
static void
startup_end(void)
{
@@ -1883,22 +1824,20 @@ startup_end(void)
*/
kcpc_hw_init(CPU);
-#if defined(__amd64)
- /*
- * Validate support for syscall/sysret
- * XX64 -- include SSE, SSE2, etc. here too?
- */
- if ((x86_feature & X86_ASYSC) == 0) {
- cmn_err(CE_WARN,
- "cpu%d does not support syscall/sysret", CPU->cpu_id);
- }
-#endif
-
#if defined(OPTERON_WORKAROUND_6323525)
if (opteron_workaround_6323525)
patch_workaround_6323525();
#endif
/*
+ * If needed, load TOD module now so that ddi_get_time(9F) etc. work
+ * (For now, "needed" is defined as set tod_module_name in /etc/system)
+ */
+ if (tod_module_name != NULL) {
+ PRM_POINT("load_tod_module()");
+ load_tod_module(tod_module_name);
+ }
+
+ /*
* Configure the system.
*/
PRM_POINT("Calling configure()...");
@@ -1917,8 +1856,8 @@ startup_end(void)
* We're done with bootops. We don't unmap the bootstrap yet because
* we're still using bootsvcs.
*/
- PRM_POINT("zeroing out bootops");
- *bootopsp = (struct bootops *)0;
+ PRM_POINT("NULLing out bootops");
+ *bootopsp = (struct bootops *)NULL;
bootops = (struct bootops *)NULL;
PRM_POINT("Enabling interrupts");
@@ -1946,13 +1885,13 @@ post_startup(void)
bind_hwcap();
/*
- * Load the System Management BIOS into the global ksmbios handle,
- * if an SMBIOS is present on this system.
+ * Load the System Management BIOS into the global ksmbios
+ * handle, if an SMBIOS is present on this system.
*/
ksmbios = smbios_open(NULL, SMB_VERSION, ksmbios_flags, NULL);
/*
- * Startup memory scrubber.
+ * Startup the memory scrubber.
*/
memscrub_init();
@@ -1999,7 +1938,6 @@ void
release_bootstrap(void)
{
int root_is_ramdisk;
- pfn_t pfn;
page_t *pp;
extern void kobj_boot_unmountroot(void);
extern dev_t rootdev;
@@ -2011,12 +1949,8 @@ release_bootstrap(void)
* We're finished using the boot loader so free its pages.
*/
PRM_POINT("Unmapping lower boot pages");
- clear_boot_mappings(0, kernelbase);
-#if defined(__amd64)
- PRM_POINT("Unmapping upper boot pages");
- clear_boot_mappings(BOOT_DOUBLEMAP_BASE,
- BOOT_DOUBLEMAP_BASE + BOOT_DOUBLEMAP_SIZE);
-#endif
+ clear_boot_mappings(0, _userlimit);
+ postbootkernelbase = kernelbase;
/*
* If root isn't on ramdisk, destroy the hardcoded
@@ -2041,8 +1975,11 @@ release_bootstrap(void)
continue;
}
pp->p_next = (struct page *)0;
+ pp->p_prev = (struct page *)0;
+ PP_CLRBOOTPAGES(pp);
page_free(pp, 1);
}
+ PRM_POINT("Boot pages released");
/*
* Find 1 page below 1 MB so that other processors can boot up.
@@ -2050,6 +1987,8 @@ release_bootstrap(void)
* We should have just free'd one up.
*/
if (use_mp) {
+ pfn_t pfn;
+
for (pfn = 1; pfn < btop(1*1024*1024); pfn++) {
if (page_numtopp_alloc(pfn) == NULL)
continue;
@@ -2067,11 +2006,6 @@ release_bootstrap(void)
"other processors");
}
-#if defined(__amd64)
- PRM_POINT("Returning boot's VA space to kernel heap");
- if (kmem_setaside != NULL)
- vmem_free(heap_arena, kmem_setaside, BOOT_DOUBLEMAP_SIZE);
-#endif
}
/*
@@ -2092,31 +2026,21 @@ add_physmem_cb(page_t *pp, pfn_t pnum)
*/
static pgcnt_t
kphysm_init(
- page_t *inpp,
- struct memseg *memsegp,
- pgcnt_t start,
+ page_t *pp,
pgcnt_t npages)
{
struct memlist *pmem;
struct memseg *cur_memseg;
- struct memseg **memsegpp;
pfn_t base_pfn;
pgcnt_t num;
- pgcnt_t total_skipped = 0;
- pgcnt_t skipping = 0;
pgcnt_t pages_done = 0;
- pgcnt_t largepgcnt;
uint64_t addr;
uint64_t size;
- page_t *pp = inpp;
- int dobreak = 0;
extern pfn_t ddiphysmin;
ASSERT(page_hash != NULL && page_hashsz != 0);
- for (cur_memseg = memsegp; cur_memseg->pages != NULL; cur_memseg++);
- ASSERT(cur_memseg == memsegp || start > 0);
-
+ cur_memseg = memseg_base;
for (pmem = phys_avail; pmem && npages; pmem = pmem->next) {
/*
* In a 32 bit kernel can't use higher memory if we're
@@ -2144,19 +2068,6 @@ kphysm_init(
if (num == 0)
continue;
- if (total_skipped < start) {
- if (start - total_skipped > num) {
- total_skipped += num;
- continue;
- }
- skipping = start - total_skipped;
- num -= skipping;
- addr += (MMU_PAGESIZE * skipping);
- total_skipped = start;
- }
- if (num == 0)
- continue;
-
if (num > npages)
num = npages;
@@ -2164,62 +2075,23 @@ kphysm_init(
pages_done += num;
base_pfn = btop(addr);
- /*
- * If the caller didn't provide space for the page
- * structures, carve them out of the memseg they will
- * represent.
- */
- if (pp == NULL) {
- pgcnt_t pp_pgs;
-
- if (num <= 1)
- continue;
-
- /*
- * Compute how many of the pages we need to use for
- * page_ts
- */
- pp_pgs = (num * sizeof (page_t)) / MMU_PAGESIZE + 1;
- while (mmu_ptob(pp_pgs - 1) / sizeof (page_t) >=
- num - pp_pgs + 1)
- --pp_pgs;
- PRM_DEBUG(pp_pgs);
-
- pp = vmem_alloc(heap_arena, mmu_ptob(pp_pgs),
- VM_NOSLEEP);
- if (pp == NULL) {
- cmn_err(CE_WARN, "Unable to add %ld pages to "
- "the system.", num);
- continue;
- }
-
- hat_devload(kas.a_hat, (void *)pp, mmu_ptob(pp_pgs),
- base_pfn, PROT_READ | PROT_WRITE | HAT_UNORDERED_OK,
- HAT_LOAD | HAT_LOAD_LOCK | HAT_LOAD_NOCONSIST);
- bzero(pp, mmu_ptob(pp_pgs));
- num -= pp_pgs;
- base_pfn += pp_pgs;
- }
-
if (prom_debug)
prom_printf("MEMSEG addr=0x%" PRIx64
" pgs=0x%lx pfn 0x%lx-0x%lx\n",
addr, num, base_pfn, base_pfn + num);
/*
- * drop pages below ddiphysmin to simplify ddi memory
+ * Ignore pages below ddiphysmin to simplify ddi memory
* allocation with non-zero addr_lo requests.
*/
if (base_pfn < ddiphysmin) {
- if (base_pfn + num <= ddiphysmin) {
- /* drop entire range below ddiphysmin */
+ if (base_pfn + num <= ddiphysmin)
continue;
- }
- /* adjust range to ddiphysmin */
pp += (ddiphysmin - base_pfn);
num -= (ddiphysmin - base_pfn);
base_pfn = ddiphysmin;
}
+
/*
* Build the memsegs entry
*/
@@ -2229,121 +2101,18 @@ kphysm_init(
cur_memseg->pages_end = base_pfn + num;
/*
- * insert in memseg list in decreasing pfn range order.
+ * Insert into memseg list in decreasing pfn range order.
* Low memory is typically more fragmented such that this
* ordering keeps the larger ranges at the front of the list
* for code that searches memseg.
+ * This ASSERTS that the memsegs coming in from boot are in
+ * increasing physical address order and not contiguous.
*/
- memsegpp = &memsegs;
- for (;;) {
- if (*memsegpp == NULL) {
- /* empty memsegs */
- memsegs = cur_memseg;
- break;
- }
- /* check for continuity with start of memsegpp */
- if (cur_memseg->pages_end == (*memsegpp)->pages_base) {
- if (cur_memseg->epages == (*memsegpp)->pages) {
- /*
- * contiguous pfn and page_t's. Merge
- * cur_memseg into *memsegpp. Drop
- * cur_memseg
- */
- (*memsegpp)->pages_base =
- cur_memseg->pages_base;
- (*memsegpp)->pages =
- cur_memseg->pages;
- /*
- * check if contiguous with the end of
- * the next memseg.
- */
- if ((*memsegpp)->next &&
- ((*memsegpp)->pages_base ==
- (*memsegpp)->next->pages_end)) {
- cur_memseg = *memsegpp;
- memsegpp = &((*memsegpp)->next);
- dobreak = 1;
- } else {
- break;
- }
- } else {
- /*
- * contiguous pfn but not page_t's.
- * drop last pfn/page_t in cur_memseg
- * to prevent creation of large pages
- * with noncontiguous page_t's if not
- * aligned to largest page boundary.
- */
- largepgcnt = page_get_pagecnt(
- page_num_pagesizes() - 1);
-
- if (cur_memseg->pages_end &
- (largepgcnt - 1)) {
- num--;
- cur_memseg->epages--;
- cur_memseg->pages_end--;
- }
- }
- }
-
- /* check for continuity with end of memsegpp */
- if (cur_memseg->pages_base == (*memsegpp)->pages_end) {
- if (cur_memseg->pages == (*memsegpp)->epages) {
- /*
- * contiguous pfn and page_t's. Merge
- * cur_memseg into *memsegpp. Drop
- * cur_memseg.
- */
- if (dobreak) {
- /* merge previously done */
- cur_memseg->pages =
- (*memsegpp)->pages;
- cur_memseg->pages_base =
- (*memsegpp)->pages_base;
- cur_memseg->next =
- (*memsegpp)->next;
- } else {
- (*memsegpp)->pages_end =
- cur_memseg->pages_end;
- (*memsegpp)->epages =
- cur_memseg->epages;
- }
- break;
- }
- /*
- * contiguous pfn but not page_t's.
- * drop first pfn/page_t in cur_memseg
- * to prevent creation of large pages
- * with noncontiguous page_t's if not
- * aligned to largest page boundary.
- */
- largepgcnt = page_get_pagecnt(
- page_num_pagesizes() - 1);
- if (base_pfn & (largepgcnt - 1)) {
- num--;
- base_pfn++;
- cur_memseg->pages++;
- cur_memseg->pages_base++;
- pp = cur_memseg->pages;
- }
- if (dobreak)
- break;
- }
-
- if (cur_memseg->pages_base >=
- (*memsegpp)->pages_end) {
- cur_memseg->next = *memsegpp;
- *memsegpp = cur_memseg;
- break;
- }
- if ((*memsegpp)->next == NULL) {
- cur_memseg->next = NULL;
- (*memsegpp)->next = cur_memseg;
- break;
- }
- memsegpp = &((*memsegpp)->next);
- ASSERT(*memsegpp != NULL);
+ if (memsegs != NULL) {
+ ASSERT(cur_memseg->pages_base >= memsegs->pages_end);
+ cur_memseg->next = memsegs;
}
+ memsegs = cur_memseg;
/*
* add_physmem() initializes the PSM part of the page
@@ -2356,12 +2125,7 @@ kphysm_init(
availrmem_initial += num;
availrmem += num;
- /*
- * If the caller provided the page frames to us, then
- * advance in that list. Otherwise, prepare to allocate
- * our own page frames for the next memseg.
- */
- pp = (inpp == NULL) ? NULL : pp + num;
+ pp += num;
}
PRM_DEBUG(availrmem_initial);
@@ -2377,11 +2141,6 @@ kphysm_init(
static void
kvm_init(void)
{
-#ifdef DEBUG
- extern void _start();
-
- ASSERT((caddr_t)_start == s_text);
-#endif
ASSERT((((uintptr_t)s_text) & MMU_PAGEOFFSET) == 0);
/*
@@ -2400,20 +2159,20 @@ kvm_init(void)
* We're about to map out /boot. This is the beginning of the
* system resource management transition. We can no longer
* call into /boot for I/O or memory allocations.
- *
- * XX64 - Is this still correct with kernelheap_extend() being called
- * later than this????
*/
(void) seg_attach(&kas, final_kernelheap,
ekernelheap - final_kernelheap, &kvseg);
(void) segkmem_create(&kvseg);
-#if defined(__amd64)
- (void) seg_attach(&kas, (caddr_t)core_base, core_size, &kvseg_core);
- (void) segkmem_create(&kvseg_core);
+ if (core_size > 0) {
+ PRM_POINT("attaching kvseg_core");
+ (void) seg_attach(&kas, (caddr_t)core_base, core_size,
+ &kvseg_core);
+ (void) segkmem_create(&kvseg_core);
+ }
- /* segzio optimization is only valid for 64-bit kernels */
- if (!segzio_fromheap) {
+ if (segziosize > 0) {
+ PRM_POINT("attaching segzio");
(void) seg_attach(&kas, segzio_base, mmu_ptob(segziosize),
&kzioseg);
(void) segkmem_zio_create(&kzioseg);
@@ -2421,10 +2180,8 @@ kvm_init(void)
/* create zio area covering new segment */
segkmem_zio_init(segzio_base, mmu_ptob(segziosize));
}
-#endif
- (void) seg_attach(&kas, (caddr_t)SEGDEBUGBASE, (size_t)SEGDEBUGSIZE,
- &kdebugseg);
+ (void) seg_attach(&kas, kdi_segdebugbase, kdi_segdebugsize, &kdebugseg);
(void) segkmem_create(&kdebugseg);
rw_exit(&kas.a_lock);
@@ -2432,6 +2189,7 @@ kvm_init(void)
/*
* Ensure that the red zone at kernelbase is never accessible.
*/
+ PRM_POINT("protecting redzone");
(void) as_setprot(&kas, (caddr_t)kernelbase, KERNEL_REDZONE_SIZE, 0);
/*
@@ -2526,8 +2284,8 @@ mtrr_sync(void)
crvalue &= ~CR0_NW;
setcr0(crvalue);
invalidate_cache();
- setcr3(getcr3());
+ reload_cr3();
if (x86_feature & X86_PAT)
wrmsr(REG_MTRRPAT, pat_attr_reg);
@@ -2555,7 +2313,8 @@ mtrr_sync(void)
wrmsr(ecx + 1, mtrrphys->mtrrphys_mask);
}
wrmsr(REG_MTRRDEF, mtrrdef);
- setcr3(getcr3());
+
+ reload_cr3();
invalidate_cache();
setcr0(cr0_orig);
}
@@ -2633,7 +2392,7 @@ get_system_configuration(void)
* new = pointer to a new struct memlist
* memlistp = memory list to which to add segment.
*/
-static void
+void
memlist_add(
uint64_t start,
uint64_t len,
@@ -2782,7 +2541,7 @@ device_arena_free(void *vaddr, size_t size)
vmem_free(device_arena, vaddr, size);
}
-#else
+#else /* __i386 */
void *
device_arena_alloc(size_t size, int vm_flag)
@@ -2798,7 +2557,7 @@ device_arena_alloc(size_t size, int vm_flag)
v = (uintptr_t)vaddr;
ASSERT(v >= kernelbase);
- ASSERT(v + size <= ptable_va);
+ ASSERT(v + size <= valloc_base);
start = btop(v - kernelbase);
end = btop(v + size - 1 - kernelbase);
@@ -2820,7 +2579,7 @@ device_arena_free(void *vaddr, size_t size)
size_t end;
ASSERT(v >= kernelbase);
- ASSERT(v + size <= ptable_va);
+ ASSERT(v + size <= valloc_base);
start = btop(v - kernelbase);
end = btop(v + size - 1 - kernelbase);
@@ -2856,7 +2615,7 @@ device_arena_contains(void *vaddr, size_t size, size_t *len)
/*
* First check if we're completely outside the bitmap range.
*/
- if (v >= ptable_va || eaddr < kernelbase)
+ if (v >= valloc_base || eaddr < kernelbase)
return (NULL);
/*
@@ -2878,4 +2637,4 @@ device_arena_contains(void *vaddr, size_t size, size_t *len)
return ((void *)v);
}
-#endif
+#endif /* __i386 */
diff --git a/usr/src/uts/i86pc/os/timestamp.c b/usr/src/uts/i86pc/os/timestamp.c
index b0d422b867..ad7db8a28e 100644
--- a/usr/src/uts/i86pc/os/timestamp.c
+++ b/usr/src/uts/i86pc/os/timestamp.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -135,19 +134,20 @@ static volatile int tsc_sync_go;
/*
* XX64 Is the faster way to do this with a 64-bit ABI?
*/
-#define TSC_CONVERT_AND_ADD(tsc, hrt, scale) { \
- unsigned int *_l = (unsigned int *)&(tsc); \
- (hrt) += mul32(_l[1], scale) << NSEC_SHIFT; \
+
+#define TSC_CONVERT_AND_ADD(tsc, hrt, scale) { \
+ unsigned int *_l = (unsigned int *)&(tsc); \
+ (hrt) += mul32(_l[1], scale) << NSEC_SHIFT; \
(hrt) += mul32(_l[0], scale) >> (32 - NSEC_SHIFT); \
}
-#define TSC_CONVERT(tsc, hrt, scale) { \
- unsigned int *_l = (unsigned int *)&(tsc); \
- (hrt) = mul32(_l[1], scale) << NSEC_SHIFT; \
+#define TSC_CONVERT(tsc, hrt, scale) { \
+ unsigned int *_l = (unsigned int *)&(tsc); \
+ (hrt) = mul32(_l[1], scale) << NSEC_SHIFT; \
(hrt) += mul32(_l[0], scale) >> (32 - NSEC_SHIFT); \
}
-
+int tsc_master_slave_sync_needed = 1;
static int tsc_max_delta;
static hrtime_t tsc_sync_snaps[2];
@@ -211,9 +211,12 @@ tsc_digest(processorid_t target)
void
tsc_sync_master(processorid_t slave)
{
- int flags;
+ ulong_t flags;
hrtime_t hrt;
+ if (!tsc_master_slave_sync_needed)
+ return;
+
ASSERT(tsc_sync_go != TSC_SYNC_GO);
flags = clear_int_flag();
@@ -264,9 +267,12 @@ tsc_sync_master(processorid_t slave)
void
tsc_sync_slave(void)
{
- int flags;
+ ulong_t flags;
hrtime_t hrt;
+ if (!tsc_master_slave_sync_needed)
+ return;
+
ASSERT(tsc_sync_go != TSC_SYNC_GO);
flags = clear_int_flag();
@@ -311,7 +317,7 @@ void
tsc_hrtimeinit(uint64_t cpu_freq_hz)
{
longlong_t tsc;
- int flags;
+ ulong_t flags;
/*
* cpu_freq_hz is the measured cpu frequency in hertz
@@ -333,8 +339,8 @@ tsc_hrtimeinit(uint64_t cpu_freq_hz)
}
/*
- * Called once per second on some CPU from the cyclic subsystem's
- * CY_HIGH_LEVEL interrupt. (no longer CPU0-only)
+ * Called once per second on a CPU from the cyclic subsystem's
+ * CY_HIGH_LEVEL interrupt. (No longer just cpu0-only)
*/
void
tsc_tick(void)
@@ -418,7 +424,6 @@ tsc_gethrtime(void)
*/
tsc = 0;
}
-
hrt = tsc_hrtime_base;
TSC_CONVERT_AND_ADD(tsc, hrt, nsec_scale);
@@ -581,13 +586,8 @@ tsc_gethrtimeunscaled(void)
do {
old_hres_lock = hres_lock;
- if ((tsc = tsc_read()) < tsc_last) {
- /*
- * see comments in tsc_gethrtime
- */
- tsc += tsc_last_jumped;
- }
-
+ /* See tsc_tick(). */
+ tsc = tsc_read() + tsc_last_jumped;
} while ((old_hres_lock & ~1) != hres_lock);
return (tsc);
diff --git a/usr/src/uts/i86pc/os/trap.c b/usr/src/uts/i86pc/os/trap.c
index 8bae150533..bce1c7ad24 100644
--- a/usr/src/uts/i86pc/os/trap.c
+++ b/usr/src/uts/i86pc/os/trap.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -50,7 +50,6 @@
#include <sys/sysinfo.h>
#include <sys/fault.h>
#include <sys/stack.h>
-#include <sys/mmu.h>
#include <sys/psw.h>
#include <sys/regset.h>
#include <sys/fp.h>
@@ -72,6 +71,7 @@
#include <vm/as.h>
#include <vm/seg.h>
#include <vm/hat_pte.h>
+#include <vm/hat_i86.h>
#include <sys/procfs.h>
@@ -92,6 +92,10 @@
#include <sys/traptrace.h>
#include <sys/ontrap.h>
#include <sys/cpc_impl.h>
+#include <sys/bootconf.h>
+#include <sys/bootinfo.h>
+#include <sys/promif.h>
+#include <sys/mach_mmu.h>
#define USER 0x10000 /* user-mode flag added to trap type */
@@ -276,11 +280,11 @@ instr_is_syscall(caddr_t pc)
#ifdef __amd64
/*
- * In the first revisions of AMD64 CPUs produced by AMD, the LAHF and
- * SAHF instructions were not implemented in 64bit mode. Later revisions
+ * In the first revisions of amd64 CPUs produced by AMD, the LAHF and
+ * SAHF instructions were not implemented in 64-bit mode. Later revisions
* did implement these instructions. An extension to the cpuid instruction
* was added to check for the capability of executing these instructions
- * in 64bit mode.
+ * in 64-bit mode.
*
* Intel originally did not implement these instructions in EM64T either,
* but added them in later revisions.
@@ -367,15 +371,18 @@ instr_is_prefetch(caddr_t pc)
*
* Note: All user-level traps that might call stop() must exit
* trap() by 'goto out' or by falling through.
+ * Note Also: trap() is usually called with interrupts enabled, (PS_IE == 1)
+ * however, there are paths that arrive here with PS_IE == 0 so special care
+ * must be taken in those cases.
*/
void
trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
{
- kthread_t *cur_thread = curthread;
+ kthread_t *ct = curthread;
enum seg_rw rw;
unsigned type;
- proc_t *p = ttoproc(cur_thread);
- klwp_t *lwp = ttolwp(cur_thread);
+ proc_t *p = ttoproc(ct);
+ klwp_t *lwp = ttolwp(ct);
uintptr_t lofault;
faultcode_t pagefault(), res, errcode;
enum fault_type fault_type;
@@ -397,8 +404,7 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
type = rp->r_trapno;
CPU_STATS_ADDQ(CPU, sys, trap, 1);
-
- ASSERT(cur_thread->t_schedflag & TS_DONT_SWAP);
+ ASSERT(ct->t_schedflag & TS_DONT_SWAP);
if (type == T_PGFLT) {
@@ -435,7 +441,8 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
}
#endif /* __i386 */
- }
+ } else if (type == T_SGLSTP && lwp != NULL)
+ lwp->lwp_pcb.pcb_drstat = (uintptr_t)addr;
if (tdebug)
showregs(type, rp, addr);
@@ -448,14 +455,14 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
* the entire trap. If trapping from the kernel, this
* should already be set up.
*/
- if (cur_thread->t_cred != p->p_cred) {
- cred_t *oldcred = cur_thread->t_cred;
+ if (ct->t_cred != p->p_cred) {
+ cred_t *oldcred = ct->t_cred;
/*
* DTrace accesses t_cred in probe context. t_cred
* must always be either NULL, or point to a valid,
* allocated cred structure.
*/
- cur_thread->t_cred = crgetcred();
+ ct->t_cred = crgetcred();
crfree(oldcred);
}
ASSERT(lwp != NULL);
@@ -477,7 +484,7 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
/* Kernel probe */
TNF_PROBE_1(thread_state, "thread", /* CSTYLED */,
tnf_microstate, state, mstate);
- mstate = new_mstate(cur_thread, mstate);
+ mstate = new_mstate(ct, mstate);
bzero(&siginfo, sizeof (siginfo));
}
@@ -518,9 +525,9 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
* If we're under on_trap() protection (see <sys/ontrap.h>),
* set ot_trap and longjmp back to the on_trap() call site.
*/
- if ((cur_thread->t_ontrap != NULL) &&
- (cur_thread->t_ontrap->ot_prot & OT_DATA_ACCESS)) {
- curthread->t_ontrap->ot_trap |= OT_DATA_ACCESS;
+ if ((ct->t_ontrap != NULL) &&
+ (ct->t_ontrap->ot_prot & OT_DATA_ACCESS)) {
+ ct->t_ontrap->ot_trap |= OT_DATA_ACCESS;
longjmp(&curthread->t_ontrap->ot_jmpbuf);
}
@@ -533,10 +540,10 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
* starting and because we know that we always have
* KERNELBASE mapped as invalid to serve as a "barrier".
*/
- lofault = cur_thread->t_lofault;
- cur_thread->t_lofault = 0;
+ lofault = ct->t_lofault;
+ ct->t_lofault = 0;
- mstate = new_mstate(cur_thread, LMS_KFAULT);
+ mstate = new_mstate(ct, LMS_KFAULT);
if (addr < (caddr_t)kernelbase) {
res = pagefault(addr,
@@ -549,13 +556,13 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
res = pagefault(addr,
(errcode & PF_ERR_PROT)? F_PROT: F_INVAL, rw, 1);
}
- (void) new_mstate(cur_thread, mstate);
+ (void) new_mstate(ct, mstate);
/*
* Restore lofault. If we resolved the fault, exit.
* If we didn't and lofault wasn't set, die.
*/
- cur_thread->t_lofault = lofault;
+ ct->t_lofault = lofault;
if (res == 0)
goto cleanup;
@@ -630,7 +637,7 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
else
res = EFAULT;
rp->r_r0 = res;
- rp->r_pc = cur_thread->t_lofault;
+ rp->r_pc = ct->t_lofault;
goto cleanup;
case T_PGFLT + USER: /* user page fault */
@@ -1008,7 +1015,7 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
if (singlestep_twiddle) {
rp->r_ps &= ~PS_T; /* turn off trace */
lwp->lwp_pcb.pcb_flags |= DEBUG_PENDING;
- cur_thread->t_post_sys = 1;
+ ct->t_post_sys = 1;
aston(curthread);
goto cleanup;
}
@@ -1032,16 +1039,20 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
#if defined(__amd64)
/*
* On amd64, we can get a #gp from referencing addresses
- * in the virtual address hole e.g. from a copyin.
+ * in the virtual address hole e.g. from a copyin
+ * or in update_sregs while updating user semgent registers.
*/
/*
* If we're under on_trap() protection (see <sys/ontrap.h>),
* set ot_trap and longjmp back to the on_trap() call site.
*/
- if ((cur_thread->t_ontrap != NULL) &&
- (cur_thread->t_ontrap->ot_prot & OT_DATA_ACCESS)) {
- curthread->t_ontrap->ot_trap |= OT_DATA_ACCESS;
+ if (ct->t_ontrap != NULL) {
+ if (ct->t_ontrap->ot_prot & OT_DATA_ACCESS)
+ ct->t_ontrap->ot_trap |= OT_DATA_ACCESS;
+
+ if (ct->t_ontrap->ot_prot & OT_SEGMENT_ACCESS)
+ ct->t_ontrap->ot_trap |= OT_SEGMENT_ACCESS;
longjmp(&curthread->t_ontrap->ot_jmpbuf);
}
@@ -1049,7 +1060,7 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
* If we're under lofault protection (copyin etc.),
* longjmp back to lofault with an EFAULT.
*/
- if (cur_thread->t_lofault) {
+ if (ct->t_lofault) {
/*
* Fault is not resolvable, so just return to lofault
*/
@@ -1058,14 +1069,28 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
traceregs(rp);
}
rp->r_r0 = EFAULT;
- rp->r_pc = cur_thread->t_lofault;
+ rp->r_pc = ct->t_lofault;
goto cleanup;
}
/*FALLTHROUGH*/
#endif
+ case T_SEGFLT: /* segment not present fault */
+#if defined(__amd64)
+ /*
+ * One example of this is #NP in update_sregs while
+ * attempting to update a user segment register
+ * that points to a descriptor that is marked not
+ * present.
+ */
+ if (ct->t_ontrap != NULL &&
+ ct->t_ontrap->ot_prot & OT_SEGMENT_ACCESS) {
+ ct->t_ontrap->ot_trap |= OT_SEGMENT_ACCESS;
+ longjmp(&curthread->t_ontrap->ot_jmpbuf);
+ }
+#endif /* __amd64 */
+ /*FALLTHROUGH*/
case T_STKFLT: /* stack fault */
case T_TSSFLT: /* invalid TSS fault */
- case T_SEGFLT: /* segment not present fault */
if (tudebug)
showregs(type, rp, (caddr_t)0);
if (kern_gpfault(rp))
@@ -1073,16 +1098,17 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
goto cleanup;
/*FALLTHROUGH*/
-/*
- * ONLY 32-bit PROCESSES can USE a PRIVATE LDT! 64-bit apps should have
- * no legacy need for them, so we put a stop to it here.
- *
- * So: not-present fault is ONLY valid for 32-bit processes with a private LDT
- * trying to do a system call. Emulate it.
- *
- * #gp fault is ONLY valid for 32-bit processes also, which DO NOT have private
- * LDT, and are trying to do a system call. Emulate it.
- */
+ /*
+ * ONLY 32-bit PROCESSES can USE a PRIVATE LDT! 64-bit apps
+ * should have no need for them, so we put a stop to it here.
+ *
+ * So: not-present fault is ONLY valid for 32-bit processes with
+ * a private LDT trying to do a system call. Emulate it.
+ *
+ * #gp fault is ONLY valid for 32-bit processes also, which DO NOT
+ * have a private LDT, and are trying to do a system call. Emulate it.
+ */
+
case T_SEGFLT + USER: /* segment not present fault */
case T_GPFLT + USER: /* general protection violation */
#ifdef _SYSCALL32_IMPL
@@ -1278,14 +1304,14 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
if (lwp->lwp_oweupc)
profil_tick(rp->r_pc);
- if (cur_thread->t_astflag | cur_thread->t_sig_check) {
+ if (ct->t_astflag | ct->t_sig_check) {
/*
* Turn off the AST flag before checking all the conditions that
* may have caused an AST. This flag is on whenever a signal or
* unusual condition should be handled after the next trap or
* syscall.
*/
- astoff(cur_thread);
+ astoff(ct);
/*
* If a single-step trap occurred on a syscall (see above)
* recognize it now. Do this before checking for signals
@@ -1295,7 +1321,7 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
if (lwp->lwp_pcb.pcb_flags & DEBUG_PENDING)
deferred_singlestep_trap((caddr_t)rp->r_pc);
- cur_thread->t_sig_check = 0;
+ ct->t_sig_check = 0;
mutex_enter(&p->p_lock);
if (curthread->t_proc_flag & TP_CHANGEBIND) {
@@ -1329,15 +1355,15 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
* All code that sets signals and makes ISSIG evaluate true must
* set t_astflag afterwards.
*/
- if (ISSIG_PENDING(cur_thread, lwp, p)) {
+ if (ISSIG_PENDING(ct, lwp, p)) {
if (issig(FORREAL))
psig();
- cur_thread->t_sig_check = 1;
+ ct->t_sig_check = 1;
}
- if (cur_thread->t_rprof != NULL) {
+ if (ct->t_rprof != NULL) {
realsigprof(0, 0);
- cur_thread->t_sig_check = 1;
+ ct->t_sig_check = 1;
}
/*
@@ -1374,15 +1400,15 @@ out: /* We can't get here from a system trap */
*/
lwp->lwp_state = LWP_USER;
- if (cur_thread->t_trapret) {
- cur_thread->t_trapret = 0;
- thread_lock(cur_thread);
- CL_TRAPRET(cur_thread);
- thread_unlock(cur_thread);
+ if (ct->t_trapret) {
+ ct->t_trapret = 0;
+ thread_lock(ct);
+ CL_TRAPRET(ct);
+ thread_unlock(ct);
}
if (CPU->cpu_runrun)
preempt();
- (void) new_mstate(cur_thread, mstate);
+ (void) new_mstate(ct, mstate);
/* Kernel probe */
TNF_PROBE_1(thread_state, "thread", /* CSTYLED */,
@@ -1419,7 +1445,7 @@ struct kpreempt_cnts { /* kernel preemption statistics */
void
kpreempt(int asyncspl)
{
- kthread_t *cur_thread = curthread;
+ kthread_t *ct = curthread;
if (IGNORE_KERNEL_PREEMPTION) {
aston(CPU->cpu_dispthread);
@@ -1430,24 +1456,24 @@ kpreempt(int asyncspl)
* Check that conditions are right for kernel preemption
*/
do {
- if (cur_thread->t_preempt) {
+ if (ct->t_preempt) {
/*
* either a privileged thread (idle, panic, interrupt)
* or will check when t_preempt is lowered
*/
- if (cur_thread->t_pri < 0)
+ if (ct->t_pri < 0)
kpreempt_cnts.kpc_idle++;
- else if (cur_thread->t_flag & T_INTR_THREAD) {
+ else if (ct->t_flag & T_INTR_THREAD) {
kpreempt_cnts.kpc_intr++;
- if (cur_thread->t_pil == CLOCK_LEVEL)
+ if (ct->t_pil == CLOCK_LEVEL)
kpreempt_cnts.kpc_clock++;
} else
kpreempt_cnts.kpc_blocked++;
aston(CPU->cpu_dispthread);
return;
}
- if (cur_thread->t_state != TS_ONPROC ||
- cur_thread->t_disp_queue != CPU->cpu_disp) {
+ if (ct->t_state != TS_ONPROC ||
+ ct->t_disp_queue != CPU->cpu_disp) {
/* this thread will be calling swtch() shortly */
kpreempt_cnts.kpc_notonproc++;
if (CPU->cpu_thread != CPU->cpu_dispthread) {
@@ -1467,15 +1493,21 @@ kpreempt(int asyncspl)
kpreempt_cnts.kpc_prilevel++;
return;
}
-
+ if (!interrupts_enabled()) {
+ /*
+ * Can't preempt while running with ints disabled
+ */
+ kpreempt_cnts.kpc_prilevel++;
+ return;
+ }
if (asyncspl != KPREEMPT_SYNC)
kpreempt_cnts.kpc_apreempt++;
else
kpreempt_cnts.kpc_spreempt++;
- cur_thread->t_preempt++;
+ ct->t_preempt++;
preempt();
- cur_thread->t_preempt--;
+ ct->t_preempt--;
} while (CPU->cpu_kprunrun);
}
@@ -1489,8 +1521,8 @@ showregs(uint_t type, struct regs *rp, caddr_t addr)
s = spl7();
type &= ~USER;
- if (u.u_comm[0])
- printf("%s: ", u.u_comm);
+ if (PTOU(curproc)->u_comm[0])
+ printf("%s: ", PTOU(curproc)->u_comm);
if (type < TRAP_TYPES)
printf("#%s %s\n", trap_type_mnemonic[type], trap_type[type]);
else
@@ -1526,7 +1558,7 @@ showregs(uint_t type, struct regs *rp, caddr_t addr)
#else
printf("cr0: %b cr4: %b\n",
(uint_t)getcr0(), FMT_CR0, (uint_t)getcr4(), FMT_CR4);
-#endif
+#endif /* __lint */
#if defined(__amd64)
printf("cr2: %lx cr3: %lx cr8: %lx\n", getcr2(), getcr3(), getcr8());
@@ -1550,7 +1582,8 @@ dumpregs(struct regs *rp)
printf(fmt, "r10", rp->r_r10, "r11", rp->r_r11, "r12", rp->r_r12);
printf(fmt, "r13", rp->r_r13, "r14", rp->r_r14, "r15", rp->r_r15);
- printf(fmt, "fsb", rp->r_fsbase, "gsb", rp->r_gsbase, " ds", rp->r_ds);
+ printf(fmt, "fsb", rdmsr(MSR_AMD_FSBASE), "gsb", rdmsr(MSR_AMD_GSBASE),
+ " ds", rp->r_ds);
printf(fmt, " es", rp->r_es, " fs", rp->r_fs, " gs", rp->r_gs);
printf(fmt, "trp", rp->r_trapno, "err", rp->r_err, "rip", rp->r_rip);
@@ -1610,7 +1643,6 @@ kern_gpfault(struct regs *rp)
extern void _sys_rtt(), sr_sup();
#if defined(__amd64)
- extern void _update_sregs(), _update_sregs_done();
static const uint8_t iretq_insn[2] = { 0x48, 0xcf };
#elif defined(__i386)
@@ -1678,23 +1710,6 @@ kern_gpfault(struct regs *rp)
ASSERT(trp->r_pc == lwptoregs(lwp)->r_pc);
ASSERT(trp->r_err == rp->r_err);
- } else if ((lwp->lwp_pcb.pcb_flags & RUPDATE_PENDING) != 0 &&
- pc >= (caddr_t)_update_sregs &&
- pc < (caddr_t)_update_sregs_done) {
- /*
- * This is the common case -- we're trying to load
- * a bad segment register value in the only section
- * of kernel code that ever loads segment registers.
- *
- * We don't need to do anything at this point because
- * the pcb contains all the pending segment register
- * state, and the regs are still intact because we
- * didn't adjust the stack pointer yet. Given the fidelity
- * of all this, we could conceivably send a signal
- * to the lwp, rather than core-ing.
- */
- trp = lwptoregs(lwp);
- ASSERT((caddr_t)trp == (caddr_t)rp->r_sp);
}
#elif defined(__i386)
@@ -1870,7 +1885,7 @@ dump_ttrace(void)
const char fmt1[] = "%3d %016lx %12llx ";
#elif defined(__i386)
const char banner[] =
- "\ncpu address timestamp type vc handler pc\n";
+ "\ncpu address timestamp type vc handler pc\n";
const char fmt1[] = "%3d %08lx %12llx ";
#endif
const char fmt2[] = "%4s %3x ";
@@ -1943,11 +1958,11 @@ dump_ttrace(void)
(uintptr_t)sys->sy_callc,
&off);
if (sym != NULL)
- printf("%s ", sym);
+ printf(fmt3, sym);
else
printf("%p ", sys->sy_callc);
} else {
- printf("unknown ");
+ printf(fmt3, "unknown");
}
break;
@@ -1958,19 +1973,36 @@ dump_ttrace(void)
sym = kobj_getsymname(
(uintptr_t)vec->av_vector, &off);
if (sym != NULL)
- printf("%s ", sym);
+ printf(fmt3, sym);
else
printf("%p ", vec->av_vector);
} else {
- printf("unknown ");
+ printf(fmt3, "unknown ");
}
break;
case TT_TRAP:
+ case TT_EVENT:
type = rec->ttr_regs.r_trapno;
printf(fmt2, "trap", type);
- printf("#%s ", type < TRAP_TYPES ?
- trap_type_mnemonic[type] : "trap");
+ if (type < TRAP_TYPES)
+ printf(" #%s ",
+ trap_type_mnemonic[type]);
+ else
+ switch (type) {
+ case T_AST:
+ printf(fmt3, "ast");
+ break;
+ default:
+ printf(fmt3, "");
+ break;
+ }
+ break;
+
+ case TT_XCALL:
+ printf(fmt2, "xcal",
+ rec->ttr_info.xc_entry.xce_marker);
+ printf(fmt3, "");
break;
default:
@@ -2026,6 +2058,36 @@ dump_ttrace(void)
}
}
+/*
+ * Help with constructing traptrace records in C
+ */
+trap_trace_rec_t *
+trap_trace_get_traceptr(uint8_t marker, ulong_t pc, ulong_t sp)
+{
+ trap_trace_rec_t *ttr;
+
+ if (trap_trace_freeze)
+ ttr = &trap_trace_postmort;
+ else {
+ trap_trace_ctl_t *ttc = &trap_trace_ctl[CPU->cpu_id];
+
+ ttr = (void *)ttc->ttc_next;
+
+ if (ttc->ttc_next >= ttc->ttc_limit)
+ ttc->ttc_next = ttc->ttc_first;
+ else
+ ttc->ttc_next += sizeof (trap_trace_rec_t);
+ }
+
+ ttr->ttr_regs.r_sp = sp;
+ ttr->ttr_regs.r_pc = pc;
+ ttr->ttr_cr2 = getcr2();
+ ttr->ttr_curthread = (uintptr_t)curthread;
+ ttr->ttr_stamp = tsc_read();
+ ttr->ttr_marker = marker;
+ return (ttr);
+}
+
#endif /* TRAPTRACE */
void
diff --git a/usr/src/uts/i86pc/os/x_call.c b/usr/src/uts/i86pc/os/x_call.c
index f29cf1a94c..2520cb95dc 100644
--- a/usr/src/uts/i86pc/os/x_call.c
+++ b/usr/src/uts/i86pc/os/x_call.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,7 +31,6 @@
*/
#include <sys/types.h>
-
#include <sys/param.h>
#include <sys/t_lock.h>
#include <sys/thread.h>
@@ -40,11 +39,13 @@
#include <sys/cpu.h>
#include <sys/psw.h>
#include <sys/sunddi.h>
-#include <sys/mmu.h>
#include <sys/debug.h>
#include <sys/systm.h>
+#include <sys/archsystm.h>
#include <sys/machsystm.h>
#include <sys/mutex_impl.h>
+#include <sys/traptrace.h>
+
static struct xc_mbox xc_mboxes[X_CALL_LEVELS];
static kmutex_t xc_mbox_lock[X_CALL_LEVELS];
@@ -58,7 +59,6 @@ static void xc_common(xc_func_t, xc_arg_t, xc_arg_t, xc_arg_t,
int, cpuset_t, int);
static int xc_initialized = 0;
-extern cpuset_t cpu_ready_set;
void
xc_init()
@@ -78,15 +78,41 @@ xc_init()
xc_initialized = 1;
}
+#if defined(TRAPTRACE)
+
/*
- * Used by the debugger to determine whether or not cross calls have been
- * initialized and are safe to use.
+ * When xc_traptrace is on, put x-call records into the trap trace buffer.
*/
-int
-kdi_xc_initialized(void)
+int xc_traptrace;
+
+void
+xc_make_trap_trace_entry(uint8_t marker, int pri, ulong_t arg)
{
- return (xc_initialized);
+ trap_trace_rec_t *ttr;
+ struct _xc_entry *xce;
+
+ if (xc_traptrace == 0)
+ return;
+
+ ttr = trap_trace_get_traceptr(TT_XCALL,
+ (ulong_t)caller(), (ulong_t)getfp());
+ xce = &(ttr->ttr_info.xc_entry);
+
+ xce->xce_marker = marker;
+ xce->xce_pri = pri;
+ xce->xce_arg = arg;
+
+ if ((uint_t)pri < X_CALL_LEVELS) {
+ struct machcpu *mcpu = &CPU->cpu_m;
+
+ xce->xce_pend = mcpu->xc_pend[pri];
+ xce->xce_ack = mcpu->xc_ack[pri];
+ xce->xce_state = mcpu->xc_state[pri];
+ xce->xce_retval = mcpu->xc_retval[pri];
+ xce->xce_func = (uintptr_t)xc_mboxes[pri].func;
+ }
}
+#endif
#define CAPTURE_CPU_ARG ~0UL
@@ -101,58 +127,53 @@ kdi_xc_initialized(void)
uint_t
xc_serv(caddr_t arg1, caddr_t arg2)
{
- int op;
- int pri = (int)(uintptr_t)arg1;
+ int op;
+ int pri = (int)(uintptr_t)arg1;
struct cpu *cpup = CPU;
- xc_arg_t *argp;
xc_arg_t arg2val;
- uint_t tlbflush;
+
+ XC_TRACE(TT_XC_SVC_BEGIN, pri, (ulong_t)arg2);
if (pri == X_CALL_MEDPRI) {
- argp = &xc_mboxes[X_CALL_MEDPRI].arg2;
- arg2val = *argp;
+ arg2val = xc_mboxes[X_CALL_MEDPRI].arg2;
+
if (arg2val != CAPTURE_CPU_ARG &&
!CPU_IN_SET((cpuset_t)arg2val, cpup->cpu_id))
- return (DDI_INTR_UNCLAIMED);
+ goto unclaimed;
+
ASSERT(arg2val == CAPTURE_CPU_ARG);
+
if (cpup->cpu_m.xc_pend[pri] == 0)
- return (DDI_INTR_UNCLAIMED);
+ goto unclaimed;
cpup->cpu_m.xc_pend[X_CALL_MEDPRI] = 0;
cpup->cpu_m.xc_ack[X_CALL_MEDPRI] = 1;
for (;;) {
if ((cpup->cpu_m.xc_state[X_CALL_MEDPRI] == XC_DONE) ||
- (cpup->cpu_m.xc_pend[X_CALL_MEDPRI]))
+ (cpup->cpu_m.xc_pend[X_CALL_MEDPRI]))
break;
- ht_pause();
+ SMT_PAUSE();
}
+ XC_TRACE(TT_XC_SVC_END, pri, DDI_INTR_CLAIMED);
return (DDI_INTR_CLAIMED);
}
+
if (cpup->cpu_m.xc_pend[pri] == 0)
- return (DDI_INTR_UNCLAIMED);
+ goto unclaimed;
cpup->cpu_m.xc_pend[pri] = 0;
op = cpup->cpu_m.xc_state[pri];
/*
- * When invalidating TLB entries, wait until the initiator changes the
- * memory PTE before doing any INVLPG. Otherwise, if the PTE in memory
- * hasn't been changed, the processor's TLB Flush filter may ignore
- * the INVLPG instruction.
- */
- tlbflush = (cpup->cpu_m.xc_wait[pri] == 2);
-
- /*
* Don't invoke a null function.
*/
- if (xc_mboxes[pri].func != NULL) {
- if (!tlbflush)
- cpup->cpu_m.xc_retval[pri] = (*xc_mboxes[pri].func)
- (xc_mboxes[pri].arg1, xc_mboxes[pri].arg2,
- xc_mboxes[pri].arg3);
- } else
+ if (xc_mboxes[pri].func != NULL)
+ cpup->cpu_m.xc_retval[pri] = (*xc_mboxes[pri].func)
+ (xc_mboxes[pri].arg1, xc_mboxes[pri].arg2,
+ xc_mboxes[pri].arg3);
+ else
cpup->cpu_m.xc_retval[pri] = 0;
/*
@@ -160,36 +181,31 @@ xc_serv(caddr_t arg1, caddr_t arg2)
*/
cpup->cpu_m.xc_ack[pri] = 1;
- if (op == XC_CALL_OP)
- return (DDI_INTR_CLAIMED);
-
- /*
- * for (op == XC_SYNC_OP)
- * Wait for the initiator of the x-call to indicate
- * that all CPUs involved can proceed.
- */
- while (cpup->cpu_m.xc_wait[pri])
- ht_pause();
-
- while (cpup->cpu_m.xc_state[pri] != XC_DONE)
- ht_pause();
-
- /*
- * Flush the TLB, if that's what is requested.
- */
- if (xc_mboxes[pri].func != NULL && tlbflush) {
- cpup->cpu_m.xc_retval[pri] = (*xc_mboxes[pri].func)
- (xc_mboxes[pri].arg1, xc_mboxes[pri].arg2,
- xc_mboxes[pri].arg3);
+ if (op != XC_CALL_OP) {
+ /*
+ * for (op == XC_SYNC_OP)
+ * Wait for the initiator of the x-call to indicate
+ * that all CPUs involved can proceed.
+ */
+ while (cpup->cpu_m.xc_wait[pri])
+ SMT_PAUSE();
+
+ while (cpup->cpu_m.xc_state[pri] != XC_DONE)
+ SMT_PAUSE();
+
+ /*
+ * Acknowledge that we have received the directive to continue.
+ */
+ ASSERT(cpup->cpu_m.xc_ack[pri] == 0);
+ cpup->cpu_m.xc_ack[pri] = 1;
}
- /*
- * Acknowledge that we have received the directive to continue.
- */
- ASSERT(cpup->cpu_m.xc_ack[pri] == 0);
- cpup->cpu_m.xc_ack[pri] = 1;
-
+ XC_TRACE(TT_XC_SVC_END, pri, DDI_INTR_CLAIMED);
return (DDI_INTR_CLAIMED);
+
+unclaimed:
+ XC_TRACE(TT_XC_SVC_END, pri, DDI_INTR_UNCLAIMED);
+ return (DDI_INTR_UNCLAIMED);
}
@@ -261,23 +277,6 @@ xc_sync(
xc_do_call(arg1, arg2, arg3, pri, set, func, 1);
}
-/*
- * xc_sync_wait: similar to xc_sync(), except that the starting
- * cpu waits for all other cpus to check in before running its
- * service locally.
- */
-void
-xc_wait_sync(
- xc_arg_t arg1,
- xc_arg_t arg2,
- xc_arg_t arg3,
- int pri,
- cpuset_t set,
- xc_func_t func)
-{
- xc_do_call(arg1, arg2, arg3, pri, set, func, 2);
-}
-
/*
* The routines xc_capture_cpus and xc_release_cpus
@@ -329,7 +328,7 @@ xc_capture_cpus(cpuset_t set)
CPUSET_AND(c, cpu_ready_set);
if (CPUSET_ISNULL(c))
break;
- ht_pause();
+ SMT_PAUSE();
}
/*
@@ -358,6 +357,7 @@ xc_capture_cpus(cpuset_t set)
cpup->cpu_m.xc_ack[X_CALL_MEDPRI] = 0;
cpup->cpu_m.xc_state[X_CALL_MEDPRI] = XC_HOLD;
cpup->cpu_m.xc_pend[X_CALL_MEDPRI] = 1;
+ XC_TRACE(TT_XC_CAPTURE, X_CALL_MEDPRI, cix);
send_dirint(cix, XC_MED_PIL);
}
i++;
@@ -366,14 +366,14 @@ xc_capture_cpus(cpuset_t set)
}
/*
- * Wait here until all remote calls to complete.
+ * Wait here until all remote calls to acknowledge.
*/
i = 0;
for (cix = 0; cix < NCPU; cix++) {
if (lcx != cix && CPU_IN_SET(set, cix)) {
cpup = cpu[cix];
while (cpup->cpu_m.xc_ack[X_CALL_MEDPRI] == 0)
- ht_pause();
+ SMT_PAUSE();
cpup->cpu_m.xc_ack[X_CALL_MEDPRI] = 0;
}
i++;
@@ -411,6 +411,7 @@ xc_release_cpus(void)
* Clear xc_ack since we will be waiting for it
* to be set again after we set XC_DONE.
*/
+ XC_TRACE(TT_XC_RELEASE, X_CALL_MEDPRI, cix);
cpup->cpu_m.xc_state[X_CALL_MEDPRI] = XC_DONE;
}
i++;
@@ -428,7 +429,6 @@ xc_release_cpus(void)
* -1 - no waiting, don't release remotes
* 0 - no waiting, release remotes immediately
* 1 - run service locally w/o waiting for remotes.
- * 2 - wait for remotes before running locally
*/
static void
xc_common(
@@ -480,37 +480,35 @@ xc_common(
else
cpup->cpu_m.xc_state[pri] = XC_CALL_OP;
cpup->cpu_m.xc_pend[pri] = 1;
+ XC_TRACE(TT_XC_START, pri, cix);
send_dirint(cix, xc_xlat_xcptoipl[pri]);
}
}
/*
- * Run service locally if not waiting for remotes.
+ * Run service locally.
*/
- if (sync != 2 && CPU_IN_SET(set, lcx) && func != NULL)
+ if (CPU_IN_SET(set, lcx) && func != NULL) {
+ XC_TRACE(TT_XC_START, pri, CPU->cpu_id);
CPU->cpu_m.xc_retval[pri] = (*func)(arg1, arg2, arg3);
+ }
if (sync == -1)
return;
/*
- * Wait here until all remote calls complete.
+ * Wait here until all remote calls acknowledge.
*/
for (cix = 0; cix < NCPU; cix++) {
if (lcx != cix && CPU_IN_SET(set, cix)) {
cpup = cpu[cix];
while (cpup->cpu_m.xc_ack[pri] == 0)
- ht_pause();
+ SMT_PAUSE();
+ XC_TRACE(TT_XC_WAIT, pri, cix);
cpup->cpu_m.xc_ack[pri] = 0;
}
}
- /*
- * Run service locally if waiting for remotes.
- */
- if (sync == 2 && CPU_IN_SET(set, lcx) && func != NULL)
- CPU->cpu_m.xc_retval[pri] = (*func)(arg1, arg2, arg3);
-
if (sync == 0)
return;
@@ -540,7 +538,8 @@ xc_common(
cpup = cpu[cix];
if (cpup != NULL && (cpup->cpu_flags & CPU_READY)) {
while (cpup->cpu_m.xc_ack[pri] == 0)
- ht_pause();
+ SMT_PAUSE();
+ XC_TRACE(TT_XC_ACK, pri, cix);
cpup->cpu_m.xc_ack[pri] = 0;
}
}
@@ -592,6 +591,9 @@ kdi_xc_others(int this_cpu, void (*func)(void))
cpuset_t set;
int x;
+ if (!xc_initialized)
+ return;
+
CPUSET_ALL_BUT(set, this_cpu);
save_kernel_preemption = IGNORE_KERNEL_PREEMPTION;
diff --git a/usr/src/uts/i86pc/pcplusmp/Makefile b/usr/src/uts/i86pc/pcplusmp/Makefile
index 18b7a414d2..f0e108904d 100644
--- a/usr/src/uts/i86pc/pcplusmp/Makefile
+++ b/usr/src/uts/i86pc/pcplusmp/Makefile
@@ -21,7 +21,7 @@
#
# uts/i86pc/pcplusmp/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -43,7 +43,7 @@ UTSBASE = ../..
MODULE = pcplusmp
OBJECTS = $(PCPLUSMP_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(PCPLUSMP_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_MACH_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_PSM_MACH_DIR)/$(MODULE)
#
# Include common rules.
diff --git a/usr/src/uts/i86pc/sys/Makefile b/usr/src/uts/i86pc/sys/Makefile
index d1ae51babe..c3afe499df 100644
--- a/usr/src/uts/i86pc/sys/Makefile
+++ b/usr/src/uts/i86pc/sys/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -22,7 +21,7 @@
#
#pragma ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# uts/i86pc/sys/Makefile
@@ -46,12 +45,14 @@ HDRS= \
clock.h \
cram.h \
ddi_subrdefs.h \
+ debug_info.h \
+ mach_mmu.h \
machcpuvar.h \
machparam.h \
machsystm.h \
machthread.h \
memnode.h \
- pmem.h \
+ pc_mmu.h \
psm.h \
psm_defs.h \
psm_modctl.h \
@@ -60,7 +61,8 @@ HDRS= \
smp_impldefs.h \
vm_machparam.h \
x_call.h \
- xc_levels.h
+ xc_levels.h \
+ xsvc.h
ROOTHDRS= $(HDRS:%=$(USR_PSM_ISYS_DIR)/%)
diff --git a/usr/src/uts/i86pc/io/pcplusmp/apic.h b/usr/src/uts/i86pc/sys/apic.h
index 56cef05819..ede1d1225e 100644
--- a/usr/src/uts/i86pc/io/pcplusmp/apic.h
+++ b/usr/src/uts/i86pc/sys/apic.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,6 +28,8 @@
#pragma ident "%Z%%M% %I% %E% SMI"
+#include <sys/psm_types.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -230,7 +232,7 @@ struct apic_io_entry {
#define IOAPIC_FLAGS_EN 0x01 /* this I/O apic is enable or not */
-#define MAX_IO_APIC 32 /* maximum # of I/O apic supported */
+#define MAX_IO_APIC 32 /* maximum # of IOAPICs supported */
struct apic_io_intr {
uint_t intr_entry: 8,
@@ -333,8 +335,8 @@ struct apic_io_intr {
/* special or reserve vectors */
#define APIC_CHECK_RESERVE_VECTORS(v) \
- ((v == T_FASTTRAP) || (v == APIC_SPUR_INTR) || (v == T_SYSCALLINT) ||\
- (v == T_DTRACE_RET) || (v == T_INT80))
+ ((v == T_FASTTRAP) || (v == APIC_SPUR_INTR) || (v == T_SYSCALLINT) || \
+ (v == T_DTRACE_RET) || (v == T_INT80))
/* cmos shutdown code for BIOS */
#define BIOS_SHUTDOWN 0x0a
@@ -421,7 +423,7 @@ typedef struct apic_irq {
* to another CPU.
*/
major_t airq_major; /* major number corresponding to the device */
- ushort_t airq_rdt_entry; /* level, polarity & trig mode */
+ ushort_t airq_rdt_entry; /* level, polarity & trig mode */
uchar_t airq_cpu; /* Which CPU are we bound to ? */
uchar_t airq_temp_cpu; /* Could be diff from cpu due to disable_intr */
uchar_t airq_vector; /* Vector chosen for this irq */
@@ -515,22 +517,21 @@ typedef struct apic_cpus_info {
#define SMS_WRITE_STATE 0x80
#define SMS_ERROR_STATE 0xc0
+extern uint32_t ioapic_read(int ioapic_ix, uint32_t reg);
+extern void ioapic_write(int ioapic_ix, uint32_t reg, uint32_t value);
+
/* Macros for reading/writing the IOAPIC RDT entries */
-#define READ_IOAPIC_RDT_ENTRY_LOW_DWORD(addr, ipin) \
- ((addr)[APIC_IO_REG] = APIC_RDT_CMD + (2 * (ipin)),\
- (addr)[APIC_IO_DATA])
+#define READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix, ipin) \
+ ioapic_read(ioapic_ix, APIC_RDT_CMD + (2 * (ipin)))
-#define READ_IOAPIC_RDT_ENTRY_HIGH_DWORD(addr, ipin) \
- ((addr)[APIC_IO_REG] = APIC_RDT_CMD2 + (2 * (ipin)),\
- (addr)[APIC_IO_DATA])
+#define READ_IOAPIC_RDT_ENTRY_HIGH_DWORD(ioapic_ix, ipin) \
+ ioapic_read(ioapic_ix, APIC_RDT_CMD2 + (2 * (ipin)))
-#define WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(addr, ipin, value) \
- (addr)[APIC_IO_REG] = APIC_RDT_CMD + (2 * (ipin));\
- (addr)[APIC_IO_DATA] = (value)
+#define WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix, ipin, value) \
+ ioapic_write(ioapic_ix, APIC_RDT_CMD + (2 * (ipin)), value)
-#define WRITE_IOAPIC_RDT_ENTRY_HIGH_DWORD(addr, ipin, value) \
- (addr)[APIC_IO_REG] = APIC_RDT_CMD2 + (2 * (ipin));\
- (addr)[APIC_IO_DATA] = (value)
+#define WRITE_IOAPIC_RDT_ENTRY_HIGH_DWORD(ioapic_ix, ipin, value) \
+ ioapic_write(ioapic_ix, APIC_RDT_CMD2 + (2 * (ipin)), value)
/* Used by PSM_INTR_OP_GET_INTR to return device information. */
typedef struct {
@@ -567,11 +568,175 @@ typedef struct {
#define APIC_NSECS_TO_TICKS(nsecs) (((int64_t)(nsecs) * \
apic_ticks_per_SFnsecs + (SF/2)) / SF)
-extern uchar_t apic_bind_intr(dev_info_t *, int, uchar_t, uchar_t);
-extern int apic_allocate_irq(int);
-extern int apic_introp_xlate(dev_info_t *, struct intrspec *, int);
-extern int apic_rebind_all(apic_irq_t *irq_ptr, int bind_cpu);
+extern int apic_verbose;
+
+/* Flag definitions for apic_verbose */
+#define APIC_VERBOSE_IOAPIC_FLAG 0x00000001
+#define APIC_VERBOSE_IRQ_FLAG 0x00000002
+#define APIC_VERBOSE_POWEROFF_FLAG 0x00000004
+#define APIC_VERBOSE_POWEROFF_PAUSE_FLAG 0x00000008
+
+
+#define APIC_VERBOSE_IOAPIC(fmt) \
+ if (apic_verbose & APIC_VERBOSE_IOAPIC_FLAG) \
+ cmn_err fmt;
+
+#define APIC_VERBOSE_IRQ(fmt) \
+ if (apic_verbose & APIC_VERBOSE_IRQ_FLAG) \
+ cmn_err fmt;
+
+#define APIC_VERBOSE_POWEROFF(fmt) \
+ if (apic_verbose & APIC_VERBOSE_POWEROFF_FLAG) \
+ prom_printf fmt;
+
+#ifdef DEBUG
+#define DENT 0x0001
+extern int apic_debug;
+/*
+ * set apic_restrict_vector to the # of vectors we want to allow per range
+ * useful in testing shared interrupt logic by setting it to 2 or 3
+ */
+extern int apic_restrict_vector;
+
+#define APIC_DEBUG_MSGBUFSIZE 2048
+extern int apic_debug_msgbuf[];
+extern int apic_debug_msgbufindex;
+
+/*
+ * Put "int" info into debug buffer. No MP consistency, but light weight.
+ * Good enough for most debugging.
+ */
+#define APIC_DEBUG_BUF_PUT(x) \
+ apic_debug_msgbuf[apic_debug_msgbufindex++] = x; \
+ if (apic_debug_msgbufindex >= (APIC_DEBUG_MSGBUFSIZE - NCPU)) \
+ apic_debug_msgbufindex = 0;
+
+#endif /* DEBUG */
+
+extern int apic_error;
+/* values which apic_error can take. Not catastrophic, but may help debug */
+#define APIC_ERR_BOOT_EOI 0x1
+#define APIC_ERR_GET_IPIVECT_FAIL 0x2
+#define APIC_ERR_INVALID_INDEX 0x4
+#define APIC_ERR_MARK_VECTOR_FAIL 0x8
+#define APIC_ERR_APIC_ERROR 0x40000000
+#define APIC_ERR_NMI 0x80000000
+
+/*
+ * ACPI definitions
+ */
+/* _PIC method arguments */
+#define ACPI_PIC_MODE 0
+#define ACPI_APIC_MODE 1
+
+/* APIC error flags we care about */
+#define APIC_SEND_CS_ERROR 0x01
+#define APIC_RECV_CS_ERROR 0x02
+#define APIC_CS_ERRORS (APIC_SEND_CS_ERROR|APIC_RECV_CS_ERROR)
+
+/* Maximum number of times to retry reprogramming at apic_intr_exit time */
+#define APIC_REPROGRAM_MAX_TRIES 10000
+
+/* Parameter to ioapic_init_intr(): Should ioapic ints be masked? */
+#define IOAPIC_MASK 1
+#define IOAPIC_NOMASK 0
+
+#define INTR_ROUND_ROBIN_WITH_AFFINITY 0
+#define INTR_ROUND_ROBIN 1
+#define INTR_LOWEST_PRIORITY 2
+
+
+
+struct ioapic_reprogram_data {
+ boolean_t done;
+ apic_irq_t *irqp;
+ /* The CPU to which the int will be bound */
+ int bindcpu;
+ /* # times the reprogram timeout was called */
+ unsigned tries;
+};
+
+/* The irq # is implicit in the array index: */
+extern struct ioapic_reprogram_data apic_reprogram_info[];
+
+extern void apic_intr_exit(int ipl, int irq);
+extern int apic_probe_common();
+extern void apic_init_common();
+extern void ioapic_init_intr();
+extern void ioapic_disable_redirection();
+extern int apic_addspl_common(int irqno, int ipl, int min_ipl, int max_ipl);
+extern int apic_delspl_common(int irqno, int ipl, int min_ipl, int max_ipl);
+extern void apic_cleanup_busy();
+extern void apic_intr_redistribute();
+extern uchar_t apic_xlate_vector(uchar_t vector);
+extern uchar_t apic_allocate_vector(int ipl, int irq, int pri);
+extern void apic_free_vector(uchar_t vector);
+extern int apic_allocate_irq(int irq);
+extern uchar_t apic_bind_intr(dev_info_t *dip, int irq, uchar_t ioapicid,
+ uchar_t intin);
+extern int apic_rebind(apic_irq_t *irq_ptr, int bind_cpu,
+ struct ioapic_reprogram_data *drep);
+extern int apic_rebind_all(apic_irq_t *irq_ptr, int bind_cpu);
+extern int apic_introp_xlate(dev_info_t *dip, struct intrspec *ispec, int type);
+extern int apic_intr_ops(dev_info_t *dip, ddi_intr_handle_impl_t *hdlp,
+ psm_intr_op_t intr_op, int *result);
extern boolean_t apic_cpu_in_range(int cpu);
+extern int apic_check_msi_support();
+extern apic_irq_t *apic_find_irq(dev_info_t *dip, struct intrspec *ispec,
+ int type);
+extern int apic_navail_vector(dev_info_t *dip, int pri);
+extern int apic_alloc_vectors(dev_info_t *dip, int inum, int count, int pri,
+ int type, int behavior);
+extern void apic_free_vectors(dev_info_t *dip, int inum, int count, int pri,
+ int type);
+extern int apic_get_vector_intr_info(int vecirq,
+ apic_get_intr_t *intr_params_p);
+extern uchar_t apic_find_multi_vectors(int pri, int count);
+extern int apic_setup_io_intr(void *p, int irq, boolean_t deferred);
+extern uint32_t *mapin_apic(uint32_t addr, size_t len, int flags);
+extern uint32_t *mapin_ioapic(uint32_t addr, size_t len, int flags);
+extern void mapout_apic(caddr_t addr, size_t len);
+extern void mapout_ioapic(caddr_t addr, size_t len);
+extern uchar_t apic_modify_vector(uchar_t vector, int irq);
+extern int apic_pci_msi_unconfigure(dev_info_t *rdip, int type, int inum);
+extern int apic_pci_msi_disable_mode(dev_info_t *rdip, int type, int inum);
+extern int apic_pci_msi_enable_mode(dev_info_t *rdip, int type, int inum);
+
+extern volatile uint32_t *apicadr; /* virtual addr of local APIC */
+extern int apic_forceload;
+extern apic_cpus_info_t *apic_cpus;
+extern cpuset_t apic_cpumask;
+extern uint_t apic_flag;
+extern uchar_t apic_ipltopri[MAXIPL+1];
+extern uchar_t apic_vector_to_irq[APIC_MAX_VECTOR+1];
+extern int apic_max_device_irq;
+extern int apic_min_device_irq;
+extern apic_irq_t *apic_irq_table[APIC_MAX_VECTOR+1];
+extern volatile uint32_t *apicioadr[MAX_IO_APIC];
+extern uchar_t apic_io_id[MAX_IO_APIC];
+extern lock_t apic_ioapic_lock;
+extern uint32_t apic_physaddr[MAX_IO_APIC];
+extern kmutex_t airq_mutex;
+extern int apic_first_avail_irq;
+extern uchar_t apic_vectortoipl[APIC_AVAIL_VECTOR / APIC_VECTOR_PER_IPL];
+extern int apic_imcrp;
+extern int apic_revector_pending;
+extern char apic_level_intr[APIC_MAX_VECTOR+1];
+extern uchar_t apic_resv_vector[MAXIPL+1];
+extern int apic_sample_factor_redistribution;
+extern int apic_int_busy_mark;
+extern int apic_int_free_mark;
+extern int apic_diff_for_redistribution;
+extern int apic_poweroff_method;
+extern int apic_enable_acpi;
+extern int apic_nproc;
+extern int apic_next_bind_cpu;
+extern int apic_redistribute_sample_interval;
+extern int apic_multi_msi_enable;
+extern int apic_multi_msi_max;
+extern int apic_sci_vect;
+
+
#ifdef __cplusplus
}
diff --git a/usr/src/uts/i86pc/sys/asm_misc.h b/usr/src/uts/i86pc/sys/asm_misc.h
index 0003f220ab..be45a97886 100644
--- a/usr/src/uts/i86pc/sys/asm_misc.h
+++ b/usr/src/uts/i86pc/sys/asm_misc.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -49,6 +48,42 @@ extern "C" {
#define STI_INSTR 0xfb
#define JMP_INSTR 0x00eb
+
+#if defined(__i386)
+
+#define _HOT_PATCH_PROLOG \
+ push %ebp; \
+ mov %esp, %ebp; \
+ push %ebx; \
+ push %esi; \
+ push %edi
+
+#define _HOT_PATCH(srcaddr, dstaddr, size) \
+ movl $srcaddr, %esi; \
+ movl $dstaddr, %edi; \
+ movl $size, %ebx; \
+0: pushl $1; \
+ /*CSTYLED*/ \
+ movzbl (%esi), %eax; \
+ pushl %eax; \
+ pushl %edi; \
+ call hot_patch_kernel_text; \
+ addl $12, %esp; \
+ inc %edi; \
+ inc %esi; \
+ dec %ebx; \
+ test %ebx, %ebx; \
+ jne 0b
+
+#define _HOT_PATCH_EPILOG \
+ pop %edi; \
+ pop %esi; \
+ pop %ebx; \
+ mov %ebp, %esp; \
+ pop %ebp
+
+#endif /* __i386 */
+
#endif /* _ASM */
#ifdef __cplusplus
diff --git a/usr/src/psm/stand/boot/i386/common/console.h b/usr/src/uts/i86pc/sys/boot_console.h
index ca28b967f6..92fa9cebf5 100644
--- a/usr/src/psm/stand/boot/i386/common/console.h
+++ b/usr/src/uts/i86pc/sys/boot_console.h
@@ -19,12 +19,16 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#ifndef _CONSOLE_H
-#define _CONSOLE_H
+/*
+ * This file is shared between dboot and the kernel.
+ */
+
+#ifndef _BOOT_CONSOLE_H
+#define _BOOT_CONSOLE_H
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -34,29 +38,27 @@ extern "C" {
#define CONS_INVALID -1
#define CONS_SCREEN_TEXT 0
-#define CONS_SCREEN_GRAPHICS 1
-#define CONS_TTYA 2
-#define CONS_TTYB 3
-#define CONS_USBSER 4
+#define CONS_TTYA 1
+#define CONS_TTYB 2
+#define CONS_USBSER 3
#define CONS_COLOR 7
-#define VGA_GRAPHICS 0x12
-
extern void kb_init(void);
extern int kb_getchar(void);
extern int kb_ischar(void);
-extern char *console_init(char *);
-extern void console_init2(char *, char *, char *);
-extern void text_init(void);
-extern void putchar(int);
-extern int getchar(void);
-extern int ischar(void);
-extern int cons_gets(char *, int);
+extern void bcons_init(char *);
+extern void bcons_init2(char *, char *, char *);
+extern void bcons_putchar(int);
+extern int bcons_getchar(void);
+extern int bcons_ischar(void);
+extern int bcons_gets(char *, int);
+
+extern int console;
#ifdef __cplusplus
}
#endif
-#endif /* _CONSOLE_H */
+#endif /* _BOOT_CONSOLE_H */
diff --git a/usr/src/uts/i86pc/sys/clock.h b/usr/src/uts/i86pc/sys/clock.h
index d058a8ae72..efabb1c84c 100644
--- a/usr/src/uts/i86pc/sys/clock.h
+++ b/usr/src/uts/i86pc/sys/clock.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -43,10 +42,13 @@ extern "C" {
#if defined(__GNUC__) && defined(_ASM_INLINES)
#include <asm/clock.h>
#endif
+#include <sys/machclock.h>
+
+extern time_t ggmtl(void);
+extern void sgmtl(time_t);
+extern void rtcsync(void);
extern void unlock_hres_lock(void);
-extern timestruc_t pc_tod_get(void);
-extern void pc_tod_set(timestruc_t);
extern void hres_tick(void);
extern void (*hrtime_tick)(void);
@@ -60,7 +62,7 @@ extern void tsc_tick(void);
extern void tsc_sync_master(processorid_t);
extern void tsc_sync_slave(void);
extern hrtime_t tsc_read(void);
-
+extern hrtime_t __rdtsc_insn(void);
#define ADJ_SHIFT 4 /* used in get_hrestime */
diff --git a/usr/src/uts/i86pc/sys/debug_info.h b/usr/src/uts/i86pc/sys/debug_info.h
new file mode 100644
index 0000000000..3c626fd360
--- /dev/null
+++ b/usr/src/uts/i86pc/sys/debug_info.h
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_DEBUG_INFO_H
+#define _SYS_DEBUG_INFO_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/machparam.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DEBUG_INFO_MAGIC 0xdeb116ed
+#define DEBUG_INFO_VERSION 0x1
+
+typedef struct debug_info {
+ uint32_t di_magic;
+ uint32_t di_version;
+} debug_info_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_DEBUG_INFO_H */
diff --git a/usr/src/uts/i86pc/sys/mach_mmu.h b/usr/src/uts/i86pc/sys/mach_mmu.h
new file mode 100644
index 0000000000..431c6045e4
--- /dev/null
+++ b/usr/src/uts/i86pc/sys/mach_mmu.h
@@ -0,0 +1,165 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_MACH_MMU_H
+#define _SYS_MACH_MMU_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ASM
+
+#include <sys/types.h>
+#include <sys/systm.h>
+
+/*
+ * Platform-dependent MMU routines and types.
+ *
+ * WARNING: this header file is used by both dboot and i86pc, so don't go using
+ * normal kernel headers.
+ */
+
+#define TWO_MEG (2 * 1024 * 1024)
+
+/*
+ * This is:
+ * The kernel nucleus pagesizes, ie: bi->bi_kseg_size
+ * The grub 64 bit file load address (see multiboot header in dboot_grub.s)
+ * The grub 32 bit and hypervisor physical load addresses of
+ * the kernel text/data (see Mapfile.unix)
+ */
+#define FOUR_MEG (4 * 1024 * 1024)
+
+#define ONE_GIG (1024 * 1024 * 1024)
+#define FOUR_GIG ((uint64_t)4 * ONE_GIG)
+
+#define MMU_STD_PAGESIZE 4096
+#ifdef __amd64
+#define MMU_STD_PAGEMASK 0xFFFFFFFFFFFFF000ULL
+#else
+#define MMU_STD_PAGEMASK 0xFFFFF000UL
+#endif
+
+/*
+ * Defines for the bits in X86 and AMD64 Page Tables
+ *
+ * Notes:
+ *
+ * Largepages and PAT bits:
+ *
+ * bit 7 at level 0 is the PAT bit
+ * bit 7 above level 0 is the Pagesize bit (set for large page)
+ * bit 12 (when a large page) is the PAT bit
+ *
+ * In Solaris the PAT/PWT/PCD values are set up so that:
+ *
+ * PAT & PWT -> Write Protected
+ * PAT & PCD -> Write Combining
+ * PAT by itself (PWT == 0 && PCD == 0) yields uncacheable (same as PCD == 1)
+ *
+ *
+ * Permission bits:
+ *
+ * - PT_USER must be set in all levels for user pages
+ * - PT_WRITE must be set in all levels for user writable pages
+ * - PT_NX applies if set at any level
+ *
+ * For these, we use the "allow" settings in all tables above level 0 and only
+ * ever disable things in PTEs.
+ *
+ * The use of PT_GLOBAL and PT_NX depend on being enabled in processor
+ * control registers. Hence, we use a variable to reference these bit
+ * masks. During hat_kern_setup() if the feature isn't enabled we
+ * clear out the variables.
+ */
+#define PT_VALID (0x001) /* a valid translation is present */
+#define PT_WRITABLE (0x002) /* the page is writable */
+#define PT_USER (0x004) /* the page is accessible by user mode */
+#define PT_WRITETHRU (0x008) /* write back caching is disabled (non-PAT) */
+#define PT_NOCACHE (0x010) /* page is not cacheable (non-PAT) */
+#define PT_REF (0x020) /* page was referenced */
+#define PT_MOD (0x040) /* page was modified */
+#define PT_PAGESIZE (0x080) /* above level 0, indicates a large page */
+#define PT_PAT_4K (0x080) /* at level 0, used for write combining */
+#define PT_GLOBAL (0x100) /* the mapping is global */
+#define PT_SOFTWARE (0xe00) /* software bits */
+
+#define PT_PAT_LARGE (0x1000) /* PAT bit for large pages */
+
+#define PT_PTPBITS (PT_VALID | PT_USER | PT_WRITABLE | PT_REF)
+#define PT_FLAGBITS (0xfff) /* for masking off flag bits */
+
+/*
+ * The software bits are used by the HAT to track attributes.
+ * Note that the attributes are inclusive as the values increase.
+ *
+ * PT_NOSYNC - The PT_REF/PT_MOD bits are not sync'd to page_t.
+ * The hat will install them as always set.
+ *
+ * PT_NOCONSIST - There is no hment entry for this mapping.
+ *
+ */
+#define PT_NOSYNC (0x200) /* PTE was created with HAT_NOSYNC */
+#define PT_NOCONSIST (0x400) /* PTE was created with HAT_LOAD_NOCONSIST */
+
+#include <sys/pc_mmu.h>
+
+/*
+ * The software extraction for a single Page Table Entry will always
+ * be a 64 bit unsigned int. If running a non-PAE hat, the page table
+ * access routines know to extend/shorten it to 32 bits.
+ */
+typedef uint64_t x86pte_t;
+typedef uint32_t x86pte32_t;
+
+x86pte_t get_pteval(paddr_t, uint_t);
+void set_pteval(paddr_t, uint_t, uint_t, x86pte_t);
+paddr_t make_ptable(x86pte_t *, uint_t);
+x86pte_t *find_pte(uint64_t, paddr_t *, uint_t, uint_t);
+x86pte_t *map_pte(paddr_t, uint_t);
+
+#ifndef _BOOT
+ulong_t getcr3();
+#endif
+
+extern uint_t *shift_amt;
+extern uint_t ptes_per_table;
+extern paddr_t top_page_table;
+extern uint_t top_level;
+extern uint_t pte_size;
+extern uint_t shift_amt_nopae[];
+extern uint_t shift_amt_pae[];
+extern uint32_t lpagesize;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ASM */
+
+#endif /* _SYS_MACH_MMU_H */
diff --git a/usr/src/uts/i86pc/sys/machclock.h b/usr/src/uts/i86pc/sys/machclock.h
new file mode 100644
index 0000000000..6b3686b95c
--- /dev/null
+++ b/usr/src/uts/i86pc/sys/machclock.h
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_MACHCLOCK_H
+#define _SYS_MACHCLOCK_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * tod module name and operations
+ */
+
+struct tod_ops;
+typedef struct tod_ops tod_ops_t;
+
+struct tod_ops {
+ int tod_version;
+ timestruc_t (*tod_get)(tod_ops_t *);
+ void (*tod_set)(tod_ops_t *, timestruc_t);
+ /*
+ * On SPARC, additional operations include setting
+ * and clearing a watchdog timer, as well as power alarms.
+ */
+ struct tod_ops *tod_next;
+};
+
+#define TOD_OPS_VERSION 1
+
+extern tod_ops_t *tod_ops;
+extern char *tod_module_name;
+
+#define TODOP_GET(top) ((top)->tod_get(top))
+#define TODOP_SET(top, ts) ((top)->tod_set(top, ts))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_MACHCLOCK_H */
diff --git a/usr/src/uts/i86pc/sys/machcpuvar.h b/usr/src/uts/i86pc/sys/machcpuvar.h
index 2cd92ac3b5..3217a674ab 100644
--- a/usr/src/uts/i86pc/sys/machcpuvar.h
+++ b/usr/src/uts/i86pc/sys/machcpuvar.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,7 +38,6 @@ extern "C" {
#include <sys/segments.h>
#include <sys/rm_platter.h>
#include <sys/avintr.h>
-#include <sys/mmu.h>
#include <sys/pte.h>
#ifndef _ASM
@@ -73,35 +72,43 @@ struct machcpu {
struct hat_cpu_info *mcpu_hat_info;
/* i86 hardware table addresses that cannot be shared */
+
user_desc_t *mcpu_gdt; /* GDT */
- gate_desc_t *mcpu_idt; /* IDT */
+ gate_desc_t *mcpu_idt; /* current IDT */
+
struct tss *mcpu_tss; /* TSS */
- struct cpu_tables *mcpu_cp_tables; /* pointer to space acquired */
- /* while starting up */
- /* auxillary processors */
kmutex_t mcpu_ppaddr_mutex;
-
caddr_t mcpu_caddr1; /* per cpu CADDR1 */
caddr_t mcpu_caddr2; /* per cpu CADDR2 */
- void *mcpu_caddr1pte;
- void *mcpu_caddr2pte;
- struct softint mcpu_softinfo;
+ uint64_t mcpu_caddr1pte;
+ uint64_t mcpu_caddr2pte;
+
+ struct softint mcpu_softinfo;
uint64_t pil_high_start[HIGH_LEVELS];
uint64_t intrstat[PIL_MAX + 1][2];
+
struct cpuid_info *mcpu_cpi;
+
struct cmi *mcpu_cmi; /* CPU module state */
void *mcpu_cmidata;
#if defined(__amd64)
greg_t mcpu_rtmp_rsp; /* syscall: temporary %rsp stash */
greg_t mcpu_rtmp_r15; /* syscall: temporary %r15 stash */
#endif
+
+ struct vcpu_info *mcpu_vcpu_info;
+ uint64_t mcpu_gdtpa; /* xen: GDT in physical address */
+
+ uint16_t mcpu_intr_pending; /* xen: pending interrupt levels */
};
#define NINTR_THREADS (LOCK_LEVEL-1) /* number of interrupt threads */
#endif /* _ASM */
+/* Please DON'T add any more of this namespace-poisoning sewage here */
+
#define cpu_nodeid cpu_m.mcpu_nodeid
#define cpu_pri cpu_m.mcpu_pri
#define cpu_pri_data cpu_m.mcpu_pri_data
diff --git a/usr/src/uts/i86pc/sys/machparam.h b/usr/src/uts/i86pc/sys/machparam.h
index e5e92f9412..4b764776c5 100644
--- a/usr/src/uts/i86pc/sys/machparam.h
+++ b/usr/src/uts/i86pc/sys/machparam.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -49,12 +49,11 @@ extern "C" {
/*
* Machine dependent parameters and limits.
*/
+
#if defined(__amd64)
-#define NCPU 64 /* NBBY * sizeof (ulong_t) for simple cpuset_t */
+#define NCPU 64 /* NBBY * sizeof (ulong_t) for simple cpuset_t */
#elif defined(__i386)
#define NCPU 32
-#else
-#error "port me"
#endif
/*
@@ -86,9 +85,9 @@ extern "C" {
#if !defined(_ASM)
#define MMU_PAGEOFFSET (MMU_PAGESIZE-1) /* Mask of address bits in page */
-#else /* !_ASM */
-#define MMU_PAGEOFFSET _CONST(MMU_PAGESIZE-1) /* assembler lameness */
-#endif /* !_ASM */
+#else /* _ASM */
+#define MMU_PAGEOFFSET _CONST(MMU_PAGESIZE-1) /* assembler lameness */
+#endif /* _ASM */
#define MMU_PAGEMASK (~MMU_PAGEOFFSET)
@@ -133,6 +132,8 @@ extern "C" {
* i86 and i86pc files use kernelbase instead of KERNELBASE, which is
* initialized in i86pc/os/startup.c.
*/
+#define KERNEL_TEXT_amd64 UINT64_C(0xfffffffffb800000)
+#define KERNEL_TEXT_i386 ADDRESS_C(0xfe800000)
#if defined(__amd64)
@@ -160,6 +161,11 @@ extern "C" {
#define SEGKPM_BASE ADDRESS_C(0xfffffe0000000000)
/*
+ * This is valloc_base, above seg_kpm, but below everything else
+ */
+#define VALLOC_BASE ADDRESS_C(0xffffff0000000000)
+
+/*
* default and boundary sizes for segkp
*/
#define SEGKPDEFSIZE (2L * 1024L * 1024L * 1024L) /* 2G */
@@ -172,20 +178,22 @@ extern "C" {
#define SEGZIOMINSIZE (400L * 1024 * 1024L) /* 400M */
/*
- * Boot (or, more precisely, vmx) maps most pages twice - once in the
- * bottom 2GB of memory and once in the bottom 2GB of the topmost 4GB.
- * When boot is unmapped this range is available to the kernel, but until
- * then we have to leave it untouched.
+ * During intial boot we limit heap to the top 4Gig.
*/
-#define BOOT_DOUBLEMAP_BASE ADDRESS_C(0xffffffff00000000)
-#define BOOT_DOUBLEMAP_SIZE ADDRESS_C(0x80000000)
+#define BOOT_KERNELHEAP_BASE ADDRESS_C(0xffffffff00000000)
/*
* VMWare works best if we don't use the top 64Meg of memory for amd64.
* Set KERNEL_TEXT to top_o_memory - 64Meg - 8 Meg for 8Meg of nucleus pages.
*/
#define PROMSTART ADDRESS_C(0xffc00000)
-#define KERNEL_TEXT ADDRESS_C(0xfffffffffb800000)
+#define KERNEL_TEXT KERNEL_TEXT_amd64
+
+/*
+ * Virtual address range available to the debugger
+ */
+#define SEGDEBUGBASE ADDRESS_C(0xffffffffff800000)
+#define SEGDEBUGSIZE ADDRESS_C(0x400000)
/*
* Define upper limit on user address space
@@ -233,7 +241,14 @@ extern "C" {
* need this region of virtual address space mapped 1-1
*/
#define PROMSTART ADDRESS_C(0xffc00000)
-#define KERNEL_TEXT ADDRESS_C(0xfe800000)
+#define KERNEL_TEXT KERNEL_TEXT_i386
+
+/*
+ * Virtual address range available to the debugger
+ * We place it just above the kernel text (4M) and kernel data (4M).
+ */
+#define SEGDEBUGBASE (KERNEL_TEXT + ADDRESS_C(0x800000))
+#define SEGDEBUGSIZE ADDRESS_C(0x400000)
/*
* Define upper limit on user address space
@@ -243,8 +258,17 @@ extern "C" {
#endif /* __i386 */
-#if !defined(_ASM) && !defined(_KADB)
-extern uintptr_t kernelbase, segkmap_start, segmapsize;
+/*
+ * Reserve two pages just below KERNEL_TEXT for the GDT and debug info page.
+ */
+#if !defined(_ASM)
+#define MISC_VA_BASE (KERNEL_TEXT - MMU_PAGESIZE * 2)
+#define GDT_VA (MISC_VA_BASE)
+#define DEBUG_INFO_VA (MISC_VA_BASE + MMU_PAGESIZE)
+#endif /* !_ASM */
+
+#if !defined(_ASM) && !defined(_KMDB)
+extern uintptr_t kernelbase, segmap_start, segmapsize;
#endif
/*
diff --git a/usr/src/uts/i86pc/sys/machprivregs.h b/usr/src/uts/i86pc/sys/machprivregs.h
new file mode 100644
index 0000000000..1d4abe0b1c
--- /dev/null
+++ b/usr/src/uts/i86pc/sys/machprivregs.h
@@ -0,0 +1,172 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_MACHPRIVREGS_H
+#define _SYS_MACHPRIVREGS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Platform dependent instruction sequences for manipulating
+ * privileged state
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ASSERT_UPCALL_MASK_IS_SET /* empty */
+
+/*
+ * CLI and STI
+ */
+
+#define CLI(r) \
+ cli
+
+#define STI \
+ sti
+
+/*
+ * Used to re-enable interrupts in the body of exception handlers
+ */
+
+#if defined(__amd64)
+
+#define ENABLE_INTR_FLAGS \
+ pushq $F_ON; \
+ popfq
+
+#elif defined(__i386)
+
+#define ENABLE_INTR_FLAGS \
+ pushl $F_ON; \
+ popfl
+
+#endif /* __i386 */
+
+/*
+ * IRET and SWAPGS
+ */
+#if defined(__amd64)
+
+#define IRET iretq
+#define SWAPGS swapgs
+
+#elif defined(__i386)
+
+#define IRET iret
+
+#endif /* __i386 */
+
+#define CLEAN_CS /* empty */
+
+/*
+ * Macros for saving the original segment registers and restoring them
+ * for fast traps.
+ */
+#if defined(__amd64)
+
+/*
+ * Smaller versions of INTR_PUSH and INTR_POP for fast traps.
+ * The following registers have been pushed onto the stack by
+ * hardware at this point:
+ *
+ * greg_t r_rip;
+ * greg_t r_cs;
+ * greg_t r_rfl;
+ * greg_t r_rsp;
+ * greg_t r_ss;
+ *
+ * This handler is executed both by 32-bit and 64-bit applications.
+ * 64-bit applications allow us to treat the set (%rdi, %rsi, %rdx,
+ * %rcx, %r8, %r9, %r10, %r11, %rax) as volatile across function calls.
+ * However, 32-bit applications only expect (%eax, %edx, %ecx) to be volatile
+ * across a function call -- in particular, %esi and %edi MUST be saved!
+ *
+ * We could do this differently by making a FAST_INTR_PUSH32 for 32-bit
+ * programs, and FAST_INTR_PUSH for 64-bit programs, but it doesn't seem
+ * particularly worth it.
+ */
+#define FAST_INTR_PUSH \
+ INTGATE_INIT_KERNEL_FLAGS; \
+ subq $REGOFF_RIP, %rsp; \
+ movq %rsi, REGOFF_RSI(%rsp); \
+ movq %rdi, REGOFF_RDI(%rsp); \
+ swapgs
+
+#define FAST_INTR_POP \
+ swapgs; \
+ movq REGOFF_RSI(%rsp), %rsi; \
+ movq REGOFF_RDI(%rsp), %rdi; \
+ addq $REGOFF_RIP, %rsp
+
+#define FAST_INTR_RETURN iretq
+
+#elif defined(__i386)
+
+#define FAST_INTR_PUSH \
+ cld; \
+ __SEGREGS_PUSH \
+ __SEGREGS_LOAD_KERNEL
+
+#define FAST_INTR_POP \
+ __SEGREGS_POP
+
+#define FAST_INTR_RETURN iret
+
+#endif /* __i386 */
+
+/*
+ * Handling the CR0.TS bit for floating point handling.
+ *
+ * When the TS bit is *set*, attempts to touch the floating
+ * point hardware will result in a #nm trap.
+ */
+#if defined(__amd64)
+
+#define STTS(rtmp) \
+ movq %cr0, rtmp; \
+ orq $CR0_TS, rtmp; \
+ movq rtmp, %cr0
+
+#elif defined(__i386)
+
+#define STTS(rtmp) \
+ movl %cr0, rtmp; \
+ orl $CR0_TS, rtmp; \
+ movl rtmp, %cr0
+
+#endif /* __i386 */
+
+#define CLTS \
+ clts
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_MACHPRIVREGS_H */
diff --git a/usr/src/uts/i86pc/sys/machsystm.h b/usr/src/uts/i86pc/sys/machsystm.h
index 43a3a94df1..caacf71e30 100644
--- a/usr/src/uts/i86pc/sys/machsystm.h
+++ b/usr/src/uts/i86pc/sys/machsystm.h
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,6 +42,9 @@
#include <sys/varargs.h>
#include <sys/thread.h>
#include <sys/cpuvar.h>
+#include <sys/privregs.h>
+#include <sys/systm.h>
+#include <sys/traptrace.h>
#include <vm/page.h>
#ifdef __cplusplus
@@ -49,7 +53,9 @@ extern "C" {
#ifdef _KERNEL
-extern void mp_halt(char *);
+extern void mach_cpu_idle(void);
+extern void mach_cpu_halt(char *);
+extern int mach_cpu_start(cpu_t *, void *);
extern int Cpudelay;
extern void setcpudelay(void);
@@ -61,10 +67,11 @@ extern void return_instr(void);
extern int kcpc_hw_load_pcbe(void);
extern void kcpc_hw_init(cpu_t *cp);
+extern void kcpc_hw_fini(cpu_t *cp);
extern int kcpc_hw_overflow_intr_installed;
struct memconf {
- pfn_t mcf_spfn; /* begin page fram number */
+ pfn_t mcf_spfn; /* begin page frame number */
pfn_t mcf_epfn; /* end page frame number */
};
@@ -84,6 +91,9 @@ extern int cpuid2nodeid(int);
extern void map_kaddr(caddr_t, pfn_t, int, int);
extern void memscrub_init(void);
+extern void trap(struct regs *, caddr_t, processorid_t);
+
+extern void do_interrupt(struct regs *, trap_trace_rec_t *);
extern void memscrub_disable(void);
extern unsigned int microdata;
@@ -92,6 +102,11 @@ extern int use_mp;
extern struct cpu cpus[]; /* pointer to other cpus */
extern struct cpu *cpu[]; /* pointer to all cpus */
+extern int mach_cpucontext_init(void);
+extern void mach_cpucontext_fini(void);
+extern void *mach_cpucontext_alloc(struct cpu *);
+extern void mach_cpucontext_free(struct cpu *, void *, int);
+
extern uintptr_t hole_start, hole_end;
#define INVALID_VADDR(a) \
@@ -102,6 +117,11 @@ extern size_t kpm_size;
extern uchar_t kpm_size_shift;
extern caddr_t kpm_vbase;
+struct memlist;
+extern void memlist_add(uint64_t, uint64_t, struct memlist *,
+ struct memlist **);
+extern page_t *page_get_physical(uintptr_t);
+
#endif /* _KERNEL */
#ifdef __cplusplus
diff --git a/usr/src/uts/i86pc/sys/pc_mmu.h b/usr/src/uts/i86pc/sys/pc_mmu.h
new file mode 100644
index 0000000000..89661449a4
--- /dev/null
+++ b/usr/src/uts/i86pc/sys/pc_mmu.h
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_PC_MMU_H
+#define _SYS_PC_MMU_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Platform-dependent MMU routines and types for real x86 hardware.
+ *
+ * WARNING: this header file is used by both dboot and i86pc, so don't go using
+ * normal kernel headers.
+ */
+
+#define IN_HYPERVISOR_VA(va) (__lintzero)
+
+void reload_cr3(void);
+
+#define pa_to_ma(pa) (pa)
+#define ma_to_pa(ma) (ma)
+#define pfn_to_mfn(pfn) (pfn)
+#define mfn_to_pfn(mfn) (mfn)
+
+#ifndef _BOOT
+
+void mmu_tlbflush_entry(caddr_t);
+void setcr3(ulong_t);
+
+#if defined(__GNUC__)
+#include <asm/mmu.h>
+#endif
+
+#endif /* !_BOOT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_PC_MMU_H */
diff --git a/usr/src/uts/i86pc/sys/psm_types.h b/usr/src/uts/i86pc/sys/psm_types.h
index 9af8bdde12..435d2da112 100644
--- a/usr/src/uts/i86pc/sys/psm_types.h
+++ b/usr/src/uts/i86pc/sys/psm_types.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -61,7 +61,7 @@ typedef enum psm_intr_op_e {
PSM_INTR_OP_GET_INTR /* 13. Get vector's info */
} psm_intr_op_t;
-struct psm_ops {
+struct psm_ops {
int (*psm_probe)(void);
void (*psm_softinit)(void);
@@ -89,7 +89,11 @@ struct psm_ops {
hrtime_t (*psm_gethrtime)(void);
processorid_t (*psm_get_next_processorid)(processorid_t cpu_id);
+#if defined(PSMI_1_5)
+ int (*psm_cpu_start)(processorid_t cpun, caddr_t ctxt);
+#else
void (*psm_cpu_start)(processorid_t cpun, caddr_t rm_code);
+#endif
int (*psm_post_cpu_start)(void);
#if defined(PSMI_1_2) || defined(PSMI_1_3) || defined(PSMI_1_4) || \
defined(PSMI_1_5)
@@ -102,9 +106,10 @@ struct psm_ops {
int (*psm_translate_irq)(dev_info_t *dip, int irqno);
+#if defined(PSMI_1_2) || defined(PSMI_1_3) || defined(PSMI_1_4)
int (*psm_tod_get)(todinfo_t *tod);
int (*psm_tod_set)(todinfo_t *tod);
-
+#endif
void (*psm_notify_error)(int level, char *errmsg);
#if defined(PSMI_1_2) || defined(PSMI_1_3) || defined(PSMI_1_4) || \
defined(PSMI_1_5)
@@ -126,7 +131,7 @@ struct psm_ops {
};
-struct psm_info {
+struct psm_info {
ushort_t p_version;
ushort_t p_owner;
struct psm_ops *p_ops;
diff --git a/usr/src/uts/i86pc/sys/rm_platter.h b/usr/src/uts/i86pc/sys/rm_platter.h
index 8f1bc977ba..b21c54dd63 100644
--- a/usr/src/uts/i86pc/sys/rm_platter.h
+++ b/usr/src/uts/i86pc/sys/rm_platter.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -98,18 +98,14 @@ typedef struct rm_platter {
} rm_platter_t;
/*
- * cpu tables put within a single structure all the tables which need to be
- * allocated when a CPU starts up. Makes it more memory efficient and easier
- * to allocate/release
+ * cpu tables put within a single structure two of the tables which need to be
+ * allocated when a CPU starts up.
*
- * Note: gdt and tss should be 16 byte aligned for best performance on
- * amd64. Since DEFAULTSTKSIZE is a multiple of pagesize gdt will be aligned.
- * We test below that the tss is properly aligned.
+ * Note: the tss should be 16 byte aligned for best performance on amd64
+ * Since DEFAULTSTKSIZE is a multiple of PAGESIZE tss will be aligned.
*/
-
struct cpu_tables {
char ct_stack[DEFAULTSTKSZ];
- user_desc_t *ct_gdt;
struct tss ct_tss;
};
diff --git a/usr/src/uts/i86pc/sys/smp_impldefs.h b/usr/src/uts/i86pc/sys/smp_impldefs.h
index e61c756381..27beafeac7 100644
--- a/usr/src/uts/i86pc/sys/smp_impldefs.h
+++ b/usr/src/uts/i86pc/sys/smp_impldefs.h
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -53,7 +54,6 @@ extern void (*picinitf)(); /* pic init entry point */
extern int (*clkinitf)(int, int *); /* clock init entry point */
extern int (*ap_mlsetup)(); /* completes init of starting cpu */
extern void (*send_dirintf)(); /* send interprocessor intr */
-extern void (*cpu_startf)(); /* start running a given processor */
extern hrtime_t (*gethrtimef)(); /* get high resolution timer value */
extern hrtime_t (*gethrtimeunscaledf)(); /* get high res timer unscaled value */
extern void (*psm_shutdownf)(int, int); /* machine dependent shutdown */
diff --git a/usr/src/uts/i86pc/sys/x_call.h b/usr/src/uts/i86pc/sys/x_call.h
index daabe989b8..37cd7e39af 100644
--- a/usr/src/uts/i86pc/sys/x_call.h
+++ b/usr/src/uts/i86pc/sys/x_call.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,7 +29,6 @@
#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* For x86, we only have three cross call levels:
* a low, med and high. (see xc_levels.h)
@@ -66,6 +65,10 @@ struct xc_mbox {
int saved_pri;
};
+#if defined(_MACHDEP)
+extern cpuset_t cpu_ready_set;
+#endif
+
/*
* Cross-call routines.
*/
@@ -76,11 +79,23 @@ extern uint_t xc_serv(caddr_t, caddr_t);
extern void xc_call(xc_arg_t, xc_arg_t, xc_arg_t, int, cpuset_t, xc_func_t);
extern void xc_trycall(xc_arg_t, xc_arg_t, xc_arg_t, cpuset_t, xc_func_t);
extern void xc_sync(xc_arg_t, xc_arg_t, xc_arg_t, int, cpuset_t, xc_func_t);
-extern void xc_wait_sync(xc_arg_t, xc_arg_t, xc_arg_t, int, cpuset_t,
- xc_func_t);
extern void xc_capture_cpus(cpuset_t);
extern void xc_release_cpus(void);
+#if defined(TRAPTRACE)
+
+/*
+ * X-call tracing can be interleaved with trap tracing
+ */
+extern void xc_make_trap_trace_entry(uint8_t, int, ulong_t);
+#define XC_TRACE(m, pri, arg) xc_make_trap_trace_entry(m, pri, arg)
+
+#else /* TRAPTRACE */
+
+#define XC_TRACE(m, pri, arg) /* nothing */
+
+#endif /* TRAPTRACE */
+
#endif /* _KERNEL */
#endif /* !_ASM */
diff --git a/usr/src/uts/i86pc/sys/xsvc.h b/usr/src/uts/i86pc/sys/xsvc.h
new file mode 100644
index 0000000000..1bf541e98d
--- /dev/null
+++ b/usr/src/uts/i86pc/sys/xsvc.h
@@ -0,0 +1,134 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_XSVC_H
+#define _SYS_XSVC_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/avl.h>
+#include <sys/types.h>
+
+/* xsvc ioctls */
+#define XSVCIOC ('Q'<< 8)
+#define XSVC_ALLOC_MEM (XSVCIOC | 130)
+#define XSVC_FREE_MEM (XSVCIOC | 131)
+#define XSVC_FLUSH_MEM (XSVCIOC | 132)
+
+/* arg * struct for ioctls */
+typedef struct _xsvc_mem_req {
+ int xsvc_mem_reqid; /* request ID */
+ uint64_t xsvc_mem_addr_lo; /* low DMA address range */
+ uint64_t xsvc_mem_addr_hi; /* high DMA address range */
+ uint64_t xsvc_mem_align; /* DMA address alignment */
+ int xsvc_mem_sgllen; /* s/g length */
+ size_t xsvc_mem_size; /* length of mem in bytes */
+ void *xsvc_sg_list; /* returned scatter gather list */
+} xsvc_mem_req;
+
+/* xsvc_sg_list format */
+typedef struct _xsvc_mloc {
+ uint64_t mloc_addr;
+ size_t mloc_size;
+} xsvc_mloc;
+
+#ifdef _KERNEL
+/* *** Driver Private Below *** */
+
+/* arg * struct for ioctls from 32-bit app in 64-bit kernel */
+#pragma pack(1)
+typedef struct _xsvc_mem_req_32 {
+ int xsvc_mem_reqid; /* request ID */
+ uint64_t xsvc_mem_addr_lo; /* low DMA address range */
+ uint64_t xsvc_mem_addr_hi; /* high DMA address range */
+ uint64_t xsvc_mem_align; /* DMA address alignment */
+ int xsvc_mem_sgllen; /* s/g length */
+ uint32_t xsvc_mem_size; /* length of mem in bytes */
+ uint32_t xsvc_sg_list; /* returned scatter gather list */
+} xsvc_mem_req_32;
+#pragma pack()
+
+/* xsvc_sg_list format */
+#pragma pack(1)
+typedef struct _xsvc_mloc_32 {
+ uint64_t mloc_addr;
+ uint32_t mloc_size;
+} xsvc_mloc_32;
+#pragma pack()
+
+/* avl node */
+typedef struct xsvc_mnode_s {
+ avl_node_t mn_link;
+ uint64_t mn_key;
+ struct xsvc_mem_s *mn_home;
+} xsvc_mnode_t;
+
+/* track memory allocs */
+typedef struct xsvc_mem_s {
+ xsvc_mnode_t xm_mnode;
+ size_t xm_size;
+ caddr_t xm_addr;
+ size_t xm_real_length;
+ ddi_dma_handle_t xm_dma_handle;
+ ddi_acc_handle_t xm_mem_handle;
+ ddi_dma_attr_t xm_dma_attr;
+ ddi_device_acc_attr_t xm_device_attr;
+ uint_t xm_cookie_count;
+ ddi_dma_cookie_t xm_cookie;
+} xsvc_mem_t;
+
+/* list of memory allocs */
+typedef struct xsvc_mlist_s {
+ kmutex_t ml_mutex;
+ avl_tree_t ml_avl;
+} xsvc_mlist_t;
+
+/* driver state */
+typedef struct xsvc_state_s {
+ dev_info_t *xs_dip;
+ int xs_instance;
+
+ /*
+ * track total memory allocated, mutex only covers
+ * xs_currently_alloced
+ */
+ kmutex_t xs_mutex;
+ uint64_t xs_currently_alloced;
+
+ xsvc_mlist_t xs_mlist;
+} xsvc_state_t;
+
+#endif /* _KERNEL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_XSVC_H */
diff --git a/usr/src/uts/i86pc/unix/Makefile b/usr/src/uts/i86pc/unix/Makefile
index 778a495e50..8bef129839 100644
--- a/usr/src/uts/i86pc/unix/Makefile
+++ b/usr/src/uts/i86pc/unix/Makefile
@@ -18,13 +18,14 @@
#
# CDDL HEADER END
#
+
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
#
-# This makefile drives the production of /unix (and unix.o).
+# This makefile drives the production of unix (and unix.o).
#
# i86pc implementation architecture dependent
#
@@ -38,25 +39,27 @@ UTSBASE = ../..
# Define the module and object file sets.
#
UNIX = unix
+DBOOT = dboot
+MULTIBOOT = multiboot
OBJECTS = $(SPECIAL_OBJS:%=$(OBJS_DIR)/%) \
$(CORE_OBJS:%=$(OBJS_DIR)/%) \
+ $(KRTLD_OBJS:%=$(OBJS_DIR)/%) \
$(MACH_NOT_YET_KMODS:%=$(OBJS_DIR)/%)
LINTS = $(SPECIAL_OBJS:%.o=$(LINTS_DIR)/%.ln) \
$(CORE_OBJS:%.o=$(LINTS_DIR)/%.ln) \
+ $(KRTLD_OBJS:%.o=$(LINTS_DIR)/%.ln) \
$(MACH_NOT_YET_KMODS:%.o=$(LINTS_DIR)/%.ln) \
$(LINTS_DIR)/vers.ln \
$(LINTS_DIR)/modstubs.ln
ROOTMODULE = $(ROOT_PSM_KERN_DIR)/$(UNIX)
+ROOT_MULTIBOOT = $(ROOT_PSM_DIR)/$(MULTIBOOT)
+BOOT_KERNEL = $(ROOT_BOOT_PSM_KERN_DIR)/$(UNIX)
UNIX_BIN = $(OBJS_DIR)/$(UNIX)
-KRTLD_32 = misc/krtld
-KRTLD_64 = misc/$(SUBDIR64)/krtld
-KRTLD = $(KRTLD_$(CLASS))
-
LIBS = $(GENLIB)
GENUNIX = genunix
@@ -66,6 +69,13 @@ LIBOPTS = -L $(GENUNIX_DIR)/$(OBJS_DIR) -l $(GENUNIX)
CTFEXTRAOBJS = $(OBJS_DIR)/vers.o
+DBOOT_OBJS_DIR = dboot/$(OBJS_DIR)
+DBOOT_OBJECTS = $(DBOOT_OBJS:%=$(DBOOT_OBJS_DIR)/%)
+DBOOT_O = $(OBJS_DIR)/$(DBOOT).o
+DBOOT_S = $(DBOOT_O:%.o=%.s)
+DBOOT_LINTS = $(DBOOT_OBJS:%.o=$(DBOOT_OBJS_DIR)/%.ln)
+DBOOT_LINT = $(i386_LINT)
+
#
# Include common rules.
#
@@ -74,9 +84,9 @@ include $(UTSBASE)/i86pc/Makefile.i86pc
#
# Define targets
#
-ALL_TARGET = $(UNIX_BIN)
-LINT_TARGET = $(LINT_LIB)
-INSTALL_TARGET = $(UNIX_BIN) $(ROOTMODULE)
+ALL_TARGET = $(UNIX_BIN) $(MULTIBOOT)
+LINT_TARGET = $(LINT_LIB) $(DBOOT_LINT_LIB)
+INSTALL_TARGET = $(UNIX_BIN) $(MULTIBOOT) $(ROOTMODULE) $(ROOT_MULTIBOOT) $(BOOT_KERNEL)
#
# This is UNIX_DIR. Use a short path.
@@ -86,12 +96,21 @@ UNIX_DIR = .
#
# Overrides
#
-CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(OBJS_DIR)/vers.c \
- $(OBJS_DIR)/vers.o \
- $(DTRACESTUBS_O) $(DTRACESTUBS)
+CLEANFILES += \
+ $(UNIX_O) $(MODSTUBS_O) \
+ $(OBJS_DIR)/vers.c $(OBJS_DIR)/vers.o \
+ $(DTRACESTUBS_O) $(DTRACESTUBS)
+
+CLEANFILES += \
+ $(DBOOT_O) $(DBOOT_S) \
+ $(DBOOT_OBJECTS) \
+ $(OBJS_DIR)/bios_call_src.o \
+ $(OBJS_DIR)/bios_call_src \
+ $(OBJS_DIR)/bios_call.s \
+ $(DBOOT_OBJS_DIR)/$(DBOOT)
-CLOBBERFILES = $(CLEANFILES) $(UNIX_BIN)
-CLEANLINTFILES += $(LINT_LIB)
+CLOBBERFILES = $(CLEANFILES) $(UNIX_BIN) $(MULTIBOOT)
+CLEANLINTFILES += $(LINT_LIB) $(DBOOT_LINT_LIB) $(DBOOT_LINTS)
# instr_size needs a special header
$(OBJS_DIR)/instr_size.o := EXTRA_OPTIONS = -I$(SRC)/common/dis/i386
@@ -136,19 +155,48 @@ MAPFILE_64 = $(MAPFILE).amd64
MAPFILE_NAME = $(MAPFILE_$(CLASS))
$(UNIX_BIN): $(UNIX_O) $(MODSTUBS_O) $(MAPFILE_NAME) \
- $(GENLIB) $(DTRACESTUBS)
- $(LD) -dy -b -o $@ -e _start -I $(KRTLD) -M $(MAPFILE_NAME) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+ $(GENLIB) $(DTRACESTUBS) $(DBOOT_O)
+ $(LD) -dy -b -o $@ -e dboot_image -znointerp -M $(MAPFILE_NAME) \
+ $(UNIX_O) $(DBOOT_O) $(MODSTUBS_O) $(LIBOPTS) \
+ $(DTRACESTUBS)
+ $(MBH_PATCH) $(UNIX_BIN)
$(CTFMERGE_UNIQUIFY_AGAINST_GENUNIX)
$(POST_PROCESS)
$(UNIX_O): $(OBJECTS) $(OBJS_DIR)/vers.o
$(LD) -r -o $@ $(OBJECTS) $(OBJS_DIR)/vers.o
+$(DBOOT_O): $(DBOOT_OBJS_DIR) $(DBOOT_OBJECTS)
+ $(LD) -dn -M dboot/Mapfile.dboot \
+ -o $(DBOOT_OBJS_DIR)/$(DBOOT) $(DBOOT_OBJECTS)
+ @echo " .data" > $(DBOOT_S)
+ @echo " .globl dboot_image" >> $(DBOOT_S)
+ @echo "dboot_image:" >> $(DBOOT_S)
+ $(ELFEXTRACT) $(DBOOT_OBJS_DIR)/$(DBOOT) >> $(DBOOT_S)
+ $(COMPILE.s) -o $(DBOOT_O) $(DBOOT_S)
+
+$(DBOOT_OBJS_DIR):
+ -@mkdir -p $@ 2> /dev/null
+
+#
+# dboot is built as an intermediate target in dboot.o, so just make
+# dboot.o the dependency here.
+#
+$(MULTIBOOT): $(DBOOT_O)
+ $(CP) $(DBOOT_OBJS_DIR)/$(DBOOT) $(MULTIBOOT)
+ $(POST_PROCESS)
+
+#
+# The boot kernel is a copy of the 32-bit kernel paired with the
+# install/failsafe miniroot
+$(BOOT_KERNEL): $(ROOTMODULE) $(ROOT_BOOT_PSM_KERN_DIR)
+ $(CP) $(ROOTMODULE) $(BOOT_KERNEL)
+ $(POST_PROCESS)
+
#
# Special rules for generating assym.h for inclusion in assembly files.
#
-$(DSF_DIR)/$(OBJS_DIR)/assym.h: FRC
+$(DSF_DIR)/$(OBJS_DIR)/assym.h $(DSF_DIR)/$(OBJS_DIR)/kdi_assym.h: FRC
@cd $(DSF_DIR); $(MAKE) all.targ
$(GENLIB): FRC
@@ -170,6 +218,11 @@ $(LINT_LIB): $(LINT_LIB_DIR) $(LINTS)
@$(LINT) -o$(UNIX) $(LINTFLAGS) $(LINTS)
@$(MV) $(@F) $@
+$(DBOOT_LINT_LIB): $(LINT_LIB_DIR) $(DBOOT_LINTS)
+ @-$(ECHO) "\n$(DBOOT): (library construction):"
+ @$(LINT) -o$(DBOOT) $(DBOOT_LINTFLAGS) $(DBOOT_LINTS)
+ @$(MV) $(@F) $@
+
lintlib: $(LINT_DEPS)
#
diff --git a/usr/src/uts/i86pc/unix/dboot/Mapfile.dboot b/usr/src/uts/i86pc/unix/dboot/Mapfile.dboot
new file mode 100644
index 0000000000..a8c6856dfe
--- /dev/null
+++ b/usr/src/uts/i86pc/unix/dboot/Mapfile.dboot
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+dboot = LOAD ?RWX V0xC00000 P0xC00000 A0x1000;
+dboot : ?A;
diff --git a/usr/src/uts/i86pc/vm/Makefile b/usr/src/uts/i86pc/vm/Makefile
index dab7916bfe..270efbe462 100644
--- a/usr/src/uts/i86pc/vm/Makefile
+++ b/usr/src/uts/i86pc/vm/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -40,7 +39,7 @@ include ../Makefile.i86pc
FILEMODE = 644
GROUP = bin
-HDRS= hat_i86.h hat_pte.h hment.h htable.h
+HDRS= hat_i86.h hat_pte.h hment.h htable.h kboot_mmu.h
ROOTHDRS= $(HDRS:%=$(USR_PSM_IVM_DIR)/%)
@@ -73,9 +72,6 @@ $(ROOTDIRS):
$(ROOTLINK): $(ROOTDIRS)
-$(RM) -r $@; $(SYMLINK) $(LINKDEST) $@ $(CHOWNLINK) $(CHGRPLINK)
-#%.check:
-# $(DOT_H_CHECK)
-
CLEANFILES=
CLOBBERFILES=
diff --git a/usr/src/uts/i86pc/vm/hat_i86.c b/usr/src/uts/i86pc/vm/hat_i86.c
index bd95917765..05bdde381a 100644
--- a/usr/src/uts/i86pc/vm/hat_i86.c
+++ b/usr/src/uts/i86pc/vm/hat_i86.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -58,6 +58,10 @@
#include <sys/x86_archext.h>
#include <sys/atomic.h>
#include <sys/bitmap.h>
+#include <sys/controlregs.h>
+#include <sys/bootconf.h>
+#include <sys/bootsvcs.h>
+#include <sys/bootinfo.h>
#include <vm/seg_kmem.h>
#include <vm/hat_i86.h>
@@ -67,16 +71,14 @@
#include <vm/seg_kp.h>
#include <vm/seg_kpm.h>
#include <vm/vm_dep.h>
+#include <vm/kboot_mmu.h>
#include <sys/cmn_err.h>
-
/*
* Basic parameters for hat operation.
*/
struct hat_mmu_info mmu;
-uint_t force_pae_off = 0; /* for testing, change with kernel debugger */
-uint_t force_pae_on = 0; /* for testing, change with kernel debugger */
/*
* The page that is the kernel's top level pagetable.
@@ -168,21 +170,6 @@ kmem_cache_t *vlp_hash_cache;
struct hatstats hatstat;
/*
- * macros to detect addresses in use by kernel only during boot
- */
-#if defined(__amd64)
-
-#define BOOT_VA(va) ((va) < kernelbase || \
- ((va) >= BOOT_DOUBLEMAP_BASE && \
- (va) < BOOT_DOUBLEMAP_BASE + BOOT_DOUBLEMAP_SIZE))
-
-#elif defined(__i386)
-
-#define BOOT_VA(va) ((va) < kernelbase)
-
-#endif /* __i386 */
-
-/*
* useful stuff for atomic access/clearing/setting REF/MOD/RO bits in page_t's.
*/
extern void atomic_orb(uchar_t *addr, uchar_t val);
@@ -238,8 +225,6 @@ hati_constructor(void *buf, void *handle, int kmflags)
sizeof (pgcnt_t) * (mmu.max_page_level + 1));
hat->hat_stats = 0;
hat->hat_flags = 0;
- mutex_init(&hat->hat_switch_mutex, NULL, MUTEX_DRIVER,
- (void *)ipltospl(DISP_LEVEL));
CPUSET_ZERO(hat->hat_cpus);
hat->hat_htable = NULL;
hat->hat_ht_hash = NULL;
@@ -305,6 +290,7 @@ hat_alloc(struct as *as)
hat->hat_htable = NULL;
hat->hat_ht_cached = NULL;
ht = htable_create(hat, (uintptr_t)0, TOP_LEVEL(hat), NULL);
+
if (!(hat->hat_flags & HAT_VLP))
x86pte_copy(kas.a_hat->hat_htable, ht, khat_start,
khat_entries);
@@ -461,39 +447,20 @@ mmu_init(void)
int i;
/*
- * if CPU enabled the page table global bit, use it for the kernel
- * This is bit 7 in CR4 (PGE - Page Global Enable)
+ * If CPU enabled the page table global bit, use it for the kernel
+ * This is bit 7 in CR4 (PGE - Page Global Enable).
*/
- if ((x86_feature & X86_PGE) != 0 && (getcr4() & 0x80) != 0)
+ if ((x86_feature & X86_PGE) != 0 && (getcr4() & CR4_PGE) != 0)
mmu.pt_global = PT_GLOBAL;
/*
- * We use PAE except when we aren't on an AMD64 and this is
- * a 32 bit kernel with all physical addresses less than 4 Gig.
+ * Detect NX and PAE usage.
*/
- mmu.pae_hat = 1;
- if (x86_feature & X86_NX) {
+ mmu.pae_hat = kbm_pae_support;
+ if (kbm_nx_support)
mmu.pt_nx = PT_NX;
- } else {
- mmu.pt_nx = 0;
-#if defined(__i386)
- if (!PFN_ABOVE4G(physmax))
- mmu.pae_hat = 0;
-#endif
- }
-
-#if defined(__i386)
- /*
- * Setting one of these two lets you force testing of the different
- * hat modes for 32 bit, regardless of the hardware setup.
- */
- if (force_pae_on) {
- mmu.pae_hat = 1;
- } else if (force_pae_off) {
- mmu.pae_hat = 0;
+ else
mmu.pt_nx = 0;
- }
-#endif
/*
* Use CPU info to set various MMU parameters
@@ -541,7 +508,7 @@ mmu_init(void)
* Initialize parameters based on the 64 or 32 bit kernels and
* for the 32 bit kernel decide if we should use PAE.
*/
- if (x86_feature & X86_LARGEPAGE)
+ if (kbm_largepage_support)
mmu.max_page_level = 1;
else
mmu.max_page_level = 0;
@@ -590,15 +557,18 @@ mmu_init(void)
mmu.level_mask[i] = ~mmu.level_offset[i];
}
- mmu.pte_bits[0] = PT_VALID;
- for (i = 1; i <= mmu.max_page_level; ++i)
- mmu.pte_bits[i] = PT_VALID | PT_PAGESIZE;
+ for (i = 0; i <= mmu.max_page_level; ++i) {
+ mmu.pte_bits[i] = PT_VALID;
+ if (i > 0)
+ mmu.pte_bits[i] |= PT_PAGESIZE;
+ }
/*
* NOTE Legacy 32 bit PAE mode only has the P_VALID bit at top level.
*/
for (i = 1; i < mmu.num_level; ++i)
mmu.ptp_bits[i] = PT_PTPBITS;
+
#if defined(__i386)
mmu.ptp_bits[2] = PT_VALID;
#endif
@@ -625,15 +595,6 @@ mmu_init(void)
while (mmu.hash_cnt * HASH_MAX_LENGTH < max_htables)
mmu.hash_cnt <<= 1;
#endif
-
- /*
- * This code knows that there are only 2 pagesizes.
- * We ignore 4MB (non-PAE) for now. The value is only used
- * for optimizing demaps across large ranges.
- * These return zero if no information is known.
- */
- mmu.tlb_entries[0] = cpuid_get_dtlb_nent(NULL, MMU_PAGESIZE);
- mmu.tlb_entries[1] = cpuid_get_dtlb_nent(NULL, 2 * 1024 * 1024);
}
@@ -765,11 +726,29 @@ hat_vlp_setup(struct cpu *cpu)
#endif /* __amd64 */
}
+/*ARGSUSED*/
+static void
+hat_vlp_teardown(cpu_t *cpu)
+{
+#if defined(__amd64)
+ struct hat_cpu_info *hci;
+
+ if ((hci = cpu->cpu_hat_info) == NULL)
+ return;
+ if (hci->hci_vlp_l2ptes)
+ kmem_free(hci->hci_vlp_l2ptes, MMU_PAGESIZE);
+ if (hci->hci_vlp_l3ptes)
+ kmem_free(hci->hci_vlp_l3ptes, MMU_PAGESIZE);
+#endif /* __amd64 */
+}
+
/*
* Finish filling in the kernel hat.
* Pre fill in all top level kernel page table entries for the kernel's
* part of the address range. From this point on we can't use any new
* kernel large pages if they need PTE's at max_level
+ *
+ * create the kmap mappings.
*/
void
hat_init_finish(void)
@@ -779,6 +758,7 @@ hat_init_finish(void)
uint_t e;
x86pte_t pte;
uintptr_t va = kernelbase;
+ size_t size;
#if defined(__i386)
@@ -826,6 +806,8 @@ hat_init_finish(void)
khat_entries = mmu.top_level_count - khat_start;
for (e = khat_start; e < mmu.top_level_count;
++e, va += LEVEL_SIZE(mmu.max_level)) {
+ if (IN_HYPERVISOR_VA(va))
+ continue;
pte = x86pte_get(top, e);
if (PTE_ISVALID(pte))
continue;
@@ -847,20 +829,30 @@ hat_init_finish(void)
* pagetable. We'll use the remainder for the "per CPU" page tables
* for VLP processes.
*
- * We map the top level kernel pagetable into the kernel's AS to make
- * it easy to use bcopy for kernel entry PTEs.
- *
- * We were guaranteed to get a physical address < 4Gig, since the 32 bit
- * boot loader uses non-PAE page tables.
+ * We also map the top level kernel pagetable into the kernel to make
+ * it easy to use bcopy to initialize new address spaces.
*/
if (mmu.pae_hat) {
vlp_page = vmem_alloc(heap_arena, MMU_PAGESIZE, VM_SLEEP);
hat_devload(kas.a_hat, (caddr_t)vlp_page, MMU_PAGESIZE,
kas.a_hat->hat_htable->ht_pfn,
- PROT_READ | PROT_WRITE | HAT_NOSYNC | HAT_UNORDERED_OK,
+ PROT_WRITE |
+ PROT_READ | HAT_NOSYNC | HAT_UNORDERED_OK,
HAT_LOAD | HAT_LOAD_NOCONSIST);
}
hat_vlp_setup(CPU);
+
+ /*
+ * Create kmap (cached mappings of kernel PTEs)
+ * for 32 bit we map from segmap_start .. ekernelheap
+ * for 64 bit we map from segmap_start .. segmap_start + segmapsize;
+ */
+#if defined(__i386)
+ size = (uintptr_t)ekernelheap - segmap_start;
+#elif defined(__amd64)
+ size = segmapsize;
+#endif
+ hat_kmap_init((uintptr_t)segmap_start, size);
}
/*
@@ -920,9 +912,7 @@ hat_switch(hat_t *hat)
* This is a spin lock at DISP_LEVEL
*/
if (hat != kas.a_hat) {
- mutex_enter(&hat->hat_switch_mutex);
CPUSET_ATOMIC_ADD(hat->hat_cpus, cpu->cpu_id);
- mutex_exit(&hat->hat_switch_mutex);
}
cpu->cpu_current_hat = hat;
@@ -968,12 +958,13 @@ hati_mkpte(pfn_t pfn, uint_t attr, level_t level, uint_t flags)
PTE_SET(pte, mmu.pt_nx);
/*
- * set the software bits used track ref/mod sync's and hments
+ * Set the software bits used track ref/mod sync's and hments.
+ * If not using REF/MOD, set them to avoid h/w rewriting PTEs.
*/
- if (attr & HAT_NOSYNC)
- PTE_SET(pte, PT_NOSYNC);
if (flags & HAT_LOAD_NOCONSIST)
- PTE_SET(pte, PT_NOCONSIST | PT_NOSYNC);
+ PTE_SET(pte, PT_NOCONSIST | PT_REF | PT_MOD);
+ else if (attr & HAT_NOSYNC)
+ PTE_SET(pte, PT_NOSYNC | PT_REF | PT_MOD);
/*
* Set the caching attributes in the PTE. The combination
@@ -1138,7 +1129,7 @@ hati_sync_pte_to_page(page_t *pp, x86pte_t pte, level_t level)
uint_t rm = 0;
pgcnt_t pgcnt;
- if (PTE_GET(pte, PT_NOSYNC))
+ if (PTE_GET(pte, PT_SOFTWARE) >= PT_NOSYNC)
return;
if (PTE_GET(pte, PT_REF))
@@ -1171,7 +1162,7 @@ hati_sync_pte_to_page(page_t *pp, x86pte_t pte, level_t level)
/*
* This the set of PTE bits for PFN, permissions and caching
- * that require a TLB flush (hat_demap) if changed on a HAT_LOAD_REMAP
+ * that require a TLB flush (hat_tlb_inval) if changed on a HAT_LOAD_REMAP
*/
#define PT_REMAP_BITS \
(PT_PADDR | PT_NX | PT_WRITABLE | PT_WRITETHRU | \
@@ -1182,7 +1173,7 @@ hati_sync_pte_to_page(page_t *pp, x86pte_t pte, level_t level)
* Do the low-level work to get a mapping entered into a HAT's pagetables
* and in the mapping list of the associated page_t.
*/
-static void
+static int
hati_pte_map(
htable_t *ht,
uint_t entry,
@@ -1196,6 +1187,7 @@ hati_pte_map(
level_t l = ht->ht_level;
hment_t *hm;
uint_t is_consist;
+ int rv = 0;
/*
* Is this a consistant (ie. need mapping list lock) mapping?
@@ -1224,18 +1216,20 @@ hati_pte_map(
old_pte = x86pte_set(ht, entry, pte, pte_ptr);
/*
- * If the mapping didn't change there is nothing more to do.
+ * did we get a large page / page table collision?
*/
- if (PTE_EQUIV(pte, old_pte)) {
- if (is_consist) {
- x86_hm_exit(pp);
- if (hm != NULL)
- hment_free(hm);
- }
- return;
+ if (old_pte == LPAGE_ERROR) {
+ rv = -1;
+ goto done;
}
/*
+ * If the mapping didn't change there is nothing more to do.
+ */
+ if (PTE_EQUIV(pte, old_pte))
+ goto done;
+
+ /*
* Install a new mapping in the page's mapping list
*/
if (!PTE_ISVALID(old_pte)) {
@@ -1247,7 +1241,7 @@ hati_pte_map(
}
HTABLE_INC(ht->ht_valid_cnt);
PGCNT_INC(hat, l);
- return;
+ return (rv);
}
/*
@@ -1262,7 +1256,7 @@ hati_pte_map(
if (PTE2PFN(old_pte, l) != PTE2PFN(pte, l)) {
REMAPASSERT(flags & HAT_LOAD_REMAP);
REMAPASSERT(flags & HAT_LOAD_NOCONSIST);
- REMAPASSERT(PTE_GET(old_pte, PT_NOCONSIST));
+ REMAPASSERT(PTE_GET(old_pte, PT_SOFTWARE) >= PT_NOCONSIST);
REMAPASSERT(pf_is_memory(PTE2PFN(old_pte, l)) ==
pf_is_memory(PTE2PFN(pte, l)));
REMAPASSERT(!is_consist);
@@ -1276,20 +1270,16 @@ hati_pte_map(
PTE_GET(pte, ~PT_REMAP_BITS));
/*
- * A remap requires invalidating the TLBs, since remapping the
- * same PFN requires NOCONSIST, we don't have to sync R/M bits.
- */
- hat_demap(hat, htable_e2va(ht, entry));
-
- /*
* We don't create any mapping list entries on a remap, so release
* any allocated hment after we drop the mapping list lock.
*/
+done:
if (is_consist) {
x86_hm_exit(pp);
if (hm != NULL)
hment_free(hm);
}
+ return (rv);
}
/*
@@ -1402,9 +1392,10 @@ hati_reserves_exit(uint_t kmem_for_hat)
}
/*
- * Internal routine to load a single page table entry.
+ * Internal routine to load a single page table entry. This only fails if
+ * we attempt to overwrite a page table link with a large page.
*/
-static void
+static int
hati_load_common(
hat_t *hat,
uintptr_t va,
@@ -1418,6 +1409,7 @@ hati_load_common(
uint_t entry;
x86pte_t pte;
uint_t kmem_for_hat = (flags & HAT_NO_KALLOC) ? 1 : 0;
+ int rv = 0;
ASSERT(hat == kas.a_hat ||
AS_LOCK_HELD(hat->hat_as, &hat->hat_as->a_lock));
@@ -1476,13 +1468,14 @@ hati_load_common(
/*
* establish the mapping
*/
- hati_pte_map(ht, entry, pp, pte, flags, NULL);
+ rv = hati_pte_map(ht, entry, pp, pte, flags, NULL);
/*
* release the htable and any reserves
*/
htable_release(ht);
hati_reserves_exit(kmem_for_hat);
+ return (rv);
}
/*
@@ -1521,7 +1514,7 @@ hat_kmap_load(
ht = mmu.kmap_htables[(va - mmu.kmap_htables[0]->ht_vaddr) >>
LEVEL_SHIFT(1)];
entry = htable_va2entry(va, ht);
- hati_pte_map(ht, entry, pp, pte, flags, pte_ptr);
+ (void) hati_pte_map(ht, entry, pp, pte, flags, pte_ptr);
}
/*
@@ -1535,7 +1528,7 @@ hat_kmap_load(
* and hat_devload().
*
* HAT_LOAD_NOCONSIST Do not add mapping to page_t mapping list.
- * sets PT_NOCONSIST (soft bit)
+ * sets PT_NOCONSIST
*
* HAT_LOAD_SHARE A flag to hat_memload() to indicate h/w page tables
* that map some user pages (not kas) is shared by more
@@ -1551,7 +1544,7 @@ hat_kmap_load(
*
* The following is a protection attribute (like PROT_READ, etc.)
*
- * HAT_NOSYNC set PT_NOSYNC (soft bit) - this mapping's ref/mod bits
+ * HAT_NOSYNC set PT_NOSYNC - this mapping's ref/mod bits
* are never cleared.
*
* Installing new valid PTE's and creation of the mapping list
@@ -1576,7 +1569,7 @@ hat_memload(
HATIN(hat_memload, hat, addr, (size_t)MMU_PAGESIZE);
ASSERT(IS_PAGEALIGNED(va));
- ASSERT(hat == kas.a_hat || va <= kernelbase);
+ ASSERT(hat == kas.a_hat || va < _userlimit);
ASSERT(hat == kas.a_hat ||
AS_LOCK_HELD(hat->hat_as, &hat->hat_as->a_lock));
ASSERT((flags & supported_memload_flags) == flags);
@@ -1598,7 +1591,8 @@ hat_memload(
* always set HAT_STORECACHING_OK.
*/
attr |= HAT_STORECACHING_OK;
- hati_load_common(hat, va, pp, attr, flags, level, pfn);
+ if (hati_load_common(hat, va, pp, attr, flags, level, pfn) != 0)
+ panic("unexpected hati_load_common() failure");
HATOUT(hat_memload, hat, addr);
}
@@ -1624,7 +1618,7 @@ hat_memload_array(
HATIN(hat_memload_array, hat, addr, len);
ASSERT(IS_PAGEALIGNED(va));
- ASSERT(hat == kas.a_hat || va + len <= kernelbase);
+ ASSERT(hat == kas.a_hat || va + len <= _userlimit);
ASSERT(hat == kas.a_hat ||
AS_LOCK_HELD(hat->hat_as, &hat->hat_as->a_lock));
ASSERT((flags & supported_memload_flags) == flags);
@@ -1647,9 +1641,10 @@ hat_memload_array(
pgsize = LEVEL_SIZE(level);
if (level == 0)
break;
+
if (!IS_P2ALIGNED(va, pgsize) ||
(eaddr - va) < pgsize ||
- !IS_P2ALIGNED(pfn << MMU_PAGESHIFT, pgsize))
+ !IS_P2ALIGNED(pfn_to_pa(pfn), pgsize))
continue;
/*
@@ -1675,36 +1670,17 @@ hat_memload_array(
}
/*
- * Shared page tables for DISM might have a pre-existing
- * level 0 page table that wasn't unlinked from all the
- * sharing hats. If we hit this for a large page, back off
- * to using level 0 pages.
- *
- * This can't be made better (ie. use large pages) until we
- * track all the htable's sharing and rewrite hat_pageunload().
- * Note that would cost a pointer in htable_t for a rare case.
- *
- * Since the 32 bit kernel caches empty page tables, check
- * the kernel too.
- */
- if ((hat == kas.a_hat || (hat->hat_flags & HAT_SHARED)) &&
- level > 0) {
- htable_t *lower;
-
- lower = htable_getpte(hat, va, NULL, NULL, level - 1);
- if (lower != NULL) {
- level = 0;
- pgsize = LEVEL_SIZE(0);
- htable_release(lower);
- }
- }
-
- /*
- * load this page mapping
+ * Load this page mapping. If the load fails, try a smaller
+ * pagesize.
*/
ASSERT(!IN_VA_HOLE(va));
- hati_load_common(hat, va, pages[pgindx], attr, flags,
- level, pfn);
+ while (hati_load_common(hat, va, pages[pgindx], attr,
+ flags, level, pfn) != 0) {
+ if (level == 0)
+ panic("unexpected hati_load_common() failure");
+ --level;
+ pgsize = LEVEL_SIZE(level);
+ }
/*
* move to next page
@@ -1764,7 +1740,7 @@ hat_devload(
HATIN(hat_devload, hat, addr, len);
ASSERT(IS_PAGEALIGNED(va));
- ASSERT(hat == kas.a_hat || eva <= kernelbase);
+ ASSERT(hat == kas.a_hat || eva <= _userlimit);
ASSERT(hat == kas.a_hat ||
AS_LOCK_HELD(hat->hat_as, &hat->hat_as->a_lock));
ASSERT((flags & supported_devload_flags) == flags);
@@ -1788,24 +1764,9 @@ hat_devload(
}
/*
- * Some kernel addresses have permanently existing page tables,
- * so be sure to use a compatible pagesize.
- */
- if (hat == kas.a_hat && level > 0) {
- htable_t *lower;
-
- lower = htable_getpte(hat, va, NULL, NULL, level - 1);
- if (lower != NULL) {
- level = 0;
- pgsize = LEVEL_SIZE(0);
- htable_release(lower);
- }
- }
-
- /*
- * If it is memory get page_t and allow caching (this happens
+ * If this is just memory then allow caching (this happens
* for the nucleus pages) - though HAT_PLAT_NOCACHE can be used
- * to override that. If we don't have a page_t, make sure
+ * to override that. If we don't have a page_t then make sure
* NOCONSIST is set.
*/
a = attr;
@@ -1827,7 +1788,12 @@ hat_devload(
* load this page mapping
*/
ASSERT(!IN_VA_HOLE(va));
- hati_load_common(hat, va, pp, a, f, level, pfn);
+ while (hati_load_common(hat, va, pp, a, f, level, pfn) != 0) {
+ if (level == 0)
+ panic("unexpected hati_load_common() failure");
+ --level;
+ pgsize = LEVEL_SIZE(level);
+ }
/*
* move to next page
@@ -1854,7 +1820,7 @@ hat_unlock(hat_t *hat, caddr_t addr, size_t len)
/*
* kernel entries are always locked, we don't track lock counts
*/
- ASSERT(hat == kas.a_hat || eaddr <= kernelbase);
+ ASSERT(hat == kas.a_hat || eaddr <= _userlimit);
ASSERT(IS_PAGEALIGNED(vaddr));
ASSERT(IS_PAGEALIGNED(eaddr));
if (hat == kas.a_hat)
@@ -1903,7 +1869,7 @@ hati_demap_func(xc_arg_t a1, xc_arg_t a2, xc_arg_t a3)
* For a normal address, we just flush one page mapping
*/
if ((uintptr_t)addr != DEMAP_ALL_ADDR) {
- mmu_tlbflush_entry((caddr_t)addr);
+ mmu_tlbflush_entry(addr);
return (0);
}
@@ -1931,10 +1897,11 @@ hati_demap_func(xc_arg_t a1, xc_arg_t a2, xc_arg_t a3)
* all CPUs using a given hat.
*/
void
-hat_demap(hat_t *hat, uintptr_t va)
+hat_tlb_inval(hat_t *hat, uintptr_t va)
{
extern int flushes_require_xcalls; /* from mp_startup.c */
cpuset_t justme;
+ cpuset_t cpus_to_shootdown;
/*
* If the hat is being destroyed, there are no more users, so
@@ -1963,29 +1930,29 @@ hat_demap(hat_t *hat, uintptr_t va)
/*
- * All CPUs must see kernel hat changes.
+ * Determine CPUs to shootdown. Kernel changes always do all CPUs.
+ * Otherwise it's just CPUs currently executing in this hat.
*/
- if (hat == kas.a_hat) {
- kpreempt_disable();
- xc_call((xc_arg_t)hat, (xc_arg_t)va, NULL,
- X_CALL_HIPRI, khat_cpuset, hati_demap_func);
- kpreempt_enable();
- return;
- }
-
- /*
- * Otherwise we notify CPUs currently running in this HAT
- */
- mutex_enter(&hat->hat_switch_mutex);
kpreempt_disable();
CPUSET_ONLY(justme, CPU->cpu_id);
- if (CPUSET_ISEQUAL(hat->hat_cpus, justme))
- (void) hati_demap_func((xc_arg_t)hat, (xc_arg_t)va, NULL);
+ if (hat == kas.a_hat)
+ cpus_to_shootdown = khat_cpuset;
else
- xc_call((xc_arg_t)hat, (xc_arg_t)va, NULL,
- X_CALL_HIPRI, hat->hat_cpus, hati_demap_func);
+ cpus_to_shootdown = hat->hat_cpus;
+
+ if (CPUSET_ISNULL(cpus_to_shootdown) ||
+ CPUSET_ISEQUAL(cpus_to_shootdown, justme)) {
+
+ (void) hati_demap_func((xc_arg_t)hat, (xc_arg_t)va, NULL);
+
+ } else {
+
+ CPUSET_ADD(cpus_to_shootdown, CPU->cpu_id);
+ xc_call((xc_arg_t)hat, (xc_arg_t)va, NULL, X_CALL_HIPRI,
+ cpus_to_shootdown, hati_demap_func);
+
+ }
kpreempt_enable();
- mutex_exit(&hat->hat_switch_mutex);
}
/*
@@ -2024,7 +1991,7 @@ hat_pte_unmap(
ASSERT(ht->ht_busy > 0);
while (PTE_ISVALID(old_pte)) {
pfn = PTE2PFN(old_pte, l);
- if (PTE_GET(old_pte, PT_NOCONSIST)) {
+ if (PTE_GET(old_pte, PT_SOFTWARE) >= PT_NOCONSIST) {
pp = NULL;
} else {
pp = page_numtopp_nolock(pfn);
@@ -2046,8 +2013,7 @@ hat_pte_unmap(
if (hat->hat_flags & HAT_FREEING)
old_pte = x86pte_get(ht, entry);
else
- old_pte =
- x86pte_invalidate_pfn(ht, entry, pfn, pte_ptr);
+ old_pte = x86pte_inval(ht, entry, old_pte, pte_ptr);
/*
* If the page hadn't changed we've unmapped it and can proceed
@@ -2063,7 +2029,7 @@ hat_pte_unmap(
x86_hm_exit(pp);
pp = NULL;
} else {
- ASSERT(PTE_GET(old_pte, PT_NOCONSIST));
+ ASSERT(PTE_GET(old_pte, PT_SOFTWARE) >= PT_NOCONSIST);
}
}
@@ -2104,24 +2070,19 @@ hat_kmap_unload(caddr_t addr, size_t len, uint_t flags)
{
uintptr_t va = (uintptr_t)addr;
uintptr_t eva = va + len;
- pgcnt_t pg_off;
+ pgcnt_t pg_index;
htable_t *ht;
uint_t entry;
- void *pte_ptr;
+ x86pte_t *pte_ptr;
x86pte_t old_pte;
for (; va < eva; va += MMU_PAGESIZE) {
/*
* Get the PTE
*/
- pg_off = mmu_btop(va - mmu.kmap_addr);
- if (mmu.pae_hat) {
- pte_ptr = mmu.kmap_ptes + pg_off;
- ATOMIC_LOAD64((x86pte_t *)pte_ptr, old_pte);
- } else {
- pte_ptr = (x86pte32_t *)mmu.kmap_ptes + pg_off;
- old_pte = *(x86pte32_t *)pte_ptr;
- }
+ pg_index = mmu_btop(va - mmu.kmap_addr);
+ pte_ptr = PT_INDEX_PTR(mmu.kmap_ptes, pg_index);
+ old_pte = GET_PTE(pte_ptr);
/*
* get the htable / entry
@@ -2145,7 +2106,8 @@ void
hat_unload(hat_t *hat, caddr_t addr, size_t len, uint_t flags)
{
uintptr_t va = (uintptr_t)addr;
- ASSERT(hat == kas.a_hat || va + len <= kernelbase);
+
+ ASSERT(hat == kas.a_hat || va + len <= _userlimit);
/*
* special case for performance.
@@ -2153,9 +2115,9 @@ hat_unload(hat_t *hat, caddr_t addr, size_t len, uint_t flags)
if (mmu.kmap_addr <= va && va < mmu.kmap_eaddr) {
ASSERT(hat == kas.a_hat);
hat_kmap_unload(addr, len, flags);
- return;
+ } else {
+ hat_unload_callback(hat, addr, len, flags, NULL);
}
- hat_unload_callback(hat, addr, len, flags, NULL);
}
/*
@@ -2212,10 +2174,24 @@ hat_unload_callback(
x86pte_t old_pte;
HATIN(hat_unload_callback, hat, addr, len);
- ASSERT(hat == kas.a_hat || eaddr <= kernelbase);
+ ASSERT(hat == kas.a_hat || eaddr <= _userlimit);
ASSERT(IS_PAGEALIGNED(vaddr));
ASSERT(IS_PAGEALIGNED(eaddr));
+ /*
+ * Special case a single page being unloaded for speed. This happens
+ * quite frequently, COW faults after a fork() for example.
+ */
+ if (cb == NULL && len == MMU_PAGESIZE) {
+ ht = htable_getpte(hat, vaddr, &entry, &old_pte, 0);
+ if (ht != NULL) {
+ if (PTE_ISVALID(old_pte))
+ hat_pte_unmap(ht, entry, flags, old_pte, NULL);
+ htable_release(ht);
+ }
+ return;
+ }
+
while (vaddr < eaddr) {
old_pte = htable_walk(hat, &ht, &vaddr, eaddr);
if (ht == NULL)
@@ -2246,7 +2222,6 @@ hat_unload_callback(
*/
entry = htable_va2entry(vaddr, ht);
hat_pte_unmap(ht, entry, flags, old_pte, NULL);
-
ASSERT(ht->ht_level <= mmu.max_page_level);
vaddr += LEVEL_SIZE(ht->ht_level);
contig_va = vaddr;
@@ -2286,7 +2261,7 @@ hat_sync(hat_t *hat, caddr_t addr, size_t len, uint_t flags)
ASSERT(!IN_VA_HOLE(vaddr));
ASSERT(IS_PAGEALIGNED(vaddr));
ASSERT(IS_PAGEALIGNED(eaddr));
- ASSERT(hat == kas.a_hat || eaddr <= kernelbase);
+ ASSERT(hat == kas.a_hat || eaddr <= _userlimit);
for (; vaddr < eaddr; vaddr += LEVEL_SIZE(ht->ht_level)) {
try_again:
@@ -2295,7 +2270,7 @@ try_again:
break;
entry = htable_va2entry(vaddr, ht);
- if (PTE_GET(pte, PT_NOSYNC) ||
+ if (PTE_GET(pte, PT_SOFTWARE) >= PT_NOSYNC ||
PTE_GET(pte, PT_REF | PT_MOD) == 0)
continue;
@@ -2313,7 +2288,7 @@ try_again:
x86_hm_exit(pp);
goto try_again;
}
- if (PTE_GET(pte, PT_NOSYNC) ||
+ if (PTE_GET(pte, PT_SOFTWARE) >= PT_NOSYNC ||
PTE_GET(pte, PT_REF | PT_MOD) == 0) {
x86_hm_exit(pp);
continue;
@@ -2366,12 +2341,12 @@ hat_getattr(hat_t *hat, caddr_t addr, uint_t *attr)
htable_t *ht = NULL;
x86pte_t pte;
- ASSERT(hat == kas.a_hat || vaddr < kernelbase);
+ ASSERT(hat == kas.a_hat || vaddr <= _userlimit);
if (IN_VA_HOLE(vaddr))
return ((uint_t)-1);
- ht = htable_getpte(hat, vaddr, NULL, &pte, MAX_PAGE_LEVEL);
+ ht = htable_getpte(hat, vaddr, NULL, &pte, mmu.max_page_level);
if (ht == NULL)
return ((uint_t)-1);
@@ -2387,7 +2362,7 @@ hat_getattr(hat_t *hat, caddr_t addr, uint_t *attr)
*attr |= PROT_USER;
if (!PTE_GET(pte, mmu.pt_nx))
*attr |= PROT_EXEC;
- if (PTE_GET(pte, PT_NOSYNC))
+ if (PTE_GET(pte, PT_SOFTWARE) >= PT_NOSYNC)
*attr |= HAT_NOSYNC;
htable_release(ht);
return (0);
@@ -2419,7 +2394,7 @@ try_again:
oldpte = htable_walk(hat, &ht, &vaddr, eaddr);
if (ht == NULL)
break;
- if (PTE_GET(oldpte, PT_NOCONSIST))
+ if (PTE_GET(oldpte, PT_SOFTWARE) >= PT_NOCONSIST)
continue;
pp = page_numtopp_nolock(PTE2PFN(oldpte, ht->ht_level));
@@ -2437,7 +2412,8 @@ try_again:
!PTE_GET(oldpte, PT_WRITABLE))
newpte |= PT_WRITABLE;
- if ((attr & HAT_NOSYNC) && !PTE_GET(oldpte, PT_NOSYNC))
+ if ((attr & HAT_NOSYNC) &&
+ PTE_GET(oldpte, PT_SOFTWARE) < PT_NOSYNC)
newpte |= PT_NOSYNC;
if ((attr & PROT_EXEC) && PTE_GET(oldpte, mmu.pt_nx))
@@ -2449,8 +2425,9 @@ try_again:
PTE_GET(oldpte, PT_WRITABLE))
newpte &= ~PT_WRITABLE;
- if (!(attr & HAT_NOSYNC) && PTE_GET(oldpte, PT_NOSYNC))
- newpte &= ~PT_NOSYNC;
+ if (!(attr & HAT_NOSYNC) &&
+ PTE_GET(oldpte, PT_SOFTWARE) >= PT_NOSYNC)
+ newpte &= ~PT_SOFTWARE;
if (!(attr & PROT_EXEC) && !PTE_GET(oldpte, mmu.pt_nx))
newpte |= mmu.pt_nx;
@@ -2460,14 +2437,22 @@ try_again:
if ((attr & PROT_WRITE) && PTE_GET(oldpte, PT_WRITABLE))
newpte &= ~PT_WRITABLE;
- if ((attr & HAT_NOSYNC) && PTE_GET(oldpte, PT_NOSYNC))
- newpte &= ~PT_NOSYNC;
+ if ((attr & HAT_NOSYNC) &&
+ PTE_GET(oldpte, PT_SOFTWARE) >= PT_NOSYNC)
+ newpte &= ~PT_SOFTWARE;
if ((attr & PROT_EXEC) && !PTE_GET(oldpte, mmu.pt_nx))
newpte |= mmu.pt_nx;
}
/*
+ * Ensure NOSYNC/NOCONSIST mappings have REF and MOD set.
+ * x86pte_set() depends on this.
+ */
+ if (PTE_GET(newpte, PT_SOFTWARE) >= PT_NOSYNC)
+ newpte |= PT_REF | PT_MOD;
+
+ /*
* what about PROT_READ or others? this code only handles:
* EXEC, WRITE, NOSYNC
*/
@@ -2495,38 +2480,31 @@ try_again:
void
hat_setattr(hat_t *hat, caddr_t addr, size_t len, uint_t attr)
{
- ASSERT(hat == kas.a_hat || (uintptr_t)addr + len <= kernelbase);
+ ASSERT(hat == kas.a_hat || (uintptr_t)addr + len <= _userlimit);
hat_updateattr(hat, addr, len, attr, HAT_SET_ATTR);
}
void
hat_clrattr(hat_t *hat, caddr_t addr, size_t len, uint_t attr)
{
- ASSERT(hat == kas.a_hat || (uintptr_t)addr + len <= kernelbase);
+ ASSERT(hat == kas.a_hat || (uintptr_t)addr + len <= _userlimit);
hat_updateattr(hat, addr, len, attr, HAT_CLR_ATTR);
}
void
hat_chgattr(hat_t *hat, caddr_t addr, size_t len, uint_t attr)
{
- ASSERT(hat == kas.a_hat || (uintptr_t)addr + len <= kernelbase);
+ ASSERT(hat == kas.a_hat || (uintptr_t)addr + len <= _userlimit);
hat_updateattr(hat, addr, len, attr, HAT_LOAD_ATTR);
}
void
hat_chgprot(hat_t *hat, caddr_t addr, size_t len, uint_t vprot)
{
- ASSERT(hat == kas.a_hat || (uintptr_t)addr + len <= kernelbase);
+ ASSERT(hat == kas.a_hat || (uintptr_t)addr + len <= _userlimit);
hat_updateattr(hat, addr, len, vprot & HAT_PROT_MASK, HAT_LOAD_ATTR);
}
-/*ARGSUSED*/
-void
-hat_chgattr_pagedir(hat_t *hat, caddr_t addr, size_t len, uint_t attr)
-{
- panic("hat_chgattr_pgdir() not supported - used by 80387 emulation");
-}
-
/*
* size_t hat_getpagesize(hat, addr)
* returns pagesize in bytes for <hat, addr>. returns -1 of there is
@@ -2539,7 +2517,7 @@ hat_getpagesize(hat_t *hat, caddr_t addr)
htable_t *ht;
size_t pagesize;
- ASSERT(hat == kas.a_hat || vaddr < kernelbase);
+ ASSERT(hat == kas.a_hat || vaddr <= _userlimit);
if (IN_VA_HOLE(vaddr))
return (-1);
ht = htable_getpage(hat, vaddr, NULL);
@@ -2564,9 +2542,9 @@ hat_getpfnum(hat_t *hat, caddr_t addr)
uint_t entry;
pfn_t pfn = PFN_INVALID;
- ASSERT(hat == kas.a_hat || vaddr < kernelbase);
+ ASSERT(hat == kas.a_hat || vaddr <= _userlimit);
if (khat_running == 0)
- panic("hat_getpfnum(): called too early\n");
+ return (PFN_INVALID);
if (IN_VA_HOLE(vaddr))
return (PFN_INVALID);
@@ -2578,14 +2556,10 @@ hat_getpfnum(hat_t *hat, caddr_t addr)
*/
if (mmu.kmap_addr <= vaddr && vaddr < mmu.kmap_eaddr) {
x86pte_t pte;
- pgcnt_t pg_off;
+ pgcnt_t pg_index;
- pg_off = mmu_btop(vaddr - mmu.kmap_addr);
- if (mmu.pae_hat) {
- ATOMIC_LOAD64(mmu.kmap_ptes + pg_off, pte);
- } else {
- pte = ((x86pte32_t *)mmu.kmap_ptes)[pg_off];
- }
+ pg_index = mmu_btop(vaddr - mmu.kmap_addr);
+ pte = GET_PTE(PT_INDEX_PTR(mmu.kmap_ptes, pg_index));
if (!PTE_ISVALID(pte))
return (PFN_INVALID);
/*LINTED [use of constant 0 causes a silly lint warning] */
@@ -2623,7 +2597,6 @@ hat_getkpfnum(caddr_t addr)
pfn_t pfn;
int badcaller = 0;
-
if (khat_running == 0)
panic("hat_getkpfnum(): called too early\n");
if ((uintptr_t)addr < kernelbase)
@@ -2657,7 +2630,7 @@ hat_probe(hat_t *hat, caddr_t addr)
htable_t *ht;
pgcnt_t pg_off;
- ASSERT(hat == kas.a_hat || vaddr < kernelbase);
+ ASSERT(hat == kas.a_hat || vaddr <= _userlimit);
ASSERT(hat == kas.a_hat ||
AS_LOCK_HELD(hat->hat_as, &hat->hat_as->a_lock));
if (IN_VA_HOLE(vaddr))
@@ -2721,7 +2694,7 @@ hat_share(
* We might be asked to share an empty DISM hat by as_dup()
*/
ASSERT(hat != kas.a_hat);
- ASSERT(eaddr <= kernelbase);
+ ASSERT(eaddr <= _userlimit);
if (!(ism_hat->hat_flags & HAT_SHARED)) {
ASSERT(hat_get_mapped_size(ism_hat) == 0);
return (0);
@@ -2833,8 +2806,12 @@ hat_share(
* XX64 -- can shm ever be written to swap?
* if not we could use HAT_NOSYNC here.
*/
- hati_load_common(hat, vaddr, pp, prot,
- HAT_LOAD, l, pfn);
+ while (hati_load_common(hat, vaddr, pp, prot, HAT_LOAD,
+ l, pfn) != 0) {
+ if (l == 0)
+ panic("hati_load_common() failure");
+ --l;
+ }
vaddr += LEVEL_SIZE(l);
ism_addr += LEVEL_SIZE(l);
@@ -2865,7 +2842,7 @@ hat_unshare(hat_t *hat, caddr_t addr, size_t len, uint_t ismszc)
uint_t need_demaps = 0;
ASSERT(hat != kas.a_hat);
- ASSERT(eaddr <= kernelbase);
+ ASSERT(eaddr <= _userlimit);
HATIN(hat_unshare, hat, addr, len);
ASSERT(IS_PAGEALIGNED(vaddr));
ASSERT(IS_PAGEALIGNED(eaddr));
@@ -2873,9 +2850,9 @@ hat_unshare(hat_t *hat, caddr_t addr, size_t len, uint_t ismszc)
/*
* First go through and remove any shared pagetables.
*
- * Note that it's ok to delay the demap until the entire range is
+ * Note that it's ok to delay the TLB shootdown till the entire range is
* finished, because if hat_pageunload() were to unload a shared
- * pagetable page, its hat_demap() will do a global user TLB invalidate.
+ * pagetable page, its hat_tlb_inval() will do a global TLB invalidate.
*/
while (vaddr < eaddr) {
ASSERT(!IN_VA_HOLE(vaddr));
@@ -2904,7 +2881,7 @@ hat_unshare(hat_t *hat, caddr_t addr, size_t len, uint_t ismszc)
* we do just one CR3 reload.
*/
if (!(hat->hat_flags & HAT_FREEING) && need_demaps)
- hat_demap(hat, DEMAP_ALL_ADDR);
+ hat_tlb_inval(hat, DEMAP_ALL_ADDR);
/*
* Now go back and clean up any unaligned mappings that
@@ -3086,9 +3063,9 @@ hati_page_unmap(page_t *pp, htable_t *ht, uint_t entry)
/*
* Invalidate the PTE and remove the hment.
*/
- old_pte = x86pte_invalidate_pfn(ht, entry, pfn, NULL);
+ old_pte = x86pte_inval(ht, entry, 0, NULL);
if (PTE2PFN(old_pte, ht->ht_level) != pfn) {
- panic("x86pte_invalidate_pfn() failure found PTE = " FMT_PTE
+ panic("x86pte_inval() failure found PTE = " FMT_PTE
" pfn being unmapped is %lx ht=0x%lx entry=0x%x",
old_pte, pfn, (uintptr_t)ht, entry);
}
@@ -3103,7 +3080,7 @@ hati_page_unmap(page_t *pp, htable_t *ht, uint_t entry)
/*
* sync ref/mod bits to the page_t
*/
- if (PTE_GET(old_pte, PT_NOSYNC) == 0)
+ if (PTE_GET(old_pte, PT_SOFTWARE) < PT_NOSYNC)
hati_sync_pte_to_page(pp, old_pte, ht->ht_level);
/*
@@ -3165,8 +3142,9 @@ next_size:
/*
* If not part of a larger page, we're done.
*/
- if (cur_pp->p_szc <= pg_szcd)
+ if (cur_pp->p_szc <= pg_szcd) {
return (0);
+ }
/*
* Else check the next larger page size.
@@ -3459,7 +3437,8 @@ try_again:
/*
* Sync the PTE
*/
- if (!(flags & HAT_SYNC_ZERORM) && PTE_GET(old, PT_NOSYNC) == 0)
+ if (!(flags & HAT_SYNC_ZERORM) &&
+ PTE_GET(old, PT_SOFTWARE) <= PT_NOSYNC)
hati_sync_pte_to_page(pp, old, ht->ht_level);
/*
@@ -3468,7 +3447,7 @@ try_again:
if ((flags & HAT_SYNC_STOPON_MOD) && PP_ISMOD(save_pp) ||
(flags & HAT_SYNC_STOPON_REF) && PP_ISREF(save_pp)) {
x86_hm_exit(pp);
- return (save_pp->p_nrm & nrmbits);
+ goto done;
}
}
x86_hm_exit(pp);
@@ -3481,6 +3460,7 @@ try_again:
goto next_size;
}
}
+done:
return (save_pp->p_nrm & nrmbits);
}
@@ -3576,28 +3556,25 @@ hat_setup(hat_t *hat, int flags)
* the htable can't disappear. We also hat_devload() the page table into
* kernel so that the PTE is quickly accessed.
*/
-void *
-hat_mempte_kern_setup(caddr_t addr, void *pt)
+hat_mempte_t
+hat_mempte_setup(caddr_t addr)
{
uintptr_t va = (uintptr_t)addr;
htable_t *ht;
uint_t entry;
x86pte_t oldpte;
- caddr_t p = (caddr_t)pt;
+ hat_mempte_t p;
+ uint_t created = 0;
ASSERT(IS_PAGEALIGNED(va));
ASSERT(!IN_VA_HOLE(va));
ht = htable_getpte(kas.a_hat, va, &entry, &oldpte, 0);
if (ht == NULL) {
- /*
- * Note that we don't need a hat_reserves_exit() check
- * for this htable_create(), since that'll be done by the
- * hat_devload() just below.
- */
ht = htable_create(kas.a_hat, va, 0, NULL);
entry = htable_va2entry(va, ht);
ASSERT(ht->ht_level == 0);
oldpte = x86pte_get(ht, entry);
+ created = 1;
}
if (PTE_ISVALID(oldpte))
panic("hat_mempte_setup(): address already mapped"
@@ -3609,65 +3586,47 @@ hat_mempte_kern_setup(caddr_t addr, void *pt)
HTABLE_INC(ht->ht_valid_cnt);
/*
- * now we need to map the page holding the pagetable for va into
- * the kernel's address space.
- */
- hat_devload(kas.a_hat, p, MMU_PAGESIZE, ht->ht_pfn,
- PROT_READ | PROT_WRITE | HAT_NOSYNC | HAT_UNORDERED_OK,
- HAT_LOAD | HAT_LOAD_NOCONSIST);
-
- /*
- * return the PTE address to the caller.
+ * return the PTE physical address to the caller.
*/
htable_release(ht);
- p += entry << mmu.pte_size_shift;
- return ((void *)p);
-}
-
-/*
- * Prepare for a CPU private mapping for the given address.
- */
-void *
-hat_mempte_setup(caddr_t addr)
-{
- x86pte_t *p;
-
- p = vmem_alloc(heap_arena, MMU_PAGESIZE, VM_SLEEP);
- return (hat_mempte_kern_setup(addr, p));
+ p = PT_INDEX_PHYSADDR(pfn_to_pa(ht->ht_pfn), entry);
+ if (created)
+ hati_reserves_exit(0);
+ return (p);
}
/*
* Release a CPU private mapping for the given address.
* We decrement the htable valid count so it might be destroyed.
*/
+/*ARGSUSED1*/
void
-hat_mempte_release(caddr_t addr, void *pteptr)
+hat_mempte_release(caddr_t addr, hat_mempte_t pte_pa)
{
htable_t *ht;
- uintptr_t va = ALIGN2PAGE(pteptr);
/*
- * first invalidate any left over mapping and decrement the
- * htable's mapping count
+ * invalidate any left over mapping and decrement the htable valid count
*/
- if (mmu.pae_hat)
- *(x86pte_t *)pteptr = 0;
- else
- *(x86pte32_t *)pteptr = 0;
- mmu_tlbflush_entry(addr);
+ {
+ x86pte_t *pteptr;
+
+ pteptr = x86pte_mapin(mmu_btop(pte_pa),
+ (pte_pa & MMU_PAGEOFFSET) >> mmu.pte_size_shift, NULL);
+ if (mmu.pae_hat)
+ *pteptr = 0;
+ else
+ *(x86pte32_t *)pteptr = 0;
+ mmu_tlbflush_entry(addr);
+ x86pte_mapout();
+ }
+
ht = htable_getpte(kas.a_hat, ALIGN2PAGE(addr), NULL, NULL, 0);
if (ht == NULL)
panic("hat_mempte_release(): invalid address");
ASSERT(ht->ht_level == 0);
HTABLE_DEC(ht->ht_valid_cnt);
htable_release(ht);
-
- /*
- * now blow away the kernel mapping to the page table page
- * XX64 -- see comment in hat_mempte_setup()
- */
- hat_unload_callback(kas.a_hat, (caddr_t)va, MMU_PAGESIZE,
- HAT_UNLOAD, NULL);
}
/*
@@ -3676,11 +3635,11 @@ hat_mempte_release(caddr_t addr, void *pteptr)
*/
void
hat_mempte_remap(
- pfn_t pfn,
- caddr_t addr,
- void *pteptr,
- uint_t attr,
- uint_t flags)
+ pfn_t pfn,
+ caddr_t addr,
+ hat_mempte_t pte_pa,
+ uint_t attr,
+ uint_t flags)
{
uintptr_t va = (uintptr_t)addr;
x86pte_t pte;
@@ -3699,14 +3658,22 @@ hat_mempte_remap(
ASSERT(ht != NULL);
ASSERT(ht->ht_level == 0);
ASSERT(ht->ht_valid_cnt > 0);
+ ASSERT(ht->ht_pfn == mmu_btop(pte_pa));
htable_release(ht);
#endif
pte = hati_mkpte(pfn, attr, 0, flags);
- if (mmu.pae_hat)
- *(x86pte_t *)pteptr = pte;
- else
- *(x86pte32_t *)pteptr = (x86pte32_t)pte;
- mmu_tlbflush_entry(addr);
+ {
+ x86pte_t *pteptr;
+
+ pteptr = x86pte_mapin(mmu_btop(pte_pa),
+ (pte_pa & MMU_PAGEOFFSET) >> mmu.pte_size_shift, NULL);
+ if (mmu.pae_hat)
+ *(x86pte_t *)pteptr = pte;
+ else
+ *(x86pte32_t *)pteptr = (x86pte32_t)pte;
+ mmu_tlbflush_entry(addr);
+ x86pte_mapout();
+ }
}
@@ -3728,64 +3695,31 @@ hat_exit(hat_t *hat)
mutex_exit(&hat->hat_mutex);
}
-
/*
- * Used by hat_kern_setup() to create initial kernel HAT mappings from
- * the boot loader's mappings.
- *
- * - size is either PAGESIZE or some multiple of a level one pagesize
- * - there may not be page_t's for every pfn. (ie. the nucleus pages)
- * - pfn's are continguous for the given va range (va to va + size * cnt)
+ * HAT part of cpu initialization.
*/
void
-hati_kern_setup_load(
- uintptr_t va, /* starting va of range to map */
- size_t size, /* either PAGESIZE or multiple of large page size */
- pfn_t pfn, /* starting PFN */
- pgcnt_t cnt, /* number of mappings, (cnt * size) == total size */
- uint_t prot) /* protections (PROT_READ, PROT_WRITE, PROT_EXEC) */
+hat_cpu_online(struct cpu *cpup)
{
- level_t level = (size == MMU_PAGESIZE ? 0 : 1);
- size_t bytes = size * cnt;
- size_t pgsize = LEVEL_SIZE(level);
- page_t *pp;
- uint_t flags = HAT_LOAD;
-
- /*
- * We're only going to throw away mappings below kernelbase or in
- * boot's special double-mapping region, so set noconsist to avoid
- * using hments
- */
- if (BOOT_VA(va))
- flags |= HAT_LOAD_NOCONSIST;
-
- prot |= HAT_STORECACHING_OK;
- while (bytes != 0) {
- ASSERT(bytes >= pgsize);
-
- pp = NULL;
- if (pf_is_memory(pfn) && !BOOT_VA(va) && level == 0)
- pp = page_numtopp_nolock(pfn);
-
- hati_load_common(kas.a_hat, va, pp, prot, flags, level, pfn);
-
- va += pgsize;
- pfn += mmu_btop(pgsize);
- bytes -= pgsize;
+ if (cpup != CPU) {
+ x86pte_cpu_init(cpup);
+ hat_vlp_setup(cpup);
}
+ CPUSET_ATOMIC_ADD(khat_cpuset, cpup->cpu_id);
}
/*
- * HAT part of cpu intialization.
+ * HAT part of cpu deletion.
+ * (currently, we only call this after the cpu is safely passivated.)
*/
void
-hat_cpu_online(struct cpu *cpup)
+hat_cpu_offline(struct cpu *cpup)
{
- if (cpup != CPU) {
- x86pte_cpu_init(cpup, NULL);
- hat_vlp_setup(cpup);
- }
- CPUSET_ATOMIC_ADD(khat_cpuset, cpup->cpu_id);
+ ASSERT(cpup != CPU);
+
+ CPUSET_ATOMIC_DEL(khat_cpuset, cpup->cpu_id);
+ x86pte_cpu_fini(cpup);
+ hat_vlp_teardown(cpup);
}
/*
@@ -3803,7 +3737,7 @@ clear_boot_mappings(uintptr_t low, uintptr_t high)
/*
* On 1st CPU we can unload the prom mappings, basically we blow away
- * all virtual mappings under kernelbase.
+ * all virtual mappings under _userlimit.
*/
while (vaddr < high) {
pte = htable_walk(kas.a_hat, &ht, &vaddr, high);
@@ -3818,7 +3752,7 @@ clear_boot_mappings(uintptr_t low, uintptr_t high)
/*
* Unload the mapping from the page tables.
*/
- (void) x86pte_set(ht, entry, 0, NULL);
+ (void) x86pte_inval(ht, entry, 0, NULL);
ASSERT(ht->ht_valid_cnt > 0);
HTABLE_DEC(ht->ht_valid_cnt);
PGCNT_DEC(ht->ht_hat, ht->ht_level);
@@ -3827,71 +3761,6 @@ clear_boot_mappings(uintptr_t low, uintptr_t high)
}
if (ht)
htable_release(ht);
-
- /*
- * cross call for a complete invalidate.
- */
- hat_demap(kas.a_hat, DEMAP_ALL_ADDR);
-}
-
-/*
- * Initialize a special area in the kernel that always holds some PTEs for
- * faster performance. This always holds segmap's PTEs.
- * In the 32 bit kernel this maps the kernel heap too.
- */
-void
-hat_kmap_init(uintptr_t base, size_t len)
-{
- uintptr_t map_addr; /* base rounded down to large page size */
- uintptr_t map_eaddr; /* base + len rounded up */
- size_t map_len;
- caddr_t ptes; /* mapping area in kernel as for ptes */
- size_t window_size; /* size of mapping area for ptes */
- ulong_t htable_cnt; /* # of page tables to cover map_len */
- ulong_t i;
- htable_t *ht;
-
- /*
- * we have to map in an area that matches an entire page table
- */
- map_addr = base & LEVEL_MASK(1);
- map_eaddr = (base + len + LEVEL_SIZE(1) - 1) & LEVEL_MASK(1);
- map_len = map_eaddr - map_addr;
- window_size = mmu_btop(map_len) * mmu.pte_size;
- htable_cnt = mmu_btop(map_len) / mmu.ptes_per_table;
-
- /*
- * allocate vmem for the kmap_ptes
- */
- ptes = vmem_xalloc(heap_arena, window_size, MMU_PAGESIZE, 0,
- 0, NULL, NULL, VM_SLEEP);
- mmu.kmap_htables =
- kmem_alloc(htable_cnt * sizeof (htable_t *), KM_SLEEP);
-
- /*
- * Map the page tables that cover kmap into the allocated range.
- * Note we don't ever htable_release() the kmap page tables - they
- * can't ever be stolen, freed, etc.
- */
- for (i = 0; i < htable_cnt; ++i) {
- ht = htable_create(kas.a_hat, map_addr + i * LEVEL_SIZE(1),
- 0, NULL);
- mmu.kmap_htables[i] = ht;
-
- hat_devload(kas.a_hat, ptes + i * MMU_PAGESIZE, MMU_PAGESIZE,
- ht->ht_pfn,
- PROT_READ | PROT_WRITE | HAT_NOSYNC | HAT_UNORDERED_OK,
- HAT_LOAD | HAT_LOAD_NOCONSIST);
-
- }
-
- /*
- * set information in mmu to activate handling of kmap
- */
- mmu.kmap_addr = base;
- mmu.kmap_eaddr = base + len;
- mmu.kmap_ptes =
- (x86pte_t *)(ptes + mmu.pte_size * mmu_btop(base - map_addr));
}
/*
@@ -3909,11 +3778,12 @@ hati_update_pte(htable_t *ht, uint_t entry, x86pte_t expected, x86pte_t new)
uint_t rm = 0;
x86pte_t replaced;
- if (!PTE_GET(expected, PT_NOSYNC | PT_NOCONSIST) &&
+ if (PTE_GET(expected, PT_SOFTWARE) < PT_NOSYNC &&
PTE_GET(expected, PT_MOD | PT_REF) &&
(PTE_GET(new, PT_NOSYNC) || !PTE_GET(new, PT_WRITABLE) ||
!PTE_GET(new, PT_MOD | PT_REF))) {
+ ASSERT(!pfn_is_foreign(PTE2PFN(expected, ht->ht_level)));
pp = page_numtopp_nolock(PTE2PFN(expected, ht->ht_level));
ASSERT(pp != NULL);
if (PTE_GET(expected, PT_MOD))
@@ -4022,11 +3892,7 @@ hat_kpm_mapout(struct page *pp, struct kpme *kpme, caddr_t vaddr)
caddr_t
hat_kpm_pfn2va(pfn_t pfn)
{
- uintptr_t vaddr;
-
- ASSERT(kpm_enable);
-
- vaddr = (uintptr_t)kpm_vbase + mmu_ptob(pfn);
+ uintptr_t vaddr = (uintptr_t)kpm_vbase + mmu_ptob(pfn);
return ((caddr_t)vaddr);
}
diff --git a/usr/src/uts/i86pc/vm/hat_i86.h b/usr/src/uts/i86pc/vm/hat_i86.h
index 9194efa660..f88d89b477 100644
--- a/usr/src/uts/i86pc/vm/hat_i86.h
+++ b/usr/src/uts/i86pc/vm/hat_i86.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -80,7 +79,6 @@ extern "C" {
*/
struct hat {
kmutex_t hat_mutex;
- kmutex_t hat_switch_mutex;
struct as *hat_as;
uint_t hat_stats;
pgcnt_t hat_pages_mapped[MAX_PAGE_LEVEL + 1];
@@ -173,10 +171,11 @@ extern kcondvar_t hat_list_cv;
*
* Used by ppcopy(), page_zero(), the memscrubber, and the kernel debugger.
*/
-extern void *hat_mempte_kern_setup(caddr_t addr, void *);
-extern void *hat_mempte_setup(caddr_t addr);
-extern void hat_mempte_remap(pfn_t, caddr_t, void *, uint_t attr, uint_t flags);
-extern void hat_mempte_release(caddr_t addr, void *);
+typedef paddr_t hat_mempte_t; /* phys addr of PTE */
+extern hat_mempte_t hat_mempte_setup(caddr_t addr);
+extern void hat_mempte_remap(pfn_t, caddr_t, hat_mempte_t,
+ uint_t attr, uint_t flags);
+extern void hat_mempte_release(caddr_t addr, hat_mempte_t);
/*
* interfaces to manage which thread has access to htable and hment reserves
@@ -189,9 +188,10 @@ extern kthread_t *hat_reserves_thread;
* initialization stuff needed by by startup, mp_startup...
*/
extern void hat_cpu_online(struct cpu *);
+extern void hat_cpu_offline(struct cpu *);
extern void setup_vaddr_for_ppcopy(struct cpu *);
+extern void teardown_vaddr_for_ppcopy(struct cpu *);
extern void clear_boot_mappings(uintptr_t, uintptr_t);
-extern int hat_boot_probe(uintptr_t *va, size_t *len, pfn_t *pfn, uint_t *prot);
/*
* magic value to indicate that all TLB entries should be demapped.
@@ -206,26 +206,26 @@ extern void halt(char *fmt);
/*
* x86 specific routines for use online in setup or i86pc/vm files
*/
-extern void hat_kern_alloc(void);
-extern void hati_kern_setup_load(uintptr_t, size_t, pfn_t, pgcnt_t, uint_t);
-extern void hat_demap(struct hat *hat, uintptr_t va);
+extern void hat_kern_alloc(caddr_t segmap_base, size_t segmap_size,
+ caddr_t ekernelheap);
+extern void hat_kern_setup(void);
+extern void hat_tlb_inval(struct hat *hat, uintptr_t va);
extern void hat_pte_unmap(htable_t *ht, uint_t entry, uint_t flags,
x86pte_t old_pte, void *pte_ptr);
extern void hat_init_finish(void);
-extern void hat_kmap_init(uintptr_t base, size_t len);
extern caddr_t hat_kpm_pfn2va(pfn_t pfn);
extern pfn_t hat_kpm_va2pfn(caddr_t);
extern page_t *hat_kpm_vaddr2page(caddr_t);
extern uintptr_t hat_kernelbase(uintptr_t);
+extern void hat_kmap_init(uintptr_t base, size_t len);
-extern pfn_t hat_boot_remap(uintptr_t, pfn_t);
-extern void hat_boot_demap(uintptr_t);
extern hment_t *hati_page_unmap(page_t *pp, htable_t *ht, uint_t entry);
/*
* Hat switch function invoked to load a new context into %cr3
*/
extern void hat_switch(struct hat *hat);
+#define pfn_is_foreign(pfn) __lintzero
#endif /* _KERNEL */
diff --git a/usr/src/uts/i86pc/vm/hat_kdi.c b/usr/src/uts/i86pc/vm/hat_kdi.c
index acdc2ddbb9..3273bd746c 100644
--- a/usr/src/uts/i86pc/vm/hat_kdi.c
+++ b/usr/src/uts/i86pc/vm/hat_kdi.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -43,39 +42,26 @@
#include <sys/cmn_err.h>
#include <vm/seg_kmem.h>
#include <vm/hat_i86.h>
+#include <sys/bootinfo.h>
+#include <vm/kboot_mmu.h>
#include <sys/machsystm.h>
/*
* The debugger needs direct access to the PTE of one page table entry
* in order to implement vtop and physical read/writes
*/
-extern uintptr_t ptable_va;
static uintptr_t hat_kdi_page = 0; /* vaddr for phsical page accesses */
static x86pte_t *hat_kdi_pte = NULL; /* vaddr of pte for hat_kdi_page */
+static uint_t use_kbm = 1;
uint_t hat_kdi_use_pae; /* if 0, use x86pte32_t for pte type */
/*
- * Allocate virtual page to use for kernel debugger accesses to physical memory.
- * This is done very early in boot - before vmem allocator is available, so
- * we use a special hand picked address. (blech) The address is one page
- * above where the hat will put pages for pagetables -- see ptable_alloc() --
- * and is outside of the kernel's address space.
- *
- * We'll pick a new VA after the kernel's hat has been initialized.
+ * Get the address for remapping physical pages during boot
*/
void
hat_boot_kdi_init(void)
{
-
- /*
- * The 1st ptable_va page is for the HAT, we use the 2nd.
- */
- hat_kdi_page = ptable_va + MMU_PAGESIZE;
-#if defined(__amd64)
- hat_kdi_use_pae = 1;
-#elif defined(__i386)
- hat_kdi_use_pae = 0;
-#endif
+ hat_kdi_page = (uintptr_t)kbm_push(0); /* first call gets address... */
}
/*
@@ -86,6 +72,7 @@ hat_boot_kdi_init(void)
void
hat_kdi_init(void)
{
+ /*LINTED:set but not used in function*/
htable_t *ht;
/*
@@ -95,6 +82,7 @@ hat_kdi_init(void)
hat_kdi_use_pae = mmu.pae_hat;
hat_kdi_page = (uintptr_t)vmem_alloc(heap_arena, PAGESIZE, VM_SLEEP);
ht = htable_create(kas.a_hat, hat_kdi_page, 0, NULL);
+ use_kbm = 0;
/*
* Get an address at which to put the pagetable and devload it.
@@ -104,12 +92,14 @@ hat_kdi_init(void)
hat_devload(kas.a_hat, (caddr_t)hat_kdi_pte, MMU_PAGESIZE, ht->ht_pfn,
PROT_READ | PROT_WRITE | HAT_NOSYNC | HAT_UNORDERED_OK,
HAT_LOAD | HAT_LOAD_NOCONSIST);
- hat_kdi_pte = (x86pte_t *)((uintptr_t)hat_kdi_pte +
- (htable_va2entry(hat_kdi_page, ht) << mmu.pte_size_shift));
+ hat_kdi_pte =
+ PT_INDEX_PTR(hat_kdi_pte, htable_va2entry(hat_kdi_page, ht));
HTABLE_INC(ht->ht_valid_cnt);
htable_release(ht);
}
+#define kdi_mtop(m) (m)
+#define kdi_ptom(p) (p)
/*ARGSUSED*/
int
@@ -128,13 +118,13 @@ kdi_vtop(uintptr_t va, uint64_t *pap)
* the boot loader's pagetables.
*/
if (!khat_running) {
- if (hat_boot_probe(&vaddr, &len, &pfn, &prot) == 0)
+ if (kbm_probe(&vaddr, &len, &pfn, &prot) == 0)
return (ENOENT);
if (vaddr > va)
return (ENOENT);
if (vaddr < va)
pfn += mmu_btop(va - vaddr);
- *pap = (uint64_t)mmu_ptob(pfn) + (vaddr & MMU_PAGEOFFSET);
+ *pap = pfn_to_pa(pfn) + (vaddr & MMU_PAGEOFFSET);
return (0);
}
@@ -153,10 +143,10 @@ kdi_vtop(uintptr_t va, uint64_t *pap)
return (ENOENT);
if (level > 0 && level <= mmu.max_page_level &&
(pte & PT_PAGESIZE)) {
- *pap = pte & PT_PADDR_LGPG;
+ *pap = kdi_mtop(pte & PT_PADDR_LGPG);
break;
} else {
- *pap = pte & PT_PADDR;
+ *pap = kdi_mtop(pte & PT_PADDR);
if (level == 0)
break;
}
@@ -189,7 +179,7 @@ kdi_prw(caddr_t buf, size_t nbytes, uint64_t pa, size_t *ncopiedp, int doread)
pgoff = pa & MMU_PAGEOFFSET;
sz = MIN(nbytes, MMU_PAGESIZE - pgoff);
va = (caddr_t)hat_kdi_page + pgoff;
- pte = MAKEPTE(btop(pa), 0);
+ pte = mmu_ptob(mmu_btop(pa)) | PT_VALID;
if (doread) {
from = va;
to = buf;
@@ -202,8 +192,8 @@ kdi_prw(caddr_t buf, size_t nbytes, uint64_t pa, size_t *ncopiedp, int doread)
/*
* map the physical page
*/
- if (hat_kdi_pte == NULL)
- (void) hat_boot_remap(hat_kdi_page, btop(pa));
+ if (use_kbm)
+ (void) kbm_push(pa);
else if (hat_kdi_use_pae)
*hat_kdi_pte = pte;
else
@@ -215,8 +205,8 @@ kdi_prw(caddr_t buf, size_t nbytes, uint64_t pa, size_t *ncopiedp, int doread)
/*
* erase the mapping
*/
- if (hat_kdi_pte == NULL)
- hat_boot_demap(hat_kdi_page);
+ if (use_kbm)
+ kbm_pop();
else if (hat_kdi_use_pae)
*hat_kdi_pte = 0;
else
@@ -257,7 +247,7 @@ kdi_pwrite(caddr_t buf, size_t nbytes, uint64_t addr, size_t *ncopiedp)
size_t
kdi_range_is_nontoxic(uintptr_t va, size_t sz, int write)
{
-#ifdef __amd64
+#if defined(__amd64)
extern uintptr_t toxic_addr;
extern size_t toxic_size;
@@ -277,7 +267,7 @@ kdi_range_is_nontoxic(uintptr_t va, size_t sz, int write)
return (sz);
-#else
+#elif defined(__i386)
extern void *device_arena_contains(void *, size_t, size_t *);
uintptr_t v;
@@ -289,10 +279,5 @@ kdi_range_is_nontoxic(uintptr_t va, size_t sz, int write)
else
return (v - va);
-#endif
-}
-
-void
-hat_kdi_fini(void)
-{
+#endif /* __i386 */
}
diff --git a/usr/src/uts/i86pc/vm/hat_pte.h b/usr/src/uts/i86pc/vm/hat_pte.h
index 6230d7c93c..9bd8c31c48 100644
--- a/usr/src/uts/i86pc/vm/hat_pte.h
+++ b/usr/src/uts/i86pc/vm/hat_pte.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,68 +32,8 @@
extern "C" {
#endif
-
#include <sys/types.h>
-
-/*
- * Defines for the bits in X86 and AMD64 Page Tables
- *
- * Notes:
- *
- * Largepages and PAT bits:
- *
- * bit 7 at level 0 is the PAT bit
- * bit 7 above level 0 is the Pagesize bit (set for large page)
- * bit 12 (when a large page) is the PAT bit
- *
- * In Solaris the PAT/PWT/PCD values are set up so that:
- *
- * PAT & PWT -> Write Protected
- * PAT & PCD -> Write Combining
- * PAT by itself (PWT == 0 && PCD == 0) yields uncacheable (same as PCD == 1)
- *
- *
- * Permission bits:
- *
- * - PT_USER must be set in all levels for user pages
- * - PT_WRITE must be set in all levels for user writable pages
- * - PT_NX applies if set at any level
- *
- * For these, we use the "allow" settings in all tables above level 0 and only
- * ever disable things in PTEs.
- *
- * The use of PT_GLOBAL and PT_NX depend on being enabled in processor
- * control registers. Hence, we use a variable to reference these bit
- * masks. During hat_kern_setup() if the feature isn't enabled we
- * clear out the variables.
- */
-#define PT_VALID (0x001) /* a valid translation is present */
-#define PT_WRITABLE (0x002) /* the page is writable */
-#define PT_USER (0x004) /* the page is accessible by user mode */
-#define PT_WRITETHRU (0x008) /* write back caching is disabled (non-PAT) */
-#define PT_NOCACHE (0x010) /* page is not cacheable (non-PAT) */
-#define PT_REF (0x020) /* page was referenced */
-#define PT_MOD (0x040) /* page was modified */
-#define PT_PAGESIZE (0x080) /* above level 0, indicates a large page */
-#define PT_PAT_4K (0x080) /* at level 0, used for write combining */
-#define PT_GLOBAL (0x100) /* the mapping is global */
-#define PT_SOFTWARE (0xe00) /* available for software */
-
-#define PT_PAT_LARGE (0x1000) /* PAT bit for large pages */
-
-#define PT_PTPBITS (PT_VALID | PT_USER | PT_WRITABLE | PT_REF)
-#define PT_FLAGBITS (0xfff) /* for masking off flag bits */
-
-/*
- * The software bits are used by the HAT to track attributes.
- *
- * PT_NOSYNC - The PT_REF/PT_MOD bits are not sync'd to page_t.
- * The hat will install them as always set.
- *
- * PT_NOCONSIST - There is no entry for this hment for this mapping.
- */
-#define PT_NOSYNC (0x200) /* PTE was created with HAT_NOSYNC */
-#define PT_NOCONSIST (0x400) /* PTE was created with HAT_LOAD_NOCONSIST */
+#include <sys/mach_mmu.h>
/*
* macros to get/set/clear the PTE fields
@@ -127,27 +66,21 @@ extern "C" {
/*
* Shorthand for converting a PTE to it's pfn.
*/
-#define PTE2PFN(p, l) \
+#define PTE2MFN(p, l) \
mmu_btop(PTE_GET((p), PTE_IS_LGPG((p), (l)) ? PT_PADDR_LGPG : PT_PADDR))
+#define PTE2PFN(p, l) PTE2MFN(p, l)
-/*
- * The software extraction for a single Page Table Entry will always
- * be a 64 bit unsigned int. If running a non-PAE hat, the page table
- * access routines know to extend/shorten it to 32 bits.
- */
-typedef uint64_t x86pte_t;
-typedef uint32_t x86pte32_t;
#define PT_NX (0x8000000000000000ull)
-#define PT_PADDR (0x00fffffffffff000ull)
-#define PT_PADDR_LGPG (0x00ffffffffffe000ull) /* phys addr for large pages */
+#define PT_PADDR (0x000ffffffffff000ull)
+#define PT_PADDR_LGPG (0x000fffffffffe000ull) /* phys addr for large pages */
/*
* Macros to create a PTP or PTE from the pfn and level
*/
#define MAKEPTP(pfn, l) \
- (((x86pte_t)(pfn) << MMU_PAGESHIFT) | mmu.ptp_bits[(l) + 1])
+ (pfn_to_pa(pfn) | mmu.ptp_bits[(l) + 1])
#define MAKEPTE(pfn, l) \
- (((x86pte_t)(pfn) << MMU_PAGESHIFT) | mmu.pte_bits[l])
+ (pfn_to_pa(pfn) | mmu.pte_bits[l])
/*
* The idea of "level" refers to the level where the page table is used in the
@@ -174,7 +107,7 @@ typedef uint32_t x86pte32_t;
*/
#define MAX_NUM_LEVEL 4
#define MAX_PAGE_LEVEL 1 /* for now.. sigh */
-typedef int16_t level_t;
+typedef int8_t level_t;
#define LEVEL_SHIFT(l) (mmu.level_shift[l])
#define LEVEL_SIZE(l) (mmu.level_size[l])
#define LEVEL_OFFSET(l) (mmu.level_offset[l])
@@ -192,7 +125,7 @@ typedef int16_t level_t;
/*
* The CR3 register holds the physical address of the top level page table.
*/
-#define MAKECR3(pfn) mmu_ptob(pfn)
+#define MAKECR3(pfn) mmu_ptob(pfn)
/*
* HAT/MMU parameters that depend on kernel mode and/or processor type
@@ -229,6 +162,14 @@ struct hat_mmu_info {
x86pte_t pte_bits[MAX_NUM_LEVEL]; /* bits set for leaf PTE */
/*
+ * A range of VA used to window pages in the i86pc/vm code.
+ * See PWIN_XXX macros.
+ */
+ caddr_t pwin_base;
+ caddr_t pwin_pte_va;
+ paddr_t pwin_pte_pa;
+
+ /*
* The following tables are equivalent to PAGEXXXXX at different levels
* in the page table hierarchy.
*/
@@ -236,12 +177,26 @@ struct hat_mmu_info {
uintptr_t level_size[MAX_NUM_LEVEL]; /* PAGESIZE for given level */
uintptr_t level_offset[MAX_NUM_LEVEL]; /* PAGEOFFSET for given level */
uintptr_t level_mask[MAX_NUM_LEVEL]; /* PAGEMASK for given level */
-
- uint_t tlb_entries[MAX_NUM_LEVEL]; /* tlb entries per pagesize */
};
#if defined(_KERNEL)
+
+/*
+ * Macros to access the HAT's private page windows. They're used for
+ * accessing pagetables, ppcopy() and page_zero().
+ * The 1st two macros are used to get an index for the particular use.
+ * The next three give you:
+ * - the virtual address of the window
+ * - the virtual address of the pte that maps the window
+ * - the physical address of the pte that map the window
+ */
+#define PWIN_TABLE(cpuid) ((cpuid) * 2)
+#define PWIN_SRC(cpuid) ((cpuid) * 2 + 1) /* for x86pte_copy() */
+#define PWIN_VA(x) (mmu.pwin_base + ((x) << MMU_PAGESHIFT))
+#define PWIN_PTE_VA(x) (mmu.pwin_pte_va + ((x) << mmu.pte_size_shift))
+#define PWIN_PTE_PA(x) (mmu.pwin_pte_pa + ((x) << mmu.pte_size_shift))
+
/*
* The concept of a VA hole exists in AMD64. This might need to be made
* model specific eventually.
@@ -256,23 +211,46 @@ struct hat_mmu_info {
#define IN_VA_HOLE(va) (mmu.hole_start <= (va) && (va) < mmu.hole_end)
#endif
-#define FMT_PTE "%lx"
-#define ATOMIC_LOAD64(ptr, pte) ((pte) = *(ptr))
+#define FMT_PTE "0x%lx"
+#define GET_PTE(ptr) (*(x86pte_t *)(ptr))
+#define SET_PTE(ptr, pte) (*(x86pte_t *)(ptr) = pte)
+#define CAS_PTE(ptr, x, y) cas64(ptr, x, y)
#elif defined(__i386)
-#ifdef lint
#define IN_VA_HOLE(va) (__lintzero)
-#else
-#define IN_VA_HOLE(va) (0)
-#endif
-#define FMT_PTE "%llx"
-#define ATOMIC_LOAD64(ptr, pte) (((pte) = *(ptr)), \
- ((pte) = cas64(ptr, pte, pte)))
+#define FMT_PTE "0x%llx"
+
+/* on 32 bit kernels, 64 bit loads aren't atomic, use get_pte64() */
+extern x86pte_t get_pte64(x86pte_t *ptr);
+#define GET_PTE(ptr) (mmu.pae_hat ? get_pte64(ptr) : *(x86pte32_t *)(ptr))
+#define SET_PTE(ptr, pte) \
+ ((mmu.pae_hat ? ((x86pte32_t *)(ptr))[1] = (pte >> 32) : 0), \
+ *(x86pte32_t *)(ptr) = pte)
+#define CAS_PTE(ptr, x, y) \
+ (mmu.pae_hat ? cas64(ptr, x, y) : \
+ cas32((uint32_t *)(ptr), (uint32_t)(x), (uint32_t)(y)))
#endif /* __i386 */
+/*
+ * Return a pointer to the pte entry at the given index within a page table.
+ */
+#define PT_INDEX_PTR(p, x) \
+ ((x86pte_t *)((uintptr_t)(p) + ((x) << mmu.pte_size_shift)))
+
+/*
+ * Return the physical address of the pte entry at the given index within a
+ * page table.
+ */
+#define PT_INDEX_PHYSADDR(p, x) \
+ ((paddr_t)(p) + ((x) << mmu.pte_size_shift))
+
+/*
+ * From pfn to bytes, careful not to lose bits on PAE.
+ */
+#define pfn_to_pa(pfn) (mmu_ptob((paddr_t)(pfn)))
extern struct hat_mmu_info mmu;
diff --git a/usr/src/uts/i86pc/vm/htable.c b/usr/src/uts/i86pc/vm/htable.c
index 3105ad9e27..bd1ac11630 100644
--- a/usr/src/uts/i86pc/vm/htable.c
+++ b/usr/src/uts/i86pc/vm/htable.c
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,6 +46,7 @@
#include <sys/promif.h>
#include <sys/var.h>
#include <sys/x86_archext.h>
+#include <sys/archsystm.h>
#include <sys/bootconf.h>
#include <sys/dumphdr.h>
#include <vm/seg_kmem.h>
@@ -53,8 +55,12 @@
#include <vm/hat_i86.h>
#include <sys/cmn_err.h>
+#include <sys/bootinfo.h>
+#include <vm/kboot_mmu.h>
+
+static void x86pte_zero(htable_t *dest, uint_t entry, uint_t count);
+
kmem_cache_t *htable_cache;
-extern cpuset_t khat_cpuset;
/*
* The variable htable_reserve_amount, rather than HTABLE_RESERVE_AMOUNT,
@@ -98,18 +104,12 @@ kmutex_t htable_mutex[NUM_HTABLE_MUTEX];
static void link_ptp(htable_t *higher, htable_t *new, uintptr_t vaddr);
static void unlink_ptp(htable_t *higher, htable_t *old, uintptr_t vaddr);
static void htable_free(htable_t *ht);
-static x86pte_t *x86pte_access_pagetable(htable_t *ht);
+static x86pte_t *x86pte_access_pagetable(htable_t *ht, uint_t index);
static void x86pte_release_pagetable(htable_t *ht);
static x86pte_t x86pte_cas(htable_t *ht, uint_t entry, x86pte_t old,
x86pte_t new);
/*
- * Address used for kernel page tables. See ptable_alloc() below.
- */
-uintptr_t ptable_va = 0;
-size_t ptable_sz = 2 * MMU_PAGESIZE;
-
-/*
* A counter to track if we are stealing or reaping htables. When non-zero
* htable_free() will directly free htables (either to the reserve or kmem)
* instead of putting them in a hat's htable cache.
@@ -124,142 +124,54 @@ static uint32_t active_ptables = 0;
/*
* Allocate a memory page for a hardware page table.
*
- * The pages allocated for page tables are currently gotten in a hacked up
- * way. It works for now, but really needs to be fixed up a bit.
- *
- * During boot: The boot loader controls physical memory allocation via
- * boot_alloc(). To avoid conflict with vmem, we just do boot_alloc()s with
- * addresses less than kernelbase. These addresses are ignored when we take
- * over mappings from the boot loader.
- *
- * Post-boot: we currently use page_create_va() on the kvp with fake offsets,
- * segments and virt address. This is pretty bogus, but was copied from the
- * old hat_i86.c code. A better approach would be to have a custom
- * page_get_physical() interface that can specify either mnode random or
- * mnode local and takes a page from whatever color has the MOST available -
- * this would have a minimal impact on page coloring.
- *
- * For now the htable pointer in ht is only used to compute a unique vnode
- * offset for the page.
+ * A wrapper around page_get_physical(), with some extra checks.
*/
-static void
-ptable_alloc(htable_t *ht)
+static pfn_t
+ptable_alloc(uintptr_t seed)
{
pfn_t pfn;
page_t *pp;
- u_offset_t offset;
- static struct seg tmpseg;
- static int first_time = 1;
- /*
- * Allocating the associated hardware page table is very different
- * before boot has finished. We get a physical page to from boot
- * w/o eating up any kernel address space.
- */
- ht->ht_pfn = PFN_INVALID;
+ pfn = PFN_INVALID;
atomic_add_32(&active_ptables, 1);
- if (use_boot_reserve) {
- ASSERT(ptable_va != 0);
-
- /*
- * Allocate, then demap the ptable_va, so that we're
- * sure there exist page table entries for the addresses
- */
- if (first_time) {
- first_time = 0;
- if ((uintptr_t)BOP_ALLOC(bootops, (caddr_t)ptable_va,
- ptable_sz, BO_NO_ALIGN) != ptable_va)
- panic("BOP_ALLOC failed");
-
- hat_boot_demap(ptable_va);
- hat_boot_demap(ptable_va + MMU_PAGESIZE);
- }
-
- pfn = ((uintptr_t)BOP_EALLOC(bootops, 0, MMU_PAGESIZE,
- BO_NO_ALIGN, BOPF_X86_ALLOC_PHYS)) >> MMU_PAGESHIFT;
- if (page_resv(1, KM_NOSLEEP) == 0)
- panic("page_resv() failed in ptable alloc");
-
- pp = page_numtopp_nolock(pfn);
- ASSERT(pp != NULL);
- if (pp->p_szc != 0)
- page_boot_demote(pp);
- pp = page_numtopp(pfn, SE_EXCL);
- ASSERT(pp != NULL);
-
- } else {
- /*
- * Post boot get a page for the table.
- *
- * The first check is to see if there is memory in
- * the system. If we drop to throttlefree, then fail
- * the ptable_alloc() and let the stealing code kick in.
- * Note that we have to do this test here, since the test in
- * page_create_throttle() would let the NOSLEEP allocation
- * go through and deplete the page reserves.
- *
- * The !NOMEMWAIT() lets pageout, fsflush, etc. skip this check.
- */
- if (!NOMEMWAIT() && freemem <= throttlefree + 1)
- return;
+ /*
+ * The first check is to see if there is memory in the system. If we
+ * drop to throttlefree, then fail the ptable_alloc() and let the
+ * stealing code kick in. Note that we have to do this test here,
+ * since the test in page_create_throttle() would let the NOSLEEP
+ * allocation go through and deplete the page reserves.
+ *
+ * The !NOMEMWAIT() lets pageout, fsflush, etc. skip this check.
+ */
+ if (!NOMEMWAIT() && freemem <= throttlefree + 1)
+ return (PFN_INVALID);
#ifdef DEBUG
- /*
- * This code makes htable_ steal() easier to test. By setting
- * force_steal we force pagetable allocations to fall
- * into the stealing code. Roughly 1 in ever "force_steal"
- * page table allocations will fail.
- */
- if (ht->ht_hat != kas.a_hat && force_steal > 1 &&
- ++ptable_cnt > force_steal) {
- ptable_cnt = 0;
- return;
- }
+ /*
+ * This code makes htable_steal() easier to test. By setting
+ * force_steal we force pagetable allocations to fall
+ * into the stealing code. Roughly 1 in ever "force_steal"
+ * page table allocations will fail.
+ */
+ if (proc_pageout != NULL && force_steal > 1 &&
+ ++ptable_cnt > force_steal) {
+ ptable_cnt = 0;
+ return (PFN_INVALID);
+ }
#endif /* DEBUG */
- /*
- * This code is temporary, so don't review too critically.
- * I'm awaiting a new phys page allocator from Kit -- Joe
- *
- * We need assign an offset for the page to call
- * page_create_va. To avoid conflicts with other pages,
- * we get creative with the offset.
- * for 32 bits, we pic an offset > 4Gig
- * for 64 bits, pic an offset somewhere in the VA hole.
- */
- offset = (uintptr_t)ht - kernelbase;
- offset <<= MMU_PAGESHIFT;
-#if defined(__amd64)
- offset += mmu.hole_start; /* something in VA hole */
-#else
- offset += 1ULL << 40; /* something > 4 Gig */
-#endif
-
- if (page_resv(1, KM_NOSLEEP) == 0)
- return;
-
-#ifdef DEBUG
- pp = page_exists(&kvp, offset);
- if (pp != NULL)
- panic("ptable already exists %p", pp);
-#endif
- pp = page_create_va(&kvp, offset, MMU_PAGESIZE,
- PG_EXCL | PG_NORELOC, &tmpseg,
- (void *)((uintptr_t)ht << MMU_PAGESHIFT));
- if (pp == NULL)
- return;
- page_io_unlock(pp);
- page_hashout(pp, NULL);
- pfn = pp->p_pagenum;
- }
+ pp = page_get_physical(seed);
+ if (pp == NULL)
+ return (PFN_INVALID);
+ pfn = pp->p_pagenum;
page_downgrade(pp);
ASSERT(PAGE_SHARED(pp));
if (pfn == PFN_INVALID)
panic("ptable_alloc(): Invalid PFN!!");
- ht->ht_pfn = pfn;
HATSTAT_INC(hs_ptable_allocs);
+ return (pfn);
}
/*
@@ -267,10 +179,9 @@ ptable_alloc(htable_t *ht)
* for ptable_alloc().
*/
static void
-ptable_free(htable_t *ht)
+ptable_free(pfn_t pfn)
{
- pfn_t pfn = ht->ht_pfn;
- page_t *pp;
+ page_t *pp = page_numtopp_nolock(pfn);
/*
* need to destroy the page used for the pagetable
@@ -278,7 +189,6 @@ ptable_free(htable_t *ht)
ASSERT(pfn != PFN_INVALID);
HATSTAT_INC(hs_ptable_frees);
atomic_add_32(&active_ptables, -1);
- pp = page_numtopp_nolock(pfn);
if (pp == NULL)
panic("ptable_free(): no page for pfn!");
ASSERT(PAGE_SHARED(pp));
@@ -299,7 +209,6 @@ ptable_free(htable_t *ht)
}
page_free(pp, 1);
page_unresv(1);
- ht->ht_pfn = PFN_INVALID;
}
/*
@@ -340,14 +249,12 @@ htable_get_reserve(void)
}
/*
- * Allocate initial htables with page tables and put them on the kernel hat's
- * cache list.
+ * Allocate initial htables and put them on the reserve list
*/
void
htable_initial_reserve(uint_t count)
{
htable_t *ht;
- hat_t *hat = kas.a_hat;
count += HTABLE_RESERVE_AMOUNT;
while (count > 0) {
@@ -355,51 +262,23 @@ htable_initial_reserve(uint_t count)
ASSERT(ht != NULL);
ASSERT(use_boot_reserve);
- ht->ht_hat = kas.a_hat; /* so htable_free() works */
- ht->ht_flags = 0; /* so x86pte_zero works */
- ptable_alloc(ht);
- if (ht->ht_pfn == PFN_INVALID)
- panic("ptable_alloc() failed");
-
- x86pte_zero(ht, 0, mmu.ptes_per_table);
-
- ht->ht_next = hat->hat_ht_cached;
- hat->hat_ht_cached = ht;
+ ht->ht_pfn = PFN_INVALID;
+ htable_put_reserve(ht);
--count;
}
}
/*
* Readjust the reserves after a thread finishes using them.
- *
- * The first time this is called post boot, we'll also clear out the
- * extra boot htables that were put in the kernel hat's cache list.
*/
void
htable_adjust_reserve()
{
- static int first_time = 1;
htable_t *ht;
ASSERT(curthread != hat_reserves_thread);
/*
- * The first time this is called after we can steal, we free up the
- * the kernel's cache htable list. It has lots of extra htable/page
- * tables that were allocated for boot up.
- */
- if (first_time) {
- first_time = 0;
- while ((ht = kas.a_hat->hat_ht_cached) != NULL) {
- kas.a_hat->hat_ht_cached = ht->ht_next;
- ASSERT(ht->ht_hat == kas.a_hat);
- ptable_free(ht);
- htable_put_reserve(ht);
- }
- return;
- }
-
- /*
* Free any excess htables in the reserve list
*/
while (htable_reserve_cnt > htable_reserve_amount) {
@@ -586,7 +465,7 @@ htable_steal(uint_t cnt)
* - unload and invalidate all PTEs
*/
for (e = 0, va = ht->ht_vaddr;
- e < ht->ht_num_ptes &&
+ e < HTABLE_NUM_PTES(ht) &&
ht->ht_valid_cnt > 0 &&
ht->ht_busy == 1 &&
ht->ht_lock_cnt == 0;
@@ -637,7 +516,7 @@ htable_steal(uint_t cnt)
/*
* Break to outer loop to release the
- * higher (ht_parent) pagtable. This
+ * higher (ht_parent) pagetable. This
* spreads out the pain caused by
* pagefaults.
*/
@@ -699,7 +578,7 @@ htable_reap(void *handle)
}
/*
- * allocate an htable, stealing one or using the reserve if necessary
+ * Allocate an htable, stealing one or using the reserve if necessary
*/
static htable_t *
htable_alloc(
@@ -723,8 +602,7 @@ htable_alloc(
/*
* First reuse a cached htable from the hat_ht_cached field, this
- * avoids unnecessary trips through kmem/page allocators. This is also
- * what happens during use_boot_reserve.
+ * avoids unnecessary trips through kmem/page allocators.
*/
if (hat->hat_ht_cached != NULL && !is_bare) {
hat_enter(hat);
@@ -739,15 +617,12 @@ htable_alloc(
}
if (ht == NULL) {
- ASSERT(!use_boot_reserve);
/*
* When allocating for hat_memload_arena, we use the reserve.
* Also use reserves if we are in a panic().
*/
- if (curthread == hat_reserves_thread || panicstr != NULL) {
- ASSERT(panicstr != NULL || !is_bare);
- ASSERT(panicstr != NULL ||
- curthread == hat_reserves_thread);
+ if (use_boot_reserve || curthread == hat_reserves_thread ||
+ panicstr != NULL) {
ht = htable_get_reserve();
} else {
/*
@@ -772,7 +647,7 @@ htable_alloc(
*/
if (ht != NULL && !is_bare) {
ht->ht_hat = hat;
- ptable_alloc(ht);
+ ht->ht_pfn = ptable_alloc((uintptr_t)ht);
if (ht->ht_pfn == PFN_INVALID) {
kmem_cache_free(htable_cache, ht);
ht = NULL;
@@ -796,8 +671,12 @@ htable_alloc(
/*
* If we stole for a bare htable, release the pagetable page.
*/
- if (ht != NULL && is_bare)
- ptable_free(ht);
+ if (ht != NULL) {
+ if (is_bare) {
+ ptable_free(ht->ht_pfn);
+ ht->ht_pfn = PFN_INVALID;
+ }
+ }
}
/*
@@ -833,13 +712,8 @@ htable_alloc(
*/
if (is_vlp) {
ht->ht_flags |= HTABLE_VLP;
- ht->ht_num_ptes = VLP_NUM_PTES;
ASSERT(ht->ht_pfn == PFN_INVALID);
need_to_zero = 0;
- } else if (level == mmu.max_level) {
- ht->ht_num_ptes = mmu.top_level_count;
- } else {
- ht->ht_num_ptes = mmu.ptes_per_table;
}
/*
@@ -858,6 +732,7 @@ htable_alloc(
*/
if (need_to_zero)
x86pte_zero(ht, 0, mmu.ptes_per_table);
+
return (ht);
}
@@ -890,14 +765,14 @@ htable_free(htable_t *ht)
/*
* If we have a hardware page table, free it.
- * We don't free page tables that are accessed by sharing someone else.
+ * We don't free page tables that are accessed by sharing.
*/
if (ht->ht_flags & HTABLE_SHARED_PFN) {
ASSERT(ht->ht_pfn != PFN_INVALID);
- ht->ht_pfn = PFN_INVALID;
} else if (!(ht->ht_flags & HTABLE_VLP)) {
- ptable_free(ht);
+ ptable_free(ht->ht_pfn);
}
+ ht->ht_pfn = PFN_INVALID;
/*
* If we are the thread using the reserves, put free htables
@@ -1015,12 +890,9 @@ link_ptp(htable_t *higher, htable_t *new, uintptr_t vaddr)
}
/*
- * Release of an htable.
- *
- * During process exit, some empty page tables are not unlinked - hat_free_end()
- * cleans them up. Upper level pagetable (mmu.max_page_level and higher) are
- * only released during hat_free_end() or by htable_steal(). We always
- * release SHARED page tables.
+ * Release of hold on an htable. If this is the last use and the pagetable
+ * is empty we may want to free it, then recursively look at the pagetable
+ * above it. The recursion is handled by the outer while() loop.
*/
void
htable_release(htable_t *ht)
@@ -1074,8 +946,8 @@ htable_release(htable_t *ht)
}
/*
- * remember if we destroy an htable that shares its PFN
- * from elsewhere
+ * Remember if we destroy an htable that shares its PFN
+ * from elsewhere.
*/
if (ht->ht_flags & HTABLE_SHARED_PFN) {
ASSERT(ht->ht_level == 0);
@@ -1103,7 +975,7 @@ htable_release(htable_t *ht)
*/
if ((hat->hat_flags & HAT_VLP) &&
level == VLP_LEVEL - 1)
- hat_demap(hat, DEMAP_ALL_ADDR);
+ hat_tlb_inval(hat, DEMAP_ALL_ADDR);
/*
* remove this htable from its hash list
@@ -1303,7 +1175,7 @@ try_again:
if ((hat->hat_flags & HAT_VLP) &&
#endif /* __i386 */
l == VLP_LEVEL - 1)
- hat_demap(hat, DEMAP_ALL_ADDR);
+ hat_tlb_inval(hat, DEMAP_ALL_ADDR);
}
ht->ht_next = hat->hat_ht_hash[h];
ASSERT(ht->ht_prev == NULL);
@@ -1336,6 +1208,96 @@ try_again:
}
/*
+ * Inherit initial pagetables from the boot program.
+ */
+void
+htable_attach(
+ hat_t *hat,
+ uintptr_t base,
+ level_t level,
+ htable_t *parent,
+ pfn_t pfn)
+{
+ htable_t *ht;
+ uint_t h;
+ uint_t i;
+ x86pte_t pte;
+ x86pte_t *ptep;
+ page_t *pp;
+ extern page_t *boot_claim_page(pfn_t);
+
+ ht = htable_get_reserve();
+ if (level == mmu.max_level)
+ kas.a_hat->hat_htable = ht;
+ ht->ht_hat = hat;
+ ht->ht_parent = parent;
+ ht->ht_vaddr = base;
+ ht->ht_level = level;
+ ht->ht_busy = 1;
+ ht->ht_next = NULL;
+ ht->ht_prev = NULL;
+ ht->ht_flags = 0;
+ ht->ht_pfn = pfn;
+ ht->ht_lock_cnt = 0;
+ ht->ht_valid_cnt = 0;
+ if (parent != NULL)
+ ++parent->ht_busy;
+
+ h = HTABLE_HASH(hat, base, level);
+ HTABLE_ENTER(h);
+ ht->ht_next = hat->hat_ht_hash[h];
+ ASSERT(ht->ht_prev == NULL);
+ if (hat->hat_ht_hash[h])
+ hat->hat_ht_hash[h]->ht_prev = ht;
+ hat->hat_ht_hash[h] = ht;
+ HTABLE_EXIT(h);
+
+ /*
+ * make sure the page table physical page is not FREE
+ */
+ if (page_resv(1, KM_NOSLEEP) == 0)
+ panic("page_resv() failed in ptable alloc");
+
+ pp = boot_claim_page(pfn);
+ ASSERT(pp != NULL);
+ page_downgrade(pp);
+ /*
+ * Record in the page_t that is a pagetable for segkpm setup.
+ */
+ if (kpm_vbase)
+ pp->p_index = 1;
+
+ /*
+ * Count valid mappings and recursively attach lower level pagetables.
+ */
+ ptep = kbm_remap_window(pfn_to_pa(pfn), 0);
+ for (i = 0; i < HTABLE_NUM_PTES(ht); ++i) {
+ if (mmu.pae_hat)
+ pte = ptep[i];
+ else
+ pte = ((x86pte32_t *)ptep)[i];
+ if (!IN_HYPERVISOR_VA(base) && PTE_ISVALID(pte)) {
+ ++ht->ht_valid_cnt;
+ if (!PTE_ISPAGE(pte, level)) {
+ htable_attach(hat, base, level - 1,
+ ht, PTE2PFN(pte, level));
+ ptep = kbm_remap_window(pfn_to_pa(pfn), 0);
+ }
+ }
+ base += LEVEL_SIZE(level);
+ if (base == mmu.hole_start)
+ base = (mmu.hole_end + MMU_PAGEOFFSET) & MMU_PAGEMASK;
+ }
+
+ /*
+ * As long as all the mappings we had were below kernel base
+ * we can release the htable.
+ */
+ if (base < kernelbase)
+ htable_release(ht);
+}
+
+/*
* Walk through a given htable looking for the first valid entry. This
* routine takes both a starting and ending address. The starting address
* is required to be within the htable provided by the caller, but there is
@@ -1355,8 +1317,8 @@ htable_scan(htable_t *ht, uintptr_t *vap, uintptr_t eaddr)
{
uint_t e;
x86pte_t found_pte = (x86pte_t)0;
- char *pte_ptr;
- char *end_pte_ptr;
+ caddr_t pte_ptr;
+ caddr_t end_pte_ptr;
int l = ht->ht_level;
uintptr_t va = *vap & LEVEL_MASK(l);
size_t pgsize = LEVEL_SIZE(l);
@@ -1373,9 +1335,9 @@ htable_scan(htable_t *ht, uintptr_t *vap, uintptr_t eaddr)
* The following page table scan code knows that the valid
* bit of a PTE is in the lowest byte AND that x86 is little endian!!
*/
- pte_ptr = (char *)x86pte_access_pagetable(ht);
- end_pte_ptr = pte_ptr + (ht->ht_num_ptes << mmu.pte_size_shift);
- pte_ptr += e << mmu.pte_size_shift;
+ pte_ptr = (caddr_t)x86pte_access_pagetable(ht, 0);
+ end_pte_ptr = (caddr_t)PT_INDEX_PTR(pte_ptr, HTABLE_NUM_PTES(ht));
+ pte_ptr = (caddr_t)PT_INDEX_PTR((x86pte_t *)pte_ptr, e);
while (!PTE_ISVALID(*pte_ptr)) {
va += pgsize;
if (va >= eaddr)
@@ -1389,13 +1351,8 @@ htable_scan(htable_t *ht, uintptr_t *vap, uintptr_t eaddr)
/*
* if we found a valid PTE, load the entire PTE
*/
- if (va < eaddr && pte_ptr != end_pte_ptr) {
- if (mmu.pae_hat) {
- ATOMIC_LOAD64((x86pte_t *)pte_ptr, found_pte);
- } else {
- found_pte = *(x86pte32_t *)pte_ptr;
- }
- }
+ if (va < eaddr && pte_ptr != end_pte_ptr)
+ found_pte = GET_PTE((x86pte_t *)pte_ptr);
x86pte_release_pagetable(ht);
#if defined(__amd64)
@@ -1611,7 +1568,7 @@ htable_va2entry(uintptr_t va, htable_t *ht)
ASSERT(va >= ht->ht_vaddr);
ASSERT(va <= HTABLE_LAST_PAGE(ht));
- return ((va >> LEVEL_SHIFT(l)) & (ht->ht_num_ptes - 1));
+ return ((va >> LEVEL_SHIFT(l)) & (HTABLE_NUM_PTES(ht) - 1));
}
/*
@@ -1624,7 +1581,7 @@ htable_e2va(htable_t *ht, uint_t entry)
level_t l = ht->ht_level;
uintptr_t va;
- ASSERT(entry < ht->ht_num_ptes);
+ ASSERT(entry < HTABLE_NUM_PTES(ht));
va = ht->ht_vaddr + ((uintptr_t)entry << LEVEL_SHIFT(l));
/*
@@ -1641,7 +1598,6 @@ htable_e2va(htable_t *ht, uint_t entry)
/*
* The code uses compare and swap instructions to read/write PTE's to
* avoid atomicity problems, since PTEs can be 8 bytes on 32 bit systems.
- * Again this can be optimized on 64 bit systems, since aligned load/store
* will naturally be atomic.
*
* The combination of using kpreempt_disable()/_enable() and the hci_mutex
@@ -1649,69 +1605,44 @@ htable_e2va(htable_t *ht, uint_t entry)
* while it's in use. If an interrupt thread tries to access a PTE, it will
* yield briefly back to the pinned thread which holds the cpu's hci_mutex.
*/
-
-static struct hat_cpu_info init_hci; /* used for cpu 0 */
-
-/*
- * Initialize a CPU private window for mapping page tables.
- * There will be 3 total pages of addressing needed:
- *
- * 1 for r/w access to pagetables
- * 1 for r access when copying pagetables (hat_alloc)
- * 1 that will map the PTEs for the 1st 2, so we can access them quickly
- *
- * We use vmem_xalloc() to get a correct alignment so that only one
- * hat_mempte_setup() is needed.
- */
void
-x86pte_cpu_init(cpu_t *cpu, void *pages)
+x86pte_cpu_init(cpu_t *cpu)
{
struct hat_cpu_info *hci;
- caddr_t va;
- /*
- * We can't use kmem_alloc/vmem_alloc for the 1st CPU, as this is
- * called before we've activated our own HAT
- */
- if (pages != NULL) {
- hci = &init_hci;
- va = pages;
- } else {
- hci = kmem_alloc(sizeof (struct hat_cpu_info), KM_SLEEP);
- va = vmem_xalloc(heap_arena, 3 * MMU_PAGESIZE, MMU_PAGESIZE, 0,
- LEVEL_SIZE(1), NULL, NULL, VM_SLEEP);
- }
+ hci = kmem_zalloc(sizeof (*hci), KM_SLEEP);
mutex_init(&hci->hci_mutex, NULL, MUTEX_DEFAULT, NULL);
+ cpu->cpu_hat_info = hci;
+}
- /*
- * If we are using segkpm, then there is no need for any of the
- * mempte support. We can access the desired memory through a kpm
- * mapping rather than setting up a temporary mempte mapping.
- */
- if (kpm_enable == 0) {
- hci->hci_mapped_pfn = PFN_INVALID;
-
- hci->hci_kernel_pte =
- hat_mempte_kern_setup(va, va + (2 * MMU_PAGESIZE));
- hci->hci_pagetable_va = (void *)va;
- }
+void
+x86pte_cpu_fini(cpu_t *cpu)
+{
+ struct hat_cpu_info *hci = cpu->cpu_hat_info;
- cpu->cpu_hat_info = hci;
+ kmem_free(hci, sizeof (*hci));
+ cpu->cpu_hat_info = NULL;
}
+#ifdef __i386
/*
- * Macro to establish temporary mappings for x86pte_XXX routines.
+ * On 32 bit kernels, loading a 64 bit PTE is a little tricky
*/
-#define X86PTE_REMAP(addr, pte, index, perm, pfn) { \
- x86pte_t t; \
- \
- t = MAKEPTE((pfn), 0) | (perm) | mmu.pt_global | mmu.pt_nx;\
- if (mmu.pae_hat) \
- pte[index] = t; \
- else \
- ((x86pte32_t *)(pte))[index] = t; \
- mmu_tlbflush_entry((caddr_t)(addr)); \
+x86pte_t
+get_pte64(x86pte_t *ptr)
+{
+ volatile uint32_t *p = (uint32_t *)ptr;
+ x86pte_t t;
+
+ ASSERT(mmu.pae_hat != 0);
+ for (;;) {
+ t = p[0];
+ t |= (uint64_t)p[1] << 32;
+ if ((t & 0xffffffff) == p[0])
+ return (t);
+ }
}
+#endif /* __i386 */
/*
* Disable preemption and establish a mapping to the pagetable with the
@@ -1719,47 +1650,65 @@ x86pte_cpu_init(cpu_t *cpu, void *pages)
* pfn as we last used referenced from this CPU.
*/
static x86pte_t *
-x86pte_access_pagetable(htable_t *ht)
+x86pte_access_pagetable(htable_t *ht, uint_t index)
{
- pfn_t pfn;
- struct hat_cpu_info *hci;
-
/*
* VLP pagetables are contained in the hat_t
*/
if (ht->ht_flags & HTABLE_VLP)
- return (ht->ht_hat->hat_vlp_ptes);
+ return (PT_INDEX_PTR(ht->ht_hat->hat_vlp_ptes, index));
+ return (x86pte_mapin(ht->ht_pfn, index, ht));
+}
+
+/*
+ * map the given pfn into the page table window.
+ */
+/*ARGSUSED*/
+x86pte_t *
+x86pte_mapin(pfn_t pfn, uint_t index, htable_t *ht)
+{
+ x86pte_t *pteptr;
+ x86pte_t pte;
+ x86pte_t newpte;
+ int x;
- /*
- * During early boot, use hat_boot_remap() of a page table adddress.
- */
- pfn = ht->ht_pfn;
ASSERT(pfn != PFN_INVALID);
- if (kpm_enable)
- return ((x86pte_t *)hat_kpm_pfn2va(pfn));
if (!khat_running) {
- (void) hat_boot_remap(ptable_va, pfn);
- return ((x86pte_t *)ptable_va);
+ caddr_t va = kbm_remap_window(pfn_to_pa(pfn), 1);
+ return (PT_INDEX_PTR(va, index));
}
/*
- * Normally, disable preemption and grab the CPU's hci_mutex
+ * If kpm is available, use it.
+ */
+ if (kpm_vbase)
+ return (PT_INDEX_PTR(hat_kpm_pfn2va(pfn), index));
+
+ /*
+ * Disable preemption and grab the CPU's hci_mutex
*/
kpreempt_disable();
- hci = CPU->cpu_hat_info;
- ASSERT(hci != NULL);
- mutex_enter(&hci->hci_mutex);
- if (hci->hci_mapped_pfn != pfn) {
- /*
- * The current mapping doesn't already point to this page.
- * Update the CPU specific pagetable mapping to map the pfn.
- */
- X86PTE_REMAP(hci->hci_pagetable_va, hci->hci_kernel_pte, 0,
- PT_WRITABLE, pfn);
- hci->hci_mapped_pfn = pfn;
+ ASSERT(CPU->cpu_hat_info != NULL);
+ mutex_enter(&CPU->cpu_hat_info->hci_mutex);
+ x = PWIN_TABLE(CPU->cpu_id);
+ pteptr = (x86pte_t *)PWIN_PTE_VA(x);
+ if (mmu.pae_hat)
+ pte = *pteptr;
+ else
+ pte = *(x86pte32_t *)pteptr;
+
+ newpte = MAKEPTE(pfn, 0) | mmu.pt_global | mmu.pt_nx;
+ newpte |= PT_WRITABLE;
+
+ if (!PTE_EQUIV(newpte, pte)) {
+ if (mmu.pae_hat)
+ *pteptr = newpte;
+ else
+ *(x86pte32_t *)pteptr = newpte;
+ mmu_tlbflush_entry((caddr_t)(PWIN_VA(x)));
}
- return (hci->hci_pagetable_va);
+ return (PT_INDEX_PTR(PWIN_VA(x), index));
}
/*
@@ -1768,31 +1717,25 @@ x86pte_access_pagetable(htable_t *ht)
static void
x86pte_release_pagetable(htable_t *ht)
{
- struct hat_cpu_info *hci;
-
- if (kpm_enable)
- return;
-
/*
* nothing to do for VLP htables
*/
if (ht->ht_flags & HTABLE_VLP)
return;
- /*
- * During boot-up hat_kern_setup(), erase the boot loader remapping.
- */
- if (!khat_running) {
- hat_boot_demap(ptable_va);
+ x86pte_mapout();
+}
+
+void
+x86pte_mapout(void)
+{
+ if (mmu.pwin_base == NULL || !khat_running)
return;
- }
/*
- * Normal Operation: drop the CPU's hci_mutex and restore preemption
+ * Drop the CPU's hci_mutex and restore preemption.
*/
- hci = CPU->cpu_hat_info;
- ASSERT(hci != NULL);
- mutex_exit(&hci->hci_mutex);
+ mutex_exit(&CPU->cpu_hat_info->hci_mutex);
kpreempt_enable();
}
@@ -1803,362 +1746,267 @@ x86pte_t
x86pte_get(htable_t *ht, uint_t entry)
{
x86pte_t pte;
- x86pte32_t *pte32p;
x86pte_t *ptep;
/*
* Be careful that loading PAE entries in 32 bit kernel is atomic.
*/
- ptep = x86pte_access_pagetable(ht);
- if (mmu.pae_hat) {
- ATOMIC_LOAD64(ptep + entry, pte);
- } else {
- pte32p = (x86pte32_t *)ptep;
- pte = pte32p[entry];
- }
+ ASSERT(entry < mmu.ptes_per_table);
+ ptep = x86pte_access_pagetable(ht, entry);
+ pte = GET_PTE(ptep);
x86pte_release_pagetable(ht);
return (pte);
}
/*
* Atomic unconditional set of a page table entry, it returns the previous
- * value.
+ * value. For pre-existing mappings if the PFN changes, then we don't care
+ * about the old pte's REF / MOD bits. If the PFN remains the same, we leave
+ * the MOD/REF bits unchanged.
+ *
+ * If asked to overwrite a link to a lower page table with a large page
+ * mapping, this routine returns the special value of LPAGE_ERROR. This
+ * allows the upper HAT layers to retry with a smaller mapping size.
*/
x86pte_t
x86pte_set(htable_t *ht, uint_t entry, x86pte_t new, void *ptr)
{
x86pte_t old;
- x86pte_t prev, n;
+ x86pte_t prev;
x86pte_t *ptep;
- x86pte32_t *pte32p;
- x86pte32_t n32, p32;
+ level_t l = ht->ht_level;
+ x86pte_t pfn_mask = (l != 0) ? PT_PADDR_LGPG : PT_PADDR;
+ x86pte_t n;
+ uintptr_t addr = htable_e2va(ht, entry);
+ hat_t *hat = ht->ht_hat;
+ ASSERT(new != 0); /* don't use to invalidate a PTE, see x86pte_update */
ASSERT(!(ht->ht_flags & HTABLE_SHARED_PFN));
- if (ptr == NULL) {
- ptep = x86pte_access_pagetable(ht);
- ptep = (void *)((caddr_t)ptep + (entry << mmu.pte_size_shift));
- } else {
+ if (ptr == NULL)
+ ptep = x86pte_access_pagetable(ht, entry);
+ else
ptep = ptr;
- }
- if (mmu.pae_hat) {
- for (;;) {
- prev = *ptep;
- n = new;
- /*
- * prevent potential data loss by preserving the
- * MOD/REF bits if set in the current PTE, the pfns are
- * the same and the 'new' pte is non-zero. For example,
- * segmap can reissue a read-only hat_memload on top
- * of a dirty page.
- *
- * 'new' is required to be non-zero on a remap as at
- * least the valid bit should be non-zero. The 'new'
- * check also avoids incorrectly preserving the REF/MOD
- * bit when unmapping pfn 0.
- */
- if (new != 0 && PTE_ISVALID(prev) &&
- PTE2PFN(prev, ht->ht_level) ==
- PTE2PFN(n, ht->ht_level)) {
- n |= prev & (PT_REF | PT_MOD);
- }
- if (prev == n) {
- old = new;
- break;
- }
- old = cas64(ptep, prev, n);
- if (old == prev)
- break;
- }
- } else {
- pte32p = (x86pte32_t *)ptep;
- for (;;) {
- p32 = *pte32p;
- n32 = new;
- if (new != 0 && PTE_ISVALID(p32) &&
- PTE2PFN(p32, ht->ht_level) ==
- PTE2PFN(n32, ht->ht_level)) {
- n32 |= p32 & (PT_REF | PT_MOD);
- }
- if (p32 == n32) {
- old = new;
- break;
- }
- old = cas32(pte32p, p32, n32);
- if (old == p32)
- break;
+ /*
+ * Install the new PTE. If remapping the same PFN, then
+ * copy existing REF/MOD bits to new mapping.
+ */
+ do {
+ prev = GET_PTE(ptep);
+ n = new;
+ if (PTE_ISVALID(n) && (prev & pfn_mask) == (new & pfn_mask))
+ n |= prev & (PT_REF | PT_MOD);
+
+ /*
+ * Another thread may have installed this mapping already,
+ * flush the local TLB and be done.
+ */
+ if (prev == n) {
+ old = new;
+ mmu_tlbflush_entry((caddr_t)addr);
+ goto done;
}
- }
+
+ /*
+ * Detect if we have a collision of installing a large
+ * page mapping where there already is a lower page table.
+ */
+ if (l > 0 && (prev & PT_VALID) && !(prev & PT_PAGESIZE))
+ return (LPAGE_ERROR);
+
+ old = CAS_PTE(ptep, prev, n);
+ } while (old != prev);
+
+ /*
+ * Do a TLB demap if needed, ie. the old pte was valid.
+ *
+ * Note that a stale TLB writeback to the PTE here either can't happen
+ * or doesn't matter. The PFN can only change for NOSYNC|NOCONSIST
+ * mappings, but they were created with REF and MOD already set, so
+ * no stale writeback will happen.
+ *
+ * Segmap is the only place where remaps happen on the same pfn and for
+ * that we want to preserve the stale REF/MOD bits.
+ */
+ if (old & PT_REF)
+ hat_tlb_inval(hat, addr);
+
+done:
if (ptr == NULL)
x86pte_release_pagetable(ht);
return (old);
}
/*
- * Atomic compare and swap of a page table entry.
+ * Atomic compare and swap of a page table entry. No TLB invalidates are done.
+ * This is used for links between pagetables of different levels.
+ * Note we always create these links with dirty/access set, so they should
+ * never change.
*/
-static x86pte_t
+x86pte_t
x86pte_cas(htable_t *ht, uint_t entry, x86pte_t old, x86pte_t new)
{
x86pte_t pte;
x86pte_t *ptep;
- x86pte32_t pte32, o32, n32;
- x86pte32_t *pte32p;
- ASSERT(!(ht->ht_flags & HTABLE_SHARED_PFN));
- ptep = x86pte_access_pagetable(ht);
- if (mmu.pae_hat) {
- pte = cas64(&ptep[entry], old, new);
- } else {
- o32 = old;
- n32 = new;
- pte32p = (x86pte32_t *)ptep;
- pte32 = cas32(&pte32p[entry], o32, n32);
- pte = pte32;
- }
+ ptep = x86pte_access_pagetable(ht, entry);
+ pte = CAS_PTE(ptep, old, new);
x86pte_release_pagetable(ht);
-
return (pte);
}
/*
- * data structure for cross call information
+ * Make sure the zero we wrote to a page table entry sticks in memory
+ * after invalidating all TLB entries on all CPUs.
*/
-typedef struct xcall_info {
- x86pte_t xi_pte;
- x86pte_t xi_old;
- x86pte_t *xi_pteptr;
- pfn_t xi_pfn;
- processorid_t xi_cpuid;
- level_t xi_level;
- xc_func_t xi_func;
-} xcall_info_t;
-
-/*
- * Cross call service function to atomically invalidate a PTE and flush TLBs
- */
-/*ARGSUSED*/
-static int
-x86pte_inval_func(xc_arg_t a1, xc_arg_t a2, xc_arg_t a3)
+static x86pte_t
+handle_tlbs(x86pte_t oldpte, x86pte_t *ptep, htable_t *ht, uint_t entry)
{
- xcall_info_t *xi = (xcall_info_t *)a1;
- caddr_t addr = (caddr_t)a2;
-
- /*
- * Only the initiating cpu invalidates the page table entry.
- * It returns the previous PTE value to the caller.
- */
- if (CPU->cpu_id == xi->xi_cpuid) {
- x86pte_t *ptep = xi->xi_pteptr;
- pfn_t pfn = xi->xi_pfn;
- level_t level = xi->xi_level;
- x86pte_t old;
- x86pte_t prev;
- x86pte32_t *pte32p;
- x86pte32_t p32;
-
- if (mmu.pae_hat) {
- for (;;) {
- prev = *ptep;
- if (PTE2PFN(prev, level) != pfn)
- break;
- old = cas64(ptep, prev, 0);
- if (old == prev)
- break;
- }
- } else {
- pte32p = (x86pte32_t *)ptep;
- for (;;) {
- p32 = *pte32p;
- if (PTE2PFN(p32, level) != pfn)
- break;
- old = cas32(pte32p, p32, 0);
- if (old == p32)
- break;
- }
- prev = p32;
- }
- xi->xi_pte = prev;
- }
+ hat_t *hat = ht->ht_hat;
+ uintptr_t addr = htable_e2va(ht, entry);
+ x86pte_t found;
/*
- * For a normal address, we just flush one page mapping
- * Otherwise reload cr3 to effect a complete TLB flush.
- *
- * Note we don't reload VLP pte's -- this assume we never have a
- * large page size at VLP_LEVEL for VLP processes.
+ * Was the PTE ever used? If not there can't be any TLB entries.
*/
- if ((uintptr_t)addr != DEMAP_ALL_ADDR) {
- mmu_tlbflush_entry(addr);
- } else {
- reload_cr3();
- }
- return (0);
-}
-
-/*
- * Cross call service function to atomically change a PTE and flush TLBs
- */
-/*ARGSUSED*/
-static int
-x86pte_update_func(xc_arg_t a1, xc_arg_t a2, xc_arg_t a3)
-{
- xcall_info_t *xi = (xcall_info_t *)a1;
- caddr_t addr = (caddr_t)a2;
+ if ((oldpte & PT_REF) == 0)
+ return (oldpte);
/*
- * Only the initiating cpu changes the page table entry.
- * It returns the previous PTE value to the caller.
+ * Do a full global TLB invalidation.
+ * We may have to loop until the new PTE in memory stays zero.
+ * Why? Because Intel/AMD don't document how the REF/MOD bits are
+ * copied back from the TLB to the PTE, sigh. We're protecting
+ * here against a blind write back of the MOD (and other) bits.
*/
- if (CPU->cpu_id == xi->xi_cpuid) {
- x86pte_t *ptep = xi->xi_pteptr;
- x86pte_t new = xi->xi_pte;
- x86pte_t old = xi->xi_old;
- x86pte_t prev;
-
- if (mmu.pae_hat) {
- prev = cas64(ptep, old, new);
- } else {
- x86pte32_t o32 = old;
- x86pte32_t n32 = new;
- x86pte32_t *pte32p = (x86pte32_t *)ptep;
- prev = cas32(pte32p, o32, n32);
- }
+ for (;;) {
+ hat_tlb_inval(hat, addr);
- xi->xi_pte = prev;
- }
-
- /*
- * Flush the TLB entry
- */
- if ((uintptr_t)addr != DEMAP_ALL_ADDR)
- mmu_tlbflush_entry(addr);
- else
- reload_cr3();
- return (0);
-}
+ /*
+ * Check for a stale writeback of a oldpte TLB entry.
+ * Done when the PTE stays zero.
+ */
+ found = GET_PTE(ptep);
+ if (found == 0)
+ return (oldpte);
-/*
- * Use cross calls to change a page table entry and invalidate TLBs.
- */
-void
-x86pte_xcall(hat_t *hat, xcall_info_t *xi, uintptr_t addr)
-{
- cpuset_t cpus;
+ /*
+ * The only acceptable PTE change must be from a TLB
+ * flush setting the MOD bit in, hence oldpte must
+ * have been writable.
+ */
+ if (!(oldpte & PT_WRITABLE) || !(found & PT_MOD))
+ break;
- /*
- * Given the current implementation of hat_share(), doing a
- * hat_pageunload() on a shared page table requries invalidating
- * all user TLB entries on all CPUs.
- */
- if (hat->hat_flags & HAT_SHARED) {
- hat = kas.a_hat;
- addr = DEMAP_ALL_ADDR;
- }
+ /*
+ * Did we see a complete writeback of oldpte?
+ * or
+ * Did we see the MOD bit set (plus possibly other
+ * bits rewritten) in a still invalid mapping?
+ */
+ if (found == (oldpte | PT_MOD) ||
+ (!(found & PT_VALID) &&
+ (oldpte | found) == (oldpte | PT_MOD)))
+ oldpte |= PT_MOD;
+ else
+ break;
- /*
- * Use a cross call to do the invalidations.
- * Note the current CPU always has to be in the cross call CPU set.
- */
- kpreempt_disable();
- xi->xi_cpuid = CPU->cpu_id;
- CPUSET_ZERO(cpus);
- if (hat == kas.a_hat) {
- CPUSET_OR(cpus, khat_cpuset);
- } else {
- mutex_enter(&hat->hat_switch_mutex);
- CPUSET_OR(cpus, hat->hat_cpus);
- CPUSET_ADD(cpus, CPU->cpu_id);
+ (void) CAS_PTE(ptep, found, 0);
}
/*
- * Use a cross call to modify the page table entry and invalidate TLBs.
- * If we're panic'ing, don't bother with the cross call.
- * Note the panicstr check isn't bullet proof and the panic system
- * ought to be made tighter.
+ * If we hit this, a processor attempted to set the DIRTY bit
+ * of a page table entry happened in a way we didn't anticipate
*/
- if (panicstr == NULL)
- xc_wait_sync((xc_arg_t)xi, addr, NULL, X_CALL_HIPRI,
- cpus, xi->xi_func);
- else
- (void) xi->xi_func((xc_arg_t)xi, (xc_arg_t)addr, NULL);
- if (hat != kas.a_hat)
- mutex_exit(&hat->hat_switch_mutex);
- kpreempt_enable();
+ panic("handle_tlbs(): unanticipated TLB shootdown scenario"
+ " oldpte=" FMT_PTE " found=" FMT_PTE, oldpte, found);
+ /*LINTED*/
}
/*
- * Invalidate a page table entry if it currently maps the given pfn.
- * This returns the previous value of the PTE.
+ * Invalidate a page table entry as long as it currently maps something that
+ * matches the value determined by expect.
+ *
+ * Also invalidates any TLB entries and returns the previous value of the PTE.
*/
x86pte_t
-x86pte_invalidate_pfn(htable_t *ht, uint_t entry, pfn_t pfn, void *pte_ptr)
+x86pte_inval(
+ htable_t *ht,
+ uint_t entry,
+ x86pte_t expect,
+ x86pte_t *pte_ptr)
{
- xcall_info_t xi;
x86pte_t *ptep;
- hat_t *hat;
- uintptr_t addr;
+ x86pte_t oldpte;
+ x86pte_t found;
ASSERT(!(ht->ht_flags & HTABLE_SHARED_PFN));
- if (pte_ptr != NULL) {
+ ASSERT(ht->ht_level != VLP_LEVEL);
+ if (pte_ptr != NULL)
ptep = pte_ptr;
- } else {
- ptep = x86pte_access_pagetable(ht);
- ptep = (void *)((caddr_t)ptep + (entry << mmu.pte_size_shift));
- }
+ else
+ ptep = x86pte_access_pagetable(ht, entry);
/*
- * Fill in the structure used by the cross call function to do the
- * invalidation.
+ * This loop deals with REF/MOD bits changing between the
+ * GET_PTE() and the CAS_PTE().
*/
- xi.xi_pte = 0;
- xi.xi_pteptr = ptep;
- xi.xi_pfn = pfn;
- xi.xi_level = ht->ht_level;
- xi.xi_func = x86pte_inval_func;
- ASSERT(xi.xi_level != VLP_LEVEL);
-
- hat = ht->ht_hat;
- addr = htable_e2va(ht, entry);
-
- x86pte_xcall(hat, &xi, addr);
-
+ do {
+ oldpte = GET_PTE(ptep);
+ if (expect != 0 && (oldpte & PT_PADDR) != (expect & PT_PADDR))
+ goto give_up;
+ found = CAS_PTE(ptep, oldpte, 0);
+ } while (found != oldpte);
+ oldpte = handle_tlbs(oldpte, ptep, ht, entry);
+
+give_up:
if (pte_ptr == NULL)
x86pte_release_pagetable(ht);
- return (xi.xi_pte);
+ return (oldpte);
}
/*
- * update a PTE and invalidate any stale TLB entries.
+ * Change a page table entry af it currently matches the value in expect.
*/
x86pte_t
-x86pte_update(htable_t *ht, uint_t entry, x86pte_t expected, x86pte_t new)
+x86pte_update(
+ htable_t *ht,
+ uint_t entry,
+ x86pte_t expect,
+ x86pte_t new)
{
- xcall_info_t xi;
x86pte_t *ptep;
- hat_t *hat;
- uintptr_t addr;
+ x86pte_t found;
+ ASSERT(new != 0);
ASSERT(!(ht->ht_flags & HTABLE_SHARED_PFN));
- ptep = x86pte_access_pagetable(ht);
- ptep = (void *)((caddr_t)ptep + (entry << mmu.pte_size_shift));
-
- /*
- * Fill in the structure used by the cross call function to do the
- * invalidation.
- */
- xi.xi_pte = new;
- xi.xi_old = expected;
- xi.xi_pteptr = ptep;
- xi.xi_func = x86pte_update_func;
-
- hat = ht->ht_hat;
- addr = htable_e2va(ht, entry);
+ ASSERT(ht->ht_level != VLP_LEVEL);
- x86pte_xcall(hat, &xi, addr);
+ ptep = x86pte_access_pagetable(ht, entry);
+ found = CAS_PTE(ptep, expect, new);
+ if (found == expect) {
+ hat_tlb_inval(ht->ht_hat, htable_e2va(ht, entry));
+ /*
+ * When removing write permission *and* clearing the
+ * MOD bit, check if a write happened via a stale
+ * TLB entry before the TLB shootdown finished.
+ *
+ * If it did happen, simply re-enable write permission and
+ * act like the original CAS failed.
+ */
+ if ((expect & (PT_WRITABLE | PT_MOD)) == PT_WRITABLE &&
+ (new & (PT_WRITABLE | PT_MOD)) == 0 &&
+ (GET_PTE(ptep) & PT_MOD) != 0) {
+ do {
+ found = GET_PTE(ptep);
+ found =
+ CAS_PTE(ptep, found, found | PT_WRITABLE);
+ } while ((found & PT_WRITABLE) == 0);
+ }
+ }
x86pte_release_pagetable(ht);
- return (xi.xi_pte);
+ return (found);
}
/*
@@ -2169,10 +2017,11 @@ x86pte_update(htable_t *ht, uint_t entry, x86pte_t expected, x86pte_t new)
void
x86pte_copy(htable_t *src, htable_t *dest, uint_t entry, uint_t count)
{
- struct hat_cpu_info *hci;
caddr_t src_va;
caddr_t dst_va;
size_t size;
+ x86pte_t *pteptr;
+ x86pte_t pte;
ASSERT(khat_running);
ASSERT(!(dest->ht_flags & HTABLE_VLP));
@@ -2181,27 +2030,31 @@ x86pte_copy(htable_t *src, htable_t *dest, uint_t entry, uint_t count)
ASSERT(!(dest->ht_flags & HTABLE_SHARED_PFN));
/*
- * Acquire access to the CPU pagetable window for the destination.
+ * Acquire access to the CPU pagetable windows for the dest and source.
*/
- dst_va = (caddr_t)x86pte_access_pagetable(dest);
- if (kpm_enable) {
- src_va = (caddr_t)x86pte_access_pagetable(src);
+ dst_va = (caddr_t)x86pte_access_pagetable(dest, entry);
+ if (kpm_vbase) {
+ src_va = (caddr_t)
+ PT_INDEX_PTR(hat_kpm_pfn2va(src->ht_pfn), entry);
} else {
- hci = CPU->cpu_hat_info;
+ uint_t x = PWIN_SRC(CPU->cpu_id);
/*
* Finish defining the src pagetable mapping
*/
- src_va = dst_va + MMU_PAGESIZE;
- X86PTE_REMAP(src_va, hci->hci_kernel_pte, 1, 0, src->ht_pfn);
+ src_va = (caddr_t)PT_INDEX_PTR(PWIN_VA(x), entry);
+ pte = MAKEPTE(src->ht_pfn, 0) | mmu.pt_global | mmu.pt_nx;
+ pteptr = (x86pte_t *)PWIN_PTE_VA(x);
+ if (mmu.pae_hat)
+ *pteptr = pte;
+ else
+ *(x86pte32_t *)pteptr = pte;
+ mmu_tlbflush_entry((caddr_t)(PWIN_VA(x)));
}
/*
* now do the copy
*/
-
- dst_va += entry << mmu.pte_size_shift;
- src_va += entry << mmu.pte_size_shift;
size = count << mmu.pte_size_shift;
bcopy(src_va, dst_va, size);
@@ -2211,42 +2064,29 @@ x86pte_copy(htable_t *src, htable_t *dest, uint_t entry, uint_t count)
/*
* Zero page table entries - Note this doesn't use atomic stores!
*/
-void
+static void
x86pte_zero(htable_t *dest, uint_t entry, uint_t count)
{
caddr_t dst_va;
- x86pte_t *p;
- x86pte32_t *p32;
size_t size;
- extern void hat_pte_zero(void *, size_t);
/*
* Map in the page table to be zeroed.
*/
ASSERT(!(dest->ht_flags & HTABLE_SHARED_PFN));
ASSERT(!(dest->ht_flags & HTABLE_VLP));
- dst_va = (caddr_t)x86pte_access_pagetable(dest);
- dst_va += entry << mmu.pte_size_shift;
+
+ dst_va = (caddr_t)x86pte_access_pagetable(dest, entry);
+
size = count << mmu.pte_size_shift;
- if (x86_feature & X86_SSE2) {
- hat_pte_zero(dst_va, size);
- } else if (khat_running) {
+ ASSERT(size > BLOCKZEROALIGN);
+#ifdef __i386
+ if ((x86_feature & X86_SSE2) == 0)
bzero(dst_va, size);
- } else {
- /*
- * Can't just use bzero during boot because it checks the
- * address against kernelbase. Instead just use a zero loop.
- */
- if (mmu.pae_hat) {
- p = (x86pte_t *)dst_va;
- while (count-- > 0)
- *p++ = 0;
- } else {
- p32 = (x86pte32_t *)dst_va;
- while (count-- > 0)
- *p32++ = 0;
- }
- }
+ else
+#endif
+ block_zero_no_xmm(dst_va, size);
+
x86pte_release_pagetable(dest);
}
diff --git a/usr/src/uts/i86pc/vm/htable.h b/usr/src/uts/i86pc/vm/htable.h
index 7f4e691c57..a3bcc81b29 100644
--- a/usr/src/uts/i86pc/vm/htable.h
+++ b/usr/src/uts/i86pc/vm/htable.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -69,10 +68,9 @@ struct htable {
struct htable *ht_next; /* forward link for hash table */
struct hat *ht_hat; /* hat this mapping comes from */
uintptr_t ht_vaddr; /* virt addr at start of this table */
- level_t ht_level; /* page table level: 0=4K, 1=2M, ... */
- uint16_t ht_flags; /* see below */
+ int8_t ht_level; /* page table level: 0=4K, 1=2M, ... */
+ uint8_t ht_flags; /* see below */
int16_t ht_busy; /* implements locking protocol */
- uint16_t ht_num_ptes; /* # of PTEs in page table */
int16_t ht_valid_cnt; /* # of valid entries in this table */
uint32_t ht_lock_cnt; /* # of locked entries in this table */
/* never used for kernel hat */
@@ -88,11 +86,11 @@ typedef struct htable htable_t;
*
* HTABLE_VLP - this is the top level htable of a VLP HAT.
*
- * HTABLE_SHARED_PFN - this htable had it's PFN assigned from sharing another
+ * HTABLE_SHARED_PFN - this htable had its PFN assigned from sharing another
* htable. Used by hat_share() for ISM.
*/
-#define HTABLE_VLP (0x0001)
-#define HTABLE_SHARED_PFN (0x0002)
+#define HTABLE_VLP (0x01)
+#define HTABLE_SHARED_PFN (0x02)
/*
* The htable hash table hashing function. The 28 is so that high
@@ -107,23 +105,9 @@ typedef struct htable htable_t;
((uintptr_t)(hat) >> 4)) & ((hat)->hat_num_hash - 1))
/*
- * For 32 bit, access to page table entries is done via the page table's PFN and
- * the index of the PTE. We use a CPU specific mapping (a la ppcopy) to map
- * in page tables on an "as needed" basis.
- *
- * 64 bit kernels will use seg_kpm style mappings and avoid any overhead.
- *
- * The code uses compare and swap instructions to read/write PTE's to
- * avoid atomicity problems, since PTEs can be 8 bytes on 32 bit systems.
- * Again this can be optimized on 64 bit systems, since aligned load/store
- * will naturally be atomic.
- *
* Each CPU gets a unique hat_cpu_info structure in cpu_hat_info.
*/
struct hat_cpu_info {
- pfn_t hci_mapped_pfn; /* pfn of currently mapped page table */
- x86pte_t *hci_pagetable_va; /* VA to use for mappings */
- x86pte_t *hci_kernel_pte; /* kernel PTE for cpu_pagetable_va */
kmutex_t hci_mutex; /* mutex to ensure sequential usage */
#if defined(__amd64)
pfn_t hci_vlp_pfn; /* pfn of hci_vlp_l3ptes */
@@ -141,12 +125,15 @@ struct hat_cpu_info {
*
* XX64 - The check for the VA hole needs to be better generalized.
*/
+#define HTABLE_NUM_PTES_PAE(ht) \
+ (((ht)->ht_flags & HTABLE_VLP) ? 4 : 512)
#if defined(__amd64)
+#define HTABLE_NUM_PTES(ht) HTABLE_NUM_PTES_PAE(ht)
#define HTABLE_LAST_PAGE(ht) \
((ht)->ht_level == mmu.max_level ? ((uintptr_t)0UL - MMU_PAGESIZE) :\
((ht)->ht_vaddr - MMU_PAGESIZE + \
- ((uintptr_t)((ht)->ht_num_ptes) << LEVEL_SHIFT((ht)->ht_level))))
+ ((uintptr_t)HTABLE_NUM_PTES(ht) << LEVEL_SHIFT((ht)->ht_level))))
#define NEXT_ENTRY_VA(va, l) \
((va & LEVEL_MASK(l)) + LEVEL_SIZE(l) == mmu.hole_start ? \
@@ -154,8 +141,10 @@ struct hat_cpu_info {
#elif defined(__i386)
+#define HTABLE_NUM_PTES(ht) (!mmu.pae_hat ? 1024 : HTABLE_NUM_PTES_PAE(ht))
+
#define HTABLE_LAST_PAGE(ht) ((ht)->ht_vaddr - MMU_PAGESIZE + \
- ((uintptr_t)((ht)->ht_num_ptes) << LEVEL_SHIFT((ht)->ht_level)))
+ ((uintptr_t)HTABLE_NUM_PTES(ht) << LEVEL_SHIFT((ht)->ht_level)))
#define NEXT_ENTRY_VA(va, l) ((va & LEVEL_MASK(l)) + LEVEL_SIZE(l))
@@ -188,6 +177,7 @@ extern htable_t *htable_create(struct hat *hat, uintptr_t vaddr, level_t level,
extern void htable_acquire(htable_t *);
extern void htable_release(htable_t *ht);
+extern void htable_destroy(htable_t *ht);
/*
* Code to free all remaining htables for a hat. Called after the hat is no
@@ -222,6 +212,17 @@ extern void htable_reserve(uint_t);
extern void htable_adjust_reserve(void);
/*
+ * Attach initial pagetables as htables
+ */
+extern void htable_attach(struct hat *, uintptr_t, level_t, struct htable *,
+ pfn_t);
+
+/*
+ * return the number of pages mapped by a hat
+ */
+extern pgcnt_t htable_count_pages(struct hat *);
+
+/*
* Routine to find the next populated htable at or above a given virtual
* address. Can specify an upper limit, or HTABLE_WALK_TO_END to indicate
* that it should search the entire address space. Similar to
@@ -259,14 +260,20 @@ extern uintptr_t htable_e2va(htable_t *ht, uint_t entry);
*
* Note that all accesses except x86pte_copy() and x86pte_zero() are atomic.
*/
-extern void x86pte_cpu_init(cpu_t *, void *);
+extern void x86pte_cpu_init(cpu_t *);
+extern void x86pte_cpu_fini(cpu_t *);
extern x86pte_t x86pte_get(htable_t *, uint_t entry);
+/*
+ * x86pte_set returns LPAGE_ERROR if it's asked to overwrite a page table
+ * link with a large page mapping.
+ */
+#define LPAGE_ERROR (-(x86pte_t)1)
extern x86pte_t x86pte_set(htable_t *, uint_t entry, x86pte_t new, void *);
-extern x86pte_t x86pte_invalidate_pfn(htable_t *ht, uint_t entry, pfn_t pfn,
- void *pte_ptr);
+extern x86pte_t x86pte_inval(htable_t *ht, uint_t entry,
+ x86pte_t old, x86pte_t *ptr);
extern x86pte_t x86pte_update(htable_t *ht, uint_t entry,
x86pte_t old, x86pte_t new);
@@ -274,8 +281,11 @@ extern x86pte_t x86pte_update(htable_t *ht, uint_t entry,
extern void x86pte_copy(htable_t *src, htable_t *dest, uint_t entry,
uint_t cnt);
-extern void x86pte_zero(htable_t *ht, uint_t entry, uint_t cnt);
-
+/*
+ * access to a pagetable knowing only the pfn
+ */
+extern x86pte_t *x86pte_mapin(pfn_t, uint_t, htable_t *);
+extern void x86pte_mapout(void);
/*
* these are actually inlines for "lock; incw", "lock; decw", etc. instructions.
diff --git a/usr/src/uts/i86pc/vm/i86_mmu.c b/usr/src/uts/i86pc/vm/i86_mmu.c
new file mode 100644
index 0000000000..7bf91af9b5
--- /dev/null
+++ b/usr/src/uts/i86pc/vm/i86_mmu.c
@@ -0,0 +1,408 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/t_lock.h>
+#include <sys/memlist.h>
+#include <sys/cpuvar.h>
+#include <sys/vmem.h>
+#include <sys/mman.h>
+#include <sys/vm.h>
+#include <sys/kmem.h>
+#include <sys/cmn_err.h>
+#include <sys/debug.h>
+#include <sys/vm_machparam.h>
+#include <sys/tss.h>
+#include <sys/vnode.h>
+#include <vm/hat.h>
+#include <vm/anon.h>
+#include <vm/as.h>
+#include <vm/page.h>
+#include <vm/seg.h>
+#include <vm/seg_kmem.h>
+#include <vm/seg_map.h>
+#include <vm/hat_i86.h>
+#include <sys/promif.h>
+#include <sys/x86_archext.h>
+#include <sys/systm.h>
+#include <sys/archsystm.h>
+#include <sys/sunddi.h>
+#include <sys/ddidmareq.h>
+#include <sys/controlregs.h>
+#include <sys/reboot.h>
+#include <sys/kdi.h>
+#include <sys/bootconf.h>
+#include <sys/bootsvcs.h>
+#include <sys/bootinfo.h>
+#include <vm/kboot_mmu.h>
+
+caddr_t
+i86devmap(pfn_t pf, pgcnt_t pgcnt, uint_t prot)
+{
+ caddr_t addr;
+ caddr_t addr1;
+ page_t *pp;
+
+ addr1 = addr = vmem_alloc(heap_arena, mmu_ptob(pgcnt), VM_SLEEP);
+
+ for (; pgcnt != 0; addr += MMU_PAGESIZE, ++pf, --pgcnt) {
+ pp = page_numtopp_nolock(pf);
+ if (pp == NULL) {
+ hat_devload(kas.a_hat, addr, MMU_PAGESIZE, pf,
+ prot | HAT_NOSYNC, HAT_LOAD_LOCK);
+ } else {
+ hat_memload(kas.a_hat, addr, pp,
+ prot | HAT_NOSYNC, HAT_LOAD_LOCK);
+ }
+ }
+
+ return (addr1);
+}
+
+/*
+ * This routine is like page_numtopp, but accepts only free pages, which
+ * it allocates (unfrees) and returns with the exclusive lock held.
+ * It is used by machdep.c/dma_init() to find contiguous free pages.
+ *
+ * XXX this and some others should probably be in vm_machdep.c
+ */
+page_t *
+page_numtopp_alloc(pfn_t pfnum)
+{
+ page_t *pp;
+
+retry:
+ pp = page_numtopp_nolock(pfnum);
+ if (pp == NULL) {
+ return (NULL);
+ }
+
+ if (!page_trylock(pp, SE_EXCL)) {
+ return (NULL);
+ }
+
+ if (page_pptonum(pp) != pfnum) {
+ page_unlock(pp);
+ goto retry;
+ }
+
+ if (!PP_ISFREE(pp)) {
+ page_unlock(pp);
+ return (NULL);
+ }
+ if (pp->p_szc) {
+ page_demote_free_pages(pp);
+ page_unlock(pp);
+ goto retry;
+ }
+
+ /* If associated with a vnode, destroy mappings */
+
+ if (pp->p_vnode) {
+
+ page_destroy_free(pp);
+
+ if (!page_lock(pp, SE_EXCL, (kmutex_t *)NULL, P_NO_RECLAIM)) {
+ return (NULL);
+ }
+
+ if (page_pptonum(pp) != pfnum) {
+ page_unlock(pp);
+ goto retry;
+ }
+ }
+
+ if (!PP_ISFREE(pp) || !page_reclaim(pp, (kmutex_t *)NULL)) {
+ page_unlock(pp);
+ return (NULL);
+ }
+
+ return (pp);
+}
+
+/*
+ * Flag is not set early in boot. Once it is set we are no longer
+ * using boot's page tables.
+ */
+uint_t khat_running = 0;
+
+/*
+ * This procedure is callable only while the boot loader is in charge of the
+ * MMU. It assumes that PA == VA for page table pointers. It doesn't live in
+ * kboot_mmu.c since it's used from common code.
+ */
+pfn_t
+va_to_pfn(void *vaddr)
+{
+ uintptr_t des_va = ALIGN2PAGE(vaddr);
+ uintptr_t va = des_va;
+ size_t len;
+ uint_t prot;
+ pfn_t pfn;
+
+ if (khat_running)
+ panic("va_to_pfn(): called too late\n");
+
+ if (kbm_probe(&va, &len, &pfn, &prot) == 0)
+ return (PFN_INVALID);
+ if (va > des_va)
+ return (PFN_INVALID);
+ if (va < des_va)
+ pfn += mmu_btop(des_va - va);
+ return (pfn);
+}
+
+/*
+ * Initialize a special area in the kernel that always holds some PTEs for
+ * faster performance. This always holds segmap's PTEs.
+ * In the 32 bit kernel this maps the kernel heap too.
+ */
+void
+hat_kmap_init(uintptr_t base, size_t len)
+{
+ uintptr_t map_addr; /* base rounded down to large page size */
+ uintptr_t map_eaddr; /* base + len rounded up */
+ size_t map_len;
+ caddr_t ptes; /* mapping area in kernel for kmap ptes */
+ size_t window_size; /* size of mapping area for ptes */
+ ulong_t htable_cnt; /* # of page tables to cover map_len */
+ ulong_t i;
+ htable_t *ht;
+ uintptr_t va;
+
+ /*
+ * We have to map in an area that matches an entire page table.
+ */
+ map_addr = base & LEVEL_MASK(1);
+ map_eaddr = (base + len + LEVEL_SIZE(1) - 1) & LEVEL_MASK(1);
+ map_len = map_eaddr - map_addr;
+ window_size = mmu_btop(map_len) * mmu.pte_size;
+ window_size = (window_size + LEVEL_SIZE(1)) & LEVEL_MASK(1);
+ htable_cnt = map_len >> LEVEL_SHIFT(1);
+
+ /*
+ * allocate vmem for the kmap_ptes
+ */
+ ptes = vmem_xalloc(heap_arena, window_size, LEVEL_SIZE(1), 0,
+ 0, NULL, NULL, VM_SLEEP);
+ mmu.kmap_htables =
+ kmem_alloc(htable_cnt * sizeof (htable_t *), KM_SLEEP);
+
+ /*
+ * Map the page tables that cover kmap into the allocated range.
+ * Note we don't ever htable_release() the kmap page tables - they
+ * can't ever be stolen, freed, etc.
+ */
+ for (va = map_addr, i = 0; i < htable_cnt; va += LEVEL_SIZE(1), ++i) {
+ ht = htable_create(kas.a_hat, va, 0, NULL);
+ if (ht == NULL)
+ panic("hat_kmap_init: ht == NULL");
+ mmu.kmap_htables[i] = ht;
+
+ hat_devload(kas.a_hat, ptes + i * MMU_PAGESIZE,
+ MMU_PAGESIZE, ht->ht_pfn,
+ PROT_READ | PROT_WRITE | HAT_NOSYNC | HAT_UNORDERED_OK,
+ HAT_LOAD | HAT_LOAD_NOCONSIST);
+ }
+
+ /*
+ * set information in mmu to activate handling of kmap
+ */
+ mmu.kmap_addr = map_addr;
+ mmu.kmap_eaddr = map_eaddr;
+ mmu.kmap_ptes = (x86pte_t *)ptes;
+}
+
+extern caddr_t kpm_vbase;
+extern size_t kpm_size;
+
+/*
+ * Routine to pre-allocate data structures for hat_kern_setup(). It computes
+ * how many pagetables it needs by walking the boot loader's page tables.
+ */
+/*ARGSUSED*/
+void
+hat_kern_alloc(
+ caddr_t segmap_base,
+ size_t segmap_size,
+ caddr_t ekernelheap)
+{
+ uintptr_t last_va = (uintptr_t)-1; /* catch 1st time */
+ uintptr_t va = 0;
+ size_t size;
+ pfn_t pfn;
+ uint_t prot;
+ uint_t table_cnt = 1;
+ uint_t mapping_cnt;
+ level_t start_level;
+ level_t l;
+ struct memlist *pmem;
+ level_t lpagel = mmu.max_page_level;
+ uint64_t paddr;
+ int64_t psize;
+
+
+ if (kpm_size > 0) {
+ /*
+ * Create the kpm page tables.
+ */
+ for (pmem = phys_install; pmem; pmem = pmem->next) {
+ paddr = pmem->address;
+ psize = pmem->size;
+ while (psize >= MMU_PAGESIZE) {
+ if ((paddr & LEVEL_OFFSET(lpagel)) == 0 &&
+ psize > LEVEL_SIZE(lpagel))
+ l = lpagel;
+ else
+ l = 0;
+ kbm_map((uintptr_t)kpm_vbase + paddr, paddr,
+ l, 1);
+ paddr += LEVEL_SIZE(l);
+ psize -= LEVEL_SIZE(l);
+ }
+ }
+ } else {
+ /*
+ * Create the page windows and 1 page of VA in
+ * which we map the PTEs of those windows.
+ */
+ mmu.pwin_base = vmem_xalloc(heap_arena, 2 * NCPU * MMU_PAGESIZE,
+ LEVEL_SIZE(1), 0, 0, NULL, NULL, VM_SLEEP);
+ ASSERT(NCPU * 2 <= MMU_PAGESIZE / mmu.pte_size);
+ mmu.pwin_pte_va = vmem_xalloc(heap_arena, MMU_PAGESIZE,
+ MMU_PAGESIZE, 0, 0, NULL, NULL, VM_SLEEP);
+
+ /*
+ * Find/Create the page table window mappings.
+ */
+ paddr = 0;
+ (void) find_pte((uintptr_t)mmu.pwin_base, &paddr, 0, 0);
+ ASSERT(paddr != 0);
+ ASSERT((paddr & MMU_PAGEOFFSET) == 0);
+ mmu.pwin_pte_pa = paddr;
+ kbm_map((uintptr_t)mmu.pwin_pte_va, mmu.pwin_pte_pa, 0, 1);
+ }
+
+ /*
+ * Walk the boot loader's page tables and figure out
+ * how many tables and page mappings there will be.
+ */
+ while (kbm_probe(&va, &size, &pfn, &prot) != 0) {
+ /*
+ * At each level, if the last_va falls into a new htable,
+ * increment table_cnt. We can stop at the 1st level where
+ * they are in the same htable.
+ */
+ if (size == MMU_PAGESIZE)
+ start_level = 0;
+ else
+ start_level = 1;
+
+ for (l = start_level; l < mmu.max_level; ++l) {
+ if (va >> LEVEL_SHIFT(l + 1) ==
+ last_va >> LEVEL_SHIFT(l + 1))
+ break;
+ ++table_cnt;
+ }
+ last_va = va;
+ va = (va & LEVEL_MASK(1)) + LEVEL_SIZE(1);
+ }
+
+ /*
+ * Besides the boot loader mappings, we're going to fill in
+ * the entire top level page table for the kernel. Make sure there's
+ * enough reserve for that too.
+ */
+ table_cnt += mmu.top_level_count - ((kernelbase >>
+ LEVEL_SHIFT(mmu.max_level)) & (mmu.top_level_count - 1));
+
+#if defined(__i386)
+ /*
+ * The 32 bit PAE hat allocates tables one level below the top when
+ * kernelbase isn't 1 Gig aligned. We'll just be sloppy and allocate
+ * a bunch more to the reserve. Any unused will be returned later.
+ * Note we've already counted these mappings, just not the extra
+ * pagetables.
+ */
+ if (mmu.pae_hat != 0 && (kernelbase & LEVEL_OFFSET(mmu.max_level)) != 0)
+ table_cnt += mmu.ptes_per_table -
+ ((kernelbase & LEVEL_OFFSET(mmu.max_level)) >>
+ LEVEL_SHIFT(mmu.max_level - 1));
+#endif
+
+ /*
+ * Add 1/4 more into table_cnt for extra slop. The unused
+ * slop is freed back when we htable_adjust_reserve() later.
+ */
+ table_cnt += table_cnt >> 2;
+
+ /*
+ * We only need mapping entries (hments) for shared pages.
+ * This should be far, far fewer than the total possible,
+ * We'll allocate enough for 1/16 of all possible PTEs.
+ */
+ mapping_cnt = (table_cnt * mmu.ptes_per_table) >> 4;
+
+ /*
+ * Now create the initial htable/hment reserves
+ */
+ htable_initial_reserve(table_cnt);
+ hment_reserve(mapping_cnt);
+ x86pte_cpu_init(CPU);
+}
+
+
+/*
+ * This routine handles the work of creating the kernel's initial mappings
+ * by deciphering the mappings in the page tables created by the boot program.
+ *
+ * We maintain large page mappings, but only to a level 1 pagesize.
+ * The boot loader can only add new mappings once this function starts.
+ * In particular it can not change the pagesize used for any existing
+ * mappings or this code breaks!
+ */
+
+void
+hat_kern_setup(void)
+{
+ /*
+ * Attach htables to the existing pagetables
+ */
+ htable_attach(kas.a_hat, 0, mmu.max_level, NULL,
+ mmu_btop(getcr3()));
+
+#if defined(__i386)
+ CPU->cpu_tss->tss_cr3 = dftss0.tss_cr3 = getcr3();
+#endif /* __i386 */
+
+ /*
+ * The kernel HAT is now officially open for business.
+ */
+ khat_running = 1;
+
+ CPUSET_ATOMIC_ADD(kas.a_hat->hat_cpus, CPU->cpu_id);
+ CPU->cpu_current_hat = kas.a_hat;
+}
diff --git a/usr/src/uts/i86pc/vm/kboot_mmu.c b/usr/src/uts/i86pc/vm/kboot_mmu.c
new file mode 100644
index 0000000000..fdf7e85460
--- /dev/null
+++ b/usr/src/uts/i86pc/vm/kboot_mmu.c
@@ -0,0 +1,420 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/archsystm.h>
+#include <sys/debug.h>
+#include <sys/bootconf.h>
+#include <sys/bootsvcs.h>
+#include <sys/bootinfo.h>
+#include <sys/mman.h>
+#include <sys/cmn_err.h>
+#include <sys/param.h>
+#include <sys/machparam.h>
+#include <sys/machsystm.h>
+#include <sys/promif.h>
+#include <sys/kobj.h>
+#include <vm/kboot_mmu.h>
+#include <vm/hat_pte.h>
+#include <vm/hat_i86.h>
+#include <vm/seg_kmem.h>
+
+#if 0
+/*
+ * Joe's debug printing
+ */
+#define DBG(x) \
+ bop_printf(NULL, "boot_mmu.c: %s is %" PRIx64 "\n", #x, (uint64_t)(x));
+#else
+#define DBG(x) /* naught */
+#endif
+
+/*
+ * Page table and memory stuff.
+ */
+static caddr_t window;
+static caddr_t pte_to_window;
+
+/*
+ * this are needed by mmu_init()
+ */
+int kbm_nx_support = 0; /* NX bit in PTEs is in use */
+int kbm_pae_support = 0; /* PAE is 64 bit Page table entries */
+int kbm_pge_support = 0; /* PGE is Page table global bit enabled */
+int kbm_largepage_support = 0;
+uint_t kbm_nucleus_size = 0;
+
+#define BOOT_SHIFT(l) (shift_amt[l])
+#define BOOT_SZ(l) ((size_t)1 << BOOT_SHIFT(l))
+#define BOOT_OFFSET(l) (BOOT_SZ(l) - 1)
+#define BOOT_MASK(l) (~BOOT_OFFSET(l))
+
+/*
+ * Initialize memory management parameters for boot time page table management
+ */
+void
+kbm_init(struct xboot_info *bi)
+{
+ /*
+ * configure mmu information
+ */
+ kbm_nucleus_size = (uintptr_t)bi->bi_kseg_size;
+ kbm_largepage_support = bi->bi_use_largepage;
+ kbm_nx_support = bi->bi_use_nx;
+ kbm_pae_support = bi->bi_use_pae;
+ kbm_pge_support = bi->bi_use_pge;
+ window = bi->bi_pt_window;
+ DBG(window);
+ pte_to_window = bi->bi_pte_to_pt_window;
+ DBG(pte_to_window);
+ if (kbm_pae_support) {
+ shift_amt = shift_amt_pae;
+ ptes_per_table = 512;
+ pte_size = 8;
+ lpagesize = TWO_MEG;
+#ifdef __amd64
+ top_level = 3;
+#else
+ top_level = 2;
+#endif
+ } else {
+ shift_amt = shift_amt_nopae;
+ ptes_per_table = 1024;
+ pte_size = 4;
+ lpagesize = FOUR_MEG;
+ top_level = 1;
+ }
+
+ top_page_table = bi->bi_top_page_table;
+ DBG(top_page_table);
+}
+
+/*
+ * Change the addressible page table window to point at a given page
+ */
+/*ARGSUSED*/
+void *
+kbm_remap_window(paddr_t physaddr, int writeable)
+{
+ uint_t pt_bits = PT_NOCONSIST | PT_VALID | PT_WRITABLE;
+
+ DBG(physaddr);
+
+ if (kbm_pae_support)
+ *((x86pte_t *)pte_to_window) = physaddr | pt_bits;
+ else
+ *((x86pte32_t *)pte_to_window) = physaddr | pt_bits;
+ mmu_tlbflush_entry(window);
+ DBG(window);
+ return (window);
+}
+
+/*
+ * Add a mapping for the physical page at the given virtual address.
+ */
+void
+kbm_map(uintptr_t va, paddr_t pa, uint_t level, uint_t is_kernel)
+{
+ x86pte_t *ptep;
+ paddr_t pte_physaddr;
+ x86pte_t pteval;
+
+ if (khat_running)
+ panic("kbm_map() called too late");
+
+ pteval = pa_to_ma(pa) | PT_NOCONSIST | PT_VALID | PT_WRITABLE;
+ if (level == 1)
+ pteval |= PT_PAGESIZE;
+ if (kbm_pge_support && is_kernel)
+ pteval |= PT_GLOBAL;
+
+ /*
+ * Find the pte that will map this address. This creates any
+ * missing intermediate level page tables.
+ */
+ ptep = find_pte(va, &pte_physaddr, level, 0);
+ if (ptep == NULL)
+ bop_panic("kbm_map: find_pte returned NULL");
+
+ if (kbm_pae_support)
+ *ptep = pteval;
+ else
+ *((x86pte32_t *)ptep) = pteval;
+ mmu_tlbflush_entry((caddr_t)va);
+}
+
+/*
+ * Probe the boot time page tables to find the first mapping
+ * including va (or higher) and return non-zero if one is found.
+ * va is updated to the starting address and len to the pagesize.
+ * pp will be set to point to the 1st page_t of the mapped page(s).
+ *
+ * Note that if va is in the middle of a large page, the returned va
+ * will be less than what was asked for.
+ */
+int
+kbm_probe(uintptr_t *va, size_t *len, pfn_t *pfn, uint_t *prot)
+{
+ uintptr_t probe_va;
+ x86pte_t *ptep;
+ paddr_t pte_physaddr;
+ x86pte_t pte_val;
+ level_t l;
+
+ if (khat_running)
+ panic("kbm_probe() called too late");
+ *len = 0;
+ *pfn = PFN_INVALID;
+ *prot = 0;
+ probe_va = *va;
+restart_new_va:
+ l = top_level;
+ for (;;) {
+ if (IN_VA_HOLE(probe_va))
+ probe_va = mmu.hole_end;
+
+ if (IN_HYPERVISOR_VA(probe_va))
+ return (0);
+
+ /*
+ * If we don't have a valid PTP/PTE at this level
+ * then we can bump VA by this level's pagesize and try again.
+ * When the probe_va wraps around, we are done.
+ */
+ ptep = find_pte(probe_va, &pte_physaddr, l, 1);
+ if (ptep == NULL)
+ bop_panic("kbm_probe: find_pte returned NULL");
+ if (kbm_pae_support)
+ pte_val = *ptep;
+ else
+ pte_val = *((x86pte32_t *)ptep);
+ if (!PTE_ISVALID(pte_val)) {
+ probe_va = (probe_va & BOOT_MASK(l)) + BOOT_SZ(l);
+ if (probe_va <= *va)
+ return (0);
+ goto restart_new_va;
+ }
+
+ /*
+ * If this entry is a pointer to a lower level page table
+ * go down to it.
+ */
+ if (!PTE_ISPAGE(pte_val, l)) {
+ ASSERT(l > 0);
+ --l;
+ continue;
+ }
+
+ /*
+ * We found a boot level page table entry
+ */
+ *len = BOOT_SZ(l);
+ *va = probe_va & ~(*len - 1);
+ *pfn = PTE2PFN(pte_val, l);
+
+
+ *prot = PROT_READ | PROT_EXEC;
+ if (PTE_GET(pte_val, PT_WRITABLE))
+ *prot |= PROT_WRITE;
+
+ /*
+ * pt_nx is cleared if processor doesn't support NX bit
+ */
+ if (PTE_GET(pte_val, mmu.pt_nx))
+ *prot &= ~PROT_EXEC;
+
+ return (1);
+ }
+}
+
+
+/*
+ * Destroy a boot loader page table 4K mapping.
+ */
+void
+kbm_unmap(uintptr_t va)
+{
+ if (khat_running)
+ panic("kbm_unmap() called too late");
+ else {
+ x86pte_t *ptep;
+ level_t level = 0;
+ uint_t probe_only = 1;
+
+ ptep = find_pte(va, NULL, level, probe_only);
+ if (ptep == NULL)
+ return;
+
+ if (kbm_pae_support)
+ *ptep = 0;
+ else
+ *((x86pte32_t *)ptep) = 0;
+ mmu_tlbflush_entry((caddr_t)va);
+ }
+}
+
+
+/*
+ * Change a boot loader page table 4K mapping.
+ * Returns the pfn of the old mapping.
+ */
+pfn_t
+kbm_remap(uintptr_t va, pfn_t pfn)
+{
+ x86pte_t *ptep;
+ level_t level = 0;
+ uint_t probe_only = 1;
+ x86pte_t pte_val = pa_to_ma(pfn_to_pa(pfn)) | PT_WRITABLE |
+ PT_NOCONSIST | PT_VALID;
+ x86pte_t old_pte;
+
+ if (khat_running)
+ panic("kbm_remap() called too late");
+ ptep = find_pte(va, NULL, level, probe_only);
+ if (ptep == NULL)
+ bop_panic("kbm_remap: find_pte returned NULL");
+
+ if (kbm_pae_support)
+ old_pte = *ptep;
+ else
+ old_pte = *((x86pte32_t *)ptep);
+
+ if (kbm_pae_support)
+ *((x86pte_t *)ptep) = pte_val;
+ else
+ *((x86pte32_t *)ptep) = pte_val;
+ mmu_tlbflush_entry((caddr_t)va);
+
+ if (!(old_pte & PT_VALID) || ma_to_pa(old_pte) == -1)
+ return (PFN_INVALID);
+ return (mmu_btop(ma_to_pa(old_pte)));
+}
+
+
+/*
+ * Change a boot loader page table 4K mapping to read only.
+ */
+void
+kbm_read_only(uintptr_t va, paddr_t pa)
+{
+ x86pte_t pte_val = pa_to_ma(pa) |
+ PT_NOCONSIST | PT_REF | PT_MOD | PT_VALID;
+ x86pte_t *ptep;
+ level_t level = 0;
+
+ ptep = find_pte(va, NULL, level, 0);
+ if (ptep == NULL)
+ bop_panic("kbm_read_only: find_pte returned NULL");
+
+ if (kbm_pae_support)
+ *ptep = pte_val;
+ else
+ *((x86pte32_t *)ptep) = pte_val;
+ mmu_tlbflush_entry((caddr_t)va);
+}
+
+/*
+ * interfaces for kernel debugger to access physical memory
+ */
+static x86pte_t save_pte;
+
+void *
+kbm_push(paddr_t pa)
+{
+ static int first_time = 1;
+
+ if (first_time) {
+ first_time = 0;
+ return (window);
+ }
+
+ if (kbm_pae_support)
+ save_pte = *((x86pte_t *)pte_to_window);
+ else
+ save_pte = *((x86pte32_t *)pte_to_window);
+ return (kbm_remap_window(pa, 0));
+}
+
+void
+kbm_pop(void)
+{
+ if (kbm_pae_support)
+ *((x86pte_t *)pte_to_window) = save_pte;
+ else
+ *((x86pte32_t *)pte_to_window) = save_pte;
+ mmu_tlbflush_entry(window);
+}
+
+x86pte_t
+get_pteval(paddr_t table, uint_t index)
+{
+ void *table_ptr = kbm_remap_window(table, 0);
+
+ if (kbm_pae_support)
+ return (((x86pte_t *)table_ptr)[index]);
+ return (((x86pte32_t *)table_ptr)[index]);
+}
+
+void
+set_pteval(paddr_t table, uint_t index, uint_t level, x86pte_t pteval)
+{
+ void *table_ptr = kbm_remap_window(table, 0);
+ if (kbm_pae_support)
+ ((x86pte_t *)table_ptr)[index] = pteval;
+ else
+ ((x86pte32_t *)table_ptr)[index] = pteval;
+ if (level == top_level && level == 2)
+ reload_cr3();
+}
+
+paddr_t
+make_ptable(x86pte_t *pteval, uint_t level)
+{
+ paddr_t new_table;
+ void *table_ptr;
+
+ new_table = do_bop_phys_alloc(MMU_PAGESIZE, MMU_PAGESIZE);
+ table_ptr = kbm_remap_window(new_table, 1);
+ bzero(table_ptr, MMU_PAGESIZE);
+
+ if (level == top_level && level == 2)
+ *pteval = pa_to_ma(new_table) | PT_VALID;
+ else
+ *pteval = pa_to_ma(new_table) |
+ PT_VALID | PT_REF | PT_USER | PT_WRITABLE;
+
+ return (new_table);
+}
+
+x86pte_t *
+map_pte(paddr_t table, uint_t index)
+{
+ void *table_ptr = kbm_remap_window(table, 0);
+ return ((x86pte_t *)((caddr_t)table_ptr + index * pte_size));
+}
diff --git a/usr/src/uts/i86pc/vm/kboot_mmu.h b/usr/src/uts/i86pc/vm/kboot_mmu.h
new file mode 100644
index 0000000000..8c34ad2187
--- /dev/null
+++ b/usr/src/uts/i86pc/vm/kboot_mmu.h
@@ -0,0 +1,106 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _KBOOT_MMU_H
+#define _KBOOT_MMU_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Kernel boot-time interfaces for handling MMU mappings before the HAT proper
+ * is running (i.e. before khat_running is set).
+ */
+
+#include <sys/mach_mmu.h>
+
+struct xboot_info;
+
+extern void kbm_init(struct xboot_info *);
+
+/*
+ * Interface to remap the page table window, also used by HAT during init.
+ */
+extern void *kbm_remap_window(paddr_t physaddr, int writeable);
+
+/*
+ * Find the next mapping at or above VA, if found returns non-zero and sets:
+ * - va : virtual address
+ * - pfn : pfn of real address
+ * - size : pagesize of the mapping
+ * - prot : protections
+ */
+extern int kbm_probe(uintptr_t *va, size_t *len, pfn_t *pfn, uint_t *prot);
+
+/*
+ * Add a new mapping
+ */
+extern void kbm_map(uintptr_t va, paddr_t pa, uint_t level, uint_t is_kernel);
+
+/*
+ * unmap a single 4K page at VA
+ */
+extern void kbm_unmap(uintptr_t va);
+
+/*
+ * Remap a single 4K page at VA (always PROT_READ|PROT_WRITE).
+ * Returns the pfn of the old mapping.
+ */
+extern pfn_t kbm_remap(uintptr_t va, pfn_t pfn);
+
+/*
+ * Make a page mapping read only
+ */
+extern void kbm_read_only(uintptr_t va, paddr_t pa);
+
+
+/*
+ * interface for kmdb to map a physical page, stack is only 1 deep
+ */
+extern void *kbm_push(paddr_t pa);
+extern void kbm_pop(void);
+
+/*
+ * These are needed by mmu_init()
+ */
+extern int kbm_nx_support;
+extern int kbm_pae_support;
+extern int kbm_largepage_support;
+
+/*
+ * The size of memory mapped for the initial kernel nucleus text
+ * and data regions setup by the boot loader. needed for startup
+ */
+extern uint_t kbm_nucleus_size;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KBOOT_MMU_H */
diff --git a/usr/src/uts/i86pc/vm/mach_i86mmu.c b/usr/src/uts/i86pc/vm/mach_i86mmu.c
deleted file mode 100644
index 2e7e305e2e..0000000000
--- a/usr/src/uts/i86pc/vm/mach_i86mmu.c
+++ /dev/null
@@ -1,708 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/t_lock.h>
-#include <sys/memlist.h>
-#include <sys/cpuvar.h>
-#include <sys/vmem.h>
-#include <sys/mman.h>
-#include <sys/vm.h>
-#include <sys/kmem.h>
-#include <sys/cmn_err.h>
-#include <sys/debug.h>
-#include <sys/vm_machparam.h>
-#include <sys/tss.h>
-#include <sys/vnode.h>
-#include <vm/hat.h>
-#include <vm/anon.h>
-#include <vm/as.h>
-#include <vm/page.h>
-#include <vm/seg.h>
-#include <vm/seg_kmem.h>
-#include <vm/seg_map.h>
-#include <vm/hat_i86.h>
-#include <sys/promif.h>
-#include <sys/x86_archext.h>
-#include <sys/systm.h>
-#include <sys/archsystm.h>
-#include <sys/sunddi.h>
-#include <sys/ddidmareq.h>
-#include <sys/controlregs.h>
-#include <sys/reboot.h>
-#include <sys/kdi.h>
-
-caddr_t
-i86devmap(pfn_t pf, pgcnt_t pgcnt, uint_t prot)
-{
- caddr_t addr;
- caddr_t addr1;
- page_t *pp;
-
- addr1 = addr = vmem_alloc(heap_arena, mmu_ptob(pgcnt), VM_SLEEP);
-
- for (; pgcnt != 0; addr += MMU_PAGESIZE, ++pf, --pgcnt) {
- pp = page_numtopp_nolock(pf);
- if (pp == NULL) {
- hat_devload(kas.a_hat, addr, MMU_PAGESIZE, pf,
- prot | HAT_NOSYNC, HAT_LOAD_LOCK);
- } else {
- hat_memload(kas.a_hat, addr, pp,
- prot | HAT_NOSYNC, HAT_LOAD_LOCK);
- }
- }
-
- return (addr1);
-}
-
-/*
- * This routine is like page_numtopp, but accepts only free pages, which
- * it allocates (unfrees) and returns with the exclusive lock held.
- * It is used by machdep.c/dma_init() to find contiguous free pages.
- */
-page_t *
-page_numtopp_alloc(pfn_t pfnum)
-{
- page_t *pp;
-
-retry:
- pp = page_numtopp_nolock(pfnum);
- if (pp == NULL) {
- return (NULL);
- }
-
- if (!page_trylock(pp, SE_EXCL)) {
- return (NULL);
- }
-
- if (page_pptonum(pp) != pfnum) {
- page_unlock(pp);
- goto retry;
- }
-
- if (!PP_ISFREE(pp)) {
- page_unlock(pp);
- return (NULL);
- }
- if (pp->p_szc) {
- page_demote_free_pages(pp);
- page_unlock(pp);
- goto retry;
- }
-
- /* If associated with a vnode, destroy mappings */
-
- if (pp->p_vnode) {
-
- page_destroy_free(pp);
-
- if (!page_lock(pp, SE_EXCL, (kmutex_t *)NULL, P_NO_RECLAIM)) {
- return (NULL);
- }
-
- if (page_pptonum(pp) != pfnum) {
- page_unlock(pp);
- goto retry;
- }
- }
-
- if (!PP_ISFREE(pp) || !page_reclaim(pp, (kmutex_t *)NULL)) {
- page_unlock(pp);
- return (NULL);
- }
-
- return (pp);
-}
-
-/*
- * The boot loader doesn't use PAE page tables for 32 bit platforms
- * so the definitions in hat_pte for LEVEL_SHIFT, etc. don't apply.
- */
-#if defined(__i386) /* 32 bit boot loader */
-
-#define BOOT_TOP_LEVEL 1
-#define BOOT_PTES_PER_TABLE 1024
-#define BOOT_PADDR 0xfffff000
-static uint_t boot_shift[] = {12, 22};
-
-#elif defined(__amd64) /* 64 bit boot loader */
-
-#define BOOT_TOP_LEVEL 3
-#define BOOT_PTES_PER_TABLE 512
-static uint_t boot_shift[] = {12, 21, 30, 39};
-#define BOOT_PADDR PT_PADDR /* boot won't use PAT, so this is ok */
-
-#endif /* __amd64 */
-
-#define BOOT_SHIFT(l) (boot_shift[l])
-#define BOOT_SZ(l) ((size_t)1 << BOOT_SHIFT(l))
-#define BOOT_OFFSET(l) (BOOT_SZ(l) - 1)
-#define BOOT_MASK(l) (~BOOT_OFFSET(l))
-
-/*
- * Flag is not set early in boot. Once it is set we are no longer
- * using boot's page tables.
- */
-uint_t khat_running = 0;
-
-
-/*
- * Probe the boot loader's page tables to find the first mapping
- * including va (or higher) and return non-zero if one is found.
- * va is updated to the starting address and len to the pagesize.
- * pp will be set to point to the 1st page_t of the mapped page(s).
- *
- * Note that if va is in the middle of a large page, the returned va
- * will be less than what was asked for.
- *
- * This works by walking the actual page table's currently in use
- * and rooted at control register 3. This code has the following fundamental
- * assumptions:
- * - In 32 bit mode the boot loader never uses PAE, so the size/type
- * of boot pte_t is compatibile with uintptr_t
- * - The 64 bit mode boot loader has enabled NX bit usage
- * - The pagetables allocated by boot have identity mappings, ie.
- * Virtual address == Physical address
- */
-int
-hat_boot_probe(uintptr_t *va, size_t *len, pfn_t *pfn, uint_t *prot)
-{
- uintptr_t probe_va;
- uint_t entry;
- uintptr_t *top_ptable;
- uintptr_t *ptable;
- level_t l = BOOT_TOP_LEVEL;
-
- *len = 0;
- *pfn = PFN_INVALID;
- *prot = 0;
- probe_va = *va;
- top_ptable = (uintptr_t *)(getcr3() & MMU_PAGEMASK);
-restart_new_va:
- l = BOOT_TOP_LEVEL;
- ptable = top_ptable;
- for (;;) {
- if (IN_VA_HOLE(probe_va))
- probe_va = mmu.hole_end;
-
- /*
- * If we don't have a valid PTP/PTE at this level
- * then we can bump VA by this level's pagesize and try again.
- * When the probe_va wraps around, we are done.
- */
- entry = (probe_va >> BOOT_SHIFT(l)) & (BOOT_PTES_PER_TABLE - 1);
- if (!PTE_ISVALID(ptable[entry])) {
- probe_va = (probe_va & BOOT_MASK(l)) + BOOT_SZ(l);
- if (probe_va <= *va)
- return (0);
- goto restart_new_va;
- }
-
- /*
- * If this entry is a pointer to a lower level page table
- * go down to it.
- */
- if (!PTE_ISPAGE(ptable[entry], l)) {
- ASSERT(l > 0);
- --l;
- ptable = (uintptr_t *)(ptable[entry] & MMU_PAGEMASK);
- continue;
- }
-
- /*
- * We found a boot level page table entry
- */
- *len = BOOT_SZ(l);
- *va = probe_va & ~(*len - 1);
- *pfn = mmu_btop(ptable[entry] & BOOT_PADDR);
-
-
- *prot = PROT_READ | PROT_EXEC;
- if (PTE_GET(ptable[entry], PT_WRITABLE))
- *prot |= PROT_WRITE;
-
- /*
- * pt_nx is cleared if processor doesn't support NX bit
- */
- if (PTE_GET(ptable[entry], mmu.pt_nx))
- *prot &= ~PROT_EXEC;
-
- return (1);
- }
-}
-
-
-/*
- * Destroy a boot loader page table 4K mapping.
- * See hat_boot_probe() for assumptions.
- */
-void
-hat_boot_demap(uintptr_t va)
-{
- uintptr_t *ptable;
- level_t level = BOOT_TOP_LEVEL;
- uint_t entry;
-
- /*
- * Walk down the page tables, which are 1 to 1 mapped, to the
- * desired mapping.
- */
- ptable = (uintptr_t *)(getcr3() & MMU_PAGEMASK);
- for (level = BOOT_TOP_LEVEL; ; --level) {
-
- entry = (va >> BOOT_SHIFT(level)) & (BOOT_PTES_PER_TABLE - 1);
-
- if (!PTE_ISVALID(ptable[entry]))
- panic("hat_boot_demap(): no pte at desired addr");
-
- if (level == 0)
- break;
-
- if (PTE_ISPAGE(ptable[entry], level))
- panic("hat_boot_demap(): large page at va");
-
- ptable = (uintptr_t *)(ptable[entry] & MMU_PAGEMASK);
- }
-
- /*
- * We found a boot level page table entry, invalidate it
- */
- ptable[entry] = 0;
- mmu_tlbflush_entry((caddr_t)va);
-}
-
-
-/*
- * Change a boot loader page table 4K mapping.
- * Returns the pfn of the old mapping.
- * See hat_boot_probe() for assumptions.
- */
-pfn_t
-hat_boot_remap(uintptr_t va, pfn_t pfn)
-{
- uintptr_t *ptable;
- level_t level = BOOT_TOP_LEVEL;
- pfn_t old_pfn;
- uint_t entry;
-
- /*
- * Walk down the page tables, which are 1 to 1 mapped, to the
- * desired mapping.
- */
- ptable = (uintptr_t *)(getcr3() & MMU_PAGEMASK);
- for (level = BOOT_TOP_LEVEL; ; --level) {
-
- entry = (va >> BOOT_SHIFT(level)) & (BOOT_PTES_PER_TABLE - 1);
-
- if (level == 0)
- break;
-
- if (!PTE_ISVALID(ptable[entry]))
- panic("hat_boot_remap(): no pte at desired addr");
-
- if (PTE_ISPAGE(ptable[entry], level))
- panic("hat_boot_remap(): large page at va");
-
- ptable = (uintptr_t *)(ptable[entry] & MMU_PAGEMASK);
- }
-
- /*
- * We found a boot level page table entry, change it and return
- * the old pfn. Assume full permissions.
- */
- old_pfn = mmu_btop(ptable[entry] & BOOT_PADDR);
- ptable[entry] = mmu_ptob((uintptr_t)pfn) | PT_VALID | PT_WRITABLE;
- mmu_tlbflush_entry((caddr_t)va);
- return (old_pfn);
-}
-
-/*
- * This procedure is callable only while the boot loader is in charge
- * of the MMU. It assumes that PA == VA for page table pointers.
- */
-pfn_t
-va_to_pfn(void *vaddr)
-{
- uintptr_t des_va = ALIGN2PAGE(vaddr);
- uintptr_t va = des_va;
- size_t len;
- uint_t prot;
- pfn_t pfn;
-
- if (khat_running)
- panic("va_to_pfn(): called too late\n");
-
- if (hat_boot_probe(&va, &len, &pfn, &prot) == 0)
- return (PFN_INVALID);
- if (va > des_va)
- return (PFN_INVALID);
- if (va < des_va)
- pfn += mmu_btop(des_va - va);
- return (pfn);
-}
-
-/*
- * Routine to pre-allocate any htable's and hments that should be needed in
- * hat_kern_setup(). It computes how many pagetables it needs by walking the
- * boot loader's page tables.
- */
-void
-hat_kern_alloc()
-{
- uintptr_t last_va = (uintptr_t)-1; /* catch 1st time */
- uintptr_t va = 0;
- size_t size;
- pfn_t pfn;
- uint_t prot;
- uint_t table_cnt = 1;
- uint_t mapping_cnt;
- level_t start_level;
- level_t l;
- extern pgcnt_t npages;
- extern pgcnt_t boot_npages;
-
- /*
- * Walk the boot loader's page tables and figure out
- * how many tables and page mappings there will be.
- */
- while (hat_boot_probe(&va, &size, &pfn, &prot) != 0) {
- /*
- * At each level, if the last_va falls into a new htable,
- * increment table_cnt. We can stop at the 1st level where
- * they are in the same htable.
- */
- if (size == MMU_PAGESIZE)
- start_level = 0;
- else
- start_level = 1;
-
- for (l = start_level; l < mmu.max_level; ++l) {
- if (va >> LEVEL_SHIFT(l + 1) ==
- last_va >> LEVEL_SHIFT(l + 1))
- break;
- ++table_cnt;
- }
- last_va = va;
- va += size;
- }
-
- /*
- * Besides the boot loader mappings, we're going to fill in
- * the entire top level page table for the kernel. Make sure there's
- * enough reserve for that too.
- */
- table_cnt += mmu.top_level_count - ((kernelbase >>
- LEVEL_SHIFT(mmu.max_level)) & (mmu.top_level_count - 1));
-
- /*
- * If we still have pages that need page_t's created for them, then
- * make sure we create the pagetables needed to map them in.
- *
- * (yes. We need pagetables to map the page_t's for the unmapped
- * pages. We also need pagetables to map the vmem structures
- * allocated to support the VA range into which they are mapped.
- * Does your head hurt yet?)
- */
- if (boot_npages < npages) {
- pgcnt_t pages;
- pgcnt_t ptables;
-
- /*
- * Number of pages needed for all the new pages_ts. This
- * assumes that they will all be mapped consecutively.
- */
- pages = (npages - boot_npages) / sizeof (page_t);
-
- /*
- * Number of level 0 pagetables needed to map these pages.
- * The '+1' is to handle the likely case that the address
- * range doesn't align with a pagetable boundary.
- */
- ptables = pages / mmu.ptes_per_table + 1;
-
- /*
- * We also add in some extra to account for the higher level
- * pagetables and for the vmem structures that get
- * allocated along the way.
- */
- table_cnt += (ptables * 3);
- }
-
-#if defined(__i386)
- /*
- * The 32 bit PAE hat allocates tables one level below the top when
- * kernelbase isn't 1 Gig aligned. We'll just be sloppy and allocate
- * a bunch more to the reserve. Any unused will be returned later.
- * Note we've already counted these mappings, just not the extra
- * pagetables.
- */
- if (mmu.pae_hat != 0 && (kernelbase & LEVEL_OFFSET(mmu.max_level)) != 0)
- table_cnt += mmu.ptes_per_table -
- ((kernelbase & LEVEL_OFFSET(mmu.max_level)) >>
- LEVEL_SHIFT(mmu.max_level - 1));
-#endif
-
- /*
- * Add 1/4 more into table_cnt for extra slop. The unused
- * slop is freed back when we htable_adjust_reserve() later.
- */
- table_cnt += table_cnt >> 2;
-
- /*
- * We only need mapping entries (hments) for shared pages.
- * This should be far, far fewer than the total possible,
- * We'll allocate enough for 1/16 of all possible PTEs.
- */
- mapping_cnt = (table_cnt * mmu.ptes_per_table) >> 4;
-
- /*
- * Now create the initial htable/hment reserves
- */
- htable_initial_reserve(table_cnt);
- hment_reserve(mapping_cnt);
-}
-
-extern void enable_pae(uintptr_t);
-extern void setup_121_andcall();
-
-/*
- * We need to setup a 1:1 (virtual to physical) mapping for the
- * page containing enable_pae() in the new kernel hat.
- */
-void
-activate_pae(void *pages)
-{
-#if defined(__amd64)
- int turning_on_pae = 0; /* it's already on */
-#elif defined(__i386)
- pfn_t pfn;
- uintptr_t va_1to1;
- htable_t *ht;
- uint_t entry;
- int turning_on_pae = mmu.pae_hat;
-#endif
-
- if (!turning_on_pae) {
- /*
- * Finish setup for x86pte_access_pagetable()
- */
- x86pte_cpu_init(CPU, pages);
-
- /*
- * switch off of boot's page tables onto the ones we've built
- */
- setcr3(MAKECR3(kas.a_hat->hat_htable->ht_pfn));
- khat_running = 1;
- return;
- }
-
-#if defined(__i386)
- if (PFN_ABOVE4G(kas.a_hat->hat_htable->ht_pfn))
- panic("cr3 value would be > 4G on 32 bit PAE");
-
- /*
- * find the htable containing the physical address that would be
- * an identity mapping for enable_pae, save the current pte,
- * then fill in the identity mapping
- */
- pfn = va_to_pfn((void *)enable_pae);
-
- if (pfn == PFN_INVALID)
- panic("activate_pae(): va_to_pfn(enable_pae) failed");
- va_1to1 = mmu_ptob(pfn) +
- ((uintptr_t)(void *)enable_pae & MMU_PAGEOFFSET);
-
- ht = htable_create(kas.a_hat, va_1to1, 0, NULL);
-
- if (ht == NULL || ht->ht_level != 0)
- panic("no htable va %p pfn %lx", (void *)va_1to1, pfn);
- entry = htable_va2entry(va_1to1, ht);
- if (x86pte_get(ht, entry) != 0)
- panic("pte used at va %p", (void *)va_1to1);
- (void) x86pte_set(ht, entry, MAKEPTE(pfn, 0) | PT_WRITABLE, NULL);
-
- /*
- * Finish setup for x86pte_access_pagetable(), this has to be
- * done after the last reference to a newly built page table and
- * before switching to the newly built pagetables.
- */
- x86pte_cpu_init(CPU, pages);
-
- /*
- * now switch to kernel hat activating PAE
- */
- setup_121_andcall(enable_pae, MAKECR3(kas.a_hat->hat_htable->ht_pfn));
- khat_running = 1;
-
- /*
- * release the mapping we used for the kernel hat
- */
- (void) x86pte_set(ht, entry, 0, NULL);
- mmu_tlbflush_entry((caddr_t)va_1to1);
- htable_release(ht);
-#endif /* __i386 */
-}
-
-
-/*
- * Function to set the EFER.NXE bit if we want to use No eXecute.
- * Note that since this is called from manually relocated code from
- * mpcore.s, we have to use an indirect call with set_nxe_func.
- * This is due to the "call" instruction always being PC relative,
- * unless you go through an indirect pointer in memory.
- */
-static void
-set_nxe(void)
-{
- if (mmu.pt_nx == 0)
- return;
-
- /*
- * AMD64 EFER is model specific register #0xc0000080 and NXE is bit 11
- */
- wrmsr(MSR_AMD_EFER, rdmsr(MSR_AMD_EFER) |
- (uint64_t)(uintptr_t)AMD_EFER_NXE);
-}
-
-void (*set_nxe_func)(void) = set_nxe;
-
-/*
- * This routine handles the work of creating the kernel's initial mappings
- * by deciphering the mappings in the page tables created by the boot program.
- *
- * We maintain large page mappings, but only to a level 1 pagesize.
- * The boot loader can only add new mappings once this function starts.
- * In particular it can not change the pagesize used for any existing
- * mappings or this code breaks!
- */
-
-uint_t hks_debug = 0;
-#define HKS_DBG if (hks_debug) prom_printf
-
-void
-hat_kern_setup(void)
-{
- uintptr_t last_va;
- uintptr_t va;
- size_t last_size;
- size_t size;
- uint_t last_prot = 0;
- uint_t prot;
- pfn_t last_pfn = PFN_INVALID;
- pfn_t pfn;
- pgcnt_t cnt = 0;
- void *pages;
-
- /*
- * activate AMD processor NX bit support
- */
- if (mmu.pt_nx != 0)
- set_nxe();
-
- /*
- * Allocate 3 initial page addresses for x86pte_cpu_init().
- */
- pages = vmem_xalloc(heap_arena, 3 * MMU_PAGESIZE, MMU_PAGESIZE, 0,
- LEVEL_SIZE(1), NULL, NULL, VM_SLEEP);
-
- /*
- * next allocate the kernel hat's top level
- */
- kas.a_hat->hat_htable =
- htable_create(kas.a_hat, 0, mmu.max_level, NULL);
-
- /*
- * Now walk through the address space copying all the page mappings.
- */
- va = 0;
- last_va = 1; /* so va doesn't match on the 1st page */
- last_size = 0;
- cnt = 0;
-#ifdef DEBUG
- HKS_DBG(" Start VA / PERM / PFN / # Mappings\n");
-#endif
- while (hat_boot_probe(&va, &size, &pfn, &prot) != 0) {
-
- if (va == last_va + (last_size * cnt) &&
- pfn == last_pfn + ((va - last_va) >> PAGESHIFT) &&
- last_prot == prot &&
- last_size == size) {
- ++cnt;
- } else {
- if (cnt) {
-#ifdef DEBUG
- HKS_DBG(" %p", (void *)last_va);
- HKS_DBG(last_size > MMU_PAGESIZE ?
- " / L" : " / -");
- HKS_DBG(last_prot & PROT_READ ? " R" : " -");
- HKS_DBG(last_prot & PROT_WRITE ? "W" : "-");
- HKS_DBG(last_prot & PROT_EXEC ? "X" : "-");
- HKS_DBG(" / %lx", last_pfn);
- HKS_DBG(" / %ld\n", cnt);
- if (va != last_va + (last_size * cnt))
- HKS_DBG("----skip----\n");
-#endif /* DEBUG */
- hati_kern_setup_load(last_va, last_size,
- last_pfn, cnt, last_prot);
- }
- last_va = va;
- last_size = size;
- last_pfn = pfn;
- last_prot = prot;
- cnt = 1;
- }
- va += size;
- }
-
- if (cnt != 0) {
-#ifdef DEBUG
- HKS_DBG(" %p", (void *)last_va);
- HKS_DBG(last_size > MMU_PAGESIZE ? " / L" : " / -");
- HKS_DBG(last_prot & PROT_READ ? " R" : " -");
- HKS_DBG(last_prot & PROT_WRITE ? "W" : "-");
- HKS_DBG(last_prot & PROT_EXEC ? "X" : "-");
- HKS_DBG(" / %lx", last_pfn);
- HKS_DBG(" / %ld\n", cnt);
-#endif
- hati_kern_setup_load(last_va, last_size, last_pfn, cnt,
- last_prot);
- }
-
-#if defined(__i386)
- CPU->cpu_tss->tss_cr3 = dftss0.tss_cr3 =
- MAKECR3(kas.a_hat->hat_htable->ht_pfn);
-#endif /* __i386 */
-
- /*
- * Now switch cr3 to the newly built page tables. This includes
- * turning on PAE for 32 bit if necessary.
- */
- activate_pae(pages);
-
- CPUSET_ATOMIC_ADD(kas.a_hat->hat_cpus, CPU->cpu_id);
- CPU->cpu_current_hat = kas.a_hat;
-}
diff --git a/usr/src/uts/i86pc/vm/vm_dep.h b/usr/src/uts/i86pc/vm/vm_dep.h
index ec5177b86b..b95f6b8e17 100644
--- a/usr/src/uts/i86pc/vm/vm_dep.h
+++ b/usr/src/uts/i86pc/vm/vm_dep.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,6 +38,7 @@ extern "C" {
#include <sys/clock.h>
#include <vm/hat_pte.h>
+#include <sys/param.h>
/*
* WARNING: vm_dep.h is included by files in common. As such, macros
@@ -333,7 +334,7 @@ extern page_t *page_get_mnode_cachelist(uint_t, uint_t, int, int);
#define PP_2_BIN(pp) (PP_2_BIN_SZC(pp, pp->p_szc))
#define PP_2_MEM_NODE(pp) (PFN_2_MEM_NODE(pp->p_pagenum))
-#define PP_2_MTYPE(pp) (pfn_2_mtype(pp->p_pagenum))
+#define PP_2_MTYPE(pp) (pfn_2_mtype(pfn_to_mfn(pp->p_pagenum)))
#define PP_2_SZC(pp) (pp->p_szc)
#define SZCPAGES(szc) (1 << PAGE_BSZS_SHIFT(szc))
diff --git a/usr/src/uts/i86pc/vm/vm_machdep.c b/usr/src/uts/i86pc/vm/vm_machdep.c
index 2d87417a56..d274494d8c 100644
--- a/usr/src/uts/i86pc/vm/vm_machdep.c
+++ b/usr/src/uts/i86pc/vm/vm_machdep.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -91,8 +91,10 @@ extern uint_t page_create_new;
extern uint_t page_create_exists;
extern uint_t page_create_putbacks;
extern uint_t page_create_putbacks;
-extern uintptr_t eprom_kernelbase;
-extern int use_sse_pagecopy, use_sse_pagezero; /* in ml/float.s */
+/*
+ * Allow users to disable the kernel's use of SSE.
+ */
+extern int use_sse_pagecopy, use_sse_pagezero;
/* 4g memory management */
pgcnt_t maxmem4g;
@@ -425,7 +427,7 @@ map_addr_vacalign_check(caddr_t addr, u_offset_t off)
/*
* map_addr_proc() is the routine called when the system is to
* choose an address for the user. We will pick an address
- * range which is the highest available below kernelbase.
+ * range which is the highest available below userlimit.
*
* addrp is a value/result parameter.
* On input it is a hint from the user to be used in a completely
@@ -667,7 +669,9 @@ valid_usr_range(caddr_t addr, size_t len, uint_t prot, struct as *as,
int
pf_is_memory(pfn_t pf)
{
- return (address_in_memlist(phys_install, mmu_ptob((uint64_t)pf), 1));
+ if (pfn_is_foreign(pf))
+ return (0);
+ return (address_in_memlist(phys_install, pfn_to_pa(pf), 1));
}
@@ -872,10 +876,10 @@ check_dma(ddi_dma_attr_t *dma_attr, page_t *pp, int cnt)
return;
while (cnt-- > 0) {
- if (mmu_ptob((uint64_t)pp->p_pagenum) <
+ if (pa_to_ma(pfn_to_pa(pp->p_pagenum)) <
dma_attr->dma_attr_addr_lo)
panic("PFN (pp=%p) below dma_attr_addr_lo", pp);
- if (mmu_ptob((uint64_t)pp->p_pagenum) >=
+ if (pa_to_ma(pfn_to_pa(pp->p_pagenum)) >=
dma_attr->dma_attr_addr_hi)
panic("PFN (pp=%p) above dma_attr_addr_hi", pp);
pp = pp->p_next;
@@ -1430,8 +1434,7 @@ page_get_mnode_anylist(ulong_t origbin, uchar_t szc, uint_t flags,
ASSERT(pp->p_szc == szc);
ASSERT(PFN_2_MEM_NODE(pp->p_pagenum) == mnode);
/* check if page within DMA attributes */
- pgaddr = mmu_ptob((uint64_t)(pp->p_pagenum));
-
+ pgaddr = pa_to_ma(pfn_to_pa(pp->p_pagenum));
if ((pgaddr >= dma_attr->dma_attr_addr_lo) &&
(pgaddr + MMU_PAGESIZE - 1 <=
dma_attr->dma_attr_addr_hi)) {
@@ -1519,8 +1522,7 @@ nextfreebin:
/* check if page within DMA attributes */
- pgaddr = ptob((uint64_t)(pp->p_pagenum));
-
+ pgaddr = pa_to_ma(pfn_to_pa(pp->p_pagenum));
if ((pgaddr >= dma_attr->dma_attr_addr_lo) &&
(pgaddr + MMU_PAGESIZE - 1 <=
dma_attr->dma_attr_addr_hi)) {
@@ -1844,7 +1846,6 @@ top:
delay(10);
goto top;
}
-
goto fail; /* undo accounting stuff */
}
@@ -1997,8 +1998,8 @@ ppcopy(page_t *frompp, page_t *topp)
{
caddr_t pp_addr1;
caddr_t pp_addr2;
- void *pte1;
- void *pte2;
+ hat_mempte_t pte1;
+ hat_mempte_t pte2;
kmutex_t *ppaddr_mutex;
label_t ljb;
int ret = 1;
@@ -2019,8 +2020,8 @@ ppcopy(page_t *frompp, page_t *topp)
pp_addr1 = CPU->cpu_caddr1;
pp_addr2 = CPU->cpu_caddr2;
- pte1 = (void *)CPU->cpu_caddr1pte;
- pte2 = (void *)CPU->cpu_caddr2pte;
+ pte1 = CPU->cpu_caddr1pte;
+ pte2 = CPU->cpu_caddr2pte;
ppaddr_mutex = &CPU->cpu_ppaddr_mutex;
mutex_enter(ppaddr_mutex);
@@ -2043,8 +2044,9 @@ ppcopy(page_t *frompp, page_t *topp)
no_fault();
faulted:
- if (!kpm_enable)
+ if (!kpm_enable) {
mutex_exit(ppaddr_mutex);
+ }
kpreempt_enable();
return (ret);
}
@@ -2060,7 +2062,7 @@ void
pagezero(page_t *pp, uint_t off, uint_t len)
{
caddr_t pp_addr2;
- void *pte2;
+ hat_mempte_t pte2;
kmutex_t *ppaddr_mutex;
ASSERT_STACK_ALIGNED();
@@ -2076,7 +2078,7 @@ pagezero(page_t *pp, uint_t off, uint_t len)
kpreempt_disable();
pp_addr2 = CPU->cpu_caddr2;
- pte2 = (void *)CPU->cpu_caddr2pte;
+ pte2 = CPU->cpu_caddr2pte;
ppaddr_mutex = &CPU->cpu_ppaddr_mutex;
mutex_enter(ppaddr_mutex);
@@ -2086,10 +2088,11 @@ pagezero(page_t *pp, uint_t off, uint_t len)
HAT_LOAD_NOCONSIST);
}
- if (use_sse_pagezero)
+ if (use_sse_pagezero) {
hwblkclr(pp_addr2 + off, len);
- else
+ } else {
bzero(pp_addr2 + off, len);
+ }
if (!kpm_enable)
mutex_exit(ppaddr_mutex);
@@ -2116,21 +2119,39 @@ void
setup_vaddr_for_ppcopy(struct cpu *cpup)
{
void *addr;
- void *pte;
+ hat_mempte_t pte_pa;
addr = vmem_alloc(heap_arena, mmu_ptob(1), VM_SLEEP);
- pte = hat_mempte_setup(addr);
+ pte_pa = hat_mempte_setup(addr);
cpup->cpu_caddr1 = addr;
- cpup->cpu_caddr1pte = (pteptr_t)pte;
+ cpup->cpu_caddr1pte = pte_pa;
addr = vmem_alloc(heap_arena, mmu_ptob(1), VM_SLEEP);
- pte = hat_mempte_setup(addr);
+ pte_pa = hat_mempte_setup(addr);
cpup->cpu_caddr2 = addr;
- cpup->cpu_caddr2pte = (pteptr_t)pte;
+ cpup->cpu_caddr2pte = pte_pa;
mutex_init(&cpup->cpu_ppaddr_mutex, NULL, MUTEX_DEFAULT, NULL);
}
+/*
+ * Undo setup_vaddr_for_ppcopy
+ */
+void
+teardown_vaddr_for_ppcopy(struct cpu *cpup)
+{
+ mutex_destroy(&cpup->cpu_ppaddr_mutex);
+
+ hat_mempte_release(cpup->cpu_caddr2, cpup->cpu_caddr2pte);
+ cpup->cpu_caddr2pte = 0;
+ vmem_free(heap_arena, cpup->cpu_caddr2, mmu_ptob(1));
+ cpup->cpu_caddr2 = 0;
+
+ hat_mempte_release(cpup->cpu_caddr1, cpup->cpu_caddr1pte);
+ cpup->cpu_caddr1pte = 0;
+ vmem_free(heap_arena, cpup->cpu_caddr1, mmu_ptob(1));
+ cpup->cpu_caddr1 = 0;
+}
/*
* Create the pageout scanner thread. The thread has to
@@ -2155,3 +2176,58 @@ exec_get_spslew(void)
{
return (0);
}
+
+/*
+ * Allocate a memory page. The argument 'seed' can be any pseudo-random
+ * number to vary where the pages come from. This is quite a hacked up
+ * method -- it works for now, but really needs to be fixed up a bit.
+ *
+ * We currently use page_create_va() on the kvp with fake offsets,
+ * segments and virt address. This is pretty bogus, but was copied from the
+ * old hat_i86.c code. A better approach would be to specify either mnode
+ * random or mnode local and takes a page from whatever color has the MOST
+ * available - this would have a minimal impact on page coloring.
+ */
+page_t *
+page_get_physical(uintptr_t seed)
+{
+ page_t *pp;
+ u_offset_t offset;
+ static struct seg tmpseg;
+ static uintptr_t ctr = 0;
+
+ /*
+ * This code is gross, we really need a simpler page allocator.
+ *
+ * We need assign an offset for the page to call page_create_va().
+ * To avoid conflicts with other pages, we get creative with the offset.
+ * For 32 bits, we pick an offset > 4Gig
+ * For 64 bits, pick an offset somewhere in the VA hole.
+ */
+ offset = seed;
+ if (offset > kernelbase)
+ offset -= kernelbase;
+ offset <<= MMU_PAGESHIFT;
+#if defined(__amd64)
+ offset += mmu.hole_start; /* something in VA hole */
+#else
+ offset += 1ULL << 40; /* something > 4 Gig */
+#endif
+
+ if (page_resv(1, KM_NOSLEEP) == 0)
+ return (NULL);
+
+#ifdef DEBUG
+ pp = page_exists(&kvp, offset);
+ if (pp != NULL)
+ panic("page already exists %p", pp);
+#endif
+
+ pp = page_create_va(&kvp, offset, MMU_PAGESIZE, PG_EXCL | PG_NORELOC,
+ &tmpseg, (caddr_t)(ctr += MMU_PAGESIZE)); /* changing VA usage */
+ if (pp == NULL)
+ return (NULL);
+ page_io_unlock(pp);
+ page_hashout(pp, NULL);
+ return (pp);
+}
diff --git a/usr/src/uts/i86pc/xsvc/Makefile b/usr/src/uts/i86pc/xsvc/Makefile
new file mode 100644
index 0000000000..6dd8477ad5
--- /dev/null
+++ b/usr/src/uts/i86pc/xsvc/Makefile
@@ -0,0 +1,95 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# uts/i86pc/xsvc/Makefile
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# This makefile drives the production of the xsvc driver kernel
+# module.
+#
+
+#
+# Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE = ../..
+
+#
+# Define the module and object file sets.
+#
+MODULE = xsvc
+OBJECTS = $(XSVC_OBJS:%=$(OBJS_DIR)/%)
+LINTS = $(XSVC_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
+CONF_SRCDIR = $(UTSBASE)/i86pc/io/xsvc
+
+#
+# Include common rules.
+#
+include $(UTSBASE)/i86pc/Makefile.i86pc
+
+#
+# Define targets
+#
+ALL_TARGET = $(BINARY) $(SRC_CONFILE)
+LINT_TARGET = $(MODULE).lint
+INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
+
+#
+# Dependency
+#
+LDFLAGS += -dy
+
+#
+# Override defaults to build a unique, local modstubs.o.
+#
+MODSTUBS_DIR = $(OBJS_DIR)
+CLEANFILES += $(MODSTUBS_O)
+
+#
+# Default build targets.
+#
+.KEEP_STATE:
+
+def: $(DEF_DEPS)
+
+all: $(ALL_DEPS)
+
+clean: $(CLEAN_DEPS)
+
+clobber: $(CLOBBER_DEPS)
+
+lint: $(LINT_DEPS)
+
+modlintlib: $(MODLINTLIB_DEPS)
+
+clean.lint: $(CLEAN_LINT_DEPS)
+
+install: $(INSTALL_DEPS)
+
+#
+# Include common targets.
+#
+include $(UTSBASE)/i86pc/Makefile.targ
+
diff --git a/usr/src/uts/intel/Makefile b/usr/src/uts/intel/Makefile
index adaa4d6158..578916b474 100644
--- a/usr/src/uts/intel/Makefile
+++ b/usr/src/uts/intel/Makefile
@@ -20,7 +20,7 @@
#
# uts/intel/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -39,9 +39,10 @@ LINT_LIBS = $(LINT_LIB) $(GEN_LINT_LIB) \
# EXPORT DELETE START
$(CLOSED_BUILD)LINT_LIBS += $(SVVS_KMODS:%=$(LINT_LIB_DIR)/llib-l%.ln)
-$(CLOSED_BUILD)LINT_CLOSED_XMOD3 = $(CLOSED_XMODS:lsimega=)
-$(CLOSED_BUILD)LINT_CLOSED_XMOD2 = $(LINT_CLOSED_XMOD3:adpu320=)
-$(CLOSED_BUILD)LINT_CLOSED_XMOD1 = $(LINT_CLOSED_XMOD2:e1000g=)
+$(CLOSED_BUILD)LINT_CLOSED_XMOD4 = $(CLOSED_XMODS:lsimega=)
+$(CLOSED_BUILD)LINT_CLOSED_XMOD3 = $(LINT_CLOSED_XMOD4:spwr=)
+$(CLOSED_BUILD)LINT_CLOSED_XMOD2 = $(LINT_CLOSED_XMOD3:adpu320=)
+$(CLOSED_BUILD)LINT_CLOSED_XMOD1 = $(LINT_CLOSED_XMOD2:e1000g=)
$(CLOSED_BUILD)LINT_XMODLIBS = $(LINT_CLOSED_XMOD1:nge=)
$(CLOSED_BUILD)LINT_LIBS += $(LINT_XMODLIBS:%=$(LINT_LIB_DIR)/llib-l%.ln)
@@ -82,8 +83,8 @@ install_h := TARGET= install_h
.KEEP_STATE:
-.PARALLEL: $(KMODS) $(CLOSED_KMODS) $(SVVS) $(XMODS) $(CLOSED_XMODS) \
- config $(LINT_DEPS)
+.PARALLEL: $(PARALLEL_KMODS) $(CLOSED_KMODS) $(SVVS) $(XMODS) \
+ $(CLOSED_XMODS) config $(LINT_DEPS)
def all install clean clobber modlist: genassym $(KMODS) $(CLOSED_KMODS) \
$(SVVS) $(XMODS) $(CLOSED_XMODS) config
@@ -119,13 +120,21 @@ install_h check: FRC
@cd amd64/sys; pwd; $(MAKE) $(TARGET)
#
+# Work-around to disable acpica global crosscheck lint warnings
+#
+LGREP.intel = grep -v 'intel/io/acpica'
+
+#
# Full kernel lint target.
#
LINT_TARGET = globallint
+# workaround for multiply defined errors
+globallint := LINTFLAGS += -erroff=E_NAME_MULTIPLY_DEF2
+
globallint:
@-$(ECHO) "\nFULL KERNEL: global crosschecks:"
- @-$(LINT) $(LINTFLAGS) $(LINT_LIBS) 2>&1 | $(LGREP.2)
+ @-$(LINT) $(LINTFLAGS) $(LINT_LIBS) 2>&1 | $(LGREP.2) | $(LGREP.intel)
lint: modlintlib .WAIT $(LINT_DEPS)
diff --git a/usr/src/uts/intel/Makefile.files b/usr/src/uts/intel/Makefile.files
index 2cdbe02a14..f401fc5507 100644
--- a/usr/src/uts/intel/Makefile.files
+++ b/usr/src/uts/intel/Makefile.files
@@ -36,6 +36,7 @@
# Core (unix) objects
#
CORE_OBJS += \
+ arch_kdi.o \
copy.o \
copy_subr.o \
cpc_subr.o \
@@ -70,7 +71,6 @@ SPECIAL_OBJS_32 += \
#
GENUNIX_OBJS += \
archdep.o \
- arch_kdi.o \
getcontext.o \
install_utrap.o \
prom_enter.o \
@@ -110,33 +110,52 @@ LX_AUTOFS_OBJS += \
lx_autofs.o
#
-# Driver modules
+# Decompression code
#
-CMDK_OBJS += cmdk.o
+CORE_OBJS += decompress.o adler32.o infblock.o infcodes.o inffast.o \
+ inflate.o inftrees.o infutil.o zutil.o zmod.o
+#
+# Driver modules
+#
+AGPGART_OBJS += agpgart.o agp_kstat.o
+AGPTARGET_OBJS += agptarget.o
+AMD64GART_OBJS += amd64_gart.o
+ATA_OBJS += $(GHD_OBJS) ata_blacklist.o ata_common.o ata_disk.o \
+ ata_dma.o atapi.o atapi_fsm.o ata_debug.o \
+ sil3xxx.o
+CMDK_OBJS += cmdk.o
CMLB_OBJS += cmlb.o
-
-DADK_OBJS += dadk.o
-
-GDA_OBJS += gda.o
-
+DADK_OBJS += dadk.o
+DNET_OBJS += dnet.o mii.o
+FD_OBJS += fd.o
+GDA_OBJS += gda.o
+GHD_OBJS += ghd.o ghd_debug.o ghd_dma.o ghd_queue.o ghd_scsa.o \
+ ghd_scsi.o ghd_timer.o ghd_waitq.o ghd_gcmd.o
+I915_OBJS += i915_sundrv.o i915_dma.o i915_drv.o i915_irq.o i915_mem.o
+LOGI_OBJS += logi.o
+MSMOUSE_OBJS += msm.o
+MSCSI_OBJS += mscsi.o
+PCI_E_PCINEXUS_OBJS += pcie_pci.o
+PCI_PCINEXUS_OBJS += pci_pci.o
+PCIEHPCNEXUS_OBJS += pciehpc_x86.o pciehpc_acpi.o pciehpc_nvidia.o
+PCN_OBJS += mii.o
+POWER_OBJS += power.o
+PCI_AUTOCONFIG_OBJS += pci_autoconfig.o pci_boot.o pcie_nvidia.o \
+ pci_memlist.o pci_resource.o
SD_OBJS += sd.o sd_xbuf.o
-
STRATEGY_OBJS += strategy.o
-
VGATEXT_OBJS += vgatext.o vgasubr.o
#
-# misc. modules
+# Kernel linker
#
-KRTLD_BOOT_OBJS += \
- kobj_boot.o
-
KRTLD_OBJS += \
bootrd.o \
ufsops.o \
hsfs.o \
doreloc.o \
+ kobj_boot.o \
kobj_convrelstr.o \
kobj_crt.o \
kobj_isa.o \
@@ -145,12 +164,42 @@ KRTLD_OBJS += \
#
# misc. modules
#
+ACPICA_OBJS += dbcmds.o dbdisply.o \
+ dbexec.o dbfileio.o dbhistry.o dbinput.o dbstats.o \
+ dbutils.o dbxface.o evevent.o evgpe.o evgpeblk.o \
+ evmisc.o evregion.o evrgnini.o evsci.o evxface.o \
+ evxfevnt.o evxfregn.o hwacpi.o hwgpe.o hwregs.o \
+ hwsleep.o hwtimer.o dsfield.o dsinit.o dsmethod.o \
+ dsmthdat.o dsobject.o dsopcode.o dsutils.o dswexec.o \
+ dswload.o dswscope.o dswstate.o exconfig.o exconvrt.o \
+ excreate.o exdump.o exfield.o exfldio.o exmisc.o \
+ exmutex.o exnames.o exoparg1.o exoparg2.o exoparg3.o \
+ exoparg6.o exprep.o exregion.o exresnte.o exresolv.o \
+ exresop.o exstore.o exstoren.o exstorob.o exsystem.o \
+ exutils.o psargs.o psopcode.o psparse.o psscope.o \
+ pstree.o psutils.o pswalk.o psxface.o nsaccess.o \
+ nsalloc.o nsdump.o nsdumpdv.o nseval.o nsinit.o \
+ nsload.o nsnames.o nsobject.o nsparse.o nssearch.o \
+ nsutils.o nswalk.o nsxfeval.o nsxfname.o nsxfobj.o \
+ rsaddr.o rscalc.o rscreate.o rsdump.o \
+ rsinfo.o rsio.o rsirq.o rslist.o rsmemory.o rsmisc.o \
+ rsutils.o rsxface.o tbconvrt.o tbget.o tbgetall.o \
+ tbinstal.o tbrsdt.o tbutils.o tbxface.o tbxfroot.o \
+ utalloc.o utclib.o utcopy.o utdebug.o utdelete.o \
+ uteval.o utglobal.o utinit.o utmath.o utmisc.o \
+ utobject.o utresrc.o utxface.o acpica.o acpi_enum.o \
+ master_ops.o osl.o osl_ml.o acpica_ec.o utcache.o \
+ utmutex.o utstate.o dmbuffer.o dmnames.o dmobject.o \
+ dmopcode.o dmresrc.o dmresrcl.o dmresrcs.o dmutils.o \
+ dmwalk.o psloop.o uttrack.o
+
ACPI_INTP_OBJS += acpi_inf.o acpi_mod.o acpi_ml.o \
acpi_decl.o acpi_exe.o acpi_gram.o acpi_io.o acpi_lex.o \
acpi_name.o acpi_ns.o acpi_op1.o acpi_op2.o acpi_rule.o \
acpi_tab.o acpi_thr.o acpi_val.o \
acpi_exc.o acpi_bst.o acpi_node.o acpi_stk.o acpi_par.o
+AGP_OBJS += agpmaster.o
FBT_OBJS += fbt.o
SDT_OBJS += sdt.o
diff --git a/usr/src/uts/intel/Makefile.intel.shared b/usr/src/uts/intel/Makefile.intel.shared
index 22f043eaeb..8a923fd369 100644
--- a/usr/src/uts/intel/Makefile.intel.shared
+++ b/usr/src/uts/intel/Makefile.intel.shared
@@ -146,16 +146,6 @@ AS_INC_PATH += -I$(GENASSYM_DIR)/$(OBJS_DIR)
BASE_INS_DIR = $(ROOT)
#
-#
-# Simulator flag
-#
-i386_SIMULATOR = -D_SIMULATOR_SUPPORT
-amd64_SIMULATOR = -D_SIMULATOR_SUPPORT
-
-SIMULATOR = $($(MACH)_SIMULATOR)
-
-
-#
# Debugging level
#
# Special knowledge of which special debugging options affect which
@@ -163,10 +153,8 @@ SIMULATOR = $($(MACH)_SIMULATOR)
#
DEBUG_DEFS_OBJ32 =
DEBUG_DEFS_DBG32 = -DDEBUG
-DEBUG_DEFS_DBG32 += $(SIMULATOR)
DEBUG_DEFS_OBJ64 =
DEBUG_DEFS_DBG64 = -DDEBUG
-DEBUG_DEFS_DBG64 += $(SIMULATOR)
DEBUG_DEFS = $(DEBUG_DEFS_$(BUILD_TYPE))
DEBUG_COND_OBJ32 :sh = echo \\043
@@ -216,10 +204,17 @@ ALL_DEFS = $(DEBUG_DEFS) $(OPTION_DEFS)
DRV_KMODS += aac
DRV_KMODS += aggr
DRV_KMODS += ahci
+DRV_KMODS += amd64_gart
DRV_KMODS += amr
+DRV_KMODS += agpgart
+DRV_KMODS += agptarget
DRV_KMODS += arp
DRV_KMODS += asy
+DRV_KMODS += ata
DRV_KMODS += ath
+DRV_KMODS += audio810
+DRV_KMODS += audiohd
+DRV_KMODS += audioixp
DRV_KMODS += bl
DRV_KMODS += bge
DRV_KMODS += bofi
@@ -233,10 +228,14 @@ DRV_KMODS += crypto
DRV_KMODS += cryptoadm
DRV_KMODS += devinfo
DRV_KMODS += dld
+DRV_KMODS_32 += dnet
DRV_KMODS += dump
DRV_KMODS += ecpp
+DRV_KMODS += fd
+DRV_KMODS += fdc
DRV_KMODS += fssnap
DRV_KMODS += i8042
+DRV_KMODS += i915
DRV_KMODS += icmp
DRV_KMODS += icmp6
DRV_KMODS += ip
@@ -246,6 +245,7 @@ DRV_KMODS += ippctl
DRV_KMODS += ipsecah
DRV_KMODS += ipsecesp
DRV_KMODS += iwscn
+DRV_KMODS += kb8042
DRV_KMODS += keysock
DRV_KMODS += kssl
DRV_KMODS += kstat
@@ -254,15 +254,22 @@ DRV_KMODS += kmdb
DRV_KMODS += llc1
DRV_KMODS += lofi
DRV_KMODS += log
+DRV_KMODS += logi
DRV_KMODS += logindmux
DRV_KMODS += mm
DRV_KMODS += mouse8042
+DRV_KMODS_32 += mscsi
+DRV_KMODS_32 += msm
DRV_KMODS += nca
DRV_KMODS += openeepr
+DRV_KMODS += pci_pci
+DRV_KMODS += pcic
+DRV_KMODS += pcie_pci
DRV_KMODS += physmem
DRV_KMODS += pm
DRV_KMODS += poll
DRV_KMODS += pool
+DRV_KMODS += power
DRV_KMODS += pseudo
DRV_KMODS += ptc
DRV_KMODS += ptm
@@ -280,8 +287,8 @@ DRV_KMODS += sctp6
DRV_KMODS += sd
DRV_KMODS += sgen
DRV_KMODS += si3124
-DRV_KMODS += spdsock
DRV_KMODS += smbios
+DRV_KMODS += spdsock
DRV_KMODS += sppp
DRV_KMODS += sppptun
DRV_KMODS += st
@@ -307,11 +314,22 @@ DRV_KMODS += zcons
#
$(CLOSED_BUILD)DRV_KMODS += dca
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += chxge
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += glm
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += llc2
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += mpt
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += marvell88sx
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += audioens
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += audiovia823x
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += bmc
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += bscbus
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += bscv
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += chxge
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += elxl
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += glm
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += iprb
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += llc2
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += marvell88sx
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += mpt
+$(CLOSED_BUILD)CLOSED_DRV_KMODS_32 += ncrs
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += pcn
+$(CLOSED_BUILD)CLOSED_DRV_KMODS += rtls
+$(CLOSED_BUILD)CLOSED_DRV_KMODS_32 += sbpro
#
# Common code drivers
@@ -446,6 +464,11 @@ STRMOD_KMODS += usb_ah
STRMOD_KMODS += drcompat
STRMOD_KMODS += nattymod
STRMOD_KMODS += cryptmod
+STRMOD_KMODS += vuid2ps2
+STRMOD_KMODS += vuid3ps2
+STRMOD_KMODS += vuidm3p
+STRMOD_KMODS += vuidm4p
+STRMOD_KMODS += vuidm5p
#
# 'System' Modules (/kernel/sys):
@@ -470,8 +493,11 @@ SYS_KMODS += acctctl
# MISC_KMODS_32 are built only 32-bit
# MISC_KMODS_64 are built only 64-bit
#
+MISC_KMODS += acpica
+MISC_KMODS += agpmaster
MISC_KMODS += amsrc2
MISC_KMODS += audiosup
+MISC_KMODS += bootdev
MISC_KMODS += busra
MISC_KMODS += cmlb
MISC_KMODS += consconfig
@@ -479,6 +505,7 @@ MISC_KMODS += ctf
MISC_KMODS += dadk
MISC_KMODS += diaudio
MISC_KMODS += dls
+MISC_KMODS += drm
MISC_KMODS += fssnap_if
MISC_KMODS += gda
MISC_KMODS += gld
@@ -496,14 +523,15 @@ MISC_KMODS += kcf
MISC_KMODS += kgssapi
MISC_KMODS += kmech_dummy
MISC_KMODS += kmech_krb5
-MISC_KMODS += krtld
MISC_KMODS += mac
MISC_KMODS += mixer
MISC_KMODS += net80211
MISC_KMODS += nfs_dlboot
MISC_KMODS += nfssrv
MISC_KMODS += neti
+MISC_KMODS += pci_autoconfig
MISC_KMODS += pcicfg
+MISC_KMODS += pciehpc
MISC_KMODS += pcihp
MISC_KMODS += pcmcia
MISC_KMODS += rpcsec
@@ -517,7 +545,6 @@ MISC_KMODS += sysinit
MISC_KMODS += tem
MISC_KMODS += tlimod
MISC_KMODS += usba usba10 usbs49_fw
-MISC_KMODS += zmod
$(CLOSED_BUILD)CLOSED_MISC_KMODS += amsrc1
$(CLOSED_BUILD)CLOSED_MISC_KMODS += klmmod klmops
@@ -550,11 +577,6 @@ IPP_KMODS += tokenmt
IPP_KMODS += tswtclmt
#
-# 'Dacf' modules (/kernel/dacf)
-#
-DACF_KMODS += consconfig_dacf
-
-#
# generic-unix module (/kernel/genunix):
#
GENUNIX_KMODS += genunix
@@ -580,6 +602,7 @@ $(CLOSED_BUILD)CLOSED_XMODS = \
lsimega \
nge \
sdpib \
+ spwr \
tavor
diff --git a/usr/src/uts/intel/Makefile.rules b/usr/src/uts/intel/Makefile.rules
index 3770e4e9dd..0ea5247643 100644
--- a/usr/src/uts/intel/Makefile.rules
+++ b/usr/src/uts/intel/Makefile.rules
@@ -37,12 +37,23 @@
# alphabetically by the remaining components.
#
+# Need a way to distinguish between the ia32 and amd64 subdirs.
+#
+SUBARCH_DIR_32 = ia32
+SUBARCH_DIR_64 = amd64
+SUBARCH_DIR = $(SUBARCH_DIR_$(CLASS))
+
+#
# Section 1a: C object build rules
#
$(OBJS_DIR)/%.o: $(SRC)/common/fs/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
+$(OBJS_DIR)/%.o: $(UTSBASE)/common/io/power/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
$(OBJS_DIR)/%.o: $(SRC)/common/util/i386/%.s
$(COMPILE.s) -o $@ $<
@@ -83,10 +94,88 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/aac/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/%.s
+ $(COMPILE.s) -o $@ $<
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/debugger/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/events/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/hardware/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/interpreter/dispatcher/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/interpreter/executer/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/interpreter/parser/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/namespace/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/resources/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/tables/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/utilities/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/acpica/disassembler/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/agpgart/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/agpmaster/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/amr/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/drm/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/drm/%.s
+ $(COMPILE.s) -o $@ $<
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/pci/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/pciex/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/pciex/hotplug/pciehpc/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/dktp/controller/ata/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
@@ -135,6 +224,44 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/common/os/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/kdi/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/kdi/%.s
+ $(COMPILE.s) -o $@ $<
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/kdi/$(SUBARCH_DIR)/%.s
+ $(COMPILE.s) -o $@ $<
+
+#
+# krtld compiled into unix
+#
+
+KRTLD_INC_PATH = -I$(UTSBASE)/common/krtld -I$(UTSBASE)/intel/sys
+KRTLD_INC_PATH += -I$(UTSBASE)/intel/$(SUBARCH_DIR)/krtld
+
+KRTLD_CPPFLAGS_32 = -DELF_TARGET_386
+KRTLD_CPPFLAGS_64 = -DELF_TARGET_AMD64 -DMODDIR_SUFFIX=\"amd64\"
+KRTLD_CPPFLAGS = $(KRTLD_CPPFLAGS_$(CLASS)) -D_KRTLD
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/common/krtld/%.c
+ $(COMPILE.c) $(KRTLD_INC_PATH) $(KRTLD_CPPFLAGS) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/$(SUBARCH_DIR)/krtld/%.c
+ $(COMPILE.c) $(KRTLD_INC_PATH) $(KRTLD_CPPFLAGS) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/$(SUBARCH_DIR)/krtld/%.s
+ $(COMPILE.s) $(KRTLD_INC_PATH) $(KRTLD_CPPFLAGS) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(OBJS_DIR)/%.o: $(SRC)/common/util/$(SUBARCH_DIR)/%.c
+ $(COMPILE.c) $(KRTLD_INC_PATH) $(KRTLD_CPPFLAGS) -o $@ $<
+ $(CTFCONVERT_O)
+
+
#
# Section 1b: Lint `object' build rules.
#
@@ -174,9 +301,69 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/%.c
$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/aac/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/%.s
+ @($(LHEAD) $(LINT.s) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/debugger/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/events/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/hardware/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/interpreter/dispatcher/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/interpreter/executer/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/interpreter/parser/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/namespace/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/resources/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/tables/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/utilities/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/acpica/disassembler/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/agpgart/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/agpmaster/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/amr/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/drm/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/drm/%.s
+ @($(LHEAD) $(LINT.s) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/pci/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/pciex/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/pciex/hotplug/pciehpc/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/dktp/controller/ata/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
@@ -212,3 +399,28 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/intel/syscall/%.c
$(LINTS_DIR)/%.ln: $(UTSBASE)/common/os/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/kdi/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/kdi/%.s
+ @($(LHEAD) $(LINT.s) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/kdi/$(SUBARCH_DIR)/%.s
+ @($(LHEAD) $(LINT.s) $< $(LTAIL))
+
+#
+# krtld lints
+#
+$(LINTS_DIR)/%.ln: $(UTSBASE)/common/krtld/%.c
+ @($(LHEAD) $(LINT.c) $(KRTLD_INC_PATH) $(KRTLD_CPPFLAGS) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/$(SUBARCH_DIR)/krtld/%.c
+ @($(LHEAD) $(LINT.c) $(KRTLD_INC_PATH) $(KRTLD_CPPFLAGS) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/$(SUBARCH_DIR)/krtld/%.s
+ @($(LHEAD) $(LINT.s) $(KRTLD_INC_PATH) $(KRTLD_CPPFLAGS) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(SRC)/common/util/$(SUBARCH_DIR)/%.c
+ @($(LHEAD) $(LINT.c) $(KRTLD_INC_PATH) $(KRTLD_CPPFLAGS) $< $(LTAIL))
+
diff --git a/usr/src/uts/i86pc/acpica/Makefile b/usr/src/uts/intel/acpica/Makefile
index 2649bae96c..5cd44bec14 100644
--- a/usr/src/uts/i86pc/acpica/Makefile
+++ b/usr/src/uts/intel/acpica/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -7,7 +7,7 @@
# This makefile drives the production of the ACPI CA services
# kernel module.
#
-# i86pc implementation architecture dependent
+# intel architecture dependent
#
#
@@ -23,11 +23,12 @@ OBJECTS = $(ACPICA_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(ACPICA_OBJS:%.o=$(LINTS_DIR)/%.ln)
ROOTMODULE = $(ROOT_MISC_DIR)/$(MODULE)
INC_PATH += -I$(UTSBASE)/intel/sys/acpi
+INC_PATH += -I$(UTSBASE)/i86pc
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -80,4 +81,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/agpgart/Makefile b/usr/src/uts/intel/agpgart/Makefile
index d50aed1e56..305f8888d7 100644
--- a/usr/src/uts/i86pc/agpgart/Makefile
+++ b/usr/src/uts/intel/agpgart/Makefile
@@ -1,8 +1,8 @@
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# uts/i86pc/agpgart/Makefile
+# uts/intel/agpgart/Makefile
#
#
#ident "%Z%%M% %I% %E% SMI"
@@ -21,13 +21,13 @@ UTSBASE = ../..
MODULE = agpgart
OBJECTS = $(AGPGART_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(AGPGART_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/i86pc/io/agpgart
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
+CONF_SRCDIR = $(UTSBASE)/intel/io/agpgart
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -69,4 +69,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/agpmaster/Makefile b/usr/src/uts/intel/agpmaster/Makefile
index 138a967e2d..c6a25d3f77 100644
--- a/usr/src/uts/i86pc/agpmaster/Makefile
+++ b/usr/src/uts/intel/agpmaster/Makefile
@@ -19,9 +19,9 @@
# CDDL HEADER END
#
-# uts/i86pc/agpmaster/Makefile
+# uts/intel/agpmaster/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -29,7 +29,7 @@
# This makefile drives the production of the common graphics
# interface kernel module.
#
-# i86pc platform dependent
+# intel platform dependent
#
#
@@ -43,8 +43,8 @@ UTSBASE = ../..
MODULE = agpmaster
OBJECTS = $(AGP_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(AGP_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_MISC_DIR)/$(MODULE)
-INC_PATH += -I$(UTSBASE)/i86pc/io/agpmaster
+ROOTMODULE = $(ROOT_MISC_DIR)/$(MODULE)
+INC_PATH += -I$(UTSBASE)/intel/io/agpmaster
#
# dependency
@@ -54,7 +54,7 @@ LDFLAGS += -dy -Nmisc/pci_autoconfig
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -94,4 +94,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/agptarget/Makefile b/usr/src/uts/intel/agptarget/Makefile
index 821f70c7ef..6d90d9f676 100644
--- a/usr/src/uts/i86pc/agptarget/Makefile
+++ b/usr/src/uts/intel/agptarget/Makefile
@@ -1,8 +1,8 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# uts/i86pc/agptarget/Makefile
+# uts/intel/agptarget/Makefile
#
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -21,12 +21,12 @@ UTSBASE = ../..
MODULE = agptarget
OBJECTS = $(AGPTARGET_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(AGPTARGET_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -59,4 +59,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/intel/amd64/krtld/kobj_boot.c b/usr/src/uts/intel/amd64/krtld/kobj_boot.c
index fb97b0b126..bdd6779d01 100644
--- a/usr/src/uts/intel/amd64/krtld/kobj_boot.c
+++ b/usr/src/uts/intel/amd64/krtld/kobj_boot.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,48 +34,20 @@
#include <sys/link.h>
#include <sys/auxv.h>
#include <sys/kobj.h>
-#include <sys/elf.h>
#include <sys/bootsvcs.h>
#include <sys/kobj_impl.h>
-
-#if !defined(__GNUC__)
-
-/*
- * We don't use the global offset table, but
- * ld may throw in an UNDEFINED reference in
- * our symbol table.
- */
-#if !defined(_KERNEL)
-#pragma weak _GLOBAL_OFFSET_TABLE_
-#endif
-
-#else
+#include <vm/kboot_mmu.h>
/*
- * We -do- use the global offset table, but only by
- * accident -- when you tell gcc to emit PIC code,
- * it -always- generates a reference to the GOT in
- * a register, even if the compilation unit never
- * uses it.
- *
- * Rumoured to be fixed in a later version of gcc..
+ * the kernel's entry point (from locore.s)
*/
-
-long _GLOBAL_OFFSET_TABLE_[1];
-
-#endif
-
-#define roundup ALIGN
-
-#define MAXSECT 64 /* max # of sects. */
-
-#define HIBITS 0xffffffff80000000 /* upper 32 bits */
+extern void _locore_start();
/*
- * Boot transfers control here. At this point,
- * we haven't relocated our own symbols, so the
- * world (as we know it) is pretty small right now.
+ * fakebop and dboot don't create the boot auxillary vector information.
+ * Do that here before calling krtld initialization.
*/
+/*ARGSUSED3*/
void
_kobj_boot(
struct boot_syscalls *syscallp,
@@ -83,337 +55,18 @@ _kobj_boot(
struct bootops *bootops,
Boot *ebp)
{
- Shdr *section[MAXSECT]; /* cache */
val_t bootaux[BA_NUM];
- struct bootops *bop;
- Phdr *phdr;
- auxv_t *auxv = NULL;
- Shdr *sh;
- Half sh_num;
- ulong_t end, edata = 0;
int i;
- bop = (dvec) ? *(struct bootops **)bootops : bootops;
-
for (i = 0; i < BA_NUM; i++)
bootaux[i].ba_val = NULL;
- /*
- * Check the bootstrap vector.
- */
- for (; ebp->eb_tag != EB_NULL; ebp++) {
- switch (ebp->eb_tag) {
- case EB_AUXV:
- auxv = (auxv_t *)ebp->eb_un.eb_ptr;
- break;
- case EB_DYNAMIC:
- bootaux[BA_DYNAMIC].ba_ptr = (void *)ebp->eb_un.eb_ptr;
- break;
- default:
- break;
- }
- }
-
- if (auxv == NULL)
- return;
-
- /*
- * Now the aux vector.
- */
- for (; auxv->a_type != AT_NULL; auxv++) {
- switch (auxv->a_type) {
- case AT_PHDR:
- bootaux[BA_PHDR].ba_ptr = auxv->a_un.a_ptr;
- break;
- case AT_PHENT:
- bootaux[BA_PHENT].ba_val = auxv->a_un.a_val;
- break;
- case AT_PHNUM:
- bootaux[BA_PHNUM].ba_val = auxv->a_un.a_val;
- break;
- case AT_PAGESZ:
- bootaux[BA_PAGESZ].ba_val = auxv->a_un.a_val;
- break;
- case AT_SUN_LDELF:
- bootaux[BA_LDELF].ba_ptr = auxv->a_un.a_ptr;
- break;
- case AT_SUN_LDSHDR:
- bootaux[BA_LDSHDR].ba_ptr = auxv->a_un.a_ptr;
- break;
- case AT_SUN_LDNAME:
- bootaux[BA_LDNAME].ba_ptr = auxv->a_un.a_ptr;
- break;
- case AT_SUN_LPAGESZ:
- bootaux[BA_LPAGESZ].ba_val = auxv->a_un.a_val;
- break;
- case AT_SUN_CPU:
- bootaux[BA_CPU].ba_ptr = auxv->a_un.a_ptr;
- break;
- case AT_SUN_MMU:
- bootaux[BA_MMU].ba_ptr = auxv->a_un.a_ptr;
- break;
- case AT_ENTRY:
- bootaux[BA_ENTRY].ba_ptr = auxv->a_un.a_ptr;
- break;
- default:
- break;
- }
- }
-
-
- sh = (Shdr *)bootaux[BA_LDSHDR].ba_ptr;
- sh_num = ((Ehdr *)bootaux[BA_LDELF].ba_ptr)->e_shnum;
- /*
- * Make sure we won't overflow stack allocated cache
- */
- if (sh_num >= MAXSECT)
- return;
-
- /*
- * Build cache table for section addresses.
- */
- for (i = 0; i < sh_num; i++) {
- section[i] = sh++;
- }
-
- /*
- * Find the end of data
- * (to allocate bss)
- */
- phdr = (Phdr *)bootaux[BA_PHDR].ba_ptr;
-
- for (i = 0; i < bootaux[BA_PHNUM].ba_val; i++) {
- if (phdr->p_type == PT_LOAD &&
- (phdr->p_flags & PF_W) && (phdr->p_flags & PF_X)) {
- edata = end = phdr->p_vaddr + phdr->p_memsz;
- break;
- }
- phdr = (Phdr *)((ulong_t)phdr + bootaux[BA_PHENT].ba_val);
- }
- if (edata == NULL)
- return;
-
- /*
- * Find the symbol table, and then loop
- * through the symbols adjusting their
- * values to reflect where the sections
- * were loaded.
- */
- for (i = 1; i < sh_num; i++) {
- Shdr *shp;
- Sym *sp;
- ulong_t off;
-
- shp = section[i];
- if (shp->sh_type != SHT_SYMTAB)
- continue;
-
- for (off = 0; off < shp->sh_size; off += shp->sh_entsize) {
- sp = (Sym *)(shp->sh_addr + off);
-
- if (sp->st_shndx == SHN_ABS ||
- sp->st_shndx == SHN_UNDEF)
- continue;
-
- /*
- * Assign the addresses for COMMON
- * symbols even though we haven't
- * actually allocated bss yet.
- */
- if (sp->st_shndx == SHN_COMMON) {
- end = ALIGN(end, sp->st_value);
- sp->st_value = end;
- /*
- * Squirrel it away for later.
- */
- if (bootaux[BA_BSS].ba_val == 0)
- bootaux[BA_BSS].ba_val = end;
- end += sp->st_size;
- continue;
- } else if (sp->st_shndx > (Half)sh_num) {
- BSVC_PUTCHAR(syscallp, '>');
- return;
- }
-
- /*
- * Symbol's new address.
- */
- sp->st_value += section[sp->st_shndx]->sh_addr;
- }
- }
-
- /*
- * Allocate bss for COMMON, if any.
- */
- if (end > edata) {
- unsigned long va, bva;
- unsigned long asize;
- unsigned long align;
-
- if (bootaux[BA_LPAGESZ].ba_val) {
- asize = bootaux[BA_LPAGESZ].ba_val;
- align = bootaux[BA_LPAGESZ].ba_val;
- } else {
- asize = bootaux[BA_PAGESZ].ba_val;
- align = BO_NO_ALIGN;
- }
- va = roundup(edata, asize);
- bva = roundup(end, asize);
-
- if (bva > va) {
- bva = (unsigned long)BOP_ALLOC(bop, (caddr_t)va,
- bva - va, align);
- if (bva == NULL)
- return;
- }
- /*
- * Zero it.
- */
- for (va = edata; va < end; va++)
- *(char *)va = 0;
- /*
- * Update the size of data.
- */
- phdr->p_memsz += (end - edata);
- }
-
- /*
- * Relocate our own symbols. We'll handle the
- * undefined symbols later.
- */
- for (i = 1; i < sh_num; i++) {
- Shdr *rshp, *shp, *ssp;
- unsigned long baseaddr, reladdr, rend;
- long relocsize;
-
- rshp = section[i];
-
- if (rshp->sh_type != SHT_RELA)
- continue;
- /*
- * Get the section being relocated
- * and the symbol table.
- */
- shp = section[rshp->sh_info];
- ssp = section[rshp->sh_link];
-
- /*
- * Only perform relocations against allocatable
- * sections.
- */
- if ((shp->sh_flags & SHF_ALLOC) == 0)
- continue;
-
- reladdr = rshp->sh_addr;
- baseaddr = shp->sh_addr;
- rend = reladdr + rshp->sh_size;
- relocsize = rshp->sh_entsize;
- /*
- * Loop through relocations.
- */
-
- while (reladdr < rend) {
- Sym *symref;
- Rela *reloc;
- unsigned long stndx;
- unsigned long off, *offptr;
- long addend, value;
- unsigned long symoff, symsize;
- int rtype;
-
- reloc = (Rela *)reladdr;
- off = reloc->r_offset;
- addend = (long)reloc->r_addend;
- rtype = ELF_R_TYPE(reloc->r_info);
- stndx = ELF_R_SYM(reloc->r_info);
-
- reladdr += relocsize;
-
- if (rtype == R_AMD64_NONE)
- continue;
-
- off += baseaddr;
-
- symsize = ssp->sh_entsize;
- symoff = stndx * symsize;
-
- /*
- * Check for bad symbol index.
- */
- if (symoff > ssp->sh_size)
- return;
-
- symref = (Sym *)(ssp->sh_addr + symoff);
-
-
- /*
- * Just bind our own symbols at this point.
- */
- if (symref->st_shndx == SHN_UNDEF)
- continue;
-
- value = symref->st_value;
-
- if ((rtype == R_AMD64_PC32) ||
- (rtype == R_AMD64_PLT32))
- /*
- * If PC-relative, subtract ref addr.
- */
- value -= off;
- else if (rtype == R_AMD64_32) {
- /*
- * It's illegal to have any HIBITS
- * set for R_AMD64_32 reloc.
- */
- if (value & HIBITS) {
- BSVC_PUTCHAR(syscallp, 'h');
- return;
- }
- } else if (rtype == R_AMD64_32S) {
- /*
- * All HIBITS for R_AMD64_32S
- * *must* be set.
- */
- if ((value & HIBITS) != HIBITS) {
- BSVC_PUTCHAR(syscallp, 'H');
- return;
- }
- }
-
- offptr = (unsigned long *)off;
- /*
- * insert value calculated at reference point
- * 2 cases - normal byte order aligned, normal byte
- * order unaligned.
- */
- switch (rtype) {
- case R_AMD64_64:
- *(unsigned long *)offptr = value + addend;
- break;
- case R_AMD64_PC32:
- case R_AMD64_32S:
- case R_AMD64_PLT32:
- *(uint_t *)offptr = (uint_t)(value + addend);
- break;
- case R_AMD64_GOT32:
- BSVC_PUTCHAR(syscallp, 'G');
- return;
- case R_AMD64_32:
- return;
- default:
- BSVC_PUTCHAR(syscallp, 'R');
- return;
- }
- /*
- * We only need to do it once.
- */
- reloc->r_info = ELF_R_INFO(stndx, R_AMD64_NONE);
- } /* while */
- }
+ bootaux[BA_ENTRY].ba_ptr = (void *)_locore_start;
+ bootaux[BA_PAGESZ].ba_val = PAGESIZE;
+ bootaux[BA_LPAGESZ].ba_val = kbm_nucleus_size;
/*
- * Done relocating all of our *defined*
- * symbols, so we hand off.
+ * Off to krtld initialization.
*/
kobj_init(syscallp, dvec, bootops, bootaux);
}
diff --git a/usr/src/uts/intel/amd64/krtld/kobj_crt.s b/usr/src/uts/intel/amd64/krtld/kobj_crt.s
index 072a012c0c..16f90bd897 100644
--- a/usr/src/uts/intel/amd64/krtld/kobj_crt.s
+++ b/usr/src/uts/intel/amd64/krtld/kobj_crt.s
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -64,14 +63,7 @@ exitto(caddr_t entrypoint)
movq $ops, %rax
movq (%rax), %rdx
- movq boothowto, %rax
- andq $RB_DEBUGENTER, %rax
- jz 1f
-
- / Enter the debugger
- int $T_DBGENTR
-
-1: / Call destination
+ / Call destination
call *%r11
SET_SIZE(exitto)
diff --git a/usr/src/uts/intel/amd64/ml/amd64.il b/usr/src/uts/intel/amd64/ml/amd64.il
index 2648db8a13..e6b56fe7dd 100644
--- a/usr/src/uts/intel/amd64/ml/amd64.il
+++ b/usr/src/uts/intel/amd64/ml/amd64.il
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -60,35 +59,6 @@
.end
/
-/ return value of cr3 register
-/
- .inline getcr3,0
- movq %cr3, %rax
- .end
-
-/
-/ reload cr3 register with its current value
-/
- .inline reload_cr3,0
- movq %cr3, %rdi
- movq %rdi, %cr3
- .end
-
-/
-/ return value of cr8 register
-/
- .inline getcr8,0
- movq %cr8, %rax
- .end
-
-/
-/ set cr8 register
-/
- .inline setcr8,0
- movq %rdi, %cr8
- .end
-
-/
/ convert ipl to spl. This is the identity function for i86
/
.inline ipltospl,0
@@ -96,20 +66,6 @@
.end
/
-/ enable interrupts
-/
- .inline sti,0
- sti
- .end
-
-/
-/ disable interrupts
-/
- .inline cli,0
- cli
- .end
-
-/
/ find the low order bit in a word
/
.inline lowbit,4
@@ -119,77 +75,6 @@
.end
/
-/ disable interrupts and return value describing if interrupts were enabled
-/
- /* XX64 These don't work correctly with SOS9 build 13.0 yet
- .inline clear_int_flag,0
- pushfq
- cli
- popq %rax
- .end
-
- .inline intr_clear,0
- pushfq
- cli
- popq %rax
- .end
- */
-
-/
-/ restore interrupt enable flag to value returned from 'clear_int_flag' above
-/
- /* XX64 These don't work correctly with SOS9 build 13.0 yet
- .inline restore_int_flag,4
- pushq %rdi
- popfq
- .end
-
- .inline intr_restore,4
- pushq %rdi
- popfq
- .end
- */
-
-/
-/ in and out
-/
- .inline inb,4
- movq %rdi, %rdx
- xorq %rax, %rax
- inb (%dx)
- .end
-
- .inline inw,4
- movq %rdi, %rdx
- xorq %rax, %rax
- inw (%dx)
- .end
-
- .inline inl,4
- movq %rdi, %rdx
- xorq %rax, %rax
- inl (%dx)
- .end
-
- .inline outb,8
- movq %rdi, %rdx
- movq %rsi, %rax
- outb (%dx)
- .end
-
- .inline outw,8
- movq %rdi, %rdx
- movq %rsi, %rax
- outw (%dx)
- .end
-
- .inline outl,8
- movq %rdi, %rdx
- movq %rsi, %rax
- outl (%dx)
- .end
-
-/
/ Networking byte order functions (too bad, Intel has the wrong byte order)
/
@@ -274,22 +159,6 @@
.end
/*
- * Read Time Stamp Counter
- * uint64_t tsc_read();
- *
- * usage:
- * uint64_t cycles = tsc_read();
- *
- * PPro & PII take no less than 34 cycles to execute rdtsc + stores.
- * Pentium takes about 16 cycles.
- */
- .inline tsc_read, 0
- rdtsc / %edx:%eax = RDTSC
- shlq $32, %rdx
- orq %rdx, %rax
- .end
-
-/*
* Call the pause instruction. To the Pentium 4 Xeon processor, it acts as
* a hint that the code sequence is a busy spin-wait loop. Without a pause
* instruction in these loops, the P4 Xeon processor may suffer a severe
@@ -303,14 +172,28 @@
.end
/*
- * Call the halt instruction. This will put the CPU to sleep until
- * it is again awoken via an interrupt.
- * This function should be called with interrupts already disabled
- * for the CPU.
- * Note that "sti" will only enable interrupts at the end of the
- * subsequent instruction...in this case: "hlt".
+ * inlines for update_sregs().
*/
- .inline i86_halt,0
- sti
- hlt
+ .inline __set_ds, 0
+ movw %di, %ds
+ .end
+
+ .inline __set_es, 0
+ movw %di, %es
+ .end
+
+ .inline __set_fs, 0
+ movw %di, %fs
+ .end
+
+ .inline __set_gs, 0
+ movw %di, %gs
+ .end
+
+ /*
+ * OPTERON_ERRATUM_88 requires mfence
+ */
+ .inline __swapgs, 0
+ mfence
+ swapgs
.end
diff --git a/usr/src/uts/intel/amd64/ml/mach_offsets.in b/usr/src/uts/intel/amd64/ml/mach_offsets.in
index 2685e9ae1a..0e41e5c098 100644
--- a/usr/src/uts/intel/amd64/ml/mach_offsets.in
+++ b/usr/src/uts/intel/amd64/ml/mach_offsets.in
@@ -1,13 +1,12 @@
\
-\ Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+\ Copyright 2007 Sun Microsystems, Inc. All rights reserved.
\ Use is subject to license terms.
\
\ CDDL HEADER START
\
\ The contents of this file are subject to the terms of the
-\ Common Development and Distribution License, Version 1.0 only
-\ (the "License"). You may not use this file except in compliance
-\ with the License.
+\ Common Development and Distribution License (the "License").
+\ You may not use this file except in compliance with the License.
\
\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
\ or http://www.opensolaris.org/os/licensing.
@@ -78,8 +77,6 @@ regs REGSIZE
r_r13 REGOFF_R13
r_r14 REGOFF_R14
r_r15 REGOFF_R15
- r_fsbase REGOFF_FSBASE
- r_gsbase REGOFF_GSBASE
r_ds REGOFF_DS
r_es REGOFF_ES
r_fs REGOFF_FS
diff --git a/usr/src/uts/intel/amd64/sys/Makefile b/usr/src/uts/intel/amd64/sys/Makefile
index 4856f12a86..6662f96476 100644
--- a/usr/src/uts/intel/amd64/sys/Makefile
+++ b/usr/src/uts/intel/amd64/sys/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -31,6 +30,7 @@
include ../../../../Makefile.master
HDRS= \
+ kdi_regs.h \
privregs.h
ROOTINCISA= $(ROOT)/usr/include/amd64
diff --git a/usr/src/uts/intel/amd64/sys/kdi_regs.h b/usr/src/uts/intel/amd64/sys/kdi_regs.h
new file mode 100644
index 0000000000..d3dc3dced1
--- /dev/null
+++ b/usr/src/uts/intel/amd64/sys/kdi_regs.h
@@ -0,0 +1,97 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _AMD64_SYS_KDI_REGS_H
+#define _AMD64_SYS_KDI_REGS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define KDIREG_NGREG 31
+
+/*
+ * A modified version of struct regs layout.
+ */
+
+#define KDIREG_SAVFP 0
+#define KDIREG_SAVPC 1
+#define KDIREG_RDI 2
+#define KDIREG_RSI 3
+#define KDIREG_RDX 4
+#define KDIREG_RCX 5
+#define KDIREG_R8 6
+#define KDIREG_R9 7
+#define KDIREG_RAX 8
+#define KDIREG_RBX 9
+#define KDIREG_RBP 10
+#define KDIREG_R10 11
+#define KDIREG_R11 12
+#define KDIREG_R12 13
+#define KDIREG_R13 14
+#define KDIREG_R14 15
+#define KDIREG_R15 16
+#define KDIREG_FSBASE 17
+#define KDIREG_GSBASE 18
+#define KDIREG_KGSBASE 19
+#define KDIREG_DS 20
+#define KDIREG_ES 21
+#define KDIREG_FS 22
+#define KDIREG_GS 23
+#define KDIREG_TRAPNO 24
+#define KDIREG_ERR 25
+#define KDIREG_RIP 26
+#define KDIREG_CS 27
+#define KDIREG_RFLAGS 28
+#define KDIREG_RSP 29
+#define KDIREG_SS 30
+
+#define KDIREG_PC KDIREG_RIP
+#define KDIREG_SP KDIREG_RSP
+#define KDIREG_FP KDIREG_RBP
+
+#ifdef _ASM
+
+/* Patch point for MSR clearing. */
+#define KDI_MSR_PATCH \
+ nop; nop; nop; nop; \
+ nop; nop; nop; nop; \
+ nop; nop; nop; nop; \
+ nop; nop; nop; nop; \
+ nop
+
+#endif /* _ASM */
+
+#define KDI_MSR_PATCHOFF 8 /* bytes of code before patch point */
+#define KDI_MSR_PATCHSZ 17 /* bytes in KDI_MSR_PATCH, above */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _AMD64_SYS_KDI_REGS_H */
diff --git a/usr/src/uts/intel/amd64/sys/privregs.h b/usr/src/uts/intel/amd64/sys/privregs.h
index e10b471de4..38672670fe 100644
--- a/usr/src/uts/intel/amd64/sys/privregs.h
+++ b/usr/src/uts/intel/amd64/sys/privregs.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,17 +18,18 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#ifndef _AMD64_SYS_PRIVREGS_H
+#ifndef _AMD64_SYS_PRIVREGS_H
#define _AMD64_SYS_PRIVREGS_H
#pragma ident "%Z%%M% %I% %E% SMI"
-#ifdef __cplusplus
+#ifdef __cplusplus
extern "C" {
#endif
@@ -42,7 +42,7 @@ extern "C" {
#error "non-amd64 code depends on amd64 privileged header!"
#endif
-#ifndef _ASM
+#ifndef _ASM
/*
* This is NOT the structure to use for general purpose debugging;
@@ -77,8 +77,16 @@ struct regs {
greg_t r_r14; /* callee-saved */
greg_t r_r15; /* callee-saved */
- greg_t r_fsbase;
- greg_t r_gsbase;
+ /*
+ * XX64
+ * We used to sample fsbase and gsbase on every exception
+ * with expensive rdmsr's. Yet this was only useful at
+ * best for debugging during amd64 bringup. We should take
+ * these away but for now simply rename them to avoid any
+ * flag days.
+ */
+ greg_t __r_fsbase; /* XX64 no longer used by the kernel */
+ greg_t __r_gsbase; /* XX64 no longer used by the kernel */
greg_t r_ds;
greg_t r_es;
greg_t r_fs; /* %fs is *never* used by the kernel */
@@ -106,22 +114,19 @@ struct regs {
#ifdef _KERNEL
#define lwptoregs(lwp) ((struct regs *)((lwp)->lwp_regs))
-#endif /* _KERNEL */
+#endif /* _KERNEL */
#else /* !_ASM */
-#define TRAPERR_PUSH(err, trapno) \
- pushq $err; \
- pushq $trapno
+#if defined(_MACHDEP)
+
+#include <sys/machprivregs.h>
+#include <sys/pcb.h>
/*
* Create a struct regs on the stack suitable for an
* interrupt trap.
*
- * The swapgs instruction is conditionalized to make sure that
- * interrupts in kernel mode don't cause us to switch back to
- * the user's gsbase!
- *
* Assumes that the trap handler has already pushed an
* appropriate r_err and r_trapno
*/
@@ -152,44 +157,9 @@ struct regs {
movw %es, %cx; \
movq %rcx, REGOFF_ES(%rsp); \
movw %ds, %cx; \
- movq %rcx, REGOFF_DS(%rsp); \
- movl $MSR_AMD_FSBASE, %ecx; \
- rdmsr; \
- movl %eax, REGOFF_FSBASE(%rsp); \
- movl %edx, REGOFF_FSBASE+4(%rsp); \
- movl $MSR_AMD_GSBASE, %ecx; \
- rdmsr; \
- movl %eax, REGOFF_GSBASE(%rsp); \
- movl %edx, REGOFF_GSBASE+4(%rsp)
-
-/*
- * Push register state onto the stack. If we've
- * interrupted userland, do a swapgs as well.
- */
-
-#define INTR_PUSH \
- subq $REGOFF_TRAPNO, %rsp; \
- __SAVE_REGS; \
- cmpw $KCS_SEL, REGOFF_CS(%rsp); \
- je 6f; \
- movq $0, REGOFF_SAVFP(%rsp); \
- swapgs; \
-6:
-
-#define TRAP_PUSH \
- subq $REGOFF_TRAPNO, %rsp; \
- __SAVE_REGS; \
- cmpw $KCS_SEL, REGOFF_CS(%rsp); \
- je 6f; \
- movq $0, REGOFF_SAVFP(%rsp); \
- swapgs; \
-6:
+ movq %rcx, REGOFF_DS(%rsp)
-#define DFTRAP_PUSH \
- subq $REGOFF_TRAPNO, %rsp; \
- __SAVE_REGS
-
-#define __RESTORE_REGS \
+#define __RESTORE_REGS \
movq REGOFF_RDI(%rsp), %rdi; \
movq REGOFF_RSI(%rsp), %rsi; \
movq REGOFF_RDX(%rsp), %rdx; \
@@ -206,6 +176,19 @@ struct regs {
movq REGOFF_R14(%rsp), %r14; \
movq REGOFF_R15(%rsp), %r15
+/*
+ * Push register state onto the stack. If we've
+ * interrupted userland, do a swapgs as well.
+ */
+#define INTR_PUSH \
+ subq $REGOFF_TRAPNO, %rsp; \
+ __SAVE_REGS; \
+ cmpw $KCS_SEL, REGOFF_CS(%rsp); \
+ je 6f; \
+ movq $0, REGOFF_SAVFP(%rsp); \
+ SWAPGS; \
+6: CLEAN_CS
+
#define INTR_POP \
leaq sys_lcall32(%rip), %r11;\
cmpq %r11, REGOFF_RIP(%rsp); \
@@ -213,12 +196,12 @@ struct regs {
je 5f; \
cmpw $KCS_SEL, REGOFF_CS(%rsp);\
je 8f; \
-5: swapgs; \
+5: SWAPGS; \
8: addq $REGOFF_RIP, %rsp
#define USER_POP \
__RESTORE_REGS; \
- swapgs; \
+ SWAPGS; \
addq $REGOFF_RIP, %rsp /* Adjust %rsp to prepare for iretq */
#define USER32_POP \
@@ -229,51 +212,23 @@ struct regs {
movl REGOFF_RAX(%rsp), %eax; \
movl REGOFF_RBX(%rsp), %ebx; \
movl REGOFF_RBP(%rsp), %ebp; \
- swapgs; \
+ SWAPGS; \
addq $REGOFF_RIP, %rsp /* Adjust %rsp to prepare for iretq */
+#define DFTRAP_PUSH \
+ subq $REGOFF_TRAPNO, %rsp; \
+ __SAVE_REGS
+
+#endif /* _MACHDEP */
/*
- * Smaller versions of INTR_PUSH and INTR_POP for fast traps.
- * The following registers have been pushed onto the stack by
- * hardware at this point:
- *
- * greg_t r_rip;
- * greg_t r_cs;
- * greg_t r_rfl;
- * greg_t r_rsp;
- * greg_t r_ss;
- *
- * This handler is executed both by 32-bit and 64-bit applications.
- * 64-bit applications allow us to treat the set (%rdi, %rsi, %rdx,
- * %rcx, %r8, %r9, %r10, %r11, %rax) as volatile across function calls.
- * However, 32-bit applications only expect (%eax, %edx, %ecx) to be volatile
- * across a function call -- in particular, %esi and %edi MUST be saved!
- *
- * We could do this differently by making a FAST_INTR_PUSH32 for 32-bit
- * programs, and FAST_INTR_PUSH for 64-bit programs, but it doesn't seem
- * particularly worth it.
+ * Used to set rflags to known values at the head of an
+ * interrupt gate handler, i.e. interrupts are -already- disabled.
*/
-#define FAST_INTR_PUSH \
- subq $REGOFF_RIP, %rsp; \
- movq %rsi, REGOFF_RSI(%rsp); \
- movq %rdi, REGOFF_RDI(%rsp); \
- swapgs
-
-#define FAST_INTR_POP \
- swapgs; \
- movq REGOFF_RSI(%rsp), %rsi; \
- movq REGOFF_RDI(%rsp), %rdi; \
- addq $REGOFF_RIP, %rsp
-
-#define DISABLE_INTR_FLAGS \
+#define INTGATE_INIT_KERNEL_FLAGS \
pushq $F_OFF; \
popfq
-#define ENABLE_INTR_FLAGS \
- pushq $F_ON; \
- popfq
-
#endif /* !_ASM */
#include <sys/controlregs.h>
@@ -322,7 +277,7 @@ extern void setcr8(ulong_t);
#define CREG_KGSBASE 0x58
#define CREG_EFER 0x60
-#if !defined(_ASM)
+#if !defined(_ASM) && defined(_INT64_TYPE)
typedef uint64_t creg64_t;
typedef upad128_t creg128_t;
@@ -345,10 +300,10 @@ struct cregs {
extern void getcregs(struct cregs *);
#endif /* _KERNEL */
-#endif /* _ASM */
+#endif /* !_ASM && _INT64_TYPE */
-#ifdef __cplusplus
+#ifdef __cplusplus
}
#endif
-#endif /* _AMD64_SYS_PRIVREGS_H */
+#endif /* !_AMD64_SYS_PRIVREGS_H */
diff --git a/usr/src/uts/i86pc/amd64_gart/Makefile b/usr/src/uts/intel/amd64_gart/Makefile
index 6fd4b8253c..f2a2200b0e 100644
--- a/usr/src/uts/i86pc/amd64_gart/Makefile
+++ b/usr/src/uts/intel/amd64_gart/Makefile
@@ -1,8 +1,8 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# uts/i86pc/amd64_gart/Makefile
+# uts/intel/amd64_gart/Makefile
#
#
#ident "%Z%%M% %I% %E% SMI"
@@ -21,12 +21,12 @@ UTSBASE = ../..
MODULE = amd64_gart
OBJECTS = $(AMD64GART_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(AMD64GART_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -59,4 +59,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/ata/Makefile b/usr/src/uts/intel/ata/Makefile
index d84a07337b..bbeff258b6 100644
--- a/usr/src/uts/i86pc/ata/Makefile
+++ b/usr/src/uts/intel/ata/Makefile
@@ -18,9 +18,9 @@
#
# CDDL HEADER END
#
-# uts/i86pc/ata/Makefile
+# uts/intel/ata/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -28,7 +28,7 @@
# This makefile drives the production of the ata "drv"
# kernel module.
#
-# i86pc implementation architecture dependent
+# intel architecture dependent
#
#
@@ -42,13 +42,13 @@ UTSBASE = ../..
MODULE = ata
OBJECTS = $(ATA_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(ATA_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
CONF_SRCDIR = $(UTSBASE)/intel/io/dktp/controller/ata
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -98,4 +98,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/audio810/Makefile b/usr/src/uts/intel/audio810/Makefile
index 13bb6fdaa6..f358574423 100644
--- a/usr/src/uts/i86pc/audio810/Makefile
+++ b/usr/src/uts/intel/audio810/Makefile
@@ -19,10 +19,10 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# uts/i86pc/audio810/Makefile
+# uts/intel/audio810/Makefile
#
#
# ident "%Z%%M% %I% %E% SMI"
@@ -50,7 +50,7 @@ WLCMD_DIR = $(UTSBASE)/common/io/warlock
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Overrides, lint pass one enforcement
@@ -104,7 +104,7 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
#
# Defines for local commands.
diff --git a/usr/src/uts/i86pc/audiohd/Makefile b/usr/src/uts/intel/audiohd/Makefile
index 303f226006..902427571d 100644
--- a/usr/src/uts/i86pc/audiohd/Makefile
+++ b/usr/src/uts/intel/audiohd/Makefile
@@ -19,10 +19,10 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# uts/i86pc/audiohd/Makefile
+# uts/intel/audiohd/Makefile
#
#
# ident "%Z%%M% %I% %E% SMI"
@@ -50,7 +50,7 @@ WLCMD_DIR = $(UTSBASE)/common/io/warlock
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Overrides, lint pass one enforcement
@@ -105,7 +105,7 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
#
# Defines for local commands.
diff --git a/usr/src/uts/i86pc/audioixp/Makefile b/usr/src/uts/intel/audioixp/Makefile
index e9ebba4c81..1f52255abb 100644
--- a/usr/src/uts/i86pc/audioixp/Makefile
+++ b/usr/src/uts/intel/audioixp/Makefile
@@ -19,10 +19,10 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# uts/i86pc/audioixp/Makefile
+# uts/intel/audioixp/Makefile
#
#
#ident "%Z%%M% %I% %E% SMI"
@@ -50,7 +50,7 @@ WLCMD_DIR = $(UTSBASE)/common/io/warlock
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Overrides, lint pass one enforcement
@@ -104,7 +104,7 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
#
# Defines for local commands.
diff --git a/usr/src/uts/i86pc/bootdev/Makefile b/usr/src/uts/intel/bootdev/Makefile
index 62989fce66..18705fe8f1 100644
--- a/usr/src/uts/i86pc/bootdev/Makefile
+++ b/usr/src/uts/intel/bootdev/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
# CDDL HEADER END
#
#
-# uts/i86pc/bootdev/Makefile
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# uts/intel/bootdev/Makefile
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -29,7 +28,7 @@
# This makefile drives the production of the bootdev driver
# kernel module.
#
-# i86pc architecture dependent
+# intel architecture dependent
#
#
@@ -43,12 +42,12 @@ UTSBASE = ../..
MODULE = bootdev
OBJECTS = $(BOOTDEV_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(BOOTDEV_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_MISC_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_MISC_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -81,4 +80,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/intel/ctf/Makefile b/usr/src/uts/intel/ctf/Makefile
index 57a944ef02..ecd389f7a6 100644
--- a/usr/src/uts/intel/ctf/Makefile
+++ b/usr/src/uts/intel/ctf/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -38,7 +38,7 @@ LINT_TARGET = $(MODULE).lint
INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
CPPFLAGS += -I$(SRC)/common/ctf -DCTF_OLD_VERSIONS
-LDFLAGS += -Breduce -M$(UTSBASE)/common/ctf/mapfile -dy -Nmisc/zmod
+LDFLAGS += -Breduce -M$(UTSBASE)/common/ctf/mapfile -dy
#
# For now, disable these lint checks; maintainers should endeavor
diff --git a/usr/src/uts/i86pc/dnet/Makefile b/usr/src/uts/intel/dnet/Makefile
index 55ad49a0e9..14e60e5c40 100644
--- a/usr/src/uts/i86pc/dnet/Makefile
+++ b/usr/src/uts/intel/dnet/Makefile
@@ -19,9 +19,9 @@
# CDDL HEADER END
#
#
-# uts/i86pc/dnet/Makefile
+# uts/intel/dnet/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -29,7 +29,7 @@
# This makefile drives the production of the dnet
# network driver kernel module.
#
-# i86pc architecture dependent
+# intel architecture dependent
#
#
@@ -44,12 +44,12 @@ MODULE = dnet
OBJECTS = $(DNET_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(DNET_OBJS:%.o=$(LINTS_DIR)/%.ln)
ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/i86pc/io
+CONF_SRCDIR = $(UTSBASE)/intel/io
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -102,4 +102,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/drm/Makefile b/usr/src/uts/intel/drm/Makefile
index 34f70fe829..0af49425f9 100644
--- a/usr/src/uts/i86pc/drm/Makefile
+++ b/usr/src/uts/intel/drm/Makefile
@@ -18,9 +18,9 @@
#
# CDDL HEADER END
#
-# uts/i86pc/drm/Makefile
+# uts/intel/drm/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -38,7 +38,7 @@ UTSBASE = ../..
MODULE = drm
OBJECTS = $(DRM_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(DRM_OBJS:%.o=$(LINTS_DIR)/%.ln)
-DRM_SRC = $(UTSBASE)/i86pc/io/drm
+DRM_SRC = $(UTSBASE)/intel/io/drm
ROOTMODULE = $(ROOT_MISC_DIR)/$(MODULE)
INC_PATH += -I$(DRM_SRC)
CMN_DRM_SRC = $(UTSBASE)/common/io/drm
@@ -47,7 +47,7 @@ CONF_SRCDIR = $(UTSBASE)/common/io/drm
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -88,4 +88,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/intel/dtrace/dtrace_isa.c b/usr/src/uts/intel/dtrace/dtrace_isa.c
index 3d7144350e..2b40fd40cb 100644
--- a/usr/src/uts/intel/dtrace/dtrace_isa.c
+++ b/usr/src/uts/intel/dtrace/dtrace_isa.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,17 +33,6 @@
#include <sys/privregs.h>
#include <sys/sysmacros.h>
-/*
- * This is gross knowledge to have to encode here...
- */
-extern void _interrupt();
-extern void _cmntrap();
-extern void _allsyscalls();
-
-extern size_t _interrupt_size;
-extern size_t _cmntrap_size;
-extern size_t _allsyscalls_size;
-
extern uintptr_t kernelbase;
void
diff --git a/usr/src/uts/intel/dtrace/fasttrap_isa.c b/usr/src/uts/intel/dtrace/fasttrap_isa.c
index c8f222e429..99301192e7 100644
--- a/usr/src/uts/intel/dtrace/fasttrap_isa.c
+++ b/usr/src/uts/intel/dtrace/fasttrap_isa.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,7 @@
#include <sys/regset.h>
#include <sys/privregs.h>
#include <sys/segments.h>
+#include <sys/x86_archext.h>
#include <sys/sysmacros.h>
#include <sys/trap.h>
#include <sys/archsystm.h>
@@ -1711,8 +1712,8 @@ fasttrap_getreg(struct regs *rp, uint_t reg)
case REG_GS: return (rp->r_gs);
case REG_DS: return (rp->r_ds);
case REG_ES: return (rp->r_es);
- case REG_FSBASE: return (rp->r_fsbase);
- case REG_GSBASE: return (rp->r_gsbase);
+ case REG_FSBASE: return (rdmsr(MSR_AMD_FSBASE));
+ case REG_GSBASE: return (rdmsr(MSR_AMD_GSBASE));
}
panic("dtrace: illegal register constant");
diff --git a/usr/src/uts/intel/dtrace/fbt.c b/usr/src/uts/intel/dtrace/fbt.c
index 5594958f47..78374511a2 100644
--- a/usr/src/uts/intel/dtrace/fbt.c
+++ b/usr/src/uts/intel/dtrace/fbt.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -607,22 +607,26 @@ fbt_getargdesc(void *arg, dtrace_id_t id, void *parg, dtrace_argdesc_t *desc)
* If we have a parent container, we must manually import it.
*/
if ((parent = ctf_parent_name(fp)) != NULL) {
- struct modctl *mod;
+ struct modctl *mp = &modules;
+ struct modctl *mod = NULL;
/*
* We must iterate over all modules to find the module that
* is our parent.
*/
- for (mod = &modules; mod != NULL; mod = mod->mod_next) {
- if (strcmp(mod->mod_filename, parent) == 0)
+ do {
+ if (strcmp(mp->mod_modname, parent) == 0) {
+ mod = mp;
break;
- }
+ }
+ } while ((mp = mp->mod_next) != &modules);
if (mod == NULL)
goto err;
- if ((pfp = ctf_modopen(mod->mod_mp, &error)) == NULL)
+ if ((pfp = ctf_modopen(mod->mod_mp, &error)) == NULL) {
goto err;
+ }
if (ctf_import(fp, pfp) != 0) {
ctf_close(pfp);
diff --git a/usr/src/uts/i86pc/fd/Makefile b/usr/src/uts/intel/fd/Makefile
index eb39f9158b..675cc9740a 100644
--- a/usr/src/uts/i86pc/fd/Makefile
+++ b/usr/src/uts/intel/fd/Makefile
@@ -19,16 +19,16 @@
# CDDL HEADER END
#
#
-# uts/i86pc/fd/Makefile
+# uts/intel/fd/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
#
# This makefile drives the production of the floppy driver
#
-# i86pc implementation architecture dependent
+# intel architecture dependent
#
#
@@ -42,13 +42,13 @@ UTSBASE = ../..
MODULE = fd
OBJECTS = $(FD_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(FD_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/i86pc/io
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
+CONF_SRCDIR = $(UTSBASE)/intel/io
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -94,4 +94,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/fdc/Makefile b/usr/src/uts/intel/fdc/Makefile
index 091cbd4a00..2ea0866fa5 100644
--- a/usr/src/uts/i86pc/fdc/Makefile
+++ b/usr/src/uts/intel/fdc/Makefile
@@ -19,16 +19,16 @@
# CDDL HEADER END
#
#
-# uts/i86pc/fdc/Makefile
+# uts/intel/fdc/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
#
# This makefile drives the production of the floppy controller dirver
#
-# i86pc implementation architecture dependent
+# intel architecture dependent
#
#
@@ -42,13 +42,13 @@ UTSBASE = ../..
MODULE = fdc
OBJECTS = $(FDC_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(FDC_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
CONF_SRCDIR = $(UTSBASE)/common/io
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -93,4 +93,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/intel/fs/proc/prmachdep.c b/usr/src/uts/intel/fs/proc/prmachdep.c
index 12f0a52da4..f9a9fc3247 100644
--- a/usr/src/uts/intel/fs/proc/prmachdep.c
+++ b/usr/src/uts/intel/fs/proc/prmachdep.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -59,8 +58,6 @@
#include <sys/debugreg.h>
#include <sys/copyops.h>
-#include <sys/mmu.h>
-#include <sys/pte.h>
#include <sys/vmem.h>
#include <sys/mman.h>
#include <sys/vmparam.h>
diff --git a/usr/src/uts/intel/genunix/Makefile b/usr/src/uts/intel/genunix/Makefile
index 90b6fd56fb..d4286bbfe3 100644
--- a/usr/src/uts/intel/genunix/Makefile
+++ b/usr/src/uts/intel/genunix/Makefile
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -118,7 +118,15 @@ modlintlib: $(MODLINTLIB_DEPS)
clean.lint: $(CLEAN_LINT_DEPS)
+#
+# if test is an ugly hack for race where genunix
+# doesn't install sometimes
+#
install: $(INSTALL_DEPS)
+ if [ ! -f "$(ROOT_KERN_DIR)/$(MODULE)" -o \
+ ! -f "$(ROOT_KERN_DIR)/amd64/$(MODULE)" ]; then \
+ $(MAKE) install; \
+ fi;
$(LIBGEN): $(GENUNIX) $(LIBSTUBS)
$(BUILD.SO) $(GENUNIX) $(LIBSTUBS)
diff --git a/usr/src/uts/i86pc/i915/Makefile b/usr/src/uts/intel/i915/Makefile
index a40f16cfe6..4118f40dd3 100644
--- a/usr/src/uts/i86pc/i915/Makefile
+++ b/usr/src/uts/intel/i915/Makefile
@@ -20,18 +20,18 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
#
-# uts/i86pc/drm_i915/Makefile
+# uts/intel/drm_i915/Makefile
#
# This makefile drives the production of i915 graphics device driver,
# which supports the DRI (Direct Rendering Infrastructure), with the help
# of drm common misc module.
#
-# i86pc platform dependent
+# intel platform dependent
#
# Path to the base of the uts directory tree (usually /usr/src/uts).
#
@@ -43,7 +43,7 @@ UTSBASE = ../..
MODULE = i915
OBJECTS = $(I915_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(I915_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
I915_DRV_O = $(OBJS_DIR)/i915_drv.o
I915_DRV_C = $(PSM_DRM_SRC)/i915_drv.c
DRM_PCIIDS_H = $(CMN_DRM_SRC)/drm_pciids.h
@@ -51,12 +51,12 @@ DRM_PCIIDS_TXT = $(CMN_DRM_SRC)/drm_pciids.txt
CREATE_SUNOS_PCI_LISTS_SH = $(CMN_DRM_SRC)/create_sunos_pci_lists.sh
# i915 driver depends on drm, agpmaster and gfx_private misc modules
-INC_PATH += -I$(UTSBASE)/i86pc/io/drm \
+INC_PATH += -I$(UTSBASE)/intel/io/drm \
-I$(UTSBASE)/common/io/drm \
- -I$(UTSBASE)/i86pc/io/agpmaster \
+ -I$(UTSBASE)/intel/io/agpmaster \
-I$(UTSBASE)/i86pc/io/gfx_private
-PSM_DRM_SRC = $(UTSBASE)/i86pc/io/drm
+PSM_DRM_SRC = $(UTSBASE)/intel/io/drm
CMN_DRM_SRC = $(UTSBASE)/common/io/drm
#
@@ -67,7 +67,7 @@ LDFLAGS += -dy -Nmisc/drm -Nmisc/agpmaster -Nmisc/gfx_private \
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Re-define targets to add drm_pciids.h dependency
@@ -119,4 +119,4 @@ $(DRM_PCIIDS_H): $(DRM_PCIIDS_TXT)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/intel/ia32/krtld/kobj_boot.c b/usr/src/uts/intel/ia32/krtld/kobj_boot.c
index 3e52f347d1..a65721d82c 100644
--- a/usr/src/uts/intel/ia32/krtld/kobj_boot.c
+++ b/usr/src/uts/intel/ia32/krtld/kobj_boot.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,46 +34,22 @@
#include <sys/link.h>
#include <sys/auxv.h>
#include <sys/kobj.h>
-#include <sys/elf.h>
#include <sys/bootsvcs.h>
#include <sys/kobj_impl.h>
-
-#if !defined(__GNUC__)
+#include <vm/kboot_mmu.h>
/*
- * We don't use the global offset table, but
- * ld may throw in an UNDEFINED reference in
- * our symbol table.
+ * the kernel's entry point (from locore.s)
*/
-
-#pragma weak _GLOBAL_OFFSET_TABLE_
-
-#else
+extern void _locore_start();
/*
- * We -do- use the global offset table, but only by
- * accident -- when you tell gcc to emit PIC code,
- * it -always- generates a reference to the GOT in
- * a register, even if the compilation unit never
- * uses it.
+ * fakebop transfers control here.
*
- * Rumoured to be fixed in a later version of gcc..
- */
-
-long _GLOBAL_OFFSET_TABLE_[1];
-
-#endif
-
-#define MASK(n) ((1<<(n))-1)
-#define IN_RANGE(v, n) ((-(1<<((n)-1))) <= (v) && (v) < (1<<((n)-1)))
-
-#define roundup ALIGN
-
-/*
- * Boot transfers control here. At this point,
- * we haven't relocated our own symbols, so the
- * world (as we know it) is pretty small right now.
+ * fakebop and dboot don't construct any boot vector or aux vector information.
+ * We figure all this out for ourself instead.
*/
+/*ARGSUSED3*/
void
_kobj_boot(
struct boot_syscalls *syscallp,
@@ -81,317 +57,18 @@ _kobj_boot(
struct bootops *bootops,
Boot *ebp)
{
- Shdr *section[24]; /* cache */
val_t bootaux[BA_NUM];
- struct bootops *bop;
- Phdr *phdr;
- auxv_t *auxv = NULL;
- Shdr *sh;
- Half sh_num;
- uint_t end, edata = 0;
int i;
- bop = (dvec) ? *(struct bootops **)bootops : bootops;
-
for (i = 0; i < BA_NUM; i++)
bootaux[i].ba_val = NULL;
- /*
- * Check the bootstrap vector.
- */
- for (; ebp->eb_tag != EB_NULL; ebp++) {
- switch (ebp->eb_tag) {
- case EB_AUXV:
- auxv = (auxv_t *)ebp->eb_un.eb_ptr;
- break;
- case EB_DYNAMIC:
- bootaux[BA_DYNAMIC].ba_ptr = (void *)ebp->eb_un.eb_ptr;
- break;
- default:
- break;
- }
- }
-
- if (auxv == NULL)
- return;
-
- /*
- * Now the aux vector.
- */
- for (; auxv->a_type != AT_NULL; auxv++) {
- switch (auxv->a_type) {
- case AT_PHDR:
- bootaux[BA_PHDR].ba_ptr = auxv->a_un.a_ptr;
- break;
- case AT_PHENT:
- bootaux[BA_PHENT].ba_val = auxv->a_un.a_val;
- break;
- case AT_PHNUM:
- bootaux[BA_PHNUM].ba_val = auxv->a_un.a_val;
- break;
- case AT_PAGESZ:
- bootaux[BA_PAGESZ].ba_val = auxv->a_un.a_val;
- break;
- case AT_SUN_LDELF:
- bootaux[BA_LDELF].ba_ptr = auxv->a_un.a_ptr;
- break;
- case AT_SUN_LDSHDR:
- bootaux[BA_LDSHDR].ba_ptr = auxv->a_un.a_ptr;
- break;
- case AT_SUN_LDNAME:
- bootaux[BA_LDNAME].ba_ptr = auxv->a_un.a_ptr;
- break;
- case AT_SUN_LPAGESZ:
- bootaux[BA_LPAGESZ].ba_val = auxv->a_un.a_val;
- break;
- case AT_SUN_CPU:
- bootaux[BA_CPU].ba_ptr = auxv->a_un.a_ptr;
- break;
- case AT_SUN_MMU:
- bootaux[BA_MMU].ba_ptr = auxv->a_un.a_ptr;
- break;
- case AT_ENTRY:
- bootaux[BA_ENTRY].ba_ptr = auxv->a_un.a_ptr;
- break;
- default:
- break;
- }
- }
-
- sh = (Shdr *)bootaux[BA_LDSHDR].ba_ptr;
- sh_num = ((Ehdr *)bootaux[BA_LDELF].ba_ptr)->e_shnum;
- /*
- * Build cache table for section addresses.
- */
- for (i = 0; i < sh_num; i++) {
- section[i] = sh++;
- }
-
- /*
- * Find the end of data
- * (to allocate bss)
- */
- phdr = (Phdr *)bootaux[BA_PHDR].ba_ptr;
- for (i = 0; i < bootaux[BA_PHNUM].ba_val; i++) {
- if (phdr->p_type == PT_LOAD &&
- (phdr->p_flags & PF_W) && (phdr->p_flags & PF_X)) {
- edata = end = phdr->p_vaddr + phdr->p_memsz;
- break;
- }
- phdr = (Phdr *)((ulong_t)phdr + bootaux[BA_PHENT].ba_val);
- }
- if (edata == NULL)
- return;
-
- /*
- * Find the symbol table, and then loop
- * through the symbols adjusting their
- * values to reflect where the sections
- * were loaded.
- */
- for (i = 1; i < sh_num; i++) {
- Shdr *shp;
- Sym *sp;
- uint_t off;
-
- shp = section[i];
- if (shp->sh_type != SHT_SYMTAB)
- continue;
-
- for (off = 0; off < shp->sh_size; off += shp->sh_entsize) {
- sp = (Sym *)(shp->sh_addr + off);
-
- if (sp->st_shndx == SHN_ABS ||
- sp->st_shndx == SHN_UNDEF)
- continue;
- /*
- * Assign the addresses for COMMON
- * symbols even though we haven't
- * actually allocated bss yet.
- */
- if (sp->st_shndx == SHN_COMMON) {
- end = ALIGN(end, sp->st_value);
- sp->st_value = end;
- /*
- * Squirrel it away for later.
- */
- if (bootaux[BA_BSS].ba_val == 0)
- bootaux[BA_BSS].ba_val = end;
- end += sp->st_size;
- continue;
- } else if (sp->st_shndx > (Half)sh_num) {
- BSVC_PUTCHAR(syscallp, '>');
- return;
- }
-
- /*
- * Symbol's new address.
- */
- sp->st_value += section[sp->st_shndx]->sh_addr;
- }
- }
-
- /*
- * Allocate bss for COMMON, if any.
- */
- if (end > edata) {
- unsigned long va, bva;
- unsigned long asize;
- unsigned long align;
-
- if (bootaux[BA_LPAGESZ].ba_val) {
- asize = bootaux[BA_LPAGESZ].ba_val;
- align = bootaux[BA_LPAGESZ].ba_val;
- } else {
- asize = bootaux[BA_PAGESZ].ba_val;
- align = BO_NO_ALIGN;
- }
- va = roundup(edata, asize);
- bva = roundup(end, asize);
-
- if (bva > va) {
- bva = (unsigned long)BOP_ALLOC(bop, (caddr_t)va,
- bva - va, align);
- if (bva == NULL)
- return;
- }
- /*
- * Zero it.
- */
- for (va = edata; va < end; va++)
- *(char *)va = 0;
- /*
- * Update the size of data.
- */
- phdr->p_memsz += (end - edata);
- }
-
- /*
- * Relocate our own symbols. We'll handle the
- * undefined symbols later.
- */
- for (i = 1; i < sh_num; i++) {
- Shdr *rshp, *shp, *ssp;
- unsigned long baseaddr, reladdr, rend;
- int relocsize;
-
- rshp = section[i];
-
- if (rshp->sh_type != SHT_REL)
- continue;
- /*
- * Get the section being relocated
- * and the symbol table.
- */
- shp = section[rshp->sh_info];
- ssp = section[rshp->sh_link];
-
- reladdr = rshp->sh_addr;
- baseaddr = shp->sh_addr;
- rend = reladdr + rshp->sh_size;
- relocsize = rshp->sh_entsize;
- /*
- * Loop through relocations.
- */
- while (reladdr < rend) {
- Sym *symref;
- Rel *reloc;
- unsigned long stndx;
- unsigned long off, *offptr;
- long value;
- int rtype;
-
- reloc = (Rel *)reladdr;
- off = reloc->r_offset;
- rtype = ELF32_R_TYPE(reloc->r_info);
- stndx = ELF32_R_SYM(reloc->r_info);
-
- reladdr += relocsize;
-
- if (rtype == R_386_NONE) {
- continue;
- }
- off += baseaddr;
-
- if (rtype == R_386_RELATIVE) {
- /*
- * add base addr to reloc location
- */
- value = baseaddr;
- } else {
- unsigned int symoff, symsize;
-
- symsize = ssp->sh_entsize;
-
- for (symoff = 0; stndx; stndx--)
- symoff += symsize;
- symref = (Sym *)(ssp->sh_addr + symoff);
-
- /*
- * Check for bad symbol index.
- */
- if (symoff > ssp->sh_size)
- return;
-
- /*
- * Just bind our own symbols at this point.
- */
- if (symref->st_shndx == SHN_UNDEF) {
- continue;
- }
-
- value = symref->st_value;
- if (ELF32_ST_BIND(symref->st_info) !=
- STB_LOCAL) {
- /*
- * If PC-relative, subtract ref addr.
- */
- if (rtype == R_386_PC32 ||
- rtype == R_386_PLT32 ||
- rtype == R_386_GOTPC)
- value -= off;
- }
- }
- offptr = (unsigned long *)off;
- /*
- * insert value calculated at reference point
- * 2 cases - normal byte order aligned, normal byte
- * order unaligned.
- */
- switch (rtype) {
- case R_386_PC32:
- case R_386_32:
- case R_386_PLT32:
- case R_386_RELATIVE:
- *offptr += value;
- break;
-
- /*
- * For now, ignore GOT references ...
- */
-
- case R_386_GOTPC:
-#if defined(DEBUG) && !defined(__GNUC__)
- BSVC_PUTCHAR(syscallp, 'p');
-#endif
- break;
- case R_386_GOTOFF:
- BSVC_PUTCHAR(syscallp, 'g');
- break;
- default:
- BSVC_PUTCHAR(syscallp, 'r');
- return;
- }
- /*
- * We only need to do it once.
- */
- reloc->r_info = ELF32_R_INFO(stndx, R_386_NONE);
- } /* while */
- }
+ bootaux[BA_ENTRY].ba_ptr = (void *)_locore_start;
+ bootaux[BA_PAGESZ].ba_val = MMU_PAGESIZE;
+ bootaux[BA_LPAGESZ].ba_val = kbm_nucleus_size;
/*
- * Done relocating all of our *defined*
- * symbols, so we hand off.
+ * Initialize krtld.
*/
kobj_init(syscallp, dvec, bootops, bootaux);
}
diff --git a/usr/src/uts/intel/ia32/krtld/kobj_crt.s b/usr/src/uts/intel/ia32/krtld/kobj_crt.s
index 531924c730..fee3a73953 100644
--- a/usr/src/uts/intel/ia32/krtld/kobj_crt.s
+++ b/usr/src/uts/intel/ia32/krtld/kobj_crt.s
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -61,14 +60,6 @@ save_esp2:
movl %esp, %eax
movl %eax, save_esp2
- movl boothowto, %eax
- andl $RB_DEBUGENTER, %eax
- jz 1f
-
- /* enter the debugger */
- int $T_DBGENTR
-
-1:
/holds address of array of pointers to functions
movl $romp, %eax
movl (%eax), %ecx
diff --git a/usr/src/uts/intel/ia32/ml/copy.s b/usr/src/uts/intel/ia32/ml/copy.s
index f30b864a46..c04aa8c88b 100644
--- a/usr/src/uts/intel/ia32/ml/copy.s
+++ b/usr/src/uts/intel/ia32/ml/copy.s
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -68,6 +68,7 @@ kcopy(const void *from, void *to, size_t count)
#else /* __lint */
.globl kernelbase
+ .globl postbootkernelbase
#if defined(__amd64)
@@ -75,10 +76,9 @@ kcopy(const void *from, void *to, size_t count)
pushq %rbp
movq %rsp, %rbp
#ifdef DEBUG
- movq kernelbase(%rip), %rax
- cmpq %rax, %rdi /* %rdi = from */
+ cmpq postbootkernelbase(%rip), %rdi /* %rdi = from */
jb 0f
- cmpq %rax, %rsi /* %rsi = to */
+ cmpq postbootkernelbase(%rip), %rsi /* %rsi = to */
jnb 1f
0: leaq .kcopy_panic_msg(%rip), %rdi
xorl %eax, %eax
@@ -127,7 +127,7 @@ _kcopy_copyerr:
#ifdef DEBUG
pushl %ebp
movl %esp, %ebp
- movl kernelbase, %eax
+ movl postbootkernelbase, %eax
cmpl %eax, ARG_FROM(%ebp)
jb 0f
cmpl %eax, ARG_TO(%ebp)
@@ -216,10 +216,9 @@ kcopy_nta(const void *from, void *to, size_t count, int copy_cached)
pushq %rbp
movq %rsp, %rbp
#ifdef DEBUG
- movq kernelbase(%rip), %rax
- cmpq %rax, %rdi /* %rdi = from */
+ cmpq postbootkernelbase(%rip), %rdi /* %rdi = from */
jb 0f
- cmpq %rax, %rsi /* %rsi = to */
+ cmpq postbootkernelbase(%rip), %rsi /* %rsi = to */
jnb 1f
0: leaq .kcopy_panic_msg(%rip), %rdi
xorl %eax, %eax
@@ -359,10 +358,9 @@ bcopy(const void *from, void *to, size_t count)
#ifdef DEBUG
orq %rdx, %rdx /* %rdx = count */
jz 1f
- movq kernelbase(%rip), %rax
- cmpq %rax, %rdi /* %rdi = from */
+ cmpq postbootkernelbase(%rip), %rdi /* %rdi = from */
jb 0f
- cmpq %rax, %rsi /* %rsi = to */
+ cmpq postbootkernelbase(%rip), %rsi /* %rsi = to */
jnb 1f
0: leaq .bcopy_panic_msg(%rip), %rdi
jmp call_panic /* setup stack and call panic */
@@ -410,7 +408,7 @@ call_panic:
movl ARG_COUNT(%esp), %eax
orl %eax, %eax
jz 1f
- movl kernelbase, %eax
+ movl postbootkernelbase, %eax
cmpl %eax, ARG_FROM(%esp)
jb 0f
cmpl %eax, ARG_TO(%esp)
@@ -467,7 +465,7 @@ kzero(void *addr, size_t count)
ENTRY(kzero)
#ifdef DEBUG
- cmpq kernelbase(%rip), %rdi /* %rdi = addr */
+ cmpq postbootkernelbase(%rip), %rdi /* %rdi = addr */
jnb 0f
leaq .kzero_panic_msg(%rip), %rdi
jmp call_panic /* setup stack and call panic */
@@ -512,7 +510,7 @@ _kzeroerr:
#ifdef DEBUG
pushl %ebp
movl %esp, %ebp
- movl kernelbase, %eax
+ movl postbootkernelbase, %eax
cmpl %eax, ARG_ADDR(%ebp)
jnb 0f
pushl $.kzero_panic_msg
@@ -578,7 +576,7 @@ bzero(void *addr, size_t count)
ENTRY(bzero)
#ifdef DEBUG
- cmpq kernelbase(%rip), %rdi /* %rdi = addr */
+ cmpq postbootkernelbase(%rip), %rdi /* %rdi = addr */
jnb 0f
leaq .bzero_panic_msg(%rip), %rdi
jmp call_panic /* setup stack and call panic */
@@ -605,7 +603,7 @@ do_zero:
ENTRY(bzero)
#ifdef DEBUG
- movl kernelbase, %eax
+ movl postbootkernelbase, %eax
cmpl %eax, ARG_ADDR(%esp)
jnb 0f
pushl %ebp
diff --git a/usr/src/uts/intel/ia32/ml/desctbls_asm.s b/usr/src/uts/intel/ia32/ml/desctbls_asm.s
index c9428ec997..b55b4ccdc2 100644
--- a/usr/src/uts/intel/ia32/ml/desctbls_asm.s
+++ b/usr/src/uts/intel/ia32/ml/desctbls_asm.s
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,6 +32,7 @@
#include <sys/ontrap.h>
#include <sys/privregs.h>
#include <sys/segments.h>
+#include <sys/trap.h>
#if defined(__lint)
#include <sys/types.h>
@@ -45,19 +46,16 @@
#include "assym.h"
#endif /* __lint */
-#if !defined(__lint)
- DGDEF3(gdt0, MMU_STD_PAGESIZE, MMU_STD_PAGESIZE)
- .zero MMU_STD_PAGESIZE
-#endif /* __lint */
-
#if defined(__lint)
/*ARGSUSED*/
-void rd_idtr(desctbr_t *idtr)
+void
+rd_idtr(desctbr_t *idtr)
{}
/*ARGSUSED*/
-void wr_idtr(desctbr_t *idtr)
+void
+wr_idtr(desctbr_t *idtr)
{}
#else /* __lint */
@@ -100,11 +98,13 @@ void wr_idtr(desctbr_t *idtr)
#if defined(__lint)
/*ARGSUSED*/
-void rd_gdtr(desctbr_t *gdtr)
+void
+rd_gdtr(desctbr_t *gdtr)
{}
/*ARGSUSED*/
-void wr_gdtr(desctbr_t *gdtr)
+void
+wr_gdtr(desctbr_t *gdtr)
{}
#else /* __lint */
@@ -112,34 +112,22 @@ void wr_gdtr(desctbr_t *gdtr)
#if defined(__amd64)
ENTRY_NP(rd_gdtr)
+ pushq %rbp
+ movq %rsp, %rbp
sgdt (%rdi)
+ leave
ret
SET_SIZE(rd_gdtr)
ENTRY_NP(wr_gdtr)
+ pushq %rbp
+ movq %rsp, %rbp
lgdt (%rdi)
jmp 1f
nop
1:
- movl $KDS_SEL, %eax
- movw %ax, %ss
- /*
- * zero %ds and %es - they're ignored anyway
- */
- xorl %eax, %eax
- movw %ax, %ds
- movw %ax, %es
- /*
- * set %fs and %gs (probably to zero also)
- */
- movl $KFS_SEL, %eax
- movw %ax, %fs
- movl $KGS_SEL, %eax
- movw %ax, %gs
- popq %rax
- pushq $KCS_SEL
- pushq %rax
- lretq
+ leave
+ ret
SET_SIZE(wr_gdtr)
#elif defined(__i386)
@@ -158,17 +146,9 @@ void wr_gdtr(desctbr_t *gdtr)
movl %esp, %ebp
movl 8(%ebp), %edx
lgdt (%edx)
+ jmp 1f
nop
- ljmp $KCS_SEL, $.next
-.next:
- movl $KDS_SEL, %eax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %ss
- movl $KFS_SEL, %eax
- movw %ax, %fs
- movl $KGS_SEL, %eax
- movw %ax, %gs
+1:
leave
ret
SET_SIZE(wr_gdtr)
@@ -176,17 +156,96 @@ void wr_gdtr(desctbr_t *gdtr)
#endif /* __i386 */
#endif /* __lint */
+#if defined(__amd64)
+#if defined(__lint)
+
+/*ARGSUSED*/
+void
+load_segment_registers(selector_t cs, selector_t fs, selector_t gs,
+ selector_t ss)
+{}
+
+#else /* __lint */
+
+ /*
+ * loads zero selector for ds and es.
+ */
+ ENTRY_NP(load_segment_registers)
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %rdi
+ pushq $.newcs
+ lretq
+.newcs:
+ /*
+ * zero %ds and %es - they're ignored anyway
+ */
+ xorl %eax, %eax
+ movw %ax, %ds
+ movw %ax, %es
+ movl %esi, %eax
+ movw %ax, %fs
+ movl %edx, %eax
+ movw %ax, %gs
+ movl %ecx, %eax
+ movw %ax, %ss
+ leave
+ ret
+ SET_SIZE(load_segment_registers)
+
+#endif /* __lint */
+#elif defined(__i386)
+
+#if defined(__lint)
+
+/*ARGSUSED*/
+void
+load_segment_registers(
+ selector_t cs, selector_t ds, selector_t es,
+ selector_t fs, selector_t gs, selector_t ss)
+{}
+
+#else /* __lint */
+
+ ENTRY_NP(load_segment_registers)
+ pushl %ebp
+ movl %esp, %ebp
+
+ pushl 0x8(%ebp)
+ pushl $.newcs
+ lret
+.newcs:
+ movw 0xc(%ebp), %ax
+ movw %ax, %ds
+ movw 0x10(%ebp), %ax
+ movw %ax, %es
+ movw 0x14(%ebp), %ax
+ movw %ax, %fs
+ movw 0x18(%ebp), %ax
+ movw %ax, %gs
+ movw 0x1c(%ebp), %ax
+ movw %ax, %ss
+ leave
+ ret
+ SET_SIZE(load_segment_registers)
+
+#endif /* __lint */
+#endif /* __i386 */
+
#if defined(__lint)
/*ARGSUSED*/
-void wr_ldtr(selector_t ldtsel)
+void
+wr_ldtr(selector_t ldtsel)
{}
-selector_t rd_ldtr(void)
+selector_t
+rd_ldtr(void)
{ return (0); }
#if defined(__amd64)
-void clr_ldt_sregs(void)
+void
+clr_ldt_sregs(void)
{}
#endif
@@ -264,7 +323,8 @@ void clr_ldt_sregs(void)
#if defined(__lint)
/*ARGSUSED*/
-void wr_tsr(selector_t tsssel)
+void
+wr_tsr(selector_t tsssel)
{}
#else /* __lint */
diff --git a/usr/src/uts/intel/ia32/ml/exception.s b/usr/src/uts/intel/ia32/ml/exception.s
index 11d38dc542..08817134a9 100644
--- a/usr/src/uts/intel/ia32/ml/exception.s
+++ b/usr/src/uts/intel/ia32/ml/exception.s
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,6 +48,7 @@
#include <sys/regset.h>
#include <sys/privregs.h>
#include <sys/dtrace.h>
+#include <sys/x86_archext.h>
#include <sys/traptrace.h>
#include <sys/machparam.h>
@@ -71,10 +72,13 @@ ndptrap_frstor(void)
* of the kernel can expect a consistent stack
* from from any exception.
*/
+
#define TRAP_NOERR(trapno) \
push $0; \
push $trapno
+#define NPTRAP_NOERR(trapno) TRAP_NOERR(trapno)
+
/*
* error code already pushed by hw
* onto stack.
@@ -82,6 +86,7 @@ ndptrap_frstor(void)
#define TRAP_ERR(trapno) \
push $trapno
+
/*
* #DE
*/
@@ -90,10 +95,17 @@ ndptrap_frstor(void)
jmp cmntrap
SET_SIZE(div0trap)
-#if defined(__amd64)
/*
* #DB
*
+ * Fetch %dr6 and clear it, handing off the value to the
+ * cmntrap code in %r15/%esi
+ */
+ ENTRY_NP(dbgtrap)
+ TRAP_NOERR(T_SGLSTP) /* $1 */
+
+#if defined(__amd64)
+ /*
* If we get here as a result of single-stepping a sysenter
* instruction, we suddenly find ourselves taking a #db
* in kernel mode -before- we've swapgs'ed. So before we can
@@ -104,36 +116,38 @@ ndptrap_frstor(void)
* Nobody said that the design of sysenter was particularly
* elegant, did they?
*/
- ENTRY_NP(dbgtrap)
pushq %r11
leaq sys_sysenter(%rip), %r11
cmpq %r11, 8(%rsp)
jne 1f
- swapgs
+ SWAPGS
1: popq %r11
- TRAP_NOERR(T_SGLSTP) /* $1 */
- jmp cmntrap
- SET_SIZE(dbgtrap)
+
+ INTR_PUSH
+ movq %db6, %r15
+ xorl %eax, %eax
+ movq %rax, %db6
#elif defined(__i386)
- /*
- * #DB
- */
- ENTRY_NP(dbgtrap)
- TRAP_NOERR(T_SGLSTP) /* $1 */
- jmp cmntrap
+
+ INTR_PUSH
+ movl %db6, %esi
+ xorl %eax, %eax
+ movl %eax, %db6
+#endif /* __i386 */
+
+ jmp cmntrap_pushed
SET_SIZE(dbgtrap)
-#endif
#if defined(__amd64)
/*
* Macro to set the gsbase or kgsbase to the address of the struct cpu
- * for this processor. If we came from userland, set kgsbase else clear
- * gs and set gsbase. We find the proper cpu struct by looping through
+ * for this processor. If we came from userland, set kgsbase else
+ * set gsbase. We find the proper cpu struct by looping through
* the cpu structs for all processors till we find a match for the gdt
* of the trapping processor. The stack is expected to be pointing at
- * The standard regs pushed by hardware on a trap (plus error code and trapno).
+ * the standard regs pushed by hardware on a trap (plus error code and trapno).
*/
#define SET_CPU_GSBASE \
subq $REGOFF_TRAPNO, %rsp; /* save regs */ \
@@ -176,13 +190,9 @@ ndptrap_frstor(void)
movq %rbp, %rsp; \
movq REGOFF_RBP(%rsp), %rbp; \
addq $REGOFF_TRAPNO, %rsp /* pop stack */
+
#endif /* __amd64 */
-
-
-
-
- .globl nmivect
- .globl idt0_default_r
+
#if defined(__amd64)
@@ -199,11 +209,9 @@ ndptrap_frstor(void)
* with kernel selectors.
*/
INTR_PUSH
-
- DISABLE_INTR_FLAGS /* and set the kernel flags */
+ INTGATE_INIT_KERNEL_FLAGS
TRACE_PTR(%r12, %rax, %eax, %rdx, $TT_TRAP)
-
TRACE_REGS(%r12, %rsp, %rax, %rbx)
TRACE_STAMP(%r12)
@@ -213,7 +221,8 @@ ndptrap_frstor(void)
call av_dispatch_nmivect
INTR_POP
- iretq
+ IRET
+ /*NOTREACHED*/
SET_SIZE(nmiint)
#elif defined(__i386)
@@ -229,30 +238,20 @@ ndptrap_frstor(void)
* with kernel selectors.
*/
INTR_PUSH
+ INTGATE_INIT_KERNEL_FLAGS
+
+ TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP)
+ TRACE_REGS(%edi, %esp, %ebx, %ecx)
+ TRACE_STAMP(%edi)
- /*
- * setup pointer to reg struct as 2nd argument.
- */
movl %esp, %ebp
+
pushl %ebp
-
- DISABLE_INTR_FLAGS
-
- movl nmivect, %esi /* get autovect structure */
-loop1:
- cmpl $0, %esi /* if pointer is null */
- je .intr_ret /* we're done */
- movl AV_VECTOR(%esi), %edx /* get the interrupt routine */
- pushl AV_INTARG1(%esi) /* get argument to interrupt routine */
- call *%edx /* call interrupt routine with arg */
+ call av_dispatch_nmivect
addl $4, %esp
- movl AV_LINK(%esi), %esi /* get next routine on list */
- jmp loop1 /* keep looping until end of list */
-.intr_ret:
- addl $4, %esp /* 'pop' %ebp */
INTR_POP_USER
- iret
+ IRET
SET_SIZE(nmiint)
#endif /* __i386 */
@@ -261,16 +260,11 @@ loop1:
* #BP
*/
ENTRY_NP(brktrap)
+
#if defined(__amd64)
cmpw $KCS_SEL, 8(%rsp)
- je bp_jmpud
-#endif
-
- TRAP_NOERR(T_BPTFLT) /* $3 */
- jmp dtrace_trap
+ jne bp_user
-#if defined(__amd64)
-bp_jmpud:
/*
* This is a breakpoint in the kernel -- it is very likely that this
* is DTrace-induced. To unify DTrace handling, we spoof this as an
@@ -282,8 +276,13 @@ bp_jmpud:
decq (%rsp)
push $1 /* error code -- non-zero for #BP */
jmp ud_kernel
-#endif
-
+
+bp_user:
+#endif /* __amd64 */
+
+ NPTRAP_NOERR(T_BPTFLT) /* $3 */
+ jmp dtrace_trap
+
SET_SIZE(brktrap)
/*
@@ -305,13 +304,14 @@ bp_jmpud:
#if defined(__amd64)
ENTRY_NP(invoptrap)
+
cmpw $KCS_SEL, 8(%rsp)
jne ud_user
push $0 /* error code -- zero for #UD */
ud_kernel:
push $0xdddd /* a dummy trap number */
- TRAP_PUSH
+ INTR_PUSH
movq REGOFF_RIP(%rsp), %rdi
movq REGOFF_RSP(%rsp), %rsi
movq REGOFF_RAX(%rsp), %rdx
@@ -353,7 +353,8 @@ ud_push:
movq 32(%rsp), %rax /* reload calling RSP */
movq %rbp, (%rax) /* store %rbp there */
popq %rax /* pop off temp */
- iretq /* return from interrupt */
+ IRET /* return from interrupt */
+ /*NOTREACHED*/
ud_leave:
/*
@@ -373,7 +374,8 @@ ud_leave:
movq %rbp, 32(%rsp) /* store new %rsp */
movq %rax, %rbp /* set new %rbp */
popq %rax /* pop off temp */
- iretq /* return from interrupt */
+ IRET /* return from interrupt */
+ /*NOTREACHED*/
ud_nop:
/*
@@ -382,7 +384,8 @@ ud_nop:
*/
INTR_POP
incq (%rsp)
- iretq
+ IRET
+ /*NOTREACHED*/
ud_ret:
INTR_POP
@@ -392,7 +395,8 @@ ud_ret:
movq %rax, 8(%rsp) /* store calling RIP */
addq $8, 32(%rsp) /* adjust new %rsp */
popq %rax /* pop off temp */
- iretq /* return from interrupt */
+ IRET /* return from interrupt */
+ /*NOTREACHED*/
ud_trap:
/*
@@ -405,13 +409,13 @@ ud_trap:
je ud_ud
incq REGOFF_RIP(%rsp)
addq $REGOFF_RIP, %rsp
- TRAP_NOERR(T_BPTFLT) /* $3 */
+ NPTRAP_NOERR(T_BPTFLT) /* $3 */
jmp cmntrap
ud_ud:
addq $REGOFF_RIP, %rsp
ud_user:
- TRAP_NOERR(T_ILLINST)
+ NPTRAP_NOERR(T_ILLINST)
jmp cmntrap
SET_SIZE(invoptrap)
@@ -428,6 +432,7 @@ ud_user:
pushl %gs
cmpw $KGS_SEL, (%esp)
jne 8f
+
addl $4, %esp
pusha
pushl %eax /* push %eax -- may be return value */
@@ -446,7 +451,6 @@ ud_user:
cmpl $DTRACE_INVOP_NOP, %eax
je 4f
jmp 7f
-
1:
/*
* We must emulate a "pushl %ebp". To do this, we pull the stack
@@ -464,8 +468,7 @@ ud_user:
movl %eax, 12(%esp) /* store calling EFLAGS */
movl %ebp, 16(%esp) /* push %ebp */
popl %eax /* pop off temp */
- iret /* return from interrupt */
-
+ jmp _emul_done
2:
/*
* We must emulate a "popl %ebp". To do this, we do the opposite of
@@ -484,8 +487,7 @@ ud_user:
movl %eax, 8(%esp) /* store calling EIP */
popl %eax /* pop off temp */
addl $4, %esp /* adjust stack pointer */
- iret /* return from interrupt */
-
+ jmp _emul_done
3:
/*
* We must emulate a "leave", which is the same as a "movl %ebp, %esp"
@@ -510,8 +512,7 @@ ud_user:
popl %eax /* pop off temp */
movl -12(%esp), %esp /* set stack pointer */
subl $8, %esp /* adjust for three pushes, one pop */
- iret /* return from interrupt */
-
+ jmp _emul_done
4:
/*
* We must emulate a "nop". This is obviously not hard: we need only
@@ -519,8 +520,8 @@ ud_user:
*/
popa
incl (%esp)
- iret
-
+_emul_done:
+ IRET /* return from interrupt */
7:
popa
pushl $0
@@ -553,9 +554,9 @@ ud_user:
LOADCPU(%rbx) /* if yes, don't swapgs */
jmp 2f
1:
- swapgs /* if from user, need swapgs */
+ SWAPGS /* if from user, need swapgs */
LOADCPU(%rbx)
- swapgs
+ SWAPGS
2:
cmpl $0, fpu_exists(%rip)
je .handle_in_trap /* let trap handle no fp case */
@@ -582,7 +583,8 @@ ud_user:
fxrstor (%rax)
popq %rbx
popq %rax
- iretq
+ IRET
+ /*NOTREACHED*/
.handle_in_trap:
popq %rbx
@@ -608,46 +610,45 @@ ud_user:
movw %bx, %ds
movl $KGS_SEL, %eax
movw %ax, %gs
- LOADCPU(%ebx)
+ LOADCPU(%eax)
cmpl $0, fpu_exists
je .handle_in_trap /* let trap handle no fp case */
- movl CPU_THREAD(%ebx), %eax /* %eax = curthread */
- movl $FPU_EN, %ebx
- movl T_LWP(%eax), %eax /* %eax = lwp */
- testl %eax, %eax
+ movl CPU_THREAD(%eax), %ebx /* %ebx = curthread */
+ movl $FPU_EN, %eax
+ movl T_LWP(%ebx), %ebx /* %ebx = lwp */
+ testl %ebx, %ebx
jz .handle_in_trap /* should not happen? */
#if LWP_PCB_FPU != 0
- addl $LWP_PCB_FPU, %eax /* &lwp->lwp_pcb.pcb_fpu */
+ addl $LWP_PCB_FPU, %ebx /* &lwp->lwp_pcb.pcb_fpu */
#endif
- testl %ebx, PCB_FPU_FLAGS(%eax)
+ testl %eax, PCB_FPU_FLAGS(%ebx)
jz .handle_in_trap /* must be the first fault */
- clts
- andl $_BITNOT(FPU_VALID), PCB_FPU_FLAGS(%eax)
+ CLTS
+ andl $_BITNOT(FPU_VALID), PCB_FPU_FLAGS(%ebx)
#if FPU_CTX_FPU_REGS != 0
- addl $FPU_CTX_FPU_REGS, %eax
+ addl $FPU_CTX_FPU_REGS, %ebx
#endif
/*
* the label below is used in trap.c to detect FP faults in kernel
* due to user fault.
*/
ALTENTRY(ndptrap_frstor)
- .globl _patch_fxrstor_eax
-_patch_fxrstor_eax:
- frstor (%eax) /* may be patched to fxrstor */
+ .globl _patch_fxrstor_ebx
+_patch_fxrstor_ebx:
+ frstor (%ebx) /* may be patched to fxrstor */
nop /* (including this byte) */
popl %gs
popl %ds
popl %ebx
popl %eax
- iret
+ IRET
.handle_in_trap:
popl %gs
popl %ds
popl %ebx
popl %eax
- pushl $0
- pushl $T_NOEXTFLT /* $7 */
+ TRAP_NOERR(T_NOEXTFLT) /* $7 */
jmp cmninttrap
SET_SIZE(ndptrap_frstor)
SET_SIZE(ndptrap)
@@ -880,11 +881,21 @@ make_frame:
*/
ENTRY_NP(pftrap)
TRAP_ERR(T_PGFLT) /* $14 already have error code on stack */
- jmp cmntrap
+ INTR_PUSH
+
+#if defined(__amd64)
+ movq %cr2, %r15
+#elif defined(__i386)
+ movl %cr2, %esi
+#endif /* __i386 */
+
+ jmp cmntrap_pushed
SET_SIZE(pftrap)
#if !defined(__amd64)
+ .globl idt0_default_r
+
/*
* #PF pentium bug workaround
*/
@@ -950,14 +961,16 @@ check_for_user_address:
ENTRY_NP(mcetrap)
TRAP_NOERR(T_MCE) /* $18 */
+
SET_CPU_GSBASE
+
INTR_PUSH
+ INTGATE_INIT_KERNEL_FLAGS
TRACE_PTR(%rdi, %rbx, %ebx, %rcx, $TT_TRAP)
TRACE_REGS(%rdi, %rsp, %rbx, %rcx)
TRACE_STAMP(%rdi)
- DISABLE_INTR_FLAGS
movq %rsp, %rbp
movq %rsp, %rdi /* arg0 = struct regs *rp */
@@ -970,9 +983,14 @@ check_for_user_address:
ENTRY_NP(mcetrap)
TRAP_NOERR(T_MCE) /* $18 */
+
INTR_PUSH
+ INTGATE_INIT_KERNEL_FLAGS
+
+ TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP)
+ TRACE_REGS(%edi, %esp, %ebx, %ecx)
+ TRACE_STAMP(%edi)
- DISABLE_INTR_FLAGS
movl %esp, %ebp
movl %esp, %ecx
@@ -1065,14 +1083,15 @@ check_for_user_address:
*/
ENTRY_NP(fast_null)
orq $PS_C, 24(%rsp) /* set carry bit in user flags */
- iretq
+ IRET
+ /*NOTREACHED*/
SET_SIZE(fast_null)
#elif defined(__i386)
ENTRY_NP(fast_null)
orw $PS_C, 8(%esp) /* set carry bit in user flags */
- iret
+ IRET
SET_SIZE(fast_null)
#endif /* __i386 */
diff --git a/usr/src/uts/intel/ia32/ml/float.s b/usr/src/uts/intel/ia32/ml/float.s
index 79ee9b8d92..81dc8dc3f4 100644
--- a/usr/src/uts/intel/ia32/ml/float.s
+++ b/usr/src/uts/intel/ia32/ml/float.s
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,7 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/asm_linkage.h>
+#include <sys/asm_misc.h>
#include <sys/regset.h>
#include <sys/privregs.h>
#include <sys/x86_archext.h>
@@ -46,380 +47,127 @@
#endif
#if defined(__lint)
-
-int fpu_exists = 1;
-int fp_kind = FP_387;
-int fpu_ignored = 0;
-
-int use_sse_pagecopy = 0;
-int use_sse_pagezero = 0;
-int use_sse_copy = 0;
-
-#if defined(__i386)
-
-int fpu_pentium_fdivbug = 0;
-
-#endif
+
+uint_t
+fpu_initial_probe(void)
+{ return (0); }
#else /* __lint */
/*
- * If fpu_exists is non-zero, fpu_probe will attempt to use any
- * hardware FPU (subject to other constraints, see below). If
- * fpu_exists is zero, fpu_probe will report that there is no
- * FPU even if there is one.
+ * Returns zero if x87 "chip" is present(!)
*/
- DGDEF3(fpu_exists, 4, 4)
- .long 1
-
- DGDEF3(fp_kind, 4, 4)
- .long FP_387 /* FP_NO, FP_287, FP_387, etc. */
-
- /*
- * The variable fpu_ignored is provided to allow other code to
- * determine whether emulation is being done because there is
- * no FPU or because of an override requested via /etc/system.
- */
- DGDEF3(fpu_ignored, 4, 4)
- .long 0
-
- /*
- * Used by ppcopy, ppzero, and xcopyin to determine whether or not
- * to use the SSE-based routines
- */
- DGDEF3(use_sse_pagecopy, 4, 4)
- .long 0
-
- DGDEF3(use_sse_pagezero, 4, 4)
- .long 0
-
- DGDEF3(use_sse_copy, 4, 4)
- .long 0
-
-#if defined(__i386)
-
- /*
- * The variable fpu_pentium_fdivbug is provided to allow other code to
- * determine whether the system contains a Pentium with the FDIV
- * problem.
- */
- DGDEF3(fpu_pentium_fdivbug, 4, 4)
- .long 0
-
- /*
- * The following constants are used for detecting the Pentium
- * divide bug.
- */
- .align 4
-num1: .4byte 0xbce4217d /* 4.999999 */
- .4byte 0x4013ffff
-num2: .4byte 0x0 /* 15.0 */
- .4byte 0x402e0000
-num3: .4byte 0xde7210bf /* 14.999999 */
- .4byte 0x402dffff
+ ENTRY_NP(fpu_initial_probe)
+ CLTS
+ fninit
+ fnstsw %ax
+ movzbl %al, %eax
+ ret
+ SET_SIZE(fpu_initial_probe)
-#endif /* __i386 */
#endif /* __lint */
-/*
- * FPU probe - check if we have any FP chip present by trying to do a reset.
- * If that succeeds, differentiate via cr0. Called from autoconf.
- */
-
#if defined(__lint)
-
+
/*ARGSUSED*/
void
-fpu_probe(void)
+fxsave_insn(struct fxsave_state *fx)
{}
#else /* __lint */
#if defined(__amd64)
- ENTRY_NP(fpu_probe)
- pushq %rbp
- movq %rsp, %rbp
- clts /* clear task switched bit in CR0 */
- fninit /* initialize chip */
- fnstsw %ax /* get status */
- orb %al, %al /* status zero? 0 = chip present */
- jnz no_fpu_hw
-
- /*
- * Ignore the FPU if fp_exists == 0
- */
- cmpl $0, fpu_exists(%rip)
- je ignore_fpu
-
- /*
- * we have a chip of some sort; use cr0 to differentiate
- */
- movq %cr0, %rdx /* check for fpu present flag */
- testl $CR0_ET, %edx
- jz no_fpu_hw /* z -> fpu not present */
- testl $X86_SSE, x86_feature(%rip)
- je no_fpu_hw /* SSE is utterly required */
- testl $X86_SSE2, x86_feature(%rip)
- je no_fpu_hw /* SSE2 too .. */
- movl $__FP_SSE, fp_kind(%rip)
+ ENTRY_NP(fxsave_insn)
+ fxsave (%rdi)
+ ret
+ SET_SIZE(fxsave_insn)
- /*
- * Tell the processor what we're doing via %cr4
- */
- movq %cr4, %rax
- orq $_CONST(CR4_OSFXSR | CR4_OSXMMEXCPT), %rax
- movq %rax, %cr4
+#elif defined(__i386)
- /*
- * make other CPUs share the same cr4 settings
- */
- orq $_CONST(CR4_OSFXSR | CR4_OSXMMEXCPT), cr4_value(%rip)
+ ENTRY_NP(fxsave_insn)
+ movl 4(%esp), %eax
+ fxsave (%eax)
+ ret
+ SET_SIZE(fxsave_insn)
- /*
- * extract the MXCSR_MASK field from our first fxsave
- */
- subq $FXSAVE_STATE_SIZE, %rsp
- movl $0, FXSAVE_STATE_MXCSR_MASK(%rsp)
- fxsave (%rsp)
- movl FXSAVE_STATE_MXCSR_MASK(%rsp), %eax
- cmpl $0, %eax
- je 1f /* default mask value set in fpu.c */
- movl %eax, sse_mxcsr_mask(%rip) /* override mask set here */
-1:
- movq %cr0, %rax
- andq $_BITNOT(CR0_TS|CR0_EM), %rdx /* clear emulate math bit */
- orq $_CONST(CR0_MP|CR0_NE), %rdx
+#endif
- /*
- * We have SSE and SSE2 so enable the extensions for
- * non-temporal copies and stores.
- */
- movl $1, use_sse_pagecopy
- movl $1, use_sse_pagezero
- movl $1, use_sse_copy
+#endif /* __lint */
- jmp done
+#if defined(__i386)
- /*
- * Do not use the FPU at all
- */
-ignore_fpu:
- movl $1, fpu_ignored(%rip)
+/*
+ * If (num1/num2 > num1/num3) the FPU has the FDIV bug.
+ */
- /*
- * No FPU hardware present
- */
-no_fpu_hw:
- andq $_BITNOT(CR0_MP), %rdx /* clear math chip present */
- orq $CR0_EM, %rdx /* set emulate math bit */
- movl $FP_NO, fp_kind(%rip) /* signify that there is no FPU */
- movl $0, fpu_exists(%rip) /* no FPU present */
- /*
- * Disable the XMM-related gorp too, in case the BIOS set them
- */
- movq %cr4, %rax
- andq $_BITNOT(CR4_OSFXSR | CR4_OSXMMEXCPT), %rax
- movq %rax, %cr4
- andq $_BITNOT(CR4_OSFXSR | CR4_OSXMMEXCPT), cr4_value(%rip)
+#if defined(__lint)
-done:
- movq %rdx, %cr0 /* set machine status word */
- leave
- ret
- SET_SIZE(fpu_probe)
+int
+fpu_probe_pentium_fdivbug(void)
+{ return (0); }
-#elif defined(__i386)
+#else /* __lint */
- ENTRY_NP(fpu_probe)
- clts / clear task switched bit in CR0
- fninit / initialize chip
- fnstsw %ax / get status
- orb %al, %al / status zero? 0 = chip present
- jnz no_fpu_hw / no, use emulator
-/
-/ If there is an FP, look for the Pentium FDIV problem even if we
-/ do not plan to use it. Set fpu_pentium_fdivbug is a bad FPU is
-/ detected. Subsequent code can report the result if desired.
-/
-/ If (num1/num2 > num1/num3) the FPU has the FDIV bug.
-/
- fldl num1
- fldl num2
+ ENTRY_NP(fpu_probe_pentium_fdivbug)
+ fldl .num1
+ fldl .num2
fdivr %st(1), %st
fxch %st(1)
- fdivl num3
+ fdivl .num3
fcompp
fstsw %ax
sahf
- jae no_bug
- movl $1, fpu_pentium_fdivbug
-no_bug:
-/
-/ Repeat the earlier initialization sequence so that the FPU is left in
-/ the expected state.
-/
- fninit
- fnstsw %ax
-/
-/ Ignore the FPU if fpu_exists == 0
-/
- cmpl $0, fpu_exists
- je ignore_fpu
-/
-/ Ignore the FPU if it has the Pentium bug
-/
- cmpl $0, fpu_pentium_fdivbug
- jne ignore_fpu
-/
-/ at this point we know we have a chip of some sort;
-/ use cr0 to differentiate.
-/
- movl %cr0, %edx / check for 387 present flag
- testl $CR0_ET, %edx / ...
- jz is287 / z -> 387 not present
- movl $FP_387, fp_kind / we have a 387 or later chip
-/
-/ clear the "XMM supported" bits in %cr4 in case the BIOS set them
-/ erroneously -- see 4965674
-/
- movl %cr4, %eax
- andl $_BITNOT(CR4_OSFXSR | CR4_OSXMMEXCPT), %eax
- movl %eax, %cr4
- andl $_BITNOT(CR4_OSFXSR | CR4_OSXMMEXCPT), cr4_value
-
- testl $X86_SSE, x86_feature / can we do SSE?
- je mathchip
-/
-/ aha .. we have an SSE-capable chip
-/
-/ - set fpsave_begin to fpxsave_begin
-/ - hot patch performance critical code to use fxsave/fxrstor directly,
-/ and hot patch membar_producer() to use sfence instead of lock
-/ - tell the processor what we're doing via %cr4
-/ - allow fully fledged #XM exceptions to be generated by SSE/SSE2
-/ (the default mask set in fpinit() disables them)
-/ - determine the mxcsr_mask so we can avoid setting reserved bits
-/
- movl $__FP_SSE, fp_kind
- movl $fpxsave_begin, %eax
- movl %eax, fpsave_begin
- call patch_sse
- mov %cr4, %eax
- orl $_CONST(CR4_OSFXSR | CR4_OSXMMEXCPT), %eax
- mov %eax, %cr4
-/
-/ make other CPUs share the same cr4 settings
-/
- orl $_CONST(CR4_OSFXSR | CR4_OSXMMEXCPT), cr4_value
-/
-/ extract the MXCSR_MASK field from our first fxsave
-/
- subl $FXSAVE_STATE_SIZE + XMM_ALIGN, %esp
- movl %esp, %eax
- addl $XMM_ALIGN, %eax
- andl $_BITNOT(XMM_ALIGN-1), %eax /* 16-byte alignment */
- movl $0, FXSAVE_STATE_MXCSR_MASK(%eax)
- fxsave (%eax)
- movl FXSAVE_STATE_MXCSR_MASK(%eax), %eax
- addl $FXSAVE_STATE_SIZE + XMM_ALIGN, %esp
- cmpl $0, %eax
- je 1f / default mask value set in fpu.c
- movl %eax, sse_mxcsr_mask / override mask set here
-1: testl $X86_SSE2, x86_feature / can we do SSE2?
- je mathchip
-/
-/ aha .. we have an SSE2-capable chip
-/
-/ - enable pagezero and pagecopy using non-temporal instructions
-/ - hot patch membar_consumer() to use lfence instead of lock
-/
- movl $1, use_sse_pagecopy / will now call hwblkpagecopy
- movl $1, use_sse_pagezero / will now call hwblkclr
- movl $1, use_sse_copy
- call patch_sse2
- jmp mathchip
-/
-/ No 387; we must have an 80287.
-/
-is287:
-#if !defined(__GNUC_AS__)
- fsetpm / set the 80287 into protected mode
- movl $FP_287, fp_kind / we have a 287 chip
-#else
- movl $FP_NO, fp_kind / maybe just explode here instead?
-#endif
-/
-/ We have either a 287, 387, 486 or P5.
-/ Setup cr0 to reflect the FPU hw type.
-/
-mathchip:
- movl %cr0, %edx
- andl $_BITNOT(CR0_TS|CR0_EM), %edx /* clear emulate math bit */
- orl $_CONST(CR0_MP|CR0_NE), %edx
- jmp cont
-
-/ Do not use the FPU
-ignore_fpu:
- movl $1, fpu_ignored
-/ No FP hw present.
-no_fpu_hw:
- movl %cr0, %edx
- andl $_BITNOT(CR0_MP), %edx /* clear math chip present */
- movl $FP_NO, fp_kind / signify that there is no FPU
- movl $0, fpu_exists / no FPU present
-cont:
- movl %edx, %cr0 / set machine status word
+ jae 0f
+ movl $1, %eax
ret
- SET_SIZE(fpu_probe)
-
-#define HOT_PATCH(srcaddr, dstaddr, size) \
- movl $srcaddr, %esi; \
- movl $dstaddr, %edi; \
- movl $size, %ebx; \
-0: pushl $1; \
- movzbl (%esi), %eax; \
- pushl %eax; \
- pushl %edi; \
- call hot_patch_kernel_text; \
- addl $12, %esp; \
- inc %edi; \
- inc %esi; \
- dec %ebx; \
- test %ebx, %ebx; \
- jne 0b
- /*
- * To cope with processors that do not implement fxsave/fxrstor
- * instructions, patch hot paths in the kernel to use them only
- * when that feature has been detected.
- */
+0: xorl %eax, %eax
+ ret
+
+ .align 4
+.num1: .4byte 0xbce4217d /* 4.999999 */
+ .4byte 0x4013ffff
+.num2: .4byte 0x0 /* 15.0 */
+ .4byte 0x402e0000
+.num3: .4byte 0xde7210bf /* 14.999999 */
+ .4byte 0x402dffff
+ SET_SIZE(fpu_probe_pentium_fdivbug)
+
+#endif /* __lint */
+
+/*
+ * To cope with processors that do not implement fxsave/fxrstor
+ * instructions, patch hot paths in the kernel to use them only
+ * when that feature has been detected.
+ */
+
+#if defined(__lint)
+
+void
+patch_sse(void)
+{}
+
+void
+patch_sse2(void)
+{}
+
+#else /* __lint */
+
ENTRY_NP(patch_sse)
- push %ebp
- mov %esp, %ebp
- push %ebx
- push %esi
- push %edi
- /
- / frstor (%eax); nop -> fxrstor (%eax)
- /
- HOT_PATCH(_fxrstor_eax_insn, _patch_fxrstor_eax, 3)
+ _HOT_PATCH_PROLOG
/
- / nop; nop; nop -> ldmxcsr (%ebx)
+ / frstor (%ebx); nop -> fxrstor (%ebx)
/
- HOT_PATCH(_ldmxcsr_ebx_insn, _patch_ldmxcsr_ebx, 3)
+ _HOT_PATCH(_fxrstor_ebx_insn, _patch_fxrstor_ebx, 3)
/
/ lock; xorl $0, (%esp) -> sfence; ret
/
- HOT_PATCH(_sfence_ret_insn, _patch_sfence_ret, 4)
- pop %edi
- pop %esi
- pop %ebx
- mov %ebp, %esp
- pop %ebp
+ _HOT_PATCH(_sfence_ret_insn, _patch_sfence_ret, 4)
+ _HOT_PATCH_EPILOG
ret
-_fxrstor_eax_insn: / see ndptrap_frstor()
- fxrstor (%eax)
+_fxrstor_ebx_insn: / see ndptrap_frstor()
+ fxrstor (%ebx)
_ldmxcsr_ebx_insn: / see resume_from_zombie()
ldmxcsr (%ebx)
_sfence_ret_insn: / see membar_producer()
@@ -427,103 +175,116 @@ _sfence_ret_insn: / see membar_producer()
ret
SET_SIZE(patch_sse)
- /*
- * Ditto, but this time for functions that depend upon SSE2 extensions
- */
ENTRY_NP(patch_sse2)
- push %ebp
- mov %esp, %ebp
- push %ebx
- push %esi
- push %edi
+ _HOT_PATCH_PROLOG
/
/ lock; xorl $0, (%esp) -> lfence; ret
/
- HOT_PATCH(_lfence_ret_insn, _patch_lfence_ret, 4)
- pop %edi
- pop %esi
- pop %ebx
- mov %ebp, %esp
- pop %ebp
+ _HOT_PATCH(_lfence_ret_insn, _patch_lfence_ret, 4)
+ _HOT_PATCH_EPILOG
ret
_lfence_ret_insn: / see membar_consumer()
.byte 0xf, 0xae, 0xe8 / [lfence instruction]
ret
SET_SIZE(patch_sse2)
-#endif /* __i386 */
#endif /* __lint */
+#endif /* __i386 */
/*
* One of these routines is called from any lwp with floating
- * point context as part of the prolog of a context switch; the
- * routine starts the floating point state save operation.
- * The completion of the save is forced by an fwait just before
- * we truly switch contexts..
+ * point context as part of the prolog of a context switch.
*/
#if defined(__lint)
/*ARGSUSED*/
void
-fpnsave_begin(void *arg)
+fpxsave_ctxt(void *arg)
{}
/*ARGSUSED*/
void
-fpxsave_begin(void *arg)
+fpnsave_ctxt(void *arg)
{}
#else /* __lint */
#if defined(__amd64)
- ENTRY_NP(fpxsave_begin)
- movl FPU_CTX_FPU_FLAGS(%rdi), %edx
- cmpl $FPU_EN, %edx
+ ENTRY_NP(fpxsave_ctxt)
+ cmpl $FPU_EN, FPU_CTX_FPU_FLAGS(%rdi)
jne 1f
-#if FPU_CTX_FPU_REGS != 0
- addq FPU_CTX_FPU_REGS, %rdi
-#endif
- fxsave (%rdi)
- fnclex /* clear pending x87 exceptions */
+
+ movl $_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%rdi)
+ fxsave FPU_CTX_FPU_REGS(%rdi)
+ /*
+ * On certain AMD processors, the "exception pointers" i.e. the last
+ * instruction pointer, last data pointer, and last opcode
+ * are saved by the fxsave instruction ONLY if the exception summary
+ * bit is set.
+ *
+ * To ensure that we don't leak these values into the next context
+ * on the cpu, we could just issue an fninit here, but that's
+ * rather slow and so we issue an instruction sequence that
+ * clears them more quickly, if a little obscurely.
+ */
+ btw $7, FXSAVE_STATE_FSW(%rdi) /* Test saved ES bit */
+ jnc 0f /* jump if ES = 0 */
+ fnclex /* clear pending x87 exceptions */
+0: ffree %st(7) /* clear tag bit to remove possible stack overflow */
+ fildl .fpzero_const(%rip)
+ /* dummy load changes all exception pointers */
+ STTS(%rsi) /* trap on next fpu touch */
1: rep; ret /* use 2 byte return instruction when branch target */
/* AMD Software Optimization Guide - Section 6.2 */
- SET_SIZE(fpxsave_begin)
+ SET_SIZE(fpxsave_ctxt)
#elif defined(__i386)
- ENTRY_NP(fpnsave_begin)
- mov 4(%esp), %eax / a struct fpu_ctx *
- mov FPU_CTX_FPU_FLAGS(%eax), %edx
- cmpl $FPU_EN, %edx
+ ENTRY_NP(fpnsave_ctxt)
+ movl 4(%esp), %eax /* a struct fpu_ctx */
+ cmpl $FPU_EN, FPU_CTX_FPU_FLAGS(%eax)
jne 1f
-#if FPU_CTX_FPU_REGS != 0
- addl FPU_CTX_FPU_REGS, %eax
-#endif
- fnsave (%eax)
+
+ movl $_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%eax)
+ fnsave FPU_CTX_FPU_REGS(%eax)
+ /* (fnsave also reinitializes x87 state) */
+ STTS(%edx) /* trap on next fpu touch */
1: rep; ret /* use 2 byte return instruction when branch target */
/* AMD Software Optimization Guide - Section 6.2 */
- SET_SIZE(fpnsave_begin)
+ SET_SIZE(fpnsave_ctxt)
- ENTRY_NP(fpxsave_begin)
- mov 4(%esp), %eax / a struct fpu_ctx *
- mov FPU_CTX_FPU_FLAGS(%eax), %edx
- cmpl $FPU_EN, %edx
+ ENTRY_NP(fpxsave_ctxt)
+ movl 4(%esp), %eax /* a struct fpu_ctx */
+ cmpl $FPU_EN, FPU_CTX_FPU_FLAGS(%eax)
jne 1f
-#if FPU_CTX_FPU_REGS != 0
- addl FPU_CTX_FPU_REGS, %eax
-#endif
- fxsave (%eax)
- fnclex / Clear pending x87 exceptions
+
+ movl $_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%eax)
+ fxsave FPU_CTX_FPU_REGS(%eax)
+ /* (see notes above about "exception pointers") */
+ btw $7, FXSAVE_STATE_FSW(%eax) /* Test saved ES bit */
+ jnc 0f /* jump if ES = 0 */
+ fnclex /* clear pending x87 exceptions */
+0: ffree %st(7) /* clear tag bit to remove possible stack overflow */
+ fildl .fpzero_const
+ /* dummy load changes all exception pointers */
+ STTS(%edx) /* trap on next fpu touch */
1: rep; ret /* use 2 byte return instruction when branch target */
/* AMD Software Optimization Guide - Section 6.2 */
- SET_SIZE(fpxsave_begin)
+ SET_SIZE(fpxsave_ctxt)
#endif /* __i386 */
+
+ .align 8
+.fpzero_const:
+ .4byte 0x0
+ .4byte 0x0
+
#endif /* __lint */
+
#if defined(__lint)
/*ARGSUSED*/
@@ -541,40 +302,29 @@ fpxsave(struct fxsave_state *f)
#if defined(__amd64)
ENTRY_NP(fpxsave)
- clts /* clear TS bit in CR0 */
+ CLTS
fxsave (%rdi)
- fnclex /* clear pending x87 exceptions */
- fwait /* wait for completion */
- fninit /* emulate fnsave: init x87 tags */
- movq %cr0, %rax
- orq $CR0_TS, %rax
- movq %rax, %cr0 /* set TS bit in CR0 (disable FPU) */
+ fninit /* clear exceptions, init x87 tags */
+ STTS(%rdi) /* set TS bit in %cr0 (disable FPU) */
ret
SET_SIZE(fpxsave)
#elif defined(__i386)
ENTRY_NP(fpsave)
- clts / clear TS bit in CR0
- movl 4(%esp), %eax / load save address
+ CLTS
+ movl 4(%esp), %eax
fnsave (%eax)
- fwait / wait for completion
- movl %cr0, %eax
- orl $CR0_TS, %eax
- movl %eax, %cr0 / set TS bit in CR0 (disable FPU)
+ STTS(%eax) /* set TS bit in %cr0 (disable FPU) */
ret
SET_SIZE(fpsave)
ENTRY_NP(fpxsave)
- clts / clear TS bit in CR0
- movl 4(%esp), %eax / save address
+ CLTS
+ movl 4(%esp), %eax
fxsave (%eax)
- fnclex / Clear pending x87 exceptions
- fwait / wait for completion
- fninit / emulate fnsave: init x87 tag words
- mov %cr0, %eax
- orl $CR0_TS, %eax
- movl %eax, %cr0 / set TS bit in CR0 (disable FPU)
+ fninit /* clear exceptions, init x87 tags */
+ STTS(%eax) /* set TS bit in %cr0 (disable FPU) */
ret
SET_SIZE(fpxsave)
@@ -598,7 +348,7 @@ fpxrestore(struct fxsave_state *f)
#if defined(__amd64)
ENTRY_NP(fpxrestore)
- clts /* clear TS bit in CR0 */
+ CLTS
fxrstor (%rdi)
ret
SET_SIZE(fpxrestore)
@@ -606,15 +356,15 @@ fpxrestore(struct fxsave_state *f)
#elif defined(__i386)
ENTRY_NP(fprestore)
- clts / clear TS bit in CR0
- movl 4(%esp), %eax / load restore address
+ CLTS
+ movl 4(%esp), %eax
frstor (%eax)
ret
SET_SIZE(fprestore)
ENTRY_NP(fpxrestore)
- clts / clear TS bit in CR0
- movl 4(%esp), %eax / load restore address
+ CLTS
+ movl 4(%esp), %eax
fxrstor (%eax)
ret
SET_SIZE(fpxrestore)
@@ -637,18 +387,14 @@ fpdisable(void)
#if defined(__amd64)
ENTRY_NP(fpdisable)
- movq %cr0, %rax
- orq $CR0_TS, %rax
- movq %rax, %cr0 /* set TS bit in CR0 (disable FPU) */
+ STTS(%rdi) /* set TS bit in %cr0 (disable FPU) */
ret
SET_SIZE(fpdisable)
#elif defined(__i386)
ENTRY_NP(fpdisable)
- movl %cr0, %eax
- orl $CR0_TS, %eax
- movl %eax, %cr0 / set TS bit in CR0 (disable FPU)
+ STTS(%eax)
ret
SET_SIZE(fpdisable)
@@ -670,7 +416,7 @@ fpinit(void)
#if defined(__amd64)
ENTRY_NP(fpinit)
- clts /* clear TS bit in CR0 */
+ CLTS
leaq sse_initial(%rip), %rax
fxrstor (%rax) /* load clean initial state */
ret
@@ -679,17 +425,17 @@ fpinit(void)
#elif defined(__i386)
ENTRY_NP(fpinit)
- clts / clear TS bit in CR0
+ CLTS
cmpl $__FP_SSE, fp_kind
je 1f
- fninit / initialize the chip
+ fninit
movl $x87_initial, %eax
- frstor (%eax) / load clean initial state
+ frstor (%eax) /* load clean initial state */
ret
1:
movl $sse_initial, %eax
- fxrstor (%eax) / load clean initial state
+ fxrstor (%eax) /* load clean initial state */
ret
SET_SIZE(fpinit)
@@ -705,25 +451,21 @@ fpinit(void)
uint32_t
fperr_reset(void)
-{
- return (0);
-}
+{ return (0); }
uint32_t
fpxerr_reset(void)
-{
- return (0);
-}
+{ return (0); }
#else /* __lint */
#if defined(__amd64)
ENTRY_NP(fperr_reset)
+ CLTS
xorl %eax, %eax
- clts /* clear TS bit in CR0 */
- fnstsw %ax /* get status */
- fnclex /* clear processor exceptions */
+ fnstsw %ax
+ fnclex
ret
SET_SIZE(fperr_reset)
@@ -731,8 +473,8 @@ fpxerr_reset(void)
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp /* make some temporary space */
- clts /* clear TS bit in CR0 */
- stmxcsr (%rsp) /* get status */
+ CLTS
+ stmxcsr (%rsp)
movl (%rsp), %eax
andl $_BITNOT(SSE_MXCSR_EFLAGS), (%rsp)
ldmxcsr (%rsp) /* clear processor exceptions */
@@ -743,20 +485,20 @@ fpxerr_reset(void)
#elif defined(__i386)
ENTRY_NP(fperr_reset)
+ CLTS
xorl %eax, %eax
- clts / clear TS bit in CR0
- fnstsw %ax / get status
- fnclex / clear processor exceptions
+ fnstsw %ax
+ fnclex
ret
SET_SIZE(fperr_reset)
ENTRY_NP(fpxerr_reset)
- clts / clear TS bit in CR0
- subl $4, %esp / make some temporary space
- stmxcsr (%esp) / get status
+ CLTS
+ subl $4, %esp /* make some temporary space */
+ stmxcsr (%esp)
movl (%esp), %eax
andl $_BITNOT(SSE_MXCSR_EFLAGS), (%esp)
- ldmxcsr (%esp) / clear processor exceptions
+ ldmxcsr (%esp) /* clear processor exceptions */
addl $4, %esp
ret
SET_SIZE(fpxerr_reset)
@@ -780,7 +522,7 @@ fpgetcwsw(void)
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp /* make some temporary space */
- clts /* clear TS bit in CR0 */
+ CLTS
fnstsw (%rsp) /* store the status word */
fnstcw 2(%rsp) /* store the control word */
movl (%rsp), %eax /* put both in %eax */
@@ -791,7 +533,7 @@ fpgetcwsw(void)
#elif defined(__i386)
ENTRY_NP(fpgetcwsw)
- clts /* clear TS bit in CR0 */
+ CLTS
subl $4, %esp /* make some temporary space */
fnstsw (%esp) /* store the status word */
fnstcw 2(%esp) /* store the control word */
@@ -822,9 +564,9 @@ fpgetmxcsr(void)
ENTRY_NP(fpgetmxcsr)
pushq %rbp
movq %rsp, %rbp
- subq $0x10, %rsp /* make some temporary space */
- clts /* clear TS bit in CR0 */
- stmxcsr (%rsp) /* get status */
+ subq $0x10, %rsp /* make some temporary space */
+ CLTS
+ stmxcsr (%rsp)
movl (%rsp), %eax
leave
ret
@@ -833,9 +575,9 @@ fpgetmxcsr(void)
#elif defined(__i386)
ENTRY_NP(fpgetmxcsr)
- clts /* clear TS bit in CR0 */
- subl $4, %esp /* make some temporary space */
- stmxcsr (%esp) /* get status */
+ CLTS
+ subl $4, %esp /* make some temporary space */
+ stmxcsr (%esp)
movl (%esp), %eax
addl $4, %esp
ret
diff --git a/usr/src/uts/intel/ia32/ml/i86_subr.s b/usr/src/uts/intel/ia32/ml/i86_subr.s
index 7aa35afbef..18a06ebdf1 100644
--- a/usr/src/uts/intel/ia32/ml/i86_subr.s
+++ b/usr/src/uts/intel/ia32/ml/i86_subr.s
@@ -18,6 +18,7 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
@@ -515,19 +516,19 @@ setcr8(ulong_t val)
ret
SET_SIZE(setcr0)
- ENTRY(getcr2)
- movq %cr2, %rax
- ret
+ ENTRY(getcr2)
+ movq %cr2, %rax
+ ret
SET_SIZE(getcr2)
ENTRY(getcr3)
- movq %cr3, %rax
+ movq %cr3, %rax
ret
SET_SIZE(getcr3)
- ENTRY(setcr3)
- movq %rdi, %cr3
- ret
+ ENTRY(setcr3)
+ movq %rdi, %cr3
+ ret
SET_SIZE(setcr3)
ENTRY(reload_cr3)
@@ -662,6 +663,28 @@ __cpuid_insn(struct cpuid_regs *regs)
#endif /* __i386 */
#endif /* __lint */
+
+#if defined(__lint)
+
+hrtime_t
+tsc_read(void)
+{
+ return (0);
+}
+
+#else /* __lint */
+
+ ENTRY_NP(tsc_read)
+ rdtsc
+#if defined(__amd64)
+ shlq $32, %rdx
+ orq %rdx, %rax
+#endif
+ ret
+ SET_SIZE(tsc_read)
+
+#endif /* __lint */
+
/*
* Insert entryp after predp in a doubly linked list.
*/
@@ -776,7 +799,7 @@ strlen(const char *str)
ENTRY(strlen)
#ifdef DEBUG
- movq kernelbase(%rip), %rax
+ movq postbootkernelbase(%rip), %rax
cmpq %rax, %rdi
jae str_valid
pushq %rbp
@@ -804,7 +827,7 @@ str_valid:
ENTRY(strlen)
#ifdef DEBUG
- movl kernelbase, %eax
+ movl postbootkernelbase, %eax
cmpl %eax, 4(%esp)
jae str_valid
pushl %ebp
@@ -900,73 +923,36 @@ int splhigh(void) { return (0); }
int splhi(void) { return (0); }
int splzs(void) { return (0); }
-#else /* __lint */
-
-/* reg = cpu->cpu_m.cpu_pri; */
-#define GETIPL_NOGS(reg, cpup) \
- movl CPU_PRI(cpup), reg;
-
-/* cpu->cpu_m.cpu_pri; */
-#define SETIPL_NOGS(val, cpup) \
- movl val, CPU_PRI(cpup);
-
-/* reg = cpu->cpu_m.cpu_pri; */
-#define GETIPL(reg) \
- movl %gs:CPU_PRI, reg;
+/* ARGSUSED */
+void
+splx(int level)
+{}
-/* cpu->cpu_m.cpu_pri; */
-#define SETIPL(val) \
- movl val, %gs:CPU_PRI;
+#else /* __lint */
-/*
- * Macro to raise processor priority level.
- * Avoid dropping processor priority if already at high level.
- * Also avoid going below CPU->cpu_base_spl, which could've just been set by
- * a higher-level interrupt thread that just blocked.
- */
#if defined(__amd64)
-#define RAISE(level) \
- cli; \
- LOADCPU(%rcx); \
- movl $/**/level, %edi;\
- GETIPL_NOGS(%eax, %rcx);\
- cmpl %eax, %edi; \
- jg spl; \
- jmp setsplhisti
-
-#elif defined(__i386)
+#define SETPRI(level) \
+ movl $/**/level, %edi; /* new priority */ \
+ jmp do_splx /* redirect to do_splx */
#define RAISE(level) \
- cli; \
- LOADCPU(%ecx); \
- movl $/**/level, %edx;\
- GETIPL_NOGS(%eax, %ecx);\
- cmpl %eax, %edx; \
- jg spl; \
- jmp setsplhisti
-
-#endif /* __i386 */
+ movl $/**/level, %edi; /* new priority */ \
+ jmp splr /* redirect to splr */
-/*
- * Macro to set the priority to a specified level.
- * Avoid dropping the priority below CPU->cpu_base_spl.
- */
-#if defined(__amd64)
+#elif defined(__i386)
#define SETPRI(level) \
- cli; \
- LOADCPU(%rcx); \
- movl $/**/level, %edi; \
- jmp spl
-
-#elif defined(__i386)
+ pushl $/**/level; /* new priority */ \
+ call do_splx; /* invoke common splx code */ \
+ addl $4, %esp; /* unstack arg */ \
+ ret
-#define SETPRI(level) \
- cli; \
- LOADCPU(%ecx); \
- movl $/**/level, %edx; \
- jmp spl
+#define RAISE(level) \
+ pushl $/**/level; /* new priority */ \
+ call splr; /* invoke common splr code */ \
+ addl $4, %esp; /* unstack args */ \
+ ret
#endif /* __i386 */
@@ -985,413 +971,29 @@ int splzs(void) { return (0); }
SETPRI(12) /* Can't be a RAISE, as it's used to lower us */
SET_SIZE(splzs)
- /*
- * should lock out clocks and all interrupts,
- * as you can see, there are exceptions
- */
-
-#if defined(__amd64)
-
- .align 16
ENTRY(splhi)
ALTENTRY(splhigh)
ALTENTRY(spl6)
ALTENTRY(i_ddi_splhigh)
- cli
- LOADCPU(%rcx)
- movl $DISP_LEVEL, %edi
- movl CPU_PRI(%rcx), %eax
- cmpl %eax, %edi
- jle setsplhisti
- SETIPL_NOGS(%edi, %rcx)
- /*
- * If we aren't using cr8 to control ipl then we patch this
- * with a jump to slow_setsplhi
- */
- ALTENTRY(setsplhi_patch)
- movq CPU_PRI_DATA(%rcx), %r11 /* get pri data ptr */
- movzb (%r11, %rdi, 1), %rdx /* get apic mask for this ipl */
- movq %rdx, %cr8 /* set new apic priority */
- /*
- * enable interrupts
- */
-setsplhisti:
- nop /* patch this to a sti when a proper setspl routine appears */
- ret
- ALTENTRY(slow_setsplhi)
- pushq %rbp
- movq %rsp, %rbp
- subq $16, %rsp
- movl %eax, -4(%rbp) /* save old ipl */
- call *setspl(%rip)
- movl -4(%rbp), %eax /* return old ipl */
- leave
- jmp setsplhisti
+ RAISE(DISP_LEVEL)
SET_SIZE(i_ddi_splhigh)
SET_SIZE(spl6)
SET_SIZE(splhigh)
SET_SIZE(splhi)
-#elif defined(__i386)
-
- .align 16
- ENTRY(splhi)
- ALTENTRY(splhigh)
- ALTENTRY(spl6)
- ALTENTRY(i_ddi_splhigh)
- cli
- LOADCPU(%ecx)
- movl $DISP_LEVEL, %edx
- movl CPU_PRI(%ecx), %eax
- cmpl %eax, %edx
- jle setsplhisti
- SETIPL_NOGS(%edx, %ecx) /* set new ipl */
-
- pushl %eax /* save old ipl */
- pushl %edx /* pass new ipl */
- call *setspl
- popl %ecx /* dummy pop */
- popl %eax /* return old ipl */
- /*
- * enable interrupts
- *
- * (we patch this to an sti once a proper setspl routine
- * is installed)
- */
-setsplhisti:
- nop /* patch this to a sti when a proper setspl routine appears */
- ret
- SET_SIZE(i_ddi_splhigh)
- SET_SIZE(spl6)
- SET_SIZE(splhigh)
- SET_SIZE(splhi)
-
-#endif /* __i386 */
-
/* allow all interrupts */
ENTRY(spl0)
SETPRI(0)
SET_SIZE(spl0)
-#endif /* __lint */
-
-/*
- * splr is like splx but will only raise the priority and never drop it
- */
-#if defined(__lint)
-
-/* ARGSUSED */
-int
-splr(int level)
-{ return (0); }
-
-#else /* __lint */
-
-#if defined(__amd64)
-
- ENTRY(splr)
- cli
- LOADCPU(%rcx)
- GETIPL_NOGS(%eax, %rcx)
- cmpl %eax, %edi /* if new level > current level */
- jg spl /* then set ipl to new level */
-splr_setsti:
- nop /* patch this to a sti when a proper setspl routine appears */
- ret /* else return the current level */
- SET_SIZE(splr)
-
-#elif defined(__i386)
-
- ENTRY(splr)
- cli
- LOADCPU(%ecx)
- movl 4(%esp), %edx /* get new spl level */
- GETIPL_NOGS(%eax, %ecx)
- cmpl %eax, %edx /* if new level > current level */
- jg spl /* then set ipl to new level */
-splr_setsti:
- nop /* patch this to a sti when a proper setspl routine appears */
- ret /* else return the current level */
- SET_SIZE(splr)
-
-#endif /* __i386 */
-#endif /* __lint */
-
-
-
-/*
- * splx - set PIL back to that indicated by the level passed as an argument,
- * or to the CPU's base priority, whichever is higher.
- * Needs to be fall through to spl to save cycles.
- * Algorithm for spl:
- *
- * turn off interrupts
- *
- * if (CPU->cpu_base_spl > newipl)
- * newipl = CPU->cpu_base_spl;
- * oldipl = CPU->cpu_pridata->c_ipl;
- * CPU->cpu_pridata->c_ipl = newipl;
- *
- * /indirectly call function to set spl values (usually setpicmasks)
- * setspl(); // load new masks into pics
- *
- * Be careful not to set priority lower than CPU->cpu_base_pri,
- * even though it seems we're raising the priority, it could be set
- * higher at any time by an interrupt routine, so we must block interrupts
- * and look at CPU->cpu_base_pri
- */
-#if defined(__lint)
-
-/* ARGSUSED */
-void
-splx(int level)
-{}
-
-#else /* __lint */
-
-#if defined(__amd64)
+ /* splx implentation */
ENTRY(splx)
- ALTENTRY(i_ddi_splx)
- cli /* disable interrupts */
- LOADCPU(%rcx)
- /*FALLTHRU*/
- .align 4
-spl:
- /*
- * New priority level is in %edi, cpu struct pointer is in %rcx
- */
- GETIPL_NOGS(%eax, %rcx) /* get current ipl */
- cmpl %edi, CPU_BASE_SPL(%rcx) /* if (base spl > new ipl) */
- ja set_to_base_spl /* then use base_spl */
-
-setprilev:
- SETIPL_NOGS(%edi, %rcx) /* set new ipl */
- /*
- * If we aren't using cr8 to control ipl then we patch this
- * with a jump to slow_spl
- */
- ALTENTRY(spl_patch)
- movq CPU_PRI_DATA(%rcx), %r11 /* get pri data ptr */
- movzb (%r11, %rdi, 1), %rdx /* get apic mask for this ipl */
- movq %rdx, %cr8 /* set new apic priority */
- xorl %edx, %edx
- bsrl CPU_SOFTINFO(%rcx), %edx /* fls(cpu->cpu_softinfo.st_pending) */
- cmpl %edi, %edx /* new ipl vs. st_pending */
- jle setsplsti
-
- pushq %rbp
- movq %rsp, %rbp
- /* stack now 16-byte aligned */
- pushq %rax /* save old spl */
- pushq %rdi /* save new ipl too */
- jmp fakesoftint
-
-setsplsti:
- nop /* patch this to a sti when a proper setspl routine appears */
- ret
-
- ALTENTRY(slow_spl)
- pushq %rbp
- movq %rsp, %rbp
- /* stack now 16-byte aligned */
-
- pushq %rax /* save old spl */
- pushq %rdi /* save new ipl too */
-
- call *setspl(%rip)
-
- LOADCPU(%rcx)
- movl CPU_SOFTINFO(%rcx), %eax
- orl %eax, %eax
- jz slow_setsplsti
-
- bsrl %eax, %edx /* fls(cpu->cpu_softinfo.st_pending) */
- cmpl 0(%rsp), %edx /* new ipl vs. st_pending */
- jg fakesoftint
-
- ALTENTRY(fakesoftint_return)
- /*
- * enable interrupts
- */
-slow_setsplsti:
- nop /* patch this to a sti when a proper setspl routine appears */
- popq %rdi
- popq %rax /* return old ipl */
- leave
- ret
- SET_SIZE(fakesoftint_return)
-
-set_to_base_spl:
- movl CPU_BASE_SPL(%rcx), %edi
- jmp setprilev
- SET_SIZE(spl)
- SET_SIZE(i_ddi_splx)
+ jmp do_splx /* redirect to common splx code */
SET_SIZE(splx)
-#elif defined(__i386)
-
- ENTRY(splx)
- ALTENTRY(i_ddi_splx)
- cli /* disable interrupts */
- LOADCPU(%ecx)
- movl 4(%esp), %edx /* get new spl level */
- /*FALLTHRU*/
-
- .align 4
- ALTENTRY(spl)
- /*
- * New priority level is in %edx
- * (doing this early to avoid an AGI in the next instruction)
- */
- GETIPL_NOGS(%eax, %ecx) /* get current ipl */
- cmpl %edx, CPU_BASE_SPL(%ecx) /* if ( base spl > new ipl) */
- ja set_to_base_spl /* then use base_spl */
-
-setprilev:
- SETIPL_NOGS(%edx, %ecx) /* set new ipl */
-
- pushl %eax /* save old ipl */
- pushl %edx /* pass new ipl */
- call *setspl
-
- LOADCPU(%ecx)
- movl CPU_SOFTINFO(%ecx), %eax
- orl %eax, %eax
- jz setsplsti
-
- /*
- * Before dashing off, check that setsplsti has been patched.
- */
- cmpl $NOP_INSTR, setsplsti
- je setsplsti
-
- bsrl %eax, %edx
- cmpl 0(%esp), %edx
- jg fakesoftint
-
- ALTENTRY(fakesoftint_return)
- /*
- * enable interrupts
- */
-setsplsti:
- nop /* patch this to a sti when a proper setspl routine appears */
- popl %eax
- popl %eax / return old ipl
- ret
- SET_SIZE(fakesoftint_return)
-
-set_to_base_spl:
- movl CPU_BASE_SPL(%ecx), %edx
- jmp setprilev
- SET_SIZE(spl)
- SET_SIZE(i_ddi_splx)
- SET_SIZE(splx)
-
-#endif /* __i386 */
-#endif /* __lint */
-
-#if defined(__lint)
-
-void
-install_spl(void)
-{}
-
-#else /* __lint */
-
-#if defined(__amd64)
-
- ENTRY_NP(install_spl)
- movq %cr0, %rax
- movq %rax, %rdx
- movl $_BITNOT(CR0_WP), %ecx
- movslq %ecx, %rcx
- andq %rcx, %rax /* we don't want to take a fault */
- movq %rax, %cr0
- jmp 1f
-1: movb $STI_INSTR, setsplsti(%rip)
- movb $STI_INSTR, slow_setsplsti(%rip)
- movb $STI_INSTR, setsplhisti(%rip)
- movb $STI_INSTR, splr_setsti(%rip)
- testl $1, intpri_use_cr8(%rip) /* are using %cr8 ? */
- jz 2f /* no, go patch more */
- movq %rdx, %cr0
- ret
-2:
- /*
- * Patch spl functions to use slow spl method
- */
- leaq setsplhi_patch(%rip), %rdi /* get patch point addr */
- leaq slow_setsplhi(%rip), %rax /* jmp target */
- subq %rdi, %rax /* calculate jmp distance */
- subq $2, %rax /* minus size of jmp instr */
- shlq $8, %rax /* construct jmp instr */
- addq $JMP_INSTR, %rax
- movw %ax, setsplhi_patch(%rip) /* patch in the jmp */
- leaq spl_patch(%rip), %rdi /* get patch point addr */
- leaq slow_spl(%rip), %rax /* jmp target */
- subq %rdi, %rax /* calculate jmp distance */
- subq $2, %rax /* minus size of jmp instr */
- shlq $8, %rax /* construct jmp instr */
- addq $JMP_INSTR, %rax
- movw %ax, spl_patch(%rip) /* patch in the jmp */
- /*
- * Ensure %cr8 is zero since we aren't using it
- */
- xorl %eax, %eax
- movq %rax, %cr8
- movq %rdx, %cr0
- ret
- SET_SIZE(install_spl)
-
-#elif defined(__i386)
-
- ENTRY_NP(install_spl)
- movl %cr0, %eax
- movl %eax, %edx
- andl $_BITNOT(CR0_WP), %eax /* we don't want to take a fault */
- movl %eax, %cr0
- jmp 1f
-1: movb $STI_INSTR, setsplsti
- movb $STI_INSTR, setsplhisti
- movb $STI_INSTR, splr_setsti
- movl %edx, %cr0
- ret
- SET_SIZE(install_spl)
-
-#endif /* __i386 */
-#endif /* __lint */
-
-
-/*
- * Get current processor interrupt level
- */
-
-#if defined(__lint)
-
-int
-getpil(void)
-{ return (0); }
-
-#else /* __lint */
-
-#if defined(__amd64)
-
- ENTRY(getpil)
- GETIPL(%eax) /* priority level into %eax */
- ret
- SET_SIZE(getpil)
-
-#elif defined(__i386)
-
- ENTRY(getpil)
- GETIPL(%eax) /* priority level into %eax */
- ret
- SET_SIZE(getpil)
-
-#endif /* __i386 */
#endif /* __lint */
#if defined(__i386)
@@ -2117,13 +1719,13 @@ scanc(size_t size, uchar_t *cp, uchar_t *table, uchar_t mask)
#if defined(__lint)
-int
+ulong_t
intr_clear(void)
-{ return 0; }
+{ return (0); }
-int
+ulong_t
clear_int_flag(void)
-{ return 0; }
+{ return (0); }
#else /* __lint */
@@ -2132,8 +1734,8 @@ clear_int_flag(void)
ENTRY(intr_clear)
ENTRY(clear_int_flag)
pushfq
- cli
popq %rax
+ CLI(%rdi)
ret
SET_SIZE(clear_int_flag)
SET_SIZE(intr_clear)
@@ -2143,8 +1745,8 @@ clear_int_flag(void)
ENTRY(intr_clear)
ENTRY(clear_int_flag)
pushfl
- cli
popl %eax
+ CLI(%edx)
ret
SET_SIZE(clear_int_flag)
SET_SIZE(intr_clear)
@@ -2261,12 +1863,12 @@ ntohs(uint16_t i)
/* ARGSUSED */
void
-intr_restore(uint_t i)
+intr_restore(ulong_t i)
{ return; }
/* ARGSUSED */
void
-restore_int_flag(int i)
+restore_int_flag(ulong_t i)
{ return; }
#else /* __lint */
@@ -2285,7 +1887,8 @@ restore_int_flag(int i)
ENTRY(intr_restore)
ENTRY(restore_int_flag)
- pushl 4(%esp)
+ movl 4(%esp), %eax
+ pushl %eax
popfl
ret
SET_SIZE(restore_int_flag)
@@ -2300,13 +1903,26 @@ void
sti(void)
{}
+void
+cli(void)
+{}
+
#else /* __lint */
ENTRY(sti)
- sti
+ STI
ret
SET_SIZE(sti)
+ ENTRY(cli)
+#if defined(__amd64)
+ CLI(%rax)
+#elif defined(__i386)
+ CLI(%eax)
+#endif /* __i386 */
+ ret
+ SET_SIZE(cli)
+
#endif /* __lint */
#if defined(__lint)
@@ -2322,7 +1938,7 @@ dtrace_interrupt_disable(void)
ENTRY(dtrace_interrupt_disable)
pushfq
popq %rax
- cli
+ CLI(%rdx)
ret
SET_SIZE(dtrace_interrupt_disable)
@@ -2331,7 +1947,7 @@ dtrace_interrupt_disable(void)
ENTRY(dtrace_interrupt_disable)
pushfl
popl %eax
- cli
+ CLI(%edx)
ret
SET_SIZE(dtrace_interrupt_disable)
@@ -2458,7 +2074,7 @@ ip_ocsum(
pushq %rbp
movq %rsp, %rbp
#ifdef DEBUG
- movq kernelbase(%rip), %rax
+ movq postbootkernelbase(%rip), %rax
cmpq %rax, %rdi
jnb 1f
xorl %eax, %eax
@@ -2878,6 +2494,7 @@ invalidate_cache(void)
#define XMSR_ACCESS_VAL $0x9c5a203a
#if defined(__amd64)
+
ENTRY(rdmsr)
movl %edi, %ecx
rdmsr
@@ -2896,21 +2513,27 @@ invalidate_cache(void)
SET_SIZE(wrmsr)
ENTRY(xrdmsr)
+ pushq %rbp
+ movq %rsp, %rbp
movl %edi, %ecx
movl XMSR_ACCESS_VAL, %edi /* this value is needed to access MSR */
rdmsr
shlq $32, %rdx
orq %rdx, %rax
+ leave
ret
SET_SIZE(xrdmsr)
ENTRY(xwrmsr)
+ pushq %rbp
+ movq %rsp, %rbp
movl %edi, %ecx
movl XMSR_ACCESS_VAL, %edi /* this value is needed to access MSR */
movq %rsi, %rdx
shrq $32, %rdx
movl %esi, %eax
wrmsr
+ leave
ret
SET_SIZE(xwrmsr)
@@ -2931,18 +2554,28 @@ invalidate_cache(void)
SET_SIZE(wrmsr)
ENTRY(xrdmsr)
- movl 4(%esp), %ecx
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%esp), %ecx
+ pushl %edi
movl XMSR_ACCESS_VAL, %edi /* this value is needed to access MSR */
rdmsr
+ popl %edi
+ leave
ret
SET_SIZE(xrdmsr)
ENTRY(xwrmsr)
- movl 4(%esp), %ecx
- movl 8(%esp), %eax
- movl 12(%esp), %edx
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%esp), %ecx
+ movl 12(%esp), %eax
+ movl 16(%esp), %edx
+ pushl %edi
movl XMSR_ACCESS_VAL, %edi /* this value is needed to access MSR */
wrmsr
+ popl %edi
+ leave
ret
SET_SIZE(xwrmsr)
@@ -2958,20 +2591,22 @@ invalidate_cache(void)
#if defined(__lint)
/*ARGSUSED*/
-void getcregs(struct cregs *crp)
+void
+getcregs(struct cregs *crp)
{}
#else /* __lint */
#if defined(__amd64)
+ ENTRY_NP(getcregs)
+
#define GETMSR(r, off, d) \
movl $r, %ecx; \
rdmsr; \
movl %eax, off(d); \
movl %edx, off+4(d)
- ENTRY_NP(getcregs)
xorl %eax, %eax
movq %rax, CREG_GDT+8(%rdi)
sgdt CREG_GDT(%rdi) /* 10 bytes */
@@ -2988,11 +2623,12 @@ void getcregs(struct cregs *crp)
movq %cr3, %rax
movq %rax, CREG_CR3(%rdi) /* cr3 */
movq %cr4, %rax
- movq %rax, CREG_CR8(%rdi) /* cr4 */
+ movq %rax, CREG_CR4(%rdi) /* cr4 */
movq %cr8, %rax
movq %rax, CREG_CR8(%rdi) /* cr8 */
GETMSR(MSR_AMD_KGSBASE, CREG_KGSBASE, %rdi)
GETMSR(MSR_AMD_EFER, CREG_EFER, %rdi)
+ ret
SET_SIZE(getcregs)
#undef GETMSR
@@ -3021,8 +2657,7 @@ void getcregs(struct cregs *crp)
.nocr4:
movl $0, CREG_CR4(%edx)
.skip:
- rep; ret /* use 2 byte return instruction when branch target */
- /* AMD Software Optimization Guide - Section 6.2 */
+ ret
SET_SIZE(getcregs)
#endif /* __i386 */
@@ -3214,16 +2849,6 @@ vpanic_common:
movq %r14, REGOFF_R14(%rsp)
movq %r15, REGOFF_R15(%rsp)
- movl $MSR_AMD_FSBASE, %ecx
- rdmsr
- movl %eax, REGOFF_FSBASE(%rsp)
- movl %edx, REGOFF_FSBASE+4(%rsp)
-
- movl $MSR_AMD_GSBASE, %ecx
- rdmsr
- movl %eax, REGOFF_GSBASE(%rsp)
- movl %edx, REGOFF_GSBASE+4(%rsp)
-
xorl %ecx, %ecx
movw %ds, %cx
movq %rcx, REGOFF_DS(%rsp)
@@ -3442,7 +3067,6 @@ hrtime_t hres_last_tick;
timestruc_t hrestime;
int64_t hrestime_adj;
volatile int hres_lock;
-uint_t nsec_scale;
hrtime_t hrtime_base;
#else /* __lint */
@@ -3788,7 +3412,7 @@ bcmp(const void *s1, const void *s2, size_t count)
pushq %rbp
movq %rsp, %rbp
#ifdef DEBUG
- movq kernelbase(%rip), %r11
+ movq postbootkernelbase(%rip), %r11
cmpq %r11, %rdi
jb 0f
cmpq %r11, %rsi
@@ -3816,7 +3440,7 @@ bcmp(const void *s1, const void *s2, size_t count)
pushl %ebp
movl %esp, %ebp / create new stack frame
#ifdef DEBUG
- movl kernelbase, %eax
+ movl postbootkernelbase, %eax
cmpl %eax, ARG_S1(%ebp)
jb 0f
cmpl %eax, ARG_S2(%ebp)
@@ -3881,3 +3505,206 @@ bcmp(const void *s1, const void *s2, size_t count)
#endif /* DEBUG */
#endif /* __lint */
+
+#if defined(__lint)
+
+uint_t
+bsrw_insn(uint16_t mask)
+{
+ uint_t index = sizeof (mask) * NBBY - 1;
+
+ while ((mask & (1 << index)) == 0)
+ index--;
+ return (index);
+}
+
+#else /* __lint */
+
+#if defined(__amd64)
+
+ ENTRY_NP(bsrw_insn)
+ xorl %eax, %eax
+ bsrw %di, %ax
+ ret
+ SET_SIZE(bsrw_insn)
+
+#elif defined(__i386)
+
+ ENTRY_NP(bsrw_insn)
+ movw 4(%esp), %cx
+ xorl %eax, %eax
+ bsrw %cx, %ax
+ ret
+ SET_SIZE(bsrw_insn)
+
+#endif /* __i386 */
+#endif /* __lint */
+
+#if defined(__lint)
+
+uint_t
+atomic_btr32(uint32_t *pending, uint_t pil)
+{
+ return (*pending &= ~(1 << pil));
+}
+
+#else /* __lint */
+
+#if defined(__i386)
+
+ ENTRY_NP(atomic_btr32)
+ movl 4(%esp), %ecx
+ movl 8(%esp), %edx
+ xorl %eax, %eax
+ lock
+ btrl %edx, (%ecx)
+ setc %al
+ ret
+ SET_SIZE(atomic_btr32)
+
+#endif /* __i386 */
+#endif /* __lint */
+
+#if defined(__lint)
+
+/*ARGSUSED*/
+void
+switch_sp_and_call(void *newsp, void (*func)(uint_t, uint_t), uint_t arg1,
+ uint_t arg2)
+{}
+
+#else /* __lint */
+
+#if defined(__amd64)
+
+ ENTRY_NP(switch_sp_and_call)
+ pushq %rbp
+ movq %rsp, %rbp /* set up stack frame */
+ movq %rdi, %rsp /* switch stack pointer */
+ movq %rdx, %rdi /* pass func arg 1 */
+ movq %rsi, %r11 /* save function to call */
+ movq %rcx, %rsi /* pass func arg 2 */
+ call *%r11 /* call function */
+ leave /* restore stack */
+ ret
+ SET_SIZE(switch_sp_and_call)
+
+#elif defined(__i386)
+
+ ENTRY_NP(switch_sp_and_call)
+ pushl %ebp
+ mov %esp, %ebp /* set up stack frame */
+ movl 8(%ebp), %esp /* switch stack pointer */
+ pushl 20(%ebp) /* push func arg 2 */
+ pushl 16(%ebp) /* push func arg 1 */
+ call *12(%ebp) /* call function */
+ addl $8, %esp /* pop arguments */
+ leave /* restore stack */
+ ret
+ SET_SIZE(switch_sp_and_call)
+
+#endif /* __i386 */
+#endif /* __lint */
+
+#if defined(__lint)
+
+void
+kmdb_enter(void)
+{}
+
+#else /* __lint */
+
+#if defined(__amd64)
+
+ ENTRY_NP(kmdb_enter)
+ pushq %rbp
+ movq %rsp, %rbp
+
+ /*
+ * Save flags, do a 'cli' then return the saved flags
+ */
+ call intr_clear
+
+ int $T_DBGENTR
+
+ /*
+ * Restore the saved flags
+ */
+ movq %rax, %rdi
+ call intr_restore
+
+ leave
+ ret
+ SET_SIZE(kmdb_enter)
+
+#elif defined(__i386)
+
+ ENTRY_NP(kmdb_enter)
+ pushl %ebp
+ movl %esp, %ebp
+
+ /*
+ * Save flags, do a 'cli' then return the saved flags
+ */
+ call intr_clear
+
+ int $T_DBGENTR
+
+ /*
+ * Restore the saved flags
+ */
+ pushl %eax
+ call intr_restore
+ addl $4, %esp
+
+ leave
+ ret
+ SET_SIZE(kmdb_enter)
+
+#endif /* __i386 */
+#endif /* __lint */
+
+#if defined(__lint)
+
+void
+return_instr(void)
+{}
+
+#else /* __lint */
+
+ ENTRY_NP(return_instr)
+ rep; ret /* use 2 byte instruction when branch target */
+ /* AMD Software Optimization Guide - Section 6.2 */
+ SET_SIZE(return_instr)
+
+#endif /* __lint */
+
+#if defined(__lint)
+
+ulong_t
+getflags(void)
+{
+ return (0);
+}
+
+#else /* __lint */
+
+#if defined(__amd64)
+
+ ENTRY(getflags)
+ pushfq
+ popq %rax
+ ret
+ SET_SIZE(getflags)
+
+#elif defined(__i386)
+
+ ENTRY(getflags)
+ pushfl
+ popl %eax
+ ret
+ SET_SIZE(getflags)
+
+#endif /* __i386 */
+
+#endif /* __lint */
diff --git a/usr/src/uts/intel/ia32/ml/ia32.il b/usr/src/uts/intel/ia32/ml/ia32.il
index 7cf9902f52..f3fd44170d 100644
--- a/usr/src/uts/intel/ia32/ml/ia32.il
+++ b/usr/src/uts/intel/ia32/ml/ia32.il
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,15 +18,17 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/
-/ In-line functions for i86 kernels.
+/ Inline functions for i386 kernels.
+/ Shared between all x86 platform variants.
/
/
@@ -60,37 +61,6 @@
.end
/
-/ return value of cr3 register
-/
- .inline getcr3,0
- movl %cr3, %eax
- .end
-
-/
-/ reload cr3 register with its current value
-/
- .inline reload_cr3,0
- movl %cr3, %eax
- movl %eax, %cr3
- .end
-
-/*
- * Put a new value into cr3 (page table base register
- * void setcr3(void *value)
- */
- .inline setcr3,4
- movl (%esp), %eax
- movl %eax, %cr3
- .end
-
-/
-/ invalidate and flush cache.
-/
- .inline cache_bug,0
- wbinvd
- .end
-
-/
/ convert ipl to spl. This is the identity function for i86
/
.inline ipltospl,0
@@ -98,20 +68,6 @@
.end
/
-/ enable interrupts
-/
- .inline sti,0
- sti
- .end
-
-/
-/ disable interrupts
-/
- .inline cli,0
- cli
- .end
-
-/
/ find the low order bit in a word
/
.inline lowbit,4
@@ -119,6 +75,7 @@
bsfl (%esp), %eax
incl %eax
.end
+
/
/ find the high order bit in a word
/
@@ -129,76 +86,8 @@
.end
/
-/ disable interrupts and return value describing if interrupts were enabled
-/
- .inline clear_int_flag,0
- pushfl
- cli
- popl %eax
- .end
-
- .inline intr_clear,0
- pushfl
- cli
- popl %eax
- .end
-
-/
-/ restore interrupt enable flag to value returned from 'clear_int_flag' above
-/
- .inline restore_int_flag,4
- pushl (%esp)
- popfl
- .end
-
- .inline intr_restore,4
- pushl (%esp)
- popfl
- .end
-
-/
-/ in and out
-/
- .inline inb,4
- movl (%esp), %edx
- xorl %eax, %eax
- inb (%dx)
- .end
-
- .inline inw,4
- movl (%esp), %edx
- xorl %eax, %eax
- inw (%dx)
- .end
-
- .inline inl,4
- movl (%esp), %edx
- xorl %eax, %eax
- inl (%dx)
- .end
-
- .inline outb,8
- movl (%esp), %edx
- movl 4(%esp), %eax
- outb (%dx)
- .end
-
- .inline outw,8
- movl (%esp), %edx
- movl 4(%esp), %eax
- outw (%dx)
- .end
-
- .inline outl,8
- movl (%esp), %edx
- movl 4(%esp), %eax
- outl (%dx)
- .end
-
-/
/ Networking byte order functions (too bad, Intel has the wrong byte order)
/
-
.inline htonl,4
movl (%esp), %eax
bswap %eax
@@ -222,7 +111,7 @@
.end
/*
- * multiply two long numbers and yield a u_lonlong_t result
+ * multiply two long numbers and yield a u_longlong_t result
* Provided to manipulate hrtime_t values.
*/
.inline mul32, 8
@@ -253,7 +142,6 @@
andb %dl,(%eax)
.end
-
/*
* atomic inc/dec operations.
* void atomic_inc16(uint16_t *addr) { ++*addr; }
@@ -272,44 +160,6 @@
.end
/*
- * Invalidate TLB translation to 1 page.
- * void mmu_tlbflush_entry(void *addr)
- */
- .inline mmu_tlbflush_entry,4
- movl (%esp), %eax
- invlpg (%eax)
- .end
-
-/*
- * Read Time Stamp Counter
- * uint64_t tsc_read();
- *
- * usage:
- * uint64_t cycles = tsc_read();
- *
- * PPro & PII take no less than 34 cycles to execute rdtsc + stores.
- * Pentium takes about 16 cycles.
- */
- .inline tsc_read, 0
- rdtsc / %edx:%eax = RDTSC
- .end
-
-/*
- * void tsc_clear(register)
- * Clear the local Time Stamp Counter via write-MSR instruction.
- * Note that while this is a 64-bit write, the top 32-bits are
- * ignored, so it isn't massively useful to write anything other
- * than zero.
- */
- .inline tsc_reset, 4
- movl (%esp), %ecx
- xorl %eax, %eax
- movl %eax, %edx
- wrmsr
- ret
- .end
-
-/*
* Call the pause instruction. To the Pentium 4 Xeon processor, it acts as
* a hint that the code sequence is a busy spin-wait loop. Without a pause
* instruction in these loops, the P4 Xeon processor may suffer a severe
@@ -322,16 +172,3 @@
rep / our compiler doesn't support "pause" yet,
nop / so we're using "F3 90" opcode directly
.end
-
-/*
- * Call the halt instruction. This will put the CPU to sleep until
- * it is again awoken via an interrupt.
- * This function should be called with interrupts already disabled
- * for the CPU.
- * Note that "sti" will only enable interrupts at the end of the
- * subsequent instruction...in this case: "hlt".
- */
- .inline i86_halt,0
- sti
- hlt
- .end
diff --git a/usr/src/uts/intel/ia32/ml/lock_prim.s b/usr/src/uts/intel/ia32/ml/lock_prim.s
index a6bd761aeb..2d74137565 100644
--- a/usr/src/uts/intel/ia32/ml/lock_prim.s
+++ b/usr/src/uts/intel/ia32/ml/lock_prim.s
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -466,31 +466,24 @@ lock_clear_splx(lock_t *lp, int s)
jmp lockstat_wrapper
SET_SIZE(lock_clear_splx)
-#if defined(__GNUC_AS__)
-#define LOCK_CLEAR_SPLX_LOCKSTAT_PATCH_VAL \
- (.lock_clear_splx_lockstat - .lock_clear_splx_lockstat_patch_point - 2)
-
-#define LOCK_CLEAR_SPLX_LOCKSTAT_PATCH_POINT \
- (.lock_clear_splx_lockstat_patch_point + 1)
-#else
-#define LOCK_CLEAR_SPLX_LOCKSTAT_PATCH_VAL \
- [.lock_clear_splx_lockstat - .lock_clear_splx_lockstat_patch_point - 2]
-
-#define LOCK_CLEAR_SPLX_LOCKSTAT_PATCH_POINT \
- [.lock_clear_splx_lockstat_patch_point + 1]
-#endif
-
#else
ENTRY(lock_clear_splx)
- LOADCPU(%ecx) /* ecx = cpu pointer */
movl 4(%esp), %eax /* eax = lock addr */
- movl 8(%esp), %edx /* edx = desired pil */
movb $0, (%eax) /* clear lock */
- cli /* disable interrupts */
- call spl /* magic calling sequence */
.lock_clear_splx_lockstat_patch_point:
- ret
+ jmp 0f
+0:
+ movl 8(%esp), %edx /* edx = desired pil */
+ movl %edx, 4(%esp) /* set spl arg up for splx */
+ jmp splx /* let splx do it's thing */
+.lock_clear_splx_lockstat:
+ movl 8(%esp), %edx /* edx = desired pil */
+ pushl %ebp /* set up stack frame */
+ movl %esp, %ebp
+ pushl %edx
+ call splx
+ leave /* unwind stack */
movl 4(%esp), %ecx /* ecx = lock pointer */
movl %gs:CPU_THREAD, %edx /* edx = thread addr */
movl $LS_LOCK_CLEAR_SPLX_RELEASE, %eax
@@ -499,6 +492,20 @@ lock_clear_splx(lock_t *lp, int s)
#endif /* !__amd64 */
+#if defined(__GNUC_AS__)
+#define LOCK_CLEAR_SPLX_LOCKSTAT_PATCH_VAL \
+ (.lock_clear_splx_lockstat - .lock_clear_splx_lockstat_patch_point - 2)
+
+#define LOCK_CLEAR_SPLX_LOCKSTAT_PATCH_POINT \
+ (.lock_clear_splx_lockstat_patch_point + 1)
+#else
+#define LOCK_CLEAR_SPLX_LOCKSTAT_PATCH_VAL \
+ [.lock_clear_splx_lockstat - .lock_clear_splx_lockstat_patch_point - 2]
+
+#define LOCK_CLEAR_SPLX_LOCKSTAT_PATCH_POINT \
+ [.lock_clear_splx_lockstat_patch_point + 1]
+#endif
+
#endif /* __lint */
/*
@@ -1255,15 +1262,9 @@ lockstat_hot_patch(void)
HOT_PATCH(.lock_set_spl_lockstat_patch_point,
LS_LOCK_SET_SPL_ACQUIRE, NOP_INSTR, RET_INSTR, 1)
-#if defined(__amd64)
HOT_PATCH(LOCK_CLEAR_SPLX_LOCKSTAT_PATCH_POINT,
LS_LOCK_CLEAR_SPLX_RELEASE,
LOCK_CLEAR_SPLX_LOCKSTAT_PATCH_VAL, 0, 1);
-#else
- HOT_PATCH(.lock_clear_splx_lockstat_patch_point,
- LS_LOCK_CLEAR_SPLX_RELEASE, NOP_INSTR, RET_INSTR, 1)
-#endif /* !__amd64 */
-
#if defined(__amd64)
leave /* unwind stack */
#endif /* __amd64 */
diff --git a/usr/src/uts/intel/ia32/ml/sseblk.s b/usr/src/uts/intel/ia32/ml/sseblk.s
index 6daa8caa8f..092b3e52fd 100644
--- a/usr/src/uts/intel/ia32/ml/sseblk.s
+++ b/usr/src/uts/intel/ia32/ml/sseblk.s
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -377,46 +376,133 @@ hwblkpagecopy(const void *src, void *dst)
#endif /* __i386 */
#endif /* __lint */
-
#if defined(__lint)
+/*
+ * Version of hwblkclr which doesn't use XMM registers.
+ * Note that it requires aligned dst and len.
+ *
+ * XXPV This needs to be performance tuned at some point.
+ * Is 4 the best number of iterations to unroll?
+ */
/*ARGSUSED*/
void
-hat_pte_zero(void *dst, size_t len)
+block_zero_no_xmm(void *dst, int len)
{}
-#else
+#else /* __lint */
#if defined(__amd64)
- ENTRY(hat_pte_zero)
+ ENTRY(block_zero_no_xmm)
+ pushq %rbp
+ movq %rsp, %rbp
xorl %eax, %eax
+ addq %rsi, %rdi
+ negq %rsi
1:
- movnti %rax, (%rdi)
- addq $8, %rdi
- subq $8, %rsi
+ movnti %rax, (%rdi, %rsi)
+ movnti %rax, 8(%rdi, %rsi)
+ movnti %rax, 16(%rdi, %rsi)
+ movnti %rax, 24(%rdi, %rsi)
+ addq $32, %rsi
jnz 1b
mfence
+ leave
ret
- SET_SIZE(hat_pte_zero)
+ SET_SIZE(block_zero_no_xmm)
#elif defined(__i386)
- ENTRY(hat_pte_zero)
+ ENTRY(block_zero_no_xmm)
+ pushl %ebp
+ movl %esp, %ebp
xorl %eax, %eax
- movl 4(%esp), %edx
- movl 8(%esp), %ecx
+ movl 8(%ebp), %edx
+ movl 12(%ebp), %ecx
+ addl %ecx, %edx
+ negl %ecx
1:
- movnti %eax, (%edx)
- addl $4, %edx
- subl $4, %ecx
+ movnti %eax, (%edx, %ecx)
+ movnti %eax, 4(%edx, %ecx)
+ movnti %eax, 8(%edx, %ecx)
+ movnti %eax, 12(%edx, %ecx)
+ addl $16, %ecx
jnz 1b
mfence
+ leave
ret
- SET_SIZE(hat_pte_zero)
+ SET_SIZE(block_zero_no_xmm)
#endif /* __i386 */
+#endif /* __lint */
+
+
+#if defined(__lint)
+
+/*
+ * Version of page copy which doesn't use XMM registers.
+ *
+ * XXPV This needs to be performance tuned at some point.
+ * Is 4 the right number of iterations to unroll?
+ * Is the load/store order optimal? Should it use prefetch?
+ */
+/*ARGSUSED*/
+void
+page_copy_no_xmm(void *dst, void *src)
+{}
+
+#else /* __lint */
+#if defined(__amd64)
+
+ ENTRY(page_copy_no_xmm)
+ movq $MMU_STD_PAGESIZE, %rcx
+ addq %rcx, %rdi
+ addq %rcx, %rsi
+ negq %rcx
+1:
+ movq (%rsi, %rcx), %rax
+ movnti %rax, (%rdi, %rcx)
+ movq 8(%rsi, %rcx), %rax
+ movnti %rax, 8(%rdi, %rcx)
+ movq 16(%rsi, %rcx), %rax
+ movnti %rax, 16(%rdi, %rcx)
+ movq 24(%rsi, %rcx), %rax
+ movnti %rax, 24(%rdi, %rcx)
+ addq $32, %rcx
+ jnz 1b
+ mfence
+ ret
+ SET_SIZE(page_copy_no_xmm)
+
+#elif defined(__i386)
+
+ ENTRY(page_copy_no_xmm)
+ pushl %esi
+ movl $MMU_STD_PAGESIZE, %ecx
+ movl 8(%esp), %edx
+ movl 12(%esp), %esi
+ addl %ecx, %edx
+ addl %ecx, %esi
+ negl %ecx
+1:
+ movl (%esi, %ecx), %eax
+ movnti %eax, (%edx, %ecx)
+ movl 4(%esi, %ecx), %eax
+ movnti %eax, 4(%edx, %ecx)
+ movl 8(%esi, %ecx), %eax
+ movnti %eax, 8(%edx, %ecx)
+ movl 12(%esi, %ecx), %eax
+ movnti %eax, 12(%edx, %ecx)
+ addl $16, %ecx
+ jnz 1b
+ mfence
+ popl %esi
+ ret
+ SET_SIZE(page_copy_no_xmm)
+
+#endif /* __i386 */
#endif /* __lint */
#if defined(DEBUG) && !defined(__lint)
diff --git a/usr/src/uts/intel/ia32/ml/swtch.s b/usr/src/uts/intel/ia32/ml/swtch.s
index 48103f954f..118c70ce89 100644
--- a/usr/src/uts/intel/ia32/ml/swtch.s
+++ b/usr/src/uts/intel/ia32/ml/swtch.s
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -214,8 +213,8 @@ resume(kthread_t *t)
movq %r13, %rdi /* arg = thread pointer */
call savectx /* call ctx ops */
-
.nosavectx:
+
/*
* Call savepctx if process has installed context ops.
*/
@@ -245,14 +244,6 @@ resume(kthread_t *t)
GET_THREAD_HATP(%rdi, %r12, %r11)
call hat_switch
- movq T_LWP(%r13), %r14
- testq %r14, %r14
- jz .disabled_fpu2
-
- cmpl $FPU_EN, PCB_FPU_FLAGS(%r14)
- je .wait_for_fpusave
-
-.disabled_fpu2:
/*
* Clear and unlock previous thread's t_lock
* to allow it to be dispatched by another processor.
@@ -384,16 +375,6 @@ resume_return:
*/
addq $CLONGSIZE, %rsp
ret
-
-.wait_for_fpusave:
- /* mark copy in pcb as valid */
- movq %cr0, %rax
- movl $_CONST(FPU_VALID|FPU_EN), PCB_FPU_FLAGS(%r14)
- orl $CR0_TS, %eax /* set to trap on next switch */
- fwait /* ensure save is done before we unlock */
- finit /* (ensure x87 tags cleared for fxsave case) */
- movq %rax, %cr0
- jmp .disabled_fpu2
SET_SIZE(_resume_from_idle)
SET_SIZE(resume)
@@ -414,6 +395,9 @@ resume_return:
LOADCPU(%ebx) /* %ebx = CPU */
movl CPU_THREAD(%ebx), %esi /* %esi = curthread */
+#ifdef DEBUG
+ call assert_ints_enabled /* panics if we are cli'd */
+#endif
/*
* Call savectx if thread has installed context ops.
*
@@ -428,8 +412,8 @@ resume_return:
pushl %esi /* arg = thread pointer */
call savectx /* call ctx ops */
addl $4, %esp /* restore stack pointer */
-
.nosavectx:
+
/*
* Call savepctx if process has installed context ops.
*/
@@ -439,7 +423,7 @@ resume_return:
pushl %eax /* arg = proc pointer */
call savepctx /* call ctx ops */
addl $4, %esp
-.nosavepctx:
+.nosavepctx:
/*
* Temporarily switch to the idle thread's stack
@@ -451,8 +435,6 @@ resume_return:
*/
movl T_SP(%eax), %esp /* It is safe to set esp */
movl %eax, CPU_THREAD(%ebx)
- movl T_LWP(%esi), %ecx /* load pointer to pcb_fpu */
- movl %ecx, %ebx /* save pcb_fpu pointer in %ebx */
/* switch in the hat context for the new thread */
GET_THREAD_HATP(%ecx, %edi, %ecx)
@@ -460,17 +442,11 @@ resume_return:
call hat_switch
addl $4, %esp
- xorl %ecx, %ecx
- testl %ebx, %ebx /* check pcb_fpu pointer */
- jz .disabled_fpu2
- cmpl $FPU_EN, PCB_FPU_FLAGS(%ebx) /* is PCB_FPU_FLAGS FPU_EN? */
- je .wait_for_fpusave
-.disabled_fpu2:
/*
* Clear and unlock previous thread's t_lock
* to allow it to be dispatched by another processor.
*/
- movb %cl, T_LOCK(%esi)
+ movb $0, T_LOCK(%esi)
/*
* IMPORTANT: Registers at this point must be:
@@ -586,18 +562,6 @@ resume_return:
addl $CLONGSIZE, %esp
ret
-.wait_for_fpusave:
- mov %cr0, %eax
-
- /* mark copy in pcb as valid */
- movl $_CONST(FPU_VALID|FPU_EN), PCB_FPU_FLAGS(%ebx)
-
- orl $CR0_TS, %eax /* set to trap on next switch */
- fwait /* ensure save is done before we unlock */
- finit /* (ensure x87 tags cleared for fxsave case) */
- movl %eax, %cr0
- jmp .disabled_fpu2
-
.L4_2:
pause
cmpb $0, T_LOCK(%edi)
@@ -647,15 +611,6 @@ resume_from_zombie(kthread_t *t)
testq $CR0_TS, %rax
jnz .zfpu_disabled /* if TS already set, nothing to do */
fninit /* init fpu & discard pending error */
-
- /*
- * Store a zero word into the mxcsr register to disable any sse
- * floating point exceptions
- */
- pushq $0
- movq %rsp, %rdi
- ldmxcsr (%rdi)
- addq $CLONGSIZE, %rsp
orq $CR0_TS, %rax
movq %rax, %cr0
.zfpu_disabled:
@@ -715,28 +670,21 @@ resume_from_zombie_return:
*/
SAVE_REGS(%eax, %ecx)
+#ifdef DEBUG
+ call assert_ints_enabled /* panics if we are cli'd */
+#endif
movl %gs:CPU_THREAD, %esi /* %esi = curthread */
/* clean up the fp unit. It might be left enabled */
+
movl %cr0, %eax
testl $CR0_TS, %eax
jnz .zfpu_disabled /* if TS already set, nothing to do */
fninit /* init fpu & discard pending error */
-
- /*
- * If this machine supports fxsave/fxrstor, the next string of
- * nops may be patched to store a zero word off the stack into
- * the mxcsr register to disable any sse floating point exceptions
- */
- pushl $0
- mov %esp, %ebx
- .globl _patch_ldmxcsr_ebx
-_patch_ldmxcsr_ebx:
- nop; nop; nop /* ldmxcsr (%ebx) */
- addl $4, %esp
orl $CR0_TS, %eax
movl %eax, %cr0
.zfpu_disabled:
+
/*
* Temporarily switch to the idle thread's stack so that the zombie
* thread's stack can be reclaimed by the reaper.
@@ -749,11 +697,14 @@ _patch_ldmxcsr_ebx:
*/
movl %eax, %gs:CPU_THREAD
- /* switch in the hat context for the new thread */
+ /*
+ * switch in the hat context for the new thread
+ */
GET_THREAD_HATP(%ecx, %edi, %ecx)
pushl %ecx
call hat_switch
addl $4, %esp
+
/*
* Put the zombie on death-row.
*/
@@ -872,6 +823,9 @@ resume_from_intr_return:
*/
SAVE_REGS(%eax, %ecx)
+#ifdef DEBUG
+ call assert_ints_enabled /* panics if we are cli'd */
+#endif
movl %gs:CPU_THREAD, %esi /* %esi = curthread */
movl %edi, %gs:CPU_THREAD /* set CPU's thread pointer */
movl T_SP(%edi), %esp /* restore resuming thread's sp */
diff --git a/usr/src/uts/intel/ia32/os/archdep.c b/usr/src/uts/intel/ia32/os/archdep.c
index c3f0688965..317cd9b77d 100644
--- a/usr/src/uts/intel/ia32/os/archdep.c
+++ b/usr/src/uts/intel/ia32/os/archdep.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -295,17 +295,6 @@ setfpregs(klwp_t *lwp, fpregset_t *fp)
#endif
fpu->fpu_regs.kfpu_status = fp->fp_reg_set.fpchip_state.status;
fpu->fpu_flags |= FPU_VALID;
-
- /*
- * If we are changing the fpu_flags in the current context,
- * disable floating point (turn on CR0_TS bit) to track
- * FPU_VALID after clearing any errors (frstor chokes
- * otherwise)
- */
- if (lwp == ttolwp(curthread)) {
- (void) fperr_reset();
- fpdisable();
- }
} else {
/*
* If we are trying to change the FPU state of a thread which
@@ -934,6 +923,11 @@ bind_hwcap(void)
* 32-bit lwp ...
*/
auxv_hwcap &= ~AV_386_SEP;
+#else
+ /*
+ * 32-bit processes can -always- use the lahf/sahf instructions
+ */
+ auxv_hwcap |= AV_386_AHF;
#endif
if (auxv_hwcap_include || auxv_hwcap_exclude)
@@ -953,6 +947,11 @@ bind_hwcap(void)
*/
if (!cpuid_syscall32_insn(NULL))
auxv_hwcap32 &= ~AV_386_AMD_SYSC;
+
+ /*
+ * 32-bit processes can -always- use the lahf/sahf instructions
+ */
+ auxv_hwcap32 |= AV_386_AHF;
#endif
if (auxv_hwcap32_include || auxv_hwcap32_exclude)
@@ -1016,8 +1015,8 @@ panic_saveregs(panic_data_t *pdp, struct regs *rp)
PANICNVADD(pnv, "r13", rp->r_r13);
PANICNVADD(pnv, "r14", rp->r_r14);
PANICNVADD(pnv, "r15", rp->r_r15);
- PANICNVADD(pnv, "fsbase", rp->r_fsbase);
- PANICNVADD(pnv, "gsbase", rp->r_gsbase);
+ PANICNVADD(pnv, "fsbase", rdmsr(MSR_AMD_FSBASE));
+ PANICNVADD(pnv, "gsbase", rdmsr(MSR_AMD_GSBASE));
PANICNVADD(pnv, "ds", rp->r_ds);
PANICNVADD(pnv, "es", rp->r_es);
PANICNVADD(pnv, "fs", rp->r_fs);
diff --git a/usr/src/uts/intel/ia32/os/cpc_subr.c b/usr/src/uts/intel/ia32/os/cpc_subr.c
index 4ab36ece98..34753229f5 100644
--- a/usr/src/uts/intel/ia32/os/cpc_subr.c
+++ b/usr/src/uts/intel/ia32/os/cpc_subr.c
@@ -44,7 +44,7 @@
#include <sys/cmn_err.h>
#include <sys/cmt.h>
#include <sys/spl.h>
-#include <io/pcplusmp/apic.h>
+#include <sys/apic.h>
static const uint64_t allstopped = 0;
static kcpc_ctx_t *(*overflow_intr_handler)(caddr_t);
@@ -111,7 +111,7 @@ static int setup_registered;
void
kcpc_hw_init(cpu_t *cp)
{
- kthread_t *t = cp->cpu_idle_thread;
+ kthread_t *t = cp->cpu_idle_thread;
if (x86_feature & X86_HTT) {
mutex_enter(&cpu_setup_lock);
@@ -133,6 +133,14 @@ kcpc_hw_init(cpu_t *cp)
NULL, NULL, NULL, NULL);
}
+void
+kcpc_hw_fini(cpu_t *cp)
+{
+ ASSERT(cp->cpu_idle_thread == NULL);
+
+ mutex_destroy(&cp->cpu_cpc_ctxlock);
+}
+
#define BITS(v, u, l) \
(((v) >> (l)) & ((1 << (1 + (u) - (l))) - 1))
diff --git a/usr/src/uts/intel/ia32/os/desctbls.c b/usr/src/uts/intel/ia32/os/desctbls.c
index ed31db4a2d..166953e30b 100644
--- a/usr/src/uts/intel/ia32/os/desctbls.c
+++ b/usr/src/uts/intel/ia32/os/desctbls.c
@@ -1,5 +1,26 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,30 +66,37 @@
*/
#include <sys/types.h>
+#include <sys/sysmacros.h>
#include <sys/tss.h>
#include <sys/segments.h>
#include <sys/trap.h>
#include <sys/cpuvar.h>
+#include <sys/bootconf.h>
#include <sys/x86_archext.h>
+#include <sys/controlregs.h>
#include <sys/archsystm.h>
#include <sys/machsystm.h>
#include <sys/kobj.h>
#include <sys/cmn_err.h>
#include <sys/reboot.h>
#include <sys/kdi.h>
+#include <sys/mach_mmu.h>
#include <sys/systm.h>
-#include <sys/controlregs.h>
-
-extern void syscall_int(void);
+#include <sys/promif.h>
+#include <sys/bootinfo.h>
+#include <vm/kboot_mmu.h>
/*
* cpu0 and default tables and structures.
*/
+user_desc_t *gdt0;
desctbr_t gdt0_default_r;
#pragma align 16(idt0)
gate_desc_t idt0[NIDT]; /* interrupt descriptor table */
+#if defined(__i386)
desctbr_t idt0_default_r; /* describes idt0 in IDTR format */
+#endif
#pragma align 16(ktss0)
struct tss ktss0; /* kernel task state structure */
@@ -248,11 +276,8 @@ set_syssegd(system_desc_t *dp, void *base, size_t size, uint_t type,
#if defined(__amd64)
-/*
- * Note stkcpy is replaced with ist. Read the PRM for details on this.
- */
void
-set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel, uint_t ist,
+set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel,
uint_t type, uint_t dpl)
{
dp->sgd_looffset = (uintptr_t)func;
@@ -260,7 +285,17 @@ set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel, uint_t ist,
dp->sgd_hi64offset = (uintptr_t)func >> (16 + 16);
dp->sgd_selector = (uint16_t)sel;
- dp->sgd_ist = ist;
+
+ /*
+ * For 64 bit native we use the IST stack mechanism
+ * for double faults. All other traps use the CPL = 0
+ * (tss_rsp0) stack.
+ */
+ if (type == T_DBLFLT)
+ dp->sgd_ist = 1;
+ else
+ dp->sgd_ist = 0;
+
dp->sgd_type = type;
dp->sgd_dpl = dpl;
dp->sgd_p = 1;
@@ -270,52 +305,35 @@ set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel, uint_t ist,
void
set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel,
- uint_t wcount, uint_t type, uint_t dpl)
+ uint_t type, uint_t dpl)
{
dp->sgd_looffset = (uintptr_t)func;
dp->sgd_hioffset = (uintptr_t)func >> 16;
dp->sgd_selector = (uint16_t)sel;
- dp->sgd_stkcpy = wcount;
+ dp->sgd_stkcpy = 0; /* always zero bytes */
dp->sgd_type = type;
dp->sgd_dpl = dpl;
dp->sgd_p = 1;
}
-#endif /* __i386 */
+#endif /* __i386 */
+
+#if defined(__amd64)
/*
* Build kernel GDT.
*/
-#if defined(__amd64)
-
static void
-init_gdt(void)
+init_gdt_common(user_desc_t *gdt)
{
- desctbr_t r_bgdt, r_gdt;
- user_desc_t *bgdt;
- size_t alen = 0xfffff; /* entire 32-bit address space */
- int i;
-
- /*
- * Copy in from boot's gdt to our gdt entries 1 - 4.
- * Entry 0 is the null descriptor by definition.
- */
- rd_gdtr(&r_bgdt);
- bgdt = (user_desc_t *)r_bgdt.dtr_base;
- if (bgdt == NULL)
- panic("null boot gdt");
-
- gdt0[GDT_B32DATA] = bgdt[GDT_B32DATA];
- gdt0[GDT_B32CODE] = bgdt[GDT_B32CODE];
- gdt0[GDT_B64DATA] = bgdt[GDT_B64DATA];
- gdt0[GDT_B64CODE] = bgdt[GDT_B64CODE];
+ int i;
/*
* 64-bit kernel code segment.
*/
- set_usegd(&gdt0[GDT_KCODE], SDP_LONG, NULL, 0, SDT_MEMERA, SEL_KPL,
+ set_usegd(&gdt[GDT_KCODE], SDP_LONG, NULL, 0, SDT_MEMERA, SEL_KPL,
SDP_PAGES, SDP_OP32);
/*
@@ -328,20 +346,20 @@ init_gdt(void)
* apps. For the same reason we must set the default op size of this
* descriptor to 32-bit operands.
*/
- set_usegd(&gdt0[GDT_KDATA], SDP_LONG, NULL, alen, SDT_MEMRWA,
+ set_usegd(&gdt[GDT_KDATA], SDP_LONG, NULL, -1, SDT_MEMRWA,
SEL_KPL, SDP_PAGES, SDP_OP32);
- gdt0[GDT_KDATA].usd_def32 = 1;
+ gdt[GDT_KDATA].usd_def32 = 1;
/*
* 64-bit user code segment.
*/
- set_usegd(&gdt0[GDT_UCODE], SDP_LONG, NULL, 0, SDT_MEMERA, SEL_UPL,
+ set_usegd(&gdt[GDT_UCODE], SDP_LONG, NULL, 0, SDT_MEMERA, SEL_UPL,
SDP_PAGES, SDP_OP32);
/*
* 32-bit user code segment.
*/
- set_usegd(&gdt0[GDT_U32CODE], SDP_SHORT, NULL, alen, SDT_MEMERA,
+ set_usegd(&gdt[GDT_U32CODE], SDP_SHORT, NULL, -1, SDT_MEMERA,
SEL_UPL, SDP_PAGES, SDP_OP32);
/*
@@ -351,7 +369,7 @@ init_gdt(void)
* as in legacy mode so they must be set correctly for a 32-bit data
* segment.
*/
- set_usegd(&gdt0[GDT_UDATA], SDP_SHORT, NULL, alen, SDT_MEMRWA, SEL_UPL,
+ set_usegd(&gdt[GDT_UDATA], SDP_SHORT, NULL, -1, SDT_MEMRWA, SEL_UPL,
SDP_PAGES, SDP_OP32);
/*
@@ -362,7 +380,7 @@ init_gdt(void)
/*
* Kernel TSS
*/
- set_syssegd((system_desc_t *)&gdt0[GDT_KTSS], &ktss0,
+ set_syssegd((system_desc_t *)&gdt[GDT_KTSS], &ktss0,
sizeof (ktss0) - 1, SDT_SYSTSS, SEL_KPL);
/*
@@ -370,9 +388,9 @@ init_gdt(void)
* Only attributes and limits are initialized, the effective
* base address is programmed via fsbase/gsbase.
*/
- set_usegd(&gdt0[GDT_LWPFS], SDP_SHORT, NULL, alen, SDT_MEMRWA,
+ set_usegd(&gdt[GDT_LWPFS], SDP_SHORT, NULL, -1, SDT_MEMRWA,
SEL_UPL, SDP_PAGES, SDP_OP32);
- set_usegd(&gdt0[GDT_LWPGS], SDP_SHORT, NULL, alen, SDT_MEMRWA,
+ set_usegd(&gdt[GDT_LWPGS], SDP_SHORT, NULL, -1, SDT_MEMRWA,
SEL_UPL, SDP_PAGES, SDP_OP32);
/*
@@ -380,17 +398,10 @@ init_gdt(void)
* Only attributes and limits are initialized.
*/
for (i = GDT_BRANDMIN; i <= GDT_BRANDMAX; i++)
- set_usegd(&gdt0[i], SDP_SHORT, NULL, alen, SDT_MEMRWA,
+ set_usegd(&gdt0[i], SDP_SHORT, NULL, -1, SDT_MEMRWA,
SEL_UPL, SDP_PAGES, SDP_OP32);
/*
- * Install our new GDT
- */
- r_gdt.dtr_limit = sizeof (gdt0) - 1;
- r_gdt.dtr_base = (uintptr_t)gdt0;
- wr_gdtr(&r_gdt);
-
- /*
* Initialize convenient zero base user descriptors for clearing
* lwp private %fs and %gs descriptors in GDT. See setregs() for
* an example.
@@ -401,28 +412,79 @@ init_gdt(void)
SDP_PAGES, SDP_OP32);
}
-#elif defined(__i386)
-
-static void
+static user_desc_t *
init_gdt(void)
{
desctbr_t r_bgdt, r_gdt;
user_desc_t *bgdt;
- int i;
+#if !defined(__lint)
/*
- * Copy in from boot's gdt to our gdt entries 1 - 4.
- * Entry 0 is null descriptor by definition.
+ * Our gdt is never larger than a single page.
+ */
+ ASSERT((sizeof (*gdt0) * NGDT) <= PAGESIZE);
+#endif
+ gdt0 = (user_desc_t *)BOP_ALLOC(bootops, (caddr_t)GDT_VA,
+ PAGESIZE, PAGESIZE);
+ if (gdt0 == NULL)
+ panic("init_gdt: BOP_ALLOC failed");
+ bzero(gdt0, PAGESIZE);
+
+ init_gdt_common(gdt0);
+
+ /*
+ * Copy in from boot's gdt to our gdt.
+ * Entry 0 is the null descriptor by definition.
*/
rd_gdtr(&r_bgdt);
bgdt = (user_desc_t *)r_bgdt.dtr_base;
if (bgdt == NULL)
panic("null boot gdt");
- gdt0[GDT_BOOTFLAT] = bgdt[GDT_BOOTFLAT];
- gdt0[GDT_BOOTCODE] = bgdt[GDT_BOOTCODE];
- gdt0[GDT_BOOTCODE16] = bgdt[GDT_BOOTCODE16];
- gdt0[GDT_BOOTDATA] = bgdt[GDT_BOOTDATA];
+ gdt0[GDT_B32DATA] = bgdt[GDT_B32DATA];
+ gdt0[GDT_B32CODE] = bgdt[GDT_B32CODE];
+ gdt0[GDT_B16CODE] = bgdt[GDT_B16CODE];
+ gdt0[GDT_B16DATA] = bgdt[GDT_B16DATA];
+ gdt0[GDT_B64CODE] = bgdt[GDT_B64CODE];
+
+ /*
+ * Install our new GDT
+ */
+ r_gdt.dtr_limit = (sizeof (*gdt0) * NGDT) - 1;
+ r_gdt.dtr_base = (uintptr_t)gdt0;
+ wr_gdtr(&r_gdt);
+
+ /*
+ * Reload the segment registers to use the new GDT
+ */
+ load_segment_registers(KCS_SEL, KFS_SEL, KGS_SEL, KDS_SEL);
+
+ /*
+ * setup %gs for kernel
+ */
+ wrmsr(MSR_AMD_GSBASE, (uint64_t)&cpus[0]);
+
+ /*
+ * XX64 We should never dereference off "other gsbase" or
+ * "fsbase". So, we should arrange to point FSBASE and
+ * KGSBASE somewhere truly awful e.g. point it at the last
+ * valid address below the hole so that any attempts to index
+ * off them cause an exception.
+ *
+ * For now, point it at 8G -- at least it should be unmapped
+ * until some 64-bit processes run.
+ */
+ wrmsr(MSR_AMD_FSBASE, 0x200000000ul);
+ wrmsr(MSR_AMD_KGSBASE, 0x200000000ul);
+ return (gdt0);
+}
+
+#elif defined(__i386)
+
+static void
+init_gdt_common(user_desc_t *gdt)
+{
+ int i;
/*
* Text and data for both kernel and user span entire 32 bit
@@ -432,43 +494,43 @@ init_gdt(void)
/*
* kernel code segment.
*/
- set_usegd(&gdt0[GDT_KCODE], NULL, -1, SDT_MEMERA, SEL_KPL, SDP_PAGES,
+ set_usegd(&gdt[GDT_KCODE], NULL, -1, SDT_MEMERA, SEL_KPL, SDP_PAGES,
SDP_OP32);
/*
* kernel data segment.
*/
- set_usegd(&gdt0[GDT_KDATA], NULL, -1, SDT_MEMRWA, SEL_KPL, SDP_PAGES,
+ set_usegd(&gdt[GDT_KDATA], NULL, -1, SDT_MEMRWA, SEL_KPL, SDP_PAGES,
SDP_OP32);
/*
* user code segment.
*/
- set_usegd(&gdt0[GDT_UCODE], NULL, -1, SDT_MEMERA, SEL_UPL, SDP_PAGES,
+ set_usegd(&gdt[GDT_UCODE], NULL, -1, SDT_MEMERA, SEL_UPL, SDP_PAGES,
SDP_OP32);
/*
* user data segment.
*/
- set_usegd(&gdt0[GDT_UDATA], NULL, -1, SDT_MEMRWA, SEL_UPL, SDP_PAGES,
+ set_usegd(&gdt[GDT_UDATA], NULL, -1, SDT_MEMRWA, SEL_UPL, SDP_PAGES,
SDP_OP32);
/*
* TSS for T_DBLFLT (double fault) handler
*/
- set_syssegd((system_desc_t *)&gdt0[GDT_DBFLT], &dftss0,
+ set_syssegd((system_desc_t *)&gdt[GDT_DBFLT], &dftss0,
sizeof (dftss0) - 1, SDT_SYSTSS, SEL_KPL);
/*
* TSS for kernel
*/
- set_syssegd((system_desc_t *)&gdt0[GDT_KTSS], &ktss0,
+ set_syssegd((system_desc_t *)&gdt[GDT_KTSS], &ktss0,
sizeof (ktss0) - 1, SDT_SYSTSS, SEL_KPL);
/*
* %gs selector for kernel
*/
- set_usegd(&gdt0[GDT_GS], &cpus[0], sizeof (struct cpu) -1, SDT_MEMRWA,
+ set_usegd(&gdt[GDT_GS], &cpus[0], sizeof (struct cpu) -1, SDT_MEMRWA,
SEL_KPL, SDP_BYTES, SDP_OP32);
/*
@@ -476,9 +538,9 @@ init_gdt(void)
* Only attributes and limits are initialized, the effective
* base address is programmed via fsbase/gsbase.
*/
- set_usegd(&gdt0[GDT_LWPFS], NULL, (size_t)-1, SDT_MEMRWA, SEL_UPL,
+ set_usegd(&gdt[GDT_LWPFS], NULL, (size_t)-1, SDT_MEMRWA, SEL_UPL,
SDP_PAGES, SDP_OP32);
- set_usegd(&gdt0[GDT_LWPGS], NULL, (size_t)-1, SDT_MEMRWA, SEL_UPL,
+ set_usegd(&gdt[GDT_LWPGS], NULL, (size_t)-1, SDT_MEMRWA, SEL_UPL,
SDP_PAGES, SDP_OP32);
/*
@@ -488,168 +550,153 @@ init_gdt(void)
for (i = GDT_BRANDMIN; i <= GDT_BRANDMAX; i++)
set_usegd(&gdt0[i], NULL, (size_t)-1, SDT_MEMRWA, SEL_UPL,
SDP_PAGES, SDP_OP32);
+ /*
+ * Initialize convenient zero base user descriptor for clearing
+ * lwp private %fs and %gs descriptors in GDT. See setregs() for
+ * an example.
+ */
+ set_usegd(&zero_udesc, NULL, -1, SDT_MEMRWA, SEL_UPL,
+ SDP_BYTES, SDP_OP32);
+}
+
+static user_desc_t *
+init_gdt(void)
+{
+ desctbr_t r_bgdt, r_gdt;
+ user_desc_t *bgdt;
+
+#if !defined(__lint)
+ /*
+ * Our gdt is never larger than a single page.
+ */
+ ASSERT((sizeof (*gdt0) * NGDT) <= PAGESIZE);
+#endif
+ /*
+ * XXX this allocation belongs in our caller, not here.
+ */
+ gdt0 = (user_desc_t *)BOP_ALLOC(bootops, (caddr_t)GDT_VA,
+ PAGESIZE, PAGESIZE);
+ if (gdt0 == NULL)
+ panic("init_gdt: BOP_ALLOC failed");
+ bzero(gdt0, PAGESIZE);
+
+ init_gdt_common(gdt0);
+
+ /*
+ * Copy in from boot's gdt to our gdt entries.
+ * Entry 0 is null descriptor by definition.
+ */
+ rd_gdtr(&r_bgdt);
+ bgdt = (user_desc_t *)r_bgdt.dtr_base;
+ if (bgdt == NULL)
+ panic("null boot gdt");
+
+ gdt0[GDT_B32DATA] = bgdt[GDT_B32DATA];
+ gdt0[GDT_B32CODE] = bgdt[GDT_B32CODE];
+ gdt0[GDT_B16CODE] = bgdt[GDT_B16CODE];
+ gdt0[GDT_B16DATA] = bgdt[GDT_B16DATA];
/*
* Install our new GDT
*/
- r_gdt.dtr_limit = sizeof (gdt0) - 1;
+ r_gdt.dtr_limit = (sizeof (*gdt0) * NGDT) - 1;
r_gdt.dtr_base = (uintptr_t)gdt0;
wr_gdtr(&r_gdt);
/*
- * Initialize convenient zero base user descriptors for clearing
- * lwp private %fs and %gs descriptors in GDT. See setregs() for
- * an example.
+ * Reload the segment registers to use the new GDT
*/
- set_usegd(&zero_udesc, 0, -1, SDT_MEMRWA, SEL_UPL, SDP_PAGES, SDP_OP32);
+ load_segment_registers(
+ KCS_SEL, KDS_SEL, KDS_SEL, KFS_SEL, KGS_SEL, KDS_SEL);
+
+ return (gdt0);
}
#endif /* __i386 */
-#if defined(__amd64)
-
/*
* Build kernel IDT.
*
- * Note that we pretty much require every gate to be an interrupt gate;
- * that's because of our dependency on using 'swapgs' every time we come
- * into the kernel to find the cpu structure - if we get interrupted just
- * before doing that, so that %cs is in kernel mode (so that the trap prolog
- * doesn't do a swapgs), but %gsbase is really still pointing at something
- * in userland, bad things ensue.
+ * Note that for amd64 we pretty much require every gate to be an interrupt
+ * gate which blocks interrupts atomically on entry; that's because of our
+ * dependency on using 'swapgs' every time we come into the kernel to find
+ * the cpu structure. If we get interrupted just before doing that, %cs could
+ * be in kernel mode (so that the trap prolog doesn't do a swapgs), but
+ * %gsbase is really still pointing at something in userland. Bad things will
+ * ensue. We also use interrupt gates for i386 as well even though this is not
+ * required for some traps.
*
* Perhaps they should have invented a trap gate that does an atomic swapgs?
- *
- * XX64 We do need to think further about the follow-on impact of this.
- * Most of the kernel handlers re-enable interrupts as soon as they've
- * saved register state and done the swapgs, but there may be something
- * more subtle going on.
*/
static void
-init_idt(void)
+init_idt_common(gate_desc_t *idt)
{
- char ivctname[80];
- void (*ivctptr)(void);
- int i;
-
- /*
- * Initialize entire table with 'reserved' trap and then overwrite
- * specific entries. T_EXTOVRFLT (9) is unsupported and reserved
- * since it can only be generated on a 386 processor. 15 is also
- * unsupported and reserved.
- */
- for (i = 0; i < NIDT; i++)
- set_gatesegd(&idt0[i], &resvtrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
-
- set_gatesegd(&idt0[T_ZERODIV], &div0trap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_SGLSTP], &dbgtrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_NMIFLT], &nmiint, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_BPTFLT], &brktrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_UPL);
- set_gatesegd(&idt0[T_OVFLW], &ovflotrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_UPL);
- set_gatesegd(&idt0[T_BOUNDFLT], &boundstrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_ILLINST], &invoptrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_NOEXTFLT], &ndptrap, KCS_SEL, 0, SDT_SYSIGT,
+ set_gatesegd(&idt[T_ZERODIV], &div0trap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
+ set_gatesegd(&idt[T_SGLSTP], &dbgtrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
+ set_gatesegd(&idt[T_NMIFLT], &nmiint, KCS_SEL, SDT_SYSIGT, SEL_KPL);
+ set_gatesegd(&idt[T_BPTFLT], &brktrap, KCS_SEL, SDT_SYSIGT, SEL_UPL);
+ set_gatesegd(&idt[T_OVFLW], &ovflotrap, KCS_SEL, SDT_SYSIGT, SEL_UPL);
+ set_gatesegd(&idt[T_BOUNDFLT], &boundstrap, KCS_SEL, SDT_SYSIGT,
SEL_KPL);
+ set_gatesegd(&idt[T_ILLINST], &invoptrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
+ set_gatesegd(&idt[T_NOEXTFLT], &ndptrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
/*
* double fault handler.
*/
- set_gatesegd(&idt0[T_DBLFLT], &syserrtrap, KCS_SEL, 1, SDT_SYSIGT,
- SEL_KPL);
-
+#if defined(__amd64)
+ set_gatesegd(&idt[T_DBLFLT], &syserrtrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
+#elif defined(__i386)
/*
- * T_EXTOVRFLT coprocessor-segment-overrun not supported.
+ * task gate required.
*/
+ set_gatesegd(&idt[T_DBLFLT], NULL, DFTSS_SEL, SDT_SYSTASKGT, SEL_KPL);
- set_gatesegd(&idt0[T_TSSFLT], &invtsstrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_SEGFLT], &segnptrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_STKFLT], &stktrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_GPFLT], &gptrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_PGFLT], &pftrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
+#endif /* __i386 */
/*
- * 15 reserved.
+ * T_EXTOVRFLT coprocessor-segment-overrun not supported.
*/
- set_gatesegd(&idt0[15], &resvtrap, KCS_SEL, 0, SDT_SYSIGT, SEL_KPL);
- set_gatesegd(&idt0[T_EXTERRFLT], &ndperr, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_ALIGNMENT], &achktrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_MCE], &mcetrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_SIMDFPE], &xmtrap, KCS_SEL, 0, SDT_SYSIGT,
+ set_gatesegd(&idt[T_TSSFLT], &invtsstrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
+ set_gatesegd(&idt[T_SEGFLT], &segnptrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
+ set_gatesegd(&idt[T_STKFLT], &stktrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
+ set_gatesegd(&idt[T_GPFLT], &gptrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
+ set_gatesegd(&idt[T_PGFLT], &pftrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
+ set_gatesegd(&idt[T_EXTERRFLT], &ndperr, KCS_SEL, SDT_SYSIGT, SEL_KPL);
+ set_gatesegd(&idt[T_ALIGNMENT], &achktrap, KCS_SEL, SDT_SYSIGT,
SEL_KPL);
-
- /*
- * 20-31 reserved
- */
- for (i = 20; i < 32; i++)
- set_gatesegd(&idt0[i], &invaltrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
-
- /*
- * interrupts 32 - 255
- */
- for (i = 32; i < 256; i++) {
- (void) snprintf(ivctname, sizeof (ivctname), "ivct%d", i);
- ivctptr = (void (*)(void))kobj_getsymvalue(ivctname, 0);
- if (ivctptr == NULL)
- panic("kobj_getsymvalue(%s) failed", ivctname);
-
- set_gatesegd(&idt0[i], ivctptr, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- }
+ set_gatesegd(&idt[T_MCE], &mcetrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
+ set_gatesegd(&idt[T_SIMDFPE], &xmtrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
/*
* install "int80" handler at, well, 0x80.
*/
- set_gatesegd(&idt0[T_INT80], &sys_int80, KCS_SEL, 0, SDT_SYSIGT,
- SEL_UPL);
+ set_gatesegd(&idt0[T_INT80], &sys_int80, KCS_SEL, SDT_SYSIGT, SEL_UPL);
/*
* install fast trap handler at 210.
*/
- set_gatesegd(&idt0[T_FASTTRAP], &fasttrap, KCS_SEL, 0,
- SDT_SYSIGT, SEL_UPL);
+ set_gatesegd(&idt[T_FASTTRAP], &fasttrap, KCS_SEL, SDT_SYSIGT, SEL_UPL);
/*
* System call handler.
*/
- set_gatesegd(&idt0[T_SYSCALLINT], &sys_syscall_int, KCS_SEL, 0,
- SDT_SYSIGT, SEL_UPL);
+#if defined(__amd64)
+ set_gatesegd(&idt[T_SYSCALLINT], &sys_syscall_int, KCS_SEL, SDT_SYSIGT,
+ SEL_UPL);
+
+#elif defined(__i386)
+ set_gatesegd(&idt[T_SYSCALLINT], &sys_call, KCS_SEL, SDT_SYSIGT,
+ SEL_UPL);
+#endif /* __i386 */
/*
* Install the DTrace interrupt handler for the pid provider.
*/
- set_gatesegd(&idt0[T_DTRACE_RET], &dtrace_ret, KCS_SEL, 0,
+ set_gatesegd(&idt[T_DTRACE_RET], &dtrace_ret, KCS_SEL,
SDT_SYSIGT, SEL_UPL);
- if (boothowto & RB_DEBUG)
- kdi_dvec_idt_sync(idt0);
-
- /*
- * We must maintain a description of idt0 in convenient IDTR format
- * for use by T_NMIFLT and T_PGFLT (nmiint() and pentium_pftrap())
- * handlers.
- */
- idt0_default_r.dtr_limit = sizeof (idt0) - 1;
- idt0_default_r.dtr_base = (uintptr_t)idt0;
- wr_idtr(&idt0_default_r);
-
/*
* Prepare interposing descriptors for the branded "int80"
* and syscall handlers and cache copies of the default
@@ -658,23 +705,24 @@ init_idt(void)
brand_tbl[0].ih_inum = T_INT80;
brand_tbl[0].ih_default_desc = idt0[T_INT80];
set_gatesegd(&(brand_tbl[0].ih_interp_desc), &brand_sys_int80, KCS_SEL,
- 0, SDT_SYSIGT, SEL_UPL);
+ SDT_SYSIGT, SEL_UPL);
brand_tbl[1].ih_inum = T_SYSCALLINT;
brand_tbl[1].ih_default_desc = idt0[T_SYSCALLINT];
+
+#if defined(__amd64)
set_gatesegd(&(brand_tbl[1].ih_interp_desc), &brand_sys_syscall_int,
- KCS_SEL, 0, SDT_SYSIGT, SEL_UPL);
+ KCS_SEL, SDT_SYSIGT, SEL_UPL);
+#elif defined(__i386)
+ set_gatesegd(&(brand_tbl[1].ih_interp_desc), &brand_sys_call,
+ KCS_SEL, SDT_SYSIGT, SEL_UPL);
+#endif /* __i386 */
brand_tbl[2].ih_inum = 0;
}
-#elif defined(__i386)
-
-/*
- * Build kernel IDT.
- */
static void
-init_idt(void)
+init_idt(gate_desc_t *idt)
{
char ivctname[80];
void (*ivctptr)(void);
@@ -687,67 +735,13 @@ init_idt(void)
* unsupported and reserved.
*/
for (i = 0; i < NIDT; i++)
- set_gatesegd(&idt0[i], &resvtrap, KCS_SEL, 0, SDT_SYSTGT,
- SEL_KPL);
-
- set_gatesegd(&idt0[T_ZERODIV], &div0trap, KCS_SEL, 0, SDT_SYSTGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_SGLSTP], &dbgtrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_NMIFLT], &nmiint, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_BPTFLT], &brktrap, KCS_SEL, 0, SDT_SYSTGT,
- SEL_UPL);
- set_gatesegd(&idt0[T_OVFLW], &ovflotrap, KCS_SEL, 0, SDT_SYSTGT,
- SEL_UPL);
- set_gatesegd(&idt0[T_BOUNDFLT], &boundstrap, KCS_SEL, 0, SDT_SYSTGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_ILLINST], &invoptrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_NOEXTFLT], &ndptrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
-
- /*
- * Install TSS for T_DBLFLT handler.
- */
- set_gatesegd(&idt0[T_DBLFLT], NULL, DFTSS_SEL, 0, SDT_SYSTASKGT,
- SEL_KPL);
-
- /*
- * T_EXTOVRFLT coprocessor-segment-overrun not supported.
- */
-
- set_gatesegd(&idt0[T_TSSFLT], &invtsstrap, KCS_SEL, 0, SDT_SYSTGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_SEGFLT], &segnptrap, KCS_SEL, 0, SDT_SYSTGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_STKFLT], &stktrap, KCS_SEL, 0, SDT_SYSTGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_GPFLT], &gptrap, KCS_SEL, 0, SDT_SYSTGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_PGFLT], &pftrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
-
- /*
- * 15 reserved.
- */
- set_gatesegd(&idt0[15], &resvtrap, KCS_SEL, 0, SDT_SYSTGT, SEL_KPL);
-
- set_gatesegd(&idt0[T_EXTERRFLT], &ndperr, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_ALIGNMENT], &achktrap, KCS_SEL, 0, SDT_SYSTGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_MCE], &mcetrap, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
- set_gatesegd(&idt0[T_SIMDFPE], &xmtrap, KCS_SEL, 0, SDT_SYSTGT,
- SEL_KPL);
+ set_gatesegd(&idt[i], &resvtrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
/*
* 20-31 reserved
*/
for (i = 20; i < 32; i++)
- set_gatesegd(&idt0[i], &invaltrap, KCS_SEL, 0, SDT_SYSTGT,
- SEL_KPL);
+ set_gatesegd(&idt[i], &invaltrap, KCS_SEL, SDT_SYSIGT, SEL_KPL);
/*
* interrupts 32 - 255
@@ -758,67 +752,16 @@ init_idt(void)
if (ivctptr == NULL)
panic("kobj_getsymvalue(%s) failed", ivctname);
- set_gatesegd(&idt0[i], ivctptr, KCS_SEL, 0, SDT_SYSIGT,
- SEL_KPL);
+ set_gatesegd(&idt[i], ivctptr, KCS_SEL, SDT_SYSIGT, SEL_KPL);
}
/*
- * install "int80" handler at, well, 0x80.
- */
- set_gatesegd(&idt0[T_INT80], &sys_int80, KCS_SEL, 0, SDT_SYSIGT,
- SEL_UPL);
-
- /*
- * install fast trap handler at 210.
- */
- set_gatesegd(&idt0[T_FASTTRAP], &fasttrap, KCS_SEL, 0,
- SDT_SYSIGT, SEL_UPL);
-
- /*
- * System call handler. Note that we don't use the hardware's parameter
- * copying mechanism here; see the comment above sys_call() for details.
+ * Now install the common ones. Note that it will overlay some
+ * entries installed above like T_SYSCALLINT, T_FASTTRAP etc.
*/
- set_gatesegd(&idt0[T_SYSCALLINT], &sys_call, KCS_SEL, 0,
- SDT_SYSIGT, SEL_UPL);
-
- /*
- * Install the DTrace interrupt handler for the pid provider.
- */
- set_gatesegd(&idt0[T_DTRACE_RET], &dtrace_ret, KCS_SEL, 0,
- SDT_SYSIGT, SEL_UPL);
-
- if (boothowto & RB_DEBUG)
- kdi_dvec_idt_sync(idt0);
-
- /*
- * We must maintain a description of idt0 in convenient IDTR format
- * for use by T_NMIFLT and T_PGFLT (nmiint() and pentium_pftrap())
- * handlers.
- */
- idt0_default_r.dtr_limit = sizeof (idt0) - 1;
- idt0_default_r.dtr_base = (uintptr_t)idt0;
- wr_idtr(&idt0_default_r);
-
- /*
- * Prepare interposing descriptors for the branded "int80"
- * and syscall handlers and cache copies of the default
- * descriptors.
- */
- brand_tbl[0].ih_inum = T_INT80;
- brand_tbl[0].ih_default_desc = idt0[T_INT80];
- set_gatesegd(&(brand_tbl[0].ih_interp_desc), &brand_sys_int80, KCS_SEL,
- 0, SDT_SYSIGT, SEL_UPL);
-
- brand_tbl[1].ih_inum = T_SYSCALLINT;
- brand_tbl[1].ih_default_desc = idt0[T_SYSCALLINT];
- set_gatesegd(&(brand_tbl[1].ih_interp_desc), &brand_sys_call,
- KCS_SEL, 0, SDT_SYSIGT, SEL_UPL);
-
- brand_tbl[2].ih_inum = 0;
+ init_idt_common(idt);
}
-#endif /* __i386 */
-
/*
* The kernel does not deal with LDTs unless a user explicitly creates
* one. Under normal circumstances, the LDTR contains 0. Any process attempting
@@ -909,15 +852,61 @@ init_tss(void)
#endif /* __i386 */
void
-init_tables(void)
+init_desctbls(void)
{
- init_gdt();
+ user_desc_t *gdt;
+ desctbr_t idtr;
+
+ /*
+ * Setup and install our GDT.
+ */
+ gdt = init_gdt();
+ ASSERT(IS_P2ALIGNED((uintptr_t)gdt, PAGESIZE));
+ CPU->cpu_m.mcpu_gdt = gdt;
+
+ /*
+ * Setup and install our IDT.
+ */
+ init_idt(&idt0[0]);
+
+ idtr.dtr_base = (uintptr_t)idt0;
+ idtr.dtr_limit = sizeof (idt0) - 1;
+ wr_idtr(&idtr);
+ CPU->cpu_m.mcpu_idt = idt0;
+
+#if defined(__i386)
+ /*
+ * We maintain a description of idt0 in convenient IDTR format
+ * for #pf's on some older pentium processors. See pentium_pftrap().
+ */
+ idt0_default_r = idtr;
+#endif /* __i386 */
+
init_tss();
- init_idt();
+ CPU->cpu_tss = &ktss0;
init_ldt();
}
/*
+ * In the early kernel, we need to set up a simple GDT to run on.
+ */
+void
+init_boot_gdt(user_desc_t *bgdt)
+{
+#if defined(__amd64)
+ set_usegd(&bgdt[GDT_B32DATA], SDP_LONG, NULL, -1, SDT_MEMRWA, SEL_KPL,
+ SDP_PAGES, SDP_OP32);
+ set_usegd(&bgdt[GDT_B64CODE], SDP_LONG, NULL, -1, SDT_MEMERA, SEL_KPL,
+ SDP_PAGES, SDP_OP32);
+#elif defined(__i386)
+ set_usegd(&bgdt[GDT_B32DATA], NULL, -1, SDT_MEMRWA, SEL_KPL,
+ SDP_PAGES, SDP_OP32);
+ set_usegd(&bgdt[GDT_B32CODE], NULL, -1, SDT_MEMERA, SEL_KPL,
+ SDP_PAGES, SDP_OP32);
+#endif /* __i386 */
+}
+
+/*
* Enable interpositioning on the system call path by rewriting the
* sys{call|enter} MSRs and the syscall-related entries in the IDT to use
* the branded entry points.
diff --git a/usr/src/uts/intel/ia32/os/fpu.c b/usr/src/uts/intel/ia32/os/fpu.c
index 7a09eba4bb..bd1ee71396 100644
--- a/usr/src/uts/intel/ia32/os/fpu.c
+++ b/usr/src/uts/intel/ia32/os/fpu.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -104,13 +103,13 @@ const struct fnsave_state x87_initial = {
};
#if defined(__amd64)
-#define fpsave_begin fpxsave_begin
+#define fpsave_ctxt fpxsave_ctxt
#elif defined(__i386)
/*
- * This vector is patched to fpxsave_begin() if we discover
+ * This vector is patched to fpxsave_ctxt() if we discover
* we have an SSE-capable chip in fpu_probe().
*/
-void (*fpsave_begin)(void *) = fpnsave_begin;
+void (*fpsave_ctxt)(void *) = fpnsave_ctxt;
#endif
static int fpe_sicode(uint_t);
@@ -168,7 +167,7 @@ fp_new_lwp(kthread_id_t t, kthread_id_t ct)
}
#endif
installctx(ct, cfp,
- fpsave_begin, NULL, fp_new_lwp, fp_new_lwp, NULL, fp_free);
+ fpsave_ctxt, NULL, fp_new_lwp, fp_new_lwp, NULL, fp_free);
/*
* Now, when the new lwp starts running, it will take a trap
* that will be handled inline in the trap table to cause
@@ -291,7 +290,7 @@ fp_seed(void)
* Always initialize a new context and initialize the hardware.
*/
installctx(curthread, fp,
- fpsave_begin, NULL, fp_new_lwp, fp_new_lwp, NULL, fp_free);
+ fpsave_ctxt, NULL, fp_new_lwp, fp_new_lwp, NULL, fp_free);
fpinit();
/*
@@ -394,6 +393,9 @@ fpnoextflt(struct regs *rp)
/*
* Handle a processor extension overrun fault
* Returns non zero for error.
+ *
+ * XXX Shouldn't this just be abolished given that we're not supporting
+ * anything prior to Pentium?
*/
/* ARGSUSED */
@@ -408,7 +410,6 @@ fpextovrflt(struct regs *rp)
fpinit(); /* initialize the FPU hardware */
setcr0(cur_cr0);
sti();
-
return (1); /* error, send SIGSEGV signal to the thread */
}
diff --git a/usr/src/uts/intel/ia32/os/sendsig.c b/usr/src/uts/intel/ia32/os/sendsig.c
index 73a8800e24..4411476dc8 100644
--- a/usr/src/uts/intel/ia32/os/sendsig.c
+++ b/usr/src/uts/intel/ia32/os/sendsig.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -184,7 +184,7 @@ sendsig(int sig, k_siginfo_t *sip, void (*hdlr)())
* and validate the stack requirements for the signal handler
* context. on_fault will catch any faults.
*/
- newstack = sigismember(&u.u_sigonstack, sig) &&
+ newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
!(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
if (newstack) {
@@ -415,7 +415,7 @@ sendsig32(int sig, k_siginfo_t *sip, void (*hdlr)())
* and validate the stack requirements for the signal handler
* context. on_fault will catch any faults.
*/
- newstack = sigismember(&u.u_sigonstack, sig) &&
+ newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
!(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
if (newstack) {
@@ -635,7 +635,7 @@ sendsig(int sig, k_siginfo_t *sip, void (*hdlr)())
* and validate the stack requirements for the signal handler
* context. on_fault will catch any faults.
*/
- newstack = sigismember(&u.u_sigonstack, sig) &&
+ newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
!(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
if (newstack) {
diff --git a/usr/src/uts/intel/ia32/os/sundep.c b/usr/src/uts/intel/ia32/os/sundep.c
index 1fe1e7e72d..29299be2f1 100644
--- a/usr/src/uts/intel/ia32/os/sundep.c
+++ b/usr/src/uts/intel/ia32/os/sundep.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -88,6 +88,7 @@
#include <sys/contract_impl.h>
#include <sys/x86_archext.h>
#include <sys/segments.h>
+#include <sys/ontrap.h>
/*
* Compare the version of boot that boot says it is against
@@ -219,7 +220,7 @@ kern_setup1(void)
* XXX - we asssume that the u-area is zeroed out except for
* ttolwp(curthread)->lwp_regs.
*/
- u.u_cmask = (mode_t)CMASK;
+ PTOU(curproc)->u_cmask = (mode_t)CMASK;
thread_init(); /* init thread_free list */
pid_init(); /* initialize pid (proc) table */
@@ -292,8 +293,8 @@ lwp_load(klwp_t *lwp, gregset_t grp, uintptr_t thrptr)
rp->r_ps = PSL_USER;
/*
- * For 64-bit lwps, we allow one magic %fs selector value, and one
- * magic %gs selector to point anywhere in the address space using
+ * For 64-bit lwps, we allow null %fs selector value, and null
+ * %gs selector to point anywhere in the address space using
* %fsbase and %gsbase behind the scenes. libc uses %fs to point
* at the ulwp_t structure.
*
@@ -308,6 +309,31 @@ lwp_load(klwp_t *lwp, gregset_t grp, uintptr_t thrptr)
if (lwp_getdatamodel(lwp) == DATAMODEL_ILP32) {
if (grp[REG_GS] == LWPGS_SEL)
(void) lwp_setprivate(lwp, _LWP_GSBASE, thrptr);
+ } else {
+ /*
+ * See lwp_setprivate in kernel and setup_context in libc.
+ *
+ * Currently libc constructs a ucontext from whole cloth for
+ * every new (not main) lwp created. For 64 bit processes
+ * %fsbase is directly set to point to current thread pointer.
+ * In the past (solaris 10) %fs was also set LWPFS_SEL to
+ * indicate %fsbase. Now we use the null GDT selector for
+ * this purpose. LWP[FS|GS]_SEL are only intended for 32 bit
+ * processes. To ease transition we support older libcs in
+ * the newer kernel by forcing %fs or %gs selector to null
+ * by calling lwp_setprivate if LWP[FS|GS]_SEL is passed in
+ * the ucontext. This is should be ripped out at some future
+ * date. Another fix would be for libc to do a getcontext
+ * and inherit the null %fs/%gs from the current context but
+ * that means an extra system call and could hurt performance.
+ */
+ if (grp[REG_FS] == 0x1bb) /* hard code legacy LWPFS_SEL */
+ (void) lwp_setprivate(lwp, _LWP_FSBASE,
+ (uintptr_t)grp[REG_FSBASE]);
+
+ if (grp[REG_GS] == 0x1c3) /* hard code legacy LWPGS_SEL */
+ (void) lwp_setprivate(lwp, _LWP_GSBASE,
+ (uintptr_t)grp[REG_GSBASE]);
}
#else
if (grp[GS] == LWPGS_SEL)
@@ -445,6 +471,125 @@ lwp_segregs_save(klwp_t *lwp)
sizeof (lwp->lwp_pcb.pcb_gsdesc)) == 0);
}
+#if defined(__amd64)
+
+/*
+ * Update the segment registers with new values from the pcb
+ *
+ * We have to do this carefully, and in the following order,
+ * in case any of the selectors points at a bogus descriptor.
+ * If they do, we'll catch trap with on_trap and return 1.
+ * returns 0 on success.
+ *
+ * This is particularly tricky for %gs.
+ * This routine must be executed under a cli.
+ */
+int
+update_sregs(struct regs *rp, klwp_t *lwp)
+{
+ pcb_t *pcb = &lwp->lwp_pcb;
+ ulong_t kgsbase;
+ on_trap_data_t otd;
+ int rc = 0;
+
+ if (!on_trap(&otd, OT_SEGMENT_ACCESS)) {
+
+ kgsbase = (ulong_t)CPU;
+ __set_gs(pcb->pcb_gs);
+
+ /*
+ * If __set_gs fails it's because the new %gs is a bad %gs,
+ * we'll be taking a trap but with the original %gs and %gsbase
+ * undamaged (i.e. pointing at curcpu).
+ *
+ * We've just mucked up the kernel's gsbase. Oops. In
+ * particular we can't take any traps at all. Make the newly
+ * computed gsbase be the hidden gs via __swapgs , and fix
+ * the kernel's gsbase back again. Later, when we return to
+ * userland we'll swapgs again restoring gsbase just loaded
+ * above.
+ */
+ __swapgs();
+ rp->r_gs = pcb->pcb_gs;
+
+ /*
+ * restore kernel's gsbase
+ */
+ wrmsr(MSR_AMD_GSBASE, kgsbase);
+
+ /*
+ * Only override the descriptor base address if
+ * r_gs == LWPGS_SEL or if r_gs == NULL. A note on
+ * NULL descriptors -- 32-bit programs take faults
+ * if they deference NULL descriptors; however,
+ * when 64-bit programs load them into %fs or %gs,
+ * they DONT fault -- only the base address remains
+ * whatever it was from the last load. Urk.
+ *
+ * XXX - note that lwp_setprivate now sets %fs/%gs to the
+ * null selector for 64 bit processes. Whereas before
+ * %fs/%gs were set to LWP(FS|GS)_SEL regardless of
+ * the process's data model. For now we check for both
+ * values so that the kernel can also support the older
+ * libc. This should be ripped out at some point in the
+ * future.
+ */
+ if (pcb->pcb_gs == LWPGS_SEL || pcb->pcb_gs == 0)
+ wrmsr(MSR_AMD_KGSBASE, pcb->pcb_gsbase);
+
+ __set_ds(pcb->pcb_ds);
+ rp->r_ds = pcb->pcb_ds;
+
+ __set_es(pcb->pcb_es);
+ rp->r_es = pcb->pcb_es;
+
+ __set_fs(pcb->pcb_fs);
+ rp->r_fs = pcb->pcb_fs;
+
+ /*
+ * Same as for %gs
+ */
+ if (pcb->pcb_fs == LWPFS_SEL || pcb->pcb_fs == 0)
+ wrmsr(MSR_AMD_FSBASE, pcb->pcb_fsbase);
+
+ } else {
+ cli();
+ rc = 1;
+ }
+ no_trap();
+ return (rc);
+}
+#endif /* __amd64 */
+
+#ifdef _SYSCALL32_IMPL
+
+/*
+ * Make it impossible for a process to change its data model.
+ * We do this by toggling the present bits for the 32 and
+ * 64-bit user code descriptors. That way if a user lwp attempts
+ * to change its data model (by using the wrong code descriptor in
+ * %cs) it will fault immediately. This also allows us to simplify
+ * assertions and checks in the kernel.
+ */
+static void
+gdt_ucode_model(model_t model)
+{
+ cpu_t *cpu;
+
+ kpreempt_disable();
+ cpu = CPU;
+ if (model == DATAMODEL_NATIVE) {
+ cpu->cpu_gdt[GDT_UCODE].usd_p = 1;
+ cpu->cpu_gdt[GDT_U32CODE].usd_p = 0;
+ } else {
+ cpu->cpu_gdt[GDT_U32CODE].usd_p = 1;
+ cpu->cpu_gdt[GDT_UCODE].usd_p = 0;
+ }
+ kpreempt_enable();
+}
+
+#endif /* _SYSCALL32_IMPL */
+
/*
* Restore lwp private fs and gs segment descriptors
* on current cpu's GDT.
@@ -452,27 +597,19 @@ lwp_segregs_save(klwp_t *lwp)
static void
lwp_segregs_restore(klwp_t *lwp)
{
- cpu_t *cpu = CPU;
pcb_t *pcb = &lwp->lwp_pcb;
+ cpu_t *cpu = CPU;
ASSERT(VALID_LWP_DESC(&pcb->pcb_fsdesc));
ASSERT(VALID_LWP_DESC(&pcb->pcb_gsdesc));
+#ifdef _SYSCALL32_IMPL
+ gdt_ucode_model(DATAMODEL_NATIVE);
+#endif
+
cpu->cpu_gdt[GDT_LWPFS] = pcb->pcb_fsdesc;
cpu->cpu_gdt[GDT_LWPGS] = pcb->pcb_gsdesc;
-#if defined(__amd64)
- /*
- * Make it impossible for a process to change its data model.
- * We do this by toggling the present bits for the 32 and
- * 64-bit user code descriptors. That way if a user lwp attempts
- * to change its data model (by using the wrong code descriptor in
- * %cs) it will fault immediately. This also allows us to simplify
- * assertions and checks in the kernel.
- */
- cpu->cpu_gdt[GDT_UCODE].usd_p = 1;
- cpu->cpu_gdt[GDT_U32CODE].usd_p = 0;
-#endif /* __amd64 */
}
#ifdef _SYSCALL32_IMPL
@@ -480,16 +617,16 @@ lwp_segregs_restore(klwp_t *lwp)
static void
lwp_segregs_restore32(klwp_t *lwp)
{
+ /*LINTED*/
cpu_t *cpu = CPU;
pcb_t *pcb = &lwp->lwp_pcb;
- ASSERT(VALID_LWP_DESC(&pcb->pcb_fsdesc));
- ASSERT(VALID_LWP_DESC(&pcb->pcb_gsdesc));
+ ASSERT(VALID_LWP_DESC(&lwp->lwp_pcb.pcb_fsdesc));
+ ASSERT(VALID_LWP_DESC(&lwp->lwp_pcb.pcb_gsdesc));
+ gdt_ucode_model(DATAMODEL_ILP32);
cpu->cpu_gdt[GDT_LWPFS] = pcb->pcb_fsdesc;
cpu->cpu_gdt[GDT_LWPGS] = pcb->pcb_gsdesc;
- cpu->cpu_gdt[GDT_UCODE].usd_p = 0;
- cpu->cpu_gdt[GDT_U32CODE].usd_p = 1;
}
#endif /* _SYSCALL32_IMPL */
@@ -644,18 +781,13 @@ setregs(uarg_t *args)
pcb->pcb_fsbase = pcb->pcb_gsbase = 0;
if (ttoproc(t)->p_model == DATAMODEL_NATIVE) {
- cpu_t *cpu;
rp->r_cs = UCS_SEL;
/*
* Only allow 64-bit user code descriptor to be present.
*/
- kpreempt_disable();
- cpu = CPU;
- cpu->cpu_gdt[GDT_UCODE].usd_p = 1;
- cpu->cpu_gdt[GDT_U32CODE].usd_p = 0;
- kpreempt_enable();
+ gdt_ucode_model(DATAMODEL_NATIVE);
/*
* Arrange that the virtualized %fs and %gs GDT descriptors
@@ -672,7 +804,6 @@ setregs(uarg_t *args)
(void) lwp_setprivate(lwp, _LWP_FSBASE, args->thrptr);
} else {
- cpu_t *cpu;
rp->r_cs = U32CS_SEL;
rp->r_ds = rp->r_es = UDS_SEL;
@@ -680,11 +811,7 @@ setregs(uarg_t *args)
/*
* only allow 32-bit user code selector to be present.
*/
- kpreempt_disable();
- cpu = CPU;
- cpu->cpu_gdt[GDT_UCODE].usd_p = 0;
- cpu->cpu_gdt[GDT_U32CODE].usd_p = 1;
- kpreempt_enable();
+ gdt_ucode_model(DATAMODEL_ILP32);
pcb->pcb_fsdesc = pcb->pcb_gsdesc = zero_u32desc;
@@ -697,7 +824,6 @@ setregs(uarg_t *args)
}
-
pcb->pcb_ds = rp->r_ds;
pcb->pcb_es = rp->r_es;
pcb->pcb_flags |= RUPDATE_PENDING;
@@ -714,7 +840,6 @@ setregs(uarg_t *args)
*/
pcb->pcb_fsdesc = pcb->pcb_gsdesc = zero_udesc;
-
/*
* For %gs we need to reset LWP_GSBASE in pcb and the
* per-cpu GDT descriptor. thrptr is either NULL
diff --git a/usr/src/uts/intel/ia32/os/sysi86.c b/usr/src/uts/intel/ia32/os/sysi86.c
index 8b56b01002..be4eedcb9c 100644
--- a/usr/src/uts/intel/ia32/os/sysi86.c
+++ b/usr/src/uts/intel/ia32/os/sysi86.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -61,15 +61,13 @@
#include <vm/faultcode.h>
#include <sys/fp.h>
#include <sys/cmn_err.h>
+#include <sys/segments.h>
+#include <sys/clock.h>
static void setup_ldt(proc_t *pp);
static void *ldt_map(proc_t *pp, uint_t seli);
static void ldt_free(proc_t *pp);
-extern void rtcsync(void);
-extern long ggmtl(void);
-extern void sgmtl(long);
-
/*
* sysi86 System Call
*/
diff --git a/usr/src/uts/intel/ia32/promif/prom_enter.c b/usr/src/uts/intel/ia32/promif/prom_enter.c
index f6ed906ea4..ba61f1e767 100644
--- a/usr/src/uts/intel/ia32/promif/prom_enter.c
+++ b/usr/src/uts/intel/ia32/promif/prom_enter.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -49,7 +48,7 @@ prom_enter_mon(void)
#endif
if (boothowto & RB_DEBUG)
- kdi_dvec_enter();
+ kmdb_enter();
else {
prom_printf("Press any key to continue.");
(void) prom_getchar();
diff --git a/usr/src/uts/intel/ia32/promif/prom_exit.c b/usr/src/uts/intel/ia32/promif/prom_exit.c
index fb5f662a78..a197cdc165 100644
--- a/usr/src/uts/intel/ia32/promif/prom_exit.c
+++ b/usr/src/uts/intel/ia32/promif/prom_exit.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -56,7 +55,7 @@ prom_exit_to_mon(void)
#else
#if !defined(_KMDB)
if (boothowto & RB_DEBUG)
- kdi_dvec_enter();
+ kmdb_enter();
#endif /* !_KMDB */
prom_reboot_prompt();
prom_reboot(NULL);
diff --git a/usr/src/uts/intel/ia32/promif/prom_panic.c b/usr/src/uts/intel/ia32/promif/prom_panic.c
index 76d29315ac..7fbd81cec2 100644
--- a/usr/src/uts/intel/ia32/promif/prom_panic.c
+++ b/usr/src/uts/intel/ia32/promif/prom_panic.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -50,7 +49,7 @@ prom_panic(char *s)
#elif defined(_KERNEL)
prom_printf(fmt, "kernel", s);
if (boothowto & RB_DEBUG)
- kdi_dvec_enter();
+ kmdb_enter();
#else
#error "configuration error"
#endif
diff --git a/usr/src/uts/intel/ia32/sys/Makefile b/usr/src/uts/intel/ia32/sys/Makefile
index bc26e0e42d..d97b2b007d 100644
--- a/usr/src/uts/intel/ia32/sys/Makefile
+++ b/usr/src/uts/intel/ia32/sys/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -22,7 +21,7 @@
#
#pragma ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# uts/intel/ia32/sys/Makefile
@@ -32,8 +31,8 @@ include ../../../../Makefile.master
HDRS= \
asm_linkage.h \
+ kdi_regs.h \
machtypes.h \
- mmu.h \
privregs.h \
psw.h \
pte.h \
diff --git a/usr/src/uts/intel/ia32/sys/kdi_regs.h b/usr/src/uts/intel/ia32/sys/kdi_regs.h
new file mode 100644
index 0000000000..3012272815
--- /dev/null
+++ b/usr/src/uts/intel/ia32/sys/kdi_regs.h
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _IA32_SYS_KDI_REGS_H
+#define _IA32_SYS_KDI_REGS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define KDIREG_NGREG 21
+
+/*
+ * %ss appears in a different place than a typical struct regs, since the
+ * machine won't save %ss on a trap entry from the same privilege level.
+ */
+
+#define KDIREG_SAVFP 0
+#define KDIREG_SAVPC 1
+#define KDIREG_SS 2
+#define KDIREG_GS 3
+#define KDIREG_FS 4
+#define KDIREG_ES 5
+#define KDIREG_DS 6
+#define KDIREG_EDI 7
+#define KDIREG_ESI 8
+#define KDIREG_EBP 9
+#define KDIREG_ESP 10
+#define KDIREG_EBX 11
+#define KDIREG_EDX 12
+#define KDIREG_ECX 13
+#define KDIREG_EAX 14
+#define KDIREG_TRAPNO 15
+#define KDIREG_ERR 16
+#define KDIREG_EIP 17
+#define KDIREG_CS 18
+#define KDIREG_EFLAGS 19
+#define KDIREG_UESP 20
+
+#define KDIREG_PC KDIREG_EIP
+#define KDIREG_SP KDIREG_ESP
+#define KDIREG_FP KDIREG_EBP
+
+#ifdef _ASM
+
+/* Patch point for MSR clearing. */
+#define KDI_MSR_PATCH \
+ nop; nop; nop; nop; \
+ nop; nop; nop; nop; \
+ nop; nop; nop; nop; \
+ nop
+
+#endif /* _ASM */
+
+#define KDI_MSR_PATCHOFF 8 /* bytes of code before patch point */
+#define KDI_MSR_PATCHSZ 13 /* bytes in KDI_MSR_PATCH, above */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IA32_SYS_KDI_REGS_H */
diff --git a/usr/src/uts/intel/ia32/sys/machtypes.h b/usr/src/uts/intel/ia32/sys/machtypes.h
index c57e83fdf3..c4cbd311dd 100644
--- a/usr/src/uts/intel/ia32/sys/machtypes.h
+++ b/usr/src/uts/intel/ia32/sys/machtypes.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -42,11 +41,24 @@ extern "C" {
#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || \
defined(__EXTENSIONS__)
+#define REG_LABEL_PC 0
+#define REG_LABEL_SP 1
+#define REG_LABEL_BP 2
#if defined(__amd64)
-typedef struct _label_t { long val[8]; } label_t;
-#else
-typedef struct _label_t { long val[6]; } label_t;
-#endif
+#define REG_LABEL_RBX 3
+#define REG_LABEL_R12 4
+#define REG_LABEL_R13 5
+#define REG_LABEL_R14 6
+#define REG_LABEL_R15 7
+#define REG_LABEL_MAX 8
+#else /* __amd64 */
+#define REG_LABEL_EBX 3
+#define REG_LABEL_ESI 4
+#define REG_LABEL_EDI 5
+#define REG_LABEL_MAX 6
+#endif /* __amd64 */
+
+typedef struct _label_t { long val[REG_LABEL_MAX]; } label_t;
#endif /* !defined(_POSIX_C_SOURCE)... */
diff --git a/usr/src/uts/intel/ia32/sys/privregs.h b/usr/src/uts/intel/ia32/sys/privregs.h
index 5c34410768..a1b5e0ae9f 100644
--- a/usr/src/uts/intel/ia32/sys/privregs.h
+++ b/usr/src/uts/intel/ia32/sys/privregs.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -88,12 +88,16 @@ struct regs {
#define GREG_NUM 8 /* Number of regs between %edi and %eax */
-#endif /* !_ASM */
-
#ifdef _KERNEL
#define lwptoregs(lwp) ((struct regs *)((lwp)->lwp_regs))
#endif /* _KERNEL */
+#else /* !_ASM */
+
+#if defined(_MACHDEP)
+
+#include <sys/machprivregs.h>
+
/*
* Save current frame on the stack. Uses %eax.
*/
@@ -149,52 +153,34 @@ struct regs {
* and restoring them on exit.
*/
#define INTR_PUSH \
+ cld; \
pusha; \
__SEGREGS_PUSH \
__FRAME_PUSH \
- cmpw $KGS_SEL, REGOFF_GS(%esp); \
- je 7f; \
+ cmpw $KGS_SEL, REGOFF_GS(%esp); \
+ je 8f; \
movl $0, REGOFF_SAVFP(%esp); \
__SEGREGS_LOAD_KERNEL \
-7:
+8: CLEAN_CS
-#define INTR_POP \
+#define __INTR_POP \
popa; \
addl $8, %esp; /* get TRAPNO and ERR off the stack */
#define INTR_POP_USER \
addl $8, %esp; /* get extra frame off the stack */ \
__SEGREGS_POP \
- INTR_POP
+ __INTR_POP
-#define INTR_POP_KERNEL \
+#define INTR_POP_KERNEL \
addl $24, %esp; /* skip extra frame and segment registers */ \
- INTR_POP
-
-/*
- * Macros for saving the original segment registers and restoring them
- * for fast traps.
- */
-#define FAST_INTR_PUSH \
- __SEGREGS_PUSH \
- __SEGREGS_LOAD_KERNEL
-
-#define FAST_INTR_POP \
- __SEGREGS_POP
-
-#define DISABLE_INTR_FLAGS \
- pushl $F_OFF; \
- popfl;
-
-#define ENABLE_INTR_FLAGS \
- pushl $F_ON; \
- popfl;
-
+ __INTR_POP
/*
* Macros for saving all registers necessary on system call entry,
* and restoring them on exit.
*/
#define SYSCALL_PUSH \
+ cld; \
pusha; \
__SEGREGS_PUSH \
subl $8, %esp; \
@@ -204,9 +190,10 @@ struct regs {
movl %ecx, REGOFF_EFL(%esp); \
movl $0, REGOFF_SAVPC(%esp); \
movl $0, REGOFF_SAVFP(%esp); \
- __SEGREGS_LOAD_KERNEL
+ __SEGREGS_LOAD_KERNEL; \
#define SYSENTER_PUSH \
+ cld; \
pusha; \
__SEGREGS_PUSH \
subl $8, %esp; \
@@ -217,7 +204,17 @@ struct regs {
#define SYSCALL_POP \
INTR_POP_USER
+#endif /* _MACHDEP */
+/*
+ * This is used to set eflags to known values at the head of an
+ * interrupt gate handler, i.e. interrupts are -already- disabled.
+ */
+#define INTGATE_INIT_KERNEL_FLAGS \
+ pushl $F_OFF; \
+ popfl
+
+#endif /* !_ASM */
#include <sys/controlregs.h>
diff --git a/usr/src/uts/intel/ia32/sys/psw.h b/usr/src/uts/intel/ia32/sys/psw.h
index 2bee78b933..5697323d40 100644
--- a/usr/src/uts/intel/ia32/sys/psw.h
+++ b/usr/src/uts/intel/ia32/sys/psw.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -24,7 +23,7 @@
/* All Rights Reserved */
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -110,7 +109,7 @@ typedef int psw_t;
#include <sys/tss.h>
#include <sys/segments.h> /* selector definitions */
-#define USERMODE(cs) ((uint_t)((cs)&CPL_MASK) != 0)
+#define USERMODE(cs) ((uint16_t)(cs) != KCS_SEL)
#include <sys/spl.h>
diff --git a/usr/src/uts/intel/ia32/sys/pte.h b/usr/src/uts/intel/ia32/sys/pte.h
index c0c2726d9c..138647347a 100644
--- a/usr/src/uts/intel/ia32/sys/pte.h
+++ b/usr/src/uts/intel/ia32/sys/pte.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,7 +30,6 @@
#ifndef _ASM
#include <sys/types.h>
-#include <ia32/sys/mmu.h>
#endif /* _ASM */
#ifdef __cplusplus
diff --git a/usr/src/uts/intel/ia32/sys/traptrace.h b/usr/src/uts/intel/ia32/sys/traptrace.h
index a105e0fde2..89e13f513f 100644
--- a/usr/src/uts/intel/ia32/sys/traptrace.h
+++ b/usr/src/uts/intel/ia32/sys/traptrace.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,19 +35,20 @@ extern "C" {
#include <sys/privregs.h>
/*
- * XX64 Need to fix the following comment.
- *
* Trap tracing. If TRAPTRACE is defined, an entry is recorded every time
* the CPU jumps through the Interrupt Descriptor Table (IDT). One exception
* is the Double Fault handler, which does not record a traptrace entry.
+ *
+ * There are facilities to (conditionally) interleave tracing of related
+ * facilities e.h. x-calls.
*/
/*
- * XX64 -- non-assembler files that include this file must include
+ * Note: non-assembler files that include this file must include
* <sys/systm.h> before it, for the typedef of pc_t to be visible.
*/
-#define TTR_STACK_DEPTH 15
+#define TTR_STACK_DEPTH 10
#ifndef _ASM
@@ -66,7 +66,7 @@ typedef struct {
greg_t ttr_cr2;
union _ttr_info {
struct _idt_entry {
- uchar_t vector;
+ short vector;
uchar_t ipl;
uchar_t spl;
uchar_t pri;
@@ -74,6 +74,17 @@ typedef struct {
struct _gate_entry {
int sysnum;
} gate_entry;
+ struct _xc_entry {
+ ulong_t xce_arg;
+ ulong_t xce_func;
+ int8_t xce_pri;
+ uint8_t xce_marker,
+ xce_pend,
+ xce_wait,
+ xce_ack,
+ xce_state;
+ uint_t xce_retval;
+ } xc_entry;
} ttr_info;
uintptr_t ttr_curthread;
uchar_t ttr_pad[TTR_PAD1_SIZE];
@@ -96,6 +107,8 @@ extern size_t trap_trace_bufsize;
extern int trap_trace_freeze;
extern trap_trace_rec_t trap_trace_postmort; /* Entry used after death */
+extern trap_trace_rec_t *trap_trace_get_traceptr(uint8_t, ulong_t, ulong_t);
+
#define TRAPTRACE_FREEZE trap_trace_freeze = 1;
#define TRAPTRACE_UNFREEZE trap_trace_freeze = 0;
@@ -160,6 +173,8 @@ extern trap_trace_rec_t trap_trace_postmort; /* Entry used after death */
* Note that this macro defines label "9".
* Also captures curthread on exit of loop.
*/
+#define __GETCR2(_mov, reg) \
+ _mov %cr2, reg
#if defined(__amd64)
@@ -173,7 +188,7 @@ extern trap_trace_rec_t trap_trace_postmort; /* Entry used after death */
jl 9b; \
movq %gs:CPU_THREAD, scr2; \
movq scr2, TTR_CURTHREAD(ptr); \
- movq %cr2, scr2; \
+ __GETCR2(movq, scr2); \
movq scr2, TTR_CR2(ptr)
#elif defined(__i386)
@@ -188,7 +203,7 @@ extern trap_trace_rec_t trap_trace_postmort; /* Entry used after death */
jl 9b; \
movl %gs:CPU_THREAD, scr2; \
movl scr2, TTR_CURTHREAD(ptr); \
- movl %cr2, scr2; \
+ __GETCR2(movl, scr2); \
movl scr2, TTR_CR2(ptr)
#endif /* __i386 */
@@ -244,6 +259,23 @@ extern trap_trace_rec_t trap_trace_postmort; /* Entry used after death */
9: movl %eax, TTR_STAMP(reg); \
movl %edx, TTR_STAMP+4(reg)
+#define TRACE_STACK(tt) \
+ pushl %eax; \
+ pushl %ecx; \
+ pushl %edx; \
+ pushl %ebx; \
+ pushl $TTR_STACK_DEPTH; \
+ movl tt, %ebx; \
+ leal TTR_STACK(%ebx), %eax; \
+ pushl %eax; \
+ call getpcstack; \
+ addl $8, %esp; \
+ movl %eax, TTR_SDEPTH(%ebx); \
+ popl %ebx; \
+ popl %edx; \
+ popl %ecx; \
+ popl %eax
+
#endif /* __i386 */
#else
@@ -264,6 +296,22 @@ extern trap_trace_rec_t trap_trace_postmort; /* Entry used after death */
#define TT_INTERRUPT 0xbb
#define TT_TRAP 0xcc
#define TT_INTTRAP 0xdd
+#define TT_EVENT 0xee /* hypervisor event */
+#define TT_XCALL 0xf0 /* x-call handling */
+
+/*
+ * TT_XCALL subcodes:
+ */
+#define TT_XC_SVC_BEGIN 0 /* xc_serv() entry */
+#define TT_XC_SVC_END 1 /* xc_serv() return */
+#define TT_XC_START 2 /* xc_common() - pre-dirint */
+#define TT_XC_WAIT 3 /* xc_common() - wait for completion */
+#define TT_XC_ACK 4 /* xc_common() - ack completion */
+#define TT_XC_CAPTURE 5 /* xc_capture() */
+#define TT_XC_RELEASE 6 /* xc_release() */
+#define TT_XC_POKE_CPU 7 /* poke_cpu() */
+#define TT_XC_CBE_FIRE 8 /* cbe_fire() */
+#define TT_XC_CBE_XCALL 9 /* cbe_xcall() */
#ifdef __cplusplus
}
diff --git a/usr/src/uts/intel/ia32/syscall/lwp_private.c b/usr/src/uts/intel/ia32/syscall/lwp_private.c
index 9e97c25efa..da9985a5a2 100644
--- a/usr/src/uts/intel/ia32/syscall/lwp_private.c
+++ b/usr/src/uts/intel/ia32/syscall/lwp_private.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -65,13 +64,14 @@ lwp_setprivate(klwp_t *lwp, int which, uintptr_t base)
* to work, which is needed by emulators for legacy application
* environments ..
*
- * 64-bit processes also point to a per-cpu GDT segment descriptor
+ * 64-bit processes may also point to a per-cpu GDT segment descriptor
* virtualized to the lwp. However the descriptor base is forced
* to zero (because we can't express the full 64-bit address range
* in a long mode descriptor), so don't reload segment registers
- * in a 64-bit program!
+ * in a 64-bit program! 64-bit processes must have selector values
+ * of zero for %fs and %gs to use the 64-bit fs_base and gs_base
+ * respectively.
*/
-
if ((pcb->pcb_flags & RUPDATE_PENDING) == 0) {
pcb->pcb_ds = rp->r_ds;
pcb->pcb_es = rp->r_es;
@@ -84,28 +84,32 @@ lwp_setprivate(klwp_t *lwp, int which, uintptr_t base)
switch (which) {
case _LWP_FSBASE:
- if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE)
+ if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE) {
set_usegd(&pcb->pcb_fsdesc, SDP_LONG, 0, 0,
SDT_MEMRWA, SEL_UPL, SDP_BYTES, SDP_OP32);
- else
+ rval = pcb->pcb_fs = 0; /* null gdt descriptor */
+ } else {
set_usegd(&pcb->pcb_fsdesc, SDP_SHORT, (void *)base, -1,
SDT_MEMRWA, SEL_UPL, SDP_PAGES, SDP_OP32);
+ rval = pcb->pcb_fs = LWPFS_SEL;
+ }
if (thisthread)
CPU->cpu_gdt[GDT_LWPFS] = pcb->pcb_fsdesc;
pcb->pcb_fsbase = base;
- rval = pcb->pcb_fs = LWPFS_SEL;
break;
case _LWP_GSBASE:
- if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE)
+ if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE) {
set_usegd(&pcb->pcb_gsdesc, SDP_LONG, 0, 0,
SDT_MEMRWA, SEL_UPL, SDP_BYTES, SDP_OP32);
- else
+ rval = pcb->pcb_gs = 0; /* null gdt descriptor */
+ } else {
set_usegd(&pcb->pcb_gsdesc, SDP_SHORT, (void *)base, -1,
SDT_MEMRWA, SEL_UPL, SDP_PAGES, SDP_OP32);
+ rval = pcb->pcb_gs = LWPGS_SEL;
+ }
if (thisthread)
CPU->cpu_gdt[GDT_LWPGS] = pcb->pcb_gsdesc;
pcb->pcb_gsbase = base;
- rval = pcb->pcb_gs = LWPGS_SEL;
break;
default:
rval = -1;
@@ -115,7 +119,7 @@ lwp_setprivate(klwp_t *lwp, int which, uintptr_t base)
#elif defined(__i386)
/*
- * 32-bit compatibility processes point to the per-cpu GDT segment
+ * 32-bit processes point to the per-cpu GDT segment
* descriptors that are virtualized to the lwp.
*/
@@ -162,24 +166,44 @@ lwp_getprivate(klwp_t *lwp, int which, uintptr_t base)
case _LWP_FSBASE:
if ((sbase = pcb->pcb_fsbase) != 0) {
- if (pcb->pcb_flags & RUPDATE_PENDING) {
- if (pcb->pcb_fs == LWPFS_SEL)
- break;
+ if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE) {
+ if (pcb->pcb_flags & RUPDATE_PENDING) {
+ if (pcb->pcb_fs == 0)
+ break;
+ } else {
+ if (rp->r_fs == 0)
+ break;
+ }
} else {
- if (rp->r_fs == LWPFS_SEL)
- break;
+ if (pcb->pcb_flags & RUPDATE_PENDING) {
+ if (pcb->pcb_fs == LWPFS_SEL)
+ break;
+ } else {
+ if (rp->r_fs == LWPFS_SEL)
+ break;
+ }
}
}
error = EINVAL;
break;
case _LWP_GSBASE:
if ((sbase = pcb->pcb_gsbase) != 0) {
- if (pcb->pcb_flags & RUPDATE_PENDING) {
- if (pcb->pcb_gs == LWPGS_SEL)
- break;
+ if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE) {
+ if (pcb->pcb_flags & RUPDATE_PENDING) {
+ if (pcb->pcb_gs == 0)
+ break;
+ } else {
+ if (rp->r_gs == 0)
+ break;
+ }
} else {
- if (rp->r_gs == LWPGS_SEL)
- break;
+ if (pcb->pcb_flags & RUPDATE_PENDING) {
+ if (pcb->pcb_gs == LWPGS_SEL)
+ break;
+ } else {
+ if (rp->r_gs == LWPGS_SEL)
+ break;
+ }
}
}
error = EINVAL;
diff --git a/usr/src/uts/i86pc/io/acpica/README.txt b/usr/src/uts/intel/io/acpica/README.txt
index b41ae583c3..b41ae583c3 100644
--- a/usr/src/uts/i86pc/io/acpica/README.txt
+++ b/usr/src/uts/intel/io/acpica/README.txt
diff --git a/usr/src/uts/i86pc/io/acpica/acpi_enum.c b/usr/src/uts/intel/io/acpica/acpi_enum.c
index 9b0977bd62..9b0977bd62 100644
--- a/usr/src/uts/i86pc/io/acpica/acpi_enum.c
+++ b/usr/src/uts/intel/io/acpica/acpi_enum.c
diff --git a/usr/src/uts/i86pc/io/acpica/acpica.c b/usr/src/uts/intel/io/acpica/acpica.c
index a1d10cb5ae..a1d10cb5ae 100644
--- a/usr/src/uts/i86pc/io/acpica/acpica.c
+++ b/usr/src/uts/intel/io/acpica/acpica.c
diff --git a/usr/src/uts/i86pc/io/acpica/acpica_ec.c b/usr/src/uts/intel/io/acpica/acpica_ec.c
index eee4b90803..eee4b90803 100644
--- a/usr/src/uts/i86pc/io/acpica/acpica_ec.c
+++ b/usr/src/uts/intel/io/acpica/acpica_ec.c
diff --git a/usr/src/uts/i86pc/io/acpica/changes.txt b/usr/src/uts/intel/io/acpica/changes.txt
index a7b0278cf5..a7b0278cf5 100644
--- a/usr/src/uts/i86pc/io/acpica/changes.txt
+++ b/usr/src/uts/intel/io/acpica/changes.txt
diff --git a/usr/src/uts/i86pc/io/acpica/cmp_ca.sh b/usr/src/uts/intel/io/acpica/cmp_ca.sh
index b23cfd1f94..0113487ef6 100755
--- a/usr/src/uts/i86pc/io/acpica/cmp_ca.sh
+++ b/usr/src/uts/intel/io/acpica/cmp_ca.sh
@@ -20,7 +20,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -33,7 +33,7 @@ ACDIR=/export/home/myers/acpica/acpica-unix-20060721
DIFF="diff -w"
WSDIR=`workspace name`
-WSSRC=usr/src/uts/i86pc/io/acpica
+WSSRC=usr/src/uts/intel/io/acpica
WSHDR=usr/src/uts/intel/sys/acpi
ACFILES=/tmp/$$.acfiles
SRCDIRS="debugger disassembler events hardware interpreter namespace \
diff --git a/usr/src/uts/i86pc/io/acpica/debugger/dbcmds.c b/usr/src/uts/intel/io/acpica/debugger/dbcmds.c
index b3ae57d306..b3ae57d306 100644
--- a/usr/src/uts/i86pc/io/acpica/debugger/dbcmds.c
+++ b/usr/src/uts/intel/io/acpica/debugger/dbcmds.c
diff --git a/usr/src/uts/i86pc/io/acpica/debugger/dbdisply.c b/usr/src/uts/intel/io/acpica/debugger/dbdisply.c
index d2a7eb578a..d2a7eb578a 100644
--- a/usr/src/uts/i86pc/io/acpica/debugger/dbdisply.c
+++ b/usr/src/uts/intel/io/acpica/debugger/dbdisply.c
diff --git a/usr/src/uts/i86pc/io/acpica/debugger/dbexec.c b/usr/src/uts/intel/io/acpica/debugger/dbexec.c
index 4547f0e5b4..4547f0e5b4 100644
--- a/usr/src/uts/i86pc/io/acpica/debugger/dbexec.c
+++ b/usr/src/uts/intel/io/acpica/debugger/dbexec.c
diff --git a/usr/src/uts/i86pc/io/acpica/debugger/dbfileio.c b/usr/src/uts/intel/io/acpica/debugger/dbfileio.c
index 7a4c761882..7a4c761882 100644
--- a/usr/src/uts/i86pc/io/acpica/debugger/dbfileio.c
+++ b/usr/src/uts/intel/io/acpica/debugger/dbfileio.c
diff --git a/usr/src/uts/i86pc/io/acpica/debugger/dbhistry.c b/usr/src/uts/intel/io/acpica/debugger/dbhistry.c
index afc12ba0d6..afc12ba0d6 100644
--- a/usr/src/uts/i86pc/io/acpica/debugger/dbhistry.c
+++ b/usr/src/uts/intel/io/acpica/debugger/dbhistry.c
diff --git a/usr/src/uts/i86pc/io/acpica/debugger/dbinput.c b/usr/src/uts/intel/io/acpica/debugger/dbinput.c
index cf0162f737..cf0162f737 100644
--- a/usr/src/uts/i86pc/io/acpica/debugger/dbinput.c
+++ b/usr/src/uts/intel/io/acpica/debugger/dbinput.c
diff --git a/usr/src/uts/i86pc/io/acpica/debugger/dbstats.c b/usr/src/uts/intel/io/acpica/debugger/dbstats.c
index 3dde13c246..3dde13c246 100644
--- a/usr/src/uts/i86pc/io/acpica/debugger/dbstats.c
+++ b/usr/src/uts/intel/io/acpica/debugger/dbstats.c
diff --git a/usr/src/uts/i86pc/io/acpica/debugger/dbutils.c b/usr/src/uts/intel/io/acpica/debugger/dbutils.c
index 5a1b1b017f..5a1b1b017f 100644
--- a/usr/src/uts/i86pc/io/acpica/debugger/dbutils.c
+++ b/usr/src/uts/intel/io/acpica/debugger/dbutils.c
diff --git a/usr/src/uts/i86pc/io/acpica/debugger/dbxface.c b/usr/src/uts/intel/io/acpica/debugger/dbxface.c
index fdc2ef797c..fdc2ef797c 100644
--- a/usr/src/uts/i86pc/io/acpica/debugger/dbxface.c
+++ b/usr/src/uts/intel/io/acpica/debugger/dbxface.c
diff --git a/usr/src/uts/i86pc/io/acpica/disassembler/dmbuffer.c b/usr/src/uts/intel/io/acpica/disassembler/dmbuffer.c
index 8f7bbb4c97..8f7bbb4c97 100644
--- a/usr/src/uts/i86pc/io/acpica/disassembler/dmbuffer.c
+++ b/usr/src/uts/intel/io/acpica/disassembler/dmbuffer.c
diff --git a/usr/src/uts/i86pc/io/acpica/disassembler/dmnames.c b/usr/src/uts/intel/io/acpica/disassembler/dmnames.c
index 939f4b183b..939f4b183b 100644
--- a/usr/src/uts/i86pc/io/acpica/disassembler/dmnames.c
+++ b/usr/src/uts/intel/io/acpica/disassembler/dmnames.c
diff --git a/usr/src/uts/i86pc/io/acpica/disassembler/dmobject.c b/usr/src/uts/intel/io/acpica/disassembler/dmobject.c
index d3756e8369..d3756e8369 100644
--- a/usr/src/uts/i86pc/io/acpica/disassembler/dmobject.c
+++ b/usr/src/uts/intel/io/acpica/disassembler/dmobject.c
diff --git a/usr/src/uts/i86pc/io/acpica/disassembler/dmopcode.c b/usr/src/uts/intel/io/acpica/disassembler/dmopcode.c
index 1d907e5bbb..1d907e5bbb 100644
--- a/usr/src/uts/i86pc/io/acpica/disassembler/dmopcode.c
+++ b/usr/src/uts/intel/io/acpica/disassembler/dmopcode.c
diff --git a/usr/src/uts/i86pc/io/acpica/disassembler/dmresrc.c b/usr/src/uts/intel/io/acpica/disassembler/dmresrc.c
index 63e68926b6..63e68926b6 100644
--- a/usr/src/uts/i86pc/io/acpica/disassembler/dmresrc.c
+++ b/usr/src/uts/intel/io/acpica/disassembler/dmresrc.c
diff --git a/usr/src/uts/i86pc/io/acpica/disassembler/dmresrcl.c b/usr/src/uts/intel/io/acpica/disassembler/dmresrcl.c
index 514e139184..514e139184 100644
--- a/usr/src/uts/i86pc/io/acpica/disassembler/dmresrcl.c
+++ b/usr/src/uts/intel/io/acpica/disassembler/dmresrcl.c
diff --git a/usr/src/uts/i86pc/io/acpica/disassembler/dmresrcs.c b/usr/src/uts/intel/io/acpica/disassembler/dmresrcs.c
index 86c9d9f8e5..86c9d9f8e5 100644
--- a/usr/src/uts/i86pc/io/acpica/disassembler/dmresrcs.c
+++ b/usr/src/uts/intel/io/acpica/disassembler/dmresrcs.c
diff --git a/usr/src/uts/i86pc/io/acpica/disassembler/dmutils.c b/usr/src/uts/intel/io/acpica/disassembler/dmutils.c
index ffcce5ca31..ffcce5ca31 100644
--- a/usr/src/uts/i86pc/io/acpica/disassembler/dmutils.c
+++ b/usr/src/uts/intel/io/acpica/disassembler/dmutils.c
diff --git a/usr/src/uts/i86pc/io/acpica/disassembler/dmwalk.c b/usr/src/uts/intel/io/acpica/disassembler/dmwalk.c
index 69e38ff69d..69e38ff69d 100644
--- a/usr/src/uts/i86pc/io/acpica/disassembler/dmwalk.c
+++ b/usr/src/uts/intel/io/acpica/disassembler/dmwalk.c
diff --git a/usr/src/uts/i86pc/io/acpica/events/evevent.c b/usr/src/uts/intel/io/acpica/events/evevent.c
index b9e880bf1a..b9e880bf1a 100644
--- a/usr/src/uts/i86pc/io/acpica/events/evevent.c
+++ b/usr/src/uts/intel/io/acpica/events/evevent.c
diff --git a/usr/src/uts/i86pc/io/acpica/events/evgpe.c b/usr/src/uts/intel/io/acpica/events/evgpe.c
index 52d244eba6..52d244eba6 100644
--- a/usr/src/uts/i86pc/io/acpica/events/evgpe.c
+++ b/usr/src/uts/intel/io/acpica/events/evgpe.c
diff --git a/usr/src/uts/i86pc/io/acpica/events/evgpeblk.c b/usr/src/uts/intel/io/acpica/events/evgpeblk.c
index 21a6692139..21a6692139 100644
--- a/usr/src/uts/i86pc/io/acpica/events/evgpeblk.c
+++ b/usr/src/uts/intel/io/acpica/events/evgpeblk.c
diff --git a/usr/src/uts/i86pc/io/acpica/events/evmisc.c b/usr/src/uts/intel/io/acpica/events/evmisc.c
index d63b1b66ac..d63b1b66ac 100644
--- a/usr/src/uts/i86pc/io/acpica/events/evmisc.c
+++ b/usr/src/uts/intel/io/acpica/events/evmisc.c
diff --git a/usr/src/uts/i86pc/io/acpica/events/evregion.c b/usr/src/uts/intel/io/acpica/events/evregion.c
index 27a470d1c7..27a470d1c7 100644
--- a/usr/src/uts/i86pc/io/acpica/events/evregion.c
+++ b/usr/src/uts/intel/io/acpica/events/evregion.c
diff --git a/usr/src/uts/i86pc/io/acpica/events/evrgnini.c b/usr/src/uts/intel/io/acpica/events/evrgnini.c
index 88a7b1b23f..88a7b1b23f 100644
--- a/usr/src/uts/i86pc/io/acpica/events/evrgnini.c
+++ b/usr/src/uts/intel/io/acpica/events/evrgnini.c
diff --git a/usr/src/uts/i86pc/io/acpica/events/evsci.c b/usr/src/uts/intel/io/acpica/events/evsci.c
index abde1c9d28..abde1c9d28 100644
--- a/usr/src/uts/i86pc/io/acpica/events/evsci.c
+++ b/usr/src/uts/intel/io/acpica/events/evsci.c
diff --git a/usr/src/uts/i86pc/io/acpica/events/evxface.c b/usr/src/uts/intel/io/acpica/events/evxface.c
index ae1a12144f..ae1a12144f 100644
--- a/usr/src/uts/i86pc/io/acpica/events/evxface.c
+++ b/usr/src/uts/intel/io/acpica/events/evxface.c
diff --git a/usr/src/uts/i86pc/io/acpica/events/evxfevnt.c b/usr/src/uts/intel/io/acpica/events/evxfevnt.c
index 5f52cdce82..5f52cdce82 100644
--- a/usr/src/uts/i86pc/io/acpica/events/evxfevnt.c
+++ b/usr/src/uts/intel/io/acpica/events/evxfevnt.c
diff --git a/usr/src/uts/i86pc/io/acpica/events/evxfregn.c b/usr/src/uts/intel/io/acpica/events/evxfregn.c
index 834d65a65d..834d65a65d 100644
--- a/usr/src/uts/i86pc/io/acpica/events/evxfregn.c
+++ b/usr/src/uts/intel/io/acpica/events/evxfregn.c
diff --git a/usr/src/uts/i86pc/io/acpica/hardware/hwacpi.c b/usr/src/uts/intel/io/acpica/hardware/hwacpi.c
index 6849bb0321..6849bb0321 100644
--- a/usr/src/uts/i86pc/io/acpica/hardware/hwacpi.c
+++ b/usr/src/uts/intel/io/acpica/hardware/hwacpi.c
diff --git a/usr/src/uts/i86pc/io/acpica/hardware/hwgpe.c b/usr/src/uts/intel/io/acpica/hardware/hwgpe.c
index a9da5e29ac..a9da5e29ac 100644
--- a/usr/src/uts/i86pc/io/acpica/hardware/hwgpe.c
+++ b/usr/src/uts/intel/io/acpica/hardware/hwgpe.c
diff --git a/usr/src/uts/i86pc/io/acpica/hardware/hwregs.c b/usr/src/uts/intel/io/acpica/hardware/hwregs.c
index 81d63f8f2a..81d63f8f2a 100644
--- a/usr/src/uts/i86pc/io/acpica/hardware/hwregs.c
+++ b/usr/src/uts/intel/io/acpica/hardware/hwregs.c
diff --git a/usr/src/uts/i86pc/io/acpica/hardware/hwsleep.c b/usr/src/uts/intel/io/acpica/hardware/hwsleep.c
index 56e7783a20..56e7783a20 100644
--- a/usr/src/uts/i86pc/io/acpica/hardware/hwsleep.c
+++ b/usr/src/uts/intel/io/acpica/hardware/hwsleep.c
diff --git a/usr/src/uts/i86pc/io/acpica/hardware/hwtimer.c b/usr/src/uts/intel/io/acpica/hardware/hwtimer.c
index 827a828b8c..827a828b8c 100644
--- a/usr/src/uts/i86pc/io/acpica/hardware/hwtimer.c
+++ b/usr/src/uts/intel/io/acpica/hardware/hwtimer.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsfield.c b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsfield.c
index 7f17d5ed4d..7f17d5ed4d 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsfield.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsfield.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsinit.c b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsinit.c
index 4ead117b08..4ead117b08 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsinit.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsinit.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsmethod.c b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsmethod.c
index cbb6869bd6..cbb6869bd6 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsmethod.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsmethod.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsmthdat.c b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsmthdat.c
index c649f10fd9..c649f10fd9 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsmthdat.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsmthdat.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsobject.c b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsobject.c
index 6ad096ba84..6ad096ba84 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsobject.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsobject.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsopcode.c b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsopcode.c
index b5e5675fa0..b5e5675fa0 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsopcode.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsopcode.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsutils.c b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsutils.c
index 496df6767b..496df6767b 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dsutils.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dsutils.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dswexec.c b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dswexec.c
index 4b84880880..4b84880880 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dswexec.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dswexec.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dswload.c b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dswload.c
index 1abe72c5fa..1abe72c5fa 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dswload.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dswload.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dswscope.c b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dswscope.c
index f5d05a7496..f5d05a7496 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dswscope.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dswscope.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dswstate.c b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dswstate.c
index 204acfc559..204acfc559 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/dispatcher/dswstate.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/dispatcher/dswstate.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exconfig.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exconfig.c
index 90bb058480..90bb058480 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exconfig.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exconfig.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exconvrt.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exconvrt.c
index a5882b183a..a5882b183a 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exconvrt.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exconvrt.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/excreate.c b/usr/src/uts/intel/io/acpica/interpreter/executer/excreate.c
index 64b2920060..64b2920060 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/excreate.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/excreate.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exdump.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exdump.c
index 2a106e871f..2a106e871f 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exdump.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exdump.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exfield.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exfield.c
index b134302c8d..b134302c8d 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exfield.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exfield.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exfldio.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exfldio.c
index d17d4fb68f..d17d4fb68f 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exfldio.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exfldio.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exmisc.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exmisc.c
index 21f065ba89..21f065ba89 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exmisc.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exmisc.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exmutex.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exmutex.c
index 23414c4457..23414c4457 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exmutex.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exmutex.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exnames.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exnames.c
index 1fd5d260db..1fd5d260db 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exnames.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exnames.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exoparg1.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exoparg1.c
index 70157e591d..70157e591d 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exoparg1.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exoparg1.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exoparg2.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exoparg2.c
index 53ee147640..53ee147640 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exoparg2.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exoparg2.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exoparg3.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exoparg3.c
index 77a4e915b6..77a4e915b6 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exoparg3.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exoparg3.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exoparg6.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exoparg6.c
index f65c313f93..f65c313f93 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exoparg6.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exoparg6.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exprep.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exprep.c
index 7c024ec11d..7c024ec11d 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exprep.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exprep.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exregion.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exregion.c
index c53757fea6..c53757fea6 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exregion.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exregion.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exresnte.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exresnte.c
index c7b5a460c5..c7b5a460c5 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exresnte.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exresnte.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exresolv.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exresolv.c
index 2efa748144..2efa748144 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exresolv.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exresolv.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exresop.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exresop.c
index 2f684ae4df..2f684ae4df 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exresop.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exresop.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exstore.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exstore.c
index bc3ee25f39..bc3ee25f39 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exstore.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exstore.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exstoren.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exstoren.c
index 452563ff44..452563ff44 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exstoren.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exstoren.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exstorob.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exstorob.c
index 4810c0b860..4810c0b860 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exstorob.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exstorob.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exsystem.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exsystem.c
index 194bdaf293..194bdaf293 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exsystem.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exsystem.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exutils.c b/usr/src/uts/intel/io/acpica/interpreter/executer/exutils.c
index 12e97cda51..12e97cda51 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/executer/exutils.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/executer/exutils.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psargs.c b/usr/src/uts/intel/io/acpica/interpreter/parser/psargs.c
index a5aca6460a..a5aca6460a 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psargs.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/parser/psargs.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psloop.c b/usr/src/uts/intel/io/acpica/interpreter/parser/psloop.c
index d3ef539bd1..d3ef539bd1 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psloop.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/parser/psloop.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psopcode.c b/usr/src/uts/intel/io/acpica/interpreter/parser/psopcode.c
index 833073f612..833073f612 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psopcode.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/parser/psopcode.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psparse.c b/usr/src/uts/intel/io/acpica/interpreter/parser/psparse.c
index 6bf7fdc7c5..6bf7fdc7c5 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psparse.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/parser/psparse.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psscope.c b/usr/src/uts/intel/io/acpica/interpreter/parser/psscope.c
index aa57aa3bc5..aa57aa3bc5 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psscope.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/parser/psscope.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/parser/pstree.c b/usr/src/uts/intel/io/acpica/interpreter/parser/pstree.c
index d7f62ebecc..d7f62ebecc 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/parser/pstree.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/parser/pstree.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psutils.c b/usr/src/uts/intel/io/acpica/interpreter/parser/psutils.c
index 63105b4615..63105b4615 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psutils.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/parser/psutils.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/parser/pswalk.c b/usr/src/uts/intel/io/acpica/interpreter/parser/pswalk.c
index 439f842b53..439f842b53 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/parser/pswalk.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/parser/pswalk.c
diff --git a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psxface.c b/usr/src/uts/intel/io/acpica/interpreter/parser/psxface.c
index ac1dbdb6f6..ac1dbdb6f6 100644
--- a/usr/src/uts/i86pc/io/acpica/interpreter/parser/psxface.c
+++ b/usr/src/uts/intel/io/acpica/interpreter/parser/psxface.c
diff --git a/usr/src/uts/i86pc/io/acpica/master_ops.c b/usr/src/uts/intel/io/acpica/master_ops.c
index e37029f6cf..e37029f6cf 100644
--- a/usr/src/uts/i86pc/io/acpica/master_ops.c
+++ b/usr/src/uts/intel/io/acpica/master_ops.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsaccess.c b/usr/src/uts/intel/io/acpica/namespace/nsaccess.c
index 9452903499..9452903499 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsaccess.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsaccess.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsalloc.c b/usr/src/uts/intel/io/acpica/namespace/nsalloc.c
index 322e0b8117..322e0b8117 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsalloc.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsalloc.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsdump.c b/usr/src/uts/intel/io/acpica/namespace/nsdump.c
index 5621745320..5621745320 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsdump.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsdump.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsdumpdv.c b/usr/src/uts/intel/io/acpica/namespace/nsdumpdv.c
index c74b4c386f..c74b4c386f 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsdumpdv.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsdumpdv.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nseval.c b/usr/src/uts/intel/io/acpica/namespace/nseval.c
index f9b7ead8d7..f9b7ead8d7 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nseval.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nseval.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsinit.c b/usr/src/uts/intel/io/acpica/namespace/nsinit.c
index be13cb49be..be13cb49be 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsinit.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsinit.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsload.c b/usr/src/uts/intel/io/acpica/namespace/nsload.c
index 10a75070e5..10a75070e5 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsload.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsload.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsnames.c b/usr/src/uts/intel/io/acpica/namespace/nsnames.c
index 236776c994..236776c994 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsnames.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsnames.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsobject.c b/usr/src/uts/intel/io/acpica/namespace/nsobject.c
index a59f0c0748..a59f0c0748 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsobject.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsobject.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsparse.c b/usr/src/uts/intel/io/acpica/namespace/nsparse.c
index c5a21928ab..c5a21928ab 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsparse.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsparse.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nssearch.c b/usr/src/uts/intel/io/acpica/namespace/nssearch.c
index 7ec8f1f048..7ec8f1f048 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nssearch.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nssearch.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsutils.c b/usr/src/uts/intel/io/acpica/namespace/nsutils.c
index 4994384da8..4994384da8 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsutils.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsutils.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nswalk.c b/usr/src/uts/intel/io/acpica/namespace/nswalk.c
index b1d5087c78..b1d5087c78 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nswalk.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nswalk.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsxfeval.c b/usr/src/uts/intel/io/acpica/namespace/nsxfeval.c
index 3b88369187..3b88369187 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsxfeval.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsxfeval.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsxfname.c b/usr/src/uts/intel/io/acpica/namespace/nsxfname.c
index 5aa6d37c42..5aa6d37c42 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsxfname.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsxfname.c
diff --git a/usr/src/uts/i86pc/io/acpica/namespace/nsxfobj.c b/usr/src/uts/intel/io/acpica/namespace/nsxfobj.c
index 799729b1a4..799729b1a4 100644
--- a/usr/src/uts/i86pc/io/acpica/namespace/nsxfobj.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsxfobj.c
diff --git a/usr/src/uts/i86pc/io/acpica/osl.c b/usr/src/uts/intel/io/acpica/osl.c
index 205e7a0ea9..205e7a0ea9 100644
--- a/usr/src/uts/i86pc/io/acpica/osl.c
+++ b/usr/src/uts/intel/io/acpica/osl.c
diff --git a/usr/src/uts/i86pc/io/acpica/osl_ml.s b/usr/src/uts/intel/io/acpica/osl_ml.s
index 07c85bbc6b..07c85bbc6b 100644
--- a/usr/src/uts/i86pc/io/acpica/osl_ml.s
+++ b/usr/src/uts/intel/io/acpica/osl_ml.s
diff --git a/usr/src/uts/i86pc/io/acpica/resources/rsaddr.c b/usr/src/uts/intel/io/acpica/resources/rsaddr.c
index 5172e77f1b..5172e77f1b 100644
--- a/usr/src/uts/i86pc/io/acpica/resources/rsaddr.c
+++ b/usr/src/uts/intel/io/acpica/resources/rsaddr.c
diff --git a/usr/src/uts/i86pc/io/acpica/resources/rscalc.c b/usr/src/uts/intel/io/acpica/resources/rscalc.c
index 97fd5a3e71..97fd5a3e71 100644
--- a/usr/src/uts/i86pc/io/acpica/resources/rscalc.c
+++ b/usr/src/uts/intel/io/acpica/resources/rscalc.c
diff --git a/usr/src/uts/i86pc/io/acpica/resources/rscreate.c b/usr/src/uts/intel/io/acpica/resources/rscreate.c
index 1cb836adc7..1cb836adc7 100644
--- a/usr/src/uts/i86pc/io/acpica/resources/rscreate.c
+++ b/usr/src/uts/intel/io/acpica/resources/rscreate.c
diff --git a/usr/src/uts/i86pc/io/acpica/resources/rsdump.c b/usr/src/uts/intel/io/acpica/resources/rsdump.c
index 1f90cf7b42..1f90cf7b42 100644
--- a/usr/src/uts/i86pc/io/acpica/resources/rsdump.c
+++ b/usr/src/uts/intel/io/acpica/resources/rsdump.c
diff --git a/usr/src/uts/i86pc/io/acpica/resources/rsinfo.c b/usr/src/uts/intel/io/acpica/resources/rsinfo.c
index e731c5413c..e731c5413c 100644
--- a/usr/src/uts/i86pc/io/acpica/resources/rsinfo.c
+++ b/usr/src/uts/intel/io/acpica/resources/rsinfo.c
diff --git a/usr/src/uts/i86pc/io/acpica/resources/rsio.c b/usr/src/uts/intel/io/acpica/resources/rsio.c
index 8cbc3c06c1..8cbc3c06c1 100644
--- a/usr/src/uts/i86pc/io/acpica/resources/rsio.c
+++ b/usr/src/uts/intel/io/acpica/resources/rsio.c
diff --git a/usr/src/uts/i86pc/io/acpica/resources/rsirq.c b/usr/src/uts/intel/io/acpica/resources/rsirq.c
index bfd15936bd..bfd15936bd 100644
--- a/usr/src/uts/i86pc/io/acpica/resources/rsirq.c
+++ b/usr/src/uts/intel/io/acpica/resources/rsirq.c
diff --git a/usr/src/uts/i86pc/io/acpica/resources/rslist.c b/usr/src/uts/intel/io/acpica/resources/rslist.c
index d1d60e4630..d1d60e4630 100644
--- a/usr/src/uts/i86pc/io/acpica/resources/rslist.c
+++ b/usr/src/uts/intel/io/acpica/resources/rslist.c
diff --git a/usr/src/uts/i86pc/io/acpica/resources/rsmemory.c b/usr/src/uts/intel/io/acpica/resources/rsmemory.c
index 0e0e3a8dae..0e0e3a8dae 100644
--- a/usr/src/uts/i86pc/io/acpica/resources/rsmemory.c
+++ b/usr/src/uts/intel/io/acpica/resources/rsmemory.c
diff --git a/usr/src/uts/i86pc/io/acpica/resources/rsmisc.c b/usr/src/uts/intel/io/acpica/resources/rsmisc.c
index e7da574321..e7da574321 100644
--- a/usr/src/uts/i86pc/io/acpica/resources/rsmisc.c
+++ b/usr/src/uts/intel/io/acpica/resources/rsmisc.c
diff --git a/usr/src/uts/i86pc/io/acpica/resources/rsutils.c b/usr/src/uts/intel/io/acpica/resources/rsutils.c
index f17c68b64f..f17c68b64f 100644
--- a/usr/src/uts/i86pc/io/acpica/resources/rsutils.c
+++ b/usr/src/uts/intel/io/acpica/resources/rsutils.c
diff --git a/usr/src/uts/i86pc/io/acpica/resources/rsxface.c b/usr/src/uts/intel/io/acpica/resources/rsxface.c
index 1ff12f34b2..1ff12f34b2 100644
--- a/usr/src/uts/i86pc/io/acpica/resources/rsxface.c
+++ b/usr/src/uts/intel/io/acpica/resources/rsxface.c
diff --git a/usr/src/uts/i86pc/io/acpica/tables/tbconvrt.c b/usr/src/uts/intel/io/acpica/tables/tbconvrt.c
index cf84622ecc..cf84622ecc 100644
--- a/usr/src/uts/i86pc/io/acpica/tables/tbconvrt.c
+++ b/usr/src/uts/intel/io/acpica/tables/tbconvrt.c
diff --git a/usr/src/uts/i86pc/io/acpica/tables/tbget.c b/usr/src/uts/intel/io/acpica/tables/tbget.c
index b16cbdded9..b16cbdded9 100644
--- a/usr/src/uts/i86pc/io/acpica/tables/tbget.c
+++ b/usr/src/uts/intel/io/acpica/tables/tbget.c
diff --git a/usr/src/uts/i86pc/io/acpica/tables/tbgetall.c b/usr/src/uts/intel/io/acpica/tables/tbgetall.c
index d6422c0f1c..d6422c0f1c 100644
--- a/usr/src/uts/i86pc/io/acpica/tables/tbgetall.c
+++ b/usr/src/uts/intel/io/acpica/tables/tbgetall.c
diff --git a/usr/src/uts/i86pc/io/acpica/tables/tbinstal.c b/usr/src/uts/intel/io/acpica/tables/tbinstal.c
index b192646abb..b192646abb 100644
--- a/usr/src/uts/i86pc/io/acpica/tables/tbinstal.c
+++ b/usr/src/uts/intel/io/acpica/tables/tbinstal.c
diff --git a/usr/src/uts/i86pc/io/acpica/tables/tbrsdt.c b/usr/src/uts/intel/io/acpica/tables/tbrsdt.c
index 68e2c5fe9e..68e2c5fe9e 100644
--- a/usr/src/uts/i86pc/io/acpica/tables/tbrsdt.c
+++ b/usr/src/uts/intel/io/acpica/tables/tbrsdt.c
diff --git a/usr/src/uts/i86pc/io/acpica/tables/tbutils.c b/usr/src/uts/intel/io/acpica/tables/tbutils.c
index ac09472a7b..ac09472a7b 100644
--- a/usr/src/uts/i86pc/io/acpica/tables/tbutils.c
+++ b/usr/src/uts/intel/io/acpica/tables/tbutils.c
diff --git a/usr/src/uts/i86pc/io/acpica/tables/tbxface.c b/usr/src/uts/intel/io/acpica/tables/tbxface.c
index 3a37e79dbd..3a37e79dbd 100644
--- a/usr/src/uts/i86pc/io/acpica/tables/tbxface.c
+++ b/usr/src/uts/intel/io/acpica/tables/tbxface.c
diff --git a/usr/src/uts/i86pc/io/acpica/tables/tbxfroot.c b/usr/src/uts/intel/io/acpica/tables/tbxfroot.c
index de849be97b..de849be97b 100644
--- a/usr/src/uts/i86pc/io/acpica/tables/tbxfroot.c
+++ b/usr/src/uts/intel/io/acpica/tables/tbxfroot.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utalloc.c b/usr/src/uts/intel/io/acpica/utilities/utalloc.c
index 91dcfcfcec..91dcfcfcec 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utalloc.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utalloc.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utcache.c b/usr/src/uts/intel/io/acpica/utilities/utcache.c
index 7b6ff37126..7b6ff37126 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utcache.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utcache.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utclib.c b/usr/src/uts/intel/io/acpica/utilities/utclib.c
index 2fbebcb804..2fbebcb804 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utclib.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utclib.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utcopy.c b/usr/src/uts/intel/io/acpica/utilities/utcopy.c
index 111af3085f..111af3085f 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utcopy.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utcopy.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utdebug.c b/usr/src/uts/intel/io/acpica/utilities/utdebug.c
index 4cb018aed2..4cb018aed2 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utdebug.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utdebug.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utdelete.c b/usr/src/uts/intel/io/acpica/utilities/utdelete.c
index c85ea669be..c85ea669be 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utdelete.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utdelete.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/uteval.c b/usr/src/uts/intel/io/acpica/utilities/uteval.c
index ab747d452f..ab747d452f 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/uteval.c
+++ b/usr/src/uts/intel/io/acpica/utilities/uteval.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utglobal.c b/usr/src/uts/intel/io/acpica/utilities/utglobal.c
index 9a7323df41..9a7323df41 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utglobal.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utglobal.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utinit.c b/usr/src/uts/intel/io/acpica/utilities/utinit.c
index e9bfab002e..e9bfab002e 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utinit.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utinit.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utmath.c b/usr/src/uts/intel/io/acpica/utilities/utmath.c
index 0cb9e0782e..0cb9e0782e 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utmath.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utmath.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utmisc.c b/usr/src/uts/intel/io/acpica/utilities/utmisc.c
index 79a6b51ac1..79a6b51ac1 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utmisc.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utmisc.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utmutex.c b/usr/src/uts/intel/io/acpica/utilities/utmutex.c
index 53186ec8c5..53186ec8c5 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utmutex.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utmutex.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utobject.c b/usr/src/uts/intel/io/acpica/utilities/utobject.c
index 6d7a058e5a..6d7a058e5a 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utobject.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utobject.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utresrc.c b/usr/src/uts/intel/io/acpica/utilities/utresrc.c
index 87f0c15e8e..87f0c15e8e 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utresrc.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utresrc.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utstate.c b/usr/src/uts/intel/io/acpica/utilities/utstate.c
index 7c9d72f125..7c9d72f125 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utstate.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utstate.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/uttrack.c b/usr/src/uts/intel/io/acpica/utilities/uttrack.c
index 4dbf0bf755..4dbf0bf755 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/uttrack.c
+++ b/usr/src/uts/intel/io/acpica/utilities/uttrack.c
diff --git a/usr/src/uts/i86pc/io/acpica/utilities/utxface.c b/usr/src/uts/intel/io/acpica/utilities/utxface.c
index 4fad6dfa2d..4fad6dfa2d 100644
--- a/usr/src/uts/i86pc/io/acpica/utilities/utxface.c
+++ b/usr/src/uts/intel/io/acpica/utilities/utxface.c
diff --git a/usr/src/uts/i86pc/io/agpgart/agp_kstat.c b/usr/src/uts/intel/io/agpgart/agp_kstat.c
index 1913fb878c..1913fb878c 100644
--- a/usr/src/uts/i86pc/io/agpgart/agp_kstat.c
+++ b/usr/src/uts/intel/io/agpgart/agp_kstat.c
diff --git a/usr/src/uts/i86pc/io/agpgart/agpgart.c b/usr/src/uts/intel/io/agpgart/agpgart.c
index 9f17285944..9f17285944 100644
--- a/usr/src/uts/i86pc/io/agpgart/agpgart.c
+++ b/usr/src/uts/intel/io/agpgart/agpgart.c
diff --git a/usr/src/uts/i86pc/io/agpgart/agpgart.conf b/usr/src/uts/intel/io/agpgart/agpgart.conf
index 0223702758..0223702758 100644
--- a/usr/src/uts/i86pc/io/agpgart/agpgart.conf
+++ b/usr/src/uts/intel/io/agpgart/agpgart.conf
diff --git a/usr/src/uts/i86pc/io/agpgart/agptarget.c b/usr/src/uts/intel/io/agpgart/agptarget.c
index 4cce6c8550..4cce6c8550 100644
--- a/usr/src/uts/i86pc/io/agpgart/agptarget.c
+++ b/usr/src/uts/intel/io/agpgart/agptarget.c
diff --git a/usr/src/uts/i86pc/io/agpgart/amd64_gart.c b/usr/src/uts/intel/io/agpgart/amd64_gart.c
index fbcebf781d..fbcebf781d 100644
--- a/usr/src/uts/i86pc/io/agpgart/amd64_gart.c
+++ b/usr/src/uts/intel/io/agpgart/amd64_gart.c
diff --git a/usr/src/uts/i86pc/io/agpmaster/agpmaster.c b/usr/src/uts/intel/io/agpmaster/agpmaster.c
index 2accb3d2fc..2accb3d2fc 100644
--- a/usr/src/uts/i86pc/io/agpmaster/agpmaster.c
+++ b/usr/src/uts/intel/io/agpmaster/agpmaster.c
diff --git a/usr/src/uts/intel/io/dktp/controller/ata/ata_disk.c b/usr/src/uts/intel/io/dktp/controller/ata/ata_disk.c
index e19a1f6427..7a172402c8 100644
--- a/usr/src/uts/intel/io/dktp/controller/ata/ata_disk.c
+++ b/usr/src/uts/intel/io/dktp/controller/ata/ata_disk.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2471,10 +2471,6 @@ ata_disk_initialize_device_parameters(
{
int rc;
-#ifdef _SIMULATOR_SUPPORT
- extern int simulator_run; /* running under simulator ? */
-#endif /* _SIMULATOR_SUPPORT */
-
rc = ata_command(ata_ctlp, ata_drvp, FALSE, FALSE,
ata_disk_init_dev_parm_wait,
ATC_SETPARAM,
@@ -2485,15 +2481,8 @@ ata_disk_initialize_device_parameters(
0, /* cyl_low n/a */
0); /* cyl_hi n/a */
-#ifdef _SIMULATOR_SUPPORT
- if (rc || simulator_run) {
- return (TRUE);
- }
-#else
- if (rc) {
+ if (rc)
return (TRUE);
- }
-#endif /* _SIMULATOR_SUPPORT */
ADBG_ERROR(("ata_init_dev_parms: failed\n"));
return (FALSE);
diff --git a/usr/src/uts/intel/io/dktp/controller/ata/atapi.c b/usr/src/uts/intel/io/dktp/controller/ata/atapi.c
index 0a0f01350a..048f498d31 100644
--- a/usr/src/uts/intel/io/dktp/controller/ata/atapi.c
+++ b/usr/src/uts/intel/io/dktp/controller/ata/atapi.c
@@ -2,7 +2,7 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
+ * Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -164,7 +164,7 @@ atapi_detach(
ADBG_TRACE(("atapi_detach entered\n"));
if (ata_ctlp->ac_flags & AC_SCSI_HBA_ATTACH)
- scsi_hba_detach(ata_ctlp->ac_dip);
+ (void) scsi_hba_detach(ata_ctlp->ac_dip);
if (ata_ctlp->ac_flags & AC_SCSI_HBA_TRAN_ALLOC)
scsi_hba_tran_free(ata_ctlp->ac_atapi_tran);
diff --git a/usr/src/uts/i86pc/io/dnet.c b/usr/src/uts/intel/io/dnet.c
index e3e4d87ae3..e3e4d87ae3 100644
--- a/usr/src/uts/i86pc/io/dnet.c
+++ b/usr/src/uts/intel/io/dnet.c
diff --git a/usr/src/uts/i86pc/io/dnet.conf b/usr/src/uts/intel/io/dnet.conf
index 4a4692dec2..4a4692dec2 100644
--- a/usr/src/uts/i86pc/io/dnet.conf
+++ b/usr/src/uts/intel/io/dnet.conf
diff --git a/usr/src/uts/i86pc/io/drm/drm_asm.s b/usr/src/uts/intel/io/drm/drm_asm.s
index 9a0440dfce..9a0440dfce 100644
--- a/usr/src/uts/i86pc/io/drm/drm_asm.s
+++ b/usr/src/uts/intel/io/drm/drm_asm.s
diff --git a/usr/src/uts/i86pc/io/drm/i915_dma.c b/usr/src/uts/intel/io/drm/i915_dma.c
index e0ffdef164..e0ffdef164 100644
--- a/usr/src/uts/i86pc/io/drm/i915_dma.c
+++ b/usr/src/uts/intel/io/drm/i915_dma.c
diff --git a/usr/src/uts/i86pc/io/drm/i915_drm.h b/usr/src/uts/intel/io/drm/i915_drm.h
index 2069454ec1..2069454ec1 100644
--- a/usr/src/uts/i86pc/io/drm/i915_drm.h
+++ b/usr/src/uts/intel/io/drm/i915_drm.h
diff --git a/usr/src/uts/i86pc/io/drm/i915_drv.c b/usr/src/uts/intel/io/drm/i915_drv.c
index bceeeb6071..bceeeb6071 100644
--- a/usr/src/uts/i86pc/io/drm/i915_drv.c
+++ b/usr/src/uts/intel/io/drm/i915_drv.c
diff --git a/usr/src/uts/i86pc/io/drm/i915_drv.h b/usr/src/uts/intel/io/drm/i915_drv.h
index 5725ffbb7b..5725ffbb7b 100644
--- a/usr/src/uts/i86pc/io/drm/i915_drv.h
+++ b/usr/src/uts/intel/io/drm/i915_drv.h
diff --git a/usr/src/uts/i86pc/io/drm/i915_irq.c b/usr/src/uts/intel/io/drm/i915_irq.c
index 9d23b2cb24..9d23b2cb24 100644
--- a/usr/src/uts/i86pc/io/drm/i915_irq.c
+++ b/usr/src/uts/intel/io/drm/i915_irq.c
diff --git a/usr/src/uts/i86pc/io/drm/i915_mem.c b/usr/src/uts/intel/io/drm/i915_mem.c
index 43f9582a57..43f9582a57 100644
--- a/usr/src/uts/i86pc/io/drm/i915_mem.c
+++ b/usr/src/uts/intel/io/drm/i915_mem.c
diff --git a/usr/src/uts/i86pc/io/drm/i915_sundrv.c b/usr/src/uts/intel/io/drm/i915_sundrv.c
index f588bd0a3c..f588bd0a3c 100644
--- a/usr/src/uts/i86pc/io/drm/i915_sundrv.c
+++ b/usr/src/uts/intel/io/drm/i915_sundrv.c
diff --git a/usr/src/uts/i86pc/io/fd.conf b/usr/src/uts/intel/io/fd.conf
index 1f3a662175..1f3a662175 100644
--- a/usr/src/uts/i86pc/io/fd.conf
+++ b/usr/src/uts/intel/io/fd.conf
diff --git a/usr/src/uts/common/io/i8254.c b/usr/src/uts/intel/io/i8254.c
index ff590fc879..80209c228b 100644
--- a/usr/src/uts/common/io/i8254.c
+++ b/usr/src/uts/intel/io/i8254.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,12 +44,6 @@
#define PIT_COUNTDOWN (PIT_READMODE | PIT_NDIVMODE)
#define MICROCOUNT 0x2000
-#ifdef _SIMULATOR_SUPPORT
-
-extern int simulator_run; /* if non-zero then running under simulator */
-
-#endif /* _SIMULATOR_SUPPORT */
-
void
microfind(void)
{
@@ -74,15 +67,9 @@ microfind(void)
* algorithm progresses in order to facilitate faster cpu's.
*/
unsigned long found, min = 0xe000;
- int s;
+ ulong_t s;
unsigned char status;
-#ifdef _SIMULATOR_SUPPORT
- if (simulator_run) {
- microdata = 133; /* 40 Mhz cpu simulator hack */
- return;
- }
-#endif /* _SIMULATOR_SUPPORT */
s = clear_int_flag(); /* disable interrupts */
/*CONSTCOND*/
diff --git a/usr/src/uts/i86pc/io/logi.c b/usr/src/uts/intel/io/logi.c
index 2207862737..2207862737 100644
--- a/usr/src/uts/i86pc/io/logi.c
+++ b/usr/src/uts/intel/io/logi.c
diff --git a/usr/src/uts/i86pc/io/mii.c b/usr/src/uts/intel/io/mii.c
index 5167ec1976..5167ec1976 100644
--- a/usr/src/uts/i86pc/io/mii.c
+++ b/usr/src/uts/intel/io/mii.c
diff --git a/usr/src/uts/i86pc/io/mscsi.c b/usr/src/uts/intel/io/mscsi.c
index 749baa478f..749baa478f 100644
--- a/usr/src/uts/i86pc/io/mscsi.c
+++ b/usr/src/uts/intel/io/mscsi.c
diff --git a/usr/src/uts/i86pc/io/mscsi.conf b/usr/src/uts/intel/io/mscsi.conf
index 90f721857e..90f721857e 100644
--- a/usr/src/uts/i86pc/io/mscsi.conf
+++ b/usr/src/uts/intel/io/mscsi.conf
diff --git a/usr/src/uts/i86pc/io/msm.c b/usr/src/uts/intel/io/msm.c
index 152b8983f2..152b8983f2 100644
--- a/usr/src/uts/i86pc/io/msm.c
+++ b/usr/src/uts/intel/io/msm.c
diff --git a/usr/src/uts/i86pc/io/pci/mps_table.h b/usr/src/uts/intel/io/pci/mps_table.h
index 8f8c1dc24e..8f8c1dc24e 100644
--- a/usr/src/uts/i86pc/io/pci/mps_table.h
+++ b/usr/src/uts/intel/io/pci/mps_table.h
diff --git a/usr/src/uts/i86pc/io/pci/pci_autoconfig.c b/usr/src/uts/intel/io/pci/pci_autoconfig.c
index bbcc2ed420..bbcc2ed420 100644
--- a/usr/src/uts/i86pc/io/pci/pci_autoconfig.c
+++ b/usr/src/uts/intel/io/pci/pci_autoconfig.c
diff --git a/usr/src/uts/i86pc/io/pci/pci_boot.c b/usr/src/uts/intel/io/pci/pci_boot.c
index 8a3bc25529..8a3bc25529 100644
--- a/usr/src/uts/i86pc/io/pci/pci_boot.c
+++ b/usr/src/uts/intel/io/pci/pci_boot.c
diff --git a/usr/src/uts/i86pc/io/pci/pci_memlist.c b/usr/src/uts/intel/io/pci/pci_memlist.c
index f03e33a785..f03e33a785 100644
--- a/usr/src/uts/i86pc/io/pci/pci_memlist.c
+++ b/usr/src/uts/intel/io/pci/pci_memlist.c
diff --git a/usr/src/uts/i86pc/io/pci/pci_pci.c b/usr/src/uts/intel/io/pci/pci_pci.c
index b6dbe7f1b9..b6dbe7f1b9 100644
--- a/usr/src/uts/i86pc/io/pci/pci_pci.c
+++ b/usr/src/uts/intel/io/pci/pci_pci.c
diff --git a/usr/src/uts/i86pc/io/pci/pci_resource.c b/usr/src/uts/intel/io/pci/pci_resource.c
index bb8c8b1ea3..bb8c8b1ea3 100644
--- a/usr/src/uts/i86pc/io/pci/pci_resource.c
+++ b/usr/src/uts/intel/io/pci/pci_resource.c
diff --git a/usr/src/uts/i86pc/io/pci/pcihrt.h b/usr/src/uts/intel/io/pci/pcihrt.h
index 7192eca2c5..7192eca2c5 100644
--- a/usr/src/uts/i86pc/io/pci/pcihrt.h
+++ b/usr/src/uts/intel/io/pci/pcihrt.h
diff --git a/usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_acpi.c b/usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_acpi.c
index ec4b63c128..753ddf8899 100644
--- a/usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_acpi.c
+++ b/usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_acpi.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -119,7 +118,7 @@ pciehpc_acpi_hotplug_enabled(dev_info_t *dip)
* No ACPI device for this bus node. Assume there is
* no ACPI hot plug support on this bus.
*/
- PCIEHPC_DEBUG((CE_CONT, "No ACPI device found (dip %p)",
+ PCIEHPC_DEBUG((CE_CONT, "No ACPI device found (dip %p)\n",
(void *)dip));
return (0);
}
@@ -368,7 +367,7 @@ pciehpc_acpi_slotinfo_init(pciehpc_t *ctrl_p)
if (pciehpc_acpi_install_event_handler(ctrl_p) != AE_OK)
return (DDI_FAILURE);
- PCIEHPC_DEBUG((CE_NOTE, "ACPI hot plug is enabled for slot #%d",
+ PCIEHPC_DEBUG((CE_NOTE, "ACPI hot plug is enabled for slot #%d\n",
ctrl_p->slot.slotNum));
return (DDI_SUCCESS);
@@ -427,7 +426,7 @@ pciehpc_acpi_slot_connect(caddr_t ops_arg, hpc_slot_t slot_hdl,
/* make sure the MRL switch is closed if present */
if ((ctrl_p->has_mrl) && (status & PCIE_SLOTSTS_MRL_SENSOR_OPEN)) {
/* MRL switch is open */
- cmn_err(CE_WARN, "MRL switch is open on slot %d\n",
+ cmn_err(CE_WARN, "MRL switch is open on slot %d",
ctrl_p->slot.slotNum);
goto cleanup;
}
@@ -505,7 +504,7 @@ pciehpc_acpi_slot_disconnect(caddr_t ops_arg, hpc_slot_t slot_hdl,
/* make sure the slot has a device present */
if (!(status & PCIE_SLOTSTS_PRESENCE_DETECTED)) {
/* slot is empty */
- PCIEHPC_DEBUG((CE_WARN, "slot %d is empty\n",
+ PCIEHPC_DEBUG((CE_WARN, "slot %d is empty",
ctrl_p->slot.slotNum));
goto cleanup;
}
@@ -587,7 +586,7 @@ pciehpc_acpi_notify_handler(ACPI_HANDLE device, uint32_t val, void *context)
acpi_p = ctrl_p->misc_data;
if (pciehpc_acpi_get_dev_state(acpi_p->slot_dev_obj,
&dev_state) != AE_OK) {
- cmn_err(CE_WARN, "failed to get device status on slot %d\n",
+ cmn_err(CE_WARN, "failed to get device status on slot %d",
ctrl_p->slot.slotNum);
}
PCIEHPC_DEBUG((CE_CONT, "(1)device state on slot #%d: 0x%x\n",
@@ -599,12 +598,12 @@ pciehpc_acpi_notify_handler(ACPI_HANDLE device, uint32_t val, void *context)
case 0: /* (re)enumerate the device */
case 3: /* Request Eject */
if (ctrl_p->slot.slot_state != HPC_SLOT_CONNECTED) {
- /* unexpected slot state; suprise removal? */
- cmn_err(CE_WARN, "Unexpteced event on slot #%d"
- "(state 0x%x)\n", ctrl_p->slot.slotNum, dev_state);
+ /* unexpected slot state; surprise removal? */
+ cmn_err(CE_WARN, "Unexpected event on slot #%d"
+ "(state 0x%x)", ctrl_p->slot.slotNum, dev_state);
}
/* send the ATTN button event to HPS framework */
- hpc_slot_event_notify(ctrl_p->slot.slot_handle,
+ (void) hpc_slot_event_notify(ctrl_p->slot.slot_handle,
HPC_EVENT_SLOT_ATTN, HPC_EVENT_NORMAL);
break;
default:
@@ -647,7 +646,7 @@ pciehpc_acpi_power_on_slot(pciehpc_t *ctrl_p)
if (status == AE_OK) {
if (pciehpc_acpi_get_dev_state(acpi_p->slot_dev_obj,
&dev_state) != AE_OK)
- cmn_err(CE_WARN, "failed to get device status on slot #%d\n",
+ cmn_err(CE_WARN, "failed to get device status on slot #%d",
ctrl_p->slot.slotNum);
}
PCIEHPC_DEBUG((CE_CONT, "(3)device state on slot #%d: 0x%x\n",
@@ -657,7 +656,7 @@ pciehpc_acpi_power_on_slot(pciehpc_t *ctrl_p)
if (ctrl_p->slot.slot_state != HPC_SLOT_CONNECTED) {
cmn_err(CE_WARN, "failed to power on the slot #%d"
- "(dev_state 0x%x, ACPI_STATUS 0x%x)\n",
+ "(dev_state 0x%x, ACPI_STATUS 0x%x)",
ctrl_p->slot.slotNum, dev_state, status);
return (AE_ERROR);
}
@@ -684,7 +683,7 @@ pciehpc_acpi_power_off_slot(pciehpc_t *ctrl_p)
if (status == AE_OK) {
if (pciehpc_acpi_get_dev_state(acpi_p->slot_dev_obj,
&dev_state) != AE_OK)
- cmn_err(CE_WARN, "failed to get device status on slot #%d\n",
+ cmn_err(CE_WARN, "failed to get device status on slot #%d",
ctrl_p->slot.slotNum);
}
PCIEHPC_DEBUG((CE_CONT, "(2)device state on slot #%d: 0x%x\n",
@@ -694,7 +693,7 @@ pciehpc_acpi_power_off_slot(pciehpc_t *ctrl_p)
if (ctrl_p->slot.slot_state == HPC_SLOT_CONNECTED) {
cmn_err(CE_WARN, "failed to power OFF the slot #%d"
- "(dev_state 0x%x, ACPI_STATUS 0x%x)\n",
+ "(dev_state 0x%x, ACPI_STATUS 0x%x)",
ctrl_p->slot.slotNum, dev_state, status);
return (AE_ERROR);
}
diff --git a/usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_acpi.h b/usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_acpi.h
index 96e78556e2..96e78556e2 100644
--- a/usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_acpi.h
+++ b/usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_acpi.h
diff --git a/usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_nvidia.c b/usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_nvidia.c
index e1294c2998..e1294c2998 100644
--- a/usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_nvidia.c
+++ b/usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_nvidia.c
diff --git a/usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_nvidia.h b/usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_nvidia.h
index 3ea7fb1f9e..3ea7fb1f9e 100644
--- a/usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_nvidia.h
+++ b/usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_nvidia.h
diff --git a/usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_x86.c b/usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_x86.c
index f9659bbd9e..f9659bbd9e 100644
--- a/usr/src/uts/i86pc/io/pciex/hotplug/pciehpc/pciehpc_x86.c
+++ b/usr/src/uts/intel/io/pciex/hotplug/pciehpc/pciehpc_x86.c
diff --git a/usr/src/uts/i86pc/io/pciex/pcie_error.c b/usr/src/uts/intel/io/pciex/pcie_error.c
index e688c7885c..e688c7885c 100644
--- a/usr/src/uts/i86pc/io/pciex/pcie_error.c
+++ b/usr/src/uts/intel/io/pciex/pcie_error.c
diff --git a/usr/src/uts/i86pc/io/pciex/pcie_error.h b/usr/src/uts/intel/io/pciex/pcie_error.h
index b829525850..b829525850 100644
--- a/usr/src/uts/i86pc/io/pciex/pcie_error.h
+++ b/usr/src/uts/intel/io/pciex/pcie_error.h
diff --git a/usr/src/uts/i86pc/io/pciex/pcie_nvidia.c b/usr/src/uts/intel/io/pciex/pcie_nvidia.c
index aec3a31580..aec3a31580 100644
--- a/usr/src/uts/i86pc/io/pciex/pcie_nvidia.c
+++ b/usr/src/uts/intel/io/pciex/pcie_nvidia.c
diff --git a/usr/src/uts/i86pc/io/pciex/pcie_nvidia.h b/usr/src/uts/intel/io/pciex/pcie_nvidia.h
index b3550a878f..b3550a878f 100644
--- a/usr/src/uts/i86pc/io/pciex/pcie_nvidia.h
+++ b/usr/src/uts/intel/io/pciex/pcie_nvidia.h
diff --git a/usr/src/uts/i86pc/io/pciex/pcie_pci.c b/usr/src/uts/intel/io/pciex/pcie_pci.c
index abf22ceb20..abf22ceb20 100644
--- a/usr/src/uts/i86pc/io/pciex/pcie_pci.c
+++ b/usr/src/uts/intel/io/pciex/pcie_pci.c
diff --git a/usr/src/uts/i86pc/io/pciex/pcie_pci.conf b/usr/src/uts/intel/io/pciex/pcie_pci.conf
index b8d0d8b148..b8d0d8b148 100644
--- a/usr/src/uts/i86pc/io/pciex/pcie_pci.conf
+++ b/usr/src/uts/intel/io/pciex/pcie_pci.conf
diff --git a/usr/src/uts/i86pc/io/smcp/smcp.c b/usr/src/uts/intel/io/smcp/smcp.c
index 74cc4ea3b6..74cc4ea3b6 100644
--- a/usr/src/uts/i86pc/io/smcp/smcp.c
+++ b/usr/src/uts/intel/io/smcp/smcp.c
diff --git a/usr/src/uts/i86pc/io/smcp/smcp.h b/usr/src/uts/intel/io/smcp/smcp.h
index 41e1a26829..41e1a26829 100644
--- a/usr/src/uts/i86pc/io/smcp/smcp.h
+++ b/usr/src/uts/intel/io/smcp/smcp.h
diff --git a/usr/src/uts/i86pc/kb8042/Makefile b/usr/src/uts/intel/kb8042/Makefile
index acfdfb36ef..173b286437 100644
--- a/usr/src/uts/i86pc/kb8042/Makefile
+++ b/usr/src/uts/intel/kb8042/Makefile
@@ -19,15 +19,15 @@
# CDDL HEADER END
#
#
-# uts/i86pc/kb8042/%M%
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# uts/intel/kb8042/%M%
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
#
# This makefile drives the production of the kb8042 driver
#
-# i86pc implementation architecture dependent
+# intel architecture dependent
#
#
@@ -41,12 +41,12 @@ UTSBASE = ../..
MODULE = kb8042
OBJECTS = $(KB8042_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(KB8042_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
LDFLAGS += -dy -Nmisc/kbtrans
@@ -88,4 +88,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/intel/kdi/amd64/kdi_asm.s b/usr/src/uts/intel/kdi/amd64/kdi_asm.s
new file mode 100644
index 0000000000..365d4fdaea
--- /dev/null
+++ b/usr/src/uts/intel/kdi/amd64/kdi_asm.s
@@ -0,0 +1,641 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Debugger entry for both master and slave CPUs
+ */
+
+#if defined(__lint)
+#include <sys/types.h>
+#endif
+
+#include <sys/segments.h>
+#include <sys/asm_linkage.h>
+#include <sys/controlregs.h>
+#include <sys/x86_archext.h>
+#include <sys/privregs.h>
+#include <sys/machprivregs.h>
+#include <sys/kdi_regs.h>
+#include <sys/psw.h>
+#include <sys/uadmin.h>
+
+#ifdef _ASM
+
+#include <kdi_assym.h>
+#include <assym.h>
+
+/* clobbers %rdx, %rcx, returns addr in %rax, CPU ID in %rbx */
+#define GET_CPUSAVE_ADDR \
+ movzbq %gs:CPU_ID, %rbx; \
+ movq %rbx, %rax; \
+ movq $KRS_SIZE, %rcx; \
+ mulq %rcx; \
+ movq $kdi_cpusave, %rdx; \
+ /*CSTYLED*/ \
+ addq (%rdx), %rax
+
+/*
+ * Save copies of the IDT and GDT descriptors. Note that we only save the IDT
+ * and GDT if the IDT isn't ours, as we may be legitimately re-entering the
+ * debugger through the trap handler. We don't want to clobber the saved IDT
+ * in the process, as we'd end up resuming the world on our IDT.
+ */
+#define SAVE_IDTGDT \
+ movq %gs:CPU_IDT, %r11; \
+ leaq kdi_idt(%rip), %rsi; \
+ cmpq %rsi, %r11; \
+ je 1f; \
+ movq %r11, KRS_IDT(%rax); \
+ movq %gs:CPU_GDT, %r11; \
+ movq %r11, KRS_GDT(%rax); \
+1:
+
+/* %ss, %rsp, %rflags, %cs, %rip, %err, %trapno already on stack */
+
+#define KDI_SAVE_REGS(base) \
+ movq %rdi, REG_OFF(KDIREG_RDI)(base); \
+ movq %rsi, REG_OFF(KDIREG_RSI)(base); \
+ movq %rdx, REG_OFF(KDIREG_RDX)(base); \
+ movq %rcx, REG_OFF(KDIREG_RCX)(base); \
+ movq %r8, REG_OFF(KDIREG_R8)(base); \
+ movq %r9, REG_OFF(KDIREG_R9)(base); \
+ movq %rax, REG_OFF(KDIREG_RAX)(base); \
+ movq %rbx, REG_OFF(KDIREG_RBX)(base); \
+ movq %rbp, REG_OFF(KDIREG_RBP)(base); \
+ movq %r10, REG_OFF(KDIREG_R10)(base); \
+ movq %r11, REG_OFF(KDIREG_R11)(base); \
+ movq %r12, REG_OFF(KDIREG_R12)(base); \
+ movq %r13, REG_OFF(KDIREG_R13)(base); \
+ movq %r14, REG_OFF(KDIREG_R14)(base); \
+ movq %r15, REG_OFF(KDIREG_R15)(base); \
+ movq %rbp, REG_OFF(KDIREG_SAVFP)(base); \
+ movq REG_OFF(KDIREG_RIP)(base), %rax; \
+ movq %rax, REG_OFF(KDIREG_SAVPC)(base); \
+ clrq %rax; \
+ movw %ds, %ax; \
+ movq %rax, REG_OFF(KDIREG_DS)(base); \
+ movw %es, %ax; \
+ movq %rax, REG_OFF(KDIREG_ES)(base); \
+ movw %fs, %ax; \
+ movq %rax, REG_OFF(KDIREG_FS)(base); \
+ movw %gs, %ax; \
+ movq %rax, REG_OFF(KDIREG_GS)(base)
+
+#define KDI_RESTORE_REGS(base) \
+ movq base, %rdi; \
+ movq REG_OFF(KDIREG_ES)(%rdi), %rax; \
+ movw %ax, %es; \
+ movq REG_OFF(KDIREG_DS)(%rdi), %rax; \
+ movw %ax, %ds; \
+ movq REG_OFF(KDIREG_R15)(%rdi), %r15; \
+ movq REG_OFF(KDIREG_R14)(%rdi), %r14; \
+ movq REG_OFF(KDIREG_R13)(%rdi), %r13; \
+ movq REG_OFF(KDIREG_R12)(%rdi), %r12; \
+ movq REG_OFF(KDIREG_R11)(%rdi), %r11; \
+ movq REG_OFF(KDIREG_R10)(%rdi), %r10; \
+ movq REG_OFF(KDIREG_RBP)(%rdi), %rbp; \
+ movq REG_OFF(KDIREG_RBX)(%rdi), %rbx; \
+ movq REG_OFF(KDIREG_RAX)(%rdi), %rax; \
+ movq REG_OFF(KDIREG_R9)(%rdi), %r9; \
+ movq REG_OFF(KDIREG_R8)(%rdi), %r8; \
+ movq REG_OFF(KDIREG_RCX)(%rdi), %rcx; \
+ movq REG_OFF(KDIREG_RDX)(%rdi), %rdx; \
+ movq REG_OFF(KDIREG_RSI)(%rdi), %rsi; \
+ movq REG_OFF(KDIREG_RDI)(%rdi), %rdi
+
+/*
+ * Each cpusave buffer has an area set aside for a ring buffer of breadcrumbs.
+ * The following macros manage the buffer.
+ */
+
+/* Advance the ring buffer */
+#define ADVANCE_CRUMB_POINTER(cpusave, tmp1, tmp2) \
+ movq KRS_CURCRUMBIDX(cpusave), tmp1; \
+ cmpq $[KDI_NCRUMBS - 1], tmp1; \
+ jge 1f; \
+ /* Advance the pointer and index */ \
+ addq $1, tmp1; \
+ movq tmp1, KRS_CURCRUMBIDX(cpusave); \
+ movq KRS_CURCRUMB(cpusave), tmp1; \
+ addq $KRM_SIZE, tmp1; \
+ jmp 2f; \
+1: /* Reset the pointer and index */ \
+ movq $0, KRS_CURCRUMBIDX(cpusave); \
+ leaq KRS_CRUMBS(cpusave), tmp1; \
+2: movq tmp1, KRS_CURCRUMB(cpusave); \
+ /* Clear the new crumb */ \
+ movq $KDI_NCRUMBS, tmp2; \
+3: movq $0, -4(tmp1, tmp2, 4); \
+ decq tmp2; \
+ jnz 3b
+
+/* Set a value in the current breadcrumb buffer */
+#define ADD_CRUMB(cpusave, offset, value, tmp) \
+ movq KRS_CURCRUMB(cpusave), tmp; \
+ movq value, offset(tmp)
+
+#endif /* _ASM */
+
+/*
+ * The main entry point for master CPUs. It also serves as the trap handler
+ * for all traps and interrupts taken during single-step.
+ */
+#if defined(__lint)
+void
+kdi_cmnint(void)
+{
+}
+#else /* __lint */
+
+ /* XXX implement me */
+ ENTRY_NP(kdi_nmiint)
+ clrq %rcx
+ movq (%rcx), %rcx
+ SET_SIZE(kdi_nmiint)
+
+ ENTRY_NP(kdi_cmnint)
+ ALTENTRY(kdi_master_entry)
+
+ pushq %rax
+ CLI(%rax)
+ popq %rax
+
+ /* Save current register state */
+ subq $REG_OFF(KDIREG_TRAPNO), %rsp
+ KDI_SAVE_REGS(%rsp)
+
+ /*
+ * Switch to the kernel's GSBASE. Neither GSBASE nor the ill-named
+ * KGSBASE can be trusted, as the kernel may or may not have already
+ * done a swapgs. All is not lost, as the kernel can divine the correct
+ * value for us.
+ */
+ subq $10, %rsp
+ sgdt (%rsp)
+ movq 2(%rsp), %rdi /* gdt base now in %rdi */
+ addq $10, %rsp
+ call kdi_gdt2gsbase /* returns kernel's GSBASE in %rax */
+
+ movq %rax, %rdx
+ shrq $32, %rdx
+ movl $MSR_AMD_GSBASE, %ecx
+ wrmsr
+
+ GET_CPUSAVE_ADDR /* %rax = cpusave, %rbx = CPU ID */
+
+ ADVANCE_CRUMB_POINTER(%rax, %rcx, %rdx)
+
+ ADD_CRUMB(%rax, KRM_CPU_STATE, $KDI_CPU_STATE_MASTER, %rdx)
+
+ movq REG_OFF(KDIREG_RIP)(%rsp), %rcx
+ ADD_CRUMB(%rax, KRM_PC, %rcx, %rdx)
+ ADD_CRUMB(%rax, KRM_SP, %rsp, %rdx)
+ movq REG_OFF(KDIREG_TRAPNO)(%rsp), %rcx
+ ADD_CRUMB(%rax, KRM_TRAPNO, %rcx, %rdx)
+
+ movq %rsp, %rbp
+ pushq %rax
+
+ /*
+ * Were we in the debugger when we took the trap (i.e. was %esp in one
+ * of the debugger's memory ranges)?
+ */
+ leaq kdi_memranges, %rcx
+ movl kdi_nmemranges, %edx
+1: cmpq MR_BASE(%rcx), %rsp
+ jl 2f /* below this range -- try the next one */
+ cmpq MR_LIM(%rcx), %rsp
+ jg 2f /* above this range -- try the next one */
+ jmp 3f /* matched within this range */
+
+2: decl %edx
+ jz kdi_save_common_state /* %rsp not within debugger memory */
+ addq $MR_SIZE, %rcx
+ jmp 1b
+
+3: /*
+ * The master is still set. That should only happen if we hit a trap
+ * while running in the debugger. Note that it may be an intentional
+ * fault. kmdb_dpi_handle_fault will sort it all out.
+ */
+
+ movq REG_OFF(KDIREG_TRAPNO)(%rbp), %rdi
+ movq REG_OFF(KDIREG_RIP)(%rbp), %rsi
+ movq REG_OFF(KDIREG_RSP)(%rbp), %rdx
+ movq %rbx, %rcx /* cpuid */
+
+ call kdi_dvec_handle_fault
+
+ /*
+ * If we're here, we ran into a debugger problem, and the user
+ * elected to solve it by having the debugger debug itself. The
+ * state we're about to save is that of the debugger when it took
+ * the fault.
+ */
+
+ jmp kdi_save_common_state
+
+ SET_SIZE(kdi_master_entry)
+ SET_SIZE(kdi_cmnint)
+
+#endif /* __lint */
+
+/*
+ * The cross-call handler for slave CPUs.
+ *
+ * The debugger is single-threaded, so only one CPU, called the master, may be
+ * running it at any given time. The other CPUs, known as slaves, spin in a
+ * busy loop until there's something for them to do. This is the entry point
+ * for the slaves - they'll be sent here in response to a cross-call sent by the
+ * master.
+ */
+
+#if defined(__lint)
+char kdi_slave_entry_patch;
+
+void
+kdi_slave_entry(void)
+{
+}
+#else /* __lint */
+ .globl kdi_slave_entry_patch;
+
+ ENTRY_NP(kdi_slave_entry)
+
+ /* kdi_msr_add_clrentry knows where this is */
+kdi_slave_entry_patch:
+ KDI_MSR_PATCH;
+
+ /*
+ * Cross calls are implemented as function calls, so our stack currently
+ * looks like one you'd get from a zero-argument function call. That
+ * is, there's the return %rip at %rsp, and that's about it. We need
+ * to make it look like an interrupt stack. When we first save, we'll
+ * reverse the saved %ss and %rip, which we'll fix back up when we've
+ * freed up some general-purpose registers. We'll also need to fix up
+ * the saved %rsp.
+ */
+
+ pushq %rsp /* pushed value off by 8 */
+ pushfq
+ CLI(%rax)
+ pushq $KCS_SEL
+ clrq %rax
+ movw %ss, %ax
+ pushq %rax /* rip should be here */
+ pushq $-1 /* phony trap error code */
+ pushq $-1 /* phony trap number */
+
+ subq $REG_OFF(KDIREG_TRAPNO), %rsp
+ KDI_SAVE_REGS(%rsp)
+
+ movq REG_OFF(KDIREG_SS)(%rsp), %rax
+ xchgq REG_OFF(KDIREG_RIP)(%rsp), %rax
+ movq %rax, REG_OFF(KDIREG_SS)(%rsp)
+
+ movq REG_OFF(KDIREG_RSP)(%rsp), %rax
+ addq $8, %rax
+ movq %rax, REG_OFF(KDIREG_RSP)(%rsp)
+
+ /*
+ * We've saved all of the general-purpose registers, and have a stack
+ * that is irettable (after we strip down to the error code)
+ */
+
+ GET_CPUSAVE_ADDR /* %rax = cpusave, %rbx = CPU ID */
+
+ ADVANCE_CRUMB_POINTER(%rax, %rcx, %rdx)
+
+ ADD_CRUMB(%rax, KRM_CPU_STATE, $KDI_CPU_STATE_SLAVE, %rdx)
+
+ movq REG_OFF(KDIREG_RIP)(%rsp), %rcx
+ ADD_CRUMB(%rax, KRM_PC, %rcx, %rdx)
+
+ pushq %rax
+ jmp kdi_save_common_state
+
+ SET_SIZE(kdi_slave_entry)
+
+#endif /* __lint */
+
+#if !defined(__lint)
+
+ ENTRY_NP(kdi_save_common_state)
+
+ /*
+ * The state of the world:
+ *
+ * The stack has a complete set of saved registers and segment
+ * selectors, arranged in the kdi_regs.h order. It also has a pointer
+ * to our cpusave area.
+ *
+ * We need to save, into the cpusave area, a pointer to these saved
+ * registers. After that, we save a few more registers, ready the
+ * machine for debugger entry, and enter the debugger.
+ */
+
+ popq %rax /* the cpusave area */
+ movq %rsp, KRS_GREGS(%rax) /* save ptr to current saved regs */
+
+ SAVE_IDTGDT
+
+ /* Save off %cr0, and clear write protect */
+ movq %cr0, %rcx
+ movq %rcx, KRS_CR0(%rax)
+ andq $_BITNOT(CR0_WP), %rcx
+ movq %rcx, %cr0
+
+ /* Save the debug registers and disable any active watchpoints */
+
+ movq %rax, %r15 /* save cpusave area ptr */
+ movl $7, %edi
+ call kdi_dreg_get
+ movq %rax, KRS_DRCTL(%r15)
+
+ andq $_BITNOT(KDIREG_DRCTL_WPALLEN_MASK), %rax
+ movq %rax, %rsi
+ movl $7, %edi
+ call kdi_dreg_set
+
+ movl $6, %edi
+ call kdi_dreg_get
+ movq %rax, KRS_DRSTAT(%r15)
+
+ movl $0, %edi
+ call kdi_dreg_get
+ movq %rax, KRS_DROFF(0)(%r15)
+
+ movl $1, %edi
+ call kdi_dreg_get
+ movq %rax, KRS_DROFF(1)(%r15)
+
+ movl $2, %edi
+ call kdi_dreg_get
+ movq %rax, KRS_DROFF(2)(%r15)
+
+ movl $3, %edi
+ call kdi_dreg_get
+ movq %rax, KRS_DROFF(3)(%r15)
+
+ movq %r15, %rax /* restore cpu save area to rax */
+
+ /*
+ * Save any requested MSRs.
+ */
+ movq KRS_MSR(%rax), %rcx
+ cmpq $0, %rcx
+ je no_msr
+
+ pushq %rax /* rdmsr clobbers %eax */
+ movq %rcx, %rbx
+
+1:
+ movl MSR_NUM(%rbx), %ecx
+ cmpl $0, %ecx
+ je msr_done
+
+ movl MSR_TYPE(%rbx), %edx
+ cmpl $KDI_MSR_READ, %edx
+ jne msr_next
+
+ rdmsr /* addr in %ecx, value into %edx:%eax */
+ movl %eax, MSR_VAL(%rbx)
+ movl %edx, _CONST(MSR_VAL + 4)(%rbx)
+
+msr_next:
+ addq $MSR_SIZE, %rbx
+ jmp 1b
+
+msr_done:
+ popq %rax
+
+no_msr:
+ clrq %rbp /* stack traces should end here */
+
+ pushq %rax
+ movq %rax, %rdi /* cpusave */
+
+ call kdi_debugger_entry
+
+ /* Pass cpusave and debugger return code for "call" to resume */
+ popq %rdi
+ movq %rax, %rsi
+
+ jmp kdi_resume
+
+ SET_SIZE(kdi_save_common_state)
+
+#endif /* !__lint */
+
+/*
+ * Given the address of the current CPU's cpusave area in %rax, the following
+ * macro restores the debugging state to said CPU. Restored state includes
+ * the debug registers from the global %dr variables, and debugging MSRs from
+ * the CPU save area. This code would be in a separate routine, but for the
+ * fact that some of the MSRs are jump-sensitive. As such, we need to minimize
+ * the number of jumps taken subsequent to the update of said MSRs. We can
+ * remove one jump (the ret) by using a macro instead of a function for the
+ * debugging state restoration code.
+ *
+ * Takes the cpusave area in %rdi as a parameter, clobbers %rax-%rdx
+ */
+#define KDI_RESTORE_DEBUGGING_STATE \
+ pushq %rdi; \
+ leaq kdi_drreg, %r15; \
+ movl $7, %edi; \
+ movq DR_CTL(%r15), %rsi; \
+ call kdi_dreg_set; \
+ \
+ movl $6, %edi; \
+ movq $KDIREG_DRSTAT_RESERVED, %rsi; \
+ call kdi_dreg_set; \
+ \
+ movl $0, %edi; \
+ movq DRADDR_OFF(0)(%r15), %rsi; \
+ call kdi_dreg_set; \
+ movl $1, %edi; \
+ movq DRADDR_OFF(1)(%r15), %rsi; \
+ call kdi_dreg_set; \
+ movl $2, %edi; \
+ movq DRADDR_OFF(2)(%r15), %rsi; \
+ call kdi_dreg_set; \
+ movl $3, %edi; \
+ movq DRADDR_OFF(3)(%r15), %rsi; \
+ call kdi_dreg_set; \
+ popq %rdi; \
+ \
+ /* \
+ * Write any requested MSRs. \
+ */ \
+ movq KRS_MSR(%rdi), %rbx; \
+ cmpq $0, %rbx; \
+ je 3f; \
+1: \
+ movl MSR_NUM(%rbx), %ecx; \
+ cmpl $0, %ecx; \
+ je 3f; \
+ \
+ movl MSR_TYPE(%rbx), %edx; \
+ cmpl $KDI_MSR_WRITE, %edx; \
+ jne 2f; \
+ \
+ movq MSR_VALP(%rbx), %rdx; \
+ movl 0(%rdx), %eax; \
+ movl 4(%rdx), %edx; \
+ wrmsr; \
+2: \
+ addq $MSR_SIZE, %rbx; \
+ jmp 1b; \
+3: \
+ /* \
+ * We must not branch after re-enabling LBR. If \
+ * kdi_wsr_wrexit_msr is set, it contains the number \
+ * of the MSR that controls LBR. kdi_wsr_wrexit_valp \
+ * contains the value that is to be written to enable \
+ * LBR. \
+ */ \
+ movl kdi_msr_wrexit_msr, %ecx; \
+ cmpl $0, %ecx; \
+ je 1f; \
+ \
+ movq kdi_msr_wrexit_valp, %rdx; \
+ movl 0(%rdx), %eax; \
+ movl 4(%rdx), %edx; \
+ \
+ wrmsr; \
+1:
+
+#if defined(__lint)
+/*ARGSUSED*/
+void
+kdi_cpu_debug_init(kdi_cpusave_t *save)
+{
+}
+#else /* __lint */
+
+ ENTRY_NP(kdi_cpu_debug_init)
+ pushq %rbp
+ movq %rsp, %rbp
+
+ pushq %rbx /* macro will clobber %rbx */
+ KDI_RESTORE_DEBUGGING_STATE
+ popq %rbx
+
+ leave
+ ret
+
+ SET_SIZE(kdi_cpu_debug_init)
+#endif /* !__lint */
+
+/*
+ * Resume the world. The code that calls kdi_resume has already
+ * decided whether or not to restore the IDT.
+ */
+#if defined(__lint)
+void
+kdi_resume(void)
+{
+}
+#else /* __lint */
+
+ ENTRY_NP(kdi_resume)
+
+ /* cpusave in %rdi, debugger command in %rsi */
+
+ cmpq $KDI_RESUME_PASS_TO_KERNEL, %rsi
+ je kdi_pass_to_kernel
+
+ /*
+ * Send this CPU back into the world
+ */
+ movq KRS_CR0(%rdi), %rdx
+ movq %rdx, %cr0
+
+ KDI_RESTORE_DEBUGGING_STATE
+
+ movq KRS_GREGS(%rdi), %rsp
+ KDI_RESTORE_REGS(%rsp)
+ addq $REG_OFF(KDIREG_RIP), %rsp /* Discard state, trapno, err */
+ IRET
+ /*NOTREACHED*/
+ SET_SIZE(kdi_resume)
+
+#endif /* __lint */
+
+#if !defined(__lint)
+
+ ENTRY_NP(kdi_pass_to_kernel)
+
+ /* cpusave is still in %rdi */
+ movq KRS_CR0(%rdi), %rdx
+ movq %rdx, %cr0
+
+ /*
+ * When we replaced the kernel's handlers in the IDT, we made note of
+ * the handlers being replaced, thus allowing us to pass traps directly
+ * to said handlers here. We won't have any registers available for use
+ * after we start popping, and we know we're single-threaded here, so
+ * we have to use a global to store the handler address.
+ */
+ movq KRS_GREGS(%rdi), %rsp
+ movq REG_OFF(KDIREG_TRAPNO)(%rsp), %rdi
+ call kdi_kernel_trap2hdlr
+ movq %rax, kdi_kernel_handler
+
+ /*
+ * The trap handler will expect the stack to be in trap order, with
+ * %rip being the last entry. Our stack is currently in kdi_regs.h
+ * order, so we'll need to pop (and restore) our way back down.
+ */
+ KDI_RESTORE_REGS(%rsp)
+ addq $REG_OFF(KDIREG_RIP), %rsp /* Discard state, trapno, err */
+
+ jmp *%cs:kdi_kernel_handler
+ /*NOTREACHED*/
+
+ SET_SIZE(kdi_pass_to_kernel)
+
+ /*
+ * Reboot the system. This routine is to be called only by the master
+ * CPU.
+ */
+ ENTRY_NP(kdi_reboot)
+
+ movl $AD_BOOT, %edi
+ movl $A_SHUTDOWN, %esi
+ call *psm_shutdownf
+
+ /*
+ * psm_shutdown didn't work or it wasn't set, try pc_reset.
+ */
+ call pc_reset
+ /*NOTREACHED*/
+
+ SET_SIZE(kdi_reboot)
+
+#endif /* !__lint */
diff --git a/usr/src/uts/intel/kdi/ia32/kdi_asm.s b/usr/src/uts/intel/kdi/ia32/kdi_asm.s
new file mode 100644
index 0000000000..b8232ab58b
--- /dev/null
+++ b/usr/src/uts/intel/kdi/ia32/kdi_asm.s
@@ -0,0 +1,692 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Debugger entry for both master and slave CPUs
+ */
+
+#if defined(__lint)
+#include <sys/types.h>
+#endif
+
+#include <sys/segments.h>
+#include <sys/asm_linkage.h>
+#include <sys/controlregs.h>
+#include <sys/x86_archext.h>
+#include <sys/privregs.h>
+#include <sys/machprivregs.h>
+#include <sys/kdi_regs.h>
+#include <sys/uadmin.h>
+#include <sys/psw.h>
+
+#ifdef _ASM
+
+#include <kdi_assym.h>
+#include <assym.h>
+
+/* clobbers %edx, %ecx, returns addr in %eax, cpu id in %ebx */
+#define GET_CPUSAVE_ADDR \
+ movl %gs:CPU_ID, %ebx; \
+ movl %ebx, %eax; \
+ movl $KRS_SIZE, %ecx; \
+ mull %ecx; \
+ movl $kdi_cpusave, %edx; \
+ /*CSTYLED*/ \
+ addl (%edx), %eax
+
+/*
+ * Save copies of the IDT and GDT descriptors. Note that we only save the IDT
+ * and GDT if the IDT isn't ours, as we may be legitimately re-entering the
+ * debugger through the trap handler. We don't want to clobber the saved IDT
+ * in the process, as we'd end up resuming the world on our IDT.
+ */
+#define SAVE_IDTGDT \
+ movl %gs:CPU_IDT, %edx; \
+ cmpl $kdi_idt, %edx; \
+ je 1f; \
+ movl %edx, KRS_IDT(%eax); \
+ movl %gs:CPU_GDT, %edx; \
+ movl %edx, KRS_GDT(%eax); \
+1:
+
+/*
+ * Each cpusave buffer has an area set aside for a ring buffer of breadcrumbs.
+ * The following macros manage the buffer.
+ */
+
+/* Advance the ring buffer */
+#define ADVANCE_CRUMB_POINTER(cpusave, tmp1, tmp2) \
+ movl KRS_CURCRUMBIDX(cpusave), tmp1; \
+ cmpl $[KDI_NCRUMBS - 1], tmp1; \
+ jge 1f; \
+ /* Advance the pointer and index */ \
+ addl $1, tmp1; \
+ movl tmp1, KRS_CURCRUMBIDX(cpusave); \
+ movl KRS_CURCRUMB(cpusave), tmp1; \
+ addl $KRM_SIZE, tmp1; \
+ jmp 2f; \
+1: /* Reset the pointer and index */ \
+ movw $0, KRS_CURCRUMBIDX(cpusave); \
+ leal KRS_CRUMBS(cpusave), tmp1; \
+2: movl tmp1, KRS_CURCRUMB(cpusave); \
+ /* Clear the new crumb */ \
+ movl $KDI_NCRUMBS, tmp2; \
+3: movl $0, -4(tmp1, tmp2, 4); \
+ decl tmp2; \
+ jnz 3b
+
+/* Set a value in the current breadcrumb buffer */
+#define ADD_CRUMB(cpusave, offset, value, tmp) \
+ movl KRS_CURCRUMB(cpusave), tmp; \
+ movl value, offset(tmp)
+
+#endif /* _ASM */
+
+/*
+ * The main entry point for master CPUs. It also serves as the trap handler
+ * for all traps and interrupts taken during single-step.
+ */
+#if defined(__lint)
+void
+kdi_cmnint(void)
+{
+}
+#else /* __lint */
+
+ /* XXX implement me */
+ ENTRY_NP(kdi_nmiint)
+ clr %ecx
+ movl (%ecx), %ecx
+ SET_SIZE(kdi_nmiint)
+
+ ENTRY_NP(kdi_cmnint)
+ ALTENTRY(kdi_master_entry)
+
+ /* Save all registers and selectors */
+
+ pushal
+ pushl %ds
+ pushl %es
+ pushl %fs
+ pushl %gs
+ pushl %ss
+
+ subl $8, %esp
+ movl %ebp, REG_OFF(KDIREG_SAVFP)(%esp)
+ movl REG_OFF(KDIREG_EIP)(%esp), %eax
+ movl %eax, REG_OFF(KDIREG_SAVPC)(%esp)
+
+ /*
+ * If the kernel has started using its own selectors, we should too.
+ * Update our saved selectors if they haven't been updated already.
+ */
+ movw %cs, %ax
+ cmpw $KCS_SEL, %ax
+ jne 1f /* The kernel hasn't switched yet */
+
+ movw $KDS_SEL, %ax
+ movw %ax, %ds
+ movw kdi_cs, %ax
+ cmpw $KCS_SEL, %ax
+ je 1f /* We already switched */
+
+ /*
+ * The kernel switched, but we haven't. Update our saved selectors
+ * to match the kernel's copies for use below.
+ */
+ movl $KCS_SEL, kdi_cs
+ movl $KDS_SEL, kdi_ds
+ movl $KFS_SEL, kdi_fs
+ movl $KGS_SEL, kdi_gs
+
+1:
+ /*
+ * Set the selectors to a known state. If we come in from kmdb's IDT,
+ * we'll be on boot's %cs. This will cause GET_CPUSAVE_ADDR to return
+ * CPU 0's cpusave, regardless of which CPU we're on, and chaos will
+ * ensue. So, if we've got $KCSSEL in kdi_cs, switch to it. The other
+ * selectors are restored normally.
+ */
+ movw %cs:kdi_cs, %ax
+ cmpw $KCS_SEL, %ax
+ jne 1f
+ ljmp $KCS_SEL, $1f
+1:
+ movw %cs:kdi_ds, %ds
+ movw kdi_ds, %es
+ movw kdi_fs, %fs
+ movw kdi_gs, %gs
+ movw kdi_ds, %ss
+
+ /*
+ * This has to come after we set %gs to the kernel descriptor. Since
+ * we've hijacked some IDT entries used in user-space such as the
+ * breakpoint handler, we can enter kdi_cmnint() with GDT_LWPGS used
+ * in %gs. On the hypervisor, CLI() needs GDT_GS to access the machcpu.
+ */
+ CLI(%eax)
+
+ GET_CPUSAVE_ADDR /* %eax = cpusave, %ebx = CPU ID */
+
+ ADVANCE_CRUMB_POINTER(%eax, %ecx, %edx)
+
+ ADD_CRUMB(%eax, KRM_CPU_STATE, $KDI_CPU_STATE_MASTER, %edx)
+
+ movl REG_OFF(KDIREG_EIP)(%esp), %ecx
+ ADD_CRUMB(%eax, KRM_PC, %ecx, %edx)
+ ADD_CRUMB(%eax, KRM_SP, %esp, %edx)
+ movl REG_OFF(KDIREG_TRAPNO)(%esp), %ecx
+ ADD_CRUMB(%eax, KRM_TRAPNO, %ecx, %edx)
+
+ movl %esp, %ebp
+ pushl %eax
+
+ /*
+ * Were we in the debugger when we took the trap (i.e. was %esp in one
+ * of the debugger's memory ranges)?
+ */
+ leal kdi_memranges, %ecx
+ movl kdi_nmemranges, %edx
+1: cmpl MR_BASE(%ecx), %esp
+ jl 2f /* below this range -- try the next one */
+ cmpl MR_LIM(%ecx), %esp
+ jg 2f /* above this range -- try the next one */
+ jmp 3f /* matched within this range */
+
+2: decl %edx
+ jz kdi_save_common_state /* %esp not within debugger memory */
+ addl $MR_SIZE, %ecx
+ jmp 1b
+
+3: /*
+ * %esp was within one of the debugger's memory ranges. This should
+ * only happen when we take a trap while running in the debugger.
+ * kmdb_dpi_handle_fault will determine whether or not it was an
+ * expected trap, and will take the appropriate action.
+ */
+
+ pushl %ebx /* cpuid */
+
+ movl REG_OFF(KDIREG_ESP)(%ebp), %ecx
+ addl $REG_OFF(KDIREG_EFLAGS - KDIREG_EAX), %ecx
+ pushl %ecx
+
+ pushl REG_OFF(KDIREG_EIP)(%ebp)
+ pushl REG_OFF(KDIREG_TRAPNO)(%ebp)
+
+ call kdi_dvec_handle_fault
+ addl $16, %esp
+
+ /*
+ * If we're here, we ran into a debugger problem, and the user
+ * elected to solve it by having the debugger debug itself. The
+ * state we're about to save is that of the debugger when it took
+ * the fault.
+ */
+
+ jmp kdi_save_common_state
+
+ SET_SIZE(kdi_master_entry)
+ SET_SIZE(kdi_cmnint)
+
+#endif /* __lint */
+
+/*
+ * The cross-call handler for slave CPUs.
+ *
+ * The debugger is single-threaded, so only one CPU, called the master, may be
+ * running it at any given time. The other CPUs, known as slaves, spin in a
+ * busy loop until there's something for them to do. This is the entry point
+ * for the slaves - they'll be sent here in response to a cross-call sent by the
+ * master.
+ */
+
+#if defined(__lint)
+char kdi_slave_entry_patch;
+
+void
+kdi_slave_entry(void)
+{
+}
+#else /* __lint */
+ .globl kdi_slave_entry_patch;
+
+ ENTRY_NP(kdi_slave_entry)
+
+ /* kdi_msr_add_clrentry knows where this is */
+kdi_slave_entry_patch:
+ KDI_MSR_PATCH;
+
+ /*
+ * Cross calls are implemented as function calls, so our stack
+ * currently looks like one you'd get from a zero-argument function
+ * call. There's an %eip at %esp, and that's about it. We want to
+ * make it look like the master CPU's stack. By doing this, we can
+ * use the same resume code for both master and slave. We need to
+ * make our stack look like a `struct regs' before we jump into the
+ * common save routine.
+ */
+
+ pushl %cs
+ pushfl
+ pushl $-1 /* A phony trap error code */
+ pushl $-1 /* A phony trap number */
+ pushal
+ pushl %ds
+ pushl %es
+ pushl %fs
+ pushl %gs
+ pushl %ss
+
+ subl $8, %esp
+ movl %ebp, REG_OFF(KDIREG_SAVFP)(%esp)
+ movl REG_OFF(KDIREG_EIP)(%esp), %eax
+ movl %eax, REG_OFF(KDIREG_SAVPC)(%esp)
+
+ /*
+ * Swap our saved EFLAGS and %eip. Each is where the other
+ * should be.
+ */
+ movl REG_OFF(KDIREG_EFLAGS)(%esp), %eax
+ xchgl REG_OFF(KDIREG_EIP)(%esp), %eax
+ movl %eax, REG_OFF(KDIREG_EFLAGS)(%esp)
+
+ /*
+ * Our stack now matches struct regs, and is irettable. We don't need
+ * to do anything special for the hypervisor w.r.t. PS_IE since we
+ * iret twice anyway; the second iret back to the hypervisor
+ * will re-enable interrupts.
+ */
+ CLI(%eax)
+
+ /* Load sanitized segment selectors */
+ movw kdi_ds, %ds
+ movw kdi_ds, %es
+ movw kdi_fs, %fs
+ movw kdi_gs, %gs
+ movw kdi_ds, %ss
+
+ GET_CPUSAVE_ADDR /* %eax = cpusave, %ebx = CPU ID */
+
+ ADVANCE_CRUMB_POINTER(%eax, %ecx, %edx)
+
+ ADD_CRUMB(%eax, KRM_CPU_STATE, $KDI_CPU_STATE_SLAVE, %edx)
+
+ movl REG_OFF(KDIREG_EIP)(%esp), %ecx
+ ADD_CRUMB(%eax, KRM_PC, %ecx, %edx)
+
+ pushl %eax
+ jmp kdi_save_common_state
+
+ SET_SIZE(kdi_slave_entry)
+
+#endif /* __lint */
+
+#if !defined(__lint)
+
+ ENTRY_NP(kdi_save_common_state)
+
+ /*
+ * The state of the world:
+ *
+ * The stack has a complete set of saved registers and segment
+ * selectors, arranged in `struct regs' order (or vice-versa), up to
+ * and including EFLAGS. It also has a pointer to our cpusave area.
+ *
+ * We need to save a pointer to these saved registers. We also want
+ * to adjust the saved %esp - it should point just beyond the saved
+ * registers to the last frame of the thread we interrupted. Finally,
+ * we want to clear out bits 16-31 of the saved selectors, as the
+ * selector pushls don't automatically clear them.
+ */
+ popl %eax /* the cpusave area */
+
+ movl %esp, KRS_GREGS(%eax) /* save ptr to current saved regs */
+
+ SAVE_IDTGDT
+
+ addl $REG_OFF(KDIREG_EFLAGS - KDIREG_EAX), KDIREG_OFF(KDIREG_ESP)(%esp)
+
+ andl $0xffff, KDIREG_OFF(KDIREG_SS)(%esp)
+ andl $0xffff, KDIREG_OFF(KDIREG_GS)(%esp)
+ andl $0xffff, KDIREG_OFF(KDIREG_FS)(%esp)
+ andl $0xffff, KDIREG_OFF(KDIREG_ES)(%esp)
+ andl $0xffff, KDIREG_OFF(KDIREG_DS)(%esp)
+
+ /* Save off %cr0, and clear write protect */
+ movl %cr0, %ecx
+ movl %ecx, KRS_CR0(%eax)
+ andl $_BITNOT(CR0_WP), %ecx
+ movl %ecx, %cr0
+ pushl %edi
+ movl %eax, %edi
+
+ /* Save the debug registers and disable any active watchpoints */
+ pushl $7
+ call kdi_dreg_get
+ addl $4, %esp
+
+ movl %eax, KRS_DRCTL(%edi)
+ andl $_BITNOT(KDIREG_DRCTL_WPALLEN_MASK), %eax
+
+ pushl %eax
+ pushl $7
+ call kdi_dreg_set
+ addl $8, %esp
+
+ pushl $6
+ call kdi_dreg_get
+ addl $4, %esp
+ movl %eax, KRS_DRSTAT(%edi)
+
+ pushl $0
+ call kdi_dreg_get
+ addl $4, %esp
+ movl %eax, KRS_DROFF(0)(%edi)
+
+ pushl $1
+ call kdi_dreg_get
+ addl $4, %esp
+ movl %eax, KRS_DROFF(1)(%edi)
+
+ pushl $2
+ call kdi_dreg_get
+ addl $4, %esp
+ movl %eax, KRS_DROFF(2)(%edi)
+
+ pushl $3
+ call kdi_dreg_get
+ addl $4, %esp
+ movl %eax, KRS_DROFF(3)(%edi)
+
+ movl %edi, %eax
+ popl %edi
+
+ /*
+ * Save any requested MSRs.
+ */
+ movl KRS_MSR(%eax), %ecx
+ cmpl $0, %ecx
+ je no_msr
+
+ pushl %eax /* rdmsr clobbers %eax */
+ movl %ecx, %ebx
+1:
+ movl MSR_NUM(%ebx), %ecx
+ cmpl $0, %ecx
+ je msr_done
+
+ movl MSR_TYPE(%ebx), %edx
+ cmpl $KDI_MSR_READ, %edx
+ jne msr_next
+
+ rdmsr /* addr in %ecx, value into %edx:%eax */
+ movl %eax, MSR_VAL(%ebx)
+ movl %edx, _CONST(MSR_VAL + 4)(%ebx)
+
+msr_next:
+ addl $MSR_SIZE, %ebx
+ jmp 1b
+
+msr_done:
+ popl %eax
+
+no_msr:
+ clr %ebp /* stack traces should end here */
+
+ pushl %eax
+ call kdi_debugger_entry
+ pushl %eax /* leave cpusave on the stack */
+
+ jmp kdi_resume
+
+ SET_SIZE(kdi_save_common_state)
+
+#endif /* !__lint */
+
+/*
+ * Given the address of the current CPU's cpusave area in %edi, the following
+ * macro restores the debugging state to said CPU. Restored state includes
+ * the debug registers from the global %dr variables, and debugging MSRs from
+ * the CPU save area. This code would be in a separate routine, but for the
+ * fact that some of the MSRs are jump-sensitive. As such, we need to minimize
+ * the number of jumps taken subsequent to the update of said MSRs. We can
+ * remove one jump (the ret) by using a macro instead of a function for the
+ * debugging state restoration code.
+ *
+ * Takes the cpusave area in %edi as a parameter, clobbers %eax-%edx
+ */
+#define KDI_RESTORE_DEBUGGING_STATE \
+ leal kdi_drreg, %ebx; \
+ \
+ pushl DR_CTL(%ebx); \
+ pushl $7; \
+ call kdi_dreg_set; \
+ addl $8, %esp; \
+ \
+ pushl $KDIREG_DRSTAT_RESERVED; \
+ pushl $6; \
+ call kdi_dreg_set; \
+ addl $8, %esp; \
+ \
+ pushl DRADDR_OFF(0)(%ebx); \
+ pushl $0; \
+ call kdi_dreg_set; \
+ addl $8, %esp; \
+ \
+ pushl DRADDR_OFF(1)(%ebx); \
+ pushl $1; \
+ call kdi_dreg_set; \
+ addl $8, %esp; \
+ \
+ pushl DRADDR_OFF(2)(%ebx); \
+ pushl $2; \
+ call kdi_dreg_set; \
+ addl $8, %esp; \
+ \
+ pushl DRADDR_OFF(3)(%ebx); \
+ pushl $3; \
+ call kdi_dreg_set; \
+ addl $8, %esp; \
+ \
+ /* \
+ * Write any requested MSRs. \
+ */ \
+ movl KRS_MSR(%edi), %ebx; \
+ cmpl $0, %ebx; \
+ je 3f; \
+1: \
+ movl MSR_NUM(%ebx), %ecx; \
+ cmpl $0, %ecx; \
+ je 3f; \
+ \
+ movl MSR_TYPE(%ebx), %edx; \
+ cmpl $KDI_MSR_WRITE, %edx; \
+ jne 2f; \
+ \
+ movl MSR_VALP(%ebx), %edx; \
+ movl 0(%edx), %eax; \
+ movl 4(%edx), %edx; \
+ wrmsr; \
+2: \
+ addl $MSR_SIZE, %ebx; \
+ jmp 1b; \
+3: \
+ /* \
+ * We must not branch after re-enabling LBR. If \
+ * kdi_wsr_wrexit_msr is set, it contains the number \
+ * of the MSR that controls LBR. kdi_wsr_wrexit_valp \
+ * contains the value that is to be written to enable \
+ * LBR. \
+ */ \
+ movl kdi_msr_wrexit_msr, %ecx; \
+ cmpl $0, %ecx; \
+ je 1f; \
+ \
+ movl kdi_msr_wrexit_valp, %edx; \
+ movl 0(%edx), %eax; \
+ movl 4(%edx), %edx; \
+ \
+ wrmsr; \
+1:
+
+#if defined(__lint)
+/*ARGSUSED*/
+void
+kdi_cpu_debug_init(kdi_cpusave_t *save)
+{
+}
+#else /* __lint */
+
+ ENTRY_NP(kdi_cpu_debug_init)
+ pushl %ebp
+ movl %esp, %ebp
+
+ pushl %edi
+ pushl %ebx
+
+ movl 8(%ebp), %edi
+
+ KDI_RESTORE_DEBUGGING_STATE
+
+ popl %ebx
+ popl %edi
+ leave
+ ret
+
+ SET_SIZE(kdi_cpu_debug_init)
+#endif /* !__lint */
+
+/*
+ * Resume the world. The code that calls kdi_resume has already
+ * decided whether or not to restore the IDT.
+ */
+#if defined(__lint)
+void
+kdi_resume(void)
+{
+}
+#else /* __lint */
+
+ ENTRY_NP(kdi_resume)
+ popl %ebx /* command */
+ popl %eax /* cpusave */
+
+ cmpl $KDI_RESUME_PASS_TO_KERNEL, %ebx
+ je kdi_pass_to_kernel
+
+ /*
+ * Send this CPU back into the world
+ */
+
+ movl KRS_CR0(%eax), %edx
+ movl %edx, %cr0
+
+ pushl %edi
+ movl %eax, %edi
+
+ KDI_RESTORE_DEBUGGING_STATE
+
+ popl %edi
+
+ addl $8, %esp /* Discard savfp and savpc */
+
+ popl %ss
+ popl %gs
+ popl %fs
+ popl %es
+ popl %ds
+ popal
+
+ addl $8, %esp /* Discard TRAPNO and ERROR */
+
+ IRET
+
+ SET_SIZE(kdi_resume)
+#endif /* __lint */
+
+#if !defined(__lint)
+
+ ENTRY_NP(kdi_pass_to_kernel)
+
+ /* cpusave is still in %eax */
+ movl KRS_CR0(%eax), %edx
+ movl %edx, %cr0
+
+ /*
+ * When we replaced the kernel's handlers in the IDT, we made note of
+ * the handlers being replaced, thus allowing us to pass traps directly
+ * to said handlers here. We won't have any registers available for use
+ * after we start popping, and we know we're single-threaded here, so
+ * we have to use a global to store the handler address.
+ */
+ pushl REG_OFF(KDIREG_TRAPNO)(%esp)
+ call kdi_kernel_trap2hdlr
+ addl $4, %esp
+ movl %eax, kdi_kernel_handler
+
+ /*
+ * The trap handler will expect the stack to be in trap order, with
+ * %eip being the last entry. Our stack is currently in KDIREG_*
+ * order, so we'll need to pop (and restore) our way back down.
+ */
+ addl $8, %esp /* Discard savfp and savpc */
+ popl %ss
+ popl %gs
+ popl %fs
+ popl %es
+ popl %ds
+ popal
+ addl $8, %esp /* Discard trapno and err */
+
+ ljmp $KCS_SEL, $1f
+1: jmp *%cs:kdi_kernel_handler
+ /*NOTREACHED*/
+
+ SET_SIZE(kdi_pass_to_kernel)
+
+ /*
+ * Reboot the system. This routine is to be called only by the master
+ * CPU.
+ */
+ ENTRY_NP(kdi_reboot)
+
+ pushl $AD_BOOT
+ pushl $A_SHUTDOWN
+ call *psm_shutdownf
+ addl $8, %esp
+
+ /*
+ * psm_shutdown didn't work or it wasn't set, try pc_reset.
+ */
+ call pc_reset
+ /*NOTREACHED*/
+
+ SET_SIZE(kdi_reboot)
+
+#endif /* !__lint */
diff --git a/usr/src/uts/intel/kdi/kdi_idt.c b/usr/src/uts/intel/kdi/kdi_idt.c
new file mode 100644
index 0000000000..5b170550d3
--- /dev/null
+++ b/usr/src/uts/intel/kdi/kdi_idt.c
@@ -0,0 +1,555 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Management of KMDB's IDT, which is installed upon KMDB activation.
+ *
+ * Debugger activation has two flavors, which cover the cases where KMDB is
+ * loaded at boot, and when it is loaded after boot. In brief, in both cases,
+ * the KDI needs to interpose upon several handlers in the IDT. When
+ * mod-loaded KMDB is deactivated, we undo the IDT interposition, restoring the
+ * handlers to what they were before we started.
+ *
+ * We also take over the entirety of IDT (except the double-fault handler) on
+ * the active CPU when we're in kmdb so we can handle things like page faults
+ * sensibly.
+ *
+ * Boot-loaded KMDB
+ *
+ * When we're first activated, we're running on boot's IDT. We need to be able
+ * to function in this world, so we'll install our handlers into boot's IDT.
+ * This is a little complicated: we're using the fake cpu_t set up by
+ * boot_kdi_tmpinit(), so we can't access cpu_idt directly. Instead,
+ * kdi_idt_write() notices that cpu_idt is NULL, and works around this problem.
+ *
+ * Later, when we're about to switch to the kernel's IDT, it'll call us via
+ * kdi_idt_sync(), allowing us to add our handlers to the new IDT. While
+ * boot-loaded KMDB can't be unloaded, we still need to save the descriptors we
+ * replace so we can pass traps back to the kernel as necessary.
+ *
+ * The last phase of boot-loaded KMDB activation occurs at non-boot CPU
+ * startup. We will be called on each non-boot CPU, thus allowing us to set up
+ * any watchpoints that may have been configured on the boot CPU and interpose
+ * on the given CPU's IDT. We don't save the interposed descriptors in this
+ * case -- see kdi_cpu_init() for details.
+ *
+ * Mod-loaded KMDB
+ *
+ * This style of activation is much simpler, as the CPUs are already running,
+ * and are using their own copy of the kernel's IDT. We simply interpose upon
+ * each CPU's IDT. We save the handlers we replace, both for deactivation and
+ * for passing traps back to the kernel. Note that for Xen's benefit, we need
+ * to xcall to the other CPUs to do this, since we need to actively set the
+ * trap entries in its virtual IDT from that vcpu's context rather than just
+ * modify the IDT table from the CPU running kdi_activate().
+ */
+
+#include <sys/types.h>
+#include <sys/segments.h>
+#include <sys/trap.h>
+#include <sys/cpuvar.h>
+#include <sys/reboot.h>
+#include <sys/sunddi.h>
+#include <sys/archsystm.h>
+#include <sys/kdi_impl.h>
+#include <sys/x_call.h>
+#include <ia32/sys/psw.h>
+
+#define KDI_GATE_NVECS 3
+
+#define KDI_IDT_NOSAVE 0
+#define KDI_IDT_SAVE 1
+
+#define KDI_IDT_DTYPE_KERNEL 0
+#define KDI_IDT_DTYPE_BOOT 1
+
+kdi_cpusave_t *kdi_cpusave;
+int kdi_ncpusave;
+
+static kdi_main_t kdi_kmdb_main;
+
+kdi_drreg_t kdi_drreg;
+
+#ifndef __amd64
+/* Used to track the current set of valid kernel selectors. */
+uint32_t kdi_cs;
+uint32_t kdi_ds;
+uint32_t kdi_fs;
+uint32_t kdi_gs;
+#endif
+
+uint_t kdi_msr_wrexit_msr;
+uint64_t *kdi_msr_wrexit_valp;
+
+uintptr_t kdi_kernel_handler;
+
+int kdi_trap_switch;
+
+#define KDI_MEMRANGES_MAX 2
+
+kdi_memrange_t kdi_memranges[KDI_MEMRANGES_MAX];
+int kdi_nmemranges;
+
+typedef void idt_hdlr_f(void);
+
+extern idt_hdlr_f kdi_trap0, kdi_trap1, kdi_int2, kdi_trap3, kdi_trap4;
+extern idt_hdlr_f kdi_trap5, kdi_trap6, kdi_trap7, kdi_trap9;
+extern idt_hdlr_f kdi_traperr10, kdi_traperr11, kdi_traperr12;
+extern idt_hdlr_f kdi_traperr13, kdi_traperr14, kdi_trap16, kdi_trap17;
+extern idt_hdlr_f kdi_trap18, kdi_trap19, kdi_trap20, kdi_ivct32;
+extern idt_hdlr_f kdi_invaltrap;
+extern size_t kdi_ivct_size;
+extern char kdi_slave_entry_patch;
+
+typedef struct kdi_gate_spec {
+ uint_t kgs_vec;
+ uint_t kgs_dpl;
+} kdi_gate_spec_t;
+
+static const kdi_gate_spec_t kdi_gate_specs[KDI_GATE_NVECS] = {
+ { T_SGLSTP, SEL_KPL },
+ { T_BPTFLT, SEL_UPL },
+ { T_DBGENTR, SEL_KPL }
+};
+
+static gate_desc_t kdi_kgates[KDI_GATE_NVECS];
+
+gate_desc_t kdi_idt[NIDT];
+
+struct idt_description {
+ uint_t id_low;
+ uint_t id_high;
+ idt_hdlr_f *id_basehdlr;
+ size_t *id_incrp;
+} idt_description[] = {
+ { T_ZERODIV, 0, kdi_trap0, NULL },
+ { T_SGLSTP, 0, kdi_trap1, NULL },
+ { T_NMIFLT, 0, kdi_int2, NULL },
+ { T_BPTFLT, 0, kdi_trap3, NULL },
+ { T_OVFLW, 0, kdi_trap4, NULL },
+ { T_BOUNDFLT, 0, kdi_trap5, NULL },
+ { T_ILLINST, 0, kdi_trap6, NULL },
+ { T_NOEXTFLT, 0, kdi_trap7, NULL },
+ { T_DBLFLT, 0, syserrtrap, NULL },
+ { T_EXTOVRFLT, 0, kdi_trap9, NULL },
+ { T_TSSFLT, 0, kdi_traperr10, NULL },
+ { T_SEGFLT, 0, kdi_traperr11, NULL },
+ { T_STKFLT, 0, kdi_traperr12, NULL },
+ { T_GPFLT, 0, kdi_traperr13, NULL },
+ { T_PGFLT, 0, kdi_traperr14, NULL },
+ { 15, 0, kdi_invaltrap, NULL },
+ { T_EXTERRFLT, 0, kdi_trap16, NULL },
+ { T_ALIGNMENT, 0, kdi_trap17, NULL },
+ { T_MCE, 0, kdi_trap18, NULL },
+ { T_SIMDFPE, 0, kdi_trap19, NULL },
+ { T_DBGENTR, 0, kdi_trap20, NULL },
+ { 21, 31, kdi_invaltrap, NULL },
+ { 32, 255, kdi_ivct32, &kdi_ivct_size },
+ { 0, 0, NULL },
+};
+
+void
+kdi_idt_init(selector_t sel)
+{
+ struct idt_description *id;
+ int i;
+
+ for (id = idt_description; id->id_basehdlr != NULL; id++) {
+ uint_t high = id->id_high != 0 ? id->id_high : id->id_low;
+ size_t incr = id->id_incrp != NULL ? *id->id_incrp : 0;
+
+ for (i = id->id_low; i <= high; i++) {
+ caddr_t hdlr = (caddr_t)id->id_basehdlr +
+ incr * (i - id->id_low);
+ set_gatesegd(&kdi_idt[i], (void (*)())hdlr, sel,
+ SDT_SYSIGT, SEL_KPL);
+ }
+ }
+}
+
+/*
+ * Patch caller-provided code into the debugger's IDT handlers. This code is
+ * used to save MSRs that must be saved before the first branch. All handlers
+ * are essentially the same, and end with a branch to kdi_cmnint. To save the
+ * MSR, we need to patch in before the branch. The handlers have the following
+ * structure: KDI_MSR_PATCHOFF bytes of code, KDI_MSR_PATCHSZ bytes of
+ * patchable space, followed by more code.
+ */
+void
+kdi_idt_patch(caddr_t code, size_t sz)
+{
+ int i;
+
+ ASSERT(sz <= KDI_MSR_PATCHSZ);
+
+ for (i = 0; i < sizeof (kdi_idt) / sizeof (struct gate_desc); i++) {
+ gate_desc_t *gd;
+ uchar_t *patch;
+
+ if (i == T_DBLFLT)
+ continue; /* uses kernel's handler */
+
+ gd = &kdi_idt[i];
+ patch = (uchar_t *)GATESEG_GETOFFSET(gd) + KDI_MSR_PATCHOFF;
+
+ /*
+ * We can't ASSERT that there's a nop here, because this may be
+ * a debugger restart. In that case, we're copying the new
+ * patch point over the old one.
+ */
+ /* FIXME: dtrace fbt ... */
+ bcopy(code, patch, sz);
+
+ /* Fill the rest with nops to be sure */
+ while (sz < KDI_MSR_PATCHSZ)
+ patch[sz++] = 0x90; /* nop */
+ }
+}
+
+static void
+kdi_idt_gates_install(selector_t sel, int saveold)
+{
+ gate_desc_t gates[KDI_GATE_NVECS];
+ int i;
+
+ bzero(gates, sizeof (*gates));
+
+ for (i = 0; i < KDI_GATE_NVECS; i++) {
+ const kdi_gate_spec_t *gs = &kdi_gate_specs[i];
+ uintptr_t func = GATESEG_GETOFFSET(&kdi_idt[gs->kgs_vec]);
+ set_gatesegd(&gates[i], (void (*)())func, sel, SDT_SYSIGT,
+ gs->kgs_dpl);
+ }
+
+ for (i = 0; i < KDI_GATE_NVECS; i++) {
+ uint_t vec = kdi_gate_specs[i].kgs_vec;
+
+ if (saveold)
+ kdi_kgates[i] = CPU->cpu_m.mcpu_idt[vec];
+
+ kdi_idt_write(&gates[i], vec);
+ }
+}
+
+static void
+kdi_idt_gates_restore(void)
+{
+ int i;
+
+ for (i = 0; i < KDI_GATE_NVECS; i++)
+ kdi_idt_write(&kdi_kgates[i], kdi_gate_specs[i].kgs_vec);
+}
+
+/*
+ * Used by the code which passes traps back to the kernel to retrieve the
+ * address of the kernel's handler for a given trap. We get this address
+ * from the descriptor save area, which we populated when we loaded the
+ * debugger (mod-loaded) or initialized the kernel's IDT (boot-loaded).
+ */
+uintptr_t
+kdi_kernel_trap2hdlr(int vec)
+{
+ int i;
+
+ for (i = 0; i < KDI_GATE_NVECS; i++) {
+ if (kdi_gate_specs[i].kgs_vec == vec)
+ return (GATESEG_GETOFFSET(&kdi_kgates[i]));
+ }
+
+ return (NULL);
+}
+
+/*
+ * Called when we switch to the kernel's IDT. We need to interpose on the
+ * kernel's IDT entries and stop using KMDBCODE_SEL.
+ */
+void
+kdi_idt_sync(void)
+{
+ kdi_idt_init(KCS_SEL);
+ kdi_idt_gates_install(KCS_SEL, KDI_IDT_SAVE);
+}
+
+/*
+ * On some processors, we'll need to clear a certain MSR before proceeding into
+ * the debugger. Complicating matters, this MSR must be cleared before we take
+ * any branches. We have patch points in every trap handler, which will cover
+ * all entry paths for master CPUs. We also have a patch point in the slave
+ * entry code.
+ */
+static void
+kdi_msr_add_clrentry(uint_t msr)
+{
+#ifdef __amd64
+ uchar_t code[] = {
+ 0x51, 0x50, 0x52, /* pushq %rcx, %rax, %rdx */
+ 0xb9, 0x00, 0x00, 0x00, 0x00, /* movl $MSRNUM, %ecx */
+ 0x31, 0xc0, /* clr %eax */
+ 0x31, 0xd2, /* clr %edx */
+ 0x0f, 0x30, /* wrmsr */
+ 0x5a, 0x58, 0x59 /* popq %rdx, %rax, %rcx */
+ };
+ uchar_t *patch = &code[4];
+#else
+ uchar_t code[] = {
+ 0x60, /* pushal */
+ 0xb9, 0x00, 0x00, 0x00, 0x00, /* movl $MSRNUM, %ecx */
+ 0x31, 0xc0, /* clr %eax */
+ 0x31, 0xd2, /* clr %edx */
+ 0x0f, 0x30, /* wrmsr */
+ 0x61 /* popal */
+ };
+ uchar_t *patch = &code[2];
+#endif
+
+ bcopy(&msr, patch, sizeof (uint32_t));
+
+ kdi_idt_patch((caddr_t)code, sizeof (code));
+
+ bcopy(code, &kdi_slave_entry_patch, sizeof (code));
+}
+
+static void
+kdi_msr_add_wrexit(uint_t msr, uint64_t *valp)
+{
+ kdi_msr_wrexit_msr = msr;
+ kdi_msr_wrexit_valp = valp;
+}
+
+void
+kdi_set_debug_msrs(kdi_msr_t *msrs)
+{
+ int nmsrs, i;
+
+ ASSERT(kdi_cpusave[0].krs_msr == NULL);
+
+ /* Look in CPU0's MSRs for any special MSRs. */
+ for (nmsrs = 0; msrs[nmsrs].msr_num != 0; nmsrs++) {
+ switch (msrs[nmsrs].msr_type) {
+ case KDI_MSR_CLEARENTRY:
+ kdi_msr_add_clrentry(msrs[nmsrs].msr_num);
+ break;
+
+ case KDI_MSR_WRITEDELAY:
+ kdi_msr_add_wrexit(msrs[nmsrs].msr_num,
+ msrs[nmsrs].kdi_msr_valp);
+ break;
+ }
+ }
+
+ nmsrs++;
+
+ for (i = 0; i < kdi_ncpusave; i++)
+ kdi_cpusave[i].krs_msr = &msrs[nmsrs * i];
+}
+
+void
+kdi_update_drreg(kdi_drreg_t *drreg)
+{
+ kdi_drreg = *drreg;
+}
+
+void
+kdi_memrange_add(caddr_t base, size_t len)
+{
+ kdi_memrange_t *mr = &kdi_memranges[kdi_nmemranges];
+
+ ASSERT(kdi_nmemranges != KDI_MEMRANGES_MAX);
+
+ mr->mr_base = base;
+ mr->mr_lim = base + len - 1;
+ kdi_nmemranges++;
+}
+
+void
+kdi_idt_switch(kdi_cpusave_t *cpusave)
+{
+ if (cpusave == NULL)
+ kdi_idtr_set(kdi_idt, sizeof (kdi_idt) - 1);
+ else
+ kdi_idtr_set(cpusave->krs_idt, sizeof (idt0) - 1);
+}
+
+/*
+ * Activation for CPUs other than the boot CPU, called from that CPU's
+ * mp_startup(). We saved the kernel's descriptors when we initialized the
+ * boot CPU, so we don't want to do it again. Saving the handlers from this
+ * CPU's IDT would actually be dangerous with the CPU initialization method in
+ * use at the time of this writing. With that method, the startup code creates
+ * the IDTs for slave CPUs by copying the one used by the boot CPU, which has
+ * already been interposed upon by KMDB. Were we to interpose again, we'd
+ * replace the kernel's descriptors with our own in the save area. By not
+ * saving, but still overwriting, we'll work in the current world, and in any
+ * future world where the IDT is generated from scratch.
+ */
+void
+kdi_cpu_init(void)
+{
+ kdi_idt_gates_install(KCS_SEL, KDI_IDT_NOSAVE);
+ /* Load the debug registers and MSRs */
+ kdi_cpu_debug_init(&kdi_cpusave[CPU->cpu_id]);
+}
+
+/*
+ * Activation for all CPUs for mod-loaded kmdb, i.e. a kmdb that wasn't
+ * loaded at boot.
+ */
+static int
+kdi_cpu_activate(void)
+{
+ kdi_idt_gates_install(KCS_SEL, KDI_IDT_SAVE);
+ return (0);
+}
+
+void
+kdi_activate(kdi_main_t main, kdi_cpusave_t *cpusave, uint_t ncpusave)
+{
+ int i;
+ cpuset_t cpuset;
+
+ CPUSET_ALL(cpuset);
+
+ kdi_cpusave = cpusave;
+ kdi_ncpusave = ncpusave;
+
+ kdi_kmdb_main = main;
+
+ for (i = 0; i < kdi_ncpusave; i++) {
+ kdi_cpusave[i].krs_cpu_id = i;
+
+ kdi_cpusave[i].krs_curcrumb =
+ &kdi_cpusave[i].krs_crumbs[KDI_NCRUMBS - 1];
+ kdi_cpusave[i].krs_curcrumbidx = KDI_NCRUMBS - 1;
+ }
+
+ if (boothowto & RB_KMDB)
+ kdi_idt_init(KMDBCODE_SEL);
+ else
+ kdi_idt_init(KCS_SEL);
+
+ /* The initial selector set. Updated by the debugger-entry code */
+#ifndef __amd64
+ kdi_cs = B32CODE_SEL;
+ kdi_ds = kdi_fs = kdi_gs = B32DATA_SEL;
+#endif
+
+ kdi_memranges[0].mr_base = kdi_segdebugbase;
+ kdi_memranges[0].mr_lim = kdi_segdebugbase + kdi_segdebugsize - 1;
+ kdi_nmemranges = 1;
+
+ kdi_drreg.dr_ctl = KDIREG_DRCTL_RESERVED;
+ kdi_drreg.dr_stat = KDIREG_DRSTAT_RESERVED;
+
+ kdi_msr_wrexit_msr = 0;
+ kdi_msr_wrexit_valp = NULL;
+
+ if (boothowto & RB_KMDB) {
+ kdi_idt_gates_install(KMDBCODE_SEL, KDI_IDT_NOSAVE);
+ } else {
+ xc_call(0, 0, 0, X_CALL_HIPRI, cpuset,
+ (xc_func_t)kdi_cpu_activate);
+ }
+}
+
+static int
+kdi_cpu_deactivate(void)
+{
+ kdi_idt_gates_restore();
+ return (0);
+}
+
+void
+kdi_deactivate(void)
+{
+ cpuset_t cpuset;
+ CPUSET_ALL(cpuset);
+
+ xc_call(0, 0, 0, X_CALL_HIPRI, cpuset, (xc_func_t)kdi_cpu_deactivate);
+ kdi_nmemranges = 0;
+}
+
+/*
+ * We receive all breakpoints and single step traps. Some of them,
+ * including those from userland and those induced by DTrace providers,
+ * are intended for the kernel, and must be processed there. We adopt
+ * this ours-until-proven-otherwise position due to the painful
+ * consequences of sending the kernel an unexpected breakpoint or
+ * single step. Unless someone can prove to us that the kernel is
+ * prepared to handle the trap, we'll assume there's a problem and will
+ * give the user a chance to debug it.
+ */
+static int
+kdi_trap_pass(kdi_cpusave_t *cpusave)
+{
+ greg_t tt = cpusave->krs_gregs[KDIREG_TRAPNO];
+ greg_t pc = cpusave->krs_gregs[KDIREG_PC];
+ greg_t cs = cpusave->krs_gregs[KDIREG_CS];
+
+ if (USERMODE(cs))
+ return (1);
+
+ if (tt != T_BPTFLT && tt != T_SGLSTP)
+ return (0);
+
+ if (tt == T_BPTFLT && kdi_dtrace_get_state() ==
+ KDI_DTSTATE_DTRACE_ACTIVE)
+ return (1);
+
+ /*
+ * See the comments in the kernel's T_SGLSTP handler for why we need to
+ * do this.
+ */
+ if (tt == T_SGLSTP &&
+ pc == (greg_t)sys_sysenter || pc == (greg_t)brand_sys_sysenter)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * State has been saved, and all CPUs are on the CPU-specific stacks. All
+ * CPUs enter here, and head off into the debugger proper.
+ */
+int
+kdi_debugger_entry(kdi_cpusave_t *cpusave)
+{
+ if (kdi_trap_pass(cpusave)) {
+ cpusave->krs_cpu_state = KDI_CPU_STATE_NONE;
+ return (KDI_RESUME_PASS_TO_KERNEL);
+ }
+
+ /*
+ * BPTFLT gives us control with %eip set to the instruction *after*
+ * the int 3. Back it off, so we're looking at the instruction that
+ * triggered the fault.
+ */
+ if (cpusave->krs_gregs[KDIREG_TRAPNO] == T_BPTFLT)
+ cpusave->krs_gregs[KDIREG_PC]--;
+
+ kdi_kmdb_main(cpusave);
+ return (KDI_RESUME);
+}
diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif_idthdl.s b/usr/src/uts/intel/kdi/kdi_idthdl.s
index 45fdba6c78..0d2e31322b 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kaif_idthdl.s
+++ b/usr/src/uts/intel/kdi/kdi_idthdl.s
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,22 +19,22 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
- * Companion to kaif_idt.c - the implementation of the trap and interrupt
+ * Companion to kdi_idt.c - the implementation of the trap and interrupt
* handlers. For the most part, these handlers do the same thing - they
- * push a trap number onto the stack, followed by a jump to kaif_cmnint.
+ * push a trap number onto the stack, followed by a jump to kdi_cmnint.
* Each trap and interrupt has its own handler because each one pushes a
* different number.
*/
#include <sys/asm_linkage.h>
-#include <kmdb/kaif_asmutil.h>
+#include <sys/kdi_regs.h>
/* Nothing in this file is of interest to lint. */
#if !defined(__lint)
@@ -49,88 +48,74 @@
/*
* We need the .align in ENTRY_NP (defined to be ASM_ENTRY_ALIGN) to match our
- * manual .align (KAIF_MSR_PATCHOFF) in order to ensure that the space reserved
- * at the beginning of the handler for code is exactly KAIF_MSR_PATCHOFF bytes
+ * manual .align (KDI_MSR_PATCHOFF) in order to ensure that the space reserved
+ * at the beginning of the handler for code is exactly KDI_MSR_PATCHOFF bytes
* long. Note that the #error below isn't supported by the preprocessor invoked
* by as(1), and won't stop the build, but it'll emit a noticeable error message
* which won't escape the filters.
*/
-#if ASM_ENTRY_ALIGN != KAIF_MSR_PATCHOFF
-#error "ASM_ENTRY_ALIGN != KAIF_MSR_PATCHOFF"
+#if ASM_ENTRY_ALIGN != KDI_MSR_PATCHOFF
+#error "ASM_ENTRY_ALIGN != KDI_MSR_PATCHOFF"
this won't assemble
#endif
/*
- * kaif_idt_patch will, on certain processors, replace the patch points below
- * with MSR-clearing code. kaif_id_patch has intimate knowledge of the size of
+ * kdi_idt_patch will, on certain processors, replace the patch points below
+ * with MSR-clearing code. kdi_id_patch has intimate knowledge of the size of
* the nop hole, as well as the structure of the handlers. Do not change
- * anything here without also changing kaif_idt_patch.
+ * anything here without also changing kdi_idt_patch.
*/
/*
* Generic trap and interrupt handlers.
*/
-#if defined(__amd64)
-
-#define TRAP_NOERR(trapno) \
- pushq $trapno
-
-#define TRAP_ERR(trapno) \
- pushq $0; \
- pushq $trapno
-
-#else /* __i386 */
-
-#define TRAP_NOERR(trapno) \
- pushl $trapno
-
-#define TRAP_ERR(trapno) \
- pushl $0; \
- pushl $trapno
-
-#endif
+#define TRAP_NOERR(trapno) \
+ push $trapno
+#define TRAP_ERR(trapno) \
+ push $0; \
+ push $trapno
#define MKIVCT(n) \
- ENTRY_NP(kaif_ivct/**/n/**/); \
+ ENTRY_NP(kdi_ivct/**/n/**/); \
TRAP_ERR(n); \
- .align KAIF_MSR_PATCHOFF; \
- KAIF_MSR_PATCH; \
- jmp kaif_cmnint; \
- SET_SIZE(kaif_ivct/**/n/**/)
+ .align KDI_MSR_PATCHOFF; \
+ KDI_MSR_PATCH; \
+ jmp kdi_cmnint; \
+ SET_SIZE(kdi_ivct/**/n/**/)
#define MKTRAPHDLR(n) \
- ENTRY_NP(kaif_trap/**/n); \
+ ENTRY_NP(kdi_trap/**/n); \
TRAP_ERR(n); \
- .align KAIF_MSR_PATCHOFF; \
- KAIF_MSR_PATCH; \
- jmp kaif_cmnint; \
- SET_SIZE(kaif_trap/**/n/**/)
+ .align KDI_MSR_PATCHOFF; \
+ KDI_MSR_PATCH; \
+ jmp kdi_cmnint; \
+ SET_SIZE(kdi_trap/**/n/**/)
#define MKTRAPERRHDLR(n) \
- ENTRY_NP(kaif_traperr/**/n); \
+ ENTRY_NP(kdi_traperr/**/n); \
TRAP_NOERR(n); \
- .align KAIF_MSR_PATCHOFF; \
- KAIF_MSR_PATCH; \
- jmp kaif_cmnint; \
- SET_SIZE(kaif_traperr/**/n)
+ .align KDI_MSR_PATCHOFF; \
+ KDI_MSR_PATCH; \
+ jmp kdi_cmnint; \
+ SET_SIZE(kdi_traperr/**/n)
#define MKNMIHDLR \
- ENTRY_NP(kaif_int2); \
+ ENTRY_NP(kdi_int2); \
TRAP_NOERR(2); \
- .align KAIF_MSR_PATCHOFF; \
- KAIF_MSR_PATCH; \
- jmp kaif_nmiint; \
- SET_SIZE(kaif_int2)
+ .align KDI_MSR_PATCHOFF; \
+ KDI_MSR_PATCH; \
+ jmp kdi_nmiint; \
+ SET_SIZE(kdi_int2)
#define MKINVALHDLR \
- ENTRY_NP(kaif_invaltrap); \
+ ENTRY_NP(kdi_invaltrap); \
TRAP_NOERR(255); \
- .align KAIF_MSR_PATCHOFF; \
- KAIF_MSR_PATCH; \
- jmp kaif_cmnint; \
- SET_SIZE(kaif_invaltrap)
+ .align KDI_MSR_PATCHOFF; \
+ KDI_MSR_PATCH; \
+ jmp kdi_cmnint; \
+ SET_SIZE(kdi_invaltrap)
/*
* The handlers themselves
@@ -160,12 +145,12 @@ this won't assemble
MKTRAPERRHDLR(13)
MKTRAPERRHDLR(14)
- .globl kaif_ivct_size
-kaif_ivct_size:
- .NWORD [kaif_ivct33-kaif_ivct32]
+ .globl kdi_ivct_size
+kdi_ivct_size:
+ .NWORD [kdi_ivct33-kdi_ivct32]
/* 10 billion and one interrupt handlers */
-kaif_ivct_base:
+kdi_ivct_base:
MKIVCT(32); MKIVCT(33); MKIVCT(34); MKIVCT(35);
MKIVCT(36); MKIVCT(37); MKIVCT(38); MKIVCT(39);
MKIVCT(40); MKIVCT(41); MKIVCT(42); MKIVCT(43);
diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif_off.in b/usr/src/uts/intel/kdi/kdi_offsets.in
index ed1a65605b..80c0c24334 100644
--- a/usr/src/cmd/mdb/intel/kmdb/kaif_off.in
+++ b/usr/src/uts/intel/kdi/kdi_offsets.in
@@ -1,13 +1,12 @@
\
-\ Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+\ Copyright 2007 Sun Microsystems, Inc. All rights reserved.
\ Use is subject to license terms.
\
\ CDDL HEADER START
\
\ The contents of this file are subject to the terms of the
-\ Common Development and Distribution License, Version 1.0 only
-\ (the "License"). You may not use this file except in compliance
-\ with the License.
+\ Common Development and Distribution License (the "License").
+\ You may not use this file except in compliance with the License.
\
\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
\ or http://www.opensolaris.org/os/licensing.
@@ -26,46 +25,41 @@
\
\ CPU-save structure offsets for use in assembly code.
\
-\ Keep in sync with kaif_regs.h
+\ Keep in sync with kdi_state.h
\
#include <sys/cpuvar.h>
#include <sys/kdi_impl.h>
-#include <kmdb/kaif.h>
-#include <kmdb/kaif_regs.h>
-#include <mdb/mdb.h>
-
-kaif_memrange_t MR_SIZE
+kdi_memrange_t MR_SIZE
mr_base
mr_lim
-kaif_crumb_t KRM_SIZE
+kdi_crumb_t KRM_SIZE
krm_cpu_state
krm_pc
krm_sp
krm_trapno
krm_flag
-kaif_drreg_t
+kdi_drreg_t
dr_ctl
dr_stat
dr_addr
-kmdb_msr_t MSR_SIZE
+kdi_msr_t MSR_SIZE
msr_num
msr_type
_u._msr_valp MSR_VALP
_u._msr_val MSR_VAL
-kaif_cpusave_t KRS_SIZE
+kdi_cpusave_t KRS_SIZE
krs_gregs
krs_dr
krs_dr.dr_ctl KRS_DRCTL
krs_dr.dr_stat KRS_DRSTAT
- krs_gdtr
- krs_idtr
- krs_tmpdesc
+ krs_gdt
+ krs_idt
krs_cr0
krs_msr
krs_cpu_state
@@ -76,15 +70,7 @@ kaif_cpusave_t KRS_SIZE
cpu
cpu_id
-#if defined(__amd64)
-mdb_t
- m_kdi MDB_KDI
-
-kdi_t
- kdi_mach.mkdi_gdt2gsbase MKDI_GDT2GSBASE
-#endif
-
-kreg_t KREG_SIZE
+greg_t KREG_SIZE
#if defined(__amd64)
\#define REG_SHIFT 3
@@ -96,4 +82,4 @@ kreg_t KREG_SIZE
\#define DRADDR_OFF(num) _CONST(DRADDR_IDX(num) + DR_ADDR)
\#define KRS_DROFF(num) _CONST(DRADDR_OFF(num) + KRS_DR)
\#define REG_OFF(reg) _CONST(_CONST(reg) << REG_SHIFT)
-\#define KREG_OFF(reg) _CONST(_MUL(KREG_SIZE, reg) + KRS_GREGS)
+\#define KDIREG_OFF(reg) _CONST(_MUL(KREG_SIZE, reg) + KRS_GREGS)
diff --git a/usr/src/uts/i86pc/logi/Makefile b/usr/src/uts/intel/logi/Makefile
index cb9c34be1e..e50b94600f 100644
--- a/usr/src/uts/i86pc/logi/Makefile
+++ b/usr/src/uts/intel/logi/Makefile
@@ -19,9 +19,9 @@
# CDDL HEADER END
#
#
-# uts/i86pc/logi/Makefile
+# uts/intel/logi/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -29,7 +29,7 @@
# This makefile drives the production of the logi driver
# kernel module.
#
-# i86pc architecture dependent
+# intel architecture dependent
#
#
@@ -43,12 +43,12 @@ UTSBASE = ../..
MODULE = logi
OBJECTS = $(LOGI_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(LOGI_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -91,4 +91,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/mscsi/Makefile b/usr/src/uts/intel/mscsi/Makefile
index 04b976bb6b..312ae3a621 100644
--- a/usr/src/uts/i86pc/mscsi/Makefile
+++ b/usr/src/uts/intel/mscsi/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,9 +19,9 @@
# CDDL HEADER END
#
#
-# uts/i86pc/mscsi/Makefile
+# uts/intel/mscsi/Makefile
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -30,7 +29,7 @@
# This makefile drives the production of the mscsi
# bus nexus driver kernel module.
#
-# i86pc architecture dependent
+# intel architecture dependent
#
#
@@ -44,13 +43,13 @@ UTSBASE = ../..
MODULE = mscsi
OBJECTS = $(MSCSI_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(MSCSI_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/i86pc/io
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
+CONF_SRCDIR = $(UTSBASE)/intel/io
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -94,4 +93,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/msm/Makefile b/usr/src/uts/intel/msm/Makefile
index 0c00a0b06f..b02a39c5cb 100644
--- a/usr/src/uts/i86pc/msm/Makefile
+++ b/usr/src/uts/intel/msm/Makefile
@@ -19,9 +19,9 @@
# CDDL HEADER END
#
#
-# uts/i86pc/msmouse/Makefile
+# uts/intel/msmouse/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -29,7 +29,7 @@
# This makefile drives the production of the msmouse driver
# kernel module.
#
-# i86pc architecture dependent
+# intel architecture dependent
#
#
@@ -43,12 +43,12 @@ UTSBASE = ../..
MODULE = msm
OBJECTS = $(MSMOUSE_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(MSMOUSE_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -94,4 +94,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/intel/os/arch_kdi.c b/usr/src/uts/intel/os/arch_kdi.c
new file mode 100644
index 0000000000..abc2dfa599
--- /dev/null
+++ b/usr/src/uts/intel/os/arch_kdi.c
@@ -0,0 +1,169 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Kernel/Debugger Interface (KDI) routines. Called during debugger under
+ * various system states (boot, while running, while the debugger has control).
+ * Functions intended for use while the debugger has control may not grab any
+ * locks or perform any functions that assume the availability of other system
+ * services.
+ */
+
+#include <sys/systm.h>
+#include <sys/x86_archext.h>
+#include <sys/kdi_impl.h>
+#include <sys/smp_impldefs.h>
+#include <sys/psm_types.h>
+#include <sys/segments.h>
+#include <sys/archsystm.h>
+#include <sys/controlregs.h>
+#include <sys/trap.h>
+#include <sys/kobj.h>
+#include <sys/kobj_impl.h>
+
+static void
+kdi_system_claim(void)
+{
+ psm_notifyf(PSM_DEBUG_ENTER);
+}
+
+static void
+kdi_system_release(void)
+{
+ psm_notifyf(PSM_DEBUG_EXIT);
+}
+
+static cpu_t *
+kdi_gdt2cpu(uintptr_t gdtbase)
+{
+ cpu_t *cp = cpu_list;
+
+ if (cp == NULL)
+ return (NULL);
+
+ do {
+ if (gdtbase == (uintptr_t)cp->cpu_gdt)
+ return (cp);
+ } while ((cp = cp->cpu_next) != cpu_list);
+
+ return (NULL);
+}
+
+#if defined(__amd64)
+uintptr_t
+kdi_gdt2gsbase(uintptr_t gdtbase)
+{
+ return ((uintptr_t)kdi_gdt2cpu(gdtbase));
+}
+#endif
+
+static uintptr_t
+kdi_get_userlimit(void)
+{
+ return (_userlimit);
+}
+
+static int
+kdi_get_cpuinfo(uint_t *vendorp, uint_t *familyp, uint_t *modelp)
+{
+ desctbr_t gdtr;
+ cpu_t *cpu;
+
+ /*
+ * CPU doesn't work until the GDT and gs/GSBASE have been set up.
+ * Boot-loaded kmdb will call us well before then, so we have to
+ * find the current cpu_t the hard way.
+ */
+ rd_gdtr(&gdtr);
+ if ((cpu = kdi_gdt2cpu(gdtr.dtr_base)) == NULL ||
+ !cpuid_checkpass(cpu, 1))
+ return (EAGAIN); /* cpuid isn't done yet */
+
+ *vendorp = cpuid_getvendor(cpu);
+ *familyp = cpuid_getfamily(cpu);
+ *modelp = cpuid_getmodel(cpu);
+
+ return (0);
+}
+
+void
+kdi_idtr_set(gate_desc_t *idt, size_t limit)
+{
+ desctbr_t idtr;
+
+ /*
+ * This rare case could happen if we entered kmdb whilst still on the
+ * fake CPU set up by boot_kdi_tmpinit(). We're trying to restore the
+ * kernel's IDT that we saved on entry, but it was from the fake cpu_t
+ * rather than the real IDT (which is still boot's). It's unpleasant,
+ * but we just encode knowledge that it's idt0 we want to restore.
+ */
+ if (idt == NULL)
+ idt = idt0;
+
+ CPU->cpu_m.mcpu_idt = idt;
+ idtr.dtr_base = (uintptr_t)idt;
+ idtr.dtr_limit = limit;
+ kdi_idtr_write(&idtr);
+}
+
+static void
+kdi_plat_call(void (*platfn)(void))
+{
+ if (platfn != NULL)
+ platfn();
+}
+
+/*
+ * On Intel, most of these are shared between i86*, so this is really an
+ * arch_kdi_init().
+ */
+void
+mach_kdi_init(kdi_t *kdi)
+{
+ kdi->kdi_plat_call = kdi_plat_call;
+ kdi->kdi_kmdb_enter = kmdb_enter;
+ kdi->mkdi_activate = kdi_activate;
+ kdi->mkdi_deactivate = kdi_deactivate;
+ kdi->mkdi_idt_switch = kdi_idt_switch;
+ kdi->mkdi_update_drreg = kdi_update_drreg;
+ kdi->mkdi_set_debug_msrs = kdi_set_debug_msrs;
+ kdi->mkdi_get_userlimit = kdi_get_userlimit;
+ kdi->mkdi_get_cpuinfo = kdi_get_cpuinfo;
+ kdi->mkdi_stop_slaves = kdi_stop_slaves;
+ kdi->mkdi_start_slaves = kdi_start_slaves;
+ kdi->mkdi_slave_wait = kdi_slave_wait;
+ kdi->mkdi_memrange_add = kdi_memrange_add;
+ kdi->mkdi_reboot = kdi_reboot;
+}
+
+void
+plat_kdi_init(kdi_t *kdi)
+{
+ kdi->pkdi_system_claim = kdi_system_claim;
+ kdi->pkdi_system_release = kdi_system_release;
+}
diff --git a/usr/src/uts/i86pc/pci_autoconfig/Makefile b/usr/src/uts/intel/pci_autoconfig/Makefile
index 4c562f700b..d858a8bbfc 100644
--- a/usr/src/uts/i86pc/pci_autoconfig/Makefile
+++ b/usr/src/uts/intel/pci_autoconfig/Makefile
@@ -19,8 +19,8 @@
# CDDL HEADER END
#
#
-# uts/i86pc/pci_autoconfig/Makefile
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# uts/intel/pci_autoconfig/Makefile
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -28,7 +28,7 @@
# This makefile drives the production of the PCI autoconfiguration
# kernel module.
#
-# i86pc platform dependent
+# intel platform dependent
#
#
@@ -44,12 +44,13 @@ OBJECTS = $(PCI_AUTOCONFIG_OBJS:%=$(OBJS_DIR)/%) \
$(PCI_STRING_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(PCI_AUTOCONFIG_OBJS:%.o=$(LINTS_DIR)/%.ln) \
$(PCI_STRING_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_MISC_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_MISC_DIR)/$(MODULE)
+INC_PATH += -I$(UTSBASE)/i86pc
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -95,4 +96,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/pci_pci/Makefile b/usr/src/uts/intel/pci_pci/Makefile
index b5e3779ed3..b278711141 100644
--- a/usr/src/uts/i86pc/pci_pci/Makefile
+++ b/usr/src/uts/intel/pci_pci/Makefile
@@ -19,9 +19,9 @@
# CDDL HEADER END
#
#
-# uts/i86pc/pci_pci/Makefile
+# uts/intel/pci_pci/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -40,14 +40,14 @@ UTSBASE = ../..
MODULE = pci_pci
OBJECTS = $(PCI_PCINEXUS_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(PCI_PCINEXUS_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
-INC_PATH += -I../../i86pc
+INC_PATH += -I$(UTSBASE)/i86pc
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -91,4 +91,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/pcic/Makefile b/usr/src/uts/intel/pcic/Makefile
index d910a5860c..4c917534ec 100644
--- a/usr/src/uts/i86pc/pcic/Makefile
+++ b/usr/src/uts/intel/pcic/Makefile
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -29,7 +29,7 @@
# This makefile drives the PCIC style PCMCIA adapter
# It is mostly a standard driver
#
-# i86pc architecture dependent
+# intel architecture dependent
#
#
@@ -49,7 +49,7 @@ CONF_SRCDIR = $(UTSBASE)/common/io
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -98,4 +98,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/pcie_pci/Makefile b/usr/src/uts/intel/pcie_pci/Makefile
index 1a7bcef5b9..51a4ba8a6d 100644
--- a/usr/src/uts/i86pc/pcie_pci/Makefile
+++ b/usr/src/uts/intel/pcie_pci/Makefile
@@ -19,9 +19,9 @@
# CDDL HEADER END
#
#
-# uts/i86pc/pcie_pci/Makefile
+# uts/intel/pcie_pci/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -41,13 +41,13 @@ UTSBASE = ../..
MODULE = pcie_pci
OBJECTS = $(PCI_E_PCINEXUS_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(PCI_E_PCINEXUS_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/i86pc/io/pciex
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
+CONF_SRCDIR = $(UTSBASE)/intel/io/pciex
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -106,5 +106,5 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/pciehpc/Makefile b/usr/src/uts/intel/pciehpc/Makefile
index c1515fca13..c457d0cfd1 100644
--- a/usr/src/uts/i86pc/pciehpc/Makefile
+++ b/usr/src/uts/intel/pciehpc/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -27,7 +27,7 @@
# This makefile drives the production of the kernel/misc/pciehpc module
# for PCI-E hotplug controller support in PCI-E nexus drivers.
#
-# i86pc implementation architecture dependent
+# intel architecture dependent
#
#
@@ -41,12 +41,12 @@ UTSBASE = ../..
MODULE = pciehpc
OBJECTS = $(PCIEHPCNEXUS_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(PCIEHPCNEXUS_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_MISC_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_MISC_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -101,4 +101,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/power/Makefile b/usr/src/uts/intel/power/Makefile
index e058e6d525..a61c18049a 100644
--- a/usr/src/uts/i86pc/power/Makefile
+++ b/usr/src/uts/intel/power/Makefile
@@ -19,15 +19,15 @@
# CDDL HEADER END
#
#
-# uts/i86pc/power/Makefile
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# uts/intel/power/Makefile
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
#
# This makefile drives the production of the power driver
#
-# sun4u implementation architecture dependent
+# intel architecture dependent
#
#
@@ -41,13 +41,13 @@ UTSBASE = ../..
MODULE = power
OBJECTS = $(POWER_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(POWER_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
CONF_SRCDIR = $(UTSBASE)/common/io
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -101,4 +101,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/intel/swrand/Makefile b/usr/src/uts/intel/swrand/Makefile
index 80a04fd6cb..05b1533808 100644
--- a/usr/src/uts/intel/swrand/Makefile
+++ b/usr/src/uts/intel/swrand/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -41,6 +41,7 @@ MODULE = swrand
OBJECTS = $(SWRANDPROV_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(SWRANDPROV_OBJS:%.o=$(LINTS_DIR)/%.ln)
ROOTMODULE = $(ROOT_CRYPTO_DIR)/$(MODULE)
+INC_PATH += -I../../i86pc
#
# Include common rules.
diff --git a/usr/src/uts/intel/sys/Makefile b/usr/src/uts/intel/sys/Makefile
index 491f4d3224..655ec9b54f 100644
--- a/usr/src/uts/intel/sys/Makefile
+++ b/usr/src/uts/intel/sys/Makefile
@@ -46,10 +46,10 @@ HDRS = \
fasttrap_isa.h \
fp.h \
frame.h \
- immu.h \
inline.h \
kd.h \
kdi_machimpl.h \
+ kdi_regs.h \
machelf.h \
machlock.h \
machsig.h \
@@ -61,11 +61,11 @@ HDRS = \
memtest.h \
mii.h \
miipriv.h \
- mmu.h \
mutex_impl.h \
obpdefs.h \
old_procfs.h \
pcb.h \
+ pmem.h \
privregs.h \
procfs_isa.h \
prom_emul.h \
diff --git a/usr/src/uts/intel/sys/archsystm.h b/usr/src/uts/intel/sys/archsystm.h
index 1eed79d0ae..f6665f6565 100644
--- a/usr/src/uts/intel/sys/archsystm.h
+++ b/usr/src/uts/intel/sys/archsystm.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -51,14 +51,22 @@ extern ulong_t getcr2(void);
#if defined(__i386)
extern uint16_t getgs(void);
extern void setgs(uint16_t);
+
+extern void patch_sse(void);
+extern void patch_sse2(void);
#endif
+extern void cli(void);
extern void sti(void);
extern void tenmicrosec(void);
-extern void restore_int_flag(int);
-extern int clear_int_flag(void);
+extern void restore_int_flag(ulong_t);
+extern void intr_restore(ulong_t);
+extern ulong_t clear_int_flag(void);
+extern ulong_t intr_clear(void);
+extern ulong_t getflags(void);
+extern int interrupts_enabled(void);
extern void int3(void);
extern void int18(void);
@@ -72,6 +80,7 @@ extern void sys_syscall_int();
extern void brand_sys_syscall();
extern void brand_sys_syscall32();
extern void brand_sys_syscall_int();
+extern int update_sregs();
#elif defined(__i386)
extern void sys_call();
extern void brand_sys_call();
@@ -85,10 +94,8 @@ extern void dosyscall(void);
extern void bind_hwcap(void);
-extern uint8_t inb(int port);
extern uint16_t inw(int port);
extern uint32_t inl(int port);
-extern void outb(int port, uint8_t value);
extern void outw(int port, uint16_t value);
extern void outl(int port, uint32_t value);
@@ -134,34 +141,52 @@ extern uint_t cpu_hwcap_flags;
extern uint_t cpu_freq;
extern uint64_t cpu_freq_hz;
+extern int use_sse_pagecopy;
+extern int use_sse_pagezero;
+extern int use_sse_copy;
+
extern caddr_t i86devmap(pfn_t, pgcnt_t, uint_t);
extern page_t *page_numtopp_alloc(pfn_t pfnum);
extern void hwblkclr(void *, size_t);
extern void hwblkpagecopy(const void *, void *);
+extern void page_copy_no_xmm(void *dst, void *src);
+extern void block_zero_no_xmm(void *dst, int len);
+#define BLOCKZEROALIGN (4 * sizeof (void *))
extern void (*kcpc_hw_enable_cpc_intr)(void);
-extern void setup_mca(void);
-extern void setup_mtrr(void);
extern void patch_tsc(void);
+extern void init_desctbls(void);
extern user_desc_t *cpu_get_gdt(void);
-/*
- * Warning: these routines do -not- use normal calling conventions!
- */
-extern void setup_121_andcall(void (*)(ulong_t), ulong_t);
-extern void enable_big_page_support(ulong_t);
-extern void enable_pae(ulong_t);
-
+extern void switch_sp_and_call(void *, void (*)(uint_t, uint_t), uint_t,
+ uint_t);
extern hrtime_t (*gethrtimef)(void);
extern hrtime_t (*gethrtimeunscaledf)(void);
extern void (*scalehrtimef)(hrtime_t *);
extern void (*gethrestimef)(timestruc_t *);
+extern void av_dispatch_softvect(uint_t);
+extern void av_dispatch_autovect(uint_t);
+extern uint_t atomic_btr32(uint32_t *, uint_t);
+extern uint_t bsrw_insn(uint16_t);
+extern int sys_rtt_common(struct regs *);
+extern void fakesoftint(void);
+
+
+extern void setup_mca(void);
+extern void setup_mtrr(void);
+#define cpr_dprintf prom_printf
+
#endif /* _KERNEL */
+#if defined(_KERNEL) || defined(_BOOT)
+extern uint8_t inb(int port);
+extern void outb(int port, uint8_t value);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/intel/sys/bootconf.h b/usr/src/uts/intel/sys/bootconf.h
index 2e1ccbf326..0cde010b88 100644
--- a/usr/src/uts/intel/sys/bootconf.h
+++ b/usr/src/uts/intel/sys/bootconf.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -219,11 +219,29 @@ extern int netboot;
extern int swaploaded;
extern int modrootloaded;
extern char kern_bootargs[];
+extern char *kobj_module_path;
extern char *default_path;
extern char *dhcack;
extern int dhcacklen;
extern char *netdev_path;
+extern void bop_no_more_mem(void);
+
+/*PRINTFLIKE2*/
+extern void bop_printf(struct bootops *, char *, ...)
+ __KPRINTFLIKE(2);
+/*PRINTFLIKE1*/
+extern void bop_panic(char *, ...)
+ __KPRINTFLIKE(1);
+extern void boot_prop_finish(void);
+
+/*
+ * Back door to fakebop.c to get physical memory allocated.
+ * 64 bit data types are fixed for 32 bit PAE use.
+ */
+extern paddr_t do_bop_phys_alloc(uint64_t, uint64_t);
+
+
#endif /* _KERNEL && !_BOOT */
#ifdef __cplusplus
diff --git a/usr/src/uts/intel/sys/bootinfo.h b/usr/src/uts/intel/sys/bootinfo.h
new file mode 100644
index 0000000000..6c25d8bcab
--- /dev/null
+++ b/usr/src/uts/intel/sys/bootinfo.h
@@ -0,0 +1,99 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_BOOTINFO_H
+#define _SYS_BOOTINFO_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The 32-bit kernel loader code needs to build several structures that the
+ * kernel is expecting. They will contain native sized pointers for the
+ * target kernel.
+ */
+
+#if defined(_BOOT_TARGET_amd64)
+
+typedef uint64_t native_ptr_t;
+
+#elif defined(_BOOT_TARGET_i386)
+
+typedef uint32_t native_ptr_t;
+
+#elif defined(_KERNEL)
+
+typedef void *native_ptr_t;
+
+#endif
+
+struct boot_memlist {
+ uint64_t addr;
+ uint64_t size;
+ native_ptr_t next;
+ native_ptr_t prev;
+};
+
+/*
+ * The kernel needs to know how to find its modules.
+ */
+struct boot_modules {
+ native_ptr_t bm_addr;
+ uint32_t bm_size;
+ uint32_t bm_padding;
+};
+
+/*
+ *
+ */
+#pragma pack(1)
+struct xboot_info {
+ uint64_t bi_next_paddr; /* next physical address not used */
+ native_ptr_t bi_next_vaddr; /* next virtual address not used */
+ native_ptr_t bi_cmdline;
+ native_ptr_t bi_phys_install;
+ native_ptr_t bi_modules;
+ uint32_t bi_module_cnt;
+ uint32_t bi_use_largepage; /* MMU uses large pages */
+ uint32_t bi_use_pae; /* MMU uses PAE mode (8 byte PTES) */
+ uint32_t bi_use_nx; /* MMU uses NX bit in PTEs */
+ uint32_t bi_use_pge; /* MMU uses Page Global Enable */
+ native_ptr_t bi_pt_window;
+ native_ptr_t bi_pte_to_pt_window;
+ native_ptr_t bi_kseg_size; /* size used for kernel nucleus pages */
+ uint64_t bi_top_page_table;
+ native_ptr_t bi_mb_info;
+};
+#pragma pack()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_BOOTINFO_H */
diff --git a/usr/src/uts/intel/sys/controlregs.h b/usr/src/uts/intel/sys/controlregs.h
index cea4e712d9..385a89fe07 100644
--- a/usr/src/uts/intel/sys/controlregs.h
+++ b/usr/src/uts/intel/sys/controlregs.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -66,6 +66,26 @@ extern "C" {
#define FMT_CR0 \
"\20\40pg\37cd\36nw\35am\21wp\6ne\5et\4ts\3em\2mp\1pe"
+/*
+ * Set the FPU-related control bits to explain to the processor that
+ * we're managing FPU state:
+ * - set monitor coprocessor (allow TS bit to control FPU)
+ * - set numeric exception (disable IGNNE# mechanism)
+ * - set task switch (#nm on first fp instruction)
+ * - clear emulate math bit (cause we're not emulating!)
+ */
+#define CR0_ENABLE_FPU_FLAGS(cr) \
+ (((cr) | CR0_MP | CR0_NE | CR0_TS) & (uint32_t)~CR0_EM)
+
+/*
+ * Set the FPU-related control bits to explain to the processor that
+ * we're -not- managing FPU state:
+ * - set emulate (all fp instructions cause #nm)
+ * - clear monitor coprocessor (so fwait/wait doesn't #nm)
+ */
+#define CR0_DISABLE_FPU_FLAGS(cr) \
+ (((cr) | CR0_EM) & (uint32_t)~CR0_MP)
+
/* CR3 Register */
#define CR3_PCD 0x00000010 /* cache disable */
@@ -86,9 +106,28 @@ extern "C" {
#define CR4_PCE 0x0100 /* perf-monitoring counter enable */
#define CR4_OSFXSR 0x0200 /* OS fxsave/fxrstor support */
#define CR4_OSXMMEXCPT 0x0400 /* OS unmasked exception support */
+ /* 0x0800 reserved */
+ /* 0x1000 reserved */
+#define CR4_VMXE 0x2000
+#define CR4_SMXE 0x4000
-#define FMT_CR4 \
- "\20\13xmme\12fxsr\11pce\10pge\7mce\6pae\5pse\4de\3tsd\2pvi\1vme"
+#define FMT_CR4 \
+ "\20\17smxe\16vmxe\13xmme\12fxsr\11pce\10pge" \
+ "\7mce\6pae\5pse\4de\3tsd\2pvi\1vme"
+
+/*
+ * Enable the SSE-related control bits to explain to the processor that
+ * we're managing XMM state and exceptions
+ */
+#define CR4_ENABLE_SSE_FLAGS(cr) \
+ ((cr) | CR4_OSFXSR | CR4_OSXMMEXCPT)
+
+/*
+ * Disable the SSE-related control bits to explain to the processor
+ * that we're NOT managing XMM state
+ */
+#define CR4_DISABLE_SSE_FLAGS(cr) \
+ ((cr) & ~(uint32_t)(CR4_OSFXSR | CR4_OSXMMEXCPT))
/* Intel's SYSENTER configuration registers */
@@ -100,13 +139,15 @@ extern "C" {
#define MSR_AMD_EFER 0xc0000080 /* extended feature enable MSR */
-#define AMD_EFER_NXE 0x800 /* no-execute enable */
-#define AMD_EFER_LMA 0x400 /* long mode active (read-only) */
-#define AMD_EFER_LME 0x100 /* long mode enable */
-#define AMD_EFER_SCE 0x001 /* system call extensions */
+#define AMD_EFER_FFXSR 0x4000 /* fast fxsave/fxrstor */
+#define AMD_EFER_SVME 0x1000 /* svm enable */
+#define AMD_EFER_NXE 0x0800 /* no-execute enable */
+#define AMD_EFER_LMA 0x0400 /* long mode active (read-only) */
+#define AMD_EFER_LME 0x0100 /* long mode enable */
+#define AMD_EFER_SCE 0x0001 /* system call extensions */
#define FMT_AMD_EFER \
- "\20\14nxe\13lma\11lme\1sce"
+ "\20\17ffxsr\15svme\14nxe\13lma\11lme\1sce"
/* AMD's SYSCFG register */
@@ -132,6 +173,7 @@ extern "C" {
#define MSR_AMD_FSBASE 0xc0000100 /* 64-bit base address for %fs */
#define MSR_AMD_GSBASE 0xc0000101 /* 64-bit base address for %gs */
#define MSR_AMD_KGSBASE 0xc0000102 /* swapgs swaps this with gsbase */
+#define MSR_AMD_TSCAUX 0xc0000103 /* %ecx value on rdtscp insn */
/* AMD's configuration MSRs, weakly documented in the revision guide */
diff --git a/usr/src/uts/intel/sys/fp.h b/usr/src/uts/intel/sys/fp.h
index 133499a3ae..02fb34fc65 100644
--- a/usr/src/uts/intel/sys/fp.h
+++ b/usr/src/uts/intel/sys/fp.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -97,7 +96,7 @@ extern "C" {
*/
#define FPS_IE 0x00000001 /* invalid operation */
#define FPS_DE 0x00000002 /* denormalized operand */
-#define FPS_ZE 0x00000004 /* zero devide */
+#define FPS_ZE 0x00000004 /* zero divide */
#define FPS_OE 0x00000008 /* overflow */
#define FPS_UE 0x00000010 /* underflow */
#define FPS_PE 0x00000020 /* precision */
@@ -164,14 +163,22 @@ extern int fpu_exists; /* FPU hw exists */
#ifdef _KERNEL
+extern int fpu_ignored;
+extern int fpu_pentium_fdivbug;
+
extern uint32_t sse_mxcsr_mask;
extern void fpu_probe(void);
+extern uint_t fpu_initial_probe(void);
+extern int fpu_probe_pentium_fdivbug(void);
-extern void fpnsave_begin(void *);
-extern void fpxsave_begin(void *);
-extern void (*fpsave_begin)(void *);
+extern void fpnsave_ctxt(void *);
+extern void fpxsave_ctxt(void *);
+extern void (*fpsave_ctxt)(void *);
+struct fnsave_state;
+struct fxsave_state;
+extern void fxsave_insn(struct fxsave_state *);
extern void fpsave(struct fnsave_state *);
extern void fprestore(struct fnsave_state *);
extern void fpxsave(struct fxsave_state *);
diff --git a/usr/src/uts/intel/sys/kdi_machimpl.h b/usr/src/uts/intel/sys/kdi_machimpl.h
index f34501385d..5ded8b44c2 100644
--- a/usr/src/uts/intel/sys/kdi_machimpl.h
+++ b/usr/src/uts/intel/sys/kdi_machimpl.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,61 +34,89 @@
* and are to be used only when the system has been stopped.
*/
-/* The VA range reserved for the debugger. */
-
#include <sys/modctl.h>
#include <sys/types.h>
+#include <sys/cpuvar.h>
+#include <sys/kdi_regs.h>
#ifdef __cplusplus
extern "C" {
#endif
+typedef void (*kdi_main_t)(kdi_cpusave_t *);
+
+typedef struct kdi_memrange {
+ caddr_t mr_base;
+ caddr_t mr_lim;
+} kdi_memrange_t;
+
+#define KDI_MEMRANGES_MAX 2
+
typedef struct kdi_mach {
- int (*mkdi_get_cpuinfo)(uint_t *, uint_t *, uint_t *);
+ void (*mkdi_activate)(kdi_main_t, kdi_cpusave_t *, uint_t);
+ void (*mkdi_deactivate)(void);
+
+ void (*mkdi_idt_switch)(kdi_cpusave_t *);
- int (*mkdi_xc_initialized)(void);
- void (*mkdi_xc_others)(int, void (*)());
+ void (*mkdi_update_drreg)(kdi_drreg_t *);
+ void (*mkdi_set_debug_msrs)(kdi_msr_t *);
uintptr_t (*mkdi_get_userlimit)(void);
- void (*mkdi_idt_init_gate)(struct gate_desc *, void (*)(void), uint_t,
- int);
- void (*mkdi_idt_read)(struct gate_desc *, struct gate_desc *, uint_t);
- void (*mkdi_idt_write)(struct gate_desc *, struct gate_desc *, uint_t);
- struct gate_desc *(*mkdi_cpu2idt)(struct cpu *);
+ int (*mkdi_get_cpuinfo)(uint_t *, uint_t *, uint_t *);
+
+ void (*mkdi_stop_slaves)(int, int);
- void (**mkdi_shutdownp)(int, int);
+ void (*mkdi_start_slaves)(void);
-#if defined(__amd64)
- uintptr_t (*mkdi_gdt2gsbase)(uintptr_t);
-#endif
+ void (*mkdi_slave_wait)(void);
- /* for use only when the kernel is running */
- void (*mkdi_cpu_iter)(void (*)(struct cpu *, uint_t),
- uint_t);
+ void (*mkdi_memrange_add)(caddr_t, size_t);
+
+ void (*mkdi_reboot)(void);
} kdi_mach_t;
-#define mkdi_get_cpuinfo kdi_mach.mkdi_get_cpuinfo
-#define mkdi_xc_initialized kdi_mach.mkdi_xc_initialized
-#define mkdi_xc_others kdi_mach.mkdi_xc_others
+#define mkdi_activate kdi_mach.mkdi_activate
+#define mkdi_deactivate kdi_mach.mkdi_deactivate
+#define mkdi_idt_switch kdi_mach.mkdi_idt_switch
+#define mkdi_update_drreg kdi_mach.mkdi_update_drreg
+#define mkdi_set_debug_msrs kdi_mach.mkdi_set_debug_msrs
#define mkdi_get_userlimit kdi_mach.mkdi_get_userlimit
-#define mkdi_idt_init_gate kdi_mach.mkdi_idt_init_gate
-#define mkdi_idt_read kdi_mach.mkdi_idt_read
-#define mkdi_idt_write kdi_mach.mkdi_idt_write
-#define mkdi_cpu2idt kdi_mach.mkdi_cpu2idt
-#define mkdi_shutdownp kdi_mach.mkdi_shutdownp
-#if defined(__amd64)
-#define mkdi_gdt2gsbase kdi_mach.mkdi_gdt2gsbase
-#endif
-#define mkdi_cpu_iter kdi_mach.mkdi_cpu_iter
-
-extern int kdi_xc_initialized(void);
-extern void kdi_xc_others(int, void (*)());
+#define mkdi_get_cpuinfo kdi_mach.mkdi_get_cpuinfo
+#define mkdi_stop_slaves kdi_mach.mkdi_stop_slaves
+#define mkdi_start_slaves kdi_mach.mkdi_start_slaves
+#define mkdi_slave_wait kdi_mach.mkdi_slave_wait
+#define mkdi_memrange_add kdi_mach.mkdi_memrange_add
+#define mkdi_reboot kdi_mach.mkdi_reboot
extern void hat_kdi_init(void);
-extern void hat_kdi_fini(void);
-extern uintptr_t kdi_get_userlimit(void);
+extern ulong_t kdi_getdr0(void), kdi_getdr1(void), kdi_getdr2(void);
+extern ulong_t kdi_getdr3(void), kdi_getdr6(void), kdi_getdr7(void);
+extern void kdi_setdr0(ulong_t), kdi_setdr1(ulong_t), kdi_setdr2(ulong_t);
+extern void kdi_setdr3(ulong_t), kdi_setdr6(ulong_t), kdi_setdr7(ulong_t);
+extern ulong_t kdi_dreg_get(int);
+extern void kdi_dreg_set(int, ulong_t);
+extern void kdi_update_drreg(kdi_drreg_t *);
+extern void kdi_set_debug_msrs(kdi_msr_t *);
+extern void kdi_cpu_debug_init(kdi_cpusave_t *);
+
+extern void kdi_cpu_init(void);
+extern void kdi_xc_others(int, void (*)(void));
+extern void kdi_start_slaves(void);
+extern void kdi_slave_wait(void);
+
+extern void kdi_idtr_set(gate_desc_t *, size_t);
+extern void kdi_idt_write(struct gate_desc *, uint_t);
+extern void kdi_idt_sync(void);
+extern void kdi_idt_switch(kdi_cpusave_t *);
+#define kdi_idtr_write(idtr) wr_idtr(idtr)
+
+extern void kdi_activate(kdi_main_t, kdi_cpusave_t *, uint_t);
+extern void kdi_deactivate(void);
+extern void kdi_stop_slaves(int, int);
+extern void kdi_memrange_add(caddr_t, size_t);
+extern void kdi_reboot(void);
#ifdef __cplusplus
}
diff --git a/usr/src/uts/intel/sys/kdi_regs.h b/usr/src/uts/intel/sys/kdi_regs.h
new file mode 100644
index 0000000000..e896e29a64
--- /dev/null
+++ b/usr/src/uts/intel/sys/kdi_regs.h
@@ -0,0 +1,135 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_KDI_REGS_H
+#define _SYS_KDI_REGS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef _ASM
+#include <sys/types.h>
+#include <sys/segments.h>
+#include <sys/regset.h>
+#include <sys/privregs.h>
+#endif
+
+#if defined(__amd64)
+#include <amd64/sys/kdi_regs.h>
+#elif defined(__i386)
+#include <ia32/sys/kdi_regs.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define KDI_NCRUMBS 5
+
+#define KDI_RESUME 0
+#define KDI_RESUME_PASS_TO_KERNEL 1
+
+#define KDI_CPU_STATE_NONE 0
+#define KDI_CPU_STATE_MASTER 1
+#define KDI_CPU_STATE_SLAVE 2
+
+#define KDIREG_DRCTL_WPALLEN_MASK 0x000000ff
+#define KDIREG_DRSTAT_RESERVED 0xffff0ff0
+#define KDIREG_DRCTL_RESERVED 0x00000700
+
+#define KDI_MSR_READ 0x1 /* read during entry (unlimited) */
+#define KDI_MSR_WRITE 0x2 /* write during exit (unlimited) */
+#define KDI_MSR_WRITEDELAY 0x4 /* write after last branch (<= 1) */
+#define KDI_MSR_CLEARENTRY 0x3 /* clear before 1st branch (<= 1) */
+
+#ifndef _ASM
+
+/*
+ * We maintain a ring buffer of bread crumbs for debugging purposes. The
+ * current buffer pointer is advanced along the ring with each intercepted
+ * trap (debugger entry, invalid memory access, fault during step, etc).
+ */
+typedef struct kdi_crumb {
+ greg_t krm_cpu_state; /* This CPU's state at last entry */
+ greg_t krm_pc; /* Instruction pointer at trap */
+ greg_t krm_sp; /* Stack pointer at trap */
+ greg_t krm_trapno; /* The last trap number */
+ greg_t krm_flag; /* KAIF_CRUMB_F_* */
+} kdi_crumb_t;
+
+#define KDI_MAXWPIDX 3
+
+/*
+ * Storage for %dr0-3, %dr6, and %dr7.
+ */
+typedef struct kdi_drreg {
+ greg_t dr_ctl;
+ greg_t dr_stat;
+ greg_t dr_addr[KDI_MAXWPIDX + 1];
+} kdi_drreg_t;
+
+typedef struct kdi_msr {
+ uint_t msr_num;
+ uint_t msr_type;
+ union {
+ uint64_t *_msr_valp;
+ uint64_t _msr_val;
+ } _u;
+} kdi_msr_t;
+
+#define kdi_msr_val _u._msr_val
+#define kdi_msr_valp _u._msr_valp
+
+/*
+ * Data structure used to hold all of the state for a given CPU.
+ */
+typedef struct kdi_cpusave {
+ greg_t *krs_gregs; /* saved registers */
+
+ kdi_drreg_t krs_dr; /* saved debug registers */
+
+ user_desc_t *krs_gdt; /* GDT address */
+ gate_desc_t *krs_idt; /* IDT address */
+
+ greg_t krs_cr0; /* saved %cr0 */
+
+ kdi_msr_t *krs_msr; /* ptr to MSR save area */
+
+ uint_t krs_cpu_state; /* KDI_CPU_STATE_* mstr/slv */
+ uint_t krs_cpu_flushed; /* Have caches been flushed? */
+ uint_t krs_cpu_id; /* this CPU's ID */
+
+ /* Bread crumb ring buffer */
+ ulong_t krs_curcrumbidx; /* Current krs_crumbs idx */
+ kdi_crumb_t *krs_curcrumb; /* Pointer to current crumb */
+ kdi_crumb_t krs_crumbs[KDI_NCRUMBS]; /* Crumbs */
+} kdi_cpusave_t;
+
+#endif /* !_ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_KDI_REGS_H */
diff --git a/usr/src/uts/i86pc/sys/pmem.h b/usr/src/uts/intel/sys/pmem.h
index 068ea349b2..068ea349b2 100644
--- a/usr/src/uts/i86pc/sys/pmem.h
+++ b/usr/src/uts/intel/sys/pmem.h
diff --git a/usr/src/uts/intel/sys/segments.h b/usr/src/uts/intel/sys/segments.h
index fe65db8575..b15131279f 100644
--- a/usr/src/uts/intel/sys/segments.h
+++ b/usr/src/uts/intel/sys/segments.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -80,7 +80,7 @@ extern "C" {
#endif
#define SELTOIDX(s) ((s) >> 3) /* selector to index */
-#define SEL_KPL 0 /* kernel priority level */
+#define SEL_KPL 0 /* kernel privilege level */
#define SEL_UPL 3 /* user priority level */
#define SEL_TI_LDT 4 /* local descriptor table */
#define SEL_LDT(s) (IDXTOSEL(s) | SEL_TI_LDT | SEL_UPL) /* local sel */
@@ -126,10 +126,28 @@ extern void wr_gdtr(desctbr_t *);
extern void wr_ldtr(selector_t);
extern selector_t rd_ldtr(void);
extern void wr_tsr(selector_t);
+extern void kmdb_enter(void);
#if defined(__amd64)
extern void clr_ldt_sregs(void);
-#endif
+
+/*
+ * inlines for update_segregs
+ */
+extern void __set_ds(selector_t);
+extern void __set_es(selector_t);
+extern void __set_fs(selector_t);
+extern void __set_gs(selector_t);
+extern void __swapgs(void);
+#endif /* __amd64 */
+
+#if defined(__amd64)
+extern void load_segment_registers(selector_t, selector_t, selector_t,
+ selector_t); /* (alphabetical) */
+#elif defined(__i386)
+extern void load_segment_registers(selector_t, selector_t, selector_t,
+ selector_t, selector_t, selector_t); /* (alphabetical) */
+#endif /* __i386 */
#if !defined(__amd64)
@@ -329,20 +347,21 @@ typedef struct gate_desc {
extern void set_usegd(user_desc_t *, uint_t, void *, size_t, uint_t, uint_t,
uint_t, uint_t);
-extern void set_gatesegd(gate_desc_t *, void (*)(void), selector_t, uint_t,
- uint_t, uint_t);
#elif defined(__i386)
extern void set_usegd(user_desc_t *, void *, size_t, uint_t, uint_t,
uint_t, uint_t);
-extern void set_gatesegd(gate_desc_t *, void (*)(void), selector_t,
- uint_t, uint_t, uint_t);
#endif /* __i386 */
+extern void set_gatesegd(gate_desc_t *, void (*)(void), selector_t,
+ uint_t, uint_t);
+
void set_syssegd(system_desc_t *, void *, size_t, uint_t, uint_t);
+void init_boot_gdt(user_desc_t *);
+
#endif /* _ASM */
/*
@@ -433,26 +452,31 @@ void set_syssegd(system_desc_t *, void *, size_t, uint_t, uint_t);
* in long mode system segment decriptors expand to 128 bits.
*
* GDT_LWPFS and GDT_LWPGS must be the same for both 32 and 64-bit
- * kernels. See setup_context in libc.
+ * kernels. See setup_context in libc. 64-bit processes must set
+ * %fs or %gs to null selector to use 64-bit fsbase or gsbase
+ * respectively.
*/
+#define GDT_NULL 0 /* null */
+#define GDT_B32DATA 1 /* dboot 32 bit data descriptor */
+#define GDT_B32CODE 2 /* dboot 32 bit code descriptor */
+#define GDT_B16CODE 3 /* bios call 16 bit code descriptor */
+#define GDT_B16DATA 4 /* bios call 16 bit data descriptor */
+#define GDT_B64CODE 5 /* dboot 64 bit code descriptor */
+#define GDT_BGSTMP 7 /* kmdb descriptor only used early in boot */
+
#if defined(__amd64)
-#define GDT_NULL 0 /* null */
-#define GDT_B32DATA 1 /* copied from boot */
-#define GDT_B32CODE 2 /* copied from boot */
-#define GDT_B64DATA 3 /* copied from boot */
-#define GDT_B64CODE 4 /* copied from boot */
-#define GDT_KCODE 5 /* kernel code seg %cs */
-#define GDT_KDATA 6 /* kernel data seg %ds */
-#define GDT_U32CODE 7 /* 32-bit process on 64-bit kernel %cs */
-#define GDT_UDATA 8 /* user data seg %ds (32 and 64 bit) */
-#define GDT_UCODE 9 /* native user code seg %cs */
-#define GDT_LDT 10 /* LDT for current process */
-#define GDT_KTSS 12 /* kernel tss */
+#define GDT_KCODE 6 /* kernel code seg %cs */
+#define GDT_KDATA 7 /* kernel data seg %ds */
+#define GDT_U32CODE 8 /* 32-bit process on 64-bit kernel %cs */
+#define GDT_UDATA 9 /* user data seg %ds (32 and 64 bit) */
+#define GDT_UCODE 10 /* native user code seg %cs */
+#define GDT_LDT 12 /* LDT for current process */
+#define GDT_KTSS 14 /* kernel tss */
#define GDT_FS GDT_NULL /* kernel %fs segment selector */
#define GDT_GS GDT_NULL /* kernel %gs segment selector */
-#define GDT_LWPFS 55 /* lwp private %fs segment selector */
-#define GDT_LWPGS 56 /* lwp private %gs segment selector */
+#define GDT_LWPFS 55 /* lwp private %fs segment selector (32-bit) */
+#define GDT_LWPGS 56 /* lwp private %gs segment selector (32-bit) */
#define GDT_BRANDMIN 57 /* first entry in GDT for brand usage */
#define GDT_BRANDMAX 61 /* last entry in GDT for brand usage */
#define NGDT 62 /* number of entries in GDT */
@@ -465,11 +489,6 @@ void set_syssegd(system_desc_t *, void *, size_t, uint_t, uint_t);
#elif defined(__i386)
-#define GDT_NULL 0 /* null */
-#define GDT_BOOTFLAT 1 /* copied from boot */
-#define GDT_BOOTCODE 2 /* copied from boot */
-#define GDT_BOOTCODE16 3 /* copied from boot */
-#define GDT_BOOTDATA 4 /* copied from boot */
#define GDT_LDT 40 /* LDT for current process */
#define GDT_KTSS 42 /* kernel tss */
#define GDT_KCODE 43 /* kernel code seg %cs */
@@ -501,17 +520,32 @@ void set_syssegd(system_desc_t *, void *, size_t, uint_t, uint_t);
#define ULDT_SEL SEL_GDT(GDT_LDT, SEL_KPL)
#define KTSS_SEL SEL_GDT(GDT_KTSS, SEL_KPL)
#define DFTSS_SEL SEL_GDT(GDT_DBFLT, SEL_KPL)
-#define KFS_SEL SEL_GDT(GDT_NULL, SEL_KPL)
+#define KFS_SEL 0
#define KGS_SEL SEL_GDT(GDT_GS, SEL_KPL)
#define LWPFS_SEL SEL_GDT(GDT_LWPFS, SEL_UPL)
#define LWPGS_SEL SEL_GDT(GDT_LWPGS, SEL_UPL)
#define BRANDMIN_SEL SEL_GDT(GDT_BRANDMIN, SEL_UPL)
#define BRANDMAX_SEL SEL_GDT(GDT_BRANDMAX, SEL_UPL)
-#if defined(__amd64)
+
#define B64CODE_SEL SEL_GDT(GDT_B64CODE, SEL_KPL)
+#define B32CODE_SEL SEL_GDT(GDT_B32CODE, SEL_KPL)
+#define B32DATA_SEL SEL_GDT(GDT_B32DATA, SEL_KPL)
+#define B16CODE_SEL SEL_GDT(GDT_B16CODE, SEL_KPL)
+#define B16DATA_SEL SEL_GDT(GDT_B16DATA, SEL_KPL)
+
+/*
+ * Temporary %gs descriptor used by kmdb with -d option. Only lives
+ * in boot's GDT and is not copied into kernel's GDT from boot.
+ */
+#define KMDBGS_SEL SEL_GDT(GDT_BGSTMP, SEL_KPL)
+
+/*
+ * Selector used for kdi_idt when kmdb has taken over the IDT.
+ */
+#if defined(__amd64)
+#define KMDBCODE_SEL B64CODE_SEL
#else
-#define BOOTCODE_SEL SEL_GDT(GDT_BOOTCODE, SEL_KPL)
-#define BOOTFLAT_SEL SEL_GDT(GDT_BOOTFLAT, SEL_KPL)
+#define KMDBCODE_SEL B32CODE_SEL
#endif
/*
@@ -532,7 +566,7 @@ void set_syssegd(system_desc_t *, void *, size_t, uint_t, uint_t);
#pragma align 16(idt0)
extern gate_desc_t idt0[NIDT];
extern desctbr_t idt0_default_reg;
-extern user_desc_t gdt0[NGDT];
+extern user_desc_t *gdt0;
extern user_desc_t zero_udesc;
extern system_desc_t zero_sdesc;
diff --git a/usr/src/uts/intel/sys/x86_archext.h b/usr/src/uts/intel/sys/x86_archext.h
index af06a50a92..d637f9b284 100644
--- a/usr/src/uts/intel/sys/x86_archext.h
+++ b/usr/src/uts/intel/sys/x86_archext.h
@@ -73,14 +73,14 @@ extern "C" {
#define CPUID_INTC_EDX_SS 0x08000000 /* self-snoop */
#define CPUID_INTC_EDX_HTT 0x10000000 /* Hyper Thread Technology */
#define CPUID_INTC_EDX_TM 0x20000000 /* thermal monitoring */
- /* 0x40000000 - reserved */
+#define CPUID_INTC_EDX_IA64 0x40000000 /* Itanium emulating IA32 */
#define CPUID_INTC_EDX_PBE 0x80000000 /* Pending Break Enable */
-#define FMT_CPUID_INTC_EDX \
- "\20" \
- "\40pbe\36tm\35htt\34ss\33sse2\32sse\31fxsr" \
- "\30mmx\27acpi\26ds\24clfsh\23psn\22pse36\21pat"\
- "\20cmov\17mca\16pge\15mtrr\14sep\12apic\11cx8" \
+#define FMT_CPUID_INTC_EDX \
+ "\20" \
+ "\40pbe\37ia64\36tm\35htt\34ss\33sse2\32sse\31fxsr" \
+ "\30mmx\27acpi\26ds\24clfsh\23psn\22pse36\21pat" \
+ "\20cmov\17mca\16pge\15mtrr\14sep\12apic\11cx8" \
"\10mce\7pae\6msr\5tsc\4pse\3de\2vme\1fpu"
/*
@@ -92,22 +92,26 @@ extern "C" {
/* 0x00000004 - reserved */
#define CPUID_INTC_ECX_MON 0x00000008 /* MONITOR/MWAIT */
#define CPUID_INTC_ECX_DSCPL 0x00000010 /* CPL-qualified debug store */
- /* 0x00000020 - reserved */
- /* 0x00000040 - reserved */
+#define CPUID_INTC_ECX_VMX 0x00000020 /* Hardware VM extensions */
+#define CPUID_INTC_ECX_SMX 0x00000040 /* Secure mode extensions */
#define CPUID_INTC_ECX_EST 0x00000080 /* enhanced SpeedStep */
#define CPUID_INTC_ECX_TM2 0x00000100 /* thermal monitoring */
- /* 0x00000200 - reserved */
+#define CPUID_INTC_ECX_SSSE3 0x00000200 /* Supplemental SSE3 insns */
#define CPUID_INTC_ECX_CID 0x00000400 /* L1 context ID */
/* 0x00000800 - reserved */
/* 0x00001000 - reserved */
- /* 0x00002000 - reserved */
-#define CPUID_INTC_ECX_CX16 0x00002000 /* CMPXCHG16B */
-#define CPUID_INTC_ECX_XTPR 0x00004000 /* disable task pri messages */
-
-#define FMT_CPUID_INTC_ECX \
- "\20" \
- "\20\17xtpr\16cx16\13cid\11tm2" \
- "\10est\5dscpl\4monitor\1sse3"
+#define CPUID_INTC_ECX_CX16 0x00002000 /* cmpxchg16 */
+#define CPUID_INTC_ECX_ETPRD 0x00004000 /* extended task pri messages */
+ /* 0x00008000 - reserved */
+ /* 0x00010000 - reserved */
+ /* 0x00020000 - reserved */
+#define CPUID_INTC_ECX_DCA 0x00040000 /* direct cache access */
+
+#define FMT_CPUID_INTC_ECX \
+ "\20" \
+ "\30\23dca" \
+ "\20\17etprd\16cx16\13cid\12ssse3\11tm2" \
+ "\10est\7smx\6vmx\5dscpl\4mon\1sse3"
/*
* cpuid instruction feature flags in %edx (extended function 0x80000001)
@@ -129,7 +133,8 @@ extern "C" {
#define CPUID_AMD_EDX_PGE 0x00002000 /* page global enable */
#define CPUID_AMD_EDX_MCA 0x00004000 /* machine check arch */
#define CPUID_AMD_EDX_CMOV 0x00008000 /* conditional move insns */
-#define CPUID_AMD_EDX_PAT 0x00010000 /* page attribute table */
+#define CPUID_AMD_EDX_PAT 0x00010000 /* K7: page attribute table */
+#define CPUID_AMD_EDX_FCMOV 0x00010000 /* FCMOVcc etc. */
#define CPUID_AMD_EDX_PSE36 0x00020000 /* 36-bit pagesize extension */
/* 0x00040000 - reserved */
/* 0x00080000 - reserved */
@@ -138,9 +143,9 @@ extern "C" {
#define CPUID_AMD_EDX_MMXamd 0x00400000 /* AMD: MMX extensions */
#define CPUID_AMD_EDX_MMX 0x00800000 /* MMX instructions */
#define CPUID_AMD_EDX_FXSR 0x01000000 /* fxsave and fxrstor */
- /* 0x02000000 - reserved */
+#define CPUID_AMD_EDX_FFXSR 0x02000000 /* fast fxsave/fxrstor */
/* 0x04000000 - reserved */
- /* 0x08000000 - reserved */
+#define CPUID_AMD_EDX_TSCP 0x08000000 /* rdtscp instruction */
/* 0x10000000 - reserved */
#define CPUID_AMD_EDX_LM 0x20000000 /* AMD: long mode */
#define CPUID_AMD_EDX_3DNowx 0x40000000 /* AMD: extensions to 3DNow! */
@@ -148,16 +153,30 @@ extern "C" {
#define FMT_CPUID_AMD_EDX \
"\20" \
- "\40a3d\37a3d+\36lm\31fxsr" \
+ "\40a3d\37a3d+\36lm\34tscp\32ffxsr\31fxsr" \
"\30mmx\27mmxext\25nx\22pse\21pat" \
"\20cmov\17mca\16pge\15mtrr\14syscall\12apic\11cx8" \
"\10mce\7pae\6msr\5tsc\4pse\3de\2vme\1fpu"
-#define CPUID_AMD_ECX_CMP_LEGACY 0x00000002 /* AMD: multi-core chip */
+#define CPUID_AMD_ECX_AHF64 0x00000001 /* LAHF and SAHF in long mode */
+#define CPUID_AMD_ECX_CMP_LGCY 0x00000002 /* AMD: multicore chip */
+#define CPUID_AMD_ECX_SVM 0x00000004 /* AMD: secure VM */
+#define CPUID_AMD_ECX_EAS 0x00000008 /* extended apic space */
+#define CPUID_AMD_ECX_CR8D 0x00000010 /* AMD: 32-bit mov %cr8 */
#define FMT_CPUID_AMD_ECX \
"\20" \
- "\1htvalid"
+ "\5cr8d\3svm\2lcmplgcy\1ahf64"
+
+/*
+ * Intel now seems to have claimed part of the "extended" function
+ * space that we previously for non-Intel implementors to use.
+ * More excitingly still, they've claimed bit 20 to mean LAHF/SAHF
+ * is available in long mode i.e. what AMD indicate using bit 0.
+ * On the other hand, everything else is labelled as reserved.
+ */
+#define CPUID_INTC_ECX_AHF64 0x00100000 /* LAHF and SAHF in long mode */
+
#define P5_MCHADDR 0x0
#define P5_CESR 0x11
@@ -329,6 +348,7 @@ typedef struct mtrrvar {
#define X86_MSR 0x00000004
#define X86_MTRR 0x00000008
#define X86_PGE 0x00000010
+#define X86_DE 0x00000020
#define X86_CMOV 0x00000040
#define X86_MMX 0x00000080
#define X86_MCA 0x00000100
@@ -344,14 +364,15 @@ typedef struct mtrrvar {
#define X86_SSE3 0x00040000
#define X86_CX16 0x00080000
#define X86_CMP 0x00100000
+#define X86_TSCP 0x00200000
#define X86_CPUID 0x01000000
#define FMT_X86_FEATURE \
"\20" \
"\31cpuid" \
- "\25cmp\24cx16\23sse3\22nx\21asysc" \
+ "\26tscp\25cmp\24cx16\23sse3\22nx\21asysc" \
"\20htt\17sse2\16sse\15sep\14pat\13cx8\12pae\11mca" \
- "\10mmx\7cmov\5pge\4mtrr\3msr\2tsc\1lgpg"
+ "\10mmx\7cmov\6de\5pge\4mtrr\3msr\2tsc\1lgpg"
/*
* x86_type is a legacy concept; this is supplanted
@@ -482,7 +503,6 @@ extern uint_t x86_feature;
extern uint_t x86_type;
extern uint_t x86_vendor;
-extern ulong_t cr4_value;
extern uint_t pentiumpro_bug4046376;
extern uint_t pentiumpro_bug4064495;
@@ -509,9 +529,13 @@ extern uint64_t rdmsr(uint_t);
extern void wrmsr(uint_t, const uint64_t);
extern uint64_t xrdmsr(uint_t);
extern void xwrmsr(uint_t, const uint64_t);
+extern int checked_rdmsr(uint_t, uint64_t *);
+extern int checked_wrmsr(uint_t, uint64_t);
+
extern void invalidate_cache(void);
extern ulong_t getcr4(void);
extern void setcr4(ulong_t);
+
extern void mtrr_sync(void);
extern void cpu_fast_syscall_enable(void *);
@@ -547,6 +571,8 @@ extern int cpuid_opteron_erratum(struct cpu *, uint_t);
struct cpuid_info;
extern void setx86isalist(void);
+extern void cpuid_alloc_space(struct cpu *);
+extern void cpuid_free_space(struct cpu *);
extern uint_t cpuid_pass1(struct cpu *);
extern void cpuid_pass2(struct cpu *);
extern void cpuid_pass3(struct cpu *);
diff --git a/usr/src/uts/i86pc/vuid2ps2/Makefile b/usr/src/uts/intel/vuid2ps2/Makefile
index 05397b2344..39d2380998 100644
--- a/usr/src/uts/i86pc/vuid2ps2/Makefile
+++ b/usr/src/uts/intel/vuid2ps2/Makefile
@@ -19,9 +19,9 @@
# CDDL HEADER END
#
#
-# uts/i86pc/vuid2ps2/Makefile
+# uts/intel/vuid2ps2/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -29,7 +29,7 @@
# This makefile drives the production of the vuid2ps2 streams kernel
# module.
#
-# i86pc implementation architecture dependent
+# intel architecture dependent
#
#
@@ -43,12 +43,12 @@ UTSBASE = ../..
MODULE = vuid2ps2
OBJECTS = $(VUIDPS2_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(VUIDPS2_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_STRMOD_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_STRMOD_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -94,4 +94,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/vuid3ps2/Makefile b/usr/src/uts/intel/vuid3ps2/Makefile
index d45bc1f8e1..7fad683d16 100644
--- a/usr/src/uts/i86pc/vuid3ps2/Makefile
+++ b/usr/src/uts/intel/vuid3ps2/Makefile
@@ -19,9 +19,9 @@
# CDDL HEADER END
#
#
-# uts/i86pc/vuid3ps2/Makefile
+# uts/intel/vuid3ps2/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -29,7 +29,7 @@
# This makefile drives the production of the vuid3ps2 streams kernel
# module.
#
-# i86pc implementation architecture dependent
+# intel architecture dependent
#
#
@@ -43,12 +43,12 @@ UTSBASE = ../..
MODULE = vuid3ps2
OBJECTS = $(VUIDPS2_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(VUIDPS2_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_STRMOD_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_STRMOD_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -94,4 +94,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/vuidm3p/Makefile b/usr/src/uts/intel/vuidm3p/Makefile
index 925dd01173..64111cb269 100644
--- a/usr/src/uts/i86pc/vuidm3p/Makefile
+++ b/usr/src/uts/intel/vuidm3p/Makefile
@@ -19,9 +19,9 @@
# CDDL HEADER END
#
#
-# uts/i86pc/vuidm3p/Makefile
+# uts/intel/vuidm3p/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -29,7 +29,7 @@
# This makefile drives the production of the vuidm3p streams kernel
# module.
#
-# i86pc implementation architecture dependent
+# intel architecture dependent
#
#
@@ -43,12 +43,12 @@ UTSBASE = ../..
MODULE = vuidm3p
OBJECTS = $(VUIDM3P_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(VUIDM3P_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_STRMOD_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_STRMOD_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -94,4 +94,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/vuidm4p/Makefile b/usr/src/uts/intel/vuidm4p/Makefile
index adc5a92015..c9ace852f8 100644
--- a/usr/src/uts/i86pc/vuidm4p/Makefile
+++ b/usr/src/uts/intel/vuidm4p/Makefile
@@ -19,9 +19,9 @@
# CDDL HEADER END
#
#
-# uts/i86pc/vuidm4p/Makefile
+# uts/intel/vuidm4p/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -29,7 +29,7 @@
# This makefile drives the production of the vuidm4p streams kernel
# module.
#
-# i86pc implementation architecture dependent
+# intel architecture dependent
#
#
@@ -43,12 +43,12 @@ UTSBASE = ../..
MODULE = vuidm4p
OBJECTS = $(VUIDM4P_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(VUIDM4P_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_STRMOD_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_STRMOD_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -94,4 +94,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/i86pc/vuidm5p/Makefile b/usr/src/uts/intel/vuidm5p/Makefile
index bf7ac45670..042d369814 100644
--- a/usr/src/uts/i86pc/vuidm5p/Makefile
+++ b/usr/src/uts/intel/vuidm5p/Makefile
@@ -19,9 +19,9 @@
# CDDL HEADER END
#
#
-# uts/i86pc/vuidm5p/Makefile
+# uts/intel/vuidm5p/Makefile
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -29,7 +29,7 @@
# This makefile drives the production of the vuidm5p streams kernel
# module.
#
-# i86pc implementation architecture dependent
+# intel architecture dependent
#
#
@@ -43,12 +43,12 @@ UTSBASE = ../..
MODULE = vuidm5p
OBJECTS = $(VUIDM5P_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(VUIDM5P_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_STRMOD_DIR)/$(MODULE)
+ROOTMODULE = $(ROOT_STRMOD_DIR)/$(MODULE)
#
# Include common rules.
#
-include $(UTSBASE)/i86pc/Makefile.i86pc
+include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
@@ -91,4 +91,4 @@ install: $(INSTALL_DEPS)
#
# Include common targets.
#
-include $(UTSBASE)/i86pc/Makefile.targ
+include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/sparc/Makefile b/usr/src/uts/sparc/Makefile
index c597432d5c..a551f117e0 100644
--- a/usr/src/uts/sparc/Makefile
+++ b/usr/src/uts/sparc/Makefile
@@ -21,7 +21,7 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# uts/sparc/Makefile
@@ -80,8 +80,8 @@ install_h := TARGET= install_h
.KEEP_STATE:
-.PARALLEL: $(KMODS) $(CLOSED_KMODS) $(SVVS) $(XMODS) $(CLOSED_XMODS) \
- config $(LINT_DEPS)
+.PARALLEL: $(PARALLEL_KMODS) $(CLOSED_KMODS) $(SVVS) $(XMODS) \
+ $(CLOSED_XMODS) config $(LINT_DEPS)
def all install clean clobber modlist: $(KMODS) $(CLOSED_KMODS) $(SVVS) \
$(XMODS) $(CLOSED_XMODS) config
diff --git a/usr/src/uts/sparc/Makefile.files b/usr/src/uts/sparc/Makefile.files
index 96d0b63d68..240a348a59 100644
--- a/usr/src/uts/sparc/Makefile.files
+++ b/usr/src/uts/sparc/Makefile.files
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -36,6 +36,12 @@
CORE_OBJS += ddi_arch.o \
polled_io.o \
sparc_ddi.o
+#
+# decompression support
+#
+CORE_OBJS += adler32.o infblock.o infcodes.o inffast.o \
+ inflate.o inftrees.o infutil.o zutil.o zmod.o
+
#
# generic-unix module
diff --git a/usr/src/uts/sparc/Makefile.sparc.shared b/usr/src/uts/sparc/Makefile.sparc.shared
index a055072202..7df1a468aa 100644
--- a/usr/src/uts/sparc/Makefile.sparc.shared
+++ b/usr/src/uts/sparc/Makefile.sparc.shared
@@ -376,7 +376,6 @@ MISC_KMODS += ibtl
MISC_KMODS += hook
MISC_KMODS += neti
MISC_KMODS += ctf
-MISC_KMODS += zmod
MISC_KMODS += mac dls
MISC_KMODS += cmlb
MISC_KMODS += tem
diff --git a/usr/src/uts/sparc/ctf/Makefile b/usr/src/uts/sparc/ctf/Makefile
index 16a3f005ad..e97e20fbe1 100644
--- a/usr/src/uts/sparc/ctf/Makefile
+++ b/usr/src/uts/sparc/ctf/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -39,7 +39,7 @@ INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
CFLAGS += $(CCVERBOSE)
CPPFLAGS += -I$(SRC)/common/ctf -DCTF_OLD_VERSIONS
-LDFLAGS += -Breduce -M$(UTSBASE)/common/ctf/mapfile -dy -Nmisc/zmod
+LDFLAGS += -Breduce -M$(UTSBASE)/common/ctf/mapfile -dy
#
# For now, disable these lint checks; maintainers should endeavor
diff --git a/usr/src/uts/sparc/dtrace/fbt.c b/usr/src/uts/sparc/dtrace/fbt.c
index 91adbfe22a..f4224a6fdb 100644
--- a/usr/src/uts/sparc/dtrace/fbt.c
+++ b/usr/src/uts/sparc/dtrace/fbt.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1636,16 +1636,19 @@ fbt_getargdesc(void *arg, dtrace_id_t id, void *parg, dtrace_argdesc_t *desc)
* If we have a parent container, we must manually import it.
*/
if ((parent = ctf_parent_name(fp)) != NULL) {
- struct modctl *mod;
+ struct modctl *mp = &modules;
+ struct modctl *mod = NULL;
/*
* We must iterate over all modules to find the module that
* is our parent.
*/
- for (mod = &modules; mod != NULL; mod = mod->mod_next) {
- if (strcmp(mod->mod_filename, parent) == 0)
+ do {
+ if (strcmp(mp->mod_modname, parent) == 0) {
+ mod = mp;
break;
- }
+ }
+ } while ((mp = mp->mod_next) != &modules);
if (mod == NULL)
goto err;
diff --git a/usr/src/uts/sparc/krtld/mapfile b/usr/src/uts/sparc/krtld/mapfile
index 6d40dc91c1..708305072d 100644
--- a/usr/src/uts/sparc/krtld/mapfile
+++ b/usr/src/uts/sparc/krtld/mapfile
@@ -1,5 +1,5 @@
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# CDDL HEADER START
@@ -44,6 +44,7 @@
kobj_load_primary_module;
kobj_lookup;
kobj_lookup_all;
+ kobj_module_path;
kobj_notify_add;
kobj_notify_remove;
kobj_open;
diff --git a/usr/src/uts/sparc/os/sundep.c b/usr/src/uts/sparc/os/sundep.c
index 1c64e705c1..42859211d9 100644
--- a/usr/src/uts/sparc/os/sundep.c
+++ b/usr/src/uts/sparc/os/sundep.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -135,7 +134,7 @@ kern_setup1(void)
/*
* We assume that the u-area is zeroed out.
*/
- u.u_cmask = (mode_t)CMASK;
+ PTOU(curproc)->u_cmask = (mode_t)CMASK;
thread_init(); /* init thread_free list */
pid_init(); /* initialize pid (proc) table */
diff --git a/usr/src/uts/sparc/sys/archsystm.h b/usr/src/uts/sparc/sys/archsystm.h
index 23e9797e78..921a7f4c1a 100644
--- a/usr/src/uts/sparc/sys/archsystm.h
+++ b/usr/src/uts/sparc/sys/archsystm.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -88,10 +88,10 @@ extern u_longlong_t gettick(void);
extern uint64_t gettick_counter(void);
extern int xcopyin_little(const void *, void *, size_t);
extern int xcopyout_little(const void *, void *, size_t);
-extern void xregs_getgfiller(klwp_id_t lwp, caddr_t xrp);
-extern void xregs_setgfiller(klwp_id_t lwp, caddr_t xrp);
-extern void xregs_getfpfiller(klwp_id_t lwp, caddr_t xrp);
-extern void xregs_setfpfiller(klwp_id_t lwp, caddr_t xrp);
+extern void xregs_getgfiller(struct _klwp *lwp, caddr_t xrp);
+extern void xregs_setgfiller(struct _klwp *lwp, caddr_t xrp);
+extern void xregs_getfpfiller(struct _klwp *lwp, caddr_t xrp);
+extern void xregs_setfpfiller(struct _klwp *lwp, caddr_t xrp);
struct ucontext;
extern void xregs_clrptr(struct _klwp *, struct ucontext *);
@@ -119,6 +119,8 @@ extern void doflush(void *);
extern uint_t cpu_hwcap_flags;
+#define cpr_dprintf prom_printf
+
#endif /* _KERNEL && !_ASM */
diff --git a/usr/src/uts/sparc/sys/kdi_machimpl.h b/usr/src/uts/sparc/sys/kdi_machimpl.h
index a9c973ba7f..c4eff32875 100644
--- a/usr/src/uts/sparc/sys/kdi_machimpl.h
+++ b/usr/src/uts/sparc/sys/kdi_machimpl.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -97,6 +96,8 @@ extern void kdi_watchdog_restore(void);
extern void kdi_tlb_page_lock(caddr_t, int);
extern void kdi_tlb_page_unlock(caddr_t, int);
+extern void kmdb_enter(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/sparc/v9/os/v9dep.c b/usr/src/uts/sparc/v9/os/v9dep.c
index 009621abdc..a22cadb54a 100644
--- a/usr/src/uts/sparc/v9/os/v9dep.c
+++ b/usr/src/uts/sparc/v9/os/v9dep.c
@@ -23,7 +23,7 @@
/* All Rights Reserved */
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -961,7 +961,7 @@ sendsig(int sig, k_siginfo_t *sip, void (*hdlr)())
* and validate the stack requirements for the signal handler
* context. on_fault will catch any faults.
*/
- newstack = (sigismember(&u.u_sigonstack, sig) &&
+ newstack = (sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
!(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE)));
tos = (caddr_t)rp->r_sp + STACK_BIAS;
@@ -1290,7 +1290,7 @@ sendsig32(int sig, k_siginfo_t *sip, void (*hdlr)())
* and validate the stack requirements for the signal handler
* context. on_fault will catch any faults.
*/
- newstack = (sigismember(&u.u_sigonstack, sig) &&
+ newstack = (sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
!(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE)));
tos = (void *)(uintptr_t)(uint32_t)rp->r_sp;
diff --git a/usr/src/uts/sun/sys/bootconf.h b/usr/src/uts/sun/sys/bootconf.h
index c96f8aa90b..8d8c361139 100644
--- a/usr/src/uts/sun/sys/bootconf.h
+++ b/usr/src/uts/sun/sys/bootconf.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -241,6 +241,7 @@ extern int netboot;
extern int swaploaded;
extern int modrootloaded;
extern char kern_bootargs[];
+extern char *kobj_module_path;
extern char *default_path;
extern char *dhcack;
extern char *netdev_path;
diff --git a/usr/src/uts/sun4/ml/subr_asm.s b/usr/src/uts/sun4/ml/subr_asm.s
index 7055aeed25..acfa423775 100644
--- a/usr/src/uts/sun4/ml/subr_asm.s
+++ b/usr/src/uts/sun4/ml/subr_asm.s
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -445,6 +445,22 @@ kdi_cpu_index(void)
#endif /* lint */
+#if defined(lint) || defined(__lint)
+void
+kmdb_enter(void)
+{
+}
+
+#else /* lint */
+
+ ENTRY_NP(kmdb_enter)
+ t ST_KMDB_TRAP
+ retl
+ nop
+ SET_SIZE(kmdb_enter)
+
+#endif /* lint */
+
/*
* The Spitfire floating point code has been changed not to use install/
* save/restore/fork/freectx() because of the special memcpy library
diff --git a/usr/src/uts/sun4/os/cpu_states.c b/usr/src/uts/sun4/os/cpu_states.c
index d45a547443..d7d5e659dd 100644
--- a/usr/src/uts/sun4/os/cpu_states.c
+++ b/usr/src/uts/sun4/os/cpu_states.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,6 +35,7 @@
#include <sys/cpu_sgnblk_defs.h>
#include <sys/ivintr.h>
#include <sys/kdi.h>
+#include <sys/kdi_machimpl.h>
#include <sys/callb.h>
#include <sys/wdt.h>
@@ -259,7 +260,7 @@ debug_enter(char *msg)
(void) setjmp(&curthread->t_pcb);
if (boothowto & RB_DEBUG)
- kdi_dvec_enter();
+ kmdb_enter();
else
prom_enter_mon();
diff --git a/usr/src/uts/sun4/os/dtrace_subr.c b/usr/src/uts/sun4/os/dtrace_subr.c
index d1afbe29b0..58c789f43d 100644
--- a/usr/src/uts/sun4/os/dtrace_subr.c
+++ b/usr/src/uts/sun4/os/dtrace_subr.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -227,3 +227,13 @@ dtrace_safe_defer_signal(void)
return (1);
}
+
+/*
+ * Additional artificial frames for the machine type. For SPARC, we're already
+ * accounted for, so return 0.
+ */
+int
+dtrace_mach_aframes(void)
+{
+ return (0);
+}
diff --git a/usr/src/uts/sun4/os/machdep.c b/usr/src/uts/sun4/os/machdep.c
index 821999a3c0..2dd3544868 100644
--- a/usr/src/uts/sun4/os/machdep.c
+++ b/usr/src/uts/sun4/os/machdep.c
@@ -56,7 +56,11 @@
#include <sys/sysmacros.h>
#include <sys/promif.h>
#include <sys/pool_pset.h>
+#include <sys/mem.h>
+#include <sys/dumphdr.h>
#include <vm/seg_kmem.h>
+#include <sys/hold_page.h>
+#include <sys/cpu.h>
int maxphys = MMU_PAGESIZE * 16; /* 128k */
int klustsize = MMU_PAGESIZE * 16; /* 128k */
@@ -676,6 +680,7 @@ void
mach_kdi_init(kdi_t *kdi)
{
kdi->kdi_plat_call = kdi_plat_call;
+ kdi->kdi_kmdb_enter = kmdb_enter;
kdi->mkdi_cpu_index = kdi_cpu_index;
kdi->mkdi_trap_vatotte = kdi_trap_vatotte;
kdi->mkdi_kernpanic = kdi_kernpanic;
@@ -774,3 +779,58 @@ get_cpu_mstate(cpu_t *cpu, hrtime_t *times)
times[CMS_SYSTEM] += intracct[i];
}
}
+
+void
+mach_cpu_pause(volatile char *safe)
+{
+ /*
+ * This cpu is now safe.
+ */
+ *safe = PAUSE_WAIT;
+ membar_enter(); /* make sure stores are flushed */
+
+ /*
+ * Now we wait. When we are allowed to continue, safe
+ * will be set to PAUSE_IDLE.
+ */
+ while (*safe != PAUSE_IDLE)
+ SMT_PAUSE();
+}
+
+/*ARGSUSED*/
+int
+plat_mem_valid_page(uintptr_t pageaddr, uio_rw_t rw)
+{
+ return (0);
+}
+
+int
+dump_plat_addr()
+{
+ return (0);
+}
+
+void
+dump_plat_pfn()
+{
+}
+
+/* ARGSUSED */
+int
+dump_plat_data(void *dump_cdata)
+{
+ return (0);
+}
+
+/* ARGSUSED */
+int
+plat_hold_page(pfn_t pfn, int lock, page_t **pp_ret)
+{
+ return (PLAT_HOLD_OK);
+}
+
+/* ARGSUSED */
+void
+plat_release_page(page_t *pp)
+{
+}
diff --git a/usr/src/uts/sun4/os/mlsetup.c b/usr/src/uts/sun4/os/mlsetup.c
index d66c6c13c1..227127092c 100644
--- a/usr/src/uts/sun4/os/mlsetup.c
+++ b/usr/src/uts/sun4/os/mlsetup.c
@@ -191,7 +191,7 @@ mlsetup(struct regs *rp, void *cif, kfpu_t *fp)
CPU->cpu_dispatch_pri = t0.t_pri;
/*
- * Initialize thread/cpu microstate accounting here
+ * Initialize thread/cpu microstate accounting
*/
init_mstate(&t0, LMS_SYSTEM);
init_cpu_mstate(CPU, CMS_SYSTEM);
diff --git a/usr/src/uts/sun4/os/prom_subr.c b/usr/src/uts/sun4/os/prom_subr.c
index 46bafd606a..f3781a1c52 100644
--- a/usr/src/uts/sun4/os/prom_subr.c
+++ b/usr/src/uts/sun4/os/prom_subr.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -44,6 +43,7 @@
#include <sys/rwlock.h>
#include <sys/reboot.h>
#include <sys/kdi.h>
+#include <sys/kdi_machimpl.h>
/*
* We are called with a pointer to a cell-sized argument array.
@@ -349,7 +349,7 @@ kern_postprom(void)
return; /* prom lock is held recursively by this CPU */
if ((boothowto & RB_DEBUG) && prom_exit_enter_debugger)
- kdi_dvec_enter();
+ kmdb_enter();
prom_thread = NULL;
membar_producer();
diff --git a/usr/src/uts/sun4/os/startup.c b/usr/src/uts/sun4/os/startup.c
index b91dab8ac7..af968271e9 100644
--- a/usr/src/uts/sun4/os/startup.c
+++ b/usr/src/uts/sun4/os/startup.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -202,6 +202,12 @@ pgcnt_t segziosize = 0; /* size of zio segment in pages */
struct vnode kdebugvp;
/*
+ * VA range available to the debugger
+ */
+const caddr_t kdi_segdebugbase = (const caddr_t)SEGDEBUGBASE;
+const size_t kdi_segdebugsize = SEGDEBUGSIZE;
+
+/*
* Segment for relocated kernel structures in 64-bit large RAM kernels
*/
struct seg kmem64;
@@ -1610,8 +1616,8 @@ startup_modules(void)
maxmem = physmem;
/* Set segkp limits. */
- ncbase = (caddr_t)SEGDEBUGBASE;
- ncend = (caddr_t)SEGDEBUGBASE;
+ ncbase = kdi_segdebugbase;
+ ncend = kdi_segdebugbase;
/*
* Initialize the hat layer.
@@ -2710,8 +2716,7 @@ kvm_init(void)
/*
* Create a segment for the debugger.
*/
- (void) seg_attach(&kas, (caddr_t)SEGDEBUGBASE, (size_t)SEGDEBUGSIZE,
- &kdebugseg);
+ (void) seg_attach(&kas, kdi_segdebugbase, kdi_segdebugsize, &kdebugseg);
(void) segkmem_create(&kdebugseg);
rw_exit(&kas.a_lock);
diff --git a/usr/src/uts/sun4u/Makefile b/usr/src/uts/sun4u/Makefile
index 0c849ab7d2..df4e9677cd 100644
--- a/usr/src/uts/sun4u/Makefile
+++ b/usr/src/uts/sun4u/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -83,7 +82,7 @@ check := TARGET= check
.KEEP_STATE:
-.PARALLEL: $(KMODS) $(CLOSED_KMODS) $(XMODS) $(CLOSED_XMODS) \
+.PARALLEL: $(PARALLEL_KMODS) $(CLOSED_KMODS) $(XMODS) $(CLOSED_XMODS) \
$(IMPLEMENTATIONS) $(CLOSED_IMPLEMENTATIONS) \
modlist modlist.sparc
diff --git a/usr/src/uts/sun4u/Makefile.sun4u.shared b/usr/src/uts/sun4u/Makefile.sun4u.shared
index 3a2f922f5c..c1398f6afc 100644
--- a/usr/src/uts/sun4u/Makefile.sun4u.shared
+++ b/usr/src/uts/sun4u/Makefile.sun4u.shared
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -37,6 +37,11 @@ PROMIF = ieee1275
PSMBASE = $(UTSBASE)/../psm
#
+# uname -m value
+#
+UNAME_M = $(PLATFORM)
+
+#
# Definitions for the platform-specific /platform directories.
#
# PLATFORMS designates those sun4u machines which have no platform
diff --git a/usr/src/uts/sun4u/boston/Makefile b/usr/src/uts/sun4u/boston/Makefile
index d791410b70..5b9dd24fa8 100644
--- a/usr/src/uts/sun4u/boston/Makefile
+++ b/usr/src/uts/sun4u/boston/Makefile
@@ -20,7 +20,7 @@
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -77,7 +77,6 @@ BOSTON_CRYPTO_LINKS += aes256
install: $(ROOT_BOSTON_DIR) \
$(USR_BOSTON_DIR) \
$(USR_BOSTON_INC_DIR) \
- $(USR_BOSTON_SBIN_EEPROM) \
$(USR_BOSTON_SBIN_PRTDIAG) \
$(USR_BOSTON_SBIN_FRUADM) \
$(USR_BOSTON_SBIN_TRAPSTAT) \
diff --git a/usr/src/uts/sun4u/boston/Makefile.boston b/usr/src/uts/sun4u/boston/Makefile.boston
index 5750bfa08e..d43099f1af 100644
--- a/usr/src/uts/sun4u/boston/Makefile.boston
+++ b/usr/src/uts/sun4u/boston/Makefile.boston
@@ -20,7 +20,7 @@
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -53,7 +53,6 @@ USR_BOSTON_LINKED_DIR = $(USR_PLAT_DIR)/$(LINKED_PLATFORM)
USR_BOSTON_INC_DIR = $(USR_BOSTON_DIR)/include
USR_BOSTON_ISYS_DIR = $(USR_BOSTON_INC_DIR)/sys
USR_BOSTON_SBIN_DIR = $(USR_BOSTON_DIR)/sbin
-USR_BOSTON_SBIN_EEPROM = $(USR_BOSTON_SBIN_DIR)/eeprom
USR_BOSTON_SBIN_PRTDIAG = $(USR_BOSTON_SBIN_DIR)/prtdiag
USR_BOSTON_SBIN_FRUADM = $(USR_BOSTON_SBIN_DIR)/fruadm
USR_BOSTON_SBIN_TRAPSTAT = $(USR_BOSTON_SBIN_DIR)/trapstat
diff --git a/usr/src/uts/sun4u/boston/Makefile.targ b/usr/src/uts/sun4u/boston/Makefile.targ
index baecde5a8a..ece1ba33e1 100644
--- a/usr/src/uts/sun4u/boston/Makefile.targ
+++ b/usr/src/uts/sun4u/boston/Makefile.targ
@@ -20,7 +20,7 @@
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -67,9 +67,6 @@ $(USR_BOSTON_INC_DIR): $(USR_BOSTON_DIR)
$(USR_BOSTON_SBIN_DIR): $(USR_BOSTON_DIR)
$(INS.dir.root.bin)
-$(USR_BOSTON_SBIN_EEPROM): $(USR_BOSTON_SBIN_DIR)
- $(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/sbin/eeprom $@ $(CHOWNLINK) $(CHGRPLINK)
-
$(USR_BOSTON_SBIN_PRTDIAG): $(USR_BOSTON_SBIN_DIR)
$(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/sbin/prtdiag $@ $(CHOWNLINK) $(CHGRPLINK)
diff --git a/usr/src/uts/sun4u/mpxu/Makefile b/usr/src/uts/sun4u/mpxu/Makefile
index a5749ac140..371dc0a151 100644
--- a/usr/src/uts/sun4u/mpxu/Makefile
+++ b/usr/src/uts/sun4u/mpxu/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
#
#
# uts/sun4u/mpxu/Makefile
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -86,7 +85,6 @@ MPXU_CRYPTO_LINKS += aes256
install: $(ROOT_MPXU_DIR) $(USR_MPXU_DIR) \
$(USR_MPXU_INC_DIR) \
- $(USR_MPXU_SBIN_EEPROM) \
$(USR_MPXU_SBIN_PRTDIAG) \
$(USR_MPXU_SBIN_TRAPSTAT) \
$(USR_MPXU_SBIN_FRUADM) \
diff --git a/usr/src/uts/sun4u/mpxu/Makefile.mpxu.shared b/usr/src/uts/sun4u/mpxu/Makefile.mpxu.shared
index 3bb083b7e1..24c701e48c 100644
--- a/usr/src/uts/sun4u/mpxu/Makefile.mpxu.shared
+++ b/usr/src/uts/sun4u/mpxu/Makefile.mpxu.shared
@@ -20,7 +20,7 @@
#
#
# uts/sun4u/mpxu/Makefile.mpxu
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -56,7 +56,6 @@ USR_MPXU_DIR = $(USR_PLAT_DIR)/SUNW,Sun-Fire-V240
USR_MPXU_INC_DIR = $(USR_MPXU_DIR)/include
USR_MPXU_ISYS_DIR = $(USR_MPXU_INC_DIR)/sys
USR_MPXU_SBIN_DIR = $(USR_MPXU_DIR)/sbin
-USR_MPXU_SBIN_EEPROM = $(USR_MPXU_SBIN_DIR)/eeprom
USR_MPXU_SBIN_PRTDIAG = $(USR_MPXU_SBIN_DIR)/prtdiag
USR_MPXU_SBIN_TRAPSTAT = $(USR_MPXU_SBIN_DIR)/trapstat
USR_MPXU_SBIN_FRUADM = $(USR_MPXU_SBIN_DIR)/fruadm
diff --git a/usr/src/uts/sun4u/mpxu/Makefile.targ.shared b/usr/src/uts/sun4u/mpxu/Makefile.targ.shared
index fb5225c2c1..f9c46c5176 100644
--- a/usr/src/uts/sun4u/mpxu/Makefile.targ.shared
+++ b/usr/src/uts/sun4u/mpxu/Makefile.targ.shared
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -71,9 +70,6 @@ $(USR_MPXU_ISYS_DIR): $(USR_MPXU_INC_DIR)
$(USR_MPXU_SBIN_DIR): $(USR_MPXU_DIR)
$(INS.dir.root.bin)
-$(USR_MPXU_SBIN_EEPROM): $(USR_MPXU_SBIN_DIR)
- $(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/sbin/eeprom $@ $(CHOWNLINK) $(CHGRPLINK)
-
$(USR_MPXU_SBIN_PRTDIAG): $(USR_MPXU_SBIN_DIR)
$(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/sbin/prtdiag $@ $(CHOWNLINK) $(CHGRPLINK)
diff --git a/usr/src/uts/sun4u/opl/Makefile b/usr/src/uts/sun4u/opl/Makefile
index f4f3831a43..5a739329d4 100644
--- a/usr/src/uts/sun4u/opl/Makefile
+++ b/usr/src/uts/sun4u/opl/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -82,7 +82,6 @@ OPL_CRYPTO_LINKS += aes256
install: $(ROOT_OPL_DIR) $(USR_OPL_DIR) \
$(USR_OPL_INC_DIR) \
$(USR_OPL_SBIN_DIR) \
- $(USR_OPL_SBIN_EEPROM) \
$(USR_OPL_SBIN_PRTDIAG) \
$(USR_OPL_SBIN_TRAPSTAT) \
$(USR_OPL_SBIN_FRUADM) \
diff --git a/usr/src/uts/sun4u/opl/Makefile.opl.shared b/usr/src/uts/sun4u/opl/Makefile.opl.shared
index ec5e0a6d2d..b92abb334e 100644
--- a/usr/src/uts/sun4u/opl/Makefile.opl.shared
+++ b/usr/src/uts/sun4u/opl/Makefile.opl.shared
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -59,7 +59,6 @@ ROOT_PLAT_MISC_DIRS_32 += $(ROOT_OPL_MISC_DIR_32)
USR_OPL_DIR = $(USR_PLAT_DIR)/SUNW,SPARC-Enterprise
USR_OPL_LIB_DIR = $(USR_OPL_DIR)/lib
USR_OPL_SBIN_DIR = $(USR_OPL_DIR)/sbin
-USR_OPL_SBIN_EEPROM = $(USR_OPL_SBIN_DIR)/eeprom
USR_OPL_SBIN_PRTDIAG = $(USR_OPL_SBIN_DIR)/prtdiag
USR_OPL_SBIN_TRAPSTAT = $(USR_OPL_SBIN_DIR)/trapstat
USR_OPL_SBIN_FRUADM = $(USR_OPL_SBIN_DIR)/fruadm
diff --git a/usr/src/uts/sun4u/opl/Makefile.targ.shared b/usr/src/uts/sun4u/opl/Makefile.targ.shared
index 69191fcf54..629a61110b 100644
--- a/usr/src/uts/sun4u/opl/Makefile.targ.shared
+++ b/usr/src/uts/sun4u/opl/Makefile.targ.shared
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -73,9 +73,6 @@ $(USR_OPL_INC_DIR): $(USR_OPL_DIR) $(USR_PSM_INCL_DIR)
$(USR_OPL_SBIN_DIR): $(USR_OPL_DIR) $(USR_PSM_SBIN_DIR)
$(INS.dir.root.bin)
-$(USR_OPL_SBIN_EEPROM): $(USR_OPL_SBIN_DIR)
- $(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/sbin/eeprom $@ $(CHOWNLINK) $(CHGRPLINK)
-
$(USR_OPL_SBIN_PRTDIAG): $(USR_OPL_SBIN_DIR)
$(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/sbin/prtdiag $@ $(CHOWNLINK) $(CHGRPLINK)
diff --git a/usr/src/uts/sun4u/os/cpr_impl.c b/usr/src/uts/sun4u/os/cpr_impl.c
index 801ef7ba8a..caefea794b 100644
--- a/usr/src/uts/sun4u/os/cpr_impl.c
+++ b/usr/src/uts/sun4u/os/cpr_impl.c
@@ -253,7 +253,7 @@ i_cpr_mp_setup(void)
if (ncpus > 1) {
sfmmu_init_tsbs();
- if (cpr_debug & LEVEL1) {
+ if (cpr_debug & CPR_DEBUG1) {
prom_interpret("stdout @ swap l!", (uintptr_t)&tmpout,
0, 0, 0, 0);
str = "MP startup...\r\n";
@@ -279,7 +279,7 @@ i_cpr_mp_setup(void)
pause_cpus(NULL);
mutex_exit(&cpu_lock);
- if (cpr_debug & LEVEL1) {
+ if (cpr_debug & CPR_DEBUG1) {
str = "MP paused...\r\n";
(void) prom_write(tmpout, str, strlen(str), 0, 0);
}
@@ -505,7 +505,7 @@ void
i_cpr_machdep_setup(void)
{
if (ncpus > 1) {
- DEBUG1(errp("MP restarted...\n"));
+ CPR_DEBUG(CPR_DEBUG1, "MP restarted...\n");
mutex_enter(&cpu_lock);
start_cpus();
mutex_exit(&cpu_lock);
@@ -587,8 +587,8 @@ i_cpr_write_machdep(vnode_t *vp)
m_info.ksb = (uint32_t)STACK_BIAS;
m_info.kpstate = (uint16_t)getpstate();
m_info.kwstate = (uint16_t)getwstate();
- DEBUG1(errp("stack bias 0x%x, pstate 0x%x, wstate 0x%x\n",
- m_info.ksb, m_info.kpstate, m_info.kwstate));
+ CPR_DEBUG(CPR_DEBUG1, "stack bias 0x%x, pstate 0x%x, wstate 0x%x\n",
+ m_info.ksb, m_info.kpstate, m_info.kwstate);
ltp = &ttolwp(curthread)->lwp_qsav;
m_info.qsav_pc = (cpr_ext)ltp->val[0];
@@ -643,9 +643,9 @@ i_cpr_write_machdep(vnode_t *vp)
void
i_cpr_save_machdep_info(void)
{
- DEBUG5(errp("jumpback size = 0x%lx\n",
+ CPR_DEBUG(CPR_DEBUG5, "jumpback size = 0x%lx\n",
(uintptr_t)&i_cpr_end_jumpback -
- (uintptr_t)i_cpr_resume_setup));
+ (uintptr_t)i_cpr_resume_setup);
/*
* Verify the jumpback code all falls in one page.
@@ -856,7 +856,7 @@ i_cpr_save_sensitive_kpages(void)
pages = spages - vpages;
str = "i_cpr_save_sensitive_kpages:";
- DEBUG7(errp(pages_fmt, "before", str, spages, vpages, pages));
+ CPR_DEBUG(CPR_DEBUG7, pages_fmt, "before", str, spages, vpages, pages);
/*
* Allocate space to save the clean sensitive kpages
@@ -876,9 +876,9 @@ i_cpr_save_sensitive_kpages(void)
addr = i_cpr_storage_data_alloc(pages,
&i_cpr_storage_data_sz, retry_cnt);
if (addr == NULL) {
- DEBUG7(errp(
+ CPR_DEBUG(CPR_DEBUG7,
"\n%s can't allocate data storage space!\n",
- str));
+ str);
return (ENOMEM);
}
i_cpr_storage_data_base = addr;
@@ -915,22 +915,22 @@ i_cpr_save_sensitive_kpages(void)
i_cpr_count_sensitive_kpages(REGULAR_BITMAP, cpr_setbit);
vpages = cpr_count_volatile_pages(REGULAR_BITMAP, cpr_clrbit);
- DEBUG7(errp(pages_fmt, "after ", str,
- spages, vpages, spages - vpages));
+ CPR_DEBUG(CPR_DEBUG7, pages_fmt, "after ", str,
+ spages, vpages, spages - vpages);
/*
* Returns 0 on success, -1 if too few descriptors, and
* ENOMEM if not enough space to save sensitive pages
*/
- DEBUG1(errp("compressing pages to storage...\n"));
+ CPR_DEBUG(CPR_DEBUG1, "compressing pages to storage...\n");
error = i_cpr_save_to_storage();
if (error == 0) {
/* Saving to storage succeeded */
- DEBUG1(errp("compressed %d pages\n",
- sensitive_pages_saved));
+ CPR_DEBUG(CPR_DEBUG1, "compressed %d pages\n",
+ sensitive_pages_saved);
break;
} else if (error == -1)
- DEBUG1(errp("%s too few descriptors\n", str));
+ CPR_DEBUG(CPR_DEBUG1, "%s too few descriptors\n", str);
}
if (error == -1)
error = ENOMEM;
@@ -958,9 +958,10 @@ i_cpr_storage_data_alloc(pgcnt_t pages, pgcnt_t *alloc_pages, int retry_cnt)
*/
alloc_pcnt = INITIAL_ALLOC_PCNT;
*alloc_pages = (pages * alloc_pcnt) / INTEGRAL;
- DEBUG7(errp("%s sensitive pages: %ld\n", str, pages));
- DEBUG7(errp("%s initial est pages: %ld, alloc %ld%%\n",
- str, *alloc_pages, alloc_pcnt));
+ CPR_DEBUG(CPR_DEBUG7, "%s sensitive pages: %ld\n", str, pages);
+ CPR_DEBUG(CPR_DEBUG7,
+ "%s initial est pages: %ld, alloc %ld%%\n",
+ str, *alloc_pages, alloc_pcnt);
} else {
/*
* calculate the prior compression percentage (x100)
@@ -969,7 +970,7 @@ i_cpr_storage_data_alloc(pgcnt_t pages, pgcnt_t *alloc_pages, int retry_cnt)
ASSERT(sensitive_pages_saved != 0);
last_pcnt = (mmu_btopr(sensitive_size_saved) * INTEGRAL) /
sensitive_pages_saved;
- DEBUG7(errp("%s last ratio %ld%%\n", str, last_pcnt));
+ CPR_DEBUG(CPR_DEBUG7, "%s last ratio %ld%%\n", str, last_pcnt);
/*
* new estimated storage size is based on
@@ -979,12 +980,12 @@ i_cpr_storage_data_alloc(pgcnt_t pages, pgcnt_t *alloc_pages, int retry_cnt)
alloc_pcnt = MAX(last_pcnt, INITIAL_ALLOC_PCNT) +
(retry_cnt * 5);
*alloc_pages = (pages * alloc_pcnt) / INTEGRAL;
- DEBUG7(errp("%s Retry est pages: %ld, alloc %ld%%\n",
- str, *alloc_pages, alloc_pcnt));
+ CPR_DEBUG(CPR_DEBUG7, "%s Retry est pages: %ld, alloc %ld%%\n",
+ str, *alloc_pages, alloc_pcnt);
}
addr = kmem_alloc(mmu_ptob(*alloc_pages), KM_NOSLEEP);
- DEBUG7(errp("%s alloc %ld pages\n", str, *alloc_pages));
+ CPR_DEBUG(CPR_DEBUG7, "%s alloc %ld pages\n", str, *alloc_pages);
return (addr);
}
@@ -1033,9 +1034,10 @@ i_cpr_compress_and_save(int chunks, pfn_t spfn, pgcnt_t pages)
*/
descp = i_cpr_storage_desc_base + chunks - 1;
if (descp >= i_cpr_storage_desc_end) {
- DEBUG1(errp("ran out of descriptors, base 0x%p, chunks %d, "
- "end 0x%p, descp 0x%p\n", i_cpr_storage_desc_base, chunks,
- i_cpr_storage_desc_end, descp));
+ CPR_DEBUG(CPR_DEBUG1, "ran out of descriptors, base 0x%p, "
+ "chunks %d, end 0x%p, descp 0x%p\n",
+ i_cpr_storage_desc_base, chunks,
+ i_cpr_storage_desc_end, descp);
return (-1);
}
ASSERT(descp->csd_dirty_spfn == (uint_t)-1);
@@ -1077,9 +1079,9 @@ i_cpr_compress_and_save(int chunks, pfn_t spfn, pgcnt_t pages)
sensitive_write_ptr += datalen;
} else {
remaining = (i_cpr_storage_data_end - sensitive_write_ptr);
- DEBUG1(errp("i_cpr_compress_and_save: The storage "
+ CPR_DEBUG(CPR_DEBUG1, "i_cpr_compress_and_save: The storage "
"space is too small!\ngot %d, want %d\n\n",
- remaining, (remaining + datalen)));
+ remaining, (remaining + datalen));
#ifdef DEBUG
/*
* Check to see if the content of the sensitive pages that we
@@ -1088,10 +1090,11 @@ i_cpr_compress_and_save(int chunks, pfn_t spfn, pgcnt_t pages)
test_usum = checksum32(CPR->c_mapping_area, mmu_ptob(pages));
descp->csd_usum = cpd.cpd_usum;
if (test_usum != descp->csd_usum) {
- DEBUG1(errp("\nWARNING: i_cpr_compress_and_save: "
+ CPR_DEBUG(CPR_DEBUG1, "\nWARNING: "
+ "i_cpr_compress_and_save: "
"Data in the range of pfn 0x%lx to pfn "
"0x%lx has changed after they are saved "
- "into storage.", spfn, (spfn + pages - 1)));
+ "into storage.", spfn, (spfn + pages - 1));
}
#endif
error = ENOMEM;
@@ -1135,9 +1138,9 @@ i_cpr_count_sensitive_kpages(int mapflag, bitfunc_t bitfunc)
segkmem_cnt += cpr_count_pages(kmem64.s_base, kmem64.s_size,
mapflag, bitfunc, DBG_SHOWRANGE);
- DEBUG7(errp("\ni_cpr_count_sensitive_kpages:\n"
+ CPR_DEBUG(CPR_DEBUG7, "\ni_cpr_count_sensitive_kpages:\n"
"\tkdata_cnt %ld + segkmem_cnt %ld = %ld pages\n",
- kdata_cnt, segkmem_cnt, kdata_cnt + segkmem_cnt));
+ kdata_cnt, segkmem_cnt, kdata_cnt + segkmem_cnt);
return (kdata_cnt + segkmem_cnt);
}
@@ -1185,9 +1188,9 @@ i_cpr_storage_desc_alloc(csd_t **basepp, pgcnt_t *pgsp, csd_t **endpp,
chunks = cpr_contig_pages(NULL, STORAGE_DESC_ALLOC) +
EXTRA_DESCS;
npages = mmu_btopr(sizeof (**basepp) * (pgcnt_t)chunks);
- DEBUG7(errp("%s chunks %d, ", str, chunks));
+ CPR_DEBUG(CPR_DEBUG7, "%s chunks %d, ", str, chunks);
} else {
- DEBUG7(errp("%s retry %d: ", str, retry));
+ CPR_DEBUG(CPR_DEBUG7, "%s retry %d: ", str, retry);
npages = *pgsp + 1;
}
/* Free old descriptors, if any */
@@ -1196,16 +1199,16 @@ i_cpr_storage_desc_alloc(csd_t **basepp, pgcnt_t *pgsp, csd_t **endpp,
descp = *basepp = kmem_alloc(mmu_ptob(npages), KM_NOSLEEP);
if (descp == NULL) {
- DEBUG7(errp("%s no space for descriptors!\n", str));
+ CPR_DEBUG(CPR_DEBUG7, "%s no space for descriptors!\n", str);
return (ENOMEM);
}
*pgsp = npages;
len = mmu_ptob(npages);
end = *endpp = descp + (len / (sizeof (**basepp)));
- DEBUG7(errp("npages 0x%lx, len 0x%lx, items 0x%lx\n\t*basepp "
+ CPR_DEBUG(CPR_DEBUG7, "npages 0x%lx, len 0x%lx, items 0x%lx\n\t*basepp "
"%p, *endpp %p\n", npages, len, (len / (sizeof (**basepp))),
- *basepp, *endpp));
+ *basepp, *endpp);
i_cpr_storage_desc_init(descp, npages, end);
return (0);
}
@@ -1252,8 +1255,8 @@ i_cpr_dump_sensitive_kpages(vnode_t *vp)
prom_printf(" \b");
}
- DEBUG7(errp("\ni_cpr_dump_sensitive_kpages: dumped %ld\n",
- i_cpr_sensitive_pgs_dumped));
+ CPR_DEBUG(CPR_DEBUG7, "\ni_cpr_dump_sensitive_kpages: dumped %ld\n",
+ i_cpr_sensitive_pgs_dumped);
return (0);
}
@@ -1326,7 +1329,7 @@ cpr_dump_sensitive(vnode_t *vp, csd_t *descp)
/* Write cpr page descriptor */
error = cpr_write(vp, (caddr_t)&cpd, sizeof (cpd));
if (error) {
- DEBUG7(errp("descp: %p\n", descp));
+ CPR_DEBUG(CPR_DEBUG7, "descp: %p\n", descp);
#ifdef DEBUG
debug_enter("cpr_dump_sensitive: cpr_write() page "
"descriptor failed!\n");
@@ -1339,10 +1342,10 @@ cpr_dump_sensitive(vnode_t *vp, csd_t *descp)
/* Write page data */
error = cpr_write(vp, (caddr_t)datap, cpd.cpd_length);
if (error) {
- DEBUG7(errp("error: %x\n", error));
- DEBUG7(errp("descp: %p\n", descp));
- DEBUG7(errp("cpr_write(%p, %p , %lx)\n", vp, datap,
- cpd.cpd_length));
+ CPR_DEBUG(CPR_DEBUG7, "error: %x\n", error);
+ CPR_DEBUG(CPR_DEBUG7, "descp: %p\n", descp);
+ CPR_DEBUG(CPR_DEBUG7, "cpr_write(%p, %p , %lx)\n", vp, datap,
+ cpd.cpd_length);
#ifdef DEBUG
debug_enter("cpr_dump_sensitive: cpr_write() data failed!\n");
#endif
@@ -1367,9 +1370,9 @@ i_cpr_check_pgs_dumped(uint_t pgs_expected, uint_t regular_pgs_dumped)
total_pgs_dumped = regular_pgs_dumped + i_cpr_sensitive_pgs_dumped;
- DEBUG7(errp("\ncheck_pgs: reg %d + sens %ld = %d, expect %d\n\n",
- regular_pgs_dumped, i_cpr_sensitive_pgs_dumped,
- total_pgs_dumped, pgs_expected));
+ CPR_DEBUG(CPR_DEBUG7, "\ncheck_pgs: reg %d + sens %ld = %d, "
+ "expect %d\n\n", regular_pgs_dumped, i_cpr_sensitive_pgs_dumped,
+ total_pgs_dumped, pgs_expected);
if (pgs_expected == total_pgs_dumped)
return (0);
@@ -1565,8 +1568,9 @@ i_cpr_find_ppages(void)
* (non-page_t pages - seg pages + vnode pages)
*/
ppage_count = pcnt - scnt + vcnt;
- DEBUG1(errp("find_ppages: pcnt %ld - scnt %ld + vcnt %ld = %ld\n",
- pcnt, scnt, vcnt, ppage_count));
+ CPR_DEBUG(CPR_DEBUG1,
+ "find_ppages: pcnt %ld - scnt %ld + vcnt %ld = %ld\n",
+ pcnt, scnt, vcnt, ppage_count);
/*
* alloc array of pfn_t to store phys page list
@@ -1633,7 +1637,7 @@ i_cpr_save_ppages(void)
dst += MMU_PAGESIZE;
}
- DEBUG1(errp("saved %ld prom pages\n", ppage_count));
+ CPR_DEBUG(CPR_DEBUG1, "saved %ld prom pages\n", ppage_count);
}
@@ -1662,7 +1666,7 @@ i_cpr_restore_ppages(void)
dcache_flushall();
- DEBUG1(errp("restored %ld prom pages\n", ppage_count));
+ CPR_DEBUG(CPR_DEBUG1, "restored %ld prom pages\n", ppage_count);
}
@@ -1693,7 +1697,8 @@ i_cpr_prom_pages(int action)
if (ppage_buf) {
ASSERT(ppage_count);
kmem_free(ppage_buf, mmu_ptob(ppage_count));
- DEBUG1(errp("freed %ld prom pages\n", ppage_count));
+ CPR_DEBUG(CPR_DEBUG1, "freed %ld prom pages\n",
+ ppage_count);
ppage_buf = NULL;
ppage_count = 0;
}
@@ -1836,7 +1841,7 @@ i_cpr_blockzero(char *base, char **bufpp, int *blkno, vnode_t *vp)
bcopy(cpr_sector, base, sizeof (cpr_sector));
*bufpp = base + sizeof (cpr_sector);
*blkno = cpr_statefile_offset();
- DEBUG1(errp("statefile data size: %ld\n\n", bytes));
+ CPR_DEBUG(CPR_DEBUG1, "statefile data size: %ld\n\n", bytes);
return (cpr_flush_write(vp));
}
}
diff --git a/usr/src/uts/sun4u/os/mach_trap.c b/usr/src/uts/sun4u/os/mach_trap.c
index 2890d313f6..f6ab0b999e 100644
--- a/usr/src/uts/sun4u/os/mach_trap.c
+++ b/usr/src/uts/sun4u/os/mach_trap.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -150,7 +149,7 @@ showregs(uint_t type, struct regs *rp, caddr_t addr, uint_t mmu_fsr)
s = spl7();
type &= ~T_USER;
- printf("%s: ", u.u_comm);
+ printf("%s: ", PTOU(curproc)->u_comm);
switch (type) {
case T_SYS_RTT_ALIGN:
diff --git a/usr/src/uts/sun4u/schumacher/Makefile b/usr/src/uts/sun4u/schumacher/Makefile
index 893dd0c41f..f44163dc26 100644
--- a/usr/src/uts/sun4u/schumacher/Makefile
+++ b/usr/src/uts/sun4u/schumacher/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -19,7 +18,7 @@
#
# CDDL HEADER END
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -75,7 +74,6 @@ install: $(ROOT_SCHUMACHER_DIR) \
$(USR_SCHUMACHER_DIR) \
$(USR_SCHUMACHER_INC_DIR) \
$(USR_SCHUMACHER_SBIN_DIR) \
- $(USR_SCHUMACHER_SBIN_EEPROM) \
$(USR_SCHUMACHER_SBIN_PRTDIAG) \
$(USR_SCHUMACHER_SBIN_TRAPSTAT) \
$(USR_SCHUMACHER_SBIN_FRUADM) \
diff --git a/usr/src/uts/sun4u/schumacher/Makefile.schumacher b/usr/src/uts/sun4u/schumacher/Makefile.schumacher
index d2e28ea88e..b250779b6d 100644
--- a/usr/src/uts/sun4u/schumacher/Makefile.schumacher
+++ b/usr/src/uts/sun4u/schumacher/Makefile.schumacher
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -19,7 +18,7 @@
#
# CDDL HEADER END
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -52,7 +51,6 @@ USR_SCHUMACHER_LINKED_DIR = $(USR_PLAT_DIR)/$(LINKED_PLATFORM)
USR_SCHUMACHER_INC_DIR = $(USR_SCHUMACHER_DIR)/include
USR_SCHUMACHER_ISYS_DIR = $(USR_SCHUMACHER_INC_DIR)/sys
USR_SCHUMACHER_SBIN_DIR = $(USR_SCHUMACHER_DIR)/sbin
-USR_SCHUMACHER_SBIN_EEPROM = $(USR_SCHUMACHER_SBIN_DIR)/eeprom
USR_SCHUMACHER_SBIN_PRTDIAG = $(USR_SCHUMACHER_SBIN_DIR)/prtdiag
USR_SCHUMACHER_SBIN_TRAPSTAT = $(USR_SCHUMACHER_SBIN_DIR)/trapstat
USR_SCHUMACHER_SBIN_FRUADM = $(USR_SCHUMACHER_SBIN_DIR)/fruadm
diff --git a/usr/src/uts/sun4u/schumacher/Makefile.targ b/usr/src/uts/sun4u/schumacher/Makefile.targ
index 799d5c596c..2864ec75db 100644
--- a/usr/src/uts/sun4u/schumacher/Makefile.targ
+++ b/usr/src/uts/sun4u/schumacher/Makefile.targ
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -19,7 +18,7 @@
#
# CDDL HEADER END
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -67,9 +66,6 @@ $(USR_SCHUMACHER_INC_DIR): $(USR_SCHUMACHER_DIR)
$(USR_SCHUMACHER_SBIN_DIR): $(USR_SCHUMACHER_DIR)
-$(INS.dir.root.bin)
-$(USR_SCHUMACHER_SBIN_EEPROM): $(USR_SCHUMACHER_SBIN_DIR)
- $(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/sbin/eeprom $@ $(CHOWNLINK) $(CHGRPLINK)
-
$(USR_SCHUMACHER_SBIN_PRTDIAG): $(USR_SCHUMACHER_SBIN_DIR)
$(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/sbin/prtdiag $@ $(CHOWNLINK) $(CHGRPLINK)
diff --git a/usr/src/uts/sun4u/seattle/Makefile b/usr/src/uts/sun4u/seattle/Makefile
index c8222eb676..60e3ed6d6a 100644
--- a/usr/src/uts/sun4u/seattle/Makefile
+++ b/usr/src/uts/sun4u/seattle/Makefile
@@ -20,7 +20,7 @@
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -79,7 +79,6 @@ SEATTLE_CRYPTO_LINKS += aes256
install: $(ROOT_SEATTLE_DIR) \
$(USR_SEATTLE_DIR) \
$(USR_SEATTLE_INC_DIR) \
- $(USR_SEATTLE_SBIN_EEPROM) \
$(USR_SEATTLE_SBIN_PRTDIAG) \
$(USR_SEATTLE_SBIN_TRAPSTAT) \
$(USR_SEATTLE_SBIN_FRUADM) \
diff --git a/usr/src/uts/sun4u/seattle/Makefile.seattle b/usr/src/uts/sun4u/seattle/Makefile.seattle
index 1f0f3305d7..b88d6b4647 100644
--- a/usr/src/uts/sun4u/seattle/Makefile.seattle
+++ b/usr/src/uts/sun4u/seattle/Makefile.seattle
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -53,7 +53,6 @@ USR_SEATTLE_LINKED_DIR = $(USR_PLAT_DIR)/$(LINKED_PLATFORM)
USR_SEATTLE_INC_DIR = $(USR_SEATTLE_DIR)/include
USR_SEATTLE_ISYS_DIR = $(USR_SEATTLE_INC_DIR)/sys
USR_SEATTLE_SBIN_DIR = $(USR_SEATTLE_DIR)/sbin
-USR_SEATTLE_SBIN_EEPROM = $(USR_SEATTLE_SBIN_DIR)/eeprom
USR_SEATTLE_SBIN_PRTDIAG = $(USR_SEATTLE_SBIN_DIR)/prtdiag
USR_SEATTLE_SBIN_TRAPSTAT = $(USR_SEATTLE_SBIN_DIR)/trapstat
USR_SEATTLE_SBIN_FRUADM = $(USR_SEATTLE_SBIN_DIR)/fruadm
diff --git a/usr/src/uts/sun4u/seattle/Makefile.targ b/usr/src/uts/sun4u/seattle/Makefile.targ
index 6c87067a04..bb2a0ce141 100644
--- a/usr/src/uts/sun4u/seattle/Makefile.targ
+++ b/usr/src/uts/sun4u/seattle/Makefile.targ
@@ -20,7 +20,7 @@
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -67,9 +67,6 @@ $(USR_SEATTLE_INC_DIR): $(USR_SEATTLE_DIR)
$(USR_SEATTLE_SBIN_DIR): $(USR_SEATTLE_DIR)
$(INS.dir.root.bin)
-$(USR_SEATTLE_SBIN_EEPROM): $(USR_SEATTLE_SBIN_DIR)
- $(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/sbin/eeprom $@ $(CHOWNLINK) $(CHGRPLINK)
-
$(USR_SEATTLE_SBIN_PRTDIAG): $(USR_SEATTLE_SBIN_DIR)
$(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/sbin/prtdiag $@ $(CHOWNLINK) $(CHGRPLINK)
diff --git a/usr/src/uts/sun4u/snowbird/Makefile b/usr/src/uts/sun4u/snowbird/Makefile
index 3aa31a6e8a..fe7b03ed64 100644
--- a/usr/src/uts/sun4u/snowbird/Makefile
+++ b/usr/src/uts/sun4u/snowbird/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
#
#
# uts/sun4u/snowbird/Makefile
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -71,7 +70,6 @@ def all clean clobber clean.lint modlist: $(SNOWBIRD_KMODS)
install: $(ROOT_SNOWBIRD_DIR) $(USR_SNOWBIRD_DIR) \
$(USR_SNOWBIRD_INC_DIR) \
$(USR_SNOWBIRD_SBIN_DIR) \
- $(USR_SNOWBIRD_SBIN_EEPROM) \
$(USR_SNOWBIRD_SBIN_PRTDIAG) \
$(USR_SNOWBIRD_SBIN_TRAPSTAT) \
$(USR_SNOWBIRD_SBIN_FRUADM) \
diff --git a/usr/src/uts/sun4u/snowbird/Makefile.snowbird b/usr/src/uts/sun4u/snowbird/Makefile.snowbird
index fd95d912d9..830837e44e 100644
--- a/usr/src/uts/sun4u/snowbird/Makefile.snowbird
+++ b/usr/src/uts/sun4u/snowbird/Makefile.snowbird
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -66,7 +66,6 @@ ROOT_SNOWBIRD_DRV_LINK = $(ROOT_SNOWBIRD_DRV_LINK_$(CLASS))
USR_SNOWBIRD_DIR = $(USR_PLAT_DIR)/SUNW,Netra-CP2300
USR_SNOWBIRD_INC_DIR = $(USR_SNOWBIRD_DIR)/include
USR_SNOWBIRD_SBIN_DIR = $(USR_SNOWBIRD_DIR)/sbin
-USR_SNOWBIRD_SBIN_EEPROM = $(USR_SNOWBIRD_SBIN_DIR)/eeprom
USR_SNOWBIRD_SBIN_PRTDIAG = $(USR_SNOWBIRD_SBIN_DIR)/prtdiag
USR_SNOWBIRD_SBIN_TRAPSTAT = $(USR_SNOWBIRD_SBIN_DIR)/trapstat
USR_SNOWBIRD_SBIN_FRUADM = $(USR_SNOWBIRD_SBIN_DIR)/fruadm
diff --git a/usr/src/uts/sun4u/snowbird/Makefile.targ b/usr/src/uts/sun4u/snowbird/Makefile.targ
index 652dd06886..9fd2bac81a 100644
--- a/usr/src/uts/sun4u/snowbird/Makefile.targ
+++ b/usr/src/uts/sun4u/snowbird/Makefile.targ
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -89,9 +88,6 @@ $(USR_SNOWBIRD_INC_DIR): $(USR_SNOWBIRD_DIR)
$(USR_SNOWBIRD_SBIN_DIR): $(USR_SNOWBIRD_DIR)
-$(INS.dir.root.bin)
-$(USR_SNOWBIRD_SBIN_EEPROM): $(USR_SNOWBIRD_SBIN_DIR)
- $(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/sbin/eeprom $@ $(CHOWNLINK) $(CHGRPLINK)
-
$(USR_SNOWBIRD_SBIN_PRTDIAG): $(USR_SNOWBIRD_SBIN_DIR)
$(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/sbin/prtdiag $@ $(CHOWNLINK) $(CHGRPLINK)
diff --git a/usr/src/uts/sun4u/sys/cpr_impl.h b/usr/src/uts/sun4u/sys/cpr_impl.h
index 40d36129dd..9f275c3e60 100644
--- a/usr/src/uts/sun4u/sys/cpr_impl.h
+++ b/usr/src/uts/sun4u/sys/cpr_impl.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -153,7 +152,7 @@ typedef struct cpr_sun4u_machdep csu_md_t;
#define prom_map_plat(addr, pa, size) \
if (prom_map(addr, pa, size) == 0) { \
- errp("PROM_MAP failed: paddr=0x%lx\n", pa); \
+ prom_printf("PROM_MAP failed: paddr=0x%lx\n", pa); \
return (-1); \
}
diff --git a/usr/src/uts/sun4u/sys/machparam.h b/usr/src/uts/sun4u/sys/machparam.h
index 68a993761d..394079a247 100644
--- a/usr/src/uts/sun4u/sys/machparam.h
+++ b/usr/src/uts/sun4u/sys/machparam.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -166,6 +166,12 @@ extern "C" {
#define KERNELBASE ADDRESS_C(0x01000000)
/*
+ * Virtual address range available to the debugger
+ */
+#define SEGDEBUGBASE ADDRESS_C(0xedd00000)
+#define SEGDEBUGSIZE (ADDRESS_C(0xf0000000) - SEGDEBUGBASE)
+
+/*
* Define the userlimits
*/
diff --git a/usr/src/uts/sun4u/vm/mach_kpm.c b/usr/src/uts/sun4u/vm/mach_kpm.c
index e12883d4af..e39c3a26d2 100644
--- a/usr/src/uts/sun4u/vm/mach_kpm.c
+++ b/usr/src/uts/sun4u/vm/mach_kpm.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -299,8 +299,6 @@ hat_kpm_fault(struct hat *hat, caddr_t vaddr)
return (error);
}
-extern krwlock_t memsegslock;
-
/*
* memseg_hash[] was cleared, need to clear memseg_phash[] too.
*/
@@ -356,7 +354,7 @@ hat_kpm_addmem_mseg_insert(struct memseg *msp)
if (kpm_enable == 0)
return;
- ASSERT(RW_LOCK_HELD(&memsegslock));
+ ASSERT(memsegs_lock_held());
msp->nextpa = (memsegs) ? va_to_pa(memsegs) : MSEG_NULLPTR_PA;
}
@@ -372,7 +370,7 @@ hat_kpm_addmem_memsegs_update(struct memseg *msp)
if (kpm_enable == 0)
return;
- ASSERT(RW_LOCK_HELD(&memsegslock));
+ ASSERT(memsegs_lock_held());
ASSERT(memsegs);
memsegspa = va_to_pa(msp);
}
@@ -411,7 +409,7 @@ hat_kpm_delmem_mseg_update(struct memseg *msp, struct memseg **mspp)
if (kpm_enable == 0)
return;
- ASSERT(RW_LOCK_HELD(&memsegslock));
+ ASSERT(memsegs_lock_held());
if (mspp == &memsegs) {
memsegspa = (msp->next) ?
@@ -447,7 +445,7 @@ hat_kpm_split_mseg_update(struct memseg *msp, struct memseg **mspp,
if (kpm_enable == 0)
return;
- ASSERT(RW_LOCK_HELD(&memsegslock));
+ ASSERT(memsegs_lock_held());
ASSERT(msp && mid && msp->kpm_pages);
kbase = ptokpmp(msp->kpm_pbase);
diff --git a/usr/src/uts/sun4v/Makefile b/usr/src/uts/sun4v/Makefile
index 97d645f59c..0cd8f4a8f6 100644
--- a/usr/src/uts/sun4v/Makefile
+++ b/usr/src/uts/sun4v/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -81,7 +81,7 @@ check := TARGET= check
.KEEP_STATE:
-.PARALLEL: $(KMODS) $(CLOSED_KMODS) $(XMODS) $(CLOSED_XMODS) \
+.PARALLEL: $(PARALLEL_KMODS) $(CLOSED_KMODS) $(XMODS) $(CLOSED_XMODS) \
modlist modlist.sparc
# Override for CPU_KMODS... they cannot be built
diff --git a/usr/src/uts/sun4v/Makefile.sun4v.shared b/usr/src/uts/sun4v/Makefile.sun4v.shared
index 921d3ad0f5..25420469a1 100644
--- a/usr/src/uts/sun4v/Makefile.sun4v.shared
+++ b/usr/src/uts/sun4v/Makefile.sun4v.shared
@@ -42,6 +42,11 @@ PROMIF = ieee1275
PSMBASE = $(UTSBASE)/../psm
#
+# uname -m value
+#
+UNAME_M = $(PLATFORM)
+
+#
# Definitions for the platform-specific /platform directories.
#
# PLATFORMS designates those sun4v machines which have no platform
diff --git a/usr/src/uts/sun4v/os/mach_trap.c b/usr/src/uts/sun4v/os/mach_trap.c
index 6a09aa1c80..e74c26df5a 100644
--- a/usr/src/uts/sun4v/os/mach_trap.c
+++ b/usr/src/uts/sun4v/os/mach_trap.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -135,7 +134,7 @@ showregs(uint_t type, struct regs *rp, caddr_t addr, uint_t mmu_fsr)
s = spl7();
type &= ~T_USER;
- printf("%s: ", u.u_comm);
+ printf("%s: ", PTOU(curproc)->u_comm);
switch (type) {
case T_SYS_RTT_ALIGN:
diff --git a/usr/src/uts/sun4v/sys/machparam.h b/usr/src/uts/sun4v/sys/machparam.h
index 6ea07291d1..3fd034bdc5 100644
--- a/usr/src/uts/sun4v/sys/machparam.h
+++ b/usr/src/uts/sun4v/sys/machparam.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -149,6 +149,12 @@ extern "C" {
#define KERNELBASE ADDRESS_C(0x01000000)
/*
+ * Virtual address range available to the debugger
+ */
+#define SEGDEBUGBASE ADDRESS_C(0xedd00000)
+#define SEGDEBUGSIZE (ADDRESS_C(0xf0000000) - SEGDEBUGBASE)
+
+/*
* Define the userlimits
*/
diff --git a/usr/src/xmod/xmod_files b/usr/src/xmod/xmod_files
index 613a6e60a9..30721f2f0a 100644
--- a/usr/src/xmod/xmod_files
+++ b/usr/src/xmod/xmod_files
@@ -28,8 +28,8 @@
../closed/uts/intel/adpu320
../closed/uts/intel/io/lsimega
../closed/uts/intel/lsimega
-../closed/uts/i86pc/spwr
-../closed/uts/i86pc/io/spwr
+../closed/uts/intel/spwr
+../closed/uts/intel/io/spwr
cmd/openssl
cmd/ssh
common/net/wanboot