cpu/via/nano: Drop support

Relocatable ramstage, postcar stage and C_ENVIRONMENT_BOOTBLOCK are
now mandatory features, which this platform lacks.

Change-Id: I6d9771e97619c3775f8325daf4b8453cd51d6571
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/36950
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr>
Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
Arthur Heymans 2019-11-19 15:40:52 +01:00 committed by Kyösti Mälkki
parent fbc59ffb64
commit 4c38ed3c38
10 changed files with 0 additions and 706 deletions

View File

@ -6,7 +6,6 @@ subdirs-y += amd
subdirs-y += armltd
subdirs-y += intel
subdirs-y += ti
subdirs-y += via
subdirs-$(CONFIG_ARCH_X86) += x86
subdirs-$(CONFIG_CPU_QEMU_X86) += qemu-x86

View File

@ -1 +0,0 @@
source src/cpu/via/nano/Kconfig

View File

@ -1 +0,0 @@
subdirs-$(CONFIG_CPU_VIA_NANO) += nano

View File

@ -1,227 +0,0 @@
/*
* This file is part of the coreboot project.
*
* 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; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <cpu/x86/mtrr.h>
#include <cpu/x86/cache.h>
#include <console/post_codes.h>
#define CacheSize CONFIG_DCACHE_RAM_SIZE
#define CacheBase CONFIG_DCACHE_RAM_BASE
/* Save the BIST result. */
movl %eax, %ebp
CacheAsRam:
/* Disable cache. */
movl %cr0, %eax
orl $CR0_CacheDisable, %eax
movl %eax, %cr0
invd
/* Set the default memory type and enable fixed and variable MTRRs. */
movl $MTRR_DEF_TYPE_MSR, %ecx
xorl %edx, %edx
movl $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax
wrmsr
/* Clear all MTRRs. */
xorl %edx, %edx
movl $all_mtrr_msrs, %esi
clear_fixed_var_mtrr:
lodsl (%esi), %eax
testl %eax, %eax
jz clear_fixed_var_mtrr_out
movl %eax, %ecx
xorl %eax, %eax
wrmsr
jmp clear_fixed_var_mtrr
all_mtrr_msrs:
/* fixed MTRR MSRs */
.long MTRR_FIX_64K_00000
.long MTRR_FIX_16K_80000
.long MTRR_FIX_16K_A0000
.long MTRR_FIX_4K_C0000
.long MTRR_FIX_4K_C8000
.long MTRR_FIX_4K_D0000
.long MTRR_FIX_4K_D8000
.long MTRR_FIX_4K_E0000
.long MTRR_FIX_4K_E8000
.long MTRR_FIX_4K_F0000
.long MTRR_FIX_4K_F8000
/* var MTRR MSRs */
.long MTRR_PHYS_BASE(0)
.long MTRR_PHYS_MASK(0)
.long MTRR_PHYS_BASE(1)
.long MTRR_PHYS_MASK(1)
.long MTRR_PHYS_BASE(2)
.long MTRR_PHYS_MASK(2)
.long MTRR_PHYS_BASE(3)
.long MTRR_PHYS_MASK(3)
.long MTRR_PHYS_BASE(4)
.long MTRR_PHYS_MASK(4)
.long MTRR_PHYS_BASE(5)
.long MTRR_PHYS_MASK(5)
.long MTRR_PHYS_BASE(6)
.long MTRR_PHYS_MASK(6)
.long MTRR_PHYS_BASE(7)
.long MTRR_PHYS_MASK(7)
.long 0x000 /* NULL, end of table */
clear_fixed_var_mtrr_out:
movl $MTRR_PHYS_BASE(0), %ecx
xorl %edx, %edx
movl $(CacheBase | MTRR_TYPE_WRBACK), %eax
wrmsr
movl $MTRR_PHYS_MASK(0), %ecx
/* This assumes we never access addresses above 2^36 in CAR. */
movl $0x0000000f, %edx
movl $(~(CacheSize - 1) | MTRR_PHYS_MASK_VALID), %eax
wrmsr
/*
* Enable write base caching so we can do execute in place (XIP)
* on the flash ROM.
*/
movl $MTRR_PHYS_BASE(1), %ecx
xorl %edx, %edx
/*
* IMPORTANT: The following calculation _must_ be done at runtime. See
* https://mail.coreboot.org/pipermail/coreboot/2010-October/060922.html
*/
movl $_program, %eax
andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
orl $MTRR_TYPE_WRBACK, %eax
wrmsr
movl $MTRR_PHYS_MASK(1), %ecx
movl $0x0000000f, %edx
movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
wrmsr
/* Set the default memory type and enable fixed and variable MTRRs. */
/* TODO: Or also enable fixed MTRRs? Bug in the code? */
movl $MTRR_DEF_TYPE_MSR, %ecx
xorl %edx, %edx
movl $(MTRR_DEF_TYPE_EN), %eax
wrmsr
/* Enable cache. */
movl %cr0, %eax
andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
movl %eax, %cr0
/* Read the range with lodsl. */
cld
movl $CacheBase, %esi
movl %esi, %edi
movl $(CacheSize >> 2), %ecx
rep lodsl
movl $CacheBase, %esi
movl %esi, %edi
movl $(CacheSize >> 2), %ecx
/* Zero out the cache-as-ram area. */
xorl %eax, %eax
rep stosl
/*
* The key point of this CAR code is C7 cache does not turn into
* "no fill" mode, which is not compatible with general CAR code.
*/
movl $(CacheBase + CacheSize - 4), %eax
movl %eax, %esp
/* Restore the BIST result. */
movl %ebp, %eax
/* We need to set EBP? No need. */
movl %esp, %ebp
pushl %eax /* BIST */
call main
/*
* TODO: Backup stack in CACHE_AS_RAM into MMX and SSE and after we
* get STACK up, we restore that. It is only needed if we
* want to go back.
*/
/* We don't need CAR from now on. */
/* Disable cache. */
movl %cr0, %eax
orl $CR0_CacheDisable, %eax
movl %eax, %cr0
/* Set the default memory type and enable variable MTRRs. */
/* TODO: Or also enable fixed MTRRs? Bug in the code? */
movl $MTRR_DEF_TYPE_MSR, %ecx
xorl %edx, %edx
movl $(MTRR_DEF_TYPE_EN), %eax
wrmsr
/* Enable caching for 0..CACHE_TMP_RAMTOP. */
movl $MTRR_PHYS_BASE(0), %ecx
xorl %edx, %edx
movl $(0x0 | MTRR_TYPE_WRBACK), %eax
wrmsr
movl $MTRR_PHYS_MASK(0), %ecx
movl $0x0000000f, %edx /* AMD 40 bit 0xff */
movl $(~(CACHE_TMP_RAMTOP - 1) | MTRR_PHYS_MASK_VALID), %eax
wrmsr
/* Cache XIP_ROM area to speedup coreboot code. */
movl $MTRR_PHYS_BASE(1), %ecx
xorl %edx, %edx
/*
* IMPORTANT: The following calculation _must_ be done at runtime. See
* https://mail.coreboot.org/pipermail/coreboot/2010-October/060922.html
*/
movl $_program, %eax
andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
orl $MTRR_TYPE_WRBACK, %eax
wrmsr
movl $MTRR_PHYS_MASK(1), %ecx
xorl %edx, %edx
movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
wrmsr
/* Enable cache. */
movl %cr0, %eax
andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
movl %eax, %cr0
invd
__main:
post_code(POST_PREPARE_RAMSTAGE)
cld /* Clear direction flag. */
movl $CONFIG_RAMTOP, %esp
movl %esp, %ebp
call copy_and_run
.Lhlt:
post_code(POST_DEAD_CODE)
hlt
jmp .Lhlt

