Commit f9677375 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull Intel Quark SoC support from Ingo Molnar:
 "This adds support for Intel Quark X1000 SoC boards, used in the low
  power 32-bit x86 Intel Galileo microcontroller board intended for the
  Arduino space.

  There's been some preparatory core x86 patches for Quark CPU quirks
  merged already, but this rounds it all up and adds Kconfig enablement.
  It's a clean hardware enablement addition tree at this point"

* 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/intel/quark: Fix simple_return.cocci warnings
  x86/intel/quark: Fix ptr_ret.cocci warnings
  x86/intel/quark: Add Intel Quark platform support
  x86/intel/quark: Add Isolated Memory Regions for Quark X1000
parents f3c233d7 c11a25f4
......@@ -488,6 +488,22 @@ config X86_INTEL_MID
Intel MID platforms are based on an Intel processor and chipset which
consume less power than most of the x86 derivatives.
config X86_INTEL_QUARK
bool "Intel Quark platform support"
depends on X86_32
depends on X86_EXTENDED_PLATFORM
depends on X86_PLATFORM_DEVICES
depends on X86_TSC
depends on PCI
depends on PCI_GOANY
depends on X86_IO_APIC
select IOSF_MBI
select INTEL_IMR
---help---
Select to include support for Quark X1000 SoC.
Say Y here if you have a Quark based system such as the Arduino
compatible Intel Galileo.
config X86_INTEL_LPSS
bool "Intel Low Power Subsystem Support"
depends on ACPI
......
......@@ -313,6 +313,19 @@ config DEBUG_NMI_SELFTEST
If unsure, say N.
config DEBUG_IMR_SELFTEST
bool "Isolated Memory Region self test"
default n
depends on INTEL_IMR
---help---
This option enables automated sanity testing of the IMR code.
Some simple tests are run to verify IMR bounds checking, alignment
and overlapping. This option is really only useful if you are
debugging an IMR memory map or are modifying the IMR code and want to
test your changes.
If unsure say N here.
config X86_DEBUG_STATIC_CPU_HAS
bool "Debug alternatives"
depends on DEBUG_KERNEL
......
/*
* imr.h: Isolated Memory Region API
*
* Copyright(c) 2013 Intel Corporation.
* Copyright(c) 2015 Bryan O'Donoghue <pure.logic@nexus-software.ie>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#ifndef _IMR_H
#define _IMR_H
#include <linux/types.h>
/*
* IMR agent access mask bits
* See section 12.7.4.7 from quark-x1000-datasheet.pdf for register
* definitions.
*/
#define IMR_ESRAM_FLUSH BIT(31)
#define IMR_CPU_SNOOP BIT(30) /* Applicable only to write */
#define IMR_RMU BIT(29)
#define IMR_VC1_SAI_ID3 BIT(15)
#define IMR_VC1_SAI_ID2 BIT(14)
#define IMR_VC1_SAI_ID1 BIT(13)
#define IMR_VC1_SAI_ID0 BIT(12)
#define IMR_VC0_SAI_ID3 BIT(11)
#define IMR_VC0_SAI_ID2 BIT(10)
#define IMR_VC0_SAI_ID1 BIT(9)
#define IMR_VC0_SAI_ID0 BIT(8)
#define IMR_CPU_0 BIT(1) /* SMM mode */
#define IMR_CPU BIT(0) /* Non SMM mode */
#define IMR_ACCESS_NONE 0
/*
* Read/Write access-all bits here include some reserved bits
* These are the values firmware uses and are accepted by hardware.
* The kernel defines read/write access-all in the same way as firmware
* in order to have a consistent and crisp definition across firmware,
* bootloader and kernel.
*/
#define IMR_READ_ACCESS_ALL 0xBFFFFFFF
#define IMR_WRITE_ACCESS_ALL 0xFFFFFFFF
/* Number of IMRs provided by Quark X1000 SoC */
#define QUARK_X1000_IMR_MAX 0x08
#define QUARK_X1000_IMR_REGBASE 0x40
/* IMR alignment bits - only bits 31:10 are checked for IMR validity */
#define IMR_ALIGN 0x400
#define IMR_MASK (IMR_ALIGN - 1)
int imr_add_range(phys_addr_t base, size_t size,
unsigned int rmask, unsigned int wmask, bool lock);
int imr_remove_range(phys_addr_t base, size_t size);
#endif /* _IMR_H */
......@@ -5,6 +5,7 @@ obj-y += geode/
obj-y += goldfish/
obj-y += iris/
obj-y += intel-mid/
obj-y += intel-quark/
obj-y += olpc/
obj-y += scx200/
obj-y += sfi/
......
obj-$(CONFIG_INTEL_IMR) += imr.o
obj-$(CONFIG_DEBUG_IMR_SELFTEST) += imr_selftest.o
This diff is collapsed.
/**
* imr_selftest.c
*
* Copyright(c) 2013 Intel Corporation.
* Copyright(c) 2015 Bryan O'Donoghue <pure.logic@nexus-software.ie>
*
* IMR self test. The purpose of this module is to run a set of tests on the
* IMR API to validate it's sanity. We check for overlapping, reserved
* addresses and setup/teardown sanity.
*
*/
#include <asm-generic/sections.h>
#include <asm/imr.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/types.h>
#define SELFTEST KBUILD_MODNAME ": "
/**
* imr_self_test_result - Print result string for self test.
*
* @res: result code - true if test passed false otherwise.
* @fmt: format string.
* ... variadic argument list.
*/
static void __init imr_self_test_result(int res, const char *fmt, ...)
{
va_list vlist;
/* Print pass/fail. */
if (res)
pr_info(SELFTEST "pass ");
else
pr_info(SELFTEST "fail ");
/* Print variable string. */
va_start(vlist, fmt);
vprintk(fmt, vlist);
va_end(vlist);
/* Optional warning. */
WARN(res == 0, "test failed");
}
#undef SELFTEST
/**
* imr_self_test
*
* Verify IMR self_test with some simple tests to verify overlap,
* zero sized allocations and 1 KiB sized areas.
*
*/
static void __init imr_self_test(void)
{
phys_addr_t base = virt_to_phys(&_text);
size_t size = virt_to_phys(&__end_rodata) - base;
const char *fmt_over = "overlapped IMR @ (0x%08lx - 0x%08lx)\n";
int ret;
/* Test zero zero. */
ret = imr_add_range(0, 0, 0, 0, false);
imr_self_test_result(ret < 0, "zero sized IMR\n");
/* Test exact overlap. */
ret = imr_add_range(base, size, IMR_CPU, IMR_CPU, false);
imr_self_test_result(ret < 0, fmt_over, __va(base), __va(base + size));
/* Test overlap with base inside of existing. */
base += size - IMR_ALIGN;
ret = imr_add_range(base, size, IMR_CPU, IMR_CPU, false);
imr_self_test_result(ret < 0, fmt_over, __va(base), __va(base + size));
/* Test overlap with end inside of existing. */
base -= size + IMR_ALIGN * 2;
ret = imr_add_range(base, size, IMR_CPU, IMR_CPU, false);
imr_self_test_result(ret < 0, fmt_over, __va(base), __va(base + size));
/* Test that a 1 KiB IMR @ zero with read/write all will bomb out. */
ret = imr_add_range(0, IMR_ALIGN, IMR_READ_ACCESS_ALL,
IMR_WRITE_ACCESS_ALL, false);
imr_self_test_result(ret < 0, "1KiB IMR @ 0x00000000 - access-all\n");
/* Test that a 1 KiB IMR @ zero with CPU only will work. */
ret = imr_add_range(0, IMR_ALIGN, IMR_CPU, IMR_CPU, false);
imr_self_test_result(ret >= 0, "1KiB IMR @ 0x00000000 - cpu-access\n");
if (ret >= 0) {
ret = imr_remove_range(0, IMR_ALIGN);
imr_self_test_result(ret == 0, "teardown - cpu-access\n");
}
/* Test 2 KiB works. */
size = IMR_ALIGN * 2;
ret = imr_add_range(0, size, IMR_READ_ACCESS_ALL,
IMR_WRITE_ACCESS_ALL, false);
imr_self_test_result(ret >= 0, "2KiB IMR @ 0x00000000\n");
if (ret >= 0) {
ret = imr_remove_range(0, size);
imr_self_test_result(ret == 0, "teardown 2KiB\n");
}
}
/**
* imr_self_test_init - entry point for IMR driver.
*
* return: -ENODEV for no IMR support 0 if good to go.
*/
static int __init imr_self_test_init(void)
{
imr_self_test();
return 0;
}
/**
* imr_self_test_exit - exit point for IMR code.
*
* return:
*/
static void __exit imr_self_test_exit(void)
{
}
module_init(imr_self_test_init);
module_exit(imr_self_test_exit);
MODULE_AUTHOR("Bryan O'Donoghue <pure.logic@nexus-software.ie>");
MODULE_DESCRIPTION("Intel Isolated Memory Region self-test driver");
MODULE_LICENSE("Dual BSD/GPL");
......@@ -735,6 +735,31 @@ config INTEL_IPS
functionality. If in doubt, say Y here; it will only load on
supported platforms.
config INTEL_IMR
bool "Intel Isolated Memory Region support"
default n
depends on X86_INTEL_QUARK && IOSF_MBI
---help---
This option provides a means to manipulate Isolated Memory Regions.
IMRs are a set of registers that define read and write access masks
to prohibit certain system agents from accessing memory with 1 KiB
granularity.
IMRs make it possible to control read/write access to an address
by hardware agents inside the SoC. Read and write masks can be
defined for:
- eSRAM flush
- Dirty CPU snoop (write only)
- RMU access
- PCI Virtual Channel 0/Virtual Channel 1
- SMM mode
- Non SMM mode
Quark contains a set of eight IMR registers and makes use of those
registers during its bootup process.
If you are running on a Galileo/Quark say Y here.
config IBM_RTL
tristate "Device driver to enable PRTL support"
depends on X86 && PCI
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment