GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,9 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2015 Google, Inc
obj-y += fsp_car.o
obj-y += fsp_common.o
obj-y += fsp_dram.o
obj-$(CONFIG_VIDEO_FSP) += fsp_graphics.o
obj-y += fsp_support.o
@@ -0,0 +1,111 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
*/
#include <config.h>
#include <asm/post.h>
.globl car_init
car_init:
/*
* Note: ebp holds the BIST value (built-in self test) so far, but ebp
* will be destroyed through the FSP call, thus we have to test the
* BIST value here before we call into FSP.
*/
test %ebp, %ebp
jz car_init_start
post_code(POST_BIST_FAILURE)
jmp die
car_init_start:
post_code(POST_CAR_START)
lea fsp_find_header_romstack, %esp
jmp fsp_find_header
fsp_find_header_ret:
/* EAX points to FSP_INFO_HEADER */
mov %eax, %ebp
/* sanity test */
cmp $CONFIG_FSP_ADDR, %eax
jb die
/* calculate TempRamInitEntry address */
mov 0x30(%ebp), %eax
add 0x1c(%ebp), %eax
/* call FSP TempRamInitEntry to setup temporary stack */
lea temp_ram_init_romstack, %esp
jmp *%eax
temp_ram_init_ret:
addl $4, %esp
cmp $0, %eax
jnz car_init_fail
post_code(POST_CAR_CPU_CACHE)
/*
* The FSP TempRamInit initializes the ecx and edx registers to
* point to a temporary but writable memory range (Cache-As-RAM).
* ecx: the start of this temporary memory range,
* edx: the end of this range.
*/
/* stack grows down from top of CAR */
movl %edx, %esp
subl $4, %esp
xor %esi, %esi
jmp car_init_done
.global fsp_init_done
fsp_init_done:
/*
* We come here from fsp_continue() with eax pointing to the HOB list.
* Save eax to esi temporarily.
*/
movl %eax, %esi
car_init_done:
/*
* Re-initialize the ebp (BIST) to zero, as we already reach here
* which means we passed BIST testing before.
*/
xorl %ebp, %ebp
jmp car_init_ret
car_init_fail:
post_code(POST_CAR_FAILURE)
die:
hlt
jmp die
hlt
/*
* The function call before CAR initialization is tricky. It cannot
* be called using the 'call' instruction but only the 'jmp' with
* the help of a handcrafted stack in the ROM. The stack needs to
* contain the function return address as well as the parameters.
*/
.balign 4
fsp_find_header_romstack:
.long fsp_find_header_ret
.balign 4
temp_ram_init_romstack:
.long temp_ram_init_ret
.long temp_ram_init_params
temp_ram_init_params:
_dt_ucode_base_size:
/* These next two fields are filled in by binman */
.globl ucode_base
ucode_base: /* Declared in microcode.h */
.long 0 /* microcode base */
.globl ucode_size
ucode_size: /* Declared in microcode.h */
.long 0 /* microcode size */
.long CONFIG_SYS_MONITOR_BASE /* code region base */
.long CONFIG_SYS_MONITOR_LEN /* code region size */
@@ -0,0 +1,77 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <acpi_s3.h>
#include <dm.h>
#include <errno.h>
#include <rtc.h>
#include <asm/cmos_layout.h>
#include <asm/early_cmos.h>
#include <asm/io.h>
#include <asm/mrccache.h>
#include <asm/post.h>
#include <asm/processor.h>
#include <asm/fsp1/fsp_support.h>
DECLARE_GLOBAL_DATA_PTR;
int arch_fsp_init(void)
{
void *nvs;
int stack = CONFIG_FSP_TEMP_RAM_ADDR;
int boot_mode = BOOT_FULL_CONFIG;
#ifdef CONFIG_HAVE_ACPI_RESUME
int prev_sleep_state = chipset_prev_sleep_state();
gd->arch.prev_sleep_state = prev_sleep_state;
#endif
if (!gd->arch.hob_list) {
if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE))
nvs = fsp_prepare_mrc_cache();
else
nvs = NULL;
#ifdef CONFIG_HAVE_ACPI_RESUME
if (prev_sleep_state == ACPI_S3) {
if (nvs == NULL) {
/* If waking from S3 and no cache then */
debug("No MRC cache found in S3 resume path\n");
post_code(POST_RESUME_FAILURE);
/* Clear Sleep Type */
chipset_clear_sleep_state();
/* Reboot */
debug("Rebooting..\n");
outb(SYS_RST | RST_CPU, IO_PORT_RESET);
/* Should not reach here.. */
panic("Reboot System");
}
/*
* DM is not available yet at this point, hence call
* CMOS access library which does not depend on DM.
*/
stack = cmos_read32(CMOS_FSP_STACK_ADDR);
boot_mode = BOOT_ON_S3_RESUME;
}
#endif
/*
* The first time we enter here, call fsp_init().
* Note the execution does not return to this function,
* instead it jumps to fsp_continue().
*/
fsp_init(stack, boot_mode, nvs);
} else {
/*
* The second time we enter here, adjust the size of malloc()
* pool before relocation. Given gd->malloc_base was adjusted
* after the call to board_init_f_init_reserve() in arch/x86/
* cpu/start.S, we should fix up gd->malloc_limit here.
*/
gd->malloc_limit += CONFIG_FSP_SYS_MALLOC_F_LEN;
}
return 0;
}
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <asm/fsp/fsp_support.h>
int dram_init(void)
{
int ret;
/* The FSP has already set up DRAM, so grab the info we need */
ret = fsp_scan_for_ram_size();
if (ret)
return ret;
if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE))
gd->arch.mrc_output = fsp_get_nvs_data(gd->arch.hob_list,
&gd->arch.mrc_output_len);
return 0;
}
/*
* This function looks for the highest region of memory lower than 4GB which
* has enough space for U-Boot where U-Boot is aligned on a page boundary.
* It overrides the default implementation found elsewhere which simply
* picks the end of ram, wherever that may be. The location of the stack,
* the relocation address, and how far U-Boot is moved by relocation are
* set in the global data structure.
*/
ulong board_get_usable_ram_top(ulong total_size)
{
return fsp_get_usable_lowmem_top(gd->arch.hob_list);
}
@@ -0,0 +1,127 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <dm.h>
#include <vbe.h>
#include <video.h>
#include <asm/fsp1/fsp_support.h>
DECLARE_GLOBAL_DATA_PTR;
struct pixel {
u8 pos;
u8 size;
};
static const struct fsp_framebuffer {
struct pixel red;
struct pixel green;
struct pixel blue;
struct pixel rsvd;
} fsp_framebuffer_format_map[] = {
[pixel_rgbx_8bpc] = { {0, 8}, {8, 8}, {16, 8}, {24, 8} },
[pixel_bgrx_8bpc] = { {16, 8}, {8, 8}, {0, 8}, {24, 8} },
};
static int save_vesa_mode(struct vesa_mode_info *vesa)
{
const struct hob_graphics_info *ginfo;
const struct fsp_framebuffer *fbinfo;
ginfo = fsp_get_graphics_info(gd->arch.hob_list, NULL);
/*
* If there is no graphics info structure, bail out and keep
* running on the serial console.
*
* Note: on some platforms (eg: Braswell), the FSP will not produce
* the graphics info HOB unless you plug some cables to the display
* interface (eg: HDMI) on the board.
*/
if (!ginfo) {
debug("FSP graphics hand-off block not found\n");
return -ENXIO;
}
vesa->x_resolution = ginfo->width;
vesa->y_resolution = ginfo->height;
vesa->bits_per_pixel = 32;
vesa->bytes_per_scanline = ginfo->pixels_per_scanline * 4;
vesa->phys_base_ptr = ginfo->fb_base;
if (ginfo->pixel_format >= pixel_bitmask) {
debug("FSP set unknown framebuffer format: %d\n",
ginfo->pixel_format);
return -EINVAL;
}
fbinfo = &fsp_framebuffer_format_map[ginfo->pixel_format];
vesa->red_mask_size = fbinfo->red.size;
vesa->red_mask_pos = fbinfo->red.pos;
vesa->green_mask_size = fbinfo->green.size;
vesa->green_mask_pos = fbinfo->green.pos;
vesa->blue_mask_size = fbinfo->blue.size;
vesa->blue_mask_pos = fbinfo->blue.pos;
vesa->reserved_mask_size = fbinfo->rsvd.size;
vesa->reserved_mask_pos = fbinfo->rsvd.pos;
return 0;
}
static int fsp_video_probe(struct udevice *dev)
{
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
struct vesa_mode_info *vesa = &mode_info.vesa;
int ret;
printf("Video: ");
/* Initialize vesa_mode_info structure */
ret = save_vesa_mode(vesa);
if (ret)
goto err;
/*
* The framebuffer base address in the FSP graphics info HOB reflects
* the value assigned by the FSP. After PCI enumeration the framebuffer
* base address may be relocated. Let's get the updated one from device.
*
* For IGD, it seems to be always on BAR2.
*/
vesa->phys_base_ptr = dm_pci_read_bar32(dev, 2);
ret = vbe_setup_video_priv(vesa, uc_priv, plat);
if (ret)
goto err;
printf("%dx%dx%d\n", uc_priv->xsize, uc_priv->ysize,
vesa->bits_per_pixel);
return 0;
err:
printf("No video mode configured in FSP!\n");
return ret;
}
static const struct udevice_id fsp_video_ids[] = {
{ .compatible = "fsp-fb" },
{ }
};
U_BOOT_DRIVER(fsp_video) = {
.name = "fsp_video",
.id = UCLASS_VIDEO,
.of_match = fsp_video_ids,
.probe = fsp_video_probe,
};
static struct pci_device_id fsp_video_supported[] = {
{ PCI_DEVICE_CLASS(PCI_CLASS_DISPLAY_VGA << 8, 0xffff00) },
{ },
};
U_BOOT_PCI_DEVICE(fsp_video, fsp_video_supported);
@@ -0,0 +1,199 @@
// SPDX-License-Identifier: Intel
/*
* Copyright (C) 2013, Intel Corporation
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <asm/fsp1/fsp_support.h>
#include <asm/post.h>
struct fsp_header *__attribute__((optimize("O0"))) fsp_find_header(void)
{
/*
* This function may be called before the a stack is established,
* so special care must be taken. First, it cannot declare any local
* variable using stack. Only register variable can be used here.
* Secondly, some compiler version will add prolog or epilog code
* for the C function. If so the function call may not work before
* stack is ready.
*
* GCC 4.8.1 has been verified to be working for the following codes.
*/
volatile register u8 *fsp asm("eax");
/* Initalize the FSP base */
fsp = (u8 *)CONFIG_FSP_ADDR;
/* Check the FV signature, _FVH */
if (((struct fv_header *)fsp)->sign == EFI_FVH_SIGNATURE) {
/* Go to the end of the FV header and align the address */
fsp += ((struct fv_header *)fsp)->ext_hdr_off;
fsp += ((struct fv_ext_header *)fsp)->ext_hdr_size;
fsp = (u8 *)(((u32)fsp + 7) & 0xFFFFFFF8);
} else {
fsp = 0;
}
/* Check the FFS GUID */
if (fsp &&
((struct ffs_file_header *)fsp)->name.b[0] == FSP_GUID_BYTE0 &&
((struct ffs_file_header *)fsp)->name.b[1] == FSP_GUID_BYTE1 &&
((struct ffs_file_header *)fsp)->name.b[2] == FSP_GUID_BYTE2 &&
((struct ffs_file_header *)fsp)->name.b[3] == FSP_GUID_BYTE3 &&
((struct ffs_file_header *)fsp)->name.b[4] == FSP_GUID_BYTE4 &&
((struct ffs_file_header *)fsp)->name.b[5] == FSP_GUID_BYTE5 &&
((struct ffs_file_header *)fsp)->name.b[6] == FSP_GUID_BYTE6 &&
((struct ffs_file_header *)fsp)->name.b[7] == FSP_GUID_BYTE7 &&
((struct ffs_file_header *)fsp)->name.b[8] == FSP_GUID_BYTE8 &&
((struct ffs_file_header *)fsp)->name.b[9] == FSP_GUID_BYTE9 &&
((struct ffs_file_header *)fsp)->name.b[10] == FSP_GUID_BYTE10 &&
((struct ffs_file_header *)fsp)->name.b[11] == FSP_GUID_BYTE11 &&
((struct ffs_file_header *)fsp)->name.b[12] == FSP_GUID_BYTE12 &&
((struct ffs_file_header *)fsp)->name.b[13] == FSP_GUID_BYTE13 &&
((struct ffs_file_header *)fsp)->name.b[14] == FSP_GUID_BYTE14 &&
((struct ffs_file_header *)fsp)->name.b[15] == FSP_GUID_BYTE15) {
/* Add the FFS header size to find the raw section header */
fsp += sizeof(struct ffs_file_header);
} else {
fsp = 0;
}
if (fsp &&
((struct raw_section *)fsp)->type == EFI_SECTION_RAW) {
/* Add the raw section header size to find the FSP header */
fsp += sizeof(struct raw_section);
} else {
fsp = 0;
}
return (struct fsp_header *)fsp;
}
void fsp_continue(u32 status, void *hob_list)
{
post_code(POST_MRC);
assert(status == 0);
/* The boot loader main function entry */
fsp_init_done(hob_list);
}
void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
{
struct fsp_config_data config_data;
fsp_init_f init;
struct fsp_init_params params;
struct fspinit_rtbuf rt_buf;
struct fsp_header *fsp_hdr;
struct fsp_init_params *params_ptr;
#ifdef CONFIG_FSP_USE_UPD
struct vpd_region *fsp_vpd;
struct upd_region *fsp_upd;
#endif
fsp_hdr = fsp_find_header();
if (fsp_hdr == NULL) {
/* No valid FSP info header was found */
panic("Invalid FSP header");
}
config_data.common.fsp_hdr = fsp_hdr;
config_data.common.stack_top = stack_top;
config_data.common.boot_mode = boot_mode;
#ifdef CONFIG_FSP_USE_UPD
/* Get VPD region start */
fsp_vpd = (struct vpd_region *)(fsp_hdr->img_base +
fsp_hdr->cfg_region_off);
/* Verify the VPD data region is valid */
assert(fsp_vpd->sign == VPD_IMAGE_ID);
fsp_upd = &config_data.fsp_upd;
/* Copy default data from Flash */
memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset),
sizeof(struct upd_region));
/* Verify the UPD data region is valid */
assert(fsp_upd->terminator == UPD_TERMINATOR);
#endif
memset(&rt_buf, 0, sizeof(struct fspinit_rtbuf));
/* Override any configuration if required */
fsp_update_configs(&config_data, &rt_buf);
memset(&params, 0, sizeof(struct fsp_init_params));
params.nvs_buf = nvs_buf;
params.rt_buf = (struct fspinit_rtbuf *)&rt_buf;
params.continuation = (fsp_continuation_f)fsp_asm_continuation;
init = (fsp_init_f)(fsp_hdr->img_base + fsp_hdr->fsp_init);
params_ptr = &params;
post_code(POST_PRE_MRC);
/* Load GDT for FSP */
setup_fsp_gdt();
/*
* Use ASM code to ensure the register value in EAX & EDX
* will be passed into fsp_continue
*/
asm volatile (
"pushl %0;"
"call *%%eax;"
".global fsp_asm_continuation;"
"fsp_asm_continuation:;"
"movl 4(%%esp), %%eax;" /* status */
"movl 8(%%esp), %%edx;" /* hob_list */
"jmp fsp_continue;"
: : "m"(params_ptr), "a"(init)
);
/*
* Should never get here.
* Control will continue from fsp_continue.
* This line below is to prevent the compiler from optimizing
* structure intialization.
*
* DO NOT REMOVE!
*/
init(&params);
}
u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase)
{
fsp_notify_f notify;
struct fsp_notify_params params;
struct fsp_notify_params *params_ptr;
u32 status;
if (!fsp_hdr)
fsp_hdr = (struct fsp_header *)fsp_find_header();
if (fsp_hdr == NULL) {
/* No valid FSP info header */
panic("Invalid FSP header");
}
notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify);
params.phase = phase;
params_ptr = &params;
/*
* Use ASM code to ensure correct parameter is on the stack for
* FspNotify as U-Boot is using different ABI from FSP
*/
asm volatile (
"pushl %1;" /* push notify phase */
"call *%%eax;" /* call FspNotify */
"addl $4, %%esp;" /* clean up the stack */
: "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr)
);
return status;
}