Subject: port-i386/6928: i386 SMP
To: None <gnats-bugs@gnats.netbsd.org>
From: Stefan Grefen <grefen@hprc.tandem.com>
List: netbsd-bugs
Date: 02/02/1999 15:45:14
>Number:         6928
>Category:       port-i386
>Synopsis:       AP processor bootstrap
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    port-i386-maintainer (NetBSD/i386 Portmaster)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Feb  2 06:35:00 1999
>Last-Modified:
>Originator:     Stefan Grefen
>Organization:
Stefan Grefen                                Tandem Computers Europe Inc.
grefen@hprc.tandem.com                       High Performance Research Center
 --- Hacking's just another word for nothing left to kludge. ---
>Release:        NetBSD-current 01 Feb 1999
>Environment:
	
System: NetBSD hrriss 1.3H NetBSD 1.3H (HRRISS) #13: Wed Oct 28 13:35:10 CET 1998 grefen@hrriss:/old/usr/src/sup/src/sys/arch/i386/compile/HRRISS i386


>Description:
	Bootstrap suuport for SMP system based on intel MP spec
>How-To-Repeat:
	
>Fix:
*** /usr/sup/src/sys/arch/i386/./conf/files.i386	Fri Jan 29 13:15:42 1999
--- ././conf/files.i386	Tue Feb  2 15:07:09 1999
***************
*** 56,61 ****
--- 56,62 ----
  file	arch/i386/i386/trap.c
  file	arch/i386/i386/vm_machdep.c
  file	dev/cons.c
+ file	arch/i386/i386/multiprocessor.s  xxmp
  major	{vnd = 14}
  
  #
***************
*** 236,241 ****
--- 237,256 ----
  attach apm at mainbus
  file	arch/i386/i386/apm.c		apm needs-count
  file	arch/i386/i386/apmcall.s	apm
+ 
+ # Intel SMP specification 1.4
+ device itlmps {id = -1}
+ attach itlmps at mainbus
+ file    arch/i386/i386/mp_ispec.c       itlmps
+ 
+ # CPUS
+ device cpu
+ attach cpu at itlmps
+ file	arch/i386/i386/cpu.c		cpu
+ #apics
+ device apic
+ attach apic at itlmps
+ file	arch/i386/i386/apic.c		apic
  
  #
  # Compatibility modules
