00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <assert.h>
00022 #include <gpxe/io.h>
00023 #include <gpxe/efi/efi.h>
00024 #include <gpxe/efi/Protocol/CpuIo.h>
00025 #include <gpxe/efi/efi_io.h>
00026
00027
00028
00029
00030
00031
00032
00033
00034 static EFI_CPU_IO_PROTOCOL *cpu_io;
00035 EFI_REQUIRE_PROTOCOL ( EFI_CPU_IO_PROTOCOL, &cpu_io );
00036
00037
00038 #define MAX_PORT_ADDRESS 0xffff
00039
00040
00041
00042
00043
00044
00045
00046 #define IS_PORT_ADDRESS(io_addr) \
00047 ( ( ( intptr_t ) (io_addr) ) <= MAX_PORT_ADDRESS )
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 static EFI_CPU_IO_PROTOCOL_WIDTH efi_width ( size_t size ) {
00061 switch ( size ) {
00062 case 1 : return EfiCpuIoWidthFifoUint8;
00063 case 2 : return EfiCpuIoWidthFifoUint16;
00064 case 4 : return EfiCpuIoWidthFifoUint32;
00065 case 8 : return EfiCpuIoWidthFifoUint64;
00066 default :
00067 assert ( 0 );
00068
00069 return EfiCpuIoWidthMaximum;
00070 }
00071 }
00072
00073
00074
00075
00076
00077
00078
00079
00080 unsigned long long efi_ioread ( volatile void *io_addr, size_t size ) {
00081 EFI_CPU_IO_PROTOCOL_IO_MEM read;
00082 unsigned long long data = 0;
00083 EFI_STATUS efirc;
00084
00085 read = ( IS_PORT_ADDRESS ( io_addr ) ?
00086 cpu_io->Io.Read : cpu_io->Mem.Read );
00087
00088 if ( ( efirc = read ( cpu_io, efi_width ( size ),
00089 ( intptr_t ) io_addr, 1,
00090 ( void * ) &data ) ) != 0 ) {
00091 DBG ( "EFI I/O read at %p failed: %s\n",
00092 io_addr, efi_strerror ( efirc ) );
00093 return -1ULL;
00094 }
00095
00096 return data;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106 void efi_iowrite ( unsigned long long data, volatile void *io_addr,
00107 size_t size ) {
00108 EFI_CPU_IO_PROTOCOL_IO_MEM write;
00109 EFI_STATUS efirc;
00110
00111 write = ( IS_PORT_ADDRESS ( io_addr ) ?
00112 cpu_io->Io.Write : cpu_io->Mem.Write );
00113
00114 if ( ( efirc = write ( cpu_io, efi_width ( size ),
00115 ( intptr_t ) io_addr, 1,
00116 ( void * ) &data ) ) != 0 ) {
00117 DBG ( "EFI I/O write at %p failed: %s\n",
00118 io_addr, efi_strerror ( efirc ) );
00119 }
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 void efi_ioreads ( volatile void *io_addr, void *data,
00131 size_t size, unsigned int count ) {
00132 EFI_CPU_IO_PROTOCOL_IO_MEM read;
00133 EFI_STATUS efirc;
00134
00135 read = ( IS_PORT_ADDRESS ( io_addr ) ?
00136 cpu_io->Io.Read : cpu_io->Mem.Read );
00137
00138 if ( ( efirc = read ( cpu_io, efi_width ( size ),
00139 ( intptr_t ) io_addr, count,
00140 ( void * ) data ) ) != 0 ) {
00141 DBG ( "EFI I/O string read at %p failed: %s\n",
00142 io_addr, efi_strerror ( efirc ) );
00143 }
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 void efi_iowrites ( volatile void *io_addr, const void *data,
00155 size_t size, unsigned int count ) {
00156 EFI_CPU_IO_PROTOCOL_IO_MEM write;
00157 EFI_STATUS efirc;
00158
00159 write = ( IS_PORT_ADDRESS ( io_addr ) ?
00160 cpu_io->Io.Write : cpu_io->Mem.Write );
00161
00162 if ( ( efirc = write ( cpu_io, efi_width ( size ),
00163 ( intptr_t ) io_addr, count,
00164 ( void * ) data ) ) != 0 ) {
00165 DBG ( "EFI I/O write at %p failed: %s\n",
00166 io_addr, efi_strerror ( efirc ) );
00167 }
00168 }
00169
00170
00171
00172
00173
00174 static void efi_iodelay ( void ) {
00175
00176 outb ( 0, 0x80 );
00177 }
00178
00179 PROVIDE_IOAPI_INLINE ( efi, phys_to_bus );
00180 PROVIDE_IOAPI_INLINE ( efi, bus_to_phys );
00181 PROVIDE_IOAPI_INLINE ( efi, ioremap );
00182 PROVIDE_IOAPI_INLINE ( efi, iounmap );
00183 PROVIDE_IOAPI_INLINE ( efi, io_to_bus );
00184 PROVIDE_IOAPI_INLINE ( efi, readb );
00185 PROVIDE_IOAPI_INLINE ( efi, readw );
00186 PROVIDE_IOAPI_INLINE ( efi, readl );
00187 PROVIDE_IOAPI_INLINE ( efi, readq );
00188 PROVIDE_IOAPI_INLINE ( efi, writeb );
00189 PROVIDE_IOAPI_INLINE ( efi, writew );
00190 PROVIDE_IOAPI_INLINE ( efi, writel );
00191 PROVIDE_IOAPI_INLINE ( efi, writeq );
00192 PROVIDE_IOAPI_INLINE ( efi, inb );
00193 PROVIDE_IOAPI_INLINE ( efi, inw );
00194 PROVIDE_IOAPI_INLINE ( efi, inl );
00195 PROVIDE_IOAPI_INLINE ( efi, outb );
00196 PROVIDE_IOAPI_INLINE ( efi, outw );
00197 PROVIDE_IOAPI_INLINE ( efi, outl );
00198 PROVIDE_IOAPI_INLINE ( efi, insb );
00199 PROVIDE_IOAPI_INLINE ( efi, insw );
00200 PROVIDE_IOAPI_INLINE ( efi, insl );
00201 PROVIDE_IOAPI_INLINE ( efi, outsb );
00202 PROVIDE_IOAPI_INLINE ( efi, outsw );
00203 PROVIDE_IOAPI_INLINE ( efi, outsl );
00204 PROVIDE_IOAPI ( efi, iodelay, efi_iodelay );
00205 PROVIDE_IOAPI_INLINE ( efi, mb );