搜尋此網誌

2012年10月22日 星期一

How to translate a main() function to ShellAppMain()?


  • Please generate the four files(test.info, teststrings.uni, test.h, test.c).
  • They will teach you how to translate your main() function to ShellAppMain(). 

/*****************************test.info***********************************/

[defines]
BASE_NAME            = test
FILE_GUID            = 8DF752F2-87B5-4c7b-AA4F-EDDA99DD3058
COMPONENT_TYPE       = APPLICATION

[sources.common]
   ..\ShCommonStrings.uni   
   testStrings.uni
   test.c
   test.h 
                                          
[includes.common]
  .
  ..\Inc
  ..\Library
  $(EDK_SOURCE)\Foundation
  $(EDK_SOURCE)\Foundation\Include
  $(EDK_SOURCE)\Foundation\Include\IndustryStandard
  $(EDK_SOURCE)\Foundation\Efi
  $(EDK_SOURCE)\Foundation\Efi\Include
  $(EDK_SOURCE)\Foundation\FrameWork
  $(EDK_SOURCE)\Foundation\FrameWork\Include
  $(EDK_SOURCE)\Foundation\Core\Dxe
  $(DEST_DIR)\

[libraries.common]  
  EfiShellLib
  EdkProtocolLib
  EdkFrameworkProtocolLib
  EfiProtocolLib
  ArchProtocolLib
  EdkGuidLib
  EdkFrameworkGuidLib
  EfiGuidLib


/*****************************teststrings.uni***********************************/
#langdef   eng "English"
#langdef   fra "Français"

#string STR_TEST_TOO_MANY_ARGS          #language eng  "%hs: Too many arguments\n"

#string STR_TEST_INVALID_ARG            #language eng  "%hs: Invalid argument - '%hs'\n"

#string STR_TEST_LINE_HELP              #language eng  "Test Function"

#string STR_TEST_VERBOSE_HELP           #language eng  "Test Function() print test string.\n"  
                                                      "\n"
                                                      "\n"
                                                      "\n"
                                                      "                 0.\n"
                                                      "                 1.\n"
                                                      "                 2.\n"
                                                      "                 3.\n"
                                                      "                 4.\n"
                                                      "                 5.\n"
                                                      "                 6.\n"
                                                      "                 7.\n"
                                                      "\n"

/*****************************test.h***********************************/
#ifndef _TEST_H
#define _TEST_H

//
//
//
#define EFI_TEST_GUID \
  { \
    0x8df752f2, 0x87b5, 0x4c7b, \
    { \
      0xaa, 0x4f, 0xed, 0xda, 0x99, 0xdd, 0x30, 0x58 \
    } \
  }

#endif

/*****************************test.c***********************************/
#include "EfiShellLib.h"
#include "test.h"

extern UINT8    STRING_ARRAY_NAME[];

#include STRING_DEFINES_FILE

EFI_HII_HANDLE  HiiHandle;
EFI_GUID        EfiTestGuid = EFI_TEST_GUID;

/*
typedef struct {
  CHAR16                    *FlagStr;
  UINT32                    FlagID;
  UINT32                    ConflictMask; //Conflict Flag ID
  SHELL_VAR_CHECK_FLAG_TYPE FlagType;
} SHELL_VAR_CHECK_ITEM;

typedef enum {
  FlagTypeSingle      = 0,
  FlagTypeNeedVar,
  FlagTypeNeedSet,    //Characters will be replaced by the blank.
  FlagTypeSkipUnknown //This set will cause the system hang.
} SHELL_VAR_CHECK_FLAG_TYPE;

typedef struct _SHELL_ARG_LIST {
  CHAR16                  *FlagStr;
  CHAR16                  *VarStr;
  UINTN                   Index;
  struct _SHELL_ARG_LIST  *Next;
} SHELL_ARG_LIST;

#define GetNextArg(a)   ((a)->Next)
#define GetFirstArg(a)  ((a)->VarList)
#define GetFirstFlag(a) ((a)->FlagList)

typedef struct {
  SHELL_ARG_LIST  *FlagList;
  SHELL_ARG_LIST  *VarList;
  UINTN           FlagCount;
  UINTN           ValueCount;
} SHELL_VAR_CHECK_PACKAGE;
*/

