00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00044 #include <ipc/services.h>
00045 #include <ipc/irc.h>
00046 #include <ipc/ns.h>
00047 #include <sysinfo.h>
00048 #include <as.h>
00049 #include <ddi.h>
00050 #include <align.h>
00051 #include <bool.h>
00052 #include <errno.h>
00053 #include <async.h>
00054 #include <align.h>
00055 #include <async.h>
00056 #include <stdio.h>
00057 #include <ipc/devmap.h>
00058
00059 #define NAME "obio"
00060
00061 #define OBIO_SIZE 0x1898
00062
00063 #define OBIO_IMR_BASE 0x200
00064 #define OBIO_IMR(ino) (OBIO_IMR_BASE + ((ino) & INO_MASK))
00065
00066 #define OBIO_CIR_BASE 0x300
00067 #define OBIO_CIR(ino) (OBIO_CIR_BASE + ((ino) & INO_MASK))
00068
00069 #define INO_MASK 0x1f
00070
00071 static void *base_phys;
00072 static volatile uint64_t *base_virt;
00073
00079 static void obio_connection(ipc_callid_t iid, ipc_call_t *icall)
00080 {
00081 ipc_callid_t callid;
00082 ipc_call_t call;
00083
00084
00085
00086
00087 async_answer_0(iid, EOK);
00088
00089 while (1) {
00090 int inr;
00091
00092 callid = async_get_call(&call);
00093 switch (IPC_GET_IMETHOD(call)) {
00094 case IRC_ENABLE_INTERRUPT:
00095
00096 async_answer_0(callid, EOK);
00097 break;
00098 case IRC_CLEAR_INTERRUPT:
00099 inr = IPC_GET_ARG1(call);
00100 base_virt[OBIO_CIR(inr & INO_MASK)] = 0;
00101 async_answer_0(callid, EOK);
00102 break;
00103 default:
00104 async_answer_0(callid, EINVAL);
00105 break;
00106 }
00107 }
00108 }
00109
00115 static bool obio_init(void)
00116 {
00117 sysarg_t paddr;
00118
00119 if (sysinfo_get_value("obio.base.physical", &paddr) != EOK) {
00120 printf(NAME ": no OBIO registers found\n");
00121 return false;
00122 }
00123
00124 base_phys = (void *) paddr;
00125 base_virt = as_get_mappable_page(OBIO_SIZE);
00126
00127 int flags = AS_AREA_READ | AS_AREA_WRITE;
00128 int retval = physmem_map(base_phys, (void *) base_virt,
00129 ALIGN_UP(OBIO_SIZE, PAGE_SIZE) >> PAGE_WIDTH, flags);
00130
00131 if (retval < 0) {
00132 printf(NAME ": Error mapping OBIO registers\n");
00133 return false;
00134 }
00135
00136 printf(NAME ": OBIO registers with base at %p\n", base_phys);
00137
00138 async_set_client_connection(obio_connection);
00139 service_register(SERVICE_IRC);
00140
00141 return true;
00142 }
00143
00144 int main(int argc, char **argv)
00145 {
00146 printf(NAME ": HelenOS OBIO driver\n");
00147
00148 if (!obio_init())
00149 return -1;
00150
00151 printf(NAME ": Accepting connections\n");
00152 async_manager();
00153
00154
00155 return 0;
00156 }
00157