source: mainline/uspace/srv/hw/irc/i8259/i8259.c@ 4c5deac

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4c5deac was b688fd8, checked in by Martin Decky <martin@…>, 10 years ago

gradually introduce async ports, initial phase

The initial phase is to reimplement the traditional async client connections as an untyped fallback port. This creates the possibility to introduce ports typed by interface type gradually in later changesets.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * Copyright (c) 2011 Martin Decky
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/** @addtogroup i8259
30 * @{
31 */
32
33/**
34 * @file i8259.c
35 * @brief i8259 driver.
36 */
37
38#include <ipc/services.h>
39#include <ipc/irc.h>
40#include <ns.h>
41#include <sysinfo.h>
42#include <as.h>
43#include <ddi.h>
44#include <align.h>
45#include <stdbool.h>
46#include <errno.h>
47#include <async.h>
48#include <align.h>
49#include <async.h>
50#include <stdio.h>
51#include <ipc/loc.h>
52
53#define NAME "i8259"
54
55#define IO_RANGE0_START ((ioport8_t *) 0x0020U)
56#define IO_RANGE0_SIZE 2
57
58#define IO_RANGE1_START ((ioport8_t *) 0x00a0U)
59#define IO_RANGE1_SIZE 2
60
61static ioport8_t *io_range0;
62static ioport8_t *io_range1;
63
64#define PIC_PIC0PORT1 0
65#define PIC_PIC0PORT2 1
66
67#define PIC_PIC1PORT1 0
68#define PIC_PIC1PORT2 1
69
70#define PIC_MAX_IRQ 15
71
72static int pic_enable_irq(sysarg_t irq)
73{
74 if (irq > PIC_MAX_IRQ)
75 return ENOENT;
76
77 uint16_t irqmask = 1 << irq;
78 uint8_t val;
79
80 if (irqmask & 0xff) {
81 val = pio_read_8(io_range0 + PIC_PIC0PORT2);
82 pio_write_8(io_range0 + PIC_PIC0PORT2,
83 (uint8_t) (val & (~(irqmask & 0xff))));
84 }
85
86 if (irqmask >> 8) {
87 val = pio_read_8(io_range1 + PIC_PIC1PORT2);
88 pio_write_8(io_range1 + PIC_PIC1PORT2,
89 (uint8_t) (val & (~(irqmask >> 8))));
90 }
91
92 return EOK;
93}
94
95/** Handle one connection to i8259.
96 *
97 * @param iid Hash of the request that opened the connection.
98 * @param icall Call data of the request that opened the connection.
99 * @param arg Local argument.
100 */
101static void i8259_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
102{
103 ipc_callid_t callid;
104 ipc_call_t call;
105
106 /*
107 * Answer the first IPC_M_CONNECT_ME_TO call.
108 */
109 async_answer_0(iid, EOK);
110
111 while (true) {
112 callid = async_get_call(&call);
113
114 if (!IPC_GET_IMETHOD(call)) {
115 /* The other side has hung up. */
116 async_answer_0(callid, EOK);
117 return;
118 }
119
120 switch (IPC_GET_IMETHOD(call)) {
121 case IRC_ENABLE_INTERRUPT:
122 async_answer_0(callid, pic_enable_irq(IPC_GET_ARG1(call)));
123 break;
124 case IRC_CLEAR_INTERRUPT:
125 /* Noop */
126 async_answer_0(callid, EOK);
127 break;
128 default:
129 async_answer_0(callid, EINVAL);
130 break;
131 }
132 }
133}
134
135/** Initialize the i8259 driver.
136 *
137 */
138static bool i8259_init(void)
139{
140 sysarg_t i8259;
141
142 if ((sysinfo_get_value("i8259", &i8259) != EOK) || (!i8259)) {
143 printf("%s: No i8259 found\n", NAME);
144 return false;
145 }
146
147 if ((pio_enable((void *) IO_RANGE0_START, IO_RANGE0_SIZE,
148 (void **) &io_range0) != EOK) ||
149 (pio_enable((void *) IO_RANGE1_START, IO_RANGE1_SIZE,
150 (void **) &io_range1) != EOK)) {
151 printf("%s: i8259 not accessible\n", NAME);
152 return false;
153 }
154
155 async_set_fallback_port_handler(i8259_connection, NULL);
156 service_register(SERVICE_IRC);
157
158 return true;
159}
160
161int main(int argc, char **argv)
162{
163 printf("%s: HelenOS i8259 driver\n", NAME);
164
165 if (!i8259_init())
166 return -1;
167
168 printf("%s: Accepting connections\n", NAME);
169 task_retval(0);
170 async_manager();
171
172 /* Never reached */
173 return 0;
174}
175
176/**
177 * @}
178 */
Note: See TracBrowser for help on using the repository browser.