View File

@ -1,42 +0,0 @@
##
## This file is part of the coreboot project.
##
## 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.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
config CPU_VIA_NANO
bool
if CPU_VIA_NANO
config CPU_SPECIFIC_OPTIONS
def_bool y
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select UDELAY_TSC
select TSC_MONOTONIC_TIMER
select UNKNOWN_TSC_RATE
select MMX
select SSE2
select SUPPORT_CPU_UCODE_IN_CBFS
select CAR_GLOBAL_MIGRATION
config DCACHE_RAM_BASE
hex
default 0xffe00000
config DCACHE_RAM_SIZE
hex
default 0x8000
endif # CPU_VIA_NANO

View File

@ -1,26 +0,0 @@
##
## This file is part of the coreboot project.
##
## 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.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
subdirs-y += ../../x86/tsc
subdirs-y += ../../x86/mtrr
subdirs-y += ../../x86/lapic
subdirs-y += ../../x86/cache
subdirs-y += ../../x86/smm
ramstage-y += nano_init.c
ramstage-y += update_ucode.c
cpu_microcode_bins += 3rdparty/blobs/cpu/via/nano/microcode.bin
cpu_incs-y += $(src)/cpu/via/car/cache_as_ram.inc

View File

@ -1,4 +0,0 @@
unsigned int array[3588] =
{
#include "../../../../3rdparty/blobs/cpu/via/nano/microcode.h"
};

