~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/pci/pcbios.c

Version: ~ [ linux-5.7 ] ~ [ linux-5.6.15 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.43 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.125 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.182 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.225 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.225 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.84 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/x86/pci/pcbios.c (Architecture m68k) and /arch/alpha/pci/pcbios.c (Architecture alpha)


  1 /*                                                  1 
  2  * BIOS32 and PCI BIOS handling.                  
  3  */                                               
  4                                                   
  5 #include <linux/pci.h>                            
  6 #include <linux/init.h>                           
  7 #include <linux/slab.h>                           
  8 #include <linux/module.h>                         
  9 #include <linux/uaccess.h>                        
 10 #include <asm/pci_x86.h>                          
 11 #include <asm/pci-functions.h>                    
 12 #include <asm/cacheflush.h>                       
 13                                                   
 14 /* BIOS32 signature: "_32_" */                    
 15 #define BIOS32_SIGNATURE        (('_' << 0) +     
 16                                                   
 17 /* PCI signature: "PCI " */                       
 18 #define PCI_SIGNATURE           (('P' << 0) +     
 19                                                   
 20 /* PCI service signature: "$PCI" */               
 21 #define PCI_SERVICE             (('$' << 0) +     
 22                                                   
 23 /* PCI BIOS hardware mechanism flags */           
 24 #define PCIBIOS_HW_TYPE1                0x01      
 25 #define PCIBIOS_HW_TYPE2                0x02      
 26 #define PCIBIOS_HW_TYPE1_SPEC           0x10      
 27 #define PCIBIOS_HW_TYPE2_SPEC           0x20      
 28                                                   
 29 int pcibios_enabled;                              
 30                                                   
 31 /* According to the BIOS specification at:        
 32  * http://members.datafast.net.au/dft0802/spec    
 33  * restrict the x zone to some pages and make     
 34  * broken on some bios, complex to handle with    
 35  * We could make the 0xe0000-0x100000 range ro    
 36  * some ISA mapping.                              
 37  *                                                
 38  * So we let's an rw and x hole when pcibios i    
 39  * happen for modern system with mmconfig, and    
 40  * you could disable pcibios...                   
 41  */                                               
 42 static inline void set_bios_x(void)               
 43 {                                                 
 44         pcibios_enabled = 1;                      
 45         set_memory_x(PAGE_OFFSET + BIOS_BEGIN,    
 46         if (__supported_pte_mask & _PAGE_NX)      
 47                 printk(KERN_INFO "PCI : PCI BI    
 48 }                                                 
 49                                                   
 50 /*                                                
 51  * This is the standard structure used to iden    
 52  * to the BIOS32 Service Directory, as documen    
 53  *      Standard BIOS 32-bit Service Directory    
 54  *      Revision 0.4 May 24, 1993                 
 55  *      Phoenix Technologies Ltd.                 
 56  *      Norwood, MA                               
 57  * and the PCI BIOS specification.                
 58  */                                               
 59                                                   
 60 union bios32 {                                    
 61         struct {                                  
 62                 unsigned long signature;          
 63                 unsigned long entry;              
 64                 unsigned char revision;           
 65                 unsigned char length;             
 66                 unsigned char checksum;           
 67                 unsigned char reserved[5];        
 68         } fields;                                 
 69         char chars[16];                           
 70 };                                                
 71                                                   
 72 /*                                                
 73  * Physical address of the service directory.     
 74  * allowed to have more than one of these or n    
 75  * we'll make pcibios_present() take a memory     
 76  * the array there.                               
 77  */                                               
 78                                                   
 79 static struct {                                   
 80         unsigned long address;                    
 81         unsigned short segment;                   
 82 } bios32_indirect __initdata = { 0, __KERNEL_C    
 83                                                   
 84 /*                                                
 85  * Returns the entry point for the given servi    
 86  */                                               
 87                                                   
 88 static unsigned long __init bios32_service(uns    
 89 {                                                 
 90         unsigned char return_code;      /* %al    
 91         unsigned long address;          /* %eb    
 92         unsigned long length;           /* %ec    
 93         unsigned long entry;            /* %ed    
 94         unsigned long flags;                      
 95                                                   
 96         local_irq_save(flags);                    
 97         __asm__("lcall *(%%edi); cld"             
 98                 : "=a" (return_code),             
 99                   "=b" (address),                 
100                   "=c" (length),                  
101                   "=d" (entry)                    
102                 : "" (service),                   
103                   "1" (0),                        
104                   "D" (&bios32_indirect));        
105         local_irq_restore(flags);                 
106                                                   
107         switch (return_code) {                    
108                 case 0:                           
109                         return address + entry    
110                 case 0x80:      /* Not present    
111                         printk(KERN_WARNING "b    
112                         return 0;                 
113                 default: /* Shouldn't happen *    
114                         printk(KERN_WARNING "b    
115                                 service, retur    
116                         return 0;                 
117         }                                         
118 }                                                 
119                                                   
120 static struct {                                   
121         unsigned long address;                    
122         unsigned short segment;                   
123 } pci_indirect = { 0, __KERNEL_CS };              
124                                                   
125 static int pci_bios_present;                      
126                                                   
127 static int __init check_pcibios(void)             
128 {                                                 
129         u32 signature, eax, ebx, ecx;             
130         u8 status, major_ver, minor_ver, hw_me    
131         unsigned long flags, pcibios_entry;       
132                                                   
133         if ((pcibios_entry = bios32_service(PC    
134                 pci_indirect.address = pcibios    
135                                                   
136                 local_irq_save(flags);            
137                 __asm__(                          
138                         "lcall *(%%edi); cld\n    
139                         "jc 1f\n\t"               
140                         "xor %%ah, %%ah\n"        
141                         "1:"                      
142                         : "=d" (signature),       
143                           "=a" (eax),             
144                           "=b" (ebx),             
145                           "=c" (ecx)              
146                         : "1" (PCIBIOS_PCI_BIO    
147                           "D" (&pci_indirect)     
148                         : "memory");              
149                 local_irq_restore(flags);         
150                                                   
151                 status = (eax >> 8) & 0xff;       
152                 hw_mech = eax & 0xff;             
153                 major_ver = (ebx >> 8) & 0xff;    
154                 minor_ver = ebx & 0xff;           
155                 if (pcibios_last_bus < 0)         
156                         pcibios_last_bus = ecx    
157                 DBG("PCI: BIOS probe returned     
158                         status, hw_mech, major    
159                 if (status || signature != PCI    
160                         printk (KERN_ERR "PCI:    
161                                 status, signat    
162                         return 0;                 
163                 }                                 
164                 printk(KERN_INFO "PCI: PCI BIO    
165                         major_ver, minor_ver,     
166 #ifdef CONFIG_PCI_DIRECT                          
167                 if (!(hw_mech & PCIBIOS_HW_TYP    
168                         pci_probe &= ~PCI_PROB    
169                 if (!(hw_mech & PCIBIOS_HW_TYP    
170                         pci_probe &= ~PCI_PROB    
171 #endif                                            
172                 return 1;                         
173         }                                         
174         return 0;                                 
175 }                                                 
176                                                   
177 static int pci_bios_read(unsigned int seg, uns    
178                          unsigned int devfn, i    
179 {                                                 
180         unsigned long result = 0;                 
181         unsigned long flags;                      
182         unsigned long bx = (bus << 8) | devfn;    
183         u16 number = 0, mask = 0;                 
184                                                   
185         WARN_ON(seg);                             
186         if (!value || (bus > 255) || (devfn >     
187                 return -EINVAL;                   
188                                                   
189         raw_spin_lock_irqsave(&pci_config_lock    
190                                                   
191         switch (len) {                            
192         case 1:                                   
193                 number = PCIBIOS_READ_CONFIG_B    
194                 mask = 0xff;                      
195                 break;                            
196         case 2:                                   
197                 number = PCIBIOS_READ_CONFIG_W    
198                 mask = 0xffff;                    
199                 break;                            
200         case 4:                                   
201                 number = PCIBIOS_READ_CONFIG_D    
202                 break;                            
203         }                                         
204                                                   
205         __asm__("lcall *(%%esi); cld\n\t"         
206                 "jc 1f\n\t"                       
207                 "xor %%ah, %%ah\n"                
208                 "1:"                              
209                 : "=c" (*value),                  
210                   "=a" (result)                   
211                 : "1" (number),                   
212                   "b" (bx),                       
213                   "D" ((long)reg),                
214                   "S" (&pci_indirect));           
215         /*                                        
216          * Zero-extend the result beyond 8 or     
217          * BIOS having done it:                   
218          */                                       
219         if (mask)                                 
220                 *value &= mask;                   
221                                                   
222         raw_spin_unlock_irqrestore(&pci_config    
223                                                   
224         return (int)((result & 0xff00) >> 8);     
225 }                                                 
226                                                   
227 static int pci_bios_write(unsigned int seg, un    
228                           unsigned int devfn,     
229 {                                                 
230         unsigned long result = 0;                 
231         unsigned long flags;                      
232         unsigned long bx = (bus << 8) | devfn;    
233         u16 number = 0;                           
234                                                   
235         WARN_ON(seg);                             
236         if ((bus > 255) || (devfn > 255) || (r    
237                 return -EINVAL;                   
238                                                   
239         raw_spin_lock_irqsave(&pci_config_lock    
240                                                   
241         switch (len) {                            
242         case 1:                                   
243                 number = PCIBIOS_WRITE_CONFIG_    
244                 break;                            
245         case 2:                                   
246                 number = PCIBIOS_WRITE_CONFIG_    
247                 break;                            
248         case 4:                                   
249                 number = PCIBIOS_WRITE_CONFIG_    
250                 break;                            
251         }                                         
252                                                   
253         __asm__("lcall *(%%esi); cld\n\t"         
254                 "jc 1f\n\t"                       
255                 "xor %%ah, %%ah\n"                
256                 "1:"                              
257                 : "=a" (result)                   
258                 : "" (number),                    
259                   "c" (value),                    
260                   "b" (bx),                       
261                   "D" ((long)reg),                
262                   "S" (&pci_indirect));           
263                                                   
264         raw_spin_unlock_irqrestore(&pci_config    
265                                                   
266         return (int)((result & 0xff00) >> 8);     
267 }                                                 
268                                                   
269                                                   
270 /*                                                
271  * Function table for BIOS32 access               
272  */                                               
273                                                   
274 static const struct pci_raw_ops pci_bios_acces    
275         .read =         pci_bios_read,            
276         .write =        pci_bios_write            
277 };                                                
278                                                   
279 /*                                                
280  * Try to find PCI BIOS.                          
281  */                                               
282                                                   
283 static const struct pci_raw_ops *__init pci_fi    
284 {                                                 
285         union bios32 *check;                      
286         unsigned char sum;                        
287         int i, length;                            
288                                                   
289         /*                                        
290          * Follow the standard procedure for l    
291          * directory by scanning the permissib    
292          * 0xe0000 through 0xfffff for a valid    
293          */                                       
294                                                   
295         for (check = (union bios32 *) __va(0xe    
296              check <= (union bios32 *) __va(0x    
297              ++check) {                           
298                 long sig;                         
299                 if (probe_kernel_address(&chec    
300                         continue;                 
301                                                   
302                 if (check->fields.signature !=    
303                         continue;                 
304                 length = check->fields.length     
305                 if (!length)                      
306                         continue;                 
307                 sum = 0;                          
308                 for (i = 0; i < length ; ++i)     
309                         sum += check->chars[i]    
310                 if (sum != 0)                     
311                         continue;                 
312                 if (check->fields.revision !=     
313                         printk("PCI: unsupport    
314                                 check->fields.    
315                         continue;                 
316                 }                                 
317                 DBG("PCI: BIOS32 Service Direc    
318                 if (check->fields.entry >= 0x1    
319                         printk("PCI: BIOS32 en    
320                                         "canno    
321                         return NULL;              
322                 } else {                          
323                         unsigned long bios32_e    
324                         DBG("PCI: BIOS32 Servi    
325                                         bios32    
326                         bios32_indirect.addres    
327                         set_bios_x();             
328                         if (check_pcibios())      
329                                 return &pci_bi    
330                 }                                 
331                 break;  /* Hopefully more than    
332         }                                         
333                                                   
334         return NULL;                              
335 }                                                 
336                                                   
337 /*                                                
338  *  BIOS Functions for IRQ Routing                
339  */                                               
340                                                   
341 struct irq_routing_options {                      
342         u16 size;                                 
343         struct irq_info *table;                   
344         u16 segment;                              
345 } __attribute__((packed));                        
346                                                   
347 struct irq_routing_table * pcibios_get_irq_rou    
348 {                                                 
349         struct irq_routing_options opt;           
350         struct irq_routing_table *rt = NULL;      
351         int ret, map;                             
352         unsigned long page;                       
353                                                   
354         if (!pci_bios_present)                    
355                 return NULL;                      
356         page = __get_free_page(GFP_KERNEL);       
357         if (!page)                                
358                 return NULL;                      
359         opt.table = (struct irq_info *) page;     
360         opt.size = PAGE_SIZE;                     
361         opt.segment = __KERNEL_DS;                
362                                                   
363         DBG("PCI: Fetching IRQ routing table..    
364         __asm__("push %%es\n\t"                   
365                 "push %%ds\n\t"                   
366                 "pop  %%es\n\t"                   
367                 "lcall *(%%esi); cld\n\t"         
368                 "pop %%es\n\t"                    
369                 "jc 1f\n\t"                       
370                 "xor %%ah, %%ah\n"                
371                 "1:"                              
372                 : "=a" (ret),                     
373                   "=b" (map),                     
374                   "=m" (opt)                      
375                 : "" (PCIBIOS_GET_ROUTING_OPTI    
376                   "1" (0),                        
377                   "D" ((long) &opt),              
378                   "S" (&pci_indirect),            
379                   "m" (opt)                       
380                 : "memory");                      
381         DBG("OK  ret=%d, size=%d, map=%x\n", r    
382         if (ret & 0xff00)                         
383                 printk(KERN_ERR "PCI: Error %0    
384         else if (opt.size) {                      
385                 rt = kmalloc(sizeof(struct irq    
386                 if (rt) {                         
387                         memset(rt, 0, sizeof(s    
388                         rt->size = opt.size +     
389                         rt->exclusive_irqs = m    
390                         memcpy(rt->slots, (voi    
391                         printk(KERN_INFO "PCI:    
392                 }                                 
393         }                                         
394         free_page(page);                          
395         return rt;                                
396 }                                                 
397 EXPORT_SYMBOL(pcibios_get_irq_routing_table);     
398                                                   
399 int pcibios_set_irq_routing(struct pci_dev *de    
400 {                                                 
401         int ret;                                  
402                                                   
403         __asm__("lcall *(%%esi); cld\n\t"         
404                 "jc 1f\n\t"                       
405                 "xor %%ah, %%ah\n"                
406                 "1:"                              
407                 : "=a" (ret)                      
408                 : "" (PCIBIOS_SET_PCI_HW_INT),    
409                   "b" ((dev->bus->number << 8)    
410                   "c" ((irq << 8) | (pin + 10)    
411                   "S" (&pci_indirect));           
412         return !(ret & 0xff00);                   
413 }                                                 
414 EXPORT_SYMBOL(pcibios_set_irq_routing);           
415                                                   
416 void __init pci_pcbios_init(void)                 
417 {                                                 
418         if ((pci_probe & PCI_PROBE_BIOS)          
419                 && ((raw_pci_ops = pci_find_bi    
420                 pci_bios_present = 1;             
421         }                                         
422 }                                                 
423                                                   
424                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp