2 Main file for Mm shell Debug1 function.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "UefiShellDebug1CommandsLib.h"
17 #include <Library/ShellLib.h>
18 #include <Library/IoLib.h>
19 #include <Protocol/PciRootBridgeIo.h>
20 #include <Protocol/DeviceIo.h>
24 ShellMmMemoryMappedIo
,
28 } SHELL_MM_ACCESS_TYPE
;
30 CONST UINT16 mShellMmAccessTypeStr
[] = {
31 STRING_TOKEN (STR_MM_MEM
),
32 STRING_TOKEN (STR_MM_MMIO
),
33 STRING_TOKEN (STR_MM_IO
),
34 STRING_TOKEN (STR_MM_PCI
),
35 STRING_TOKEN (STR_MM_PCIE
)
38 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
49 CONST UINT64 mShellMmMaxNumber
[] = {
50 0, MAX_UINT8
, MAX_UINT16
, 0, MAX_UINT32
, 0, 0, 0, MAX_UINT64
52 CONST EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH mShellMmRootBridgeIoWidth
[] = {
53 0, EfiPciWidthUint8
, EfiPciWidthUint16
, 0, EfiPciWidthUint32
, 0, 0, 0, EfiPciWidthUint64
55 CONST EFI_CPU_IO_PROTOCOL_WIDTH mShellMmCpuIoWidth
[] = {
56 0, EfiCpuIoWidthUint8
, EfiCpuIoWidthUint16
, 0, EfiCpuIoWidthUint32
, 0, 0, 0, EfiCpuIoWidthUint64
60 Extract the PCI segment, bus, device, function, register from
61 from a SHELL_MM_PCI or SHELL_MM_PCIE format of address..
63 @param[in] PciFormat Whether the address is of PCI format of PCIE format.
64 @param[in] Address SHELL_MM_PCI or SHELL_MM_PCIE address.
65 @param[out] Segment PCI segment number.
66 @param[out] Bus PCI bus number.
67 @param[out] Device PCI device number.
68 @param[out] Function PCI function number.
69 @param[out] Register PCI register offset.
73 ShellMmDecodePciAddress (
78 OUT UINT8
*Device
, OPTIONAL
79 OUT UINT8
*Function
, OPTIONAL
80 OUT UINT32
*Register OPTIONAL
85 // PCI Configuration Space.The address will have the format 0x000000ssbbddffrr,
86 // where ss = Segment, bb = Bus, dd = Device, ff = Function and rr = Register.
88 *Segment
= (UINT32
) (RShiftU64 (Address
, 32) & 0xFF);
89 *Bus
= (UINT8
) (((UINT32
) Address
) >> 24);
92 *Device
= (UINT8
) (((UINT32
) Address
) >> 16);
94 if (Function
!= NULL
) {
95 *Function
= (UINT8
) (((UINT32
) Address
) >> 8);
97 if (Register
!= NULL
) {
98 *Register
= (UINT8
) Address
;
102 // PCI Express Configuration Space.The address will have the format 0x0000000ssbbddffrrr,
103 // where ss = Segment, bb = Bus, dd = Device, ff = Function and rrr = Register.
105 *Segment
= (UINT32
) (RShiftU64 (Address
, 36) & 0xFF);
106 *Bus
= (UINT8
) RShiftU64 (Address
, 28);
107 if (Device
!= NULL
) {
108 *Device
= (UINT8
) (((UINT32
) Address
) >> 20);
110 if (Function
!= NULL
) {
111 *Function
= (UINT8
) (((UINT32
) Address
) >> 12);
113 if (Register
!= NULL
) {
114 *Register
= (UINT32
) (Address
& 0xFFF);
120 Read or write some data from or into the Address.
122 @param[in] AccessType Access type.
123 @param[in] PciRootBridgeIo PciRootBridgeIo instance.
124 @param[in] CpuIo CpuIo instance.
125 @param[in] Read TRUE for read, FALSE for write.
126 @param[in] Addresss The memory location to access.
127 @param[in] Size The size of Buffer in Width sized units.
128 @param[in, out] Buffer The buffer to read into or write from.
132 IN SHELL_MM_ACCESS_TYPE AccessType
,
133 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
134 IN EFI_CPU_IO2_PROTOCOL
*CpuIo
,
142 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM RootBridgeIoMem
;
143 EFI_CPU_IO_PROTOCOL_IO_MEM CpuIoMem
;
150 if (AccessType
== ShellMmMemory
) {
152 CopyMem (Buffer
, (VOID
*) (UINTN
) Address
, Size
);
154 CopyMem ((VOID
*) (UINTN
) Address
, Buffer
, Size
);
157 RootBridgeIoMem
= NULL
;
159 switch (AccessType
) {
161 case ShellMmPciExpress
:
162 ASSERT (PciRootBridgeIo
!= NULL
);
163 ShellMmDecodePciAddress ((BOOLEAN
) (AccessType
== ShellMmPci
), Address
, &Segment
, &Bus
, &Device
, &Function
, &Register
);
165 Status
= PciRootBridgeIo
->Pci
.Read (
166 PciRootBridgeIo
, mShellMmRootBridgeIoWidth
[Size
],
167 EFI_PCI_ADDRESS (Bus
, Device
, Function
, Register
),
171 Status
= PciRootBridgeIo
->Pci
.Write (
172 PciRootBridgeIo
, mShellMmRootBridgeIoWidth
[Size
],
173 EFI_PCI_ADDRESS (Bus
, Device
, Function
, Register
),
177 ASSERT_EFI_ERROR (Status
);
180 case ShellMmMemoryMappedIo
:
181 if (PciRootBridgeIo
!= NULL
) {
182 RootBridgeIoMem
= Read
? PciRootBridgeIo
->Mem
.Read
: PciRootBridgeIo
->Mem
.Write
;
185 CpuIoMem
= Read
? CpuIo
->Mem
.Read
: CpuIo
->Mem
.Write
;
190 if (PciRootBridgeIo
!= NULL
) {
191 RootBridgeIoMem
= Read
? PciRootBridgeIo
->Io
.Read
: PciRootBridgeIo
->Io
.Write
;
194 CpuIoMem
= Read
? CpuIo
->Io
.Read
: CpuIo
->Io
.Write
;
202 Status
= EFI_UNSUPPORTED
;
203 if (RootBridgeIoMem
!= NULL
) {
204 Status
= RootBridgeIoMem (PciRootBridgeIo
, mShellMmRootBridgeIoWidth
[Size
], Address
, 1, Buffer
);
206 if (EFI_ERROR (Status
) && (CpuIoMem
!= NULL
)) {
207 Status
= CpuIoMem (CpuIo
, mShellMmCpuIoWidth
[Size
], Address
, 1, Buffer
);
210 if (EFI_ERROR (Status
)) {
211 if (AccessType
== ShellMmIo
) {
215 *(UINT8
*) Buffer
= IoRead8 ((UINTN
) Address
);
217 IoWrite8 ((UINTN
) Address
, *(UINT8
*) Buffer
);
222 *(UINT16
*) Buffer
= IoRead16 ((UINTN
) Address
);
224 IoWrite16 ((UINTN
) Address
, *(UINT16
*) Buffer
);
229 *(UINT32
*) Buffer
= IoRead32 ((UINTN
) Address
);
231 IoWrite32 ((UINTN
) Address
, *(UINT32
*) Buffer
);
236 *(UINT64
*) Buffer
= IoRead64 ((UINTN
) Address
);
238 IoWrite64 ((UINTN
) Address
, *(UINT64
*) Buffer
);
249 *(UINT8
*) Buffer
= MmioRead8 ((UINTN
) Address
);
251 MmioWrite8 ((UINTN
) Address
, *(UINT8
*) Buffer
);
256 *(UINT16
*) Buffer
= MmioRead16 ((UINTN
) Address
);
258 MmioWrite16 ((UINTN
) Address
, *(UINT16
*) Buffer
);
263 *(UINT32
*) Buffer
= MmioRead32 ((UINTN
) Address
);
265 MmioWrite32 ((UINTN
) Address
, *(UINT32
*) Buffer
);
270 *(UINT64
*) Buffer
= MmioRead64 ((UINTN
) Address
);
272 MmioWrite64 ((UINTN
) Address
, *(UINT64
*) Buffer
);
285 Find the CpuIo instance and PciRootBridgeIo instance in the platform.
286 If there are multiple PciRootBridgeIo instances, the instance which manages
287 the Address is returned.
289 @param[in] AccessType Access type.
290 @param[in] Address Address to access.
291 @param[out] CpuIo Return the CpuIo instance.
292 @param[out] PciRootBridgeIo Return the proper PciRootBridgeIo instance.
294 @retval TRUE There are PciRootBridgeIo instances in the platform.
295 @retval FALSE There isn't PciRootBridgeIo instance in the platform.
298 ShellMmLocateIoProtocol (
299 IN SHELL_MM_ACCESS_TYPE AccessType
,
301 OUT EFI_CPU_IO2_PROTOCOL
**CpuIo
,
302 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
**PciRootBridgeIo
308 EFI_HANDLE
*HandleBuffer
;
309 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*Io
;
312 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
314 Status
= gBS
->LocateProtocol (&gEfiCpuIo2ProtocolGuid
, NULL
, (VOID
**) CpuIo
);
315 if (EFI_ERROR (Status
)) {
319 *PciRootBridgeIo
= NULL
;
321 Status
= gBS
->LocateHandleBuffer (
323 &gEfiPciRootBridgeIoProtocolGuid
,
328 if (EFI_ERROR (Status
) || (HandleCount
== 0) || (HandleBuffer
== NULL
)) {
334 if ((AccessType
== ShellMmPci
) || (AccessType
== ShellMmPciExpress
)) {
335 ShellMmDecodePciAddress ((BOOLEAN
) (AccessType
== ShellMmPci
), Address
, &Segment
, &Bus
, NULL
, NULL
, NULL
);
339 // Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment & bus number
341 for (Index
= 0; (Index
< HandleCount
) && (*PciRootBridgeIo
== NULL
); Index
++) {
342 Status
= gBS
->HandleProtocol (
344 &gEfiPciRootBridgeIoProtocolGuid
,
347 if (EFI_ERROR (Status
)) {
351 if ((((AccessType
== ShellMmPci
) || (AccessType
== ShellMmPciExpress
)) && (Io
->SegmentNumber
== Segment
)) ||
352 ((AccessType
== ShellMmIo
) || (AccessType
== ShellMmMemoryMappedIo
))
354 Status
= Io
->Configuration (Io
, (VOID
**) &Descriptors
);
355 if (!EFI_ERROR (Status
)) {
356 while (Descriptors
->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
358 // Compare the segment and bus range for PCI/PCIE access
360 if ((Descriptors
->ResType
== ACPI_ADDRESS_SPACE_TYPE_BUS
) &&
361 ((AccessType
== ShellMmPci
) || (AccessType
== ShellMmPciExpress
)) &&
362 ((Bus
>= Descriptors
->AddrRangeMin
) && (Bus
<= Descriptors
->AddrRangeMax
))
364 *PciRootBridgeIo
= Io
;
368 // Compare the address range for MMIO/IO access
370 } else if ((((Descriptors
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) && (AccessType
== ShellMmIo
)) ||
371 ((Descriptors
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) && (AccessType
== ShellMmMemoryMappedIo
))
372 ) && ((Address
>= Descriptors
->AddrRangeMin
) && (Address
<= Descriptors
->AddrRangeMax
))
374 *PciRootBridgeIo
= Io
;
382 if (HandleBuffer
!= NULL
) {
383 FreePool (HandleBuffer
);
390 Function for 'mm' command.
392 @param[in] ImageHandle Handle to the Image (NULL if Internal).
393 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
398 IN EFI_HANDLE ImageHandle
,
399 IN EFI_SYSTEM_TABLE
*SystemTable
403 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
404 EFI_CPU_IO2_PROTOCOL
*CpuIo
;
407 SHELL_MM_ACCESS_TYPE AccessType
;
415 CHAR16
*ProblemParam
;
416 SHELL_STATUS ShellStatus
;
418 BOOLEAN HasPciRootBridgeIo
;
422 ShellStatus
= SHELL_SUCCESS
;
425 AccessType
= ShellMmMemory
;
430 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
431 if (EFI_ERROR (Status
)) {
432 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
433 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"mm", ProblemParam
);
434 FreePool (ProblemParam
);
435 ShellStatus
= SHELL_INVALID_PARAMETER
;
441 if (ShellCommandLineGetCount (Package
) < 2) {
442 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
, L
"mm");
443 ShellStatus
= SHELL_INVALID_PARAMETER
;
445 } else if (ShellCommandLineGetCount (Package
) > 3) {
446 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
, L
"mm");
447 ShellStatus
= SHELL_INVALID_PARAMETER
;
449 } else if (ShellCommandLineGetFlag (Package
, L
"-w") && ShellCommandLineGetValue (Package
, L
"-w") == NULL
) {
450 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellDebug1HiiHandle
, L
"mm", L
"-w");
451 ShellStatus
= SHELL_INVALID_PARAMETER
;
454 if (ShellCommandLineGetFlag (Package
, L
"-mmio")) {
455 AccessType
= ShellMmMemoryMappedIo
;
456 if (ShellCommandLineGetFlag (Package
, L
"-mem")
457 || ShellCommandLineGetFlag (Package
, L
"-io")
458 || ShellCommandLineGetFlag (Package
, L
"-pci")
459 || ShellCommandLineGetFlag (Package
, L
"-pcie")
461 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
, L
"mm");
462 ShellStatus
= SHELL_INVALID_PARAMETER
;
465 } else if (ShellCommandLineGetFlag (Package
, L
"-mem")) {
466 AccessType
= ShellMmMemory
;
467 if (ShellCommandLineGetFlag (Package
, L
"-io")
468 || ShellCommandLineGetFlag (Package
, L
"-pci")
469 || ShellCommandLineGetFlag (Package
, L
"-pcie")
471 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
, L
"mm");
472 ShellStatus
= SHELL_INVALID_PARAMETER
;
475 } else if (ShellCommandLineGetFlag (Package
, L
"-io")) {
476 AccessType
= ShellMmIo
;
477 if (ShellCommandLineGetFlag (Package
, L
"-pci")
478 || ShellCommandLineGetFlag (Package
, L
"-pcie")
480 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
, L
"mm");
481 ShellStatus
= SHELL_INVALID_PARAMETER
;
484 } else if (ShellCommandLineGetFlag (Package
, L
"-pci")) {
485 AccessType
= ShellMmPci
;
486 if (ShellCommandLineGetFlag (Package
, L
"-pcie")
488 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
, L
"mm");
489 ShellStatus
= SHELL_INVALID_PARAMETER
;
492 } else if (ShellCommandLineGetFlag (Package
, L
"-pcie")) {
493 AccessType
= ShellMmPciExpress
;
498 // Non interactive for a script file or for the specific parameter
501 if (gEfiShellProtocol
->BatchIsActive () || ShellCommandLineGetFlag (Package
, L
"-n")) {
505 Temp
= ShellCommandLineGetValue (Package
, L
"-w");
507 Size
= ShellStrToUintn (Temp
);
509 if ((Size
!= 1) && (Size
!= 2) && (Size
!= 4) && (Size
!= 8)) {
510 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_VAL
), gShellDebug1HiiHandle
, L
"mm", Temp
, L
"-w");
511 ShellStatus
= SHELL_INVALID_PARAMETER
;
515 Temp
= ShellCommandLineGetRawValue (Package
, 1);
516 Status
= ShellConvertStringToUint64 (Temp
, &Address
, TRUE
, FALSE
);
517 if (EFI_ERROR (Status
)) {
518 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellDebug1HiiHandle
, L
"mm", Temp
);
519 ShellStatus
= SHELL_INVALID_PARAMETER
;
523 if ((Address
& (Size
- 1)) != 0) {
524 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_MM_NOT_ALIGNED
), gShellDebug1HiiHandle
, L
"mm", Address
);
525 ShellStatus
= SHELL_INVALID_PARAMETER
;
529 if ((AccessType
== ShellMmIo
) && (Address
+ Size
> MAX_UINT16
+ 1)) {
530 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_MM_IO_ADDRESS_RANGE
), gShellDebug1HiiHandle
, L
"mm");
531 ShellStatus
= SHELL_INVALID_PARAMETER
;
536 // locate IO protocol interface
538 HasPciRootBridgeIo
= ShellMmLocateIoProtocol (AccessType
, Address
, &CpuIo
, &PciRootBridgeIo
);
539 if ((AccessType
== ShellMmPci
) || (AccessType
== ShellMmPciExpress
)) {
540 if (!HasPciRootBridgeIo
) {
541 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PCIRBIO_NF
), gShellDebug1HiiHandle
, L
"mm");
542 ShellStatus
= SHELL_NOT_FOUND
;
545 if (PciRootBridgeIo
== NULL
) {
546 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_MM_PCIE_ADDRESS_RANGE
), gShellDebug1HiiHandle
, L
"mm", Address
);
547 ShellStatus
= SHELL_INVALID_PARAMETER
;
553 // Mode 1: Directly set a value
555 Temp
= ShellCommandLineGetRawValue (Package
, 2);
557 Status
= ShellConvertStringToUint64 (Temp
, &Value
, TRUE
, FALSE
);
558 if (EFI_ERROR (Status
)) {
559 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellDebug1HiiHandle
, L
"mm", Temp
);
560 ShellStatus
= SHELL_INVALID_PARAMETER
;
564 if (Value
> mShellMmMaxNumber
[Size
]) {
565 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellDebug1HiiHandle
, L
"mm", Temp
);
566 ShellStatus
= SHELL_INVALID_PARAMETER
;
570 ShellMmAccess (AccessType
, PciRootBridgeIo
, CpuIo
, FALSE
, Address
, Size
, &Value
);
575 // Mode 2: Directly show a value
578 if (!gEfiShellProtocol
->BatchIsActive ()) {
579 ShellPrintHiiEx (-1, -1, NULL
, mShellMmAccessTypeStr
[AccessType
], gShellDebug1HiiHandle
);
581 ShellMmAccess (AccessType
, PciRootBridgeIo
, CpuIo
, TRUE
, Address
, Size
, &Buffer
);
583 if (!gEfiShellProtocol
->BatchIsActive ()) {
584 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_MM_ADDRESS
), gShellDebug1HiiHandle
, Address
);
586 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF
), gShellDebug1HiiHandle
, Size
* 2, Buffer
& mShellMmMaxNumber
[Size
]);
587 ShellPrintEx (-1, -1, L
"\r\n");
592 // Mode 3: Show or set values in interactive mode
596 if ((AccessType
== ShellMmIo
) && (Address
+ Size
> MAX_UINT16
+ 1)) {
597 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_MM_ADDRESS_RANGE2
), gShellDebug1HiiHandle
, L
"mm");
601 ShellMmAccess (AccessType
, PciRootBridgeIo
, CpuIo
, TRUE
, Address
, Size
, &Buffer
);
602 ShellPrintHiiEx (-1, -1, NULL
, mShellMmAccessTypeStr
[AccessType
], gShellDebug1HiiHandle
);
603 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_MM_ADDRESS
), gShellDebug1HiiHandle
, Address
);
604 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_MM_BUF
), gShellDebug1HiiHandle
, Size
* 2, Buffer
& mShellMmMaxNumber
[Size
]);
605 ShellPrintEx (-1, -1, L
" > ");
607 // wait user input to modify
609 if (InputStr
!= NULL
) {
613 ShellPromptForResponse (ShellPromptResponseTypeFreeform
, NULL
, (VOID
**) &InputStr
);
615 if (InputStr
!= NULL
) {
617 // skip space characters
619 for (Index
= 0; InputStr
[Index
] == ' '; Index
++);
621 if (InputStr
[Index
] != CHAR_NULL
) {
622 if ((InputStr
[Index
] == '.') || (InputStr
[Index
] == 'q') || (InputStr
[Index
] == 'Q')) {
624 } else if (!EFI_ERROR (ShellConvertStringToUint64 (InputStr
+ Index
, &Buffer
, TRUE
, TRUE
)) &&
625 (Buffer
<= mShellMmMaxNumber
[Size
])
627 ShellMmAccess (AccessType
, PciRootBridgeIo
, CpuIo
, FALSE
, Address
, Size
, &Buffer
);
629 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_MM_ERROR
), gShellDebug1HiiHandle
, L
"mm");
636 ShellPrintEx (-1, -1, L
"\r\n");
639 ASSERT (ShellStatus
== SHELL_SUCCESS
);
642 if (InputStr
!= NULL
) {
645 if (Package
!= NULL
) {
646 ShellCommandLineFreeVarList (Package
);