View File

@ -1,196 +0,0 @@
/*
* This file is part of the coreboot project.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "update_ucode.h"
#include <console/console.h>
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/lapic.h>
#include <cpu/x86/cache.h>
#include <delay.h>
#define MODEL_NANO 0x2
#define MODEL_NANO_3000_B0 0x8
#define MODEL_NANO_3000_B2 0xa
#define NANO_MYSTERIOUS_MSR 0x120e
static void nano_finish_fid_vid_transition(void)
{
msr_t msr;
/* Wait until the power transition ends */
int cnt = 0;
do {
udelay(16);
msr = rdmsr(IA32_PERF_STATUS);
cnt++;
if (cnt > 128) {
printk(BIOS_WARNING,
"Error while updating multiplier and voltage\n");
break;
}
} while (msr.lo & ((1 << 16) | (1 << 17)));
/* Print the new FID and Voltage */
u8 cur_vid = (msr.lo >> 0) & 0xff;
u8 cur_fid = (msr.lo >> 8) & 0xff;
printk(BIOS_INFO, "New CPU multiplier: %dx\n", cur_fid);
printk(BIOS_INFO, "New Voltage ID : %dx\n", cur_vid);
}
static void nano_set_max_fid_vid(void)
{
msr_t msr;
/* Get voltage and frequency info */
msr = rdmsr(IA32_PERF_STATUS);
u8 min_fid = (msr.hi >> 24);
u8 max_fid = (msr.hi >> 8) & 0xff;
u8 min_vid = (msr.hi >> 16) & 0xff;
u8 max_vid = (msr.hi >> 0) & 0xff;
u8 cur_vid = (msr.lo >> 0) & 0xff;
u8 cur_fid = (msr.lo >> 8) & 0xff;
printk(BIOS_INFO, "CPU multiplier: %dx (min %dx; max %dx)\n",
cur_fid, min_fid, max_fid);
printk(BIOS_INFO, "Voltage ID : %dx (min %dx; max %dx)\n",
cur_vid, min_vid, max_vid);
if ((cur_fid != max_fid) || (cur_vid != max_vid)) {
/* Set highest frequency and VID */
msr.lo = msr.hi;
msr.hi = 0;
wrmsr(IA32_PERF_CTL, msr);
/* Wait for the transition to complete, otherwise, the CPU
* might reset itself repeatedly */
nano_finish_fid_vid_transition();
}
/* As a side note, if we didn't update the microcode by this point, the
* second PLL will not lock correctly. The clock will still be provided
* by the first PLL, and execution will continue normally, ___until___
* the CPU switches PLL. Once that happens we will no longer have a
* working clock source, and the CPU will hang
* Moral of the story: update the microcode, or don't change FID
* This check is handled before calling nano_power() */
}
static void nano_power(void)
{
msr_t msr;
/* Enable Powersaver */
msr = rdmsr(IA32_MISC_ENABLE);
msr.lo |= (1 << 16);
wrmsr(IA32_MISC_ENABLE, msr);
/* Enable 6 bit or 7-bit VRM support
* This MSR is not documented by VIA docs, other than setting these
* bits */
msr = rdmsr(NANO_MYSTERIOUS_MSR);
msr.lo |= ((1 << 7) | (1 << 4));
/* FIXME: Do we have a 6-bit or 7-bit VRM?
* set bit [5] for 7-bit, or don't set it for 6 bit VRM
* This will probably require a Kconfig option
* My board has a 7-bit VRM, so I can't test the 6-bit VRM stuff */
msr.lo |= (1 << 5);
wrmsr(NANO_MYSTERIOUS_MSR, msr);
/* Set the maximum frequency and voltage */
nano_set_max_fid_vid();
/* Enable TM3 */
msr = rdmsr(IA32_MISC_ENABLE);
msr.lo |= ((1 << 3) | (1 << 13));
wrmsr(IA32_MISC_ENABLE, msr);
u8 stepping = (cpuid_eax(0x1)) & 0xf;
if (stepping >= MODEL_NANO_3000_B0) {
/* Hello Nano 3000. The Terminator needs a CPU upgrade */
/* Enable C1e, C2e, C3e, and C4e states */
msr = rdmsr(IA32_MISC_ENABLE);
msr.lo |= ((1 << 25) | (1 << 26) | (1 << 31)); /* C1e, C2e, C3e */
msr.hi |= (1 << 0); /* C4e */
wrmsr(IA32_MISC_ENABLE, msr);
}
/* Lock on Powersaver */
msr = rdmsr(IA32_MISC_ENABLE);
msr.lo |= (1 << 20);
wrmsr(IA32_MISC_ENABLE, msr);
}
static void nano_init(struct device *dev)
{
struct cpuinfo_x86 c;
get_fms(&c, dev->device);
/* We didn't test this on the Nano 1000/2000 series, so warn the user */
if (c.x86_mask < MODEL_NANO_3000_B0) {
printk(BIOS_EMERG, "WARNING: This CPU has not been tested. "
"Please report any issues encountered.\n");
}
switch (c.x86_mask) {
case MODEL_NANO:
printk(BIOS_INFO, "VIA Nano");
break;
case MODEL_NANO_3000_B0:
printk(BIOS_INFO, "VIA Nano 3000 rev B0");
break;
case MODEL_NANO_3000_B2:
printk(BIOS_INFO, "VIA Nano 3000 rev B2");
break;
default:
printk(BIOS_EMERG, "Stepping not recognized: %x\n", c.x86_mask);
}
printk(BIOS_INFO, "\n");
/* We only read microcode from CBFS. If we don't have any microcode in
* CBFS, we'll just get back with 0 updates. User choice FTW. */
unsigned int n_updates = nano_update_ucode();
if (n_updates != 0){
nano_power();
} else {
/* Changing the frequency or voltage without first updating the
* microcode will hang the CPU, so just don't do it */
printk(BIOS_EMERG, "WARNING: CPU Microcode not updated.\n"
" Will not change frequency, as this may hang the CPU.\n");
}
/* Turn on cache */
x86_enable_cache();
/* Set up Memory Type Range Registers */
x86_setup_mtrrs();
x86_mtrr_check();
/* Enable the local CPU APICs */
setup_lapic();
}
static struct device_operations cpu_dev_ops = {
.init = nano_init,
};
static const struct cpu_device_id cpu_table[] = {
{X86_VENDOR_CENTAUR, 0x06f2}, // VIA NANO 1000/2000 Series
{X86_VENDOR_CENTAUR, 0x06f8}, // VIA NANO 3000 rev B0
{X86_VENDOR_CENTAUR, 0x06fa}, // VIA NANO 3000 rev B2
{0, 0},
};
static const struct cpu_driver driver __cpu_driver = {
.ops = &cpu_dev_ops,
.id_table = cpu_table,
};

