[U-Boot] [PATCH v4 3/3] riscv: Remove unused _relocate arguments

2018-06-28 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

Signed-off-by: Ivan Gorinov 
---
 arch/riscv/lib/reloc_riscv_efi.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/riscv/lib/reloc_riscv_efi.c b/arch/riscv/lib/reloc_riscv_efi.c
index 8b4b2b1..c1039dd 100644
--- a/arch/riscv/lib/reloc_riscv_efi.c
+++ b/arch/riscv/lib/reloc_riscv_efi.c
@@ -50,8 +50,7 @@
 #define ELF_R_TYPE ELF32_R_TYPE
 #endif
 
-efi_status_t _relocate(long ldbase, Elf_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t EFIAPI _relocate(long ldbase, Elf_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf_Rela *rel = 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v4 2/3] arm: Remove unused _relocate arguments

2018-06-28 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

Signed-off-by: Ivan Gorinov 
---
 arch/arm/lib/crt0_aarch64_efi.S  | 2 --
 arch/arm/lib/crt0_arm_efi.S  | 2 --
 arch/arm/lib/reloc_aarch64_efi.c | 3 +--
 arch/arm/lib/reloc_arm_efi.c | 3 +--
 4 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S
index 5b6c384..0db4360 100644
--- a/arch/arm/lib/crt0_aarch64_efi.S
+++ b/arch/arm/lib/crt0_aarch64_efi.S
@@ -122,8 +122,6 @@ _start:
mov x29, sp
 
stp x0, x1, [sp, #16]
-   mov x2, x0
-   mov x3, x1
adr x0, ImageBase
adrpx1, _DYNAMIC
add x1, x1, #:lo12:_DYNAMIC
diff --git a/arch/arm/lib/crt0_arm_efi.S b/arch/arm/lib/crt0_arm_efi.S
index 0f296f3..23db49f 100644
--- a/arch/arm/lib/crt0_arm_efi.S
+++ b/arch/arm/lib/crt0_arm_efi.S
@@ -119,8 +119,6 @@ section_table:
 _start:
stmfd   sp!, {r0-r2, lr}
 
-   mov r2, r0
-   mov r3, r1
adr r1, .L_DYNAMIC
ldr r0, [r1]
add r1, r0, r1
diff --git a/arch/arm/lib/reloc_aarch64_efi.c b/arch/arm/lib/reloc_aarch64_efi.c
index 38c13d3..1aa57db 100644
--- a/arch/arm/lib/reloc_aarch64_efi.c
+++ b/arch/arm/lib/reloc_aarch64_efi.c
@@ -38,8 +38,7 @@
 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t EFIAPI _relocate(long ldbase, Elf64_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf64_Rela *rel = 0;
diff --git a/arch/arm/lib/reloc_arm_efi.c b/arch/arm/lib/reloc_arm_efi.c
index 6232e3f..9103c03 100644
--- a/arch/arm/lib/reloc_arm_efi.c
+++ b/arch/arm/lib/reloc_arm_efi.c
@@ -14,8 +14,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t EFIAPI _relocate(long ldbase, Elf32_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf32_Rel *rel = 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v4 1/3] x86: Remove unused _relocate arguments

2018-06-28 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

Signed-off-by: Ivan Gorinov 
---
 arch/x86/lib/crt0_x86_64_efi.S  | 3 ---
 arch/x86/lib/reloc_ia32_efi.c   | 3 +--
 arch/x86/lib/reloc_x86_64_efi.c | 3 +--
 3 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/arch/x86/lib/crt0_x86_64_efi.S b/arch/x86/lib/crt0_x86_64_efi.S
index bb8d3cf..47ed5af 100644
--- a/arch/x86/lib/crt0_x86_64_efi.S
+++ b/arch/x86/lib/crt0_x86_64_efi.S
@@ -18,9 +18,6 @@ _start:
pushq %rcx
pushq %rdx
 
-   mov %rcx, %r8
-   mov %rdx, %r9
-
lea image_base(%rip), %rcx
lea _DYNAMIC(%rip), %rdx
 
diff --git a/arch/x86/lib/reloc_ia32_efi.c b/arch/x86/lib/reloc_ia32_efi.c
index e838af3..a262533 100644
--- a/arch/x86/lib/reloc_ia32_efi.c
+++ b/arch/x86/lib/reloc_ia32_efi.c
@@ -12,8 +12,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t EFIAPI _relocate(long ldbase, Elf32_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf32_Rel *rel = 0;
diff --git a/arch/x86/lib/reloc_x86_64_efi.c b/arch/x86/lib/reloc_x86_64_efi.c
index 34c5b2e..59d6f8d 100644
--- a/arch/x86/lib/reloc_x86_64_efi.c
+++ b/arch/x86/lib/reloc_x86_64_efi.c
@@ -14,8 +14,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t EFIAPI _relocate(long ldbase, Elf64_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf64_Rel *rel = 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v4 0/3] Remove unused _relocate arguments

2018-06-28 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

v4:
  Consistently use EFIABI for _relocate() everywhere.

v3:
  Use EFIABI for _relocate() on x86;
  Rebased on u-boot/master.

v2:
  Separated the changes in efi_main() arguments and calling convention.


Ivan Gorinov (3):
  x86: Remove unused _relocate arguments
  arm: Remove unused _relocate arguments
  riscv: Remove unused _relocate arguments

 arch/arm/lib/crt0_aarch64_efi.S  | 2 --
 arch/arm/lib/crt0_arm_efi.S  | 2 --
 arch/arm/lib/reloc_aarch64_efi.c | 3 +--
 arch/arm/lib/reloc_arm_efi.c | 3 +--
 arch/riscv/lib/reloc_riscv_efi.c | 3 +--
 arch/x86/lib/crt0_x86_64_efi.S   | 3 ---
 arch/x86/lib/reloc_ia32_efi.c| 3 +--
 arch/x86/lib/reloc_x86_64_efi.c  | 3 +--
 8 files changed, 5 insertions(+), 17 deletions(-)

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v3 0/3] Remove unused _relocate arguments

2018-06-28 Thread Ivan Gorinov
On Thu, Jun 28, 2018 at 03:57:24PM +0800, Bin Meng wrote:
> Hi Ivan,
> 
> On Wed, Jun 27, 2018 at 11:41 PM, Ivan Gorinov  wrote:
> > EFI image handle and system table are not used in _relocate().
> >
> > v3:
> >   Rebased on u-boot/master
> >
> > v2:
> >   Separated the changes in efi_main() arguments and calling convention.
> >
> > Ivan Gorinov (3):
> >   x86: Remove unused _relocate arguments
> 
> I don't understand the v3 patch now.
> 
> In previous v1/v2 patch, you did not change x86's _relocate() to
> declare EFIAPI, but in v3, you suddenly added EFIAPI to the x86
> version but without adding EFIAPI to arm and risv, why?

Keeping default calling convention in v2 was a mistake because the
x86_64 startup code passes _relocate() arguments using EFI convention.

I will submit another version that consistently uses EFIAPI in _relocate().

> 
> >   arm: Remove unused _relocate arguments
> >   riscv: Remove unused _relocate arguments
> >
> >  arch/arm/lib/crt0_aarch64_efi.S  | 2 --
> >  arch/arm/lib/crt0_arm_efi.S  | 2 --
> >  arch/arm/lib/reloc_aarch64_efi.c | 3 +--
> >  arch/arm/lib/reloc_arm_efi.c | 3 +--
> >  arch/riscv/lib/reloc_riscv_efi.c | 3 +--
> >  arch/x86/lib/crt0_x86_64_efi.S   | 3 ---
> >  arch/x86/lib/reloc_ia32_efi.c| 3 +--
> >  arch/x86/lib/reloc_x86_64_efi.c  | 3 +--
> >  8 files changed, 5 insertions(+), 17 deletions(-)
> >
> 
> Regards,
> Bin
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v3] x86: Use microcode update from device tree for all processors

2018-06-28 Thread Ivan Gorinov
On Tue, Jun 26, 2018 at 03:47:49PM +0800, Bin Meng wrote:
> Hi Ivan,
> 
> On Fri, Jun 22, 2018 at 12:13 PM, Bin Meng  wrote:
> > Hi Ivan,
> >
> > On Fri, Jun 22, 2018 at 12:16 PM, Bin Meng  wrote:
> >> From: Ivan Gorinov 
> >>
> >> Built without a ROM image with FSP (u-boot.rom), the U-Boot loader applies
> >> the microcode update data block encoded in Device Tree to the bootstrap
> >> processor but not passed to the other CPUs when multiprocessing is enabled.
> >>
> >> If the bootstrap processor successfully performs a microcode update
> >> from Device Tree, use the same data block for the other processors.
> >>
> >> Signed-off-by: Ivan Gorinov 
> >> Reviewed-by: Bin Meng 
> >> [bmeng: fixed build errors on edison and qemu-x86]
> >> Signed-off-by: Bin Meng 
> >>
> >> ---
> >>
> >> Changes in v3:
> >> - don't change arch/x86/cpu/i386/cpu.c to fix build errors on edison and
> >>   qemu-x86
> >>
> >
> > I don't think the update to arch/x86/cpu/i386/cpu.c in previous
> > version is needed as mp_params.microcode_pointer is not needed during
> > the MP boot. Please test this patch to see if it works on your board.
> >
> >>  arch/x86/cpu/intel_common/car.S   |  2 ++
> >>  arch/x86/cpu/intel_common/microcode.c | 10 +++---
> >>  arch/x86/include/asm/microcode.h  |  1 +
> >>  arch/x86/lib/fsp/fsp_car.S|  4 +++-
> >>  4 files changed, 13 insertions(+), 4 deletions(-)
> 
> Did you get a chance to test this? If no issue, I will take this patch
> for v2018.07.

No issues. Thank you!

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3 3/3] riscv: Remove unused _relocate arguments

2018-06-27 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

Signed-off-by: Ivan Gorinov 
---
 arch/riscv/lib/reloc_riscv_efi.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/riscv/lib/reloc_riscv_efi.c b/arch/riscv/lib/reloc_riscv_efi.c
index 8b4b2b1..2fbbfcb 100644
--- a/arch/riscv/lib/reloc_riscv_efi.c
+++ b/arch/riscv/lib/reloc_riscv_efi.c
@@ -50,8 +50,7 @@
 #define ELF_R_TYPE ELF32_R_TYPE
 #endif
 
-efi_status_t _relocate(long ldbase, Elf_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t _relocate(long ldbase, Elf_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf_Rela *rel = 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3 1/3] x86: Remove unused _relocate arguments

2018-06-27 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

Signed-off-by: Ivan Gorinov 
---
 arch/x86/lib/crt0_x86_64_efi.S  | 3 ---
 arch/x86/lib/reloc_ia32_efi.c   | 3 +--
 arch/x86/lib/reloc_x86_64_efi.c | 3 +--
 3 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/arch/x86/lib/crt0_x86_64_efi.S b/arch/x86/lib/crt0_x86_64_efi.S
index bb8d3cf..47ed5af 100644
--- a/arch/x86/lib/crt0_x86_64_efi.S
+++ b/arch/x86/lib/crt0_x86_64_efi.S
@@ -18,9 +18,6 @@ _start:
pushq %rcx
pushq %rdx
 
-   mov %rcx, %r8
-   mov %rdx, %r9
-
lea image_base(%rip), %rcx
lea _DYNAMIC(%rip), %rdx
 
diff --git a/arch/x86/lib/reloc_ia32_efi.c b/arch/x86/lib/reloc_ia32_efi.c
index e838af3..a262533 100644
--- a/arch/x86/lib/reloc_ia32_efi.c
+++ b/arch/x86/lib/reloc_ia32_efi.c
@@ -12,8 +12,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t EFIAPI _relocate(long ldbase, Elf32_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf32_Rel *rel = 0;
diff --git a/arch/x86/lib/reloc_x86_64_efi.c b/arch/x86/lib/reloc_x86_64_efi.c
index 34c5b2e..59d6f8d 100644
--- a/arch/x86/lib/reloc_x86_64_efi.c
+++ b/arch/x86/lib/reloc_x86_64_efi.c
@@ -14,8 +14,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t EFIAPI _relocate(long ldbase, Elf64_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf64_Rel *rel = 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3 2/3] arm: Remove unused _relocate arguments

2018-06-27 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

Signed-off-by: Ivan Gorinov 
---
 arch/arm/lib/crt0_aarch64_efi.S  | 2 --
 arch/arm/lib/crt0_arm_efi.S  | 2 --
 arch/arm/lib/reloc_aarch64_efi.c | 3 +--
 arch/arm/lib/reloc_arm_efi.c | 3 +--
 4 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S
index 5b6c384..0db4360 100644
--- a/arch/arm/lib/crt0_aarch64_efi.S
+++ b/arch/arm/lib/crt0_aarch64_efi.S
@@ -122,8 +122,6 @@ _start:
mov x29, sp
 
stp x0, x1, [sp, #16]
-   mov x2, x0
-   mov x3, x1
adr x0, ImageBase
adrpx1, _DYNAMIC
add x1, x1, #:lo12:_DYNAMIC
diff --git a/arch/arm/lib/crt0_arm_efi.S b/arch/arm/lib/crt0_arm_efi.S
index 0f296f3..23db49f 100644
--- a/arch/arm/lib/crt0_arm_efi.S
+++ b/arch/arm/lib/crt0_arm_efi.S
@@ -119,8 +119,6 @@ section_table:
 _start:
stmfd   sp!, {r0-r2, lr}
 
-   mov r2, r0
-   mov r3, r1
adr r1, .L_DYNAMIC
ldr r0, [r1]
add r1, r0, r1
diff --git a/arch/arm/lib/reloc_aarch64_efi.c b/arch/arm/lib/reloc_aarch64_efi.c
index 38c13d3..1cf5cdc 100644
--- a/arch/arm/lib/reloc_aarch64_efi.c
+++ b/arch/arm/lib/reloc_aarch64_efi.c
@@ -38,8 +38,7 @@
 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf64_Rela *rel = 0;
diff --git a/arch/arm/lib/reloc_arm_efi.c b/arch/arm/lib/reloc_arm_efi.c
index 6232e3f..336a98a 100644
--- a/arch/arm/lib/reloc_arm_efi.c
+++ b/arch/arm/lib/reloc_arm_efi.c
@@ -14,8 +14,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf32_Rel *rel = 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3 0/3] Remove unused _relocate arguments

2018-06-27 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

v3:
  Rebased on u-boot/master

v2:
  Separated the changes in efi_main() arguments and calling convention.

Ivan Gorinov (3):
  x86: Remove unused _relocate arguments
  arm: Remove unused _relocate arguments
  riscv: Remove unused _relocate arguments

 arch/arm/lib/crt0_aarch64_efi.S  | 2 --
 arch/arm/lib/crt0_arm_efi.S  | 2 --
 arch/arm/lib/reloc_aarch64_efi.c | 3 +--
 arch/arm/lib/reloc_arm_efi.c | 3 +--
 arch/riscv/lib/reloc_riscv_efi.c | 3 +--
 arch/x86/lib/crt0_x86_64_efi.S   | 3 ---
 arch/x86/lib/reloc_ia32_efi.c| 3 +--
 arch/x86/lib/reloc_x86_64_efi.c  | 3 +--
 8 files changed, 5 insertions(+), 17 deletions(-)

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 2/3] arm: Remove unused _relocate arguments

2018-06-25 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

Signed-off-by: Ivan Gorinov 
---
 arch/arm/lib/crt0_aarch64_efi.S  | 2 --
 arch/arm/lib/crt0_arm_efi.S  | 2 --
 arch/arm/lib/reloc_aarch64_efi.c | 3 +--
 arch/arm/lib/reloc_arm_efi.c | 3 +--
 4 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S
index 5b6c384..0db4360 100644
--- a/arch/arm/lib/crt0_aarch64_efi.S
+++ b/arch/arm/lib/crt0_aarch64_efi.S
@@ -122,8 +122,6 @@ _start:
mov x29, sp
 
stp x0, x1, [sp, #16]
-   mov x2, x0
-   mov x3, x1
adr x0, ImageBase
adrpx1, _DYNAMIC
add x1, x1, #:lo12:_DYNAMIC
diff --git a/arch/arm/lib/crt0_arm_efi.S b/arch/arm/lib/crt0_arm_efi.S
index 0f296f3..23db49f 100644
--- a/arch/arm/lib/crt0_arm_efi.S
+++ b/arch/arm/lib/crt0_arm_efi.S
@@ -119,8 +119,6 @@ section_table:
 _start:
stmfd   sp!, {r0-r2, lr}
 
-   mov r2, r0
-   mov r3, r1
adr r1, .L_DYNAMIC
ldr r0, [r1]
add r1, r0, r1
diff --git a/arch/arm/lib/reloc_aarch64_efi.c b/arch/arm/lib/reloc_aarch64_efi.c
index 38c13d3..1cf5cdc 100644
--- a/arch/arm/lib/reloc_aarch64_efi.c
+++ b/arch/arm/lib/reloc_aarch64_efi.c
@@ -38,8 +38,7 @@
 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf64_Rela *rel = 0;
diff --git a/arch/arm/lib/reloc_arm_efi.c b/arch/arm/lib/reloc_arm_efi.c
index 6232e3f..336a98a 100644
--- a/arch/arm/lib/reloc_arm_efi.c
+++ b/arch/arm/lib/reloc_arm_efi.c
@@ -14,8 +14,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf32_Rel *rel = 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 3/3] riscv: Remove unused _relocate arguments

2018-06-25 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

Signed-off-by: Ivan Gorinov 
---
 arch/riscv/lib/reloc_riscv_efi.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/riscv/lib/reloc_riscv_efi.c b/arch/riscv/lib/reloc_riscv_efi.c
index 8b4b2b1..2fbbfcb 100644
--- a/arch/riscv/lib/reloc_riscv_efi.c
+++ b/arch/riscv/lib/reloc_riscv_efi.c
@@ -50,8 +50,7 @@
 #define ELF_R_TYPE ELF32_R_TYPE
 #endif
 
-efi_status_t _relocate(long ldbase, Elf_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t _relocate(long ldbase, Elf_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf_Rela *rel = 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 1/3] x86: Remove unused _relocate arguments

2018-06-25 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

Signed-off-by: Ivan Gorinov 
---
 arch/x86/lib/crt0_x86_64_efi.S  | 3 ---
 arch/x86/lib/reloc_ia32_efi.c   | 3 +--
 arch/x86/lib/reloc_x86_64_efi.c | 3 +--
 3 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/arch/x86/lib/crt0_x86_64_efi.S b/arch/x86/lib/crt0_x86_64_efi.S
index bb8d3cf..47ed5af 100644
--- a/arch/x86/lib/crt0_x86_64_efi.S
+++ b/arch/x86/lib/crt0_x86_64_efi.S
@@ -18,9 +18,6 @@ _start:
pushq %rcx
pushq %rdx
 
-   mov %rcx, %r8
-   mov %rdx, %r9
-
lea image_base(%rip), %rcx
lea _DYNAMIC(%rip), %rdx
 
diff --git a/arch/x86/lib/reloc_ia32_efi.c b/arch/x86/lib/reloc_ia32_efi.c
index f0bd2db..4fb0e56 100644
--- a/arch/x86/lib/reloc_ia32_efi.c
+++ b/arch/x86/lib/reloc_ia32_efi.c
@@ -11,8 +11,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf32_Rel *rel = 0;
diff --git a/arch/x86/lib/reloc_x86_64_efi.c b/arch/x86/lib/reloc_x86_64_efi.c
index adc80ea..9361235 100644
--- a/arch/x86/lib/reloc_x86_64_efi.c
+++ b/arch/x86/lib/reloc_x86_64_efi.c
@@ -13,8 +13,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf64_Rel *rel = 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 0/3] Remove unused _relocate arguments

2018-06-25 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

v2:
  Separated the changes in efi_main() arguments and calling convention.

Ivan Gorinov (3):
  x86: Remove unused _relocate arguments
  arm: Remove unused _relocate arguments
  riscv: Remove unused _relocate arguments

 arch/arm/lib/crt0_aarch64_efi.S  | 2 --
 arch/arm/lib/crt0_arm_efi.S  | 2 --
 arch/arm/lib/reloc_aarch64_efi.c | 3 +--
 arch/arm/lib/reloc_arm_efi.c | 3 +--
 arch/riscv/lib/reloc_riscv_efi.c | 3 +--
 arch/x86/lib/crt0_x86_64_efi.S   | 3 ---
 arch/x86/lib/reloc_ia32_efi.c| 3 +--
 arch/x86/lib/reloc_x86_64_efi.c  | 3 +--
 8 files changed, 5 insertions(+), 17 deletions(-)

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] x86: fix broken qemu and edison builds

2018-06-21 Thread Ivan Gorinov
Commit 2407183f98cf130b008125ef1718ccf89a192998 breaks
the qemu-x86 and edison builds.

Move ucode_base and ucode_size into common startup code,
except for configs with FSP.

Signed-off-by: Ivan Gorinov 
---
 arch/x86/cpu/intel_common/car.S | 10 --
 arch/x86/cpu/start.S| 10 ++
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/x86/cpu/intel_common/car.S b/arch/x86/cpu/intel_common/car.S
index 52a77bb..7295e0f 100644
--- a/arch/x86/cpu/intel_common/car.S
+++ b/arch/x86/cpu/intel_common/car.S
@@ -232,13 +232,3 @@ mtrr_table:
.word 0x20C, 0x20D, 0x20E, 0x20F
.word 0x210, 0x211, 0x212, 0x213
 mtrr_table_end:
-
-   .align 4
-_dt_ucode_base_size:
-   /* These next two fields are filled in by ifdtool */
-.globl ucode_base
-ucode_base:/* Declared in microcode.h */
-   .long   0   /* microcode base */
-.globl ucode_size
-ucode_size:/* Declared in microcode.h */
-   .long   0   /* microcode size */
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
index e4e997e..1fdd82a 100644
--- a/arch/x86/cpu/start.S
+++ b/arch/x86/cpu/start.S
@@ -291,3 +291,13 @@ gdt_rom2:
.byte   0xcf/* flags + limit_high */
.byte   0x00/* base_high */
 #endif
+
+#ifndef CONFIG_HAVE_FSP
+   .align 4
+.globl ucode_base
+ucode_base:/* Declared in microcode.h */
+   .long   0   /* microcode base */
+.globl ucode_size
+ucode_size:/* Declared in microcode.h */
+   .long   0   /* microcode size */
+#endif
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3] x86: Add 64-bit setjmp/longjmp implementation

2018-06-19 Thread Ivan Gorinov
Add setjmp/longjmp functions for x86_64.

v3:
  Removed the FPU control word and MXCSR;
  Corrected SPDX License Identifier.

v2:
  Added the FPU control word and MXCSR to jmp_buf;
  Using ENTRY/ENDPROC macros.

Ivan Gorinov (1):
  x86: Add 64-bit setjmp/longjmp implementation

 arch/x86/cpu/x86_64/setjmp.S  | 49 +++
 arch/x86/cpu/x86_64/setjmp.c  | 19 -
 arch/x86/include/asm/setjmp.h | 17 +++
 3 files changed, 66 insertions(+), 19 deletions(-)
 create mode 100644 arch/x86/cpu/x86_64/setjmp.S
 delete mode 100644 arch/x86/cpu/x86_64/setjmp.c

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3] x86: Add 64-bit setjmp/longjmp implementation

2018-06-19 Thread Ivan Gorinov
Add setjmp/longjmp functions for x86_64.

Signed-off-by: Ivan Gorinov 
---
 arch/x86/cpu/x86_64/setjmp.S  | 49 +++
 arch/x86/cpu/x86_64/setjmp.c  | 19 -
 arch/x86/include/asm/setjmp.h | 17 +++
 3 files changed, 66 insertions(+), 19 deletions(-)
 create mode 100644 arch/x86/cpu/x86_64/setjmp.S
 delete mode 100644 arch/x86/cpu/x86_64/setjmp.c

