home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / arch / alpha / kernel / lca.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-03  |  5.9 KB  |  301 lines

  1. /*
  2.  * Code common to all LCA chips.
  3.  */
  4.  
  5. #include <linux/config.h>
  6. #include <linux/types.h>
  7. #include <linux/bios32.h>
  8. #include <linux/pci.h>
  9.  
  10. #include <asm/system.h>
  11. #include <asm/lca.h>
  12.  
  13. /*
  14.  * BIOS32-style PCI interface:
  15.  */
  16.  
  17. /*
  18.  * PCI BIOS32 interface:
  19.  */
  20. #define MAJOR_REV    0
  21. #define MINOR_REV    0
  22.  
  23. #ifdef CONFIG_PCI
  24.  
  25. #define mtpr_mces(v) \
  26. ({ \
  27.     register unsigned long v0 asm ("0"); \
  28.     register unsigned long a0 asm ("16"); \
  29.     a0 = (v); \
  30.     asm volatile ("call_pal %1 # %0 %2" : "r="(v0) \
  31.           : "i"(PAL_mtpr_mces), "r"(a0) \
  32.           : "memory", "0", "1", "16", "22", "23", "24", "25"); \
  33.     v0; \
  34. })
  35.  
  36. #define draina()    asm volatile ("call_pal %0" :: "i"(PAL_draina))
  37.  
  38.  
  39. /*
  40.  * Given a bus, device, and function number, compute resulting
  41.  * configuration space address and setup the LCA_IOC_CONF register
  42.  * accordingly.  It is therefore not safe to have concurrent
  43.  * invocations to configuration space access routines, but there
  44.  * really shouldn't be any need for this.
  45.  */
  46. static int
  47. mk_conf_addr(unsigned char bus, unsigned char device_fn,
  48.         unsigned char where, unsigned long *pci_addr)
  49. {
  50.     unsigned long addr;
  51.  
  52.     if (bus == 0) {
  53.         int device = device_fn >> 3;
  54.         int func = device_fn & 0x7;
  55.  
  56.         /* type 0 configuration cycle: */
  57.  
  58.         if (device > 12) {
  59.             return -1;
  60.         } /* if */
  61.  
  62.         *((volatile unsigned long*) LCA_IOC_CONF) = 0;
  63.         addr = (1 << (11 + device)) | (func << 8) | where;
  64.     } else {
  65.         /* type 1 configuration cycle: */
  66.         *((volatile unsigned long*) LCA_IOC_CONF) = 1;
  67.         addr = (bus << 16) | (device_fn << 8) | where;
  68.     } /* if */
  69.     *pci_addr = addr;
  70.  
  71.     return 0;
  72. }
  73.  
  74.  
  75. static unsigned int
  76. conf_read(unsigned long addr)
  77. {
  78.     unsigned long old_ipl, code, stat0;
  79.     unsigned int value;
  80.  
  81.     old_ipl = swpipl(7);    /* avoid getting hit by machine check */
  82.  
  83.     /* reset status register to avoid loosing errors: */
  84.     stat0 = *((volatile unsigned long*)LCA_IOC_STAT0);
  85.     *((volatile unsigned long*)LCA_IOC_STAT0) = stat0;
  86.     mb();
  87.  
  88.     /* access configuration space: */
  89.  
  90.     value = *((volatile unsigned int*)addr);
  91.     draina();
  92.  
  93.     stat0 = *((unsigned long*)LCA_IOC_STAT0);
  94.     if (stat0 & LCA_IOC_STAT0_ERR) {
  95.         code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
  96.             & LCA_IOC_STAT0_CODE_MASK);
  97.         if (code != 1) {
  98.             printk("lca.c:conf_read: got stat0=%lx\n", stat0);
  99.         }
  100.  
  101.         /* reset error status: */
  102.         *((volatile unsigned long*)LCA_IOC_STAT0) = stat0;
  103.         mb();
  104.         mtpr_mces(0x7);            /* reset machine check */
  105.  
  106.         value = 0xffffffff;
  107.     }
  108.     swpipl(old_ipl);
  109.  
  110.     return value;
  111. }
  112.  
  113.  
  114. static void
  115. conf_write(unsigned long addr, unsigned int value)
  116. {
  117. }
  118.  
  119.  
  120. int
  121. pcibios_present (void)
  122. {
  123.     return 1;        /* present if configured */
  124. }
  125.  
  126.  
  127. int
  128. pcibios_find_class (unsigned long class_code, unsigned short index,
  129.             unsigned char *bus, unsigned char *device_fn)
  130. {
  131.     pci_resource_t *dev;
  132.     unsigned long w;
  133.  
  134.     for (dev = pci_device_list; dev; dev = dev->next) {
  135.         pcibios_read_config_dword(dev->bus, dev->dev_fn,
  136.                       PCI_CLASS_REVISION, &w);
  137.         if ((w >> 8) == class_code) {
  138.             if (index == 0) {
  139.                 *bus = dev->bus;
  140.                 *device_fn = dev->dev_fn;
  141.                 return PCIBIOS_SUCCESSFUL;
  142.             }
  143.             --index;
  144.         }
  145.     }
  146.     return PCIBIOS_DEVICE_NOT_FOUND;
  147. }
  148.  
  149.  
  150. int
  151. pcibios_find_device (unsigned short vendor, unsigned short device_id,
  152.              unsigned short index, unsigned char *bus,
  153.              unsigned char *device_fn)
  154. {
  155.     unsigned long w, desired = (device_id << 16) | vendor;
  156.     pci_resource_t *dev;
  157.  
  158.     if (vendor == 0xffff) {
  159.         return PCIBIOS_BAD_VENDOR_ID;
  160.     }
  161.  
  162.     for (dev = pci_device_list; dev; dev = dev->next) {
  163.         pcibios_read_config_dword(dev->bus, dev->dev_fn,
  164.                       PCI_VENDOR_ID, &w);
  165.         if (w == desired) {
  166.             if (index == 0) {
  167.                 *bus = dev->bus;
  168.                 *device_fn = dev->dev_fn;
  169.                 return PCIBIOS_SUCCESSFUL;
  170.             }
  171.             --index;
  172.         }
  173.     }
  174.     return PCIBIOS_DEVICE_NOT_FOUND;
  175. }
  176.  
  177.  
  178. int
  179. pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
  180.               unsigned char where, unsigned char *value)
  181. {
  182.     unsigned long addr = LCA_CONF;
  183.     unsigned long pci_addr;
  184.  
  185.     *value = 0xff;
  186.  
  187.     if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
  188.         return PCIBIOS_SUCCESSFUL;
  189.     } /* if */
  190.  
  191.     addr |= (pci_addr << 5) + 0x00;
  192.  
  193.     *value = conf_read(addr) >> ((where & 3) * 8);
  194.  
  195.     return PCIBIOS_SUCCESSFUL;
  196. }
  197.  
  198.  
  199. int
  200. pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
  201.               unsigned char where, unsigned short *value)
  202. {
  203.     unsigned long addr = LCA_CONF;
  204.     unsigned long pci_addr;
  205.  
  206.     *value = 0xffff;
  207.  
  208.     if (where & 0x1) {
  209.         return PCIBIOS_BAD_REGISTER_NUMBER;
  210.     } /* if */
  211.  
  212.     if (mk_conf_addr(bus, device_fn, where, &pci_addr)) {
  213.         return PCIBIOS_SUCCESSFUL;
  214.     } /* if */
  215.  
  216.     addr |= (pci_addr << 5) + 0x08;
  217.  
  218.     *value = conf_read(addr) >> ((where & 3) * 8);
  219.     return PCIBIOS_SUCCESSFUL;
  220. }
  221.  
  222.  
  223. int
  224. pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
  225.                unsigned char where, unsigned long *value)
  226. {
  227.     unsigned long addr = LCA_CONF;
  228.     unsigned long pci_addr;
  229.  
  230.     *value = 0xffffffff;
  231.  
  232.     if (where & 0x3) {
  233.         return PCIBIOS_BAD_REGISTER_NUMBER;
  234.     } /* if */
  235.  
  236.     if (mk_conf_addr(bus, device_fn, where, &pci_addr)) {
  237.         return PCIBIOS_SUCCESSFUL;
  238.     } /* if */
  239.  
  240.     addr |= (pci_addr << 5) + 0x18;
  241.  
  242.     *value = conf_read(addr);
  243.  
  244.     return PCIBIOS_SUCCESSFUL;
  245. }
  246.  
  247.  
  248. int
  249. pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
  250.                unsigned char where, unsigned char value)
  251. {
  252.     panic("pcibios_write_config_byte");
  253. }
  254.  
  255. int
  256. pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
  257.                unsigned char where, unsigned short value)
  258. {
  259.     panic("pcibios_write_config_word");
  260. }
  261.  
  262. int
  263. pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
  264.                 unsigned char where, unsigned long value)
  265. {
  266.     panic("pcibios_write_config_dword");
  267. }
  268.  
  269. #endif /* CONFIG_PCI */
  270.  
  271.  
  272. unsigned long
  273. bios32_init(unsigned long memory_start, unsigned long memory_end)
  274. {
  275. #ifdef CONFIG_PCI
  276.     printk("LCA PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV);
  277.  
  278.     probe_pci();
  279.  
  280. #if 0
  281.     {
  282.         char buf[4096];
  283.  
  284.         get_pci_list(buf);
  285.         printk("%s", buf);
  286.     }
  287. #endif
  288.  
  289. #if 0
  290.     {
  291.         extern void NCR53c810_test(void);
  292.         NCR53c810_test();
  293.     }
  294. #endif
  295. #endif /* CONFIG_PCI */
  296.  
  297.     return memory_start;
  298. } /* bios32_init */
  299.  
  300.             /*** end of lca.c ***/
  301.