00001
00002
00011
00012
00013
00014
00015
00016 #include <stdio.h>
00017
00018
00019 #include <l4/sys/types.h>
00020 #include <l4/env/errno.h>
00021 #include <l4/sys/syscalls.h>
00022 #include <l4/l4rm/l4rm.h>
00023 #include <l4/names/libnames.h>
00024
00025
00026 #include <l4/generic_io/libio.h>
00027
00028
00029 #include "internal.h"
00030 #include "__macros.h"
00031
00032
00033 char *IO_NAMES_STR = "io";
00035
00036 #define CONFIG_LOG_INFOPAGE_MAPPING 0
00037
00038 l4_threadid_t io_l4id = L4_INVALID_ID;
00040 static int _initialized = 0;
00041 static l4io_info_t *io_info_page_pointer;
00042
00043 extern l4io_info_t io_info;
00044
00045
00053
00054 static int __io_register(l4_uint32_t * type)
00055 {
00056 int error;
00057 CORBA_Environment _env = dice_default_environment;
00058
00059 error = l4_io_register_client_call(&io_l4id, *type, &_env);
00060 return DICE_ERR(error, &_env);
00061 }
00062
00063
00073
00074 static int __io_mapping(l4io_info_t **addr)
00075 {
00076 int error;
00077 CORBA_Environment _env = dice_default_environment;
00078
00079 l4_fpage_t rfp;
00080 l4_snd_fpage_t info;
00081
00082 if (*addr == 0)
00083 *addr = &io_info;
00084
00085
00086 rfp = l4_fpage((l4_umword_t)*addr, L4_LOG2_PAGESIZE, 0, 0);
00087
00088
00089 l4_fpage_unmap(rfp, L4_FP_FLUSH_PAGE | L4_FP_ALL_SPACES);
00090
00091 LOGd(CONFIG_LOG_INFOPAGE_MAPPING,
00092 "receiving fpage {0x%08x, 0x%08x}", rfp.fp.page << 12, 1 << rfp.fp.size);
00093 _env.rcv_fpage = rfp;
00094
00095 error = l4_io_map_info_call(&io_l4id, &info, &_env);
00096
00097 LOGd(CONFIG_LOG_INFOPAGE_MAPPING,
00098 "received fpage {0x%08x, 0x%08x}",
00099 info.fpage.fp.page << 12, 1 << info.fpage.fp.size);
00100
00101 if ((error=DICE_ERR(error, &_env)))
00102 return error;
00103
00104 if ((*addr)->magic != L4IO_INFO_MAGIC)
00105 {
00106 #ifdef DEBUG_ERRORS
00107 l4dm_dataspace_t ds;
00108 l4_offs_t offset;
00109 l4_addr_t map_addr;
00110 l4_size_t map_size;
00111 l4_threadid_t dummy;
00112
00113 LOG_Error("mapping io info page");
00114
00115 error = l4rm_lookup(*addr, &map_addr, &map_size, &ds, &offset, &dummy);
00116 if (error < 0)
00117 LOG(" l4rm_lookup for io info page address failed (%s)",
00118 l4env_errstr(error));
00119 else if (error == L4RM_REGION_DATASPACE)
00120 LOG(" io info page: offset=%d addr=%d size=%d",
00121 offset, map_addr, map_size);
00122 else
00123 LOG(" invalid region type for io info page (type %d)", error);
00124 l4rm_show_region_list();
00125 #endif
00126 return -L4_ENOTFOUND;
00127 }
00128
00129 LOGd(CONFIG_LOG_INFOPAGE_MAPPING,
00130 "magic: %08lx (%c%c%c%c)",
00131 (*addr)->magic,
00132 (char)(((*addr)->magic) >> 24),
00133 (char)(((*addr)->magic) >> 16 & 0xff),
00134 (char)(((*addr)->magic) >> 8 & 0xff),
00135 (char)(((*addr)->magic) & 0xff));
00136
00137 io_info_page_pointer = *addr;
00138
00139 return 0;
00140 }
00141
00142
00163
00164 int l4io_init(l4io_info_t **io_info_addr, l4io_drv_t type)
00165 {
00166 int error;
00167 l4_uint32_t tmp_type;
00168
00169
00170 if (!io_info_addr ||
00171 (((l4_umword_t)*io_info_addr & ~L4_PAGEMASK) && (*io_info_addr != (void*)-1)))
00172 return -L4_EINVAL;
00173
00174
00175 if (names_waitfor_name(IO_NAMES_STR, &io_l4id, 50000) == 0)
00176 {
00177 LOG_Error("%s not registered at names", IO_NAMES_STR);
00178 return -L4_ENOTFOUND;
00179 }
00180
00181
00182 memcpy(&tmp_type, &type, sizeof(tmp_type));
00183 if (!_initialized)
00184 if ((error = __io_register(&tmp_type)))
00185 {
00186 LOG_Error("while registering at io (%d)", error);
00187 return error;
00188 }
00189
00190
00191 if ((*io_info_addr != (void*)-1) && (error = __io_mapping(io_info_addr)))
00192 {
00193 LOG_Error("while mapping io info page (%d)", error);
00194 return error;
00195 }
00196
00197 ++_initialized;
00198 return 0;
00199 }
00200
00201
00202
00203
00204 l4io_info_t *l4io_info_page(void)
00205 {
00206 return io_info_page_pointer;
00207
00208 }