Skip to content
This repository has been archived by the owner on Nov 8, 2022. It is now read-only.

Commit

Permalink
Merge pull request #5 from mprinn/master
Browse files Browse the repository at this point in the history
QMSI 1.3.0 Release
  • Loading branch information
danicarles committed Oct 28, 2016
2 parents b31c8eb + c2f6a52 commit c9d265f
Show file tree
Hide file tree
Showing 15 changed files with 123 additions and 31 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ help:
$(info bootloader.)
$(info By default, ENABLE_FIRMWARE_MANAGER=none)
$(info )
$(info To disable context saving on sleep for Quark SE, compile the ROM)
$(info with ENABLE_RESTORE_CONTEXT=0)
$(info By default, ENABLE_RESTORE_CONTEXT=1)
$(info )
$(info QMSI source code is needed for compilation. By default QMSI)
$(info code is expected to be located in '../qmsi'.)
$(info The QMSI_SRC_DIR variable can be defined to change it.)
Expand All @@ -82,4 +86,3 @@ distclean:
$(foreach build, $(SUPPORTED_BUILDS),\
$(MAKE) SOC=$(soc) BUILD=$(build) realclean \
$(END_CMD)))
make -C tests/unit_tests/bootloader realclean
16 changes: 16 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ Building options
The bootloader makefile supports the following build parameters:
- SOC
- ENABLE_FIRMWARE_MANAGER
- ENABLE_RESTORE_CONTEXT

Target SoC selection
--------------------
Expand Down Expand Up @@ -141,6 +142,21 @@ By default, firmware management mode is not enabled.
More info on building and flashing an application using the firmware management
mode can be found in the `Firmware Manager User Guide`_.

Return from sleep
-----------------

The Quark SE has support for sleep states that power off the CPU. When a
wake event happens, the CPU starts over from the reset vector as in a normal
power on. To do so, build both the bootloader and libqmsi with
'ENABLE_RESTORE_CONTEXT=1'.

``make SOC=quark_se ENABLE_RESTORE_CONTEXT=1``

The context of the Quark D2000 is restored by the hw. For that reason,
the ENABLE_RESTORE_CONTEXT option has no effect on Quark D2000 SoC.

By default, context save and restore management is enabled on Quark SE.

Flashing
========

Expand Down
15 changes: 14 additions & 1 deletion base.mk
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ DEFAULT_SOC = quark_se
SOC ?= $(DEFAULT_SOC)
$(info SOC = $(SOC))
SUPPORTED_SOCS = quark_se \
quark_se_2 \
quark_d2000
ifeq ($(filter $(SOC),$(SUPPORTED_SOCS)),)
$(error SOC=$(SOC) is not supported.)
Expand Down Expand Up @@ -105,6 +104,20 @@ $(error "Cannot combine (first-stage) Firmware Management over UART with \
endif
endif

# TODO: move to a soc-specific mk
ifeq ($(SOC),quark_se)
# Option to enable context sleep
ENABLE_RESTORE_CONTEXT ?= 1
SUPPORTED_ENABLE_RESTORE_CONTEXT = 0 \
1
$(info ENABLE_RESTORE_CONTEXT = $(ENABLE_RESTORE_CONTEXT))
ifeq ($(filter $(ENABLE_RESTORE_CONTEXT),\
$(SUPPORTED_ENABLE_RESTORE_CONTEXT)),)
$(error Supported ENABLE_RESTORE_CONTEXT values are '0' and '1'.)
endif
QMSI_BUILD_OPTIONS += ENABLE_RESTORE_CONTEXT=$(ENABLE_RESTORE_CONTEXT)
endif

# Special parameters for custom-boards (not mentioned in the help)
BOARD_HAS_RTC_XTAL ?= 1
SUPPORTED_BOARD_HAS_RTC_XTAL = 0 \
Expand Down
18 changes: 10 additions & 8 deletions bootstrap/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,23 @@ void boot_sense_jtag_probe(void)

static QM_ISR_DECLARE(aonpt_spurious_isr)
{
QM_ISR_EOI(QM_IRQ_AONPT_0_VECTOR);
QM_ISR_EOI(QM_IRQ_AONPT_0_INT_VECTOR);
}

static QM_ISR_DECLARE(rtc_spurious_isr)
{
QM_ISR_EOI(QM_IRQ_RTC_0);
QM_ISR_EOI(QM_IRQ_RTC_0_INT);
}

static QM_ISR_DECLARE(aon_cmp_spurious_isr)
{
QM_ISR_EOI(QM_IRQ_AC);
QM_ISR_EOI(QM_IRQ_COMPARATOR_0_INT);
}

#if (QUARK_SE)
static QM_ISR_DECLARE(aongpio_spurious_isr)
{
QM_ISR_EOI(QM_IRQ_AONGPIO_0_VECTOR);
QM_ISR_EOI(QM_IRQ_AON_GPIO_0_INT_VECTOR);
}
#endif

Expand All @@ -92,10 +92,12 @@ void boot_aon_handle_spurious_irq(void)
/* The PIC IRR register may be asserted by the application before a warm
* reset. IRR cannot be cleared by software, so let's just catch this
* single spurious interrupt. */
qm_int_vector_request(QM_IRQ_AONPT_0_VECTOR, aonpt_spurious_isr);
qm_int_vector_request(QM_IRQ_AC_VECTOR, aon_cmp_spurious_isr);
qm_int_vector_request(QM_IRQ_RTC_0_VECTOR, rtc_spurious_isr);
qm_int_vector_request(QM_IRQ_AONPT_0_INT_VECTOR, aonpt_spurious_isr);
qm_int_vector_request(QM_IRQ_COMPARATOR_0_INT_VECTOR,
aon_cmp_spurious_isr);
qm_int_vector_request(QM_IRQ_RTC_0_INT_VECTOR, rtc_spurious_isr);
#if (QUARK_SE)
qm_int_vector_request(QM_IRQ_AONGPIO_0_VECTOR, aongpio_spurious_isr);
qm_int_vector_request(QM_IRQ_AON_GPIO_0_INT_VECTOR,
aongpio_spurious_isr);
#endif
}
8 changes: 4 additions & 4 deletions bootstrap/rom_startup.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ static __inline__ void irq_setup(void)
uint8_t i;