SHELL_VAR_CHECK_ITEM    TestCheckList[] = {
  {
    L"+a",
    0x01,
    0x02,
    FlagTypeSingle
  },
  {
    L"-a",
    0x02,
    0x01,
    FlagTypeSingle
  },
  {
    L"-b",
    0x03,
    0,
    FlagTypeNeedVar
  },
  {
    L"-c",
    0x04,
    0,
    FlagTypeNeedSet
  },
  {
    L"-z",
    0x05,
    0,
    FlagTypeSkipUnknown
  },
  {
    L"-?",
    0x02,
    0,
    FlagTypeSingle
  },
  {
    NULL,
    0,
    0,
    0
  }
};

CHAR8 *
test_unicode_str_to_ascii_str (
  IN  CHAR16   *Source,
  OUT  CHAR8  *Destination
  )
{
  ASSERT (Destination != NULL);
  ASSERT (Source != NULL);

  while (*Source != '\0') {
    *(Destination++) = (CHAR8) *(Source++);
  }

  *Destination = '\0';

  return Destination;
}

INTN 
unicode_strlen(
IN const CHAR16 *s
) {
const CHAR16 *sc;

for (sc = s; *sc != 0x00; ++sc)
/* nothing */;
return (INTN)((unsigned long long)sc - (unsigned long long)s);
}


EFI_STATUS
EFIAPI
InitializeTest (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  );

EFI_BOOTSHELL_CODE(
  EFI_DRIVER_ENTRY_POINT (InitializeTest)
)

EFI_STATUS
EFIAPI
InitializeTest (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
/*++

Routine Description:

  Clear the sreen

Arguments:

  ImageHandle - The image handle
  SystemTable - The system table

Returns:

  EFI_SUCCESS - Success

--*/
{
  EFI_STATUS              Status;
//  UINTN                   Background;
//  UINTN                   ForeColor;
  CHAR16                  *Useful;
  SHELL_VAR_CHECK_CODE    RetCode;
  SHELL_VAR_CHECK_PACKAGE ChkPck;
  SHELL_ARG_LIST          *Item;

  ZeroMem (&ChkPck, sizeof (SHELL_VAR_CHECK_PACKAGE));

  //
  // We are no being installed as an internal command driver, initialize
  // as an nshell app and run
  //
  EFI_SHELL_APP_INIT (ImageHandle, SystemTable);

  //
  // Enable tab key which can pause the output
  //
  EnableOutputTabPause();
  
  Status = LibInitializeStrings (&HiiHandle, STRING_ARRAY_NAME, &EfiTestGuid);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  RetCode = LibCheckVariables (SI, TestCheckList, &ChkPck, &Useful);
  if (VarCheckOk != RetCode) {
    switch (RetCode) {
    case VarCheckUnknown:
      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_UNKNOWN_FLAG), HiiHandle, L"test", Useful);
      break;

    case VarCheckDuplicate:
      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_DUP_FLAG), HiiHandle, L"test", Useful);
      break;

    default:
      break;
    }

    Status = EFI_INVALID_PARAMETER;
    goto Done;
  }

  Print(L"test.c:main called with %d parameters\n", ChkPck.FlagCount);
  {
  int _Argc = (int)ChkPck.FlagCount, i;
  char buffer[1024], *str;
  int length, argc;
  char *argv[20];
 
  if (_Argc > 20)
  _Argc = 20;

   Item = GetFirstFlag (&ChkPck);
   for (i = 0; i < _Argc; i ++) {
   Print(L"[%d]=> FlagStr:%s VarStr:%s\n", Item->Index, Item->FlagStr, Item->VarStr);
   Item = GetNextArg (Item);
   }
 
  str = buffer;
  length = 0;
  argc = 0;
   Item = GetFirstFlag (&ChkPck);
   for (i = 0; i < _Argc; i++) {
  if (Item->FlagStr != NULL) {
  argv[argc] = str + length;
   length += (int)unicode_strlen(Item->FlagStr);
  if (length > 1024)
  break;
   test_unicode_str_to_ascii_str(Item->FlagStr, argv[argc]);
   argc ++;
  if (Item->VarStr != NULL) {
  argv[argc] = str + length;
   length += (int)unicode_strlen(Item->VarStr);
  if (length > 1024)
  break;
   test_unicode_str_to_ascii_str(Item->VarStr, argv[argc]);
   argc ++;
   }
   }
   Item = GetNextArg (Item);
   }

//   main( argc, argv ); /*Call your main() function here.*/
  }

  Status = EFI_SUCCESS;
