1 /*
2  * Written by: Garry Forsgren, Unisys Corporation
3  *             Natalie Protasevich, Unisys Corporation
4  *
5  * This file contains the code to configure and interface
6  * with Unisys ES7000 series hardware system manager.
7  *
8  * Copyright (c) 2003 Unisys Corporation.
9  * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
10  *
11  *   All Rights Reserved.
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of version 2 of the GNU General Public License as
15  * published by the Free Software Foundation.
16  *
17  * This program is distributed in the hope that it would be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write the Free Software Foundation, Inc., 59
23  * Temple Place - Suite 330, Boston MA 02111-1307, USA.
24  *
25  * Contact information: Unisys Corporation, Township Line & Union Meeting
26  * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
27  *
28  * http://www.unisys.com
29  */
30 
31 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
32 
33 #include <linux/notifier.h>
34 #include <linux/spinlock.h>
35 #include <linux/cpumask.h>
36 #include <linux/threads.h>
37 #include <linux/kernel.h>
38 #include <linux/module.h>
39 #include <linux/reboot.h>
40 #include <linux/string.h>
41 #include <linux/types.h>
42 #include <linux/errno.h>
43 #include <linux/acpi.h>
44 #include <linux/init.h>
45 #include <linux/gfp.h>
46 #include <linux/nmi.h>
47 #include <linux/smp.h>
48 #include <linux/io.h>
49 
50 #include <asm/apicdef.h>
51 #include <linux/atomic.h>
52 #include <asm/fixmap.h>
53 #include <asm/mpspec.h>
54 #include <asm/setup.h>
55 #include <asm/apic.h>
56 #include <asm/ipi.h>
57 
58 /*
59  * ES7000 chipsets
60  */
61 
62 #define NON_UNISYS			0
63 #define ES7000_CLASSIC			1
64 #define ES7000_ZORRO			2
65 
66 #define	MIP_REG				1
67 #define	MIP_PSAI_REG			4
68 
69 #define	MIP_BUSY			1
70 #define	MIP_SPIN			0xf0000
71 #define	MIP_VALID			0x0100000000000000ULL
72 #define	MIP_SW_APIC			0x1020b
73 
74 #define	MIP_PORT(val)			((val >> 32) & 0xffff)
75 
76 #define	MIP_RD_LO(val)			(val & 0xffffffff)
77 
78 struct mip_reg {
79 	unsigned long long		off_0x00;
80 	unsigned long long		off_0x08;
81 	unsigned long long		off_0x10;
82 	unsigned long long		off_0x18;
83 	unsigned long long		off_0x20;
84 	unsigned long long		off_0x28;
85 	unsigned long long		off_0x30;
86 	unsigned long long		off_0x38;
87 };
88 
89 struct mip_reg_info {
90 	unsigned long long		mip_info;
91 	unsigned long long		delivery_info;
92 	unsigned long long		host_reg;
93 	unsigned long long		mip_reg;
94 };
95 
96 struct psai {
97 	unsigned long long		entry_type;
98 	unsigned long long		addr;
99 	unsigned long long		bep_addr;
100 };
101 
102 #ifdef CONFIG_ACPI
103 
104 struct es7000_oem_table {
105 	struct acpi_table_header	Header;
106 	u32				OEMTableAddr;
107 	u32				OEMTableSize;
108 };
109 
110 static unsigned long			oem_addrX;
111 static unsigned long			oem_size;
112 
113 #endif
114 
115 /*
116  * ES7000 Globals
117  */
118 
119 static volatile unsigned long		*psai;
120 static struct mip_reg			*mip_reg;
121 static struct mip_reg			*host_reg;
122 static int 				mip_port;
123 static unsigned long			mip_addr;
124 static unsigned long			host_addr;
125 
126 int					es7000_plat;
127 
128 /*
129  * GSI override for ES7000 platforms.
130  */
131 
132 
wakeup_secondary_cpu_via_mip(int cpu,unsigned long eip)133 static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
134 {
135 	unsigned long vect = 0, psaival = 0;
136 
137 	if (psai == NULL)
138 		return -1;
139 
140 	vect = ((unsigned long)__pa(eip)/0x1000) << 16;
141 	psaival = (0x1000000 | vect | cpu);
142 
143 	while (*psai & 0x1000000)
144 		;
145 
146 	*psai = psaival;
147 
148 	return 0;
149 }
150 
es7000_apic_is_cluster(void)151 static int es7000_apic_is_cluster(void)
152 {
153 	/* MPENTIUMIII */
154 	if (boot_cpu_data.x86 == 6 &&
155 	    (boot_cpu_data.x86_model >= 7 && boot_cpu_data.x86_model <= 11))
156 		return 1;
157 
158 	return 0;
159 }
160 
setup_unisys(void)161 static void setup_unisys(void)
162 {
163 	/*
164 	 * Determine the generation of the ES7000 currently running.
165 	 *
166 	 * es7000_plat = 1 if the machine is a 5xx ES7000 box
167 	 * es7000_plat = 2 if the machine is a x86_64 ES7000 box
168 	 *
169 	 */
170 	if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
171 		es7000_plat = ES7000_ZORRO;
172 	else
173 		es7000_plat = ES7000_CLASSIC;
174 }
175 
176 /*
177  * Parse the OEM Table:
178  */
parse_unisys_oem(char * oemptr)179 static int parse_unisys_oem(char *oemptr)
180 {
181 	int			i;
182 	int 			success = 0;
183 	unsigned char		type, size;
184 	unsigned long		val;
185 	char			*tp = NULL;
186 	struct psai		*psaip = NULL;
187 	struct mip_reg_info 	*mi;
188 	struct mip_reg		*host, *mip;
189 
190 	tp = oemptr;
191 
192 	tp += 8;
193 
194 	for (i = 0; i <= 6; i++) {
195 		type = *tp++;
196 		size = *tp++;
197 		tp -= 2;
198 		switch (type) {
199 		case MIP_REG:
200 			mi = (struct mip_reg_info *)tp;
201 			val = MIP_RD_LO(mi->host_reg);
202 			host_addr = val;
203 			host = (struct mip_reg *)val;
204 			host_reg = __va(host);
205 			val = MIP_RD_LO(mi->mip_reg);
206 			mip_port = MIP_PORT(mi->mip_info);
207 			mip_addr = val;
208 			mip = (struct mip_reg *)val;
209 			mip_reg = __va(mip);
210 			pr_debug("host_reg = 0x%lx\n",
211 				 (unsigned long)host_reg);
212 			pr_debug("mip_reg = 0x%lx\n",
213 				 (unsigned long)mip_reg);
214 			success++;
215 			break;
216 		case MIP_PSAI_REG:
217 			psaip = (struct psai *)tp;
218 			if (tp != NULL) {
219 				if (psaip->addr)
220 					psai = __va(psaip->addr);
221 				else
222 					psai = NULL;
223 				success++;
224 			}
225 			break;
226 		default:
227 			break;
228 		}
229 		tp += size;
230 	}
231 
232 	if (success < 2)
233 		es7000_plat = NON_UNISYS;
234 	else
235 		setup_unisys();
236 
237 	return es7000_plat;
238 }
239 
240 #ifdef CONFIG_ACPI
find_unisys_acpi_oem_table(unsigned long * oem_addr)241 static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
242 {
243 	struct acpi_table_header *header = NULL;
244 	struct es7000_oem_table *table;
245 	acpi_size tbl_size;
246 	acpi_status ret;
247 	int i = 0;
248 
249 	for (;;) {
250 		ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size);
251 		if (!ACPI_SUCCESS(ret))
252 			return -1;
253 
254 		if (!memcmp((char *) &header->oem_id, "UNISYS", 6))
255 			break;
256 
257 		early_acpi_os_unmap_memory(header, tbl_size);
258 	}
259 
260 	table = (void *)header;
261 
262 	oem_addrX	= table->OEMTableAddr;
263 	oem_size	= table->OEMTableSize;
264 
265 	early_acpi_os_unmap_memory(header, tbl_size);
266 
267 	*oem_addr	= (unsigned long)__acpi_map_table(oem_addrX, oem_size);
268 
269 	return 0;
270 }
271 
unmap_unisys_acpi_oem_table(unsigned long oem_addr)272 static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
273 {
274 	if (!oem_addr)
275 		return;
276 
277 	__acpi_unmap_table((char *)oem_addr, oem_size);
278 }
279 
es7000_check_dsdt(void)280 static int es7000_check_dsdt(void)
281 {
282 	struct acpi_table_header header;
283 
284 	if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) &&
285 	    !strncmp(header.oem_id, "UNISYS", 6))
286 		return 1;
287 	return 0;
288 }
289 
290 static int es7000_acpi_ret;
291 
292 /* Hook from generic ACPI tables.c */
es7000_acpi_madt_oem_check(char * oem_id,char * oem_table_id)293 static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
294 {
295 	unsigned long oem_addr = 0;
296 	int check_dsdt;
297 	int ret = 0;
298 
299 	/* check dsdt at first to avoid clear fix_map for oem_addr */
300 	check_dsdt = es7000_check_dsdt();
301 
302 	if (!find_unisys_acpi_oem_table(&oem_addr)) {
303 		if (check_dsdt) {
304 			ret = parse_unisys_oem((char *)oem_addr);
305 		} else {
306 			setup_unisys();
307 			ret = 1;
308 		}
309 		/*
310 		 * we need to unmap it
311 		 */
312 		unmap_unisys_acpi_oem_table(oem_addr);
313 	}
314 
315 	es7000_acpi_ret = ret;
316 
317 	return ret && !es7000_apic_is_cluster();
318 }
319 
es7000_acpi_madt_oem_check_cluster(char * oem_id,char * oem_table_id)320 static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
321 {
322 	int ret = es7000_acpi_ret;
323 
324 	return ret && es7000_apic_is_cluster();
325 }
326 
327 #else /* !CONFIG_ACPI: */
es7000_acpi_madt_oem_check(char * oem_id,char * oem_table_id)328 static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
329 {
330 	return 0;
331 }
332 
es7000_acpi_madt_oem_check_cluster(char * oem_id,char * oem_table_id)333 static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
334 {
335 	return 0;
336 }
337 #endif /* !CONFIG_ACPI */
338 
es7000_spin(int n)339 static void es7000_spin(int n)
340 {
341 	int i = 0;
342 
343 	while (i++ < n)
344 		rep_nop();
345 }
346 
es7000_mip_write(struct mip_reg * mip_reg)347 static int es7000_mip_write(struct mip_reg *mip_reg)
348 {
349 	int status = 0;
350 	int spin;
351 
352 	spin = MIP_SPIN;
353 	while ((host_reg->off_0x38 & MIP_VALID) != 0) {
354 		if (--spin <= 0) {
355 			WARN(1,	"Timeout waiting for Host Valid Flag\n");
356 			return -1;
357 		}
358 		es7000_spin(MIP_SPIN);
359 	}
360 
361 	memcpy(host_reg, mip_reg, sizeof(struct mip_reg));
362 	outb(1, mip_port);
363 
364 	spin = MIP_SPIN;
365 
366 	while ((mip_reg->off_0x38 & MIP_VALID) == 0) {
367 		if (--spin <= 0) {
368 			WARN(1,	"Timeout waiting for MIP Valid Flag\n");
369 			return -1;
370 		}
371 		es7000_spin(MIP_SPIN);
372 	}
373 
374 	status = (mip_reg->off_0x00 & 0xffff0000000000ULL) >> 48;
375 	mip_reg->off_0x38 &= ~MIP_VALID;
376 
377 	return status;
378 }
379 
es7000_enable_apic_mode(void)380 static void es7000_enable_apic_mode(void)
381 {
382 	struct mip_reg es7000_mip_reg;
383 	int mip_status;
384 
385 	if (!es7000_plat)
386 		return;
387 
388 	pr_info("Enabling APIC mode.\n");
389 	memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
390 	es7000_mip_reg.off_0x00 = MIP_SW_APIC;
391 	es7000_mip_reg.off_0x38 = MIP_VALID;
392 
393 	while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0)
394 		WARN(1, "Command failed, status = %x\n", mip_status);
395 }
396 
es7000_vector_allocation_domain(int cpu,struct cpumask * retmask)397 static void es7000_vector_allocation_domain(int cpu, struct cpumask *retmask)
398 {
399 	/* Careful. Some cpus do not strictly honor the set of cpus
400 	 * specified in the interrupt destination when using lowest
401 	 * priority interrupt delivery mode.
402 	 *
403 	 * In particular there was a hyperthreading cpu observed to
404 	 * deliver interrupts to the wrong hyperthread when only one
405 	 * hyperthread was specified in the interrupt desitination.
406 	 */
407 	cpumask_clear(retmask);
408 	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
409 }
410 
411 
es7000_wait_for_init_deassert(atomic_t * deassert)412 static void es7000_wait_for_init_deassert(atomic_t *deassert)
413 {
414 	while (!atomic_read(deassert))
415 		cpu_relax();
416 }
417 
es7000_get_apic_id(unsigned long x)418 static unsigned int es7000_get_apic_id(unsigned long x)
419 {
420 	return (x >> 24) & 0xFF;
421 }
422 
es7000_send_IPI_mask(const struct cpumask * mask,int vector)423 static void es7000_send_IPI_mask(const struct cpumask *mask, int vector)
424 {
425 	default_send_IPI_mask_sequence_phys(mask, vector);
426 }
427 
es7000_send_IPI_allbutself(int vector)428 static void es7000_send_IPI_allbutself(int vector)
429 {
430 	default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
431 }
432 
es7000_send_IPI_all(int vector)433 static void es7000_send_IPI_all(int vector)
434 {
435 	es7000_send_IPI_mask(cpu_online_mask, vector);
436 }
437 
es7000_apic_id_registered(void)438 static int es7000_apic_id_registered(void)
439 {
440 	return 1;
441 }
442 
target_cpus_cluster(void)443 static const struct cpumask *target_cpus_cluster(void)
444 {
445 	return cpu_all_mask;
446 }
447 
es7000_target_cpus(void)448 static const struct cpumask *es7000_target_cpus(void)
449 {
450 	return cpumask_of(smp_processor_id());
451 }
452 
es7000_check_apicid_used(physid_mask_t * map,int apicid)453 static unsigned long es7000_check_apicid_used(physid_mask_t *map, int apicid)
454 {
455 	return 0;
456 }
457 
es7000_check_apicid_present(int bit)458 static unsigned long es7000_check_apicid_present(int bit)
459 {
460 	return physid_isset(bit, phys_cpu_present_map);
461 }
462 
es7000_early_logical_apicid(int cpu)463 static int es7000_early_logical_apicid(int cpu)
464 {
465 	/* on es7000, logical apicid is the same as physical */
466 	return early_per_cpu(x86_bios_cpu_apicid, cpu);
467 }
468 
calculate_ldr(int cpu)469 static unsigned long calculate_ldr(int cpu)
470 {
471 	unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu);
472 
473 	return SET_APIC_LOGICAL_ID(id);
474 }
475 
476 /*
477  * Set up the logical destination ID.
478  *
479  * Intel recommends to set DFR, LdR and TPR before enabling
480  * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
481  * document number 292116).  So here it goes...
482  */
es7000_init_apic_ldr_cluster(void)483 static void es7000_init_apic_ldr_cluster(void)
484 {
485 	unsigned long val;
486 	int cpu = smp_processor_id();
487 
488 	apic_write(APIC_DFR, APIC_DFR_CLUSTER);
489 	val = calculate_ldr(cpu);
490 	apic_write(APIC_LDR, val);
491 }
492 
es7000_init_apic_ldr(void)493 static void es7000_init_apic_ldr(void)
494 {
495 	unsigned long val;
496 	int cpu = smp_processor_id();
497 
498 	apic_write(APIC_DFR, APIC_DFR_FLAT);
499 	val = calculate_ldr(cpu);
500 	apic_write(APIC_LDR, val);
501 }
502 
es7000_setup_apic_routing(void)503 static void es7000_setup_apic_routing(void)
504 {
505 	int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
506 
507 	pr_info("Enabling APIC mode:  %s. Using %d I/O APICs, target cpus %lx\n",
508 		(apic_version[apic] == 0x14) ?
509 			"Physical Cluster" : "Logical Cluster",
510 		nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
511 }
512 
es7000_cpu_present_to_apicid(int mps_cpu)513 static int es7000_cpu_present_to_apicid(int mps_cpu)
514 {
515 	if (!mps_cpu)
516 		return boot_cpu_physical_apicid;
517 	else if (mps_cpu < nr_cpu_ids)
518 		return per_cpu(x86_bios_cpu_apicid, mps_cpu);
519 	else
520 		return BAD_APICID;
521 }
522 
523 static int cpu_id;
524 
es7000_apicid_to_cpu_present(int phys_apicid,physid_mask_t * retmap)525 static void es7000_apicid_to_cpu_present(int phys_apicid, physid_mask_t *retmap)
526 {
527 	physid_set_mask_of_physid(cpu_id, retmap);
528 	++cpu_id;
529 }
530 
es7000_ioapic_phys_id_map(physid_mask_t * phys_map,physid_mask_t * retmap)531 static void es7000_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
532 {
533 	/* For clustered we don't have a good way to do this yet - hack */
534 	physids_promote(0xFFL, retmap);
535 }
536 
es7000_check_phys_apicid_present(int cpu_physical_apicid)537 static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
538 {
539 	boot_cpu_physical_apicid = read_apic_id();
540 	return 1;
541 }
542 
es7000_cpu_mask_to_apicid(const struct cpumask * cpumask)543 static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask)
544 {
545 	unsigned int round = 0;
546 	int cpu, uninitialized_var(apicid);
547 
548 	/*
549 	 * The cpus in the mask must all be on the apic cluster.
550 	 */
551 	for_each_cpu(cpu, cpumask) {
552 		int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
553 
554 		if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
555 			WARN(1, "Not a valid mask!");
556 
557 			return BAD_APICID;
558 		}
559 		apicid = new_apicid;
560 		round++;
561 	}
562 	return apicid;
563 }
564 
565 static unsigned int
es7000_cpu_mask_to_apicid_and(const struct cpumask * inmask,const struct cpumask * andmask)566 es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask,
567 			      const struct cpumask *andmask)
568 {
569 	int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0);
570 	cpumask_var_t cpumask;
571 
572 	if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
573 		return apicid;
574 
575 	cpumask_and(cpumask, inmask, andmask);
576 	cpumask_and(cpumask, cpumask, cpu_online_mask);
577 	apicid = es7000_cpu_mask_to_apicid(cpumask);
578 
579 	free_cpumask_var(cpumask);
580 
581 	return apicid;
582 }
583 
es7000_phys_pkg_id(int cpuid_apic,int index_msb)584 static int es7000_phys_pkg_id(int cpuid_apic, int index_msb)
585 {
586 	return cpuid_apic >> index_msb;
587 }
588 
probe_es7000(void)589 static int probe_es7000(void)
590 {
591 	/* probed later in mptable/ACPI hooks */
592 	return 0;
593 }
594 
595 static int es7000_mps_ret;
es7000_mps_oem_check(struct mpc_table * mpc,char * oem,char * productid)596 static int es7000_mps_oem_check(struct mpc_table *mpc, char *oem,
597 		char *productid)
598 {
599 	int ret = 0;
600 
601 	if (mpc->oemptr) {
602 		struct mpc_oemtable *oem_table =
603 			(struct mpc_oemtable *)mpc->oemptr;
604 
605 		if (!strncmp(oem, "UNISYS", 6))
606 			ret = parse_unisys_oem((char *)oem_table);
607 	}
608 
609 	es7000_mps_ret = ret;
610 
611 	return ret && !es7000_apic_is_cluster();
612 }
613 
es7000_mps_oem_check_cluster(struct mpc_table * mpc,char * oem,char * productid)614 static int es7000_mps_oem_check_cluster(struct mpc_table *mpc, char *oem,
615 		char *productid)
616 {
617 	int ret = es7000_mps_ret;
618 
619 	return ret && es7000_apic_is_cluster();
620 }
621 
622 /* We've been warned by a false positive warning.Use __refdata to keep calm. */
623 static struct apic __refdata apic_es7000_cluster = {
624 
625 	.name				= "es7000",
626 	.probe				= probe_es7000,
627 	.acpi_madt_oem_check		= es7000_acpi_madt_oem_check_cluster,
628 	.apic_id_registered		= es7000_apic_id_registered,
629 
630 	.irq_delivery_mode		= dest_LowestPrio,
631 	/* logical delivery broadcast to all procs: */
632 	.irq_dest_mode			= 1,
633 
634 	.target_cpus			= target_cpus_cluster,
635 	.disable_esr			= 1,
636 	.dest_logical			= 0,
637 	.check_apicid_used		= es7000_check_apicid_used,
638 	.check_apicid_present		= es7000_check_apicid_present,
639 
640 	.vector_allocation_domain	= es7000_vector_allocation_domain,
641 	.init_apic_ldr			= es7000_init_apic_ldr_cluster,
642 
643 	.ioapic_phys_id_map		= es7000_ioapic_phys_id_map,
644 	.setup_apic_routing		= es7000_setup_apic_routing,
645 	.multi_timer_check		= NULL,
646 	.cpu_present_to_apicid		= es7000_cpu_present_to_apicid,
647 	.apicid_to_cpu_present		= es7000_apicid_to_cpu_present,
648 	.setup_portio_remap		= NULL,
649 	.check_phys_apicid_present	= es7000_check_phys_apicid_present,
650 	.enable_apic_mode		= es7000_enable_apic_mode,
651 	.phys_pkg_id			= es7000_phys_pkg_id,
652 	.mps_oem_check			= es7000_mps_oem_check_cluster,
653 
654 	.get_apic_id			= es7000_get_apic_id,
655 	.set_apic_id			= NULL,
656 	.apic_id_mask			= 0xFF << 24,
657 
658 	.cpu_mask_to_apicid		= es7000_cpu_mask_to_apicid,
659 	.cpu_mask_to_apicid_and		= es7000_cpu_mask_to_apicid_and,
660 
661 	.send_IPI_mask			= es7000_send_IPI_mask,
662 	.send_IPI_mask_allbutself	= NULL,
663 	.send_IPI_allbutself		= es7000_send_IPI_allbutself,
664 	.send_IPI_all			= es7000_send_IPI_all,
665 	.send_IPI_self			= default_send_IPI_self,
666 
667 	.wakeup_secondary_cpu		= wakeup_secondary_cpu_via_mip,
668 
669 	.trampoline_phys_low		= 0x467,
670 	.trampoline_phys_high		= 0x469,
671 
672 	.wait_for_init_deassert		= NULL,
673 
674 	/* Nothing to do for most platforms, since cleared by the INIT cycle: */
675 	.smp_callin_clear_local_apic	= NULL,
676 	.inquire_remote_apic		= default_inquire_remote_apic,
677 
678 	.read				= native_apic_mem_read,
679 	.write				= native_apic_mem_write,
680 	.icr_read			= native_apic_icr_read,
681 	.icr_write			= native_apic_icr_write,
682 	.wait_icr_idle			= native_apic_wait_icr_idle,
683 	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
684 
685 	.x86_32_early_logical_apicid	= es7000_early_logical_apicid,
686 };
687 
688 static struct apic __refdata apic_es7000 = {
689 
690 	.name				= "es7000",
691 	.probe				= probe_es7000,
692 	.acpi_madt_oem_check		= es7000_acpi_madt_oem_check,
693 	.apic_id_registered		= es7000_apic_id_registered,
694 
695 	.irq_delivery_mode		= dest_Fixed,
696 	/* phys delivery to target CPUs: */
697 	.irq_dest_mode			= 0,
698 
699 	.target_cpus			= es7000_target_cpus,
700 	.disable_esr			= 1,
701 	.dest_logical			= 0,
702 	.check_apicid_used		= es7000_check_apicid_used,
703 	.check_apicid_present		= es7000_check_apicid_present,
704 
705 	.vector_allocation_domain	= es7000_vector_allocation_domain,
706 	.init_apic_ldr			= es7000_init_apic_ldr,
707 
708 	.ioapic_phys_id_map		= es7000_ioapic_phys_id_map,
709 	.setup_apic_routing		= es7000_setup_apic_routing,
710 	.multi_timer_check		= NULL,
711 	.cpu_present_to_apicid		= es7000_cpu_present_to_apicid,
712 	.apicid_to_cpu_present		= es7000_apicid_to_cpu_present,
713 	.setup_portio_remap		= NULL,
714 	.check_phys_apicid_present	= es7000_check_phys_apicid_present,
715 	.enable_apic_mode		= es7000_enable_apic_mode,
716 	.phys_pkg_id			= es7000_phys_pkg_id,
717 	.mps_oem_check			= es7000_mps_oem_check,
718 
719 	.get_apic_id			= es7000_get_apic_id,
720 	.set_apic_id			= NULL,
721 	.apic_id_mask			= 0xFF << 24,
722 
723 	.cpu_mask_to_apicid		= es7000_cpu_mask_to_apicid,
724 	.cpu_mask_to_apicid_and		= es7000_cpu_mask_to_apicid_and,
725 
726 	.send_IPI_mask			= es7000_send_IPI_mask,
727 	.send_IPI_mask_allbutself	= NULL,
728 	.send_IPI_allbutself		= es7000_send_IPI_allbutself,
729 	.send_IPI_all			= es7000_send_IPI_all,
730 	.send_IPI_self			= default_send_IPI_self,
731 
732 	.trampoline_phys_low		= 0x467,
733 	.trampoline_phys_high		= 0x469,
734 
735 	.wait_for_init_deassert		= es7000_wait_for_init_deassert,
736 
737 	/* Nothing to do for most platforms, since cleared by the INIT cycle: */
738 	.smp_callin_clear_local_apic	= NULL,
739 	.inquire_remote_apic		= default_inquire_remote_apic,
740 
741 	.read				= native_apic_mem_read,
742 	.write				= native_apic_mem_write,
743 	.icr_read			= native_apic_icr_read,
744 	.icr_write			= native_apic_icr_write,
745 	.wait_icr_idle			= native_apic_wait_icr_idle,
746 	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
747 
748 	.x86_32_early_logical_apicid	= es7000_early_logical_apicid,
749 };
750 
751 /*
752  * Need to check for es7000 followed by es7000_cluster, so this order
753  * in apic_drivers is important.
754  */
755 apic_drivers(apic_es7000, apic_es7000_cluster);
756