|  | @@ -0,0 +1,483 @@
 | 
		
	
		
			
			|  | 1 | +#ifndef _GPXE_IO_H
 | 
		
	
		
			
			|  | 2 | +#define _GPXE_IO_H
 | 
		
	
		
			
			|  | 3 | +
 | 
		
	
		
			
			|  | 4 | +/** @file
 | 
		
	
		
			
			|  | 5 | + *
 | 
		
	
		
			
			|  | 6 | + * gPXE I/O API
 | 
		
	
		
			
			|  | 7 | + *
 | 
		
	
		
			
			|  | 8 | + * The I/O API provides methods for reading from and writing to
 | 
		
	
		
			
			|  | 9 | + * memory-mapped and I/O-mapped devices.
 | 
		
	
		
			
			|  | 10 | + *
 | 
		
	
		
			
			|  | 11 | + * The standard methods (readl()/writel() etc.) do not strictly check
 | 
		
	
		
			
			|  | 12 | + * the type of the address parameter; this is because traditional
 | 
		
	
		
			
			|  | 13 | + * usage does not necessarily provide the correct pointer type.  For
 | 
		
	
		
			
			|  | 14 | + * example, code written for ISA devices at fixed I/O addresses (such
 | 
		
	
		
			
			|  | 15 | + * as the keyboard controller) tend to use plain integer constants for
 | 
		
	
		
			
			|  | 16 | + * the address parameter.
 | 
		
	
		
			
			|  | 17 | + */
 | 
		
	
		
			
			|  | 18 | +
 | 
		
	
		
			
			|  | 19 | +#include <stdint.h>
 | 
		
	
		
			
			|  | 20 | +#include <gpxe/api.h>
 | 
		
	
		
			
			|  | 21 | +#include <config/ioapi.h>
 | 
		
	
		
			
			|  | 22 | +
 | 
		
	
		
			
			|  | 23 | +/**
 | 
		
	
		
			
			|  | 24 | + * Calculate static inline I/O API function name
 | 
		
	
		
			
			|  | 25 | + *
 | 
		
	
		
			
			|  | 26 | + * @v _prefix		Subsystem prefix
 | 
		
	
		
			
			|  | 27 | + * @v _api_func		API function
 | 
		
	
		
			
			|  | 28 | + * @ret _subsys_func	Subsystem API function
 | 
		
	
		
			
			|  | 29 | + */
 | 
		
	
		
			
			|  | 30 | +#define IOAPI_INLINE( _subsys, _api_func ) \
 | 
		
	
		
			
			|  | 31 | +	SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
 | 
		
	
		
			
			|  | 32 | +
 | 
		
	
		
			
			|  | 33 | +/**
 | 
		
	
		
			
			|  | 34 | + * Provide an I/O API implementation
 | 
		
	
		
			
			|  | 35 | + *
 | 
		
	
		
			
			|  | 36 | + * @v _prefix		Subsystem prefix
 | 
		
	
		
			
			|  | 37 | + * @v _api_func		API function
 | 
		
	
		
			
			|  | 38 | + * @v _func		Implementing function
 | 
		
	
		
			
			|  | 39 | + */
 | 
		
	
		
			
			|  | 40 | +#define PROVIDE_IOAPI( _subsys, _api_func, _func ) \
 | 
		
	
		
			
			|  | 41 | +	PROVIDE_SINGLE_API ( IOAPI_PREFIX_ ## _subsys, _api_func, _func )
 | 
		
	
		
			
			|  | 42 | +
 | 
		
	
		
			
			|  | 43 | +/**
 | 
		
	
		
			
			|  | 44 | + * Provide a static inline I/O API implementation
 | 
		
	
		
			
			|  | 45 | + *
 | 
		
	
		
			
			|  | 46 | + * @v _prefix		Subsystem prefix
 | 
		
	
		
			
			|  | 47 | + * @v _api_func		API function
 | 
		
	
		
			
			|  | 48 | + */
 | 
		
	
		
			
			|  | 49 | +#define PROVIDE_IOAPI_INLINE( _subsys, _api_func ) \
 | 
		
	
		
			
			|  | 50 | +	PROVIDE_SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
 | 
		
	
		
			
			|  | 51 | +
 | 
		
	
		
			
			|  | 52 | +/* Include all architecture-independent I/O API headers */
 | 
		
	
		
			
			|  | 53 | +
 | 
		
	
		
			
			|  | 54 | +/* Include all architecture-dependent I/O API headers */
 | 
		
	
		
			
			|  | 55 | +#include <bits/io.h>
 | 
		
	
		
			
			|  | 56 | +
 | 
		
	
		
			
			|  | 57 | +/**
 | 
		
	
		
			
			|  | 58 | + * Wrap an I/O read
 | 
		
	
		
			
			|  | 59 | + *
 | 
		
	
		
			
			|  | 60 | + * @v _func		I/O API function
 | 
		
	
		
			
			|  | 61 | + * @v _type		Data type
 | 
		
	
		
			
			|  | 62 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 63 | + * @v _prefix		Prefix for address in debug message
 | 
		
	
		
			
			|  | 64 | + * @v _ndigits		Number of hex digits for this data type
 | 
		
	
		
			
			|  | 65 | + */
 | 
		
	
		
			
			|  | 66 | +#define IOAPI_READ( _func, _type, io_addr, _prefix, _ndigits ) ( {	      \
 | 
		
	
		
			
			|  | 67 | +	volatile _type *_io_addr =					      \
 | 
		
	
		
			
			|  | 68 | +		( ( volatile _type * ) ( intptr_t ) (io_addr) );	      \
 | 
		
	
		
			
			|  | 69 | +	_type _data = _func ( _io_addr );				      \
 | 
		
	
		
			
			|  | 70 | +	DBGIO ( "[" _prefix " %08lx] => %0" #_ndigits "llx\n",		      \
 | 
		
	
		
			
			|  | 71 | +		io_to_bus ( _io_addr ), ( unsigned long long ) _data );	      \
 | 
		
	
		
			
			|  | 72 | +	_data; } )
 | 
		
	
		
			
			|  | 73 | +
 | 
		
	
		
			
			|  | 74 | +/**
 | 
		
	
		
			
			|  | 75 | + * Wrap an I/O write
 | 
		
	
		
			
			|  | 76 | + *
 | 
		
	
		
			
			|  | 77 | + * @v _func		I/O API function
 | 
		
	
		
			
			|  | 78 | + * @v _type		Data type
 | 
		
	
		
			
			|  | 79 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 80 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 81 | + * @v _prefix		Prefix for address in debug message
 | 
		
	
		
			
			|  | 82 | + * @v _ndigits		Number of hex digits for this data type
 | 
		
	
		
			
			|  | 83 | + */
 | 
		
	
		
			
			|  | 84 | +#define IOAPI_WRITE( _func, _type, data, io_addr, _prefix, _ndigits ) do {    \
 | 
		
	
		
			
			|  | 85 | +	volatile _type *_io_addr =					      \
 | 
		
	
		
			
			|  | 86 | +		( ( volatile _type * ) ( intptr_t ) (io_addr) );	      \
 | 
		
	
		
			
			|  | 87 | +	_type _data = (data);						      \
 | 
		
	
		
			
			|  | 88 | +	DBGIO ( "[" _prefix " %08lx] <= %0" #_ndigits "llx\n",		      \
 | 
		
	
		
			
			|  | 89 | +		io_to_bus ( _io_addr ), ( unsigned long long ) _data );	      \
 | 
		
	
		
			
			|  | 90 | +	_func ( _data, _io_addr );					      \
 | 
		
	
		
			
			|  | 91 | +	} while ( 0 )
 | 
		
	
		
			
			|  | 92 | +
 | 
		
	
		
			
			|  | 93 | +/**
 | 
		
	
		
			
			|  | 94 | + * Wrap an I/O string read
 | 
		
	
		
			
			|  | 95 | + *
 | 
		
	
		
			
			|  | 96 | + * @v _func		I/O API function
 | 
		
	
		
			
			|  | 97 | + * @v _type		Data type
 | 
		
	
		
			
			|  | 98 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 99 | + * @v data		Data buffer
 | 
		
	
		
			
			|  | 100 | + * @v count		Number of elements to read
 | 
		
	
		
			
			|  | 101 | + * @v _prefix		Prefix for address in debug message
 | 
		
	
		
			
			|  | 102 | + * @v _ndigits		Number of hex digits for this data type
 | 
		
	
		
			
			|  | 103 | + */
 | 
		
	
		
			
			|  | 104 | +#define IOAPI_READS( _func, _type, io_addr, data, count, _prefix, _ndigits )  \
 | 
		
	
		
			
			|  | 105 | +	do {								      \
 | 
		
	
		
			
			|  | 106 | +	volatile _type *_io_addr =					      \
 | 
		
	
		
			
			|  | 107 | +		( ( volatile _type * ) ( intptr_t ) (io_addr) );	      \
 | 
		
	
		
			
			|  | 108 | +	void *_data_void = (data); /* Check data is a pointer */	      \
 | 
		
	
		
			
			|  | 109 | +	_type * _data = ( ( _type * ) _data_void );			      \
 | 
		
	
		
			
			|  | 110 | +	const _type * _dbg_data = _data;				      \
 | 
		
	
		
			
			|  | 111 | +	unsigned int _count = (count);					      \
 | 
		
	
		
			
			|  | 112 | +	unsigned int _dbg_count = _count;				      \
 | 
		
	
		
			
			|  | 113 | +	_func ( _io_addr, _data, _count );				      \
 | 
		
	
		
			
			|  | 114 | +	DBGIO ( "[" _prefix " %08lx] =>", io_to_bus ( _io_addr ) );	      \
 | 
		
	
		
			
			|  | 115 | +	while ( _dbg_count-- ) {					      \
 | 
		
	
		
			
			|  | 116 | +		DBGIO ( " %0" #_ndigits "llx",				      \
 | 
		
	
		
			
			|  | 117 | +			( ( unsigned long long ) *(_dbg_data++) ) );	      \
 | 
		
	
		
			
			|  | 118 | +	}								      \
 | 
		
	
		
			
			|  | 119 | +	DBGIO ( "\n" );							      \
 | 
		
	
		
			
			|  | 120 | +	} while ( 0 )
 | 
		
	
		
			
			|  | 121 | +
 | 
		
	
		
			
			|  | 122 | +/**
 | 
		
	
		
			
			|  | 123 | + * Wrap an I/O string write
 | 
		
	
		
			
			|  | 124 | + *
 | 
		
	
		
			
			|  | 125 | + * @v _func		I/O API function
 | 
		
	
		
			
			|  | 126 | + * @v _type		Data type
 | 
		
	
		
			
			|  | 127 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 128 | + * @v data		Data buffer
 | 
		
	
		
			
			|  | 129 | + * @v count		Number of elements to write
 | 
		
	
		
			
			|  | 130 | + * @v _prefix		Prefix for address in debug message
 | 
		
	
		
			
			|  | 131 | + * @v _ndigits		Number of hex digits for this data type
 | 
		
	
		
			
			|  | 132 | + */
 | 
		
	
		
			
			|  | 133 | +#define IOAPI_WRITES( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
 | 
		
	
		
			
			|  | 134 | +	do {								      \
 | 
		
	
		
			
			|  | 135 | +	volatile _type *_io_addr =					      \
 | 
		
	
		
			
			|  | 136 | +		( ( volatile _type * ) ( intptr_t ) (io_addr) );	      \
 | 
		
	
		
			
			|  | 137 | +	const void *_data_void = (data); /* Check data is a pointer */	      \
 | 
		
	
		
			
			|  | 138 | +	const _type * _data = ( ( const _type * ) _data_void );		      \
 | 
		
	
		
			
			|  | 139 | +	const _type * _dbg_data = _data;				      \
 | 
		
	
		
			
			|  | 140 | +	unsigned int _count = (count);					      \
 | 
		
	
		
			
			|  | 141 | +	unsigned int _dbg_count = _count;				      \
 | 
		
	
		
			
			|  | 142 | +	DBGIO ( "[" _prefix " %08lx] <=", io_to_bus ( _io_addr ) );	      \
 | 
		
	
		
			
			|  | 143 | +	while ( _dbg_count-- ) {					      \
 | 
		
	
		
			
			|  | 144 | +		DBGIO ( " %0" #_ndigits "llx",				      \
 | 
		
	
		
			
			|  | 145 | +			( ( unsigned long long ) *(_dbg_data++) ) );	      \
 | 
		
	
		
			
			|  | 146 | +	}								      \
 | 
		
	
		
			
			|  | 147 | +	DBGIO ( "\n" );							      \
 | 
		
	
		
			
			|  | 148 | +	_func ( _io_addr, _data, _count );				      \
 | 
		
	
		
			
			|  | 149 | +	} while ( 0 )
 | 
		
	
		
			
			|  | 150 | +
 | 
		
	
		
			
			|  | 151 | +/**
 | 
		
	
		
			
			|  | 152 | + * Map bus address as an I/O address
 | 
		
	
		
			
			|  | 153 | + *
 | 
		
	
		
			
			|  | 154 | + * @v bus_addr		Bus address
 | 
		
	
		
			
			|  | 155 | + * @v len		Length of region
 | 
		
	
		
			
			|  | 156 | + * @ret io_addr		I/O address
 | 
		
	
		
			
			|  | 157 | + */
 | 
		
	
		
			
			|  | 158 | +void * ioremap ( unsigned long bus_addr, size_t len );
 | 
		
	
		
			
			|  | 159 | +
 | 
		
	
		
			
			|  | 160 | +/**
 | 
		
	
		
			
			|  | 161 | + * Unmap I/O address
 | 
		
	
		
			
			|  | 162 | + *
 | 
		
	
		
			
			|  | 163 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 164 | + */
 | 
		
	
		
			
			|  | 165 | +void iounmap ( volatile const void *io_addr );
 | 
		
	
		
			
			|  | 166 | +
 | 
		
	
		
			
			|  | 167 | +/**
 | 
		
	
		
			
			|  | 168 | + * Convert I/O address to bus address (for debug only)
 | 
		
	
		
			
			|  | 169 | + *
 | 
		
	
		
			
			|  | 170 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 171 | + * @ret bus_addr	Bus address
 | 
		
	
		
			
			|  | 172 | + */
 | 
		
	
		
			
			|  | 173 | +unsigned long io_to_bus ( volatile const void *io_addr );
 | 
		
	
		
			
			|  | 174 | +
 | 
		
	
		
			
			|  | 175 | +/**
 | 
		
	
		
			
			|  | 176 | + * Convert virtual address to a bus address
 | 
		
	
		
			
			|  | 177 | + *
 | 
		
	
		
			
			|  | 178 | + * @v addr		Virtual address
 | 
		
	
		
			
			|  | 179 | + * @ret bus_addr	Bus address
 | 
		
	
		
			
			|  | 180 | + */
 | 
		
	
		
			
			|  | 181 | +unsigned long virt_to_bus ( volatile const void *addr );
 | 
		
	
		
			
			|  | 182 | +
 | 
		
	
		
			
			|  | 183 | +/**
 | 
		
	
		
			
			|  | 184 | + * Convert bus address to a virtual address
 | 
		
	
		
			
			|  | 185 | + *
 | 
		
	
		
			
			|  | 186 | + * @v bus_addr		Bus address
 | 
		
	
		
			
			|  | 187 | + * @ret addr		Virtual address
 | 
		
	
		
			
			|  | 188 | + *
 | 
		
	
		
			
			|  | 189 | + * This operation isn't actually valid within our memory model, and is
 | 
		
	
		
			
			|  | 190 | + * impossible to achieve under -DKEEP_IT_REAL.  Some drivers haven't
 | 
		
	
		
			
			|  | 191 | + * been updated to avoid it yet, though.
 | 
		
	
		
			
			|  | 192 | + */
 | 
		
	
		
			
			|  | 193 | +void * bus_to_virt ( unsigned long bus_addr );
 | 
		
	
		
			
			|  | 194 | +
 | 
		
	
		
			
			|  | 195 | +/**
 | 
		
	
		
			
			|  | 196 | + * Read byte from memory-mapped device
 | 
		
	
		
			
			|  | 197 | + *
 | 
		
	
		
			
			|  | 198 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 199 | + * @ret data		Value read
 | 
		
	
		
			
			|  | 200 | + */
 | 
		
	
		
			
			|  | 201 | +uint8_t readb ( volatile uint8_t *io_addr );
 | 
		
	
		
			
			|  | 202 | +#define readb( io_addr ) IOAPI_READ ( readb, uint8_t, io_addr, "MEM", 2 )
 | 
		
	
		
			
			|  | 203 | +
 | 
		
	
		
			
			|  | 204 | +/**
 | 
		
	
		
			
			|  | 205 | + * Read 16-bit word from memory-mapped device
 | 
		
	
		
			
			|  | 206 | + *
 | 
		
	
		
			
			|  | 207 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 208 | + * @ret data		Value read
 | 
		
	
		
			
			|  | 209 | + */
 | 
		
	
		
			
			|  | 210 | +uint16_t readw ( volatile uint16_t *io_addr );
 | 
		
	
		
			
			|  | 211 | +#define readw( io_addr ) IOAPI_READ ( readw, uint16_t, io_addr, "MEM", 4 )
 | 
		
	
		
			
			|  | 212 | +
 | 
		
	
		
			
			|  | 213 | +/**
 | 
		
	
		
			
			|  | 214 | + * Read 32-bit dword from memory-mapped device
 | 
		
	
		
			
			|  | 215 | + *
 | 
		
	
		
			
			|  | 216 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 217 | + * @ret data		Value read
 | 
		
	
		
			
			|  | 218 | + */
 | 
		
	
		
			
			|  | 219 | +uint32_t readl ( volatile uint32_t *io_addr );
 | 
		
	
		
			
			|  | 220 | +#define readl( io_addr ) IOAPI_READ ( readl, uint32_t, io_addr, "MEM", 8 )
 | 
		
	
		
			
			|  | 221 | +
 | 
		
	
		
			
			|  | 222 | +/**
 | 
		
	
		
			
			|  | 223 | + * Read 64-bit qword from memory-mapped device
 | 
		
	
		
			
			|  | 224 | + *
 | 
		
	
		
			
			|  | 225 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 226 | + * @ret data		Value read
 | 
		
	
		
			
			|  | 227 | + */
 | 
		
	
		
			
			|  | 228 | +uint64_t readq ( volatile uint64_t *io_addr );
 | 
		
	
		
			
			|  | 229 | +#define readq( io_addr ) IOAPI_READ ( readq, uint64_t, io_addr, "MEM", 16 )
 | 
		
	
		
			
			|  | 230 | +
 | 
		
	
		
			
			|  | 231 | +/**
 | 
		
	
		
			
			|  | 232 | + * Write byte to memory-mapped device
 | 
		
	
		
			
			|  | 233 | + *
 | 
		
	
		
			
			|  | 234 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 235 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 236 | + */
 | 
		
	
		
			
			|  | 237 | +void writeb ( uint8_t data, volatile uint8_t *io_addr );
 | 
		
	
		
			
			|  | 238 | +#define writeb( data, io_addr ) \
 | 
		
	
		
			
			|  | 239 | +	IOAPI_WRITE ( writeb, uint8_t, data, io_addr, "MEM", 2 )
 | 
		
	
		
			
			|  | 240 | +
 | 
		
	
		
			
			|  | 241 | +/**
 | 
		
	
		
			
			|  | 242 | + * Write 16-bit word to memory-mapped device
 | 
		
	
		
			
			|  | 243 | + *
 | 
		
	
		
			
			|  | 244 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 245 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 246 | + */
 | 
		
	
		
			
			|  | 247 | +void writew ( uint16_t data, volatile uint16_t *io_addr );
 | 
		
	
		
			
			|  | 248 | +#define writew( data, io_addr ) \
 | 
		
	
		
			
			|  | 249 | +	IOAPI_WRITE ( writew, uint16_t, data, io_addr, "MEM", 4 )
 | 
		
	
		
			
			|  | 250 | +
 | 
		
	
		
			
			|  | 251 | +/**
 | 
		
	
		
			
			|  | 252 | + * Write 32-bit dword to memory-mapped device
 | 
		
	
		
			
			|  | 253 | + *
 | 
		
	
		
			
			|  | 254 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 255 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 256 | + */
 | 
		
	
		
			
			|  | 257 | +void writel ( uint32_t data, volatile uint32_t *io_addr );
 | 
		
	
		
			
			|  | 258 | +#define writel( data, io_addr ) \
 | 
		
	
		
			
			|  | 259 | +	IOAPI_WRITE ( writel, uint32_t, data, io_addr, "MEM", 8 )
 | 
		
	
		
			
			|  | 260 | +
 | 
		
	
		
			
			|  | 261 | +/**
 | 
		
	
		
			
			|  | 262 | + * Write 64-bit qword to memory-mapped device
 | 
		
	
		
			
			|  | 263 | + *
 | 
		
	
		
			
			|  | 264 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 265 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 266 | + */
 | 
		
	
		
			
			|  | 267 | +void writeq ( uint64_t data, volatile uint64_t *io_addr );
 | 
		
	
		
			
			|  | 268 | +#define writeq( data, io_addr ) \
 | 
		
	
		
			
			|  | 269 | +	IOAPI_WRITE ( writeq, uint64_t, data, io_addr, "MEM", 16 )
 | 
		
	
		
			
			|  | 270 | +
 | 
		
	
		
			
			|  | 271 | +/**
 | 
		
	
		
			
			|  | 272 | + * Read byte from I/O-mapped device
 | 
		
	
		
			
			|  | 273 | + *
 | 
		
	
		
			
			|  | 274 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 275 | + * @ret data		Value read
 | 
		
	
		
			
			|  | 276 | + */
 | 
		
	
		
			
			|  | 277 | +uint8_t inb ( volatile uint8_t *io_addr );
 | 
		
	
		
			
			|  | 278 | +#define inb( io_addr ) IOAPI_READ ( inb, uint8_t, io_addr, "IO", 2 )
 | 
		
	
		
			
			|  | 279 | +
 | 
		
	
		
			
			|  | 280 | +/**
 | 
		
	
		
			
			|  | 281 | + * Read 16-bit word from I/O-mapped device
 | 
		
	
		
			
			|  | 282 | + *
 | 
		
	
		
			
			|  | 283 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 284 | + * @ret data		Value read
 | 
		
	
		
			
			|  | 285 | + */
 | 
		
	
		
			
			|  | 286 | +uint16_t inw ( volatile uint16_t *io_addr );
 | 
		
	
		
			
			|  | 287 | +#define inw( io_addr ) IOAPI_READ ( inw, uint16_t, io_addr, "IO", 4 )
 | 
		
	
		
			
			|  | 288 | +
 | 
		
	
		
			
			|  | 289 | +/**
 | 
		
	
		
			
			|  | 290 | + * Read 32-bit dword from I/O-mapped device
 | 
		
	
		
			
			|  | 291 | + *
 | 
		
	
		
			
			|  | 292 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 293 | + * @ret data		Value read
 | 
		
	
		
			
			|  | 294 | + */
 | 
		
	
		
			
			|  | 295 | +uint32_t inl ( volatile uint32_t *io_addr );
 | 
		
	
		
			
			|  | 296 | +#define inl( io_addr ) IOAPI_READ ( inl, uint32_t, io_addr, "IO", 8 )
 | 
		
	
		
			
			|  | 297 | +
 | 
		
	
		
			
			|  | 298 | +/**
 | 
		
	
		
			
			|  | 299 | + * Write byte to I/O-mapped device
 | 
		
	
		
			
			|  | 300 | + *
 | 
		
	
		
			
			|  | 301 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 302 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 303 | + */
 | 
		
	
		
			
			|  | 304 | +void outb ( uint8_t data, volatile uint8_t *io_addr );
 | 
		
	
		
			
			|  | 305 | +#define outb( data, io_addr ) \
 | 
		
	
		
			
			|  | 306 | +	IOAPI_WRITE ( outb, uint8_t, data, io_addr, "IO", 2 )
 | 
		
	
		
			
			|  | 307 | +
 | 
		
	
		
			
			|  | 308 | +/**
 | 
		
	
		
			
			|  | 309 | + * Write 16-bit word to I/O-mapped device
 | 
		
	
		
			
			|  | 310 | + *
 | 
		
	
		
			
			|  | 311 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 312 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 313 | + */
 | 
		
	
		
			
			|  | 314 | +void outw ( uint16_t data, volatile uint16_t *io_addr );
 | 
		
	
		
			
			|  | 315 | +#define outw( data, io_addr ) \
 | 
		
	
		
			
			|  | 316 | +	IOAPI_WRITE ( outw, uint16_t, data, io_addr, "IO", 4 )
 | 
		
	
		
			
			|  | 317 | +
 | 
		
	
		
			
			|  | 318 | +/**
 | 
		
	
		
			
			|  | 319 | + * Write 32-bit dword to I/O-mapped device
 | 
		
	
		
			
			|  | 320 | + *
 | 
		
	
		
			
			|  | 321 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 322 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 323 | + */
 | 
		
	
		
			
			|  | 324 | +void outl ( uint32_t data, volatile uint32_t *io_addr );
 | 
		
	
		
			
			|  | 325 | +#define outl( data, io_addr ) \
 | 
		
	
		
			
			|  | 326 | +	IOAPI_WRITE ( outl, uint32_t, data, io_addr, "IO", 8 )
 | 
		
	
		
			
			|  | 327 | +
 | 
		
	
		
			
			|  | 328 | +/**
 | 
		
	
		
			
			|  | 329 | + * Read bytes from I/O-mapped device
 | 
		
	
		
			
			|  | 330 | + *
 | 
		
	
		
			
			|  | 331 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 332 | + * @v data		Data buffer
 | 
		
	
		
			
			|  | 333 | + * @v count		Number of bytes to read
 | 
		
	
		
			
			|  | 334 | + */
 | 
		
	
		
			
			|  | 335 | +void insb ( volatile uint8_t *io_addr, uint8_t *data, unsigned int count );
 | 
		
	
		
			
			|  | 336 | +#define insb( io_addr, data, count ) \
 | 
		
	
		
			
			|  | 337 | +	IOAPI_READS ( insb, uint8_t, io_addr, data, count, "IO", 2 )
 | 
		
	
		
			
			|  | 338 | +
 | 
		
	
		
			
			|  | 339 | +/**
 | 
		
	
		
			
			|  | 340 | + * Read 16-bit words from I/O-mapped device
 | 
		
	
		
			
			|  | 341 | + *
 | 
		
	
		
			
			|  | 342 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 343 | + * @v data		Data buffer
 | 
		
	
		
			
			|  | 344 | + * @v count		Number of words to read
 | 
		
	
		
			
			|  | 345 | + */
 | 
		
	
		
			
			|  | 346 | +void insw ( volatile uint16_t *io_addr, uint16_t *data, unsigned int count );
 | 
		
	
		
			
			|  | 347 | +#define insw( io_addr, data, count ) \
 | 
		
	
		
			
			|  | 348 | +	IOAPI_READS ( insw, uint16_t, io_addr, data, count, "IO", 4 )
 | 
		
	
		
			
			|  | 349 | +
 | 
		
	
		
			
			|  | 350 | +/**
 | 
		
	
		
			
			|  | 351 | + * Read 32-bit words from I/O-mapped device
 | 
		
	
		
			
			|  | 352 | + *
 | 
		
	
		
			
			|  | 353 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 354 | + * @v data		Data buffer
 | 
		
	
		
			
			|  | 355 | + * @v count		Number of words to read
 | 
		
	
		
			
			|  | 356 | + */
 | 
		
	
		
			
			|  | 357 | +void insl ( volatile uint32_t *io_addr, uint32_t *data, unsigned int count );
 | 
		
	
		
			
			|  | 358 | +#define insl( io_addr, data, count ) \
 | 
		
	
		
			
			|  | 359 | +	IOAPI_READS ( insl, uint32_t, io_addr, data, count, "IO", 8 )
 | 
		
	
		
			
			|  | 360 | +
 | 
		
	
		
			
			|  | 361 | +/**
 | 
		
	
		
			
			|  | 362 | + * Write bytes to I/O-mapped device
 | 
		
	
		
			
			|  | 363 | + *
 | 
		
	
		
			
			|  | 364 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 365 | + * @v data		Data buffer
 | 
		
	
		
			
			|  | 366 | + * @v count		Number of bytes to write
 | 
		
	
		
			
			|  | 367 | + */
 | 
		
	
		
			
			|  | 368 | +void outsb ( volatile uint8_t *io_addr, const uint8_t *data,
 | 
		
	
		
			
			|  | 369 | +	     unsigned int count );
 | 
		
	
		
			
			|  | 370 | +#define outsb( io_addr, data, count ) \
 | 
		
	
		
			
			|  | 371 | +	IOAPI_WRITES ( outsb, uint8_t, io_addr, data, count, "IO", 2 )
 | 
		
	
		
			
			|  | 372 | +
 | 
		
	
		
			
			|  | 373 | +/**
 | 
		
	
		
			
			|  | 374 | + * Write 16-bit words to I/O-mapped device
 | 
		
	
		
			
			|  | 375 | + *
 | 
		
	
		
			
			|  | 376 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 377 | + * @v data		Data buffer
 | 
		
	
		
			
			|  | 378 | + * @v count		Number of words to write
 | 
		
	
		
			
			|  | 379 | + */
 | 
		
	
		
			
			|  | 380 | +void outsw ( volatile uint16_t *io_addr, const uint16_t *data,
 | 
		
	
		
			
			|  | 381 | +	     unsigned int count );
 | 
		
	
		
			
			|  | 382 | +#define outsw( io_addr, data, count ) \
 | 
		
	
		
			
			|  | 383 | +	IOAPI_WRITES ( outsw, uint16_t, io_addr, data, count, "IO", 4 )
 | 
		
	
		
			
			|  | 384 | +
 | 
		
	
		
			
			|  | 385 | +/**
 | 
		
	
		
			
			|  | 386 | + * Write 32-bit words to I/O-mapped device
 | 
		
	
		
			
			|  | 387 | + *
 | 
		
	
		
			
			|  | 388 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 389 | + * @v data		Data buffer
 | 
		
	
		
			
			|  | 390 | + * @v count		Number of words to write
 | 
		
	
		
			
			|  | 391 | + */
 | 
		
	
		
			
			|  | 392 | +void outsl ( volatile uint32_t *io_addr, const uint32_t *data,
 | 
		
	
		
			
			|  | 393 | +	     unsigned int count );
 | 
		
	
		
			
			|  | 394 | +#define outsl( io_addr, data, count ) \
 | 
		
	
		
			
			|  | 395 | +	IOAPI_WRITES ( outsl, uint32_t, io_addr, data, count, "IO", 8 )
 | 
		
	
		
			
			|  | 396 | +
 | 
		
	
		
			
			|  | 397 | +/**
 | 
		
	
		
			
			|  | 398 | + * Slow down I/O
 | 
		
	
		
			
			|  | 399 | + *
 | 
		
	
		
			
			|  | 400 | + */
 | 
		
	
		
			
			|  | 401 | +void iodelay ( void );
 | 
		
	
		
			
			|  | 402 | +
 | 
		
	
		
			
			|  | 403 | +/**
 | 
		
	
		
			
			|  | 404 | + * Read value from I/O-mapped device, slowly
 | 
		
	
		
			
			|  | 405 | + *
 | 
		
	
		
			
			|  | 406 | + * @v _func		Function to use to read value
 | 
		
	
		
			
			|  | 407 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 408 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 409 | + */
 | 
		
	
		
			
			|  | 410 | +#define INX_P( _func, _type, io_addr ) ( {				      \
 | 
		
	
		
			
			|  | 411 | +	_type _data = _func ( (io_addr) );				      \
 | 
		
	
		
			
			|  | 412 | +	iodelay();							      \
 | 
		
	
		
			
			|  | 413 | +	_data; } )
 | 
		
	
		
			
			|  | 414 | +
 | 
		
	
		
			
			|  | 415 | +/**
 | 
		
	
		
			
			|  | 416 | + * Read byte from I/O-mapped device
 | 
		
	
		
			
			|  | 417 | + *
 | 
		
	
		
			
			|  | 418 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 419 | + * @ret data		Value read
 | 
		
	
		
			
			|  | 420 | + */
 | 
		
	
		
			
			|  | 421 | +#define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
 | 
		
	
		
			
			|  | 422 | +
 | 
		
	
		
			
			|  | 423 | +/**
 | 
		
	
		
			
			|  | 424 | + * Read 16-bit word from I/O-mapped device
 | 
		
	
		
			
			|  | 425 | + *
 | 
		
	
		
			
			|  | 426 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 427 | + * @ret data		Value read
 | 
		
	
		
			
			|  | 428 | + */
 | 
		
	
		
			
			|  | 429 | +#define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
 | 
		
	
		
			
			|  | 430 | +
 | 
		
	
		
			
			|  | 431 | +/**
 | 
		
	
		
			
			|  | 432 | + * Read 32-bit dword from I/O-mapped device
 | 
		
	
		
			
			|  | 433 | + *
 | 
		
	
		
			
			|  | 434 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 435 | + * @ret data		Value read
 | 
		
	
		
			
			|  | 436 | + */
 | 
		
	
		
			
			|  | 437 | +#define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
 | 
		
	
		
			
			|  | 438 | +
 | 
		
	
		
			
			|  | 439 | +/**
 | 
		
	
		
			
			|  | 440 | + * Write value to I/O-mapped device, slowly
 | 
		
	
		
			
			|  | 441 | + *
 | 
		
	
		
			
			|  | 442 | + * @v _func		Function to use to write value
 | 
		
	
		
			
			|  | 443 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 444 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 445 | + */
 | 
		
	
		
			
			|  | 446 | +#define OUTX_P( _func, data, io_addr ) do {				      \
 | 
		
	
		
			
			|  | 447 | +	_func ( (data), (io_addr) );					      \
 | 
		
	
		
			
			|  | 448 | +	iodelay();							      \
 | 
		
	
		
			
			|  | 449 | +	} while ( 0 )
 | 
		
	
		
			
			|  | 450 | +
 | 
		
	
		
			
			|  | 451 | +/**
 | 
		
	
		
			
			|  | 452 | + * Write byte to I/O-mapped device, slowly
 | 
		
	
		
			
			|  | 453 | + *
 | 
		
	
		
			
			|  | 454 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 455 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 456 | + */
 | 
		
	
		
			
			|  | 457 | +#define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
 | 
		
	
		
			
			|  | 458 | +
 | 
		
	
		
			
			|  | 459 | +/**
 | 
		
	
		
			
			|  | 460 | + * Write 16-bit word to I/O-mapped device, slowly
 | 
		
	
		
			
			|  | 461 | + *
 | 
		
	
		
			
			|  | 462 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 463 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 464 | + */
 | 
		
	
		
			
			|  | 465 | +#define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
 | 
		
	
		
			
			|  | 466 | +
 | 
		
	
		
			
			|  | 467 | +/**
 | 
		
	
		
			
			|  | 468 | + * Write 32-bit dword to I/O-mapped device, slowly
 | 
		
	
		
			
			|  | 469 | + *
 | 
		
	
		
			
			|  | 470 | + * @v data		Value to write
 | 
		
	
		
			
			|  | 471 | + * @v io_addr		I/O address
 | 
		
	
		
			
			|  | 472 | + */
 | 
		
	
		
			
			|  | 473 | +#define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
 | 
		
	
		
			
			|  | 474 | +
 | 
		
	
		
			
			|  | 475 | +/**
 | 
		
	
		
			
			|  | 476 | + * Memory barrier
 | 
		
	
		
			
			|  | 477 | + *
 | 
		
	
		
			
			|  | 478 | + */
 | 
		
	
		
			
			|  | 479 | +void mb ( void );
 | 
		
	
		
			
			|  | 480 | +#define rmb()	mb()
 | 
		
	
		
			
			|  | 481 | +#define wmb()	mb()
 | 
		
	
		
			
			|  | 482 | +
 | 
		
	
		
			
			|  | 483 | +#endif /* _GPXE_IO_H */
 |