summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/northbridge/intel/haswell/me_uma.asm153
-rw-r--r--src/northbridge/intel/haswell/me_uma.c94
2 files changed, 87 insertions, 160 deletions
diff --git a/src/northbridge/intel/haswell/me_uma.asm b/src/northbridge/intel/haswell/me_uma.asm
index dbdc05ab96..550c31f939 100644
--- a/src/northbridge/intel/haswell/me_uma.asm
+++ b/src/northbridge/intel/haswell/me_uma.asm
@@ -1,160 +1,11 @@
global PchMeUmaDesc
global gPchMeUmaPpiGuid
-extern gEfiPeiStallPpiGuid
-extern mrc_sku_type
-extern gWdtPpiGuid
extern get_uma_size
extern fcn_fffbe070
extern fcn_fffbe14d
-
-global fcn_fffbe110
-global fcn_fffbdf70
-
-fcn_fffbdf70: ; not directly referenced
-push ebp
-mov ebp, esp
-push esi
-push ebx
-mov ebx, eax
-lea esp, [esp - 0x20]
-mov byte [ebp - 0x1c], dl
-mov dword [ebp - 0xc], 0
-call mrc_sku_type
-sub esp, 0xc
-lea edx, [ebp - 0xc]
-mov esi, eax
-mov eax, dword [ebx]
-push edx
-push 0
-push 0
-push gWdtPpiGuid
-push ebx
-call dword [eax + 0x20] ; ucall
-mov eax, dword [0xf00f80ac]
-and eax, 0xffebffff
-mov dword [0xf00f80ac], eax
-mov edx, 0xcf9
-in al, dx
-mov bl, al
-mov cl, byte [ebp - 0x1c]
-and ebx, 0xfffffff1
-add esp, 0x20
-cmp cl, 6
-jne short loc_fffbdfd2 ; jne 0xfffbdfd2
-mov ecx, dword [0xf00f8048]
-and ecx, 0xfffffffe
-jmp short loc_fffbdffc ; jmp 0xfffbdffc
-
-loc_fffbdfd2: ; not directly referenced
-cmp cl, 2
-je short loc_fffbdfe8 ; je 0xfffbdfe8
-cmp cl, 6
-je short loc_fffbdffa ; je 0xfffbdffa
-mov al, bl
-or eax, 6
-dec cl
-cmove ebx, eax
-jmp short loc_fffbe059 ; jmp 0xfffbe059
-
-loc_fffbdfe8: ; not directly referenced
-sub esp, 0xc
-mov eax, dword [ebp - 0xc]
-push 2
-or ebx, 0xe
-call dword [eax] ; ucall
-add esp, 0x10
-jmp short loc_fffbe059 ; jmp 0xfffbe059
-
-loc_fffbdffa: ; not directly referenced
-xor ecx, ecx
-
-loc_fffbdffc: ; not directly referenced
-cmp esi, 1
-jne short loc_fffbe021 ; jne 0xfffbe021
-mov edx, ecx
-in eax, dx
-or eax, 0x40000000
-out dx, eax
-mov esi, ecx
-lea edx, [esi + 4]
-in eax, dx
-and eax, 0xbfffffff
-out dx, eax
-lea edx, [esi + 0xc]
-in eax, dx
-and eax, 0xbfffffff
-jmp short loc_fffbe03c ; jmp 0xfffbe03c
-
-loc_fffbe021: ; not directly referenced
-cmp esi, 2
-jne short loc_fffbe03d ; jne 0xfffbe03d
-lea edx, [ecx + 0x1f0]
-in eax, dx
-or eax, 1
-out dx, eax
-in eax, dx
-and eax, 0xfffffffb
-out dx, eax
-in eax, dx
-and eax, 0x7fffffff
-
-loc_fffbe03c: ; not directly referenced
-out dx, eax
-
-loc_fffbe03d: ; not directly referenced
-lea edx, [ecx + 0x60]
-in eax, dx
-or eax, 0x40000000
-out dx, eax
-mov eax, dword [0xf00f80ac]
-or eax, 0x100000
-mov dword [0xf00f80ac], eax
-or ebx, 0xe
-
-loc_fffbe059: ; not directly referenced
-mov eax, dword [ebp - 0xc]
-call dword [eax + 0xc] ; ucall
-mov edx, 0xcf9
-mov al, bl
-out dx, al
-lea esp, [ebp - 8]
-xor eax, eax
-pop ebx
-pop esi
-pop ebp
-ret
-
-fcn_fffbe110: ; not directly referenced
-push ebp
-mov ebp, esp
-lea esp, [esp - 8]
-mov ecx, dword [0xf00b0048]
-mov dl, byte [ebp + 0x10]
-mov eax, dword [ebp + 8]
-cmp dl, 2
-je short loc_fffbe138 ; je 0xfffbe138
-cmp dl, 6
-je short loc_fffbe13f ; je 0xfffbe13f
-dec dl
-jne short loc_fffbe149 ; jne 0xfffbe149
-mov edx, 1
-jmp short loc_fffbe144 ; jmp 0xfffbe144
-
-loc_fffbe138: ; not directly referenced
-mov edx, 2
-jmp short loc_fffbe144 ; jmp 0xfffbe144
-
-loc_fffbe13f: ; not directly referenced
-mov edx, 6
-
-loc_fffbe144: ; not directly referenced
-call fcn_fffbdf70 ; call 0xfffbdf70
-
-loc_fffbe149: ; not directly referenced
-xor eax, eax
-leave
-ret
+extern fcn_fffbe110
+extern fcn_fffbdf70
PchMeUmaDesc:
dd 0x80000010
diff --git a/src/northbridge/intel/haswell/me_uma.c b/src/northbridge/intel/haswell/me_uma.c
index 0528e5d4be..19cf744404 100644
--- a/src/northbridge/intel/haswell/me_uma.c
+++ b/src/northbridge/intel/haswell/me_uma.c
@@ -3,8 +3,16 @@
#include "mrc_pei.h"
#include "mrc_utils.h"
#include <console/console.h>
+#include "mrc_sku.h"
+#include "mrc_wdt.h"
u32 get_uma_size(EFI_PEI_SERVICES **pps, void *me);
+int fcn_fffbe070(const EFI_PEI_SERVICES **pps, void *me, u8 *a2);
+int fcn_fffbe110(const EFI_PEI_SERVICES **pps, u32, u8);
+int fcn_fffbe14d(const EFI_PEI_SERVICES **pps, void *me, int a3, u32 a4);
+int __attribute((regparm(2)))
+fcn_fffbdf70(const EFI_PEI_SERVICES **pps, int v);
+
u32 get_uma_size(EFI_PEI_SERVICES **pps, void *me)
{
int i = 0;
@@ -39,11 +47,7 @@ u32 get_uma_size(EFI_PEI_SERVICES **pps, void *me)
}
}
-int __attribute((regparm(2)))
-fcn_fffbdf70(EFI_PEI_SERVICES **pps, int v);
-
-int fcn_fffbe070(EFI_PEI_SERVICES **pps, void *me, u8 *a2);
-int fcn_fffbe070(EFI_PEI_SERVICES **pps, void *me, u8 *a2)
+int fcn_fffbe070(const EFI_PEI_SERVICES **pps, void *me, u8 *a2)
{
int i = 0;
int ret = 0;
@@ -72,10 +76,7 @@ int fcn_fffbe070(EFI_PEI_SERVICES **pps, void *me, u8 *a2)
return ret;
}
-int fcn_fffbe110(EFI_PEI_SERVICES **pps, u32, u32);
-
-int fcn_fffbe14d(EFI_PEI_SERVICES **pps, void *me, int a3, u32 a4);
-int fcn_fffbe14d(EFI_PEI_SERVICES **pps, void *me, int a3, u32 a4)
+int fcn_fffbe14d(const EFI_PEI_SERVICES **pps, void *me, int a3, u32 a4)
{
u32 hfs = pci_read_config32(PCH_ME_DEV, 0x40);
@@ -109,3 +110,78 @@ int fcn_fffbe14d(EFI_PEI_SERVICES **pps, void *me, int a3, u32 a4)
}
return fcn_fffbe110(pps, a3, ((hfs >> 25) & 7));
}
+
+int fcn_fffbe110(const EFI_PEI_SERVICES **pps, u32 me, u8 a3)
+{
+ pci_read_config32(PCH_ME_DEV, 0x48);
+ int v;
+
+ if (a3 == 2) {
+ v = 2;
+ } else if (a3 == 6) {
+ v = 6;
+ } else if (a3 == 1) {
+ v = 1;
+ } else {
+ return 0;
+ }
+ fcn_fffbdf70(pps, v);
+ return 0;
+}
+
+extern EFI_GUID gWdtPpiGuid;
+int __attribute((regparm(2))) fcn_fffbdf70(const EFI_PEI_SERVICES **pps, int v)
+{
+ PEI_WDT_PPI *wdt = NULL;
+ (*pps)->LocatePpi(pps, &gWdtPpiGuid, 0, NULL, (void**)&wdt);
+ int sku = mrc_sku_type();
+ pci_update_config32(PCH_LPC_DEV, 0xac, 0xffebffff, 0);
+ u8 io_cf9 = inb(0xcf9) & 0xf1;
+
+ if (v == 6) {
+ u32 gpiobase = pci_read_config32(PCH_LPC_DEV, 0x48) & 0xfffffffe;
+ /* GPIO Pin 30 used as GPIO, as output, level low */
+ u32 tmp;
+ if (sku == 1) {
+ tmp = inl(gpiobase);
+ tmp |= 0x40000000;
+ outl(tmp, gpiobase);
+
+ tmp = inl(gpiobase + 4);
+ tmp &= 0xbfffffff;
+ outl(tmp, gpiobase + 4);
+
+ tmp = inl(gpiobase + 0xc);
+ tmp &= 0xbfffffff;
+ outl(tmp, gpiobase + 0xc);
+ } else if (sku == 2) {
+ u32 gpio30 = gpiobase + 0x1f0;
+
+ tmp = inl(gpio30);
+ tmp |= 1;
+ outl(tmp, gpio30);
+
+ tmp = inl(gpio30);
+ tmp &= 0xfffffffb;
+ outl(tmp, gpio30);
+
+ tmp = inl(gpio30);
+ tmp &= 0x7fffffff;
+ outl(tmp, gpio30);
+ }
+ tmp = inl(gpiobase + 0x60);
+ tmp |= 0x40000000; /* GPIO30 will be reset by RSMRST# assertion only */
+ outl(tmp, gpiobase + 0x60);
+
+ pci_or_config32(PCH_LPC_DEV, 0xac, 0x100000);
+ io_cf9 |= 0xe;
+ } else if (v == 2) {
+ wdt->wdt_f0(2);
+ io_cf9 |= 0xe;
+ } else if (v == 1) {
+ io_cf9 |= 6;
+ }
+ wdt->wdt_f3();
+ outb(io_cf9, 0xcf9);
+ return 0;
+}