aThis patch updates the BTX to emulate the BIOS function "Copy Extended

Memory" called as function 0x87 of interrupt 0x15.  Since the Mylex RAID
adapter's BIOS used this function to access memory (actually PCI bus
space) beyond 16 MB, this patch also allows BTX to address all 4 Gig of
possible address space on i386+.  Since the loader does not have room for
4 MB of page tables, this was done by turning off paging.

Paging was turned off via a compile time setting which defaults to off.
To enable paging, simply define the make variable PAGING.

rnordier might want to clean this up later.

Submitted by:	W. Gerald Hicks <wghicks@bellsouth.net>,
		Bosko Milekic <bmilekic@ares.dsuper.net>
Reviewed by:	msmith
Required by:	Mylex RAID adapter's BIOS
This commit is contained in:
John Baldwin 1999-10-12 21:33:49 +00:00
parent 831ac5c655
commit 228ace6ebf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=52173
3 changed files with 138 additions and 9 deletions

View File

@ -2,6 +2,10 @@
M4?= m4
.if defined(PAGING)
M4FLAGS+= -DPAGING
.endif
ORG= 0x9000
all: btx
@ -16,7 +20,8 @@ btx: btx.o
.endif
btx.o: btx.m4 btx.s
(cd ${.CURDIR}; ${M4} btx.m4 btx.s) | ${AS} ${AFLAGS} -o ${.TARGET}
(cd ${.CURDIR}; ${M4} ${M4FLAGS} btx.m4 btx.s) | \
${AS} ${AFLAGS} -o ${.TARGET}
CLEANFILES+= btx btx.out btx.o

View File

@ -155,6 +155,7 @@ init.4: movbi1(_ESP0H,TSS_ESP0+1,_di_) # Set ESP0
movbi1(SEL_SDATA,TSS_SS0,_di_) # Set SS0
movbi1(_ESP1H,TSS_ESP1+1,_di_) # Set ESP1
movbi1(_TSSIO,TSS_MAP,_di_) # Set I/O bit map base
ifdef(`PAGING',`
#
# Create page directory.
#
@ -187,20 +188,23 @@ init.6: movb $0x7,%al # Set U:W:P flags
init.7: stosw # Set entry
addw %dx,%ax # Next address
loop init.6 # Till done
')
#
# Bring up the system.
#
movwir(0x2820,_bx) # Set protected mode
callwi(setpic) # IRQ offsets
lidtwm(idtdesc) # Set IDT
ifdef(`PAGING',`
xorw %ax,%ax # Set base
movb $MEM_DIR>>0x8,%ah # of page
movl %eax,%cr3 # directory
')
lgdtwm(gdtdesc) # Set GDT
movl %cr0,%eax # Switch to
o16 # protected mode
orl $0x80000001,%eax # and enable
movl %eax,%cr0 # paging
orl $0x01,%eax #
movl %eax,%cr0 #
jmpfwi(SEL_SCODE,init.8) # To 32-bit code
init.8: xorl %ecx,%ecx # Zero
movb $SEL_SDATA,%cl # To 32-bit
@ -240,14 +244,18 @@ init.9: pushb $0x0 # general
#
exit: cli # Disable interrupts
movl $MEM_ESP0,%esp # Clear stack
ifdef(`PAGING',`
#
# Turn off paging.
#
movl %cr0,%eax # Get CR0
andl $~0x80000000,%eax # Disable
movl %eax,%cr0 # paging
')
xorl %ecx,%ecx # Zero
ifdef(`PAGING',`
movl %ecx,%cr3 # Flush TLB
')
#
# To 16 bits.
#
@ -545,10 +553,64 @@ v86popf.1: movl (%ebx),%eax # Load flags
orl %eax,%edx # flags
jmp v86mon.5 # Finish up
#
# Emulate INT imm8.
# 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 %eax # Save
pushl %ebx # some information
pushl %esi # onto the stack.
pushl %edi
xorl %eax,%eax # clean EAX
xorl %ebx,%ebx # clean EBX
movl 0x4(%ebp),%esi # Get user's ESI
movl 0x3C(%ebp),%ebx # store ES
movw %si,%ax # store SI
shll $0x4,%ebx # Make it a seg.
addl %eax,%ebx # ebx=(es<<4)+si
movb 0x14(%ebx),%al # Grab the
movb 0x17(%ebx),%ah # necessary
shll $0x10,%eax # information
movw 0x12(%ebx),%ax # from
movl %eax,%esi # the
movb 0x1c(%ebx),%al # GDT in order to
movb 0x1f(%ebx),%ah # have %esi offset
shll $0x10,%eax # of source and %edi
movw 0x1a(%ebx),%ax # of destination.
movl %eax,%edi
pushl %ds # Make:
popl %es # es = ds
pushl %ecx # stash ECX
xorl %ecx,%ecx # highw of ECX is clear
movw 0x18(%ebp),%cx # Get user's ECX
rep # repeat...
movsb # perform copy.
popl %ecx # Restore
popl %edi
popl %esi # previous
popl %ebx # register
popl %eax # values.
movb $0x0,0x1d(%ebp) # set ah = 0 to indicate
# success
andb $0xfe,%dl # clear CF
jmp v86mon.5 # Finish up
#
# Emulate INT imm8... also make sure to check if it's int 15/87
#
v86intn: lodsb # Get int no
subl %edi,%esi # From
cmpb $0x15,%al # is it int 15?
jne v86intn.2 # no, skip parse
pushl %eax # stash EAX
movl 0x1c(%ebp),%eax # user's saved EAX
cmpb $0x87,%ah # is it our sub function?
jne v86intn.1 # no, don't handle it
popl %eax # get the stack straight
jmp int15_87 # it's our cue
v86intn.1: popl %eax # restore EAX
v86intn.2: subl %edi,%esi # From
shrl $0x4,%edi # linear
movw %dx,-0x2(%ebx) # Save flags
movw %di,-0x4(%ebx) # Save CS

View File

@ -155,6 +155,7 @@ init.4: movbi1(_ESP0H,TSS_ESP0+1,_di_) # Set ESP0
movbi1(SEL_SDATA,TSS_SS0,_di_) # Set SS0
movbi1(_ESP1H,TSS_ESP1+1,_di_) # Set ESP1
movbi1(_TSSIO,TSS_MAP,_di_) # Set I/O bit map base
ifdef(`PAGING',`
#
# Create page directory.
#
@ -187,20 +188,23 @@ init.6: movb $0x7,%al # Set U:W:P flags
init.7: stosw # Set entry
addw %dx,%ax # Next address
loop init.6 # Till done
')
#
# Bring up the system.
#
movwir(0x2820,_bx) # Set protected mode
callwi(setpic) # IRQ offsets
lidtwm(idtdesc) # Set IDT
ifdef(`PAGING',`
xorw %ax,%ax # Set base
movb $MEM_DIR>>0x8,%ah # of page
movl %eax,%cr3 # directory
')
lgdtwm(gdtdesc) # Set GDT
movl %cr0,%eax # Switch to
o16 # protected mode
orl $0x80000001,%eax # and enable
movl %eax,%cr0 # paging
orl $0x01,%eax #
movl %eax,%cr0 #
jmpfwi(SEL_SCODE,init.8) # To 32-bit code
init.8: xorl %ecx,%ecx # Zero
movb $SEL_SDATA,%cl # To 32-bit
@ -240,14 +244,18 @@ init.9: pushb $0x0 # general
#
exit: cli # Disable interrupts
movl $MEM_ESP0,%esp # Clear stack
ifdef(`PAGING',`
#
# Turn off paging.
#
movl %cr0,%eax # Get CR0
andl $~0x80000000,%eax # Disable
movl %eax,%cr0 # paging
')
xorl %ecx,%ecx # Zero
ifdef(`PAGING',`
movl %ecx,%cr3 # Flush TLB
')
#
# To 16 bits.
#
@ -545,10 +553,64 @@ v86popf.1: movl (%ebx),%eax # Load flags
orl %eax,%edx # flags
jmp v86mon.5 # Finish up
#
# Emulate INT imm8.
# 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 %eax # Save
pushl %ebx # some information
pushl %esi # onto the stack.
pushl %edi
xorl %eax,%eax # clean EAX
xorl %ebx,%ebx # clean EBX
movl 0x4(%ebp),%esi # Get user's ESI
movl 0x3C(%ebp),%ebx # store ES
movw %si,%ax # store SI
shll $0x4,%ebx # Make it a seg.
addl %eax,%ebx # ebx=(es<<4)+si
movb 0x14(%ebx),%al # Grab the
movb 0x17(%ebx),%ah # necessary
shll $0x10,%eax # information
movw 0x12(%ebx),%ax # from
movl %eax,%esi # the
movb 0x1c(%ebx),%al # GDT in order to
movb 0x1f(%ebx),%ah # have %esi offset
shll $0x10,%eax # of source and %edi
movw 0x1a(%ebx),%ax # of destination.
movl %eax,%edi
pushl %ds # Make:
popl %es # es = ds
pushl %ecx # stash ECX
xorl %ecx,%ecx # highw of ECX is clear
movw 0x18(%ebp),%cx # Get user's ECX
rep # repeat...
movsb # perform copy.
popl %ecx # Restore
popl %edi
popl %esi # previous
popl %ebx # register
popl %eax # values.
movb $0x0,0x1d(%ebp) # set ah = 0 to indicate
# success
andb $0xfe,%dl # clear CF
jmp v86mon.5 # Finish up
#
# Emulate INT imm8... also make sure to check if it's int 15/87
#
v86intn: lodsb # Get int no
subl %edi,%esi # From
cmpb $0x15,%al # is it int 15?
jne v86intn.2 # no, skip parse
pushl %eax # stash EAX
movl 0x1c(%ebp),%eax # user's saved EAX
cmpb $0x87,%ah # is it our sub function?
jne v86intn.1 # no, don't handle it
popl %eax # get the stack straight
jmp int15_87 # it's our cue
v86intn.1: popl %eax # restore EAX
v86intn.2: subl %edi,%esi # From
shrl $0x4,%edi # linear
movw %dx,-0x2(%ebx) # Save flags
movw %di,-0x4(%ebx) # Save CS