From e5bc97578c189a99c291f7fe7ce89092474e43e9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:22 -0700 Subject: bios_emulator: Fix an #ifdef typo in the header file This stops the debug mode from working properly. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/bios_emulator/include/x86emu/debug.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bios_emulator/include/x86emu/debug.h b/drivers/bios_emulator/include/x86emu/debug.h index 304b2bf..4962a2a 100644 --- a/drivers/bios_emulator/include/x86emu/debug.h +++ b/drivers/bios_emulator/include/x86emu/debug.h @@ -102,7 +102,7 @@ # define ERR_PRINTF(x) printf(x) # define ERR_PRINTF2(x, y) printf(x, y) -#ifdef CONFIG_X86EMU_DEBUG103 +#ifdef CONFIG_X86EMU_DEBUG # define DECODE_PRINTF(x) if (DEBUG_DECODE()) \ -- cgit v1.1 From 40305240c66ab5e3725c131e321402c7dfe687a2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:23 -0700 Subject: x86: Correct endianness isues in pci_rom This code is too x86-dependent at present. Correct it so that it can run on big-endian machines. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci_rom.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 7d25cc9..86f0e95 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -66,6 +66,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class, struct pci_rom_header *rom_header; struct pci_rom_data *rom_data; u16 vendor, device; + u16 rom_vendor, rom_device; u32 vendev; u32 mapped_vendev; u32 rom_address; @@ -95,25 +96,27 @@ static int pci_rom_probe(pci_dev_t dev, uint class, rom_header = (struct pci_rom_header *)rom_address; debug("PCI expansion ROM, signature %#04x, INIT size %#04x, data ptr %#04x\n", - le32_to_cpu(rom_header->signature), - rom_header->size * 512, le32_to_cpu(rom_header->data)); + le16_to_cpu(rom_header->signature), + rom_header->size * 512, le16_to_cpu(rom_header->data)); - if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) { + if (le16_to_cpu(rom_header->signature) != PCI_ROM_HDR) { printf("Incorrect expansion ROM header signature %04x\n", - le32_to_cpu(rom_header->signature)); + le16_to_cpu(rom_header->signature)); return -EINVAL; } - rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data)); + rom_data = (((void *)rom_header) + le16_to_cpu(rom_header->data)); + rom_vendor = le16_to_cpu(rom_data->vendor); + rom_device = le16_to_cpu(rom_data->device); debug("PCI ROM image, vendor ID %04x, device ID %04x,\n", - rom_data->vendor, rom_data->device); + rom_vendor, rom_device); /* If the device id is mapped, a mismatch is expected */ - if ((vendor != rom_data->vendor || device != rom_data->device) && + if ((vendor != rom_vendor || device != rom_device) && (vendev == mapped_vendev)) { printf("ID mismatch: vendor ID %04x, device ID %04x\n", - rom_data->vendor, rom_data->device); + rom_vendor, rom_device); return -EPERM; } @@ -144,10 +147,10 @@ int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header, image_size); rom_data = (struct pci_rom_data *)((void *)rom_header + - le32_to_cpu(rom_header->data)); + le16_to_cpu(rom_header->data)); - image_size = le32_to_cpu(rom_data->ilen) * 512; - } while ((rom_data->type != 0) && (rom_data->indicator != 0)); + image_size = le16_to_cpu(rom_data->ilen) * 512; + } while ((rom_data->type != 0) && (rom_data->indicator == 0)); if (rom_data->type != 0) return -EACCES; -- cgit v1.1 From bdc88d4eb31e2bc84afb427c216c79e87a4233ef Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:24 -0700 Subject: x86: Support ROMs on other archs We shouldn't assume that the VGA ROM can always be loaded at c0000. This is only true on x86 machines. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/include/asm/u-boot-x86.h | 2 ++ drivers/pci/pci_rom.c | 6 ++++++ include/pci_rom.h | 1 - 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 36145cb..b98afa8 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -70,4 +70,6 @@ uint64_t timer_get_tsc(void); void quick_ram_check(void); +#define PCI_VGA_RAM_IMAGE_START 0xc0000 + #endif /* _U_BOOT_I386_H_ */ diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 86f0e95..124b730 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -157,7 +157,13 @@ int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header, rom_size = rom_header->size * 512; +#ifdef PCI_VGA_RAM_IMAGE_START target = (void *)PCI_VGA_RAM_IMAGE_START; +#else + target = (void *)malloc(rom_size); + if (!target) + return -ENOMEM; +#endif if (target != rom_header) { ulong start = get_timer(0); diff --git a/include/pci_rom.h b/include/pci_rom.h index 8b2674c..4ba36eb 100644 --- a/include/pci_rom.h +++ b/include/pci_rom.h @@ -8,7 +8,6 @@ #define _PCI_ROM_H #define PCI_ROM_HDR 0xaa55 -#define PCI_VGA_RAM_IMAGE_START 0xc0000 struct pci_rom_header { uint16_t signature; -- cgit v1.1 From e78dd86998298df6d6108b1bc070d934bd805873 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:25 -0700 Subject: bios_emulator: Don't display error when emulator terminates As it turns out this is a normal condition, so suppress the error. Signed-off-by: Simon Glass --- drivers/bios_emulator/x86emu/ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bios_emulator/x86emu/ops.c b/drivers/bios_emulator/x86emu/ops.c index 2bb5e2d..5752fee 100644 --- a/drivers/bios_emulator/x86emu/ops.c +++ b/drivers/bios_emulator/x86emu/ops.c @@ -179,7 +179,7 @@ void x86emuOp_illegal_op( { START_OF_INSTR(); if (M.x86.R_SP != 0) { - ERR_PRINTF("ILLEGAL X86 OPCODE\n"); + DB(printf("ILLEGAL X86 OPCODE\n")); TRACE_REGS(); DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n", M.x86.R_CS, M.x86.R_IP-1,op1)); -- cgit v1.1 From 222f25f85503f19acb9cb7ff138d3fe5215c3ad9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:26 -0700 Subject: bios_emulator: Add some VESA interface debugging Allow the supported modes to be listed when in debug mode. Signed-off-by: Simon Glass --- drivers/bios_emulator/atibios.c | 161 +++++++++++++++++++++++++++++++++++----- include/vbe.h | 9 ++- 2 files changed, 148 insertions(+), 22 deletions(-) diff --git a/drivers/bios_emulator/atibios.c b/drivers/bios_emulator/atibios.c index 93b815c..7ea5fa6 100644 --- a/drivers/bios_emulator/atibios.c +++ b/drivers/bios_emulator/atibios.c @@ -62,40 +62,158 @@ static u32 saveBaseAddress14; static u32 saveBaseAddress18; static u32 saveBaseAddress20; -static void atibios_set_vesa_mode(RMREGS *regs, int vesa_mode, - struct vbe_mode_info *mode_info) +/* Addres im memory of VBE region */ +const int vbe_offset = 0x2000; + +static const void *bios_ptr(const void *buf, BE_VGAInfo *vga_info, + u32 x86_dword_ptr) +{ + u32 seg_ofs, flat; + + seg_ofs = le32_to_cpu(x86_dword_ptr); + flat = ((seg_ofs & 0xffff0000) >> 12) | (seg_ofs & 0xffff); + if (flat >= 0xc0000) + return vga_info->BIOSImage + flat - 0xc0000; + else + return buf + (flat - vbe_offset); +} + +static int atibios_debug_mode(BE_VGAInfo *vga_info, RMREGS *regs, + int vesa_mode, struct vbe_mode_info *mode_info) +{ + void *buffer = (void *)(M.mem_base + vbe_offset); + u16 buffer_seg = (((unsigned long)vbe_offset) >> 4) & 0xff00; + u16 buffer_adr = ((unsigned long)vbe_offset) & 0xffff; + struct vesa_mode_info *vm; + struct vbe_info *info; + const u16 *modes_bios, *ptr; + u16 *modes; + int size; + + debug("VBE: Getting information\n"); + regs->e.eax = VESA_GET_INFO; + regs->e.esi = buffer_seg; + regs->e.edi = buffer_adr; + info = buffer; + memset(info, '\0', sizeof(*info)); + strcpy(info->signature, "VBE2"); + BE_int86(0x10, regs, regs); + if (regs->e.eax != 0x4f) { + debug("VESA_GET_INFO: error %x\n", regs->e.eax); + return -ENOSYS; + } + debug("version %x\n", le16_to_cpu(info->version)); + debug("oem '%s'\n", (char *)bios_ptr(buffer, vga_info, + info->oem_string_ptr)); + debug("vendor '%s'\n", (char *)bios_ptr(buffer, vga_info, + info->vendor_name_ptr)); + debug("product '%s'\n", (char *)bios_ptr(buffer, vga_info, + info->product_name_ptr)); + debug("rev '%s'\n", (char *)bios_ptr(buffer, vga_info, + info->product_rev_ptr)); + modes_bios = bios_ptr(buffer, vga_info, info->modes_ptr); + debug("Modes: "); + for (ptr = modes_bios; *ptr != 0xffff; ptr++) + debug("%x ", le16_to_cpu(*ptr)); + debug("\nmemory %dMB\n", le16_to_cpu(info->total_memory) >> 4); + size = (ptr - modes_bios) * sizeof(u16) + 2; + modes = malloc(size); + if (!modes) + return -ENOMEM; + memcpy(modes, modes_bios, size); + + regs->e.eax = VESA_GET_CUR_MODE; + BE_int86(0x10, regs, regs); + if (regs->e.eax != 0x4f) { + debug("VESA_GET_CUR_MODE: error %x\n", regs->e.eax); + return -ENOSYS; + } + debug("Current mode %x\n", regs->e.ebx); + + for (ptr = modes; *ptr != 0xffff; ptr++) { + int mode = le16_to_cpu(*ptr); + bool linear_ok; + int attr; + + break; + debug("Mode %x: ", mode); + memset(buffer, '\0', sizeof(struct vbe_mode_info)); + regs->e.eax = VESA_GET_MODE_INFO; + regs->e.ebx = 0; + regs->e.ecx = mode; + regs->e.edx = 0; + regs->e.esi = buffer_seg; + regs->e.edi = buffer_adr; + BE_int86(0x10, regs, regs); + if (regs->e.eax != 0x4f) { + debug("VESA_GET_MODE_INFO: error %x\n", regs->e.eax); + continue; + } + memcpy(mode_info->mode_info_block, buffer, + sizeof(struct vesa_mode_info)); + mode_info->valid = true; + vm = &mode_info->vesa; + attr = le16_to_cpu(vm->mode_attributes); + linear_ok = attr & 0x80; + debug("res %d x %d, %d bpp, mm %d, (Linear %s, attr %02x)\n", + le16_to_cpu(vm->x_resolution), + le16_to_cpu(vm->y_resolution), + vm->bits_per_pixel, vm->memory_model, + linear_ok ? "OK" : "not available", + attr); + debug("\tRGB pos=%d,%d,%d, size=%d,%d,%d\n", + vm->red_mask_pos, vm->green_mask_pos, vm->blue_mask_pos, + vm->red_mask_size, vm->green_mask_size, + vm->blue_mask_size); + } + + return 0; +} + +static int atibios_set_vesa_mode(RMREGS *regs, int vesa_mode, + struct vbe_mode_info *mode_info) { + void *buffer = (void *)(M.mem_base + vbe_offset); + u16 buffer_seg = (((unsigned long)vbe_offset) >> 4) & 0xff00; + u16 buffer_adr = ((unsigned long)vbe_offset) & 0xffff; + struct vesa_mode_info *vm; + debug("VBE: Setting VESA mode %#04x\n", vesa_mode); - /* request linear framebuffer mode */ - vesa_mode |= (1 << 14); - /* request clearing of framebuffer */ - vesa_mode &= ~(1 << 15); regs->e.eax = VESA_SET_MODE; regs->e.ebx = vesa_mode; + /* request linear framebuffer mode and don't clear display */ + regs->e.ebx |= (1 << 14) | (1 << 15); BE_int86(0x10, regs, regs); + if (regs->e.eax != 0x4f) { + debug("VESA_SET_MODE: error %x\n", regs->e.eax); + return -ENOSYS; + } - int offset = 0x2000; - void *buffer = (void *)(M.mem_base + offset); - - u16 buffer_seg = (((unsigned long)offset) >> 4) & 0xff00; - u16 buffer_adr = ((unsigned long)offset) & 0xffff; + memset(buffer, '\0', sizeof(struct vbe_mode_info)); + debug("VBE: Geting info for VESA mode %#04x\n", vesa_mode); regs->e.eax = VESA_GET_MODE_INFO; - regs->e.ebx = 0; regs->e.ecx = vesa_mode; - regs->e.edx = 0; regs->e.esi = buffer_seg; regs->e.edi = buffer_adr; BE_int86(0x10, regs, regs); + if (regs->e.eax != 0x4f) { + debug("VESA_GET_MODE_INFO: error %x\n", regs->e.eax); + return -ENOSYS; + } + memcpy(mode_info->mode_info_block, buffer, - sizeof(struct vbe_mode_info)); + sizeof(struct vesa_mode_info)); mode_info->valid = true; + mode_info->video_mode = vesa_mode; + vm = &mode_info->vesa; + vm->x_resolution = le16_to_cpu(vm->x_resolution); + vm->y_resolution = le16_to_cpu(vm->y_resolution); + vm->bytes_per_scanline = le16_to_cpu(vm->bytes_per_scanline); + vm->phys_base_ptr = le32_to_cpu(vm->phys_base_ptr); + vm->mode_attributes = le16_to_cpu(vm->mode_attributes); + debug("VBE: Init complete\n"); - vesa_mode |= (1 << 14); - /* request clearing of framebuffer */ - vesa_mode &= ~(1 << 15); - regs->e.eax = VESA_SET_MODE; - regs->e.ebx = vesa_mode; - BE_int86(0x10, regs, regs); + return 0; } /**************************************************************************** @@ -132,6 +250,9 @@ static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo *vga_info, /*Cleanup and exit*/ BE_getVGA(vga_info); + /* Useful for debugging */ + if (0) + atibios_debug_mode(vga_info, ®s, vesa_mode, mode_info); if (vesa_mode != -1) atibios_set_vesa_mode(®s, vesa_mode, mode_info); } diff --git a/include/vbe.h b/include/vbe.h index d405691..c5deee9 100644 --- a/include/vbe.h +++ b/include/vbe.h @@ -35,10 +35,14 @@ struct __packed screen_info_input { struct __packed vbe_info { char signature[4]; u16 version; - u8 *oem_string_ptr; + u32 oem_string_ptr; u32 capabilities; - u16 video_mode_list[256]; + u32 modes_ptr; u16 total_memory; + u16 oem_version; + u32 vendor_name_ptr; + u32 product_name_ptr; + u32 product_rev_ptr; }; struct __packed vesa_mode_info { @@ -96,6 +100,7 @@ struct vbe_ddc_info { #define VESA_GET_INFO 0x4f00 #define VESA_GET_MODE_INFO 0x4f01 #define VESA_SET_MODE 0x4f02 +#define VESA_GET_CUR_MODE 0x4f03 struct graphic_device; int vbe_get_video_info(struct graphic_device *gdev); -- cgit v1.1 From c5caba03665b0491832ca4c38209d71ff28bf593 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:27 -0700 Subject: x86: pci: Don't stop when we get a vendor/device mismatch These are quite common and we may as well press on and not be so picky. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci_rom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 124b730..a16e99f 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -117,7 +117,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class, (vendev == mapped_vendev)) { printf("ID mismatch: vendor ID %04x, device ID %04x\n", rom_vendor, rom_device); - return -EPERM; + /* Continue anyway */ } debug("PCI ROM image, Class Code %04x%02x, Code Type %02x\n", -- cgit v1.1 From 6b1ba984507039a893b14c2dec3c7b1edbc8413d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:28 -0700 Subject: x86: Add a VESA video driver Add a driver intended to cope with any VESA-compatible x86 graphics adapter. It will not support ROMs which use OpenFirmware (Forth) since there is no support for that in U-Boot. This means that MAC OS cards will not work. Signed-off-by: Simon Glass --- drivers/video/Kconfig | 10 ++++++++ drivers/video/Makefile | 1 + drivers/video/vesa_fb.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 drivers/video/vesa_fb.c diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index ccbd7e2..697171e 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1,3 +1,13 @@ +config VIDEO_VESA + bool "Enable VESA video driver support" + depends on X86 + default n + help + Turn on this option to enable a very simple driver which uses vesa + to discover the video mode and then provides a frame buffer for use + by U-Boot. This can in principle be used with any platform that + supports PCI and video cards that support VESA BIOS Extension (VBE). + config VIDEO_X86 bool "Enable x86 video driver support" depends on X86 diff --git a/drivers/video/Makefile b/drivers/video/Makefile index c3fcf45..9f3c8bb 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o videomodes.o obj-$(CONFIG_VIDEO_TEGRA) += tegra.o obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o +obj-$(CONFIG_VIDEO_VESA) += vesa_fb.o obj-$(CONFIG_VIDEO_X86) += x86_fb.o obj-$(CONFIG_FORMIKE) += formike.o obj-$(CONFIG_AM335X_LCD) += am335x-fb.o diff --git a/drivers/video/vesa_fb.c b/drivers/video/vesa_fb.c new file mode 100644 index 0000000..3dacafd --- /dev/null +++ b/drivers/video/vesa_fb.c @@ -0,0 +1,64 @@ +/* + * + * Vesa frame buffer driver for x86 + * + * Copyright (C) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +/* + * The Graphic Device + */ +GraphicDevice ctfb; + +/* Devices to allow - only the last one works fully */ +struct pci_device_id vesa_video_ids[] = { + { .vendor = 0x102b, .device = 0x0525 }, + { .vendor = 0x1002, .device = 0x5159 }, + { .vendor = 0x1002, .device = 0x4752 }, + { .vendor = 0x1002, .device = 0x5452 }, + {}, +}; + +void *video_hw_init(void) +{ + GraphicDevice *gdev = &ctfb; + int bits_per_pixel; + pci_dev_t dev; + int ret; + + printf("Video: "); + if (vbe_get_video_info(gdev)) { + /* TODO: Should we look these up by class? */ + dev = pci_find_devices(vesa_video_ids, 0); + if (dev == -1) { + printf("no card detected\n"); + return NULL; + } + printf("bdf %x\n", dev); + ret = pci_run_vga_bios(dev, NULL, true); + if (ret) { + printf("failed to run video BIOS: %d\n", ret); + return NULL; + } + } + + if (vbe_get_video_info(gdev)) { + printf("No video mode configured\n"); + return NULL; + } + + bits_per_pixel = gdev->gdfBytesPP * 8; + sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY, + bits_per_pixel); + printf("%s\n", gdev->modeIdent); + debug("Framex buffer at %x\n", gdev->pciBase); + + return (void *)gdev; +} -- cgit v1.1 From edb8b7a66b75045cc9e16a2762cd8344cdcd9bf5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:29 -0700 Subject: x86: Drop the x86_fb driver Now that we have a full VESA driver we may as well use that. We need to support the VESA layer being set up by early start-up code or by running a VGA ROM. Signed-off-by: Simon Glass --- configs/chromebook_link_defconfig | 2 +- drivers/video/Kconfig | 9 --------- drivers/video/Makefile | 1 - drivers/video/x86_fb.c | 38 -------------------------------------- 4 files changed, 1 insertion(+), 49 deletions(-) delete mode 100644 drivers/video/x86_fb.c diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig index e956835..2f0c714 100644 --- a/configs/chromebook_link_defconfig +++ b/configs/chromebook_link_defconfig @@ -6,6 +6,6 @@ CONFIG_OF_SEPARATE=y CONFIG_DEFAULT_DEVICE_TREE="chromebook_link" CONFIG_HAVE_MRC=y CONFIG_SMM_TSEG_SIZE=0x800000 -CONFIG_VIDEO_X86=y +CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 697171e..51728b3 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -8,15 +8,6 @@ config VIDEO_VESA by U-Boot. This can in principle be used with any platform that supports PCI and video cards that support VESA BIOS Extension (VBE). -config VIDEO_X86 - bool "Enable x86 video driver support" - depends on X86 - default n - help - Turn on this option to enable a very simple driver which uses vesa - to discover the video mode and then provides a frame buffer for use - by U-Boot. - config VIDEO_LCD_SSD2828 bool "SSD2828 bridge chip" default n diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 9f3c8bb..af2d47b 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o videomodes.o obj-$(CONFIG_VIDEO_TEGRA) += tegra.o obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o obj-$(CONFIG_VIDEO_VESA) += vesa_fb.o -obj-$(CONFIG_VIDEO_X86) += x86_fb.o obj-$(CONFIG_FORMIKE) += formike.o obj-$(CONFIG_AM335X_LCD) += am335x-fb.o obj-$(CONFIG_VIDEO_PARADE) += parade.o diff --git a/drivers/video/x86_fb.c b/drivers/video/x86_fb.c deleted file mode 100644 index 6641033..0000000 --- a/drivers/video/x86_fb.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * Vesa frame buffer driver for x86 - * - * Copyright (C) 2014 Google, Inc - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include "videomodes.h" - -/* - * The Graphic Device - */ -GraphicDevice ctfb; - -void *video_hw_init(void) -{ - GraphicDevice *gdev = &ctfb; - int bits_per_pixel; - - printf("Video: "); - if (vbe_get_video_info(gdev)) { - printf("No video mode configured\n"); - return NULL; - } - - bits_per_pixel = gdev->gdfBytesPP * 8; - sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY, - bits_per_pixel); - printf("%s\n", gdev->modeIdent); - debug("Frame buffer at %x\n", gdev->frameAdrs); - - return (void *)gdev; -} -- cgit v1.1 From 4df2b48fbee148cd2c4137ee920220338f0dcaf0 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 31 Dec 2014 17:18:39 +0800 Subject: x86: ahci: Make sure interface is not busy after enabling the port Each time U-Boot boots on Intel Crown Bay board, the displayed hard drive information is wrong. It could be either wrong capacity or just a 'Capacity: not available' message. After enabling the debug switch, we can see the scsi inquiry command did not execute successfully. However, doing a 'scsi scan' in the U-Boot shell does not expose this issue. SCSI: Target spinup took 0 ms. SATA link 1 timeout. AHCI 0001.0100 32 slots 2 ports 3 Gbps 0x3 impl SATA mode flags: ncq stag pm led clo only pmp pio slum part ccc apst scanning bus for devices... ahci_device_data_io: 0 byte transferred. <--- scsi inquiry fails ahci_device_data_io: 512 byte transferred. ahci_device_data_io: 512 byte transferred. ahci_device_data_io: 512 byte transferred. Device 0: (0:0) Vendor: ATA Prod.: Rev: ?8 Type: Hard Disk Capacity: 912968.3 MB = 891.5 GB (1869759264 x 512) Found 1 device(s). So uninitialized contents on the stack were passed to dev_print() to display those wrong information. The symptom were observed on two hard drives (one is Seagate, the other one is Western Digital). The fix is to make sure the AHCI interface is not busy by checking the error and status information from task file register after enabling the port in ahci_port_start() before proceeding other operations like scsi_scan(). Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- drivers/block/ahci.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index 37d2d2a..c908fab 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -513,6 +513,20 @@ static void ahci_set_feature(u8 port) } #endif +static int wait_spinup(volatile u8 *port_mmio) +{ + ulong start; + u32 tf_data; + + start = get_timer(0); + do { + tf_data = readl(port_mmio + PORT_TFDATA); + if (!(tf_data & ATA_BUSY)) + return 0; + } while (get_timer(start) < WAIT_MS_SPINUP); + + return -ETIMEDOUT; +} static int ahci_port_start(u8 port) { @@ -579,7 +593,11 @@ static int ahci_port_start(u8 port) debug("Exit start port %d\n", port); - return 0; + /* + * Make sure interface is not busy based on error and status + * information from task file data register before proceeding + */ + return wait_spinup(port_mmio); } -- cgit v1.1 From 07570e709765e93f2b1e9506cfd8fa24455636b5 Mon Sep 17 00:00:00 2001 From: Sebastien Ronsse Date: Mon, 12 Jan 2015 17:17:25 +0000 Subject: x86: Fix out of bounds irq handlers access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using coreboot-x86_defconfig, the following error occurred prior to this modification: CC arch/x86/lib/interrupts arch/x86/lib/interrupts.c: In function ‘do_irqinfo’: arch/x86/lib/interrupts.c:134:24: error: iteration 16u invokes undefined behavior [-Werror=aggressive-loop-optimizations] if (irq_handlers[irq].handler != NULL) { ^ arch/x86/lib/interrupts.c:133:2: note: containing loop for (irq = 0; irq <= CONFIG_SYS_NUM_IRQS; irq++) { ^ cc1: all warnings being treated as errors scripts/Makefile.build:275: recipe for target 'arch/x86/lib/interrupts.o' failed make[1]: *** [arch/x86/lib/interrupts.o] Error 1 Makefile:1093: recipe for target 'arch/x86/lib' failed make: *** [arch/x86/lib] Error 2 Change-Id: I3572a822081b72ab760f1eb99442e1161d3d167e Signed-off-by: Sebastien Ronsse Acked-by: Simon Glass --- arch/x86/lib/interrupts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/lib/interrupts.c b/arch/x86/lib/interrupts.c index 6bb22d2..146ad11 100644 --- a/arch/x86/lib/interrupts.c +++ b/arch/x86/lib/interrupts.c @@ -130,7 +130,7 @@ int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("Interrupt-Information:\n"); printf("Nr Routine Arg Count\n"); - for (irq = 0; irq <= CONFIG_SYS_NUM_IRQS; irq++) { + for (irq = 0; irq < CONFIG_SYS_NUM_IRQS; irq++) { if (irq_handlers[irq].handler != NULL) { printf("%02d %08lx %08lx %d\n", irq, -- cgit v1.1 From 4a2708a097eacd7aa3d10ccf26a70a467fa69217 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 14 Jan 2015 21:37:04 -0700 Subject: x86: Access the VGA ROM when needed Add code to the generic pci_rom file to access the VGA ROM in PCI space when needed. Signed-off-by: Simon Glass --- drivers/pci/pci_auto.c | 28 +++++++++++++++++++++++++++- drivers/pci/pci_rom.c | 7 ++++++- include/pci.h | 9 +++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 44470fa..ed92857 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -11,7 +11,7 @@ */ #include - +#include #include #undef DEBUG @@ -191,6 +191,32 @@ void pciauto_setup_device(struct pci_controller *hose, pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); } +int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev) +{ + pci_addr_t bar_value; + pci_size_t bar_size; + u32 bar_response; + u16 cmdstat = 0; + + pci_hose_write_config_dword(hose, dev, PCI_ROM_ADDRESS, 0xfffffffe); + pci_hose_read_config_dword(hose, dev, PCI_ROM_ADDRESS, &bar_response); + if (!bar_response) + return -ENOENT; + + bar_size = -(bar_response & ~1); + DEBUGF("PCI Autoconfig: ROM, size=%#x, ", bar_size); + if (pciauto_region_allocate(hose->pci_mem, bar_size, &bar_value) == 0) { + pci_hose_write_config_dword(hose, dev, PCI_ROM_ADDRESS, + bar_value); + } + DEBUGF("\n"); + pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); + cmdstat |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + pci_hose_write_config_word(hose, dev, PCI_COMMAND, cmdstat); + + return 0; +} + void pciauto_prescan_setup_bridge(struct pci_controller *hose, pci_dev_t dev, int sub_bus) { diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index a16e99f..eb76591 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -81,7 +81,12 @@ static int pci_rom_probe(pci_dev_t dev, uint class, #ifdef CONFIG_X86_OPTION_ROM_ADDR rom_address = CONFIG_X86_OPTION_ROM_ADDR; #else - pci_write_config_dword(dev, PCI_ROM_ADDRESS, (u32)PCI_ROM_ADDRESS_MASK); + + if (pciauto_setup_rom(pci_bus_to_hose(PCI_BUS(dev)), dev)) { + debug("Cannot find option ROM\n"); + return -ENOENT; + } + pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_address); if (rom_address == 0x00000000 || rom_address == 0xffffffff) { debug("%s: rom_address=%x\n", __func__, rom_address); diff --git a/include/pci.h b/include/pci.h index 7f67ca6..4fbb8f6 100644 --- a/include/pci.h +++ b/include/pci.h @@ -697,5 +697,14 @@ void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum, * */ u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum); +/** + * pciauto_setup_rom() - Set up access to a device ROM + * + * @hose: PCI hose to use + * @dev: PCI device to adjust + * @return 0 if done, -ve on error + */ +int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev); + #endif /* __ASSEMBLY__ */ #endif /* _PCI_H */ -- cgit v1.1 From 3c0b668f6672334a68be83cde9aaabf0e87a31e9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 1 Jan 2015 16:17:57 -0700 Subject: x86: video: Add support for CONFIG_CONSOLE_SCROLL_LINES Some machines are very slow to scroll their displays. To cope with this, support the CONFIG_CONSOLE_SCROLL_LINES option. Setting this to 5 allows the display to operate at an acceptable speed by scrolling 5 lines at a time. This same option is available for LCDs so when these systems are unified this code can be unified also. Signed-off-by: Simon Glass Acked-by: Anatolij Gustschin --- drivers/video/cfb_console.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index d4226e3..a81affa 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -299,7 +299,11 @@ void console_cursor(int state); #define CONSOLE_ROW_SECOND (video_console_address + CONSOLE_ROW_SIZE) #define CONSOLE_ROW_LAST (video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE) #define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS) -#define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE) + +/* By default we scroll by a single line */ +#ifndef CONFIG_CONSOLE_SCROLL_LINES +#define CONFIG_CONSOLE_SCROLL_LINES 1 +#endif /* Macros */ #ifdef VIDEO_FB_LITTLE_ENDIAN @@ -740,26 +744,33 @@ static void console_clear_line(int line, int begin, int end) static void console_scrollup(void) { + const int rows = CONFIG_CONSOLE_SCROLL_LINES; + int i; + /* copy up rows ignoring the first one */ #ifdef VIDEO_HW_BITBLT video_hw_bitblt(VIDEO_PIXEL_SIZE, /* bytes per pixel */ 0, /* source pos x */ video_logo_height + - VIDEO_FONT_HEIGHT, /* source pos y */ + VIDEO_FONT_HEIGHT * rows, /* source pos y */ 0, /* dest pos x */ video_logo_height, /* dest pos y */ VIDEO_VISIBLE_COLS, /* frame width */ VIDEO_VISIBLE_ROWS - video_logo_height - - VIDEO_FONT_HEIGHT /* frame height */ + - VIDEO_FONT_HEIGHT * rows /* frame height */ ); #else - memcpyl(CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, - CONSOLE_SCROLL_SIZE >> 2); + memcpyl(CONSOLE_ROW_FIRST, CONSOLE_ROW_FIRST + rows * CONSOLE_ROW_SIZE, + (CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows) >> 2); #endif /* clear the last one */ - console_clear_line(CONSOLE_ROWS - 1, 0, CONSOLE_COLS - 1); + for (i = 1; i <= rows; i++) + console_clear_line(CONSOLE_ROWS - i, 0, CONSOLE_COLS - 1); + + /* Decrement row number */ + console_row -= rows; } static void console_back(void) @@ -871,9 +882,6 @@ static void console_newline(int n) if (console_row >= CONSOLE_ROWS) { /* Scroll everything up */ console_scrollup(); - - /* Decrement row number */ - console_row = CONSOLE_ROWS - 1; } } -- cgit v1.1 From d1a5d3c133a07d6035b9f97a6315afed7d73514a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 1 Jan 2015 16:17:58 -0700 Subject: x86: config: Always scroll the display by 5 lines, for speed Scrolling a line at a time is very slow for reasons that I don't understand. It seems to take about 100ms to copy 4MB of RAM in the frame buffer. To cope with this, scroll 5 lines each time. Signed-off-by: Simon Glass --- include/configs/x86-common.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index f16ae32..4f0a3c5 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -179,6 +179,7 @@ #define VIDEO_FB_16BPP_WORD_SWAP #define CONFIG_I8042_KBD #define CONFIG_CFB_CONSOLE +#define CONFIG_CONSOLE_SCROLL_LINES 5 /*----------------------------------------------------------------------- * CPU Features -- cgit v1.1 From 566d1754d3a84819d9e2829421898d115ef2c116 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 22 Jan 2015 11:29:39 +0800 Subject: x86: Add missing DECLARE_GLOBAL_DATA_PTR for mtrr.c arch/x86/cpu/mtrr.c has access to the U-Boot global data thus DECLARE_GLOBAL_DATA_PTR is needed. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/mtrr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c index d5a825d..ac8765f 100644 --- a/arch/x86/cpu/mtrr.c +++ b/arch/x86/cpu/mtrr.c @@ -17,6 +17,8 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + /* Prepare to adjust MTRRs */ void mtrr_open(struct mtrr_state *state) { -- cgit v1.1 From 49491669065c1c718d8dc0b0ebc151b3d010c17b Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 22 Jan 2015 11:29:40 +0800 Subject: x86: Save mtrr support flag in global data CPUID (EAX 01H) returns MTRR support flag in EDX bit 12. Probe this flag in x86_cpu_init_f() and save it in global data. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/cpu.c | 7 +++++++ arch/x86/include/asm/global_data.h | 13 +++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 30e5069..ed7905c 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -223,6 +223,11 @@ static bool has_cpuid(void) return flag_is_changeable_p(X86_EFLAGS_ID); } +static bool has_mtrr(void) +{ + return cpuid_edx(0x00000001) & (1 << 12) ? true : false; +} + static int build_vendor_name(char *vendor_name) { struct cpuid_result result; @@ -318,6 +323,8 @@ int x86_cpu_init_f(void) gd->arch.x86_model = c.x86_model; gd->arch.x86_mask = c.x86_mask; gd->arch.x86_device = cpu.device; + + gd->arch.has_mtrr = has_mtrr(); } return 0; diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 24e3052..243ed5c 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -44,11 +44,11 @@ struct mtrr_request { /* Architecture-specific global data */ struct arch_global_data { - struct global_data *gd_addr; /* Location of Global Data */ - uint8_t x86; /* CPU family */ - uint8_t x86_vendor; /* CPU vendor */ - uint8_t x86_model; - uint8_t x86_mask; + struct global_data *gd_addr; /* Location of Global Data */ + uint8_t x86; /* CPU family */ + uint8_t x86_vendor; /* CPU vendor */ + uint8_t x86_model; + uint8_t x86_mask; uint32_t x86_device; uint64_t tsc_base; /* Initial value returned by rdtsc() */ uint32_t tsc_base_kclocks; /* Initial tsc as a kclocks value */ @@ -60,10 +60,11 @@ struct arch_global_data { const struct pch_gpio_map *gpio_map; /* board GPIO map */ struct memory_info meminfo; /* Memory information */ #ifdef CONFIG_HAVE_FSP - void *hob_list; /* FSP HOB list */ + void *hob_list; /* FSP HOB list */ #endif struct mtrr_request mtrr_req[MAX_MTRR_REQUESTS]; int mtrr_req_count; + int has_mtrr; }; #endif -- cgit v1.1 From 3b621ccabdccb34891bb58865a9654a09c2b7279 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 22 Jan 2015 11:29:41 +0800 Subject: x86: Test mtrr support flag before accessing mtrr msr On some x86 processors (like Intel Quark) the MTRR registers are not supported. This is reflected by the CPUID (EAX 01H) result EDX[12]. Accessing the MTRR registers on such processors will cause #GP so we must test the support flag before accessing MTRR MSRs. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/mtrr.c | 12 ++++++++++++ arch/x86/include/asm/mtrr.h | 5 ++++- arch/x86/lib/init_helpers.c | 4 +++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c index ac8765f..5d36b3e 100644 --- a/arch/x86/cpu/mtrr.c +++ b/arch/x86/cpu/mtrr.c @@ -22,6 +22,9 @@ DECLARE_GLOBAL_DATA_PTR; /* Prepare to adjust MTRRs */ void mtrr_open(struct mtrr_state *state) { + if (!gd->arch.has_mtrr) + return; + state->enable_cache = dcache_status(); if (state->enable_cache) @@ -33,6 +36,9 @@ void mtrr_open(struct mtrr_state *state) /* Clean up after adjusting MTRRs, and enable them */ void mtrr_close(struct mtrr_state *state) { + if (!gd->arch.has_mtrr) + return; + wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype | MTRR_DEF_TYPE_EN); if (state->enable_cache) enable_caches(); @@ -45,6 +51,9 @@ int mtrr_commit(bool do_caches) uint64_t mask; int i; + if (!gd->arch.has_mtrr) + return -ENOSYS; + mtrr_open(&state); for (i = 0; i < gd->arch.mtrr_req_count; i++, req++) { mask = ~(req->size - 1); @@ -66,6 +75,9 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size) struct mtrr_request *req; uint64_t mask; + if (!gd->arch.has_mtrr) + return -ENOSYS; + if (gd->arch.mtrr_req_count == MAX_MTRR_REQUESTS) return -ENOSPC; req = &gd->arch.mtrr_req[gd->arch.mtrr_req_count++]; diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index 3c11740..fda4eae 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -65,7 +65,6 @@ void mtrr_open(struct mtrr_state *state); * * @state: Structure from mtrr_open() */ -/* */ void mtrr_close(struct mtrr_state *state); /** @@ -76,6 +75,8 @@ void mtrr_close(struct mtrr_state *state); * @type: Requested type (MTRR_TYPE_) * @start: Start address * @size: Size + * + * @return: 0 on success, non-zero on failure */ int mtrr_add_request(int type, uint64_t start, uint64_t size); @@ -86,6 +87,8 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size); * It must be called with caches disabled. * * @do_caches: true if caches are currently on + * + * @return: 0 on success, non-zero on failure */ int mtrr_commit(bool do_caches); diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index fc211d9..5097ca2 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -71,7 +72,8 @@ int init_cache_f_r(void) int ret; ret = mtrr_commit(false); - if (ret) + /* If MTRR MSR is not implemented by the processor, just ignore it */ + if (ret && ret != -ENOSYS) return ret; #endif /* Initialise the CPU cache(s) */ -- cgit v1.1 From fea1c47f5481871f9aad70a02dc8c66b91332774 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Tue, 20 Jan 2015 11:25:44 +0800 Subject: x86: Fix various code format issues in start16.S Various minor code format issues are fixed in start16.S: - U-boot -> U-Boot - 32bit -> 32-bit - Use TAB instead of SPACE to indent - Move the indention location of the GDT comment block Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/start16.S | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/x86/cpu/start16.S b/arch/x86/cpu/start16.S index 9550502..826e2b4 100644 --- a/arch/x86/cpu/start16.S +++ b/arch/x86/cpu/start16.S @@ -1,5 +1,5 @@ /* - * U-boot - x86 Startup Code + * U-Boot - x86 Startup Code * * (C) Copyright 2008-2011 * Graeme Russ, @@ -28,7 +28,7 @@ start16: movl $GD_FLG_COLD_BOOT, %ebx xorl %eax, %eax - movl %eax, %cr3 /* Invalidate TLB */ + movl %eax, %cr3 /* Invalidate TLB */ /* Turn off cache (this might require a 486-class CPU) */ movl %cr0, %eax @@ -49,7 +49,7 @@ o32 cs lgdt gdt_ptr jmp ff ff: - /* Finally restore BIST and jump to the 32bit initialization code */ + /* Finally restore BIST and jump to the 32-bit initialization code */ movw $code32start, %ax movw %ax, %bp movl %ecx, %eax @@ -64,17 +64,17 @@ idt_ptr: .word 0 /* limit */ .long 0 /* base */ -/* - * The following Global Descriptor Table is just enough to get us into - * 'Flat Protected Mode' - It will be discarded as soon as the final - * GDT is setup in a safe location in RAM - */ + /* + * The following Global Descriptor Table is just enough to get us into + * 'Flat Protected Mode' - It will be discarded as soon as the final + * GDT is setup in a safe location in RAM + */ gdt_ptr: .word 0x1f /* limit (31 bytes = 4 GDT entries - 1) */ .long BOOT_SEG + gdt /* base */ -/* Some CPUs are picky about GDT alignment... */ -.align 16 + /* Some CPUs are picky about GDT alignment... */ + .align 16 gdt: /* * The GDT table ... -- cgit v1.1 From 053b86e6d8e50359412e626c33bae3f7bafd74dd Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Tue, 20 Jan 2015 18:06:53 +0100 Subject: pci: tegra: Fix port information parsing commit a62e84d7b1824a202dd incorrectly changed the tegra pci code to the new fdtdec pci helpers. To get the device index of the root port, the "reg" property should be parsed from the dtb (as was previously the case). With this patch i can successfully network boot my jetson tk1 Signed-off-by: Sjoerd Simons Tested-by: Thierry Reding Acked-by: Thierry Reding --- drivers/pci/pci_tegra.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c index f9e05ad..67b5fdf 100644 --- a/drivers/pci/pci_tegra.c +++ b/drivers/pci/pci_tegra.c @@ -459,7 +459,6 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node, unsigned int *lanes) { struct fdt_pci_addr addr; - pci_dev_t bdf; int err; err = fdtdec_get_int(fdt, node, "nvidia,num-lanes", 0); @@ -470,13 +469,13 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node, *lanes = err; - err = fdtdec_get_pci_bdf(fdt, node, &addr, &bdf); + err = fdtdec_get_pci_addr(fdt, node, 0, "reg", &addr); if (err < 0) { error("failed to parse \"reg\" property"); return err; } - *index = PCI_DEV(bdf) - 1; + *index = PCI_DEV(addr.phys_hi) - 1; return 0; } -- cgit v1.1 From 5da38086bd6c39efd09e57900702b99541844339 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:06 -0700 Subject: x86: dts: Add compatible string for Intel ICH9 SPI controller Add this to the enum so that we can use the various fdtdec functions. A later commit will move this driver to driver model. Signed-off-by: Simon Glass --- include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/fdtdec.h b/include/fdtdec.h index 75af750..8c2bd21 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -173,6 +173,7 @@ enum fdt_compat_id { COMPAT_INTEL_MODEL_206AX, /* Intel Model 206AX CPU */ COMPAT_INTEL_GMA, /* Intel Graphics Media Accelerator */ COMPAT_AMS_AS3722, /* AMS AS3722 PMIC */ + COMPAT_INTEL_ICH_SPI, /* Intel ICH7/9 SPI controller */ COMPAT_COUNT, }; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 487122e..e989241 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -83,6 +83,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(INTEL_MODEL_206AX, "intel,model-206ax"), COMPAT(INTEL_GMA, "intel,gma"), COMPAT(AMS_AS3722, "ams,as3722"), + COMPAT(INTEL_ICH_SPI, "intel,ich-spi"), }; const char *fdtdec_get_compatible(enum fdt_compat_id id) -- cgit v1.1 From 9b0e35cb4889eb04a7ea5dd648d73df0bf37cc68 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:07 -0700 Subject: net: Add a separate file for IP checksumming Move the checksum code out into its own file so it can be used elsewhere. Also use a new version which supports a length which is not a multiple of 2 and add a new function to add two checksums. Signed-off-by: Simon Glass --- include/net.h | 30 +++++++++++++++++++++++++++++ net/Makefile | 1 + net/checksum.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 net/checksum.c diff --git a/include/net.h b/include/net.h index 3da35fe..73ea88b 100644 --- a/include/net.h +++ b/include/net.h @@ -482,6 +482,36 @@ extern void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source); extern void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, int sport, int len); +/** + * compute_ip_checksum() - Compute IP checksum + * + * @addr: Address to check (must be 16-bit aligned) + * @nbytes: Number of bytes to check (normally a multiple of 2) + * @return 16-bit IP checksum + */ +unsigned compute_ip_checksum(const void *addr, unsigned nbytes); + +/** + * add_ip_checksums() - add two IP checksums + * + * @offset: Offset of first sum (if odd we do a byte-swap) + * @sum: First checksum + * @new_sum: New checksum to add + * @return updated 16-bit IP checksum + */ +unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new_sum); + +/** + * ip_checksum_ok() - check if a checksum is correct + * + * This works by making sure the checksum sums to 0 + * + * @addr: Address to check (must be 16-bit aligned) + * @nbytes: Number of bytes to check (normally a multiple of 2) + * @return true if the checksum matches, false if not + */ +int ip_checksum_ok(const void *addr, unsigned nbytes); + /* Checksum */ extern int NetCksumOk(uchar *, int); /* Return true if cksum OK */ extern uint NetCksum(uchar *, int); /* Calculate the checksum */ diff --git a/net/Makefile b/net/Makefile index 9425950..e9cc8ad 100644 --- a/net/Makefile +++ b/net/Makefile @@ -7,6 +7,7 @@ #ccflags-y += -DDEBUG +obj-y += checksum.o obj-$(CONFIG_CMD_NET) += arp.o obj-$(CONFIG_CMD_NET) += bootp.o obj-$(CONFIG_CMD_CDP) += cdp.o diff --git a/net/checksum.c b/net/checksum.c new file mode 100644 index 0000000..a8c9ff5 --- /dev/null +++ b/net/checksum.c @@ -0,0 +1,60 @@ +/* + * This file was originally taken from the FreeBSD project. + * + * Copyright (c) 2001 Charles Mott + * Copyright (c) 2008 coresystems GmbH + * All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +unsigned compute_ip_checksum(const void *vptr, unsigned nbytes) +{ + int sum, oddbyte; + const unsigned short *ptr = vptr; + + sum = 0; + while (nbytes > 1) { + sum += *ptr++; + nbytes -= 2; + } + if (nbytes == 1) { + oddbyte = 0; + ((u8 *)&oddbyte)[0] = *(u8 *)ptr; + ((u8 *)&oddbyte)[1] = 0; + sum += oddbyte; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + sum = ~sum & 0xffff; + + return sum; +} + +unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new) +{ + unsigned long checksum; + + sum = ~sum & 0xffff; + new = ~new & 0xffff; + if (offset & 1) { + /* + * byte-swap the sum if it came from an odd offset; since the + * computation is endian independant this works. + */ + new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00); + } + checksum = sum + new; + if (checksum > 0xffff) + checksum -= 0xffff; + + return (~checksum) & 0xffff; +} + +int ip_checksum_ok(const void *addr, unsigned nbytes) +{ + return !(compute_ip_checksum(addr, nbytes) & 0xfffe); +} -- cgit v1.1 From b18c68d8918095672b295aef7bfbfc466b82c710 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:09 -0700 Subject: x86: Use ipchecksum from net/ The existing IP checksum function is only accessible to the 'coreboot' cpu. Drop it in favour of the new code in the network subsystem. Signed-off-by: Simon Glass --- arch/x86/cpu/coreboot/Makefile | 1 - arch/x86/cpu/coreboot/ipchecksum.c | 55 ------------------------- arch/x86/cpu/coreboot/tables.c | 8 ++-- arch/x86/include/asm/arch-coreboot/ipchecksum.h | 37 ----------------- 4 files changed, 4 insertions(+), 97 deletions(-) delete mode 100644 arch/x86/cpu/coreboot/ipchecksum.c delete mode 100644 arch/x86/include/asm/arch-coreboot/ipchecksum.h diff --git a/arch/x86/cpu/coreboot/Makefile b/arch/x86/cpu/coreboot/Makefile index 35e6cdd..b6e870a 100644 --- a/arch/x86/cpu/coreboot/Makefile +++ b/arch/x86/cpu/coreboot/Makefile @@ -16,7 +16,6 @@ obj-y += car.o obj-y += coreboot.o obj-y += tables.o -obj-y += ipchecksum.o obj-y += sdram.o obj-y += timestamp.o obj-$(CONFIG_PCI) += pci.o diff --git a/arch/x86/cpu/coreboot/ipchecksum.c b/arch/x86/cpu/coreboot/ipchecksum.c deleted file mode 100644 index 3340872..0000000 --- a/arch/x86/cpu/coreboot/ipchecksum.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the libpayload project. - * - * It has originally been taken from the FreeBSD project. - * - * Copyright (c) 2001 Charles Mott - * Copyright (c) 2008 coresystems GmbH - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include - -unsigned short ipchksum(const void *vptr, unsigned long nbytes) -{ - int sum, oddbyte; - const unsigned short *ptr = vptr; - - sum = 0; - while (nbytes > 1) { - sum += *ptr++; - nbytes -= 2; - } - if (nbytes == 1) { - oddbyte = 0; - ((u8 *)&oddbyte)[0] = *(u8 *) ptr; - ((u8 *)&oddbyte)[1] = 0; - sum += oddbyte; - } - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - return ~sum; -} diff --git a/arch/x86/cpu/coreboot/tables.c b/arch/x86/cpu/coreboot/tables.c index 92b7528..2b12b19 100644 --- a/arch/x86/cpu/coreboot/tables.c +++ b/arch/x86/cpu/coreboot/tables.c @@ -8,7 +8,7 @@ */ #include -#include +#include #include #include @@ -131,11 +131,11 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info) return 0; /* Make sure the checksums match. */ - if (ipchksum((u16 *) header, sizeof(*header)) != 0) + if (!ip_checksum_ok(header, sizeof(*header))) return -1; - if (ipchksum((u16 *) (ptr + sizeof(*header)), - header->table_bytes) != header->table_checksum) + if (compute_ip_checksum(ptr + sizeof(*header), header->table_bytes) != + header->table_checksum) return -1; /* Now, walk the tables. */ diff --git a/arch/x86/include/asm/arch-coreboot/ipchecksum.h b/arch/x86/include/asm/arch-coreboot/ipchecksum.h deleted file mode 100644 index 1d73b4d..0000000 --- a/arch/x86/include/asm/arch-coreboot/ipchecksum.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of the libpayload project. - * - * It has originally been taken from the FreeBSD project. - * - * Copyright (c) 2001 Charles Mott - * Copyright (c) 2008 coresystems GmbH - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _COREBOOT_IPCHECKSUM_H -#define _COREBOOT_IPCHECKSUM_H - -unsigned short ipchksum(const void *vptr, unsigned long nbytes); - -#endif -- cgit v1.1 From fc4860c089a6b6603e1ae4f9c1f8bd1b3aadfc8b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:10 -0700 Subject: x86: rtc: mc146818: Add helpers to read/write CMOS RAM On x86 we use CMOS RAM to read and write some settings. Add basic support for this, including access to registers 128-255. Signed-off-by: Simon Glass --- drivers/rtc/mc146818.c | 121 +++++++++++++++++++++++++++++-------------------- include/rtc.h | 32 +++++++++++++ 2 files changed, 105 insertions(+), 48 deletions(-) diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c index 39e6041..c9d318c 100644 --- a/drivers/rtc/mc146818.c +++ b/drivers/rtc/mc146818.c @@ -27,9 +27,6 @@ /* Set this to 1 to clear the CMOS RAM */ #define CLEAR_CMOS 0 -static uchar rtc_read (uchar reg); -static void rtc_write (uchar reg, uchar val); - #define RTC_PORT_MC146818 CONFIG_SYS_ISA_IO_BASE_ADDRESS + 0x70 #define RTC_SECONDS 0x00 #define RTC_SECONDS_ALARM 0x01 @@ -60,24 +57,24 @@ int rtc_get (struct rtc_time *tmp) { uchar sec, min, hour, mday, wday, mon, year; /* here check if rtc can be accessed */ - while((rtc_read(RTC_CONFIG_A)&0x80)==0x80); - sec = rtc_read (RTC_SECONDS); - min = rtc_read (RTC_MINUTES); - hour = rtc_read (RTC_HOURS); - mday = rtc_read (RTC_DATE_OF_MONTH); - wday = rtc_read (RTC_DAY_OF_WEEK); - mon = rtc_read (RTC_MONTH); - year = rtc_read (RTC_YEAR); + while ((rtc_read8(RTC_CONFIG_A) & 0x80) == 0x80); + sec = rtc_read8(RTC_SECONDS); + min = rtc_read8(RTC_MINUTES); + hour = rtc_read8(RTC_HOURS); + mday = rtc_read8(RTC_DATE_OF_MONTH); + wday = rtc_read8(RTC_DAY_OF_WEEK); + mon = rtc_read8(RTC_MONTH); + year = rtc_read8(RTC_YEAR); #ifdef RTC_DEBUG printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x " "hr: %02x min: %02x sec: %02x\n", year, mon, mday, wday, hour, min, sec ); printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n", - rtc_read (RTC_CONFIG_D) & 0x3F, - rtc_read (RTC_HOURS_ALARM), - rtc_read (RTC_MINUTES_ALARM), - rtc_read (RTC_SECONDS_ALARM) ); + rtc_read8(RTC_CONFIG_D) & 0x3F, + rtc_read8(RTC_HOURS_ALARM), + rtc_read8(RTC_MINUTES_ALARM), + rtc_read8(RTC_SECONDS_ALARM)); #endif tmp->tm_sec = bcd2bin (sec & 0x7F); tmp->tm_min = bcd2bin (min & 0x7F); @@ -108,80 +105,108 @@ int rtc_set (struct rtc_time *tmp) tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); #endif - rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */ + rtc_write8(RTC_CONFIG_B, 0x82); /* disable the RTC to update the regs */ - rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100)); - rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon)); - rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)); - rtc_write (RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday)); - rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour)); - rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min )); - rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec )); - rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */ + rtc_write8(RTC_YEAR, bin2bcd(tmp->tm_year % 100)); + rtc_write8(RTC_MONTH, bin2bcd(tmp->tm_mon)); + rtc_write8(RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)); + rtc_write8(RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday)); + rtc_write8(RTC_HOURS, bin2bcd(tmp->tm_hour)); + rtc_write8(RTC_MINUTES, bin2bcd(tmp->tm_min)); + rtc_write8(RTC_SECONDS, bin2bcd(tmp->tm_sec)); + rtc_write8(RTC_CONFIG_B, 0x02); /* enable the RTC to update the regs */ return 0; } void rtc_reset (void) { - rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */ - rtc_write(RTC_CONFIG_A,0x20); /* Normal OP */ - rtc_write(RTC_CONFIG_B,0x00); - rtc_write(RTC_CONFIG_B,0x00); - rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */ + rtc_write8(RTC_CONFIG_B, 0x82); /* disable the RTC to update the regs */ + rtc_write8(RTC_CONFIG_A, 0x20); /* Normal OP */ + rtc_write8(RTC_CONFIG_B, 0x00); + rtc_write8(RTC_CONFIG_B, 0x00); + rtc_write8(RTC_CONFIG_B, 0x02); /* enable the RTC to update the regs */ } /* ------------------------------------------------------------------------- */ -#ifdef CONFIG_SYS_RTC_REG_BASE_ADDR /* * use direct memory access */ -static uchar rtc_read (uchar reg) +int rtc_read8(int reg) { +#ifdef CONFIG_SYS_RTC_REG_BASE_ADDR return in8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg); +#else + int ofs = 0; + + if (reg >= 128) { + ofs = 2; + reg -= 128; + } + out8(RTC_PORT_MC146818 + ofs, reg); + + return in8(RTC_PORT_MC146818 + ofs + 1); +#endif } -static void rtc_write (uchar reg, uchar val) +void rtc_write8(int reg, uchar val) { +#ifdef CONFIG_SYS_RTC_REG_BASE_ADDR out8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg, val); -} #else -static uchar rtc_read (uchar reg) + int ofs = 0; + + if (reg >= 128) { + ofs = 2; + reg -= 128; + } + out8(RTC_PORT_MC146818 + ofs, reg); + out8(RTC_PORT_MC146818 + ofs + 1, val); +#endif +} + +u32 rtc_read32(int reg) { - out8(RTC_PORT_MC146818,reg); - return in8(RTC_PORT_MC146818 + 1); + u32 value = 0; + int i; + + for (i = 0; i < sizeof(value); i++) + value |= rtc_read8(reg + i) << (i << 3); + + return value; } -static void rtc_write (uchar reg, uchar val) +void rtc_write32(int reg, u32 value) { - out8(RTC_PORT_MC146818,reg); - out8(RTC_PORT_MC146818+1, val); + int i; + + for (i = 0; i < sizeof(value); i++) + rtc_write8(reg + i, (value >> (i << 3)) & 0xff); } -#endif void rtc_init(void) { #if CLEAR_CMOS int i; - rtc_write(RTC_SECONDS_ALARM, 0); - rtc_write(RTC_MINUTES_ALARM, 0); - rtc_write(RTC_HOURS_ALARM, 0); + rtc_write8(RTC_SECONDS_ALARM, 0); + rtc_write8(RTC_MINUTES_ALARM, 0); + rtc_write8(RTC_HOURS_ALARM, 0); for (i = RTC_CONFIG_A; i < RTC_REG_SIZE; i++) - rtc_write(i, 0); + rtc_write8(i, 0); printf("RTC: zeroing CMOS RAM\n"); #endif /* Setup the real time clock */ - rtc_write(RTC_CONFIG_B, RTC_CONFIG_B_24H); + rtc_write8(RTC_CONFIG_B, RTC_CONFIG_B_24H); /* Setup the frequency it operates at */ - rtc_write(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ | + rtc_write8(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ | RTC_CONFIG_A_RATE_1024HZ); /* Ensure all reserved bits are 0 in register D */ - rtc_write(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME); + rtc_write8(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME); /* Clear any pending interrupts */ - rtc_read(RTC_CONFIG_C); + rtc_read8(RTC_CONFIG_C); } #endif diff --git a/include/rtc.h b/include/rtc.h index d11aa8b..54e361e 100644 --- a/include/rtc.h +++ b/include/rtc.h @@ -51,6 +51,38 @@ unsigned long mktime (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); /** + * rtc_read8() - Read an 8-bit register + * + * @reg: Register to read + * @return value read + */ +int rtc_read8(int reg); + +/** + * rtc_write8() - Write an 8-bit register + * + * @reg: Register to write + * @value: Value to write + */ +void rtc_write8(int reg, uchar val); + +/** + * rtc_read32() - Read a 32-bit value from the RTC + * + * @reg: Offset to start reading from + * @return value read + */ +u32 rtc_read32(int reg); + +/** + * rtc_write32() - Write a 32-bit value to the RTC + * + * @reg: Register to start writing to + * @value: Value to write + */ +void rtc_write32(int reg, u32 value); + +/** * rtc_init() - Set up the real time clock ready for use */ void rtc_init(void); -- cgit v1.1 From 8e899af0597a43d70752654b227f308dd0d0039c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:11 -0700 Subject: x86: spi: Add device tree support As a temporary measure before the ICH driver moves over to driver model, add device tree support to the driver. Signed-off-by: Simon Glass --- drivers/spi/ich.c | 7 +++++++ include/configs/x86-common.h | 1 + 2 files changed, 8 insertions(+) diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index 0379444..fdff158 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -153,6 +153,13 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, return &ich->slave; } +struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node, + int spi_node) +{ + /* We only support a single SPI at present */ + return spi_setup_slave(0, 0, 20000000, 0); +} + void spi_free_slave(struct spi_slave *slave) { struct ich_spi_slave *ich = to_ich_spi(slave); diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index 4f0a3c5..ecedfc3 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -211,6 +211,7 @@ #define CONFIG_CMD_SF_TEST #define CONFIG_CMD_SPI #define CONFIG_SPI +#define CONFIG_OF_SPI_FLASH /*----------------------------------------------------------------------- * Environment configuration -- cgit v1.1 From 146251f87eaebbd77ca9596391890b44cbda47fb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:12 -0700 Subject: Allow architecture-specific memory reservation All memory to be reserved for use after relocation by adding a new call to perform this reservation. Signed-off-by: Simon Glass --- common/board_f.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/common/board_f.c b/common/board_f.c index 3a4b32c..215108b 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -807,6 +807,12 @@ static int initf_dm(void) return 0; } +/* Architecture-specific memory reservation */ +__weak int reserve_arch(void) +{ + return 0; +} + static init_fnc_t init_sequence_f[] = { #ifdef CONFIG_SANDBOX setup_ram_buf, @@ -970,6 +976,7 @@ static init_fnc_t init_sequence_f[] = { setup_machine, reserve_global_data, reserve_fdt, + reserve_arch, reserve_stacks, setup_dram_config, show_dram_config, -- cgit v1.1 From a9aff2f46a7f7d29a662531dbc181773f16a606d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:13 -0700 Subject: x86: dts: Add SPI flash MRC details for chromebook_link Correct the SPI flash compatible string, add an alias and specify the position of the MRC cache, used to store SDRAM training settings for the Memory Reference Code. Signed-off-by: Simon Glass --- arch/x86/dts/chromebook_link.dts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts index 9490b16..45ada61 100644 --- a/arch/x86/dts/chromebook_link.dts +++ b/arch/x86/dts/chromebook_link.dts @@ -7,6 +7,10 @@ model = "Google Link"; compatible = "google,link", "intel,celeron-ivybridge"; + aliases { + spi0 = "/spi"; + }; + config { silent_console = <0>; }; @@ -150,11 +154,20 @@ spi { #address-cells = <1>; #size-cells = <0>; - compatible = "intel,ich9"; + compatible = "intel,ich-spi"; spi-flash@0 { + #size-cells = <1>; + #address-cells = <1>; reg = <0>; compatible = "winbond,w25q64", "spi-flash"; memory-map = <0xff800000 0x00800000>; + rw-mrc-cache { + label = "rw-mrc-cache"; + /* Alignment: 4k (for updating) */ + reg = <0x003e0000 0x00010000>; + type = "wiped"; + wipe-value = [ff]; + }; }; }; -- cgit v1.1 From 191c008a2155f99fc6476539878640b4032a457b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:14 -0700 Subject: x86: Implement a cache for Memory Reference Code parameters The memory reference code takes a very long time to 'train' its SDRAM interface, around half a second. To avoid this delay on every boot we can store the parameters from the last training sessions to speed up the next. Add an implementation of this, storing the training data in CMOS RAM and SPI flash. Signed-off-by: Simon Glass --- arch/x86/cpu/ivybridge/Makefile | 1 + arch/x86/cpu/ivybridge/mrccache.c | 156 +++++++++++++++ arch/x86/cpu/ivybridge/sdram.c | 253 +++++++++++++++++++++++++ arch/x86/include/asm/arch-ivybridge/mrccache.h | 51 +++++ arch/x86/include/asm/global_data.h | 3 + 5 files changed, 464 insertions(+) create mode 100644 arch/x86/cpu/ivybridge/mrccache.c create mode 100644 arch/x86/include/asm/arch-ivybridge/mrccache.h diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile index 0c7efae..3576b83 100644 --- a/arch/x86/cpu/ivybridge/Makefile +++ b/arch/x86/cpu/ivybridge/Makefile @@ -14,6 +14,7 @@ obj-y += lpc.o obj-y += me_status.o obj-y += model_206ax.o obj-y += microcode_intel.o +obj-y += mrccache.o obj-y += northbridge.o obj-y += pch.o obj-y += pci.o diff --git a/arch/x86/cpu/ivybridge/mrccache.c b/arch/x86/cpu/ivybridge/mrccache.c new file mode 100644 index 0000000..0f1a64b --- /dev/null +++ b/arch/x86/cpu/ivybridge/mrccache.c @@ -0,0 +1,156 @@ +/* + * From Coreboot src/southbridge/intel/bd82x6x/mrccache.c + * + * Copyright (C) 2014 Google Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct mrc_data_container *next_mrc_block( + struct mrc_data_container *mrc_cache) +{ + /* MRC data blocks are aligned within the region */ + u32 mrc_size = sizeof(*mrc_cache) + mrc_cache->data_size; + if (mrc_size & (MRC_DATA_ALIGN - 1UL)) { + mrc_size &= ~(MRC_DATA_ALIGN - 1UL); + mrc_size += MRC_DATA_ALIGN; + } + + u8 *region_ptr = (u8 *)mrc_cache; + region_ptr += mrc_size; + return (struct mrc_data_container *)region_ptr; +} + +static int is_mrc_cache(struct mrc_data_container *cache) +{ + return cache && (cache->signature == MRC_DATA_SIGNATURE); +} + +/* + * Find the largest index block in the MRC cache. Return NULL if none is + * found. + */ +struct mrc_data_container *mrccache_find_current(struct fmap_entry *entry) +{ + struct mrc_data_container *cache, *next; + ulong base_addr, end_addr; + uint id; + + base_addr = (1ULL << 32) - CONFIG_ROM_SIZE + entry->offset; + end_addr = base_addr + entry->length; + cache = NULL; + + /* Search for the last filled entry in the region */ + for (id = 0, next = (struct mrc_data_container *)base_addr; + is_mrc_cache(next); + id++) { + cache = next; + next = next_mrc_block(next); + if ((ulong)next >= end_addr) + break; + } + + if (id-- == 0) { + debug("%s: No valid MRC cache found.\n", __func__); + return NULL; + } + + /* Verify checksum */ + if (cache->checksum != compute_ip_checksum(cache->data, + cache->data_size)) { + printf("%s: MRC cache checksum mismatch\n", __func__); + return NULL; + } + + debug("%s: picked entry %u from cache block\n", __func__, id); + + return cache; +} + +/** + * find_next_mrc_cache() - get next cache entry + * + * @entry: MRC cache flash area + * @cache: Entry to start from + * + * @return next cache entry if found, NULL if we got to the end + */ +static struct mrc_data_container *find_next_mrc_cache(struct fmap_entry *entry, + struct mrc_data_container *cache) +{ + ulong base_addr, end_addr; + + base_addr = (1ULL << 32) - CONFIG_ROM_SIZE + entry->offset; + end_addr = base_addr + entry->length; + + cache = next_mrc_block(cache); + if ((ulong)cache >= end_addr) { + /* Crossed the boundary */ + cache = NULL; + debug("%s: no available entries found\n", __func__); + } else { + debug("%s: picked next entry from cache block at %p\n", + __func__, cache); + } + + return cache; +} + +int mrccache_update(struct spi_flash *sf, struct fmap_entry *entry, + struct mrc_data_container *cur) +{ + struct mrc_data_container *cache; + ulong offset; + ulong base_addr; + int ret; + + /* Find the last used block */ + base_addr = (1ULL << 32) - CONFIG_ROM_SIZE + entry->offset; + debug("Updating MRC cache data\n"); + cache = mrccache_find_current(entry); + if (cache && (cache->data_size == cur->data_size) && + (!memcmp(cache, cur, cache->data_size + sizeof(*cur)))) { + debug("MRC data in flash is up to date. No update\n"); + return -EEXIST; + } + + /* Move to the next block, which will be the first unused block */ + if (cache) + cache = find_next_mrc_cache(entry, cache); + + /* + * If we have got to the end, erase the entire mrc-cache area and start + * again at block 0. + */ + if (!cache) { + debug("Erasing the MRC cache region of %x bytes at %x\n", + entry->length, entry->offset); + + ret = spi_flash_erase(sf, entry->offset, entry->length); + if (ret) { + debug("Failed to erase flash region\n"); + return ret; + } + cache = (struct mrc_data_container *)base_addr; + } + + /* Write the data out */ + offset = (ulong)cache - base_addr + entry->offset; + debug("Write MRC cache update to flash at %lx\n", offset); + ret = spi_flash_write(sf, offset, cur->data_size + sizeof(*cur), cur); + if (ret) { + debug("Failed to write to SPI flash\n"); + return ret; + } + + return 0; +} diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c index 9504735..4963448 100644 --- a/arch/x86/cpu/ivybridge/sdram.c +++ b/arch/x86/cpu/ivybridge/sdram.c @@ -14,12 +14,17 @@ #include #include #include +#include +#include +#include +#include #include #include #include #include #include #include +#include #include #include #include @@ -27,6 +32,10 @@ DECLARE_GLOBAL_DATA_PTR; +#define CMOS_OFFSET_MRC_SEED 152 +#define CMOS_OFFSET_MRC_SEED_S3 156 +#define CMOS_OFFSET_MRC_SEED_CHK 160 + /* * This function looks for the highest region of memory lower than 4GB which * has enough space for U-Boot where U-Boot is aligned on a page boundary. @@ -80,6 +89,202 @@ void dram_init_banksize(void) } } +static int get_mrc_entry(struct spi_flash **sfp, struct fmap_entry *entry) +{ + const void *blob = gd->fdt_blob; + int node, spi_node, mrc_node; + int upto; + + /* Find the flash chip within the SPI controller node */ + upto = 0; + spi_node = fdtdec_next_alias(blob, "spi", COMPAT_INTEL_ICH_SPI, &upto); + if (spi_node < 0) + return -ENOENT; + node = fdt_first_subnode(blob, spi_node); + if (node < 0) + return -ECHILD; + + /* Find the place where we put the MRC cache */ + mrc_node = fdt_subnode_offset(blob, node, "rw-mrc-cache"); + if (mrc_node < 0) + return -EPERM; + + if (fdtdec_read_fmap_entry(blob, mrc_node, "rm-mrc-cache", entry)) + return -EINVAL; + + if (sfp) { + *sfp = spi_flash_probe_fdt(blob, node, spi_node); + if (!*sfp) + return -EBADF; + } + + return 0; +} + +static int read_seed_from_cmos(struct pei_data *pei_data) +{ + u16 c1, c2, checksum, seed_checksum; + + /* + * Read scrambler seeds from CMOS RAM. We don't want to store them in + * SPI flash since they change on every boot and that would wear down + * the flash too much. So we store these in CMOS and the large MRC + * data in SPI flash. + */ + pei_data->scrambler_seed = rtc_read32(CMOS_OFFSET_MRC_SEED); + debug("Read scrambler seed 0x%08x from CMOS 0x%02x\n", + pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED); + + pei_data->scrambler_seed_s3 = rtc_read32(CMOS_OFFSET_MRC_SEED_S3); + debug("Read S3 scrambler seed 0x%08x from CMOS 0x%02x\n", + pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3); + + /* Compute seed checksum and compare */ + c1 = compute_ip_checksum((u8 *)&pei_data->scrambler_seed, + sizeof(u32)); + c2 = compute_ip_checksum((u8 *)&pei_data->scrambler_seed_s3, + sizeof(u32)); + checksum = add_ip_checksums(sizeof(u32), c1, c2); + + seed_checksum = rtc_read8(CMOS_OFFSET_MRC_SEED_CHK); + seed_checksum |= rtc_read8(CMOS_OFFSET_MRC_SEED_CHK + 1) << 8; + + if (checksum != seed_checksum) { + debug("%s: invalid seed checksum\n", __func__); + pei_data->scrambler_seed = 0; + pei_data->scrambler_seed_s3 = 0; + return -EINVAL; + } + + return 0; +} + +static int prepare_mrc_cache(struct pei_data *pei_data) +{ + struct mrc_data_container *mrc_cache; + struct fmap_entry entry; + int ret; + + ret = read_seed_from_cmos(pei_data); + if (ret) + return ret; + ret = get_mrc_entry(NULL, &entry); + if (ret) + return ret; + mrc_cache = mrccache_find_current(&entry); + if (!mrc_cache) + return -ENOENT; + + /* + * TODO(sjg@chromium.org): Skip this for now as it causes boot + * problems + */ + if (0) { + pei_data->mrc_input = mrc_cache->data; + pei_data->mrc_input_len = mrc_cache->data_size; + } + debug("%s: at %p, size %x checksum %04x\n", __func__, + pei_data->mrc_input, pei_data->mrc_input_len, + mrc_cache->checksum); + + return 0; +} + +static int build_mrc_data(struct mrc_data_container **datap) +{ + struct mrc_data_container *data; + int orig_len; + int output_len; + + orig_len = gd->arch.mrc_output_len; + output_len = ALIGN(orig_len, 16); + data = malloc(output_len + sizeof(*data)); + if (!data) + return -ENOMEM; + data->signature = MRC_DATA_SIGNATURE; + data->data_size = output_len; + data->reserved = 0; + memcpy(data->data, gd->arch.mrc_output, orig_len); + + /* Zero the unused space in aligned buffer. */ + if (output_len > orig_len) + memset(data->data + orig_len, 0, output_len - orig_len); + + data->checksum = compute_ip_checksum(data->data, output_len); + *datap = data; + + return 0; +} + +static int write_seeds_to_cmos(struct pei_data *pei_data) +{ + u16 c1, c2, checksum; + + /* Save the MRC seed values to CMOS */ + rtc_write32(CMOS_OFFSET_MRC_SEED, pei_data->scrambler_seed); + debug("Save scrambler seed 0x%08x to CMOS 0x%02x\n", + pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED); + + rtc_write32(CMOS_OFFSET_MRC_SEED_S3, pei_data->scrambler_seed_s3); + debug("Save s3 scrambler seed 0x%08x to CMOS 0x%02x\n", + pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3); + + /* Save a simple checksum of the seed values */ + c1 = compute_ip_checksum((u8 *)&pei_data->scrambler_seed, + sizeof(u32)); + c2 = compute_ip_checksum((u8 *)&pei_data->scrambler_seed_s3, + sizeof(u32)); + checksum = add_ip_checksums(sizeof(u32), c1, c2); + + rtc_write8(CMOS_OFFSET_MRC_SEED_CHK, checksum & 0xff); + rtc_write8(CMOS_OFFSET_MRC_SEED_CHK + 1, (checksum >> 8) & 0xff); + + return 0; +} + +static int sdram_save_mrc_data(void) +{ + struct mrc_data_container *data; + struct fmap_entry entry; + struct spi_flash *sf; + int ret; + + if (!gd->arch.mrc_output_len) + return 0; + debug("Saving %d bytes of MRC output data to SPI flash\n", + gd->arch.mrc_output_len); + + ret = get_mrc_entry(&sf, &entry); + if (ret) + goto err_entry; + ret = build_mrc_data(&data); + if (ret) + goto err_data; + ret = mrccache_update(sf, &entry, data); + if (!ret) + debug("Saved MRC data with checksum %04x\n", data->checksum); + + free(data); +err_data: + spi_flash_free(sf); +err_entry: + if (ret) + debug("%s: Failed: %d\n", __func__, ret); + return ret; +} + +/* Use this hook to save our SDRAM parameters */ +int misc_init_r(void) +{ + int ret; + + ret = sdram_save_mrc_data(); + if (ret) + printf("Unable to save MRC data: %d\n", ret); + + return 0; +} + static const char *const ecc_decoder[] = { "inactive", "active on IO", @@ -142,6 +347,11 @@ static asmlinkage void console_tx_byte(unsigned char byte) #endif } +static int recovery_mode_enabled(void) +{ + return false; +} + /** * Find the PEI executable in the ROM and execute it. * @@ -166,6 +376,17 @@ int sdram_initialise(struct pei_data *pei_data) debug("Starting UEFI PEI System Agent\n"); + /* + * Do not pass MRC data in for recovery mode boot, + * Always pass it in for S3 resume. + */ + if (!recovery_mode_enabled() || + pei_data->boot_mode == PEI_BOOT_RESUME) { + ret = prepare_mrc_cache(pei_data); + if (ret) + debug("prepare_mrc_cache failed: %d\n", ret); + } + /* If MRC data is not found we cannot continue S3 resume. */ if (pei_data->boot_mode == PEI_BOOT_RESUME && !pei_data->mrc_input) { debug("Giving up in sdram_initialize: No MRC data\n"); @@ -216,6 +437,8 @@ int sdram_initialise(struct pei_data *pei_data) debug("System Agent Version %d.%d.%d Build %d\n", version >> 24 , (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); + debug("MCR output data length %#x at %p\n", pei_data->mrc_output_len, + pei_data->mrc_output); /* * Send ME init done for SandyBridge here. This is done inside the @@ -231,6 +454,36 @@ int sdram_initialise(struct pei_data *pei_data) post_system_agent_init(pei_data); report_memory_config(); + /* S3 resume: don't save scrambler seed or MRC data */ + if (pei_data->boot_mode != PEI_BOOT_RESUME) { + /* + * This will be copied to SDRAM in reserve_arch(), then written + * to SPI flash in sdram_save_mrc_data() + */ + gd->arch.mrc_output = (char *)pei_data->mrc_output; + gd->arch.mrc_output_len = pei_data->mrc_output_len; + ret = write_seeds_to_cmos(pei_data); + if (ret) + debug("Failed to write seeds to CMOS: %d\n", ret); + } + + return 0; +} + +int reserve_arch(void) +{ + u16 checksum; + + checksum = compute_ip_checksum(gd->arch.mrc_output, + gd->arch.mrc_output_len); + debug("Saving %d bytes for MRC output data, checksum %04x\n", + gd->arch.mrc_output_len, checksum); + gd->start_addr_sp -= gd->arch.mrc_output_len; + memcpy((void *)gd->start_addr_sp, gd->arch.mrc_output, + gd->arch.mrc_output_len); + gd->arch.mrc_output = (char *)gd->start_addr_sp; + gd->start_addr_sp &= ~0xf; + return 0; } diff --git a/arch/x86/include/asm/arch-ivybridge/mrccache.h b/arch/x86/include/asm/arch-ivybridge/mrccache.h new file mode 100644 index 0000000..968b2ef --- /dev/null +++ b/arch/x86/include/asm/arch-ivybridge/mrccache.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARCH_MRCCACHE_H +#define _ASM_ARCH_MRCCACHE_H + +#define MRC_DATA_ALIGN 0x1000 +#define MRC_DATA_SIGNATURE (('M' << 0) | ('R' << 8) | ('C' << 16) | \ + ('D'<<24)) + +__packed struct mrc_data_container { + u32 signature; /* "MRCD" */ + u32 data_size; /* Size of the 'data' field */ + u32 checksum; /* IP style checksum */ + u32 reserved; /* For header alignment */ + u8 data[0]; /* Variable size, platform/run time dependent */ +}; + +struct fmap_entry; +struct spi_flash; + +/** + * mrccache_find_current() - find the latest MRC cache record + * + * This searches the MRC cache region looking for the latest record to use + * for setting up SDRAM + * + * @entry: Information about the position and size of the MRC cache + * @return pointer to latest record, or NULL if none + */ +struct mrc_data_container *mrccache_find_current(struct fmap_entry *entry); + +/** + * mrccache_update() - update the MRC cache with a new record + * + * This writes a new record to the end of the MRC cache. If the new record is + * the same as the latest record then the write is skipped + * + * @sf: SPI flash to write to + * @entry: Position and size of MRC cache in SPI flash + * @cur: Record to write + * @return 0 if updated, -EEXIST if the record is the same as the latest + * record, other error if SPI write failed + */ +int mrccache_update(struct spi_flash *sf, struct fmap_entry *entry, + struct mrc_data_container *cur); + +#endif diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 243ed5c..5ee06eb 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -65,6 +65,9 @@ struct arch_global_data { struct mtrr_request mtrr_req[MAX_MTRR_REQUESTS]; int mtrr_req_count; int has_mtrr; + /* MRC training data to save for the next boot */ + char *mrc_output; + unsigned int mrc_output_len; }; #endif -- cgit v1.1 From 069f5481ba19b819ef11ba23181a264fc566b180 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:15 -0700 Subject: x86: config: Enable hook for saving MRC configuration Add a hook to ensure that this information is saved. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/coreboot/coreboot.c | 5 +++++ include/configs/chromebook_link.h | 1 + 2 files changed, 6 insertions(+) diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c index 6d06d5a..4cdd0d4 100644 --- a/arch/x86/cpu/coreboot/coreboot.c +++ b/arch/x86/cpu/coreboot/coreboot.c @@ -99,3 +99,8 @@ void panic_puts(const char *str) while (*str) NS16550_putc(port, *str++); } + +int misc_init_r(void) +{ + return 0; +} diff --git a/include/configs/chromebook_link.h b/include/configs/chromebook_link.h index 7e6d239..6e8b9ef 100644 --- a/include/configs/chromebook_link.h +++ b/include/configs/chromebook_link.h @@ -20,6 +20,7 @@ #define CONFIG_DCACHE_RAM_MRC_VAR_SIZE 0x4000 #define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_MISC_INIT_R #define CONFIG_NR_DRAM_BANKS 8 #define CONFIG_X86_MRC_ADDR 0xfffa0000 -- cgit v1.1 From 380ab5cc27051781864dea1f895181026954ab58 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:16 -0700 Subject: x86: ivybridge: Drop the Kconfig MRC cache information This is now stored in the device tree. Signed-off-by: Simon Glass --- arch/x86/cpu/ivybridge/Kconfig | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/arch/x86/cpu/ivybridge/Kconfig b/arch/x86/cpu/ivybridge/Kconfig index afca957..e4595be 100644 --- a/arch/x86/cpu/ivybridge/Kconfig +++ b/arch/x86/cpu/ivybridge/Kconfig @@ -26,20 +26,6 @@ config CACHE_MRC_SIZE_KB int default 256 -config MRC_CACHE_BASE - hex - default 0xff800000 - -config MRC_CACHE_LOCATION - hex - depends on !CHROMEOS - default 0x1ec000 - -config MRC_CACHE_SIZE - hex - depends on !CHROMEOS - default 0x10000 - config DCACHE_RAM_BASE hex default 0xff7f0000 @@ -64,20 +50,6 @@ config CACHE_MRC_SIZE_KB int default 512 -config MRC_CACHE_BASE - hex - default 0xff800000 - -config MRC_CACHE_LOCATION - hex - depends on !CHROMEOS - default 0x370000 - -config MRC_CACHE_SIZE - hex - depends on !CHROMEOS - default 0x10000 - config DCACHE_RAM_BASE hex default 0xff7e0000 -- cgit v1.1 From e43ade3749ff10bc313f33bf23705465e4163896 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:17 -0700 Subject: x86: config: chromebook_link: Enable environment Enable an environment area. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- include/configs/chromebook_link.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/configs/chromebook_link.h b/include/configs/chromebook_link.h index 6e8b9ef..7b460e8 100644 --- a/include/configs/chromebook_link.h +++ b/include/configs/chromebook_link.h @@ -64,6 +64,13 @@ #define CONFIG_CMD_CROS_EC #define CONFIG_ARCH_EARLY_INIT_R +#undef CONFIG_ENV_IS_NOWHERE +#undef CONFIG_ENV_SIZE +#define CONFIG_ENV_SIZE 0x1000 +#define CONFIG_ENV_SECT_SIZE 0x1000 +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_OFFSET 0x003f8000 + #define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \ "stdout=vga,serial\0" \ "stderr=vga,serial\0" -- cgit v1.1