diff --git a/examples/galileo/Makefile b/examples/galileo/Makefile index f925f565a..94a327bfd 100644 --- a/examples/galileo/Makefile +++ b/examples/galileo/Makefile @@ -1,6 +1,6 @@ TARGET=galileo -KNOWN_EXAMPLES = gpio-input gpio-output gpio-interrupt i2c-LSM9DS0 i2c-callbacks +KNOWN_EXAMPLES = gpio-input gpio-output gpio-interrupt i2c-LSM9DS0 i2c-callbacks print-imr ifeq ($(filter $(EXAMPLE),$(KNOWN_EXAMPLES)),) $(info Set the variable EXAMPLE to one of the following Galileo-specific examples:) diff --git a/examples/galileo/README.md b/examples/galileo/README.md index b725ec867..49777a16c 100644 --- a/examples/galileo/README.md +++ b/examples/galileo/README.md @@ -83,6 +83,16 @@ MODE1 register, which should have previously been initialized to the value 0x20. The test verifies that this expected value is returned by the read. +Isolated Memory Regions +----------------------- + +### Print IMR info (EXAMPLE=print-imr) + +This application prints out information about the configuration of the +Intel Quark X1000 SoC Isolated Memory Regions (IMRs), the Host System +Management Mode Controls register, and the Host Memory I/O Boundary +register. + References ---------- diff --git a/examples/galileo/print-imr.c b/examples/galileo/print-imr.c new file mode 100644 index 000000000..07cd89fed --- /dev/null +++ b/examples/galileo/print-imr.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. 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. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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 "contiki.h" + +#include "imr.h" +#include "msg-bus.h" + +#define HOST_BRIGE_PORT 3 + +#define HSMMCTL_OFFSET 4 + +#define HMBOUND_OFFSET 8 + +/* Refer to Intel Quark SoC X1000 Datasheet, Section 12.7.2.2 for more details + * on the Host System Management Mode Controls register. + */ +typedef union hsmmctl { + struct { + uint32_t lock : 1; + uint32_t rd_open : 1; + uint32_t wr_open : 1; + uint32_t : 1; + uint32_t start : 12; + uint32_t : 1; + uint32_t non_host_rd_open : 1; + uint32_t non_host_wr_open : 1; + uint32_t : 1; + uint32_t end : 12; + }; + uint32_t raw; +} hsmmctl_t; + +/* Amount to shift hsmmctl.start/end left to obtain the bound address */ +#define HSMMCTL_SHAMT 20 + +/* Refer to Intel Quark SoC X1000 Datasheet, Section 12.7.2.3 for more details + * on the Host Memory I/O Boundary register. + */ +typedef union hmbound { + struct { + uint32_t lock : 1; + uint32_t io_dis : 1; + uint32_t : 10; + uint32_t io_bnd : 20; + }; + uint32_t raw; +} hmbound_t; + +/* Amount to shift hmbound.io_bnd left to obtain the bound address */ +#define HMBOUND_SHAMT 12 + +PROCESS(imr_process, "IMR Process"); +AUTOSTART_PROCESSES(&imr_process); +/*---------------------------------------------------------------------------*/ +static hsmmctl_t +hsmmctl_read(void) +{ + hsmmctl_t hsmm; + + quarkX1000_msg_bus_read(HOST_BRIGE_PORT, HSMMCTL_OFFSET, &hsmm.raw); + + return hsmm; +} +/*---------------------------------------------------------------------------*/ +static void +hsmmctl_print(hsmmctl_t hsmm) +{ + printf("[%08x, %08x) %slocked, non-SMM host: %c%c, non-host: %c%c", + hsmm.start << HSMMCTL_SHAMT, hsmm.end << HSMMCTL_SHAMT, + hsmm.lock ? "" : "un", + hsmm.rd_open ? 'R' : '-', hsmm.wr_open ? 'W' : '-', + hsmm.non_host_rd_open ? 'R' : '-', hsmm.non_host_wr_open ? 'W' : '-'); +} +/*---------------------------------------------------------------------------*/ +static hmbound_t +hmbound_read(void) +{ + hmbound_t hmb; + + quarkX1000_msg_bus_read(HOST_BRIGE_PORT, HMBOUND_OFFSET, &hmb.raw); + + return hmb; +} +/*---------------------------------------------------------------------------*/ +static void +hmbound_print(hmbound_t hmb) +{ + printf("%08x %slocked, IO %sabled", + hmb.io_bnd << HMBOUND_SHAMT, + hmb.lock ? "" : "un", + hmb.io_dis ? "dis" : "en"); +} +/*---------------------------------------------------------------------------*/ +static void +imr_print(quarkX1000_imr_t imr) +{ + printf("[%08x, %08x) %slocked, rdmsk: %08x, wrmsk: %08x", + imr.lo.addr << QUARKX1000_IMR_SHAMT, + imr.hi.addr << QUARKX1000_IMR_SHAMT, + imr.lo.lock ? "" : "un", imr.rdmsk.raw, imr.wrmsk.raw); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(imr_process, ev, data) +{ + int i; + quarkX1000_imr_t imr; + hsmmctl_t hsmm; + hmbound_t hmb; + + PROCESS_BEGIN(); + + fputs("Host SMM Controls: ", stdout); + hsmm = hsmmctl_read(); + hsmmctl_print(hsmm); + fputs("\nHost Memory IO Boundary: ", stdout); + hmb = hmbound_read(); + hmbound_print(hmb); + puts("\nIsolated Memory Regions:"); + for(i = 0; i < QUARKX1000_IMR_CNT; i++) { + printf(" - #%d: ", i); + imr = quarkX1000_imr_read(i); + imr_print(imr); + puts(""); + } + + PROCESS_END(); +}