Done:
  LibCheckVarFreeVarList (&ChkPck);
  LibUnInitializeStrings ();
  return Status;
}

EFI_STATUS
EFIAPI
InitializeTestGetLineHelp (
  OUT CHAR16              **Str
  ) {
  return LibCmdGetStringByToken (STRING_ARRAY_NAME, &EfiTestGuid, STRING_TOKEN (STR_TEST_LINE_HELP), Str);
}



2012年10月15日 星期一

The definitions is about Hii DriverCallback() function

The description of Hii DriverCallback() is for EDK II.


typedef UINTN EFI_BROWSER_ACTION;

#define EFI_BROWSER_ACTION_CHANGING   0
#define EFI_BROWSER_ACTION_CHANGED    1
#define EFI_BROWSER_ACTION_RETRIEVE   2
#define EFI_BROWSER_ACTION_FORM_OPEN  3
#define EFI_BROWSER_ACTION_FORM_CLOSE 4
#define EFI_BROWSER_ACTION_DEFAULT_STANDARD      0x1000
#define EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING 0x1001
#define EFI_BROWSER_ACTION_DEFAULT_SAFE          0x1002
#define EFI_BROWSER_ACTION_DEFAULT_PLATFORM      0x2000
#define EFI_BROWSER_ACTION_DEFAULT_HARDWARE      0x3000
#define EFI_BROWSER_ACTION_DEFAULT_FIRMWARE      0x4000

//
// Types of the option's value.
//
#define EFI_IFR_TYPE_NUM_SIZE_8        0x00
#define EFI_IFR_TYPE_NUM_SIZE_16       0x01
#define EFI_IFR_TYPE_NUM_SIZE_32       0x02
#define EFI_IFR_TYPE_NUM_SIZE_64       0x03
#define EFI_IFR_TYPE_BOOLEAN           0x04
#define EFI_IFR_TYPE_TIME              0x05
#define EFI_IFR_TYPE_DATE              0x06
#define EFI_IFR_TYPE_STRING            0x07
#define EFI_IFR_TYPE_OTHER             0x08
#define EFI_IFR_TYPE_UNDEFINED         0x09
#define EFI_IFR_TYPE_ACTION            0x0A
#define EFI_IFR_TYPE_BUFFER            0x0B
#define EFI_IFR_TYPE_REF               0x0C

#define EFI_IFR_OPTION_DEFAULT         0x10
#define EFI_IFR_OPTION_DEFAULT_MFG     0x20


typedef struct {
  UINT8 Hour;
  UINT8 Minute;
  UINT8 Second;
} EFI_HII_TIME;

typedef struct {
  UINT16 Year;
  UINT8  Month;
  UINT8  Day;
} EFI_HII_DATE;

