File indexing completed on 2025-05-11 08:23:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include <sys/cdefs.h>
0028 #ifndef __rtems__
0029 __FBSDID("$FreeBSD$");
0030 #endif
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 #ifndef __rtems__
0051 #include <sys/param.h>
0052 #include <sys/bus.h>
0053 #include <sys/systm.h>
0054 #include <machine/intr_machdep.h>
0055 #endif
0056
0057 #ifdef __rtems__
0058 #include <bsp.h>
0059 #include "i386_io.h"
0060 #include <errno.h>
0061 #include "elcr.h"
0062 #endif
0063
0064 #define ELCR_PORT 0x4d0
0065 #define ELCR_MASK(irq) (1 << (irq))
0066
0067 static int elcr_status;
0068 #ifdef __rtems__
0069 static
0070 #endif
0071 int elcr_found;
0072
0073 #ifdef __rtems__
0074 #undef printf
0075 #define printf printk
0076 #define bootverbose 1
0077 #define KASSERT(...)
0078 #endif
0079
0080
0081
0082
0083
0084 int
0085 elcr_probe(void)
0086 {
0087 int i;
0088
0089 elcr_status = inb(ELCR_PORT) | inb(ELCR_PORT + 1) << 8;
0090 if ((elcr_status & (ELCR_MASK(0) | ELCR_MASK(1) | ELCR_MASK(2) |
0091 ELCR_MASK(8) | ELCR_MASK(13))) != 0)
0092 return (ENXIO);
0093 if (bootverbose) {
0094 printf("ELCR Found. ISA IRQs programmed as:\n");
0095 for (i = 0; i < 16; i++)
0096 printf(" %2d", i);
0097 printf("\n");
0098 for (i = 0; i < 16; i++)
0099 if (elcr_status & ELCR_MASK(i))
0100 printf(" L");
0101 else
0102 printf(" E");
0103 printf("\n");
0104 }
0105 #ifndef __rtems__
0106 if (resource_disabled("elcr", 0))
0107 return (ENXIO);
0108 #endif
0109 elcr_found = 1;
0110 return (0);
0111 }
0112
0113
0114
0115
0116 enum intr_trigger
0117 elcr_read_trigger(u_int irq)
0118 {
0119 #ifdef __rtems__
0120 if (!elcr_found)
0121 return INTR_TRIGGER_EDGE;
0122 #endif
0123 KASSERT(elcr_found, ("%s: no ELCR was found!", __func__));
0124 KASSERT(irq <= 15, ("%s: invalid IRQ %u", __func__, irq));
0125 if (elcr_status & ELCR_MASK(irq))
0126 return (INTR_TRIGGER_LEVEL);
0127 else
0128 return (INTR_TRIGGER_EDGE);
0129 }
0130
0131
0132
0133
0134
0135 void
0136 elcr_write_trigger(u_int irq, enum intr_trigger trigger)
0137 {
0138 int new_status;
0139
0140 #ifdef __rtems__
0141 if (!elcr_found)
0142 return;
0143 #endif
0144 KASSERT(elcr_found, ("%s: no ELCR was found!", __func__));
0145 KASSERT(irq <= 15, ("%s: invalid IRQ %u", __func__, irq));
0146 if (trigger == INTR_TRIGGER_LEVEL)
0147 new_status = elcr_status | ELCR_MASK(irq);
0148 else
0149 new_status = elcr_status & ~ELCR_MASK(irq);
0150 if (new_status == elcr_status)
0151 return;
0152 elcr_status = new_status;
0153 if (irq >= 8)
0154 outb(ELCR_PORT + 1, elcr_status >> 8);
0155 else
0156 outb(ELCR_PORT, elcr_status & 0xff);
0157 }
0158
0159 void
0160 elcr_resume(void)
0161 {
0162 #ifdef __rtems__
0163 if (!elcr_found)
0164 return;
0165 #endif
0166
0167 KASSERT(elcr_found, ("%s: no ELCR was found!", __func__));
0168 outb(ELCR_PORT, elcr_status & 0xff);
0169 outb(ELCR_PORT + 1, elcr_status >> 8);
0170 }