diff --git a/arch/x86/cpu/x86_64/setjmp.S b/arch/x86/cpu/x86_64/setjmp.S
new file mode 100644
index 000..97b8128
--- /dev/null
+++ b/arch/x86/cpu/x86_64/setjmp.S
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Intel Corporation
+ *
+ * See arch/x86/include/asm/setjmp.h for jmp_buf format
+ */
+
+#include 
+
+.text
+.align 8
+
+ENTRY(setjmp)
+
+   pop %rcx
+   movq%rcx, (%rdi)/* Return address */
+   movq%rsp, 8(%rdi)
+   movq%rbp, 16(%rdi)
+   movq%rbx, 24(%rdi)
+   movq%r12, 32(%rdi)
+   movq%r13, 40(%rdi)
+   movq%r14, 48(%rdi)
+   movq%r15, 56(%rdi)
+   xorq%rax, %rax  /* Direct invocation returns 0 */
+   jmpq*%rcx
+
+ENDPROC(setjmp)
+
+.align 8
+
+ENTRY(longjmp)
+
+   movq(%rdi), %rcx/* Return address */
+   movq8(%rdi), %rsp
+   movq16(%rdi), %rbp
+   movq24(%rdi), %rbx
+   movq32(%rdi), %r12
+   movq40(%rdi), %r13
+   movq48(%rdi), %r14
+   movq56(%rdi), %r15
+
+   movq%rsi, %rax  /* Value to be returned by setjmp() */
+   testq   %rax, %rax  /* cannot be 0 in this case */
+   jnz 1f
+   incq%rax/* Return 1 instead */
+1:
+   jmpq*%rcx
+
+ENDPROC(longjmp)
diff --git a/arch/x86/cpu/x86_64/setjmp.c b/arch/x86/cpu/x86_64/setjmp.c
deleted file mode 100644
index 5d4a74a..000
--- a/arch/x86/cpu/x86_64/setjmp.c
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2016 Google, Inc
- */
-
-#include 
-#include 
-
-int setjmp(struct jmp_buf_data *jmp_buf)
-{
-   printf("WARNING: setjmp() is not supported\n");
-
-   return 0;
-}
-
-void longjmp(struct jmp_buf_data *jmp_buf, int val)
-{
-   printf("WARNING: longjmp() is not supported\n");
-}
diff --git a/arch/x86/include/asm/setjmp.h b/arch/x86/include/asm/setjmp.h
index f25975f..49c36c1 100644
--- a/arch/x86/include/asm/setjmp.h
+++ b/arch/x86/include/asm/setjmp.h
@@ -8,6 +8,21 @@
 #ifndef __setjmp_h
 #define __setjmp_h
 
+#ifdef CONFIG_X86_64
+
+struct jmp_buf_data {
+   unsigned long __rip;
+   unsigned long __rsp;
+   unsigned long __rbp;
+   unsigned long __rbx;
+   unsigned long __r12;
+   unsigned long __r13;
+   unsigned long __r14;
+   unsigned long __r15;
+};
+
+#else
+
 struct jmp_buf_data {
unsigned int __ebx;
unsigned int __esp;
@@ -17,6 +32,8 @@ struct jmp_buf_data {
unsigned int __eip;
 };
 
+#endif
+
 int setjmp(struct jmp_buf_data *jmp_buf);
 void longjmp(struct jmp_buf_data *jmp_buf, int val);
 
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2] x86: Use microcode update from device tree for all processors

2018-06-15 Thread Ivan Gorinov
Built without a ROM image with FSP (u-boot.rom), the U-Boot loader applies
the microcode update data block encoded in Device Tree to the bootstrap
processor but not passed to the other CPUs when multiprocessing is enabled.

If the bootstrap processor successfully performs a microcode update
from Device Tree, use the same data block for the other processors.

Signed-off-by: Ivan Gorinov 
---
 arch/x86/cpu/i386/cpu.c   |  3 ++-
 arch/x86/cpu/intel_common/car.S   |  2 ++
 arch/x86/cpu/intel_common/microcode.c | 10 +++---
 arch/x86/include/asm/microcode.h  |  1 +
 arch/x86/lib/fsp/fsp_car.S|  4 +++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index 208ef08..90e3e8b 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -585,7 +586,7 @@ int x86_mp_init(void)
mp_params.parallel_microcode_load = 0,
mp_params.flight_plan = _steps[0];
mp_params.num_records = ARRAY_SIZE(mp_steps);
-   mp_params.microcode_pointer = 0;
+   mp_params.microcode_pointer = (void *)ucode_base;
 
if (mp_init(_params)) {
printf("Warning: MP init failure\n");
diff --git a/arch/x86/cpu/intel_common/car.S b/arch/x86/cpu/intel_common/car.S
index fe8dfbc..52a77bb 100644
--- a/arch/x86/cpu/intel_common/car.S
+++ b/arch/x86/cpu/intel_common/car.S
@@ -239,4 +239,6 @@ _dt_ucode_base_size:
 .globl ucode_base
 ucode_base:/* Declared in microcode.h */
.long   0   /* microcode base */
+.globl ucode_size
+ucode_size:/* Declared in microcode.h */
.long   0   /* microcode size */
diff --git a/arch/x86/cpu/intel_common/microcode.c 
b/arch/x86/cpu/intel_common/microcode.c
index 11b1ec8..c7a539d 100644
--- a/arch/x86/cpu/intel_common/microcode.c
+++ b/arch/x86/cpu/intel_common/microcode.c
@@ -43,8 +43,6 @@ static int microcode_decode_node(const void *blob, int node,
update->data = fdt_getprop(blob, node, "data", >size);
if (!update->data)
return -ENOENT;
-   update->data += UCODE_HEADER_LEN;
-   update->size -= UCODE_HEADER_LEN;
 
update->header_version = fdtdec_get_int(blob, node,
"intel,header-version", 0);
@@ -124,6 +122,7 @@ static void microcode_read_cpu(struct microcode_update *cpu)
 int microcode_update_intel(void)
 {
struct microcode_update cpu, update;
+   ulong address;
const void *blob = gd->fdt_blob;
int skipped;
int count;
@@ -167,7 +166,8 @@ int microcode_update_intel(void)
skipped++;
continue;
}
-   wrmsr(MSR_IA32_UCODE_WRITE, (ulong)update.data, 0);
+   address = (ulong)update.data + UCODE_HEADER_LEN;
+   wrmsr(MSR_IA32_UCODE_WRITE, address, 0);
rev = microcode_read_rev();
debug("microcode: updated to revision 0x%x 
date=%04x-%02x-%02x\n",
  rev, update.date_code & 0x,
@@ -178,5 +178,9 @@ int microcode_update_intel(void)
return -EFAULT;
}
count++;
+   if (!ucode_base) {
+   ucode_base = (ulong)update.data;
+   ucode_size = update.size;
+   }
} while (1);
 }
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index f7b32a5..4ab7504 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -10,6 +10,7 @@
 
 /* This is a declaration for ucode_base in start.S */
 extern u32 ucode_base;
+extern u32 ucode_size;
 
 /**
  * microcode_update_intel() - Apply microcode updates
diff --git a/arch/x86/lib/fsp/fsp_car.S b/arch/x86/lib/fsp/fsp_car.S
index 549d863..48edc83 100644
--- a/arch/x86/lib/fsp/fsp_car.S
+++ b/arch/x86/lib/fsp/fsp_car.S
@@ -102,8 +102,10 @@ temp_ram_init_params:
 _dt_ucode_base_size:
/* These next two fields are filled in by ifdtool */
 .globl ucode_base
-ucode_base:/* Declared in micrcode.h */
+ucode_base:/* Declared in microcode.h */
.long   0   /* microcode base */
+.globl ucode_size
+ucode_size:/* Declared in microcode.h */
.long   0   /* microcode size */
.long   CONFIG_SYS_MONITOR_BASE /* code region base */
.long   CONFIG_SYS_MONITOR_LEN  /* code region size */
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2] x86: Use microcode update from device tree for all processors

2018-06-15 Thread Ivan Gorinov
Built without a ROM image with FSP (u-boot.rom), the U-Boot loader applies
the microcode update data block encoded in Device Tree to the bootstrap
processor but not passed to the other CPUs when multiprocessing is enabled.

If the bootstrap processor successfully performs a microcode update
from Device Tree, use the same data block for the other processors.

v2:
  Corrected the order of included header files

Ivan Gorinov (1):
  x86: Use microcode update from device tree for all processors

 arch/x86/cpu/i386/cpu.c   |  3 ++-
 arch/x86/cpu/intel_common/car.S   |  2 ++
 arch/x86/cpu/intel_common/microcode.c | 10 +++---
 arch/x86/include/asm/microcode.h  |  1 +
 arch/x86/lib/fsp/fsp_car.S|  4 +++-
 5 files changed, 15 insertions(+), 5 deletions(-)

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation

2018-06-14 Thread Ivan Gorinov
On Wed, Jun 13, 2018 at 05:36:26PM -0700, Ivan Gorinov wrote:

> > But bootefi selftest with your patch leads to an immediate reset of the
> > qemu-x86_64 board.
> 
> Reproduced the qemu-x86_64 reset.
> The "info registers" command shows CR0.MP = 0.
> Setting it in 64-bit startup code did not help.
> I will try to fix that.
> 
> On a 64-bit Minnowboard configuration, bootefi works without reset.

The "bootefi selftest" command works on qemu-x86_64 when $loadaddr is changed:
  => env set loadaddr 0x1000

Another patch "x86: use EFI calling convention for efi_main on x86_64"
also needs to be applied.

The self test starts but crashes on 'manage protocols':

  Tearing down 'graphical output'
  Tearing down 'graphical output' succeeded

  Setting up 'manage protocols'


Same effect with a 64-bit build for Minnowboard.
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation

2018-06-13 Thread Ivan Gorinov
On Tue, Jun 12, 2018 at 05:57:34PM +0200, Heinrich Schuchardt wrote:
> On 06/06/2018 08:28 PM, Ivan Gorinov wrote:
> > Add setjmp/longjmp functions for x86_64.
> > The FPU control word and MXCSR control bits are preserved across calls.
> 
> With this patch
> 
> make mrproper && make qemu-x86_64_defconfig && make -j6
> 
> produces
> 
> arch/x86/cpu/built-in.o: In function `car_init':
> arch/x86/cpu/qemu/car.S:25: undefined reference to `car_init_ret'
> 
> The error does not occur without this patch.
> 
> The missing symbol is defined in
> arch/x86/cpu/start.S:98:car_init_ret:
> but it is not defined in
> arch/x86/cpu/start64.S
> 
> The following patch helps:
> 
> [PATCH 1/1] x86: qemu: do not build car.o with start64.o
> https://lists.denx.de/pipermail/u-boot/2018-June/331440.html

Thank you! Now it builds.

> But bootefi selftest with your patch leads to an immediate reset of the
> qemu-x86_64 board.

Reproduced the qemu-x86_64 reset.
The "info registers" command shows CR0.MP = 0.
Setting it in 64-bit startup code did not help.
I will try to fix that.

On a 64-bit Minnowboard configuration, bootefi works without reset.

> 
> Best regards
> 
> Heinrich
> 
> > 
> > Signed-off-by: Ivan Gorinov 
> > ---
> >  arch/x86/cpu/x86_64/setjmp.S  | 66 
> > +++
> >  arch/x86/cpu/x86_64/setjmp.c  | 19 -
> >  arch/x86/include/asm/setjmp.h | 19 +
> >  3 files changed, 85 insertions(+), 19 deletions(-)
> >  create mode 100644 arch/x86/cpu/x86_64/setjmp.S
> >  delete mode 100644 arch/x86/cpu/x86_64/setjmp.c
> > 
> > diff --git a/arch/x86/cpu/x86_64/setjmp.S b/arch/x86/cpu/x86_64/setjmp.S
> > new file mode 100644
> > index 000..ef61a4a
> > --- /dev/null
> > +++ b/arch/x86/cpu/x86_64/setjmp.S
> > @@ -0,0 +1,66 @@
> > +/*
> > + * Copyright (C) 2018 Intel Corporation
> > + *
> > + * SPDX-License-Identifier: GPL-2.0+
> > + *
> > + * See arch/x86/include/asm/setjmp.h for jmp_buf format
> > + */
> > +
> > +#include 
> > +
> > +.text
> > +.align 8
> > +
> > +ENTRY(setjmp)
> > +
> > +   pop %rcx
> > +   movq%rcx, (%rdi)/* Return address */
> > +   movq%rsp, 8 (%rdi)
> > +   movq%rbp, 16 (%rdi)
> > +   movq%rbx, 24 (%rdi)
> > +   movq%r12, 32 (%rdi)
> > +   movq%r13, 40 (%rdi)
> > +   movq%r14, 48 (%rdi)
> > +   movq%r15, 56 (%rdi)
> > +   fnstcw  64 (%rdi)
> > +   stmxcsr 68 (%rdi)
> > +   xorq%rax, %rax  /* Direct invocation returns 0 */
> > +   jmpq*%rcx
> > +
> > +ENDPROC(setjmp)
> > +
> > +.align 8
> > +
> > +ENTRY(longjmp)
> > +
> > +   subq$8, %rsp
> > +
> > +/* Restore the control bits of MXCSR */
> > +
> > +   stmxcsr (%rsp)
> > +   movl$0x3f, %eax
> > +   andl%eax, (%rsp)
> > +   notl%eax
> > +   andl68 (%rdi), %eax
> > +   orl %eax, (%rsp)
> > +   ldmxcsr (%rsp)
> > +
> > +   fldcw   64 (%rdi)
> > +
> > +   movq(%rdi), %rcx/* Return address */
> > +   movq8 (%rdi), %rsp
> > +   movq16 (%rdi), %rbp
> > +   movq24 (%rdi), %rbx
> > +   movq32 (%rdi), %r12
> > +   movq40 (%rdi), %r13
> > +   movq48 (%rdi), %r14
> > +   movq56 (%rdi), %r15
> > +
> > +   movq%rsi, %rax  /* Value to be returned by setjmp() */
> > +   testq   %rax, %rax  /* cannot be 0 in this case */
> > +   jnz 1f
> > +   incq%rax/* Return 1 instead */
> > +1:
> > +   jmpq*%rcx
> > +
> > +ENDPROC(longjmp)
> > diff --git a/arch/x86/cpu/x86_64/setjmp.c b/arch/x86/cpu/x86_64/setjmp.c
> > deleted file mode 100644
> > index 5d4a74a..000
> > --- a/arch/x86/cpu/x86_64/setjmp.c
> > +++ /dev/null
> > @@ -1,19 +0,0 @@
> > -// SPDX-License-Identifier: GPL-2.0+
> > -/*
> > - * Copyright (c) 2016 Google, Inc
> > - */
> > -
> > -#include 
> > -#include 
> > -
> > -int setjmp(struct jmp_buf_data *jmp_buf)
> > -{
> > -   printf("WARNING: setjmp() is not supported\n");
> > -
> > -   return 0;
> > -}
> > -
> > -void longjmp(struct jmp_buf_data *jmp_buf, int val)
> > -{
> > -   printf("WARNING: longjmp() is not supported\n");
> > -}
> > diff --git a/arch/x86/include/asm/setjmp.h b/arch/x86/include/asm/setjmp.h
> > index f25975f..eae33fb 100644
> > --- a/arc

[U-Boot] [PATCH v5] x86: use EFI calling convention for efi_main on x86_64

2018-06-13 Thread Ivan Gorinov
UEFI specifies the calling convention used in Microsoft compilers;
first arguments of a function are passed in (%rcx, %rdx, %r8, %r9).

All other compilers use System V ABI by default, passing first integer
arguments of a function in (%rdi, %rsi, %rdx, %rcx, %r8, %r9).

These ABI also specify different sets of registers that must be preserved
across function calls (callee-saved).

GCC allows using the Microsoft calling convention by adding the ms_abi
attribute to a function declaration.

Current EFI implementation in U-Boot specifies EFIAPI for efi_main()
in the test apps but uses default calling convention in lib/efi.

Save efi_main() arguments in the startup code on x86_64;
use EFI calling convention for _relocate() on x86_64;
consistently use EFI calling convention for efi_main() everywhere.

Signed-off-by: Ivan Gorinov 
---
 arch/x86/lib/crt0_x86_64_efi.S | 24 +---
 lib/efi/efi_app.c  |  3 ++-
 lib/efi/efi_stub.c |  3 ++-
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/arch/x86/lib/crt0_x86_64_efi.S b/arch/x86/lib/crt0_x86_64_efi.S
index 989799f..8a25ceb 100644
--- a/arch/x86/lib/crt0_x86_64_efi.S
+++ b/arch/x86/lib/crt0_x86_64_efi.S
@@ -3,7 +3,7 @@
  * crt0-efi-x86_64.S - x86_64 EFI startup code.
  * Copyright (C) 1999 Hewlett-Packard Co.
  * Contributed by David Mosberger .
- * Copyright (C) 2005 Intel Co.
+ * Copyright (C) 2005 Intel Corporation
  * Contributed by Fenghua Yu .
  *
  * All rights reserved.
@@ -14,26 +14,28 @@
.globl _start
 _start:
subq $8, %rsp
+
pushq %rcx
pushq %rdx
 
-0:
-   lea image_base(%rip), %rdi
-   lea _DYNAMIC(%rip), %rsi
+   mov %rcx, %r8
+   mov %rdx, %r9
+
+   lea image_base(%rip), %rcx
+   lea _DYNAMIC(%rip), %rdx
 
-   popq %rcx
-   popq %rdx
-   pushq %rcx
-   pushq %rdx
call _relocate
 
-   popq %rdi
-   popq %rsi
+   popq %rdx
+   popq %rcx
+
+   testq %rax, %rax
+   jnz .exit
 
call efi_main
+.exit:
addq $8, %rsp
 
-.exit:
ret
 
/*
diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c
index c828093..3eb8eeb 100644
--- a/lib/efi/efi_app.c
+++ b/lib/efi/efi_app.c
@@ -96,7 +96,8 @@ static void free_memory(struct efi_priv *priv)
  * U-Boot. If it returns, EFI will continue. Another way to get back to EFI
  * is via reset_cpu().
  */
-efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+efi_status_t EFIAPI efi_main(efi_handle_t image,
+struct efi_system_table *sys_table)
 {
struct efi_priv local_priv, *priv = _priv;
efi_status_t ret;
diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
index 3138739..399d16b 100644
--- a/lib/efi/efi_stub.c
+++ b/lib/efi/efi_stub.c
@@ -268,7 +268,8 @@ static void add_entry_addr(struct efi_priv *priv, enum 
efi_entry_t type,
  * This function is called by our EFI start-up code. It handles running
  * U-Boot. If it returns, EFI will continue.
  */
-efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+efi_status_t EFIAPI efi_main(efi_handle_t image,
+struct efi_system_table *sys_table)
 {
struct efi_priv local_priv, *priv = _priv;
struct efi_boot_services *boot = sys_table->boottime;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v5] x86: use EFI calling convention for efi_main on x86_64

2018-06-13 Thread Ivan Gorinov
UEFI specifies the calling convention used in Microsoft compilers;
first arguments of a function are passed in (%rcx, %rdx, %r8, %r9).

All other compilers use System V ABI by default, passing first integer
arguments of a function in (%rdi, %rsi, %rdx, %rcx, %r8, %r9).

These ABI also specify different sets of registers that must be preserved
across function calls (callee-saved).

GCC allows using the Microsoft calling convention by adding the ms_abi
attribute to a function declaration.

Current EFI implementation in U-Boot specifies EFIAPI for efi_main()
in the test apps but uses default calling convention in lib/efi.

Save efi_main() arguments in the startup code on x86_64;
use EFI calling convention for _relocate() on x86_64;
consistently use EFI calling convention for efi_main() everywhere.

v5:
  Keeping unused _relocate() arguments, to be submitted as another patch.

v4:
  Keeping .exit label in x86_64 startup code;
  Also removed the unused _relocate() arguments for arm, x86, riscv.

v3:
  Updated patch description.

v2:
  Added EFIABI to _relocate() declaration.

Ivan Gorinov (1):
  x86: use EFI calling convention for efi_main on x86_64

 arch/x86/lib/crt0_x86_64_efi.S | 24 +---
 lib/efi/efi_app.c  |  3 ++-
 lib/efi/efi_stub.c |  3 ++-
 3 files changed, 17 insertions(+), 13 deletions(-)

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v4 4/4] riscv: Remove unused _relocate arguments

2018-06-12 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

Signed-off-by: Ivan Gorinov 
---
 arch/riscv/lib/reloc_riscv_efi.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/riscv/lib/reloc_riscv_efi.c b/arch/riscv/lib/reloc_riscv_efi.c
index 8b4b2b1..51b7520 100644
--- a/arch/riscv/lib/reloc_riscv_efi.c
+++ b/arch/riscv/lib/reloc_riscv_efi.c
@@ -50,8 +50,7 @@
 #define ELF_R_TYPE ELF32_R_TYPE
 #endif
 
-efi_status_t _relocate(long ldbase, Elf_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t _relocate(long ldbase, Elf_Dyn *dyn, efi_handle_t image)
 {
long relsz = 0, relent = 0;
Elf_Rela *rel = 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v4 3/4] x86: Remove unused _relocate arguments

2018-06-12 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

Signed-off-by: Ivan Gorinov 
---
 arch/x86/lib/reloc_ia32_efi.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/lib/reloc_ia32_efi.c b/arch/x86/lib/reloc_ia32_efi.c
index e838af3..49a0b94 100644
--- a/arch/x86/lib/reloc_ia32_efi.c
+++ b/arch/x86/lib/reloc_ia32_efi.c
@@ -12,8 +12,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf32_Rel *rel = 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v4 2/4] arm: Remove unused _relocate arguments

2018-06-12 Thread Ivan Gorinov
EFI image handle and system table are not used in _relocate().

Signed-off-by: Ivan Gorinov 
---
 arch/arm/lib/crt0_aarch64_efi.S  | 2 --
 arch/arm/lib/crt0_arm_efi.S  | 2 --
 arch/arm/lib/reloc_aarch64_efi.c | 3 +--
 arch/arm/lib/reloc_arm_efi.c | 3 +--
 4 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S
index 5b6c384..0db4360 100644
--- a/arch/arm/lib/crt0_aarch64_efi.S
+++ b/arch/arm/lib/crt0_aarch64_efi.S
@@ -122,8 +122,6 @@ _start:
mov x29, sp
 
stp x0, x1, [sp, #16]
-   mov x2, x0
-   mov x3, x1
adr x0, ImageBase
adrpx1, _DYNAMIC
add x1, x1, #:lo12:_DYNAMIC
diff --git a/arch/arm/lib/crt0_arm_efi.S b/arch/arm/lib/crt0_arm_efi.S
index 0f296f3..23db49f 100644
--- a/arch/arm/lib/crt0_arm_efi.S
+++ b/arch/arm/lib/crt0_arm_efi.S
@@ -119,8 +119,6 @@ section_table:
 _start:
stmfd   sp!, {r0-r2, lr}
 
-   mov r2, r0
-   mov r3, r1
adr r1, .L_DYNAMIC
ldr r0, [r1]
add r1, r0, r1
diff --git a/arch/arm/lib/reloc_aarch64_efi.c b/arch/arm/lib/reloc_aarch64_efi.c
index 38c13d3..c648fe4 100644
--- a/arch/arm/lib/reloc_aarch64_efi.c
+++ b/arch/arm/lib/reloc_aarch64_efi.c
@@ -38,8 +38,7 @@
 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image)
 {
long relsz = 0, relent = 0;
Elf64_Rela *rel = 0;
diff --git a/arch/arm/lib/reloc_arm_efi.c b/arch/arm/lib/reloc_arm_efi.c
index 6232e3f..336a98a 100644
--- a/arch/arm/lib/reloc_arm_efi.c
+++ b/arch/arm/lib/reloc_arm_efi.c
@@ -14,8 +14,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf32_Rel *rel = 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v4 1/4] x86: use EFI calling convention for efi_main on x86_64

2018-06-12 Thread Ivan Gorinov
UEFI specifies the calling convention used in Microsoft compilers;
first arguments of a function are passed in (%rcx, %rdx, %r8, %r9).

All other compilers use System V ABI by default, passing first integer
arguments of a function in (%rdi, %rsi, %rdx, %rcx, %r8, %r9).

These ABI also specify different sets of registers that must be preserved
across function calls (callee-saved).

GCC allows using the Microsoft calling convention by adding the ms_abi
attribute to a function declaration.

Current EFI implementation in U-Boot specifies EFIAPI for efi_main()
in the test apps but uses default calling convention in lib/efi.
The arguments of efi_main() are also passed as unused arguments to the
_relocate() function.

Save efi_main() arguments in the startup code on x86_64;
use EFI calling convention for _relocate() on x86_64;
remove unused _relocate() arguments;
consistently use EFI calling convention for efi_main() everywhere.

Signed-off-by: Ivan Gorinov 
---
 arch/x86/lib/crt0_x86_64_efi.S  | 21 ++---
 arch/x86/lib/reloc_x86_64_efi.c |  3 +--
 lib/efi/efi_app.c   |  3 ++-
 lib/efi/efi_stub.c  |  3 ++-
 4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/x86/lib/crt0_x86_64_efi.S b/arch/x86/lib/crt0_x86_64_efi.S
index 989799f..096f347 100644
--- a/arch/x86/lib/crt0_x86_64_efi.S
+++ b/arch/x86/lib/crt0_x86_64_efi.S
@@ -3,7 +3,7 @@
  * crt0-efi-x86_64.S - x86_64 EFI startup code.
  * Copyright (C) 1999 Hewlett-Packard Co.
  * Contributed by David Mosberger .
- * Copyright (C) 2005 Intel Co.
+ * Copyright (C) 2005 Intel Corporation
  * Contributed by Fenghua Yu .
  *
  * All rights reserved.
@@ -14,26 +14,25 @@
.globl _start
 _start:
subq $8, %rsp
+
pushq %rcx
pushq %rdx
 
-0:
-   lea image_base(%rip), %rdi
-   lea _DYNAMIC(%rip), %rsi
+   lea image_base(%rip), %rcx
+   lea _DYNAMIC(%rip), %rdx
 
-   popq %rcx
-   popq %rdx
-   pushq %rcx
-   pushq %rdx
call _relocate
 
-   popq %rdi
-   popq %rsi
+   popq %rdx
+   popq %rcx
+
+   testq %rax, %rax
+   jnz _exit
 
call efi_main
+.exit:
addq $8, %rsp
 
-.exit:
ret
 
/*
diff --git a/arch/x86/lib/reloc_x86_64_efi.c b/arch/x86/lib/reloc_x86_64_efi.c
index 34c5b2e..59d6f8d 100644
--- a/arch/x86/lib/reloc_x86_64_efi.c
+++ b/arch/x86/lib/reloc_x86_64_efi.c
@@ -14,8 +14,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t EFIAPI _relocate(long ldbase, Elf64_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf64_Rel *rel = 0;
diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c
index c828093..3eb8eeb 100644
--- a/lib/efi/efi_app.c
+++ b/lib/efi/efi_app.c
@@ -96,7 +96,8 @@ static void free_memory(struct efi_priv *priv)
  * U-Boot. If it returns, EFI will continue. Another way to get back to EFI
  * is via reset_cpu().
  */
-efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+efi_status_t EFIAPI efi_main(efi_handle_t image,
+struct efi_system_table *sys_table)
 {
struct efi_priv local_priv, *priv = _priv;
efi_status_t ret;
diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
index 3138739..399d16b 100644
--- a/lib/efi/efi_stub.c
+++ b/lib/efi/efi_stub.c
@@ -268,7 +268,8 @@ static void add_entry_addr(struct efi_priv *priv, enum 
efi_entry_t type,
  * This function is called by our EFI start-up code. It handles running
  * U-Boot. If it returns, EFI will continue.
  */
-efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+efi_status_t EFIAPI efi_main(efi_handle_t image,
+struct efi_system_table *sys_table)
 {
struct efi_priv local_priv, *priv = _priv;
struct efi_boot_services *boot = sys_table->boottime;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v4 0/4] x86: use EFI calling convention for efi_main on x86_64

2018-06-12 Thread Ivan Gorinov
UEFI specifies the calling convention used in Microsoft compilers;
first arguments of a function are passed in (%rcx, %rdx, %r8, %r9).

All other compilers use System V ABI by default, passing first integer
arguments of a function in (%rdi, %rsi, %rdx, %rcx, %r8, %r9).

These ABI also specify different sets of registers that must be preserved
across function calls (callee-saved).

GCC allows using the Microsoft calling convention by adding the ms_abi
attribute to a function declaration.

Current EFI implementation in U-Boot specifies EFIAPI for efi_main()
in the test apps but uses default calling convention in lib/efi.
The arguments of efi_main() are also passed as unused arguments to the
_relocate() function.

Save efi_main() arguments in the startup code on x86_64;
use EFI calling convention for _relocate() on x86_64;
remove unused _relocate() arguments;
consistently use EFI calling convention for efi_main() everywhere.

v4:
  Keeping .exit label in x86_64 startup code;
  Also removed the unused _relocate() arguments for arm, x86, riscv.

v3:
  Updated patch description.

v2:
  Added EFIABI to _relocate() declaration.

Ivan Gorinov (4):
  x86: use EFI calling convention for efi_main on x86_64
  arm: Remove unused _relocate arguments
  x86: Remove unused _relocate arguments
  riscv: Remove unused _relocate arguments

 arch/arm/lib/crt0_aarch64_efi.S  |  2 --
 arch/arm/lib/crt0_arm_efi.S  |  2 --
 arch/arm/lib/reloc_aarch64_efi.c |  3 +--
 arch/arm/lib/reloc_arm_efi.c |  3 +--
 arch/riscv/lib/reloc_riscv_efi.c |  3 +--
 arch/x86/lib/crt0_x86_64_efi.S   | 21 ++---
 arch/x86/lib/reloc_ia32_efi.c|  3 +--
 arch/x86/lib/reloc_x86_64_efi.c  |  3 +--
 lib/efi/efi_app.c|  3 ++-
 lib/efi/efi_stub.c   |  3 ++-
 10 files changed, 19 insertions(+), 27 deletions(-)

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation

2018-06-06 Thread Ivan Gorinov
Add setjmp/longjmp functions for x86_64.
The FPU control word and MXCSR control bits are preserved across calls.

Signed-off-by: Ivan Gorinov 
---
 arch/x86/cpu/x86_64/setjmp.S  | 66 +++
 arch/x86/cpu/x86_64/setjmp.c  | 19 -
 arch/x86/include/asm/setjmp.h | 19 +
 3 files changed, 85 insertions(+), 19 deletions(-)
 create mode 100644 arch/x86/cpu/x86_64/setjmp.S
 delete mode 100644 arch/x86/cpu/x86_64/setjmp.c

diff --git a/arch/x86/cpu/x86_64/setjmp.S b/arch/x86/cpu/x86_64/setjmp.S
new file mode 100644
index 000..ef61a4a
--- /dev/null
+++ b/arch/x86/cpu/x86_64/setjmp.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 Intel Corporation
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * See arch/x86/include/asm/setjmp.h for jmp_buf format
+ */
+
+#include 
+
+.text
+.align 8
+
+ENTRY(setjmp)
+
+   pop %rcx
+   movq%rcx, (%rdi)/* Return address */
+   movq%rsp, 8 (%rdi)
+   movq%rbp, 16 (%rdi)
+   movq%rbx, 24 (%rdi)
+   movq%r12, 32 (%rdi)
+   movq%r13, 40 (%rdi)
+   movq%r14, 48 (%rdi)
+   movq%r15, 56 (%rdi)
+   fnstcw  64 (%rdi)
+   stmxcsr 68 (%rdi)
+   xorq%rax, %rax  /* Direct invocation returns 0 */
+   jmpq*%rcx
+
+ENDPROC(setjmp)
+
+.align 8
+
+ENTRY(longjmp)
+
+   subq$8, %rsp
+
+/* Restore the control bits of MXCSR */
+
+   stmxcsr (%rsp)
+   movl$0x3f, %eax
+   andl%eax, (%rsp)
+   notl%eax
+   andl68 (%rdi), %eax
+   orl %eax, (%rsp)
+   ldmxcsr (%rsp)
+
+   fldcw   64 (%rdi)
+
+   movq(%rdi), %rcx/* Return address */
+   movq8 (%rdi), %rsp
+   movq16 (%rdi), %rbp
+   movq24 (%rdi), %rbx
+   movq32 (%rdi), %r12
+   movq40 (%rdi), %r13
+   movq48 (%rdi), %r14
+   movq56 (%rdi), %r15
+
+   movq%rsi, %rax  /* Value to be returned by setjmp() */
+   testq   %rax, %rax  /* cannot be 0 in this case */
+   jnz 1f
+   incq%rax/* Return 1 instead */
+1:
+   jmpq*%rcx
+
+ENDPROC(longjmp)
diff --git a/arch/x86/cpu/x86_64/setjmp.c b/arch/x86/cpu/x86_64/setjmp.c
deleted file mode 100644
index 5d4a74a..000
--- a/arch/x86/cpu/x86_64/setjmp.c
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2016 Google, Inc
- */
-
-#include 
-#include 
-
-int setjmp(struct jmp_buf_data *jmp_buf)
-{
-   printf("WARNING: setjmp() is not supported\n");
-
-   return 0;
-}
-
-void longjmp(struct jmp_buf_data *jmp_buf, int val)
-{
-   printf("WARNING: longjmp() is not supported\n");
-}
diff --git a/arch/x86/include/asm/setjmp.h b/arch/x86/include/asm/setjmp.h
index f25975f..eae33fb 100644
--- a/arch/x86/include/asm/setjmp.h
+++ b/arch/x86/include/asm/setjmp.h
@@ -8,6 +8,23 @@
 #ifndef __setjmp_h
 #define __setjmp_h
 
+#ifdef CONFIG_X86_64
+
+struct jmp_buf_data {
+   unsigned long __rip;
+   unsigned long __rsp;
+   unsigned long __rbp;
+   unsigned long __rbx;
+   unsigned long __r12;
+   unsigned long __r13;
+   unsigned long __r14;
+   unsigned long __r15;
+   unsigned int __fcw;
+   unsigned int __mxcsr;
+};
+
+#else
+
 struct jmp_buf_data {
unsigned int __ebx;
unsigned int __esp;
@@ -17,6 +34,8 @@ struct jmp_buf_data {
unsigned int __eip;
 };
 
+#endif
+
 int setjmp(struct jmp_buf_data *jmp_buf);
 void longjmp(struct jmp_buf_data *jmp_buf, int val);
 
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation

2018-06-06 Thread Ivan Gorinov
Add setjmp/longjmp functions for x86_64.
The FPU control word and MXCSR control bits are preserved across calls.

v2:
  Added the FPU control word and MXCSR to jmp_buf;
  Using ENTRY/ENDPROC macros.

Ivan Gorinov (1):
  x86: Add 64-bit setjmp/longjmp implementation

 arch/x86/cpu/x86_64/setjmp.S  | 66 +++
 arch/x86/cpu/x86_64/setjmp.c  | 19 -
 arch/x86/include/asm/setjmp.h | 19 +
 3 files changed, 85 insertions(+), 19 deletions(-)
 create mode 100644 arch/x86/cpu/x86_64/setjmp.S
 delete mode 100644 arch/x86/cpu/x86_64/setjmp.c

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH] x86: Add 64-bit setjmp/longjmp implementation

2018-06-05 Thread Ivan Gorinov
On Sun, Jun 03, 2018 at 02:06:47PM +0200, Alexander Graf wrote:
> On 02.06.18 20:44, Heinrich Schuchardt wrote:
> > On 05/31/2018 12:50 AM, Ivan Gorinov wrote:
> >> Add setjmp/longjmp functions for x86_64,
> >> based on existing 32-bit implementation.
> > 
> > Thank you for your patch. This addresses a gap that really should be closed.
> > 
> > Please, add a line to the commit message indicating the calling
> > conventions that are supported. This is important because we use
> > different calling conventions in different places.
> > 
> > One function where we need setjmp() is efi_start_image(). The function
> > is defined as EFIAPI. So we need an implementation supporting the ms_abi
> > calling convention.
> 
> I don't quite follow. The calling convention is declared in the C header
> (omitted means sysv, EFIAPI means ms). The compiler will adapt the call
> to the respective convention automatically. So if you call a sysv
> function from an EFIAPI function, gcc will push all registers that are
> potentially getting clobbered on the stack.

I can confirm that gcc does save %rsi and %rdi in EFIAPI functions before
using those two registers for setjmp() parameters. The other callee-saved
registers in ms_abi are also callee-saved in sysv and correctly handled by
the proposed implementation.

static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
   unsigned long *exit_data_size,
   s16 **exit_data)
{
5f03ce56:   57  push   %rdi
5f03ce57:   56  push   %rsi

...

/* call the image! */
if (setjmp(>exit_jmp)) {
5f03cecd:   48 8b 84 24 f0 00 00mov0xf0(%rsp),%rax
5f03ced4:   00 
5f03ced5:   48 8d 78 78 lea0x78(%rax),%rdi
5f03ced9:   e8 82 32 fc ff  callq  5f000160 
5f03cede:   85 c0   test   %eax,%eax
5f03cee0:   74 1b   je 5f03cefd 

...

> So IIUC we really only need the sysv variant - which this patch
> implements, right? This also shouldn't need any mentioning, as it's the
> default throughout the code base, unless the function is annotated with
> the EFIAPI tag.

> > Another function where we use setjmp() is do_bootefi_exec() but this
> > function is defined as sysv_abi.
> > 
> > I guess the patch relates to the sysv_abi calling convention:
> > 
> > "System V Application Binary Interface: AMD64 Architecture Processor
> > Supplement (With LP64 and ILP32 Programming Models)"
> > https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
> > 
> > This document contains the following sentence:
> > 
> > The control bits of the MXCSR register are callee-saved  (preserved
> > across calls), while the status bits are caller-saved (not preserved).
> > I cannot see that this is reflected in the patch.

Thank you for the link! I will add MXCSR to the callee-saved register set.

> > See also https://msdn.microsoft.com/en-us/library/36d3b75w.aspx
> > 
> > Your setjmp implemantion is not usable for the ms_abi that we need in
> > for efi_start_image(). Here you would have to save registers RBX, RBP,
> > RDI, RSI, RSP, R12, R13, R14, and R15.
> > 
> > As reference have a look at this implementation:
> > https://github.com/freebsd/freebsd/blob/master/lib/libc/amd64/gen/setjmp.S
> > 
> >>
> >> Signed-off-by: Ivan Gorinov 
> > 
> > 
> > 
> >> ---
> >>  arch/x86/cpu/x86_64/setjmp.S  | 56 
> >> +++
> >>  arch/x86/cpu/x86_64/setjmp.c  | 19 ---
> >>  arch/x86/include/asm/setjmp.h | 17 +
> >>  3 files changed, 73 insertions(+), 19 deletions(-)
> >>  create mode 100644 arch/x86/cpu/x86_64/setjmp.S
> >>  delete mode 100644 arch/x86/cpu/x86_64/setjmp.c
> >>
> >> diff --git a/arch/x86/cpu/x86_64/setjmp.S b/arch/x86/cpu/x86_64/setjmp.S
> >> new file mode 100644
> >> index 000..e10ee49
> >> --- /dev/null
> >> +++ b/arch/x86/cpu/x86_64/setjmp.S
> >> @@ -0,0 +1,56 @@
> >> +/*
> >> + * Based on arch/x86/cpu/i386/setjmp.S by H. Peter Anvin 
> >> + *
> >> + * SPDX-License-Identifier:   GPL-2.0
> >> + */
> >> +
> >> +/*
> >> + * The jmp_buf is assumed to contain the following, in order:
> >> + *
> >> + *%rsp
> >> + *%rbp
> >> + *%rbx
> >> + *%r12
> >> + *%r13
> >> + *%r14
>

Re: [U-Boot] [PATCH v2] x86: use EFI calling convention for efi_main on x86_64

2018-05-31 Thread Ivan Gorinov
On Thu, May 31, 2018 at 11:26:50AM +0300, Andy Shevchenko wrote:
> > Save efi_main() arguments in the startup code on x86_64;
> > use EFI calling convention for _relocate() on x86_64;
> > remove unused _relocate() arguments;
> > consistently use EFI calling convention for efi_main() everywhere.
> 
> I think it rather requires more explanation here what EFI calling
> convetion is and how it differs in _relloc() with changes you did.
> (Btw, the mail has no changelog provided)

Added in v3.

> > diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c
> > index c828093..3eb8eeb 100644
> > --- a/lib/efi/efi_app.c
> > +++ b/lib/efi/efi_app.c
> > @@ -96,7 +96,8 @@ static void free_memory(struct efi_priv *priv)
> >   * U-Boot. If it returns, EFI will continue. Another way to get back to EFI
> >   * is via reset_cpu().
> >   */
> > -efi_status_t efi_main(efi_handle_t image, struct efi_system_table 
> > *sys_table)
> > +efi_status_t EFIAPI efi_main(efi_handle_t image,
> > +struct efi_system_table *sys_table)
> 
> Perhaps still leave at one line?

That one line would exceed the limit of 80 columns on a punch card.

> 
> >  {
> > struct efi_priv local_priv, *priv = _priv;
> > efi_status_t ret;
> > diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
> > index 3138739..399d16b 100644
> > --- a/lib/efi/efi_stub.c
> > +++ b/lib/efi/efi_stub.c
> > @@ -268,7 +268,8 @@ static void add_entry_addr(struct efi_priv *priv, enum 
> > efi_entry_t type,
> >   * This function is called by our EFI start-up code. It handles running
> >   * U-Boot. If it returns, EFI will continue.
> >   */
> > -efi_status_t efi_main(efi_handle_t image, struct efi_system_table 
> > *sys_table)
> > +efi_status_t EFIAPI efi_main(efi_handle_t image,
> > +struct efi_system_table *sys_table)
> 
> Ditto.
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3] x86: use EFI calling convention for efi_main on x86_64

2018-05-31 Thread Ivan Gorinov
UEFI specifies the calling convention used in Microsoft compilers;
first arguments of a function are passed in (%rcx, %rdx, %r8, %r9).

All other compilers use System V ABI by default, passing first integer
arguments of a function in (%rdi, %rsi, %rdx, %rcx, %r8, %r9).

These ABI also specify different sets of registers that must be preserved
across function calls (callee-saved).

GCC allows using the Microsoft calling convention by adding the ms_abi
attribute to a function declaration.

Current EFI implementation in U-Boot specifies EFIAPI for efi_main()
in the test apps but uses default calling convention in lib/efi.
The arguments of efi_main() are also passed as unused arguments to the
_relocate() function.

Save efi_main() arguments in the startup code on x86_64;
use EFI calling convention for _relocate() on x86_64;
remove unused _relocate() arguments;
consistently use EFI calling convention for efi_main() everywhere.

Signed-off-by: Ivan Gorinov 
---
 arch/x86/lib/crt0_x86_64_efi.S  | 21 ++---
 arch/x86/lib/reloc_x86_64_efi.c |  3 +--
 lib/efi/efi_app.c   |  3 ++-
 lib/efi/efi_stub.c  |  3 ++-
 4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/x86/lib/crt0_x86_64_efi.S b/arch/x86/lib/crt0_x86_64_efi.S
index 989799f..3abb5e3 100644
--- a/arch/x86/lib/crt0_x86_64_efi.S
+++ b/arch/x86/lib/crt0_x86_64_efi.S
@@ -3,7 +3,7 @@
  * crt0-efi-x86_64.S - x86_64 EFI startup code.
  * Copyright (C) 1999 Hewlett-Packard Co.
  * Contributed by David Mosberger .
- * Copyright (C) 2005 Intel Co.
+ * Copyright (C) 2005 Intel Corporation
  * Contributed by Fenghua Yu .
  *
  * All rights reserved.
@@ -14,26 +14,25 @@
.globl _start
 _start:
subq $8, %rsp
+
pushq %rcx
pushq %rdx
 
-0:
-   lea image_base(%rip), %rdi
-   lea _DYNAMIC(%rip), %rsi
+   lea image_base(%rip), %rcx
+   lea _DYNAMIC(%rip), %rdx
 
-   popq %rcx
-   popq %rdx
-   pushq %rcx
-   pushq %rdx
call _relocate
 
-   popq %rdi
-   popq %rsi
+   popq %rdx
+   popq %rcx
+
+   testq %rax, %rax
+   jnz _exit
 
call efi_main
+_exit:
addq $8, %rsp
 
-.exit:
ret
 
/*
diff --git a/arch/x86/lib/reloc_x86_64_efi.c b/arch/x86/lib/reloc_x86_64_efi.c
index 34c5b2e..59d6f8d 100644
--- a/arch/x86/lib/reloc_x86_64_efi.c
+++ b/arch/x86/lib/reloc_x86_64_efi.c
@@ -14,8 +14,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t EFIAPI _relocate(long ldbase, Elf64_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf64_Rel *rel = 0;
diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c
index c828093..3eb8eeb 100644
--- a/lib/efi/efi_app.c
+++ b/lib/efi/efi_app.c
@@ -96,7 +96,8 @@ static void free_memory(struct efi_priv *priv)
  * U-Boot. If it returns, EFI will continue. Another way to get back to EFI
  * is via reset_cpu().
  */
-efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+efi_status_t EFIAPI efi_main(efi_handle_t image,
+struct efi_system_table *sys_table)
 {
struct efi_priv local_priv, *priv = _priv;
efi_status_t ret;
diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
index 3138739..399d16b 100644
--- a/lib/efi/efi_stub.c
+++ b/lib/efi/efi_stub.c
@@ -268,7 +268,8 @@ static void add_entry_addr(struct efi_priv *priv, enum 
efi_entry_t type,
  * This function is called by our EFI start-up code. It handles running
  * U-Boot. If it returns, EFI will continue.
  */
-efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+efi_status_t EFIAPI efi_main(efi_handle_t image,
+struct efi_system_table *sys_table)
 {
struct efi_priv local_priv, *priv = _priv;
struct efi_boot_services *boot = sys_table->boottime;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3] x86: use EFI calling convention for efi_main on x86_64

2018-05-31 Thread Ivan Gorinov
UEFI specifies the calling convention used in Microsoft compilers;
first arguments of a function are passed in (%rcx, %rdx, %r8, %r9).

All other compilers use System V ABI by default, passing first integer
arguments of a function in (%rdi, %rsi, %rdx, %rcx, %r8, %r9).

These ABI also specify different sets of registers that must be preserved
across function calls (callee-saved).

GCC allows using the Microsoft calling convention by adding the ms_abi
attribute to a function declaration.

Current EFI implementation in U-Boot specifies EFIAPI for efi_main()
in the test apps but uses default calling convention in lib/efi.
The arguments of efi_main() are also passed as unused arguments to the
_relocate() function.

Save efi_main() arguments in the startup code on x86_64;
use EFI calling convention for _relocate() on x86_64;
remove unused _relocate() arguments;
consistently use EFI calling convention for efi_main() everywhere.

v3:
  Updated patch description.

v2:
  Added EFIABI to _relocate() declaration.


Ivan Gorinov (1):
  x86: use EFI calling convention for efi_main on x86_64

 arch/x86/lib/crt0_x86_64_efi.S  | 21 ++---
 arch/x86/lib/reloc_x86_64_efi.c |  3 +--
 lib/efi/efi_app.c   |  3 ++-
 lib/efi/efi_stub.c  |  3 ++-
 4 files changed, 15 insertions(+), 15 deletions(-)

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] x86: Add 64-bit setjmp/longjmp implementation

2018-05-30 Thread Ivan Gorinov
Add setjmp/longjmp functions for x86_64,
based on existing 32-bit implementation.

Signed-off-by: Ivan Gorinov 
---
 arch/x86/cpu/x86_64/setjmp.S  | 56 +++
 arch/x86/cpu/x86_64/setjmp.c  | 19 ---
 arch/x86/include/asm/setjmp.h | 17 +
 3 files changed, 73 insertions(+), 19 deletions(-)
 create mode 100644 arch/x86/cpu/x86_64/setjmp.S
 delete mode 100644 arch/x86/cpu/x86_64/setjmp.c

diff --git a/arch/x86/cpu/x86_64/setjmp.S b/arch/x86/cpu/x86_64/setjmp.S
new file mode 100644
index 000..e10ee49
--- /dev/null
+++ b/arch/x86/cpu/x86_64/setjmp.S
@@ -0,0 +1,56 @@
+/*
+ * Based on arch/x86/cpu/i386/setjmp.S by H. Peter Anvin 
+ *
+ * SPDX-License-Identifier:GPL-2.0
+ */
+
+/*
+ * The jmp_buf is assumed to contain the following, in order:
+ * 
+ * %rsp
+ * %rbp
+ * %rbx
+ * %r12
+ * %r13
+ * %r14
+ * %r15
+ */
+
+.text
+.align 8
+.globl setjmp
+.type setjmp, @function
+
+setjmp:
+   pop %rcx
+   movq%rcx, (%rdi)/* Return address */
+   movq%rsp, 8 (%rdi)  /* Post-return %rsp! */
+   movq%rbp, 16 (%rdi)
+   movq%rbx, 24 (%rdi)
+   movq%r12, 32 (%rdi)
+   movq%r13, 40 (%rdi)
+   movq%r14, 48 (%rdi)
+   movq%r15, 56 (%rdi)
+   xorq%rax, %rax  /* Return value */
+   jmpq*%rcx
+
+/* Provide function size if needed */
+.size setjmp, .-setjmp
+
+.align 8
+.globl longjmp
+.type longjmp, @function
+
+longjmp:
+   movq32 (%rdi), %r12
+   movq40 (%rdi), %r13
+   movq48 (%rdi), %r14
+   movq56 (%rdi), %r15
+   movq16 (%rdi), %rbp
+   movq24 (%rdi), %rbx
+   movq8 (%rdi), %rsp
+   movq(%rdi), %rcx
+   movq%rsi, %rdi
+   jmpq*%rcx
+
+   .size longjmp, .-longjmp
diff --git a/arch/x86/cpu/x86_64/setjmp.c b/arch/x86/cpu/x86_64/setjmp.c
deleted file mode 100644
index 5d4a74a..000
--- a/arch/x86/cpu/x86_64/setjmp.c
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2016 Google, Inc
- */
-
-#include 
-#include 
-
-int setjmp(struct jmp_buf_data *jmp_buf)
-{
-   printf("WARNING: setjmp() is not supported\n");
-
-   return 0;
-}
-
-void longjmp(struct jmp_buf_data *jmp_buf, int val)
-{
-   printf("WARNING: longjmp() is not supported\n");
-}
diff --git a/arch/x86/include/asm/setjmp.h b/arch/x86/include/asm/setjmp.h
index f25975f..49c36c1 100644
--- a/arch/x86/include/asm/setjmp.h
+++ b/arch/x86/include/asm/setjmp.h
@@ -8,6 +8,21 @@
 #ifndef __setjmp_h
 #define __setjmp_h
 
+#ifdef CONFIG_X86_64
+
+struct jmp_buf_data {
+   unsigned long __rip;
+   unsigned long __rsp;
+   unsigned long __rbp;
+   unsigned long __rbx;
+   unsigned long __r12;
+   unsigned long __r13;
+   unsigned long __r14;
+   unsigned long __r15;
+};
+
+#else
+
 struct jmp_buf_data {
unsigned int __ebx;
unsigned int __esp;
@@ -17,6 +32,8 @@ struct jmp_buf_data {
unsigned int __eip;
 };
 
+#endif
+
 int setjmp(struct jmp_buf_data *jmp_buf);
 void longjmp(struct jmp_buf_data *jmp_buf, int val);
 
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2] x86: use EFI calling convention for efi_main on x86_64

2018-05-30 Thread Ivan Gorinov
Save efi_main() arguments in the startup code on x86_64;
use EFI calling convention for _relocate() on x86_64;
remove unused _relocate() arguments;
consistently use EFI calling convention for efi_main() everywhere.

Signed-off-by: Ivan Gorinov 
---
 arch/x86/lib/crt0_x86_64_efi.S  | 21 ++---
 arch/x86/lib/reloc_x86_64_efi.c |  3 +--
 lib/efi/efi_app.c   |  3 ++-
 lib/efi/efi_stub.c  |  3 ++-
 4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/x86/lib/crt0_x86_64_efi.S b/arch/x86/lib/crt0_x86_64_efi.S
index 989799f..3abb5e3 100644
--- a/arch/x86/lib/crt0_x86_64_efi.S
+++ b/arch/x86/lib/crt0_x86_64_efi.S
@@ -3,7 +3,7 @@
  * crt0-efi-x86_64.S - x86_64 EFI startup code.
  * Copyright (C) 1999 Hewlett-Packard Co.
  * Contributed by David Mosberger .
- * Copyright (C) 2005 Intel Co.
+ * Copyright (C) 2005 Intel Corporation
  * Contributed by Fenghua Yu .
  *
  * All rights reserved.
@@ -14,26 +14,25 @@
.globl _start
 _start:
subq $8, %rsp
+
pushq %rcx
pushq %rdx
 
-0:
-   lea image_base(%rip), %rdi
-   lea _DYNAMIC(%rip), %rsi
+   lea image_base(%rip), %rcx
+   lea _DYNAMIC(%rip), %rdx
 
-   popq %rcx
-   popq %rdx
-   pushq %rcx
-   pushq %rdx
call _relocate
 
-   popq %rdi
-   popq %rsi
+   popq %rdx
+   popq %rcx
+
+   testq %rax, %rax
+   jnz _exit
 
call efi_main
+_exit:
addq $8, %rsp
 
-.exit:
ret
 
/*
diff --git a/arch/x86/lib/reloc_x86_64_efi.c b/arch/x86/lib/reloc_x86_64_efi.c
index 34c5b2e..59d6f8d 100644
--- a/arch/x86/lib/reloc_x86_64_efi.c
+++ b/arch/x86/lib/reloc_x86_64_efi.c
@@ -14,8 +14,7 @@
 #include 
 #include 
 
-efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
-  struct efi_system_table *systab)
+efi_status_t EFIAPI _relocate(long ldbase, Elf64_Dyn *dyn)
 {
long relsz = 0, relent = 0;
Elf64_Rel *rel = 0;
diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c
index c828093..3eb8eeb 100644
--- a/lib/efi/efi_app.c
+++ b/lib/efi/efi_app.c
@@ -96,7 +96,8 @@ static void free_memory(struct efi_priv *priv)
  * U-Boot. If it returns, EFI will continue. Another way to get back to EFI
  * is via reset_cpu().
  */
-efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+efi_status_t EFIAPI efi_main(efi_handle_t image,
+struct efi_system_table *sys_table)
 {
struct efi_priv local_priv, *priv = _priv;
efi_status_t ret;
diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
index 3138739..399d16b 100644
--- a/lib/efi/efi_stub.c
+++ b/lib/efi/efi_stub.c
@@ -268,7 +268,8 @@ static void add_entry_addr(struct efi_priv *priv, enum 
efi_entry_t type,
  * This function is called by our EFI start-up code. It handles running
  * U-Boot. If it returns, EFI will continue.
  */
-efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+efi_status_t EFIAPI efi_main(efi_handle_t image,
+struct efi_system_table *sys_table)
 {
struct efi_priv local_priv, *priv = _priv;
struct efi_boot_services *boot = sys_table->boottime;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH] x86: enable cpu-specific functions for x86_64 target

2018-05-30 Thread Ivan Gorinov
On Sat, May 26, 2018 at 06:53:40PM -0600, Simon Glass wrote:
> Hi Ivan,
> 
> On 25 May 2018 at 16:00, Ivan Gorinov  wrote:
> > Add __weak prefix to the following functions to allow override:
> > misc_init_r(), checkcpu(), print_cpuinfo().
> >
> > Signed-off-by: Ivan Gorinov 
> > ---
> >  arch/x86/cpu/x86_64/cpu.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/x86/cpu/x86_64/cpu.c b/arch/x86/cpu/x86_64/cpu.c
> > index 18b3e94..6f14efc 100644
> > --- a/arch/x86/cpu/x86_64/cpu.c
> > +++ b/arch/x86/cpu/x86_64/cpu.c
> > @@ -59,17 +59,17 @@ int x86_mp_init(void)
> > return 0;
> >  }
> >
> > -int misc_init_r(void)
> > +__weak int misc_init_r(void)
> >  {
> > return 0;
> >  }
> >
> > -int checkcpu(void)
> > +__weak int checkcpu(void)
> >  {
> > return 0;
> >  }
> >
> > -int print_cpuinfo(void)
> > +__weak int print_cpuinfo(void)
> >  {
> > return 0;
> >  }
> > --
> > 2.7.4
> >
> 
> We should do with with a different CPU driver I think. What exactly is
> the problem?

When I change a Minnowboard configuration (baytrail) to run in 64-bit mode,
there are two conflicting definitions of misc_init_r():

  arch/x86/cpu/x86_64/cpu.c
  board/intel/minnowmax/minnowmax.c

On other CPU models, functions checkcpu() and print_cpuinfo() conflict with
model-specific definitions for Tangier, Ivy Bridge, Broadwell, Quark.
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] x86: enable cpu-specific functions for x86_64 target

2018-05-25 Thread Ivan Gorinov
Add __weak prefix to the following functions to allow override:
misc_init_r(), checkcpu(), print_cpuinfo().

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/x86/cpu/x86_64/cpu.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/cpu/x86_64/cpu.c b/arch/x86/cpu/x86_64/cpu.c
index 18b3e94..6f14efc 100644
--- a/arch/x86/cpu/x86_64/cpu.c
+++ b/arch/x86/cpu/x86_64/cpu.c
@@ -59,17 +59,17 @@ int x86_mp_init(void)
return 0;
 }
 
-int misc_init_r(void)
+__weak int misc_init_r(void)
 {
return 0;
 }
 
-int checkcpu(void)
+__weak int checkcpu(void)
 {
return 0;
 }
 
-int print_cpuinfo(void)
+__weak int print_cpuinfo(void)
 {
return 0;
 }
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] x86: use EFI calling convention for efi_main on x86_64

2018-05-25 Thread Ivan Gorinov
Save the arguments passed in %rcx and %rdx for efi_main() on x86_64;
consistently use EFI calling convention for efi_main().

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/x86/lib/crt0_x86_64_efi.S | 8 
 lib/efi/efi_app.c  | 3 ++-
 lib/efi/efi_stub.c | 3 ++-
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/x86/lib/crt0_x86_64_efi.S b/arch/x86/lib/crt0_x86_64_efi.S
index 989799f..2d53d1b 100644
--- a/arch/x86/lib/crt0_x86_64_efi.S
+++ b/arch/x86/lib/crt0_x86_64_efi.S
@@ -16,19 +16,19 @@ _start:
subq $8, %rsp
pushq %rcx
pushq %rdx
+   pushq %rsi
+   pushq %rdi
 
 0:
lea image_base(%rip), %rdi
lea _DYNAMIC(%rip), %rsi
 
-   popq %rcx
-   popq %rdx
-   pushq %rcx
-   pushq %rdx
call _relocate
 
popq %rdi
popq %rsi
+   popq %rdx
+   popq %rcx
 
call efi_main
addq $8, %rsp
diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c
index c828093..3eb8eeb 100644
--- a/lib/efi/efi_app.c
+++ b/lib/efi/efi_app.c
@@ -96,7 +96,8 @@ static void free_memory(struct efi_priv *priv)
  * U-Boot. If it returns, EFI will continue. Another way to get back to EFI
  * is via reset_cpu().
  */
-efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+efi_status_t EFIAPI efi_main(efi_handle_t image,
+struct efi_system_table *sys_table)
 {
struct efi_priv local_priv, *priv = _priv;
efi_status_t ret;
diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
index 3138739..399d16b 100644
--- a/lib/efi/efi_stub.c
+++ b/lib/efi/efi_stub.c
@@ -268,7 +268,8 @@ static void add_entry_addr(struct efi_priv *priv, enum 
efi_entry_t type,
  * This function is called by our EFI start-up code. It handles running
  * U-Boot. If it returns, EFI will continue.
  */
-efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+efi_status_t EFIAPI efi_main(efi_handle_t image,
+struct efi_system_table *sys_table)
 {
struct efi_priv local_priv, *priv = _priv;
struct efi_boot_services *boot = sys_table->boottime;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2] efi_selftest: check for buffer overflow in efi_get_variable

2018-05-25 Thread Ivan Gorinov
Allocate a buffer on the stack instead of an array of uninitialized
pointers; check if GetVariable writes past the end of the buffer.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 lib/efi_selftest/efi_selftest_variables.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/lib/efi_selftest/efi_selftest_variables.c 
b/lib/efi_selftest/efi_selftest_variables.c
index f5e8eb6..146378f 100644
--- a/lib/efi_selftest/efi_selftest_variables.c
+++ b/lib/efi_selftest/efi_selftest_variables.c
@@ -49,7 +49,7 @@ static int execute(void)
u32 attr;
u8 v[16] = {0x5d, 0xd1, 0x5e, 0x51, 0x5a, 0x05, 0xc7, 0x0c,
0x35, 0x4a, 0xae, 0x87, 0xa5, 0xdf, 0x0f, 0x65,};
-   u8 *data[EFI_ST_MAX_DATA_SIZE];
+   u8 data[EFI_ST_MAX_DATA_SIZE];
u16 varname[EFI_ST_MAX_VARNAME_SIZE];
int flag;
efi_guid_t guid;
@@ -72,6 +72,22 @@ static int execute(void)
efi_st_error("SetVariable failed\n");
return EFI_ST_FAILURE;
}
+   data[3] = 0xff;
+   len = 3;
+   ret = runtime->get_variable(L"efi_st_var0", _vendor0,
+   , , data);
+   if (ret != EFI_SUCCESS) {
+   efi_st_error("GetVariable failed\n");
+   return EFI_ST_FAILURE;
+   }
+   if (efi_st_memcmp(data, v + 4, 3)) {
+   efi_st_error("GetVariable returned wrong value\n");
+   return EFI_ST_FAILURE;
+   }
+   if (data[3] != 0xff) {
+   efi_st_error("GetVariable wrote past the end of the buffer\n");
+   return EFI_ST_FAILURE;
+   }
/* Set variable 1 */
ret = runtime->set_variable(L"efi_st_var1", _vendor1,
EFI_VARIABLE_BOOTSERVICE_ACCESS,
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] efi_selftest: check for buffer overflow in efi_get_variable

2018-05-24 Thread Ivan Gorinov
Check if GetVariable writes past the end of the output data buffer.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 lib/efi_selftest/efi_selftest_variables.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/lib/efi_selftest/efi_selftest_variables.c 
b/lib/efi_selftest/efi_selftest_variables.c
index f5e8eb6..8a02dbc 100644
--- a/lib/efi_selftest/efi_selftest_variables.c
+++ b/lib/efi_selftest/efi_selftest_variables.c
@@ -72,6 +72,22 @@ static int execute(void)
efi_st_error("SetVariable failed\n");
return EFI_ST_FAILURE;
}
+   data[3] = 0xff;
+   len = 3;
+   ret = runtime->get_variable(L"efi_st_var0", _vendor0,
+   , , data);
+   if (ret != EFI_SUCCESS) {
+   efi_st_error("GetVariable failed\n");
+   return EFI_ST_FAILURE;
+   }
+   if (efi_st_memcmp(data, v + 4, 3)) {
+   efi_st_error("GetVariable returned wrong value\n");
+   return EFI_ST_FAILURE;
+   }
+   if (data[3] != 0xff) {
+   efi_st_error("GetVariable wrote past the end of the buffer\n");
+   return EFI_ST_FAILURE;
+   }
/* Set variable 1 */
ret = runtime->set_variable(L"efi_st_var1", _vendor1,
EFI_VARIABLE_BOOTSERVICE_ACCESS,
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v4] efi_loader: fix off-by-one bug in efi_get_variable

2018-05-11 Thread Ivan Gorinov
efi_get_variable() always stores an extra zero byte after the output data.
When the returned data size matches the output buffer size, the extra zero
byte is stored past the end of the output buffer.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 lib/efi_loader/efi_variable.c | 40 
 1 file changed, 16 insertions(+), 24 deletions(-)

diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index 6c177da..9e7d3e6 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -50,7 +50,7 @@
(strlen("efi_---_") + \
(MAX_VAR_NAME * MAX_UTF8_PER_UTF16))
 
-static int hex(unsigned char ch)
+static int hex(int ch)
 {
if (ch >= 'a' && ch <= 'f')
return ch-'a'+10;
@@ -61,44 +61,32 @@ static int hex(unsigned char ch)
return -1;
 }
 
-static const char *hex2mem(u8 *mem, const char *hexstr, int count)
+static int hex2mem(u8 *mem, const char *hexstr, int size)
 {
-   memset(mem, 0, count/2);
+   int nibble;
+   int i;
 
-   do {
-   int nibble;
-
-   *mem = 0;
-
-   if (!count || !*hexstr)
+   for (i = 0; i < size; i++) {
+   if (*hexstr == '\0')
break;
 
nibble = hex(*hexstr);
if (nibble < 0)
-   break;
+   return -1;
 
*mem = nibble;
-   count--;
hexstr++;
 
-   if (!count || !*hexstr)
-   break;
-
nibble = hex(*hexstr);
if (nibble < 0)
-   break;
+   return -1;
 
*mem = (*mem << 4) | nibble;
-   count--;
hexstr++;
mem++;
+   }
 
-   } while (1);
-
-   if (*hexstr)
-   return hexstr;
-
-   return NULL;
+   return i;
 }
 
 static char *mem2hex(char *hexstr, const u8 *mem, int count)
@@ -210,8 +198,12 @@ efi_status_t EFIAPI efi_get_variable(s16 *variable_name,
if ((s = prefix(val, "(blob)"))) {
unsigned len = strlen(s);
 
+   /* number of hexadecimal digits must be even */
+   if (len & 1)
+   return EFI_EXIT(EFI_DEVICE_ERROR);
+
/* two characters per byte: */
-   len = DIV_ROUND_UP(len, 2);
+   len /= 2;
*data_size = len;
 
if (in_size < len)
@@ -220,7 +212,7 @@ efi_status_t EFIAPI efi_get_variable(s16 *variable_name,
if (!data)
return EFI_EXIT(EFI_INVALID_PARAMETER);
 
-   if (hex2mem(data, s, len * 2))
+   if (hex2mem(data, s, len) != len)
return EFI_EXIT(EFI_DEVICE_ERROR);
 
debug("%s: got value: \"%s\"\n", __func__, s);
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v3] efi_loader: fix off-by-one bug in efi_get_variable

2018-05-11 Thread Ivan Gorinov
On Fri, May 11, 2018 at 08:18:27PM +0200, Heinrich Schuchardt wrote:
> On 05/11/2018 07:54 PM, Ivan Gorinov wrote:
> > efi_get_variable() always stores an extra zero byte after the output data.
> > When the returned data size matches the output buffer size, the extra zero
> > byte is stored past the end of the output buffer.
> > 
> > Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
> > ---
> >  lib/efi_loader/efi_variable.c | 40 +---
> >  1 file changed, 17 insertions(+), 23 deletions(-)
> > 
> > diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
> > index 6c177da..28b2f5c 100644
> > --- a/lib/efi_loader/efi_variable.c
> > +++ b/lib/efi_loader/efi_variable.c
> > @@ -50,7 +50,7 @@
> > (strlen("efi_---_") + \
> > (MAX_VAR_NAME * MAX_UTF8_PER_UTF16))
> >  
> > -static int hex(unsigned char ch)
> > +static int hex(int ch)
> >  {
> > if (ch >= 'a' && ch <= 'f')
> > return ch-'a'+10;
> > @@ -61,44 +61,34 @@ static int hex(unsigned char ch)
> > return -1;
> >  }
> >  
> > -static const char *hex2mem(u8 *mem, const char *hexstr, int count)
> > +static int hex2mem(u8 *mem, const char *hexstr, int size)
> >  {
> > -   memset(mem, 0, count/2);
> > +   int nibble;
> > +   int i;
> >  
> > -   do {
> > -   int nibble;
> > +   memset(mem, 0, size);
> 
> Why should we call memset?
> 
> The memory is supplied by the caller of efi_get_variable().
> Either we copy size bytes to mem or we return EFI_DEVICE_ERROR.

OK.

> >  
> > -   *mem = 0;
> > -
> > -   if (!count || !*hexstr)
> > +   for (i = 0; i < size; i++) {
> > +   if (*hexstr == '\0')
> > break;
> >  
> > nibble = hex(*hexstr);
> > if (nibble < 0)
> > -   break;
> > +   return -1;
> >  
> > *mem = nibble;
> > -   count--;
> > hexstr++;
> >  
> > -   if (!count || !*hexstr)
> > -   break;
> > -
> > nibble = hex(*hexstr);
> > if (nibble < 0)
> > -   break;
> > +   return -1;
> >  
> > *mem = (*mem << 4) | nibble;
> > -   count--;
> > hexstr++;
> > mem++;
> > +   }
> >  
> > -   } while (1);
> > -
> > -   if (*hexstr)
> > -   return hexstr;
> > -
> > -   return NULL;
> > +   return i;
> >  }
> >  
> >  static char *mem2hex(char *hexstr, const u8 *mem, int count)
> > @@ -210,8 +200,12 @@ efi_status_t EFIAPI efi_get_variable(s16 
> > *variable_name,
> > if ((s = prefix(val, "(blob)"))) {
> > unsigned len = strlen(s);
> >  
> > +   /* number of hexadecimal digits must be even */
> > +   if (len & 1)
> > +   return EFI_EXIT(EFI_DEVICE_ERROR);
> > +
> > /* two characters per byte: */
> > -   len = DIV_ROUND_UP(len, 2);
> > +   len /= 2;
> 
> You do not catch the case that len & 1 == 1 which should cause
> EFI_DEVICE_ERROR because the data in the blob is not valid.

This is exactly what new code in efi_get_variable() does:

if (len & 1)
return EFI_EXIT(EFI_DEVICE_ERROR);

> 
> Best regards
> 
> Heinrich
> 
> > *data_size = len;
> >  
> > if (in_size < len)
> > @@ -220,7 +214,7 @@ efi_status_t EFIAPI efi_get_variable(s16 *variable_name,
> > if (!data)
> > return EFI_EXIT(EFI_INVALID_PARAMETER);
> >  
> > -   if (hex2mem(data, s, len * 2))
> > +   if (hex2mem(data, s, len) != len)
> > return EFI_EXIT(EFI_DEVICE_ERROR);

Even if we did not check the string length early, hex2mem() would
return -1 when the number of digits is odd.

> >  
> > debug("%s: got value: \"%s\"\n", __func__, s);
> > 
> 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3] efi_loader: fix off-by-one bug in efi_get_variable

2018-05-11 Thread Ivan Gorinov
efi_get_variable() always stores an extra zero byte after the output data.
When the returned data size matches the output buffer size, the extra zero
byte is stored past the end of the output buffer.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 lib/efi_loader/efi_variable.c | 40 +---
 1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index 6c177da..28b2f5c 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -50,7 +50,7 @@
(strlen("efi_---_") + \
(MAX_VAR_NAME * MAX_UTF8_PER_UTF16))
 
-static int hex(unsigned char ch)
+static int hex(int ch)
 {
if (ch >= 'a' && ch <= 'f')
return ch-'a'+10;
@@ -61,44 +61,34 @@ static int hex(unsigned char ch)
return -1;
 }
 
-static const char *hex2mem(u8 *mem, const char *hexstr, int count)
+static int hex2mem(u8 *mem, const char *hexstr, int size)
 {
-   memset(mem, 0, count/2);
+   int nibble;
+   int i;
 
-   do {
-   int nibble;
+   memset(mem, 0, size);
 
-   *mem = 0;
-
-   if (!count || !*hexstr)
+   for (i = 0; i < size; i++) {
+   if (*hexstr == '\0')
break;
 
nibble = hex(*hexstr);
if (nibble < 0)
-   break;
+   return -1;
 
*mem = nibble;
-   count--;
hexstr++;
 
-   if (!count || !*hexstr)
-   break;
-
nibble = hex(*hexstr);
if (nibble < 0)
-   break;
+   return -1;
 
*mem = (*mem << 4) | nibble;
-   count--;
hexstr++;
mem++;
+   }
 
-   } while (1);
-
-   if (*hexstr)
-   return hexstr;
-
-   return NULL;
+   return i;
 }
 
 static char *mem2hex(char *hexstr, const u8 *mem, int count)
@@ -210,8 +200,12 @@ efi_status_t EFIAPI efi_get_variable(s16 *variable_name,
if ((s = prefix(val, "(blob)"))) {
unsigned len = strlen(s);
 
+   /* number of hexadecimal digits must be even */
+   if (len & 1)
+   return EFI_EXIT(EFI_DEVICE_ERROR);
+
/* two characters per byte: */
-   len = DIV_ROUND_UP(len, 2);
+   len /= 2;
*data_size = len;
 
if (in_size < len)
@@ -220,7 +214,7 @@ efi_status_t EFIAPI efi_get_variable(s16 *variable_name,
if (!data)
return EFI_EXIT(EFI_INVALID_PARAMETER);
 
-   if (hex2mem(data, s, len * 2))
+   if (hex2mem(data, s, len) != len)
return EFI_EXIT(EFI_DEVICE_ERROR);
 
debug("%s: got value: \"%s\"\n", __func__, s);
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2] efi_loader: fix off-by-one bug in efi_get_variable

2018-05-09 Thread Ivan Gorinov
efi_get_variable() always stores an extra zero byte after the output data.
When the returned data size matches the output buffer size, the extra zero
byte is stored past the end of the output buffer.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 lib/efi_loader/efi_variable.c | 64 +--
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index 6c177da..b1e6a73 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -50,7 +50,7 @@
(strlen("efi_---_") + \
(MAX_VAR_NAME * MAX_UTF8_PER_UTF16))
 
-static int hex(unsigned char ch)
+static int hex(char ch)
 {
if (ch >= 'a' && ch <= 'f')
return ch-'a'+10;
@@ -61,44 +61,41 @@ static int hex(unsigned char ch)
return -1;
 }
 
-static const char *hex2mem(u8 *mem, const char *hexstr, int count)
+static int hex2mem(u8 *mem, const char *hexstr, int size)
 {
-   memset(mem, 0, count/2);
+   u8 data;
+   int nibble;
+   char ch;
+   int i, k;
 
-   do {
-   int nibble;
+   memset(mem, 0, size);
 
-   *mem = 0;
+   for (i = 0; i < size; i += 1) {
+   data = 0;
+   for (k = 0; k < 2; k += 1) {
+   ch = *(hexstr++);
 
-   if (!count || !*hexstr)
-   break;
-
-   nibble = hex(*hexstr);
-   if (nibble < 0)
-   break;
-
-   *mem = nibble;
-   count--;
-   hexstr++;
-
-   if (!count || !*hexstr)
-   break;
+   if (!ch) {
+   if (k == 0)
+   return i;
+   else
+   return -1;
+   }
 
-   nibble = hex(*hexstr);
-   if (nibble < 0)
-   break;
+   nibble = hex(ch);
+   if (nibble < 0)
+   return -1;
 
-   *mem = (*mem << 4) | nibble;
-   count--;
-   hexstr++;
-   mem++;
+   hexstr++;
 
-   } while (1);
+   data <<= 4;
+   data |= nibble;
 
-   if (*hexstr)
-   return hexstr;
+   }
+   mem[i] = data;
+   }
 
-   return NULL;
+   return i;
 }
 
 static char *mem2hex(char *hexstr, const u8 *mem, int count)
@@ -210,8 +207,11 @@ efi_status_t EFIAPI efi_get_variable(s16 *variable_name,
if ((s = prefix(val, "(blob)"))) {
unsigned len = strlen(s);
 
+   if (len & 1)
+   return EFI_EXIT(EFI_DEVICE_ERROR);
+
/* two characters per byte: */
-   len = DIV_ROUND_UP(len, 2);
+   len /= 2;
*data_size = len;
 
if (in_size < len)
@@ -220,7 +220,7 @@ efi_status_t EFIAPI efi_get_variable(s16 *variable_name,
if (!data)
return EFI_EXIT(EFI_INVALID_PARAMETER);
 
-   if (hex2mem(data, s, len * 2))
+   if (hex2mem(data, s, len) != len)
return EFI_EXIT(EFI_DEVICE_ERROR);
 
debug("%s: got value: \"%s\"\n", __func__, s);
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] efi_loader: fix off-by-one bug in efi_get_variable

2018-05-08 Thread Ivan Gorinov
efi_get_variable() always stores an extra zero byte after the output data.
When the returned data size matches the output buffer size, the extra zero
byte is stored past the end of the output buffer.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 lib/efi_loader/efi_variable.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index 6c177da..d031338 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -68,11 +68,11 @@ static const char *hex2mem(u8 *mem, const char *hexstr, int 
count)
do {
int nibble;
 
-   *mem = 0;
-
if (!count || !*hexstr)
break;
 
+   *mem = 0;
+
nibble = hex(*hexstr);
if (nibble < 0)
break;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] efi_loader: correctly apply relocations from the .reloc section

2018-05-02 Thread Ivan Gorinov
Instead of difference between preferred and actual image base, the
actual base is added to the fields specified in the .reloc section.

Use ImageBase from PE optional header to compute the delta,
exit early if the image is loaded at the preferred address.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 lib/efi_loader/efi_image_loader.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/lib/efi_loader/efi_image_loader.c 
b/lib/efi_loader/efi_image_loader.c
index d5fbba3..80c08d2 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -93,11 +93,16 @@ void efi_print_image_infos(void *pc)
 }
 
 static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
-   unsigned long rel_size, void *efi_reloc)
+   unsigned long rel_size, void *efi_reloc,
+   unsigned long pref_address)
 {
+   unsigned long delta = (unsigned long)efi_reloc - pref_address;
const IMAGE_BASE_RELOCATION *end;
int i;
 
+   if (delta == 0)
+   return EFI_SUCCESS;
+
end = (const IMAGE_BASE_RELOCATION *)((const char *)rel + rel_size);
while (rel < end - 1 && rel->SizeOfBlock) {
const uint16_t *relocs = (const uint16_t *)(rel + 1);
@@ -106,7 +111,6 @@ static efi_status_t efi_loader_relocate(const 
IMAGE_BASE_RELOCATION *rel,
uint32_t offset = (uint32_t)(*relocs & 0xfff) +
  rel->VirtualAddress;
int type = *relocs >> EFI_PAGE_SHIFT;
-   unsigned long delta = (unsigned long)efi_reloc;
uint64_t *x64 = efi_reloc + offset;
uint32_t *x32 = efi_reloc + offset;
uint16_t *x16 = efi_reloc + offset;
@@ -194,6 +198,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
unsigned long rel_size;
int rel_idx = IMAGE_DIRECTORY_ENTRY_BASERELOC;
void *entry;
+   uint64_t image_base;
uint64_t image_size;
unsigned long virt_size = 0;
int supported = 0;
@@ -237,6 +242,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
IMAGE_NT_HEADERS64 *nt64 = (void *)nt;
IMAGE_OPTIONAL_HEADER64 *opt = >OptionalHeader;
+   image_base = opt->ImageBase;
image_size = opt->SizeOfImage;
efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
efi_reloc = efi_alloc(virt_size,
@@ -252,6 +258,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
virt_size = ALIGN(virt_size, opt->SectionAlignment);
} else if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
IMAGE_OPTIONAL_HEADER32 *opt = >OptionalHeader;
+   image_base = opt->ImageBase;
image_size = opt->SizeOfImage;
efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
efi_reloc = efi_alloc(virt_size,
@@ -282,7 +289,8 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
}
 
/* Run through relocations */
-   if (efi_loader_relocate(rel, rel_size, efi_reloc) != EFI_SUCCESS) {
+   if (efi_loader_relocate(rel, rel_size, efi_reloc,
+   (unsigned long)image_base) != EFI_SUCCESS) {
efi_free_pages((uintptr_t) efi_reloc,
   (virt_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT);
return NULL;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v6 1/2] x86: Add TSC-specific timer functions

2018-04-23 Thread Ivan Gorinov
Hi Bin,

On Mon, Apr 23, 2018 at 01:38:05AM -0600, Bin Meng wrote:
> > Coreboot timestamp functions and Quark memory reference code use
> > get_tbclk() to get TSC frequency. This will not work if another
> > early timer is selected.
> 
> Thanks for working on this. But get_tbclk() is one API provided by the
> timer library. The get_tbclk_mhz() is something that is implemented by
> the TSC timer driver, so can we get rid of the get_tbclk_mhz() and use
> the get_tbclk() instead in coreboot/timestamp.c and quark/mrc_util.c?

The Coreboot timestamp code and Quark MRC specifically use rdtsc().
We can replace it with timer_early_get_count() or provide a function
to get the TSC frequency even when another early timer is selected.

> > Add tsc_rate_mhz() function and use it in the code that specifically
> > needs to get TSC rate regardless of currently selected early timer.
> >
> > Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
> > ---
> >  arch/x86/cpu/coreboot/timestamp.c |  2 +-
> >  arch/x86/cpu/quark/mrc_util.c | 13 ++---
> >  arch/x86/include/asm/u-boot-x86.h |  2 +-
> >  drivers/timer/tsc_timer.c | 33 -
> >  4 files changed, 32 insertions(+), 18 deletions(-)
> >
> > diff --git a/arch/x86/cpu/coreboot/timestamp.c 
> > b/arch/x86/cpu/coreboot/timestamp.c
> > index b382795..05bb214 100644
> > --- a/arch/x86/cpu/coreboot/timestamp.c
> > +++ b/arch/x86/cpu/coreboot/timestamp.c
> > @@ -78,7 +78,7 @@ int timestamp_add_to_bootstage(void)
> > if (name) {
> > bootstage_add_record(0, name, BOOTSTAGEF_ALLOC,
> >  tse->entry_stamp /
> > -   get_tbclk_mhz());
> > +   tsc_rate_mhz());
> > }
> > }
> >
> > diff --git a/arch/x86/cpu/quark/mrc_util.c b/arch/x86/cpu/quark/mrc_util.c
> > index fac2d72..4794395 100644
> > --- a/arch/x86/cpu/quark/mrc_util.c
> > +++ b/arch/x86/cpu/quark/mrc_util.c
> > @@ -57,19 +57,18 @@ void mrc_post_code(uint8_t major, uint8_t minor)
> >  void delay_n(uint32_t ns)
> >  {
> > /* 1000 MHz clock has 1ns period --> no conversion required */
> > -   uint64_t final_tsc = rdtsc();
> > +   uint64_t start_tsc = rdtsc();
> > +   uint64_t ticks;
> >
> > -   final_tsc += ((get_tbclk_mhz() * ns) / 1000);
> > -
> > -   while (rdtsc() < final_tsc)
> > -   ;
> > +   ticks = (tsc_rate_mhz() * ns) / 1000;
> > +   while (rdtsc() - start_tsc < ticks);
> >  }
> >
> >  /* Delay number of microseconds */
> > -void delay_u(uint32_t ms)
> > +void delay_u(uint32_t us)
> >  {
> > /* 64-bit math is not an option, just use loops */
> > -   while (ms--)
> > +   while (us--)
> > delay_n(1000);
> >  }
> >
> > diff --git a/arch/x86/include/asm/u-boot-x86.h 
> > b/arch/x86/include/asm/u-boot-x86.h
> > index 187fe5f..de68120 100644
> > --- a/arch/x86/include/asm/u-boot-x86.h
> > +++ b/arch/x86/include/asm/u-boot-x86.h
> > @@ -29,7 +29,7 @@ int cleanup_before_linux(void);
> >  void timer_isr(void *);
> >  typedef void (timer_fnc_t) (void);
> >  int register_timer_isr (timer_fnc_t *isr_func);
> > -unsigned long get_tbclk_mhz(void);
> > +unsigned long tsc_rate_mhz(void);
> >  void timer_set_base(uint64_t base);
> >  int i8254_init(void);
> >
> > diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
> > index 9296de6..98cbf12 100644
> > --- a/drivers/timer/tsc_timer.c
> > +++ b/drivers/timer/tsc_timer.c
> > @@ -277,15 +277,12 @@ success:
> > return delta / 1000;
> >  }
> >
> > -/* Get the speed of the TSC timer in MHz */
> > -unsigned notrace long get_tbclk_mhz(void)
> > -{
> > -   return get_tbclk() / 100;
> > -}
> > -
> >  static ulong get_ms_timer(void)
> >  {
> > -   return (get_ticks() * 1000) / get_tbclk();
> > +   if (gd->arch.clock_rate == 0)
> > +   return 0;
> > +
> > +   return (rdtsc() * 1000) / gd->arch.clock_rate;
> >  }
> >
> >  ulong get_timer(ulong base)
> > @@ -295,7 +292,10 @@ ulong get_timer(ulong base)
> >
> >  ulong notrace timer_get_us(void)
> >  {
> > -   return get_ticks() / get_tbclk_mhz();
> > +   if (gd->arch.clock_rate == 0)
> > +

Re: [U-Boot] [PATCH v6 1/2] x86: Add TSC-specific timer functions

2018-04-20 Thread Ivan Gorinov
On Fri, Apr 20, 2018 at 06:25:08AM -0600, Andy Shevchenko wrote:
> > Coreboot timestamp functions and Quark memory reference code use
> > get_tbclk() to get TSC frequency. This will not work if another
> > early timer is selected.
> > 
> > Add tsc_rate_mhz() function and use it in the code that specifically
> > needs to get TSC rate regardless of currently selected early timer.
> 
> 
> >  void delay_n(uint32_t ns)
> >  {
> > /* 1000 MHz clock has 1ns period --> no conversion required
> > */
> > -   uint64_t final_tsc = rdtsc();
> > +   uint64_t start_tsc = rdtsc();
> > +   uint64_t ticks;
> >  
> > -   final_tsc += ((get_tbclk_mhz() * ns) / 1000);
> > -
> > -   while (rdtsc() < final_tsc)
> > -   ;
> > +   ticks = (tsc_rate_mhz() * ns) / 1000;
> 
> > +   while (rdtsc() - start_tsc < ticks);
> 
> I would rather preserve existing style.

OK. Existing style does not correctly handle overflow,
but for a 64-bit counter it's a very unlikely event.
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH] x86: Use microcode update from device tree for all processors

2018-04-20 Thread Ivan Gorinov
Hi Bin,

On Wed, Apr 18, 2018 at 07:05:28PM -0600, Bin Meng wrote:
> >> >
> >> > If there is no ROM image, ucode_base and ucode_size are not initialized 
> >> > and
> >> > the microcode update data from DTB applied by microcode_update_intel() 
> >> > to the
> >> > bootstrap CPU is not used by the multiprocessing code.
> >>
> >> Correct. If it's not a ROM image, which means U-Boot is probably not
> >> the 1st stage bootloader, which means updating microcode is not
> >> necessary. So is there any issue with current implementation?
> >
> > If the 1st stage bootloader is running from the on-chip SRAM, there may be
> > not enough space to include the microcode update data. In this case, U-Boot
> > is a secondary boot loader but still has to update the microcode.
> 
> Thanks for the information. Correct, if that's the case, then we
> should tune our codes to support that.
> 
> But I guess the "1st stage" bootloader is loaded by some on-chip
> BOOTROM to the internal SRAM?

Correct.

> Is the "1st stage" bootloader running from SRAM the U-Boot SPL? Or
> some proprietary implementation?

It's usually a proprietary implementation.
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH] x86: Use microcode update from device tree for all processors

2018-04-18 Thread Ivan Gorinov
Hi Bin,

On Wed, Apr 18, 2018 at 06:48:59AM -0600, Bin Meng wrote:
> >> I don't understand what the bug is here. The AP microcode update is
> >> done in sipi_vector.S.
> >
> > I have found how it works. When a ROM image is built, the binman tool
> > looks for symbol '_dt_ucode_base_size' and updates position and size
> > of the microcode update data in the ucode_base and ucode_size variables.
> > The ucode_base pointer is used to update the bootstrap CPU very early,
> > and the other CPUs later in the multiprocessing code.
> >
> > On x86, binman is called from Makefile only if a ROM image is created:
> >
> > u-boot.rom: u-boot-x86-16bit.bin u-boot.bin \
> > ...
> > $(call if_changed,binman)
> >
> > If there is no ROM image, ucode_base and ucode_size are not initialized and
> > the microcode update data from DTB applied by microcode_update_intel() to 
> > the
> > bootstrap CPU is not used by the multiprocessing code.
> 
> Correct. If it's not a ROM image, which means U-Boot is probably not
> the 1st stage bootloader, which means updating microcode is not
> necessary. So is there any issue with current implementation?

If the 1st stage bootloader is running from the on-chip SRAM, there may be
not enough space to include the microcode update data. In this case, U-Boot
is a secondary boot loader but still has to update the microcode.
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH] x86: Use microcode update from device tree for all processors

2018-04-17 Thread Ivan Gorinov
On Thu, Apr 05, 2018 at 09:31:34AM -0600, Bin Meng wrote:
> > The microcode update data block encoded in Device Tree is used by
> > the bootstrap processor (BSP) but not passed to the other CPUs (AP).
> 
> I don't understand what the bug is here. The AP microcode update is
> done in sipi_vector.S.

I have found how it works. When a ROM image is built, the binman tool
looks for symbol '_dt_ucode_base_size' and updates position and size
of the microcode update data in the ucode_base and ucode_size variables.
The ucode_base pointer is used to update the bootstrap CPU very early,
and the other CPUs later in the multiprocessing code.

On x86, binman is called from Makefile only if a ROM image is created:

u-boot.rom: u-boot-x86-16bit.bin u-boot.bin \
...
$(call if_changed,binman)

If there is no ROM image, ucode_base and ucode_size are not initialized and
the microcode update data from DTB applied by microcode_update_intel() to the
bootstrap CPU is not used by the multiprocessing code.
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v6 1/2] x86: Add TSC-specific timer functions

2018-04-12 Thread Ivan Gorinov
Coreboot timestamp functions and Quark memory reference code use
get_tbclk() to get TSC frequency. This will not work if another
early timer is selected.

Add tsc_rate_mhz() function and use it in the code that specifically
needs to get TSC rate regardless of currently selected early timer.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/x86/cpu/coreboot/timestamp.c |  2 +-
 arch/x86/cpu/quark/mrc_util.c | 13 ++---
 arch/x86/include/asm/u-boot-x86.h |  2 +-
 drivers/timer/tsc_timer.c | 33 -
 4 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/arch/x86/cpu/coreboot/timestamp.c 
b/arch/x86/cpu/coreboot/timestamp.c
index b382795..05bb214 100644
--- a/arch/x86/cpu/coreboot/timestamp.c
+++ b/arch/x86/cpu/coreboot/timestamp.c
@@ -78,7 +78,7 @@ int timestamp_add_to_bootstage(void)
if (name) {
bootstage_add_record(0, name, BOOTSTAGEF_ALLOC,
 tse->entry_stamp /
-   get_tbclk_mhz());
+   tsc_rate_mhz());
}
}
 
diff --git a/arch/x86/cpu/quark/mrc_util.c b/arch/x86/cpu/quark/mrc_util.c
index fac2d72..4794395 100644
--- a/arch/x86/cpu/quark/mrc_util.c
+++ b/arch/x86/cpu/quark/mrc_util.c
@@ -57,19 +57,18 @@ void mrc_post_code(uint8_t major, uint8_t minor)
 void delay_n(uint32_t ns)
 {
/* 1000 MHz clock has 1ns period --> no conversion required */
-   uint64_t final_tsc = rdtsc();
+   uint64_t start_tsc = rdtsc();
+   uint64_t ticks;
 
-   final_tsc += ((get_tbclk_mhz() * ns) / 1000);
-
-   while (rdtsc() < final_tsc)
-   ;
+   ticks = (tsc_rate_mhz() * ns) / 1000;
+   while (rdtsc() - start_tsc < ticks);
 }
 
 /* Delay number of microseconds */
-void delay_u(uint32_t ms)
+void delay_u(uint32_t us)
 {
/* 64-bit math is not an option, just use loops */
-   while (ms--)
+   while (us--)
delay_n(1000);
 }
 
diff --git a/arch/x86/include/asm/u-boot-x86.h 
b/arch/x86/include/asm/u-boot-x86.h
index 187fe5f..de68120 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -29,7 +29,7 @@ int cleanup_before_linux(void);
 void timer_isr(void *);
 typedef void (timer_fnc_t) (void);
 int register_timer_isr (timer_fnc_t *isr_func);
-unsigned long get_tbclk_mhz(void);
+unsigned long tsc_rate_mhz(void);
 void timer_set_base(uint64_t base);
 int i8254_init(void);
 
diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
index 9296de6..98cbf12 100644
--- a/drivers/timer/tsc_timer.c
+++ b/drivers/timer/tsc_timer.c
@@ -277,15 +277,12 @@ success:
return delta / 1000;
 }
 
-/* Get the speed of the TSC timer in MHz */
-unsigned notrace long get_tbclk_mhz(void)
-{
-   return get_tbclk() / 100;
-}
-
 static ulong get_ms_timer(void)
 {
-   return (get_ticks() * 1000) / get_tbclk();
+   if (gd->arch.clock_rate == 0)
+   return 0;
+
+   return (rdtsc() * 1000) / gd->arch.clock_rate;
 }
 
 ulong get_timer(ulong base)
@@ -295,7 +292,10 @@ ulong get_timer(ulong base)
 
 ulong notrace timer_get_us(void)
 {
-   return get_ticks() / get_tbclk_mhz();
+   if (gd->arch.clock_rate == 0)
+   return 0;
+
+   return (rdtsc() * 100) / gd->arch.clock_rate;
 }
 
 ulong timer_get_boot_us(void)
@@ -308,7 +308,7 @@ void __udelay(unsigned long usec)
u64 now = get_ticks();
u64 stop;
 
-   stop = now + usec * get_tbclk_mhz();
+   stop = now + ((u64)usec * gd->arch.clock_rate) / 100;
 
while ((int64_t)(stop - get_ticks()) > 0)
 #if defined(CONFIG_QEMU) && defined(CONFIG_SMP)
@@ -355,6 +355,14 @@ static void tsc_timer_ensure_setup(void)
}
 }
 
+/* Get the speed of the TSC timer in MHz */
+unsigned notrace long tsc_rate_mhz(void)
+{
+   tsc_timer_ensure_setup();
+
+   return gd->arch.clock_rate / 100;
+}
+
 static int tsc_timer_probe(struct udevice *dev)
 {
struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
@@ -365,6 +373,13 @@ static int tsc_timer_probe(struct udevice *dev)
return 0;
 }
 
+int timer_init(void)
+{
+   tsc_timer_ensure_setup();
+
+   return 0;
+}
+
 unsigned long notrace timer_early_get_rate(void)
 {
tsc_timer_ensure_setup();
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v6 2/2] timer: Add High Precision Event Timers (HPET) support

2018-04-12 Thread Ivan Gorinov
Add HPET driver as an alternative timer for x86 (default is TSC).
HPET counter has constant frequency and does not need calibration.
New HPET driver can also be selected as the early timer on x86.

HPET can be selected as the tick timer in the Device Tree "chosen" node:

/include/ "hpet.dtsi"

...

chosen {
tick-timer = "/hpet";
};

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/Kconfig   |   1 +
 arch/x86/Kconfig   |  21 +
 arch/x86/dts/hpet.dtsi |   7 ++
 common/Kconfig |   1 +
 drivers/timer/Kconfig  |   9 ++
 drivers/timer/Makefile |   1 +
 drivers/timer/hpet_timer.c | 209 +
 drivers/timer/tsc_timer.c  |   8 ++
 8 files changed, 257 insertions(+)
 create mode 100644 arch/x86/dts/hpet.dtsi
 create mode 100644 drivers/timer/hpet_timer.c

diff --git a/arch/Kconfig b/arch/Kconfig
index e599e7a..f904fab 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -105,6 +105,7 @@ config X86
select PCI
select TIMER
select X86_TSC_TIMER
+   imply HPET_TIMER
imply BLK
imply DM_ETH
imply DM_GPIO
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5c23b2c..8f64b95 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -119,6 +119,27 @@ source "arch/x86/cpu/tangier/Kconfig"
 
 # architecture-specific options below
 
+choice
+   prompt "Select which timer to use early"
+   depends on TIMER_EARLY
+   default X86_EARLY_TIMER_TSC
+
+config X86_EARLY_TIMER_TSC
+   bool "TSC"
+   depends on X86_TSC_TIMER
+   help
+ This selects x86 Time Stamp Counter (TSC) as the early timer.
+ See CONFIG_TIMER_EARLY for the early timer description.
+
+config X86_EARLY_TIMER_HPET
+   bool "HPET"
+   depends on HPET_TIMER
+   help
+ This selects High Precision Event Timers as the early timer.
+ Early HPET base address is specified by CONFIG_HPET_ADDRESS.
+
+endchoice
+
 config AHCI
default y
 
diff --git a/arch/x86/dts/hpet.dtsi b/arch/x86/dts/hpet.dtsi
new file mode 100644
index 000..a74f739
--- /dev/null
+++ b/arch/x86/dts/hpet.dtsi
@@ -0,0 +1,7 @@
+/ {
+   hpet: hpet@fed0 {
+   compatible = "hpet-x86";
+   u-boot,dm-pre-reloc;
+   reg = <0xfed0 0x1000>;
+   };
+};
diff --git a/common/Kconfig b/common/Kconfig
index 03eeeb2..b02384c 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -2,6 +2,7 @@ menu "Boot timing"
 
 config BOOTSTAGE
bool "Boot timing and reporting"
+   select TIMER_EARLY
help
  Enable recording of boot time while booting. To use it, insert
  calls to bootstage_mark() with a suitable BOOTSTAGE_ID from
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 2c96896..26743b7 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -65,6 +65,15 @@ config X86_TSC_TIMER
help
  Select this to enable Time-Stamp Counter (TSC) timer for x86.
 
+config HPET_TIMER
+   bool "High Precision Event Timers (HPET) support"
+   depends on TIMER
+   default y if X86
+   help
+ Select this to enable High Precision Event Timers (HPET) on x86.
+ HPET main counter increments at constant rate and does not need
+ calibration.
+
 config OMAP_TIMER
bool "Omap timer support"
depends on TIMER
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index a6e7832..557fecc 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -8,6 +8,7 @@ obj-y += timer-uclass.o
 obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)+= tsc_timer.o
+obj-$(CONFIG_HPET_TIMER)   += hpet_timer.o
 obj-$(CONFIG_OMAP_TIMER)   += omap-timer.o
 obj-$(CONFIG_AST_TIMER)+= ast_timer.o
 obj-$(CONFIG_STI_TIMER)+= sti-timer.o
diff --git a/drivers/timer/hpet_timer.c b/drivers/timer/hpet_timer.c
new file mode 100644
index 000..0914dd5
--- /dev/null
+++ b/drivers/timer/hpet_timer.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HPET_PERIOD_REG 0x004
+#define HPET_CONFIG_REG 0x010
+#define HPET_MAIN_COUNT 0x0f0
+
+#define ENABLE_CNF 1
+
+#define HPET_MAX_PERIOD 1
+
+struct hpet_timer_priv {
+   void *regs;
+};
+
+/*
+ * Returns HPET clock frequency in HZ
+ * (rounding to the nearest integer),
+ * or 0 if HPET is not available.
+ */
+static inline u32 get_clock_frequency(void *regs)
+{
+   u64 d = 1000ull;
+   u32 period;
+
+   period = readl(regs + HPET_PERIOD_REG);
+   if (period == 0)
+   

[U-Boot] [PATCH v6 0/2] timer: Add High Precision Event Timers (HPET) support

2018-04-12 Thread Ivan Gorinov
Add HPET driver as an alternative timer for x86 (default is TSC).
HPET counter has constant frequency and does not need calibration.
This change also makes TSC timer driver optional on x86.
New HPET driver can also be selected as the early timer on x86.

v6:
Added TSC-specific timer functions to use instead of early timer
in the code that specifically needs TSC.

v5:
Using readq() and writeq() for main counter access.

v3:
Added early timer choice in x86 Kconfig.

Ivan Gorinov (2):
  x86: Add TSC-specific timer functions
  timer: Add High Precision Event Timers (HPET) support

 arch/Kconfig  |   1 +
 arch/x86/Kconfig  |  21 
 arch/x86/cpu/coreboot/timestamp.c |   2 +-
 arch/x86/cpu/quark/mrc_util.c |  13 ++-
 arch/x86/dts/hpet.dtsi|   7 ++
 arch/x86/include/asm/u-boot-x86.h |   2 +-
 common/Kconfig|   1 +
 drivers/timer/Kconfig |   9 ++
 drivers/timer/Makefile|   1 +
 drivers/timer/hpet_timer.c| 209 ++
 drivers/timer/tsc_timer.c |  39 +--
 11 files changed, 288 insertions(+), 17 deletions(-)
 create mode 100644 arch/x86/dts/hpet.dtsi
 create mode 100644 drivers/timer/hpet_timer.c

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v6] x86: Add 64-bit memory-mapped I/O functions

2018-04-06 Thread Ivan Gorinov
Add readq() and writeq() definitions for x86.

Please note: in 32-bit code readq/writeq will generate two 32-bit
memory access instructions instead of one atomic 64-bit operation.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/x86/include/asm/io.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 263dd8f..4ab0080 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -61,16 +61,20 @@
 #define readb(addr) (*(volatile unsigned char *) (addr))
 #define readw(addr) (*(volatile unsigned short *) (addr))
 #define readl(addr) (*(volatile unsigned int *) (addr))
+#define readq(addr) (*(volatile unsigned long long *) (addr))
 #define __raw_readb readb
 #define __raw_readw readw
 #define __raw_readl readl
+#define __raw_readq readq
 
 #define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b))
 #define writew(b,addr) (*(volatile unsigned short *) (addr) = (b))
 #define writel(b,addr) (*(volatile unsigned int *) (addr) = (b))
+#define writeq(b,addr) (*(volatile unsigned long long *) (addr) = (b))
 #define __raw_writeb writeb
 #define __raw_writew writew
 #define __raw_writel writel
+#define __raw_writeq writeq
 
 #define memset_io(a,b,c)   memset((a),(b),(c))
 #define memcpy_fromio(a,b,c)   memcpy((a),(b),(c))
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v5 2/2] timer: Add High Precision Event Timers (HPET) support

2018-04-06 Thread Ivan Gorinov
Add HPET driver as an alternative timer for x86 (default is TSC).
HPET counter has constant frequency and does not need calibration.
This change also makes TSC timer driver optional on x86.
New HPET driver can also be selected as the early timer on x86.

HPET can be selected as the tick timer in the Device Tree "chosen" node:

/include/ "hpet.dtsi"

...

chosen {
tick-timer = "/hpet";
};

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/Kconfig   |   2 +-
 arch/x86/Kconfig   |  21 ++
 arch/x86/dts/hpet.dtsi |   7 ++
 drivers/timer/Kconfig  |   9 +++
 drivers/timer/Makefile |   1 +
 drivers/timer/hpet_timer.c | 179 +
 drivers/timer/tsc_timer.c  |   8 ++
 7 files changed, 226 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/dts/hpet.dtsi
 create mode 100644 drivers/timer/hpet_timer.c

diff --git a/arch/Kconfig b/arch/Kconfig
index e599e7a..37dabae 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -104,7 +104,7 @@ config X86
select DM_PCI
select PCI
select TIMER
-   select X86_TSC_TIMER
+   imply X86_TSC_TIMER
imply BLK
imply DM_ETH
imply DM_GPIO
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5c23b2c..2fe5b6a 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -119,6 +119,27 @@ source "arch/x86/cpu/tangier/Kconfig"
 
 # architecture-specific options below
 
+choice
+   prompt "Select which timer to use early on x86"
+   depends on X86
+   default X86_EARLY_TIMER_TSC
+
+config X86_EARLY_TIMER_TSC
+   bool "TSC"
+   depends on X86_TSC_TIMER
+   help
+ This selects x86 Time Stamp Counter (TSC) as the early timer.
+ See CONFIG_TIMER_EARLY for the early timer description.
+
+config X86_EARLY_TIMER_HPET
+   bool "HPET"
+   depends on HPET_TIMER
+   help
+ This selects High Precision Event Timers as the early timer.
+ Early HPET base address is specified by CONFIG_HPET_ADDRESS.
+
+endchoice
+
 config AHCI
default y
 
diff --git a/arch/x86/dts/hpet.dtsi b/arch/x86/dts/hpet.dtsi
new file mode 100644
index 000..a74f739
--- /dev/null
+++ b/arch/x86/dts/hpet.dtsi
@@ -0,0 +1,7 @@
+/ {
+   hpet: hpet@fed0 {
+   compatible = "hpet-x86";
+   u-boot,dm-pre-reloc;
+   reg = <0xfed0 0x1000>;
+   };
+};
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 2c96896..26743b7 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -65,6 +65,15 @@ config X86_TSC_TIMER
help
  Select this to enable Time-Stamp Counter (TSC) timer for x86.
 
+config HPET_TIMER
+   bool "High Precision Event Timers (HPET) support"
+   depends on TIMER
+   default y if X86
+   help
+ Select this to enable High Precision Event Timers (HPET) on x86.
+ HPET main counter increments at constant rate and does not need
+ calibration.
+
 config OMAP_TIMER
bool "Omap timer support"
depends on TIMER
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index a6e7832..557fecc 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -8,6 +8,7 @@ obj-y += timer-uclass.o
 obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)+= tsc_timer.o
+obj-$(CONFIG_HPET_TIMER)   += hpet_timer.o
 obj-$(CONFIG_OMAP_TIMER)   += omap-timer.o
 obj-$(CONFIG_AST_TIMER)+= ast_timer.o
 obj-$(CONFIG_STI_TIMER)+= sti-timer.o
diff --git a/drivers/timer/hpet_timer.c b/drivers/timer/hpet_timer.c
new file mode 100644
index 000..b1ce226
--- /dev/null
+++ b/drivers/timer/hpet_timer.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HPET_PERIOD_REG 0x004
+#define HPET_CONFIG_REG 0x010
+#define HPET_MAIN_COUNT 0x0f0
+
+#define ENABLE_CNF 1
+
+#define HPET_MAX_PERIOD 1
+
+struct hpet_timer_priv {
+   void *regs;
+};
+
+/*
+ * Returns HPET clock frequency in HZ
+ * (rounding to the nearest integer),
+ * or 0 if HPET is not available.
+ */
+static inline u32 get_clock_frequency(void *regs)
+{
+   u64 d = 1000ull;
+   u32 period;
+
+   period = readl(regs + HPET_PERIOD_REG);
+   if (period == 0)
+   return 0;
+   if (period > HPET_MAX_PERIOD)
+   return 0;
+
+   d += period / 2;
+
+   return d / period;
+}
+
+/* Reset and start the main counter. */
+static void start_main_counter(void *regs)
+{
+   u32 config;
+
+   config = readl(regs + HPET_CONFIG_REG);
+   config &= ~ENABLE_CNF;
+   writel(config, regs +

[U-Boot] [PATCH v5 1/2] x86: Add 64-bit memory-mapped I/O functions

2018-04-06 Thread Ivan Gorinov
Add readq() and writeq() definitions for x86.

Please note: in 32-bit code readq/writeq will generate two 32-bit
memory access instructions instead of one atomic 64-bit operation.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/x86/include/asm/io.h | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 263dd8f..c7f6fcb 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -58,19 +58,23 @@
  * memory location directly.
  */
 
-#define readb(addr) (*(volatile unsigned char *) (addr))
-#define readw(addr) (*(volatile unsigned short *) (addr))
-#define readl(addr) (*(volatile unsigned int *) (addr))
+#define readb(addr) (*(volatile u8 *) (addr))
+#define readw(addr) (*(volatile u16 *) (addr))
+#define readl(addr) (*(volatile u32 *) (addr))
+#define readq(addr) (*(volatile u64 *) (addr))
 #define __raw_readb readb
 #define __raw_readw readw
 #define __raw_readl readl
+#define __raw_readq readq
 
-#define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b))
-#define writew(b,addr) (*(volatile unsigned short *) (addr) = (b))
-#define writel(b,addr) (*(volatile unsigned int *) (addr) = (b))
+#define writeb(b, addr) (*(volatile u8 *) (addr) = (b))
+#define writew(b, addr) (*(volatile u16 *) (addr) = (b))
+#define writel(b, addr) (*(volatile u32 *) (addr) = (b))
+#define writeq(b, addr) (*(volatile u64 *) (addr) = (b))
 #define __raw_writeb writeb
 #define __raw_writew writew
 #define __raw_writel writel
+#define __raw_writeq writeq
 
 #define memset_io(a,b,c)   memset((a),(b),(c))
 #define memcpy_fromio(a,b,c)   memcpy((a),(b),(c))
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v5 0/2] timer: Add High Precision Event Timers (HPET) support

2018-04-06 Thread Ivan Gorinov

Add HPET driver as an alternative timer for x86 (default is TSC).
HPET counter has constant frequency and does not need calibration.
This change also makes TSC timer driver optional on x86.
New HPET driver can also be selected as the early timer on x86.

v5:
  Using new readq() and writeq() definitions.

v4:
  Using 64-bit pointer for main counter access.

v3:
  Added early timer choice in x86-specific configuration.

v2:
  Moved duplicated code to static functions.

Ivan Gorinov (2):
  x86: Add 64-bit memory-mapped I/O functions
  timer: Add High Precision Event Timers (HPET) support

 arch/Kconfig   |   2 +-
 arch/x86/Kconfig   |  21 ++
 arch/x86/dts/hpet.dtsi |   7 ++
 arch/x86/include/asm/io.h  |  16 ++--
 drivers/timer/Kconfig  |   9 +++
 drivers/timer/Makefile |   1 +
 drivers/timer/hpet_timer.c | 179 +
 drivers/timer/tsc_timer.c  |   8 ++
 8 files changed, 236 insertions(+), 7 deletions(-)
 create mode 100644 arch/x86/dts/hpet.dtsi
 create mode 100644 drivers/timer/hpet_timer.c

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v4] timer: Add High Precision Event Timers (HPET) support

2018-04-06 Thread Ivan Gorinov
Add HPET driver as an alternative timer for x86 (default is TSC).
HPET counter has constant frequency and does not need calibration.
This change also makes TSC timer driver optional on x86.
New HPET driver can also be selected as the early timer on x86.

HPET can be selected as the tick timer in the Device Tree "chosen" node:

/include/ "hpet.dtsi"

...

chosen {
tick-timer = "/hpet";
};

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/Kconfig   |   2 +-
 arch/x86/Kconfig   |  21 ++
 arch/x86/dts/hpet.dtsi |   7 ++
 drivers/timer/Kconfig  |   9 +++
 drivers/timer/Makefile |   1 +
 drivers/timer/hpet_timer.c | 181 +
 drivers/timer/tsc_timer.c  |   8 ++
 7 files changed, 228 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/dts/hpet.dtsi
 create mode 100644 drivers/timer/hpet_timer.c

diff --git a/arch/Kconfig b/arch/Kconfig
index e599e7a..37dabae 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -104,7 +104,7 @@ config X86
select DM_PCI
select PCI
select TIMER
-   select X86_TSC_TIMER
+   imply X86_TSC_TIMER
imply BLK
imply DM_ETH
imply DM_GPIO
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5c23b2c..2fe5b6a 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -119,6 +119,27 @@ source "arch/x86/cpu/tangier/Kconfig"
 
 # architecture-specific options below
 
+choice
+   prompt "Select which timer to use early on x86"
+   depends on X86
+   default X86_EARLY_TIMER_TSC
+
+config X86_EARLY_TIMER_TSC
+   bool "TSC"
+   depends on X86_TSC_TIMER
+   help
+ This selects x86 Time Stamp Counter (TSC) as the early timer.
+ See CONFIG_TIMER_EARLY for the early timer description.
+
+config X86_EARLY_TIMER_HPET
+   bool "HPET"
+   depends on HPET_TIMER
+   help
+ This selects High Precision Event Timers as the early timer.
+ Early HPET base address is specified by CONFIG_HPET_ADDRESS.
+
+endchoice
+
 config AHCI
default y
 
diff --git a/arch/x86/dts/hpet.dtsi b/arch/x86/dts/hpet.dtsi
new file mode 100644
index 000..a74f739
--- /dev/null
+++ b/arch/x86/dts/hpet.dtsi
@@ -0,0 +1,7 @@
+/ {
+   hpet: hpet@fed0 {
+   compatible = "hpet-x86";
+   u-boot,dm-pre-reloc;
+   reg = <0xfed0 0x1000>;
+   };
+};
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 2c96896..26743b7 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -65,6 +65,15 @@ config X86_TSC_TIMER
help
  Select this to enable Time-Stamp Counter (TSC) timer for x86.
 
+config HPET_TIMER
+   bool "High Precision Event Timers (HPET) support"
+   depends on TIMER
+   default y if X86
+   help
+ Select this to enable High Precision Event Timers (HPET) on x86.
+ HPET main counter increments at constant rate and does not need
+ calibration.
+
 config OMAP_TIMER
bool "Omap timer support"
depends on TIMER
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index a6e7832..557fecc 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -8,6 +8,7 @@ obj-y += timer-uclass.o
 obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)+= tsc_timer.o