typedef union {
  UINT8           u8;
  UINT16          u16;
  UINT32          u32;
  UINT64          u64;
  BOOLEAN         b;
  EFI_HII_TIME    time;
  EFI_HII_DATE    date;
  EFI_STRING_ID   string;
} EFI_IFR_TYPE_VALUE;

// The operand (first byte) of this Statement or Question
#define EFI_IFR_FORM_OP                0x01
#define EFI_IFR_SUBTITLE_OP            0x02
#define EFI_IFR_TEXT_OP                0x03
#define EFI_IFR_IMAGE_OP               0x04
#define EFI_IFR_ONE_OF_OP              0x05
#define EFI_IFR_CHECKBOX_OP            0x06
#define EFI_IFR_NUMERIC_OP             0x07
#define EFI_IFR_PASSWORD_OP            0x08
#define EFI_IFR_ONE_OF_OPTION_OP       0x09
#define EFI_IFR_SUPPRESS_IF_OP         0x0A
#define EFI_IFR_LOCKED_OP              0x0B
#define EFI_IFR_ACTION_OP              0x0C
#define EFI_IFR_RESET_BUTTON_OP        0x0D
#define EFI_IFR_FORM_SET_OP            0x0E
#define EFI_IFR_REF_OP                 0x0F
#define EFI_IFR_NO_SUBMIT_IF_OP        0x10
#define EFI_IFR_INCONSISTENT_IF_OP     0x11
#define EFI_IFR_EQ_ID_VAL_OP           0x12
#define EFI_IFR_EQ_ID_ID_OP            0x13
#define EFI_IFR_EQ_ID_LIST_OP          0x14
#define EFI_IFR_AND_OP                 0x15
#define EFI_IFR_OR_OP                  0x16
#define EFI_IFR_NOT_OP                 0x17
#define EFI_IFR_RULE_OP                0x18
#define EFI_IFR_GRAY_OUT_IF_OP         0x19
#define EFI_IFR_DATE_OP                0x1A
#define EFI_IFR_TIME_OP                0x1B
#define EFI_IFR_STRING_OP              0x1C
#define EFI_IFR_REFRESH_OP             0x1D
#define EFI_IFR_DISABLE_IF_OP          0x1E
#define EFI_IFR_TO_LOWER_OP            0x20
#define EFI_IFR_TO_UPPER_OP            0x21
#define EFI_IFR_ORDERED_LIST_OP        0x23
#define EFI_IFR_VARSTORE_OP            0x24
#define EFI_IFR_VARSTORE_NAME_VALUE_OP 0x25
#define EFI_IFR_VARSTORE_EFI_OP        0x26
#define EFI_IFR_VARSTORE_DEVICE_OP     0x27
#define EFI_IFR_VERSION_OP             0x28
#define EFI_IFR_END_OP                 0x29
#define EFI_IFR_MATCH_OP               0x2A
#define EFI_IFR_EQUAL_OP               0x2F
#define EFI_IFR_NOT_EQUAL_OP           0x30
#define EFI_IFR_GREATER_THAN_OP        0x31
#define EFI_IFR_GREATER_EQUAL_OP       0x32
#define EFI_IFR_LESS_THAN_OP           0x33
#define EFI_IFR_LESS_EQUAL_OP          0x34
#define EFI_IFR_BITWISE_AND_OP         0x35
#define EFI_IFR_BITWISE_OR_OP          0x36
#define EFI_IFR_BITWISE_NOT_OP         0x37
#define EFI_IFR_SHIFT_LEFT_OP          0x38
#define EFI_IFR_SHIFT_RIGHT_OP         0x39
#define EFI_IFR_ADD_OP                 0x3A
#define EFI_IFR_SUBTRACT_OP            0x3B
#define EFI_IFR_MULTIPLY_OP            0x3C
#define EFI_IFR_DIVIDE_OP              0x3D
#define EFI_IFR_MODULO_OP              0x3E
#define EFI_IFR_RULE_REF_OP            0x3F
#define EFI_IFR_QUESTION_REF1_OP       0x40
#define EFI_IFR_QUESTION_REF2_OP       0x41
#define EFI_IFR_UINT8_OP               0x42
#define EFI_IFR_UINT16_OP              0x43
#define EFI_IFR_UINT32_OP              0x44
#define EFI_IFR_UINT64_OP              0x45
#define EFI_IFR_TRUE_OP                0x46
#define EFI_IFR_FALSE_OP               0x47
#define EFI_IFR_TO_UINT_OP             0x48
#define EFI_IFR_TO_STRING_OP           0x49
#define EFI_IFR_TO_BOOLEAN_OP          0x4A
#define EFI_IFR_MID_OP                 0x4B
#define EFI_IFR_FIND_OP                0x4C
#define EFI_IFR_TOKEN_OP               0x4D
#define EFI_IFR_STRING_REF1_OP         0x4E
#define EFI_IFR_STRING_REF2_OP         0x4F
#define EFI_IFR_CONDITIONAL_OP         0x50
#define EFI_IFR_QUESTION_REF3_OP       0x51
#define EFI_IFR_ZERO_OP                0x52
#define EFI_IFR_ONE_OP                 0x53
#define EFI_IFR_ONES_OP                0x54
#define EFI_IFR_UNDEFINED_OP           0x55
#define EFI_IFR_LENGTH_OP              0x56
#define EFI_IFR_DUP_OP                 0x57
#define EFI_IFR_THIS_OP                0x58
#define EFI_IFR_SPAN_OP                0x59
#define EFI_IFR_VALUE_OP               0x5A
#define EFI_IFR_DEFAULT_OP             0x5B
#define EFI_IFR_DEFAULTSTORE_OP        0x5C
#define EFI_IFR_CATENATE_OP            0x5E
#define EFI_IFR_GUID_OP                0x5F

