This patch configures Isolated Memory Regions (IMRs) to block DMA to
code and data regions that do not contain any data that needs to be
DMA-accessible.
This patch revises the I2C and GPIO initialization code to always be
run during platform boot rather than within each process that requires
it.
This patch also revises the gpio-output example to use a pin that is
set as an output by the default pinmux configuration. Previously, it
used a pin that was set as an output by the pinmux configuration that
is in effect when the OS does not change the pinmux configuration.
This patch permits interrupts to be generated by both the I2C and GPIO
controllers for simultaneously-executing applications. The controllers
share a single interrupt pin, INTC. Prior to this patch,
quarkX1000_gpio_init() routed INTA to PIRQC and IRQ 10 (due to an
incorrect assumption that INTA is connected to the GPIO controller),
and quarkX1000_i2c_init() routed INTC to PIRQC and IRQ 9. The I2C
controller initialization is a prerequisite for GPIO initialization,
so the final configuration was that INTA and INTC were both routed to
PIRQC and IRQ 10. Thus, only the GPIO ISR was being invoked, even if
the I2C controller was actually responsible for the interrupt.
This patch refactors the I2C and GPIO ISR setup and handler code so
that the shared portions are combined in
cpu/x86/drivers/legacy_pc/shared-isr.[ch]. The I2C and GPIO drivers
communicate their interrupt information to the shared component by
placing structures in a specific section of the binary.
This patch adds support for Ethernet to the Intel Galileo port. It
uses the Intel Quark X1000 Ethernet driver. It initializes the first
Ethernet interface and starts some common network services. By
default, it uses the following addresses:
- Host: 192.0.2.2
- Netmask: 255.255.255.0
- Default gateway: 192.0.2.1
- DNS server: (same as default gateway)
These settings can be changed by editing eth-conf.c.
This patch introduces the initial support for stdio library in Galileo
platform. For now, only standard output and error are supported. Both
streams use the UART1 device.
Newlib doesn't call open() for stdin, stdout, and stderr which means
that the _write_r call is the first activity the stub will see on
those streams. For that reason, we initialize the UART1 device in
Galileo's platform main() function instead of in open() system call.
This patch adds support for rtimer library on Galileo's platform.
We use the PIT to implement the rtimer platform dependent
functionalities. We chose the PIT for mainly two reason: I) its
configuration is very simple II) it has a high frequency which
provides us a good clock resolution (requirement from rtimer
library).
Since we keep track of the number of ticks in software, we define
rtimer_clock_t type as uint64_t. This gives us a good amount of time
til the variable overflows. For instance, a 32-bit type would overflow
in about one hour for high clock resolution (~ 1us).
The rtimer clock frequency (RTIMER_ARCH_SECOND) is setup to 1 kHz.
There is no technical matter regarding this value. It is just an
initial guess.
Just for the record, we might want to use HPET in future to
implement the rtimer library since it seems to be more appropriate.
The reason why we don't use it at this moment is that, in order to
configure it, we need support for ACPI 2.0 which we don't. Once we
have use-cases for the rtimer library we'll probably replace PIT
by HPET or any other timer more suitable for the job.
This patch adds support for the Etimer and Ctimer libraries. To support
the Etimer library, we should poll the etimer process every time the
system clock is updated. To do this more efficiently, by taking advantage
of etimer_next_expiration_time() API, we poll the etimer process only
when an 'Event Timer' has expired.
We don't need any platform specific support in order to enable the Ctimer
library since it relies completely on Etimer.
The others timer libraries (Timer and Stime) don't required any specific
platform support as well since they rely on the system Clock module only.
This patch adds support for Contiki's clock module. All functions from
core/sys/clock.h are implemented, except clock_set_seconds() and clock_
delay_usec(). The CLOCK_CONF_SECOND macro is set to 128. This value
seems to be good enough since several platforms used it. Finally, we
use the RTC driver to track the number of ticks from the system clock.
The Programmable Interrupt Controller is a chip responsible for
translating hardware interrupts to system interrupts. When it
receives an Interrupt Request (IRQ), it triggers the appropriate
interrupt line reaching the appropriate IDT gate, following a
previously setup offset.
There are 2 daisy-chained PICs. PIC1 handles IRQs 0-7 and PIC2
handles IRQs 8-15. If no vector offset is set, an IRQ0, for instance,
would trigger the interrupt 0, clashing with the "Division by zero exception"
handler. Thus the IRQs must be remapped.
This patch implements the PICs initialization through their 4
Initialization Command Words (ICWs) in a very "canonical" way:
- ICW1: the initializing command;
- ICW2: the vector offset for the PIC1 and PIC2 (we add an offset of 32 positions);
- ICW3: the inter-PICs wiring setup (we connect PIC2 to PIC1's IRQ2);
- ICW4: extra systems information (we set PIC1 as Master and PIC2 as slave).
It then masks the Interrupt Mask Register, blocking all IRQs but #2 initially.
These must be unmasked on demand. The IMR is 8-bits long, so setting the n^th bit to 1
would DISABLE the IRQ n while setting it to 0 would ENABLE IRQ n.
As stated, this is an implementation of the legacy 8259 PIC. More
investigation is needed so we decide if it is enough or if we need
the (newer) APIC implementation instead.
This patch also adds the outb() helper function to helpers.h. The helpers
is a wrapper for assembly 'out' instruction.
Finally, since we now properly support hardware interrupts, this patch
also enables IRQs in platform main().
More information:
- Quark X1000 Datasheet, section 21.12, page 898.
- http://wiki.osdev.org/8259_PIC
- http://stanislavs.org/helppc/8259.html
This patch defines the cpu_init() function which should encapsulate
all code related to x86 CPU initialization. For now, this function
initializes GDT and IDT.
This patch implements the main() function for Galileo platform. At this
moment, only Processes subsystem is enabled. After this patch we are
able to some rudimentary debugging to ensure that process thread from
applications are being indeed executed.
Once we properly support more Contiki subsystems, such as clock, ctimer,
etimer, and rtimer, we will add them to Galileo platform's main() as well.
This patch adds the initial support for Intel Galileo Platform. It
contains the minimum set of code required to boot a dummy Contiki
image.
For Galileo initial support, we implemented a linker script, a minimal
bootstrap code, a set of stubbed functions required by newlib, and a
very simple main() function. Moreover, we also define some header files
and macros required by Contiki.
To build applications for this platform you should first build newlib
(in case it wasn't already built). To build newlib you can run the
following command:
$ platform/galileo/bsp/libc/build_newlib.sh
Once newlib is built, you can build applications. To build applications
for Galileo platform you should set TARGET variable to 'galileo'. For
instance, building the hello-world application should look like this:
$ cd examples/hello-world/ && make TARGET=galileo
This will generate the 'hello-world.galileo' file which is a multiboot-
compliant [1] ELF image. This image can be booted by any multiboot-
complaint bootloader such as Grub.
Finally, this patch should be used as a guideline to add the initial
support for others platforms based on x86 SoCs.
[1] https://www.gnu.org/software/grub/manual/multiboot/multiboot.html