+obj-$(CONFIG_HPET_TIMER)   += hpet_timer.o
 obj-$(CONFIG_OMAP_TIMER)   += omap-timer.o
 obj-$(CONFIG_AST_TIMER)+= ast_timer.o
 obj-$(CONFIG_STI_TIMER)+= sti-timer.o
diff --git a/drivers/timer/hpet_timer.c b/drivers/timer/hpet_timer.c
new file mode 100644
index 000..86b05fa
--- /dev/null
+++ b/drivers/timer/hpet_timer.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HPET_PERIOD_REG 0x004
+#define HPET_CONFIG_REG 0x010
+#define HPET_MAIN_COUNT 0x0f0
+
+#define ENABLE_CNF 1
+
+#define HPET_MAX_PERIOD 1
+
+struct hpet_timer_priv {
+   void *regs;
+};
+
+/*
+ * Returns HPET clock frequency in HZ
+ * (rounding to the nearest integer),
+ * or 0 if HPET is not available.
+ */
+static inline u32 get_clock_frequency(void *regs)
+{
+   u64 d = 1000ull;
+   u32 period;
+
+   period = readl(regs + HPET_PERIOD_REG);
+   if (period == 0)
+   return 0;
+   if (period > HPET_MAX_PERIOD)
+   return 0;
+
+   d += period / 2;
+
+   return d / period;
+}
+
+/* Reset and start the main counter. */
+static void start_main_counter(void *regs)
+{
+   volatile u64 *main_counter = regs + HPET_MAIN_COUNT;
+   u32 config;
+
+   config = readl(regs + HPET_CONFIG_REG);
+

[U-Boot] [PATCH v4] timer: Add High Precision Event Timers (HPET) support

2018-04-06 Thread Ivan Gorinov
Add HPET driver as an alternative timer for x86 (default is TSC).
HPET counter has constant frequency and does not need calibration.
This change also makes TSC timer driver optional on x86.
New HPET driver can also be selected as the early timer on x86.

v4:
  Using 64-bit pointer for main counter access.

v3:
  Added early timer choice in x86-specific configuration.

v2:
  Moved duplicated code to static functions.

Ivan Gorinov (1):
  timer: Add High Precision Event Timers (HPET) support

 arch/Kconfig   |   2 +-
 arch/x86/Kconfig   |  21 ++
 arch/x86/dts/hpet.dtsi |   7 ++
 drivers/timer/Kconfig  |   9 +++
 drivers/timer/Makefile |   1 +
 drivers/timer/hpet_timer.c | 181 +
 drivers/timer/tsc_timer.c  |   8 ++
 7 files changed, 228 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/dts/hpet.dtsi
 create mode 100644 drivers/timer/hpet_timer.c

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3] efi_loader: Check machine type in the image header

