Subversion Repositories HelenOS

Rev

Rev 4344 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4344 Rev 4346
1
/*
1
/*
2
 * Copyright (c) 2009 Jakub Jermar
2
 * Copyright (c) 2009 Jakub Jermar
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
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
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.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
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
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
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.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup obio
29
/** @addtogroup obio
30
 * @{
30
 * @{
31
 */
31
 */
32
 
32
 
33
/**
33
/**
34
 * @file    obio.c
34
 * @file    obio.c
35
 * @brief   OBIO driver.
35
 * @brief   OBIO driver.
36
 *
36
 *
37
 * OBIO is a short for on-board I/O. On UltraSPARC IIi and systems with U2P,
37
 * OBIO is a short for on-board I/O. On UltraSPARC IIi and systems with U2P,
38
 * there is a piece of the root PCI bus controller address space, which
38
 * there is a piece of the root PCI bus controller address space, which
39
 * contains interrupt mapping and clear registers for all on-board devices.
39
 * contains interrupt mapping and clear registers for all on-board devices.
40
 * Although UltraSPARC IIi and U2P are different in general, these registers can
40
 * Although UltraSPARC IIi and U2P are different in general, these registers can
41
 * be found at the same addresses.
41
 * be found at the same addresses.
42
 */
42
 */
43
 
43
 
44
#include <ipc/ipc.h>
44
#include <ipc/ipc.h>
45
#include <ipc/services.h>
45
#include <ipc/services.h>
46
#include <ipc/bus.h>
46
#include <ipc/bus.h>
47
#include <ipc/ns.h>
47
#include <ipc/ns.h>
48
#include <sysinfo.h>
48
#include <sysinfo.h>
49
#include <as.h>
49
#include <as.h>
50
#include <ddi.h>
50
#include <ddi.h>
51
#include <align.h>
51
#include <align.h>
52
#include <bool.h>
52
#include <bool.h>
53
#include <errno.h>
53
#include <errno.h>
54
#include <async.h>
54
#include <async.h>
55
#include <align.h>
55
#include <align.h>
56
#include <async.h>
56
#include <async.h>
57
#include <stdio.h>
57
#include <stdio.h>
58
#include <ipc/devmap.h>
58
#include <ipc/devmap.h>
59
 
59
 
60
#define NAME "obio"
60
#define NAME "obio"
61
 
61
 
62
#define OBIO_SIZE   0x1898  
62
#define OBIO_SIZE   0x1898  
63
 
63
 
64
#define OBIO_IMR_BASE   0x200
64
#define OBIO_IMR_BASE   0x200
65
#define OBIO_IMR(ino)   (OBIO_IMR_BASE + ((ino) & INO_MASK))
65
#define OBIO_IMR(ino)   (OBIO_IMR_BASE + ((ino) & INO_MASK))
66
 
66
 
67
#define OBIO_CIR_BASE   0x300
67
#define OBIO_CIR_BASE   0x300
68
#define OBIO_CIR(ino)   (OBIO_CIR_BASE + ((ino) & INO_MASK))
68
#define OBIO_CIR(ino)   (OBIO_CIR_BASE + ((ino) & INO_MASK))
69
 
69
 
70
#define INO_MASK    0x1f
70
#define INO_MASK    0x1f
71
 
71
 
72
static void *base_phys;
72
static void *base_phys;
73
static volatile uint64_t *base_virt;
73
static volatile uint64_t *base_virt;
74
 
74
 
75
/** Handle one connection to obio.
75
/** Handle one connection to obio.
76
 *
76
 *
77
 * @param iid       Hash of the request that opened the connection.
77
 * @param iid       Hash of the request that opened the connection.
78
 * @param icall     Call data of the request that opened the connection.
78
 * @param icall     Call data of the request that opened the connection.
79
 */
79
 */
