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 <assert.h>
00039 #include <stdio.h>
00040 #include <errno.h>
00041 #include <bool.h>
00042 #include <fibril_synch.h>
00043 #include <stdlib.h>
00044 #include <str.h>
00045 #include <ctype.h>
00046 #include <macros.h>
00047
00048 #include <ddf/driver.h>
00049 #include <ddf/log.h>
00050 #include <devman.h>
00051 #include <ipc/devman.h>
00052 #include <ipc/dev_iface.h>
00053 #include <ops/hw_res.h>
00054 #include <device/hw_res.h>
00055
00056 #define NAME "rootpc"
00057
00059 #define ROOTPC_FUN(fnode) ((rootpc_fun_t *) (fnode)->driver_data)
00060
00061 typedef struct rootpc_fun {
00062 hw_resource_list_t hw_resources;
00063 } rootpc_fun_t;
00064
00065 static int rootpc_add_device(ddf_dev_t *dev);
00066 static void root_pc_init(void);
00067
00069 static driver_ops_t rootpc_ops = {
00070 .add_device = &rootpc_add_device
00071 };
00072
00074 static driver_t rootpc_driver = {
00075 .name = NAME,
00076 .driver_ops = &rootpc_ops
00077 };
00078
00079 static hw_resource_t pci_conf_regs = {
00080 .type = IO_RANGE,
00081 .res.io_range = {
00082 .address = 0xCF8,
00083 .size = 8,
00084 .endianness = LITTLE_ENDIAN
00085 }
00086 };
00087
00088 static rootpc_fun_t pci_data = {
00089 .hw_resources = {
00090 1,
00091 &pci_conf_regs
00092 }
00093 };
00094
00095 static hw_resource_list_t *rootpc_get_resources(ddf_fun_t *fnode)
00096 {
00097 rootpc_fun_t *fun = ROOTPC_FUN(fnode);
00098
00099 assert(fun != NULL);
00100 return &fun->hw_resources;
00101 }
00102
00103 static bool rootpc_enable_interrupt(ddf_fun_t *fun)
00104 {
00105
00106
00107 return false;
00108 }
00109
00110 static hw_res_ops_t fun_hw_res_ops = {
00111 &rootpc_get_resources,
00112 &rootpc_enable_interrupt
00113 };
00114
00115
00116 static ddf_dev_ops_t rootpc_fun_ops;
00117
00118 static bool
00119 rootpc_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id,
00120 rootpc_fun_t *fun)
00121 {
00122 ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name);
00123
00124 ddf_fun_t *fnode = NULL;
00125 match_id_t *match_id = NULL;
00126
00127
00128 fnode = ddf_fun_create(dev, fun_inner, name);
00129 if (fnode == NULL)
00130 goto failure;
00131
00132 fnode->driver_data = fun;
00133
00134
00135 match_id = create_match_id();
00136 if (match_id == NULL)
00137 goto failure;
00138
00139 match_id->id = str_match_id;
00140 match_id->score = 100;
00141 add_match_id(&fnode->match_ids, match_id);
00142
00143
00144 fnode->ops = &rootpc_fun_ops;
00145
00146
00147 if (ddf_fun_bind(fnode) != EOK) {
00148 ddf_msg(LVL_ERROR, "Failed binding function %s.", name);
00149 goto failure;
00150 }
00151
00152 return true;
00153
00154 failure:
00155 if (match_id != NULL)
00156 match_id->id = NULL;
00157
00158 if (fnode != NULL)
00159 ddf_fun_destroy(fnode);
00160
00161 ddf_msg(LVL_ERROR, "Failed adding function '%s'.", name);
00162
00163 return false;
00164 }
00165
00166 static bool rootpc_add_functions(ddf_dev_t *dev)
00167 {
00168 return rootpc_add_fun(dev, "pci0", "intel_pci", &pci_data);
00169 }
00170
00177 static int rootpc_add_device(ddf_dev_t *dev)
00178 {
00179 ddf_msg(LVL_DEBUG, "rootpc_add_device, device handle = %d",
00180 (int)dev->handle);
00181
00182
00183 if (!rootpc_add_functions(dev)) {
00184 ddf_msg(LVL_ERROR, "Failed to add functions for PC platform.");
00185 }
00186
00187 return EOK;
00188 }
00189
00190 static void root_pc_init(void)
00191 {
00192 ddf_log_init(NAME, LVL_ERROR);
00193 rootpc_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops;
00194 }
00195
00196 int main(int argc, char *argv[])
00197 {
00198 printf(NAME ": HelenOS PC platform driver\n");
00199 root_pc_init();
00200 return ddf_driver_main(&rootpc_driver);
00201 }
00202