Home | History | Annotate | Line # | Download | only in lib
      1 /*	$NetBSD: biosmemx.S,v 1.13 2024/08/24 20:23:11 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1997, 1999
      5  *	Matthias Drochner.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  *
     27  */
     28 
     29 #include <machine/asm.h>
     30 
     31 	.text
     32 
     33 /*
     34  * int getextmem2(int buffer[2])
     35  *
     36  * return: 0=OK, -1=error
     37  * buffer[0]: extmem kBytes below 16M (max 15M/1024)
     38  * buffer[1]: extmem above 16M, in 64k units
     39  */
     40 ENTRY(getextmem2)
     41 	pushl	%ebp
     42 	movl	%esp,%ebp
     43 	pushl	%ebx
     44 	pushl	%ecx
     45 	pushl	%edx
     46 	push	%esi
     47 	push	%edi
     48 
     49 	call	_C_LABEL(prot_to_real)
     50 	.code16
     51 
     52 	xorl	%ebx,%ebx
     53 	movl	$0xe801,%eax
     54 	int	$0x15
     55 	pushf
     56 
     57 	movw	%si,%ax
     58 	orw	%si,%bx
     59 	jz	1f		/* if zero use configured values */
     60 	movw	%cx,%ax		/* k below 16M (max 0x3c00 = 15MB) */
     61 	movw	%dx,%bx		/* 64k above 16M */
     62 1:
     63 	popf
     64 	setc	%bl
     65 
     66 	calll	_C_LABEL(real_to_prot)
     67 	.code32
     68 
     69 	movl	8(%ebp),%edi
     70 	xorl	%eax,%eax
     71 	movw	%cx,%ax
     72 	stosl
     73 	movw	%dx,%ax
     74 	stosl
     75 	movb	%bl,%al
     76 	cbw
     77 
     78 	pop	%edi
     79 	pop	%esi
     80 	popl	%edx
     81 	popl	%ecx
     82 	popl	%ebx
     83 	popl	%ebp
     84 	ret
     85 
     86 /*
     87  * int getmementry(int *iterator, int buffer[6])
     88  *
     89  * return: 0=ok, else error
     90  * buffer[0]: start of memory chunk
     91  * buffer[2]: length (bytes)
     92  * buffer[4]: type
     93  * buffer[5]: ACPI 3.0 Extended Attributes bitfield (unused)
     94  *
     95  * Some buggy BIOSes may write to 24 bytes even if only 20 were requested.
     96  * Therefore, the buffer is defined for 6 elements to avoid stack buffer
     97  * overruns.  See PR install/49470.
     98  *
     99  * More details can be found in the:
    100  *
    101  *	Advanced Configuration and Power Interface (ACPI)
    102  *	Specification, Release 6.5, 2022-08-29, UEFI Forum, Inc.,
    103  *	Sec. 15.1 `INT 15H E820H - Query System Address Map',
    104  *	pp. 756-757
    105  *	https://uefi.org/sites/default/files/resources/ACPI_Spec_6_5_Aug29.pdf#page=824
    106  *	https://uefi.org/specs/ACPI/6.5/15_System_Address_Map_Interfaces.html#int-15h-e820h-query-system-address-map
    107  *
    108  * as well as this OSDev.org wiki page:
    109  *
    110  *	https://wiki.osdev.org/Detecting_Memory_(x86)#BIOS_Function:_INT_0x15,_EAX_=_0xE820
    111  */
    112 ENTRY(getmementry)
    113 	pushl	%ebp
    114 	movl	%esp,%ebp
    115 	pushl	%ebx
    116 	pushl	%ecx
    117 	pushl	%edx
    118 	push	%esi
    119 	push	%edi
    120 
    121 	movl	8(%ebp),%eax
    122 	movl	0(%eax),%ebx		/* index */
    123 	movl	$20,%ecx		/* Buffer size */
    124 	movl	$0x534d4150,%edx	/* "SMAP" */
    125 	movl	12(%ebp),%edi		/* buffer address */
    126 
    127 	call	_C_LABEL(prot_to_real)
    128 	.code16
    129 
    130 	push	%di
    131 	shrl	$4,%edi
    132 	mov	%ds,%ax
    133 	add	%di,%ax
    134 	mov	%ax,%es
    135 	pop	%di
    136 	and	$0xf,%di		/* buffer address now in ES:DI */
    137 
    138 	movl	$0xe820,%eax		/* Some BIOS check EAX value */
    139 	int	$0x15
    140 
    141 	setc	%cl
    142 
    143 	calll	_C_LABEL(real_to_prot)
    144 	.code32
    145 
    146 	movl	8(%ebp),%eax
    147 	movl	%ebx,0(%eax)		/* updated index */
    148 	xorl	%eax,%eax
    149 	movb	%cl,%al
    150 
    151 	pop	%edi
    152 	pop	%esi
    153 	popl	%edx
    154 	popl	%ecx
    155 	popl	%ebx
    156 	popl	%ebp
    157 	ret
    158 
    159 /*
    160  * int biosA20(void)
    161  *
    162  * return: 0=ok, else error
    163  */
    164 ENTRY(biosA20)
    165 	pushl	%ebp
    166 	movl	%esp,%ebp
    167 	pushl	%ebx
    168 	pushl	%ecx
    169 	pushl	%edx
    170 	push	%esi
    171 	push	%edi
    172 
    173 	call	_C_LABEL(prot_to_real)
    174 	.code16
    175 
    176 	movl	$0x2401,%eax
    177 	int	$0x15
    178 	setc	%cl
    179 
    180 	calll	_C_LABEL(real_to_prot)
    181 	.code32
    182 
    183 	movzbl	%cl,%eax
    184 
    185 	pop	%edi
    186 	pop	%esi
    187 	popl	%edx
    188 	popl	%ecx
    189 	popl	%ebx
    190 	popl	%ebp
    191 	ret
    192