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

Last change on this file was b25970f, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix ISA-only PC support.

  • Property mode set to 100644
File size: 5.5 KB
RevLine 
[eff1a590]1/*
[b25970f]2 * Copyright (c) 2018 Jiri Svoboda
[eff1a590]3 * Copyright (c) 2010 Lenka Trochtova
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/**
[4122410]31 * @addtogroup pc pc
[eff1a590]32 * @{
33 */
34
35/** @file
36 */
37
38#include <assert.h>
39#include <stdio.h>
40#include <errno.h>
[3e6a98c5]41#include <stdbool.h>
[eff1a590]42#include <fibril_synch.h>
43#include <stdlib.h>
[c47e1a8]44#include <str.h>
[eff1a590]45#include <ctype.h>
46#include <macros.h>
47
[af6b5157]48#include <ddf/driver.h>
[fc51296]49#include <ddf/log.h>
[5cd136ab]50#include <ipc/dev_iface.h>
[41b56084]51#include <ops/hw_res.h>
[26bc0fd1]52#include <ops/pio_window.h>
[eff1a590]53
[2a37b9f]54#define NAME "pc"
[eff1a590]55
[2a37b9f]56typedef struct pc_fun {
[b9ccc46d]57 hw_resource_list_t hw_resources;
[26bc0fd1]58 pio_window_t pio_window;
[2a37b9f]59} pc_fun_t;
[5cd136ab]60
[b7fd2a0]61static errno_t pc_dev_add(ddf_dev_t *dev);
[0f2a9be]62static void pc_init(void);
[eff1a590]63
[b9ccc46d]64/** The root device driver's standard operations. */
[2a37b9f]65static driver_ops_t pc_ops = {
66 .dev_add = &pc_dev_add
[eff1a590]67};
68
[b9ccc46d]69/** The root device driver structure. */
[2a37b9f]70static driver_t pc_driver = {
[eff1a590]71 .name = NAME,
[2a37b9f]72 .driver_ops = &pc_ops
[eff1a590]73};
74
[230385c]75static hw_resource_t pci_conf_regs[] = {
76 {
77 .type = IO_RANGE,
78 .res.io_range = {
79 .address = 0xCF8,
80 .size = 4,
[9e470c0]81 .relative = false,
[230385c]82 .endianness = LITTLE_ENDIAN
83 }
84 },
85 {
86 .type = IO_RANGE,
87 .res.io_range = {
88 .address = 0xCFC,
89 .size = 4,
[9e470c0]90 .relative = false,
[230385c]91 .endianness = LITTLE_ENDIAN
92 }
[b9ccc46d]93 }
[5cd136ab]94};
95
[b25970f]96static pc_fun_t sys_data = {
[5cd136ab]97 .hw_resources = {
[26bc0fd1]98 sizeof(pci_conf_regs) / sizeof(pci_conf_regs[0]),
[230385c]99 pci_conf_regs
[26bc0fd1]100 },
101 .pio_window = {
102 .mem = {
103 .base = UINT32_C(0),
104 .size = UINT32_C(0xffffffff) /* practical maximum */
105 },
106 .io = {
107 .base = UINT32_C(0),
108 .size = UINT32_C(0x10000)
109 }
[5cd136ab]110 }
111};
112
[56fd7cf]113/** Obtain function soft-state from DDF function node */
[2a37b9f]114static pc_fun_t *pc_fun(ddf_fun_t *fnode)
[56fd7cf]115{
116 return ddf_fun_data_get(fnode);
117}
118
[2a37b9f]119static hw_resource_list_t *pc_get_resources(ddf_fun_t *fnode)
[9a66bc2e]120{
[2a37b9f]121 pc_fun_t *fun = pc_fun(fnode);
[a35b458]122
[68414f4a]123 assert(fun != NULL);
124 return &fun->hw_resources;
[9a66bc2e]125}
126
[b7fd2a0]127static errno_t pc_enable_interrupt(ddf_fun_t *fun, int irq)
[9a66bc2e]128{
[b9ccc46d]129 /* TODO */
[a35b458]130
[9a66bc2e]131 return false;
132}
133
[2a37b9f]134static pio_window_t *pc_get_pio_window(ddf_fun_t *fnode)
[26bc0fd1]135{
[2a37b9f]136 pc_fun_t *fun = pc_fun(fnode);
[a35b458]137
[26bc0fd1]138 assert(fun != NULL);
139 return &fun->pio_window;
140}
141
[8b1e15ac]142static hw_res_ops_t fun_hw_res_ops = {
[2a37b9f]143 .get_resource_list = &pc_get_resources,
144 .enable_interrupt = &pc_enable_interrupt,
[9a66bc2e]145};
146
[26bc0fd1]147static pio_window_ops_t fun_pio_window_ops = {
[2a37b9f]148 .get_pio_window = &pc_get_pio_window
[26bc0fd1]149};
150
[0f2a9be]151/* Initialized in pc_init() function. */
[2a37b9f]152static ddf_dev_ops_t pc_fun_ops;
[3843ecb]153
[b25970f]154static errno_t pc_add_sysbus(ddf_dev_t *dev)
[5cd136ab]155{
[83a2f43]156 ddf_fun_t *fnode = NULL;
[b7fd2a0]157 errno_t rc;
[a35b458]158
[b25970f]159 ddf_msg(LVL_DEBUG, "Adding system bus.");
160
[b9ccc46d]161 /* Create new device. */
[b25970f]162 fnode = ddf_fun_create(dev, fun_inner, "sys");
163 if (fnode == NULL) {
164 rc = ENOMEM;
165 goto error;
166 }
[a35b458]167
[2a37b9f]168 pc_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(pc_fun_t));
[b25970f]169 *fun = sys_data;
170
171 /* Add match IDs */
172 rc = ddf_fun_add_match_id(fnode, "intel_pci", 100);
173 if (rc != EOK)
174 goto error;
[a35b458]175
[b25970f]176 rc = ddf_fun_add_match_id(fnode, "isa", 10);
[56fd7cf]177 if (rc != EOK)
[b25970f]178 goto error;
[a35b458]179
[b9ccc46d]180 /* Set provided operations to the device. */
[2a37b9f]181 ddf_fun_set_ops(fnode, &pc_fun_ops);
[a35b458]182
[8b1e15ac]183 /* Register function. */
[b25970f]184 rc = ddf_fun_bind(fnode);
185 if (rc != EOK) {
186 ddf_msg(LVL_ERROR, "Failed binding system bus function.");
187 goto error;
[97a62fe]188 }
[a35b458]189
[b25970f]190 return EOK;
[a35b458]191
[b25970f]192error:
[97a62fe]193 if (fnode != NULL)
194 ddf_fun_destroy(fnode);
[a35b458]195
[b25970f]196 ddf_msg(LVL_ERROR, "Failed adding system bus.");
197 return rc;
[eff1a590]198}
199
[b25970f]200static errno_t pc_add_functions(ddf_dev_t *dev)
[eff1a590]201{
[b25970f]202 errno_t rc;
203
204 rc = pc_add_sysbus(dev);
205 if (rc != EOK)
206 return rc;
207
208 return EOK;
[eff1a590]209}
210
211/** Get the root device.
[b9ccc46d]212 *
213 * @param dev The device which is root of the whole device tree (both
214 * of HW and pseudo devices).
[cde999a]215 * @return Zero on success, error number otherwise.
[eff1a590]216 */
[b7fd2a0]217static errno_t pc_dev_add(ddf_dev_t *dev)
[eff1a590]218{
[b25970f]219 errno_t rc;
220
[2a37b9f]221 ddf_msg(LVL_DEBUG, "pc_dev_add, device handle = %d",
[56fd7cf]222 (int)ddf_dev_get_handle(dev));
[a35b458]223
[8b1e15ac]224 /* Register functions. */
[b25970f]225 rc = pc_add_functions(dev);
226 if (rc != EOK) {
[ebcb05a]227 ddf_msg(LVL_ERROR, "Failed to add functions for PC platform.");
[b25970f]228 return rc;
[eff1a590]229 }
[a35b458]230
[df747b9c]231 return EOK;
[eff1a590]232}
233
[0f2a9be]234static void pc_init(void)
[b9ccc46d]235{
[267f235]236 ddf_log_init(NAME);
[2a37b9f]237 pc_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops;
238 pc_fun_ops.interfaces[PIO_WINDOW_DEV_IFACE] = &fun_pio_window_ops;
[3843ecb]239}
240
[eff1a590]241int main(int argc, char *argv[])
242{
[5f0123b]243 printf(NAME ": HelenOS PC platform driver\n");
[0f2a9be]244 pc_init();
[2a37b9f]245 return ddf_driver_main(&pc_driver);
[eff1a590]246}
247
248/**
249 * @}
250 */
Note: See TracBrowser for help on using the repository browser.