Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86: Add support for 0x22/0x23 port I/O configuration space

Define macros and accessors for the configuration space addressed
indirectly with an index register and a data register at the port I/O
locations of 0x22 and 0x23 respectively.

This space is defined by the Intel MultiProcessor Specification for the
IMCR register used to switch between the PIC and the APIC mode[1], by
Cyrix processors for their configuration[2][3], and also some chipsets.

Given the lack of atomicity with the indirect addressing a spinlock is
required to protect accesses, although for Cyrix processors it is enough
if accesses are executed with interrupts locally disabled, because the
registers are local to the accessing CPU, and IMCR is only ever poked at
by the BSP and early enough for interrupts not to have been configured
yet. Therefore existing code does not have to change or use the new
spinlock and neither it does.

Put the spinlock in a library file then, so that it does not get pulled
unnecessarily for configurations that do not refer it.

Convert Cyrix accessors to wrappers so as to retain the brevity and
clarity of the `getCx86' and `setCx86' calls.

References:

[1] "MultiProcessor Specification", Version 1.4, Intel Corporation,
Order Number: 242016-006, May 1997, Section 3.6.2.1 "PIC Mode", pp.
3-7, 3-8

[2] "5x86 Microprocessor", Cyrix Corporation, Order Number: 94192-00,
July 1995, Section 2.3.2.4 "Configuration Registers", p. 2-23

[3] "6x86 Processor", Cyrix Corporation, Order Number: 94175-01, March
1996, Section 2.4.4 "6x86 Configuration Registers", p. 2-23

Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/alpine.DEB.2.21.2107182353140.9461@angie.orcam.me.uk

authored by

Maciej W. Rozycki and committed by
Thomas Gleixner
fb6a0408 36a21d51

+54 -10
+33
arch/x86/include/asm/pc-conf-reg.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Support for the configuration register space at port I/O locations 4 + * 0x22 and 0x23 variously used by PC architectures, e.g. the MP Spec, 5 + * Cyrix CPUs, numerous chipsets. 6 + */ 7 + #ifndef _ASM_X86_PC_CONF_REG_H 8 + #define _ASM_X86_PC_CONF_REG_H 9 + 10 + #include <linux/io.h> 11 + #include <linux/spinlock.h> 12 + #include <linux/types.h> 13 + 14 + #define PC_CONF_INDEX 0x22 15 + #define PC_CONF_DATA 0x23 16 + 17 + #define PC_CONF_MPS_IMCR 0x70 18 + 19 + extern raw_spinlock_t pc_conf_lock; 20 + 21 + static inline u8 pc_conf_get(u8 reg) 22 + { 23 + outb(reg, PC_CONF_INDEX); 24 + return inb(PC_CONF_DATA); 25 + } 26 + 27 + static inline void pc_conf_set(u8 reg, u8 data) 28 + { 29 + outb(reg, PC_CONF_INDEX); 30 + outb(data, PC_CONF_DATA); 31 + } 32 + 33 + #endif /* _ASM_X86_PC_CONF_REG_H */
+4 -4
arch/x86/include/asm/processor-cyrix.h
··· 5 5 * Access order is always 0x22 (=offset), 0x23 (=value) 6 6 */ 7 7 8 + #include <asm/pc-conf-reg.h> 9 + 8 10 static inline u8 getCx86(u8 reg) 9 11 { 10 - outb(reg, 0x22); 11 - return inb(0x23); 12 + return pc_conf_get(reg); 12 13 } 13 14 14 15 static inline void setCx86(u8 reg, u8 data) 15 16 { 16 - outb(reg, 0x22); 17 - outb(data, 0x23); 17 + pc_conf_set(reg, data); 18 18 }
+3 -6
arch/x86/kernel/apic/apic.c
··· 38 38 39 39 #include <asm/trace/irq_vectors.h> 40 40 #include <asm/irq_remapping.h> 41 + #include <asm/pc-conf-reg.h> 41 42 #include <asm/perf_event.h> 42 43 #include <asm/x86_init.h> 43 44 #include <linux/atomic.h> ··· 133 132 */ 134 133 static inline void imcr_pic_to_apic(void) 135 134 { 136 - /* select IMCR register */ 137 - outb(0x70, 0x22); 138 135 /* NMI and 8259 INTR go through APIC */ 139 - outb(0x01, 0x23); 136 + pc_conf_set(PC_CONF_MPS_IMCR, 0x01); 140 137 } 141 138 142 139 static inline void imcr_apic_to_pic(void) 143 140 { 144 - /* select IMCR register */ 145 - outb(0x70, 0x22); 146 141 /* NMI and 8259 INTR go directly to BSP */ 147 - outb(0x00, 0x23); 142 + pc_conf_set(PC_CONF_MPS_IMCR, 0x00); 148 143 } 149 144 #endif 150 145
+1
arch/x86/lib/Makefile
··· 44 44 lib-y := delay.o misc.o cmdline.o cpu.o 45 45 lib-y += usercopy_$(BITS).o usercopy.o getuser.o putuser.o 46 46 lib-y += memcpy_$(BITS).o 47 + lib-y += pc-conf-reg.o 47 48 lib-$(CONFIG_ARCH_HAS_COPY_MC) += copy_mc.o copy_mc_64.o 48 49 lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o insn-eval.o 49 50 lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
+13
arch/x86/lib/pc-conf-reg.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Support for the configuration register space at port I/O locations 4 + * 0x22 and 0x23 variously used by PC architectures, e.g. the MP Spec, 5 + * Cyrix CPUs, numerous chipsets. As the space is indirectly addressed 6 + * it may have to be protected with a spinlock, depending on the context. 7 + */ 8 + 9 + #include <linux/spinlock.h> 10 + 11 + #include <asm/pc-conf-reg.h> 12 + 13 + DEFINE_RAW_SPINLOCK(pc_conf_lock);