source: mainline/uspace/drv/platform/pc/pc.c@ c8ea6eca

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c8ea6eca was 4122410, checked in by Jakub Jermar <jakub@…>, 7 years ago

Improve Doxygen documentaion

This is stil WiP. A number of libraries, drivers and services were
converted to using a more hierarchical and decentralized scheme when it
comes to specifying to which doxygen group they belong.

  • Property mode set to 100644
File size: 5.3 KB
RevLine 
[eff1a590]1/*
2 * Copyright (c) 2010 Lenka Trochtova
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/**
[4122410]30 * @addtogroup pc pc
[eff1a590]31 * @{
32 */
33
34/** @file
35 */
36
37#include <assert.h>
38#include <stdio.h>
39#include <errno.h>
[3e6a98c5]40#include <stdbool.h>
[eff1a590]41#include <fibril_synch.h>
42#include <stdlib.h>
[c47e1a8]43#include <str.h>
[eff1a590]44#include <ctype.h>
45#include <macros.h>
46
[af6b5157]47#include <ddf/driver.h>
[fc51296]48#include <ddf/log.h>
[5cd136ab]49#include <ipc/dev_iface.h>
[41b56084]50#include <ops/hw_res.h>
[26bc0fd1]51#include <ops/pio_window.h>
[eff1a590]52
[2a37b9f]53#define NAME "pc"
[eff1a590]54
[2a37b9f]55typedef struct pc_fun {
[b9ccc46d]56 hw_resource_list_t hw_resources;
[26bc0fd1]57 pio_window_t pio_window;
[2a37b9f]58} pc_fun_t;
[5cd136ab]59
[b7fd2a0]60static errno_t pc_dev_add(ddf_dev_t *dev);
[0f2a9be]61static void pc_init(void);
[eff1a590]62
[b9ccc46d]63/** The root device driver's standard operations. */
[2a37b9f]64static driver_ops_t pc_ops = {
65 .dev_add = &pc_dev_add
[eff1a590]66};
67
[b9ccc46d]68/** The root device driver structure. */
[2a37b9f]69static driver_t pc_driver = {
[eff1a590]70 .name = NAME,
[2a37b9f]71 .driver_ops = &pc_ops
[eff1a590]72};
73
[230385c]74static hw_resource_t pci_conf_regs[] = {
75 {
76 .type = IO_RANGE,
77 .res.io_range = {
78 .address = 0xCF8,
79 .size = 4,
[9e470c0]80 .relative = false,
[230385c]81 .endianness = LITTLE_ENDIAN
82 }
83 },
84 {
85 .type = IO_RANGE,
86 .res.io_range = {
87 .address = 0xCFC,
88 .size = 4,
[9e470c0]89 .relative = false,
[230385c]90 .endianness = LITTLE_ENDIAN
91 }
[b9ccc46d]92 }
[5cd136ab]93};
94
[2a37b9f]95static pc_fun_t pci_data = {
[5cd136ab]96 .hw_resources = {
[26bc0fd1]97 sizeof(pci_conf_regs) / sizeof(pci_conf_regs[0]),
[230385c]98 pci_conf_regs
[26bc0fd1]99 },
100 .pio_window = {
101 .mem = {
102 .base = UINT32_C(0),
103 .size = UINT32_C(0xffffffff) /* practical maximum */
104 },
105 .io = {
106 .base = UINT32_C(0),
107 .size = UINT32_C(0x10000)
108 }
[5cd136ab]109 }
110};
111
[56fd7cf]112/** Obtain function soft-state from DDF function node */
[2a37b9f]113static pc_fun_t *pc_fun(ddf_fun_t *fnode)
[56fd7cf]114{
115 return ddf_fun_data_get(fnode);
116}
117
[2a37b9f]118static hw_resource_list_t *pc_get_resources(ddf_fun_t *fnode)
[9a66bc2e]119{
[2a37b9f]120 pc_fun_t *fun = pc_fun(fnode);
[a35b458]121
[68414f4a]122 assert(fun != NULL);
123 return &fun->hw_resources;
[9a66bc2e]124}
125
[b7fd2a0]126static errno_t pc_enable_interrupt(ddf_fun_t *fun, int irq)
[9a66bc2e]127{
[b9ccc46d]128 /* TODO */
[a35b458]129
[9a66bc2e]130 return false;
131}
132
[2a37b9f]133static pio_window_t *pc_get_pio_window(ddf_fun_t *fnode)
[26bc0fd1]134{
[2a37b9f]135 pc_fun_t *fun = pc_fun(fnode);
[a35b458]136
[26bc0fd1]137 assert(fun != NULL);
138 return &fun->pio_window;
139}
140
[8b1e15ac]141static hw_res_ops_t fun_hw_res_ops = {
[2a37b9f]142 .get_resource_list = &pc_get_resources,
143 .enable_interrupt = &pc_enable_interrupt,
[9a66bc2e]144};
145
[26bc0fd1]146static pio_window_ops_t fun_pio_window_ops = {
[2a37b9f]147 .get_pio_window = &pc_get_pio_window
[26bc0fd1]148};
149
[0f2a9be]150/* Initialized in pc_init() function. */
[2a37b9f]151static ddf_dev_ops_t pc_fun_ops;
[3843ecb]152
[b9ccc46d]153static bool
[2a37b9f]154pc_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id,
155 pc_fun_t *fun_proto)
[5cd136ab]156{
[ebcb05a]157 ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name);
[a35b458]158
[83a2f43]159 ddf_fun_t *fnode = NULL;
[b7fd2a0]160 errno_t rc;
[a35b458]161
[b9ccc46d]162 /* Create new device. */
[97a62fe]163 fnode = ddf_fun_create(dev, fun_inner, name);
[68414f4a]164 if (fnode == NULL)
[eff1a590]165 goto failure;
[a35b458]166
[2a37b9f]167 pc_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(pc_fun_t));
[56fd7cf]168 *fun = *fun_proto;
[a35b458]169
[56fd7cf]170 /* Add match ID */
171 rc = ddf_fun_add_match_id(fnode, str_match_id, 100);
172 if (rc != EOK)
[eff1a590]173 goto failure;
[a35b458]174
[b9ccc46d]175 /* Set provided operations to the device. */
[2a37b9f]176 ddf_fun_set_ops(fnode, &pc_fun_ops);
[a35b458]177
[8b1e15ac]178 /* Register function. */
[97a62fe]179 if (ddf_fun_bind(fnode) != EOK) {
[ebcb05a]180 ddf_msg(LVL_ERROR, "Failed binding function %s.", name);
[eff1a590]181 goto failure;
[97a62fe]182 }
[a35b458]183
[eff1a590]184 return true;
[a35b458]185
[eff1a590]186failure:
[97a62fe]187 if (fnode != NULL)
188 ddf_fun_destroy(fnode);
[a35b458]189
[ebcb05a]190 ddf_msg(LVL_ERROR, "Failed adding function '%s'.", name);
[a35b458]191
[b9ccc46d]192 return false;
[eff1a590]193}
194
[2a37b9f]195static bool pc_add_functions(ddf_dev_t *dev)
[eff1a590]196{
[2a37b9f]197 return pc_add_fun(dev, "pci0", "intel_pci", &pci_data);
[eff1a590]198}
199
200/** Get the root device.
[b9ccc46d]201 *
202 * @param dev The device which is root of the whole device tree (both
203 * of HW and pseudo devices).
[cde999a]204 * @return Zero on success, error number otherwise.
[eff1a590]205 */
[b7fd2a0]206static errno_t pc_dev_add(ddf_dev_t *dev)
[eff1a590]207{
[2a37b9f]208 ddf_msg(LVL_DEBUG, "pc_dev_add, device handle = %d",
[56fd7cf]209 (int)ddf_dev_get_handle(dev));
[a35b458]210
[8b1e15ac]211 /* Register functions. */
[2a37b9f]212 if (!pc_add_functions(dev)) {
[ebcb05a]213 ddf_msg(LVL_ERROR, "Failed to add functions for PC platform.");
[eff1a590]214 }
[a35b458]215
[df747b9c]216 return EOK;
[eff1a590]217}
218
[0f2a9be]219static void pc_init(void)
[b9ccc46d]220{
[267f235]221 ddf_log_init(NAME);
[2a37b9f]222 pc_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops;
223 pc_fun_ops.interfaces[PIO_WINDOW_DEV_IFACE] = &fun_pio_window_ops;
[3843ecb]224}
225
[eff1a590]226int main(int argc, char *argv[])
227{
[5f0123b]228 printf(NAME ": HelenOS PC platform driver\n");
[0f2a9be]229 pc_init();
[2a37b9f]230 return ddf_driver_main(&pc_driver);
[eff1a590]231}
232
233/**
234 * @}
235 */
Note: See TracBrowser for help on using the repository browser.