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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c7fbb90 was 5857be2, checked in by Jan Vesely <jano.vesely@…>, 15 years ago

APIC & i8259 should end connection fibril on hangup

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