/* Apply POR settings to SCSS int routing as SCSS regs are sticky */
for (i = 0; i < QM_SCSS_INT_MASK_NUMREG; i++) {
*((volatile uint32_t *)QM_SCSS_INT + i) =
QM_SCSS_INT_MASK_DEFAULT;
for (i = 0; i < QM_INTERRUPT_ROUTER_MASK_NUMREG; i++) {
*((volatile uint32_t *)QM_INTERRUPT_ROUTER + i) =
QM_INTERRUPT_ROUTER_MASK_DEFAULT;
}
}

Expand Down Expand Up @@ -179,7 +179,7 @@ void rom_startup(void)
idt_init();
boot_aon_handle_spurious_irq();
#if (DEBUG)
qm_int_vector_request(QM_INT_VECTOR_DOUBLE_FAULT, double_fault_isr);
qm_int_vector_request(QM_X86_DOUBLE_FAULT_INT, double_fault_isr);
#endif
soc_boot_init_interrupt_controller();
__asm__ __volatile__("sti");
Expand Down
7 changes: 6 additions & 1 deletion bootstrap/soc/quark_se/rom.ld
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ MEMORY
*/
esram (rw) : ORIGIN = 0xA800A220, LENGTH = 40K - 1K - 0x220
/* Stack */
stack (rw) : ORIGIN = 0xA8013C00, LENGTH = 1K
stack (rw) : ORIGIN = 0xA8013C00, LENGTH = 1K - 0x4
/* Shared RAM */
esram_restore_info (rw) : ORIGIN = 0xA8013FFC, LENGTH = 0x4
}

/* Sensor Subsystem reset vector definition */
Expand All @@ -64,6 +66,9 @@ __stack_start = ORIGIN(stack) + LENGTH(stack);
__idt_start = ORIGIN(esram_idt);
__idt_end = __idt_start + LENGTH(esram_idt);

/* Shared RAM definition */
__x86_restore_info = ORIGIN(esram_restore_info);

