diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/cpu/ivybridge/early_me.c | 68 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/sdram.c | 20 | ||||
-rw-r--r-- | arch/x86/dts/chromebook_link.dts | 6 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-ivybridge/me.h | 45 |
4 files changed, 101 insertions, 38 deletions
diff --git a/arch/x86/cpu/ivybridge/early_me.c b/arch/x86/cpu/ivybridge/early_me.c index 711470f364..612c9103e3 100644 --- a/arch/x86/cpu/ivybridge/early_me.c +++ b/arch/x86/cpu/ivybridge/early_me.c @@ -7,6 +7,7 @@ */ #include <common.h> +#include <dm.h> #include <errno.h> #include <asm/pci.h> #include <asm/processor.h> @@ -25,33 +26,36 @@ static const char *const me_ack_values[] = { [ME_HFS_ACK_CONTINUE] = "Continue to boot" }; -static inline void pci_read_dword_ptr(void *ptr, int offset) +static inline void pci_read_dword_ptr(struct udevice *me_dev, void *ptr, + int offset) { u32 dword; - dword = x86_pci_read_config32(PCH_ME_DEV, offset); + dm_pci_read_config32(me_dev, offset, &dword); memcpy(ptr, &dword, sizeof(dword)); } -static inline void pci_write_dword_ptr(void *ptr, int offset) +static inline void pci_write_dword_ptr(struct udevice *me_dev, void *ptr, + int offset) { u32 dword = 0; + memcpy(&dword, ptr, sizeof(dword)); - x86_pci_write_config32(PCH_ME_DEV, offset, dword); + dm_pci_write_config32(me_dev, offset, dword); } -void intel_early_me_status(void) +void intel_early_me_status(struct udevice *me_dev) { struct me_hfs hfs; struct me_gmes gmes; - pci_read_dword_ptr(&hfs, PCI_ME_HFS); - pci_read_dword_ptr(&gmes, PCI_ME_GMES); + pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS); + pci_read_dword_ptr(me_dev, &gmes, PCI_ME_GMES); intel_me_status(&hfs, &gmes); } -int intel_early_me_init(void) +int intel_early_me_init(struct udevice *me_dev) { int count; struct me_uma uma; @@ -61,7 +65,7 @@ int intel_early_me_init(void) /* Wait for ME UMA SIZE VALID bit to be set */ for (count = ME_RETRY; count > 0; --count) { - pci_read_dword_ptr(&uma, PCI_ME_UMA); + pci_read_dword_ptr(me_dev, &uma, PCI_ME_UMA); if (uma.valid) break; udelay(ME_DELAY); @@ -72,7 +76,7 @@ int intel_early_me_init(void) } /* Check for valid firmware */ - pci_read_dword_ptr(&hfs, PCI_ME_HFS); + pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS); if (hfs.fpt_bad) { printf("WARNING: ME has bad firmware\n"); return -EBADF; @@ -83,11 +87,11 @@ int intel_early_me_init(void) return 0; } -int intel_early_me_uma_size(void) +int intel_early_me_uma_size(struct udevice *me_dev) { struct me_uma uma; - pci_read_dword_ptr(&uma, PCI_ME_UMA); + pci_read_dword_ptr(me_dev, &uma, PCI_ME_UMA); if (uma.valid) { debug("ME: Requested %uMB UMA\n", uma.size); return uma.size; @@ -97,11 +101,11 @@ int intel_early_me_uma_size(void) return -EINVAL; } -static inline void set_global_reset(int enable) +static inline void set_global_reset(struct udevice *dev, int enable) { u32 etr3; - etr3 = x86_pci_read_config32(PCH_LPC_DEV, ETR3); + dm_pci_read_config32(dev, ETR3, &etr3); /* Clear CF9 Without Resume Well Reset Enable */ etr3 &= ~ETR3_CWORWRE; @@ -112,10 +116,11 @@ static inline void set_global_reset(int enable) else etr3 &= ~ETR3_CF9GR; - x86_pci_write_config32(PCH_LPC_DEV, ETR3, etr3); + dm_pci_write_config32(dev, ETR3, etr3); } -int intel_early_me_init_done(u8 status) +int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev, + uint status) { int count; u32 mebase_l, mebase_h; @@ -126,8 +131,8 @@ int intel_early_me_init_done(u8 status) }; /* MEBASE from MESEG_BASE[35:20] */ - mebase_l = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L); - mebase_h = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H); + dm_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L, &mebase_l); + dm_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H, &mebase_h); mebase_h &= 0xf; did.uma_base = (mebase_l >> 20) | (mebase_h << 12); @@ -135,25 +140,25 @@ int intel_early_me_init_done(u8 status) debug("ME: Sending Init Done with status: %d, UMA base: 0x%04x\n", status, did.uma_base); - pci_write_dword_ptr(&did, PCI_ME_H_GS); + pci_write_dword_ptr(me_dev, &did, PCI_ME_H_GS); /* Must wait for ME acknowledgement */ for (count = ME_RETRY; count > 0; --count) { - pci_read_dword_ptr(&hfs, PCI_ME_HFS); + pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS); if (hfs.bios_msg_ack) break; udelay(ME_DELAY); } if (!count) { printf("ERROR: ME failed to respond\n"); - return -1; + return -ETIMEDOUT; } /* Return the requested BIOS action */ debug("ME: Requested BIOS Action: %s\n", me_ack_values[hfs.ack_data]); /* Check status after acknowledgement */ - intel_early_me_status(); + intel_early_me_status(me_dev); switch (hfs.ack_data) { case ME_HFS_ACK_CONTINUE: @@ -161,17 +166,17 @@ int intel_early_me_init_done(u8 status) return 0; case ME_HFS_ACK_RESET: /* Non-power cycle reset */ - set_global_reset(0); + set_global_reset(dev, 0); reset_cpu(0); break; case ME_HFS_ACK_PWR_CYCLE: /* Power cycle reset */ - set_global_reset(0); + set_global_reset(dev, 0); x86_full_reset(); break; case ME_HFS_ACK_GBL_RESET: /* Global reset */ - set_global_reset(1); + set_global_reset(dev, 1); x86_full_reset(); break; case ME_HFS_ACK_S3: @@ -180,5 +185,16 @@ int intel_early_me_init_done(u8 status) break; } - return -1; + return -EINVAL; } + +static const struct udevice_id ivybridge_syscon_ids[] = { + { .compatible = "intel,me", }, + { } +}; + +U_BOOT_DRIVER(syscon_intel_me) = { + .name = "intel_me_syscon", + .id = UCLASS_SYSCON, + .of_match = ivybridge_syscon_ids, +}; diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c index 6105cc0259..696351b7bf 100644 --- a/arch/x86/cpu/ivybridge/sdram.c +++ b/arch/x86/cpu/ivybridge/sdram.c @@ -286,7 +286,8 @@ static int recovery_mode_enabled(void) * @dev: Northbridge device * @pei_data: configuration data for UEFI PEI reference code */ -int sdram_initialise(struct udevice *dev, struct pei_data *pei_data) +int sdram_initialise(struct udevice *dev, struct udevice *me_dev, + struct pei_data *pei_data) { unsigned version; const char *data; @@ -296,10 +297,10 @@ int sdram_initialise(struct udevice *dev, struct pei_data *pei_data) report_platform_info(); /* Wait for ME to be ready */ - ret = intel_early_me_init(); + ret = intel_early_me_init(me_dev); if (ret) return ret; - ret = intel_early_me_uma_size(); + ret = intel_early_me_uma_size(me_dev); if (ret < 0) return ret; @@ -378,9 +379,9 @@ int sdram_initialise(struct udevice *dev, struct pei_data *pei_data) dm_pci_read_config16(dev, PCI_DEVICE_ID, &done); done &= BASE_REV_MASK; if (BASE_REV_SNB == done) - intel_early_me_init_done(ME_INIT_STATUS_SUCCESS); + intel_early_me_init_done(dev, me_dev, ME_INIT_STATUS_SUCCESS); else - intel_early_me_status(); + intel_early_me_status(me_dev); post_system_agent_init(pei_data); report_memory_config(); @@ -730,7 +731,7 @@ int dram_init(void) { 0, 4, 0x0000 }, /* P13= Empty */ }, }; - struct udevice *dev; + struct udevice *dev, *me_dev; int ret; ret = uclass_first_device(UCLASS_NORTHBRIDGE, &dev); @@ -738,12 +739,17 @@ int dram_init(void) return ret; if (!dev) return -ENODEV; + ret = uclass_first_device(UCLASS_SYSCON, &me_dev); + if (ret) + return ret; + if (!me_dev) + return -ENODEV; debug("Boot mode %d\n", gd->arch.pei_boot_mode); debug("mrc_input %p\n", pei_data.mrc_input); pei_data.boot_mode = gd->arch.pei_boot_mode; ret = copy_spd(&pei_data); if (!ret) - ret = sdram_initialise(dev, &pei_data); + ret = sdram_initialise(dev, me_dev, &pei_data); if (ret) return ret; diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts index 54f2043172..329eae8658 100644 --- a/arch/x86/dts/chromebook_link.dts +++ b/arch/x86/dts/chromebook_link.dts @@ -220,6 +220,12 @@ intel,pch-backlight = <0x04000000>; }; + me@16,0 { + reg = <0x0000b000 0 0 0 0>; + compatible = "intel,me"; + u-boot,dm-pre-reloc; + }; + pch@1f,0 { reg = <0x0000f800 0 0 0 0>; compatible = "intel,bd82x6x", "intel,pch9"; diff --git a/arch/x86/include/asm/arch-ivybridge/me.h b/arch/x86/include/asm/arch-ivybridge/me.h index 3a0809d6ec..eb1b73f92e 100644 --- a/arch/x86/include/asm/arch-ivybridge/me.h +++ b/arch/x86/include/asm/arch-ivybridge/me.h @@ -345,12 +345,47 @@ struct __packed me_fwcaps { u8 reserved[3]; }; -/* Defined in me_status.c for both romstage and ramstage */ +/** + * intel_me_status() - Check Intel Management Engine status + * + * struct hfs: Firmware status + * struct gmes: Management engine status + */ void intel_me_status(struct me_hfs *hfs, struct me_gmes *gmes); -void intel_early_me_status(void); -int intel_early_me_init(void); -int intel_early_me_uma_size(void); -int intel_early_me_init_done(u8 status); +/** + * intel_early_me_status() - Check early Management Engine Status + * + * @me_dev: Management engine PCI device + */ +void intel_early_me_status(struct udevice *me_dev); + +/** + * intel_early_me_init() - Early Intel Management Engine init + * + * @me_dev: Management engine PCI device + * @return 0 if OK, -ve on error + */ +int intel_early_me_init(struct udevice *me_dev); + +/** + * intel_early_me_uma_size() - Get UMA size from the Intel Management Engine + * + * @me_dev: Management engine PCI device + * @return UMA size if OK, -EINVAL on error + */ +int intel_early_me_uma_size(struct udevice *me_dev); + +/** + * intel_early_me_init_done() - Complete Intel Management Engine init + * + * @dev: Northbridge device + * @me_dev: Management engine PCI device + * @status: Status result (ME_INIT_...) + * @return 0 to continue to boot, -EINVAL on unknown result data, -ETIMEDOUT + * if ME did not respond + */ +int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev, + uint status); #endif |