Tuesday, January 2, 2018

LoLeOp Introduction

LoLeOp (Low Level Operation) can access (Read/Write) system memory/information in bit unit.
To get bit 2 at memory address 0xC0000000: Mem8[0xC0000000][2]
To get bit 3, 4, 5 at  memory address 0xC0000000: Mem8[0xC0000000][3:5]
To set bit 2 at memory address 0xC0000000 as 1: Mem8[0xC0000000][2] = 1
To set bit 3, 4, 5 at  memory address 0xC0000000 as 3: Mem8[0xC0000000][5:3] = 3

In hardware description, it often provides this kind of register tables.
(PCI BAR Address Map as example)

    BAR0L: BAR0 Lower Address Map (offset 0x010)
    Reset: 0000_0000h.
    +-------+--------------+------+-------------------------------------------+
    | Bits  | Name         | Attr | Description                               |
    +-------+--------------+------+-------------------------------------------+
    | 31:17 | BaseAddr     | R/w  | Indicates the Addr[31:17] of the base     |
    |       |              |      | address.                                  |
    +-------+--------------+------+-------------------------------------------+
    | 16:4  | Reserved     |      |                                           |
    +-------+--------------+------+-------------------------------------------+
    |  3    | Prefetchable | R/w  | Indicates BAR 0 is prefetchable.          |
    +-------+--------------+------+-------------------------------------------+
    | 2:1   | Type         | R/w  | Indicates BAR 0 is in a 64-bit access     |
    |       |              |      | space.                                    |
    +-------+--------------+------+-------------------------------------------+
    |  0    | Space        | R/w  | Indicates BAR 0 is a memory space.        |
    +-------+--------------+------+-------------------------------------------+

    BAR0H: BAR0 Upper Address Map (offset 0x014)
    Reset: 0000_0000h.
    +-------+--------------+------+-------------------------------------------+
    | Bits  | Name         | Attr | Description                               |
    +-------+--------------+------+-------------------------------------------+
    | 31:0  | BaseAddr     | R/w  | Indicates the Addr[63:32] of the base     |
    |       |              |      | address.                                  |
    +-------+--------------+------+-------------------------------------------+

If PCI bus 1, device 1, function 2 Configuration Space maps in MMIO address  is 0xE010A000. Each field of registers BAR0 can be read from 0xE010A010 and  0xE010A014. ( *(UINT32 *)0xE010A010 and *(UINT32 *)0xE010A014 )
It is more programmable/Readable with LoLeOp library.

    from LoLeOp.Mem import Mem8, Mem16, Mem32, Mem64
    #
    # Read each register fields of BAR0 (Bus 1, Device 1, Function 2)
    #
    BAR0L = 0xE010A010
    BAR0H = 0xE010A014
    print 'Register "Prefetchable": 0x%02X'  % Mem32[BAR0L][0]
    print 'Register "Type":         0x%02X'  % Mem32[BAR0L][2:1]
    print 'Register "Space":        0x%02X'  % Mem32[BAR0L][3]
    print 'Register "BaseAddr":     0x%016X' % (Mem32[Mem32[BAR0L][31:17], Mem32[BAR0H]] << 17)
    #
    # Setting BaseAddr of BAR0 as 0xD0000000 >> 17
    #
    Mem32[Mem32[BAR0L][31:17], Mem32[BAR0H]] = 0xD0000000 >> 17

In above Python code Mem32[BAR0L][2:1], It has the same effect of C language.

    {
      UINT32 BAR0L = 0xE010A010;
      Printf (L"Register \"Type\":  0x%02X", (*((UINT32 *)0xE010A010) >> 1) & 0x03);
    }

Mem32[BAR0L] means an instance at address 0xE010A010 with 32 bits width. Mem32[BAR0L][2:1] and Mem32[BAR0L][1:2] means an instance with bit 1 and bit 2 at address 0xE010A010. Mem32[Mem32[BAR0L][31:17], Mem32[BAR0H]] means an instance includes Mem32[BAR0H] and Mem32[BAR0L][31:17].

LoLeOp includes these application classes

    Mem8, Mem16, Mem32, Mem64
      Memory (including mmio) Read/Write in any memory area.
    Io8, Io16, Io32, Io64
      Io Read/Write
    Cmos
      cmos area data read/write
    CpuId
      x86 cpuid instruction input EAX and ECX (optional), output EAX, EBX, ECX, EDX.
    Msr
      x86 rdmsr/wrmsr instruction with input ECX, output EDX:EAX.

  LeLoOp includes these basic classes
    _MemArray, _MemCell, _CellConj, rUnionOp

Samples:
    Host\AppPkg\LoLeOp\Samples

2 comments: