Commit 871a57bb817a7f4129d924d72f308228180c49ef

Authored by Miao Yan
Committed by Tom Rini
1 parent de37cdc223

common/cmd_bootm: extend do_bootm_vxworks to support the new VxWorks boot interface.

The next version VxWorks adopts device tree (for PowerPC and ARM) as its hardware
description mechanism. For PowerPC, the boot interface conforms to
the ePAPR standard, which is:

   void (*kernel_entry)(ulong fdt_addr,
          ulong r4 /* 0 */,
          ulong r5 /* 0 */,
          ulong r6 /* EPAPR_MAGIC */, ulong r7 /* IMA size */,
          ulong r8 /* 0 */, ulong r9 /* 0 */)

For ARM, the boot interface is:

   void (*kernel_entry)(void *fdt_addr)

Signed-off-by: Miao Yan <miao.yan@windriver.com>
[trini: Fix build error when !CONFIG_OF_FDT is set, typo on PowerPC,
missing extern ft_fixup_num_cores]
Signed-off-by: Tom Rini <trini@ti.com>

Showing 5 changed files with 155 additions and 12 deletions Side-by-side Diff

arch/arm/lib/bootm.c
... ... @@ -326,4 +326,27 @@
326 326 }
327 327  
328 328 #endif /* CONFIG_CMD_BOOTZ */
  329 +
  330 +#if defined(CONFIG_BOOTM_VXWORKS)
  331 +void boot_prep_vxworks(bootm_headers_t *images)
  332 +{
  333 +#if defined(CONFIG_OF_LIBFDT)
  334 + int off;
  335 +
  336 + if (images->ft_addr) {
  337 + off = fdt_path_offset(images->ft_addr, "/memory");
  338 + if (off < 0) {
  339 + if (arch_fixup_memory_node(images->ft_addr))
  340 + puts("## WARNING: fixup memory failed!\n");
  341 + }
  342 + }
  343 +#endif
  344 + cleanup_before_linux();
  345 +}
  346 +void boot_jump_vxworks(bootm_headers_t *images)
  347 +{
  348 + /* ARM VxWorks requires device tree physical address to be passed */
  349 + ((void (*)(void *))images->ep)(images->ft_addr);
  350 +}
  351 +#endif
arch/powerpc/lib/bootm.c
... ... @@ -32,6 +32,7 @@
32 32  
33 33 extern ulong get_effective_memsize(void);
34 34 static ulong get_sp (void);
  35 +extern void ft_fixup_num_cores(void *blob);
35 36 static void set_clocks_in_mhz (bd_t *kbd);
36 37  
37 38 #ifndef CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE
... ... @@ -277,4 +278,59 @@
277 278 #endif /* CONFIG_MPC5xxx */
278 279 }
279 280 }
  281 +
  282 +#if defined(CONFIG_BOOTM_VXWORKS)
  283 +void boot_prep_vxworks(bootm_headers_t *images)
  284 +{
  285 +#if defined(CONFIG_OF_LIBFDT)
  286 + int off;
  287 + u64 base, size;
  288 +
  289 + if (!images->ft_addr)
  290 + return;
  291 +
  292 + base = (u64)gd->bd->bi_memstart;
  293 + size = (u64)gd->bd->bi_memsize;
  294 +
  295 + off = fdt_path_offset(images->ft_addr, "/memory");
  296 + if (off < 0)
  297 + fdt_fixup_memory(images->ft_addr, base, size);
  298 +
  299 +#if defined(CONFIG_MP)
  300 +#if defined(CONFIG_MPC85xx)
  301 + ft_fixup_cpu(images->ft_addr, base + size);
  302 + ft_fixup_num_cores(images->ft_addr);
  303 +#elif defined(CONFIG_MPC86xx)
  304 + off = fdt_add_mem_rsv(images->ft_addr,
  305 + determine_mp_bootpg(NULL), (u64)4096);
  306 + if (off < 0)
  307 + printf("## WARNING %s: %s\n", __func__, fdt_strerror(off));
  308 + ft_fixup_num_cores(images->ft_addr);
  309 +#endif
  310 + flush_cache((unsigned long)images->ft_addr, images->ft_len);
  311 +#endif
  312 +#endif
  313 +}
  314 +
  315 +void boot_jump_vxworks(bootm_headers_t *images)
  316 +{
  317 + /* PowerPC VxWorks boot interface conforms to the ePAPR standard
  318 + * general purpuse registers:
  319 + *
  320 + * r3: Effective address of the device tree image
  321 + * r4: 0
  322 + * r5: 0
  323 + * r6: ePAPR magic value
  324 + * r7: shall be the size of the boot IMA in bytes
  325 + * r8: 0
  326 + * r9: 0
  327 + * TCR: WRC = 0, no watchdog timer reset will occur
  328 + */
  329 + WATCHDOG_RESET();
  330 +
  331 + ((void (*)(void *, ulong, ulong, ulong,
  332 + ulong, ulong, ulong))images->ep)(images->ft_addr,
  333 + 0, 0, EPAPR_MAGIC, getenv_bootm_mapsize(), 0, 0);
  334 +}
  335 +#endif
... ... @@ -23,6 +23,11 @@
23 23 #include <asm/io.h>
24 24 #include <linux/compiler.h>
25 25  
  26 +#if defined(CONFIG_BOOTM_VXWORKS) && \
  27 + (defined(CONFIG_PPC) || defined(CONFIG_ARM))
  28 +#include <vxworks.h>
  29 +#endif
  30 +
26 31 #if defined(CONFIG_CMD_USB)
27 32 #include <usb.h>
28 33 #endif
... ... @@ -120,7 +125,8 @@
120 125 #if defined(CONFIG_BOOTM_PLAN9)
121 126 static boot_os_fn do_bootm_plan9;
122 127 #endif
123   -#if defined(CONFIG_BOOTM_VXWORKS)
  128 +#if defined(CONFIG_BOOTM_VXWORKS) && \
  129 + (defined(CONFIG_PPC) || defined(CONFIG_ARM))
124 130 static boot_os_fn do_bootm_vxworks;
125 131 #endif
126 132 #if defined(CONFIG_CMD_ELF)
... ... @@ -151,7 +157,8 @@
151 157 #if defined(CONFIG_BOOTM_PLAN9)
152 158 [IH_OS_PLAN9] = do_bootm_plan9,
153 159 #endif
154   -#if defined(CONFIG_BOOTM_VXWORKS)
  160 +#if defined(CONFIG_BOOTM_VXWORKS) && \
  161 + (defined(CONFIG_PPC) || defined(CONFIG_ARM))
155 162 [IH_OS_VXWORKS] = do_bootm_vxworks,
156 163 #endif
157 164 #if defined(CONFIG_CMD_ELF)
... ... @@ -337,7 +344,8 @@
337 344 if (((images.os.type == IH_TYPE_KERNEL) ||
338 345 (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||
339 346 (images.os.type == IH_TYPE_MULTI)) &&
340   - (images.os.os == IH_OS_LINUX)) {
  347 + (images.os.os == IH_OS_LINUX ||
  348 + images.os.os == IH_OS_VXWORKS)) {
341 349 if (bootm_find_ramdisk(flag, argc, argv))
342 350 return 1;
343 351  
344 352  
... ... @@ -1682,12 +1690,66 @@
1682 1690 }
1683 1691 #endif /* CONFIG_BOOTM_PLAN9 */
1684 1692  
1685   -#if defined(CONFIG_BOOTM_VXWORKS)
  1693 +#if defined(CONFIG_BOOTM_VXWORKS) && \
  1694 + (defined(CONFIG_PPC) || defined(CONFIG_ARM))
  1695 +
  1696 +void do_bootvx_fdt(bootm_headers_t *images)
  1697 +{
  1698 +#if defined(CONFIG_OF_LIBFDT)
  1699 + int ret;
  1700 + char *bootline;
  1701 + ulong of_size = images->ft_len;
  1702 + char **of_flat_tree = &images->ft_addr;
  1703 + struct lmb *lmb = &images->lmb;
  1704 +
  1705 + if (*of_flat_tree) {
  1706 + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
  1707 +
  1708 + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
  1709 + if (ret)
  1710 + return;
  1711 +
  1712 + ret = fdt_add_subnode(*of_flat_tree, 0, "chosen");
  1713 + if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) {
  1714 + bootline = getenv("bootargs");
  1715 + if (bootline) {
  1716 + ret = fdt_find_and_setprop(*of_flat_tree,
  1717 + "/chosen", "bootargs",
  1718 + bootline,
  1719 + strlen(bootline) + 1, 1);
  1720 + if (ret < 0) {
  1721 + printf("## ERROR: %s : %s\n", __func__,
  1722 + fdt_strerror(ret));
  1723 + return;
  1724 + }
  1725 + }
  1726 + } else {
  1727 + printf("## ERROR: %s : %s\n", __func__,
  1728 + fdt_strerror(ret));
  1729 + return;
  1730 + }
  1731 + }
  1732 +#endif
  1733 +
  1734 + boot_prep_vxworks(images);
  1735 +
  1736 + bootstage_mark(BOOTSTAGE_ID_RUN_OS);
  1737 +
  1738 +#if defined(CONFIG_OF_LIBFDT)
  1739 + printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n",
  1740 + (ulong)images->ep, (ulong)*of_flat_tree);
  1741 +#else
  1742 + printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep);
  1743 +#endif
  1744 +
  1745 + boot_jump_vxworks(images);
  1746 +
  1747 + puts("## vxWorks terminated\n");
  1748 +}
  1749 +
1686 1750 static int do_bootm_vxworks(int flag, int argc, char * const argv[],
1687 1751 bootm_headers_t *images)
1688 1752 {
1689   - char str[80];
1690   -
1691 1753 if (flag != BOOTM_STATE_OS_GO)
1692 1754 return 0;
1693 1755  
... ... @@ -1698,12 +1760,7 @@
1698 1760 }
1699 1761 #endif
1700 1762  
1701   - sprintf(str, "%lx", images->ep); /* write entry-point into string */
1702   - setenv("loadaddr", str);
1703   -
1704   -#if defined(CONFIG_CMD_ELF)
1705   - do_bootvx(NULL, 0, 0, NULL);
1706   -#endif
  1763 + do_bootvx_fdt(images);
1707 1764  
1708 1765 return 1;
1709 1766 }
... ... @@ -698,6 +698,10 @@
698 698 #if defined(CONFIG_MPC85xx)
699 699 typedef MPC85xx_SYS_INFO sys_info_t;
700 700 void get_sys_info ( sys_info_t * );
  701 +# if defined(CONFIG_OF_LIBFDT)
  702 + void ft_fixup_cpu(void *, u64);
  703 + void ft_fixup_num_cores(void *);
  704 +# endif
701 705 #endif
702 706 #if defined(CONFIG_MPC86xx)
703 707 typedef MPC86xx_SYS_INFO sys_info_t;
... ... @@ -9,6 +9,9 @@
9 9 #define _VXWORKS_H_
10 10  
11 11 int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
  12 +void boot_prep_vxworks(bootm_headers_t *images);
  13 +void boot_jump_vxworks(bootm_headers_t *images);
  14 +void do_bootvx_fdt(bootm_headers_t *images);
12 15  
13 16 /*
14 17 * Use bootaddr to find the location in memory that VxWorks