View File

@ -1,143 +0,0 @@
/*
* This file is part of the coreboot project.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "update_ucode.h"
#include <cpu/x86/msr.h>
#include <console/console.h>
#include <stddef.h>
#include <arch/cpu.h>
#include <cbfs.h>
static ucode_update_status nano_apply_ucode(const nano_ucode_header *ucode)
{
printk(BIOS_SPEW, "Attempting to apply microcode update\n");
msr_t msr;
/* Address of ucode block goes in msr.lo for 32-bit mode
* Now remember, we need to pass the address of the actual microcode,
* not the header. The header is just there to help us. */
msr.lo = (unsigned int)(&(ucode->ucode_start));
msr.hi = 0;
wrmsr(IA32_BIOS_UPDT_TRIG, msr);
/* Let's see if we updated successfully */
msr = rdmsr(MSR_UCODE_UPDATE_STATUS);
return msr.lo & 0x07;
}
static void nano_print_ucode_info(const nano_ucode_header *ucode)
{
printk(BIOS_SPEW, "Microcode update information:\n");
printk(BIOS_SPEW, "Name: %8s\n", ucode->name);
printk(BIOS_SPEW, "Date: %u/%u/%u\n", ucode->month,
ucode->day, ucode->year);
}
static ucode_validity nano_ucode_is_valid(const nano_ucode_header *ucode)
{
/* We must have a valid signature */
if (ucode->signature != NANO_UCODE_SIGNATURE)
return NANO_UCODE_SIGNATURE_ERROR;
/* The size of the head must be exactly 12 double words */
if ((ucode->total_size - ucode->payload_size) != NANO_UCODE_HEADER_SIZE)
return NANO_UCODE_WRONG_SIZE;
/* How about a checksum ? Checksum must be 0
* Two's complement done over the entire file, including the header */
int i;
u32 check = 0;
u32 *raw = (void *) ucode;
for (i = 0; i < ((ucode->total_size) >> 2); i++) {
check += raw[i];
}
if (check != 0)
return NANO_UCODE_CHECKSUM_FAIL;
/* Made it here huh? Then it looks valid to us.
* If there's anything else wrong, the CPU will reject the update */
return NANO_UCODE_VALID;
}
static void nano_print_ucode_status(ucode_update_status stat)
{
switch (stat)
{
case UCODE_UPDATE_SUCCESS:
printk(BIOS_INFO, "Microcode update successful.\n");
break;
case UCODE_UPDATE_FAIL:
printk(BIOS_ALERT, "Microcode update failed, bad environment."
"Update was not applied.\n");
break;
case UCODE_UPDATE_WRONG_CPU:
printk(BIOS_ALERT, "Update not applicable to this CPU.\n");
break;
case UCODE_INVALID_UPDATE_BLOCK:
printk(BIOS_ALERT, "Microcode block invalid."
"Update was not applied.\n");
break;
default:
printk(BIOS_ALERT, "Unknown status. No update applied.\n");
}
}
unsigned int nano_update_ucode(void)
{
size_t i;
unsigned int n_updates = 0;
u32 fms = cpuid_eax(0x1);
/* Considering we are running with eXecute-In-Place (XIP), there's no
* need to worry that accessing data from ROM will slow us down.
* Microcode data should be aligned to a 4-byte boundary, but CBFS
* already does that for us (Do you, CBFS?) */
u32 *ucode_data;
size_t ucode_len;
ucode_data = cbfs_boot_map_with_leak("cpu_microcode_blob.bin",
CBFS_TYPE_MICROCODE, &ucode_len);
/* Oops, did you forget to include the microcode ? */
if (ucode_data == NULL) {
printk(BIOS_ALERT, "WARNING: No microcode file found in CBFS. "
"Aborting microcode updates\n");
return 0;
}
/* We might do a lot of loops searching for the microcode updates, but
* keep in mind, nano_ucode_is_valid searches for the signature before
* doing anything else. */
for (i = 0; i < (ucode_len >> 2); /* don't increment i here */)
{
ucode_update_status stat;
const nano_ucode_header * ucode = (void *)(&ucode_data[i]);
if (nano_ucode_is_valid(ucode) != NANO_UCODE_VALID) {
i++;
continue;
}
/* Since we have a valid microcode, there's no need to search
* in this region, so we restart our search at the end of this
* microcode */
i += (ucode->total_size >> 2);
/* Is the microcode compatible with our CPU? */
if (ucode->applicable_fms != fms) continue;
/* For our most curious users */
nano_print_ucode_info(ucode);
/* The meat of the pie */
stat = nano_apply_ucode(ucode);
/* The user might want to know how the update went */
nano_print_ucode_status(stat);
if (stat == UCODE_UPDATE_SUCCESS) n_updates++;
}
return n_updates;
}

