Subversion Repositories HelenOS

Rev

Rev 1946 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2006 Jakub Jermar
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup sparc64
  30.  * @{
  31.  */
  32. /**
  33.  * @file
  34.  * @brief   PCI driver.
  35.  */
  36.  
  37. #include <arch/drivers/pci.h>
  38. #include <genarch/ofw/ofw_tree.h>
  39. #include <arch/trap/interrupt.h>
  40. #include <arch/mm/page.h>
  41. #include <mm/slab.h>
  42. #include <arch/types.h>
  43. #include <typedefs.h>
  44. #include <debug.h>
  45. #include <print.h>
  46. #include <func.h>
  47. #include <arch/asm.h>
  48.  
  49. #define PCI_SABRE_REGS_REG  0
  50.  
  51. #define PCI_SABRE_IMAP_BASE 0x200
  52. #define PCI_SABRE_ICLR_BASE 0x300
  53.  
  54. static pci_t *pci_sabre_init(ofw_tree_node_t *node);
  55. static void pci_sabre_enable_interrupt(pci_t *pci, int inr);
  56. static void pci_sabre_clear_interrupt(pci_t *pci, int inr);
  57.  
  58. /** PCI operations for Sabre model. */
  59. static pci_operations_t pci_sabre_ops = {
  60.     .enable_interrupt = pci_sabre_enable_interrupt,
  61.     .clear_interrupt = pci_sabre_clear_interrupt
  62. };
  63.  
  64. /** Initialize PCI controller (model Sabre). */
  65. pci_t *pci_sabre_init(ofw_tree_node_t *node)
  66. {
  67.     pci_t *pci;
  68.     ofw_tree_property_t *prop;
  69.  
  70.     /*
  71.      * Get registers.
  72.      */
  73.     prop = ofw_tree_getprop(node, "reg");
  74.     if (!prop || !prop->value)
  75.         return NULL;
  76.  
  77.     ofw_upa_reg_t *reg = prop->value;
  78.     count_t regs = prop->size / sizeof(ofw_upa_reg_t);
  79.  
  80.     if (regs < PCI_SABRE_REGS_REG + 1)
  81.         return NULL;
  82.  
  83.     uintptr_t paddr;
  84.     if (!ofw_upa_apply_ranges(node->parent, &reg[PCI_SABRE_REGS_REG], &paddr))
  85.         return NULL;
  86.  
  87.     pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC);
  88.     if (!pci)
  89.         return NULL;
  90.  
  91.     pci->model = PCI_SABRE;
  92.     pci->op = &pci_sabre_ops;
  93.     pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_SABRE_REGS_REG].size);
  94.  
  95.     return pci;
  96. }
  97.  
  98. void pci_sabre_enable_interrupt(pci_t *pci, int inr)
  99. {
  100.     pci->reg[PCI_SABRE_ICLR_BASE + (inr & INO_MASK)] = 0;
  101.     pci->reg[PCI_SABRE_IMAP_BASE + (inr & INO_MASK)] |= IMAP_V_MASK;
  102. }
  103.  
  104. void pci_sabre_clear_interrupt(pci_t *pci, int inr)
  105. {
  106.     pci->reg[PCI_SABRE_ICLR_BASE + (inr & INO_MASK)] = 0;
  107. }
  108.  
  109. /** Initialize PCI controller. */
  110. pci_t *pci_init(ofw_tree_node_t *node)
  111. {
  112.     ofw_tree_property_t *prop;
  113.  
  114.     /*
  115.      * First, verify this is a PCI node.
  116.      */
  117.     ASSERT(strcmp(ofw_tree_node_name(node), "pci") == 0);
  118.  
  119.     /*
  120.      * Determine PCI controller model.
  121.      */
  122.     prop = ofw_tree_getprop(node, "model");
  123.     if (!prop || !prop->value)
  124.         return NULL;
  125.    
  126.     if (strcmp(prop->value, "SUNW,sabre") == 0) {
  127.         /*
  128.          * PCI controller Sabre.
  129.          * This model is found on UltraSPARC IIi based machines.
  130.          */
  131.         return pci_sabre_init(node);
  132.     } else {
  133.         /*
  134.          * Unsupported model.
  135.          */
  136.         printf("Unsupported PCI controller model (%s).\n", prop->value);
  137.     }
  138.  
  139.     return NULL;
  140. }
  141.  
  142. void pci_enable_interrupt(pci_t *pci, int inr)
  143. {
  144.     ASSERT(pci->model);
  145.     ASSERT(pci->op && pci->op->enable_interrupt);
  146.     pci->op->enable_interrupt(pci, inr);
  147. }
  148.  
  149. void pci_clear_interrupt(pci_t *pci, int inr)
  150. {
  151.     ASSERT(pci->model);
  152.     ASSERT(pci->op && pci->op->clear_interrupt);
  153.     pci->op->clear_interrupt(pci, inr);
  154. }
  155.  
  156. /** @}
  157.  */
  158.