2018-04-05 Thread Ivan Gorinov
Check FileHeader.Machine to make sure the EFI executable image is built
for the same architecture. For example, 32-bit U-Boot on x86 will print
an error message instead of loading an x86_64 image and crashing.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 include/pe.h  |  4 +++
 lib/efi_loader/efi_image_loader.c | 51 ++-
 2 files changed, 43 insertions(+), 12 deletions(-)

diff --git a/include/pe.h b/include/pe.h
index c3a19ce..e7845bb 100644
--- a/include/pe.h
+++ b/include/pe.h
@@ -38,11 +38,15 @@ typedef struct _IMAGE_DOS_HEADER {
 #define IMAGE_DOS_SIGNATURE0x5A4D /* MZ   */
 #define IMAGE_NT_SIGNATURE 0x4550 /* PE00 */
 
+#define IMAGE_FILE_MACHINE_I3860x014c
 #define IMAGE_FILE_MACHINE_ARM 0x01c0
 #define IMAGE_FILE_MACHINE_THUMB   0x01c2
 #define IMAGE_FILE_MACHINE_ARMNT   0x01c4
 #define IMAGE_FILE_MACHINE_AMD64   0x8664
 #define IMAGE_FILE_MACHINE_ARM64   0xaa64
+#define IMAGE_FILE_MACHINE_RISCV32 0x5032
+#define IMAGE_FILE_MACHINE_RISCV64 0x5064
+
 #define IMAGE_NT_OPTIONAL_HDR32_MAGIC  0x10b
 #define IMAGE_NT_OPTIONAL_HDR64_MAGIC  0x20b
 #define IMAGE_SUBSYSTEM_EFI_APPLICATION10
diff --git a/lib/efi_loader/efi_image_loader.c 
b/lib/efi_loader/efi_image_loader.c
index f588576..d5fbba3 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -22,6 +22,30 @@ const efi_guid_t efi_simple_file_system_protocol_guid =
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
 const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID;
 
+static int machines[] = {
+#if defined(CONFIG_ARM64)
+   IMAGE_FILE_MACHINE_ARM64,
+#elif defined(CONFIG_ARM)
+   IMAGE_FILE_MACHINE_ARM,
+   IMAGE_FILE_MACHINE_THUMB,
+   IMAGE_FILE_MACHINE_ARMNT,
+#endif
+
+#if defined(CONFIG_X86_64)
+   IMAGE_FILE_MACHINE_AMD64,
+#elif defined(CONFIG_X86)
+   IMAGE_FILE_MACHINE_I386,
+#endif
+
+#if defined(CONFIG_CPU_RISCV_32)
+   IMAGE_FILE_MACHINE_RISCV32,
+#endif
+
+#if defined(CONFIG_CPU_RISCV_64)
+   IMAGE_FILE_MACHINE_RISCV64,
+#endif
+   0 };
+
 /*
  * Print information about a loaded image.
  *
@@ -172,14 +196,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
void *entry;
uint64_t image_size;
unsigned long virt_size = 0;
-   bool can_run_nt64 = true;
-   bool can_run_nt32 = true;
-
-#if defined(CONFIG_ARM64)
-   can_run_nt32 = false;
-#elif defined(CONFIG_ARM)
-   can_run_nt64 = false;
-#endif
+   int supported = 0;
 
dos = efi;
if (dos->e_magic != IMAGE_DOS_SIGNATURE) {
@@ -193,6 +210,18 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
return NULL;
}
 
+   for (i = 0; machines[i]; i++)
+   if (machines[i] == nt->FileHeader.Machine) {
+   supported = 1;
+   break;
+   }
+
+   if (!supported) {
+   printf("%s: Machine type 0x%04x is not supported\n",
+  __func__, nt->FileHeader.Machine);
+   return NULL;
+   }
+
/* Calculate upper virtual address boundary */
num_sections = nt->FileHeader.NumberOfSections;
sections = (void *)>OptionalHeader +
@@ -205,8 +234,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
}
 
