Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c029b55a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, asm: Use a lower case name for the end macro in atomic64_386_32.S
  x86, asm: Refactor atomic64_386_32.S to support old binutils and be cleaner
  x86: Document __phys_reloc_hide() usage in __pa_symbol()
  x86, apic: Map the local apic when parsing the MP table.
parents 96054569 417484d4
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -37,6 +37,13 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
#define __pa_nodebug(x)	__phys_addr_nodebug((unsigned long)(x))
#define __pa_nodebug(x)	__phys_addr_nodebug((unsigned long)(x))
/* __pa_symbol should be used for C visible symbols.
/* __pa_symbol should be used for C visible symbols.
   This seems to be the official gcc blessed way to do such arithmetic. */
   This seems to be the official gcc blessed way to do such arithmetic. */
/*
 * We need __phys_reloc_hide() here because gcc may assume that there is no
 * overflow during __pa() calculation and can optimize it unexpectedly.
 * Newer versions of gcc provide -fno-strict-overflow switch to handle this
 * case properly. Once all supported versions of gcc understand it, we can
 * remove this Voodoo magic stuff. (i.e. once gcc3.x is deprecated)
 */
#define __pa_symbol(x)	__pa(__phys_reloc_hide((unsigned long)(x)))
#define __pa_symbol(x)	__pa(__phys_reloc_hide((unsigned long)(x)))


#define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
#define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
+1 −1
Original line number Original line Diff line number Diff line
@@ -1606,7 +1606,7 @@ void __init init_apic_mappings(void)
		 * acpi lapic path already maps that address in
		 * acpi lapic path already maps that address in
		 * acpi_register_lapic_address()
		 * acpi_register_lapic_address()
		 */
		 */
		if (!acpi_lapic)
		if (!acpi_lapic && !smp_found_config)
			set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
			set_fixmap_nocache(FIX_APIC_BASE, apic_phys);


		apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
		apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
+16 −0
Original line number Original line Diff line number Diff line
@@ -274,6 +274,18 @@ static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt)


void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { }
void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { }


static void __init smp_register_lapic_address(unsigned long address)
{
	mp_lapic_addr = address;

	set_fixmap_nocache(FIX_APIC_BASE, address);
	if (boot_cpu_physical_apicid == -1U) {
		boot_cpu_physical_apicid  = read_apic_id();
		apic_version[boot_cpu_physical_apicid] =
			 GET_APIC_VERSION(apic_read(APIC_LVR));
	}
}

