summaryrefslogtreecommitdiffstats
path: root/qemu/roms/u-boot/arch/avr32/lib
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/u-boot/arch/avr32/lib')
-rw-r--r--qemu/roms/u-boot/arch/avr32/lib/Makefile13
-rw-r--r--qemu/roms/u-boot/arch/avr32/lib/board.c315
-rw-r--r--qemu/roms/u-boot/arch/avr32/lib/bootm.c213
-rw-r--r--qemu/roms/u-boot/arch/avr32/lib/interrupts.c30
-rw-r--r--qemu/roms/u-boot/arch/avr32/lib/memset.S65
5 files changed, 636 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/arch/avr32/lib/Makefile b/qemu/roms/u-boot/arch/avr32/lib/Makefile
new file mode 100644
index 000000000..bb45cbe15
--- /dev/null
+++ b/qemu/roms/u-boot/arch/avr32/lib/Makefile
@@ -0,0 +1,13 @@
+#
+# (C) Copyright 2002-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2004-2006 Atmel Corporation
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += memset.o
+obj-y += board.o
+obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-y += interrupts.o
diff --git a/qemu/roms/u-boot/arch/avr32/lib/board.c b/qemu/roms/u-boot/arch/avr32/lib/board.c
new file mode 100644
index 000000000..7680102f5
--- /dev/null
+++ b/qemu/roms/u-boot/arch/avr32/lib/board.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <stdio_dev.h>
+#include <version.h>
+#include <net.h>
+#include <atmel_mci.h>
+
+#ifdef CONFIG_BITBANGMII
+#include <miiphy.h>
+#endif
+
+#include <asm/sections.h>
+#include <asm/arch/mmu.h>
+#include <asm/arch/hardware.h>
+
+#ifndef CONFIG_IDENT_STRING
+#define CONFIG_IDENT_STRING ""
+#endif
+
+#ifdef CONFIG_GENERIC_ATMEL_MCI
+#include <mmc.h>
+#endif
+DECLARE_GLOBAL_DATA_PTR;
+
+unsigned long monitor_flash_len;
+
+/* Weak aliases for optional board functions */
+static int __do_nothing(void)
+{
+ return 0;
+}
+int board_postclk_init(void) __attribute__((weak, alias("__do_nothing")));
+int board_early_init_r(void) __attribute__((weak, alias("__do_nothing")));
+
+/* provide cpu_mmc_init, to overwrite provide board_mmc_init */
+int cpu_mmc_init(bd_t *bd)
+{
+ /* This calls the atmel_mci_init in gen_atmel_mci.c */
+ return atmel_mci_init((void *)ATMEL_BASE_MMCI);
+}
+
+#ifdef CONFIG_SYS_DMA_ALLOC_LEN
+#include <asm/arch/cacheflush.h>
+#include <asm/io.h>
+
+static unsigned long dma_alloc_start;
+static unsigned long dma_alloc_end;
+static unsigned long dma_alloc_brk;
+
+static void dma_alloc_init(void)
+{
+ unsigned long monitor_addr;
+
+ monitor_addr = CONFIG_SYS_MONITOR_BASE + gd->reloc_off;
+ dma_alloc_end = monitor_addr - CONFIG_SYS_MALLOC_LEN;
+ dma_alloc_start = dma_alloc_end - CONFIG_SYS_DMA_ALLOC_LEN;
+ dma_alloc_brk = dma_alloc_start;
+
+ printf("DMA: Using memory from 0x%08lx to 0x%08lx\n",
+ dma_alloc_start, dma_alloc_end);
+
+ dcache_invalidate_range(cached(dma_alloc_start),
+ dma_alloc_end - dma_alloc_start);
+}
+
+void *dma_alloc_coherent(size_t len, unsigned long *handle)
+{
+ unsigned long paddr = dma_alloc_brk;
+
+ if (dma_alloc_brk + len > dma_alloc_end)
+ return NULL;
+
+ dma_alloc_brk = ((paddr + len + CONFIG_SYS_DCACHE_LINESZ - 1)
+ & ~(CONFIG_SYS_DCACHE_LINESZ - 1));
+
+ *handle = paddr;
+ return uncached(paddr);
+}
+#else
+static inline void dma_alloc_init(void)
+{
+
+}
+#endif
+
+static int init_baudrate(void)
+{
+ gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
+ return 0;
+}
+
+static int display_banner (void)
+{
+ printf ("\n\n%s\n\n", version_string);
+ printf ("U-Boot code: %08lx -> %08lx data: %08lx -> %08lx\n",
+ (unsigned long)_text, (unsigned long)_etext,
+ (unsigned long)_data, (unsigned long)(&__bss_end));
+ return 0;
+}
+
+static int display_dram_config (void)
+{
+ int i;
+
+ puts ("DRAM Configuration:\n");
+
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
+ print_size (gd->bd->bi_dram[i].size, "\n");
+ }
+
+ return 0;
+}
+
+static void display_flash_config (void)
+{
+ puts ("Flash: ");
+ print_size(gd->bd->bi_flashsize, " ");
+ printf("at address 0x%08lx\n", gd->bd->bi_flashstart);
+}
+
+void board_init_f(ulong board_type)
+{
+ gd_t gd_data;
+ gd_t *new_gd;
+ bd_t *bd;
+ unsigned long *new_sp;
+ unsigned long monitor_len;
+ unsigned long monitor_addr;
+ unsigned long addr;
+ long sdram_size;
+
+ /* Initialize the global data pointer */
+ memset(&gd_data, 0, sizeof(gd_data));
+ gd = &gd_data;
+
+ /* Perform initialization sequence */
+ board_early_init_f();
+ cpu_init();
+ board_postclk_init();
+ env_init();
+ init_baudrate();
+ serial_init();
+ console_init_f();
+ display_banner();
+ sdram_size = initdram(board_type);
+
+ /* If we have no SDRAM, we can't go on */
+ if (sdram_size <= 0)
+ panic("No working SDRAM available\n");
+
+ /*
+ * Now that we have DRAM mapped and working, we can
+ * relocate the code and continue running from DRAM.
+ *
+ * Reserve memory at end of RAM for (top down in that order):
+ * - u-boot image
+ * - heap for malloc()
+ * - board info struct
+ * - global data struct
+ * - stack
+ */
+ addr = CONFIG_SYS_SDRAM_BASE + sdram_size;
+ monitor_len = (char *)(&__bss_end) - _text;
+
+ /*
+ * Reserve memory for u-boot code, data and bss.
+ * Round down to next 4 kB limit.
+ */
+ addr -= monitor_len;
+ addr &= ~(4096UL - 1);
+ monitor_addr = addr;
+
+ /* Reserve memory for malloc() */
+ addr -= CONFIG_SYS_MALLOC_LEN;
+
+#ifdef CONFIG_SYS_DMA_ALLOC_LEN
+ /* Reserve DMA memory (must be cache aligned) */
+ addr &= ~(CONFIG_SYS_DCACHE_LINESZ - 1);
+ addr -= CONFIG_SYS_DMA_ALLOC_LEN;
+#endif
+
+#ifdef CONFIG_LCD
+#ifdef CONFIG_FB_ADDR
+ printf("LCD: Frame buffer allocated at preset 0x%08x\n",
+ CONFIG_FB_ADDR);
+ gd->fb_base = CONFIG_FB_ADDR;
+#else
+ addr = lcd_setmem(addr);
+ printf("LCD: Frame buffer allocated at 0x%08lx\n", addr);
+ gd->fb_base = addr;
+#endif /* CONFIG_FB_ADDR */
+#endif /* CONFIG_LCD */
+
+ /* Allocate a Board Info struct on a word boundary */
+ addr -= sizeof(bd_t);
+ addr &= ~3UL;
+ gd->bd = bd = (bd_t *)addr;
+
+ /* Allocate a new global data copy on a 8-byte boundary. */
+ addr -= sizeof(gd_t);
+ addr &= ~7UL;
+ new_gd = (gd_t *)addr;
+
+ /* And finally, a new, bigger stack. */
+ new_sp = (unsigned long *)addr;
+ gd->arch.stack_end = addr;
+ *(--new_sp) = 0;
+ *(--new_sp) = 0;
+
+ /*
+ * Initialize the board information struct with the
+ * information we have.
+ */
+ bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ bd->bi_dram[0].size = sdram_size;
+
+ memcpy(new_gd, gd, sizeof(gd_t));
+
+ relocate_code((unsigned long)new_sp, new_gd, monitor_addr);
+}
+
+void board_init_r(gd_t *new_gd, ulong dest_addr)
+{
+#ifndef CONFIG_ENV_IS_NOWHERE
+ extern char * env_name_spec;
+#endif
+ bd_t *bd;
+
+ gd = new_gd;
+ bd = gd->bd;
+
+ gd->flags |= GD_FLG_RELOC;
+ gd->reloc_off = dest_addr - CONFIG_SYS_MONITOR_BASE;
+
+ /* Enable the MMU so that we can keep u-boot simple */
+ mmu_init_r(dest_addr);
+
+ board_early_init_r();
+
+ monitor_flash_len = _edata - _text;
+
+#if defined(CONFIG_NEEDS_MANUAL_RELOC)
+ /*
+ * We have to relocate the command table manually
+ */
+ fixup_cmdtable(ll_entry_start(cmd_tbl_t, cmd),
+ ll_entry_count(cmd_tbl_t, cmd));
+#endif /* defined(CONFIG_NEEDS_MANUAL_RELOC) */
+
+ /* there are some other pointer constants we must deal with */
+#ifndef CONFIG_ENV_IS_NOWHERE
+ env_name_spec += gd->reloc_off;
+#endif
+
+ timer_init();
+
+ /* The malloc area is right below the monitor image in RAM */
+ mem_malloc_init(CONFIG_SYS_MONITOR_BASE + gd->reloc_off -
+ CONFIG_SYS_MALLOC_LEN, CONFIG_SYS_MALLOC_LEN);
+ dma_alloc_init();
+
+ enable_interrupts();
+
+ bd->bi_flashstart = 0;
+ bd->bi_flashsize = 0;
+ bd->bi_flashoffset = 0;
+
+#ifndef CONFIG_SYS_NO_FLASH
+ bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
+ bd->bi_flashsize = flash_init();
+ bd->bi_flashoffset = (unsigned long)_edata - (unsigned long)_text;
+
+ if (bd->bi_flashsize)
+ display_flash_config();
+#endif
+
+ if (bd->bi_dram[0].size)
+ display_dram_config();
+
+ gd->bd->bi_boot_params = malloc(CONFIG_SYS_BOOTPARAMS_LEN);
+ if (!gd->bd->bi_boot_params)
+ puts("WARNING: Cannot allocate space for boot parameters\n");
+
+ /* initialize environment */
+ env_relocate();
+
+ stdio_init();
+ jumptable_init();
+ console_init_r();
+
+ /* Initialize from environment */
+ load_addr = getenv_ulong("loadaddr", 16, load_addr);
+
+#ifdef CONFIG_BITBANGMII
+ bb_miiphy_init();
+#endif
+#if defined(CONFIG_CMD_NET)
+ puts("Net: ");
+ eth_initialize(gd->bd);
+#endif
+
+#ifdef CONFIG_GENERIC_ATMEL_MCI
+ mmc_initialize(gd->bd);
+#endif
+ for (;;) {
+ main_loop();
+ }
+}
diff --git a/qemu/roms/u-boot/arch/avr32/lib/bootm.c b/qemu/roms/u-boot/arch/avr32/lib/bootm.c
new file mode 100644
index 000000000..1c26f1b36
--- /dev/null
+++ b/qemu/roms/u-boot/arch/avr32/lib/bootm.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <command.h>
+#include <image.h>
+#include <u-boot/zlib.h>
+#include <asm/byteorder.h>
+#include <asm/arch/addrspace.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/arch/clk.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* CPU-specific hook to allow flushing of caches, etc. */
+extern void prepare_to_boot(void);
+
+static struct tag *setup_start_tag(struct tag *params)
+{
+ params->hdr.tag = ATAG_CORE;
+ params->hdr.size = tag_size(tag_core);
+
+ params->u.core.flags = 0;
+ params->u.core.pagesize = 4096;
+ params->u.core.rootdev = 0;
+
+ return tag_next(params);
+}
+
+static struct tag *setup_memory_tags(struct tag *params)
+{
+ bd_t *bd = gd->bd;
+ int i;
+
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ params->hdr.tag = ATAG_MEM;
+ params->hdr.size = tag_size(tag_mem_range);
+
+ params->u.mem_range.addr = bd->bi_dram[i].start;
+ params->u.mem_range.size = bd->bi_dram[i].size;
+
+ params = tag_next(params);
+ }
+
+ return params;
+}
+
+static struct tag *setup_commandline_tag(struct tag *params, char *cmdline)
+{
+ if (!cmdline)
+ return params;
+
+ /* eat leading white space */
+ while (*cmdline == ' ') cmdline++;
+
+ /*
+ * Don't include tags for empty command lines; let the kernel
+ * use its default command line.
+ */
+ if (*cmdline == '\0')
+ return params;
+
+ params->hdr.tag = ATAG_CMDLINE;
+ params->hdr.size =
+ (sizeof (struct tag_header) + strlen(cmdline) + 1 + 3) >> 2;
+ strcpy(params->u.cmdline.cmdline, cmdline);
+
+ return tag_next(params);
+}
+
+static struct tag *setup_ramdisk_tag(struct tag *params,
+ unsigned long rd_start,
+ unsigned long rd_end)
+{
+ if (rd_start == rd_end)
+ return params;
+
+ params->hdr.tag = ATAG_RDIMG;
+ params->hdr.size = tag_size(tag_mem_range);
+
+ params->u.mem_range.addr = rd_start;
+ params->u.mem_range.size = rd_end - rd_start;
+
+ return tag_next(params);
+}
+
+static struct tag *setup_clock_tags(struct tag *params)
+{
+ params->hdr.tag = ATAG_CLOCK;
+ params->hdr.size = tag_size(tag_clock);
+ params->u.clock.clock_id = ACLOCK_BOOTCPU;
+ params->u.clock.clock_flags = 0;
+ params->u.clock.clock_hz = gd->arch.cpu_hz;
+
+#ifdef CONFIG_AT32AP7000
+ /*
+ * New kernels don't need this, but we should be backwards
+ * compatible for a while...
+ */
+ params = tag_next(params);
+
+ params->hdr.tag = ATAG_CLOCK;
+ params->hdr.size = tag_size(tag_clock);
+ params->u.clock.clock_id = ACLOCK_HSB;
+ params->u.clock.clock_flags = 0;
+ params->u.clock.clock_hz = get_hsb_clk_rate();
+#endif
+
+ return tag_next(params);
+}
+
+static struct tag *setup_ethernet_tag(struct tag *params,
+ char *addr, int index)
+{
+ char *s, *e;
+ int i;
+
+ params->hdr.tag = ATAG_ETHERNET;
+ params->hdr.size = tag_size(tag_ethernet);
+
+ params->u.ethernet.mac_index = index;
+ params->u.ethernet.mii_phy_addr = gd->bd->bi_phy_id[index];
+
+ s = addr;
+ for (i = 0; i < 6; i++) {
+ params->u.ethernet.hw_address[i] = simple_strtoul(s, &e, 16);
+ s = e + 1;
+ }
+
+ return tag_next(params);
+}
+
+static struct tag *setup_ethernet_tags(struct tag *params)
+{
+ char name[16] = "ethaddr";
+ char *addr;
+ int i = 0;
+
+ do {
+ addr = getenv(name);
+ if (addr)
+ params = setup_ethernet_tag(params, addr, i);
+ sprintf(name, "eth%daddr", ++i);
+ } while (i < 4);
+
+ return params;
+}
+
+static struct tag *setup_boardinfo_tag(struct tag *params)
+{
+ params->hdr.tag = ATAG_BOARDINFO;
+ params->hdr.size = tag_size(tag_boardinfo);
+
+ params->u.boardinfo.board_number = gd->bd->bi_board_number;
+
+ return tag_next(params);
+}
+
+static void setup_end_tag(struct tag *params)
+{
+ params->hdr.tag = ATAG_NONE;
+ params->hdr.size = 0;
+}
+
+int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
+{
+ void (*theKernel)(int magic, void *tagtable);
+ struct tag *params, *params_start;
+ char *commandline = getenv("bootargs");
+
+ /*
+ * allow the PREP bootm subcommand, it is required for bootm to work
+ *
+ * TODO: Andreas Bießmann <andreas.devel@googlemail.com> refactor the
+ * do_bootm_linux() for avr32
+ */
+ if (flag & BOOTM_STATE_OS_PREP)
+ return 0;
+
+ if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
+ return 1;
+
+ theKernel = (void *)images->ep;
+
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+ params = params_start = (struct tag *)gd->bd->bi_boot_params;
+ params = setup_start_tag(params);
+ params = setup_memory_tags(params);
+ if (images->rd_start) {
+ params = setup_ramdisk_tag(params,
+ PHYSADDR(images->rd_start),
+ PHYSADDR(images->rd_end));
+ }
+ params = setup_commandline_tag(params, commandline);
+ params = setup_clock_tags(params);
+ params = setup_ethernet_tags(params);
+ params = setup_boardinfo_tag(params);
+ setup_end_tag(params);
+
+ printf("\nStarting kernel at %p (params at %p)...\n\n",
+ theKernel, params_start);
+
+ prepare_to_boot();
+
+ theKernel(ATAG_MAGIC, params_start);
+ /* does not return */
+
+ return 1;
+}
diff --git a/qemu/roms/u-boot/arch/avr32/lib/interrupts.c b/qemu/roms/u-boot/arch/avr32/lib/interrupts.c
new file mode 100644
index 000000000..bacb2d186
--- /dev/null
+++ b/qemu/roms/u-boot/arch/avr32/lib/interrupts.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+
+#include <asm/sysreg.h>
+
+void enable_interrupts(void)
+{
+ asm volatile("csrf %0" : : "n"(SYSREG_GM_OFFSET));
+}
+
+int disable_interrupts(void)
+{
+ unsigned long sr;
+
+ sr = sysreg_read(SR);
+ asm volatile("ssrf %0" : : "n"(SYSREG_GM_OFFSET));
+
+#ifdef CONFIG_AT32UC3A0xxx
+ /* Two NOPs are required after masking interrupts on the
+ * AT32UC3A0512ES. See errata 41.4.5.5. */
+ asm("nop");
+ asm("nop");
+#endif
+
+ return !SYSREG_BFEXT(GM, sr);
+}
diff --git a/qemu/roms/u-boot/arch/avr32/lib/memset.S b/qemu/roms/u-boot/arch/avr32/lib/memset.S
new file mode 100644
index 000000000..ac2d38860
--- /dev/null
+++ b/qemu/roms/u-boot/arch/avr32/lib/memset.S
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+ /*
+ * r12: void *b
+ * r11: int c
+ * r10: size_t len
+ *
+ * Returns b in r12
+ */
+ .section .text.memset, "ax", @progbits
+
+ .global memset
+ .type memset, @function
+ .align 2
+memset:
+ mov r9, r12
+ mov r8, r12
+ or r11, r11, r11 << 8
+ andl r9, 3, COH
+ brne 1f
+
+2: or r11, r11, r11 << 16
+ sub r10, 4
+ brlt 5f
+
+ /* Let's do some real work */
+4: st.w r8++, r11
+ sub r10, 4
+ brge 4b
+
+ /*
+ * When we get here, we've got less than 4 bytes to set. r10
+ * might be negative.
+ */
+5: sub r10, -4
+ reteq r12
+
+ /* Fastpath ends here, exactly 32 bytes from memset */
+
+ /* Handle unaligned count or pointer */
+ bld r10, 1
+ brcc 6f
+ st.b r8++, r11
+ st.b r8++, r11
+ bld r10, 0
+ retcc r12
+6: st.b r8++, r11
+ mov pc, lr
+
+ /* Handle unaligned pointer */
+1: sub r10, 4
+ brlt 5b
+ add r10, r9
+ lsl r9, 1
+ add pc, r9
+ st.b r8++, r11
+ st.b r8++, r11
+ st.b r8++, r11
+ rjmp 2b
+
+ .size memset, . - memset