source: mainline/uspace/srv/hw/irc/i8259/i8259.c@ 7ea7db31

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

uspace interrupt controller drivers for i8259 and APIC (non-functional yet)
convert NE2000 driver to use these drivers (not enabling the IRQ in kernel), this solves the "spurious interrupt" issue
(however, on SMP machines this renders the driver unusable for now since the APIC driver does not do anything yet)

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