pxeparent.c
Go to the documentation of this file.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 <gpxe/dhcp.h>
00022 #include <pxeparent.h>
00023 #include <pxe_api.h>
00024 #include <pxe_types.h>
00025 #include <pxe.h>
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 static inline __attribute__ (( always_inline )) const char *
00040 pxeparent_function_name ( unsigned int function ) {
00041 switch ( function ) {
00042 case PXENV_START_UNDI:
00043 return "PXENV_START_UNDI";
00044 case PXENV_STOP_UNDI:
00045 return "PXENV_STOP_UNDI";
00046 case PXENV_UNDI_STARTUP:
00047 return "PXENV_UNDI_STARTUP";
00048 case PXENV_UNDI_CLEANUP:
00049 return "PXENV_UNDI_CLEANUP";
00050 case PXENV_UNDI_INITIALIZE:
00051 return "PXENV_UNDI_INITIALIZE";
00052 case PXENV_UNDI_RESET_ADAPTER:
00053 return "PXENV_UNDI_RESET_ADAPTER";
00054 case PXENV_UNDI_SHUTDOWN:
00055 return "PXENV_UNDI_SHUTDOWN";
00056 case PXENV_UNDI_OPEN:
00057 return "PXENV_UNDI_OPEN";
00058 case PXENV_UNDI_CLOSE:
00059 return "PXENV_UNDI_CLOSE";
00060 case PXENV_UNDI_TRANSMIT:
00061 return "PXENV_UNDI_TRANSMIT";
00062 case PXENV_UNDI_SET_MCAST_ADDRESS:
00063 return "PXENV_UNDI_SET_MCAST_ADDRESS";
00064 case PXENV_UNDI_SET_STATION_ADDRESS:
00065 return "PXENV_UNDI_SET_STATION_ADDRESS";
00066 case PXENV_UNDI_SET_PACKET_FILTER:
00067 return "PXENV_UNDI_SET_PACKET_FILTER";
00068 case PXENV_UNDI_GET_INFORMATION:
00069 return "PXENV_UNDI_GET_INFORMATION";
00070 case PXENV_UNDI_GET_STATISTICS:
00071 return "PXENV_UNDI_GET_STATISTICS";
00072 case PXENV_UNDI_CLEAR_STATISTICS:
00073 return "PXENV_UNDI_CLEAR_STATISTICS";
00074 case PXENV_UNDI_INITIATE_DIAGS:
00075 return "PXENV_UNDI_INITIATE_DIAGS";
00076 case PXENV_UNDI_FORCE_INTERRUPT:
00077 return "PXENV_UNDI_FORCE_INTERRUPT";
00078 case PXENV_UNDI_GET_MCAST_ADDRESS:
00079 return "PXENV_UNDI_GET_MCAST_ADDRESS";
00080 case PXENV_UNDI_GET_NIC_TYPE:
00081 return "PXENV_UNDI_GET_NIC_TYPE";
00082 case PXENV_UNDI_GET_IFACE_INFO:
00083 return "PXENV_UNDI_GET_IFACE_INFO";
00084
00085
00086
00087
00088
00089
00090 case PXENV_UNDI_ISR:
00091 return "PXENV_UNDI_ISR";
00092 case PXENV_GET_CACHED_INFO:
00093 return "PXENV_GET_CACHED_INFO";
00094 default:
00095 return "UNKNOWN API CALL";
00096 }
00097 }
00098
00099
00100
00101
00102
00103
00104
00105 static union u_PXENV_ANY __bss16 ( pxeparent_params );
00106 #define pxeparent_params __use_data16 ( pxeparent_params )
00107
00108
00109
00110
00111
00112
00113 SEGOFF16_t __bss16 ( pxeparent_entry_point );
00114 #define pxeparent_entry_point __use_data16 ( pxeparent_entry_point )
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 int pxeparent_call ( SEGOFF16_t entry, unsigned int function,
00126 void *params, size_t params_len ) {
00127 PXENV_EXIT_t exit;
00128 int discard_b, discard_D;
00129 int rc;
00130
00131
00132 assert ( params_len <= sizeof ( pxeparent_params ) );
00133 memcpy ( &pxeparent_params, params, params_len );
00134 memcpy ( &pxeparent_entry_point, &entry, sizeof ( entry ) );
00135
00136
00137
00138
00139 __asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t"
00140 "pushw %%di\n\t"
00141 "pushw %%bx\n\t"
00142 "lcall *pxeparent_entry_point\n\t"
00143 "addw $6, %%sp\n\t" )
00144 : "=a" ( exit ), "=b" ( discard_b ),
00145 "=D" ( discard_D )
00146 : "b" ( function ),
00147 "D" ( __from_data16 ( &pxeparent_params ) )
00148 : "ecx", "edx", "esi", "ebp" );
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 gateA20_set();
00159
00160
00161
00162
00163 if ( exit == PXENV_EXIT_SUCCESS ) {
00164 rc = 0;
00165 } else {
00166 rc = -pxeparent_params.Status;
00167
00168
00169
00170 if ( rc == 0 )
00171 rc = -EIO;
00172 }
00173
00174
00175
00176
00177 if ( rc != 0 ) {
00178 SEGOFF16_t rm_params = {
00179 .segment = rm_ds,
00180 .offset = __from_data16 ( &pxeparent_params ),
00181 };
00182
00183 DBG ( "PXEPARENT %s failed: %s\n",
00184 pxeparent_function_name ( function ), strerror ( rc ) );
00185 DBG ( "PXEPARENT parameters at %04x:%04x length "
00186 "%#02zx, entry point at %04x:%04x\n",
00187 rm_params.segment, rm_params.offset, params_len,
00188 pxeparent_entry_point.segment,
00189 pxeparent_entry_point.offset );
00190 DBG ( "PXEPARENT parameters provided:\n" );
00191 DBG_HDA ( rm_params, params, params_len );
00192 DBG ( "PXEPARENT parameters returned:\n" );
00193 DBG_HDA ( rm_params, &pxeparent_params, params_len );
00194 }
00195
00196
00197 memcpy ( params, &pxeparent_params, params_len );
00198
00199 return rc;
00200 }
00201