blob: a92fbb3fc8c7f64c10561970cb7dfdca118d7703 [file] [log] [blame]
Andrey Petrov5672dcd2016-02-12 15:12:43 -08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2015 Intel Corp.
5 * (Written by Andrey Petrov <andrey.petrov@intel.com> for Intel Corp.)
6 * (Written by Alexandru Gagniuc <alexandrux.gagniuc@intel.com> for Intel Corp.)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
Martin Rothebabfad2016-04-10 11:09:16 -060012 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
Andrey Petrov5672dcd2016-02-12 15:12:43 -080017 */
18
Furquan Shaikh0be3da52016-06-19 23:20:43 -070019#include <arch/early_variables.h>
Andrey Petrov5672dcd2016-02-12 15:12:43 -080020#include <boot_device.h>
21#include <cbfs.h>
22#include <commonlib/region.h>
23#include <console/console.h>
24#include <fmap.h>
Furquan Shaikhd6c55592016-11-21 12:41:20 -080025#include <soc/flash_ctrlr.h>
Furquan Shaikh8065bd42016-06-21 12:50:13 -070026#include <soc/mmap_boot.h>
Andrey Petrov5672dcd2016-02-12 15:12:43 -080027
28/*
Furquan Shaikh0be3da52016-06-19 23:20:43 -070029 * BIOS region on the flash is mapped right below 4GiB in the address
30 * space. However, 256KiB right below 4GiB is decoded by read-only SRAM and not
31 * boot media.
32 *
Lee Leahy07441b52017-03-09 10:59:25 -080033 * +-----------+ 0
34 * | |
35 * | |
36 * | |
37 * | |
38 * | |
39 * | |
40 * | |
41 * | |
42 * +--------+ | |
43 * | IFD | | |
44 * bios_start +---> +--------+------------------> +-----------+ 4GiB - bios_size
45 * ^ | | ^ | |
46 * | | | | | |
47 * | | | bios_mapped_size | BIOS |
48 * | | BIOS | | | |
49 * bios_size | | | | |
50 * | | | v | |
51 * | | +------------------> +-----------+ 4GiB - 256KiB
52 * | | | | Read only |
53 * v | | | SRAM |
54 * bios_end +---> +--------+ +-----------+ 4GiB
55 * | Device |
56 * | ext |
57 * +--------+
Furquan Shaikh0be3da52016-06-19 23:20:43 -070058 *
Andrey Petrov5672dcd2016-02-12 15:12:43 -080059 */
Andrey Petrov5672dcd2016-02-12 15:12:43 -080060
Furquan Shaikh0be3da52016-06-19 23:20:43 -070061static size_t bios_start CAR_GLOBAL;
62static size_t bios_size CAR_GLOBAL;
Andrey Petrov5672dcd2016-02-12 15:12:43 -080063
Furquan Shaikh0be3da52016-06-19 23:20:43 -070064static struct mem_region_device shadow_dev CAR_GLOBAL;
65static struct xlate_region_device real_dev CAR_GLOBAL;
66
67static void bios_mmap_init(void)
68{
69 size_t size;
70
71 size = car_get_var(bios_size);
72
73 /* If bios_size is initialized, then bail out. */
74 if (size != 0)
75 return;
76
77 size_t start, bios_end, bios_mapped_size;
78 uintptr_t base;
79
80 /*
81 * BIOS_BFPREG provides info about BIOS Flash Primary Region
82 * Base and Limit.
83 * Base and Limit fields are in units of 4KiB.
84 */
Furquan Shaikhd6c55592016-11-21 12:41:20 -080085 uint32_t val = spi_flash_ctrlr_reg_read(SPIBAR_BIOS_BFPREG);
Furquan Shaikh0be3da52016-06-19 23:20:43 -070086
87 start = (val & SPIBAR_BFPREG_PRB_MASK) * 4 * KiB;
88 bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >>
89 SPIBAR_BFPREG_PRL_SHIFT) + 1) * 4 * KiB;
90 size = bios_end - start;
91
Furquan Shaikh0be3da52016-06-19 23:20:43 -070092 /* BIOS region is mapped right below 4G. */
93 base = 4ULL * GiB - size;
94
95 /*
96 * The 256 KiB right below 4G are decoded by readonly SRAM,
97 * not boot media.
98 */
99 bios_mapped_size = size - 256 * KiB;
100
101 struct mem_region_device *shadow_dev_ptr;
102 struct xlate_region_device *real_dev_ptr;
103 shadow_dev_ptr = car_get_var_ptr(&shadow_dev);
104 real_dev_ptr = car_get_var_ptr(&real_dev);
105
Antonello Dettorie5f48d22016-06-22 21:09:08 +0200106 mem_region_device_ro_init(shadow_dev_ptr, (void *)base,
Furquan Shaikh0be3da52016-06-19 23:20:43 -0700107 bios_mapped_size);
108
Antonello Dettorie5f48d22016-06-22 21:09:08 +0200109 xlate_region_device_ro_init(real_dev_ptr, &shadow_dev_ptr->rdev,
Furquan Shaikh0be3da52016-06-19 23:20:43 -0700110 start, bios_mapped_size,
111 CONFIG_ROM_SIZE);
112
113 car_set_var(bios_start, start);
114 car_set_var(bios_size, size);
115}
Andrey Petrov5672dcd2016-02-12 15:12:43 -0800116
117const struct region_device *boot_device_ro(void)
118{
Furquan Shaikh0be3da52016-06-19 23:20:43 -0700119 bios_mmap_init();
120
121 struct xlate_region_device *real_dev_ptr;
122 real_dev_ptr = car_get_var_ptr(&real_dev);
123
124 return &real_dev_ptr->rdev;
Andrey Petrov5672dcd2016-02-12 15:12:43 -0800125}
126
127static int iafw_boot_region_properties(struct cbfs_props *props)
128{
129 struct region regn;
130
131 /* use fmap to locate CBFS area */
132 if (fmap_locate_area("COREBOOT", &regn))
133 return -1;
134
135 props->offset = region_offset(&regn);
136 props->size = region_sz(&regn);
137
138 printk(BIOS_DEBUG, "CBFS @ %zx size %zx\n", props->offset, props->size);
139
140 return 0;
141}
142
143/*
144 * Named cbfs_master_header_locator so that it overrides the default, but
145 * incompatible locator in cbfs.c
146 */
147const struct cbfs_locator cbfs_master_header_locator = {
148 .name = "IAFW Locator",
149 .locate = iafw_boot_region_properties,
150};
Alexandru Gagniuc0a4b47e2016-03-03 13:16:36 -0800151
Furquan Shaikh8065bd42016-06-21 12:50:13 -0700152size_t get_bios_size(void)
153{
154 bios_mmap_init();
155 return car_get_var(bios_size);
156}