18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Author: Huacai Chen <chenhuacai@loongson.cn>
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#include <linux/acpi.h>
88c2ecf20Sopenharmony_ci#include <linux/efi.h>
98c2ecf20Sopenharmony_ci#include <linux/export.h>
108c2ecf20Sopenharmony_ci#include <linux/memblock.h>
118c2ecf20Sopenharmony_ci#include <linux/of_fdt.h>
128c2ecf20Sopenharmony_ci#include <asm/early_ioremap.h>
138c2ecf20Sopenharmony_ci#include <asm/bootinfo.h>
148c2ecf20Sopenharmony_ci#include <loongson.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ciu64 efi_system_table;
178c2ecf20Sopenharmony_ciunsigned long long smp_group[MAX_PACKAGES];
188c2ecf20Sopenharmony_cistruct loongson_system_configuration loongson_sysconf;
198c2ecf20Sopenharmony_ciEXPORT_SYMBOL(loongson_sysconf);
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_cistatic void __init register_addrs_set(u64 *registers, const u64 addr, int num)
228c2ecf20Sopenharmony_ci{
238c2ecf20Sopenharmony_ci	u64 i;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	for (i = 0; i < num; i++) {
268c2ecf20Sopenharmony_ci		*registers = (i << 44) | addr;
278c2ecf20Sopenharmony_ci		registers++;
288c2ecf20Sopenharmony_ci	}
298c2ecf20Sopenharmony_ci}
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_civoid __init init_environ(void)
328c2ecf20Sopenharmony_ci{
338c2ecf20Sopenharmony_ci	int efi_boot = fw_arg0;
348c2ecf20Sopenharmony_ci	char *cmdline = early_memremap_ro(fw_arg1, COMMAND_LINE_SIZE);
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	if (efi_boot)
378c2ecf20Sopenharmony_ci		set_bit(EFI_BOOT, &efi.flags);
388c2ecf20Sopenharmony_ci	else
398c2ecf20Sopenharmony_ci		clear_bit(EFI_BOOT, &efi.flags);
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE);
428c2ecf20Sopenharmony_ci	early_memunmap(cmdline, COMMAND_LINE_SIZE);
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	efi_system_table = fw_arg2;
458c2ecf20Sopenharmony_ci	register_addrs_set(smp_group, TO_UNCACHE(0x1fe01000), 16);
468c2ecf20Sopenharmony_ci}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistatic int __init init_cpu_fullname(void)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci	int cpu;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	if (loongson_sysconf.cpuname && !strncmp(loongson_sysconf.cpuname, "Loongson", 8)) {
538c2ecf20Sopenharmony_ci		for (cpu = 0; cpu < NR_CPUS; cpu++)
548c2ecf20Sopenharmony_ci			__cpu_full_name[cpu] = loongson_sysconf.cpuname;
558c2ecf20Sopenharmony_ci	}
568c2ecf20Sopenharmony_ci	return 0;
578c2ecf20Sopenharmony_ci}
588c2ecf20Sopenharmony_ciarch_initcall(init_cpu_fullname);
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_cistatic ssize_t boardinfo_show(struct kobject *kobj,
618c2ecf20Sopenharmony_ci			      struct kobj_attribute *attr, char *buf)
628c2ecf20Sopenharmony_ci{
638c2ecf20Sopenharmony_ci	return sprintf(buf,
648c2ecf20Sopenharmony_ci		"BIOS Information\n"
658c2ecf20Sopenharmony_ci		"Vendor\t\t\t: %s\n"
668c2ecf20Sopenharmony_ci		"Version\t\t\t: %s\n"
678c2ecf20Sopenharmony_ci		"ROM Size\t\t: %d KB\n"
688c2ecf20Sopenharmony_ci		"Release Date\t\t: %s\n\n"
698c2ecf20Sopenharmony_ci		"Board Information\n"
708c2ecf20Sopenharmony_ci		"Manufacturer\t\t: %s\n"
718c2ecf20Sopenharmony_ci		"Board Name\t\t: %s\n"
728c2ecf20Sopenharmony_ci		"Family\t\t\t: LOONGSON64\n\n",
738c2ecf20Sopenharmony_ci		b_info.bios_vendor, b_info.bios_version,
748c2ecf20Sopenharmony_ci		b_info.bios_size, b_info.bios_release_date,
758c2ecf20Sopenharmony_ci		b_info.board_vendor, b_info.board_name);
768c2ecf20Sopenharmony_ci}
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_cistatic struct kobj_attribute boardinfo_attr = __ATTR(boardinfo, 0444,
798c2ecf20Sopenharmony_ci						     boardinfo_show, NULL);
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_cistatic int __init boardinfo_init(void)
828c2ecf20Sopenharmony_ci{
838c2ecf20Sopenharmony_ci	struct kobject *loongson_kobj;
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	loongson_kobj = kobject_create_and_add("loongson", firmware_kobj);
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	return sysfs_create_file(loongson_kobj, &boardinfo_attr.attr);
888c2ecf20Sopenharmony_ci}
898c2ecf20Sopenharmony_cilate_initcall(boardinfo_init);
90