u-boot-brain/arch/x86/lib/coreboot_table.c
Tom Rini 83d290c56f SPDX: Convert all of our single license tags to Linux Kernel style
When U-Boot started using SPDX tags we were among the early adopters and
there weren't a lot of other examples to borrow from.  So we picked the
area of the file that usually had a full license text and replaced it
with an appropriate SPDX-License-Identifier: entry.  Since then, the
Linux Kernel has adopted SPDX tags and they place it as the very first
line in a file (except where shebangs are used, then it's second line)
and with slightly different comment styles than us.

In part due to community overlap, in part due to better tag visibility
and in part for other minor reasons, switch over to that style.

This commit changes all instances where we have a single declared
license in the tag as both the before and after are identical in tag
contents.  There's also a few places where I found we did not have a tag
and have introduced one.

Signed-off-by: Tom Rini <trini@konsulko.com>
2018-05-07 09:34:12 -04:00

172 lines
4.5 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <vbe.h>
#include <asm/acpi_s3.h>
#include <asm/coreboot_tables.h>
#include <asm/e820.h>
DECLARE_GLOBAL_DATA_PTR;
int high_table_reserve(void)
{
/* adjust stack pointer to reserve space for configuration tables */
gd->arch.high_table_limit = gd->start_addr_sp;
gd->start_addr_sp -= CONFIG_HIGH_TABLE_SIZE;
gd->arch.high_table_ptr = gd->start_addr_sp;
/* clear the memory */
#ifdef CONFIG_HAVE_ACPI_RESUME
if (gd->arch.prev_sleep_state != ACPI_S3)
#endif
memset((void *)gd->arch.high_table_ptr, 0,
CONFIG_HIGH_TABLE_SIZE);
gd->start_addr_sp &= ~0xf;
return 0;
}
void *high_table_malloc(size_t bytes)
{
u32 new_ptr;
void *ptr;
new_ptr = gd->arch.high_table_ptr + bytes;
if (new_ptr >= gd->arch.high_table_limit)
return NULL;
ptr = (void *)gd->arch.high_table_ptr;
gd->arch.high_table_ptr = new_ptr;
return ptr;
}
/**
* cb_table_init() - initialize a coreboot table header
*
* This fills in the coreboot table header signature and the header bytes.
* Other fields are set to zero.
*
* @cbh: coreboot table header address
*/
static void cb_table_init(struct cb_header *cbh)
{
memset(cbh, 0, sizeof(struct cb_header));
memcpy(cbh->signature, "LBIO", 4);
cbh->header_bytes = sizeof(struct cb_header);
}
/**
* cb_table_add_entry() - add a coreboot table entry
*
* This increases the coreboot table entry size with added table entry length
* and increases entry count by 1.
*
* @cbh: coreboot table header address
* @cbr: to be added table entry address
* @return: pointer to next table entry address
*/
static u32 cb_table_add_entry(struct cb_header *cbh, struct cb_record *cbr)
{
cbh->table_bytes += cbr->size;
cbh->table_entries++;
return (u32)cbr + cbr->size;
}
/**
* cb_table_finalize() - finalize the coreboot table
*
* This calculates the checksum for all coreboot table entries as well as
* the checksum for the coreboot header itself.
*
* @cbh: coreboot table header address
*/
static void cb_table_finalize(struct cb_header *cbh)
{
struct cb_record *cbr = (struct cb_record *)(cbh + 1);
cbh->table_checksum = compute_ip_checksum(cbr, cbh->table_bytes);
cbh->header_checksum = compute_ip_checksum(cbh, cbh->header_bytes);
}
void write_coreboot_table(u32 addr, struct memory_area *cfg_tables)
{
struct cb_header *cbh = (struct cb_header *)addr;
struct cb_record *cbr;
struct cb_memory *mem;
struct cb_memory_range *map;
struct e820_entry e820[32];
struct cb_framebuffer *fb;
struct vesa_mode_info *vesa;
int i, num;
cb_table_init(cbh);
cbr = (struct cb_record *)(cbh + 1);
/*
* Two type of coreboot table entries are generated by us.
* They are 'struct cb_memory' and 'struct cb_framebuffer'.
*/
/* populate memory map table */
mem = (struct cb_memory *)cbr;
mem->tag = CB_TAG_MEMORY;
map = mem->map;
/* first install e820 defined memory maps */
num = install_e820_map(ARRAY_SIZE(e820), e820);
for (i = 0; i < num; i++) {
map->start.lo = e820[i].addr & 0xffffffff;
map->start.hi = e820[i].addr >> 32;
map->size.lo = e820[i].size & 0xffffffff;
map->size.hi = e820[i].size >> 32;
map->type = e820[i].type;
map++;
}
/* then install all configuration tables */
while (cfg_tables->size) {
map->start.lo = cfg_tables->start & 0xffffffff;
map->start.hi = cfg_tables->start >> 32;
map->size.lo = cfg_tables->size & 0xffffffff;
map->size.hi = cfg_tables->size >> 32;
map->type = CB_MEM_TABLE;
map++;
num++;
cfg_tables++;
}
mem->size = num * sizeof(struct cb_memory_range) +
sizeof(struct cb_record);
cbr = (struct cb_record *)cb_table_add_entry(cbh, cbr);
/* populate framebuffer table if we have sane vesa info */
vesa = &mode_info.vesa;
if (vesa->x_resolution && vesa->y_resolution) {
fb = (struct cb_framebuffer *)cbr;
fb->tag = CB_TAG_FRAMEBUFFER;
fb->size = sizeof(struct cb_framebuffer);
fb->x_resolution = vesa->x_resolution;
fb->y_resolution = vesa->y_resolution;
fb->bits_per_pixel = vesa->bits_per_pixel;
fb->bytes_per_line = vesa->bytes_per_scanline;
fb->physical_address = vesa->phys_base_ptr;
fb->red_mask_size = vesa->red_mask_size;
fb->red_mask_pos = vesa->red_mask_pos;
fb->green_mask_size = vesa->green_mask_size;
fb->green_mask_pos = vesa->green_mask_pos;
fb->blue_mask_size = vesa->blue_mask_size;
fb->blue_mask_pos = vesa->blue_mask_pos;
fb->reserved_mask_size = vesa->reserved_mask_size;
fb->reserved_mask_pos = vesa->reserved_mask_pos;
cbr = (struct cb_record *)cb_table_add_entry(cbh, cbr);
}
cb_table_finalize(cbh);
}