*** /dev/null	Sun Jan 31 22:45:35 1999
--- ././conf/PIIMP	Tue Feb  2 14:32:57 1999
***************
*** 0 ****
--- 1,594 ----
+ 
+ #
+ #	GENERIC -- everything that's currently supported
+ #
+ 
+ include "arch/i386/conf/std.i386"
+ 
+ maxusers	32		# estimated number of users
+ 
+ # CPU support.  At least one is REQUIRED.
+ options 	I386_CPU
+ options 	I486_CPU
+ options 	I586_CPU
+ options 	I686_CPU
+ options 	XXMP
+ 
+ # CPU-related options.
+ options 	MATH_EMULATE	# floating point emulation
+ #options 	VM86		# virtual 8086 emulation
+ options 	USER_LDT	# user-settable LDT; used by WINE
+ # eliminate delay no-ops in I/O; recommended on all but very old machines
+ #options 	DUMMY_NOPS
+ 
+ # delay between "rebooting ..." message and hardware reset, in milliseconds
+ #options 	CPURESET_DELAY=2000
+ 
+ # Misc. i386-specific options
+ options 	XSERVER		# X server support in console drivers
+ #options 	XSERVER_DDB	# PF12 gets you into DDB when X is running
+ 
+ # This option allows you to force a serial console at the specified
+ # I/O address.   see console(4) for details.
+ #options 	"CONSDEVNAME=\"com\"",CONADDR=0x2f8,CONSPEED=57600
+ #	you don't want the option below ON iff you are using the
+ #	serial console option of the new boot strap code.
+ #options	CONS_OVERRIDE	# Always use above! independent of boot info
+ 
+ # The following options override the memory sizes passed in from the boot
+ # block.  Use them *only* if the boot block is unable to determine the correct
+ # values.  Note that the BIOS may *correctly* report less than 640k of base
+ # memory if the extended BIOS data area is located at the top of base memory
+ # (as is the case on most recent systems).
+ #options 	REALBASEMEM=639		# size of base memory (in KB)
+ #options 	REALEXTMEM=15360	# size of extended memory (in KB)
+ 
+ # Standard system options
+ 
+ options 	UCONSOLE	# users can use TIOCCONS (for xconsole)
+ options 	INSECURE	# disable kernel security levels
+ 
+ options 	RTC_OFFSET=0	# hardware clock is this many mins. west of GMT
+ #options 	NTP		# NTP phase/frequency locked loop
+ 
+ options 	KTRACE		# system call tracing via ktrace(1)
+ 
+ options 	SYSVMSG		# System V-like message queues
+ options 	SYSVSEM		# System V-like semaphores
+ options 	SYSVSHM		# System V-like memory sharing
+ #options 	SHMMAXPGS=1024	# 1024 pages is the default
+ 
+ options 	LKM		# loadable kernel modules
+ 
+ # Diagnostic/debugging support options
+ options 	DIAGNOSTIC	# cheap kernel consistency checks
+ #options 	DEBUG		# expensive debugging checks/support
+ #options 	KMEMSTATS	# kernel memory statistics (vmstat -m)
+ options 	DDB		# in-kernel debugger
+ options 	DDB_HISTORY_SIZE=100	# enable history editing in DDB
+ #options 	KGDB		# remote debugger
+ #options 	"KGDB_DEVNAME=\"com\"",KGDBADDR=0x3f8,KGDBRATE=9600
+ #makeoptions	DEBUG="-g"	# compile full symbol table
+ 
+ # Compatibility options
+ options 	COMPAT_NOMID	# compatibility with 386BSD, BSDI, NetBSD 0.8,
+ options 	COMPAT_09	# NetBSD 0.9,
+ options 	COMPAT_10	# NetBSD 1.0,
+ options 	COMPAT_11	# NetBSD 1.1,
+ options 	COMPAT_12	# NetBSD 1.2,
+ options 	COMPAT_13	# NetBSD 1.3,
+ options 	COMPAT_43	# and 4.3BSD
+ options 	COMPAT_386BSD_MBRPART # recognize old partition ID
+ 
+ options 	COMPAT_SVR4	# binary compatibility with SVR4
+ options 	COMPAT_IBCS2	# binary compatibility with SCO and ISC
+ options 	COMPAT_LINUX	# binary compatibility with Linux
+ options 	COMPAT_FREEBSD	# binary compatibility with FreeBSD
+ 
+ # Executable format options
+ options 	EXEC_ELF32	# 32-bit ELF executables (SVR4, Linux)
+ 
+ # File systems
+ file-system 	FFS		# UFS
+ #file-system 	EXT2FS		# second extended file system (linux)
+ file-system 	LFS		# log-structured file system
+ file-system 	MFS		# memory file system
+ file-system 	NFS		# Network File System client
+ file-system 	CD9660		# ISO 9660 + Rock Ridge file system
+ file-system 	MSDOSFS		# MS-DOS file system
+ file-system 	FDESC		# /dev/fd
+ file-system 	KERNFS		# /kern
+ file-system 	NULLFS		# loopback file system
+ file-system 	PORTAL		# portal filesystem (still experimental)
+ file-system 	PROCFS		# /proc
+ file-system 	UMAPFS		# NULLFS + uid and gid remapping
+ file-system 	UNION		# union file system
+ file-system	CODA		# Coda File System; also needs vcoda (below)
+ 
+ # File system options
+ options 	QUOTA		# UFS quotas
+ #options 	FFS_EI		# FFS Endian Independant support
+ options 	NFSSERVER	# Network File System server
+ #options 	EXT2FS_SYSTEM_FLAGS # makes ext2fs file flags (append and
+ 				# immutable) behave as system flags.
+ 
+ # Networking options
+ #options 	GATEWAY		# packet forwarding
+ options 	INET		# IP + ICMP + TCP + UDP
+ #options 	MROUTING	# IP multicast routing
+ #options 	NS		# XNS
+ #options 	NSIP		# XNS tunneling over IP
+ #options 	ISO,TPIP	# OSI
+ #options 	EON		# OSI tunneling over IP
+ #options 	CCITT,LLC,HDLC	# X.25
+ #options 	NETATALK	# AppleTalk networking protocols
+ #options 	PPP_BSDCOMP	# BSD-Compress compression support for PPP
+ #options 	PPP_DEFLATE	# Deflate compression support for PPP
+ #options 	PPP_FILTER	# Active filter support for PPP (requires bpf)
+ #options 	PFIL_HOOKS	# pfil(9) packet filter hooks
+ #options 	IPFILTER_LOG	# ipmon(8) log support
+ 
+ # Compatibility with 4.2BSD implementation of TCP/IP.  Not recommended.
+ #options 	TCP_COMPAT_42
+ 
+ # These options enable verbose messages for several subsystems.
+ # Warning, these may compile large string tables into the kernel!
+ options 	EISAVERBOSE	# verbose EISA device autoconfig messages
+ options 	PCIVERBOSE	# verbose PCI device autoconfig messages
+ #options 	PCMCIAVERBOSE	# verbose PCMCIA configuration messages
+ options 	SCSIVERBOSE	# human readable SCSI error messages
+ options 	USBVERBOSE	# verbose USB device autoconfig messages
+ 
+ options 	NFS_BOOT_BOOTP,NFS_BOOT_BOOTPARAM
+ 
+ # Kernel root file system and dump configuration.
+ config		netbsd	root on ? type ?
+ #config		netbsd	root on sd0a type ffs
+ #config		netbsd	root on ? type nfs
+ 
+ #
+ # Device configuration
+ #
+ 
+ mainbus0 at root
+ 
+ itlmps0 at mainbus0
+ apm0	at mainbus0			# Advanced power management
+ #cpu*   at mainbus0
+ cpu* 	at itlmps0 id ?
+ apic* 	at itlmps0 id ?
+ 
+ # Basic Bus Support
+ 
+ # PCI bus support
+ pci*	at mainbus? bus ?
+ pci*	at pchb? bus ?
+ pci*	at ppb? bus ?
+ 
+ # PCI bridges
+ pchb*	at pci? dev ? function ?	# PCI-Host bridges
+ pceb*	at pci? dev ? function ?	# PCI-EISA bridges
+ pcib*	at pci? dev ? function ?	# PCI-ISA bridges
+ ppb*	at pci? dev ? function ?	# PCI-PCI bridges
+ # XXX 'puc's aren't really bridges, but there's no better place for them here
+ puc*	at pci? dev ? function ?	# PCI "universal" comm. cards
+ 
+ # EISA bus support
+ eisa*	at mainbus?
+ eisa*	at pceb?
+ 
+ # ISA bus support
+ isa*	at mainbus?
+ isa*	at pceb?
+ isa*	at pcib?
+ 
+ # PCMCIA bus support
+ pcmcia*	at pcic? controller ? socket ?
+ 
+ # ISA PCMCIA controllers
+ pcic0	at isa? port 0x3e0 iomem 0xd0000 iosiz 0x4000
+ pcic1	at isa? port 0x3e2 iomem 0xd4000 iosiz 0x4000
+ 
+ # PCI PCMCIA controllers
+ #pcic0	at pci? dev? function ?
+ 
+ # ISA Plug-and-Play bus support
+ isapnp0	at isa?
+ 
+ # ISA Plug-and-Play PCMCIA controllers
+ pcic*	at isapnp?
+ 
+ # Coprocessor Support
+ 
+ # Math Coprocessor support
+ npx0	at isa? port 0xf0 irq 13	# x86 math coprocessor
+ 
+ 
+ # Console Devices
+ 
+ # ISA console.  You can only configure one of these!
+ pc0	at isa? port 0x60 irq 1		# pccons generic PC console driver
+ #vt0	at isa? port 0x60 irq 1		# PCVT console driver
+ 
+ # Keyboard layout configuration for pccons
+ #options 	FRENCH_KBD
+ #options 	FINNISH_KBD
+ #options 	GERMAN_KBD
+ #options 	NORWEGIAN_KBD
+ 
+ pcppi0	at isa?
+ sysbeep0	at pcppi?
+ 
+ # Serial Devices
+ 
+ # PCI serial interfaces
+ #com*	at puc? port ?			# 16x450s on "universal" comm boards
+ #cy*	at pci? dev ? function ?	# Cyclades Cyclom-Y serial boards
+ 
+ # ISA Plug-and-Play serial interfaces
+ #com*	at isapnp?			# Modems and serial boards
+ 
+ # PCMCIA serial interfaces
+ com*	at pcmcia? function ?		# Modems and serial cards
+ 
+ pcmcom*	at pcmcia? function ?		# PCMCIA multi-port serial cards
+ com*	at pcmcom? slave ?		# ...and the slave devices
+ 
+ # ISA serial interfaces
+ #options 	COM_HAYESP		# adds Hayes ESP serial board support
+ com0	at isa? port 0x3f8 irq 4	# Standard PC serial ports
+ com1	at isa? port 0x2f8 irq 3
+ com2	at isa? port 0x3e8 irq 5
+ #com3	at isa? port 0x2e8 irq 9
+ #ast0	at isa? port 0x1a0 irq 5	# AST 4-port serial cards
+ #com*	at ast? slave ?
+ #boca0	at isa? port 0x100 irq 5	# BOCA 8-port serial cards
+ #com*	at boca? slave ?
+ #tcom0	at isa? port 0x100 irq 7	# TC-800 8-port serial cards
+ #com*	at tcom? slave ?
+ #rtfps0	at isa? port 0x1230 irq 10	# RT 4-port serial cards
+ #com*	at rtfps? slave ?
+ #cy0	at isa? iomem 0xd4000 irq 12	# Cyclades serial cards
+ 
+ 
+ # Parallel Printer Interfaces
+ 
+ # PCI parallel printer interfaces
+ #lpt*	at puc? port ?			# || ports on "universal" comm boards
+ 
+ # ISA parallel printer interfaces
+ lpt0	at isa? port 0x378 irq 7	# standard PC parallel ports
+ lpt1	at isa? port 0x278
+ lpt2	at isa? port 0x3bc
+ 
+ 
+ # SCSI Controllers and Devices
+ 
+ # PCI SCSI controllers
+ #adv*	at pci? dev ? function ?	# AdvanSys 1200[A,B], 9xx[U,UA] SCSI
+ #adw*	at pci? dev ? function ?	# AdvanSys 9xxUW SCSI
+ #ahc*	at pci? dev ? function ?	# Adaptec [23]94x, aic78x0 SCSI
+ #bha*	at pci? dev ? function ?	# BusLogic 9xx SCSI
+ #isp*	at pci? dev ? function ?	# Qlogic ISP [12]0x0 SCSI/FibreChannel
+ ncr*	at pci? dev ? function ?	# NCR 53c8xx SCSI
+ 
+ # EISA SCSI controllers
+ #jahb*	at eisa? slot ?			# Adaptec 174[02] SCSI
+ #ajhc*	at eisa? slot ?			# Adaptec 274x, aic7770 SCSI
+ #bha*	at eisa? slot ?			# BusLogic 7xx SCSI
+ #uha*	at eisa? slot ?			# UltraStor 24f SCSI
+ 
+ # PCMCIA SCSI controllers
+ aic*	at pcmcia? function ?		# Adaptec APA-1460 SCSI
+ 
+ # ISA Plug-and-Play SCSI controllers
+ #aha*	at isapnp? 			# Adaptec AHA-154[02
+ #aic*	at isapnp?			# Adaptec AHA-1520B
+ 
+ # ISA SCSI controllers
+ #aha0	at isa? port 0x330 irq ? drq ?	# Adaptec 154[02] SCSI
+ #aha1	at isa? port 0x334 irq ? drq ?
+ #ahc0	at isa? port ? irq ?		# Adaptec 284x SCSI
+ #aic0	at isa? port 0x340 irq 11	# Adaptec 152[02] SCSI
+ #bha0	at isa? port 0x330 irq ? drq ?	# BusLogic [457]4X SCSI
+ #bha1	at isa? port 0x334 irq ? drq ?
+ #nca0	at isa? port 0x360 irq 15	# Port-mapped NCR 53C80 contoller
+ #nca1	at isa? iomem 0xd8000 irq 5	# Memory-mapped controller (T128, etc.)
+ #sea0	at isa? iomem 0xc8000 irq 5	# Seagate/Future Domain SCSI
+ #uha0	at isa? port 0x330 irq ? drq ?	# UltraStor [13]4f SCSI
+ #uha1	at isa? port 0x340 irq ? drq ?
+ #wds0	at isa? port 0x350 irq 15 drq 6	# WD7000 and TMC-7000 controllers
+ #wds1	at isa? port 0x358 irq 11 drq 5
+ 
+ # SCSI bus support
+ #scsibus* at adv?
+ #scsibus* at adw?
+ #scsibus* at aha?
+ #scsibus* at ahb?
+ #scsibus* at ahc?
+ #scsibus* at aic?
+ #scsibus* at bha?
+ #scsibus* at isp?
+ #scsibus* at nca?
+ scsibus* at ncr?
+ #scsibus* at sea?
+ #scsibus* at uha?
+ #scsibus* at wds?
+ 
+ # SCSI devices
+ sd*	at scsibus? target ? lun ?	# SCSI disk drives
+ st*	at scsibus? target ? lun ?	# SCSI tape drives
+ cd*	at scsibus? target ? lun ?	# SCSI CD-ROM drives
+ ch*	at scsibus? target ? lun ?	# SCSI autochangers
+ ss*	at scsibus? target ? lun ?	# SCSI scanners
+ uk*	at scsibus? target ? lun ?	# SCSI unknown
+ 
+ 
+ # IDE and Related Devices
+ # PCI IDE controllers (CMD tech's PCI0640, Intel's PIIx, ...).
+ # The 0x0001 flag force the driver to use DMA, even if the driver doesn't know
+ # how to set up DMA modes for this chip. This may work, or may cause
+ # a machine hang with some controllers.
+ pciide* at pci ? dev ? function ? flags 0x0000
+ 
+ # ISA Plug-and-Play IDE controllers
+ wdc*	at isapnp? 
+ 
+ # PCMCIA IDE controllers
+ wdc*	at pcmcia? function ?
+ 
+ # ISA ST506, ESDI, and IDE controllers
+ wdc0	at isa? port 0x1f0 irq 14
+ wdc1	at isa? port 0x170 irq 15
+ 
+ # IDE drives.
+ # Flags are used only with controlers that support DMA operations
+ # and mode settings (e.g. some pciide controllers)
+ # The first 4 bytes of the flags define the PIO mode to use, the
+ # second DMA mode and the third UltraDMA mode. For each group of 4 bytes,
+ # the 3 lower define the mode to use, and the last one must be 1 for the
+ # setting to be used. For DMA and UDMA, 0xf means 'disable'.
+ # 0x0fac means 'use PIO mode 4 DMA mode 2, disable UltraDMA'.
+ # 0x0000 means "use whatever the drive claims to support.
+ wd*	at wdc? channel ? drive ? flags 0x0000
+ wd*	at pciide? channel ? drive ? flags 0x0000
+ 
+ # ATAPI bus support
+ atapibus* at wdc? channel ?
+ atapibus* at pciide? channel ?
+ 
+ # ATAPI devices
+ # flags have the same meaning as for IDE drives.
+ cd*	at atapibus? drive ? flags 0x0000	# ATAPI CD-ROM drives
+ sd*	at atapibus? drive ? flags 0x0000	# ATAPI disk drives
+ uk*	at atapibus? drive ? flags 0x0000	# ATAPI unknown
+ 
+ 
+ # Miscellaneous mass storage devices
+ 
+ # ISA floppy
+ fdc0	at isa? port 0x3f0 irq 6 drq 2	# standard PC floppy controllers
+ #fdc1	at isa? port 0x370 irq ? drq ?
+ fd*	at fdc? drive ?			# the drives themselves
+ # some machines need you to do this instead of fd*
+ #fd0	at fdc0 drive 0
+ 
+ # ISA CD-ROM devices
+ #mcd0	at isa? port 0x300 irq 10	# Mitsumi CD-ROM drives
+ 
+ # ISA tape devices
+ # note: the wt driver conflicts unpleasantly with SMC boards at the
+ # same I/O address. The probe reprograms their EEPROMs. Don't
+ # uncomment it unless you are actually using it.
+ #wt0	at isa? port 0x308 irq 5 drq 1	# Archive and Wangtek QIC tape drives
+ 
+ 
+ # Network Interfaces
+ 
+ # PCI network interfaces
+ de*	at pci? dev ? function ?	# DEC 21x4x-based Ethernet
+ #en*	at pci? dev ? function ?	# ENI/Adaptec ATM
+ #ep*	at pci? dev ? function ?	# 3Com 3c59x
+ #ex*	at pci? dev ? function ?	# 3Com 90x[B]
+ #epic*	at pci? dev ? function ?	# SMC EPIC/100 Ethernet
+ #esh*	at pci? dev ? function ?	# Essential HIPPI card
+ #fpa*	at pci? dev ? function ?	# DEC DEFPA FDDI
+ #fxp*	at pci? dev ? function ?	# Intel EtherExpress PRO 10+/100B
+ #le*	at pci? dev ? function ?	# PCnet-PCI Ethernet
+ #ne*	at pci? dev ? function ?	# NE2000-compatible Ethernet
+ #tl*	at pci? dev ? function ?	# ThunderLAN-based Ethernet
+ 
+ # EISA network interfaces
+ #ep*	at eisa? slot ?			# 3Com 3c579 Ethernet
+ #fea*	at eisa? slot ?			# DEC DEFEA FDDI
+ 
+ # ISA Plug-and-Play network interfaces
+ #ep*	at isapnp?			# 3Com 3c509 Ethernet
+ #ne*	at isapnp?			# NE2000-compatible Ethernet
+ 
+ # PCMCIA network interfaces
+ ep*	at pcmcia? function ?		# 3Com 3c589 and 3c562 Ethernet
+ #mbe*	at pcmcia? function ?		# MB8696x based Ethernet
+ ne*	at pcmcia? function ?		# NE2000-compatible Ethernet
+ #sm*	at pcmcia? function ?		# Megahertz Ethernet
+ 
+ # ISA network interfaces
+ #ate0	at isa? port 0x2a0 irq ?		# AT1700
+ #cs0	at isa? port 0x300 iomem ? irq ? drq ?	# CS8900 Ethernet
+ #ec0	at isa? port 0x250 iomem 0xd8000 irq 9	# 3Com 3c503 Ethernet
+ #eg0	at isa? port 0x280 irq 9		# 3C505 ethernet cards
+ #el0	at isa? port 0x300 irq 9		# 3C501 ethernet cards
+ #ep0	at isa? port ? irq ?			# 3C509 ethernet cards
+ #ef0	at isa? port 0x360 iomem 0xd0000 irq 7	# 3C507
+ #ai0	at isa? port 0x360 iomem 0xd0000 irq 7	# StarLAN
+ #fmv0	at isa? port 0x2a0 irq ?		# FMV-180 series
+ #ix0	at isa? port 0x300 irq 10		# EtherExpress/16
+ #iy0	at isa? port 0x360 irq ?		# EtherExpress PRO 10 ISA
+ #lc0	at isa? port 0x320 iomem ? irq ?	# DEC EtherWORKS III (LEMAC)
+ ##depca0	at isa? port 0x300 iomem 0xc8000 iosiz 0x8000 irq 5	# DEPCA
+ ##le*	at depca?
+ #nele0	at isa? port 0x320 irq 9 drq 7		# NE2100
+ #le*	at nele?
+ #bicc0	at isa? port 0x320 irq 10 drq 7		# BICC IsoLan
+ #le*	at bicc?
+ #ne0	at isa? port 0x280 irq 9		# NE[12]000 ethernet cards
+ #ne1	at isa? port 0x300 irq 10
+ #sm0	at isa? port 0x300 irq 10		# SMC91C9x Ethernet
+ #we0	at isa? port 0x280 iomem 0xd0000 irq 9	# WD/SMC Ethernet
+ #we1	at isa? port 0x300 iomem 0xcc000 irq 10
+ 
+ # MII/PHY support
+ #exphy*	at mii? phy ?			# 3Com internal PHYs
+ #icsphy*	at mii? phy ?			# Integrated Circuit Systems ICS1890
+ #inphy*	at mii? phy ?			# Intel 82555 PHYs
+ #lxtphy*	at mii? phy ?			# Level One LXT-970 PHYs
+ #nsphy*	at mii? phy ?			# NS83840 PHYs
+ #qsphy*	at mii? phy ?			# Quality Semiconductor QS6612 PHYs
+ ##sqphy*	at mii? phy ?			# Seeq 80220/80221/80223 PHYs
+ #tlphy*	at mii? phy ?			# ThunderLAN PHYs
+ ukphy*	at mii? phy ?			# generic unknown PHYs
+ 
+ # USB Controller and Devices
+ 
+ # PCI USB controllers
+ uhci*	at pci?				# Universal Host Controller (Intel)
+ ohci*	at pci?				# Open Host Controller
+ 
+ # USB bus support
+ usb*	at uhci?
+ usb*	at ohci?
+ 
+ # USB Hubs
+ uhub*	at usb?
+ uhub*	at uhub? port ? configuration ? interface ?
+ 
+ # USB Mice
+ ums*	at uhub? port ? configuration ? interface ?
+ wsmouse*	at ums?
+ 
+ # USB Keyboards
+ ukbd*	at uhub? port ? configuration ? interface ?
+ wskbd*	at ukbd? console ?
+ 
+ # USB Generic HID devices
+ uhid*	at uhub? port ? configuration ? interface ?
+ 
+ # USB Printer
+ ulpt*	at uhub? port ? configuration ? interface ?
+ 
+ # USB Generic driver
+ ugen*	at uhub? port ? configuration ? interface ?
+ 
+ # Audio Devices
+ 
+ # PCI audio devices
+ #eap*	at pci? dev ? function ?	# Ensoniq AudioPCI
+ #sv*	at pci? dev ? function ?	# S3 SonicVibes
+ 
+ # ISA Plug-and-Play audio devices
+ #ess*	at isapnp?			# ESS Tech ES1887, ES1888, ES888 audio
+ #guspnp*	at isapnp?			# Gravis Ultra Sound PnP audio
+ sb*	at isapnp?			# SoundBlaster-compatible audio
+ wss*	at isapnp?			# Windows Sound System
+ #ym*	at isapnp?			# Yamaha OPL3-SA3 audio
+ 
+ # ISA audio devices
+ #aria0	at isa? port 0x290 irq 10 		# Aria
+ #gus0	at isa? port 0x220 irq 7 drq 1 drq2 6	# Gravis Ultra Sound
+ #pas0	at isa? port 0x220 irq 7 drq 1		# ProAudio Spectrum
+ #pss0	at isa? port 0x220 irq 7 drq 6  	# Personal Sound System
+ #sp0	at pss0 port 0x530 irq 10 drq 0		# 	sound port driver
+ #sb0	at isa? port 0x220 irq 5 drq 1 drq2 5	# SoundBlaster
+ #wss0	at isa? port 0x530 irq 10 drq 0	drq2 1	# Windows Sound System
+ 
+ # OPL[23] FM syntheziers
+ #opl0	at isa? port 0x388	# use only if not attached to sound card
+ #opl*	at ess?
+ opl*	at sb?
+ #opl*	at sv?
+ 
+ # USB Audio devices
+ #uaudio*	at uhub? port ? configuration ? interface ?
+ 
+ # Audio support
+ #audio*	at aria?
+ #audio*	at eap?
+ #audio*	at ess?
+ #audio*	at gus?
+ #audio*	at guspnp?
+ #audio*	at pas?
+ audio*	at sb?
+ #audio*	at sp?
+ #audio*	at sv?
+ #audio*	at uaudio?
+ audio*	at wss?
+ #audio*	at ym?
+ 
+ # MIDI support
+ midi*	at pcppi?		# MIDI interface to the PC speaker
+ midi*	at sb?			# SB MPU401 port
+ midi*	at opl?			# OPL FM synth
+ 
+ # The spkr driver provides a simple tone interface to the built in speaker.
+ #spkr0	at pcppi?		# PC speaker
+ 
+ 
+ # Mice
+ 
+ # ISA busmice
+ #lms0	at isa? port 0x23c irq 5	# Logitech bus mouse
+ #lms1	at isa? port 0x238 irq 5
+ #mms0	at isa? port 0x23c irq 5	# Microsoft InPort mouse
+ #mms1	at isa? port 0x238 irq 5
+ opms0	at pc? irq 12		# PS/2 auxiliary port mouse
+ #pms0	at vt? irq 12		# PS/2 auxiliary port mouse
+ 
+ 
+ # Joysticks
+ 
+ # ISA Plug-and-Play joysticks
+ joy*	at isapnp?			# Game ports (usually on audio cards)
+ 
+ # ISA joysticks. Probe is a little strange; add only if you have one.
+ #joy0	at isa? port 0x201
+ 
+ 
+ # Miscellaneous Devices
+ 
+ # Planetconnect Satellite receiver driver.
+ #satlink0 at isa? port 0x300 drq 1
+ 
+ 
+ # Pull in optional local configuration
+ include	"arch/i386/conf/GENERIC.local"
+ 
+ 
+ # Pseudo-Devices
+ 
+ # disk/mass storage pseudo-devices
+ pseudo-device	ccd		4	# concatenated/striped disk devices
+ #pseudo-device	raid		4	# RAIDframe disk driver
+ pseudo-device	md		1	# memory disk device (ramdisk)
+ pseudo-device	vnd		4	# disk-like interface to files
+ 
+ # network pseudo-devices
+ pseudo-device	bpfilter	8	# Berkeley packet filter
+ pseudo-device	ipfilter		# IP filter (firewall) and NAT
+ pseudo-device	loop			# network loopback
+ pseudo-device	ppp		2	# Point-to-Point Protocol
+ pseudo-device	sl		2	# Serial Line IP
+ #pseudo-device	strip		2	# Starmode Radio IP (Metricom)
+ pseudo-device	tun		2	# network tunneling over tty
+ pseudo-device	gre		2	# generic L3 over IP tunnel
+ 
+ # miscellaneous pseudo-devices
+ pseudo-device	pty		64	# pseudo-terminals
+ #pseudo-device	tb		1	# tablet line discipline
+ pseudo-device	sequencer	1	# MIDI sequencer
+ 
+ # rnd is EXPERIMENTAL at this point.
+ #pseudo-device	rnd			# /dev/random and in-kernel generator
+ #options 	RND_COM			# use "com" randomness as well (BROKEN)
+ 
+ # a pseudo device needed for Coda	# also needs CODA (above)
+ pseudo-device	vcoda		4	# coda minicache <-> venus comm.
*** /usr/sup/src/sys/arch/i386/./conf/Makefile.i386	Fri Jan 29 13:15:42 1999
--- ././conf/Makefile.i386	Tue Feb  2 15:09:47 1999
***************
*** 191,198 ****
--- 191,205 ----
  # depend on CPU configuration
  locore.o machdep.o: Makefile
  