View File

@ -1,65 +0,0 @@
/*
* This file is part of the coreboot project.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __UPDATE_UCODE_H
#define __UPDATE_UCODE_H
#include <stdint.h>
#define MSR_UCODE_UPDATE_STATUS 0x00001205
#define NANO_UCODE_SIGNATURE 0x53415252
#define NANO_UCODE_HEADER_SIZE 0x30
/* These are values returned by the CPU after we attempt microcode updates.
* We care what these values are exactly, so we define them to be sure */
typedef enum {
UCODE_UPDATE_NOT_ATTEMPTED = 0x0,
UCODE_UPDATE_SUCCESS = 0x1,
UCODE_UPDATE_FAIL = 0x2,
UCODE_UPDATE_WRONG_CPU = 0x3,
UCODE_INVALID_UPDATE_BLOCK = 0x4,
} ucode_update_status;
typedef enum {
NANO_UCODE_VALID = 0, /* We only care that valid == 0 */
NANO_UCODE_SIGNATURE_ERROR,
NANO_UCODE_WRONG_SIZE,
NANO_UCODE_CHECKSUM_FAIL,
} ucode_validity;
typedef struct {
u32 signature; /* NANO_UCODE_SIGNATURE */
u32 update_revision; /* Revision of the update header */
u16 year; /* Year of patch release */
u8 day; /* Day of patch release */
u8 month; /* Month of patch release */
u32 applicable_fms; /* Fam/model/stepping to which ucode applies */
u32 checksum; /* Two's complement checksum of ucode+header */
u32 loader_revision; /* Revision of hardware ucode update loader*/
u32 rfu_1; /* Reserved for future use */
u32 payload_size; /* Size of the ucode payload only */
u32 total_size; /* Size of the ucode, including header */
char name[8]; /* ASCII string of ucode filename */
u32 rfu_2; /* Reserved for future use */
/* First double-word of the ucode payload
* Its address represents the beginning of the ucode update we need to
* send to the CPU */
u32 ucode_start;
} nano_ucode_header;
unsigned int nano_update_ucode(void);
#endif /* __UPDATE_UCODE_H */