80
static void obio_connection(ipc_callid_t iid, ipc_call_t *icall)
80
static void obio_connection(ipc_callid_t iid, ipc_call_t *icall)
81
{
81
{
82
    ipc_callid_t callid;
82
    ipc_callid_t callid;
83
    ipc_call_t call;
83
    ipc_call_t call;
84
 
84
 
85
    /*
85
    /*
86
     * Answer the first IPC_M_CONNECT_ME_TO call.
86
     * Answer the first IPC_M_CONNECT_ME_TO call.
87
     */
87
     */
88
    ipc_answer_0(iid, EOK);
88
    ipc_answer_0(iid, EOK);
89
 
89
 
90
    while (1) {
90
    while (1) {
91
        int inr;
91
        int inr;
92
   
92
   
93
        callid = async_get_call(&call);
93
        callid = async_get_call(&call);
94
        switch (IPC_GET_METHOD(call)) {
94
        switch (IPC_GET_METHOD(call)) {
95
        case BUS_CLEAR_INTERRUPT:
95
        case BUS_CLEAR_INTERRUPT:
96
            inr = IPC_GET_ARG1(call);
96
            inr = IPC_GET_ARG1(call);
97
            base_virt[OBIO_CIR(inr) & INO_MASK] = 0;
97
            base_virt[OBIO_CIR(inr & INO_MASK)] = 0;
98
            ipc_answer_0(callid, EOK);
98
            ipc_answer_0(callid, EOK);
99
            break;
99
            break;
100
        default:
100
        default:
101
            ipc_answer_0(callid, EINVAL);
101
            ipc_answer_0(callid, EINVAL);
102
            break;
102
            break;
103
        }
103
        }
104
    }
104
    }
105
}
105
}
106
 
106
 
107
/** Initialize the OBIO driver.
107
/** Initialize the OBIO driver.
108
 *
108
 *
109
 * So far, the driver heavily depends on information provided by the kernel via
109
 * So far, the driver heavily depends on information provided by the kernel via
110
 * sysinfo. In the future, there should be a standalone OBIO driver.
110
 * sysinfo. In the future, there should be a standalone OBIO driver.
111
 */
111
 */
112
static bool obio_init(void)
112
static bool obio_init(void)
113
{
113
{
114
    ipcarg_t phonead;
114
    ipcarg_t phonead;
115
 
115
 
116
    base_phys = (void *) sysinfo_value("obio.base.physical");
116
    base_phys = (void *) sysinfo_value("obio.base.physical");
117
   
117
   
118
    if (!base_phys) {
118
    if (!base_phys) {
119
        printf(NAME ": no OBIO registers found\n");
119
        printf(NAME ": no OBIO registers found\n");
120
        return false;
120
        return false;
121
    }
121
    }
122
 
122
 
123
    base_virt = as_get_mappable_page(OBIO_SIZE);
123
    base_virt = as_get_mappable_page(OBIO_SIZE);
124
   
124
   
125
    int flags = AS_AREA_READ | AS_AREA_WRITE;
125
    int flags = AS_AREA_READ | AS_AREA_WRITE;
126
    int retval = physmem_map(base_phys, (void *) base_virt,
126
    int retval = physmem_map(base_phys, (void *) base_virt,
127
        ALIGN_UP(OBIO_SIZE, PAGE_SIZE) >> PAGE_WIDTH, flags);
127
        ALIGN_UP(OBIO_SIZE, PAGE_SIZE) >> PAGE_WIDTH, flags);
128
   
128
   
129
    if (retval < 0) {
129
    if (retval < 0) {
130
        printf(NAME ": Error mapping OBIO registers\n");
130
        printf(NAME ": Error mapping OBIO registers\n");
131
        return false;
131
        return false;
132
    }
132
    }
133
   
133
   
134
    printf(NAME ": OBIO registers with base at %p\n", base_phys);
134
    printf(NAME ": OBIO registers with base at %p\n", base_phys);
135
 
135
 
136
    async_set_client_connection(obio_connection);
136
    async_set_client_connection(obio_connection);
137
    ipc_connect_to_me(PHONE_NS, SERVICE_OBIO, 0, 0, &phonead);
137
    ipc_connect_to_me(PHONE_NS, SERVICE_OBIO, 0, 0, &phonead);
138
   
138
   
139
    return true;
139
    return true;
140
}
140
}
141
 
141
 
142
int main(int argc, char **argv)
142
int main(int argc, char **argv)
143
{
143
{
144
    printf(NAME ": HelenOS OBIO driver\n");
144
    printf(NAME ": HelenOS OBIO driver\n");
145
   
145
   
146
    if (!obio_init())
146
    if (!obio_init())
147
        return -1;
147
        return -1;
148
   
148
   
149
    printf(NAME ": Accepting connections\n");
149
    printf(NAME ": Accepting connections\n");
150
    async_manager();
150
    async_manager();
151
 
151
 
152
    /* Never reached */
152
    /* Never reached */
153
    return 0;
153
    return 0;
154
}
154
}
155
 
155
 
156
/**
156
/**
157
 * @}
157
 * @}
158
 */
158
 */
159
 
159