static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
{
{
	char str[16];
	char str[16];
@@ -295,6 +307,10 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
	if (early)
	if (early)
		return 1;
		return 1;


	/* Initialize the lapic mapping */
	if (!acpi_lapic)
		smp_register_lapic_address(mpc->lapic);

	if (mpc->oemptr)
	if (mpc->oemptr)
		x86_init.mpparse.smp_read_mpc_oem(mpc);
		x86_init.mpparse.smp_read_mpc_oem(mpc);


+130 −108
Original line number Original line Diff line number Diff line
@@ -25,150 +25,172 @@
	CFI_ADJUST_CFA_OFFSET -4
	CFI_ADJUST_CFA_OFFSET -4
.endm
.endm


.macro BEGIN func reg
#define BEGIN(op) \
$v = \reg
.macro endp; \

	CFI_ENDPROC; \
ENTRY(atomic64_\func\()_386)
ENDPROC(atomic64_##op##_386); \
	CFI_STARTPROC
.purgem endp; \
	LOCK $v
.endm; \

ENTRY(atomic64_##op##_386); \
.macro RETURN
	CFI_STARTPROC; \
	UNLOCK $v
	LOCK v;

#define ENDP endp

#define RET \
	UNLOCK v; \
	ret
	ret
.endm

.macro END_
	CFI_ENDPROC
ENDPROC(atomic64_\func\()_386)
.purgem RETURN
.purgem END_
.purgem END
.endm

.macro END
RETURN
END_
.endm
.endm


BEGIN read %ecx
#define RET_ENDP \
	movl  ($v), %eax
	RET; \
	movl 4($v), %edx
	ENDP
END


#define v %ecx
BEGIN set %esi
BEGIN(read)
	movl %ebx,  ($v)
	movl  (v), %eax
	movl %ecx, 4($v)
	movl 4(v), %edx
END
RET_ENDP

#undef v
BEGIN xchg %esi

	movl  ($v), %eax
#define v %esi
	movl 4($v), %edx
BEGIN(set)
	movl %ebx,  ($v)
	movl %ebx,  (v)
	movl %ecx, 4($v)
	movl %ecx, 4(v)
END
RET_ENDP

#undef v
BEGIN add %ecx

	addl %eax,  ($v)
#define v  %esi
	adcl %edx, 4($v)
BEGIN(xchg)
END
	movl  (v), %eax

	movl 4(v), %edx
BEGIN add_return %ecx
	movl %ebx,  (v)
	addl  ($v), %eax
	movl %ecx, 4(v)
	adcl 4($v), %edx
RET_ENDP
	movl %eax,  ($v)
#undef v
	movl %edx, 4($v)

END
#define v %ecx

BEGIN(add)
BEGIN sub %ecx
	addl %eax,  (v)
	subl %eax,  ($v)
	adcl %edx, 4(v)
	sbbl %edx, 4($v)
RET_ENDP
END
#undef v


BEGIN sub_return %ecx
#define v %ecx
BEGIN(add_return)
	addl  (v), %eax
	adcl 4(v), %edx
	movl %eax,  (v)
	movl %edx, 4(v)
RET_ENDP
#undef v

#define v %ecx
BEGIN(sub)
	subl %eax,  (v)
	sbbl %edx, 4(v)
RET_ENDP
#undef v

#define v %ecx
BEGIN(sub_return)
	negl %edx
	negl %edx
	negl %eax
	negl %eax
	sbbl $0, %edx
	sbbl $0, %edx
	addl  ($v), %eax
	addl  (v), %eax
	adcl 4($v), %edx
	adcl 4(v), %edx
	movl %eax,  ($v)
	movl %eax,  (v)
	movl %edx, 4($v)
	movl %edx, 4(v)
END
RET_ENDP

#undef v
BEGIN inc %esi

	addl $1,  ($v)
#define v %esi
	adcl $0, 4($v)
BEGIN(inc)
END
	addl $1,  (v)

	adcl $0, 4(v)
BEGIN inc_return %esi
RET_ENDP
	movl  ($v), %eax
#undef v
	movl 4($v), %edx

#define v %esi
BEGIN(inc_return)
	movl  (v), %eax
	movl 4(v), %edx
	addl $1, %eax
	addl $1, %eax
	adcl $0, %edx
	adcl $0, %edx
	movl %eax,  ($v)
	movl %eax,  (v)
	movl %edx, 4($v)
	movl %edx, 4(v)
END
RET_ENDP

#undef v
BEGIN dec %esi

	subl $1,  ($v)
#define v %esi
	sbbl $0, 4($v)
BEGIN(dec)
END
	subl $1,  (v)

	sbbl $0, 4(v)
BEGIN dec_return %esi
RET_ENDP
	movl  ($v), %eax
#undef v
	movl 4($v), %edx

#define v %esi
BEGIN(dec_return)
	movl  (v), %eax
	movl 4(v), %edx
	subl $1, %eax
	subl $1, %eax
	sbbl $0, %edx
	sbbl $0, %edx
	movl %eax,  ($v)
	movl %eax,  (v)
	movl %edx, 4($v)
	movl %edx, 4(v)
END
RET_ENDP
#undef v


BEGIN add_unless %ecx
#define v %ecx
BEGIN(add_unless)
	addl %eax, %esi
	addl %eax, %esi
	adcl %edx, %edi
	adcl %edx, %edi
	addl  ($v), %eax
	addl  (v), %eax
	adcl 4($v), %edx
	adcl 4(v), %edx
	cmpl %eax, %esi
	cmpl %eax, %esi
	je 3f
	je 3f
1:
1:
	movl %eax,  ($v)
	movl %eax,  (v)
	movl %edx, 4($v)
	movl %edx, 4(v)
	movl $1, %eax
	movl $1, %eax
2:
2:
RETURN
	RET
3:
3:
	cmpl %edx, %edi
	cmpl %edx, %edi
	jne 1b
	jne 1b
	xorl %eax, %eax
	xorl %eax, %eax
	jmp 2b
	jmp 2b
END_
ENDP
#undef v


BEGIN inc_not_zero %esi
#define v %esi
	movl  ($v), %eax
BEGIN(inc_not_zero)
	movl 4($v), %edx
	movl  (v), %eax
	movl 4(v), %edx
	testl %eax, %eax
	testl %eax, %eax
	je 3f
	je 3f
1:
1:
	addl $1, %eax
	addl $1, %eax
	adcl $0, %edx
	adcl $0, %edx
	movl %eax,  ($v)
	movl %eax,  (v)
	movl %edx, 4($v)
	movl %edx, 4(v)
	movl $1, %eax
	movl $1, %eax
2:
2:
RETURN
	RET
3:
3:
	testl %edx, %edx
	testl %edx, %edx
	jne 1b
	jne 1b
	jmp 2b
	jmp 2b
END_
ENDP
#undef v


BEGIN dec_if_positive %esi
#define v %esi
	movl  ($v), %eax
BEGIN(dec_if_positive)
	movl 4($v), %edx
	movl  (v), %eax
	movl 4(v), %edx
	subl $1, %eax
	subl $1, %eax
	sbbl $0, %edx
	sbbl $0, %edx
	js 1f
	js 1f
	movl %eax,  ($v)
	movl %eax,  (v)
	movl %edx, 4($v)
	movl %edx, 4(v)
1:
1:
END
RET_ENDP
#undef v