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

Commit 6fc31d54 authored by Russell King's avatar Russell King
Browse files

ARM: Defer lookup of machine_type to setup.c



Since the debug macros no longer depend on the machine type information,
the machine type lookup can be deferred to setup_arch() in setup.c which
simplifies the code somewhat.

We also move the __error_a functionality into setup.c for displaying a
message when a bad machine ID is passed to the kernel via the LL debug
code.  We also log this into the kernel ring buffer which makes it
possible to retrieve the message via a debugger.

Original idea from Grant Likely.

Acked-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Tested-by: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent ebf53826
Loading
Loading
Loading
Loading
+0 −90
Original line number Diff line number Diff line
@@ -25,83 +25,6 @@
 * machine ID for example).
 */
	__HEAD
__error_a:
#ifdef CONFIG_DEBUG_LL
	mov	r4, r1				@ preserve machine ID
	adr	r0, str_a1
	bl	printascii
	mov	r0, r4
	bl	printhex8
	adr	r0, str_a2
	bl	printascii
	adr	r3, __lookup_machine_type_data
	ldmia	r3, {r4, r5, r6}		@ get machine desc list
	sub	r4, r3, r4			@ get offset between virt&phys
	add	r5, r5, r4			@ convert virt addresses to
	add	r6, r6, r4			@ physical address space
1:	ldr	r0, [r5, #MACHINFO_TYPE]	@ get machine type
	bl	printhex8
	mov	r0, #'\t'
	bl	printch
	ldr     r0, [r5, #MACHINFO_NAME]	@ get machine name
	add	r0, r0, r4
	bl	printascii
	mov	r0, #'\n'
	bl	printch
	add	r5, r5, #SIZEOF_MACHINE_DESC	@ next machine_desc
	cmp	r5, r6
	blo	1b
	adr	r0, str_a3
	bl	printascii
	b	__error
ENDPROC(__error_a)

str_a1:	.asciz	"\nError: unrecognized/unsupported machine ID (r1 = 0x"
str_a2:	.asciz	").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
str_a3:	.asciz	"\nPlease check your kernel config and/or bootloader.\n"
	.align
#else
	b	__error
#endif

/*
 * Lookup machine architecture in the linker-build list of architectures.
 * Note that we can't use the absolute addresses for the __arch_info
 * lists since we aren't running with the MMU on (and therefore, we are
 * not in the correct address space).  We have to calculate the offset.
 *
 *  r1 = machine architecture number
 * Returns:
 *  r3, r4, r6 corrupted
 *  r5 = mach_info pointer in physical address space
 */
__lookup_machine_type:
	adr	r3, __lookup_machine_type_data
	ldmia	r3, {r4, r5, r6}
	sub	r3, r3, r4			@ get offset between virt&phys
	add	r5, r5, r3			@ convert virt addresses to
	add	r6, r6, r3			@ physical address space
1:	ldr	r3, [r5, #MACHINFO_TYPE]	@ get machine type
	teq	r3, r1				@ matches loader number?
	beq	2f				@ found
	add	r5, r5, #SIZEOF_MACHINE_DESC	@ next machine_desc
	cmp	r5, r6
	blo	1b
	mov	r5, #0				@ unknown machine
2:	mov	pc, lr
ENDPROC(__lookup_machine_type)

/*
 * Look in arch/arm/kernel/arch.[ch] for information about the
 * __arch_info structures.
 */
	.align	2
	.type	__lookup_machine_type_data, %object
__lookup_machine_type_data:
	.long	.
	.long	__arch_info_begin
	.long	__arch_info_end
	.size	__lookup_machine_type_data, . - __lookup_machine_type_data

/* Determine validity of the r2 atags pointer.  The heuristic requires
 * that the pointer be aligned, in the first 16k of physical RAM and
@@ -109,8 +32,6 @@ __lookup_machine_type_data:
 * of this function may be more lenient with the physical address and
 * may also be able to move the ATAGS block if necessary.
 *
 * r8  = machinfo
 *
 * Returns:
 *  r2 either valid atags pointer, or zero
 *  r5, r6 corrupted
@@ -184,17 +105,6 @@ __mmap_switched_data:
	.long	init_thread_union + THREAD_START_SP @ sp
	.size	__mmap_switched_data, . - __mmap_switched_data

/*
 * This provides a C-API version of __lookup_machine_type
 */
ENTRY(lookup_machine_type)
	stmfd	sp!, {r4 - r6, lr}
	mov	r1, r0
	bl	__lookup_machine_type
	mov	r0, r5
	ldmfd	sp!, {r4 - r6, pc}
ENDPROC(lookup_machine_type)

/*
 * This provides a C-API version of __lookup_processor_type
 */
+0 −3
Original line number Diff line number Diff line
@@ -44,9 +44,6 @@ ENTRY(stext)
	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
	movs	r10, r5				@ invalid processor (r5=0)?
	beq	__error_p				@ yes, error 'p'
	bl	__lookup_machine_type		@ r5=machinfo
	movs	r8, r5				@ invalid machine (r5=0)?
	beq	__error_a			@ yes, error 'a'

	adr	lr, BSYM(__after_proc_init)	@ return (PIC) address
 ARM(	add	pc, r10, #PROCINFO_INITFUNC	)
+2 −7
Original line number Diff line number Diff line
@@ -87,14 +87,10 @@ ENTRY(stext)
	movs	r10, r5				@ invalid processor (r5=0)?
 THUMB( it	eq )		@ force fixup-able long branch encoding
	beq	__error_p			@ yes, error 'p'
	bl	__lookup_machine_type		@ r5=machinfo
	movs	r8, r5				@ invalid machine (r5=0)?
 THUMB( it	eq )		@ force fixup-able long branch encoding
	beq	__error_a			@ yes, error 'a'

	/*
	 * r1 = machine no, r2 = atags,
	 * r8 = machinfo, r9 = cpuid, r10 = procinfo
	 * r9 = cpuid, r10 = procinfo
	 */
	bl	__vet_atags
#ifdef CONFIG_SMP_ON_UP
@@ -105,7 +101,7 @@ ENTRY(stext)
	/*
	 * The following calls CPU specific code in a position independent
	 * manner.  See arch/arm/mm/proc-*.S for details.  r10 = base of
	 * xxx_proc_info structure selected by __lookup_machine_type
	 * xxx_proc_info structure selected by __lookup_processor_type
	 * above.  On return, the CPU will be ready for the MMU to be
	 * turned on, and r0 will hold the CPU control register value.
	 */
@@ -124,7 +120,6 @@ ENDPROC(stext)
 * amount which are required to get the kernel running, which
 * generally means mapping in the kernel code.
 *
 * r8  = machinfo
 * r9  = cpuid
 * r10 = procinfo
 *
+38 −1
Original line number Diff line number Diff line
@@ -308,7 +308,44 @@ static void __init cacheid_init(void)
 * already provide the required functionality.
 */
extern struct proc_info_list *lookup_processor_type(unsigned int);
extern struct machine_desc *lookup_machine_type(unsigned int);

static void __init early_print(const char *str, ...)
{
	extern void printascii(const char *);
	char buf[256];
	va_list ap;

	va_start(ap, str);
	vsnprintf(buf, sizeof(buf), str, ap);
	va_end(ap);

#ifdef CONFIG_DEBUG_LL
	printascii(buf);
#endif
	printk("%s", buf);
}

static struct machine_desc * __init lookup_machine_type(unsigned int type)
{
	extern struct machine_desc __arch_info_begin[], __arch_info_end[];
	struct machine_desc *p;

	for (p = __arch_info_begin; p < __arch_info_end; p++)
		if (type == p->nr)
			return p;

	early_print("\n"
		"Error: unrecognized/unsupported machine ID (r1 = 0x%08x).\n\n"
		"Available machine support:\n\nID (hex)\tNAME\n", type);

	for (p = __arch_info_begin; p < __arch_info_end; p++)
		early_print("%08x\t%s\n", p->nr, p->name);

	early_print("\nPlease check your kernel config and/or bootloader.\n");

	while (true)
		/* can't use cpu_relax() here as it may require MMU setup */;
}

static void __init feat_v6_fixup(void)
{