Subversion Repositories HelenOS

Rev

Rev 4344 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2009 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 obio
  30.  * @{
  31.  */
  32.  
  33. /**
  34.  * @file    obio.c
  35.  * @brief   OBIO driver.
  36.  *
  37.  * OBIO is a short for on-board I/O. On UltraSPARC IIi and systems with U2P,
  38.  * there is a piece of the root PCI bus controller address space, which
  39.  * contains interrupt mapping and clear registers for all on-board devices.
  40.  * Although UltraSPARC IIi and U2P are different in general, these registers can
  41.  * be found at the same addresses.
  42.  */
  43.  
  44. #include <ipc/ipc.h>
  45. #include <ipc/services.h>
  46. #include <ipc/bus.h>
  47. #include <ipc/ns.h>
  48. #include <sysinfo.h>
  49. #include <as.h>
  50. #include <ddi.h>
  51. #include <align.h>
  52. #include <bool.h>
  53. #include <errno.h>
  54. #include <async.h>
  55. #include <align.h>
  56. #include <async.h>
  57. #include <stdio.h>
  58. #include <ipc/devmap.h>
  59.  
  60. #define NAME "obio"
  61.  
  62. #define OBIO_SIZE   0x1898 
  63.  
  64. #define OBIO_IMR_BASE   0x200
  65. #define OBIO_IMR(ino)   (OBIO_IMR_BASE + ((ino) & INO_MASK))
  66.  
  67. #define OBIO_CIR_BASE   0x300
  68. #define OBIO_CIR(ino)   (OBIO_CIR_BASE + ((ino) & INO_MASK))
  69.  
  70. #define INO_MASK    0x1f
  71.  
  72. static void *base_phys;
  73. static volatile uint64_t *base_virt;
  74.  
  75. /** Handle one connection to obio.
  76.  *
  77.  * @param iid       Hash of the request that opened the connection.
  78.  * @param icall     Call data of the request that opened the connection.
  79.  */
  80. static void obio_connection(ipc_callid_t iid, ipc_call_t *icall)
  81. {
  82.     ipc_callid_t callid;
  83.     ipc_call_t call;
  84.  
  85.     /*
  86.      * Answer the first IPC_M_CONNECT_ME_TO call.
  87.      */
  88.     ipc_answer_0(iid, EOK);
  89.  
  90.     while (1) {
  91.         int inr;
  92.    
  93.         callid = async_get_call(&call);
  94.         switch (IPC_GET_METHOD(call)) {
  95.         case BUS_CLEAR_INTERRUPT:
  96.             inr = IPC_GET_ARG1(call);
  97.             base_virt[OBIO_CIR(inr & INO_MASK)] = 0;
  98.             ipc_answer_0(callid, EOK);
  99.             break;
  100.         default:
  101.             ipc_answer_0(callid, EINVAL);
  102.             break;
  103.         }
  104.     }
  105. }
  106.  
  107. /** Initialize the OBIO driver.
  108.  *
  109.  * So far, the driver heavily depends on information provided by the kernel via
  110.  * sysinfo. In the future, there should be a standalone OBIO driver.
  111.  */
  112. static bool obio_init(void)
  113. {
  114.     ipcarg_t phonead;
  115.  
  116.     base_phys = (void *) sysinfo_value("obio.base.physical");
  117.    
  118.     if (!base_phys) {
  119.         printf(NAME ": no OBIO registers found\n");
  120.         return false;
  121.     }
  122.  
  123.     base_virt = as_get_mappable_page(OBIO_SIZE);
  124.    
  125.     int flags = AS_AREA_READ | AS_AREA_WRITE;
  126.     int retval = physmem_map(base_phys, (void *) base_virt,
  127.         ALIGN_UP(OBIO_SIZE, PAGE_SIZE) >> PAGE_WIDTH, flags);
  128.    
  129.     if (retval < 0) {
  130.         printf(NAME ": Error mapping OBIO registers\n");
  131.         return false;
  132.     }
  133.    
  134.     printf(NAME ": OBIO registers with base at %p\n", base_phys);
  135.  
  136.     async_set_client_connection(obio_connection);
  137.     ipc_connect_to_me(PHONE_NS, SERVICE_OBIO, 0, 0, &phonead);
  138.    
  139.     return true;
  140. }
  141.  
  142. int main(int argc, char **argv)
  143. {
  144.     printf(NAME ": HelenOS OBIO driver\n");
  145.    
  146.     if (!obio_init())
  147.         return -1;
  148.    
  149.     printf(NAME ": Accepting connections\n");
  150.     async_manager();
  151.  
  152.     /* Never reached */
  153.     return 0;
  154. }
  155.  
  156. /**
  157.  * @}
  158.  */
  159.