]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CapsuleReset.c
MdeModulePkg/CapsuleRuntimeDxe: clean the capsule payload to DRAM
[mirror_edk2.git] / MdeModulePkg / Universal / CapsuleRuntimeDxe / Arm / CapsuleReset.c
1 /** @file
2 ARM implementation of architecture specific routines related to
3 PersistAcrossReset capsules
4
5 Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
6
7 This program and the accompanying materials are licensed and made available
8 under the terms and conditions of the BSD License which accompanies this
9 distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 #include "CapsuleService.h"
18
19 #include <Library/CacheMaintenanceLib.h>
20
21 /**
22 Whether the platform supports capsules that persist across reset. Note that
23 some platforms only support such capsules at boot time.
24
25 @return TRUE if a PersistAcrossReset capsule may be passed to UpdateCapsule()
26 at this time
27 FALSE otherwise
28 **/
29 BOOLEAN
30 IsPersistAcrossResetCapsuleSupported (
31 VOID
32 )
33 {
34 //
35 // ARM requires the capsule payload to be cleaned to the point of coherency
36 // (PoC), but only permits doing so using cache maintenance instructions that
37 // operate on virtual addresses. Since at runtime, we don't know the virtual
38 // addresses of the data structures that make up the scatter/gather list, we
39 // cannot perform the maintenance, and all we can do is give up.
40 //
41 return FeaturePcdGet (PcdSupportUpdateCapsuleReset) && !EfiAtRuntime ();
42 }
43
44 /**
45 Writes Back a range of data cache lines covering a set of capsules in memory.
46
47 Writes Back the data cache lines specified by ScatterGatherList.
48
49 @param ScatterGatherList Physical address of the data structure that
50 describes a set of capsules in memory
51
52 **/
53 VOID
54 CapsuleCacheWriteBack (
55 IN EFI_PHYSICAL_ADDRESS ScatterGatherList
56 )
57 {
58 EFI_CAPSULE_BLOCK_DESCRIPTOR *Desc;
59
60 Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)ScatterGatherList;
61 do {
62 WriteBackDataCacheRange (Desc, sizeof *Desc);
63
64 if (Desc->Length > 0) {
65 WriteBackDataCacheRange ((VOID *)(UINTN)Desc->Union.DataBlock,
66 Desc->Length
67 );
68 Desc++;
69 } else if (Desc->Union.ContinuationPointer > 0) {
70 Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)Desc->Union.ContinuationPointer;
71 }
72 } while (Desc->Length > 0 || Desc->Union.ContinuationPointer > 0);
73
74 WriteBackDataCacheRange (Desc, sizeof *Desc);
75 }