/* Read 32/64bit specific header bits */
-   if (can_run_nt64 &&
-   (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)) {
+   if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
IMAGE_NT_HEADERS64 *nt64 = (void *)nt;
IMAGE_OPTIONAL_HEADER64 *opt = >OptionalHeader;
image_size = opt->SizeOfImage;
@@ -222,8 +250,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
rel_size = opt->DataDirectory[rel_idx].Size;
rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
virt_size = ALIGN(virt_size, opt->SectionAlignment);
-   } else if (can_run_nt32 &&
-  (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)) 
{
+   } else if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
IMAGE_OPTIONAL_HEADER32 *opt = >OptionalHeader;
image_size = opt->SizeOfImage;
efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2] efi_loader: Check machine type in the image header

2018-04-05 Thread Ivan Gorinov
Check FileHeader.Machine to make sure the EFI executable image is built
for the same architecture. For example, 32-bit U-Boot on x86 will print
an error message instead of loading an x86_64 image and crashing.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 include/pe.h  | 24 
 lib/efi_loader/efi_image_loader.c | 24 
 2 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/include/pe.h b/include/pe.h
index c3a19ce..0dc33f0 100644
--- a/include/pe.h
+++ b/include/pe.h
@@ -38,11 +38,35 @@ typedef struct _IMAGE_DOS_HEADER {
 #define IMAGE_DOS_SIGNATURE0x5A4D /* MZ   */
 #define IMAGE_NT_SIGNATURE 0x4550 /* PE00 */
 
+#define IMAGE_FILE_MACHINE_I3860x014c
 #define IMAGE_FILE_MACHINE_ARM 0x01c0
 #define IMAGE_FILE_MACHINE_THUMB   0x01c2
 #define IMAGE_FILE_MACHINE_ARMNT   0x01c4
 #define IMAGE_FILE_MACHINE_AMD64   0x8664
 #define IMAGE_FILE_MACHINE_ARM64   0xaa64
+#define IMAGE_FILE_MACHINE_RISCV32 0x5032
+#define IMAGE_FILE_MACHINE_RISCV64 0x5064
+
+#if defined(CONFIG_ARM64)
+#define TARGET_PE_MACHINE_TYPE IMAGE_FILE_MACHINE_ARM64
+#elif defined(CONFIG_ARM)
+#define TARGET_PE_MACHINE_TYPE IMAGE_FILE_MACHINE_THUMB
+#endif
+
+#if defined(CONFIG_X86_64)
+#define TARGET_PE_MACHINE_TYPE IMAGE_FILE_MACHINE_AMD64
+#elif defined(CONFIG_X86)
+#define TARGET_PE_MACHINE_TYPE IMAGE_FILE_MACHINE_I386
+#endif
+
+#if defined(CONFIG_CPU_RISCV_32)
+#define TARGET_PE_MACHINE_TYPE IMAGE_FILE_MACHINE_RISCV32
+#endif
+
+#if defined(CONFIG_CPU_RISCV_64)
+#define TARGET_PE_MACHINE_TYPE IMAGE_FILE_MACHINE_RISCV64
+#endif
+
 #define IMAGE_NT_OPTIONAL_HDR32_MAGIC  0x10b
 #define IMAGE_NT_OPTIONAL_HDR64_MAGIC  0x20b
 #define IMAGE_SUBSYSTEM_EFI_APPLICATION10
diff --git a/lib/efi_loader/efi_image_loader.c 
b/lib/efi_loader/efi_image_loader.c
index f588576..ac20488 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -172,14 +172,6 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
void *entry;
uint64_t image_size;
unsigned long virt_size = 0;
-   bool can_run_nt64 = true;
-   bool can_run_nt32 = true;
-
-#if defined(CONFIG_ARM64)
-   can_run_nt32 = false;
-#elif defined(CONFIG_ARM)
-   can_run_nt64 = false;
-#endif
 
dos = efi;
if (dos->e_magic != IMAGE_DOS_SIGNATURE) {
@@ -193,6 +185,16 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
return NULL;
}
 
+#ifdef TARGET_PE_MACHINE_TYPE
+
+   if (nt->FileHeader.Machine != TARGET_PE_MACHINE_TYPE) {
+   printf("%s: Machine type 0x%04x is not supported\n",
+  __func__, nt->FileHeader.Machine);
+   return NULL;
+   }
+
+#endif
+
/* Calculate upper virtual address boundary */
num_sections = nt->FileHeader.NumberOfSections;
sections = (void *)>OptionalHeader +
@@ -205,8 +207,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
}
 
