• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/x86/kernel/apic/
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 <asm/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
78struct 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
89struct 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
96struct 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
104struct es7000_oem_table {
105	struct acpi_table_header	Header;
106	u32				OEMTableAddr;
107	u32				OEMTableSize;
108};
109
110static unsigned long			oem_addrX;
111static unsigned long			oem_size;
112
113#endif
114
115/*
116 * ES7000 Globals
117 */
118
119static volatile unsigned long		*psai;
120static struct mip_reg			*mip_reg;
121static struct mip_reg			*host_reg;
122static int 				mip_port;
123static unsigned long			mip_addr;
124static unsigned long			host_addr;
125
126int					es7000_plat;
127
128/*
129 * GSI override for ES7000 platforms.
130 */
131
132
133static 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
151static 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
161static 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 */
179static 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
241static 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
272static 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
280static 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
290static int es7000_acpi_ret;
291
292/* Hook from generic ACPI tables.c */
293static 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
320static 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: */
328static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
329{
330	return 0;
331}
332
333static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
334{
335	return 0;
336}
337#endif /* !CONFIG_ACPI */
338
339static void es7000_spin(int n)
340{
341	int i = 0;
342
343	while (i++ < n)
344		rep_nop();
345}
346
347static 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
380static 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
397static 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
412static void es7000_wait_for_init_deassert(atomic_t *deassert)
413{
414	while (!atomic_read(deassert))
415		cpu_relax();
416}
417
418static unsigned int es7000_get_apic_id(unsigned long x)
419{
420	return (x >> 24) & 0xFF;
421}
422
423static void es7000_send_IPI_mask(const struct cpumask *mask, int vector)
424{
425	default_send_IPI_mask_sequence_phys(mask, vector);
426}
427
428static void es7000_send_IPI_allbutself(int vector)
429{
430	default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
431}
432
433static void es7000_send_IPI_all(int vector)
434{
435	es7000_send_IPI_mask(cpu_online_mask, vector);
436}
437
438static int es7000_apic_id_registered(void)
439{
440	return 1;
441}
442
443static const struct cpumask *target_cpus_cluster(void)
444{
445	return cpu_all_mask;
446}
447
448static const struct cpumask *es7000_target_cpus(void)
449{
450	return cpumask_of(smp_processor_id());
451}
452
453static unsigned long es7000_check_apicid_used(physid_mask_t *map, int apicid)
454{
455	return 0;
456}
457
458static unsigned long es7000_check_apicid_present(int bit)
459{
460	return physid_isset(bit, phys_cpu_present_map);
461}
462
463static unsigned long calculate_ldr(int cpu)
464{
465	unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu);
466
467	return SET_APIC_LOGICAL_ID(id);
468}
469
470/*
471 * Set up the logical destination ID.
472 *
473 * Intel recommends to set DFR, LdR and TPR before enabling
474 * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
475 * document number 292116).  So here it goes...
476 */
477static void es7000_init_apic_ldr_cluster(void)
478{
479	unsigned long val;
480	int cpu = smp_processor_id();
481
482	apic_write(APIC_DFR, APIC_DFR_CLUSTER);
483	val = calculate_ldr(cpu);
484	apic_write(APIC_LDR, val);
485}
486
487static void es7000_init_apic_ldr(void)
488{
489	unsigned long val;
490	int cpu = smp_processor_id();
491
492	apic_write(APIC_DFR, APIC_DFR_FLAT);
493	val = calculate_ldr(cpu);
494	apic_write(APIC_LDR, val);
495}
496
497static void es7000_setup_apic_routing(void)
498{
499	int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
500
501	pr_info("Enabling APIC mode:  %s. Using %d I/O APICs, target cpus %lx\n",
502		(apic_version[apic] == 0x14) ?
503			"Physical Cluster" : "Logical Cluster",
504		nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
505}
506
507static int es7000_apicid_to_node(int logical_apicid)
508{
509	return 0;
510}
511
512
513static 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
523static int cpu_id;
524
525static 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
531/* Mapping from cpu number to logical apicid */
532static int es7000_cpu_to_logical_apicid(int cpu)
533{
534#ifdef CONFIG_SMP
535	if (cpu >= nr_cpu_ids)
536		return BAD_APICID;
537	return cpu_2_logical_apicid[cpu];
538#else
539	return logical_smp_processor_id();
540#endif
541}
542
543static void es7000_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
544{
545	/* For clustered we don't have a good way to do this yet - hack */
546	physids_promote(0xFFL, retmap);
547}
548
549static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
550{
551	boot_cpu_physical_apicid = read_apic_id();
552	return 1;
553}
554
555static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask)
556{
557	unsigned int round = 0;
558	int cpu, uninitialized_var(apicid);
559
560	/*
561	 * The cpus in the mask must all be on the apic cluster.
562	 */
563	for_each_cpu(cpu, cpumask) {
564		int new_apicid = es7000_cpu_to_logical_apicid(cpu);
565
566		if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
567			WARN(1, "Not a valid mask!");
568
569			return BAD_APICID;
570		}
571		apicid = new_apicid;
572		round++;
573	}
574	return apicid;
575}
576
577static unsigned int
578es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask,
579			      const struct cpumask *andmask)
580{
581	int apicid = es7000_cpu_to_logical_apicid(0);
582	cpumask_var_t cpumask;
583
584	if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
585		return apicid;
586
587	cpumask_and(cpumask, inmask, andmask);
588	cpumask_and(cpumask, cpumask, cpu_online_mask);
589	apicid = es7000_cpu_mask_to_apicid(cpumask);
590
591	free_cpumask_var(cpumask);
592
593	return apicid;
594}
595
596static int es7000_phys_pkg_id(int cpuid_apic, int index_msb)
597{
598	return cpuid_apic >> index_msb;
599}
600
601static int probe_es7000(void)
602{
603	/* probed later in mptable/ACPI hooks */
604	return 0;
605}
606
607static int es7000_mps_ret;
608static int es7000_mps_oem_check(struct mpc_table *mpc, char *oem,
609		char *productid)
610{
611	int ret = 0;
612
613	if (mpc->oemptr) {
614		struct mpc_oemtable *oem_table =
615			(struct mpc_oemtable *)mpc->oemptr;
616
617		if (!strncmp(oem, "UNISYS", 6))
618			ret = parse_unisys_oem((char *)oem_table);
619	}
620
621	es7000_mps_ret = ret;
622
623	return ret && !es7000_apic_is_cluster();
624}
625
626static int es7000_mps_oem_check_cluster(struct mpc_table *mpc, char *oem,
627		char *productid)
628{
629	int ret = es7000_mps_ret;
630
631	return ret && es7000_apic_is_cluster();
632}
633
634/* We've been warned by a false positive warning.Use __refdata to keep calm. */
635struct apic __refdata apic_es7000_cluster = {
636
637	.name				= "es7000",
638	.probe				= probe_es7000,
639	.acpi_madt_oem_check		= es7000_acpi_madt_oem_check_cluster,
640	.apic_id_registered		= es7000_apic_id_registered,
641
642	.irq_delivery_mode		= dest_LowestPrio,
643	/* logical delivery broadcast to all procs: */
644	.irq_dest_mode			= 1,
645
646	.target_cpus			= target_cpus_cluster,
647	.disable_esr			= 1,
648	.dest_logical			= 0,
649	.check_apicid_used		= es7000_check_apicid_used,
650	.check_apicid_present		= es7000_check_apicid_present,
651
652	.vector_allocation_domain	= es7000_vector_allocation_domain,
653	.init_apic_ldr			= es7000_init_apic_ldr_cluster,
654
655	.ioapic_phys_id_map		= es7000_ioapic_phys_id_map,
656	.setup_apic_routing		= es7000_setup_apic_routing,
657	.multi_timer_check		= NULL,
658	.apicid_to_node			= es7000_apicid_to_node,
659	.cpu_to_logical_apicid		= es7000_cpu_to_logical_apicid,
660	.cpu_present_to_apicid		= es7000_cpu_present_to_apicid,
661	.apicid_to_cpu_present		= es7000_apicid_to_cpu_present,
662	.setup_portio_remap		= NULL,
663	.check_phys_apicid_present	= es7000_check_phys_apicid_present,
664	.enable_apic_mode		= es7000_enable_apic_mode,
665	.phys_pkg_id			= es7000_phys_pkg_id,
666	.mps_oem_check			= es7000_mps_oem_check_cluster,
667
668	.get_apic_id			= es7000_get_apic_id,
669	.set_apic_id			= NULL,
670	.apic_id_mask			= 0xFF << 24,
671
672	.cpu_mask_to_apicid		= es7000_cpu_mask_to_apicid,
673	.cpu_mask_to_apicid_and		= es7000_cpu_mask_to_apicid_and,
674
675	.send_IPI_mask			= es7000_send_IPI_mask,
676	.send_IPI_mask_allbutself	= NULL,
677	.send_IPI_allbutself		= es7000_send_IPI_allbutself,
678	.send_IPI_all			= es7000_send_IPI_all,
679	.send_IPI_self			= default_send_IPI_self,
680
681	.wakeup_secondary_cpu		= wakeup_secondary_cpu_via_mip,
682
683	.trampoline_phys_low		= 0x467,
684	.trampoline_phys_high		= 0x469,
685
686	.wait_for_init_deassert		= NULL,
687
688	/* Nothing to do for most platforms, since cleared by the INIT cycle: */
689	.smp_callin_clear_local_apic	= NULL,
690	.inquire_remote_apic		= default_inquire_remote_apic,
691
692	.read				= native_apic_mem_read,
693	.write				= native_apic_mem_write,
694	.icr_read			= native_apic_icr_read,
695	.icr_write			= native_apic_icr_write,
696	.wait_icr_idle			= native_apic_wait_icr_idle,
697	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
698};
699
700struct apic __refdata apic_es7000 = {
701
702	.name				= "es7000",
703	.probe				= probe_es7000,
704	.acpi_madt_oem_check		= es7000_acpi_madt_oem_check,
705	.apic_id_registered		= es7000_apic_id_registered,
706
707	.irq_delivery_mode		= dest_Fixed,
708	/* phys delivery to target CPUs: */
709	.irq_dest_mode			= 0,
710
711	.target_cpus			= es7000_target_cpus,
712	.disable_esr			= 1,
713	.dest_logical			= 0,
714	.check_apicid_used		= es7000_check_apicid_used,
715	.check_apicid_present		= es7000_check_apicid_present,
716
717	.vector_allocation_domain	= es7000_vector_allocation_domain,
718	.init_apic_ldr			= es7000_init_apic_ldr,
719
720	.ioapic_phys_id_map		= es7000_ioapic_phys_id_map,
721	.setup_apic_routing		= es7000_setup_apic_routing,
722	.multi_timer_check		= NULL,
723	.apicid_to_node			= es7000_apicid_to_node,
724	.cpu_to_logical_apicid		= es7000_cpu_to_logical_apicid,
725	.cpu_present_to_apicid		= es7000_cpu_present_to_apicid,
726	.apicid_to_cpu_present		= es7000_apicid_to_cpu_present,
727	.setup_portio_remap		= NULL,
728	.check_phys_apicid_present	= es7000_check_phys_apicid_present,
729	.enable_apic_mode		= es7000_enable_apic_mode,
730	.phys_pkg_id			= es7000_phys_pkg_id,
731	.mps_oem_check			= es7000_mps_oem_check,
732
733	.get_apic_id			= es7000_get_apic_id,
734	.set_apic_id			= NULL,
735	.apic_id_mask			= 0xFF << 24,
736
737	.cpu_mask_to_apicid		= es7000_cpu_mask_to_apicid,
738	.cpu_mask_to_apicid_and		= es7000_cpu_mask_to_apicid_and,
739
740	.send_IPI_mask			= es7000_send_IPI_mask,
741	.send_IPI_mask_allbutself	= NULL,
742	.send_IPI_allbutself		= es7000_send_IPI_allbutself,
743	.send_IPI_all			= es7000_send_IPI_all,
744	.send_IPI_self			= default_send_IPI_self,
745
746	.trampoline_phys_low		= 0x467,
747	.trampoline_phys_high		= 0x469,
748
749	.wait_for_init_deassert		= es7000_wait_for_init_deassert,
750
751	/* Nothing to do for most platforms, since cleared by the INIT cycle: */
752	.smp_callin_clear_local_apic	= NULL,
753	.inquire_remote_apic		= default_inquire_remote_apic,
754
755	.read				= native_apic_mem_read,
756	.write				= native_apic_mem_write,
757	.icr_read			= native_apic_icr_read,
758	.icr_write			= native_apic_icr_write,
759	.wait_icr_idle			= native_apic_wait_icr_idle,
760	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
761};
762