00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00020 #include "src/common/shared.hpp"
00021 #include "src/memory/memset.hpp"
00022
00023 #include "src/memory/align.hpp"
00024 #include "src/memory/heap.hpp"
00025
00026
00027
00028 #include "src/arch/x86/pcibios.hpp"
00029
00030 uint32 Pci32_Addr=0;
00031
00032 struct bios32_service_directory_struct
00033 {
00034 uint32 signature;
00035 uint32 entry_point;
00036 uint8 revision_level;
00037 uint8 length;
00038 uint8 checksum;
00039 uint8 resvd[5];
00040 } __attribute__ ((packed));
00041
00045 struct bios32_service_directory_struct* find_bios32_service_directory_header()
00046 {
00047
00048 uint8 *ptr;
00049 struct bios32_service_directory_struct *b32;
00050 ptr= (uint8*) (0xe0000);
00051
00052 for ( ; (uint32) ptr < 0x100000; ptr+=16)
00053 {
00054 if (ptr[0] == '_')
00055 if (ptr[1] == '3')
00056 if (ptr[2] == '2')
00057 if (ptr[3] == '_')
00058 {
00059 b32= (bios32_service_directory_struct*)ptr;
00060 int i;
00061 uint8 j=0;
00062 for (i=0;i<16;i++)
00063 j+=ptr[i];
00064 if (j==0)
00065 return b32;
00066 }
00067 }
00068 return NULL;
00069 }
00070
00071 int bios32_service (struct bios32_service_directory_struct* b32, uint32 magic, uint32 *cseg_size, uint32 *offset, uint32 *base_addr)
00072 {
00073 uint32 retval;
00074 __asm__ __volatile (
00075
00076 "xorl %%ebx, %%ebx\n"
00077 "pushl %%ebp\n"
00078 "movl %%edx, %%ebp\n"
00079 "pushl %%cs\n"
00080 "call *%%ebp\n"
00081 "popl %%ebp\n"
00082 : "=c" (*cseg_size),
00083 "=d" (*offset),
00084 "=b" (*base_addr),
00085 "=a" (retval)
00086 : "d" ((b32->entry_point)), "a" (magic) );
00087 if ((retval&0xff)==0) return 0;
00088 return -1;
00089 }
00090
00091 int pci32_installation_check(uint32 addr)
00092 {
00093 uint32 jk,a1;
00094
00095 __asm__ __volatile (
00096 "pushl %%cs\n"
00097 "call *%%esi\n"
00098 "jc 1\n"
00099 "xor %%ah, %%ah\n"
00100 "1:"
00101 :"=a" (jk), "=d" (a1)
00102 : "a" (0xb101), "S" (addr));
00103
00104 if ( ((jk >> 8)==0) && (a1==0x20494350) )
00105 return 1;
00106 return 0;
00107 }
00108
00109 int pci32_read_configuration_dword(uint32 *result, uint32 addr, uint8 bus_no, uint8 dev_no, uint8 func_no, uint16 reg_no)
00110 {
00111 uint32 jk,a1;
00112
00113 __asm__ __volatile (
00114 "pushl %%cs\n"
00115 "call *%%esi\n"
00116 "jc 1\n"
00117 "xor %%ah, %%ah\n"
00118 "1:"
00119 :"=a" (jk), "=c" (a1)
00120 : "a" (0xb10a), "S" (addr), "b" ( (bus_no<<8)+(dev_no<<3)+func_no ),
00121 "D" (reg_no) );
00122
00123 *result= a1;
00124 if ( (jk >> 8) == 0)
00125 return 1;
00126
00127 return 0;
00128 }
00129
00130 int pci32_write_configuration_dword(uint32 val, uint32 addr, uint8 bus_no, uint8 dev_no, uint8 func_no, uint16 reg_no)
00131 {
00132 uint32 jk;
00133
00134 __asm__ __volatile (
00135 "pushl %%cs\n"
00136 "call *%%esi\n"
00137 "jc 1\n"
00138 "xor %%ah, %%ah\n"
00139 "1:"
00140 :"=a" (jk)
00141 : "a" (0xb10d), "S" (addr), "b" ( (bus_no<<8)+(dev_no<<3)+func_no ),
00142 "D" (reg_no), "c" (val) );
00143
00144 if ( (jk >> 8) == 0)
00145 return 1;
00146
00147 return 0;
00148 }
00149
00150 int pci32_read_configuration_word(uint16 *result, uint32 addr, uint8 bus_no, uint8 dev_no, uint8 func_no, uint16 reg_no)
00151 {
00152 uint32 jk,a1=0;
00153
00154 __asm__ __volatile (
00155 "pushl %%cs\n"
00156 "call *%%esi\n"
00157 "jc 1\n"
00158 "xor %%ah, %%ah\n"
00159 "1:"
00160 :"=a" (jk), "=c" (a1)
00161 : "a" (0xb109), "S" (addr), "b" ( (bus_no<<8)+(dev_no<<3)+func_no ),
00162 "D" (reg_no) );
00163
00164 *result= a1;
00165 if ( (jk >> 8) == 0)
00166 return 1;
00167
00168 return 0;
00169 }
00170
00171 int pci32_write_configuration_word(uint16 val, uint32 addr, uint8 bus_no, uint8 dev_no, uint8 func_no, uint16 reg_no)
00172 {
00173 uint32 jk;
00174
00175 __asm__ __volatile (
00176 "pushl %%cs\n"
00177 "call *%%esi\n"
00178 "jc 1\n"
00179 "xor %%ah, %%ah\n"
00180 "1:"
00181 :"=a" (jk)
00182 : "a" (0xb10c), "S" (addr), "b" ( (bus_no<<8)+(dev_no<<3)+func_no ),
00183 "D" (reg_no), "c" (val) );
00184
00185 if ( (jk >> 8) == 0)
00186 return 1;
00187
00188 return 0;
00189 }
00190
00191 int pci32_read_configuration_byte(uint8 *result, uint32 addr, uint8 bus_no, uint8 dev_no, uint8 func_no, uint16 reg_no)
00192 {
00193 uint32 jk,a1=0;
00194
00195 __asm__ __volatile (
00196 "pushl %%cs\n"
00197 "call *%%esi\n"
00198 "jc 1\n"
00199 "xor %%ah, %%ah\n"
00200 "1:"
00201 :"=a" (jk), "=c" (a1)
00202 : "a" (0xb108), "S" (addr), "b" ( (bus_no<<8)+(dev_no<<3)+func_no ),
00203 "D" (reg_no) );
00204
00205 *result= a1;
00206 if ( (jk >> 8) == 0)
00207 return 1;
00208
00209 return 0;
00210 }
00211
00212 int pci32_write_configuration_byte(uint8 val, uint32 addr, uint8 bus_no, uint8 dev_no, uint8 func_no, uint16 reg_no)
00213 {
00214 uint32 jk;
00215
00216 __asm__ __volatile (
00217 "pushl %%cs\n"
00218 "call *%%esi\n"
00219 "jc 1\n"
00220 "xor %%ah, %%ah\n"
00221 "1:"
00222 :"=a" (jk)
00223 : "a" (0xb10b), "S" (addr), "b" ( (bus_no<<8)+(dev_no<<3)+func_no ),
00224 "D" (reg_no), "c" (val) );
00225
00226 if ( (jk >> 8) == 0)
00227 return 1;
00228
00229 return 0;
00230 }
00231
00232 const char *pci32_base_class_name (uint16 class_no)
00233 {
00234 switch (class_no)
00235 {
00236 case 0: return "pci1";
00237 case 2: return "nic";
00238 case 3: return "video";
00239 case 4: return "mmedia";
00240 case 6: return "bridge";
00241 case 7: return "SmpCom";
00242 default:
00243 static char class_name[20];
00244 ksnprintf(class_name,20,"%02x",class_no);
00245 return class_name;
00246 }
00247 }
00248
00249 const char *pci32_vendor_name (uint16 vendor_no)
00250 {
00251 switch (vendor_no)
00252 {
00253 case 0x1002: return "ATI";
00254 case 0x104c: return "TI";
00255 case 0x10b7: return "3Com";
00256 case 0x10ec: return "Realtek";
00257 case 0x125d: return "ESS";
00258 case 0x8086: return "Intel";
00259 default:
00260 static char class_name[20];
00261 ksnprintf(class_name,20,"%04x",vendor_no);
00262 return class_name;
00263 }
00264 }
00265
00266 const char *pci32_sub_class_name (uint16 class_no, uint16 subclass_no)
00267 {
00268 static char class_name[20];
00269 switch (class_no)
00270 {
00271 case 2:
00272 switch (subclass_no)
00273 {
00274 case 0: return "ethernet";
00275 default:
00276 ksnprintf(class_name,20,"%02x ",subclass_no);
00277 return class_name;
00278 }
00279 case 4:
00280 switch (subclass_no)
00281 {
00282 case 1: return "audio ";
00283 default:
00284 ksnprintf(class_name,20,"%02x ",subclass_no);
00285 return class_name;
00286 }
00287 case 6:
00288 switch (subclass_no)
00289 {
00290 case 0: return "host-pci";
00291 case 1: return "pci-isa ";
00292 case 4: return "pci-pci ";
00293 case 7: return "pci-cardbus";
00294 default:
00295 ksnprintf(class_name,20,"%02x ",subclass_no);
00296 return class_name;
00297 }
00298 default:
00299 ksnprintf(class_name,20,"%02x ",subclass_no);
00300 return class_name;
00301 }
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312