2013-03-15 Niibe Yutaka <gniibe@fsij.org>
+ Support relocatable reGNUal.
+
+ * src/neug.ld.in (_regnual_start): Now, it's just '.'.
+ * src/main.c (calculate_regnual_entry_address): New.
+ (main): Use calculate_regnual_entry_address for entry point.
+
New USB stack.
* src/main.c (device_desc, config_desc, string_descs): Remove.
usb_lld_txcpy (&v, ENDP1, i * 4, 4);
}
+/*
+ * In Gnuk 1.0.[12], reGNUal was not relocatable.
+ * Now, it's relocatable, but we need to calculate its entry address
+ * based on it's pre-defined address.
+ */
+#define REGNUAL_START_ADDRESS_COMPATIBLE 0x20001400
+static uint32_t
+calculate_regnual_entry_address (const uint8_t *addr)
+{
+ const uint8_t *p = addr + 4;
+ uint32_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
+
+ v -= REGNUAL_START_ADDRESS_COMPATIBLE;
+ v += (uint32_t)addr;
+ return v;
+}
+
+
/*
* Entry point.
*
int
main (int argc, char **argv)
{
+ uint32_t entry;
+
(void)argc;
(void)argv;
port_disable ();
/* Set vector */
SCB->VTOR = (uint32_t)&_regnual_start;
+ entry = calculate_regnual_entry_address (&_regnual_start);
#ifdef DFU_SUPPORT
#define FLASH_SYS_START_ADDR 0x08000000
#define FLASH_SYS_END_ADDR (0x08000000+0x1000)
flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000);
/* Leave NeuG to exec reGNUal */
- (*func) (*((void (**)(void))(&_regnual_start+4)));
+ (*func) ((void (*)(void))entry);
for (;;);
}
#else
/* Leave NeuG to exec reGNUal */
- flash_erase_all_and_exec (*((void (**)(void))(&_regnual_start+4)));
+ flash_erase_all_and_exec ((void (*)(void))entry);
#endif
/* Never reached */