Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Mar 2008 07:58:20 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 137384 for review
Message-ID:  <200803110758.m2B7wKeQ047853@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=137384

Change 137384 by rwatson@rwatson_cinnamon on 2008/03/11 07:58:19

	Integrate zcopybpf branch.

Affected files ...

.. //depot/projects/zcopybpf/src/sys/amd64/amd64/legacy.c#4 integrate
.. //depot/projects/zcopybpf/src/sys/amd64/amd64/mp_machdep.c#8 integrate
.. //depot/projects/zcopybpf/src/sys/boot/i386/btx/btx/btx.S#3 integrate
.. //depot/projects/zcopybpf/src/sys/conf/files#20 integrate
.. //depot/projects/zcopybpf/src/sys/dev/acpica/acpi.c#10 integrate
.. //depot/projects/zcopybpf/src/sys/dev/cpufreq/ichss.c#2 integrate
.. //depot/projects/zcopybpf/src/sys/dev/msk/if_msk.c#11 integrate
.. //depot/projects/zcopybpf/src/sys/dev/vr/if_vr.c#1 branch
.. //depot/projects/zcopybpf/src/sys/dev/vr/if_vrreg.h#1 branch
.. //depot/projects/zcopybpf/src/sys/dev/wpi/if_wpi.c#6 integrate
.. //depot/projects/zcopybpf/src/sys/dev/wpi/if_wpireg.h#3 integrate
.. //depot/projects/zcopybpf/src/sys/dev/wpi/if_wpivar.h#2 integrate
.. //depot/projects/zcopybpf/src/sys/i386/cpufreq/est.c#3 integrate
.. //depot/projects/zcopybpf/src/sys/i386/i386/legacy.c#4 integrate
.. //depot/projects/zcopybpf/src/sys/i386/i386/mp_machdep.c#10 integrate
.. //depot/projects/zcopybpf/src/sys/kern/kern_synch.c#9 integrate
.. //depot/projects/zcopybpf/src/sys/kern/sched_4bsd.c#10 integrate
.. //depot/projects/zcopybpf/src/sys/kern/sched_ule.c#16 integrate
.. //depot/projects/zcopybpf/src/sys/kern/subr_bus.c#9 integrate
.. //depot/projects/zcopybpf/src/sys/kern/subr_smp.c#8 integrate
.. //depot/projects/zcopybpf/src/sys/modules/vr/Makefile#2 integrate
.. //depot/projects/zcopybpf/src/sys/netsmb/smb_conn.h#3 integrate
.. //depot/projects/zcopybpf/src/sys/pc98/conf/GENERIC#10 integrate
.. //depot/projects/zcopybpf/src/sys/pci/if_vr.c#6 delete
.. //depot/projects/zcopybpf/src/sys/pci/if_vrreg.h#3 delete
.. //depot/projects/zcopybpf/src/sys/security/audit/audit_worker.c#6 integrate
.. //depot/projects/zcopybpf/src/sys/sparc64/conf/GENERIC#9 integrate
.. //depot/projects/zcopybpf/src/sys/sun4v/sun4v/mp_machdep.c#5 integrate
.. //depot/projects/zcopybpf/src/sys/sys/sched.h#4 integrate
.. //depot/projects/zcopybpf/src/sys/ufs/ffs/ffs_softdep.c#11 integrate

Differences ...

==== //depot/projects/zcopybpf/src/sys/amd64/amd64/legacy.c#4 (text+ko) ====

@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/legacy.c,v 1.61 2007/09/30 11:05:13 marius Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/legacy.c,v 1.62 2008/03/10 22:18:06 jhb Exp $");
 
 /*
  * This code implements a system driver for legacy systems that do not
@@ -132,20 +132,10 @@
 legacy_attach(device_t dev)
 {
 	device_t child;
-	int i;
 
-	/* First, attach the CPU pseudo-driver. */
-	for (i = 0; i <= mp_maxid; i++)
-		if (!CPU_ABSENT(i)) {
-			child = BUS_ADD_CHILD(dev, 0, "cpu", i);
-			if (child == NULL)
-				panic("legacy_attach cpu");
-			device_probe_and_attach(child);
-		}
-
 	/*
-	 * Second, let our child driver's identify any child devices that
-	 * they can find.  Once that is done attach any devices that we
+	 * Let our child drivers identify any child devices that they
+	 * can find.  Once that is done attach any devices that we
 	 * found.
 	 */
 	bus_generic_probe(dev);
@@ -241,6 +231,7 @@
  * Legacy CPU attachment when ACPI is not available.  Drivers like
  * cpufreq(4) hang off this.
  */
