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 adds the helpers.h. This file should contain only x86-related
helper functions and macros. For now, we define the BIT macro and halt()
helpers which will be used in upcoming patches.
Additionally, this patch also changes loader.S to call the halt().
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.
All we need to provide to C at this point is a region in memory dedicated to
its stack. This is done by allocating a region in .bss and pushing its start
address to esp. Since the multiboot spec says it is not safe to rely on the
initial stack provided by the bootloader, this patch provides our own stack.
Galileo boards have 512Kb of SRAM and 256Mb of DDR3 RAM, so providing 8kb as
a start seems safe. Moreover, stack sizes are very application-oriented
so it may be too early to provide a bigger (or smaller) stack.
This patch changes Galileo's buildsystem to print the elf sections
sizes after a new image is built. This way we can easily track how
these sections increase or decrease after any change.
To achieve that, we define a custom linking rule which is pretty much
the same as the default linking rule define in Makefile.include, but
we run 'size' command after the image is built.
This patch adds a README file which contains general information about
the Intel Galileo board support. The file provides information about
supported features as well as instructions on how to build, run and debug
applications for this platform.
This patch the 'debug' rule to simplify the debugging process. This new
rule runs OpenOCD and gdb with the right parameters. OpenOCD runs in
background and its output will be redirected to a log file in the
application's path called LOG_OPENOCD. Once gdb client is detached,
OpenOCD is terminated.
The 'debug' rule is defined in Makefile.customrules-galileo file (create
by this patch) which is included by the Contiki's buildsystem. So to
debug a Contiki application for Galileo board, run the following command:
$ make TARGET=galileo debug
If you use a gdb front-end, you can define the "GDB" environment variable
and your gdb front-end will be used instead of default gdb. For instance,
if you want to use cgdb front-end, just run the command:
$ make BOARD=galileo debug GDB=cgdb
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
This patch creates the platform/galileo/bsp directory. This directory
contain all files related to Galileo's Board Support Package (BSP). For
now, the BSP consists of libc and bootloader.
Within the BSP directory, we have the scripts build_newlib.sh and build_
grub.sh. These scripts provide an easy and quick way to build the newlib
and the grub for the Galileo platform.