blob: 0c2b45dd1885bc6510257959bd54ba5619239ce3 [file] [log] [blame]
Gabe Black396b0722013-09-26 16:22:09 -07001/*
2 * This file is part of the coreboot project.
3 *
Aaron Durbinc6588c52015-05-15 13:15:34 -05004 * Copyright 2015 Google Inc.
Gabe Black396b0722013-09-26 16:22:09 -07005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Gabe Black396b0722013-09-26 16:22:09 -070014 */
15
Aaron Durbinc6588c52015-05-15 13:15:34 -050016#include <boot_device.h>
Aaron Durbin899d13d2015-05-15 23:39:23 -050017#include <cbfs.h>
18#include <endian.h>
19#include <stdlib.h>
Gabe Black396b0722013-09-26 16:22:09 -070020
Aaron Durbinc6588c52015-05-15 13:15:34 -050021/* The ROM is memory mapped just below 4GiB. Form a pointer for the base. */
Stefan Reinauerfb82ebe2015-08-04 11:14:17 -070022#define rom_base ((void *)(uintptr_t)(0x100000000ULL-CONFIG_ROM_SIZE))
Gabe Black396b0722013-09-26 16:22:09 -070023
Aaron Durbinc6588c52015-05-15 13:15:34 -050024static const struct mem_region_device boot_dev =
25 MEM_REGION_DEV_INIT(rom_base, CONFIG_ROM_SIZE);
26
27const struct region_device *boot_device_ro(void)
Gabe Black396b0722013-09-26 16:22:09 -070028{
Aaron Durbinc6588c52015-05-15 13:15:34 -050029 return &boot_dev.rdev;
Gabe Black396b0722013-09-26 16:22:09 -070030}
Aaron Durbin899d13d2015-05-15 23:39:23 -050031
Aaron Durbin6d720f32015-12-08 17:00:23 -060032static int cbfs_master_header_props(struct cbfs_props *props)
Aaron Durbin899d13d2015-05-15 23:39:23 -050033{
34 struct cbfs_header header;
35 int32_t offset;
36 const struct region_device *bdev;
37
38 bdev = boot_device_ro();
39
40 rdev_readat(bdev, &offset, CONFIG_ROM_SIZE - sizeof(offset),
41 sizeof(offset));
42
43 /* The offset is relative to the end of the media. */
44 offset += CONFIG_ROM_SIZE;
45
46 rdev_readat(bdev, &header , offset, sizeof(header));
47
48 header.magic = ntohl(header.magic);
49 header.romsize = ntohl(header.romsize);
50 header.bootblocksize = ntohl(header.bootblocksize);
Aaron Durbin899d13d2015-05-15 23:39:23 -050051 header.offset = ntohl(header.offset);
52
53 if (header.magic != CBFS_HEADER_MAGIC)
54 return -1;
55
Aaron Durbin899d13d2015-05-15 23:39:23 -050056 props->offset = header.offset;
57 if (CONFIG_ROM_SIZE != header.romsize)
Nico Huber65e33c02015-12-28 20:17:13 +010058 props->offset += CONFIG_ROM_SIZE - header.romsize;
59 props->size = CONFIG_ROM_SIZE;
Aaron Durbin899d13d2015-05-15 23:39:23 -050060 props->size -= props->offset;
61 props->size -= header.bootblocksize;
Patrick Georgi4d3e4c42015-07-14 22:28:27 +020062 props->size = ALIGN_DOWN(props->size, 64);
Aaron Durbin899d13d2015-05-15 23:39:23 -050063
Aaron Durbin899d13d2015-05-15 23:39:23 -050064 return 0;
65}
Aaron Durbin6d720f32015-12-08 17:00:23 -060066
67const struct cbfs_locator cbfs_master_header_locator = {
68 .name = "Master Header Locator",
69 .locate = cbfs_master_header_props,
70};