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
00038 #include <ipc/services.h>
00039 #include <ipc/irc.h>
00040 #include <ipc/ns.h>
00041 #include <sysinfo.h>
00042 #include <as.h>
00043 #include <ddi.h>
00044 #include <align.h>
00045 #include <bool.h>
00046 #include <errno.h>
00047 #include <async.h>
00048 #include <align.h>
00049 #include <async.h>
00050 #include <stdio.h>
00051 #include <ipc/devmap.h>
00052
00053 #define NAME "fhc"
00054
00055 #define FHC_UART_INR 0x39
00056
00057 #define FHC_UART_IMAP 0x0
00058 #define FHC_UART_ICLR 0x4
00059
00060 static void *fhc_uart_phys;
00061 static volatile uint32_t *fhc_uart_virt;
00062 static size_t fhc_uart_size;
00063
00069 static void fhc_connection(ipc_callid_t iid, ipc_call_t *icall)
00070 {
00071 ipc_callid_t callid;
00072 ipc_call_t call;
00073
00074
00075
00076
00077 async_answer_0(iid, EOK);
00078
00079 while (1) {
00080 int inr;
00081
00082 callid = async_get_call(&call);
00083 switch (IPC_GET_IMETHOD(call)) {
00084 case IRC_ENABLE_INTERRUPT:
00085
00086 async_answer_0(callid, EOK);
00087 break;
00088 case IRC_CLEAR_INTERRUPT:
00089 inr = IPC_GET_ARG1(call);
00090 switch (inr) {
00091 case FHC_UART_INR:
00092 fhc_uart_virt[FHC_UART_ICLR] = 0;
00093 async_answer_0(callid, EOK);
00094 break;
00095 default:
00096 async_answer_0(callid, ENOTSUP);
00097 break;
00098 }
00099 break;
00100 default:
00101 async_answer_0(callid, EINVAL);
00102 break;
00103 }
00104 }
00105 }
00106
00112 static bool fhc_init(void)
00113 {
00114 sysarg_t paddr;
00115
00116 if ((sysinfo_get_value("fhc.uart.physical", &paddr) != EOK)
00117 || (sysinfo_get_value("fhc.uart.size", &fhc_uart_size) != EOK)) {
00118 printf(NAME ": no FHC UART registers found\n");
00119 return false;
00120 }
00121
00122 fhc_uart_phys = (void *) paddr;
00123 fhc_uart_virt = as_get_mappable_page(fhc_uart_size);
00124
00125 int flags = AS_AREA_READ | AS_AREA_WRITE;
00126 int retval = physmem_map(fhc_uart_phys, (void *) fhc_uart_virt,
00127 ALIGN_UP(fhc_uart_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
00128
00129 if (retval < 0) {
00130 printf(NAME ": Error mapping FHC UART registers\n");
00131 return false;
00132 }
00133
00134 printf(NAME ": FHC UART registers at %p, %zu bytes\n", fhc_uart_phys,
00135 fhc_uart_size);
00136
00137 async_set_client_connection(fhc_connection);
00138 service_register(SERVICE_IRC);
00139
00140 return true;
00141 }
00142
00143 int main(int argc, char **argv)
00144 {
00145 printf(NAME ": HelenOS FHC bus controller driver\n");
00146
00147 if (!fhc_init())
00148 return -1;
00149
00150 printf(NAME ": Accepting connections\n");
00151 async_manager();
00152
00153
00154 return 0;
00155 }
00156