typedef struct _EFI_IFR_OP_HEADER {
  UINT8                    OpCode;
  UINT8                    Length:7;
  UINT8                    Scope:1;
} EFI_IFR_OP_HEADER;

2012年10月9日 星期二

轉換簽章驅動程式成.rom檔案

1.7 轉換簽章驅動程式成一個.rom檔案
UEFI 2.3驅動程式寫作指南( Drivers Writers Guide for UEFI 2.3 (DWG) )的第32章中介紹的方法去分散UEFI驅動程式。如果簽章的驅動程式將被安裝在一個PCI卡的Option ROM,它必須從.efi檔案轉換到.rom檔案。
這UEFI DWG描述多種方式去做此轉換。然而,"EfiRom"工具將

然而,"EfiRom"工具將適用於最常使用的方法簽署對簽章影像檔,因為簽章的發生在EDK II的建構後與包裝成Option ROM前. 這EDK II的編譯系統沒有能力去自動簽署UEFI驅動程式的章,在包裝它們一個Option ROM之前。這處理過程被描述在DWG的18.7.1章節。

此"EfiRom"二進制的工具可以發現在BaseTools/Bin/Win32的目錄中,在EDK2的工作區中。

這個範例從剛才作簽章的MyDriver.efi,所創建出來的MyDriver.bin:
〉EfiRom -f 0x1013 -i 0x00b8  -e MyDriver.efi
這裡的–f是廠商辨識ID與 –i是裝置ID。
這個範例顯示對於Cirrus Logic的5446設備在OvmfPkg引含的數值。

1.8 安裝簽章的驅動程式
如果簽章的驅動程式將被安裝在一個PCI裝置卡的Option ROM,接下來更新PCI卡的Option ROM方式將由卡供應商提供。
如果簽章的驅動程式將被分散在EFI系統磁碟分區,它已準備好進行佈置。

1.9 添加簽章驅動程式到開機程序
此簽章的驅動程式在開機維護管理員(Boot Maintenance Manager)設定被添加到開機程序,藉由選擇驅動程式選項,然後加入驅動程式選項用途檔案(Add Driver Option Using File)。

