Commit 610626af30fc142e3d420cbce6ac8bdb70377b50
1 parent
d154615d
From 67e94ae77f8de4d5d822917f1723cefa7ebfb64d Mon Sep 17 00:00:00 2001
From: Xiantao Zhang <xiantao.zhang@intel.com> Date: Tue, 3 Mar 2009 13:33:13 +0800 Subject: [PATCH] Split ioapic logic from the current apic. Add a new ioapic.c to hold ioapic's logic, and also make it work for ia64. Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com> --- Makefile.target | 2 +- hw/apic.c | 237 +++---------------------------------------------- hw/ioapic.c | 263 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/pc.h | 5 +- 4 files changed, 281 insertions(+), 226 deletions(-) create mode 100644 hw/ioapic.c git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6827 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
279 additions
and
224 deletions
Makefile.target
... | ... | @@ -586,7 +586,7 @@ ifeq ($(TARGET_BASE_ARCH), i386) |
586 | 586 | # Hardware support |
587 | 587 | OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o |
588 | 588 | OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o |
589 | -OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o | |
589 | +OBJS+= cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o | |
590 | 590 | OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o |
591 | 591 | OBJS += device-hotplug.o pci-hotplug.o |
592 | 592 | CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE | ... | ... |
hw/apic.c
... | ... | @@ -23,7 +23,6 @@ |
23 | 23 | #include "host-utils.h" |
24 | 24 | |
25 | 25 | //#define DEBUG_APIC |
26 | -//#define DEBUG_IOAPIC | |
27 | 26 | |
28 | 27 | /* APIC Local Vector Table */ |
29 | 28 | #define APIC_LVT_TIMER 0 |
... | ... | @@ -57,8 +56,6 @@ |
57 | 56 | #define APIC_INPUT_POLARITY (1<<13) |
58 | 57 | #define APIC_SEND_PENDING (1<<12) |
59 | 58 | |
60 | -#define IOAPIC_NUM_PINS 0x18 | |
61 | - | |
62 | 59 | #define ESR_ILLEGAL_ADDRESS (1 << 7) |
63 | 60 | |
64 | 61 | #define APIC_SV_ENABLE (1 << 8) |
... | ... | @@ -89,14 +86,6 @@ typedef struct APICState { |
89 | 86 | QEMUTimer *timer; |
90 | 87 | } APICState; |
91 | 88 | |
92 | -struct IOAPICState { | |
93 | - uint8_t id; | |
94 | - uint8_t ioregsel; | |
95 | - | |
96 | - uint32_t irr; | |
97 | - uint64_t ioredtbl[IOAPIC_NUM_PINS]; | |
98 | -}; | |
99 | - | |
100 | 89 | static int apic_io_memory; |
101 | 90 | static APICState *local_apics[MAX_APICS + 1]; |
102 | 91 | static int last_apic_id = 0; |
... | ... | @@ -106,6 +95,8 @@ static int apic_irq_delivered; |
106 | 95 | static void apic_init_ipi(APICState *s); |
107 | 96 | static void apic_set_irq(APICState *s, int vector_num, int trigger_mode); |
108 | 97 | static void apic_update_irq(APICState *s); |
98 | +static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask, | |
99 | + uint8_t dest, uint8_t dest_mode); | |
109 | 100 | |
110 | 101 | /* Find first bit starting from msb */ |
111 | 102 | static int fls_bit(uint32_t value) |
... | ... | @@ -272,6 +263,17 @@ static void apic_bus_deliver(const uint32_t *deliver_bitmask, |
272 | 263 | apic_set_irq(apic_iter, vector_num, trigger_mode) ); |
273 | 264 | } |
274 | 265 | |
266 | +void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, | |
267 | + uint8_t delivery_mode, uint8_t vector_num, | |
268 | + uint8_t polarity, uint8_t trigger_mode) | |
269 | +{ | |
270 | + uint32_t deliver_bitmask[MAX_APIC_WORDS]; | |
271 | + | |
272 | + apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode); | |
273 | + apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity, | |
274 | + trigger_mode); | |
275 | +} | |
276 | + | |
275 | 277 | void cpu_set_apic_base(CPUState *env, uint64_t val) |
276 | 278 | { |
277 | 279 | APICState *s = env->apic_state; |
... | ... | @@ -923,214 +925,3 @@ int apic_init(CPUState *env) |
923 | 925 | return 0; |
924 | 926 | } |
925 | 927 | |
926 | -static void ioapic_service(IOAPICState *s) | |
927 | -{ | |
928 | - uint8_t i; | |
929 | - uint8_t trig_mode; | |
930 | - uint8_t vector; | |
931 | - uint8_t delivery_mode; | |
932 | - uint32_t mask; | |
933 | - uint64_t entry; | |
934 | - uint8_t dest; | |
935 | - uint8_t dest_mode; | |
936 | - uint8_t polarity; | |
937 | - uint32_t deliver_bitmask[MAX_APIC_WORDS]; | |
938 | - | |
939 | - for (i = 0; i < IOAPIC_NUM_PINS; i++) { | |
940 | - mask = 1 << i; | |
941 | - if (s->irr & mask) { | |
942 | - entry = s->ioredtbl[i]; | |
943 | - if (!(entry & APIC_LVT_MASKED)) { | |
944 | - trig_mode = ((entry >> 15) & 1); | |
945 | - dest = entry >> 56; | |
946 | - dest_mode = (entry >> 11) & 1; | |
947 | - delivery_mode = (entry >> 8) & 7; | |
948 | - polarity = (entry >> 13) & 1; | |
949 | - if (trig_mode == APIC_TRIGGER_EDGE) | |
950 | - s->irr &= ~mask; | |
951 | - if (delivery_mode == APIC_DM_EXTINT) | |
952 | - vector = pic_read_irq(isa_pic); | |
953 | - else | |
954 | - vector = entry & 0xff; | |
955 | - | |
956 | - apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode); | |
957 | - apic_bus_deliver(deliver_bitmask, delivery_mode, | |
958 | - vector, polarity, trig_mode); | |
959 | - } | |
960 | - } | |
961 | - } | |
962 | -} | |
963 | - | |
964 | -void ioapic_set_irq(void *opaque, int vector, int level) | |
965 | -{ | |
966 | - IOAPICState *s = opaque; | |
967 | - | |
968 | - /* ISA IRQs map to GSI 1-1 except for IRQ0 which maps | |
969 | - * to GSI 2. GSI maps to ioapic 1-1. This is not | |
970 | - * the cleanest way of doing it but it should work. */ | |
971 | - | |
972 | - if (vector == 0) | |
973 | - vector = 2; | |
974 | - | |
975 | - if (vector >= 0 && vector < IOAPIC_NUM_PINS) { | |
976 | - uint32_t mask = 1 << vector; | |
977 | - uint64_t entry = s->ioredtbl[vector]; | |
978 | - | |
979 | - if ((entry >> 15) & 1) { | |
980 | - /* level triggered */ | |
981 | - if (level) { | |
982 | - s->irr |= mask; | |
983 | - ioapic_service(s); | |
984 | - } else { | |
985 | - s->irr &= ~mask; | |
986 | - } | |
987 | - } else { | |
988 | - /* edge triggered */ | |
989 | - if (level) { | |
990 | - s->irr |= mask; | |
991 | - ioapic_service(s); | |
992 | - } | |
993 | - } | |
994 | - } | |
995 | -} | |
996 | - | |
997 | -static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr) | |
998 | -{ | |
999 | - IOAPICState *s = opaque; | |
1000 | - int index; | |
1001 | - uint32_t val = 0; | |
1002 | - | |
1003 | - addr &= 0xff; | |
1004 | - if (addr == 0x00) { | |
1005 | - val = s->ioregsel; | |
1006 | - } else if (addr == 0x10) { | |
1007 | - switch (s->ioregsel) { | |
1008 | - case 0x00: | |
1009 | - val = s->id << 24; | |
1010 | - break; | |
1011 | - case 0x01: | |
1012 | - val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */ | |
1013 | - break; | |
1014 | - case 0x02: | |
1015 | - val = 0; | |
1016 | - break; | |
1017 | - default: | |
1018 | - index = (s->ioregsel - 0x10) >> 1; | |
1019 | - if (index >= 0 && index < IOAPIC_NUM_PINS) { | |
1020 | - if (s->ioregsel & 1) | |
1021 | - val = s->ioredtbl[index] >> 32; | |
1022 | - else | |
1023 | - val = s->ioredtbl[index] & 0xffffffff; | |
1024 | - } | |
1025 | - } | |
1026 | -#ifdef DEBUG_IOAPIC | |
1027 | - printf("I/O APIC read: %08x = %08x\n", s->ioregsel, val); | |
1028 | -#endif | |
1029 | - } | |
1030 | - return val; | |
1031 | -} | |
1032 | - | |
1033 | -static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) | |
1034 | -{ | |
1035 | - IOAPICState *s = opaque; | |
1036 | - int index; | |
1037 | - | |
1038 | - addr &= 0xff; | |
1039 | - if (addr == 0x00) { | |
1040 | - s->ioregsel = val; | |
1041 | - return; | |
1042 | - } else if (addr == 0x10) { | |
1043 | -#ifdef DEBUG_IOAPIC | |
1044 | - printf("I/O APIC write: %08x = %08x\n", s->ioregsel, val); | |
1045 | -#endif | |
1046 | - switch (s->ioregsel) { | |
1047 | - case 0x00: | |
1048 | - s->id = (val >> 24) & 0xff; | |
1049 | - return; | |
1050 | - case 0x01: | |
1051 | - case 0x02: | |
1052 | - return; | |
1053 | - default: | |
1054 | - index = (s->ioregsel - 0x10) >> 1; | |
1055 | - if (index >= 0 && index < IOAPIC_NUM_PINS) { | |
1056 | - if (s->ioregsel & 1) { | |
1057 | - s->ioredtbl[index] &= 0xffffffff; | |
1058 | - s->ioredtbl[index] |= (uint64_t)val << 32; | |
1059 | - } else { | |
1060 | - s->ioredtbl[index] &= ~0xffffffffULL; | |
1061 | - s->ioredtbl[index] |= val; | |
1062 | - } | |
1063 | - ioapic_service(s); | |
1064 | - } | |
1065 | - } | |
1066 | - } | |
1067 | -} | |
1068 | - | |
1069 | -static void ioapic_save(QEMUFile *f, void *opaque) | |
1070 | -{ | |
1071 | - IOAPICState *s = opaque; | |
1072 | - int i; | |
1073 | - | |
1074 | - qemu_put_8s(f, &s->id); | |
1075 | - qemu_put_8s(f, &s->ioregsel); | |
1076 | - for (i = 0; i < IOAPIC_NUM_PINS; i++) { | |
1077 | - qemu_put_be64s(f, &s->ioredtbl[i]); | |
1078 | - } | |
1079 | -} | |
1080 | - | |
1081 | -static int ioapic_load(QEMUFile *f, void *opaque, int version_id) | |
1082 | -{ | |
1083 | - IOAPICState *s = opaque; | |
1084 | - int i; | |
1085 | - | |
1086 | - if (version_id != 1) | |
1087 | - return -EINVAL; | |
1088 | - | |
1089 | - qemu_get_8s(f, &s->id); | |
1090 | - qemu_get_8s(f, &s->ioregsel); | |
1091 | - for (i = 0; i < IOAPIC_NUM_PINS; i++) { | |
1092 | - qemu_get_be64s(f, &s->ioredtbl[i]); | |
1093 | - } | |
1094 | - return 0; | |
1095 | -} | |
1096 | - | |
1097 | -static void ioapic_reset(void *opaque) | |
1098 | -{ | |
1099 | - IOAPICState *s = opaque; | |
1100 | - int i; | |
1101 | - | |
1102 | - memset(s, 0, sizeof(*s)); | |
1103 | - for(i = 0; i < IOAPIC_NUM_PINS; i++) | |
1104 | - s->ioredtbl[i] = 1 << 16; /* mask LVT */ | |
1105 | -} | |
1106 | - | |
1107 | -static CPUReadMemoryFunc *ioapic_mem_read[3] = { | |
1108 | - ioapic_mem_readl, | |
1109 | - ioapic_mem_readl, | |
1110 | - ioapic_mem_readl, | |
1111 | -}; | |
1112 | - | |
1113 | -static CPUWriteMemoryFunc *ioapic_mem_write[3] = { | |
1114 | - ioapic_mem_writel, | |
1115 | - ioapic_mem_writel, | |
1116 | - ioapic_mem_writel, | |
1117 | -}; | |
1118 | - | |
1119 | -IOAPICState *ioapic_init(void) | |
1120 | -{ | |
1121 | - IOAPICState *s; | |
1122 | - int io_memory; | |
1123 | - | |
1124 | - s = qemu_mallocz(sizeof(IOAPICState)); | |
1125 | - ioapic_reset(s); | |
1126 | - s->id = last_apic_id++; | |
1127 | - | |
1128 | - io_memory = cpu_register_io_memory(0, ioapic_mem_read, | |
1129 | - ioapic_mem_write, s); | |
1130 | - cpu_register_physical_memory(0xfec00000, 0x1000, io_memory); | |
1131 | - | |
1132 | - register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s); | |
1133 | - qemu_register_reset(ioapic_reset, s); | |
1134 | - | |
1135 | - return s; | |
1136 | -} | ... | ... |
hw/ioapic.c
0 โ 100644
1 | +/* | |
2 | + * ioapic.c IOAPIC emulation logic | |
3 | + * | |
4 | + * Copyright (c) 2004-2005 Fabrice Bellard | |
5 | + * | |
6 | + * Split the ioapic logic from apic.c | |
7 | + * Xiantao Zhang <xiantao.zhang@intel.com> | |
8 | + * | |
9 | + * This library is free software; you can redistribute it and/or | |
10 | + * modify it under the terms of the GNU Lesser General Public | |
11 | + * License as published by the Free Software Foundation; either | |
12 | + * version 2 of the License, or (at your option) any later version. | |
13 | + * | |
14 | + * This library is distributed in the hope that it will be useful, | |
15 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | + * Lesser General Public License for more details. | |
18 | + * | |
19 | + * You should have received a copy of the GNU Lesser General Public | |
20 | + * License along with this library; if not, write to the Free Software | |
21 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA | |
22 | + */ | |
23 | + | |
24 | +#include "hw.h" | |
25 | +#include "pc.h" | |
26 | +#include "qemu-timer.h" | |
27 | +#include "host-utils.h" | |
28 | + | |
29 | +//#define DEBUG_IOAPIC | |
30 | + | |
31 | +#define IOAPIC_NUM_PINS 0x18 | |
32 | +#define IOAPIC_LVT_MASKED (1<<16) | |
33 | + | |
34 | +#define IOAPIC_TRIGGER_EDGE 0 | |
35 | +#define IOAPIC_TRIGGER_LEVEL 1 | |
36 | + | |
37 | +/*io{apic,sapic} delivery mode*/ | |
38 | +#define IOAPIC_DM_FIXED 0x0 | |
39 | +#define IOAPIC_DM_LOWEST_PRIORITY 0x1 | |
40 | +#define IOAPIC_DM_PMI 0x2 | |
41 | +#define IOAPIC_DM_NMI 0x4 | |
42 | +#define IOAPIC_DM_INIT 0x5 | |
43 | +#define IOAPIC_DM_SIPI 0x5 | |
44 | +#define IOAPIC_DM_EXTINT 0x7 | |
45 | + | |
46 | +struct IOAPICState { | |
47 | + uint8_t id; | |
48 | + uint8_t ioregsel; | |
49 | + | |
50 | + uint32_t irr; | |
51 | + uint64_t ioredtbl[IOAPIC_NUM_PINS]; | |
52 | +}; | |
53 | + | |
54 | +static void ioapic_service(IOAPICState *s) | |
55 | +{ | |
56 | + uint8_t i; | |
57 | + uint8_t trig_mode; | |
58 | + uint8_t vector; | |
59 | + uint8_t delivery_mode; | |
60 | + uint32_t mask; | |
61 | + uint64_t entry; | |
62 | + uint8_t dest; | |
63 | + uint8_t dest_mode; | |
64 | + uint8_t polarity; | |
65 | + | |
66 | + for (i = 0; i < IOAPIC_NUM_PINS; i++) { | |
67 | + mask = 1 << i; | |
68 | + if (s->irr & mask) { | |
69 | + entry = s->ioredtbl[i]; | |
70 | + if (!(entry & IOAPIC_LVT_MASKED)) { | |
71 | + trig_mode = ((entry >> 15) & 1); | |
72 | + dest = entry >> 56; | |
73 | + dest_mode = (entry >> 11) & 1; | |
74 | + delivery_mode = (entry >> 8) & 7; | |
75 | + polarity = (entry >> 13) & 1; | |
76 | + if (trig_mode == IOAPIC_TRIGGER_EDGE) | |
77 | + s->irr &= ~mask; | |
78 | + if (delivery_mode == IOAPIC_DM_EXTINT) | |
79 | + vector = pic_read_irq(isa_pic); | |
80 | + else | |
81 | + vector = entry & 0xff; | |
82 | + | |
83 | + apic_deliver_irq(dest, dest_mode, delivery_mode, | |
84 | + vector, polarity, trig_mode); | |
85 | + } | |
86 | + } | |
87 | + } | |
88 | +} | |
89 | + | |
90 | +void ioapic_set_irq(void *opaque, int vector, int level) | |
91 | +{ | |
92 | + IOAPICState *s = opaque; | |
93 | + | |
94 | + /* ISA IRQs map to GSI 1-1 except for IRQ0 which maps | |
95 | + * to GSI 2. GSI maps to ioapic 1-1. This is not | |
96 | + * the cleanest way of doing it but it should work. */ | |
97 | + | |
98 | + if (vector == 0) | |
99 | + vector = 2; | |
100 | + | |
101 | + if (vector >= 0 && vector < IOAPIC_NUM_PINS) { | |
102 | + uint32_t mask = 1 << vector; | |
103 | + uint64_t entry = s->ioredtbl[vector]; | |
104 | + | |
105 | + if ((entry >> 15) & 1) { | |
106 | + /* level triggered */ | |
107 | + if (level) { | |
108 | + s->irr |= mask; | |
109 | + ioapic_service(s); | |
110 | + } else { | |
111 | + s->irr &= ~mask; | |
112 | + } | |
113 | + } else { | |
114 | + /* edge triggered */ | |
115 | + if (level) { | |
116 | + s->irr |= mask; | |
117 | + ioapic_service(s); | |
118 | + } | |
119 | + } | |
120 | + } | |
121 | +} | |
122 | + | |
123 | +static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr) | |
124 | +{ | |
125 | + IOAPICState *s = opaque; | |
126 | + int index; | |
127 | + uint32_t val = 0; | |
128 | + | |
129 | + addr &= 0xff; | |
130 | + if (addr == 0x00) { | |
131 | + val = s->ioregsel; | |
132 | + } else if (addr == 0x10) { | |
133 | + switch (s->ioregsel) { | |
134 | + case 0x00: | |
135 | + val = s->id << 24; | |
136 | + break; | |
137 | + case 0x01: | |
138 | + val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */ | |
139 | + break; | |
140 | + case 0x02: | |
141 | + val = 0; | |
142 | + break; | |
143 | + default: | |
144 | + index = (s->ioregsel - 0x10) >> 1; | |
145 | + if (index >= 0 && index < IOAPIC_NUM_PINS) { | |
146 | + if (s->ioregsel & 1) | |
147 | + val = s->ioredtbl[index] >> 32; | |
148 | + else | |
149 | + val = s->ioredtbl[index] & 0xffffffff; | |
150 | + } | |
151 | + } | |
152 | +#ifdef DEBUG_IOAPIC | |
153 | + printf("I/O APIC read: %08x = %08x\n", s->ioregsel, val); | |
154 | +#endif | |
155 | + } | |
156 | + return val; | |
157 | +} | |
158 | + | |
159 | +static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) | |
160 | +{ | |
161 | + IOAPICState *s = opaque; | |
162 | + int index; | |
163 | + | |
164 | + addr &= 0xff; | |
165 | + if (addr == 0x00) { | |
166 | + s->ioregsel = val; | |
167 | + return; | |
168 | + } else if (addr == 0x10) { | |
169 | +#ifdef DEBUG_IOAPIC | |
170 | + printf("I/O APIC write: %08x = %08x\n", s->ioregsel, val); | |
171 | +#endif | |
172 | + switch (s->ioregsel) { | |
173 | + case 0x00: | |
174 | + s->id = (val >> 24) & 0xff; | |
175 | + return; | |
176 | + case 0x01: | |
177 | + case 0x02: | |
178 | + return; | |
179 | + default: | |
180 | + index = (s->ioregsel - 0x10) >> 1; | |
181 | + if (index >= 0 && index < IOAPIC_NUM_PINS) { | |
182 | + if (s->ioregsel & 1) { | |
183 | + s->ioredtbl[index] &= 0xffffffff; | |
184 | + s->ioredtbl[index] |= (uint64_t)val << 32; | |
185 | + } else { | |
186 | + s->ioredtbl[index] &= ~0xffffffffULL; | |
187 | + s->ioredtbl[index] |= val; | |
188 | + } | |
189 | + ioapic_service(s); | |
190 | + } | |
191 | + } | |
192 | + } | |
193 | +} | |
194 | + | |
195 | +static void ioapic_save(QEMUFile *f, void *opaque) | |
196 | +{ | |
197 | + IOAPICState *s = opaque; | |
198 | + int i; | |
199 | + | |
200 | + qemu_put_8s(f, &s->id); | |
201 | + qemu_put_8s(f, &s->ioregsel); | |
202 | + for (i = 0; i < IOAPIC_NUM_PINS; i++) { | |
203 | + qemu_put_be64s(f, &s->ioredtbl[i]); | |
204 | + } | |
205 | +} | |
206 | + | |
207 | +static int ioapic_load(QEMUFile *f, void *opaque, int version_id) | |
208 | +{ | |
209 | + IOAPICState *s = opaque; | |
210 | + int i; | |
211 | + | |
212 | + if (version_id != 1) | |
213 | + return -EINVAL; | |
214 | + | |
215 | + qemu_get_8s(f, &s->id); | |
216 | + qemu_get_8s(f, &s->ioregsel); | |
217 | + for (i = 0; i < IOAPIC_NUM_PINS; i++) { | |
218 | + qemu_get_be64s(f, &s->ioredtbl[i]); | |
219 | + } | |
220 | + return 0; | |
221 | +} | |
222 | + | |
223 | +static void ioapic_reset(void *opaque) | |
224 | +{ | |
225 | + IOAPICState *s = opaque; | |
226 | + int i; | |
227 | + | |
228 | + memset(s, 0, sizeof(*s)); | |
229 | + for(i = 0; i < IOAPIC_NUM_PINS; i++) | |
230 | + s->ioredtbl[i] = 1 << 16; /* mask LVT */ | |
231 | +} | |
232 | + | |
233 | +static CPUReadMemoryFunc *ioapic_mem_read[3] = { | |
234 | + ioapic_mem_readl, | |
235 | + ioapic_mem_readl, | |
236 | + ioapic_mem_readl, | |
237 | +}; | |
238 | + | |
239 | +static CPUWriteMemoryFunc *ioapic_mem_write[3] = { | |
240 | + ioapic_mem_writel, | |
241 | + ioapic_mem_writel, | |
242 | + ioapic_mem_writel, | |
243 | +}; | |
244 | + | |
245 | +IOAPICState *ioapic_init(void) | |
246 | +{ | |
247 | + IOAPICState *s; | |
248 | + int io_memory; | |
249 | + | |
250 | + s = qemu_mallocz(sizeof(IOAPICState)); | |
251 | + ioapic_reset(s); | |
252 | + | |
253 | + io_memory = cpu_register_io_memory(0, ioapic_mem_read, | |
254 | + ioapic_mem_write, s); | |
255 | + cpu_register_physical_memory(0xfec00000, 0x1000, io_memory); | |
256 | + | |
257 | + register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s); | |
258 | + qemu_register_reset(ioapic_reset, s); | |
259 | + | |
260 | + return s; | |
261 | +} | ... | ... |
hw/pc.h
... | ... | @@ -42,7 +42,10 @@ void irq_info(Monitor *mon); |
42 | 42 | |
43 | 43 | /* APIC */ |
44 | 44 | typedef struct IOAPICState IOAPICState; |
45 | - | |
45 | +void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, | |
46 | + uint8_t delivery_mode, | |
47 | + uint8_t vector_num, uint8_t polarity, | |
48 | + uint8_t trigger_mode); | |
46 | 49 | int apic_init(CPUState *env); |
47 | 50 | int apic_accept_pic_intr(CPUState *env); |
48 | 51 | void apic_deliver_pic_intr(CPUState *env, int level); | ... | ... |