diff --git a/ChangeLog b/ChangeLog index d3f44ae..d42d18a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,31 @@ 2012-05-25 Niibe Yutaka + * boards/STM8S_DISCOVERY/board.h (SET_USB_CONDITION) + (SET_LED_CONDITION, GPIO_LED, IOPORT_LED, FLASH_PAGE_SIZE): New. + * boards/STM8S_DISCOVERY/board.c (USB_Cable_Config, set_led): + Remove. + + * regnual/Makefile: Add -I ../src to CFLAGS. + + * regnual/regnual.ld (vector): New. + + * regnual/sys.c: Remove implementation, but jump to vector by sys.h. + + * src/Makefile.in: Follow change of files. + + * src/configure: Undo changes of 2012-05-22. + + * boards/common/hw_config.c: Remove. Mov function to sys.c. + * src/flash.c: Move functions to sys.c. + * src/sys.c: New. + + * src/main.c (main): Call flash_mass_erase_and_exec. + + * src/usb_lld.c: Include sys.h. + + * src/usb_lld_sys.c: Remove. Move interrupt handler to... + * src/usb_ctrl.c: ... this file. + * regnual/sys.c (clock_init, gpio_init, flash_unlock): Removed. (entry): Rename (was: reset). diff --git a/boards/STM8S_DISCOVERY/board.c b/boards/STM8S_DISCOVERY/board.c index 355efc9..554b598 100644 --- a/boards/STM8S_DISCOVERY/board.c +++ b/boards/STM8S_DISCOVERY/board.c @@ -46,22 +46,6 @@ hwinit1 (void) AFIO->MAPR |= AFIO_MAPR_TIM3_REMAP_PARTIALREMAP; } -void -USB_Cable_Config (FunctionalState NewState) -{ - /* No functionality to stop USB. */ - (void)NewState; -} - -void -set_led (int value) -{ - if (value) - palSetPad (IOPORT1, GPIOA_LED); - else - palClearPad (IOPORT1, GPIOA_LED); -} - #if defined(PINPAD_CIR_SUPPORT) void cir_ext_disable (void) diff --git a/boards/STM8S_DISCOVERY/board.h b/boards/STM8S_DISCOVERY/board.h index 71ad5f2..a9cb272 100644 --- a/boards/STM8S_DISCOVERY/board.h +++ b/boards/STM8S_DISCOVERY/board.h @@ -32,6 +32,12 @@ * Setup for the ST-Link part of STM8S-Discovery board. */ +#undef SET_USB_CONDITION /* No functionality to disconnect USB */ +#define SET_LED_CONDITION(on) on /* To emit light, call palSetPad */ +#define GPIO_LED GPIOA_LED +#define IOPORT_LED GPIOA +#define FLASH_PAGE_SIZE 1024 + /* * Board identifier. */ diff --git a/boards/common/hw_config.c b/boards/common/hw_config.c deleted file mode 100644 index 0a59997..0000000 --- a/boards/common/hw_config.c +++ /dev/null @@ -1,14 +0,0 @@ -/* Hardware specific function */ - -#include "ch.h" -#include "hal.h" -#include "board.h" - -const uint8_t * -unique_device_id (void) -{ - /* STM32F103 has 96-bit unique device identifier */ - const uint8_t *addr = (const uint8_t *)0x1ffff7e8; - - return addr; -} diff --git a/regnual/Makefile b/regnual/Makefile index a6cad6f..991fad4 100644 --- a/regnual/Makefile +++ b/regnual/Makefile @@ -23,7 +23,7 @@ MCFLAGS= -mcpu=$(MCU) -mfix-cortex-m3-ldrd DEFS = -DFREE_STANDING CFLAGS = -O2 -g -CFLAGS += $(CWARN) -fno-common $(MCFLAGS) $(TOPT) $(DEFS) +CFLAGS += $(CWARN) -I ../src -fno-common $(MCFLAGS) $(TOPT) $(DEFS) LDFLAGS = -T$(LDSCRIPT) -nostartfiles $(MCFLAGS) $(TOPT) diff --git a/regnual/regnual.c b/regnual/regnual.c index 8fcca88..1b761da 100644 --- a/regnual/regnual.c +++ b/regnual/regnual.c @@ -27,6 +27,7 @@ #include "types.h" #include "usb_lld.h" +#include "sys.h" extern void *memset (void *s, int c, size_t n); diff --git a/regnual/regnual.ld b/regnual/regnual.ld index c2f2df4..8b7313e 100644 --- a/regnual/regnual.ld +++ b/regnual/regnual.ld @@ -11,6 +11,7 @@ MEMORY ram1 : org = 0x20001400, len = 20k - 0x1400 } +vector = 0x08000000; _flash_start = 0x08000000; _flash_end = 0x08020000; diff --git a/regnual/sys-stbee.h b/regnual/sys-stbee.h deleted file mode 100644 index e164790..0000000 --- a/regnual/sys-stbee.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * system settings. - */ -#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 -#define STM32_PLLMUL_VALUE 6 -#define STM32_HSECLK 12000000 - -#define GPIO_USB_CLEAR_TO_ENABLE 3 -#define GPIO_LED_CLEAR_TO_EMIT 4 - -#define VAL_GPIO_ODR 0xFFFFFFFF -#define VAL_GPIO_CRH 0x88888888 /* PD15...PD8 */ -#define VAL_GPIO_CRL 0x88862888 /* PD7...PD0 */ - -#define GPIO_USB_BASE GPIOD_BASE -#define GPIO_LED_BASE GPIOD_BASE diff --git a/regnual/sys-stm8s-discovery.h b/regnual/sys-stm8s-discovery.h deleted file mode 100644 index d9d6933..0000000 --- a/regnual/sys-stm8s-discovery.h +++ /dev/null @@ -1,13 +0,0 @@ -#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 -#define STM32_PLLMUL_VALUE 9 -#define STM32_HSECLK 8000000 - -#undef GPIO_USB_CLEAR_TO_ENABLE -#define GPIO_LED_SET_TO_EMIT 8 - -#define VAL_GPIO_ODR 0xFFFFFFFF -#define VAL_GPIO_CRH 0x88888883 /* PD15...PD8 */ -#define VAL_GPIO_CRL 0x88888888 /* PD7...PD0 */ - -#define GPIO_LED_BASE GPIOA_BASE -#undef GPIO_USB_BASE diff --git a/regnual/sys.c b/regnual/sys.c index ff92e23..fc8d0a9 100644 --- a/regnual/sys.c +++ b/regnual/sys.c @@ -1,240 +1,4 @@ #include "types.h" -#include "sys.h" - -#define STM32_SW_PLL (2 << 0) -#define STM32_PLLSRC_HSE (1 << 16) - -#define STM32_PLLXTPRE_DIV1 (0 << 17) -#define STM32_PLLXTPRE_DIV2 (1 << 17) - -#define STM32_HPRE_DIV1 (0 << 4) - -#define STM32_PPRE1_DIV2 (4 << 8) - -#define STM32_PPRE2_DIV2 (4 << 11) - -#define STM32_ADCPRE_DIV4 (1 << 14) - -#define STM32_MCO_NOCLOCK (0 << 24) - -#define STM32_SW STM32_SW_PLL -#define STM32_PLLSRC STM32_PLLSRC_HSE -#define STM32_HPRE STM32_HPRE_DIV1 -#define STM32_PPRE1 STM32_PPRE1_DIV2 -#define STM32_PPRE2 STM32_PPRE2_DIV2 -#define STM32_ADCPRE STM32_ADCPRE_DIV4 -#define STM32_MCO STM32_MCO_NOCLOCK - -#define STM32_PLLCLKIN (STM32_HSECLK / 1) -#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) -#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) -#define STM32_SYSCLK STM32_PLLCLKOUT -#define STM32_HCLK (STM32_SYSCLK / 1) - -#define STM32_FLASHBITS 0x00000012 - -struct NVIC { - uint32_t ISER[8]; - uint32_t unused1[24]; - uint32_t ICER[8]; - uint32_t unused2[24]; - uint32_t ISPR[8]; - uint32_t unused3[24]; - uint32_t ICPR[8]; - uint32_t unused4[24]; - uint32_t IABR[8]; - uint32_t unused5[56]; - uint32_t IPR[60]; -}; - -#define NVICBase ((struct NVIC *)0xE000E100) -#define NVIC_ISER(n) (NVICBase->ISER[n]) -#define NVIC_ICPR(n) (NVICBase->ICPR[n]) -#define NVIC_IPR(n) (NVICBase->IPR[n]) - -static void NVICEnableVector (uint32_t n, uint32_t prio) -{ - unsigned int sh = (n & 3) << 3; - - NVIC_IPR (n >> 2) = (NVIC_IPR(n >> 2) & ~(0xFF << sh)) | (prio << sh); - NVIC_ICPR (n >> 5) = 1 << (n & 0x1F); - NVIC_ISER (n >> 5) = 1 << (n & 0x1F); -} - - -#define PERIPH_BASE 0x40000000 -#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) -#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) - -struct RCC { - __IO uint32_t CR; - __IO uint32_t CFGR; - __IO uint32_t CIR; - __IO uint32_t APB2RSTR; - __IO uint32_t APB1RSTR; - __IO uint32_t AHBENR; - __IO uint32_t APB2ENR; - __IO uint32_t APB1ENR; - __IO uint32_t BDCR; - __IO uint32_t CSR; -}; - -#define RCC_BASE (AHBPERIPH_BASE + 0x1000) -#define RCC ((struct RCC *)RCC_BASE) - -#define RCC_APB1ENR_USBEN 0x00800000 -#define RCC_APB1RSTR_USBRST 0x00800000 - -#define RCC_CR_HSION 0x00000001 -#define RCC_CR_HSIRDY 0x00000002 -#define RCC_CR_HSITRIM 0x000000F8 -#define RCC_CR_HSEON 0x00010000 -#define RCC_CR_HSERDY 0x00020000 -#define RCC_CR_PLLON 0x01000000 -#define RCC_CR_PLLRDY 0x02000000 - -#define RCC_CFGR_SWS 0x0000000C -#define RCC_CFGR_SWS_HSI 0x00000000 - -struct FLASH { - __IO uint32_t ACR; - __IO uint32_t KEYR; - __IO uint32_t OPTKEYR; - __IO uint32_t SR; - __IO uint32_t CR; - __IO uint32_t AR; - __IO uint32_t RESERVED; - __IO uint32_t OBR; - __IO uint32_t WRPR; -}; - -#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000) -#define FLASH ((struct FLASH *) FLASH_R_BASE) - - -#define RCC_APB2ENR_IOPAEN 0x00000004 -#define RCC_APB2RSTR_IOPARST 0x00000004 -#define RCC_APB2ENR_IOPDEN 0x00000020 -#define RCC_APB2RSTR_IOPDRST 0x00000020 - -#define VAL_GPIOAODR 0xFFFFFFFF -#define VAL_GPIOACRH 0x88888888 /* PA15...PA8 */ -#define VAL_GPIOACRL 0x88888884 /* PA7...PA0 */ - -struct GPIO { - __IO uint32_t CRL; - __IO uint32_t CRH; - __IO uint32_t IDR; - __IO uint32_t ODR; - __IO uint32_t BSRR; - __IO uint32_t BRR; - __IO uint32_t LCKR; -}; - -#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) -#define GPIOA ((struct GPIO *) GPIOA_BASE) -#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) -#define GPIOB ((struct GPIO *) GPIOB_BASE) -#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) -#define GPIOC ((struct GPIO *) GPIOC_BASE) -#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) -#define GPIOD ((struct GPIO *) GPIOD_BASE) -#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) -#define GPIOE ((struct GPIO *) GPIOE_BASE) - -#ifdef GPIO_USB_BASE -#define GPIO_USB ((struct GPIO *) GPIO_USB_BASE) -#endif -#define GPIO_LED ((struct GPIO *) GPIO_LED_BASE) - -static void -usb_cable_config (int on) -{ -#ifdef GPIO_USB_BASE -# ifdef GPIO_USB_CLEAR_TO_ENABLE - if (on) - GPIO_USB->BRR = (1 << GPIO_USB_CLEAR_TO_ENABLE); - else - GPIO_USB->BSRR = (1 << GPIO_USB_CLEAR_TO_ENABLE); -# endif -# ifdef GPIO_USB_SET_TO_ENABLE - if (on) - GPIO_USB->BSRR = (1 << GPIO_USB_SET_TO_ENABLE); - else - GPIO_USB->BRR = (1 << GPIO_USB_SET_TO_ENABLE); -# endif -#else - (void)on; -#endif -} - -void -set_led (int on) -{ -#ifdef GPIO_LED_CLEAR_TO_EMIT - if (on) - GPIO_LED->BRR = (1 << GPIO_LED_CLEAR_TO_EMIT); - else - GPIO_LED->BSRR = (1 << GPIO_LED_CLEAR_TO_EMIT); -#endif -#ifdef GPIO_LED_SET_TO_EMIT - if (on) - GPIO_LED->BSRR = (1 << GPIO_LED_SET_TO_EMIT); - else - GPIO_LED->BRR = (1 << GPIO_LED_SET_TO_EMIT); -#endif -} - - -#define USB_IRQ 20 -#define USB_IRQ_PRIORITY ((11) << 4) - -void usb_lld_sys_init (void) -{ - RCC->APB1ENR |= RCC_APB1ENR_USBEN; - NVICEnableVector (USB_IRQ, USB_IRQ_PRIORITY); - RCC->APB1RSTR = RCC_APB1RSTR_USBRST; - RCC->APB1RSTR = 0; - usb_cable_config (1); -} - -void usb_lld_sys_shutdown (void) -{ - RCC->APB1ENR &= ~RCC_APB1ENR_USBEN; -} - - -#define FLASH_KEY1 0x45670123UL -#define FLASH_KEY2 0xCDEF89ABUL - -enum flash_status -{ - FLASH_BUSY = 1, - FLASH_ERROR_PG, - FLASH_ERROR_WRP, - FLASH_COMPLETE, - FLASH_TIMEOUT -}; - -#define FLASH_SR_BSY 0x01 -#define FLASH_SR_PGERR 0x04 -#define FLASH_SR_WRPRTERR 0x10 -#define FLASH_SR_EOP 0x20 - -#define FLASH_CR_PG 0x0001 -#define FLASH_CR_PER 0x0002 -#define FLASH_CR_MER 0x0004 -#define FLASH_CR_OPTPG 0x0010 -#define FLASH_CR_OPTER 0x0020 -#define FLASH_CR_STRT 0x0040 -#define FLASH_CR_LOCK 0x0080 -#define FLASH_CR_OPTWRE 0x0200 -#define FLASH_CR_ERRIE 0x0400 -#define FLASH_CR_EOPIE 0x1000 - -#define FLASH_OBR_RDPRT 0x00000002 - -#define OPTION_BYTES_ADDR 0x1ffff800 static void fatal (void) { @@ -249,9 +13,7 @@ static void none (void) static __attribute__ ((naked)) void entry (void) { - asm volatile ("cpsid i\n\t" /* Mask all interrupts */ - "ldr r0, =__ram_end__\n\t" - "msr MSP, r0\n\t" /* Main (interrupt handler) stack */ + asm volatile ("ldr r0, =__ram_end__\n\t" "ldr r1, =__main_stack_size__\n\t" "subs r0, r0, r1\n\t" "msr PSP, r0\n\t" /* Process (main routine) stack */ @@ -278,11 +40,6 @@ void entry (void) : /* no output */ : /* no input */ : "memory"); } -#define intr_disable() asm volatile ("cpsid i" : : "r" (0) : "memory") - -#define intr_enable() asm volatile ("msr BASEPRI, %0\n\t" \ - "cpsie i" : : "r" (0) : "memory") - typedef void (*handler)(void); extern uint8_t __ram_end__; extern void usb_interrupt_handler (void); @@ -308,144 +65,3 @@ handler vector_table[] __attribute__ ((section(".vectors"))) = { /* 90 */ usb_interrupt_handler, }; - -static int -flash_get_status (void) -{ - int status; - - if ((FLASH->SR & FLASH_SR_BSY) != 0) - status = FLASH_BUSY; - else if ((FLASH->SR & FLASH_SR_PGERR) != 0) - status = FLASH_ERROR_PG; - else if((FLASH->SR & FLASH_SR_WRPRTERR) != 0 ) - status = FLASH_ERROR_WRP; - else - status = FLASH_COMPLETE; - - return status; -} - -static int -flash_wait_for_last_operation (uint32_t timeout) -{ - int status; - - do - if (--timeout == 0) - return FLASH_TIMEOUT; - else - status = flash_get_status (); - while (status == FLASH_BUSY); - - return status; -} - -#define FLASH_PROGRAM_TIMEOUT 0x00010000 -#define FLASH_ERASE_TIMEOUT 0x01000000 - -static int -flash_program_halfword (uint32_t addr, uint16_t data) -{ - int status; - - status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT); - - intr_disable (); - if (status == FLASH_COMPLETE) - { - FLASH->CR |= FLASH_CR_PG; - - *(volatile uint16_t *)addr = data; - - status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT); - FLASH->CR &= ~FLASH_CR_PG; - } - intr_enable (); - - return status; -} - -int -flash_write (uint32_t dst_addr, const uint8_t *src, size_t len) -{ - int status; - - while (len) - { - uint16_t hw = *src++; - - hw |= (*src++ << 8); - status = flash_program_halfword (dst_addr, hw); - if (status != FLASH_COMPLETE) - return 0; /* error return */ - - dst_addr += 2; - len -= 2; - } - - return 1; -} - -int -flash_protect (void) -{ - int status; - uint32_t option_bytes_value; - - status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); - - intr_disable (); - if (status == FLASH_COMPLETE) - { - FLASH->OPTKEYR = FLASH_KEY1; - FLASH->OPTKEYR = FLASH_KEY2; - - FLASH->CR |= FLASH_CR_OPTER; - FLASH->CR |= FLASH_CR_STRT; - - status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); - FLASH->CR &= ~FLASH_CR_OPTER; - } - intr_enable (); - - if (status != FLASH_COMPLETE) - return 0; - - option_bytes_value = *(uint32_t *)OPTION_BYTES_ADDR; - return (option_bytes_value & 0xff) == 0xff ? 1 : 0; -} - -struct SCB -{ - __IO uint32_t CPUID; - __IO uint32_t ICSR; - __IO uint32_t VTOR; - __IO uint32_t AIRCR; - __IO uint32_t SCR; - __IO uint32_t CCR; - __IO uint8_t SHP[12]; - __IO uint32_t SHCSR; - __IO uint32_t CFSR; - __IO uint32_t HFSR; - __IO uint32_t DFSR; - __IO uint32_t MMFAR; - __IO uint32_t BFAR; - __IO uint32_t AFSR; - __IO uint32_t PFR[2]; - __IO uint32_t DFR; - __IO uint32_t ADR; - __IO uint32_t MMFR[4]; - __IO uint32_t ISAR[5]; -}; - -#define SCS_BASE (0xE000E000) -#define SCB_BASE (SCS_BASE + 0x0D00) -#define SCB ((struct SCB *) SCB_BASE) - -#define SYSRESETREQ 0x04 -void nvic_system_reset (void) -{ - SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ); - asm volatile ("dsb"); -} diff --git a/src/Makefile.in b/src/Makefile.in index 4130b46..d896426 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -76,15 +76,14 @@ CSRC = $(PORTSRC) \ $(HALSRC) \ $(PLATFORMSRC) \ $(BOARDSRC) \ - ../boards/common/hw_config.c \ $(BOARD_DIR)/board.c \ $(CHIBIOS)/os/various/evtimer.c \ $(CHIBIOS)/os/various/syscalls.c \ $(CRYPTSRC) \ - main.c usb_lld.c usb_lld_sys.c \ + main.c usb_lld.c \ usb_desc.c usb_ctrl.c \ usb-icc.c openpgp.c ac.c openpgp-do.c flash.c \ - random.c neug.c + random.c neug.c sys.c ifneq ($(ENABLE_DEBUG),) CSRC += debug.c diff --git a/src/configure b/src/configure index 28e45b8..25ddd0e 100755 --- a/src/configure +++ b/src/configure @@ -135,7 +135,6 @@ fi BOARD_DIR=../boards/$target if test -d $BOARD_DIR; then echo "Configured for target: $target" - TARGET_LOWER=`echo $target | tr '[:upper:]_' '[:lower:]-'` else echo "Unsupported target \`$target'" >&2 exit 1 @@ -219,8 +218,6 @@ else echo "CERT.3 Data Object is not supported" fi -ln -sf sys-$TARGET_LOWER.h ../regnual/sys.h - sed -e "s%@BOARD_DIR@%$BOARD_DIR%" \ -e "s%@DEBUG_MAKE_OPTION@%$DEBUG_MAKE_OPTION%" \ -e "s%@PINPAD_MAKE_OPTION@%$PINPAD_MAKE_OPTION%" \ diff --git a/src/flash.c b/src/flash.c index 4f4bc07..76b98a2 100644 --- a/src/flash.c +++ b/src/flash.c @@ -32,108 +32,9 @@ #include "config.h" #include "ch.h" #include "hal.h" +#include "sys.h" #include "gnuk.h" -#define FLASH_KEY1 0x45670123UL -#define FLASH_KEY2 0xCDEF89ABUL - -enum flash_status -{ - FLASH_BUSY = 1, - FLASH_ERROR_PG, - FLASH_ERROR_WRP, - FLASH_COMPLETE, - FLASH_TIMEOUT -}; - -void -flash_unlock (void) -{ - FLASH->KEYR = FLASH_KEY1; - FLASH->KEYR = FLASH_KEY2; -} - -static int -flash_get_status (void) -{ - int status; - - if ((FLASH->SR & FLASH_SR_BSY) != 0) - status = FLASH_BUSY; - else if ((FLASH->SR & FLASH_SR_PGERR) != 0) - status = FLASH_ERROR_PG; - else if((FLASH->SR & FLASH_SR_WRPRTERR) != 0) - status = FLASH_ERROR_WRP; - else - status = FLASH_COMPLETE; - - return status; -} - -static int -flash_wait_for_last_operation (uint32_t timeout) -{ - int status; - - do - if (--timeout == 0) - return FLASH_TIMEOUT; - else - status = flash_get_status (); - while (status == FLASH_BUSY); - - return status; -} - -#define FLASH_PROGRAM_TIMEOUT 0x00010000 -#define FLASH_ERASE_TIMEOUT 0x01000000 - -static int -flash_program_halfword (uint32_t addr, uint16_t data) -{ - int status; - - status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT); - - chSysLock (); - if (status == FLASH_COMPLETE) - { - FLASH->CR |= FLASH_CR_PG; - - *(volatile uint16_t *)addr = data; - - status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT); - if (status != FLASH_TIMEOUT) - FLASH->CR &= ~FLASH_CR_PG; - } - chSysUnlock (); - - return status; -} - -static int -flash_erase_page (uint32_t addr) -{ - int status; - - status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); - - chSysLock (); - if (status == FLASH_COMPLETE) - { - FLASH->CR |= FLASH_CR_PER; - FLASH->AR = addr; - FLASH->CR |= FLASH_CR_STRT; - - status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); - if (status != FLASH_TIMEOUT) - FLASH->CR &= ~FLASH_CR_PER; - } - chSysUnlock () - - return status; -} - /* * Flash memory map * @@ -294,14 +195,14 @@ flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *data, int len) addr = (uint32_t)p; hw = nr | (len << 8); - if (flash_program_halfword (addr, hw) != FLASH_COMPLETE) + if (flash_program_halfword (addr, hw) != 0) flash_warning ("DO WRITE ERROR"); addr += 2; for (i = 0; i < len/2; i++) { hw = data[i*2] | (data[i*2+1]<<8); - if (flash_program_halfword (addr, hw) != FLASH_COMPLETE) + if (flash_program_halfword (addr, hw) != 0) flash_warning ("DO WRITE ERROR"); addr += 2; } @@ -309,7 +210,7 @@ flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *data, int len) if ((len & 1)) { hw = data[i*2] | 0xff00; - if (flash_program_halfword (addr, hw) != FLASH_COMPLETE) + if (flash_program_halfword (addr, hw) != 0) flash_warning ("DO WRITE ERROR"); } } @@ -359,19 +260,19 @@ flash_do_release (const uint8_t *do_data) /* Fill zero for content and pad */ for (i = 0; i < len/2; i ++) { - if (flash_program_halfword (addr, 0) != FLASH_COMPLETE) + if (flash_program_halfword (addr, 0) != 0) flash_warning ("fill-zero failure"); addr += 2; } if ((len & 1)) { - if (flash_program_halfword (addr, 0) != FLASH_COMPLETE) + if (flash_program_halfword (addr, 0) != 0) flash_warning ("fill-zero pad failure"); } /* Fill 0x0000 for "tag_number and length" word */ - if (flash_program_halfword (addr_tag, 0) != FLASH_COMPLETE) + if (flash_program_halfword (addr_tag, 0) != 0) flash_warning ("fill-zero tag_nr failure"); } @@ -399,7 +300,7 @@ flash_key_write (uint8_t *key_addr, const uint8_t *key_data, for (i = 0; i < KEY_CONTENT_LEN/2; i ++) { hw = key_data[i*2] | (key_data[i*2+1]<<8); - if (flash_program_halfword (addr, hw) != FLASH_COMPLETE) + if (flash_program_halfword (addr, hw) != 0) return -1; addr += 2; } @@ -407,7 +308,7 @@ flash_key_write (uint8_t *key_addr, const uint8_t *key_data, for (i = 0; i < KEY_CONTENT_LEN/2; i ++) { hw = modulus[i*2] | (modulus[i*2+1]<<8); - if (flash_program_halfword (addr, hw) != FLASH_COMPLETE) + if (flash_program_halfword (addr, hw) != 0) return -1; addr += 2; } @@ -579,18 +480,6 @@ flash_cnt123_clear (const uint8_t **addr_p) } -static int -flash_check_blank (const uint8_t *p_start, int size) -{ - const uint8_t *p; - - for (p = p_start; p < p_start + size; p++) - if (*p != 0xff) - return 0; - - return 1; -} - #if defined(CERTDO_SUPPORT) #define FLASH_CH_CERTIFICATE_SIZE 2048 int @@ -652,7 +541,7 @@ flash_write_binary (uint8_t file_id, const uint8_t *data, for (i = 0; i < len/2; i++) { hw = data[i*2] | (data[i*2+1]<<8); - if (flash_program_halfword (addr, hw) != FLASH_COMPLETE) + if (flash_program_halfword (addr, hw) != 0) flash_warning ("DO WRITE ERROR"); addr += 2; } diff --git a/src/gnuk.h b/src/gnuk.h index 5972d3d..36b333f 100644 --- a/src/gnuk.h +++ b/src/gnuk.h @@ -129,7 +129,6 @@ enum kind_of_key { GPG_KEY_FOR_AUTHENTICATION, }; -extern void flash_unlock (void); extern const uint8_t *flash_init (void); extern void flash_do_release (const uint8_t *); extern const uint8_t *flash_do_write (uint8_t nr, const uint8_t *data, int len); @@ -322,8 +321,6 @@ extern uint32_t get_salt (void); extern uint32_t hardclock (void); -extern void set_led (int); - #define NUM_ALL_PRV_KEYS 3 /* SIG, DEC and AUT */ extern uint8_t pw1_keystring[KEYSTRING_SIZE_PW1]; @@ -351,7 +348,6 @@ extern void flash_bool_write_internal (const uint8_t *p, int nr); extern void flash_cnt123_write_internal (const uint8_t *p, int which, int v); extern void flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *data, int len); -extern const unsigned char *unique_device_id (void); extern const uint8_t gnukStringSerial[]; #define LED_ONESHOT_SHORT ((eventmask_t)1) diff --git a/src/main.c b/src/main.c index 135a9d4..2df00c4 100644 --- a/src/main.c +++ b/src/main.c @@ -24,6 +24,7 @@ #include "config.h" #include "ch.h" #include "hal.h" +#include "sys.h" #include "gnuk.h" #include "usb_lld.h" #include "usb-cdc.h" @@ -370,55 +371,6 @@ led_blink (int spec) } -#define FMEAE_SIZE 128 - -#define FLASH_MASS_ERASE_TIMEOUT 0xF0000000 - -static void __attribute__((naked)) -flash_mass_erase_and_exec (void) -{ - void (**func )(void) = (void (**)(void))(&_regnual_start + 4); - - if ((FLASH->SR & FLASH_SR_BSY) == 0) - { - FLASH->CR |= FLASH_CR_MER; - FLASH->CR |= FLASH_CR_STRT; - - while ((FLASH->SR & FLASH_SR_BSY) != 0) - ; - - FLASH->CR &= ~FLASH_CR_MER; - - if ((FLASH->SR & (FLASH_SR_BSY|FLASH_SR_PGERR|FLASH_SR_WRPRTERR)) == 0) - (**func) (); - } - - for (;;); -} - -static void __attribute__((noreturn)) -good_bye (void) -{ - register uint32_t dst __asm__ ("r0") = 0x20000000; /* SRAM top */ - register uint32_t src __asm__ ("r1") = (uint32_t)flash_mass_erase_and_exec & ~1; - register uint32_t len __asm__ ("r2") = FMEAE_SIZE; - register uint32_t entry __asm__ ("r3") = dst | 1; - register uint32_t use __asm__ ("r4"); - - /* copy function flash_mass_erase_and_exec to SRAM and jump to it */ - asm volatile("add r2, r2, r1\n" - "0: ldr r4, [r1], #4\n\t" - "cmp r2, r1\n\t" - "str r4, [r0], #4\n\t" - "bhi 0b\n\t" - "isb\n\t" - "bx r3" - : "=r" (dst), "=r" (src), "=r" (len), "=r" (use) - : "0" (dst), "1" (src), "2" (len), "r" (entry) - : "memory"); - for (;;); -} - /* * Entry point. * @@ -524,15 +476,12 @@ main (int argc, char *argv[]) } set_led (1); - /* USB Dissconnect (when supported) */ usb_lld_shutdown (); - USB_Cable_Config (0); - chThdSleep (MS2ST (1)); /* > 2.5us required */ port_disable (); /* set vector */ SCB->VTOR = (uint32_t)&_regnual_start; /* leave Gnuk */ - good_bye (); + flash_mass_erase_and_exec (); /* Never reached */ return 0; diff --git a/src/openpgp-do.c b/src/openpgp-do.c index 90de71b..5849f6f 100644 --- a/src/openpgp-do.c +++ b/src/openpgp-do.c @@ -25,6 +25,7 @@ #include "config.h" #include "ch.h" +#include "sys.h" #include "gnuk.h" #include "openpgp.h" diff --git a/src/sys.c b/src/sys.c new file mode 100644 index 0000000..0c6e7b7 --- /dev/null +++ b/src/sys.c @@ -0,0 +1,276 @@ +#include "ch.h" +#include "hal.h" +#include "board.h" +#include "usb_lld.h" + +static const uint8_t * +unique_device_id (void) +{ + /* STM32F103 has 96-bit unique device identifier */ + const uint8_t *addr = (const uint8_t *)0x1ffff7e8; + + return addr; +} + +static void +usb_cable_config (int enable) +{ +#if defined(SET_USB_CONDITION) + if (SET_USB_CONDITION (enable)) + palSetPad (IOPORT_USB, GPIO_USB); + else + palClearPad (IOPORT_USB, GPIO_USB); +#else + (void)enable; +#endif +} + +static void +set_led (int on) +{ + if (SET_LED_CONDITION (on)) + palSetPad (IOPORT_LED, GPIO_LED); + else + palClearPad (IOPORT_LED, GPIO_LED); +} + + +#define FLASH_KEY1 0x45670123UL +#define FLASH_KEY2 0xCDEF89ABUL + +static void +flash_unlock (void) +{ + FLASH->KEYR = FLASH_KEY1; + FLASH->KEYR = FLASH_KEY2; +} + + +static int +flash_wait_for_last_operation (uint32_t timeout) +{ + int status; + + do + { + status = FLASH->SR; + if (--timeout == 0) + break; + } + while ((status & FLASH_SR_BSY) != 0); + + return status & (FLASH_SR_BSY|FLASH_SR_PGERR|FLASH_SR_WRPRTERR); +} + +#define FLASH_PROGRAM_TIMEOUT 0x00010000 +#define FLASH_ERASE_TIMEOUT 0x01000000 + +static int +flash_program_halfword (uint32_t addr, uint16_t data) +{ + int status; + + status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT); + + port_disable (); + if (status == 0) + { + FLASH->CR |= FLASH_CR_PG; + + *(volatile uint16_t *)addr = data; + + status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT); + FLASH->CR &= ~FLASH_CR_PG; + } + port_enable (); + + return status; +} + +static int +flash_erase_page (uint32_t addr) +{ + int status; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + + port_disable (); + if (status == 0) + { + FLASH->CR |= FLASH_CR_PER; + FLASH->AR = addr; + FLASH->CR |= FLASH_CR_STRT; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + FLASH->CR &= ~FLASH_CR_PER; + } + port_enable (); + + return status; +} + +static int +flash_check_blank (const uint8_t *p_start, size_t size) +{ + const uint8_t *p; + + for (p = p_start; p < p_start + size; p++) + if (*p != 0xff) + return 0; + + return 1; +} + +static int +flash_write (uint32_t dst_addr, const uint8_t *src, size_t len) +{ + int status; + + while (len) + { + uint16_t hw = *src++; + + hw |= (*src++ << 8); + status = flash_program_halfword (dst_addr, hw); + if (status != 0) + return 0; /* error return */ + + dst_addr += 2; + len -= 2; + } + + return 1; +} + +#define OPTION_BYTES_ADDR 0x1ffff800 + +static int +flash_protect (void) +{ + int status; + uint32_t option_bytes_value; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + + port_disable (); + if (status == 0) + { + FLASH->OPTKEYR = FLASH_KEY1; + FLASH->OPTKEYR = FLASH_KEY2; + + FLASH->CR |= FLASH_CR_OPTER; + FLASH->CR |= FLASH_CR_STRT; + + status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); + FLASH->CR &= ~FLASH_CR_OPTER; + } + port_enable (); + + if (status != 0) + return 0; + + option_bytes_value = *(uint32_t *)OPTION_BYTES_ADDR; + return (option_bytes_value & 0xff) == 0xff ? 1 : 0; +} + +#define FLASH_MASS_ERASE_TIMEOUT 0xF0000000 + +extern uint8_t __flash_start__, __flash_end__; +extern uint8_t _regnual_start; + +static void __attribute__((naked)) +flash_mass_erase_and_exec (void) +{ + void (**func )(void) = (void (**)(void))(&_regnual_start + 4); + uint32_t addr = (uint32_t)&__flash_start__; + uint32_t end = (uint32_t)&__flash_end__; + int r; + + while (addr < end) + { + r = flash_erase_page (addr); + if (r != 0) + break; + + addr += FLASH_PAGE_SIZE; + } + + if (addr >= end) + (**func) (); + + for (;;); +} + +static void +nvic_enable_vector (uint32_t n, uint32_t prio) +{ + unsigned int sh = (n & 3) << 3; + + NVIC_IPR (n >> 2) = (NVIC_IPR(n >> 2) & ~(0xFF << sh)) | (prio << sh); + NVIC_ICPR (n >> 5) = 1 << (n & 0x1F); + NVIC_ISER (n >> 5) = 1 << (n & 0x1F); +} + +static void +usb_lld_sys_init (void) +{ + RCC->APB1ENR |= RCC_APB1ENR_USBEN; + nvic_enable_vector (USB_LP_CAN1_RX0_IRQn, + CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY)); + /* + * Note that we also have other IRQ(s): + * USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous) + * USBWakeUp_IRQn (suspend/resume) + */ + RCC->APB1RSTR = RCC_APB1RSTR_USBRST; + RCC->APB1RSTR = 0; + + usb_cable_config (1); +} + +static void +usb_lld_sys_shutdown (void) +{ + RCC->APB1ENR &= ~RCC_APB1ENR_USBEN; + usb_cable_config (0); +} + +#define SYSRESETREQ 0x04 +static void +nvic_system_reset (void) +{ + SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ); + asm volatile ("dsb"); +} + +static void __attribute__ ((naked)) +reset (void) +{ + asm volatile ("cpsid i\n\t" /* Mask all interrupts */ + "ldr r0, =_text\n\t" + "ldr r1, [r0], #4\n\t" + "msr MSP, r1\n\t" /* Main (exception handler) stack */ + "ldr r1, [r0]\n\t" /* Reset handler */ + "bx r1\n" + : /* no output */ : /* no input */ : "memory"); +} + +typedef void (*handler)(void); +extern uint8_t __ram_end__; + +handler vector[] __attribute__ ((section(".vectors"))) = { + (handler)&__ram_end__, + reset, + (handler)unique_device_id, + (handler)set_led, + flash_unlock, + (handler)flash_program_halfword, + (handler)flash_erase_page, + (handler)flash_check_blank, + (handler)flash_write, + (handler)flash_protect, + (handler)flash_mass_erase_and_exec, + usb_lld_sys_init, + usb_lld_sys_shutdown, + nvic_system_reset, +}; diff --git a/src/sys.h b/src/sys.h new file mode 100644 index 0000000..18b6b3f --- /dev/null +++ b/src/sys.h @@ -0,0 +1,92 @@ +typedef void (*handler)(void); +extern handler vector[12]; + +static inline const uint8_t * +unique_device_id (void) +{ + const uint8_t * (*func) (void) = (const uint8_t * (*)(void))vector[0]; + + return (*func) (); +} + +static inline void +set_led (int on) +{ + void (*func) (int) = (void (*)(int))vector[1]; + + return (*func) (on); +} + +static inline void +flash_unlock (void) +{ + (*vector[2]) (); +} + +static inline int +flash_program_halfword (uint32_t addr, uint16_t data) +{ + int (*func) (uint32_t, uint16_t) = (int (*)(uint32_t, uint16_t))vector[3]; + + return (*func) (addr, data); +} + +static inline int +flash_erase_page (uint32_t addr) +{ + int (*func) (uint32_t) = (int (*)(uint32_t))vector[4]; + + return (*func) (addr); +} + +static inline int +flash_check_blank (const uint8_t *p_start, size_t size) +{ + int (*func) (const uint8_t *, int) = (int (*)(const uint8_t *, int))vector[5]; + + return (*func) (p_start, size); +} + +static inline int +flash_write (uint32_t dst_addr, const uint8_t *src, size_t len) +{ + int (*func) (uint32_t, const uint8_t *, size_t) + = (int (*)(uint32_t, const uint8_t *, size_t))vector[6]; + + return (*func) (dst_addr, src, len); +} + +static inline int +flash_protect (void) +{ + int (*func) (void) = (int (*)(void))vector[7]; + + return (*func) (); +} + +static inline void __attribute__((noreturn)) +flash_mass_erase_and_exec (void) +{ + void (*func) (void) = (void (*)(void))vector[8]; + + (*func) (); + for (;;); +} + +static inline void +usb_lld_sys_init (void) +{ + (*vector[9]) (); +} + +static inline void +usb_lld_sys_shutdown (void) +{ + (*vector[10]) (); +} + +static inline void +nvic_system_reset (void) +{ + (*vector[11]) (); +} diff --git a/src/usb_ctrl.c b/src/usb_ctrl.c index da116d0..c7ee886 100644 --- a/src/usb_ctrl.c +++ b/src/usb_ctrl.c @@ -423,3 +423,14 @@ const struct usb_device_method Device_Method = { gnuk_usb_event, gnuk_interface, }; + +CH_IRQ_HANDLER (Vector90) +{ + CH_IRQ_PROLOGUE(); + chSysLockFromIsr(); + + usb_interrupt_handler (); + + chSysUnlockFromIsr(); + CH_IRQ_EPILOGUE(); +} diff --git a/src/usb_lld.c b/src/usb_lld.c index 5fc9bac..1c31a04 100644 --- a/src/usb_lld.c +++ b/src/usb_lld.c @@ -4,7 +4,7 @@ #include "ch.h" #include "hal.h" #endif - +#include "sys.h" #include "usb_lld.h" #define USB_MAX_PACKET_SIZE 64 /* For FS device */ diff --git a/src/usb_lld.h b/src/usb_lld.h index cffbfbe..78a35e3 100644 --- a/src/usb_lld.h +++ b/src/usb_lld.h @@ -156,6 +156,3 @@ extern void usb_lld_prepare_shutdown (void); extern void usb_lld_shutdown (void); extern void usb_interrupt_handler (void); - -extern void usb_lld_sys_init (void); -extern void usb_lld_sys_shutdown (void); diff --git a/src/usb_lld_sys.c b/src/usb_lld_sys.c deleted file mode 100644 index be78d7e..0000000 --- a/src/usb_lld_sys.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "ch.h" -#include "hal.h" -#include "usb_lld.h" - -CH_IRQ_HANDLER (Vector90) { - CH_IRQ_PROLOGUE(); - chSysLockFromIsr(); - - usb_interrupt_handler (); - - chSysUnlockFromIsr(); - CH_IRQ_EPILOGUE(); -} - -void usb_lld_sys_init (void) -{ - RCC->APB1ENR |= RCC_APB1ENR_USBEN; - NVICEnableVector (USB_LP_CAN1_RX0_IRQn, - CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY)); - /* - * Note that we also have other IRQ(s): - * USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous) - * USBWakeUp_IRQn (suspend/resume) - */ - RCC->APB1RSTR = RCC_APB1RSTR_USBRST; - RCC->APB1RSTR = 0; - - USB_Cable_Config (1); -} - -void usb_lld_sys_shutdown (void) -{ - RCC->APB1ENR &= ~RCC_APB1ENR_USBEN; -}