/* * Copyright (C) 2015, Bin Meng * * Adapted from coreboot src/arch/x86/smbios.c * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include #ifdef CONFIG_CPU #include #include #include #endif DECLARE_GLOBAL_DATA_PTR; /** * smbios_add_string() - add a string to the string area * * This adds a string to the string area which is appended directly after * the formatted portion of an SMBIOS structure. * * @start: string area start address * @str: string to add * @return: string number in the string area */ static int smbios_add_string(char *start, const char *str) { int i = 1; char *p = start; for (;;) { if (!*p) { strcpy(p, str); p += strlen(str); *p++ = '\0'; *p++ = '\0'; return i; } if (!strcmp(p, str)) return i; p += strlen(p) + 1; i++; } } /** * smbios_string_table_len() - compute the string area size * * This computes the size of the string area including the string terminator. * * @start: string area start address * @return: string area size */ static int smbios_string_table_len(char *start) { char *p = start; int i, len = 0; while (*p) { i = strlen(p) + 1; p += i; len += i; } return len + 1; } static int smbios_write_type0(ulong *current, int handle) { struct smbios_type0 *t = (struct smbios_type0 *)*current; int len = sizeof(struct smbios_type0); memset(t, 0, sizeof(struct smbios_type0)); fill_smbios_header(t, SMBIOS_BIOS_INFORMATION, len, handle); t->vendor = smbios_add_string(t->eos, "U-Boot"); t->bios_ver = smbios_add_string(t->eos, PLAIN_VERSION); t->bios_release_date = smbios_add_string(t->eos, U_BOOT_DMI_DATE); #ifdef CONFIG_ROM_SIZE t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1; #endif t->bios_characteristics = BIOS_CHARACTERISTICS_PCI_SUPPORTED | BIOS_CHARACTERISTICS_SELECTABLE_BOOT | BIOS_CHARACTERISTICS_UPGRADEABLE; #ifdef CONFIG_GENERATE_ACPI_TABLE t->bios_characteristics_ext1 = BIOS_CHARACTERISTICS_EXT1_ACPI; #endif #ifdef CONFIG_EFI_LOADER t->bios_characteristics_ext1 |= BIOS_CHARACTERISTICS_EXT1_UEFI; #endif t->bios_characteristics_ext2 = BIOS_CHARACTERISTICS_EXT2_TARGET; t->bios_major_release = 0xff; t->bios_minor_release = 0xff; t->ec_major_release = 0xff; t->ec_minor_release = 0xff; len = t->length + smbios_string_table_len(t->eos); *current += len; return len; } static int smbios_write_type1(ulong *current, int handle) { struct smbios_type1 *t = (struct smbios_type1 *)*current; int len = sizeof(struct smbios_type1); char *serial_str = getenv("serial#"); memset(t, 0, sizeof(struct smbios_type1)); fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle); t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER); t->product_name = smbios_add_string(t->eos, CONFIG_SMBIOS_PRODUCT_NAME); if (serial_str) { strncpy((char*)t->uuid, serial_str, sizeof(t->uuid)); t->serial_number = smbios_add_string(t->eos, serial_str); } len = t->length + smbios_string_table_len(t->eos); *current += len; return len; } static int smbios_write_type2(ulong *current, int handle) { struct smbios_type2 *t = (struct smbios_type2 *)*current; int len = sizeof(struct smbios_type2); memset(t, 0, sizeof(struct smbios_type2)); fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle); t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER); t->product_name = smbios_add_string(t->eos, CONFIG_SMBIOS_PRODUCT_NAME); t->feature_flags = SMBIOS_BOARD_FEATURE_HOSTING; t->board_type = SMBIOS_BOARD_MOTHERBOARD; len = t->length + smbios_string_table_len(t->eos); *current += len; return len; } static int smbios_write_type3(ulong *current, int handle) { struct smbios_type3 *t = (struct smbios_type3 *)*current; int len = sizeof(struct smbios_type3); memset(t, 0, sizeof(struct smbios_type3)); fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle); t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER); t->chassis_type = SMBIOS_ENCLOSURE_DESKTOP; t->bootup_state = SMBIOS_STATE_SAFE; t->power_supply_state = SMBIOS_STATE_SAFE; t->thermal_state = SMBIOS_STATE_SAFE; t->security_status = SMBIOS_SECURITY_NONE; len = t->length + smbios_string_table_len(t->eos); *current += len; return len; } static void smbios_write_type4_dm(struct smbios_type4 *t) { u16 processor_family = SMBIOS_PROCESSOR_FAMILY_UNKNOWN; const char *vendor = "Unknown"; const char *name = "Unknown"; #ifdef CONFIG_CPU char processor_name[49]; char vendor_name[49]; struct udevice *dev = NULL; uclass_find_first_device(UCLASS_CPU, &dev); if (dev) { struct cpu_platdata *plat = dev_get_parent_platdata(dev); if (plat->family) processor_family = plat->family; t->processor_id[0] = plat->id[0]; t->processor_id[1] = plat->id[1]; if (!cpu_get_vendor(dev, vendor_name, sizeof(vendor_name))) vendor = vendor_name; if (!cpu_get_desc(dev, processor_name, sizeof(processor_name))) name = processor_name; } #endif t->processor_family = processor_family; t->processor_manufacturer = smbios_add_string(t->eos, vendor); t->processor_version = smbios_add_string(t->eos, name); } static int smbios_write_type4(ulong *current, int handle) { struct smbios_type4 *t = (struct smbios_type4 *)*current; int len = sizeof(struct smbios_type4); memset(t, 0, sizeof(struct smbios_type4)); fill_smbios_header(t, SMBIOS_PROCESSOR_INFORMATION, len, handle); t->processor_type = SMBIOS_PROCESSOR_TYPE_CENTRAL; smbios_write_type4_dm(t); t->status = SMBIOS_PROCESSOR_STATUS_ENABLED; t->processor_upgrade = SMBIOS_PROCESSOR_UPGRADE_NONE; t->l1_cache_handle = 0xffff; t->l2_cache_handle = 0xffff; t->l3_cache_handle = 0xffff; t->processor_family2 = t->processor_family; len = t->length + smbios_string_table_len(t->eos); *current += len; return len; } static int smbios_write_type32(ulong *current, int handle) { stru/* * This file contains the power_save function for 970-family CPUs. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include <linux/threads.h> #include <asm/processor.h> #include <asm/page.h> #include <asm/cputable.h> #include <asm/thread_info.h> #include <asm/ppc_asm.h> #include <asm/asm-offsets.h> #undef DEBUG .text _GLOBAL(power4_idle) BEGIN_FTR_SECTION blr END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) /* Now check if user or arch enabled NAP mode */ LOAD_REG_ADDRBASE(r3,powersave_nap) lwz r4,ADDROFF(powersave_nap)(r3) cmpwi 0,r4,0 beqlr /* Go to NAP now */ mfmsr r7 rldicl r0,r7,48,1 rotldi r0,r0,16 mtmsrd r0,1 /* hard-disable interrupts */ li r0,1 stb r0,PACASOFTIRQEN(r13) /* we'll hard-enable shortly */ stb r0,PACAHARDIRQEN(r13) BEGIN_FTR_SECTION DSSALL sync END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) clrrdi r9,r1,THREAD_SHIFT /* current thread_info */ ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ ori r8,r8,_TLF_NAPPING /* so when we take an exception */ std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ ori r7,r7,MSR_EE oris r7,r7,MSR_POW@h 1: sync isync mtmsrd r7 isync b 1b