2012年10月8日 星期一

SPI Flash Chip - Winbond(W25Q80, W25Q16, W25Q32) Command List


Winbond(W25Q80, W25Q16, W25Q32)

FEATURES
 Family of SpiFlash Memories
 W25Q80: 8M-bit / 1M -byte (1,048,576)
 W25Q16: 16M-bit / 2M-byte (2,097,152)
 W25Q32: 32M-bit / 4M-byte (4,194,304)
 256-bytes per programmable page
 Standard, Dual or Quad SPI
 Standard SPI: CLK, /CS, DI, DO, /WP, /Hold
 Dual SPI: CLK, /CS, IO 0 , IO 1 , /WP, /Hold
 Quad SPI: CLK, /CS, IO 0 , IO 1 , IO 2 , IO 3
 Highest Performance Serial Flash  
 Up to 6X that of ordinary Serial Flash
 80MHz clock operation
 160MHz equivalent Dual SPI
 320MHz equivalent Quad SPI
 40MB/S continuous data transfer rate
 30MB/S random access (32-byte fetch)
 Comparable to X16 Parallel Flash
 Low Power, Wide Temperature Range  
 Single 2.7 to 3.6V supply
 4mA active current, 〈1 data-blogger-escaped-op=“o:p” data-blogger-escaped-power-down=“power-down”data-blogger-escaped-typ.=“typ.”〉
 -40°C to +85°C operating range
 Flexible Architecture with 4KB sectors
 Uniform Sector Erase (4K-bytes)
 Block Erase (32K and 64K-bytes)
 Program one to 256 bytes
 Up to 100,000 erase/write cycles
 20-year data retention
 Advanced Security Features
 Software and Hardware Write-Protect
 Top or Bottom, Sector or Block selection
 Lock-Down and OTP protection
 64-Bit Unique ID for each device
Note 1:
These features are on special order.
Please contact Winbond for details.
 Space Efficient Packaging
 8-pin SOIC 208-mil  
 8-pad WSON 6x5-mm (W25Q80 & W25Q16)
16-pin SOIC 300-mil (W25Q16 & W25Q32)


Instruction Set Table
INSTRUCTION NAME
BYTE 1 CODE
BYTE 2
BYTE 3
BYTE 4
BYTE 5
BYTE 6
N-BYTES
Write Enable
06h
Write Disable 
04h
Read Status Register-1
05h
(S7–S0) (2)
Read Status Register-2
35h
(S15-S8) (2)
Write Status Register
01h
(S7–S0)
(S15-S8)
Page Program
02h
A23–A16
A15–A8
A7–A0
(D7–D0)
(Next byte)
Up to 256 bytes
Quad Page Program
32h
A23–A16
A15–A8
A7–A0
(D7–D0)
Block Erase (64KB)
D8h
A23–A16
A15–A8
A7–A0
Block Erase (32KB)
52h
A23–A16
A15–A8
A7–A0
Sector Erase (4KB)
20h
A23–A16
A15–A8
A7–A0
Chip Erase
C7h/60h
Erase Suspend
75h
Erase Resume
94h
Power-down
B9h
High Performance Mode
A3h
dummy
dummy
dummy
Mode Bit Reset (4)
FFh
FFh
Release Power-down / Device ID
ABh
dummy
dummy
dummy
(ID7-ID0)(5)
Manufacturer/
Device ID
90h
dummy
dummy
00h
(M7-M0)
(ID7-ID0)
Read Unique ID(7)
4Bh
dummy
dummy
dummy
dummy
(ID63-ID0)
JEDEC ID
9Fh
(M7-M0) Manufacturer
(ID15-ID8) Memory Type
(ID7-ID0)
Capacity
Read Data
03h
A23–A16
A15–A8
A7–A0
(D7–D0)
(Next byte)
continuous
Fast Read
0Bh
A23–A16
A15–A8
A7–A0
dummy
(D7–D0)
(Next Byte) continuous
Fast Read Dual Output
3Bh
A23–A16
A15–A8
A7–A0
dummy
I/O = (D6,D4,D2,D0)
O = (D7,D5,D3,D1)
(one byte
per 4 clocks,
continuous)
Fast Read Dual Output
3Bh
A23–A16
A15–A8
A7–A0
dummy
(D7–D0, …)(8)
Fast Read Dual I/O
BBh
A23-A8(2)
A7-A0, M7-M0(9)
(D7–D0, …)(1)
Fast Read Quad Output
6Bh
A23–A16
A15–A8
A7–A0
dummy
(D7–D0, …)(10)
Fast Read Quad I/O
EBh
A23-A0, M7-M0(4)
(x,x,x,x, D7–D0, …)(12)
(D7-D0, …)(10)