SECTIONS
{
. = ORIGIN(reset_vector);
Expand Down
22 changes: 21 additions & 1 deletion bootstrap/soc/quark_se/rom_startup.s
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,19 @@

.extern rom_startup
.extern __stack_start
.extern __x86_restore_info

#
# CR0 cache control bit definition
#
.equ CR0_CACHE_DISABLE, 0x040000000
.equ CR0_NO_WRITE, 0x020000000
.equ GPS1_REGISTER, 0xb0800104

#
# Context save/restore definitions
#
.equ GPS0_REGISTER, 0xb0800100
.equ RESTORE_BIT, 1

.text
#----------------------------------------------------------------------------
Expand Down Expand Up @@ -142,6 +148,20 @@ protected_mode_entry:
andl $~(CR0_CACHE_DISABLE + CR0_NO_WRITE), %eax
movl %eax, %cr0

#if (ENABLE_RESTORE_CONTEXT)
#
# Check if we are returning from a 'sleep' state and jump to the
# restore trap if that's the case. The restore trap will restore the
# execution context we had before entering in 'sleep' state.
#
btr $RESTORE_BIT, GPS0_REGISTER
jnc regular_boot

movl $__x86_restore_info, %eax
jmp *(%eax)

regular_boot:
#endif
#
# Set up stack pointer. The stack start address is defined in
# the linker script. ESP = top of the stack (the stack grows
Expand Down
6 changes: 6 additions & 0 deletions doc/boot_flow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ FLOW
- Move to 32bit protected mode.
- Enable cache [Quark SE only].

#. Resume from sleep: [Compile option: ``ENABLE_RESTORE_CONTEXT=1``]
- Resume application execution if the device was put into sleep mode. A
soft reboot is performed when a device comes out of sleep mode. The
bootloader checks if the ``GPS1`` sticky register is set and perform a
jump to the address stored in ``GPS1``.

#. Set-up primary peripherals and registers:
- Stack pointer set-up
- RAM set-up
Expand Down
21 changes: 19 additions & 2 deletions doc/boot_resources.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ Overview
+------------------+---------------+----------------+------------------+
| JTAG probe | GPIO_13 | GPI0_15 | Do not ground |
+------------------+---------------+----------------+------------------+
| Sleep register | N/A | GPS0 bit 1 | x86 restore bit |
| | N/A | GPS0 bit 2 | arc restore bit |
+------------------+---------------+----------------+------------------+
| Sleep storage | | __x86_restore_ | |
| | | info | |
+ + + + +
| - x86 trap | N/A | 4 bytes | Reserved |
+------------------+---------------+----------------+------------------+
| UART port | Uart 0 | Uart 1 | Available to app |
+------------------+---------------+----------------+------------------+
| USB controller | n/a | USB 0 | Available to app |
Expand Down Expand Up @@ -56,12 +64,21 @@ Sticky registers

The bootloader uses the following sticky registers:

* Resume from sleep: [Compile option: ``ENABLE_RESTORE_CONTEXT=1``]
- Quark SE C1000: ``GPS0 bit1 and the 4 bytes in esram_shared``

The bootloader will use the sticky register to handle resuming the
application from a sleep power state as well as the 4 bytes of the
common RAM defined as a section esram_restore_info will be used to
save the restore trap address.

* FM sticky bit: [Compile option: ``ENABLE_FIRMWARE_MANAGER=[uart|2nd-stage]``]
- All SoC's: ``GPS0 bit 0``

This register is used to start the bootloader in Firmware Management (FM)
mode. **This bit is reserved for the bootloader, the application should not
use it.**
mode.

**The application must not use the sticky registers used by the bootloader.**

Peripherals
***********
Expand Down
1 change: 1 addition & 0 deletions doc/fw-manager-user-guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ to be ``8086`` and ``48FC`` respectively.

dfu-util -D examples/blinky/release/quark_se/x86/bin/blinky.bin.dfu -d 8086:48FC -R -a 1


.. note:: The path of the binary may differ when building a D2000 or a
Sensor Subsystem image.

Expand Down
4 changes: 2 additions & 2 deletions fw-manager/dfu/qda/xmodem_io_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ void xmodem_io_uart_init()

#if (HAS_APIC)
/* Request interrupts for PIC Timer */
qm_int_vector_request(QM_INT_VECTOR_PIC_TIMER, qm_pic_timer_isr);
qm_int_vector_request(QM_X86_PIC_TIMER_INT_VECTOR, qm_pic_timer_0_isr);
#elif(HAS_MVIC)
qm_irq_request(QM_IRQ_PIC_TIMER, qm_pic_timer_isr);
qm_irq_request(QM_IRQ_PIC_TIMER, qm_pic_timer_0_isr);
#endif
}
2 changes: 1 addition & 1 deletion fw-manager/dfu/usb-dfu/usb_dfu.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ static void timeout(void *data)

