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

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

Fix vertical spacing with new Ccheck revision.

  • Property mode set to 100644
File size: 6.4 KB
RevLine 
[9191607]1/*
2 * Copyright (c) 2016 Jakub Jermar
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 sun4u sun4u
[9191607]31 * @{
32 */
33
34/** @file
35 */
36
37#include <assert.h>
38#include <stdio.h>
39#include <errno.h>
40#include <stdbool.h>
41#include <fibril_synch.h>
42#include <stdlib.h>
43#include <str.h>
44#include <ctype.h>
45#include <macros.h>
46
47#include <ddi.h>
48#include <ddf/driver.h>
49#include <ddf/log.h>
50#include <ipc/dev_iface.h>
51#include <ops/hw_res.h>
52#include <ops/pio_window.h>
53#include <byteorder.h>
54
55#define NAME "sun4u"
56
57#define PBM_BASE UINT64_C(0x1fe00000000)
58#define PBM_SIZE UINT64_C(0x00200000000)
59
[54861ca]60#define PBM_PCI_CONFIG_BASE UINT64_C(0x00001000000)
[9191607]61#define PBM_PCI_CONFIG_SIZE UINT64_C(0x00001000000)
62
[54861ca]63#define PBM_PCI_IO_BASE UINT64_C(0x00002000000)
64#define PBM_PCI_IO_SIZE UINT64_C(0x00001000000)
65
66#define PBM_PCI_MEM_BASE UINT64_C(0x00100000000)
67#define PBM_PCI_MEM_SIZE UINT64_C(0x00100000000)
68
[48adf0f]69#define PBM_OBIO_BASE UINT64_C(0)
70#define PBM_OBIO_SIZE UINT64_C(0x1898)
71
[9191607]72typedef struct sun4u_fun {
73 hw_resource_list_t hw_resources;
74 pio_window_t pio_window;
75} sun4u_fun_t;
76
[b7fd2a0]77static errno_t sun4u_dev_add(ddf_dev_t *dev);
[9191607]78static void sun4u_init(void);
79
80/** The root device driver's standard operations. */
81static driver_ops_t sun4u_ops = {
82 .dev_add = &sun4u_dev_add
83};
84
85/** The root device driver structure. */
86static driver_t sun4u_driver = {
87 .name = NAME,
88 .driver_ops = &sun4u_ops
89};
90
[be1b1e68]91static hw_resource_t obio_res[] = {
92 {
93 .type = MEM_RANGE,
94 .res.mem_range = {
[48adf0f]95 .address = PBM_BASE + PBM_OBIO_BASE,
96 .size = PBM_OBIO_SIZE,
[be1b1e68]97 .relative = false,
98 .endianness = LITTLE_ENDIAN
99 }
100 }
101};
102
103static sun4u_fun_t obio_data = {
104 .hw_resources = {
105 .count = sizeof(obio_res) / sizeof(obio_res[0]),
106 .resources = obio_res
107 },
108 .pio_window = {
109 .mem = {
[48adf0f]110 .base = PBM_BASE + PBM_OBIO_BASE,
111 .size = PBM_OBIO_SIZE
[be1b1e68]112 }
113 }
114};
115
[9191607]116static hw_resource_t pci_conf_regs[] = {
117 {
118 .type = MEM_RANGE,
119 .res.mem_range = {
[54861ca]120 .address = PBM_BASE + PBM_PCI_CONFIG_BASE,
[9191607]121 .size = PBM_PCI_CONFIG_SIZE,
[54861ca]122 .relative = false,
[9191607]123 .endianness = LITTLE_ENDIAN
124 }
125 }
126};
127
128static sun4u_fun_t pci_data = {
129 .hw_resources = {
130 .count = sizeof(pci_conf_regs) / sizeof(pci_conf_regs[0]),
131 .resources = pci_conf_regs
132 },
133 .pio_window = {
134 .mem = {
[54861ca]135 .base = PBM_BASE + PBM_PCI_MEM_BASE,
136 .size = PBM_PCI_MEM_SIZE
[9191607]137 },
138 .io = {
[54861ca]139 .base = PBM_BASE + PBM_PCI_IO_BASE,
140 .size = PBM_PCI_IO_SIZE
[9191607]141 }
142 }
143};
144
145/** Obtain function soft-state from DDF function node */
146static sun4u_fun_t *sun4u_fun(ddf_fun_t *fnode)
147{
148 return ddf_fun_data_get(fnode);
149}
150
151static hw_resource_list_t *sun4u_get_resources(ddf_fun_t *fnode)
152{
153 sun4u_fun_t *fun = sun4u_fun(fnode);
[a35b458]154
[9191607]155 assert(fun != NULL);
156 return &fun->hw_resources;
157}
158
[b7fd2a0]159static errno_t sun4u_enable_interrupt(ddf_fun_t *fun, int irq)
[9191607]160{
161 /* TODO */
[a35b458]162
[9191607]163 return false;
164}
165
166static pio_window_t *sun4u_get_pio_window(ddf_fun_t *fnode)
167{
168 sun4u_fun_t *fun = sun4u_fun(fnode);
169
170 assert(fun != NULL);
171 return &fun->pio_window;
172}
173
174static hw_res_ops_t fun_hw_res_ops = {
175 .get_resource_list = &sun4u_get_resources,
176 .enable_interrupt = &sun4u_enable_interrupt,
177};
178
179static pio_window_ops_t fun_pio_window_ops = {
180 .get_pio_window = &sun4u_get_pio_window
181};
182
183/* Initialized in sun4u_init() function. */
184static ddf_dev_ops_t sun4u_fun_ops;
185
186static bool
187sun4u_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id,
188 sun4u_fun_t *fun_proto)
189{
190 ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name);
[a35b458]191
[9191607]192 ddf_fun_t *fnode = NULL;
[b7fd2a0]193 errno_t rc;
[a35b458]194
[9191607]195 /* Create new device. */
196 fnode = ddf_fun_create(dev, fun_inner, name);
197 if (fnode == NULL)
198 goto failure;
[a35b458]199
[9191607]200 sun4u_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(sun4u_fun_t));
201 *fun = *fun_proto;
[a35b458]202
[9191607]203 /* Add match ID */
204 rc = ddf_fun_add_match_id(fnode, str_match_id, 100);
205 if (rc != EOK)
206 goto failure;
[a35b458]207
[9191607]208 /* Set provided operations to the device. */
209 ddf_fun_set_ops(fnode, &sun4u_fun_ops);
[a35b458]210
[9191607]211 /* Register function. */
212 if (ddf_fun_bind(fnode) != EOK) {
213 ddf_msg(LVL_ERROR, "Failed binding function %s.", name);
214 goto failure;
215 }
[a35b458]216
[9191607]217 return true;
[a35b458]218
[9191607]219failure:
220 if (fnode != NULL)
221 ddf_fun_destroy(fnode);
[a35b458]222
[9191607]223 ddf_msg(LVL_ERROR, "Failed adding function '%s'.", name);
[a35b458]224
[9191607]225 return false;
226}
227
228static bool sun4u_add_functions(ddf_dev_t *dev)
229{
[be1b1e68]230 if (!sun4u_add_fun(dev, "obio", "ebus/obio", &obio_data))
231 return false;
232
[9191607]233 return sun4u_add_fun(dev, "pci0", "intel_pci", &pci_data);
234}
235
236/** Get the root device.
237 *
238 * @param dev The device which is root of the whole device tree (both
239 * of HW and pseudo devices).
[cde999a]240 * @return Zero on success, error number otherwise.
[9191607]241 */
[b7fd2a0]242static errno_t sun4u_dev_add(ddf_dev_t *dev)
[9191607]243{
244 ddf_msg(LVL_DEBUG, "sun4u_dev_add, device handle = %d",
245 (int)ddf_dev_get_handle(dev));
246
247 /* Register functions. */
248 if (!sun4u_add_functions(dev)) {
249 ddf_msg(LVL_ERROR, "Failed to add functions for the Malta platform.");
250 }
[a35b458]251
[9191607]252 return EOK;
253}
254
255static void sun4u_init(void)
256{
257 ddf_log_init(NAME);
258 sun4u_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops;
259 sun4u_fun_ops.interfaces[PIO_WINDOW_DEV_IFACE] = &fun_pio_window_ops;
260}
261
262int main(int argc, char *argv[])
263{
264 printf(NAME ": HelenOS sun4u platform driver\n");
265 sun4u_init();
266 return ddf_driver_main(&sun4u_driver);
267}
268
269/**
270 * @}
271 */
Note: See TracBrowser for help on using the repository browser.