blob: 1b02f8b7dabc08025e7ea32470e7ea004f50ceda [file] [log] [blame]
Aaron Durbin716738a2013-05-10 00:33:32 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 Google, Inc.
5 *
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.
Aaron Durbin716738a2013-05-10 00:33:32 -050014 */
15
16#include <string.h>
17#include <stddef.h>
18#include <console/console.h>
19#include <cbmem.h>
Stefan Reinauerfd4f4132013-06-19 12:25:44 -070020#include <arch/early_variables.h>
Ben Gardnere597e632015-11-23 20:47:59 -060021#include <symbols.h>
Aaron Durbin716738a2013-05-10 00:33:32 -050022
Marc Jones78687972015-04-22 23:16:31 -060023#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_0)
24#include <drivers/intel/fsp1_0/fsp_util.h>
Martin Roth582b2ae2015-01-11 14:29:29 -070025#endif
Aaron Durbin716738a2013-05-10 00:33:32 -050026typedef void (* const car_migration_func_t)(void);
27
28extern car_migration_func_t _car_migrate_start;
Aaron Durbin716738a2013-05-10 00:33:32 -050029
Aaron Durbin716738a2013-05-10 00:33:32 -050030/*
31 * The car_migrated global variable determines if the cache-as-ram space has
Martin Roth4c3ab732013-07-08 16:23:54 -060032 * been migrated to real RAM. It does this by assuming the following things:
Aaron Durbin716738a2013-05-10 00:33:32 -050033 * 1. cache-as-ram space is zero'd out once it is set up.
34 * 2. Either the cache-as-ram space is memory-backed after getting torn down
35 * or the space returns 0xff's for each byte read.
36 * Based on these 2 attributes there is the ability to tell when the
37 * cache-as-ram region has been migrated.
38 */
39static int car_migrated CAR_GLOBAL;
40
Martin Roth582b2ae2015-01-11 14:29:29 -070041/** @brief returns pointer to a CAR variable, before or after migration.
42 *
43 * @param var pointer to the CAR variable
44 */
Aaron Durbin716738a2013-05-10 00:33:32 -050045void *car_get_var_ptr(void *var)
46{
Martin Roth582b2ae2015-01-11 14:29:29 -070047 char *migrated_base = NULL;
Aaron Durbin716738a2013-05-10 00:33:32 -050048 int offset;
Lee Leahy5f945412017-03-15 13:59:00 -070049 void *_car_start = _car_relocatable_data_start;
50 void *_car_end = _car_relocatable_data_end;
Aaron Durbin716738a2013-05-10 00:33:32 -050051
52 /* If the cache-as-ram has not been migrated return the pointer
53 * passed in. */
54 if (!car_migrated)
55 return var;
56
57 if (var < _car_start || var >= _car_end) {
58 printk(BIOS_ERR,
59 "Requesting CAR variable outside of CAR region: %p\n",
60 var);
61 return var;
62 }
63
Marc Jones78687972015-04-22 23:16:31 -060064#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_0)
Lee Leahy8bad6d22017-03-15 14:15:38 -070065 migrated_base = (char *)find_saved_temp_mem(
Martin Roth582b2ae2015-01-11 14:29:29 -070066 *(void **)CBMEM_FSP_HOB_PTR);
Ben Gardnere597e632015-11-23 20:47:59 -060067 /* FSP 1.0 migrates the entire DCACHE RAM */
68 offset = (char *)var - (char *)CONFIG_DCACHE_RAM_BASE;
Martin Roth582b2ae2015-01-11 14:29:29 -070069#else
Aaron Durbin716738a2013-05-10 00:33:32 -050070 migrated_base = cbmem_find(CBMEM_ID_CAR_GLOBALS);
Ben Gardnere597e632015-11-23 20:47:59 -060071 offset = (char *)var - (char *)_car_start;
Martin Roth582b2ae2015-01-11 14:29:29 -070072#endif
Aaron Durbin716738a2013-05-10 00:33:32 -050073
Martin Roth582b2ae2015-01-11 14:29:29 -070074 if (migrated_base == NULL)
Lee Leahy8bad6d22017-03-15 14:15:38 -070075 die("CAR: Could not find migration base!\n");
Aaron Durbin716738a2013-05-10 00:33:32 -050076
Aaron Durbin716738a2013-05-10 00:33:32 -050077 return &migrated_base[offset];
78}
79
Kyösti Mälkkie4554252014-12-31 18:34:59 +020080/*
81 * Update a CAR_GLOBAL variable var, originally pointing to CAR region,
82 * with the address in migrated CAR region in DRAM.
83 */
84void *car_sync_var_ptr(void *var)
85{
Lee Leahy5f945412017-03-15 13:59:00 -070086 void **mig_var = car_get_var_ptr(var);
87 void *_car_start = _car_relocatable_data_start;
88 void *_car_end = _car_relocatable_data_end;
Kyösti Mälkkie4554252014-12-31 18:34:59 +020089
90 /* Not moved or migrated yet. */
91 if (mig_var == var)
92 return mig_var;
93
Ben Gardnere597e632015-11-23 20:47:59 -060094 /*
95 * Migrate the cbmem console pointer for FSP 1.0 platforms. Otherwise,
96 * keep console buffer in CAR until cbmemc_reinit() moves it.
97 */
98 if (*mig_var == _preram_cbmem_console) {
99 if (IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_0))
100 *mig_var += (char *)mig_var - (char *)var;
101 return mig_var;
102 }
103
Kyösti Mälkkie4554252014-12-31 18:34:59 +0200104 /* It's already pointing outside car.global_data. */
105 if (*mig_var < _car_start || *mig_var > _car_end)
106 return mig_var;
107
Kyösti Mälkkie4554252014-12-31 18:34:59 +0200108 /* Move the pointer by the same amount the variable storing it was
109 * moved by.
110 */
111 *mig_var += (char *)mig_var - (char *)var;
112
113 return mig_var;
114}
115
Julius Wernera9285192017-05-18 14:44:08 -0700116int car_active(void)
117{
118 return !car_migrated;
119}
120
Kyösti Mälkki87acccc2014-12-19 09:19:29 +0200121static void do_car_migrate_variables(void)
Aaron Durbin716738a2013-05-10 00:33:32 -0500122{
123 void *migrated_base;
Aaron Durbin0dc73542015-07-16 16:07:02 -0500124 size_t car_size = car_data_size();
Aaron Durbin716738a2013-05-10 00:33:32 -0500125
Aaron Durbin7f5897a2013-06-21 18:02:26 +0300126 /* Check if already migrated. */
127 if (car_migrated)
128 return;
129
Aaron Durbin0dc73542015-07-16 16:07:02 -0500130 migrated_base = cbmem_add(CBMEM_ID_CAR_GLOBALS, car_size);
Aaron Durbin716738a2013-05-10 00:33:32 -0500131
132 if (migrated_base == NULL) {
133 printk(BIOS_ERR, "Could not migrate CAR data!\n");
134 return;
135 }
136
Andrey Petrovdd56de92016-02-25 17:22:17 -0800137 memcpy(migrated_base, _car_relocatable_data_start, car_size);
Aaron Durbin716738a2013-05-10 00:33:32 -0500138
139 /* Mark that the data has been moved. */
140 car_migrated = ~0;
Kyösti Mälkki91fac612014-12-31 20:55:19 +0200141}
Aaron Durbin716738a2013-05-10 00:33:32 -0500142
Aaron Durbin41607a42015-06-09 13:54:10 -0500143static void car_migrate_variables(int is_recovery)
Kyösti Mälkki91fac612014-12-31 20:55:19 +0200144{
Martin Roth9346d502015-07-15 18:32:43 -0600145 if (!IS_ENABLED(PLATFORM_USES_FSP1_0))
Kyösti Mälkki87acccc2014-12-19 09:19:29 +0200146 do_car_migrate_variables();
147}
Kyösti Mälkki4fbac462015-01-07 04:48:43 +0200148ROMSTAGE_CBMEM_INIT_HOOK(car_migrate_variables)