static __inline__ void start_timer(void)
{
qm_int_vector_request(QM_INT_VECTOR_PIC_TIMER, qm_pic_timer_isr);
qm_int_vector_request(QM_X86_PIC_TIMER_INT_VECTOR, qm_pic_timer_0_isr);

qm_pic_timer_set_config(&pic_conf);

Expand Down
2 changes: 1 addition & 1 deletion fw-manager/entries/fm_entry_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ int fm_entry_usb(void)
clk_sys_udelay(50000);
usb_dfu_start();

qm_irq_request(QM_IRQ_USB_0, qm_usb_0_isr_0);
qm_irq_request(QM_IRQ_USB_0_INT, qm_usb_0_isr);

/*
* NOTE: consider making this loop smarter by moving the timeout logic
Expand Down
12 changes: 6 additions & 6 deletions fw-manager/fw-manager_comm.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@
#define FM_COMM_UART_PIN_RX_ID (QM_PIN_ID_19)
#define FM_COMM_UART_PIN_RX_FN (QM_PMUX_FN_0)
#define FM_COMM_UART_CLK (CLK_PERIPH_UARTA_REGISTER)
#define fm_comm_irq_request() qm_irq_request(QM_IRQ_UART_0, qm_uart_0_isr)
#define fm_comm_irq_request() qm_irq_request(QM_IRQ_UART_0_INT, qm_uart_0_isr)
#elif(FM_CONFIG_UART == 1)
#define FM_COMM_UART_PIN_TX_ID (QM_PIN_ID_16)
#define FM_COMM_UART_PIN_TX_FN (QM_PMUX_FN_2)
#define FM_COMM_UART_PIN_RX_ID (QM_PIN_ID_17)
#define FM_COMM_UART_PIN_RX_FN (QM_PMUX_FN_2)
#define FM_COMM_UART_IRQ (QM_IRQ_UART_1)
#define FM_COMM_UART_IRQ (QM_IRQ_UART_1_INT)
#define FM_COMM_UART_CLK (CLK_PERIPH_UARTB_REGISTER)
#define fm_comm_irq_request() qm_irq_request(QM_IRQ_UART_1, qm_uart_1_isr)
#define fm_comm_irq_request() qm_irq_request(QM_IRQ_UART_1_INT, qm_uart_1_isr)
#else
#error "Invalid UART ID for FM comm"
#endif /* FM_CONFIG_UART */
Expand All @@ -63,15 +63,15 @@
#define FM_COMM_UART_PIN_RX_ID (QM_PIN_ID_13)
#define FM_COMM_UART_PIN_RX_FN (QM_PMUX_FN_2)
#define FM_COMM_UART_CLK (CLK_PERIPH_UARTA_REGISTER)
#define fm_comm_irq_request() qm_irq_request(QM_IRQ_UART_0, qm_uart_0_isr)
#define fm_comm_irq_request() qm_irq_request(QM_IRQ_UART_0_INT, qm_uart_0_isr)
#elif(FM_CONFIG_UART == 1)
#define FM_COMM_UART_PIN_TX_ID (QM_PIN_ID_20)
#define FM_COMM_UART_PIN_TX_FN (QM_PMUX_FN_2)
#define FM_COMM_UART_PIN_RX_ID (QM_PIN_ID_21)
#define FM_COMM_UART_PIN_RX_FN (QM_PMUX_FN_2)
#define FM_COMM_UART_IRQ (QM_IRQ_UART_1)
#define FM_COMM_UART_IRQ (QM_IRQ_UART_1_INT)
#define FM_COMM_UART_CLK (CLK_PERIPH_UARTB_REGISTER)
#define fm_comm_irq_request() qm_irq_request(QM_IRQ_UART_1, qm_uart_1_isr)
#define fm_comm_irq_request() qm_irq_request(QM_IRQ_UART_1_INT, qm_uart_1_isr)
#else
#error "Invalid UART ID for FM comm"
#endif /* FM_CONFIG_UART */
Expand Down
15 changes: 12 additions & 3 deletions rom.mk
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,18 @@ STARTUP_BIN = $(BOOT_SOC_DIR)/$(BUILD)/$(OBJ)/rom_startup.bin
ROM_LINKER_FILE ?= $(BOOT_SOC_DIR)/rom.ld

# TODO: create a soc-specific mk for this or a centralized config.mk. This will
# be responsible for:
# 1) documenting all possible build options
# 2) doing the "contract checking"
# be responsible for 1) documenting all possible build options, 2) doing the
# "contract checking" (i.e. if quark_d2000 and ENABLE_RESTORE_CONTEXT, fail),
# 3) expanding the CFLAGS that result from the build-time options.
ifeq ($(SOC),quark_se)
ENABLE_RESTORE_CONTEXT ?= 1
ifeq ($(ENABLE_RESTORE_CONTEXT),0)
CFLAGS += -DENABLE_RESTORE_CONTEXT=0
ROM_SUFFIX_NO_RESTORE_CONTEXT = _no_restore_context
else
CFLAGS += -DENABLE_RESTORE_CONTEXT=1
endif
endif

# Always include fw-manager (FM) makefile to ensure that
# clean/realclean/distclean works properly, i.e., also delete FM objects and
Expand Down Expand Up @@ -81,6 +89,7 @@ endif
# Define ROM file name
# (Suffix is built on multiple lines to respect 80 chars limit)
ROM_SUFFIX := $(ROM_SUFFIX_FM)
ROM_SUFFIX := $(ROM_SUFFIX)$(ROM_SUFFIX_NO_RESTORE_CONTEXT)
ROM = $(ROM_BUILD_DIR)/$(SOC)_rom$(ROM_SUFFIX).bin

.PHONY: rom
Expand Down

0 comments on commit c9d265f

Please sign in to comment.