/* Read 32/64bit specific header bits */
-   if (can_run_nt64 &&
-   (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)) {
+   if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
IMAGE_NT_HEADERS64 *nt64 = (void *)nt;
IMAGE_OPTIONAL_HEADER64 *opt = >OptionalHeader;
image_size = opt->SizeOfImage;
@@ -222,8 +223,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
rel_size = opt->DataDirectory[rel_idx].Size;
rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
virt_size = ALIGN(virt_size, opt->SectionAlignment);
-   } else if (can_run_nt32 &&
-  (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)) 
{
+   } else if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
IMAGE_OPTIONAL_HEADER32 *opt = >OptionalHeader;
image_size = opt->SizeOfImage;
efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] x86: Use microcode update from device tree for all processors

2018-04-04 Thread Ivan Gorinov
The microcode update data block encoded in Device Tree is used by
the bootstrap processor (BSP) but not passed to the other CPUs (AP).

If the bootstrap processor successfully performs a microcode update
from Device Tree, use the same data block for the other processors.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/x86/cpu/i386/cpu.c   |  3 ++-
 arch/x86/cpu/intel_common/car.S   |  2 ++
 arch/x86/cpu/intel_common/microcode.c | 10 +++---
 arch/x86/include/asm/microcode.h  |  1 +
 arch/x86/lib/fsp/fsp_car.S|  2 ++
 5 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index aabdc94..05d8312 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -586,7 +587,7 @@ int x86_mp_init(void)
mp_params.parallel_microcode_load = 0,
mp_params.flight_plan = _steps[0];
mp_params.num_records = ARRAY_SIZE(mp_steps);
-   mp_params.microcode_pointer = 0;
+   mp_params.microcode_pointer = (void *)ucode_base;
 
if (mp_init(_params)) {
printf("Warning: MP init failure\n");
diff --git a/arch/x86/cpu/intel_common/car.S b/arch/x86/cpu/intel_common/car.S
index 6e0db96..099bf28 100644
--- a/arch/x86/cpu/intel_common/car.S
+++ b/arch/x86/cpu/intel_common/car.S
@@ -240,4 +240,6 @@ _dt_ucode_base_size:
 .globl ucode_base
 ucode_base:/* Declared in microcode.h */
.long   0   /* microcode base */
+.globl ucode_size
+ucode_size:/* Declared in microcode.h */
.long   0   /* microcode size */
diff --git a/arch/x86/cpu/intel_common/microcode.c 
b/arch/x86/cpu/intel_common/microcode.c
index 8813258..9321ae1 100644
--- a/arch/x86/cpu/intel_common/microcode.c
+++ b/arch/x86/cpu/intel_common/microcode.c
@@ -44,8 +44,6 @@ static int microcode_decode_node(const void *blob, int node,
update->data = fdt_getprop(blob, node, "data", >size);
if (!update->data)
return -ENOENT;
-   update->data += UCODE_HEADER_LEN;
-   update->size -= UCODE_HEADER_LEN;
 
update->header_version = fdtdec_get_int(blob, node,
"intel,header-version", 0);
@@ -125,6 +123,7 @@ static void microcode_read_cpu(struct microcode_update *cpu)
 int microcode_update_intel(void)
 {
struct microcode_update cpu, update;
+   ulong address;
const void *blob = gd->fdt_blob;
int skipped;
int count;
@@ -168,7 +167,8 @@ int microcode_update_intel(void)
skipped++;
continue;
}
-   wrmsr(MSR_IA32_UCODE_WRITE, (ulong)update.data, 0);
+   address = (ulong)update.data + UCODE_HEADER_LEN;
+   wrmsr(MSR_IA32_UCODE_WRITE, address, 0);
rev = microcode_read_rev();
debug("microcode: updated to revision 0x%x 
date=%04x-%02x-%02x\n",
  rev, update.date_code & 0x,
@@ -179,5 +179,9 @@ int microcode_update_intel(void)
return -EFAULT;
}
count++;
+   if (!ucode_base) {
+   ucode_base = (ulong)update.data;
+   ucode_size = update.size;
+   }
} while (1);
 }
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 29bf060..b30b8b6 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -11,6 +11,7 @@
 
 /* This is a declaration for ucode_base in start.S */
 extern u32 ucode_base;
+extern u32 ucode_size;
 
 /**
  * microcode_update_intel() - Apply microcode updates
diff --git a/arch/x86/lib/fsp/fsp_car.S b/arch/x86/lib/fsp/fsp_car.S
index fbe8aef..157600a 100644
--- a/arch/x86/lib/fsp/fsp_car.S
+++ b/arch/x86/lib/fsp/fsp_car.S
@@ -105,6 +105,8 @@ _dt_ucode_base_size:
 .globl ucode_base
 ucode_base:/* Declared in micrcode.h */
.long   0   /* microcode base */
+.globl ucode_size
+ucode_size:/* Declared in micrcode.h */
.long   0   /* microcode size */
.long   CONFIG_SYS_MONITOR_BASE /* code region base */
.long   CONFIG_SYS_MONITOR_LEN  /* code region size */
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] efi_loader: Check machine type in the image header

2018-04-04 Thread Ivan Gorinov
Check FileHeader.Machine to make sure the EFI executable image is built
for the same architecture. After this change, 32-bit U-Boot on x86 will
print an error message instead of loading an x86_64 image and crashing.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 include/pe.h  |  1 +
 lib/efi_loader/efi_image_loader.c | 13 +
 2 files changed, 14 insertions(+)

diff --git a/include/pe.h b/include/pe.h
index c3a19ce..2435069 100644
--- a/include/pe.h
+++ b/include/pe.h
@@ -38,6 +38,7 @@ typedef struct _IMAGE_DOS_HEADER {
 #define IMAGE_DOS_SIGNATURE0x5A4D /* MZ   */
 #define IMAGE_NT_SIGNATURE 0x4550 /* PE00 */
 
+#define IMAGE_FILE_MACHINE_INTEL3860x014c
 #define IMAGE_FILE_MACHINE_ARM 0x01c0
 #define IMAGE_FILE_MACHINE_THUMB   0x01c2
 #define IMAGE_FILE_MACHINE_ARMNT   0x01c4
diff --git a/lib/efi_loader/efi_image_loader.c 
b/lib/efi_loader/efi_image_loader.c
index 74c6a9f..9b4db62 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -126,15 +126,23 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
void *entry;
uint64_t image_size;
unsigned long virt_size = 0;
+   int machine_type = 0;
bool can_run_nt64 = true;
bool can_run_nt32 = true;
 
 #if defined(CONFIG_ARM64)
+   machine_type = IMAGE_FILE_MACHINE_ARM64;
can_run_nt32 = false;
 #elif defined(CONFIG_ARM)
can_run_nt64 = false;
 #endif
 
+#if defined(CONFIG_X86_64)
+   machine_type = IMAGE_FILE_MACHINE_AMD64;
+#elif defined(CONFIG_X86)
+   machine_type = IMAGE_FILE_MACHINE_INTEL386;
+#endif
+
dos = efi;
if (dos->e_magic != IMAGE_DOS_SIGNATURE) {
printf("%s: Invalid DOS Signature\n", __func__);
@@ -147,6 +155,11 @@ void *efi_load_pe(void *efi, struct efi_loaded_image 
*loaded_image_info)
return NULL;
}
 
+   if (machine_type && nt->FileHeader.Machine != machine_type) {
+   printf("%s: Incorrect machine type\n", __func__);
+   return NULL;
+   }
+
/* Calculate upper virtual address boundary */
num_sections = nt->FileHeader.NumberOfSections;
sections = (void *)>OptionalHeader +
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2] timer: add High Precision Event Timers (HPET) support

2018-04-03 Thread Ivan Gorinov
On Wed, Apr 04, 2018 at 12:15:24PM +0800, Bin Meng wrote:
> > Doesn't readX/writeX imply a single I/O operation?
> > It may be misleading to define it as two.
> >
> > Assuming MMX or SSE2 to be supported by all x86 processors, 64-bit I/O
> > registers can be accessed as a single operation even in 32-bit code:
> >
> 
> Adding such requirement (MMX or SSE2) to U-Boot is not good. Why do we
> require MMX or SSE2 for readq? Can we use general purpose registers?

In 32-bit code, we can't make a 64-bit memory read operation using only
general purpose registers.

> 
> > static inline u64 readq(void *addr)
> > {
> > u64 value;
> >
> > asm volatile ("movq (%0), %%xmm0" : : "r" (addr));
> > asm volatile ("movq %%xmm0, %0" : "=m" (value));
> >
> > return value;
> > }
> >
> > I can add these definitions to "asm/io.h".
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2] timer: add High Precision Event Timers (HPET) support

2018-04-03 Thread Ivan Gorinov
On Tue, Apr 03, 2018 at 06:17:42AM -0600, Andy Shevchenko wrote:
> >> > If readq() is defined as two read operations in 32-bit code, main counter
> >> > rollover (low part overflow, high part increment) can happen between 
> >> > them.
> >> And how this contradicts ther current code?
> > It just does not make the code simpler,
> ...b/c you misread what I suggested.
> > rollover check is
> > still required if U-Boot is compiled as 32-bit code.
> > Can we do something like the following?
> Yes, but... why?
> What's wrong with replacing two sequential 32-bit reads with one 64-bit?

Doesn't readX/writeX imply a single I/O operation?
It may be misleading to define it as two.

Assuming MMX or SSE2 to be supported by all x86 processors, 64-bit I/O
registers can be accessed as a single operation even in 32-bit code:

static inline u64 readq(void *addr)
{
u64 value;

asm volatile ("movq (%0), %%xmm0" : : "r" (addr));
asm volatile ("movq %%xmm0, %0" : "=m" (value));

return value;
}

I can add these definitions to "asm/io.h".
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2] timer: add High Precision Event Timers (HPET) support

2018-04-02 Thread Ivan Gorinov
On Sat, Mar 31, 2018 at 06:31:03AM -0600, Andy Shevchenko wrote:
> >> > +   tl = readl(regs + HPET_MAIN_COUNT_L);
> >> > +   th = readl(regs + HPET_MAIN_COUNT_H);
> >>
> >> Ditto.
> >
> > If readq() is defined as two read operations in 32-bit code, main counter
> > rollover (low part overflow, high part increment) can happen between them.
> 
> And how this contradicts ther current code?

It just does not make the code simpler, rollover check is
still required if U-Boot is compiled as 32-bit code.

Can we do something like the following?


#ifdef CONFIG_X86_64

static u64 read_main_counter(void *regs)
{
return readq(regs + HPET_MAIN_COUNT);
}

#else

/*
 * Read the main counter as two 32-bit registers,
 * repeat if rollover happens.
 */
static u64 read_main_counter(void *regs)
{
u64 now_tick;
u32 tl, th, th0;

th = readl(regs + HPET_MAIN_COUNT_H);
do {
th0 = th;
tl = readl(regs + HPET_MAIN_COUNT_L);
th = readl(regs + HPET_MAIN_COUNT_H);
now_tick = th;
now_tick <<= 32;
now_tick |= tl;
} while (th != th0);

return now_tick;
}

#endif
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3] timer: Add High Precision Event Timers (HPET) support

2018-03-30 Thread Ivan Gorinov
Add HPET driver as an alternative timer for x86 (default is TSC).
HPET counter has constant frequency and does not need calibration.
This change also makes TSC timer driver optional on x86.
New HPET driver can also be selected as the early timer on x86.

HPET can be selected as the tick timer in the Device Tree "chosen" node:

/include/ "hpet.dtsi"

...

chosen {
tick-timer = "/hpet";
};

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/Kconfig   |   2 +-
 arch/x86/Kconfig   |  21 +
 arch/x86/dts/hpet.dtsi |   7 ++
 drivers/timer/Kconfig  |   9 +++
 drivers/timer/Makefile |   1 +
 drivers/timer/hpet_timer.c | 190 +
 drivers/timer/tsc_timer.c  |   8 ++
 7 files changed, 237 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/dts/hpet.dtsi
 create mode 100644 drivers/timer/hpet_timer.c

diff --git a/arch/Kconfig b/arch/Kconfig
index e599e7a..37dabae 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -104,7 +104,7 @@ config X86
select DM_PCI
select PCI
select TIMER
-   select X86_TSC_TIMER
+   imply X86_TSC_TIMER
imply BLK
imply DM_ETH
imply DM_GPIO
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5c23b2c..bd1a644 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -119,6 +119,27 @@ source "arch/x86/cpu/tangier/Kconfig"
 
 # architecture-specific options below
 
+choice
+   prompt "Select which timer to use early on x86"
+   depends on X86
+   default X86_EARLY_TIMER_TSC
+
+config X86_EARLY_TIMER_TSC
+   bool "TSC"
+   depends on X86_TSC_TIMER
+   help
+ This selects x86 Time Stamp Counter (TSC) as the early timer.
+ See CONFIG_TIMER_EARLY for the early timer description.
+
+config X86_EARLY_TIMER_HPET
+   bool "HPET"
+   depends on HPET_TIMER
+   help
+ This selects High Precision Event Timers as the early timer.
+ Early HPET base address is specified by CONFIG_HPET_ADDRESS.
+
+endchoice
+
 config AHCI
default y
 
diff --git a/arch/x86/dts/hpet.dtsi b/arch/x86/dts/hpet.dtsi
new file mode 100644
index 000..a74f739
--- /dev/null
+++ b/arch/x86/dts/hpet.dtsi
@@ -0,0 +1,7 @@
+/ {
+   hpet: hpet@fed0 {
+   compatible = "hpet-x86";
+   u-boot,dm-pre-reloc;
+   reg = <0xfed0 0x1000>;
+   };
+};
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 2c96896..26743b7 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -65,6 +65,15 @@ config X86_TSC_TIMER
help
  Select this to enable Time-Stamp Counter (TSC) timer for x86.
 
+config HPET_TIMER
+   bool "High Precision Event Timers (HPET) support"
+   depends on TIMER
+   default y if X86
+   help
+ Select this to enable High Precision Event Timers (HPET) on x86.
+ HPET main counter increments at constant rate and does not need
+ calibration.
+
 config OMAP_TIMER
bool "Omap timer support"
depends on TIMER
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index a6e7832..557fecc 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -8,6 +8,7 @@ obj-y += timer-uclass.o
 obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)+= tsc_timer.o
+obj-$(CONFIG_HPET_TIMER)   += hpet_timer.o
 obj-$(CONFIG_OMAP_TIMER)   += omap-timer.o
 obj-$(CONFIG_AST_TIMER)+= ast_timer.o
 obj-$(CONFIG_STI_TIMER)+= sti-timer.o
diff --git a/drivers/timer/hpet_timer.c b/drivers/timer/hpet_timer.c
new file mode 100644
index 000..7287589
--- /dev/null
+++ b/drivers/timer/hpet_timer.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HPET_PERIOD_REG 0x004
+#define HPET_CONFIG_REG 0x010
+#define HPET_MAIN_COUNT_L 0x0f0
+#define HPET_MAIN_COUNT_H 0x0f4
+
+#define ENABLE_CNF 1
+
+#define HPET_MAX_PERIOD 1
+
+struct hpet_timer_priv {
+   void *regs;
+};
+
+/*
+ * Returns HPET clock frequency in HZ
+ * (rounding to the nearest integer),
+ * or 0 if HPET is not available.
+ */
+static inline u32 get_clock_frequency(void *regs)
+{
+   u64 d = 1000ull;
+   u32 period;
+
+   period = readl(regs + HPET_PERIOD_REG);
+   if (period == 0)
+   return 0;
+   if (period > HPET_MAX_PERIOD)
+   return 0;
+
+   d += period / 2;
+
+   return d / period;
+}
+
+/* Reset and start the main counter. */
+static void start_main_counter(void *regs)
+{
+   u32 config;
+
+   config = readl(regs + HPET_CONFIG_REG);
+   config &= ~ENABLE_C

[U-Boot] [PATCH v3] timer: Add High Precision Event Timers (HPET) support

2018-03-30 Thread Ivan Gorinov
Add HPET driver as an alternative timer for x86 (default is TSC).
HPET counter has constant frequency and does not need calibration.
This change also makes TSC timer driver optional on x86.
New HPET driver can also be selected as the early timer on x86.

v3:
  Added early timer choice in x86-specific configuration.

v2:
  Moved duplicated code to static functions.

Ivan Gorinov (1):
  timer: Add High Precision Event Timers (HPET) support

 arch/Kconfig   |   2 +-
 arch/x86/Kconfig   |  21 +
 arch/x86/dts/hpet.dtsi |   7 ++
 drivers/timer/Kconfig  |   9 +++
 drivers/timer/Makefile |   1 +
 drivers/timer/hpet_timer.c | 190 +
 drivers/timer/tsc_timer.c  |   8 ++
 7 files changed, 237 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/dts/hpet.dtsi
 create mode 100644 drivers/timer/hpet_timer.c

-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2] timer: add High Precision Event Timers (HPET) support

2018-03-30 Thread Ivan Gorinov
On Fri, Mar 30, 2018 at 10:46:40PM +0300, Andy Shevchenko wrote:

> > +   writel(0, regs + HPET_MAIN_COUNT_L);
> > +   writel(0, regs + HPET_MAIN_COUNT_H);
> 
> Can we use writeq() here?

I don't see readq/writeq defined for x86, even x86_64.

> > +   tl = readl(regs + HPET_MAIN_COUNT_L);
> > +   th = readl(regs + HPET_MAIN_COUNT_H);
> 
> Ditto.

If readq() is defined as two read operations in 32-bit code, main counter
rollover (low part overflow, high part increment) can happen between them.

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH] timer: Add High Precision Event Timers (HPET) support

2018-03-30 Thread Ivan Gorinov
On Fri, Mar 30, 2018 at 10:42:57PM +0300, Andy Shevchenko wrote:
> On Fri, Mar 30, 2018 at 1:39 AM, Simon Glass  wrote:
> > On 29 March 2018 at 18:52, Andy Shevchenko
> >  wrote:
> 
> >> First question is how this will work in case of Broadwell and Ivybridge
> >> that have something to do with HPET in their CPU code, i.e.
> >>
> >> arch/x86/cpu/broadwell/pch.c
> >> arch/x86/cpu/ivybridge/lpc.c
> >>
> >> ?
> >>
> >> Look for
> >>
> >> clrsetbits_le32(RCB_REG(HPTC), 3, 1 << 7);
> 
> 
> > Perhaps that code can be removed in favour of this driver? I am happy
> > to test on these platforms if it helps.
> 
> That's my point.
> 

This code performs platform-specific enabling and may be required
for the generic HPET driver and OS kernel to work.
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2] timer: add High Precision Event Timers (HPET) support

2018-03-29 Thread Ivan Gorinov
Adding HPET as an alternative timer for x86 (default is TSC).
HPET counter has constant frequency and does not need calibration.
This change also makes TSC timer driver optional on x86.
If X86_TSC is disabled, early timer functions are provided by HPET.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/Kconfig   |   2 +-
 arch/x86/dts/hpet.dtsi |   7 ++
 drivers/timer/Kconfig  |   6 ++
 drivers/timer/Makefile |   1 +
 drivers/timer/hpet_timer.c | 191 +
 5 files changed, 206 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/dts/hpet.dtsi
 create mode 100644 drivers/timer/hpet_timer.c

diff --git a/arch/Kconfig b/arch/Kconfig
index e599e7a..37dabae 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -104,7 +104,7 @@ config X86
select DM_PCI
select PCI
select TIMER
-   select X86_TSC_TIMER
+   imply X86_TSC_TIMER
imply BLK
imply DM_ETH
imply DM_GPIO
diff --git a/arch/x86/dts/hpet.dtsi b/arch/x86/dts/hpet.dtsi
new file mode 100644
index 000..037dc7e
--- /dev/null
+++ b/arch/x86/dts/hpet.dtsi
@@ -0,0 +1,7 @@
+/ {
+   hpet0: hpet@fed0 {
+   compatible = "hpet-x86";
+   u-boot,dm-pre-reloc;
+   reg = <0xfed0 0x1000>;
+   };
+};
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 2c96896..72ae6c5 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -65,6 +65,12 @@ config X86_TSC_TIMER
help
  Select this to enable Time-Stamp Counter (TSC) timer for x86.
 
+config HPET_TIMER
+   bool "High Precision Event Timers (HPET) support"
+   depends on TIMER && X86
+   help
+ Select this to enable High Precision Event Timers (HPET) for x86.
+
 config OMAP_TIMER
bool "Omap timer support"
depends on TIMER
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index a6e7832..557fecc 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -8,6 +8,7 @@ obj-y += timer-uclass.o
 obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)+= tsc_timer.o