+ mp_tramp_values.h: ${I386}/i386/multiprocessor.s  ${I386}/i386/mps2h
+ 	${I386}/i386/mps2h ${CPPFLAGS} -D_LOCORE ${I386}/i386/multiprocessor.s >mp_tramp_values.h
  	
  locore.o: ${I386}/i386/locore.s assym.h
  	${NORMAL_S}
+ 
+ multiprocessor.o:  ${I386}/i386/multiprocessor.s assym.h mp_tramp_values.h
+ 	${NORMAL_S}
+ 	
+ 
  
  %RULES
*** /dev/null	Sun Jan 31 22:45:35 1999
--- ././i386/mp_ispec.c	Tue Feb  2 12:58:57 1999
***************
*** 0 ****
--- 1,923 ----
+ /*
+  * Copyright (c) 1999 Stefan Grefen
+  *
+  * 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.
+  * 3. All advertising materials mentioning features or use of this software
+  *    must display the following acknowledgement:
+  *      This product includes software developed by Stefan Grefen.
+  * 4. The name Stefan Grefen may not be used to endorse or promote
+  *    products derived from this software without specific prior written
+  *    permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``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 TERRENCE R. LAMBERT 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.
+  */
+ /*
+  * Derived from FreeBSD's mp_machdep.c
+  */
+ /*
+  * Copyright (c) 1996, by Steve Passe
+  * All rights reserved.
+  *
+  * 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. The name of the developer may NOT be used to endorse or promote products
+  *    derived from this software without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+  *
+  *	$Id:$
+  */
+ 
+ /*
+  * The Intel MP-stuff is just one way of x386 SMP systems
+  * so only Intel MP specific stuff is here.
+  */
+ 
+ #include <sys/param.h>
+ #include <sys/systm.h>
+ #include <sys/kernel.h>
+ #include <sys/device.h>
+ #include <sys/malloc.h>
+ 
+ #include <vm/vm.h>
+ #include <vm/vm_param.h>
+ #include <vm/pmap.h>
+ #include <vm/vm_kern.h>
+ #include <vm/vm_extern.h>
+ #include <machine/specialreg.h>
+ #include <machine/cputypes.h>
+ #include <machine/cpuvar.h>
+ #include <machine/bus.h>
+ #include <machine/multiprocessor.h>
+ #include <machine/apic.h>
+ #include <machine/apicvar.h>
+ #include <dev/isa/isareg.h>
+ 
+ #include "locators.h"
+ 
+ /*
+  * imho this is dead. IS there any board that needs it ??
+  */
+ #define WARMBOOT_TARGET		0
+ #define WARMBOOT_OFF		(KERNBASE + 0x0467)
+ #define WARMBOOT_SEG		(KERNBASE + 0x0469)
+ 
+ #define BIOS_BASE		(0xf0000)
+ #define BIOS_SIZE		(0x10000)
+ #define BIOS_COUNT		(BIOS_SIZE)
+ 
+ #define CMOS_REG		(0x70)
+ #define CMOS_DATA		(0x71)
+ #define BIOS_RESET		(0x0f)
+ #define BIOS_WARM		(0x0a)
+ 
+ #define PROCENTRY_FLAG_EN	0x01
+ #define PROCENTRY_FLAG_BP	0x02
+ #define IOAPICENTRY_FLAG_EN	0x01
+ 
+ static int itlmpsmatch __P((struct device *, struct cfdata *, void *));
+ static void itlmpsattach __P((struct device *, struct device *, void *));
+ 
+ 
+ struct cfattach itlmps_ca = {
+     sizeof(struct device), itlmpsmatch, itlmpsattach
+ };
+ 
+ 
+ /* MP Floating Pointer Structure */
+ typedef struct MPFPS {
+ 	char    signature[4];
+ 	void   *pap;
+ 	u_char  length;
+ 	u_char  spec_rev;
+ 	u_char  checksum;
+ 	u_char  mpfb1;
+ 	u_char  mpfb2;
+ 	u_char  mpfb3;
+ 	u_char  mpfb4;
+ 	u_char  mpfb5;
+ }      *mpfps_t;
+ 
+ /* MP Configuration Table Header */
+ typedef struct MPCTH {
+ 	char    signature[4];
+ 	u_short base_table_length;
+ 	u_char  spec_rev;
+ 	u_char  checksum;
+ 	u_char  oem_id[8];
+ 	u_char  product_id[12];
+ 	void   *oem_table_pointer;
+ 	u_short oem_table_size;
+ 	u_short entry_count;
+ 	void   *apic_address;
+ 	u_short extended_table_length;
+ 	u_char  extended_table_checksum;
+ 	u_char  reserved;
+ }      *mpcth_t;
+ 
+ 
+ typedef struct PROCENTRY {
+ 	u_char  type;
+ 	u_char  apic_id;
+ 	u_char  apic_version;
+ 	u_char  cpu_flags;
+ 	u_long  cpu_signature;
+ 	u_long  feature_flags;
+ 	u_long  reserved1;
+ 	u_long  reserved2;
+ }      *proc_entry_ptr;
+ 
+ typedef struct BUSENTRY {
+ 	u_char  type;
+ 	u_char  bus_id;
+ 	char    bus_type[6];
+ }      *bus_entry_ptr;
+ 
+ typedef struct IOAPICENTRY {
+ 	u_char  type;
+ 	u_char  apic_id;
+ 	u_char  apic_version;
+ 	u_char  apic_flags;
+ 	void   *apic_address;
+ }      *io_apic_entry_ptr;
+ 
+ static struct IOAPICENTRY default_io_apic = {
+     2,0,1,IOAPICENTRY_FLAG_EN,(caddr_t)DEFAULT_IO_APIC_BASE
+ };
+ 
+ typedef struct INTENTRY {
+ 	u_char  type;
+ 	u_char  int_type;
+ 	u_short int_flags;
+ 	u_char  src_bus_id;
+ 	u_char  src_bus_irq;
+ 	u_char  dst_apic_id;
+ 	u_char  dst_apic_int;
+ }      *int_entry_ptr;
+ 
+ /* descriptions of MP basetable entries */
+ typedef struct BASETABLE_ENTRY {
+ 	u_char  type;
+ 	u_char  length;
+ 	char    name[16];
+ }       basetable_entry;
+ 
+ struct mp_float_loc {
+     paddr_t	loc;
+     size_t	len;
+     int 	scan;
+     mpfps_t	mpfps;
+     mpcth_t	cth;
+ 
+ };
+ 
+ static int	search_for_sig(caddr_t target, int count, struct mp_float_loc *);
+ static int imp_chksum(void *p,int len);
+ 
+ static char *scan2name[] = {
+    "???", "EBDA","basemem","BIOS"
+ };
+ 
+ static struct mp_float_loc loc = { 0, 0, 0};
+ 
+ int itlmps_verbose = 0;
+ 
+ static struct mp_info _mpi, *mpi = &_mpi;
+ 
+ int mp_print __P((void *, const char *));
+ int mp_match __P((struct device *,struct cfdata *,void *));
+ int itlmpscpustart __P((struct cpu_softc *));
+ 
+ struct cpu_functions itlmpsf = { itlmpscpustart, NULL };
+ 
+ 
+ int mp_probe(void);
+ extern char *vmmap; 
+ int     i386_mem_add_mapping __P((bus_addr_t, bus_size_t,
+             int, bus_space_handle_t *));
+ 
+ struct mp_info * mptable_scan(struct mp_float_loc *loc, struct device *);
+ 
+ static int
+ itlmpsmatch(parent, match, aux)
+         struct device *parent;
+         struct cfdata *match;
+         void *aux;
+ {
+     const char **name = (const char **)aux;
+ 
+     if (strcmp(*name, "itlmps"))
+ 	return 0;
+     return mp_probe();
+ }
+ 
+ int
+ mp_print(aux, pnp)
+ 	void *aux;
+ 	const char *pnp;
+ {
+     struct mp_attach_arg * maa = (struct mp_attach_arg *) aux;
+     char *what;
+     switch (maa->type) {
+ 	case MP_CPU: what = "cpu"; break;
+ 	case MP_IO_APIC: what = "apic"; break;
+ 	default: what = "unkown"; break;
+     }
+     if (pnp)
+ 	printf("%s at %s:",what, pnp);
+     return (UNCONF);
+ }
+ 
+ int
+ mp_match(parent, cf, aux)
+ 	struct device *parent;
+ 	struct cfdata *cf;
+ 	void *aux;
+ {
+     struct mp_attach_arg * maa = (struct mp_attach_arg *) aux;
+ 
+     if (cf->cf_loc[ITLMPSCF_ID] != ITLMPSCF_ID_DEFAULT &&
+ 	cf->cf_loc[ITLMPSCF_ID] != maa->id )
+ 	    return 0;
+     return ((*cf->cf_attach->ca_match)(parent, cf, aux));
+ }
+ 
+ int
+ itlmpscpustart(struct cpu_softc *csc) {
+     int error;
+ 
+     if (csc->bp) {
+ 	extern u_char cpu_spinup_trampoline[],cpu_spinup_trampoline_end[];
+ 
+ 
+ 	/*
+ 	 * Copy boot code 
+ 	 */
+ #if defined(PMAP_NEW)
+ 	pmap_kenter_pa((vaddr_t)MP_TRAMPOLINE,	/* virtual */
+ 	       (paddr_t)MP_TRAMPOLINE,	/* physical */
+ 	       VM_PROT_ALL);		/* protection */
+ #else
+ 	pmap_enter(pmap_kernel(),
+ 	       (vaddr_t)MP_TRAMPOLINE,	/* virtual */
+ 	       (paddr_t)MP_TRAMPOLINE,	/* physical */
+ 	       VM_PROT_ALL,		/* protection */
+ 	       TRUE);			/* wired down */
+ #endif
+ 	memcpy((caddr_t)MP_TRAMPOLINE, 
+ 	    cpu_spinup_trampoline, 
+ 	    cpu_spinup_trampoline_end-cpu_spinup_trampoline);
+ 
+ 	/*
+ 	 * Map local apic
+ 	 */
+ 	pmap_enter(pmap_kernel(),(vaddr_t)&local_apic,mpi->cpu_apic_address,
+ 	    VM_PROT_ALL, 1);
+ 	return 0;
+     } else if (csc->ap) {
+ 	if ((error = i386_init(csc->sc_cpuid)) != 0)
+ 	    return error;
+ 
+ 	if ((error = i386_ipi(MP_TRAMPOLINE/NBPG,csc->sc_cpuid,
+ 					    APIC_DELMODE_STARTUP)) != 0)
+ 	return error;
+     } else {
+ 	return 0;
+     }
+ 
+     return 0;
+ }
+ 
+ 
+ static void 
+ itlmpsattach (parent, self, aux)
+         struct device *parent, *self;
+ 	void *aux;
+ {
+ 	printf (": Intel SMP specification (Rev. %d.%d)\n  found at 0x%x in %s[%d]\n  Board OEMId [%8.8s] ProdId [%8.8s]\n"
+ 	    , loc.mpfps->spec_rev
+ 	    , loc.cth->spec_rev
+ 	    , (unsigned int)loc.loc
+ 	    , scan2name[loc.scan]
+ 	    , loc.len
+ 	    , loc.cth->oem_id
+ 	    , loc.cth->product_id);
+ 	mptable_scan(&loc, self);
+ }
+ 
+ /*
+  * Look for an Intel MP spec table (ie, SMP capable hardware).
+  * vmmap is initialized, but not used yet (no need for locking) .
+  */
+ int
+ mp_probe(void)
+ {
+ 	caddr_t  ebda,memtop;
+ 
+ 	if (loc.scan != 0 )  {
+ 	    return 1;
+ 	}
+ 
+ 
+ 	/* see if EBDA exists */
+ 	pmap_kenter_pa((vaddr_t)vmmap, 0,VM_PROT_READ);
+ 
+ 	ebda =  (caddr_t) ((* (u_short *) ((vaddr_t)vmmap + 0x40e))<<4);
+ 	memtop =  (caddr_t) ((* (u_short *) ((vaddr_t)vmmap + 0x413))<<10);
+ 
+ 	pmap_kremove((vaddr_t)vmmap, NBPG);
+ 
+ 	loc.scan = 1;
+ 
+ 	if (ebda && ebda <(caddr_t)IOM_BEGIN ) {
+ 	    if (search_for_sig(ebda, 1024, &loc )) {
+ 		goto found;
+ 	    } 
+ 	}
+ 
+ 	loc.scan = 2;
+ 
+ 	if (memtop && memtop < (caddr_t)IOM_BEGIN ) {
+ 	    if (search_for_sig(memtop - 1024, 1024, &loc)) {
+ 		goto found;
+ 	    } 
+ 	}
+ 
+ 	loc.scan = 3;
+ 	
+ 	/* search the BIOS */
+ 	if (search_for_sig((caddr_t)BIOS_BASE, BIOS_COUNT, &loc))
+ 		goto found;
+ 
+ 	/* nothing found */
+ 
+ 	loc.mpfps = (mpfps_t)0;
+ 	return 0;
+ 
+ found:
+ 	/*
+ 	 * found a MP float structure
+ 	 * now map it
+ 	 */
+ 	if (i386_mem_add_mapping(loc.loc, loc.len,BUS_SPACE_MAP_CACHEABLE,
+ 			     (bus_space_handle_t *)&loc.mpfps)) {
+ 	    printf ("can't map MP float structure\n");
+ 	    return 0;
+ 	}
+ 	if(itlmps_verbose)
+ 	    printf("found floating structure at  %lx[%d] -> %p\n",loc.loc,loc.len,loc.mpfps);
+ 	if (loc.mpfps->pap) {
+ 	    mpcth_t cth = loc.mpfps->pap;
+ 	    pmap_kenter_pa((vaddr_t)vmmap, 
+ 				i386_trunc_page(&(cth->base_table_length)), VM_PROT_READ);
+ 	    cth = (mpcth_t) ((caddr_t)vmmap) + (((int)cth) &PGOFSET);
+ 
+ 	    if(itlmps_verbose)
+ 		printf("Config table at %p[%d] -> %p\n",loc.mpfps->pap,cth->base_table_length,cth);
+ 	    if (imp_chksum(loc.mpfps->pap, cth->base_table_length)) {
+ 		printf ("Warning: Configuration Table checksum error\n");
+ 	    }
+ 	    if (i386_trunc_page(loc.loc) == i386_trunc_page(loc.mpfps->pap) 
+ 	     && i386_trunc_page(loc.loc) == i386_trunc_page(((caddr_t)loc.mpfps->pap)
+ 		+ cth->base_table_length))  {
+ 		loc.cth = (mpcth_t)((caddr_t)loc.mpfps + (int)(((caddr_t)loc.mpfps->pap) - loc.loc));
+ 	    } else {
+ 		if (i386_mem_add_mapping((paddr_t)loc.mpfps->pap, cth->base_table_length,
+ 				    BUS_SPACE_MAP_CACHEABLE, (bus_space_handle_t *)&loc.cth)) {
+ 		    printf ("can't map MP Configuration structure\n");
+ 		    return 0;
+ 		}
+ 	    }
+ 	    pmap_kremove((vaddr_t)vmmap, NBPG);
+ 	}
+ 
+ 	return 10;
+ }
+ 
+ 
+ /*
+  * look for the MP spec signature
+  */
+ static int     
+ imp_chksum(void *vp,int len) {
+     unsigned char res=0;
+     char *p = (char *)vp;
+     unsigned int map = i386_trunc_page(p); 
+     while(len--) {
+ 	if (i386_trunc_page(p) != map) {
+ 	    pmap_kenter_pa((vaddr_t)vmmap, (map = i386_trunc_page(p)),VM_PROT_READ);
+ 	}
+ 	res += *(((char *)vmmap) + ((unsigned)p & PGOFSET));
+ 	p++;
+     }
+     return res;
+ }
+ 
+ 
+ /* string defined by the Intel MP Spec as identifying the MP table */
+ #define MP_SIG		0x5f504d5f	/* _MP_ */
+ static int
+ search_for_sig(caddr_t target, int count, struct mp_float_loc *loc)
+ {
+ 	unsigned int  map = ~0; 
+ 	int *p = (int *)target,*end = (int *)(target + count-12);
+ 
+ 	for (p = 0; p < end; p++) {
+ 		if (i386_trunc_page(p) != map) {
+ 		    pmap_kenter_pa((vaddr_t)vmmap, 
+ 				    (map = i386_trunc_page(p)),VM_PROT_READ);
+ 		}
+ 		if (*((int *)(((caddr_t)vmmap) + ((unsigned)p & PGOFSET))) == MP_SIG) {
+ 			/*
+ 			 * enough space?
+ 			 */
+ 			if ((end - p) >=16 ){
+ 			    /*
+ 			     * checksum ??
+ 			     */
+ 			    mpfps_t m = (mpfps_t)(vmmap + ((unsigned)p & PGOFSET));
+ 			    if (i386_trunc_page(&(m->length)) != i386_trunc_page(m)) {
+ 				/*
+ 				 *grmblle
+ 				 */
+ 				pmap_kenter_pa((vaddr_t)vmmap,
+ 				    (map = i386_trunc_page(&(m->length))),VM_PROT_READ);
+ 				m = (mpfps_t)(((char *)m) - NBPG);
+ 			    }
+ 			    if (!imp_chksum(p,m->length*16))  {
+ 				loc->loc = (paddr_t)p;
+ 				loc->len = m->length*16;
+ 				pmap_kremove((vaddr_t)vmmap, NBPG);
+ 				return 1;
+ 			    }
+ 			}
+ 		}
+ 	}
+ 	pmap_kremove((vaddr_t)vmmap, NBPG);
+ 
+ 	return 0;
+ }
+ 
+ 
+ static basetable_entry basetable_entry_types[] =
+ {
+ 	{0, 20, "Processor"},
+ 	{1, 8, "Bus"},
+ 	{2, 8, "I/O APIC"},
+ 	{3, 8, "I/O INT"},
+ 	{4, 8, "Local INT"}
+ };
+ 
+ enum busTypes {
+     UNKNOWN_BUSTYPE = 0 ,
+     ISA,
+     EISA,
+     PCI,
+     CBUS,
+     CBUSII,
+     XPRESS
+ };
+ 
+ typedef struct BUSDATA {
+ 	u_char  bus_id;
+ 	enum busTypes bus_type;
+ }       bus_datum;
+ 
+ typedef struct INTDATA {
+ 	u_char  int_type;
+ 	u_short int_flags;
+ 	u_char  src_bus_id;
+ 	u_char  src_bus_irq;
+ 	u_char  dst_apic_id;
+ 	u_char  dst_apic_int;
+ 	u_char	int_vector;
+ }       io_int, local_int;
+ 
+ typedef struct BUSTYPENAME {
+ 	u_char  type;
+ 	char    name[7];
+ }       bus_type_name;
+ 
+ static bus_type_name bus_type_table[] =
+ {
+ 	{CBUS, "CBUS"},
+ 	{CBUSII, "CBUSII"},
+ 	{EISA, "EISA"},
+ 	{UNKNOWN_BUSTYPE, "---"},
+ 	{UNKNOWN_BUSTYPE, "---"},
+ 	{ISA, "ISA"},
+ 	{UNKNOWN_BUSTYPE, "---"},
+ 	{UNKNOWN_BUSTYPE, "---"},
+ 	{UNKNOWN_BUSTYPE, "---"},
+ 	{UNKNOWN_BUSTYPE, "---"},
+ 	{UNKNOWN_BUSTYPE, "---"},
+ 	{UNKNOWN_BUSTYPE, "---"},
+ 	{PCI, "PCI"},
+ 	{UNKNOWN_BUSTYPE, "---"},
+ 	{UNKNOWN_BUSTYPE, "---"},
+ 	{UNKNOWN_BUSTYPE, "---"},
+ 	{UNKNOWN_BUSTYPE, "---"},
+ 	{XPRESS, "XPRESS"},
+ 	{UNKNOWN_BUSTYPE, "---"}
+ };
+ 
+ #define MAX_BUSTYPE (sizeof(bus_type_table)/sizeof(bus_type_table[0]))
+ 
+ static int processor_entry	__P((struct mp_info *,proc_entry_ptr entry,struct device *));
+ static int bus_entry		__P((struct mp_info *,bus_entry_ptr entry,struct device *));
+ static int io_apic_entry	__P((struct mp_info *,io_apic_entry_ptr entry,struct device *));
+ static int int_entry		__P((struct mp_info *,int_entry_ptr entry));
+ static int lookup_bus_type	__P((char *name));
+ 
+ 
+ /*
+  * 1st pass on motherboard's Intel MP specification table.
+  *
+  * initializes:
+  *	mp_ncpus = 1
+  *
+  * determines:
+  *	cpu_apic_address (common to all CPUs)
+  *	io_apic_address[N]
+  *	mp_naps
+  *	mp_nbusses
+  *	mp_napics
+  *	nintrs
+  */
+ struct mp_info *
+ mptable_scan(struct mp_float_loc *loc, struct device *self)
+ {
+ 	mpcth_t	cth;
+ 	int	totalSize;
+ 	void*	position;
+ 	int	count;
+ 	int	type;
+ 	static int done = 0;
+ 
+ 	if (done) {
+ 	    printf("DONE???\n");
+ 	    return mpi;
+ 	}
+ 
+ 	/* init everything to empty */
+ 	mpi->ncpus = 0;
+ 	mpi->boot_cpu_id = 0; /* we don't ned it anyway ... */
+ 	mpi->cpu_apic_address = 0;
+ 
+ 	/* record whether PIC or virtual-wire mode */
+ 	mpi->flags = (loc->mpfps->mpfb2 & 0x80) ? MP_PICMODE : 0;
+ 	if (itlmps_verbose) {
+ 	    printf("MP mode %s\n",mpi->flags?"picmode":"virtual wire");
+ 	}
+ 
+ 
+ 	/* check for use of 'default' configuration */
+ 	if (loc->mpfps->mpfb1 != 0) {
+ 		struct PROCENTRY pe;
+ 		extern int cpu_id, cpu_feature;
+ 		/* use default addresses */
+ 		mpi->cpu_apic_address = DEFAULT_APIC_BASE;
+ 
+ 		pe.apic_id = 0;
+ 		pe.cpu_flags = PROCENTRY_FLAG_EN|PROCENTRY_FLAG_BP;
+ 		pe.cpu_signature = cpu_id;
+ 		pe.feature_flags = cpu_feature;
+ 
+ 		processor_entry(mpi, &pe, self);
+ 
+ 		pe.apic_id = 1;
+ 		pe.cpu_flags = PROCENTRY_FLAG_EN;
+ 
+ 		processor_entry(mpi, &pe, self);
+ 
+ 
+ 		io_apic_entry(mpi, &default_io_apic,self);
+ 
+ 		return mpi;
+ 	} else {
+ 		if (loc->mpfps->pap == 0) {
+ 			printf("MP Configuration Table Header MISSING!");
+ 			return NULL ;
+ 		}
+ 		cth = loc->cth;
+ 
+ 		mpi->cpu_apic_address = (paddr_t)cth->apic_address;
+ 
+ 		/* walk the table, recording info of interest */
+ 		totalSize = cth->base_table_length - sizeof(struct MPCTH);
+ 		position = (u_char *) cth + sizeof(struct MPCTH);
+ 		count = cth->entry_count;
+ 
+ 		while (count--) {
+ 			switch (type = *(u_char *) position) {
+ 			case 0: /* processor_entry */
+ 				 processor_entry(mpi, position,self);
+ 				 break;
+ 			case 1: /* bus_entry */
+ 				bus_entry(mpi, position, self);
+ 				break;
+ 			case 2: /* io_apic_entry */
+ 				io_apic_entry(mpi, position, self);
+ 				break;
+ 			case 3: /* int_entry */
+ 				int_entry(mpi, position);
+ 				break;
+ 			case 4:	/* int_entry */
+ 				break;
+ 			default:
+ 				printf("mpfps Base Table HOSED!");
+ 				/* NOTREACHED */
+ 				return NULL;
+ 			}
+ 
+ 			totalSize -= basetable_entry_types[type].length;
+ 			(u_char*)position += basetable_entry_types[type].length;
+ 		}
+ 	}
+ 
+ 	return mpi ;
+ }
+ 
+ static int
+ processor_entry(struct mp_info *mpi, proc_entry_ptr entry,struct device *self)
+ {
+ 	struct cpu_attach_args caa;
+ 	if(itlmps_verbose) {
+ 	    printf("Found CPU %d flags [%x]%s\n",
+ 		entry->apic_id,
+ 		entry->cpu_flags,
+ 		entry->cpu_flags & PROCENTRY_FLAG_BP?"BP":"AP");
+ 	}
+ 	/* check for usability */
+ 	if (!(entry->cpu_flags & PROCENTRY_FLAG_EN))
+ 		return 0;
+ 
+ 	/* check for BSP flag */
+ 	if (entry->cpu_flags & PROCENTRY_FLAG_BP) {
+ 		mpi->boot_cpu_id = entry->apic_id;
+ 		caa.bp = 1 ;
+ 	} else {
+ 		caa.ap = 1;
+ 	}
+ 
+ 	caa.type   = MP_CPU;
+ 	caa.cpu_id = entry->apic_id;
+ 	caa.cpu_func = &itlmpsf;
+ 	caa.cpu_signature = entry->cpu_signature;
+ 	caa.feature_flags = entry->feature_flags;
+ 
+ 	config_found_sm(self, &caa, mp_print, mp_match);
+ 
+ 	mpi->cpu_mask |= 1<<entry->apic_id;
+ 	mpi->ncpus++;
+ 	return 1;
+ }
+ 
+ 
+ #define TAB_UNIT	4
+ #define TAB_ROUND(a)	_TAB_ROUND(a, TAB_UNIT)
+ 
+ #define _TAB_ROUND(a,u)	(((a) + (u - 1)) & ~(u-1))
+ #define EXTEND_TAB(a,u)	(!(_TAB_ROUND(a,u) == _TAB_ROUND((a+1),u)))
+ static int
+ bus_entry(struct mp_info *mpi, bus_entry_ptr entry,struct device *self)
+ {
+ 	int     x;
+ 	char    c, name[8];
+ #if 0
+ 	struct  bus_info *bus;
+ 	union mainbus_attach_args {
+ 		const char *mba_busname;		/* first elem of all */
+ 		struct pcibus_attach_args mba_pba;
+ 		struct eisabus_attach_args mba_eba;
+ 		struct isabus_attach_args mba_iba;
+ 	} maa;
+ #endif
+ 
+ 
+ 	if(itlmps_verbose) {
+ 	    printf("Found  BUS %d type [%6.6s]\n",
+ 		entry->bus_id,
+ 		entry->bus_type);
+ 	}
+ 	/* encode the name into an index */
+ 	for (x = 0; x < 6; ++x) {
+ 		if ((c = entry->bus_type[x]) == ' ')
+ 			break;
+ 		name[x] = c;
+ 	}
+ 	name[x] = '\0';
+ 
+ 	if ((x = lookup_bus_type(name)) == UNKNOWN_BUSTYPE) {
+ 		printf("unknown bus type: '%s'", name);
+ 		return 0; /* ignore  */
+ 	}
+ #if 0
+ 	switch (x->type) {
+ 	    case PCI: if (pci_mode_detect() != 0) {
+ 		extern int pci_seen;
+ 		mba.mba_pba.pba_busname = "pci";
+ 		mba.mba_pba.pba_iot = I386_BUS_SPACE_IO;
+ 		mba.mba_pba.pba_memt = I386_BUS_SPACE_MEM;
+ 		mba.mba_pba.pba_dmat = &pci_bus_dma_tag;
+ 		mba.mba_pba.pba_flags = pci_bus_flags();
+ 		mba.mba_pba.pba_bus = entry->bus_id ;		/* TODO fix busid's for bad bioses */
+ 		config_found(self, &mba.mba_pba, mp_print);
+ 		pci_seen = 1;
+ 	    } 
+ 	    break;
+ 	    case EISA: {
+ 		extern int eisa_has_been_seen;
+ 		if (memcmp(ISA_HOLE_VADDR(EISA_ID_PADDR), EISA_ID, EISA_ID_LEN) == 0 &&
+ 		    eisa_has_been_seen == 0) {
+ 			mba.mba_eba.eba_busname = "eisa";
+ 			mba.mba_eba.eba_iot = I386_BUS_SPACE_IO;
+ 			mba.mba_eba.eba_memt = I386_BUS_SPACE_MEM;
+ #if NEISA > 0
+ 			mba.mba_eba.eba_dmat = &eisa_bus_dma_tag;
+ #endif
+ 			config_found(self, &mba.mba_eba, mp_print);
+ 		}
+ 	    }
+ 	    break;
+ 	    case ISA: {
+ 		extern int isa_has_been_seen;
+ 		if (isa_has_been_seen == 0) {
+ 			mba.mba_iba.iba_busname = "isa";
+ 			mba.mba_iba.iba_iot = I386_BUS_SPACE_IO;
+ 			mba.mba_iba.iba_memt = I386_BUS_SPACE_MEM;
+ #if NISA > 0
+ 			mba.mba_iba.iba_dmat = &isa_bus_dma_tag;
+ #endif
+ 			config_found(self, &mba.mba_iba, mp_print);
+ 		}
+ 	    }
+ 	    break;
+ 	}
+ #endif
+ 
+ 	return 1;
+ }
+ 
+ 
+ static int
+ io_apic_entry(struct mp_info *mpi, io_apic_entry_ptr entry,struct device *self)
+ {
+ 	struct apic_attach_args aaa;
+ 	if(itlmps_verbose) {
+ 	    printf("Found IO-APIC %d vers. %d flags [%x] at %p\n",
+ 		entry->apic_id,
+ 		entry->apic_version,
+ 		entry->apic_flags,
+ 		entry->apic_address);
+ 	}
+ 	/* encode the name into an index */
+ 	if (!(entry->apic_flags & IOAPICENTRY_FLAG_EN))
+ 		return 0;
+ 	aaa.type   = MP_IO_APIC;
+ 	aaa.apic_id = entry->apic_id;
+ 	aaa.apic_version = entry->apic_version;
+ 	aaa.apic_address = (paddr_t)entry->apic_address;
+ 
+ 	config_found_sm(self, &aaa, mp_print, mp_match);
+ 
+ 	return 1;
+ }
+ 
+ 
+ 
+ static int
+ lookup_bus_type(char *name)
+ {
+ 	int     x;
+ 
+ 	for (x = 0; x < MAX_BUSTYPE; ++x)
+ 		if (strcmp(bus_type_table[x].name, name) == 0)
+ 			return bus_type_table[x].type;
+ 
+ 	return UNKNOWN_BUSTYPE;
+ }
+ 
+ 
+ static char f2pol[] = "DHRL";
+ static char f2trg[] = "DERL";
+ static  char t2t2[] = "INSE";
+ 
+ static int
+ int_entry(struct mp_info  *mpi, int_entry_ptr entry)
+ {
+ 	struct intr_info *inti;
+ 	if(itlmps_verbose) {
+ 	    printf("Found INTR entry APIC %d.#%d Bus %d.#%d %c%c%c\n",
+ 		entry->dst_apic_id,
+ 		entry->dst_apic_int,
+ 		entry->src_bus_id,
+ 		entry->src_bus_irq,
+ 		f2pol[entry->int_flags&3],
+ 		f2trg[(entry->int_flags<<2)&3],
+ 		t2t2[entry->int_type&3]);
+ 	}
+ 
+ 	if (EXTEND_TAB(mpi->nints, 16) ) {
+ 	    struct intr_info *tmp;
+ 
+ 	    MALLOC(tmp, struct intr_info *, 
+ 		    _TAB_ROUND(mpi->nints + 1, 16) * sizeof(*tmp), 
+ 		    M_DEVBUF, M_NOWAIT);
+ 	    if (tmp == NULL) {
+ 		 printf("Can't alloc table space for a %s\n","intr");
+ 		 return 0;
+ 	    }
+ 	    memset(&tmp[_TAB_ROUND(mpi->nints,16)], 
+ 			0, 
+ 			16 * sizeof(*tmp));
+ 	    if (mpi->ints)  {
+ 		memcpy(tmp, mpi->ints, _TAB_ROUND(mpi->nints ,16) 
+ 			* sizeof(*tmp));
+ 		FREE(mpi->ints, M_DEVBUF);
+ 	    }
+ 	    mpi->ints = tmp;
+ 	}
+ 
+ 	inti = &mpi->ints[mpi->nints++];
+ 
+ 	inti->type = entry->int_type;
+ 	inti->flags = entry->int_flags;
+ 	inti->bus_irq = entry->src_bus_irq;
+ 	inti->apic_int = entry->dst_apic_int;
+ 
+ 
+ 	return 1;
+ }
+ 
+ 
+ int
+ i386_init(target)
+     int target;
+ {
+     unsigned j;
+     if((target&APIC_DEST_MASK)==0) {
+         local_apic.icr_hi=(target<<24);
+     }
+ 
+     local_apic.icr_lo= (local_apic.icr_lo&APIC_RESV2_MASK)|
+ 		(target&APIC_DEST_MASK)|APIC_TRIGMOD_LEVEL|
+ 		    APIC_LEVEL_ASSERT|APIC_DELMODE_INIT;
+     j=100000;
+     while(j--&&(local_apic.icr_lo&APIC_DELSTAT_PEND));
+ 
+     local_apic.icr_lo= (local_apic.icr_lo&APIC_RESV2_MASK)|
+ 		(target&APIC_DEST_MASK)|APIC_TRIGMOD_LEVEL|
+ 		    APIC_LEVEL_DEASSERT|APIC_DELMODE_INIT;
+     j=100000;
+     delay(10000);
+     while(j--&&(local_apic.icr_lo&APIC_DELSTAT_PEND));
+ 
+     return (local_apic.icr_lo&APIC_DELSTAT_PEND)?EBUSY:0;
+ }
+ 
+ int
+ i386_ipi(vec,target,dl)
+     int vec,target,dl;
+ {
+     unsigned j;
+     if((target&APIC_DEST_MASK)==0) {
+         local_apic.icr_hi=(target<<24);
+     }
+     local_apic.icr_lo=(target&APIC_DEST_MASK)|(vec|dl)|APIC_LEVEL_ASSERT;
+     j=100000;
+     while(j--&&(local_apic.icr_lo&APIC_DELSTAT_PEND));
+     return (local_apic.icr_lo&APIC_DELSTAT_PEND)?EBUSY:0;
+ }
+ 
+ 
*** /dev/null	Sun Jan 31 22:45:35 1999
--- ././i386/multiprocessor.s	Tue Feb  2 12:58:53 1999
***************
*** 0 ****
--- 1,181 ----
+ /*
+  * Copyright (c) 1999 Stefan Grefen
+  *
+  * 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.
+  * 3. All advertising materials mentioning features or use of this software
+  *    must display the following acknowledgement:
+  *      This product includes software developed by Stefan Grefen.
+  * 4. The name Stefan Grefen may not be used to endorse or promote
+  *    products derived from this software without specific prior written
+  *    permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``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 TERRENCE R. LAMBERT 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.
+  */
+ /*
+  * MP startup ...
+  * the stuff from cpu_spinup_trampoline to mp_startup 
+  * is copied into the first 640 KB
+  * the script mps2h defines GETVALUES and assembles the whole stuff
+  * and than uses the listing to define values for the _TRMP_LABELs
+  * These are included in the real assembly run 
+  * What we would like todo is #define _TRMP_LABEL as a expression
+  * label =  . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE, but
+  * gas can't handle it ... :-((
+  * This would eliminate the mps2sh script ...
+  */
+ #include "assym.h"
+ #include <machine/param.h>
+ #include <machine/asm.h>
+ #include <machine/specialreg.h>
+ #include <machine/segments.h>
+ #include <machine/multiprocessor.h>
+ #ifndef GETVALUES
+ #include "mp_tramp_values.h"
+ #endif
+ 
+ #define GDTE(a,b)               .byte   0xff,0xff,0x0,0x0,0x0,a,b,0x0
+ #define _RELOC(x)       ((x) - KERNBASE)
+ #define RELOC(x)        _RELOC(_C_LABEL(x))
+ 
+ #ifdef GETVALUES
+ #define _TRMP_LABEL(a)	a :
+ #else
+ #define _TRMP_LABEL(a)
+ #endif
+ 
+ #if 0
+ /*
+  * What we would like todo, but gas can't handle it ...
+  *
+ #define _TRMP_LABEL(a)  a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE
+ */
+ #endif
+ 
+ /*
+  * Debug code to stop the 2'nd processor in various stages based on the
+  * value in cpu_trace
+  */
+ #ifdef MP_DEBUG
+ #define HALT(x)	1: movl (%edi),%ebx;cmpl $ x,%ebx ; jle 1b ; movl %edi,%ebx; addl $4,%ebx; movl	$ x,(%ebx)
+ #else
+ #define HALT(x)	/**/
+ #endif
+ 
+ 	.text
+ #ifdef GETVALUES
+ 	.org MP_TRAMPOLINE
+ #endif
+ 	.align 4,0x0
+ 	.global _C_LABEL(cpu_spinup_trampoline),_C_LABEL(cpu_spinup_trampoline_end)
+ 	.global _C_LABEL(init386_ap), _C_LABEL(cpu_hatch)
+ 	.global _C_LABEL(SPTD), _C_LABEL(SPST)
+ 	.global _C_LABEL(gdt)
+ 
+ _C_LABEL(cpu_spinup_trampoline):
+ 	cli
+ 	xorl    %eax,%eax
+ 	movl    %ax, %ds
+ 	movl    %ax, %es
+ 	movl    %ax, %ss
+ 	aword
+ 	word
+ 	lgdt    (gdt_desc)      # load flat descriptor table
+ 	movl    %cr0,%eax       # get cr0
+ 	word
+ 	orl     $0x1, %eax      # enable protected mode
+ 	movl    %eax, %cr0      # doit
+ 	movl    $0x10, %eax     # data segment
+ 	movl    %ax, %ds
+ 	movl    %ax, %ss
+ 	movl    %ax, %es
+ 	movl    %ax, %fs
+ 	movl    %ax, %gs
+ 	word
+ 	ljmp    $0x8, $mp_startup
+ _TRMP_LABEL(mp_startup)
+ 	movl    $ (MP_TRAMPOLINE+NBPG-4),%esp       # bootstrap stack end location
+ #ifdef MP_DEBUG
+ 	leal    RELOC(cpu_trace),%edi       
+ #endif
+ 	HALT(0)
+ 	/* First, reset the PSL. */
+ 	pushl   $PSL_MBO
+ 	popfl
+         movl    RELOC(SPTD),%esi	# get page directory
+ 
+         /* Load base of page directory and enable mapping. */
+         movl    %esi,%eax               # phys address of ptd 
+         movl    %eax,%cr3               # load ptd addr into mmu
+         movl    %cr0,%eax               # get control word
+                                         # enable paging & NPX emulation
+         orl     $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_EM|CR0_MP|CR0_WP),%eax
+         movl    %eax,%cr0               # and let's page NOW!
+ #ifdef MP_DEBUG
+ 	leal    _C_LABEL(cpu_trace),%edi       # bootstrap stack end location
+ #endif
+ 	HALT(1)
+ 	movw    $((NGDT*8) - 1), ngdt_table	# prepare segment descriptor
+ 	movl    _C_LABEL(gdt), %eax		# for real gdt
+ 	movl    %eax, ngdt_table+2
+ 	lgdt	ngdt_table
+ 	jmp	1f
+ 	nop
+ 1:	
+ 	HALT(2)
+ 	movl    $GSEL(GDATA_SEL, SEL_KPL),%eax 	#switch to new segment
+ 	movl    %ax,%ds
+ 	movl    %ax,%es
+ 	movl    %ax,%ss
+ 	HALT(3)
+ 	pushl   $GSEL(GCODE_SEL, SEL_KPL)
+ 	pushl	$mp_cont
+ 	HALT(4)
+ 	lret
+ 	.align 4,0x0
+ _TRMP_LABEL(gdt_table)   
+ 	.word   0x0,0x0,0x0,0x0  # null GDTE
+ 	 GDTE(0x9f,0xcf)         # Kernel text
+ 	 GDTE(0x93,0xcf)         # Kernel data
+ _TRMP_LABEL(gdt_desc)	
+ 	.word   0x17             # limit 3 entrys
+ 	.long   gdt_table              # where is is gdt
+ _TRMP_LABEL(ngdt_table)   
+ 	.long  0		# filled in after paging in enabled
+ 	.long  0
+ 	.align 4,0x0
+ _C_LABEL(cpu_spinup_trampoline_end):	#end of code copied to MP_TRAMPOLINE
+ mp_cont:
+ 	movl	_C_LABEL(SPST),%esp
+ 	call _C_LABEL(init386_ap)
+ 	HALT(0x010)
+ 	call _C_LABEL(cpu_hatch)	# cpu is running now should never return
+ mps:
+ 	hlt
+ 	jmp mps
+ 	 .global _C_LABEL(spurious_intr)
+ _C_LABEL(spurious_intr):		# for APIC
+ 	iret
+ #ifdef MP_DEBUG
+ 	.data
+ 	.global _C_LABEL(cpu_trace)
+ _C_LABEL(cpu_trace):
+ 	.long  0x40
+ 	.long  0
+ #endif
*** /dev/null	Sun Jan 31 22:45:35 1999
--- ././i386/cpu.c	Tue Feb  2 12:58:16 1999
***************
*** 0 ****
--- 1,398 ----
+ /*
+  * Copyright (c) 1999 Stefan Grefen
+  *
+  * 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.
+  * 3. All advertising materials mentioning features or use of this software
+  *    must display the following acknowledgement:
+  *      This product includes software developed by Stefan Grefen.
+  * 4. The name Stefan Grefen may not be used to endorse or promote
+  *    products derived from this software without specific prior written
+  *    permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``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 TERRENCE R. LAMBERT BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #include "opt_ddb.h"
+ #include <sys/param.h>
+ #include <sys/systm.h>
+ #include <sys/device.h>
+ 
+ #include <vm/vm.h>
+ #include <vm/vm_kern.h>
+ #include <vm/vm_page.h>
+  
+ #if defined(UVM)
+ #include <uvm/uvm_extern.h>
+ #endif  
+ 
+ 
+ #include <machine/apic.h>
+ #include <machine/cpu.h>
+ #include <machine/cpufunc.h>
+ #include <machine/cpuvar.h>
+ #include <machine/pmap.new.h>
+ #include <machine/vmparam.h>
+ #include <machine/multiprocessor.h>
+ 
+ 
+ int     cpu_match __P((struct device *, struct cfdata *, void *));
+ void    cpu_attach __P((struct device *, struct device *, void *));
+ 
+ void    init386_ap __P((void));
+ void    cpu_hatch __P((void));
+ int     enable_local_apic __P((void));
+ void    cpu_start __P((struct cpu_softc *sc));
+ void    ap_cpu_callback __P((struct device *self));
+ 
+ 
+ int cpu_verbose = 0;
+ 
+ 
+ struct cfattach cpu_ca = {
+     sizeof(struct cpu_softc), cpu_match, cpu_attach
+ };
+ 
+ struct cpu_softc *cpus[16] = { 0 };
+ void identifycpu1(struct cpu_softc * );
+ extern union   descriptor *idt, *gdt, *ldt,*pentium_idt;
+ extern int spurious_intr(void);
+ int boot_cpu = -1;
+ 
+ /*
+  * Needed by the bootstrap code
+  */
+ unsigned long SPTD;
+ caddr_t SPST;
+ 
+ /*
+  * enable local apic
+  */
+ int 
+ enable_local_apic(void) {
+     local_apic.svr = 64 | APIC_SVR_ENABLE;
+     return 0;
+ }
+ 
+ int
+ cpu_match(parent, match, aux)
+     struct device *parent;  
+     struct cfdata *match;   
+     void *aux;
+ {
+     struct mp_attach_arg * maa = (struct mp_attach_arg *) aux;
+ 
+     if (maa->type == MP_CPU)
+ 	return 1;
+     return 0;
+ }
+ 
+ /*
+  * start an application processor (AP)
+  */
+ void
+ cpu_start(sc) 
+ 	struct cpu_softc *sc;
+ {
+ 	int i;
+ 	unsigned long *rec_mem = 
+ 			(unsigned long *)uvm_km_alloc(kernel_map, NBPG);
+ 
+ 	for (i =0 ; i < 1024; i++) {
+ 	    rec_mem[i] = (i << 12) | PG_V | PG_RW;
+ 	}
+ 
+ 	/*
+ 	 * double map 0-4MB v === phys
+ 	 */
+ 	sc->sc_ptd->pm_pdir[0] = vtophys(rec_mem)| PG_V | PG_RW;
+ 
+ 	/*
+ 	 * pass PTF and stack to boot code
+ 	 */
+ 	SPTD = sc->sc_ptd->pm_pdirpa;
+ 	SPST = sc->sc_stack;
+ 
+ 	/*
+ 	 * now startup the CPU
+ 	 */
+ 	printf("{");
+ 	CPU_STARTUP(sc);
+ 
+ 	/*
+ 	 * wait for it to become ready
+ 	 */
+ 	i = 100000;
+ 	for (i = 100000; !(sc->sc_flags & CPU_RUNNING) && i>0;i--) {
+ 	    delay(10);
+ 	}
+ 	/* Debugger(); */
+ 	printf ("}");
+ #ifdef MP_DEBUG
+ 	if (cpu_verbose)
+ 	{ 
+ 	 extern  int cpu_trace;
+ 	 printf ("[%d,%d]",cpu_trace,(&cpu_trace)[1]);
+ 	}
+ #endif
+ 	/*
+ 	 * unmap boot code
+ 	 */
+ 	sc->sc_ptd->pm_pdir[0] = 0;
+ 
+ 	/*
+ 	 * free tmp page_table
+ 	 */
+ 	uvm_km_free(kernel_map, (vaddr_t) rec_mem, NBPG);
+ }
+ 
+ /*
+  * AP can only be started after the boot processor (BP) has 
+  * been initialized. We call config_defer until the BP
+  * is initialized and this is the callback that
+  * starts the defered AP's
+  */
+ void
+ ap_cpu_callback(self)
+ 	struct device *self;
+ {
+ 	struct cpu_softc *sc = (struct cpu_softc *) self;
+ 
+ 	printf("%s: defered startup (",sc->sc_dev.dv_xname);
+ 	cpu_start(sc);
+ 	printf(") %srunning\n",sc->sc_flags & CPU_RUNNING?"":"not ");
+ 	if (sc->sc_flags & CPU_RUNNING)
+ 	    identifycpu1(sc);
+ }
+ 
+ void 
+ cpu_attach(parent, self, aux)   
+ 	struct device *parent, *self;
+ 	void *aux;
+ {
+ 	struct cpu_softc *sc = (struct cpu_softc *)self;  
+ 	struct cpu_attach_args  *caa = (struct cpu_attach_args  *) aux;
+ 
+ 	if (cpus[caa->cpu_id] == NULL) {
+ 	    cpus[caa->cpu_id] = sc;
+ 	    sc->sc_cpuid = caa->cpu_id;
+ 	    sc->sc_cpu_type = caa->cpu_signature;
+ 	    sc->sc_func = caa->cpu_func;
+ 	    sc->feature_flags = caa->feature_flags;
+ 
+ 	    /*
+ 	     * create copy of kernel PTD
+ 	     */
+ 	    sc->sc_ptd = pmap_create();
+ 
+ 	    /*
+ 	     * Allocate private page 
+ 	     */
+ 	    sc->sc_stack = ((caddr_t)uvm_km_alloc(kernel_map, NBPG)) + NBPG-4;
+ 
+ 	    printf(": (");
+ 
+ 	    if (caa->ap && boot_cpu == -1) {
+ 		/*
+ 		 * can't start AP yet ...
+ 		 */
+ 		sc->ap = 1;
+ 		printf("startup defered");
+ 		config_defer(self, ap_cpu_callback);
+ 		return;
+ 	    }
+ 
+ 	    /*
+ 	     * start an AP
+ 	     */
+ 	    if (caa->ap) {
+ 		sc->ap = 1;
+ 		cpu_start(sc);
+ 	    } else if (caa->bp) {
+ 		printf("bootprocessor");
+ 		boot_cpu = sc->sc_cpuid;
+ 		sc->sc_flags |= CPU_RUNNING;
+ 		sc->bp = 1;
+ 		/*
+ 		 * this initializes the BP (apic mapping)
+ 		 */
+ 		CPU_STARTUP(sc);
+ 
+ 		/*
+ 		 * Enable local apic
+ 		 */
+ 		setgate(&idt[64].gd, spurious_intr, 0,SDT_SYS386IGT, SEL_KPL);
+ 		enable_local_apic();
+ 	    } else {
+ 		/*
+ 		 * Single processor (not used yet)
+ 		 * this is for eliminating identifycpu from machdep
+ 		 */
+ 		printf("single processor");
+ 		sc->sc_flags |= CPU_RUNNING;
+ 		sc->sp = 1;
+ 	    }
+ 	    printf(") %srunning\n",sc->sc_flags & CPU_RUNNING?"":"not ");
+ 	    if (sc->sc_flags & CPU_RUNNING)
+ 		identifycpu1(sc);
+ 	}
+ }
+ 
+ /*
+  * initialize an AP
+  * GDT is done in the boot code
+  * IDT is done here
+  */
+ void
+ init386_ap(void)
+ {
+         struct region_descriptor region;
+ 	/*
+ 	 * gdt is loaded already
+ 	 */
+         setregion(&region, pentium_idt, NIDT * sizeof(idt[0]) - 1);
+         lidt(&region);
+ 
+ 	//enable_local_apic();
+ }
+ 
+ /*
+  * for now the CPU ends up here when its ready to run
+  * for now it jumps into an etenrnal loop
+  */
+ void
+ cpu_hatch(void) 
+ {
+     struct cpu_softc *sc = cpus[cpuid()];
+ 
+     if (sc) {
+ 	printf("CPU %d reports for duty",cpuid());
+ 	sc->sc_flags |= CPU_RUNNING;
+ 	while(1);
+     }
+ }
+ 
+ 
+ extern const char *modifiers[] ;
+ 
+ static struct cpu_cpuid_nameclass i386_cpuid_cpus[] = {
+ 	{
+ 		"GenuineIntel",
+ 		CPUVENDOR_INTEL,
+ 		"Intel",
+ 		/* Family 4 */
+ 		{ {
+ 			CPUCLASS_486, 
+ 			{
+ 				"486DX", "486DX", "486SX", "486DX2", "486SL",
+ 				"486SX2", 0, "486DX2 W/B Enhanced",
+ 				"486DX4", 0, 0, 0, 0, 0, 0, 0,
+ 				"486"		/* Default */
+ 			},
+ 			NULL
+ 		},
+ 		/* Family 5 */
+ 		{
+ 			CPUCLASS_586,
+ 			{
+ 				0, "Pentium", "Pentium (P54C)",
+ 				"Pentium (P24T)", "Pentium/MMX", "Pentium", 0,
+ 				"Pentium (P54C)", 0, 0, 0, 0, 0, 0, 0, 0,
+ 				"Pentium"	/* Default */
+ 			},
+ 			NULL
+ 		},
+ 		/* Family 6 */
+ 		{
+ 			CPUCLASS_686,
+ 			{
+ 				0, "Pentium Pro", 0, "Pentium II",
+ 				"Pentium Pro", "Pentium II", 0,
+ 				0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 				"Pentium Pro"	/* Default */
+ 			},
+ 			NULL
+ 		} }
+ 	}
+ };
+ 
+ extern char *classnames[] ;
+ 
+ void
+ identifycpu1(sc)
+     struct cpu_softc *sc;
+ {
+ 	extern char cpu_vendor[];
+ 	const char *name, *modifier, *vendorname;
+ 	int class = CPUCLASS_386, vendor, i, max;
+ 	int family, model, step, modif;
+ 	struct cpu_cpuid_nameclass *cpup = NULL;
+ 	char    cpu_model[120];
+ 
+ 
+ 
+ 	max = sizeof (i386_cpuid_cpus) / sizeof (i386_cpuid_cpus[0]);
+ 	modif = (sc->sc_cpu_type >> 12) & 3;
+ 	family = (sc->sc_cpu_type >> 8) & 15;
+ 	if (family < CPU_MINFAMILY)
+ 	    printf("identifycpu: strange family value");
+ 	model = (sc->sc_cpu_type >> 4) & 15;
+ 	step = sc->sc_cpu_type & 15;
+ 	printf("%s: family %x model %x step %x\n", sc->sc_dev.dv_xname,
+ 		    family, model,step);
+ 
+ 	for (i = 0; i < max; i++) {
+ 		if (!strncmp(cpu_vendor,
+ 		    i386_cpuid_cpus[i].cpu_id, 12)) {
+ 			cpup = &i386_cpuid_cpus[i];
+ 			break;
+ 		}
+ 	}
+ 
+ 	if (cpup == NULL) {
+ 		vendor = CPUVENDOR_UNKNOWN;
+ 		if (cpu_vendor[0] != '\0')
+ 			vendorname = &cpu_vendor[0];
+ 		else
+ 			vendorname = "Unknown";
+ 		if (family > CPU_MAXFAMILY)
+ 			family = CPU_MAXFAMILY;
+ 		class = family - 3;
+ 		modifier = "";
+ 		name = "";
+ 	} else {
+ 		vendor = cpup->cpu_vendor;
+ 		vendorname = cpup->cpu_vendorname;
+ 		modifier = modifiers[modif];
+ 		if (family > CPU_MAXFAMILY) {
+ 			family = CPU_MAXFAMILY;
+ 			model = CPU_DEFMODEL;
+ 		} else if (model > CPU_MAXMODEL)
+ 			model = CPU_DEFMODEL;
+ 		i = family - CPU_MINFAMILY;
+ 		name = cpup->cpu_family[i].cpu_models[model];
+ 		if (name == NULL)
+ 		    name = cpup->cpu_family[i].cpu_models[CPU_DEFMODEL];
+ 		class = cpup->cpu_family[i].cpu_class;
+ 	}
+ 
+ 	sprintf(cpu_model, "%s %s%s (%s-class)", vendorname, modifier, name,
+ 		classnames[class]);
+ 	printf("%s: %s\n", sc->sc_dev.dv_xname, cpu_model);
+ }
*** /dev/null	Sun Jan 31 22:45:35 1999
--- ././i386/mps2h	Tue Feb  2 12:56:25 1999
***************
*** 0 ****
--- 1,25 ----
+ #!/bin/sh
+ # Copyright (c) 1999 Stefan Grefen
+ #
+ cpp  -DGETVALUES  $*| as  -al -R | \
+ awk 'BEGIN{start=0;bc=0;label="";}
+     /^[ ]*[1-9][0-9]?[0-9]? (([0-9a-f][0-9a-f][0-9a-f][0-9a-f])|(    )) [0-9A-F].*/{ 
+ 	    val=$3
+ 	    if(length(val)==0) {
+ 		if(start==0)
+ 		    next
+ 		val=$2
+ 	    } else {
+ 		start=1
+ 	    }
+ 	    if (label != "" ) {
+ 		printf("#define %s 0x%s\n",label,$2);
+ 		label = "";
+ 	    }
+     }
+     /^[ ]*[1-9][0-9]?[0-9]?/ && /_TRMP_LABEL[(][-_A-Za-z0-9][-_A-Za-z0-9]+[)]/ {
+ 	sub("_TRMP_LABEL","",$2);
+ 	gsub("[()]","",$2);
+ 	label = $2;
+     }'
+ rm -f a.out
*** /dev/null	Sun Jan 31 22:45:35 1999
--- ././i386/apic.c	Tue Feb  2 14:32:05 1999
***************
*** 0 ****
--- 1,158 ----
+ /*
+  * Copyright (c) 1999 Stefan Grefen
+  *
+  * 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.
+  * 3. All advertising materials mentioning features or use of this software
+  *    must display the following acknowledgement:
+  *      This product includes software developed by Stefan Grefen.
+  * 4. The name Stefan Grefen may not be used to endorse or promote
+  *    products derived from this software without specific prior written
+  *    permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``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 TERRENCE R. LAMBERT BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ #include "opt_ddb.h"
+ #include <sys/param.h>
+ #include <sys/systm.h>
+ #include <sys/device.h>
+ 
+ #include <vm/vm.h>
+ #include <vm/vm_kern.h>
+ #include <vm/vm_page.h>
+ 
+ #include <machine/bus.h>
+  
+ #if defined(UVM)
+ #include <uvm/uvm_extern.h>
+ #endif  
+ 
+ 
+ #include <machine/apic.h>
+ #include <machine/apicvar.h>
+ #include <machine/pmap.new.h>
+ #include <machine/multiprocessor.h>
+ 
+ /*
+  * maps an IO-apic
+  * TODO locking, export of interrupt functions
+  * and mapping of interrupts.
+  */
+ 
+ int     apic_match __P((struct device *, struct cfdata *, void *));
+ void    apic_attach __P((struct device *, struct device *, void *));
+ 
+ int     i386_mem_add_mapping __P((bus_addr_t, bus_size_t,
+             int, bus_space_handle_t *));
+ 
+ int apic_verbose = 0;
+ 
+ static __inline  unsigned int 
+ read_apic(struct apic_softc *sc,int regid) {
+     /*
+      * todo lock apic  
+      */
+     sc->sc_register->ioregsel = regid;
+     return sc->sc_register->iowin;
+ }
+ 
+ static __inline  void
+ write_apic(struct apic_softc *sc,int regid, int val) {
+     /*
+      * todo lock apic  
+      */
+     sc->sc_register->ioregsel = regid; 
+     sc->sc_register->iowin = val;
+ }
+ 
+ 
+ 
+ 
+ 
+ struct cfattach apic_ca = {
+     sizeof(struct apic_softc), apic_match, apic_attach
+ };
+ 
+ struct apic_softc *apics[16] = { 0 };
+ 
+ int
+ apic_match(parent, match, aux)
+     struct device *parent;  
+     struct cfdata *match;   
+     void *aux;
+ {
+     struct mp_attach_arg * maa = (struct mp_attach_arg *) aux;
+ 
+     if (maa->type == MP_IO_APIC)
+ 	return 1;
+     return 0;
+ }
+ 
+ /*
+  * can't use bus_space_xxx as we don't have a bus handle ...
+  */
+ void 
+ apic_attach(parent, self, aux)   
+ 	struct device *parent, *self;
+ 	void *aux;
+ {
+ 	struct apic_softc *sc = (struct apic_softc *)self;  
+ 	struct apic_attach_args  *aaa = (struct apic_attach_args  *) aux;
+ 
+ 	if (apics[aaa->apic_id] == NULL) {
+ 	    int apic_id;
+ 	    apics[aaa->apic_id] = sc;
+ 	    sc->sc_apicid = aaa->apic_id;
+ 
+ 	    printf(" at 0x%lx\n", aaa->apic_address);
+ 	    if (i386_mem_add_mapping(aaa->apic_address,
+ 		    NBPG,0,(bus_space_handle_t *)&sc->sc_register)) {
+ 		printf("can't map io_apic\n");
+ 	    }
+ 
+ 	    apic_id = (read_apic(sc,IOAPIC_ID)&APIC_ID_MASK)>>24;
+ 	    printf("%s: io-apic id %d, vers %x\n",
+ 			 sc->sc_dev.dv_xname,
+ 			 apic_id,
+ 			 read_apic(sc,IOAPIC_VER)&0xff);
+             /*
+ 	     * in case the APIC is not initialized to the correct ID
+ 	     * do it now, maye we should record the original ID
+ 	     * for interrupt mapping later ...
+ 	     */
+ 	    if (apic_id != sc->sc_apicid) {
+ 		 write_apic(sc,IOAPIC_VER,
+ 			(read_apic(sc,IOAPIC_ID)&~APIC_ID_MASK)
+ 			    |(sc->sc_apicid<<24));
+ 
+ 		apic_id = (read_apic(sc,IOAPIC_ID)&APIC_ID_MASK)>>24;
+ 
+ 		if (apic_id != sc->sc_apicid) {
+ 		    printf("%s: can't remap io-apic id to %d\n",
+ 			sc->sc_dev.dv_xname,
+ 			sc->sc_apicid);
+ 		} else {
+ 		    printf("%s: remaped io-apic id to %d\n",
+ 			sc->sc_dev.dv_xname,
+ 			sc->sc_apicid);
+ 		}
+ 	    }
+ 	}
+ }
+ 
*** /usr/sup/src/sys/arch/i386/./i386/machdep.c	Fri Jan 29 13:15:47 1999
--- ././i386/machdep.c	Tue Feb  2 15:12:35 1999
***************
*** 1876,1887 ****
--- 1876,1893 ----
  	}
  #endif
  
+ #ifdef XXMP 
+ 	/* Assuming bioscall .... */
+ 	avail_start = 4*NBPG;	/* save us a page for trampoline code and
+ 				 one additional PT page! */
+ #else
  #if NBIOSCALL > 0
  	avail_start = 3*NBPG;	/* save us a page for trampoline code and
  				 one additional PT page! */
  #else
  	avail_start = NBPG;	/* BIOS leaves data in low memory */
  				/* and VM system doesn't work with phys 0 */
+ #endif
  #endif
  	avail_end = IOM_END + trunc_page(biosextmem * 1024);
  
*** /usr/sup/src/sys/arch/i386/./i386/locore.s	Wed Jan 27 13:13:56 1999
--- ././i386/locore.s	Sun Jan 31 23:27:35 1999
***************
*** 233,238 ****
--- 233,240 ----
  #ifdef I586_CPU
  	.globl	_C_LABEL(idt)
  #endif
+ 	.global _C_LABEL(local_apic)
+ _C_LABEL(local_apic):	.space  NBPG
  _C_LABEL(cpu):		.long	0	# are we 386, 386sx, or 486,
  					#   or Pentium, or..
  _C_LABEL(cpu_id):	.long	0	# saved from `cpuid' instruction
*** /usr/sup/src/sys/arch/i386/./i386/mainbus.c	Wed Aug  5 13:09:31 1998
--- ././i386/mainbus.c	Sat Jan 30 21:45:51 1999
***************
*** 84,89 ****
--- 84,94 ----
  int	eisa_has_been_seen;
  
  /*
+  * Same as above, but for PCI.
+  */
+ int	pci_has_been_seen;
+ 
+ /*
   * Probe for the mainbus; always succeeds.
   */
  int
***************
*** 108,113 ****
--- 113,125 ----
  
  	printf("\n");
  
+ #ifdef XXMP
+ 	/*
+ 	 * First check for Intel MP-structure
+ 	 */
+ 	mba.mba_busname = "itlmps";
+ 	config_found(self, &mba.mba_aaa, mainbus_print);
+ #endif
  	/*
  	 * XXX Note also that the presence of a PCI bus should
  	 * XXX _always_ be checked, and if present the bus should be
*** /dev/null	Sun Jan 31 22:45:35 1999
--- ././include/cpuvar.h	Tue Feb  2 13:00:51 1999
***************
*** 0 ****
--- 1,114 ----
+ /*
+  * Copyright (c) 1999 Stefan Grefen
+  *
+  * 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.
+  * 3. All advertising materials mentioning features or use of this software
+  *    must display the following acknowledgement:
+  *      This product includes software developed by Stefan Grefen.
+  * 4. The name Stefan Grefen may not be used to endorse or promote
+  *    products derived from this software without specific prior written
+  *    permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``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 TERRENCE R. LAMBERT 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.
+  */
+ #define CPU_STARTUP(_sc)	((_sc)->sc_func->start(_sc))
+ #define CPU_STOP(_sc)	        ((_sc)->sc_func->stop(_sc))
+ 
+ struct cpu_softc {
+     struct device sc_dev;           /* generic device glue */
+     u_long sc_cpuid;                /* CPU ID */
+     int sc_cpu_type;		    /* CPU type */
+     int sc_apic_version;	    /* APIC version */
+     caddr_t sc_idle_stack;          /* our idle stack */
+     u_long sc_flags;                /* flags; see below */
+     struct cpu_functions *sc_func;  /* basic functions */
+     TAILQ_ENTRY(cpu_softc) sc_q;    /* processing queue */
+     int bp:1;
+     int ap:1;
+     int sp:1;
+     int xx:29;
+     struct pmap *sc_ptd;
+     caddr_t sc_stack;
+     int feature_flags;
+ };
+ 
+ struct cpu_functions {
+     int (*start)(struct cpu_softc *);
+     int (*stop)(struct cpu_softc *);
+ };
+ 
+ struct cpu_attach_args {
+     int type;
+     int cpu_id;
+     int bp:1;
+     int ap:1;
+     int sp:1;
+     int xx:29;
+     struct cpu_functions *cpu_func;
+     int cpu_signature;
+     int feature_flags;
+ };
+ 
+ struct bus_info {
+     int bus_id;
+     struct bus_info *parent;
+     struct bus_info *next,*child;
+     int bus_type;
+ };
+ 
+ struct intr_info {
+     int type;
+     int flags;
+     struct bus_info *bus;
+     struct apic_info *apic;
+     int bus_irq;
+     int apic_int;
+     int cpu_class;
+ };
+ #define CPU_CLASS_ALL	0	/* All, the default */
+ #define CPU_CLASS_BSP	1	/* only the boot processor */
+ 
+ struct mp_info {
+     int ncpus;               /* # of CPUs, including BSP */
+     int cpu_mask;	    /* Bit mask of availale CPU's */
+     int boot_cpu_id;         /* designated BSP */
+     int flags;		     /* various flags */	
+     int nints;
+     paddr_t cpu_apic_address;
+     struct intr_info *ints;
+ };
+ 
+ #define CPUF_PRIMARY    0x00000001      /* CPU is primary CPU */
+ #define CPUF_APIC_CD    0x00000002      /* CPU has apic configured */
+ 
+ #define MP_PICMODE	0x00000001      /* System booted in picmode */
+ 
+ #define CPU_RUNNING	0x00001000
+ 
+ 
+ #ifdef _KERNEL
+ extern  unsigned long cpus_running;
+ extern  struct cpu_softc *cpus[];
+ extern  struct cpu_softc *primary_cpu;
+ 
+ int i386_ipi __P((int,int,int));
+ int i386_init __P((int));
+ #endif
+ 
*** /dev/null	Sun Jan 31 22:45:35 1999
--- ././include/apic.h	Tue Feb  2 13:00:21 1999
***************
*** 0 ****
--- 1,484 ----
+ /*
+  * Copyright (c) 1999 Stefan Grefen
+  *
+  * 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.
+  * 3. All advertising materials mentioning features or use of this software
+  *    must display the following acknowledgement:
+  *      This product includes software developed by Stefan Grefen.
+  * 4. The name Stefan Grefen may not be used to endorse or promote
+  *    products derived from this software without specific prior written
+  *    permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``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 TERRENCE R. LAMBERT 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.
+  */
+ /*
+  * Imported to NetBSD by Stefan Grefen 1999
+  */
+ /*
+  * Copyright (c) 1996, by Peter Wemm and Steve Passe
+  * All rights reserved.
+  *
+  * 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. The name of the developer may NOT be used to endorse or promote products
+  *    derived from this software without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+  *
+  *	$Id: apic.h,v 1.12 1998/09/06 22:41:40 tegge Exp $
+  */
+ 
+ #ifndef _MACHINE_APIC_H_
+ #define _MACHINE_APIC_H_
+ 
+ /*
+  * Local && I/O APIC definitions.
+  */
+ 
+ /*
+  * Pentium P54C+ Build-in APIC
+  * (Advanced programmable Interrupt Controller)
+  * 
+  * Base Address of Build-in APIC in memory location
+  * is 0xfee00000.
+  * 
+  * Map of APIC REgisters:
+  * 
+  * Offset (hex)    Description                     Read/Write state
+  * 000             Reserved
+  * 010             Reserved
+  * 020 ID          Local APIC ID                   R/W
+  * 030 VER         Local APIC Version              R
+  * 040             Reserved
+  * 050             Reserved
+  * 060             Reserved
+  * 070             Reserved
+  * 080             Task Priority Register          R/W
+  * 090             Arbitration Priority Register   R
+  * 0A0             Processor Priority Register     R
+  * 0B0             EOI Register                    W
+  * 0C0 RRR         Remote read                     R
+  * 0D0             Logical Destination             R/W
+  * 0E0             Destination Format Register     0..27 R;  28..31 R/W
+  * 0F0 SVR         Spurious Interrupt Vector Reg.  0..3  R;  4..9   R/W
+  * 100             ISR  000-031                    R
+  * 110             ISR  032-063                    R
+  * 120             ISR  064-095                    R
+  * 130             ISR  095-128                    R
+  * 140             ISR  128-159                    R
+  * 150             ISR  160-191                    R
+  * 160             ISR  192-223                    R
+  * 170             ISR  224-255                    R
+  * 180             TMR  000-031                    R
+  * 190             TMR  032-063                    R
+  * 1A0             TMR  064-095                    R
+  * 1B0             TMR  095-128                    R
+  * 1C0             TMR  128-159                    R
+  * 1D0             TMR  160-191                    R
+  * 1E0             TMR  192-223                    R
+  * 1F0             TMR  224-255                    R
+  * 200             IRR  000-031                    R
+  * 210             IRR  032-063                    R
+  * 220             IRR  064-095                    R
+  * 230             IRR  095-128                    R
+  * 240             IRR  128-159                    R
+  * 250             IRR  160-191                    R
+  * 260             IRR  192-223                    R
+  * 270             IRR  224-255                    R
+  * 280             Error Status Register           R
+  * 290             Reserved
+  * 2A0             Reserved
+  * 2B0             Reserved
+  * 2C0             Reserved
+  * 2D0             Reserved
+  * 2E0             Reserved
+  * 2F0             Reserved
+  * 300 ICR_LOW     Interrupt Command Reg. (0-31)   R/W
+  * 310 ICR_HI      Interrupt Command Reg. (32-63)  R/W
+  * 320             Local Vector Table (Timer)      R/W
+  * 330             Reserved
+  * 340             Reserved
+  * 350 LVT1        Local Vector Table (LINT0)      R/W
+  * 360 LVT2        Local Vector Table (LINT1)      R/W
+  * 370 LVT3        Local Vector Table (ERROR)      R/W
+  * 380             Initial Count Reg. for Timer    R/W
+  * 390             Current Count of Timer          R
+  * 3A0             Reserved
+  * 3B0             Reserved
+  * 3C0             Reserved
+  * 3D0             Reserved
+  * 3E0             Timer Divide Configuration Reg. R/W
+  * 3F0             Reserved
+  */
+ 
+ 
+ /******************************************************************************
+  * global defines, etc.
+  */
+ 
+ 
+ /******************************************************************************
+  * LOCAL APIC structure
+  */
+ 
+ #ifndef _LOCORE
+ 
+ 
+ #define PAD3	int : 32; int : 32; int : 32
+ #define PAD4	int : 32; int : 32; int : 32; int : 32
+ 
+ struct local_apic {
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	unsigned int dummy:24;unsigned int   id:8;	PAD3;
+ 	unsigned int version;	PAD3;
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	unsigned int tpr;		PAD3;
+ 	unsigned int apr;		PAD3;
+ 	unsigned int ppr;		PAD3;
+ 	unsigned int eoi;		PAD3;
+ 	/* reserved */		PAD4;
+ 	unsigned int ldr;		PAD3;
+ 	unsigned int dfr;		PAD3;
+ 	unsigned int svr;		PAD3;
+ 	unsigned int isr0;		PAD3;
+ 	unsigned int isr1;		PAD3;
+ 	unsigned int isr2;		PAD3;
+ 	unsigned int isr3;		PAD3;
+ 	unsigned int isr4;		PAD3;
+ 	unsigned int isr5;		PAD3;
+ 	unsigned int isr6;		PAD3;
+ 	unsigned int isr7;		PAD3;
+ 	unsigned int tmr0;		PAD3;
+ 	unsigned int tmr1;		PAD3;
+ 	unsigned int tmr2;		PAD3;
+ 	unsigned int tmr3;		PAD3;
+ 	unsigned int tmr4;		PAD3;
+ 	unsigned int tmr5;		PAD3;
+ 	unsigned int tmr6;		PAD3;
+ 	unsigned int tmr7;		PAD3;
+ 	unsigned int irr0;		PAD3;
+ 	unsigned int irr1;		PAD3;
+ 	unsigned int irr2;		PAD3;
+ 	unsigned int irr3;		PAD3;
+ 	unsigned int irr4;		PAD3;
+ 	unsigned int irr5;		PAD3;
+ 	unsigned int irr6;		PAD3;
+ 	unsigned int irr7;		PAD3;
+ 	unsigned int esr;		PAD3;
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	unsigned int icr_lo;	PAD3;
+ 	unsigned int icr_hi;	PAD3;
+ 	unsigned int lvt_timer;	PAD3;
+ 	/* reserved */		PAD4;
+ 	unsigned int lvt_pcint;	PAD3;
+ 	unsigned int lvt_lint0;	PAD3;
+ 	unsigned int lvt_lint1;	PAD3;
+ 	unsigned int lvt_error;	PAD3;
+ 	unsigned int icr_timer;	PAD3;
+ 	unsigned int ccr_timer;	PAD3;
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	/* reserved */		PAD4;
+ 	unsigned int dcr_timer;	PAD3;
+ 	/* reserved */		PAD4;
+ };
+ 
+ /******************************************************************************
+  * I/O APIC structure
+  */
+ 
+ struct io_apic {
+ 	unsigned int ioregsel;	PAD3;
+ 	unsigned int iowin;	PAD3;
+ };
+ 
+ #undef PAD4
+ #undef PAD3
+ 
+ #endif  /* !LOCORE */
+ 
+ 
+ /******************************************************************************
+  * various code 'logical' values
+  */
+ 
+ /* default level for TPR */
+ #define LOPRIO_LEVEL		0x00000010	/* TPR of CPU accepting INTs */
+ 
+ #ifdef GRAB_LOPRIO
+ #define ALLHWI_LEVEL		0x00000000	/* TPR of CPU grabbing INTs */
+ #endif /** GRAB_LOPRIO */
+ 
+ 
+ /******************************************************************************
+  * LOCAL APIC defines
+  */
+ 
+ /* default physical locations of LOCAL (CPU) APICs */
+ #define DEFAULT_APIC_BASE	0xfee00000
+ 
+ /* fields in VER */
+ #define APIC_VER_VERSION	0x000000ff
+ #define APIC_VER_MAXLVT		0x00ff0000
+ #define MAXLVTSHIFT		16
+ 
+ /* fields in SVR */
+ #define APIC_SVR_VECTOR		0x000000ff
+ #define APIC_SVR_VEC_PROG	0x000000f0
+ #define APIC_SVR_VEC_FIX	0x0000000f
+ #define APIC_SVR_ENABLE		0x00000100
+ # define APIC_SVR_SWDIS		0x00000000
+ # define APIC_SVR_SWEN		0x00000100
+ #define APIC_SVR_FOCUS		0x00000200
+ # define APIC_SVR_FEN		0x00000000
+ # define APIC_SVR_FDIS		0x00000200
+ 
+ /* fields in TPR */
+ #define APIC_TPR_PRIO		0x000000ff
+ # define APIC_TPR_INT		0x000000f0
+ # define APIC_TPR_SUB		0x0000000f
+ 
+ 
+ /* fields in ICR_LOW */
+ #define APIC_VECTOR_MASK	0x000000ff
+ 
+ #define APIC_DELMODE_MASK	0x00000700
+ # define APIC_DELMODE_FIXED	0x00000000
+ # define APIC_DELMODE_LOWPRIO	0x00000100
+ # define APIC_DELMODE_SMI	0x00000200
+ # define APIC_DELMODE_RR	0x00000300
+ # define APIC_DELMODE_NMI	0x00000400
+ # define APIC_DELMODE_INIT	0x00000500
+ # define APIC_DELMODE_STARTUP	0x00000600
+ # define APIC_DELMODE_RESV	0x00000700
+ 
+ #define APIC_DESTMODE_MASK	0x00000800
+ # define APIC_DESTMODE_PHY	0x00000000
+ # define APIC_DESTMODE_LOG	0x00000800
+ 
+ #define APIC_DELSTAT_MASK	0x00001000
+ # define APIC_DELSTAT_IDLE	0x00000000
+ # define APIC_DELSTAT_PEND	0x00001000
+ 
+ /* #define APIC_RESV1_MASK		0x00002000 */
+ #define APIC_POLARITY_MASK	0x00002000
+ # define APIC_POLARITY_HIGH	0x00000000
+ # define APIC_POLARITY_LOW	0x00000000
+ 
+ #define APIC_LEVEL_MASK		0x00004000
+ # define APIC_LEVEL_DEASSERT	0x00000000
+ # define APIC_LEVEL_ASSERT	0x00004000
+ 
+ #define APIC_TRIGMOD_MASK	0x00008000
+ # define APIC_TRIGMOD_EDGE	0x00000000
+ # define APIC_TRIGMOD_LEVEL	0x00008000
+ 
+ #define APIC_RRSTAT_MASK	0x00030000
+ # define APIC_RRSTAT_INVALID	0x00000000
+ # define APIC_RRSTAT_INPROG	0x00010000
+ # define APIC_RRSTAT_VALID	0x00020000
+ # define APIC_RRSTAT_RESV	0x00030000
+ 
+ #define APIC_DEST_MASK		0x000c0000
+ # define APIC_DEST_DESTFLD	0x00000000
+ # define APIC_DEST_SELF		0x00040000
+ # define APIC_DEST_ALLISELF	0x00080000
+ # define APIC_DEST_ALLESELF	0x000c0000
+ 
+ #define APIC_RESV2_MASK		0xfff00000
+ 
+ 
+ /* fields in ICR_HIGH */
+ #define APIC_ID_MASK		0x0f000000
+ #define APIC_ID_SHIFT		24
+ 
+ /* fields in LVT1/2 */
+ #define APIC_LVT_VECTOR		0x000000ff
+ #define APIC_LVT_DM		0x00000700
+ # define APIC_LVT_DM_FIXED	0x00000000
+ # define APIC_LVT_DM_NMI	0x00000400
+ # define APIC_LVT_DM_EXTINT	0x00000700
+ #define APIC_LVT_DS		0x00001000
+ #define APIC_LVT_IIPP		0x00002000
+ #define APIC_LVT_IIPP_INTALO	0x00002000
+ #define APIC_LVT_IIPP_INTAHI	0x00000000
+ #define APIC_LVT_RIRR		0x00004000
+ #define APIC_LVT_TM		0x00008000
+ #define APIC_LVT_M		0x00010000
+ 
+ 
+ /* fields in LVT Timer */
+ #define APIC_LVTT_VECTOR	0x000000ff
+ #define APIC_LVTT_DS		0x00001000
+ #define APIC_LVTT_M		0x00010000
+ #define APIC_LVTT_TM		0x00020000
+ 
+ 
+ /* fields in TDCR */
+ #define APIC_TDCR_2		0x00
+ #define APIC_TDCR_4		0x01
+ #define APIC_TDCR_8		0x02
+ #define APIC_TDCR_16		0x03
+ #define APIC_TDCR_32		0x08
+ #define APIC_TDCR_64		0x09
+ #define APIC_TDCR_128		0x0a
+ #define APIC_TDCR_1		0x0b
+ 
+ 
+ /*
+  * fields in IRR
+  * ISA INTerrupts are in bits 16-31 of the 1st IRR register.
+  * these masks DON'T EQUAL the isa IRQs of the same name.
+  */
+ #define APIC_IRQ0		0x00000001
+ #define APIC_IRQ1		0x00000002
+ #define APIC_IRQ2		0x00000004
+ #define APIC_IRQ3		0x00000008
+ #define APIC_IRQ4		0x00000010
+ #define APIC_IRQ5		0x00000020
+ #define APIC_IRQ6		0x00000040
+ #define APIC_IRQ7		0x00000080
+ #define APIC_IRQ8		0x00000100
+ #define APIC_IRQ9		0x00000200
+ #define APIC_IRQ10		0x00000400
+ #define APIC_IRQ11		0x00000800
+ #define APIC_IRQ12		0x00001000
+ #define APIC_IRQ13		0x00002000
+ #define APIC_IRQ14		0x00004000
+ #define APIC_IRQ15		0x00008000
+ #define APIC_IRQ16		0x00010000
+ #define APIC_IRQ17		0x00020000
+ #define APIC_IRQ18		0x00040000
+ #define APIC_IRQ19		0x00080000
+ #define APIC_IRQ20		0x00100000
+ #define APIC_IRQ21		0x00200000
+ #define APIC_IRQ22		0x00400000
+ #define APIC_IRQ23		0x00800000
+ 
+ 
+ /******************************************************************************
+  * I/O APIC defines
+  */
+ 
+ /* default physical locations of an IO APIC */
+ #define DEFAULT_IO_APIC_BASE	0xfec00000
+ 
+ /* window register offset */
+ #define IOAPIC_WINDOW		0x10
+ 
+ /* indexes into IO APIC */
+ #define IOAPIC_ID		0x00
+ #define IOAPIC_VER		0x01
+ #define IOAPIC_ARB		0x02
+ #define IOAPIC_REDTBL		0x10
+ #define IOAPIC_REDTBL0		IOAPIC_REDTBL
+ #define IOAPIC_REDTBL1		(IOAPIC_REDTBL+0x02)
+ #define IOAPIC_REDTBL2		(IOAPIC_REDTBL+0x04)
+ #define IOAPIC_REDTBL3		(IOAPIC_REDTBL+0x06)
+ #define IOAPIC_REDTBL4		(IOAPIC_REDTBL+0x08)
+ #define IOAPIC_REDTBL5		(IOAPIC_REDTBL+0x0a)
+ #define IOAPIC_REDTBL6		(IOAPIC_REDTBL+0x0c)
+ #define IOAPIC_REDTBL7		(IOAPIC_REDTBL+0x0e)
+ #define IOAPIC_REDTBL8		(IOAPIC_REDTBL+0x10)
+ #define IOAPIC_REDTBL9		(IOAPIC_REDTBL+0x12)
+ #define IOAPIC_REDTBL10		(IOAPIC_REDTBL+0x14)
+ #define IOAPIC_REDTBL11		(IOAPIC_REDTBL+0x16)
+ #define IOAPIC_REDTBL12		(IOAPIC_REDTBL+0x18)
+ #define IOAPIC_REDTBL13		(IOAPIC_REDTBL+0x1a)
+ #define IOAPIC_REDTBL14		(IOAPIC_REDTBL+0x1c)
+ #define IOAPIC_REDTBL15		(IOAPIC_REDTBL+0x1e)
+ #define IOAPIC_REDTBL16		(IOAPIC_REDTBL+0x20)
+ #define IOAPIC_REDTBL17		(IOAPIC_REDTBL+0x22)
+ #define IOAPIC_REDTBL18		(IOAPIC_REDTBL+0x24)
+ #define IOAPIC_REDTBL19		(IOAPIC_REDTBL+0x26)
+ #define IOAPIC_REDTBL20		(IOAPIC_REDTBL+0x28)
+ #define IOAPIC_REDTBL21		(IOAPIC_REDTBL+0x2a)
+ #define IOAPIC_REDTBL22		(IOAPIC_REDTBL+0x2c)
+ #define IOAPIC_REDTBL23		(IOAPIC_REDTBL+0x2e)
+ 
+ /* fields in VER */
+ #define IOART_VER_VERSION	0x000000ff
+ #define IOART_VER_MAXREDIR	0x00ff0000
+ #define MAXREDIRSHIFT		16
+ 
+ /*
+  * fields in the IO APIC's redirection table entries
+  */
+ #define IOART_DEST	APIC_ID_MASK	/* broadcast addr: all APICs */
+ 
+ #define IOART_RESV	0x00fe0000	/* reserved */
+ 
+ #define IOART_INTMASK	0x00010000	/* R/W: INTerrupt mask */
+ # define IOART_INTMCLR	0x00000000	/*       clear, allow INTs */
+ # define IOART_INTMSET	0x00010000	/*       set, inhibit INTs */
+ 
+ #define IOART_TRGRMOD	0x00008000	/* R/W: trigger mode */
+ # define IOART_TRGREDG	0x00000000	/*       edge */
+ # define IOART_TRGRLVL	0x00008000	/*       level */
+ 
+ #define IOART_REM_IRR	0x00004000	/* RO: remote IRR */
+ 
+ #define IOART_INTPOL	0x00002000	/* R/W: INT input pin polarity */
+ # define IOART_INTAHI	0x00000000	/*      active high */
+ # define IOART_INTALO	0x00002000	/*      active low */
+ 
+ #define IOART_DELIVS	0x00001000	/* RO: delivery status */
+ 
+ #define IOART_DESTMOD	0x00000800	/* R/W: destination mode */
+ # define IOART_DESTPHY	0x00000000	/*      physical */
+ # define IOART_DESTLOG	0x00000800	/*      logical */
+ 
+ #define IOART_DELMOD	0x00000700	/* R/W: delivery mode */
+ # define IOART_DELFIXED	0x00000000	/*       fixed */
+ # define IOART_DELLOPRI	0x00000100	/*       lowest priority */
+ # define IOART_DELSMI	0x00000200	/*       System Management INT */
+ # define IOART_DELRSV1	0x00000300	/*       reserved */
+ # define IOART_DELNMI	0x00000400	/*       NMI signal */
+ # define IOART_DELINIT	0x00000500	/*       INIT signal */
+ # define IOART_DELRSV2	0x00000600	/*       reserved */
+ # define IOART_DELEXINT	0x00000700	/*       External INTerrupt */
+ 
+ #define IOART_INTVEC	0x000000ff	/* R/W: INTerrupt vector field */
+ 
+ #endif /* _MACHINE_APIC_H_ */
*** /dev/null	Sun Jan 31 22:45:35 1999
--- ././include/multiprocessor.h	Tue Feb  2 13:01:00 1999
***************
*** 0 ****
--- 1,54 ----
+ /*
+  * Copyright (c) 1999 Stefan Grefen
+  *
+  * 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.
+  * 3. All advertising materials mentioning features or use of this software
+  *    must display the following acknowledgement:
+  *      This product includes software developed by Stefan Grefen.
+  * 4. The name Stefan Grefen may not be used to endorse or promote
+  *    products derived from this software without specific prior written
+  *    permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``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 TERRENCE R. LAMBERT 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.
+  */
+ #ifndef _MULTIPROCESSOR_H_
+ #define _MULTIPROCESSOR_H_
+ #define MP_TRAMPOLINE  (3 * NBPG)
+ 
+ #ifndef _LOCORE
+ #include <machine/apic.h>
+ 
+ struct mp_attach_arg {
+     int type;
+     int id;
+ };
+ 
+ #define MP_CPU	   1
+ #define MP_IO_APIC 2
+ 
+ 
+ #ifdef _KERNEL
+ extern struct local_apic local_apic;
+ #define cpuid()		(local_apic.id)
+ #endif
+ 
+ #endif
+ #endif
+ 
*** /dev/null	Sun Jan 31 22:45:35 1999
--- ././include/apicvar.h	Tue Feb  2 13:00:43 1999
***************
*** 0 ****
--- 1,45 ----
+ /*
+  * Copyright (c) 1999 Stefan Grefen
+  *
+  * 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.
+  * 3. All advertising materials mentioning features or use of this software
+  *    must display the following acknowledgement:
+  *      This product includes software developed by Stefan Grefen.
+  * 4. The name Stefan Grefen may not be used to endorse or promote
+  *    products derived from this software without specific prior written
+  *    permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``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 TERRENCE R. LAMBERT 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.
+  */
+ struct apic_attach_args {
+     int type;
+     int apic_id;
+     int apic_version;
+     int flags;
+     paddr_t apic_address;
+ };
+ 
+ struct apic_softc {
+     struct device sc_dev;           /* generic device glue */
+     int   sc_apicid;
+ 
+     struct io_apic  *sc_register;
+ };      
+ 
>Audit-Trail:
>Unformatted: