• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <drivers/vpd/vpd.h>
5 #include <drivers/ocp/include/vpd.h>
6 #include <string.h>
7 #include <program_loading.h>
8 
9 #define CMDLINE_LOGLVL_STR	"loglevel="
10 
overwrite_kernel_loglevel(uintptr_t start)11 static void overwrite_kernel_loglevel(uintptr_t start)
12 {
13 	int val;
14 	if (!vpd_get_int(KERNEL_LOG_LEVEL, VPD_RW_THEN_RO, &val)) {
15 		printk(BIOS_DEBUG, "%s: not able to get VPD %s\n", __func__, KERNEL_LOG_LEVEL);
16 		return;
17 	}
18 
19 	printk(BIOS_DEBUG, "%s: VPD %s, got %d\n", __func__, KERNEL_LOG_LEVEL, val);
20 	if (val < 0 || val > 7) {
21 		printk(BIOS_INFO, "Invalid VPD for Linux kernel log level\n");
22 		return;
23 	}
24 
25 	int loglevel;
26 	char *loc = strstr((const char *)start, CMDLINE_LOGLVL_STR);
27 	if (!loc) {
28 		printk(BIOS_INFO, "%s is not found from LINUX_COMMAND_LINE\n",
29 			CMDLINE_LOGLVL_STR);
30 		return;
31 	}
32 
33 	char *loc_bkup;
34 	loc += strlen(CMDLINE_LOGLVL_STR);
35 	loc_bkup = loc;
36 	loglevel = skip_atoi(&loc);
37 	printk(BIOS_DEBUG, "Original kernel log level is %d\n", loglevel);
38 	/* Unlikely but don't overwrite with such an unexpected case. */
39 	if (loglevel < 0 || loglevel > 7) {
40 		printk(BIOS_DEBUG, "Invalid kernel log level, must be from 0 to 7.\n");
41 		return;
42 	}
43 
44 	char c = '0' + val;
45 	printk(BIOS_INFO, "Overwrite kernel log level with %c from VPD.\n", c);
46 	memcpy(loc_bkup, &c, 1);
47 }
48 
platform_segment_loaded(uintptr_t start,size_t size,int flags)49 void platform_segment_loaded(uintptr_t start, size_t size, int flags)
50 {
51 	/* CONFIG_LINUX_COMMAND_LINE is in the final segment. */
52 	if (flags != SEG_FINAL)
53 		return;
54 
55 	overwrite_kernel_loglevel(start);
56 }
57