1*58a2b000SEvgeniy Ivanov/* $NetBSD: bios_pci.S,v 1.6 2005/12/11 12:17:48 christos Exp $ */ 2*58a2b000SEvgeniy Ivanov 3*58a2b000SEvgeniy Ivanov/* 4*58a2b000SEvgeniy Ivanov * Copyright (c) 1996 5*58a2b000SEvgeniy Ivanov * Matthias Drochner. All rights reserved. 6*58a2b000SEvgeniy Ivanov * 7*58a2b000SEvgeniy Ivanov * Redistribution and use in source and binary forms, with or without 8*58a2b000SEvgeniy Ivanov * modification, are permitted provided that the following conditions 9*58a2b000SEvgeniy Ivanov * are met: 10*58a2b000SEvgeniy Ivanov * 1. Redistributions of source code must retain the above copyright 11*58a2b000SEvgeniy Ivanov * notice, this list of conditions and the following disclaimer. 12*58a2b000SEvgeniy Ivanov * 2. Redistributions in binary form must reproduce the above copyright 13*58a2b000SEvgeniy Ivanov * notice, this list of conditions and the following disclaimer in the 14*58a2b000SEvgeniy Ivanov * documentation and/or other materials provided with the distribution. 15*58a2b000SEvgeniy Ivanov * 16*58a2b000SEvgeniy Ivanov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17*58a2b000SEvgeniy Ivanov * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18*58a2b000SEvgeniy Ivanov * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19*58a2b000SEvgeniy Ivanov * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20*58a2b000SEvgeniy Ivanov * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21*58a2b000SEvgeniy Ivanov * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22*58a2b000SEvgeniy Ivanov * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23*58a2b000SEvgeniy Ivanov * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24*58a2b000SEvgeniy Ivanov * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25*58a2b000SEvgeniy Ivanov * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26*58a2b000SEvgeniy Ivanov * 27*58a2b000SEvgeniy Ivanov */ 28*58a2b000SEvgeniy Ivanov 29*58a2b000SEvgeniy Ivanov/* minimal calls to PCI BIOS */ 30*58a2b000SEvgeniy Ivanov 31*58a2b000SEvgeniy Ivanov#include <machine/asm.h> 32*58a2b000SEvgeniy Ivanov 33*58a2b000SEvgeniy Ivanov#define addr32 .byte 0x67 34*58a2b000SEvgeniy Ivanov#define data32 .byte 0x66 35*58a2b000SEvgeniy Ivanov 36*58a2b000SEvgeniy Ivanov#define PCI_FUNCTION_ID 0xb1 37*58a2b000SEvgeniy Ivanov#define PCI_BIOS_PRESENT 0x01 38*58a2b000SEvgeniy Ivanov#define FIND_PCI_DEVICE 0x02 39*58a2b000SEvgeniy Ivanov#define READ_CONFIG_DWORD 0x0a 40*58a2b000SEvgeniy Ivanov#define WRITE_CONFIG_DWORD 0x0d 41*58a2b000SEvgeniy Ivanov 42*58a2b000SEvgeniy Ivanov/* int pcibios_present(int *signature) 43*58a2b000SEvgeniy Ivanov return: AX from BIOS call, -1 on error 44*58a2b000SEvgeniy Ivanov var param: EDX from BIOS call, must be signature "PCI " 45*58a2b000SEvgeniy Ivanov*/ 46*58a2b000SEvgeniy IvanovENTRY(pcibios_present) 47*58a2b000SEvgeniy Ivanov pushl %ebp 48*58a2b000SEvgeniy Ivanov movl %esp, %ebp 49*58a2b000SEvgeniy Ivanov pushl %ebx 50*58a2b000SEvgeniy Ivanov pushl %ecx 51*58a2b000SEvgeniy Ivanov pushl %edx 52*58a2b000SEvgeniy Ivanov 53*58a2b000SEvgeniy Ivanov call _C_LABEL(prot_to_real) # enter real mode 54*58a2b000SEvgeniy Ivanov .code16 55*58a2b000SEvgeniy Ivanov 56*58a2b000SEvgeniy Ivanov movb $PCI_FUNCTION_ID, %ah 57*58a2b000SEvgeniy Ivanov movb $PCI_BIOS_PRESENT, %al 58*58a2b000SEvgeniy Ivanov int $0x1a 59*58a2b000SEvgeniy Ivanov 60*58a2b000SEvgeniy Ivanov jnc ok1 61*58a2b000SEvgeniy Ivanov movl $-1, %ebx 62*58a2b000SEvgeniy Ivanov jmp err1 63*58a2b000SEvgeniy Ivanov 64*58a2b000SEvgeniy Ivanovok1: 65*58a2b000SEvgeniy Ivanov xorl %ebx, %ebx 66*58a2b000SEvgeniy Ivanov mov %ax, %bx 67*58a2b000SEvgeniy Ivanoverr1: 68*58a2b000SEvgeniy Ivanov calll _C_LABEL(real_to_prot) # back to protected mode 69*58a2b000SEvgeniy Ivanov .code32 70*58a2b000SEvgeniy Ivanov 71*58a2b000SEvgeniy Ivanov movl 8(%ebp), %eax 72*58a2b000SEvgeniy Ivanov movl %edx, (%eax) 73*58a2b000SEvgeniy Ivanov 74*58a2b000SEvgeniy Ivanov movl %ebx, %eax # return value in %eax 75*58a2b000SEvgeniy Ivanov 76*58a2b000SEvgeniy Ivanov popl %edx 77*58a2b000SEvgeniy Ivanov popl %ecx 78*58a2b000SEvgeniy Ivanov popl %ebx 79*58a2b000SEvgeniy Ivanov popl %ebp 80*58a2b000SEvgeniy Ivanov ret 81*58a2b000SEvgeniy Ivanov 82*58a2b000SEvgeniy Ivanov/* int pcibios_finddev(int vendor, int device, int index, int *busdevfcn) 83*58a2b000SEvgeniy Ivanov return: AH from BIOS call, -1 on error 84*58a2b000SEvgeniy Ivanov var param: BX from BIOS call, contains bus/device/function 85*58a2b000SEvgeniy Ivanov*/ 86*58a2b000SEvgeniy IvanovENTRY(pcibios_finddev) 87*58a2b000SEvgeniy Ivanov pushl %ebp 88*58a2b000SEvgeniy Ivanov movl %esp, %ebp 89*58a2b000SEvgeniy Ivanov pushl %ebx 90*58a2b000SEvgeniy Ivanov pushl %ecx 91*58a2b000SEvgeniy Ivanov pushl %edx 92*58a2b000SEvgeniy Ivanov pushl %esi 93*58a2b000SEvgeniy Ivanov 94*58a2b000SEvgeniy Ivanov movl 8(%ebp), %edx 95*58a2b000SEvgeniy Ivanov movl 12(%ebp), %ecx 96*58a2b000SEvgeniy Ivanov movl 16(%ebp), %esi 97*58a2b000SEvgeniy Ivanov 98*58a2b000SEvgeniy Ivanov call _C_LABEL(prot_to_real) # enter real mode 99*58a2b000SEvgeniy Ivanov .code16 100*58a2b000SEvgeniy Ivanov 101*58a2b000SEvgeniy Ivanov movb $PCI_FUNCTION_ID, %ah 102*58a2b000SEvgeniy Ivanov movb $FIND_PCI_DEVICE, %al 103*58a2b000SEvgeniy Ivanov int $0x1a 104*58a2b000SEvgeniy Ivanov 105*58a2b000SEvgeniy Ivanov jnc ok2 106*58a2b000SEvgeniy Ivanov movl $-1, %edx 107*58a2b000SEvgeniy Ivanov jmp err2 108*58a2b000SEvgeniy Ivanov 109*58a2b000SEvgeniy Ivanovok2: 110*58a2b000SEvgeniy Ivanov movl $0,%edx 111*58a2b000SEvgeniy Ivanov movb %ah, %dl 112*58a2b000SEvgeniy Ivanoverr2: 113*58a2b000SEvgeniy Ivanov calll _C_LABEL(real_to_prot) # back to protected mode 114*58a2b000SEvgeniy Ivanov .code32 115*58a2b000SEvgeniy Ivanov 116*58a2b000SEvgeniy Ivanov movl 20(%ebp), %eax 117*58a2b000SEvgeniy Ivanov mov %bx, (%eax) 118*58a2b000SEvgeniy Ivanov 119*58a2b000SEvgeniy Ivanov movl %edx, %eax # return value in %eax 120*58a2b000SEvgeniy Ivanov 121*58a2b000SEvgeniy Ivanov popl %esi 122*58a2b000SEvgeniy Ivanov popl %edx 123*58a2b000SEvgeniy Ivanov popl %ecx 124*58a2b000SEvgeniy Ivanov popl %ebx 125*58a2b000SEvgeniy Ivanov popl %ebp 126*58a2b000SEvgeniy Ivanov ret 127*58a2b000SEvgeniy Ivanov 128*58a2b000SEvgeniy Ivanov/* int pcibios_cfgread(int busdevfcn, int offset, int *value) 129*58a2b000SEvgeniy Ivanov return: AH from BIOS call, -1 on error 130*58a2b000SEvgeniy Ivanov var param: ECX from BIOS call, contains value read 131*58a2b000SEvgeniy Ivanov*/ 132*58a2b000SEvgeniy IvanovENTRY(pcibios_cfgread) 133*58a2b000SEvgeniy Ivanov pushl %ebp 134*58a2b000SEvgeniy Ivanov movl %esp, %ebp 135*58a2b000SEvgeniy Ivanov pushl %ebx 136*58a2b000SEvgeniy Ivanov pushl %ecx 137*58a2b000SEvgeniy Ivanov pushl %edx 138*58a2b000SEvgeniy Ivanov pushl %edi 139*58a2b000SEvgeniy Ivanov 140*58a2b000SEvgeniy Ivanov movl 8(%ebp), %ebx 141*58a2b000SEvgeniy Ivanov movl 12(%ebp), %edi 142*58a2b000SEvgeniy Ivanov 143*58a2b000SEvgeniy Ivanov call _C_LABEL(prot_to_real) # enter real mode 144*58a2b000SEvgeniy Ivanov .code16 145*58a2b000SEvgeniy Ivanov 146*58a2b000SEvgeniy Ivanov movb $PCI_FUNCTION_ID, %ah 147*58a2b000SEvgeniy Ivanov movb $READ_CONFIG_DWORD, %al 148*58a2b000SEvgeniy Ivanov int $0x1a 149*58a2b000SEvgeniy Ivanov 150*58a2b000SEvgeniy Ivanov jnc ok3 151*58a2b000SEvgeniy Ivanov movl $-1, %edx 152*58a2b000SEvgeniy Ivanov jmp err3 153*58a2b000SEvgeniy Ivanov 154*58a2b000SEvgeniy Ivanovok3: 155*58a2b000SEvgeniy Ivanov movl $0,%edx 156*58a2b000SEvgeniy Ivanov movb %ah, %dl 157*58a2b000SEvgeniy Ivanoverr3: 158*58a2b000SEvgeniy Ivanov calll _C_LABEL(real_to_prot) # back to protected mode 159*58a2b000SEvgeniy Ivanov .code32 160*58a2b000SEvgeniy Ivanov 161*58a2b000SEvgeniy Ivanov movl 16(%ebp), %eax 162*58a2b000SEvgeniy Ivanov movl %ecx, (%eax) 163*58a2b000SEvgeniy Ivanov 164*58a2b000SEvgeniy Ivanov movl %edx, %eax # return value in %eax 165*58a2b000SEvgeniy Ivanov 166*58a2b000SEvgeniy Ivanov popl %edi 167*58a2b000SEvgeniy Ivanov popl %edx 168*58a2b000SEvgeniy Ivanov popl %ecx 169*58a2b000SEvgeniy Ivanov popl %ebx 170*58a2b000SEvgeniy Ivanov popl %ebp 171*58a2b000SEvgeniy Ivanov ret 172*58a2b000SEvgeniy Ivanov 173*58a2b000SEvgeniy Ivanov/* int pcibios_cfgwrite(int busdevfcn, int offset, int value) 174*58a2b000SEvgeniy Ivanov return: AH from BIOS call, -1 on error 175*58a2b000SEvgeniy Ivanov var param: ECX from BIOS call, contains value read 176*58a2b000SEvgeniy Ivanov*/ 177*58a2b000SEvgeniy IvanovENTRY(pcibios_cfgwrite) 178*58a2b000SEvgeniy Ivanov pushl %ebp 179*58a2b000SEvgeniy Ivanov movl %esp, %ebp 180*58a2b000SEvgeniy Ivanov pushl %ebx 181*58a2b000SEvgeniy Ivanov pushl %ecx 182*58a2b000SEvgeniy Ivanov pushl %edx 183*58a2b000SEvgeniy Ivanov pushl %edi 184*58a2b000SEvgeniy Ivanov 185*58a2b000SEvgeniy Ivanov movl 8(%ebp), %ebx 186*58a2b000SEvgeniy Ivanov movl 12(%ebp), %edi 187*58a2b000SEvgeniy Ivanov movl 16(%ebp), %ecx 188*58a2b000SEvgeniy Ivanov 189*58a2b000SEvgeniy Ivanov call _C_LABEL(prot_to_real) # enter real mode 190*58a2b000SEvgeniy Ivanov .code16 191*58a2b000SEvgeniy Ivanov 192*58a2b000SEvgeniy Ivanov movb $PCI_FUNCTION_ID, %ah 193*58a2b000SEvgeniy Ivanov movb $WRITE_CONFIG_DWORD, %al 194*58a2b000SEvgeniy Ivanov int $0x1a 195*58a2b000SEvgeniy Ivanov 196*58a2b000SEvgeniy Ivanov jnc ok4 197*58a2b000SEvgeniy Ivanov movl $-1, %edx 198*58a2b000SEvgeniy Ivanov jmp err4 199*58a2b000SEvgeniy Ivanov 200*58a2b000SEvgeniy Ivanovok4: 201*58a2b000SEvgeniy Ivanov movl $0,%edx 202*58a2b000SEvgeniy Ivanov movb %ah, %dl 203*58a2b000SEvgeniy Ivanoverr4: 204*58a2b000SEvgeniy Ivanov calll _C_LABEL(real_to_prot) # back to protected mode 205*58a2b000SEvgeniy Ivanov .code32 206*58a2b000SEvgeniy Ivanov 207*58a2b000SEvgeniy Ivanov movl %edx, %eax # return value in %eax 208*58a2b000SEvgeniy Ivanov 209*58a2b000SEvgeniy Ivanov popl %edi 210*58a2b000SEvgeniy Ivanov popl %edx 211*58a2b000SEvgeniy Ivanov popl %ecx 212*58a2b000SEvgeniy Ivanov popl %ebx 213*58a2b000SEvgeniy Ivanov popl %ebp 214*58a2b000SEvgeniy Ivanov ret 215