Notes:
1. Data bytes are shifted with Most Significant Bit first. Byte fields with data in parenthesis “()” indicate data being read from the device on the DO pin.

2. The Status Register contents will repeat continuously until /CS terminates the instruction.

3. Quad Page Program Input Data
IO0 = (D4, D0, ...)
IO1 = (D5, D1, ...)
IO2 = (D6, D2, ...)
IO3 = (D7, D3, ...)

4. This instruction is recommended when using the Dual or Quad Mode bit feature. See section 10.2.28 for more information.

5. The Device ID will repeat continuously until /CS terminates the instruction.

6. See Manufacturer and Device Identification table for Device ID information.

7. This feature is available upon special order. Please contact Winbond for details.


8. Dual Output data  
IO0 = (D6, D4, D2, D0)
IO1 = (D7, D5, D3, D1)

9. Dual Input Address
IO0 = A22, A20, A18, A16, A14, A12, A10, A8    A6, A4, A2, A0, M6, M4, M2, M0  
IO1 = A23, A21, A19, A17, A15, A13, A11, A9    A7, A5, A3, A1, M7, M5, M3, M1

10. Quad Output Data
IO0 = (D4, D0, ...)
IO1 = (D5, D1, ...)
IO2 = (D6, D2, ...)
IO3 = (D7, D3, ...)

11. Quad Input Address
IO0 = A20, A16, A12, A8 , A4, A0, M4, M0
IO1 = A21, A17, A13, A9 , A5, A1, M5, M1
IO2 = A22, A18, A14, A10, A6, A2, M6, M2
IO3 = A23, A19, A15, A11, A7, A3, M7, M3

12. Fast Read Quad I/O Data  
IO0 = (x, x, x, x, D4, D0, ...)
IO1 = (x, x, x, x, D5, D1, ...)
IO2 = (x, x, x, x, D6, D2, ...)
IO3 = (x, x, x, x, D7, D3, ...)

Status Register-1
Bit
Name
Description
S7
SRP
Status Register Protect(NON-VOLATILE)
S6
SEC
Sector Protect(NON-VOLITILE)
S5
TB
Top/Bottom Block Protect
S4:2
BP2:0
Block Protect Bits (BP2, BP1, BP0)
S1
WEL
Write Enable Latch
S0
BUSY
Busy Status

Status Register-2
Bit
Name
Description
S15
R
Reserved
S14
R
Reserved
S13
R
Reserved
S12
R
Reserved
S11
R
Reserved
S10
R
Reserved
S9
QE
Quad Enable(NON-VOLITILE)
S8
SRP1
Status Register Protect1(NON-VOLITILE)

Manufacturer and Device Identification
MANUFACTURER ID
(M7-M0)
Winbond Serial Flash
EFH
Device ID
(ID7-ID0)
(ID15-ID0)
Instruction
ABh, 90h
9Fh
W25Q80
13h
4014h
W25Q16
14h
4015h
W25Q32
15h
4016h