+obj-$(CONFIG_HPET_TIMER)   += hpet_timer.o
 obj-$(CONFIG_OMAP_TIMER)   += omap-timer.o
 obj-$(CONFIG_AST_TIMER)+= ast_timer.o
 obj-$(CONFIG_STI_TIMER)+= sti-timer.o
diff --git a/drivers/timer/hpet_timer.c b/drivers/timer/hpet_timer.c
new file mode 100644
index 000..0bef859
--- /dev/null
+++ b/drivers/timer/hpet_timer.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HPET_PERIOD_REG 0x004
+#define HPET_CONFIG_REG 0x010
+#define HPET_MAIN_COUNT_L 0x0f0
+#define HPET_MAIN_COUNT_H 0x0f4
+
+#define HPET_MAX_PERIOD 1
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct hpet_timer_priv {
+   void *regs;
+};
+
+/*
+ * Returns HPET clock frequency in HZ
+ * (rounding to the nearest integer),
+ * or 0 if HPET is not available.
+ */
+static inline u32 get_clock_frequency(void *regs)
+{
+   u64 d = 1000ull;
+   u32 period;
+
+   period = readl(regs + HPET_PERIOD_REG);
+   if (period == 0)
+   return 0;
+   if (period > HPET_MAX_PERIOD)
+   return 0;
+
+   d += period / 2;
+
+   return d / period;
+}
+
+/*
+ * Reset and start the main counter.
+ */
+static void start_main_counter(void *regs)
+{
+   u32 config;
+
+   config = readl(regs + HPET_CONFIG_REG);
+   config &= ~1;
+   writel(config, regs + HPET_CONFIG_REG);
+   writel(0, regs + HPET_MAIN_COUNT_L);
+   writel(0, regs + HPET_MAIN_COUNT_H);
+   config |= 1;
+   writel(config, regs + HPET_CONFIG_REG);
+}
+
+/*
+ * Read the main counter as two 32-bit registers,
+ * repeat if rollover happens.
+ */
+static u64 read_main_counter(void *regs)
+{
+   u64 now_tick;
+   u32 tl, th, th0;
+
+   th = readl(regs + HPET_MAIN_COUNT_H);
+   do {
+   th0 = th;
+   tl = readl(regs + HPET_MAIN_COUNT_L);
+   th = readl(regs + HPET_MAIN_COUNT_H);
+   } while (th != th0);
+
+   now_tick = th;
+   now_tick <<= 32;
+   now_tick |= tl;
+
+   return now_tick;
+}
+
+static int hpet_timer_get_count(struct udevice *dev, u64 *count)
+{
+   struct hpet_timer_priv *priv = dev_get_priv(dev);
+
+   *count = read_main_counter(priv->regs);
+
+   return 0;
+}
+
+static int hpet_timer_probe(struct udevice *dev)
+{
+   struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+   struct hpet_timer_priv *priv = dev_get_priv(dev);
+   u32 rate;
+
+   rate = get_clock_frequency(priv->regs);
+   if (rate == 0)
+   return -ENODEV;
+
+   start_main_counter(

Re: [U-Boot] [PATCH] timer: Add High Precision Event Timers (HPET) support

2018-03-29 Thread Ivan Gorinov
On Thu, Mar 29, 2018 at 01:52:10PM +0300, Andy Shevchenko wrote:
> On Wed, 2018-03-28 at 17:58 -0700, Ivan Gorinov wrote:
> > Adding HPET as an alternative timer for x86 (default is TSC).
> > HPET main counter has constant clock frequency, calibration is not
> > required.
> > This change also makes TSC timer driver optional on x86 platforms.
> > If X86_TSC is disabled, early timer functions are provided by HPET.
> > 
> > HPET can be selected as the tick timer in the Device Tree "chosen"
> > node:
> > 
> >   /include/ "hpet.dtsi"
> > 
> >   chosen {
> > tick-timer = "/hpet0";
> >   };
> 
> First question is how this will work in case of Broadwell and Ivybridge
> that have something to do with HPET in their CPU code, i.e.
> 
> arch/x86/cpu/broadwell/pch.c
> arch/x86/cpu/ivybridge/lpc.c

The platform-specific code maps HPET registers to make sure they are
available to the timer driver added by this patch.

Apparently, HPET is also used by the DRAM initialization code (MRC)
on Ivy Bridge, before the U-Boot timer driver starts.

> Look for
> 
> clrsetbits_le32(RCB_REG(HPTC), 3, 1 << 7);
> 
> > +static int hpet_timer_get_count(struct udevice *dev, u64 *count)
> 
> > +static int hpet_timer_probe(struct udevice *dev)
> 
> > +#ifndef CONFIG_X86_TSC_TIMER
> 
> > +#define EARLY_HPET_BASE 0xfed0
> 
> HPET address is fixed, AFAIU, on x86, and provided by config option in
> U-Boot.

Found it. Thank you!

> > +unsigned long notrace timer_early_get_rate(void)
> > +u64 notrace timer_early_get_count(void)
> > +int timer_init(void)
> These functions have too much code duplication with above.

I will move the duplicated code into static functions.
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] timer: Add High Precision Event Timers (HPET) support

2018-03-28 Thread Ivan Gorinov
Adding HPET as an alternative timer for x86 (default is TSC).
HPET main counter has constant clock frequency, calibration is not required.
This change also makes TSC timer driver optional on x86 platforms.
If X86_TSC is disabled, early timer functions are provided by HPET.

HPET can be selected as the tick timer in the Device Tree "chosen" node:

  /include/ "hpet.dtsi"

  chosen {
tick-timer = "/hpet0";
  };

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/Kconfig   |   2 +-
 arch/x86/dts/hpet.dtsi |   7 ++
 drivers/timer/Kconfig  |   6 ++
 drivers/timer/Makefile |   1 +
 drivers/timer/hpet_timer.c | 197 +
 5 files changed, 212 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/dts/hpet.dtsi
 create mode 100644 drivers/timer/hpet_timer.c

diff --git a/arch/Kconfig b/arch/Kconfig
index e599e7a..37dabae 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -104,7 +104,7 @@ config X86
select DM_PCI
select PCI
select TIMER
-   select X86_TSC_TIMER
+   imply X86_TSC_TIMER
imply BLK
imply DM_ETH
imply DM_GPIO
diff --git a/arch/x86/dts/hpet.dtsi b/arch/x86/dts/hpet.dtsi
new file mode 100644
index 000..037dc7e
--- /dev/null
+++ b/arch/x86/dts/hpet.dtsi
@@ -0,0 +1,7 @@
+/ {
+   hpet0: hpet@fed0 {
+   compatible = "hpet-x86";
+   u-boot,dm-pre-reloc;
+   reg = <0xfed0 0x1000>;
+   };
+};
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 2c96896..72ae6c5 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -65,6 +65,12 @@ config X86_TSC_TIMER
help
  Select this to enable Time-Stamp Counter (TSC) timer for x86.
 
+config HPET_TIMER
+   bool "High Precision Event Timers (HPET) support"
+   depends on TIMER && X86
+   help
+ Select this to enable High Precision Event Timers (HPET) for x86.
+
 config OMAP_TIMER
bool "Omap timer support"
depends on TIMER
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index a6e7832..557fecc 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -8,6 +8,7 @@ obj-y += timer-uclass.o
 obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)+= tsc_timer.o
+obj-$(CONFIG_HPET_TIMER)   += hpet_timer.o
 obj-$(CONFIG_OMAP_TIMER)   += omap-timer.o
 obj-$(CONFIG_AST_TIMER)+= ast_timer.o
 obj-$(CONFIG_STI_TIMER)+= sti-timer.o
diff --git a/drivers/timer/hpet_timer.c b/drivers/timer/hpet_timer.c
new file mode 100644
index 000..66462a6
--- /dev/null
+++ b/drivers/timer/hpet_timer.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define HPET_PERIOD_REG 0x004
+#define HPET_CONFIG_REG 0x010
+#define HPET_MAIN_COUNT_L 0x0f0
+#define HPET_MAIN_COUNT_H 0x0f4
+
+#define HPET_MAX_PERIOD 1
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct hpet_timer_priv {
+   void *regs;
+};
+
+static inline u32 freq_hz(u32 period)
+{
+   u64 d = 1000ull;
+
+   d += period / 2;
+
+   return d / period;
+}
+
+static int hpet_timer_get_count(struct udevice *dev, u64 *count)
+{
+   struct hpet_timer_priv *priv = dev_get_priv(dev);
+   u64 now_tick;
+   u32 tl, th, th0;
+
+   th = readl(priv->regs + HPET_MAIN_COUNT_H);
+   do {
+   th0 = th;
+   tl = readl(priv->regs + HPET_MAIN_COUNT_L);
+   th = readl(priv->regs + HPET_MAIN_COUNT_H);
+   } while (th != th0);
+
+   now_tick = th;
+   now_tick <<= 32;
+   now_tick |= tl;
+
+   *count = now_tick;
+
+   return 0;
+}
+
+static int hpet_timer_probe(struct udevice *dev)
+{
+   struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+   struct hpet_timer_priv *priv = dev_get_priv(dev);
+   u32 period, config;
+
+   period = readl(priv->regs + HPET_PERIOD_REG);
+   if (period == 0)
+   return -ENODEV;
+   if (period > HPET_MAX_PERIOD)
+   return -ENODEV;
+
+   config = readl(priv->regs + HPET_CONFIG_REG);
+   config &= ~1;
+   writel(config, priv->regs + HPET_CONFIG_REG);
+   writel(0, priv->regs + HPET_MAIN_COUNT_L);
+   writel(0, priv->regs + HPET_MAIN_COUNT_H);
+   config |= 1;
+   writel(config, priv->regs + HPET_CONFIG_REG);
+
+   uc_priv->clock_rate = freq_hz(period);
+
+   return 0;
+}
+
+#ifndef CONFIG_X86_TSC_TIMER
+
+#define EARLY_HPET_BASE 0xfed0
+
+unsigned long notrace timer_early_get_rate(void)
+{
+   void *regs = (void *) EARLY_HPET_BASE;
+   u32 period, config;
+
+   period = r

[U-Boot] [PATCH v3] x86: zImage: Pass working device tree data to the kernel

2018-03-26 Thread Ivan Gorinov
On x86 platforms, U-Boot does not pass Device Tree data to the kernel.
This prevents the kernel from using FDT loaded by U-Boot.

Read the working FDT address from the "fdtaddr" environment variable
and add a copy of the FDT data to the kernel setup_data list.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/x86/include/asm/bootparam.h |  7 +--
 arch/x86/lib/zimage.c| 34 ++
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index 90768a9..6aba614 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -10,8 +10,11 @@
 #include 
 
 /* setup data types */
-#define SETUP_NONE 0
-#define SETUP_E820_EXT 1
+enum {
+   SETUP_NONE = 0,
+   SETUP_E820_EXT,
+   SETUP_DTB,
+};
 
 /* extensible setup data list node */
 struct setup_data {
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 2a82bc8..1ff77e9 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -14,6 +14,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -95,6 +96,38 @@ static int get_boot_protocol(struct setup_header *hdr)
}
 }
 
+static int setup_device_tree(struct setup_header *hdr, const void *fdt_blob)
+{
+   int bootproto = get_boot_protocol(hdr);
+   struct setup_data *sd;
+   int size;
+
+   if (bootproto < 0x0209)
+   return -ENOTSUPP;
+
+   if (!fdt_blob)
+   return 0;
+
+   size = fdt_totalsize(fdt_blob);
+   if (size < 0)
+   return -EINVAL;
+
+   size += sizeof(struct setup_data);
+   sd = (struct setup_data *)malloc(size);
+   if (!sd) {
+   printf("Not enough memory for DTB setup data\n");
+   return -ENOMEM;
+   }
+
+   sd->next = hdr->setup_data;
+   sd->type = SETUP_DTB;
+   sd->len = fdt_totalsize(fdt_blob);
+   memcpy(sd->data, fdt_blob, sd->len);
+   hdr->setup_data = (unsigned long)sd;
+
+   return 0;
+}
+
 struct boot_params *load_zimage(char *image, unsigned long kernel_size,
ulong *load_addressp)
 {
@@ -261,6 +294,7 @@ int setup_zimage(struct boot_params *setup_base, char 
*cmd_line, int auto_boot,
hdr->acpi_rsdp_addr = acpi_get_rsdp_addr();
 #endif
 
+   setup_device_tree(hdr, (const void *)env_get_hex("fdtaddr", 0));
setup_video(_base->screen_info);
 
return 0;
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3] x86: zImage: pass device tree setup data to the kernel

2018-03-16 Thread Ivan Gorinov
On x86 platforms, U-Boot does not provide Device Tree data to the kernel.
This prevents the kernel from using the same hardware description.

Make a copy of DTB data with setup_data header and insert new item
into the the setup data linked list.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/x86/include/asm/bootparam.h |  7 +--
 arch/x86/lib/zimage.c| 31 +++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index 90768a9..6aba614 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -10,8 +10,11 @@
 #include 
 
 /* setup data types */
-#define SETUP_NONE 0
-#define SETUP_E820_EXT 1
+enum {
+   SETUP_NONE = 0,
+   SETUP_E820_EXT,
+   SETUP_DTB,
+};
 
 /* extensible setup data list node */
 struct setup_data {
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 2a82bc8..7e7ec5e 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -14,6 +14,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -95,6 +96,35 @@ static int get_boot_protocol(struct setup_header *hdr)
}
 }
 
+static int setup_device_tree(struct setup_header *hdr)
+{
+   const void *fdt_blob = gd->fdt_blob;
+   struct setup_data *sd;
+   int size;
+
+   if (!fdt_blob)
+   return 0;
+
+   size = fdt_totalsize(fdt_blob);
+   if (size < 0)
+   return -EINVAL;
+
+   size += sizeof(struct setup_data);
+   sd = (struct setup_data *)malloc(size);
+   if (!sd) {
+   printf("Not enough memory for DTB setup data\n");
+   return -ENOMEM;
+   }
+
+   sd->next = hdr->setup_data;
+   sd->type = SETUP_DTB;
+   sd->len = fdt_totalsize(fdt_blob);
+   memcpy(sd->data, fdt_blob, sd->len);
+   hdr->setup_data = (unsigned long)sd;
+
+   return 0;
+}
+
 struct boot_params *load_zimage(char *image, unsigned long kernel_size,
ulong *load_addressp)
 {
@@ -262,6 +292,7 @@ int setup_zimage(struct boot_params *setup_base, char 
*cmd_line, int auto_boot,
 #endif
 
setup_video(_base->screen_info);
+   setup_device_tree(hdr);
 
return 0;
 }
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2] x86: zImage: pass device tree setup data to the kernel

2018-03-16 Thread Ivan Gorinov
On Fri, 2018-03-16 at 19:52 +0200, Andy Shevchenko wrote:
> On x86 platforms, U-Boot does not provide Device Tree data to the
> > kernel.
> > This prevents the kernel from using the same hardware description.
> > 
> > Make a copy of DTB data with setup_data header and insert new item
> > into the the setup data linked list.
> So, now is the question, what to do with x86 hardware that has DTS in U-
> Boot, but uses ACPI tables, generated by U-Boot.
> 
> Would it work properly?

It will work because CONFIG_OF is disabled in most x86 kernel configurations.

> I would try to test it on Intel Edison (I hope you may do this yourself
> as well), though I don't know when, have not much time to work with
> Edison right now.

I am going to try that on a Minnowboard.

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2] x86: zImage: pass device tree setup data to the kernel

2018-03-16 Thread Ivan Gorinov
On x86 platforms, U-Boot does not provide Device Tree data to the kernel.
This prevents the kernel from using the same hardware description.

Make a copy of DTB data with setup_data header and insert new item
into the the setup data linked list.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/x86/include/asm/bootparam.h |  1 +
 arch/x86/lib/zimage.c| 32 
 2 files changed, 33 insertions(+)

diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index 90768a9..ea25cf7 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -12,6 +12,7 @@
 /* setup data types */
 #define SETUP_NONE 0
 #define SETUP_E820_EXT 1
+#define SETUP_DTB  2
 
 /* extensible setup data list node */
 struct setup_data {
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 2a82bc8..41ad4c7 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -14,6 +14,8 @@
  */
 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -95,6 +97,35 @@ static int get_boot_protocol(struct setup_header *hdr)
}
 }
 
+static int setup_device_tree(struct setup_header *hdr)
+{
+   const void *fdt_blob = gd->fdt_blob;
+   struct setup_data *sd;
+   int size;
+
+   if (!fdt_blob)
+   return 0;
+
+   size = fdt_totalsize(fdt_blob);
+   if (size < 0)
+   return -EINVAL;
+
+   size += sizeof(struct setup_data);
+   sd = (struct setup_data *)malloc(size);
+   if (!sd) {
+   printf("Not enough memory for DTB setup data\n");
+   return -ENOMEM;
+   }
+
+   sd->next = hdr->setup_data;
+   sd->type = SETUP_DTB;
+   sd->len = fdt_totalsize(fdt_blob);
+   memcpy(sd->data, fdt_blob, sd->len);
+   hdr->setup_data = (unsigned long)sd;
+
+   return 0;
+}
+
 struct boot_params *load_zimage(char *image, unsigned long kernel_size,
ulong *load_addressp)
 {
@@ -262,6 +293,7 @@ int setup_zimage(struct boot_params *setup_base, char 
*cmd_line, int auto_boot,
 #endif
 
setup_video(_base->screen_info);
+   setup_device_tree(hdr);
 
return 0;
 }
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] x86: zImage: pass device tree setup data to the kernel

2018-03-15 Thread Ivan Gorinov
Make a copy of DTB data with setup_data header and insert new item
into the the setup data linked list.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 arch/x86/include/asm/bootparam.h |  1 +
 arch/x86/lib/zimage.c| 32 
 2 files changed, 33 insertions(+)

diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index 90768a9..ea25cf7 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -12,6 +12,7 @@
 /* setup data types */
 #define SETUP_NONE 0
 #define SETUP_E820_EXT 1
+#define SETUP_DTB  2
 
 /* extensible setup data list node */
 struct setup_data {
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 2a82bc8..41ad4c7 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -14,6 +14,8 @@
  */
 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -95,6 +97,35 @@ static int get_boot_protocol(struct setup_header *hdr)
}
 }
 
+static int setup_device_tree(struct setup_header *hdr)
+{
+   const void *fdt_blob = gd->fdt_blob;
+   struct setup_data *sd;
+   int size;
+
+   if (!fdt_blob)
+   return 0;
+
+   size = fdt_totalsize(fdt_blob);
+   if (size < 0)
+   return -EINVAL;
+
+   size += sizeof(struct setup_data);
+   sd = (struct setup_data *)malloc(size);
+   if (!sd) {
+   printf("Not enough memory for DTB setup data\n");
+   return -ENOMEM;
+   }
+
+   sd->next = hdr->setup_data;
+   sd->type = SETUP_DTB;
+   sd->len = fdt_totalsize(fdt_blob);
+   memcpy(sd->data, fdt_blob, sd->len);
+   hdr->setup_data = (unsigned long)sd;
+
+   return 0;
+}
+
 struct boot_params *load_zimage(char *image, unsigned long kernel_size,
ulong *load_addressp)
 {
@@ -262,6 +293,7 @@ int setup_zimage(struct boot_params *setup_base, char 
*cmd_line, int auto_boot,
 #endif
 
setup_video(_base->screen_info);
+   setup_device_tree(hdr);
 
return 0;
 }
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 1/1] efi_loader: correctly support parameter delta in Blt

2018-03-15 Thread Ivan Gorinov
On Thu, 2018-03-15 at 11:19 +0100, Alexander Graf wrote:
> In the Blt service of the EFI_GRAPHICS_OUTPUT_PROTOCOL the parameter delta
> > is measured in bytes and not in pixels.
> > 
> > The coding only supports delta being a multiple of four. The UEFI
> > specification does not explicitly require this but as pixels have a size of
> > four bytes we should be able to assume four byte alignment.
> > 
> > The corresponding unit test is corrected, too. It can be launched with
> > 
> > setenv efi_selftest block image transfer
> > bootefi selftest
> > 
> > Signed-off-by: Heinrich Schuchardt 
> I can verify that this makes grub GOP work again :)

Kernelflinger works too.

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] efi_loader: Allow width smaller than buffer stride in efi_gop Blt()

2018-03-14 Thread Ivan Gorinov
On Wed, 2018-03-14 at 18:21 +0100, Heinrich Schuchardt wrote:

@@ -87,7 +93,7 @@ efi_status_t EFIAPI gop_blt(struct efi_gop *this, void
> > *buffer,
> >     for (i = 0; i < height; i++) {
> >     u32 *dest = fb + ((i + dy)  * line_len32) +
> >      (dx * sizeof(u32));
> > -   u32 *src = buffer + ((i + sy)  * line_len32) +
> > +   u32 *src = buffer + ((i + sy) * buffer_stride) +
> >      (sx * sizeof(u32));
> >  
> >     /* Same color format, just memcpy */
> > @@ -102,7 +108,7 @@ efi_status_t EFIAPI gop_blt(struct efi_gop *this, void
> > *buffer,
> >     for (i = 0; i < height; i++) {
> >     u16 *dest = fb + ((i + dy)  * line_len16) +
> >      (dx * sizeof(u16));
> > -   u32 *src = buffer + ((i + sy)  * line_len32) +
> > +   u32 *src = buffer + ((i + sy) * buffer_stride) +
> If delta cannot be divided by 4 a misaligned access error will occur on
> arm64.

This is unlikely because EFI spec allows only 32-bit pixel data in BLT buffer,
regardless of actual video frame buffer pixel format.

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] efi_loader: Allow width smaller than buffer stride in efi_gop Blt()

2018-03-13 Thread Ivan Gorinov
Current implementation of Blt() in EFI_GRAPHICS_OUTPUT_PROTOCOL
assumes the memory buffer stride (number of bytes in a row)
always matches the rectangle Width, ignoring non-zero Delta.

Signed-off-by: Ivan Gorinov <ivan.gori...@intel.com>
---
 lib/efi_loader/efi_gop.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/lib/efi_loader/efi_gop.c b/lib/efi_loader/efi_gop.c
index 3caddd5..362065b 100644
--- a/lib/efi_loader/efi_gop.c
+++ b/lib/efi_loader/efi_gop.c
@@ -64,6 +64,7 @@ efi_status_t EFIAPI gop_blt(struct efi_gop *this, void 
*buffer,
 {
struct efi_gop_obj *gopobj = container_of(this, struct efi_gop_obj, 
ops);
int i, j, line_len16, line_len32;
+   int buffer_stride;
void *fb;
 
EFI_ENTRY("%p, %p, %u, %zu, %zu, %zu, %zu, %zu, %zu, %zu", this,
@@ -72,6 +73,11 @@ efi_status_t EFIAPI gop_blt(struct efi_gop *this, void 
*buffer,
if (operation != EFI_BLT_BUFFER_TO_VIDEO)
return EFI_EXIT(EFI_INVALID_PARAMETER);
 
+   if (delta == 0)
+   buffer_stride = width * sizeof(u32);
+   else
+   buffer_stride = delta;
+
fb = gopobj->fb;
line_len16 = gopobj->info.width * sizeof(u16);
line_len32 = gopobj->info.width * sizeof(u32);
@@ -87,7 +93,7 @@ efi_status_t EFIAPI gop_blt(struct efi_gop *this, void 
*buffer,
for (i = 0; i < height; i++) {
u32 *dest = fb + ((i + dy)  * line_len32) +
 (dx * sizeof(u32));
-   u32 *src = buffer + ((i + sy)  * line_len32) +
+   u32 *src = buffer + ((i + sy) * buffer_stride) +
 (sx * sizeof(u32));
 
/* Same color format, just memcpy */
@@ -102,7 +108,7 @@ efi_status_t EFIAPI gop_blt(struct efi_gop *this, void 
*buffer,
for (i = 0; i < height; i++) {
u16 *dest = fb + ((i + dy)  * line_len16) +
 (dx * sizeof(u16));
-   u32 *src = buffer + ((i + sy)  * line_len32) +
+   u32 *src = buffer + ((i + sy) * buffer_stride) +
 (sx * sizeof(u32));
 
/* Convert from rgb888 to rgb565 */
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot