arch/s390/boot/printk.c

Source file repositories/reference/linux-study-clean/arch/s390/boot/printk.c

File Facts

System
Linux kernel
Corpus path
arch/s390/boot/printk.c
Extension
.c
Size
6804 bytes
Lines
300
Domain
Architecture Layer
Bucket
arch/s390
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (decimal && zero_pad && *src == '-') {
			*p++ = '-';
			src++;
			len--;
			pad--;
		}
		memset(p, zero_pad ? '0' : ' ', pad - len);
		p += pad - len;
	}
	memcpy(p, src, len);
	p += len;
	if (pad < 0 && -pad > len) {
		memset(p, ' ', -pad - len);
		p += -pad - len;
	}
	*p = '\0';
	return p - dst;
}

static char *symstart(char *p)
{
	while (*p)
		p--;
	return p + 1;
}

static noinline char *findsym(unsigned long ip, unsigned short *off, unsigned short *len)
{
	/* symbol entries are in a form "10000 c4 startup\0" */
	char *a = _decompressor_syms_start;
	char *b = _decompressor_syms_end;
	unsigned long start;
	unsigned long size;
	char *pivot;
	char *endp;

	while (a < b) {
		pivot = symstart(a + (b - a) / 2);
		start = simple_strtoull(pivot, &endp, 16);
		size = simple_strtoull(endp + 1, &endp, 16);
		if (ip < start) {
			b = pivot;
			continue;
		}
		if (ip > start + size) {
			a = pivot + strlen(pivot) + 1;
			continue;
		}
		*off = ip - start;
		*len = size;
		return endp + 1;
	}
	return NULL;
}

#define MAX_SYMLEN 64
static noinline char *strsym(char *buf, void *ip)
{
	unsigned short off;
	unsigned short len;
	char *p;

	p = findsym((unsigned long)ip, &off, &len);
	if (p) {
		strscpy(buf, p, MAX_SYMLEN);
		/* reserve 15 bytes for offset/len in symbol+0x1234/0x1234 */
		p = buf + strnlen(buf, MAX_SYMLEN - 15);
		strscpy(p, "+0x", MAX_SYMLEN - (p - buf));
		as_hex(p + 3, off, 0);
		strcat(p, "/0x");
		as_hex(p + strlen(p), len, 0);
	} else {
		as_hex(buf, (unsigned long)ip, 16);
	}
	return buf;
}

static inline int printk_loglevel(const char *buf)
{
	if (buf[0] == KERN_SOH_ASCII && buf[1]) {
		switch (buf[1]) {
		case '0' ... '7':
			return buf[1] - '0';
		}
	}
	return MESSAGE_LOGLEVEL_DEFAULT;
}

static void boot_console_earlyprintk(const char *buf)
{

Annotation

Implementation Notes