#include <config.h>
#include <util.h>
#include <machine/io.h>
#include <arch/kernel/cmdline.h>
#include <arch/kernel/boot_sys.h>
#include <arch/linker.h>
#include <plat/machine/io.h>
#define MAX_CMDLINE_VAL_LEN 1000
BOOT_BSS
char cmdline_val[MAX_CMDLINE_VAL_LEN];
const char cmdline_str_max_num_nodes[] = {'m', 'a', 'x', '_', 'n', 'u', 'm', '_', 'n', 'o', 'd', 'e', 's', 0};
const char cmdline_str_num_sh_frames[] = {'n', 'u', 'm', '_', 's', 'h', '_', 'f', 'r', 'a', 'm', 'e', 's', 0};
const char cmdline_str_disable_iommu[] = {'d', 'i', 's', 'a', 'b', 'l', 'e', '_', 'i', 'o', 'm', 'm', 'u', 0};
static int is_space(char c)
{
return c <= ' ';
}
static int UNUSED parse_opt(const char *cmdline, const char *opt, char *value, int bufsize)
{
int len = -1;
const char *optptr = NULL;
while (true) {
for (; is_space(*cmdline) && (*cmdline != 0); cmdline++);
if (*cmdline == 0) {
break;
}
for (optptr = opt; *optptr && *cmdline && (*cmdline != '=') && !is_space(*cmdline) && (*optptr == *cmdline); optptr++, cmdline++);
if (*optptr == '\0' && *cmdline == '=') {
cmdline++;
for (len = 0; !is_space(*cmdline) && (len < bufsize - 1); cmdline++, len++) {
value[len] = *cmdline;
}
if (bufsize) {
value[len] = '\0';
}
}
for (; !is_space(*cmdline); cmdline++);
}
return len;
}
static int parse_bool(const char *cmdline, const char *opt)
{
const char *optptr = NULL;
while (1) {
for (; is_space(*cmdline) && (*cmdline != 0); cmdline++);
if (*cmdline == 0) {
return 0;
}
for (optptr = opt; *optptr && *cmdline && !is_space(*cmdline) && (*optptr == *cmdline); optptr++, cmdline++);
if (*optptr == '\0' && is_space(*cmdline)) {
return 1;
} else {
for (; !is_space(*cmdline); cmdline++);
}
}
}
static void UNUSED parse_uint16_array(char* str, uint16_t* array, int array_size)
{
char* last;
int i = 0;
int v;
while (str && i < array_size) {
for (last = str; *str && *str != ','; str++);
if (*str == 0) {
str = 0;
} else {
*str = 0;
str++;
}
v = str_to_long(last);
if (v == -1) {
array[i] = 0;
} else {
array[i] = v;
}
i++;
}
}
void cmdline_parse(const char *cmdline, cmdline_opt_t* cmdline_opt)
{
#if defined(CONFIG_PRINTING) || defined(CONFIG_DEBUG_BUILD)
const unsigned short * bda_port = (unsigned short *)0x400;
const unsigned short * bda_equi = (unsigned short *)0x410;
int const bda_ports_count = (*bda_equi >> 9) & 0x7;
#endif
#ifdef CONFIG_PRINTING
cmdline_opt->console_port = bda_ports_count && *bda_port ? *bda_port : 0x3f8;
if (parse_opt(cmdline, "console_port", cmdline_val, MAX_CMDLINE_VAL_LEN) != -1) {
parse_uint16_array(cmdline_val, &cmdline_opt->console_port, 1);
}
if (cmdline_opt->console_port) {
serial_init(cmdline_opt->console_port);
x86KSconsolePort = cmdline_opt->console_port;
}
printf("\nBoot config: parsing cmdline '%s'\n", cmdline);
if (cmdline_opt->console_port) {
printf("Boot config: console_port = 0x%x\n", cmdline_opt->console_port);
}
#endif
#ifdef CONFIG_DEBUG_BUILD
cmdline_opt->debug_port = bda_ports_count && *bda_port ? *bda_port : 0x3f8;
if (parse_opt(cmdline, "debug_port", cmdline_val, MAX_CMDLINE_VAL_LEN) != -1) {
parse_uint16_array(cmdline_val, &cmdline_opt->debug_port, 1);
}
if (cmdline_opt->debug_port) {
serial_init(cmdline_opt->debug_port);
x86KSdebugPort = cmdline_opt->debug_port;
printf("Boot config: debug_port = 0x%x\n", cmdline_opt->debug_port);
}
#endif
cmdline_opt->disable_iommu = parse_bool(cmdline, cmdline_str_disable_iommu);
printf("Boot config: disable_iommu = %s\n", cmdline_opt->disable_iommu ? "true" : "false");
}