source: rtems/bsps/mips/shared/irq/i8259.c @ 6a02c11b

Last change on this file since 6a02c11b was 6a02c11b, checked in by Sebastian Huber <sebastian.huber@…>, on 07/05/20 at 10:52:01

bsps/mips: Fix issues with -fno-common

  • Property mode set to 100644
File size: 8.0 KB
Line 
1/**
2 *  @file
3 * 
4 *  This file was based upon the powerpc and the i386.
5 */
6
7/*
8 *  COPYRIGHT (c) 1989-2012.
9 *  On-Line Applications Research Corporation (OAR).
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.org/license/LICENSE.
14 */
15
16/*
17 *  Copyright (C) 1998, 1999 valette@crf.canon.fr
18 */
19
20#include <bsp.h>
21#include <bsp/irq.h>
22#include <bsp/i8259.h>
23#include <bsp/pci.h>
24#include <bsp/irq-generic.h>
25#include <rtems/bspIo.h>
26
27
28#define DEBUG_8259      1
29
30#define ValidateIrqLine( _irq ) \
31   if ( ((int)_irq < 0) ||((int)_irq > 16)) return 1;
32
33/*-------------------------------------------------------------------------+
34| Cache for 1st and 2nd PIC IRQ line's status (enabled or disabled) register.
35+--------------------------------------------------------------------------*/
36/*
37 * lower byte is interrupt mask on the master PIC.
38 * while upper bits are interrupt on the slave PIC.
39 */
40volatile rtems_i8259_masks i8259s_cache = 0xfffb;
41
42/*-------------------------------------------------------------------------+
43|         Function:  BSP_irq_disable_at_i8259s
44|      Description: Mask IRQ line in appropriate PIC chip.
45| Global Variables: i8259s_cache
46|        Arguments: vector_offset - number of IRQ line to mask.
47|          Returns: original state or -1 on error.
48+--------------------------------------------------------------------------*/
49int BSP_irq_disable_at_i8259s    (const rtems_irq_number irqLine)
50{
51  unsigned short        mask;
52  rtems_interrupt_level level;
53  int                   rval;
54
55  ValidateIrqLine(irqLine);
56
57  rtems_interrupt_disable(level);
58
59  /* Recalculate the value */
60  mask = 1 << irqLine;
61  rval = i8259s_cache & mask ? 0 : 1;
62  i8259s_cache |= mask;
63
64  /* Determine which chip and write the value. */
65  if (irqLine < 8) {
66    simple_out_8(
67      BSP_8259_BASE_ADDRESS,
68      PIC_MASTER_IMR_IO_PORT,
69      i8259s_cache & 0xff
70    );
71  } else {
72    simple_out_8(
73      BSP_8259_BASE_ADDRESS,
74      PIC_SLAVE_IMR_IO_PORT,
75      ((i8259s_cache & 0xff00) >> 8)
76    );
77  }
78
79  rtems_interrupt_enable(level);
80
81  return rval;
82}
83
84/*-------------------------------------------------------------------------+
85|         Function:  BSP_irq_enable_at_i8259s
86|      Description: Unmask IRQ line in appropriate PIC chip.
87| Global Variables: i8259s_cache
88|        Arguments: irqLine - number of IRQ line to mask.
89|          Returns: Nothing.
90+--------------------------------------------------------------------------*/
91int BSP_irq_enable_at_i8259s    (const rtems_irq_number irqLine)
92{
93  unsigned short        mask;
94  rtems_interrupt_level level;
95 
96  ValidateIrqLine( irqLine );
97
98  rtems_interrupt_disable(level);
99
100  /* Calculate the value */
101  mask = ~(1 << irqLine);
102  i8259s_cache &= mask;
103
104  /* Determine which chip and write the value */
105  if (irqLine < 8) {
106    simple_out_8(
107      BSP_8259_BASE_ADDRESS,
108      PIC_MASTER_IMR_IO_PORT,
109      i8259s_cache & 0xff
110    );
111  } else {
112    simple_out_8(
113      BSP_8259_BASE_ADDRESS,
114      PIC_SLAVE_IMR_IO_PORT,
115      ((i8259s_cache & 0xff00) >> 8)
116    );
117  }
118
119  rtems_interrupt_enable(level);
120
121  return 0;
122} /* mask_irq */
123
124
125int BSP_irq_enabled_at_i8259s(const rtems_irq_number irqLine)
126{
127  unsigned short mask;
128
129  ValidateIrqLine( irqLine );
130
131  mask = (1 << irqLine);
132
133  return  (~(i8259s_cache & mask));
134}
135
136/*-------------------------------------------------------------------------+
137|         Function: BSP_irq_ack_at_i8259s
138|      Description: Signal generic End Of Interrupt (EOI) to appropriate PIC.
139| Global Variables: None.
140|        Arguments: irqLine - number of IRQ line to acknowledge.
141|          Returns: Nothing.
142+--------------------------------------------------------------------------*/
143int BSP_irq_ack_at_i8259s (const rtems_irq_number irqLine)
144{
145  if (irqLine >= 8) {
146    simple_out_8(
147      BSP_8259_BASE_ADDRESS,
148      PIC_MASTER_COMMAND_IO_PORT,
149      SLAVE_PIC_EOSI
150    );
151    simple_out_8(
152      BSP_8259_BASE_ADDRESS,
153      PIC_SLAVE_COMMAND_IO_PORT,
154      (PIC_EOSI | (irqLine - 8))
155    );
156  }else {
157    simple_out_8(
158      BSP_8259_BASE_ADDRESS,
159      PIC_MASTER_COMMAND_IO_PORT,
160      (PIC_EOSI | irqLine)
161    );
162  }
163
164  return 0;
165
166} /* ackIRQ */
167
168void BSP_i8259s_init(void)
169{
170  volatile uint32_t i;
171
172  simple_out_8(BSP_8259_BASE_ADDRESS, PIC_MASTER_IMR_IO_PORT, 0xff );
173  simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT,  0xff );
174 
175
176  /*
177   * init master 8259 interrupt controller
178   */
179
180  /* Start init sequence */
181  simple_out_8(
182    BSP_8259_BASE_ADDRESS,
183    PIC_MASTER_COMMAND_IO_PORT,
184    0x11
185  );
186  /* Vector base  = 0 */
187  simple_out_8(
188    BSP_8259_BASE_ADDRESS,
189    PIC_MASTER_IMR_IO_PORT,
190    0x00
191  );
192
193  /* edge tiggered, Cascade (slave) on IRQ2 */
194  simple_out_8(
195    BSP_8259_BASE_ADDRESS,
196    PIC_MASTER_IMR_IO_PORT,
197    0x04
198  );
199
200  /* Select 8086 mode */
201  simple_out_8(
202    BSP_8259_BASE_ADDRESS,
203    PIC_MASTER_IMR_IO_PORT,
204    0x01
205  );
206
207  /*
208   * init slave  interrupt controller
209   */
210
211  /* Start init sequence */
212  simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_COMMAND_IO_PORT, 0x11);
213
214  /* Vector base  = 8 */
215  simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0x08);
216
217  /* edge triggered, Cascade (slave) on IRQ2 */
218  simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0x02);
219
220  /* Select 8086 mode */
221  simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0x01);
222
223  /* Mask all except cascade */
224  simple_out_8(BSP_8259_BASE_ADDRESS, PIC_MASTER_IMR_IO_PORT, 0xFB);
225
226  /* Mask all */
227  simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0xFF);
228
229  /*
230   * Enable all interrupts in debug mode.
231   */
232
233  if ( DEBUG_8259 ) {
234     i8259s_cache = 0x0101;
235  }
236
237  simple_out_8(
238    BSP_8259_BASE_ADDRESS,
239    PIC_MASTER_IMR_IO_PORT,
240    i8259s_cache & 0xff
241  );
242  simple_out_8(
243    BSP_8259_BASE_ADDRESS,
244    PIC_SLAVE_IMR_IO_PORT,
245    ((i8259s_cache & 0xff00) >> 8)
246  );
247
248  for (i=0; i<10000; i++);
249}
250
251#define PCI__GEN(bus, off, num)         (((off)^((bus) << 7))+((num) << 4))
252#define PCI_INTR_ACK(bus)               PCI__GEN(bus, 0x0c34, 0)
253
254static volatile uint8_t  master;
255static volatile uint8_t  slave;
256
257void bsp_show_interrupt_regs(void);
258void bsp_show_interrupt_regs() {
259  unsigned int sr;
260  unsigned int cause;
261  unsigned int pending;
262
263  mips_get_sr( sr );
264  mips_get_cause( cause );
265  pending = (cause & sr & 0xff00) >> CAUSE_IPSHIFT;
266
267  master = simple_in_8(BSP_8259_BASE_ADDRESS, PIC_MASTER_COMMAND_IO_PORT);
268  slave  = simple_in_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_COMMAND_IO_PORT);
269
270  printk("sr: 0x%x cause: 0x%x pending: 0x%x  master: 0x%x slave: 0x%x\n",
271    sr, cause, pending, master, slave
272  );
273}
274
275int BSP_i8259s_int_process()
276{
277  uint8_t           irq;
278  volatile uint32_t temp;
279
280  /* Get the Interrupt */
281  irq = simple_in_le32(BSP_PCI_BASE_ADDRESS, PCI_INTR_ACK(0) );
282
283  /*
284   *  Mask interrupts
285   *   + Mask all except cascade on master
286   *   + Mask all on slave
287   */
288  simple_out_8(BSP_8259_BASE_ADDRESS, PIC_MASTER_IMR_IO_PORT, 0xFB);
289  simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0xFF);
290
291  /* Call the Handler */
292  temp = irq + MALTA_SB_IRQ_0;
293  bsp_interrupt_handler_dispatch( temp );
294
295  /* Reset the interrupt on the 8259 either the master or the slave chip */
296  if (irq & 8) {
297    temp = simple_in_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT);
298
299    /* Mask all */
300    simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0xFF);
301    simple_out_8(
302      BSP_8259_BASE_ADDRESS,
303      PIC_SLAVE_COMMAND_IO_PORT,
304      (PIC_EOSI + (irq&7))
305    );
306    simple_out_8(
307      BSP_8259_BASE_ADDRESS,
308      PIC_MASTER_COMMAND_IO_PORT,
309      SLAVE_PIC_EOSI
310    );
311  } else {
312    temp = simple_in_8(BSP_8259_BASE_ADDRESS, PIC_MASTER_IMR_IO_PORT);
313    /* Mask all except cascade */
314    simple_out_8(BSP_8259_BASE_ADDRESS, PIC_MASTER_IMR_IO_PORT, 0xFB);
315    simple_out_8(
316      BSP_8259_BASE_ADDRESS,
317      PIC_MASTER_COMMAND_IO_PORT,
318      (PIC_EOSI+irq)
319    );
320  }
321
322  /* Restore the interrupts */
323  simple_out_8(BSP_8259_BASE_ADDRESS,PIC_MASTER_IMR_IO_PORT,i8259s_cache&0xff);
324  simple_out_8(
325    BSP_8259_BASE_ADDRESS,
326    PIC_SLAVE_IMR_IO_PORT,
327    ((i8259s_cache & 0xff00) >> 8)
328  );
329
330  return 0;
331}
Note: See TracBrowser for help on using the repository browser.