TianoCore EDK2 master
Loading...
Searching...
No Matches
Flash.c
Go to the documentation of this file.
1
7#include <Library/BaseLib.h>
8#include <Library/DebugLib.h>
9
10#include "VirtHstiDxe.h"
11
12#define WRITE_BYTE_CMD 0x10
13#define BLOCK_ERASE_CMD 0x20
14#define CLEAR_STATUS_CMD 0x50
15#define READ_STATUS_CMD 0x70
16#define READ_DEVID_CMD 0x90
17#define BLOCK_ERASE_CONFIRM_CMD 0xd0
18#define READ_ARRAY_CMD 0xff
19#define CLEARED_ARRAY_STATUS 0x00
20
21/* based on QemuFlashDetected (QemuFlashFvbServicesRuntimeDxe) */
22UINT32
23VirtHstiQemuFirmwareFlashCheck (
24 UINT32 Address
25 )
26{
27 volatile UINT8 *Ptr;
28
29 UINTN Offset;
30 UINT8 OriginalUint8;
31 UINT8 ProbeUint8;
32
33 for (Offset = 0; Offset < EFI_PAGE_SIZE; Offset++) {
34 Ptr = (UINT8 *)(UINTN)(Address + Offset);
35 ProbeUint8 = *Ptr;
36 if ((ProbeUint8 != CLEAR_STATUS_CMD) &&
37 (ProbeUint8 != READ_STATUS_CMD) &&
38 (ProbeUint8 != CLEARED_ARRAY_STATUS))
39 {
40 break;
41 }
42 }
43
44 if (Offset >= EFI_PAGE_SIZE) {
45 DEBUG ((DEBUG_INFO, "%a: check failed\n", __func__));
46 return QEMU_FIRMWARE_FLASH_UNKNOWN;
47 }
48
49 OriginalUint8 = *Ptr;
50 *Ptr = CLEAR_STATUS_CMD;
51 ProbeUint8 = *Ptr;
52 if ((OriginalUint8 != CLEAR_STATUS_CMD) &&
53 (ProbeUint8 == CLEAR_STATUS_CMD))
54 {
55 *Ptr = OriginalUint8;
56 DEBUG ((DEBUG_INFO, "%a: %p behaves as RAM\n", __func__, Ptr));
57 return QEMU_FIRMWARE_FLASH_IS_RAM;
58 }
59
60 *Ptr = READ_STATUS_CMD;
61 ProbeUint8 = *Ptr;
62 if (ProbeUint8 == OriginalUint8) {
63 DEBUG ((DEBUG_INFO, "%a: %p behaves as ROM\n", __func__, Ptr));
64 return QEMU_FIRMWARE_FLASH_IS_ROM;
65 }
66
67 if (ProbeUint8 == READ_STATUS_CMD) {
68 *Ptr = OriginalUint8;
69 DEBUG ((DEBUG_INFO, "%a: %p behaves as RAM\n", __func__, Ptr));
70 return QEMU_FIRMWARE_FLASH_IS_RAM;
71 }
72
73 if (ProbeUint8 == CLEARED_ARRAY_STATUS) {
74 *Ptr = WRITE_BYTE_CMD;
75 *Ptr = OriginalUint8;
76 *Ptr = READ_STATUS_CMD;
77 ProbeUint8 = *Ptr;
78 *Ptr = READ_ARRAY_CMD;
79 if (ProbeUint8 & 0x10 /* programming error */) {
80 DEBUG ((DEBUG_INFO, "%a: %p behaves as FLASH, write-protected\n", __func__, Ptr));
81 return QEMU_FIRMWARE_FLASH_READ_ONLY;
82 } else {
83 DEBUG ((DEBUG_INFO, "%a: %p behaves as FLASH, writable\n", __func__, Ptr));
84 return QEMU_FIRMWARE_FLASH_WRITABLE;
85 }
86 }
87
88 DEBUG ((DEBUG_INFO, "%a: check failed\n", __func__));
89 return QEMU_FIRMWARE_FLASH_UNKNOWN;
90}
UINT64 UINTN
#define DEBUG(Expression)
Definition: DebugLib.h:434