+static void	cpu_identify(driver_t *driver, device_t parent);
 static int	cpu_read_ivar(device_t dev, device_t child, int index,
 		    uintptr_t *result);
 static device_t cpu_add_child(device_t bus, int order, const char *name,
@@ -254,6 +245,7 @@
 
 static device_method_t cpu_methods[] = {
 	/* Device interface */
+	DEVMETHOD(device_identify,	cpu_identify),
 	DEVMETHOD(device_probe,		bus_generic_probe),
 	DEVMETHOD(device_attach,	bus_generic_attach),
 	DEVMETHOD(device_detach,	bus_generic_detach),
@@ -287,6 +279,25 @@
 static devclass_t cpu_devclass;
 DRIVER_MODULE(cpu, legacy, cpu_driver, cpu_devclass, 0, 0);
 
+static void
+cpu_identify(driver_t *driver, device_t parent)
+{
+	device_t child;
+	int i;
+
+	/*
+	 * Attach a cpuX device for each CPU.  We use an order of 150
+	 * so that these devices are attached after the Host-PCI
+	 * bridges (which are added at order 100).
+	 */
+	for (i = 0; i <= mp_maxid; i++)
+		if (!CPU_ABSENT(i)) {
+			child = BUS_ADD_CHILD(parent, 150, "cpu", i);
+			if (child == NULL)
+				panic("legacy_attach cpu");
+		}
+}
+
 static device_t
 cpu_add_child(device_t bus, int order, const char *name, int unit)
 {

==== //depot/projects/zcopybpf/src/sys/amd64/amd64/mp_machdep.c#8 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/mp_machdep.c,v 1.288 2008/03/02 07:58:40 jeff Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/mp_machdep.c,v 1.289 2008/03/10 01:32:48 jeff Exp $");
 
 #include "opt_cpu.h"
 #include "opt_kstack_pages.h"
@@ -950,15 +950,8 @@
 
 	ipi_bitmap = atomic_readandclear_int(&cpu_ipi_pending[cpu]);
 
-	if (ipi_bitmap & (1 << IPI_PREEMPT)) {
-		struct thread *running_thread = curthread;
-		thread_lock(running_thread);
-		if (running_thread->td_critnest > 1) 
-			running_thread->td_owepreempt = 1;
-		else 		
-			mi_switch(SW_INVOL | SW_PREEMPT, NULL);
-		thread_unlock(running_thread);
-	}
+	if (ipi_bitmap & (1 << IPI_PREEMPT))
+		sched_preempt(curthread);
 
 	/* Nothing to do for AST */
 }

==== //depot/projects/zcopybpf/src/sys/boot/i386/btx/btx/btx.S#3 (text+ko) ====

@@ -12,7 +12,7 @@
  * warranties of merchantability and fitness for a particular
  * purpose.
  *
- * $FreeBSD: src/sys/boot/i386/btx/btx/btx.S,v 1.45 2008/02/27 23:35:39 jhb Exp $
+ * $FreeBSD: src/sys/boot/i386/btx/btx/btx.S,v 1.46 2008/03/10 21:43:31 jhb Exp $
  */
 
 /*
@@ -21,11 +21,11 @@
 		.set MEM_BTX,0x1000		# Start of BTX memory
 		.set MEM_ESP0,0x1800		# Supervisor stack
 		.set MEM_BUF,0x1800		# Scratch buffer
-		.set MEM_ESP1,0x1e00		# Link stack
-		.set MEM_IDT,0x1e00		# IDT
-		.set MEM_TSS,0x1f98		# TSS
-		.set MEM_MAP,0x2000		# I/O bit map
-		.set MEM_TSS_END,0x3fff		# Page directory
+		.set MEM_ESPR,0x5e00		# Real mode stack
+		.set MEM_IDT,0x5e00		# IDT
+		.set MEM_TSS,0x5f98		# TSS
+		.set MEM_MAP,0x6000		# I/O bit map
+		.set MEM_TSS_END,0x7fff		# End of TSS
 		.set MEM_ORG,0x9000		# BTX code
 		.set MEM_USR,0xa000		# Start of user memory
 /*
@@ -48,7 +48,6 @@
  */
 		.set TSS_ESP0,0x4		# PL 0 ESP
 		.set TSS_SS0,0x8		# PL 0 SS
-		.set TSS_ESP1,0xc		# PL 1 ESP
 		.set TSS_MAP,0x66		# I/O bit map base
 /*
  * System calls.
@@ -56,10 +55,20 @@
 		.set SYS_EXIT,0x0		# Exit
 		.set SYS_EXEC,0x1		# Exec
 /*
- * V86 constants.
+ * Fields in V86 interface structure.
+ */
+		.set V86_CTL,0x0		# Control flags
+		.set V86_ADDR,0x4		# Int number/address
+		.set V86_ES,0x8			# V86 ES
+		.set V86_DS,0xc			# V86 DS
+		.set V86_FS,0x10		# V86 FS
+		.set V86_GS,0x14		# V86 GS
+/*
+ * V86 control flags.
  */
-		.set V86_FLG,0x208eff		# V86 flag mask
-		.set V86_STK,0x400		# V86 stack allowance
+		.set V86F_ADDR,0x10000		# Segment:offset address
+		.set V86F_CALLF,0x20000		# Emulate far call
+		.set V86F_FLAGS,0x40000		# Return flags
 /*
  * Dump format control bytes.
  */
@@ -77,7 +86,6 @@
  * BIOS Data Area locations.
  */
 		.set BDA_MEM,0x413		# Free memory
-		.set BDA_KEYFLAGS,0x417		# Keyboard shift-state flags
 		.set BDA_SCR,0x449		# Video mode
 		.set BDA_POS,0x450		# Cursor position
 		.set BDA_BOOT,0x472		# Boot howto flag
@@ -85,7 +93,6 @@
  * Derivations, for brevity.
  */
 		.set _ESP0H,MEM_ESP0>>0x8	# Byte 1 of ESP0
-		.set _ESP1H,MEM_ESP1>>0x8	# Byte 1 of ESP1
 		.set _TSSIO,MEM_MAP-MEM_TSS	# TSS I/O base
 		.set _TSSLM,MEM_TSS_END-MEM_TSS	# TSS limit
 		.set _IDTLM,MEM_TSS-MEM_IDT-1	# IDT limit
@@ -102,7 +109,7 @@
 		.byte 0xe			# Header size
 		.ascii "BTX"			# Magic
 		.byte 0x1			# Major version
-		.byte 0x1			# Minor version
+		.byte 0x2			# Minor version
 		.byte BTX_FLAGS			# Flags
 		.word PAG_CNT-MEM_ORG>>0xc	# Paging control
 		.word break-start		# Text size
@@ -123,13 +130,24 @@
  */
 		mov $MEM_IDT,%di		# Memory to initialize
 		mov $(MEM_ORG-MEM_IDT)/2,%cx	# Words to zero
-		push %di			# Save
 		rep				# Zero-fill
 		stosw				#  memory
-		pop %di				# Restore
+/*
+ * Update real mode IDT for reflecting hardware interrupts.
+ */
+		mov $intr20,%bx			# Address first handler
+		mov $0x10,%cx			# Number of handlers
+		mov $0x20*4,%di			# First real mode IDT entry
+init.0:		mov %bx,(%di)			# Store IP
+		inc %di				# Address next
+		inc %di				#  entry
+		stosw				# Store CS
+		add $4,%bx			# Next handler
+		loop init.0			# Next IRQ
 /*
  * Create IDT.
  */
+		mov $MEM_IDT,%di
 		mov $idtctl,%si			# Control string
 init.1: 	lodsb				# Get entry
 		cbw				#  count
@@ -155,7 +173,6 @@
  */
 init.4: 	movb $_ESP0H,TSS_ESP0+1(%di)	# Set ESP0
 		movb $SEL_SDATA,TSS_SS0(%di)	# Set SS0
-		movb $_ESP1H,TSS_ESP1+1(%di)	# Set ESP1
 		movb $_TSSIO,TSS_MAP(%di)	# Set I/O bit map base
 /*
  * Bring up the system.
@@ -281,10 +298,6 @@
 		retw				# To caller
 		.code32
 /*
- * Initiate return from V86 mode to user mode.
- */
-inthlt: 	hlt				# To supervisor mode
-/*
  * Exception jump table.
  */
 intx00: 	push $0x0			# Int 0x0: #DE
@@ -310,18 +323,12 @@
 		push $0xc			# Int 0xc: #SS
 		jmp except			# Stack segment fault
 		push $0xd			# Int 0xd: #GP
-		jmp ex_v86			# General protection
+		jmp except			# General protection
 		push $0xe			# Int 0xe: #PF
 		jmp except			# Page fault
 intx10: 	push $0x10			# Int 0x10: #MF
 		jmp ex_noc			# Floating-point error
 /*
- * Handle #GP exception.
- */
-ex_v86: 	testb $0x2,0x12(%esp,1) 	# V86 mode?
-		jz except			# No
-		jmp v86mon			# To monitor
-/*
  * Save a zero error code.
  */
 ex_noc: 	pushl (%esp,1)			# Duplicate int no
@@ -333,24 +340,17 @@
 		pushl %ds			# Save
 		pushl %es			#  most
 		pusha				#  registers
-		movb $0x6,%al			# Push loop count
-		testb $0x2,0x3a(%esp,1) 	# V86 mode?
-		jnz except.1			# Yes
 		pushl %gs			# Set GS
 		pushl %fs			# Set FS
 		pushl %ds			# Set DS
 		pushl %es			# Set ES
-		movb $0x2,%al			# Push loop count
 		cmpw $SEL_SCODE,0x44(%esp,1)	# Supervisor mode?
 		jne except.1			# No
 		pushl %ss			# Set SS
-		leal 0x50(%esp,1),%eax		# Set
-		pushl %eax			#  ESP
 		jmp except.2			# Join common code
-except.1:	pushl 0x50(%esp,1)		# Set GS, FS, DS, ES
-		decb %al			#  (if V86 mode), and
-		jne except.1			#  SS, ESP
-except.2:	push $SEL_SDATA			# Set up
+except.1:	pushl 0x50(%esp,1)		# Set SS
+except.2:	pushl 0x50(%esp,1)		# Set ESP
+		push $SEL_SDATA			# Set up
 		popl %ds			#  to
 		pushl %ds			#  address
 		popl %es			#  data
@@ -374,234 +374,6 @@
 except.2a:	jmp exit			# Exit
 except.3:	leal 0x8(%esp,1),%esp		# Discard err, int no
 		iret				# From interrupt
-/*
- * Return to user mode from V86 mode.
- */
-intrtn: 	cld				# String ops inc
-		pushl %ds			# Address
-		popl %es			#  data
-		leal 0x3c(%ebp),%edx		# V86 Segment registers
-		movl MEM_TSS+TSS_ESP1,%esi	# Link stack pointer
-		lodsl				# INT_V86 args pointer
-		movl %esi,%ebx			# Saved exception frame
-		testl %eax,%eax 		# INT_V86 args?
-		jz intrtn.2			# No
-		movl $MEM_USR,%edi		# User base
-		movl 0x1c(%esi),%ebx		# User ESP
-		movl %eax,(%edi,%ebx,1) 	# Restore to user stack
-		leal 0x8(%edi,%eax,1),%edi	# Arg segment registers
-		testb $0x4,-0x6(%edi)		# Return flags?
-		jz intrtn.1			# No
-		movl 0x30(%ebp),%eax		# Get V86 flags
-		movw %ax,0x18(%esi)		# Set user flags
-intrtn.1:	leal 0x10(%esi),%ebx		# Saved exception frame
-		xchgl %edx,%esi 		# Segment registers
-		movb $0x4,%cl			# Update seg regs
-		rep				#  in INT_V86
-		movsl				#  args
-intrtn.2:	xchgl %edx,%esi			# Segment registers
-		leal 0x28(%ebp),%edi		# Set up seg
-		movb $0x4,%cl			#  regs for
-		rep				#  later
-		movsl				#  pop
-		xchgl %ebx,%esi			# Restore exception
-		movb $0x5,%cl			#  frame to
-		rep				#  supervisor
-		movsl				#  stack
-		movl %esi,MEM_TSS+TSS_ESP1	# Link stack pointer
-		popa				# Restore
-		leal 0x8(%esp,1),%esp		# Discard err, int no
-		popl %es			# Restore
-		popl %ds			#  user
-		popl %fs			#  segment
-		popl %gs			#  registers
-		iret				# To user mode
-/*
- * V86 monitor.
- */
-v86mon: 	cld				# String ops inc
-		pushl $SEL_SDATA		# Set up for
-		popl %ds			#  flat addressing
-		pusha				# Save registers
-		movl %esp,%ebp			# Address stack frame
-		movzwl 0x2c(%ebp),%edi		# Load V86 CS
-		shll $0x4,%edi			# To linear
-		movl 0x28(%ebp),%esi		# Load V86 IP
-		addl %edi,%esi			# Code pointer
-		xorl %ecx,%ecx			# Zero
-		movb $0x2,%cl			# 16-bit operands
-		xorl %eax,%eax			# Zero
-v86mon.1:	lodsb				# Get opcode
-		cmpb $0x66,%al			# Operand size prefix?
-		jne v86mon.2			# No
-		movb $0x4,%cl			# 32-bit operands
-		jmp v86mon.1			# Continue
-v86mon.2:	cmpb $0xf4,%al			# HLT?
-		jne v86mon.3			# No
-		cmpl $inthlt+0x1,%esi		# Is inthlt?
-		jne v86mon.7			# No (ignore)
-		jmp intrtn			# Return to user mode
-v86mon.3:	cmpb $0xf,%al			# Prefixed instruction?
-		jne v86mon.4			# No
-		cmpb $0x09,(%esi)		# Is it a WBINVD?
-		je v86wbinvd			# Yes
-		cmpb $0x30,(%esi)		# Is it a WRMSR?
-		je v86wrmsr			# Yes
-		cmpb $0x32,(%esi)		# Is it a RDMSR?
-		je v86rdmsr			# Yes
-		cmpb $0x20,(%esi)		# Is this a MOV reg,CRx?
-		je v86mov			# Yes
-v86mon.4:	cmpb $0xfa,%al			# CLI?
-		je v86cli			# Yes
-		cmpb $0xfb,%al			# STI?
-		je v86sti			# Yes
-		cmpb $0xcc,%al			# INT3?
-		je v86mon.7			# Yes, ignore
-		movzwl 0x38(%ebp),%ebx		# Load V86 SS
-		shll $0x4,%ebx			# To offset
-		pushl %ebx			# Save
-		addl 0x34(%ebp),%ebx		# Add V86 SP
-		movl 0x30(%ebp),%edx		# Load V86 flags
-		cmpb $0x9c,%al			# PUSHF/PUSHFD?
-		je v86pushf			# Yes
-		cmpb $0x9d,%al			# POPF/POPFD?
-		je v86popf			# Yes
-		cmpb $0xcd,%al			# INT imm8?
-		je v86intn			# Yes
-		cmpb $0xcf,%al			# IRET/IRETD?
-		je v86iret			# Yes
-		popl %ebx			# Restore
-		popa				# Restore
-		jmp except			# Handle exception
-v86mon.5:	movl %edx,0x30(%ebp)		# Save V86 flags
-v86mon.6:	popl %edx			# V86 SS adjustment
-		subl %edx,%ebx			# Save V86
-		movl %ebx,0x34(%ebp)		#  SP
-v86mon.7:	subl %edi,%esi			# From linear
-		movl %esi,0x28(%ebp)		# Save V86 IP
-		popa				# Restore
-		leal 0x8(%esp,1),%esp		# Discard int no, error
-		iret				# To V86 mode
-/*
- * Emulate MOV reg,CRx.
- */
-v86mov: 	movb 0x1(%esi),%bl		# Fetch Mod R/M byte
-		testb $0x10,%bl			# Read CR2 or CR3?
-		jnz v86mov.1			# Yes
-		movl %cr0,%eax			# Read CR0
-		testb $0x20,%bl			# Read CR4 instead?
-		jz v86mov.2			# No
-		movl %cr4,%eax			# Read CR4
-		jmp v86mov.2
-v86mov.1:	movl %cr2,%eax			# Read CR2
-		testb $0x08,%bl			# Read CR3 instead?
-		jz v86mov.2			# No
-		movl %cr3,%eax			# Read CR3
-v86mov.2:	andl $0x7,%ebx			# Compute offset in
-		shl $2,%ebx			#  frame of destination
-		neg %ebx			#  register
-		movl %eax,0x1c(%ebp,%ebx,1)	# Store CR to reg
-		incl %esi			# Adjust IP
-/*
- * Return from emulating a 0x0f prefixed instruction
- */
-v86preret:	incl %esi			# Adjust IP
-		jmp v86mon.7			# Finish up
-/*
- * Emulate WBINVD
- */
-v86wbinvd:	wbinvd				# Write back and invalidate
-						#  cache
-		jmp v86preret			# Finish up
-/*
- * Emulate WRMSR
- */
-v86wrmsr:	movl 0x18(%ebp),%ecx		# Get user's %ecx (MSR to write)
-		movl 0x14(%ebp),%edx		# Load the value
-		movl 0x1c(%ebp),%eax		#  to write
-		wrmsr				# Write MSR
-		jmp v86preret			# Finish up
-/*
- * Emulate RDMSR
- */
-v86rdmsr:	movl 0x18(%ebp),%ecx		# MSR to read
-		rdmsr				# Read the MSR
-		movl %eax,0x1c(%ebp)		# Return the value of
-		movl %edx,0x14(%ebp)		#  the MSR to the user
-		jmp v86preret			# Finish up
-/*
- * Emulate CLI.
- */
-v86cli: 	andb $~0x2,0x31(%ebp)		# Clear IF
-		jmp v86mon.7			# Finish up
-/*
- * Emulate STI.
- */
-v86sti: 	orb $0x2,0x31(%ebp)		# Set IF
-		jmp v86mon.7			# Finish up
-/*
- * Emulate PUSHF/PUSHFD.
- */
-v86pushf:	subl %ecx,%ebx			# Adjust SP
-		cmpb $0x4,%cl			# 32-bit
-		je v86pushf.1			# Yes
-		data16				# 16-bit
-v86pushf.1:	movl %edx,(%ebx)		# Save flags
-		jmp v86mon.6			# Finish up
-/*
- * Emulate IRET/IRETD.
- */
-v86iret:	movzwl (%ebx),%esi		# Load V86 IP
-		movzwl 0x2(%ebx),%edi		# Load V86 CS
-		leal 0x4(%ebx),%ebx		# Adjust SP
-		movl %edi,0x2c(%ebp)		# Save V86 CS
-		xorl %edi,%edi			# No ESI adjustment
-/*
- * Emulate POPF/POPFD (and remainder of IRET/IRETD).
- */
-v86popf:	cmpb $0x4,%cl			# 32-bit?
-		je v86popf.1			# Yes
-		movl %edx,%eax			# Initialize
-		data16				# 16-bit
-v86popf.1:	movl (%ebx),%eax		# Load flags
-		addl %ecx,%ebx			# Adjust SP
-		andl $V86_FLG,%eax		# Merge
-		andl $~V86_FLG,%edx		#  the
-		orl %eax,%edx			#  flags
-		jmp v86mon.5			# Finish up
-/*
- * trap int 15, function 87
- * reads %es:%si from saved registers on stack to find a GDT containing
- * source and destination locations
- * reads count of words from saved %cx
- * returns success by setting %ah to 0
- */
-int15_87:	pushl %esi			# Save 
-		pushl %edi			#  registers
-		movl 0x3C(%ebp),%edi		# Load ES
-		movzwl 0x4(%ebp),%eax		# Load user's SI
-		shll $0x4,%edi			# EDI = (ES << 4) +
-		addl %eax,%edi			#   SI
-		movl 0x11(%edi),%eax		# Read base of
-		movb 0x17(%edi),%al		#  GDT entry
-		ror $8,%eax			#  for source
-		xchgl %eax,%esi			#  into %esi
-		movl 0x19(%edi),%eax		# Read base of
-		movb 0x1f(%edi),%al		#  GDT entry for
-		ror $8,%eax			#  destination
-		xchgl %eax,%edi			#  into %edi
-		pushl %ds			# Make:
-		popl %es			# es = ds
-		movzwl 0x18(%ebp),%ecx		# Get user's CX
-		shll $0x1,%ecx			# Convert count from words
-		rep				# repeat...
-		movsb				#  perform copy.
-		popl %edi			# Restore
-		popl %esi			#  registers
-		movb $0x0,0x1d(%ebp)		# set ah = 0 to indicate
-						#  success
-		andb $0xfe,%dl			# clear CF
-		jmp v86mon.5			# Finish up
 
 /*
  * Reboot the machine by setting the reboot flag and exiting
@@ -610,37 +382,8 @@
 		jmp exit			# Terminate BTX and reboot
 
 /*
- * Emulate INT imm8... also make sure to check if it's int 15/87
+ * Protected Mode Hardware interrupt jump table.
  */
-v86intn:	lodsb				# Get int no
-		cmpb $0x19,%al			# is it int 19?
-		je reboot			#  yes, reboot the machine
-		cmpb $0x15,%al			# is it int 15?
-		jne v86intn.1			#  no, skip parse
-		cmpb $0x87,0x1d(%ebp)		# is it the memcpy subfunction?
-		je int15_87			#  yes
-		cmpw $0x4f53,0x1c(%ebp)		# is it the delete key callout?
-		jne v86intn.1			#  no, handle the int normally
-		movb BDA_KEYFLAGS,%ch		# get the shift key state
-		andb $0xc,%ch			# mask off just Ctrl and Alt
-		cmpb $0xc,%ch			# are both Ctrl and Alt down?
-		je reboot			# yes, reboot the machine
-v86intn.1:	subl %edi,%esi			# From
-		shrl $0x4,%edi			#  linear
-		movw %dx,-0x2(%ebx)		# Save flags
-		movw %di,-0x4(%ebx)		# Save CS
-		leal -0x6(%ebx),%ebx		# Adjust SP
-		movw %si,(%ebx) 		# Save IP
-		shll $0x2,%eax			# Scale
-		movzwl (%eax),%esi		# Load IP
-		movzwl 0x2(%eax),%edi		# Load CS
-		movl %edi,0x2c(%ebp)		# Save CS
-		xorl %edi,%edi			# No ESI adjustment
-		andb $~0x1,%dh			# Clear TF
-		jmp v86mon.5			# Finish up
-/*
- * Hardware interrupt jump table.
- */
 intx20: 	push $0x8			# Int 0x20: IRQ0
 		jmp int_hw			# V86 int 0x8
 		push $0x9			# Int 0x21: IRQ1
@@ -673,127 +416,239 @@
 		jmp int_hw			# V86 int 0x76
 		push $0x77			# Int 0x2f: IRQ15
 		jmp int_hw			# V86 int 0x77
+
 /*
- * Reflect hardware interrupts.
+ * Invoke real mode interrupt/function call from user mode with arguments.
  */
-int_hw: 	testb $0x2,0xe(%esp,1)		# V86 mode?
-		jz intusr			# No
-		pushl $SEL_SDATA		# Address
-		popl %ds			#  data
-		xchgl %eax,(%esp,1)		# Swap EAX, int no
-		pushl %ebp			# Address
-		movl %esp,%ebp			#  stack frame
-		pushl %ebx			# Save
-		shll $0x2,%eax			# Get int
-		movl (%eax),%eax		#  vector
-		subl $0x6,0x14(%ebp)		# Adjust V86 ESP
-		movzwl 0x18(%ebp),%ebx		# V86 SS
-		shll $0x4,%ebx			#  * 0x10
-		addl 0x14(%ebp),%ebx		#  + V86 ESP
-		xchgw %ax,0x8(%ebp)		# Swap V86 IP
-		rorl $0x10,%eax 		# Swap words
-		xchgw %ax,0xc(%ebp)		# Swap V86 CS
-		roll $0x10,%eax 		# Swap words
-		movl %eax,(%ebx)		# CS:IP for IRET
-		movl 0x10(%ebp),%eax		# V86 flags
-		movw %ax,0x4(%ebx)		# Flags for IRET
-		andb $~0x3,0x11(%ebp)		# Clear IF, TF
-		popl %ebx			# Restore
-		popl %ebp			#  saved
-		popl %eax			#  registers
-		iret				# To V86 mode
+intx31: 	pushl $-1			# Dummy int no for btx_v86
 /*
- * Invoke V86 interrupt from user mode, with arguments.
+ * Invoke real mode interrupt/function call from protected mode.
+ *
+ * We place a trampoline on the user stack that will return to rret_tramp
+ * which will reenter protected mode and then finally return to the user
+ * client.
+ *
+ * Kernel frame %esi points to:		Real mode stack frame at MEM_ESPR:
+ *
+ * -0x00 user %ss			-0x04 kernel %esp (with full frame)
+ * -0x04 user %esp			-0x08 btx_v86 pointer
+ * -0x08 user %eflags			-0x0c flags (only used if interrupt)
+ * -0x0c user %cs			-0x10 real mode CS:IP return trampoline
+ * -0x10 user %eip			-0x12 real mode flags
+ * -0x14 int no				-0x16 real mode CS:IP (target)
+ * -0x18 %eax
+ * -0x1c %ecx
+ * -0x20 %edx
+ * -0x24 %ebx
+ * -0x28 %esp
+ * -0x2c %ebp
+ * -0x30 %esi
+ * -0x34 %edi
+ * -0x38 %gs
+ * -0x3c %fs
+ * -0x40 %ds
+ * -0x44 %es
  */
-intx31: 	stc				# Have btx_v86
-		pushl %eax			# Missing int no
-/*
- * Invoke V86 interrupt from user mode.
- */
-intusr: 	std				# String ops dec
-		pushl %eax			# Expand
-		pushl %eax			#  stack
-		pushl %eax			#  frame
-		pusha				# Save
+int_hw: 	cld				# String ops inc
+		pusha				# Save gp regs
 		pushl %gs			# Save
-		movl %esp,%eax			#  seg regs
-		pushl %fs			#  and
-		pushl %ds			#  point
-		pushl %es			#  to them
+		pushl %fs			#  seg
+		pushl %ds			#  regs
+		pushl %es
 		push $SEL_SDATA			# Set up
 		popl %ds			#  to
 		pushl %ds			#  address
 		popl %es			#  data
+		leal 0x44(%esp,1),%esi		# Base of frame
+		movl -0x14(%esi),%eax		# Get Int no
+		cmpl $-1,%eax			# Hardware interrupt?
+		jne intusr.2			# Yes
+/*
+ * v86 calls save the btx_v86 pointer on the real mode stack and read the
+ * address and flags from the btx_v86 structure.
+ */
 		movl $MEM_USR,%ebx		# User base
 		movl %ebx,%edx			#  address
-		jc intusr.1			# If btx_v86
-		xorl %edx,%edx			# Control flags
-		xorl %ebp,%ebp			# btx_v86 pointer
-intusr.1:	leal 0x50(%esp,1),%esi		# Base of frame
-		pushl %esi			# Save
 		addl -0x4(%esi),%ebx		# User ESP
-		movl MEM_TSS+TSS_ESP1,%edi	# Link stack pointer
-		leal -0x4(%edi),%edi		# Adjust for push
-		xorl %ecx,%ecx			# Zero
-		movb $0x5,%cl			# Push exception
-		rep				#  frame on
-		movsl				#  link stack
-		xchgl %eax,%esi 		# Saved seg regs
-		movl 0x40(%esp,1),%eax		# Get int no
-		testl %edx,%edx 		# Have btx_v86?
-		jz intusr.2			# No
 		movl (%ebx),%ebp		# btx_v86 pointer
-		movb $0x4,%cl			# Count
-		addl %ecx,%ebx			# Adjust for pop
-		rep				# Push saved seg regs
-		movsl				#  on link stack
 		addl %ebp,%edx			# Flatten btx_v86 ptr
-		leal 0x14(%edx),%esi		# Seg regs pointer
-		movl 0x4(%edx),%eax		# Get int no/address
-		movzwl 0x2(%edx),%edx		# Get control flags
-intusr.2:	movl %ebp,(%edi)		# Push btx_v86 and
-		movl %edi,MEM_TSS+TSS_ESP1	#  save link stack ptr
-		popl %edi			# Base of frame
-		xchgl %eax,%ebp 		# Save intno/address
-		movl 0x48(%esp,1),%eax		# Get flags
-		testb $0x2,%dl			# Simulate CALLF?
-		jnz intusr.3			# Yes
-		decl %ebx			# Push flags
-		decl %ebx			#  on V86
-		movw %ax,(%ebx) 		#  stack
-intusr.3:	movb $0x4,%cl			# Count
-		subl %ecx,%ebx			# Push return address
-		movl $inthlt,(%ebx)		#  on V86 stack
-		rep				# Copy seg regs to
-		movsl				#  exception frame
-		xchgl %eax,%ecx 		# Save flags
-		movl %ebx,%eax			# User ESP
-		subl $V86_STK,%eax		# Less bytes
-		ja intusr.4			#  to
-		xorl %eax,%eax			#  keep
-intusr.4:	shrl $0x4,%eax			# Gives segment
-		stosl				# Set SS
-		shll $0x4,%eax			# To bytes
-		xchgl %eax,%ebx 		# Swap
-		subl %ebx,%eax			# Gives offset
-		stosl				# Set ESP
-		xchgl %eax,%ecx 		# Get flags
-		btsl $0x11,%eax 		# Set VM
-		andb $~0x1,%ah			# Clear TF
-		stosl				# Set EFL
-		xchgl %eax,%ebp 		# Get int no/address
-		testb $0x1,%dl			# Address?
-		jnz intusr.5			# Yes
+		movl %edx,MEM_ESPR-0x08		# Save btx_v86 ptr
+		movl -0x08(%esi),%ebx		# Pass user flags to
+		movw %bx,MEM_ESPR-0x12		#  real mode target
+		movl V86_ADDR(%edx),%eax	# Get int no/address
+		movl V86_CTL(%edx),%edx		# Get control flags
+		jmp intusr.3			# Skip hardware interrupt
+/*
+ * Hardware interrupts store a NULL btx_v86 pointer and use the address
+ * (interrupt number) from the stack with empty flags.  Also, we clear
+ * the segment registers for the interrupt handler and ensure interrupts
+ * are disabled when the interrupt handler is invoked.
+ */
+intusr.2:	xorl %edx,%edx			# Control flags
+		movl %edx,MEM_ESPR-0x08		# NULL btx_v86 ptr
+		movl %edx,-0x38(%esi)		# Real mode %gs of 0
+		movl %edx,-0x3c(%esi)		# Real mode %fs of 0
+		movl %edx,-0x40(%esi)		# Real mode %ds of 0
+		movl %edx,-0x44(%esi)		# Real mode %es of 0
+		movl -0x08(%esi),%ebx		# Pass user flags with
+		andl $~0x200,%ebx		#  interrupts disabled
+		movw %bx,MEM_ESPR-0x12		#  to real mode target
+/*
+ * %eax now holds either the interrupt number or segment:offset of function.
+ * %edx now holds the V86F_* flags.
+ */
+intusr.3:	testl $V86F_ADDR,%edx		# Segment:offset?
+		jnz intusr.4			# Yes
 		shll $0x2,%eax			# Scale
 		movl (%eax),%eax		# Load int vector
-intusr.5:	movl %eax,%ecx			# Save
-		shrl $0x10,%eax 		# Gives segment
-		stosl				# Set CS
-		movw %cx,%ax			# Restore
-		stosl				# Set EIP
-		leal 0x10(%esp,1),%esp		# Discard seg regs
-		popa				# Restore
-		iret				# To V86 mode
+		jmp intusr.5			# Skip CALLF test
+intusr.4:	testl $V86F_CALLF,%edx		# Far call?
+		jnz intusr.5			# Ok
+		movl %edx,0x30(%esp,1)		# Place VM86 flags in int no
+		movl $badvm86,%esi		# Display bad
+		call putstr			#  VM86 call
+		popl %es			# Restore
+		popl %ds			#  seg
+		popl %fs			#  regs
+		popl %gs
+		popal				# Restore gp regs
+		jmp ex_noc			# Panic
+/*
+ * If this is a v86 call, copy the seg regs out of the btx_v86 structure.
+ */
+intusr.5:	movl MEM_ESPR-0x08,%ecx		# Get btx_v86 ptr
+		jecxz intusr.6			# Skip for hardware ints
+		leal -0x44(%esi),%edi		# %edi => kernel stack seg regs
+		pushl %esi			# Save
+		leal V86_ES(%ecx),%esi		# %esi => btx_v86 seg regs
+		movl $4,%ecx			# Copy seg regs
+		rep				#  from btx_v86
+		movsl				#  to kernel stack
+		popl %esi			# Restore
+intusr.6:	movl %esp,MEM_ESPR-0x04		# Save kernel stack pointer
+		movl -0x08(%esi),%ebx		# Copy user flags to real
+		movl %ebx,MEM_ESPR-0x0c		#  mode return trampoline
+		movl $rret_tramp,%ebx		# Set return trampoline
+		movl %ebx,MEM_ESPR-0x10		#  CS:IP
+		movl %eax,MEM_ESPR-0x16		# Real mode target CS:IP
+		ljmpw $SEL_RCODE,$intusr.7	# Change to 16-bit segment
+		.code16
+intusr.7:	movl %cr0,%eax			# Leave
+		dec %al				#  protected
+		movl %eax,%cr0			#  mode
+		ljmpw $0x0,$intusr.8
+intusr.8:	xorw %ax,%ax			# Reset %ds
+		movw %ax,%ds			#  and
+		movw %ax,%ss			#  %ss
+		lidt ivtdesc	 		# Set IVT
+		popl %es			# Restore
+		popl %ds			#  seg
+		popl %fs			#  regs
+		popl %gs
+		popal				# Restore gp regs
+		movw $MEM_ESPR-0x16,%sp		# Switch to real mode stack
+		iret				# Call target routine
+/*
+ * For the return to real mode we setup a stack frame like this on the real
+ * mode stack.  Note that callf calls won't pop off the flags, but we just
+ * ignore that by repositioning %sp to be just above the btx_v86 pointer
+ * so it is aligned.  The stack is relative to MEM_ESPR.
+ *
+ * -0x04	kernel %esp
+ * -0x08	btx_v86
+ * -0x0c	%eax
+ * -0x10	%ecx
+ * -0x14	%edx
+ * -0x18	%ebx
+ * -0x1c	%esp
+ * -0x20	%ebp
+ * -0x24	%esi
+ * -0x28	%edi
+ * -0x2c	%gs
+ * -0x30	%fs
+ * -0x34	%ds
+ * -0x38	%es
+ * -0x3c	%eflags
+ */
+rret_tramp:	movw $MEM_ESPR-0x08,%sp		# Reset stack pointer
+		pushal				# Save gp regs
+		pushl %gs			# Save
+		pushl %fs			#  seg
+		pushl %ds			#  regs
+		pushl %es
+		pushfl				# Save %eflags
+		cli				# Disable interrupts
+		std				# String ops dec
+		xorw %ax,%ax			# Reset seg 
+		movw %ax,%ds			#  regs
+		movw %ax,%es			#  (%ss is already 0)
+		lidt idtdesc	 		# Set IDT
+		lgdt gdtdesc	 		# Set GDT
+		mov %cr0,%eax			# Switch to protected
+		inc %ax				#  mode
+		mov %eax,%cr0			#
+		ljmp $SEL_SCODE,$rret_tramp.1	# To 32-bit code
+		.code32
+rret_tramp.1:	xorl %ecx,%ecx			# Zero
+		movb $SEL_SDATA,%cl		# Setup
+		movw %cx,%ss			#  32-bit
+		movw %cx,%ds			#  seg
+		movw %cx,%es			#  regs
+		movl MEM_ESPR-0x04,%esp		# Switch to kernel stack
+		leal 0x44(%esp,1),%esi		# Base of frame
+		andb $~0x2,tss_desc+0x5		# Clear TSS busy
+		movb $SEL_TSS,%cl		# Set task
+		ltr %cx				#  register
+/*
+ * Now we are back in protected mode.  Copy the registers off of the real
+ * mode stack onto the kernel stack.  Also, initialize all the seg regs on
+ * the kernel stack.
+ *
+ * Note that the %esp in the kernel stack after this is garbage, but popa
+ * ignores it, so we don't have to fix it up.
+ */
+		leal -0x18(%esi),%edi		# Kernel stack GP regs
+		pushl %esi			# Save
+		movl $MEM_ESPR-0x0c,%esi	# Real mode stack GP regs
+		movl $8,%ecx			# Copy GP regs from
+		rep				#  real mode stack
+		movsl				#  to kernel stack
+		popl %esi			# Restore
+		movl $SEL_UDATA,%eax		# Selector for data seg regs
+		movl $4,%ecx			# Initialize %ds,
+		rep				#  %es, %fs, and
+		stosl				#  %gs
+/*
+ * If this was a V86 call, copy the saved seg regs on the real mode stack
+ * back over to the btx_v86 structure.  Also, conditionally update the saved
+ * eflags on the kernel stack based on the flags from the user.
+ */
+		movl MEM_ESPR-0x08,%ecx		# Get btx_v86 ptr
+		jecxz rret_tramp.3		# Skip for hardware ints
+		leal V86_GS(%ecx),%edi		# %edi => btx_v86 seg regs
+		pushl %esi			# Save
+		leal MEM_ESPR-0x2c,%esi		# %esi => real mode seg regs
+		xchgl %ecx,%edx			# Save btx_v86 ptr
+		movl $4,%ecx			# Copy seg regs
+		rep				#  from real mode stack
+		movsl				#  to btx_v86
+		popl %esi			# Restore
+		movl V86_CTL(%edx),%edx		# Read V86 control flags
+		testl $V86F_FLAGS,%edx		# User wants flags?
+		jz rret_tramp.3			# No
+		movl MEM_ESPR-0x3c,%eax		# Read real mode flags
+		movw %ax,-0x08(%esi)		# Update user flags (low 16)
+/*
+ * Return to the user task
+ */
+rret_tramp.3:	popl %es			# Restore
+		popl %ds			#  seg
+		popl %fs			#  regs
+		popl %gs
+		popal				# Restore gp regs
+		addl $4,%esp			# Discard int no
+		iret				# Return to user mode
+
 /*
  * System Call.
  */
@@ -1035,6 +890,61 @@
 		ret				# To caller
 #endif
 
+		.code16
+/*
+ * Real Mode Hardware interrupt jump table.
+ */
+intr20: 	push $0x8			# Int 0x20: IRQ0
+		jmp int_hwr			# V86 int 0x8
+		push $0x9			# Int 0x21: IRQ1
+		jmp int_hwr			# V86 int 0x9
+		push $0xa			# Int 0x22: IRQ2
+		jmp int_hwr			# V86 int 0xa
+		push $0xb			# Int 0x23: IRQ3
+		jmp int_hwr			# V86 int 0xb
+		push $0xc			# Int 0x24: IRQ4
+		jmp int_hwr			# V86 int 0xc
+		push $0xd			# Int 0x25: IRQ5
+		jmp int_hwr			# V86 int 0xd
+		push $0xe			# Int 0x26: IRQ6
+		jmp int_hwr			# V86 int 0xe
+		push $0xf			# Int 0x27: IRQ7
+		jmp int_hwr			# V86 int 0xf
+		push $0x70			# Int 0x28: IRQ8
+		jmp int_hwr			# V86 int 0x70
+		push $0x71			# Int 0x29: IRQ9
+		jmp int_hwr			# V86 int 0x71
+		push $0x72			# Int 0x2a: IRQ10
+		jmp int_hwr			# V86 int 0x72
+		push $0x73			# Int 0x2b: IRQ11
+		jmp int_hwr			# V86 int 0x73
+		push $0x74			# Int 0x2c: IRQ12
+		jmp int_hwr			# V86 int 0x74
+		push $0x75			# Int 0x2d: IRQ13
+		jmp int_hwr			# V86 int 0x75
+		push $0x76			# Int 0x2e: IRQ14
+		jmp int_hwr			# V86 int 0x76
+		push $0x77			# Int 0x2f: IRQ15
+		jmp int_hwr			# V86 int 0x77
+/*
+ * Reflect hardware interrupts in real mode.
+ */
+int_hwr: 	push %ax			# Save
+		push %ds			# Save
+		push %bp			# Save
+		mov %sp,%bp			# Address stack frame 
+		xchg %bx,6(%bp)			# Swap BX, int no
+		xor %ax,%ax			# Set %ds:%bx to
+		shl $2,%bx			#  point to
+		mov %ax,%ds			#  IDT entry
+		mov (%bx),%ax			# Load IP
+		mov 2(%bx),%bx			# Load CS
+		xchg %ax,4(%bp)			# Swap saved %ax,%bx with
+		xchg %bx,6(%bp)			#  CS:IP of handler
+		pop %bp				# Restore

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803110758.m2B7wKeQ047853>