Annotation of qemu/roms/ipxe/src/interface/efi/efi_io.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (C) 2008 Michael Brown <[email protected]>.
                      3:  *
                      4:  * This program is free software; you can redistribute it and/or
                      5:  * modify it under the terms of the GNU General Public License as
                      6:  * published by the Free Software Foundation; either version 2 of the
                      7:  * License, or any later version.
                      8:  *
                      9:  * This program is distributed in the hope that it will be useful, but
                     10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     12:  * General Public License for more details.
                     13:  *
                     14:  * You should have received a copy of the GNU General Public License
                     15:  * along with this program; if not, write to the Free Software
                     16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17:  */
                     18: 
                     19: FILE_LICENCE ( GPL2_OR_LATER );
                     20: 
                     21: #include <assert.h>
                     22: #include <ipxe/io.h>
                     23: #include <ipxe/efi/efi.h>
                     24: #include <ipxe/efi/Protocol/CpuIo.h>
                     25: #include <ipxe/efi/efi_io.h>
                     26: 
                     27: /** @file
                     28:  *
                     29:  * iPXE I/O API for EFI
                     30:  *
                     31:  */
                     32: 
                     33: /** CPU I/O protocol */
                     34: static EFI_CPU_IO_PROTOCOL *cpu_io;
                     35: EFI_REQUIRE_PROTOCOL ( EFI_CPU_IO_PROTOCOL, &cpu_io );
                     36: 
                     37: /** Maximum address that can be used for port I/O */
                     38: #define MAX_PORT_ADDRESS 0xffff
                     39: 
                     40: /**
                     41:  * Determine whether or not address is a port I/O address
                     42:  *
                     43:  * @v io_addr          I/O address
                     44:  * @v is_port          I/O address is a port I/O address
                     45:  */
                     46: #define IS_PORT_ADDRESS(io_addr) \
                     47:        ( ( ( intptr_t ) (io_addr) ) <= MAX_PORT_ADDRESS )
                     48: 
                     49: /**
                     50:  * Determine EFI CPU I/O width code
                     51:  *
                     52:  * @v size             Size of value
                     53:  * @ret width          EFI width code
                     54:  *
                     55:  * Someone at Intel clearly gets paid by the number of lines of code
                     56:  * they write.  No-one should ever be able to make I/O this
                     57:  * convoluted.  The EFI_CPU_IO_PROTOCOL_WIDTH enum is my favourite
                     58:  * idiocy.
                     59:  */
                     60: static EFI_CPU_IO_PROTOCOL_WIDTH efi_width ( size_t size ) {
                     61:        switch ( size ) {
                     62:        case 1 :        return EfiCpuIoWidthFifoUint8;
                     63:        case 2 :        return EfiCpuIoWidthFifoUint16;
                     64:        case 4 :        return EfiCpuIoWidthFifoUint32;
                     65:        case 8 :        return EfiCpuIoWidthFifoUint64;
                     66:        default :
                     67:                assert ( 0 );
                     68:                /* I wonder what this will actually do... */
                     69:                return EfiCpuIoWidthMaximum;
                     70:        }
                     71: }
                     72: 
                     73: /**
                     74:  * Read from device
                     75:  *
                     76:  * @v io_addr          I/O address
                     77:  * @v size             Size of value
                     78:  * @ret data           Value read
                     79:  */
                     80: unsigned long long efi_ioread ( volatile void *io_addr, size_t size ) {
                     81:        EFI_CPU_IO_PROTOCOL_IO_MEM read;
                     82:        unsigned long long data = 0;
                     83:        EFI_STATUS efirc;
                     84: 
                     85:        read = ( IS_PORT_ADDRESS ( io_addr ) ?
                     86:                 cpu_io->Io.Read : cpu_io->Mem.Read );
                     87: 
                     88:        if ( ( efirc = read ( cpu_io, efi_width ( size ),
                     89:                              ( intptr_t ) io_addr, 1,
                     90:                              ( void * ) &data ) ) != 0 ) {
                     91:                DBG ( "EFI I/O read at %p failed: %s\n",
                     92:                      io_addr, efi_strerror ( efirc ) );
                     93:                return -1ULL;
                     94:        }
                     95: 
                     96:        return data;
                     97: }
                     98: 
                     99: /**
                    100:  * Write to device
                    101:  *
                    102:  * @v data             Value to write
                    103:  * @v io_addr          I/O address
                    104:  * @v size             Size of value
                    105:  */
                    106: void efi_iowrite ( unsigned long long data, volatile void *io_addr,
                    107:                   size_t size ) {
                    108:        EFI_CPU_IO_PROTOCOL_IO_MEM write;
                    109:        EFI_STATUS efirc;
                    110: 
                    111:        write = ( IS_PORT_ADDRESS ( io_addr ) ?
                    112:                  cpu_io->Io.Write : cpu_io->Mem.Write );
                    113: 
                    114:        if ( ( efirc = write ( cpu_io, efi_width ( size ),
                    115:                               ( intptr_t ) io_addr, 1,
                    116:                               ( void * ) &data ) ) != 0 ) {
                    117:                DBG ( "EFI I/O write at %p failed: %s\n",
                    118:                      io_addr, efi_strerror ( efirc ) );
                    119:        }
                    120: }
                    121: 
                    122: /**
                    123:  * String read from device
                    124:  *
                    125:  * @v io_addr          I/O address
                    126:  * @v data             Data buffer
                    127:  * @v size             Size of values
                    128:  * @v count            Number of values to read
                    129:  */
                    130: void efi_ioreads ( volatile void *io_addr, void *data,
                    131:                   size_t size, unsigned int count ) {
                    132:        EFI_CPU_IO_PROTOCOL_IO_MEM read;
                    133:        EFI_STATUS efirc;
                    134: 
                    135:        read = ( IS_PORT_ADDRESS ( io_addr ) ?
                    136:                 cpu_io->Io.Read : cpu_io->Mem.Read );
                    137: 
                    138:        if ( ( efirc = read ( cpu_io, efi_width ( size ),
                    139:                              ( intptr_t ) io_addr, count,
                    140:                              ( void * ) data ) ) != 0 ) {
                    141:                DBG ( "EFI I/O string read at %p failed: %s\n",
                    142:                      io_addr, efi_strerror ( efirc ) );
                    143:        }
                    144: }
                    145: 
                    146: /**
                    147:  * String write to device
                    148:  *
                    149:  * @v io_addr          I/O address
                    150:  * @v data             Data buffer
                    151:  * @v size             Size of values
                    152:  * @v count            Number of values to write
                    153:  */
                    154: void efi_iowrites ( volatile void *io_addr, const void *data,
                    155:                    size_t size, unsigned int count ) {
                    156:        EFI_CPU_IO_PROTOCOL_IO_MEM write;
                    157:        EFI_STATUS efirc;
                    158: 
                    159:        write = ( IS_PORT_ADDRESS ( io_addr ) ?
                    160:                 cpu_io->Io.Write : cpu_io->Mem.Write );
                    161: 
                    162:        if ( ( efirc = write ( cpu_io, efi_width ( size ),
                    163:                               ( intptr_t ) io_addr, count,
                    164:                               ( void * ) data ) ) != 0 ) {
                    165:                DBG ( "EFI I/O write at %p failed: %s\n",
                    166:                      io_addr, efi_strerror ( efirc ) );
                    167:        }
                    168: }
                    169: 
                    170: /**
                    171:  * Wait for I/O-mapped operation to complete
                    172:  *
                    173:  */
                    174: static void efi_iodelay ( void ) {
                    175:        /* Write to non-existent port.  Probably x86-only. */
                    176:        outb ( 0, 0x80 );
                    177: }
                    178: 
                    179: /**
                    180:  * Get memory map
                    181:  *
                    182:  * Can't be done on EFI so return an empty map
                    183:  *
                    184:  * @v memmap           Memory map to fill in
                    185:  */
                    186: static void efi_get_memmap ( struct memory_map *memmap ) {
                    187:        memmap->count = 0;
                    188: }
                    189: 
                    190: PROVIDE_IOAPI_INLINE ( efi, phys_to_bus );
                    191: PROVIDE_IOAPI_INLINE ( efi, bus_to_phys );
                    192: PROVIDE_IOAPI_INLINE ( efi, ioremap );
                    193: PROVIDE_IOAPI_INLINE ( efi, iounmap );
                    194: PROVIDE_IOAPI_INLINE ( efi, io_to_bus );
                    195: PROVIDE_IOAPI_INLINE ( efi, readb );
                    196: PROVIDE_IOAPI_INLINE ( efi, readw );
                    197: PROVIDE_IOAPI_INLINE ( efi, readl );
                    198: PROVIDE_IOAPI_INLINE ( efi, readq );
                    199: PROVIDE_IOAPI_INLINE ( efi, writeb );
                    200: PROVIDE_IOAPI_INLINE ( efi, writew );
                    201: PROVIDE_IOAPI_INLINE ( efi, writel );
                    202: PROVIDE_IOAPI_INLINE ( efi, writeq );
                    203: PROVIDE_IOAPI_INLINE ( efi, inb );
                    204: PROVIDE_IOAPI_INLINE ( efi, inw );
                    205: PROVIDE_IOAPI_INLINE ( efi, inl );
                    206: PROVIDE_IOAPI_INLINE ( efi, outb );
                    207: PROVIDE_IOAPI_INLINE ( efi, outw );
                    208: PROVIDE_IOAPI_INLINE ( efi, outl );
                    209: PROVIDE_IOAPI_INLINE ( efi, insb );
                    210: PROVIDE_IOAPI_INLINE ( efi, insw );
                    211: PROVIDE_IOAPI_INLINE ( efi, insl );
                    212: PROVIDE_IOAPI_INLINE ( efi, outsb );
                    213: PROVIDE_IOAPI_INLINE ( efi, outsw );
                    214: PROVIDE_IOAPI_INLINE ( efi, outsl );
                    215: PROVIDE_IOAPI ( efi, iodelay, efi_iodelay );
                    216: PROVIDE_IOAPI_INLINE ( efi, mb );
                    217: PROVIDE_IOAPI ( efi, get_memmap, efi_get_memmap );

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.