From 76316a318de91f6184e7c22a10e02d275ade2441 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Sun, 11 Mar 2007 13:42:58 +0100 Subject: [PATCH 01/17] [Microblaze][PATCH] timer support interrupt controller support flash support ethernet support cache support board information support env support booting image support adding support for Xilinx ML401 --- board/xilinx/ml401/Makefile | 65 +++++++ board/xilinx/ml401/config.mk | 29 +++ board/xilinx/ml401/ml401.c | 49 +++++ board/xilinx/ml401/u-boot.lds | 66 +++++++ board/xilinx/ml401/xparameters.h | 56 ++++++ cpu/microblaze/cache.c | 48 +++++ cpu/microblaze/dcache.S | 68 +++++++ cpu/microblaze/disable_int.S | 46 +++++ cpu/microblaze/enable_int.S | 38 ++++ cpu/microblaze/exception.c | 68 +++++++ cpu/microblaze/icache.S | 69 +++++++ cpu/microblaze/irq.S | 165 ++++++++++++++++ cpu/microblaze/timer.c | 68 +++++++ include/asm-microblaze/microblaze_intc.h | 41 ++++ include/asm-microblaze/microblaze_timer.h | 42 ++++ include/configs/ml401.h | 221 ++++++++++++++++++++++ 16 files changed, 1139 insertions(+) create mode 100644 board/xilinx/ml401/Makefile create mode 100644 board/xilinx/ml401/config.mk create mode 100644 board/xilinx/ml401/ml401.c create mode 100644 board/xilinx/ml401/u-boot.lds create mode 100644 board/xilinx/ml401/xparameters.h create mode 100644 cpu/microblaze/cache.c create mode 100644 cpu/microblaze/dcache.S create mode 100644 cpu/microblaze/disable_int.S create mode 100644 cpu/microblaze/enable_int.S create mode 100644 cpu/microblaze/exception.c create mode 100644 cpu/microblaze/icache.S create mode 100644 cpu/microblaze/irq.S create mode 100644 cpu/microblaze/timer.c create mode 100644 include/asm-microblaze/microblaze_intc.h create mode 100644 include/asm-microblaze/microblaze_timer.h create mode 100644 include/configs/ml401.h diff --git a/board/xilinx/ml401/Makefile b/board/xilinx/ml401/Makefile new file mode 100644 index 0000000000..9ab5633626 --- /dev/null +++ b/board/xilinx/ml401/Makefile @@ -0,0 +1,65 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk +ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)../common) +$(shell mkdir -p $(obj)../xilinx_enet) +endif + +INCS := -I../common -I../xilinx_enet +CFLAGS += $(INCS) +HOST_CFLAGS += $(INCS) + +LIB = $(obj)lib$(BOARD).a + +COBJS = $(BOARD).o \ + ../xilinx_enet/emac_adapter.o ../xilinx_enet/xemac.o \ + ../xilinx_enet/xemac_options.o ../xilinx_enet/xemac_polled.o \ + ../xilinx_enet/xemac_intr.o ../xilinx_enet/xemac_g.o \ + ../xilinx_enet/xemac_intr_dma.o ../common/xipif_v1_23_b.o \ + ../common/xbasic_types.o ../common/xdma_channel.o \ + ../common/xdma_channel_sg.o ../common/xpacket_fifo_v1_00_b.o \ + ../common/xversion.o \ + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/xilinx/ml401/config.mk b/board/xilinx/ml401/config.mk new file mode 100644 index 0000000000..48f792a14f --- /dev/null +++ b/board/xilinx/ml401/config.mk @@ -0,0 +1,29 @@ +# +# (C) Copyright 2004 Atmark Techno, Inc. +# +# Yasushi SHOJI +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +TEXT_BASE = 0x12000000 + +PLATFORM_CPPFLAGS += -mno-xl-soft-mul +PLATFORM_CPPFLAGS += -mno-xl-soft-div +PLATFORM_CPPFLAGS += -mxl-barrel-shift diff --git a/board/xilinx/ml401/ml401.c b/board/xilinx/ml401/ml401.c new file mode 100644 index 0000000000..a341ac2584 --- /dev/null +++ b/board/xilinx/ml401/ml401.c @@ -0,0 +1,49 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* This is a board specific file. It's OK to include board specific + * header files */ + +#include +#include + +void do_reset (void) +{ +#ifdef CFG_GPIO_0 + *((unsigned long *)(CFG_GPIO_0_ADDR)) = + ++(*((unsigned long *)(CFG_GPIO_0_ADDR))); +#endif +#ifdef CFG_RESET_ADDRESS + puts ("Reseting board\n"); + asm ("bra r0"); +#endif +} + +int gpio_init (void) +{ +#ifdef CFG_GPIO_0 + *((unsigned long *)(CFG_GPIO_0_ADDR)) = 0x0; +#endif + return 0; +} diff --git a/board/xilinx/ml401/u-boot.lds b/board/xilinx/ml401/u-boot.lds new file mode 100644 index 0000000000..93147fc6e9 --- /dev/null +++ b/board/xilinx/ml401/u-boot.lds @@ -0,0 +1,66 @@ +/* + * (C) Copyright 2004 Atmark Techno, Inc. + * + * Yasushi SHOJI + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(microblaze) +ENTRY(_start) + +SECTIONS +{ + .text ALIGN(0x4): + { + __text_start = .; + cpu/microblaze/start.o (.text) + *(.text) + __text_end = .; + } + + .rodata ALIGN(0x4): + { + __rodata_start = .; + *(.rodata) + __rodata_end = .; + } + + .data ALIGN(0x4): + { + __data_start = .; + *(.data) + __data_end = .; + } + + .u_boot_cmd ALIGN(0x4): + { + . = .; + __u_boot_cmd_start = .; + *(.u_boot_cmd) + __u_boot_cmd_end = .; + } + + .bss ALIGN(0x4): + { + __bss_start = .; + *(.bss) + __bss_end = .; + } +} diff --git a/board/xilinx/ml401/xparameters.h b/board/xilinx/ml401/xparameters.h new file mode 100644 index 0000000000..8ec2864cb3 --- /dev/null +++ b/board/xilinx/ml401/xparameters.h @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* DDR SDRAM */ +#define CONFIG_XILINX_ERAM_START 0x10000000 +#define CONFIG_XILINX_ERAM_SIZE 0x04000000 + +/* FLASH_MEMORY Settings */ +#define CONFIG_XILINX_FLASH_START 0x28000000 +#define CONFIG_XILINX_FLASH_SIZE 0x00800000 + +/* serial line */ +#define CONFIG_XILINX_UARTLITE_0_BASEADDR 0xA0000000 +#define CONFIG_XILINX_UARTLITE_0_BAUDRATE 115200 + +/* GPIO */ +#define CONFIG_XILINX_GPIO_0_BASEADDR 0x90000000 + +/* INTC */ +#define CONFIG_XILINX_INTC_0_BASEADDR 0xD1000FC0 +#define CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS 12 + +/* TIMER */ +#define CONFIG_XILINX_TIMER_0_BASEADDR 0xA2000000 +#define CONFIG_XILINX_TIMER_0_IRQ 0 + +/* ethernet */ +#define XPAR_XEMAC_NUM_INSTANCES 1 +#define XPAR_OPB_ETHERNET_0_BASEADDR 0x60000000 +#define XPAR_OPB_ETHERNET_0_HIGHADDR 0x60003FFF +#define XPAR_OPB_ETHERNET_0_DEVICE_ID 0 +#define XPAR_EMAC_0_DEVICE_ID 0 +#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST 1 +#define XPAR_OPB_ETHERNET_0_DMA_PRESENT 1 +#define XPAR_OPB_ETHERNET_0_MII_EXIST 1 diff --git a/cpu/microblaze/cache.c b/cpu/microblaze/cache.c new file mode 100644 index 0000000000..fc388ebb56 --- /dev/null +++ b/cpu/microblaze/cache.c @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#if (CONFIG_COMMANDS & CFG_CMD_CACHE) + +int dcache_status (void) +{ + int i = 0; + int mask = 0x80; + __asm__ __volatile__ ("mfs %0,rmsr"::"r" (i):"memory"); + /* i&=0x80 */ + __asm__ __volatile__ ("and %0,%0,%1"::"r" (i), "r" (mask):"memory"); + return i; +} + +int icache_status (void) +{ + int i = 0; + int mask = 0x20; + __asm__ __volatile__ ("mfs %0,rmsr"::"r" (i):"memory"); + /* i&=0x20 */ + __asm__ __volatile__ ("and %0,%0,%1"::"r" (i), "r" (mask):"memory"); + return i; +} +#endif diff --git a/cpu/microblaze/dcache.S b/cpu/microblaze/dcache.S new file mode 100644 index 0000000000..eaf96717eb --- /dev/null +++ b/cpu/microblaze/dcache.S @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + .text + .globl dcache_enable + .ent dcache_enable + .align 2 +dcache_enable: + /* Make space on stack for a temporary */ + addi r1, r1, -4 + /* Save register r12 */ + swi r12, r1, 0 + /* Read the MSR register */ + mfs r12, rmsr + /* Set the instruction enable bit */ + ori r12, r12, 0x80 + /* Save the MSR register */ + mts rmsr, r12 + /* Load register r12 */ + lwi r12, r1, 0 + /* Return */ + rtsd r15, 8 + /* Update stack in the delay slot */ + addi r1, r1, 4 + .end dcache_enable + + .text + .globl dcache_disable + .ent dcache_disable + .align 2 +dcache_disable: + /* Make space on stack for a temporary */ + addi r1, r1, -4 + /* Save register r12 */ + swi r12, r1, 0 + /* Read the MSR register */ + mfs r12, rmsr + /* Clear the data cache enable bit */ + andi r12, r12, ~0x80 + /* Save the MSR register */ + mts rmsr, r12 + /* Load register r12 */ + lwi r12, r1, 0 + /* Return */ + rtsd r15, 8 + /* Update stack in the delay slot */ + addi r1, r1, 4 + .end dcache_disable diff --git a/cpu/microblaze/disable_int.S b/cpu/microblaze/disable_int.S new file mode 100644 index 0000000000..aecd79513c --- /dev/null +++ b/cpu/microblaze/disable_int.S @@ -0,0 +1,46 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + .text + .globl microblaze_disable_interrupts + .ent microblaze_disable_interrupts + .align 2 +microblaze_disable_interrupts: + #Make space on stack for a temporary + addi r1, r1, -4 + #Save register r12 + swi r12, r1, 0 + #Read the MSR register + mfs r12, rmsr + #Clear the interrupt enable bit + andi r12, r12, ~2 + #Save the MSR register + mts rmsr, r12 + #Load register r12 + lwi r12, r1, 0 + #Return + rtsd r15, 8 + #Update stack in the delay slot + addi r1, r1, 4 + .end microblaze_disable_interrupts diff --git a/cpu/microblaze/enable_int.S b/cpu/microblaze/enable_int.S new file mode 100644 index 0000000000..c096c6c3c0 --- /dev/null +++ b/cpu/microblaze/enable_int.S @@ -0,0 +1,38 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + .text + .globl microblaze_enable_interrupts + .ent microblaze_enable_interrupts + .align 2 +microblaze_enable_interrupts: + addi r1, r1, -4 + swi r12, r1, 0 + mfs r12, rmsr + ori r12, r12, 2 + mts rmsr, r12 + lwi r12, r1, 0 + rtsd r15, 8 + addi r1, r1, 4 + .end microblaze_enable_interrupts diff --git a/cpu/microblaze/exception.c b/cpu/microblaze/exception.c new file mode 100644 index 0000000000..b135acbad9 --- /dev/null +++ b/cpu/microblaze/exception.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +void _hw_exception_handler (void) +{ + int address = 0; + int state = 0; + /* loading address of exception EAR */ + __asm__ __volatile ("mfs %0,rear"::"r" (address):"memory"); + /* loading excetpion state register ESR */ + __asm__ __volatile ("mfs %0,resr"::"r" (state):"memory"); + printf ("Hardware exception at 0x%x address\n", address); + switch (state & 0x1f) { /* mask on exception cause */ + case 0x1: + puts ("Unaligned data access exception\n"); + break; + case 0x2: + puts ("Illegal op-code exception\n"); + break; + case 0x3: + puts ("Instruction bus error exception\n"); + break; + case 0x4: + puts ("Data bus error exception\n"); + break; + case 0x5: + puts ("Divide by zero exception\n"); + break; + default: + puts ("Undefined cause\n"); + break; + } + printf ("Unaligned %sword access\n", ((state & 0x800) ? "" : "half")); + printf ("Unaligned %s access\n", ((state & 0x400) ? "store" : "load")); + printf ("Register R%x\n", (state & 0x3E) >> 5); + hang (); +} + +#ifdef CFG_USR_EXCEP +void _exception_handler (void) +{ + puts ("User vector_exception\n"); + hang (); +} +#endif diff --git a/cpu/microblaze/icache.S b/cpu/microblaze/icache.S new file mode 100644 index 0000000000..25940d106e --- /dev/null +++ b/cpu/microblaze/icache.S @@ -0,0 +1,69 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + .text + .globl icache_enable + .ent icache_enable + .align 2 +icache_enable: + /* Make space on stack for a temporary */ + addi r1, r1, -4 + /* Save register r12 */ + swi r12, r1, 0 + /* Read the MSR register */ + mfs r12, rmsr + /* Set the instruction enable bit */ + ori r12, r12, 0x20 + /* Save the MSR register */ + mts rmsr, r12 + /* Load register r12 */ + lwi r12, r1, 0 + /* Return */ + rtsd r15, 8 + /* Update stack in the delay slot */ + addi r1, r1, 4 + .end icache_enable + + .text + .globl icache_disable + .ent icache_disable + .align 2 +icache_disable: + /* Make space on stack for a temporary */ + addi r1, r1, -4 + /* Save register r12 */ + swi r12, r1, 0 + /* Read the MSR register */ + mfs r12, rmsr + /* Clear the instruction enable bit */ + andi r12, r12, ~0x20 + /* Save the MSR register */ + mts rmsr, r12 + /* Load register r12 */ + lwi r12, r1, 0 + /* Return */ + rtsd r15, 8 + /* Update stack in the delay slot */ + addi r1, r1, 4 + .end icache_disable diff --git a/cpu/microblaze/irq.S b/cpu/microblaze/irq.S new file mode 100644 index 0000000000..a4e3fbfad6 --- /dev/null +++ b/cpu/microblaze/irq.S @@ -0,0 +1,165 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + .text + .global _interrupt_handler +_interrupt_handler: + addi r1, r1, -4 + swi r2, r1, 0 + addi r1, r1, -4 + swi r3, r1, 0 + addi r1, r1, -4 + swi r4, r1, 0 + addi r1, r1, -4 + swi r5, r1, 0 + addi r1, r1, -4 + swi r6, r1, 0 + addi r1, r1, -4 + swi r7, r1, 0 + addi r1, r1, -4 + swi r8, r1, 0 + addi r1, r1, -4 + swi r9, r1, 0 + addi r1, r1, -4 + swi r10, r1, 0 + addi r1, r1, -4 + swi r11, r1, 0 + addi r1, r1, -4 + swi r12, r1, 0 + addi r1, r1, -4 + swi r13, r1, 0 + addi r1, r1, -4 + swi r14, r1, 0 + addi r1, r1, -4 + swi r15, r1, 0 + addi r1, r1, -4 + swi r16, r1, 0 + addi r1, r1, -4 + swi r17, r1, 0 + addi r1, r1, -4 + swi r18, r1, 0 + addi r1, r1, -4 + swi r19, r1, 0 + addi r1, r1, -4 + swi r20, r1, 0 + addi r1, r1, -4 + swi r21, r1, 0 + addi r1, r1, -4 + swi r22, r1, 0 + addi r1, r1, -4 + swi r23, r1, 0 + addi r1, r1, -4 + swi r24, r1, 0 + addi r1, r1, -4 + swi r25, r1, 0 + addi r1, r1, -4 + swi r26, r1, 0 + addi r1, r1, -4 + swi r27, r1, 0 + addi r1, r1, -4 + swi r28, r1, 0 + addi r1, r1, -4 + swi r29, r1, 0 + addi r1, r1, -4 + swi r30, r1, 0 + addi r1, r1, -4 + swi r31, r1, 0 + brlid r15, interrupt_handler + nop + nop + lwi r31, r1, 0 + addi r1, r1, 4 + lwi r30, r1, 0 + addi r1, r1, 4 + lwi r29, r1, 0 + addi r1, r1, 4 + lwi r28, r1, 0 + addi r1, r1, 4 + lwi r27, r1, 0 + addi r1, r1, 4 + lwi r26, r1, 0 + addi r1, r1, 4 + lwi r25, r1, 0 + addi r1, r1, 4 + lwi r24, r1, 0 + addi r1, r1, 4 + lwi r23, r1, 0 + addi r1, r1, 4 + lwi r22, r1, 0 + addi r1, r1, 4 + lwi r21, r1, 0 + addi r1, r1, 4 + lwi r20, r1, 0 + addi r1, r1, 4 + lwi r19, r1, 0 + addi r1, r1, 4 + lwi r18, r1, 0 + addi r1, r1, 4 + lwi r17, r1, 0 + addi r1, r1, 4 + lwi r16, r1, 0 + addi r1, r1, 4 + lwi r15, r1, 0 + addi r1, r1, 4 + lwi r14, r1, 0 + addi r1, r1, 4 + lwi r13, r1, 0 + addi r1, r1, 4 + lwi r12, r1, 0 + addi r1, r1, 4 + lwi r11, r1, 0 + addi r1, r1, 4 + lwi r10, r1, 0 + addi r1, r1, 4 + lwi r9, r1, 0 + addi r1, r1, 4 + lwi r8, r1, 0 + addi r1, r1, 4 + lwi r7, r1, 0 + addi r1, r1, 4 + lwi r6, r1, 0 + addi r1, r1, 4 + lwi r5, r1, 0 + addi r1, r1, 4 + lwi r4, r1, 0 + addi r1, r1, 4 + lwi r3, r1, 0 + addi r1, r1, 4 + lwi r2, r1, 0 + addi r1, r1, 4 + + /* enable_interrupt */ + addi r1, r1, -4 + swi r12, r1, 0 + mfs r12, rmsr + ori r12, r12, 2 + mts rmsr, r12 + lwi r12, r1, 0 + addi r1, r1, 4 + nop + bra r14 + nop + nop + .size _interrupt_handler,.-_interrupt_handler diff --git a/cpu/microblaze/timer.c b/cpu/microblaze/timer.c new file mode 100644 index 0000000000..be4fd57cc4 --- /dev/null +++ b/cpu/microblaze/timer.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +volatile int timestamp = 0; + +void reset_timer (void) +{ + timestamp = 0; +} + +ulong get_timer (ulong base) +{ + return (timestamp - base); +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +#ifdef CFG_INTC_0 +#ifdef CFG_TIMER_0 +extern void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, + void *arg); + +microblaze_timer_t *tmr = (microblaze_timer_t *) (CFG_TIMER_0_ADDR); + +void timer_isr (void *arg) +{ + timestamp++; + tmr->control = tmr->control | TIMER_INTERRUPT; +} + +void timer_init (void) +{ + tmr->loadreg = CFG_TIMER_0_PRELOAD; + tmr->control = TIMER_INTERRUPT | TIMER_RESET; + tmr->control = + TIMER_ENABLE | TIMER_ENABLE_INTR | TIMER_RELOAD | TIMER_DOWN_COUNT; + reset_timer (); + install_interrupt_handler (CFG_TIMER_0_IRQ, timer_isr, (void *)tmr); +} +#endif +#endif diff --git a/include/asm-microblaze/microblaze_intc.h b/include/asm-microblaze/microblaze_intc.h new file mode 100644 index 0000000000..73f732c566 --- /dev/null +++ b/include/asm-microblaze/microblaze_intc.h @@ -0,0 +1,41 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +typedef volatile struct microblaze_intc_t { + int isr; /* interrupt status register */ + int ipr; /* interrupt pending register */ + int ier; /* interrupt enable register */ + int iar; /* interrupt acknowledge register */ + int sie; /* set interrupt enable bits */ + int cie; /* clear interrupt enable bits */ + int ivr; /* interrupt vector register */ + int mer; /* master enable register */ +} microblaze_intc_t; + +struct irq_action { + interrupt_handler_t *handler; /* pointer to interrupt rutine */ + void *arg; + int count; /* number of interrupt */ +}; + diff --git a/include/asm-microblaze/microblaze_timer.h b/include/asm-microblaze/microblaze_timer.h new file mode 100644 index 0000000000..b3d194bd47 --- /dev/null +++ b/include/asm-microblaze/microblaze_timer.h @@ -0,0 +1,42 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#define TIMER_ENABLE_ALL 0x400 /* ENALL */ +#define TIMER_PWM 0x200 /* PWMA0 */ +#define TIMER_INTERRUPT 0x100 /* T0INT */ +#define TIMER_ENABLE 0x080 /* ENT0 */ +#define TIMER_ENABLE_INTR 0x040 /* ENIT0 */ +#define TIMER_RESET 0x020 /* LOAD0 */ +#define TIMER_RELOAD 0x010 /* ARHT0 */ +#define TIMER_EXT_CAPTURE 0x008 /* CAPT0 */ +#define TIMER_EXT_COMPARE 0x004 /* GENT0 */ +#define TIMER_DOWN_COUNT 0x002 /* UDT0 */ +#define TIMER_CAPTURE_MODE 0x001 /* MDT0 */ + +typedef volatile struct microblaze_timer_t { + int control; /* control/statuc register TCSR */ + int loadreg; /* load register TLR */ + int counter; /* timer/counter register */ +} microblaze_timer_t; + diff --git a/include/configs/ml401.h b/include/configs/ml401.h new file mode 100644 index 0000000000..4dc2afc63d --- /dev/null +++ b/include/configs/ml401.h @@ -0,0 +1,221 @@ +/* + * (C) Copyright 2007 Czech Technical University. + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include "../board/xilinx/ml401/xparameters.h" + +#define CONFIG_MICROBLAZE 1 /* MicroBlaze CPU */ +#define CONFIG_ML401 1 /* ML401 Board */ + +/* uart */ +#define CONFIG_SERIAL_BASE CONFIG_XILINX_UARTLITE_0_BASEADDR +#define CONFIG_BAUDRATE CONFIG_XILINX_UARTLITE_0_BAUDRATE +#define CFG_BAUDRATE_TABLE { CONFIG_BAUDRATE } + +/* setting reset address */ +#define CFG_RESET_ADDRESS TEXT_BASE + +/* gpio */ +#define CFG_GPIO_0 1 +#define CFG_GPIO_0_ADDR CONFIG_XILINX_GPIO_0_BASEADDR + +/* interrupt controller */ +#define CFG_INTC_0 1 +#define CFG_INTC_0_ADDR CONFIG_XILINX_INTC_0_BASEADDR +#define CFG_INTC_0_NUM CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS + +/* timer */ +#define CFG_TIMER_0 1 +#define CFG_TIMER_0_ADDR CONFIG_XILINX_TIMER_0_BASEADDR +#define CFG_TIMER_0_IRQ CONFIG_XILINX_TIMER_0_IRQ +#define FREQUENCE 66666666 +#define CFG_TIMER_0_PRELOAD ( FREQUENCE/1000 ) + +/* + * memory layout - Example + * TEXT_BASE = 0x1200_0000; + * CFG_SRAM_BASE = 0x1000_0000; + * CFG_SRAM_SIZE = 0x0400_0000; + * + * CFG_GBL_DATA_OFFSET = 0x1000_0000 + 0x0400_0000 - 0x1000 = 0x13FF_F000 + * CFG_MONITOR_BASE = 0x13FF_F000 - 0x40000 = 0x13FB_F000 + * + * 0x1000_0000 CFG_SDRAM_BASE + * FREE + * 0x1200_0000 TEXT_BASE + * U-BOOT code + * 0x1202_0000 + * FREE + * + * STACK + * 0x11FB_F000 CFG_MONITOR_BASE + * MONITOR_CODE + * 0x13FF_F000 CFG_GBL_DATA_OFFSET + * GLOBAL_DATA + * 0x1400_0000 CFG_SDRAM_BASE + CFG_SDRAM_SIZE + */ + +/* ddr sdram - main memory */ +#define CFG_SDRAM_BASE CONFIG_XILINX_ERAM_START +#define CFG_SDRAM_SIZE CONFIG_XILINX_ERAM_SIZE +#define CFG_MEMTEST_START CFG_SDRAM_BASE +#define CFG_MEMTEST_END (CFG_SDRAM_BASE + 0x1000) + +/* global pointer */ +#define CFG_GBL_DATA_SIZE 0x1000 /* size of global data */ +#define CFG_GBL_DATA_OFFSET (CFG_SDRAM_BASE + CFG_SDRAM_SIZE - CFG_GBL_DATA_SIZE) /* start of global data */ + +/* monitor code */ +#define SIZE 0x40000 +#define CFG_MONITOR_LEN SIZE +#define CFG_MONITOR_BASE (CFG_GBL_DATA_OFFSET - CFG_MONITOR_LEN) +#define CFG_MALLOC_LEN SIZE + +/* stack */ +#define CFG_INIT_SP_OFFSET CFG_MONITOR_BASE + +/*#define RAMENV */ +#define FLASH + +#ifdef FLASH + #define CFG_FLASH_BASE CONFIG_XILINX_FLASH_START + #define CFG_FLASH_SIZE CONFIG_XILINX_FLASH_SIZE + #define CFG_FLASH_CFI 1 + #define CFG_FLASH_CFI_DRIVER 1 + #define CFG_FLASH_EMPTY_INFO 1 /* ?empty sector */ + #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ + #define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ + + #ifdef RAMENV + #define CFG_ENV_IS_NOWHERE 1 + #define CFG_ENV_SIZE 0x1000 + #define CFG_ENV_ADDR (CFG_MONITOR_BASE - CFG_ENV_SIZE) + + #else /* !RAMENV */ + #define CFG_ENV_IS_IN_FLASH 1 + #define CFG_ENV_ADDR 0x40000 + #define CFG_ENV_SECT_SIZE 0x40000 /* 256K(one sector) for env */ + #define CFG_ENV_SIZE 0x2000 + #endif /* !RAMBOOT */ +#else /* !FLASH */ + /* ENV in RAM */ + #define CFG_NO_FLASH 1 + #define CFG_ENV_IS_NOWHERE 1 + #define CFG_ENV_SIZE 0x1000 + #define CFG_ENV_ADDR (CFG_MONITOR_BASE - CFG_ENV_SIZE) +#endif /* !FLASH */ + +#ifdef FLASH + #ifdef RAMENV + #define CONFIG_COMMANDS (CONFIG__CMD_DFL |\ + CFG_CMD_MEMORY |\ + CFG_CMD_MISC |\ + CFG_CMD_AUTOSCRIPT |\ + CFG_CMD_IRQ |\ + CFG_CMD_ASKENV |\ + CFG_CMD_BDI |\ + CFG_CMD_RUN |\ + CFG_CMD_LOADS |\ + CFG_CMD_LOADB |\ + CFG_CMD_IMI |\ + CFG_CMD_NET |\ + CFG_CMD_CACHE |\ + CFG_CMD_IMLS |\ + CFG_CMD_FLASH |\ + CFG_CMD_PING \ + ) + #else /* !RAMENV */ + #define CONFIG_COMMANDS (CONFIG__CMD_DFL |\ + CFG_CMD_MEMORY |\ + CFG_CMD_MISC |\ + CFG_CMD_AUTOSCRIPT |\ + CFG_CMD_IRQ |\ + CFG_CMD_ASKENV |\ + CFG_CMD_BDI |\ + CFG_CMD_RUN |\ + CFG_CMD_LOADS |\ + CFG_CMD_LOADB |\ + CFG_CMD_IMI |\ + CFG_CMD_NET |\ + CFG_CMD_CACHE |\ + CFG_CMD_IMLS |\ + CFG_CMD_FLASH |\ + CFG_CMD_PING |\ + CFG_CMD_ENV |\ + CFG_CMD_SAVES \ + ) + + #endif + +#else /* !FLASH */ + #define CONFIG_COMMANDS (CONFIG__CMD_DFL |\ + CFG_CMD_MEMORY |\ + CFG_CMD_MISC |\ + CFG_CMD_AUTOSCRIPT |\ + CFG_CMD_IRQ |\ + CFG_CMD_ASKENV |\ + CFG_CMD_BDI |\ + CFG_CMD_RUN |\ + CFG_CMD_LOADS |\ + CFG_CMD_LOADB |\ + CFG_CMD_IMI |\ + CFG_CMD_NET |\ + CFG_CMD_CACHE |\ + CFG_CMD_PING \ + ) +#endif /* !FLASH */ +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + +/* Miscellaneous configurable options */ +#define CFG_PROMPT "U-Boot-mONStR> " +#define CFG_CBSIZE 512 /* size of console buffer */ +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) /* print buffer size */ +#define CFG_MAXARGS 15 /* max number of command args */ +#define CFG_LONGHELP +#define CFG_LOAD_ADDR 0x12000000 /* default load address */ + +#define CONFIG_BOOTDELAY 30 +#define CONFIG_BOOTARGS "root=romfs" +#define CONFIG_HOSTNAME "ml401" +#define CONFIG_BOOTCOMMAND "base 0;tftp 11000000 image.img;bootm" +#define CONFIG_IPADDR 192.168.0.3 +#define CONFIG_SERVERIP 192.168.0.5 +#define CONFIG_GATEWAYIP 192.168.0.1 +#define CONFIG_ETHADDR 00:E0:0C:00:00:FD + +/* architecture dependent code */ +#define CFG_USR_EXCEP /* user exception */ +#define CFG_HZ 1000 + +/* system ace */ +/*#define CONFIG_SYSTEMACE +#define DEBUG_SYSTEMACE +#define CFG_SYSTEMACE_BASE 0xCF000000 +#define CFG_SYSTEMACE_WIDTH 8 +#define CONFIG_DOS_PARTITION +*/ +#endif /* __CONFIG_H */ From cfc67116a706fd18b8f6a9c11a16753c5626d689 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Sun, 11 Mar 2007 13:48:24 +0100 Subject: [PATCH 02/17] [Microblaze][PATCH] part 2 timer support interrupt controller support flash support ethernet support cache support board information support env support booting image support adding support for Xilinx ML401 --- MAKEALL | 2 +- Makefile | 6 + board/AtmarkTechno/suzaku/u-boot.lds | 2 +- board/xilinx/xilinx_enet/emac_adapter.c | 4 + common/cmd_bdinfo.c | 26 ++++ common/env_common.c | 8 ++ cpu/microblaze/Makefile | 3 +- cpu/microblaze/interrupts.c | 182 +++++++++++++++++++++++- cpu/microblaze/start.S | 62 +++++++- lib_microblaze/board.c | 95 +++++++++++-- lib_microblaze/microblaze_linux.c | 146 ++++++++++++++++++- lib_microblaze/time.c | 9 +- microblaze_config.mk | 2 +- 13 files changed, 518 insertions(+), 29 deletions(-) diff --git a/MAKEALL b/MAKEALL index 8431b3ea53..172f3e50a3 100755 --- a/MAKEALL +++ b/MAKEALL @@ -292,7 +292,7 @@ LIST_nios2=" \ ######################################################################### LIST_microblaze=" \ - suzaku + suzaku ml401 " ######################################################################### diff --git a/Makefile b/Makefile index 358d1817c9..f67eb26f80 100644 --- a/Makefile +++ b/Makefile @@ -2304,6 +2304,11 @@ suzaku_config: unconfig @echo "#define CONFIG_SUZAKU 1" >> $(obj)include/config.h @$(MKCONFIG) -a $(@:_config=) microblaze microblaze suzaku AtmarkTechno +ml401_config: unconfig + @ >include/config.h + @echo "#define CONFIG_ML401 1" >> include/config.h + @./mkconfig -a $(@:_config=) microblaze microblaze ml401 xilinx + ######################################################################### ## Blackfin ######################################################################### @@ -2381,3 +2386,4 @@ backup: gtar --force-local -zcvf `date "+$$F-%Y-%m-%d-%T.tar.gz"` $$F ######################################################################### + diff --git a/board/AtmarkTechno/suzaku/u-boot.lds b/board/AtmarkTechno/suzaku/u-boot.lds index 00a8ef7ad9..93147fc6e9 100644 --- a/board/AtmarkTechno/suzaku/u-boot.lds +++ b/board/AtmarkTechno/suzaku/u-boot.lds @@ -61,6 +61,6 @@ SECTIONS { __bss_start = .; *(.bss) - __bss_start = .; + __bss_end = .; } } diff --git a/board/xilinx/xilinx_enet/emac_adapter.c b/board/xilinx/xilinx_enet/emac_adapter.c index f159cb6e39..de62695e5e 100644 --- a/board/xilinx/xilinx_enet/emac_adapter.c +++ b/board/xilinx/xilinx_enet/emac_adapter.c @@ -147,7 +147,11 @@ eth_rx(void) RecvFrameLength = PKTSIZE; Result = XEmac_PollRecv(&Emac, (u8 *) etherrxbuff, &RecvFrameLength); if (Result == XST_SUCCESS) { +#ifndef CONFIG_MICROBLAZE NetReceive((uchar *)etherrxbuff, RecvFrameLength); +#else + NetReceive(etherrxbuff, RecvFrameLength); +#endif return (1); } else { return (0); diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index 70de795dee..d97c09e88e 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -180,6 +180,32 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } +#elif defined(CONFIG_MICROBLAZE) /* ! PPC, which leaves Microblaze */ + +int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int i; + bd_t *bd = gd->bd; + print_num ("mem start ", (ulong)bd->bi_memstart); + print_num ("mem size ", (ulong)bd->bi_memsize); + print_num ("flash start ", (ulong)bd->bi_flashstart); + print_num ("flash size ", (ulong)bd->bi_flashsize); + print_num ("flash offset ", (ulong)bd->bi_flashoffset); +#if defined(CFG_SRAM_BASE) + print_num ("sram start ", (ulong)bd->bi_sramstart); + print_num ("sram size ", (ulong)bd->bi_sramsize); +#endif +#if defined(CFG_CMD_NET) + puts ("ethaddr ="); + for (i=0; i<6; ++i) { + printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]); + } + puts ("\nip_addr = "); + print_IPaddr (bd->bi_ip_addr); +#endif + printf ("\nbaudrate = %d bps\n", (ulong)bd->bi_baudrate); + return 0; +} #else /* ! PPC, which leaves MIPS */ diff --git a/common/env_common.c b/common/env_common.c index eb33422af4..6e193cf051 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -222,6 +222,14 @@ void env_relocate (void) DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); #endif +#ifdef CONFIG_MICROBLAZE + /* + * FIXME MALLOC error for Microblaze - error malloc return + * bad value. Correct value is CFG_MONITOR_BASE - CFG_MALLOC_LEN. + */ + env_ptr = (env_t *)CFG_MONITOR_BASE; + DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); +#endif /* * After relocation to RAM, we can always use the "memory" functions */ diff --git a/cpu/microblaze/Makefile b/cpu/microblaze/Makefile index fd544254f0..db1afa553d 100644 --- a/cpu/microblaze/Makefile +++ b/cpu/microblaze/Makefile @@ -26,7 +26,8 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o -COBJS = cpu.o interrupts.o +SOBJS = dcache.o icache.o irq.o disable_int.o enable_int.o +COBJS = cpu.o interrupts.o cache.o exception.o timer.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/microblaze/interrupts.c b/cpu/microblaze/interrupts.c index ccf67e1721..37ed16dfe1 100644 --- a/cpu/microblaze/interrupts.c +++ b/cpu/microblaze/interrupts.c @@ -1,6 +1,8 @@ /* + * (C) Copyright 2007 Michal Simek * (C) Copyright 2004 Atmark Techno, Inc. * + * Michal SIMEK * Yasushi SHOJI * * See file CREDITS for list of people who contributed to this @@ -13,7 +15,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -22,11 +24,185 @@ * MA 02111-1307 USA */ -void enable_interrupts(void) +#include +#include +#include + +#undef DEBUG_INT + +extern void microblaze_disable_interrupts (void); +extern void microblaze_enable_interrupts (void); + +void enable_interrupts (void) { + microblaze_enable_interrupts (); } -int disable_interrupts(void) +int disable_interrupts (void) { + microblaze_disable_interrupts (); return 0; } + +#ifdef CFG_INTC_0 +#ifdef CFG_TIMER_0 +extern void timer_init (void); +#endif + +static struct irq_action vecs[CFG_INTC_0_NUM]; + +/* mapping structure to interrupt controller */ +microblaze_intc_t *intc = (microblaze_intc_t *) (CFG_INTC_0_ADDR); + +/* default handler */ +void def_hdlr (void) +{ + puts ("def_hdlr\n"); +} + +void enable_one_interrupt (int irq) +{ + int mask; + int offset = 1; + offset <<= irq; + mask = intc->ier; + intc->ier = (mask | offset); +#ifdef DEBUG_INT + printf ("Enable one interrupt irq %x - mask %x,ier %x\n", offset, mask, + intc->ier); + printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + intc->iar, intc->mer); +#endif +} + +void disable_one_interrupt (int irq) +{ + int mask; + int offset = 1; + offset <<= irq; + mask = intc->ier; + intc->ier = (mask & ~offset); +#ifdef DEBUG_INT + printf ("Disable one interrupt irq %x - mask %x,ier %x\n", irq, mask, + intc->ier); + printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + intc->iar, intc->mer); +#endif +} + +/* adding new handler for interrupt */ +void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg) +{ + struct irq_action *act; + /* irq out of range */ + if ((irq < 0) || (irq > CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS)) { + puts ("IRQ out of range\n"); + return; + } + act = &vecs[irq]; + if (hdlr) { /* enable */ + act->handler = hdlr; + act->arg = arg; + act->count = 0; + enable_one_interrupt (irq); + } else { /* disable */ + + act->handler = (interrupt_handler_t *) def_hdlr; + act->arg = (void *)irq; + disable_one_interrupt (irq); + } +} + +/* initialization interrupt controller - hardware */ +void intc_init (void) +{ + intc->mer = 0; + intc->ier = 0; + intc->iar = 0xFFFFFFFF; + /* XIntc_Start - hw_interrupt enable and all interrupt enable */ + intc->mer = 0x3; +#ifdef DEBUG_INT + printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + intc->iar, intc->mer); +#endif +} + +int interrupts_init (void) +{ + int i; + /* initialize irq list */ + for (i = 0; i < CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS; i++) { + vecs[i].handler = (interrupt_handler_t *) def_hdlr; + vecs[i].arg = (void *)i; + vecs[i].count = 0; + } + /* initialize intc controller */ + intc_init (); +#ifdef CFG_TIMER_0 + timer_init (); +#endif + enable_interrupts (); + return 0; +} + +void interrupt_handler (void) +{ + int irqs; + irqs = (intc->isr & intc->ier); /* find active interrupt */ + +#ifdef DEBUG_INT + printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + intc->iar, intc->mer); + printf ("Interrupt handler on %x line, r14 %x\n", irqs, value); +#endif + struct irq_action *act = vecs; + while (irqs) { + if (irqs & 1) { +#ifdef DEBUG_INT + printf + ("Jumping to interrupt handler rutine addr %x,count %x,arg %x\n", + act->handler, act->count, act->arg); +#endif + act->handler (act->arg); + act->count++; + } + irqs >>= 1; + act++; + } + intc->iar = 0xFFFFFFFF; /* erase all events */ +#ifdef DEBUG + printf ("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr, + intc->ier, intc->iar, intc->mer); + printf ("Interrupt handler on %x line, r14\n", irqs); +#endif +} +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_IRQ) +#ifdef CFG_INTC_0 +int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + int i; + struct irq_action *act = vecs; + + puts ("\nInterrupt-Information:\n\n" + "Nr Routine Arg Count\n" + "-----------------------------\n"); + + for (i = 0; i < CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS; i++) { + if (act->handler != (interrupt_handler_t*) def_hdlr) { + printf ("%02d %08lx %08lx %d\n", i, + (int)act->handler, (int)act->arg, act->count); + } + act++; + } + puts ("\n"); + return (0); +} +#else +int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + puts ("Undefined interrupt controller\n"); +} +#endif +#endif /* CONFIG_COMMANDS & CFG_CMD_IRQ */ diff --git a/cpu/microblaze/start.S b/cpu/microblaze/start.S index 7efdbb0970..bce32978fd 100644 --- a/cpu/microblaze/start.S +++ b/cpu/microblaze/start.S @@ -1,6 +1,8 @@ /* + * (C) Copyright 2007 Michal Simek * (C) Copyright 2004 Atmark Techno, Inc. * + * Michal SIMEK * Yasushi SHOJI * * See file CREDITS for list of people who contributed to this @@ -13,7 +15,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -27,10 +29,62 @@ .text .global _start _start: + mts rmsr, r0 /* disable cache */ + addi r1, r0, CFG_INIT_SP_OFFSET + /* add opcode instruction for 32bit jump - 2 instruction imm & brai*/ + addi r6, r0, 0xb000 /* hex b000 opcode imm */ + bslli r6, r6, 16 /* shift */ + swi r6, r0, 0x0 /* reset address */ + swi r6, r0, 0x8 /* user vector exception */ + swi r6, r0, 0x10 /* interrupt */ + swi r6, r0, 0x20 /* hardware exception */ - addi r1, r0, CFG_SDRAM_BASE /* init stack pointer */ - addi r1, r1, CFG_SDRAM_SIZE /* set sp to high up */ + addi r6, r0, 0xb808 /* hew b808 opcode brai*/ + bslli r6, r6, 16 + swi r6, r0, 0x4 /* reset address */ + swi r6, r0, 0xC /* user vector exception */ + swi r6, r0, 0x14 /* interrupt */ + swi r6, r0, 0x24 /* hardware exception */ +#ifdef CFG_RESET_ADDRESS + /* reset address */ + addik r6, r0, CFG_RESET_ADDRESS + sw r6, r1, r0 + lhu r7, r1, r0 + shi r7, r0, 0x2 + shi r6, r0, 0x6 +#endif + +#ifdef CFG_USR_EXCEP + /* user_vector_exception */ + addik r6, r0, _exception_handler + sw r6, r1, r0 + lhu r7, r1, r0 + shi r7, r0, 0xa + shi r6, r0, 0xe +#endif + +#ifdef CFG_INTC_0 + /* interrupt_handler */ + addik r6, r0, _interrupt_handler + sw r6, r1, r0 + lhu r7, r1, r0 + shi r7, r0, 0x12 + shi r6, r0, 0x16 +#endif + + /* hardware exception */ + addik r6, r0, _hw_exception_handler + sw r6, r1, r0 + lhu r7, r1, r0 + shi r7, r0, 0x22 + shi r6, r0, 0x26 + + /* enable instruction and data cache */ + mfs r12, rmsr + ori r12, r12, 0xa0 + mts rmsr, r12 + + /* jumping to board_init */ brai board_init - 1: bri 1b diff --git a/lib_microblaze/board.c b/lib_microblaze/board.c index 026d247e54..273d9c441f 100644 --- a/lib_microblaze/board.c +++ b/lib_microblaze/board.c @@ -1,6 +1,8 @@ /* + * (C) Copyright 2007 Michal Simek * (C) Copyright 2004 Atmark Techno, Inc. * + * Michal SIMEK * Yasushi SHOJI * * See file CREDITS for list of people who contributed to this @@ -13,7 +15,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -30,8 +32,18 @@ DECLARE_GLOBAL_DATA_PTR; -const char version_string[] = - U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")"; +const char version_string[] = U_BOOT_VERSION " (" __DATE__ " - " __TIME__ ")"; + +#ifdef CFG_GPIO_0 +extern int gpio_init (void); +#endif +#ifdef CFG_INTC_0 +extern int interrupts_init (void); +#endif +#if (CONFIG_COMMANDS & CFG_CMD_NET) +extern int eth_init (bd_t * bis); +extern int getenv_IPaddr (char *); +#endif /* * Begin and End of memory area for malloc(), and current "brk" @@ -40,6 +52,18 @@ static ulong mem_malloc_start; static ulong mem_malloc_end; static ulong mem_malloc_brk; +/* + * The Malloc area is immediately below the monitor copy in DRAM + * aka CFG_MONITOR_BASE - Note there is no need for reloc_off + * as our monitory code is run from SDRAM + */ +static void mem_malloc_init (void) +{ + mem_malloc_end = CFG_MONITOR_BASE + CFG_MONITOR_LEN; + mem_malloc_start = CFG_MONITOR_BASE; + mem_malloc_brk = mem_malloc_start; + memset ((void *)mem_malloc_start, 0, mem_malloc_end - mem_malloc_start); +} void *sbrk (ptrdiff_t increment) { @@ -50,7 +74,7 @@ void *sbrk (ptrdiff_t increment) return (NULL); } mem_malloc_brk = new; - return ((void *) old); + return ((void *)old); } /* @@ -68,24 +92,36 @@ void *sbrk (ptrdiff_t increment) typedef int (init_fnc_t) (void); init_fnc_t *init_sequence[] = { - serial_init, /* serial communications setup */ + env_init, + serial_init, +#ifdef CFG_GPIO_0 + gpio_init, +#endif +#ifdef CFG_INTC_0 + interrupts_init, +#endif NULL, }; -void board_init(void) +void board_init (void) { bd_t *bd; init_fnc_t **init_fnc_ptr; - - /* Pointer is writable since we allocated a register for it. */ - gd = (gd_t *)CFG_GBL_DATA_OFFSET; - memset((void *)gd, 0, CFG_GBL_DATA_SIZE); - - gd->bd = (bd_t *)(gd+1); /* At end of global data */ + gd = (gd_t *) CFG_GBL_DATA_OFFSET; +#if (CONFIG_COMMANDS & CFG_CMD_FLASH) + ulong flash_size = 0; +#endif + asm ("nop"); /* FIXME gd is not initialize - wait */ + memset ((void *)gd, 0, CFG_GBL_DATA_SIZE); + gd->bd = (bd_t *) (gd + 1); /* At end of global data */ gd->baudrate = CONFIG_BAUDRATE; - bd = gd->bd; bd->bi_baudrate = CONFIG_BAUDRATE; + bd->bi_memstart = CFG_SDRAM_BASE; + bd->bi_memsize = CFG_SDRAM_SIZE; + + /* Initialise malloc() area */ + mem_malloc_init (); for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { WATCHDOG_RESET (); @@ -94,6 +130,37 @@ void board_init(void) } } +#if (CONFIG_COMMANDS & CFG_CMD_FLASH) + bd->bi_flashstart = CFG_FLASH_BASE; + if (0 < (flash_size = flash_init ())) { + bd->bi_flashsize = flash_size; + bd->bi_flashoffset = CFG_FLASH_BASE + flash_size; + } else { + puts ("Flash init FAILED"); + bd->bi_flashstart = 0; + bd->bi_flashsize = 0; + bd->bi_flashoffset = 0; + } +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_NET) + char *s, *e; + int i; + /* board MAC address */ + s = getenv ("ethaddr"); + for (i = 0; i < 6; ++i) { + bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0; + if (s) + s = (*e) ? e + 1 : e; + } + /* IP Address */ + bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); + eth_init (bd); +#endif + + /* relocate environment function pointers etc. */ + env_relocate (); + /* main_loop */ for (;;) { WATCHDOG_RESET (); @@ -104,5 +171,5 @@ void board_init(void) void hang (void) { puts ("### ERROR ### Please RESET the board ###\n"); - for (;;); + for (;;) ; } diff --git a/lib_microblaze/microblaze_linux.c b/lib_microblaze/microblaze_linux.c index b3a0815510..2c7885c1f1 100644 --- a/lib_microblaze/microblaze_linux.c +++ b/lib_microblaze/microblaze_linux.c @@ -1,6 +1,8 @@ /* + * (C) Copyright 2007 Michal Simek * (C) Copyright 2004 Atmark Techno, Inc. * + * Michal SIMEK * Yasushi SHOJI * * See file CREDITS for list of people who contributed to this @@ -13,7 +15,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -24,8 +26,146 @@ #include #include +#include +#include +#include -void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# include +# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) +#else +# define SHOW_BOOT_PROGRESS(arg) +#endif + +extern image_header_t header; /* from cmd_bootm.c */ +/*cmd_boot.c*/ +extern int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); + +void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], + ulong addr, ulong * len_ptr, int verify) { + ulong len = 0, checksum; + ulong initrd_start, initrd_end; + ulong data; + /* First parameter is mapped to $r5 for kernel boot args */ + void (*theKernel) (char *); + image_header_t *hdr = &header; + char *commandline = getenv ("bootargs"); + int i; + + theKernel = (void (*)(char *))ntohl (hdr->ih_ep); + + /* Check if there is an initrd image */ + if (argc >= 3) { + SHOW_BOOT_PROGRESS (9); + + addr = simple_strtoul (argv[2], NULL, 16); + + printf ("## Loading Ramdisk Image at %08lx ...\n", addr); + + /* Copy header so we can blank CRC field for re-calculation */ + memcpy (&header, (char *)addr, sizeof (image_header_t)); + + if (ntohl (hdr->ih_magic) != IH_MAGIC) { + printf ("Bad Magic Number\n"); + SHOW_BOOT_PROGRESS (-10); + do_reset (cmdtp, flag, argc, argv); + } + + data = (ulong) & header; + len = sizeof (image_header_t); + + checksum = ntohl (hdr->ih_hcrc); + hdr->ih_hcrc = 0; + + if (crc32 (0, (char *)data, len) != checksum) { + printf ("Bad Header Checksum\n"); + SHOW_BOOT_PROGRESS (-11); + do_reset (cmdtp, flag, argc, argv); + } + + SHOW_BOOT_PROGRESS (10); + + print_image_hdr (hdr); + + data = addr + sizeof (image_header_t); + len = ntohl (hdr->ih_size); + + if (verify) { + ulong csum = 0; + + printf (" Verifying Checksum ... "); + csum = crc32 (0, (char *)data, len); + if (csum != ntohl (hdr->ih_dcrc)) { + printf ("Bad Data CRC\n"); + SHOW_BOOT_PROGRESS (-12); + do_reset (cmdtp, flag, argc, argv); + } + printf ("OK\n"); + } + + SHOW_BOOT_PROGRESS (11); + + if ((hdr->ih_os != IH_OS_LINUX) || + (hdr->ih_arch != IH_CPU_MICROBLAZE) || + (hdr->ih_type != IH_TYPE_RAMDISK)) { + printf ("No Linux Microblaze Ramdisk Image\n"); + SHOW_BOOT_PROGRESS (-13); + do_reset (cmdtp, flag, argc, argv); + } + + /* + * Now check if we have a multifile image + */ + } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) { + ulong tail = ntohl (len_ptr[0]) % 4; + + SHOW_BOOT_PROGRESS (13); + + /* skip kernel length and terminator */ + data = (ulong) (&len_ptr[2]); + /* skip any additional image length fields */ + for (i = 1; len_ptr[i]; ++i) + data += 4; + /* add kernel length, and align */ + data += ntohl (len_ptr[0]); + if (tail) { + data += 4 - tail; + } + + len = ntohl (len_ptr[1]); + + } else { + /* + * no initrd image + */ + SHOW_BOOT_PROGRESS (14); + + data = 0; + } + +#ifdef DEBUG + if (!data) { + printf ("No initrd\n"); + } +#endif + + if (data) { + initrd_start = data; + initrd_end = initrd_start + len; + } else { + initrd_start = 0; + initrd_end = 0; + } + + SHOW_BOOT_PROGRESS (15); + +#ifdef DEBUG + printf ("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) theKernel); +#endif + + theKernel (commandline); } diff --git a/lib_microblaze/time.c b/lib_microblaze/time.c index 12e84888bd..3fa1b11262 100644 --- a/lib_microblaze/time.c +++ b/lib_microblaze/time.c @@ -1,6 +1,8 @@ /* + * (C) Copyright 2007 Michal Simek * (C) Copyright 2004 Atmark Techno, Inc. * + * Michal SIMEK * Yasushi SHOJI * * See file CREDITS for list of people who contributed to this @@ -22,6 +24,11 @@ * MA 02111-1307 USA */ -void udelay(unsigned long usec) +#include + +void udelay (unsigned long usec) { + int i; + i = get_timer (0); + while ((get_timer (0) - i) < (usec / 1000)) ; } diff --git a/microblaze_config.mk b/microblaze_config.mk index b3ac8e08cf..06ddefa4ce 100644 --- a/microblaze_config.mk +++ b/microblaze_config.mk @@ -22,7 +22,7 @@ # MA 02111-1307 USA # -PLATFORM_CPPFLAGS += -ffixed-r31 +PLATFORM_CPPFLAGS += -ffixed-r31 -D__microblaze__ ifdef CONFIG_MICROBLAZE_HARD_MULT PLATFORM_CPPFLAGS += -mno-xl-soft-mul From 1798049522f594013aea29457d46794298c6ae15 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 26 Mar 2007 01:39:07 +0200 Subject: [PATCH 03/17] Support for XUPV2P board Reset support BSP autoconfig support --- CREDITS | 5 + MAINTAINERS | 5 + MAKEALL | 2 +- Makefile | 5 + board/AtmarkTechno/suzaku/u-boot.lds | 1 + board/xilinx/ml401/config.mk | 27 +--- board/xilinx/ml401/u-boot.lds | 1 + board/xilinx/ml401/xparameters.h | 90 ++++++------ board/xilinx/xilinx_enet/emac_adapter.c | 2 +- board/xilinx/xupv2p/Makefile | 65 +++++++++ board/xilinx/xupv2p/config.mk | 14 ++ board/xilinx/xupv2p/u-boot.lds | 67 +++++++++ board/xilinx/xupv2p/xparameters.h | 46 +++++++ board/xilinx/xupv2p/xupv2p.c | 49 +++++++ common/env_common.c | 8 -- cpu/microblaze/interrupts.c | 6 +- cpu/microblaze/start.S | 31 ++++- include/configs/ml401.h | 41 +++--- include/configs/suzaku.h | 3 +- include/configs/xupv2p.h | 174 ++++++++++++++++++++++++ lib_microblaze/board.c | 4 +- 21 files changed, 543 insertions(+), 103 deletions(-) create mode 100644 board/xilinx/xupv2p/Makefile create mode 100644 board/xilinx/xupv2p/config.mk create mode 100644 board/xilinx/xupv2p/u-boot.lds create mode 100644 board/xilinx/xupv2p/xparameters.h create mode 100644 board/xilinx/xupv2p/xupv2p.c create mode 100644 include/configs/xupv2p.h diff --git a/CREDITS b/CREDITS index 802158879f..f896e7c7dc 100644 --- a/CREDITS +++ b/CREDITS @@ -470,3 +470,8 @@ N: Timur Tabi E: timur@freescale.com D: Support for MPC8349E-mITX W: www.freescale.com + +N: Michal Simek +E: monstr@monstr.eu +D: Support for Microblaze, ML401, XUPV2P board +W: www.monstr.eu diff --git a/MAINTAINERS b/MAINTAINERS index 1d0a8dfdb3..965f64626f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -562,6 +562,11 @@ Yasushi Shoji SUZAKU MicroBlaze +Michal Simek + + ML401 MicroBlaze + XUPV2P MicroBlaze + ######################################################################### # Coldfire Systems: # # # diff --git a/MAKEALL b/MAKEALL index 172f3e50a3..36efa40f92 100755 --- a/MAKEALL +++ b/MAKEALL @@ -292,7 +292,7 @@ LIST_nios2=" \ ######################################################################### LIST_microblaze=" \ - suzaku ml401 + suzaku ml401 xupv2p " ######################################################################### diff --git a/Makefile b/Makefile index f67eb26f80..db7b04070e 100644 --- a/Makefile +++ b/Makefile @@ -2309,6 +2309,11 @@ ml401_config: unconfig @echo "#define CONFIG_ML401 1" >> include/config.h @./mkconfig -a $(@:_config=) microblaze microblaze ml401 xilinx +xupv2p_config: unconfig + @ >include/config.h + @echo "#define CONFIG_XUPV2P 1" >> include/config.h + @./mkconfig -a $(@:_config=) microblaze microblaze xupv2p xilinx + ######################################################################### ## Blackfin ######################################################################### diff --git a/board/AtmarkTechno/suzaku/u-boot.lds b/board/AtmarkTechno/suzaku/u-boot.lds index 93147fc6e9..cb90854a39 100644 --- a/board/AtmarkTechno/suzaku/u-boot.lds +++ b/board/AtmarkTechno/suzaku/u-boot.lds @@ -63,4 +63,5 @@ SECTIONS *(.bss) __bss_end = .; } + __end = . ; } diff --git a/board/xilinx/ml401/config.mk b/board/xilinx/ml401/config.mk index 48f792a14f..07c9c4fc62 100644 --- a/board/xilinx/ml401/config.mk +++ b/board/xilinx/ml401/config.mk @@ -1,26 +1,11 @@ +#********************************************************************* # -# (C) Copyright 2004 Atmark Techno, Inc. -# -# Yasushi SHOJI -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA +# CAUTION: This file is automatically generated by libgen. +# Version: Xilinx EDK 6.3 EDK_Gmm.12.3 +# Description: U-BOOT Configuration File +# Michal Simek - monstr@monstr.eu # +#********************************************************************** TEXT_BASE = 0x12000000 diff --git a/board/xilinx/ml401/u-boot.lds b/board/xilinx/ml401/u-boot.lds index 93147fc6e9..cb90854a39 100644 --- a/board/xilinx/ml401/u-boot.lds +++ b/board/xilinx/ml401/u-boot.lds @@ -63,4 +63,5 @@ SECTIONS *(.bss) __bss_end = .; } + __end = . ; } diff --git a/board/xilinx/ml401/xparameters.h b/board/xilinx/ml401/xparameters.h index 8ec2864cb3..10ffd98ab0 100644 --- a/board/xilinx/ml401/xparameters.h +++ b/board/xilinx/ml401/xparameters.h @@ -1,56 +1,48 @@ -/* - * (C) Copyright 2007 Michal Simek - * - * Michal SIMEK - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ +/********************************************************************* +# +# CAUTION: This file is automatically generated by libgen. +# Version: Xilinx EDK 6.3 EDK_Gmm.12.3 +# Description: U-BOOT Configuration File +# Michal Simek - monstr@monstr.eu +# +**********************************************************************/ -/* DDR SDRAM */ -#define CONFIG_XILINX_ERAM_START 0x10000000 -#define CONFIG_XILINX_ERAM_SIZE 0x04000000 +/* System Clock Frequency */ +#define XILINX_CLOCK_FREQ 66666667 -/* FLASH_MEMORY Settings */ -#define CONFIG_XILINX_FLASH_START 0x28000000 -#define CONFIG_XILINX_FLASH_SIZE 0x00800000 +/* Interrupt controller is intc_0 */ +#define XILINX_INTC_BASEADDR 0xd1000fc0 +#define XILINX_INTC_NUM_INTR_INPUTS 12 -/* serial line */ -#define CONFIG_XILINX_UARTLITE_0_BASEADDR 0xA0000000 -#define CONFIG_XILINX_UARTLITE_0_BAUDRATE 115200 +/* Timer pheriphery is opb_timer_0 */ +#define XILINX_TIMER_BASEADDR 0xa2000000 +#define XILINX_TIMER_IRQ 0 -/* GPIO */ -#define CONFIG_XILINX_GPIO_0_BASEADDR 0x90000000 +/* Uart pheriphery is console_uart */ +#define XILINX_UART_BASEADDR 0xa0000000 +#define XILINX_UART_BAUDRATE 115200 -/* INTC */ -#define CONFIG_XILINX_INTC_0_BASEADDR 0xD1000FC0 -#define CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS 12 +/* GPIO is opb_gpio_0*/ +#define XILINX_GPIO_BASEADDR 0x90000000 -/* TIMER */ -#define CONFIG_XILINX_TIMER_0_BASEADDR 0xA2000000 -#define CONFIG_XILINX_TIMER_0_IRQ 0 +/* Flash Memory is opb_emc_0 */ +#define XILINX_FLASH_START 0x28000000 +#define XILINX_FLASH_SIZE 0x00800000 -/* ethernet */ -#define XPAR_XEMAC_NUM_INSTANCES 1 -#define XPAR_OPB_ETHERNET_0_BASEADDR 0x60000000 -#define XPAR_OPB_ETHERNET_0_HIGHADDR 0x60003FFF -#define XPAR_OPB_ETHERNET_0_DEVICE_ID 0 -#define XPAR_EMAC_0_DEVICE_ID 0 -#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST 1 -#define XPAR_OPB_ETHERNET_0_DMA_PRESENT 1 -#define XPAR_OPB_ETHERNET_0_MII_EXIST 1 +/* Main Memory is plb_ddr_0 */ +#define XILINX_RAM_START 0x10000000 +#define XILINX_RAM_SIZE 0x10000000 + +/* Sysace Controller is opb_sysace_0 */ +#define XILINX_SYSACE_BASEADDR 0xCF000000 +#define XILINX_SYSACE_HIGHADDR 0xCF0001FF +#define XILINX_SYSACE_MEM_WIDTH 16 + +/* Ethernet controller is opb_ethernet_0 */ +#define XPAR_XEMAC_NUM_INSTANCES 1 +#define XPAR_OPB_ETHERNET_0_DEVICE_ID 0 +#define XPAR_OPB_ETHERNET_0_BASEADDR 0x60000000 +#define XPAR_OPB_ETHERNET_0_HIGHADDR 0x60003FFF +#define XPAR_OPB_ETHERNET_0_DMA_PRESENT 1 +#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST 1 +#define XPAR_OPB_ETHERNET_0_MII_EXIST 1 diff --git a/board/xilinx/xilinx_enet/emac_adapter.c b/board/xilinx/xilinx_enet/emac_adapter.c index de62695e5e..5a7e59e634 100644 --- a/board/xilinx/xilinx_enet/emac_adapter.c +++ b/board/xilinx/xilinx_enet/emac_adapter.c @@ -147,7 +147,7 @@ eth_rx(void) RecvFrameLength = PKTSIZE; Result = XEmac_PollRecv(&Emac, (u8 *) etherrxbuff, &RecvFrameLength); if (Result == XST_SUCCESS) { -#ifndef CONFIG_MICROBLAZE +#ifndef CONFIG_EMACLITE NetReceive((uchar *)etherrxbuff, RecvFrameLength); #else NetReceive(etherrxbuff, RecvFrameLength); diff --git a/board/xilinx/xupv2p/Makefile b/board/xilinx/xupv2p/Makefile new file mode 100644 index 0000000000..9ab5633626 --- /dev/null +++ b/board/xilinx/xupv2p/Makefile @@ -0,0 +1,65 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk +ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)../common) +$(shell mkdir -p $(obj)../xilinx_enet) +endif + +INCS := -I../common -I../xilinx_enet +CFLAGS += $(INCS) +HOST_CFLAGS += $(INCS) + +LIB = $(obj)lib$(BOARD).a + +COBJS = $(BOARD).o \ + ../xilinx_enet/emac_adapter.o ../xilinx_enet/xemac.o \ + ../xilinx_enet/xemac_options.o ../xilinx_enet/xemac_polled.o \ + ../xilinx_enet/xemac_intr.o ../xilinx_enet/xemac_g.o \ + ../xilinx_enet/xemac_intr_dma.o ../common/xipif_v1_23_b.o \ + ../common/xbasic_types.o ../common/xdma_channel.o \ + ../common/xdma_channel_sg.o ../common/xpacket_fifo_v1_00_b.o \ + ../common/xversion.o \ + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/xilinx/xupv2p/config.mk b/board/xilinx/xupv2p/config.mk new file mode 100644 index 0000000000..94c13c8904 --- /dev/null +++ b/board/xilinx/xupv2p/config.mk @@ -0,0 +1,14 @@ +#********************************************************************* +# +# CAUTION: This file is automatically generated by libgen. +# Version: Xilinx EDK 8.2.02 EDK_Im_Sp2.4 +# Description: U-BOOT Configuration File +# Michal Simek - monstr@monstr.eu +# +#********************************************************************** + +TEXT_BASE = 0x38000000 + +PLATFORM_CPPFLAGS += -mno-xl-soft-mul +PLATFORM_CPPFLAGS += -mno-xl-soft-div +PLATFORM_CPPFLAGS += -mxl-barrel-shift diff --git a/board/xilinx/xupv2p/u-boot.lds b/board/xilinx/xupv2p/u-boot.lds new file mode 100644 index 0000000000..cb90854a39 --- /dev/null +++ b/board/xilinx/xupv2p/u-boot.lds @@ -0,0 +1,67 @@ +/* + * (C) Copyright 2004 Atmark Techno, Inc. + * + * Yasushi SHOJI + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(microblaze) +ENTRY(_start) + +SECTIONS +{ + .text ALIGN(0x4): + { + __text_start = .; + cpu/microblaze/start.o (.text) + *(.text) + __text_end = .; + } + + .rodata ALIGN(0x4): + { + __rodata_start = .; + *(.rodata) + __rodata_end = .; + } + + .data ALIGN(0x4): + { + __data_start = .; + *(.data) + __data_end = .; + } + + .u_boot_cmd ALIGN(0x4): + { + . = .; + __u_boot_cmd_start = .; + *(.u_boot_cmd) + __u_boot_cmd_end = .; + } + + .bss ALIGN(0x4): + { + __bss_start = .; + *(.bss) + __bss_end = .; + } + __end = . ; +} diff --git a/board/xilinx/xupv2p/xparameters.h b/board/xilinx/xupv2p/xparameters.h new file mode 100644 index 0000000000..fc7d6e7e85 --- /dev/null +++ b/board/xilinx/xupv2p/xparameters.h @@ -0,0 +1,46 @@ +/********************************************************************* +# +# CAUTION: This file is automatically generated by libgen. +# Version: Xilinx EDK 8.2.02 EDK_Im_Sp2.4 +# Description: U-BOOT Configuration File +# Michal Simek - monstr@monstr.eu +# +**********************************************************************/ + +/* System Clock Frequency */ +#define XILINX_CLOCK_FREQ 100000000 + +/* Interrupt controller is opb_intc_0 */ +#define XILINX_INTC_BASEADDR 0x41200000 +#define XILINX_INTC_NUM_INTR_INPUTS 11 + +/* Timer pheriphery is opb_timer_1 */ +#define XILINX_TIMER_BASEADDR 0x41c00000 +#define XILINX_TIMER_IRQ 1 + +/* Uart pheriphery is RS232_Uart_1 */ +#define XILINX_UART_BASEADDR 0x40600000 +#define XILINX_UART_BAUDRATE 115200 + +/* GPIO is LEDs_4Bit*/ +#define XILINX_GPIO_BASEADDR 0x40000000 + +/* FLASH doesn't exist none */ + +/* Main Memory is DDR_256MB_32MX64_rank1_row13_col10_cl2_5 */ +#define XILINX_RAM_START 0x30000000 +#define XILINX_RAM_SIZE 0x10000000 + +/* Sysace Controller is SysACE_CompactFlash */ +#define XILINX_SYSACE_BASEADDR 0x41800000 +#define XILINX_SYSACE_HIGHADDR 0x4180ffff +#define XILINX_SYSACE_MEM_WIDTH 16 + +/* Ethernet controller is Ethernet_MAC */ +#define XPAR_XEMAC_NUM_INSTANCES 1 +#define XPAR_OPB_ETHERNET_0_DEVICE_ID 0 +#define XPAR_OPB_ETHERNET_0_BASEADDR 0x40c00000 +#define XPAR_OPB_ETHERNET_0_HIGHADDR 0x40c0ffff +#define XPAR_OPB_ETHERNET_0_DMA_PRESENT 1 +#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST 1 +#define XPAR_OPB_ETHERNET_0_MII_EXIST 1 diff --git a/board/xilinx/xupv2p/xupv2p.c b/board/xilinx/xupv2p/xupv2p.c new file mode 100644 index 0000000000..a341ac2584 --- /dev/null +++ b/board/xilinx/xupv2p/xupv2p.c @@ -0,0 +1,49 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* This is a board specific file. It's OK to include board specific + * header files */ + +#include +#include + +void do_reset (void) +{ +#ifdef CFG_GPIO_0 + *((unsigned long *)(CFG_GPIO_0_ADDR)) = + ++(*((unsigned long *)(CFG_GPIO_0_ADDR))); +#endif +#ifdef CFG_RESET_ADDRESS + puts ("Reseting board\n"); + asm ("bra r0"); +#endif +} + +int gpio_init (void) +{ +#ifdef CFG_GPIO_0 + *((unsigned long *)(CFG_GPIO_0_ADDR)) = 0x0; +#endif + return 0; +} diff --git a/common/env_common.c b/common/env_common.c index 6e193cf051..eb33422af4 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -222,14 +222,6 @@ void env_relocate (void) DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); #endif -#ifdef CONFIG_MICROBLAZE - /* - * FIXME MALLOC error for Microblaze - error malloc return - * bad value. Correct value is CFG_MONITOR_BASE - CFG_MALLOC_LEN. - */ - env_ptr = (env_t *)CFG_MONITOR_BASE; - DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); -#endif /* * After relocation to RAM, we can always use the "memory" functions */ diff --git a/cpu/microblaze/interrupts.c b/cpu/microblaze/interrupts.c index 37ed16dfe1..2db847cd02 100644 --- a/cpu/microblaze/interrupts.c +++ b/cpu/microblaze/interrupts.c @@ -95,7 +95,7 @@ void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg) { struct irq_action *act; /* irq out of range */ - if ((irq < 0) || (irq > CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS)) { + if ((irq < 0) || (irq > CFG_INTC_0_NUM)) { puts ("IRQ out of range\n"); return; } @@ -131,7 +131,7 @@ int interrupts_init (void) { int i; /* initialize irq list */ - for (i = 0; i < CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS; i++) { + for (i = 0; i < CFG_INTC_0_NUM; i++) { vecs[i].handler = (interrupt_handler_t *) def_hdlr; vecs[i].arg = (void *)i; vecs[i].count = 0; @@ -189,7 +189,7 @@ int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) "Nr Routine Arg Count\n" "-----------------------------\n"); - for (i = 0; i < CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS; i++) { + for (i = 0; i < CFG_INTC_0_NUM; i++) { if (act->handler != (interrupt_handler_t*) def_hdlr) { printf ("%02d %08lx %08lx %d\n", i, (int)act->handler, (int)act->arg, act->count); diff --git a/cpu/microblaze/start.S b/cpu/microblaze/start.S index bce32978fd..29481af9ae 100644 --- a/cpu/microblaze/start.S +++ b/cpu/microblaze/start.S @@ -31,6 +31,7 @@ _start: mts rmsr, r0 /* disable cache */ addi r1, r0, CFG_INIT_SP_OFFSET + addi r1, r1, -4 /* Decrement SP to top of memory */ /* add opcode instruction for 32bit jump - 2 instruction imm & brai*/ addi r6, r0, 0xb000 /* hex b000 opcode imm */ bslli r6, r6, 16 /* shift */ @@ -53,6 +54,23 @@ _start: lhu r7, r1, r0 shi r7, r0, 0x2 shi r6, r0, 0x6 +/* + * Copy U-Boot code to TEXT_BASE + * solve problem with sbrk_base + */ +#if (CFG_RESET_ADDRESS != TEXT_BASE) + addi r4, r0, __end + addi r5, r0, __text_start + rsub r4, r5, r4 /* size = __end - __text_start */ + addi r6, r0, CFG_RESET_ADDRESS /* source address */ + addi r7, r0, 0 /* counter */ +4: + lw r8, r6, r7 + sw r8, r5, r7 + addi r7, r7, 0x4 + cmp r8, r4, r7 + blti r8, 4b +#endif #endif #ifdef CFG_USR_EXCEP @@ -85,6 +103,17 @@ _start: ori r12, r12, 0xa0 mts rmsr, r12 - /* jumping to board_init */ +clear_bss: + /* clear BSS segments */ + addi r5, r0, __bss_start + addi r4, r0, __bss_end + cmp r6, r5, r4 + beqi r6, 3f +2: + swi r0, r5, 0 /* write zero to loc */ + addi r5, r5, 4 /* increment to next loc */ + cmp r6, r5, r4 /* check if we have reach the end */ + bnei r6, 2b +3: /* jumping to board_init */ brai board_init 1: bri 1b diff --git a/include/configs/ml401.h b/include/configs/ml401.h index 4dc2afc63d..f4a8a1f228 100644 --- a/include/configs/ml401.h +++ b/include/configs/ml401.h @@ -31,27 +31,31 @@ #define CONFIG_ML401 1 /* ML401 Board */ /* uart */ -#define CONFIG_SERIAL_BASE CONFIG_XILINX_UARTLITE_0_BASEADDR -#define CONFIG_BAUDRATE CONFIG_XILINX_UARTLITE_0_BAUDRATE +#define CONFIG_SERIAL_BASE XILINX_UART_BASEADDR +#define CONFIG_BAUDRATE XILINX_UART_BAUDRATE #define CFG_BAUDRATE_TABLE { CONFIG_BAUDRATE } /* setting reset address */ #define CFG_RESET_ADDRESS TEXT_BASE +/* ethernet */ +#define CONFIG_EMACLITE 1 +#define XPAR_EMAC_0_DEVICE_ID XPAR_XEMAC_NUM_INSTANCES + /* gpio */ #define CFG_GPIO_0 1 -#define CFG_GPIO_0_ADDR CONFIG_XILINX_GPIO_0_BASEADDR +#define CFG_GPIO_0_ADDR XILINX_GPIO_BASEADDR /* interrupt controller */ #define CFG_INTC_0 1 -#define CFG_INTC_0_ADDR CONFIG_XILINX_INTC_0_BASEADDR -#define CFG_INTC_0_NUM CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS +#define CFG_INTC_0_ADDR XILINX_INTC_BASEADDR +#define CFG_INTC_0_NUM XILINX_INTC_NUM_INTR_INPUTS /* timer */ #define CFG_TIMER_0 1 -#define CFG_TIMER_0_ADDR CONFIG_XILINX_TIMER_0_BASEADDR -#define CFG_TIMER_0_IRQ CONFIG_XILINX_TIMER_0_IRQ -#define FREQUENCE 66666666 +#define CFG_TIMER_0_ADDR XILINX_TIMER_BASEADDR +#define CFG_TIMER_0_IRQ XILINX_TIMER_IRQ +#define FREQUENCE XILINX_CLOCK_FREQ #define CFG_TIMER_0_PRELOAD ( FREQUENCE/1000 ) /* @@ -62,6 +66,7 @@ * * CFG_GBL_DATA_OFFSET = 0x1000_0000 + 0x0400_0000 - 0x1000 = 0x13FF_F000 * CFG_MONITOR_BASE = 0x13FF_F000 - 0x40000 = 0x13FB_F000 + * CFG_MALLOC_BASE = 0x13FB_F000 - 0x40000 = 0x13F7_F000 * * 0x1000_0000 CFG_SDRAM_BASE * FREE @@ -71,16 +76,18 @@ * FREE * * STACK + * 0x13F7_F000 CFG_MALLOC_BASE + * MALLOC_AREA 256kB Alloc * 0x11FB_F000 CFG_MONITOR_BASE - * MONITOR_CODE + * MONITOR_CODE 256kB Env * 0x13FF_F000 CFG_GBL_DATA_OFFSET - * GLOBAL_DATA + * GLOBAL_DATA 4kB bd, gd * 0x1400_0000 CFG_SDRAM_BASE + CFG_SDRAM_SIZE */ /* ddr sdram - main memory */ -#define CFG_SDRAM_BASE CONFIG_XILINX_ERAM_START -#define CFG_SDRAM_SIZE CONFIG_XILINX_ERAM_SIZE +#define CFG_SDRAM_BASE XILINX_RAM_START +#define CFG_SDRAM_SIZE XILINX_RAM_SIZE #define CFG_MEMTEST_START CFG_SDRAM_BASE #define CFG_MEMTEST_END (CFG_SDRAM_BASE + 0x1000) @@ -92,7 +99,9 @@ #define SIZE 0x40000 #define CFG_MONITOR_LEN SIZE #define CFG_MONITOR_BASE (CFG_GBL_DATA_OFFSET - CFG_MONITOR_LEN) +#define CFG_MONITOR_END (CFG_MONITOR_BASE + CFG_MONITOR_LEN) #define CFG_MALLOC_LEN SIZE +#define CFG_MALLOC_BASE (CFG_MONITOR_BASE - CFG_MALLOC_LEN) /* stack */ #define CFG_INIT_SP_OFFSET CFG_MONITOR_BASE @@ -101,8 +110,8 @@ #define FLASH #ifdef FLASH - #define CFG_FLASH_BASE CONFIG_XILINX_FLASH_START - #define CFG_FLASH_SIZE CONFIG_XILINX_FLASH_SIZE + #define CFG_FLASH_BASE XILINX_FLASH_START + #define CFG_FLASH_SIZE XILINX_FLASH_SIZE #define CFG_FLASH_CFI 1 #define CFG_FLASH_CFI_DRIVER 1 #define CFG_FLASH_EMPTY_INFO 1 /* ?empty sector */ @@ -214,8 +223,8 @@ /* system ace */ /*#define CONFIG_SYSTEMACE #define DEBUG_SYSTEMACE -#define CFG_SYSTEMACE_BASE 0xCF000000 -#define CFG_SYSTEMACE_WIDTH 8 +#define CFG_SYSTEMACE_BASE XILINX_SYSACE_BASEADDR +#define CFG_SYSTEMACE_WIDTH XILINX_SYSACE_MEM_WIDTH #define CONFIG_DOS_PARTITION */ #endif /* __CONFIG_H */ diff --git a/include/configs/suzaku.h b/include/configs/suzaku.h index 1ee6be174f..be19269180 100644 --- a/include/configs/suzaku.h +++ b/include/configs/suzaku.h @@ -44,8 +44,9 @@ #define CFG_FLASH_SIZE 0x00400000 #define CFG_RESET_ADDRESS 0xfff00100 #define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ -#define CFG_MONITOR_BASE (CFG_SDRAM_BASE + CFG_SDRAM_SIZE - (1024 * 1024)) +#define CFG_MONITOR_BASE (CFG_SDRAM_BASE + CFG_SDRAM_SIZE - (1024 * 1024)) #define CFG_MALLOC_LEN (256 << 10) /* Reserve 256 kB for malloc */ +#define CFG_MALLOC_BASE (CFG_MONITOR_BASE - (1024 * 1024)) #define CONFIG_BAUDRATE 115200 #define CFG_BAUDRATE_TABLE { 115200 } diff --git a/include/configs/xupv2p.h b/include/configs/xupv2p.h new file mode 100644 index 0000000000..224db5c8be --- /dev/null +++ b/include/configs/xupv2p.h @@ -0,0 +1,174 @@ +/* + * (C) Copyright 2007 Czech Technical University. + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include "../board/xilinx/xupv2p/xparameters.h" + +#define CONFIG_MICROBLAZE 1 /* MicroBlaze CPU */ +#define CONFIG_XUPV2P 1 + +/* uart */ +#define CONFIG_SERIAL_BASE XILINX_UART_BASEADDR +#define CONFIG_BAUDRATE XILINX_UART_BAUDRATE +#define CFG_BAUDRATE_TABLE { CONFIG_BAUDRATE } + +/* ethernet */ +#define CONFIG_EMAC 1 +#define XPAR_EMAC_0_DEVICE_ID XPAR_XEMAC_NUM_INSTANCES + +/* + * setting reset address + * + * TEXT_BASE is set to place, where the U-BOOT run in RAM, but + * if you want to store U-BOOT in flash, set CFG_RESET_ADDRESS + * to FLASH memory and after loading bitstream jump to FLASH. + * U-BOOT auto-relocate to TEXT_BASE. After RESET command Microblaze + * jump to CFG_RESET_ADDRESS where is the original U-BOOT code. + */ +#define CFG_RESET_ADDRESS 0x36000000 + +/* gpio */ +#define CFG_GPIO_0 1 +#define CFG_GPIO_0_ADDR XILINX_GPIO_BASEADDR + +/* interrupt controller */ +#define CFG_INTC_0 1 +#define CFG_INTC_0_ADDR XILINX_INTC_BASEADDR +#define CFG_INTC_0_NUM XILINX_INTC_NUM_INTR_INPUTS + +/* timer */ +#define CFG_TIMER_0 1 +#define CFG_TIMER_0_ADDR XILINX_TIMER_BASEADDR +#define CFG_TIMER_0_IRQ XILINX_TIMER_IRQ +#define FREQUENCE XILINX_CLOCK_FREQ +#define CFG_TIMER_0_PRELOAD ( FREQUENCE/1000 ) + +/* + * memory layout - Example + * TEXT_BASE = 0x3600_0000; + * CFG_SRAM_BASE = 0x3000_0000; + * CFG_SRAM_SIZE = 0x1000_0000; + * + * CFG_GBL_DATA_OFFSET = 0x3000_0000 + 0x1000_0000 - 0x1000 = 0x3FFF_F000 + * CFG_MONITOR_BASE = 0x3FFF_F000 - 0x40000 = 0x3FFB_F000 + * CFG_MALLOC_BASE = 0x3FFB_F000 - 0x40000 = 0x3FF7_F000 + * + * 0x3000_0000 CFG_SDRAM_BASE + * FREE + * 0x3600_0000 TEXT_BASE + * U-BOOT code + * 0x3602_0000 + * FREE + * + * STACK + * 0x3FF7_F000 CFG_MALLOC_BASE + * MALLOC_AREA 256kB Alloc + * 0x3FFB_F000 CFG_MONITOR_BASE + * MONITOR_CODE 256kB Env + * 0x3FFF_F000 CFG_GBL_DATA_OFFSET + * GLOBAL_DATA 4kB bd, gd + * 0x4000_0000 CFG_SDRAM_BASE + CFG_SDRAM_SIZE + */ + +/* ddr sdram - main memory */ +#define CFG_SDRAM_BASE XILINX_RAM_START +#define CFG_SDRAM_SIZE XILINX_RAM_SIZE +#define CFG_MEMTEST_START CFG_SDRAM_BASE +#define CFG_MEMTEST_END (CFG_SDRAM_BASE + 0x1000) + +/* global pointer */ +#define CFG_GBL_DATA_SIZE 0x1000 /* size of global data */ +#define CFG_GBL_DATA_OFFSET (CFG_SDRAM_BASE + CFG_SDRAM_SIZE - CFG_GBL_DATA_SIZE) /* start of global data */ + +/* monitor code */ +#define SIZE 0x40000 +#define CFG_MONITOR_LEN SIZE +#define CFG_MONITOR_BASE (CFG_GBL_DATA_OFFSET - CFG_MONITOR_LEN) +#define CFG_MONITOR_END (CFG_MONITOR_BASE + CFG_MONITOR_LEN) +#define CFG_MALLOC_LEN SIZE +#define CFG_MALLOC_BASE (CFG_MONITOR_BASE - CFG_MALLOC_LEN) + +/* stack */ +#define CFG_INIT_SP_OFFSET CFG_MALLOC_BASE + +#define CFG_NO_FLASH 1 +#define CFG_ENV_IS_NOWHERE 1 +#define CFG_ENV_SIZE 0x1000 +#define CFG_ENV_ADDR (CFG_MONITOR_BASE - CFG_ENV_SIZE) +#define CONFIG_COMMANDS (CONFIG__CMD_DFL |\ + CFG_CMD_MEMORY |\ + CFG_CMD_IRQ |\ + CFG_CMD_BDI |\ + CFG_CMD_NET |\ + CFG_CMD_IMI |\ + CFG_CMD_ECHO |\ + CFG_CMD_CACHE |\ + CFG_CMD_RUN |\ + CFG_CMD_AUTOSCRIPT |\ + CFG_CMD_ASKENV |\ + CFG_CMD_LOADS |\ + CFG_CMD_LOADB |\ + CFG_CMD_MISC |\ + CFG_CMD_PING \ + ) + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + +/* Miscellaneous configurable options */ +#define CFG_PROMPT "U-Boot-mONStR> " +#define CFG_CBSIZE 512 /* size of console buffer */ +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) /* print buffer size */ +#define CFG_MAXARGS 15 /* max number of command args */ +#define CFG_LONGHELP +#define CFG_LOAD_ADDR 0x12000000 /* default load address */ + +#define CONFIG_BOOTDELAY 30 +#define CONFIG_BOOTARGS "root=romfs" +#define CONFIG_HOSTNAME "ml401" +#define CONFIG_BOOTCOMMAND "base 0;tftp 11000000 image.img;bootm" +#define CONFIG_IPADDR 192.168.0.3 +#define CONFIG_SERVERIP 192.168.0.5 +#define CONFIG_GATEWAYIP 192.168.0.1 +#define CONFIG_ETHADDR 00:E0:0C:00:00:FD + +/* architecture dependent code */ +#define CFG_USR_EXCEP /* user exception */ +#define CFG_HZ 1000 + +#define CONFIG_PREBOOT "echo U-BOOT by mONStR;" \ + "base 0;" \ + "echo" + + +/* system ace */ +/*#define CONFIG_SYSTEMACE +#define DEBUG_SYSTEMACE +#define CFG_SYSTEMACE_BASE 0xCF000000 +#define CFG_SYSTEMACE_WIDTH 16 +#define CONFIG_DOS_PARTITION*/ + +#endif /* __CONFIG_H */ diff --git a/lib_microblaze/board.c b/lib_microblaze/board.c index 273d9c441f..c95125ad33 100644 --- a/lib_microblaze/board.c +++ b/lib_microblaze/board.c @@ -59,8 +59,8 @@ static ulong mem_malloc_brk; */ static void mem_malloc_init (void) { - mem_malloc_end = CFG_MONITOR_BASE + CFG_MONITOR_LEN; - mem_malloc_start = CFG_MONITOR_BASE; + mem_malloc_end = (CFG_MALLOC_BASE + CFG_MALLOC_LEN); + mem_malloc_start = CFG_MALLOC_BASE; mem_malloc_brk = mem_malloc_start; memset ((void *)mem_malloc_start, 0, mem_malloc_end - mem_malloc_start); } From 5da048adf44bea5e3b94080d02903c2e3fe7aa4a Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 27 Mar 2007 00:32:16 +0200 Subject: [PATCH 04/17] PATCH: Resolve GPL license problem --- board/xilinx/ml401/config.mk | 26 +++++++++++++++++++---- board/xilinx/ml401/xparameters.h | 35 ++++++++++++++++++++++++------- board/xilinx/xupv2p/config.mk | 26 +++++++++++++++++++---- board/xilinx/xupv2p/xparameters.h | 34 +++++++++++++++++++++++------- 4 files changed, 97 insertions(+), 24 deletions(-) diff --git a/board/xilinx/ml401/config.mk b/board/xilinx/ml401/config.mk index 07c9c4fc62..807f169fa7 100644 --- a/board/xilinx/ml401/config.mk +++ b/board/xilinx/ml401/config.mk @@ -1,11 +1,29 @@ -#********************************************************************* +# +# (C) Copyright 2007 Michal Simek +# +# Michal SIMEK +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA # # CAUTION: This file is automatically generated by libgen. # Version: Xilinx EDK 6.3 EDK_Gmm.12.3 -# Description: U-BOOT Configuration File -# Michal Simek - monstr@monstr.eu # -#********************************************************************** TEXT_BASE = 0x12000000 diff --git a/board/xilinx/ml401/xparameters.h b/board/xilinx/ml401/xparameters.h index 10ffd98ab0..18d24f9c1d 100644 --- a/board/xilinx/ml401/xparameters.h +++ b/board/xilinx/ml401/xparameters.h @@ -1,11 +1,30 @@ -/********************************************************************* -# -# CAUTION: This file is automatically generated by libgen. -# Version: Xilinx EDK 6.3 EDK_Gmm.12.3 -# Description: U-BOOT Configuration File -# Michal Simek - monstr@monstr.eu -# -**********************************************************************/ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * CAUTION: This file is automatically generated by libgen. + * Version: Xilinx EDK 6.3 EDK_Gmm.12.3 + */ /* System Clock Frequency */ #define XILINX_CLOCK_FREQ 66666667 diff --git a/board/xilinx/xupv2p/config.mk b/board/xilinx/xupv2p/config.mk index 94c13c8904..c07b0b35b1 100644 --- a/board/xilinx/xupv2p/config.mk +++ b/board/xilinx/xupv2p/config.mk @@ -1,11 +1,29 @@ -#********************************************************************* +# +# (C) Copyright 2007 Michal Simek +# +# Michal SIMEK +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA # # CAUTION: This file is automatically generated by libgen. # Version: Xilinx EDK 8.2.02 EDK_Im_Sp2.4 -# Description: U-BOOT Configuration File -# Michal Simek - monstr@monstr.eu # -#********************************************************************** TEXT_BASE = 0x38000000 diff --git a/board/xilinx/xupv2p/xparameters.h b/board/xilinx/xupv2p/xparameters.h index fc7d6e7e85..a96c693c55 100644 --- a/board/xilinx/xupv2p/xparameters.h +++ b/board/xilinx/xupv2p/xparameters.h @@ -1,11 +1,29 @@ -/********************************************************************* -# -# CAUTION: This file is automatically generated by libgen. -# Version: Xilinx EDK 8.2.02 EDK_Im_Sp2.4 -# Description: U-BOOT Configuration File -# Michal Simek - monstr@monstr.eu -# -**********************************************************************/ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal SIMEK + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * CAUTION: This file is automatically generated by libgen. + * Version: Xilinx EDK 8.2.02 EDK_Im_Sp2.4 + */ /* System Clock Frequency */ #define XILINX_CLOCK_FREQ 100000000 From 6f934210fb293fde2cfb4251c6d96fdc58b6a906 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 30 Mar 2007 22:42:45 +0200 Subject: [PATCH 05/17] [CLEAN] Remove inefficient Suzaku code --- board/AtmarkTechno/suzaku/suzaku.c | 2 +- include/asm-microblaze/platform.h | 29 ----------------------------- include/asm-microblaze/suzaku.h | 27 --------------------------- include/configs/suzaku.h | 4 ++++ 4 files changed, 5 insertions(+), 57 deletions(-) delete mode 100644 include/asm-microblaze/platform.h delete mode 100644 include/asm-microblaze/suzaku.h diff --git a/board/AtmarkTechno/suzaku/suzaku.c b/board/AtmarkTechno/suzaku/suzaku.c index afe124a9d3..267c476f06 100644 --- a/board/AtmarkTechno/suzaku/suzaku.c +++ b/board/AtmarkTechno/suzaku/suzaku.c @@ -24,7 +24,7 @@ /* This is a board specific file. It's OK to include board specific * header files */ -#include +#include void do_reset(void) { diff --git a/include/asm-microblaze/platform.h b/include/asm-microblaze/platform.h deleted file mode 100644 index 2096cce45e..0000000000 --- a/include/asm-microblaze/platform.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * (C) Copyright 2004 Atmark Techno, Inc. - * - * Yasushi SHOJI - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#ifdef CONFIG_SUZAKU -#include -#endif diff --git a/include/asm-microblaze/suzaku.h b/include/asm-microblaze/suzaku.h deleted file mode 100644 index c57a144d3a..0000000000 --- a/include/asm-microblaze/suzaku.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * (C) Copyright 2004 Atmark Techno, Inc. - * - * Yasushi SHOJI - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* System Register (GPIO) */ -#define MICROBLAZE_SYSREG_BASE_ADDR 0xFFFFA000 -#define MICROBLAZE_SYSREG_RECONFIGURE (1 << 0) diff --git a/include/configs/suzaku.h b/include/configs/suzaku.h index be19269180..8224555896 100644 --- a/include/configs/suzaku.h +++ b/include/configs/suzaku.h @@ -51,6 +51,10 @@ #define CONFIG_BAUDRATE 115200 #define CFG_BAUDRATE_TABLE { 115200 } +/* System Register (GPIO) */ +#define MICROBLAZE_SYSREG_BASE_ADDR 0xFFFFA000 +#define MICROBLAZE_SYSREG_RECONFIGURE (1 << 0) + #define CONFIG_COMMANDS (CONFIG__CMD_DFL) /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ From 342cd097be1e7affe82f42ab3da220959a699e64 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 30 Mar 2007 22:52:09 +0200 Subject: [PATCH 06/17] [PATCH] Clean include dependence --- board/xilinx/ml401/ml401.c | 2 +- board/xilinx/xupv2p/xupv2p.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/board/xilinx/ml401/ml401.c b/board/xilinx/ml401/ml401.c index a341ac2584..b48103fdc0 100644 --- a/board/xilinx/ml401/ml401.c +++ b/board/xilinx/ml401/ml401.c @@ -26,7 +26,7 @@ * header files */ #include -#include +#include void do_reset (void) { diff --git a/board/xilinx/xupv2p/xupv2p.c b/board/xilinx/xupv2p/xupv2p.c index a341ac2584..b48103fdc0 100644 --- a/board/xilinx/xupv2p/xupv2p.c +++ b/board/xilinx/xupv2p/xupv2p.c @@ -26,7 +26,7 @@ * header files */ #include -#include +#include void do_reset (void) { From 7cd5da0fe877e7171a4cdd44880bce783132871a Mon Sep 17 00:00:00 2001 From: Gerald Van Baren Date: Sat, 31 Mar 2007 11:59:59 -0400 Subject: [PATCH 07/17] libfdt: Import libfdt source (1 of 2) This adds the applicable libfdt source files (unmodified) and a README to explain where the source came from. --- include/fdt.h | 60 +++++++++++++++++ include/libfdt.h | 135 +++++++++++++++++++++++++++++++++++++++ include/libfdt_env.h | 22 +++++++ libfdt/Makefile | 88 +++++++++++++++++++++++++ libfdt/README | 23 +++++++ libfdt/fdt.c | 124 +++++++++++++++++++++++++++++++++++ libfdt/fdt_strerror.c | 64 +++++++++++++++++++ libfdt/libfdt_internal.h | 41 ++++++++++++ 8 files changed, 557 insertions(+) create mode 100644 include/fdt.h create mode 100644 include/libfdt.h create mode 100644 include/libfdt_env.h create mode 100644 libfdt/Makefile create mode 100644 libfdt/README create mode 100644 libfdt/fdt.c create mode 100644 libfdt/fdt_strerror.c create mode 100644 libfdt/libfdt_internal.h diff --git a/include/fdt.h b/include/fdt.h new file mode 100644 index 0000000000..e00559ad6d --- /dev/null +++ b/include/fdt.h @@ -0,0 +1,60 @@ +#ifndef _FDT_H +#define _FDT_H + +#ifndef __ASSEMBLY__ + +struct fdt_header { + uint32_t magic; /* magic word FDT_MAGIC */ + uint32_t totalsize; /* total size of DT block */ + uint32_t off_dt_struct; /* offset to structure */ + uint32_t off_dt_strings; /* offset to strings */ + uint32_t off_mem_rsvmap; /* offset to memory reserve map */ + uint32_t version; /* format version */ + uint32_t last_comp_version; /* last compatible version */ + + /* version 2 fields below */ + uint32_t boot_cpuid_phys; /* Which physical CPU id we're + booting on */ + /* version 3 fields below */ + uint32_t size_dt_strings; /* size of the strings block */ + + /* version 17 fields below */ + uint32_t size_dt_struct; /* size of the structure block */ +}; + +struct fdt_reserve_entry { + uint64_t address; + uint64_t size; +}; + +struct fdt_node_header { + uint32_t tag; + char name[0]; +}; + +struct fdt_property { + uint32_t tag; + uint32_t len; + uint32_t nameoff; + char data[0]; +}; + +#endif /* !__ASSEMBLY */ + +#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ +#define FDT_TAGSIZE sizeof(uint32_t) + +#define FDT_BEGIN_NODE 0x1 /* Start node: full name */ +#define FDT_END_NODE 0x2 /* End node */ +#define FDT_PROP 0x3 /* Property: name off, + size, content */ +#define FDT_NOP 0x4 /* nop */ +#define FDT_END 0x9 + +#define FDT_V1_SIZE (7*sizeof(uint32_t)) +#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t)) +#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t)) +#define FDT_V16_SIZE FDT_V3_SIZE +#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t)) + +#endif /* _FDT_H */ diff --git a/include/libfdt.h b/include/libfdt.h new file mode 100644 index 0000000000..acdc72eac6 --- /dev/null +++ b/include/libfdt.h @@ -0,0 +1,135 @@ +#ifndef _LIBFDT_H +#define _LIBFDT_H +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#define FDT_FIRST_SUPPORTED_VERSION 0x10 +#define FDT_LAST_SUPPORTED_VERSION 0x11 + +/* Error codes: informative error codes */ +#define FDT_ERR_NOTFOUND 1 +#define FDT_ERR_EXISTS 2 +#define FDT_ERR_NOSPACE 3 + +/* Error codes: codes for bad parameters */ +#define FDT_ERR_BADOFFSET 4 +#define FDT_ERR_BADPATH 5 +#define FDT_ERR_BADSTATE 6 + +/* Error codes: codes for bad device tree blobs */ +#define FDT_ERR_TRUNCATED 7 +#define FDT_ERR_BADMAGIC 8 +#define FDT_ERR_BADVERSION 9 +#define FDT_ERR_BADSTRUCTURE 10 +#define FDT_ERR_BADLAYOUT 11 + +#define FDT_ERR_MAX 11 + +#define fdt_get_header(fdt, field) \ + (fdt32_to_cpu(((struct fdt_header *)(fdt))->field)) +#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) +#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) +#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) +#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) +#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) +#define fdt_version(fdt) (fdt_get_header(fdt, version)) +#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) +#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) +#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) +#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) + +#define fdt_set_header(fdt, field, val) \ + ((struct fdt_header *)(fdt))->field = cpu_to_fdt32(val) + +void *fdt_offset_ptr(const void *fdt, int offset, int checklen); + +#define fdt_offset_ptr_typed(fdt, offset, var) \ + ((typeof(var))(fdt_offset_ptr((fdt), (offset), sizeof(*(var))))) + +int fdt_move(const void *fdt, void *buf, int bufsize); + +/* Read-only functions */ +char *fdt_string(const void *fdt, int stroffset); + +int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, + const char *name, int namelen); +int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); + +int fdt_path_offset(const void *fdt, const char *path); + +struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, + const char *name, int *lenp); +void *fdt_getprop(const void *fdt, int nodeoffset, + const char *name, int *lenp); + +/* Write-in-place functions */ +int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, + const void *val, int len); + +#define fdt_setprop_inplace_typed(fdt, nodeoffset, name, val) \ + ({ \ + typeof(val) x = val; \ + fdt_setprop_inplace(fdt, nodeoffset, name, &x, sizeof(x)); \ + }) + +int fdt_nop_property(void *fdt, int nodeoffset, const char *name); +int fdt_nop_node(void *fdt, int nodeoffset); + +/* Sequential-write functions */ +int fdt_create(void *buf, int bufsize); +int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); +int fdt_finish_reservemap(void *fdt); +int fdt_begin_node(void *fdt, const char *name); +int fdt_property(void *fdt, const char *name, const void *val, int len); +#define fdt_property_typed(fdt, name, val) \ + ({ \ + typeof(val) x = (val); \ + fdt_property((fdt), (name), &x, sizeof(x)); \ + }) +#define fdt_property_string(fdt, name, str) \ + fdt_property(fdt, name, str, strlen(str)+1) +int fdt_end_node(void *fdt); +int fdt_finish(void *fdt); + +/* Read-write functions */ +int fdt_open_into(void *fdt, void *buf, int bufsize); +int fdt_pack(void *fdt); + +int fdt_setprop(void *fdt, int nodeoffset, const char *name, + const void *val, int len); +#define fdt_setprop_typed(fdt, nodeoffset, name, val) \ + ({ \ + typeof(val) x = (val); \ + fdt_setprop((fdt), (nodeoffset), (name), &x, sizeof(x)); \ + }) +#define fdt_setprop_string(fdt, nodeoffset, name, str) \ + fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) +int fdt_delprop(void *fdt, int nodeoffset, const char *name); +int fdt_add_subnode_namelen(void *fdt, int parentoffset, + const char *name, int namelen); +int fdt_add_subnode(void *fdt, int parentoffset, const char *name); +int fdt_del_node(void *fdt, int nodeoffset); + +/* Extra functions */ +const char *fdt_strerror(int errval); + +#endif /* _LIBFDT_H */ diff --git a/include/libfdt_env.h b/include/libfdt_env.h new file mode 100644 index 0000000000..59f2536d28 --- /dev/null +++ b/include/libfdt_env.h @@ -0,0 +1,22 @@ +#ifndef _LIBFDT_ENV_H +#define _LIBFDT_ENV_H + +#include +#include +#include +#include +#include + +#if __BYTE_ORDER == __BIG_ENDIAN +#define fdt32_to_cpu(x) (x) +#define cpu_to_fdt32(x) (x) +#define fdt64_to_cpu(x) (x) +#define cpu_to_fdt64(x) (x) +#else +#define fdt32_to_cpu(x) (bswap_32((x))) +#define cpu_to_fdt32(x) (bswap_32((x))) +#define fdt64_to_cpu(x) (bswap_64((x))) +#define cpu_to_fdt64(x) (bswap_64((x))) +#endif + +#endif /* _LIBFDT_ENV_H */ diff --git a/libfdt/Makefile b/libfdt/Makefile new file mode 100644 index 0000000000..c8240bba3a --- /dev/null +++ b/libfdt/Makefile @@ -0,0 +1,88 @@ +PREFIX = /usr/local +TARGETLIBS = libfdt.a +LIBOBJS = fdt.o fdt_ro.o fdt_wip.o fdt_sw.o fdt_rw.o fdt_strerror.o + +SOURCE = $(shell find . -maxdepth 1 ! -name version.h -a -name '*.[h]') +SOURCE += *.c Makefile +NODEPTARGETS= + +CPPFLAGS = -I. +CFLAGS = -Wall -g + +LIBDIR = $(PREFIX)/$(LIB32) + +EXTRA_DIST = \ + README \ + HOWTO \ + LGPL-2.1 + +ifdef V +VECHO = : +else +VECHO = echo " " +ARFLAGS = rc +.SILENT: +endif + +DEPFILES = $(LIBOBJS:%.o=%.d) + +all: libs tests + +.PHONY: tests libs + +libs: $(TARGETLIBS) + +tests: tests/all + +tests/%: libs + $(MAKE) -C tests $* + +check: all + cd tests; ./run_tests.sh + +checkv: all + cd tests; ./run_tests.sh -v + +func: all + cd tests; ./run_tests.sh -t func + +funcv: all + cd tests; ./run_tests.sh -t func -v + +stress: all + cd tests; ./run_tests.sh -t stress + +stressv: all + cd tests; ./run_tests.sh -t stress -v + +%.o: %.c + @$(VECHO) CC $@ + $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< + +libfdt.a: $(LIBOBJS) + @$(VECHO) AR $@ + $(AR) $(ARFLAGS) $@ $^ + +%.i: %.c + @$(VECHO) CPP $@ + $(CC) $(CPPFLAGS) -E $< > $@ + +%.s: %.c + @$(VECHO) CC -S $@ + $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -S $< + +clean: + @$(VECHO) CLEAN + rm -f *~ *.o *.so *.a *.d *.i *.s core a.out $(VERSION) + $(MAKE) -C tests clean + +%.d: %.c + @$(CC) $(CPPFLAGS) -MM -MT "$*.o $@" $< > $@ + +# Workaround: Don't build dependencies for certain targets +# When the include below is executed, make will use the %.d target above to +# generate missing files. For certain targets (clean, version.h, etc) we don't +# need or want these dependency files, so don't include them in this case. +ifeq (,$(findstring <$(MAKECMDGOALS)>,$(NODEPTARGETS))) +-include $(DEPFILES) +endif diff --git a/libfdt/README b/libfdt/README new file mode 100644 index 0000000000..f4cca3499c --- /dev/null +++ b/libfdt/README @@ -0,0 +1,23 @@ +The libfdt functionality was written by David Gibson. The original +source came from the git repository: + +URL: git://ozlabs.org/home/dgibson/git/libfdt.git + +author David Gibson + Fri, 23 Mar 2007 04:16:54 +0000 (15:16 +1100) +committer David Gibson + Fri, 23 Mar 2007 04:16:54 +0000 (15:16 +1100) +commit 857f54e79f74429af20c2b5ecc00ee98af6a3b8b +tree 2f648f0f88225a51ded452968d28b4402df8ade0 +parent 07a12a08005f3b5cd9337900a6551e450c07b515 + +To adapt for u-boot usage, only the applicable files were copied and +imported into the u-boot git repository. +Omitted: +* GPL - u-boot comes with a copy of the GPL license +* test subdirectory - not directly useful for u-boot + +After importing, other customizations were performed. See the git log +for details. + +Jerry Van Baren diff --git a/libfdt/fdt.c b/libfdt/fdt.c new file mode 100644 index 0000000000..772da46a7e --- /dev/null +++ b/libfdt/fdt.c @@ -0,0 +1,124 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +int _fdt_check_header(const void *fdt) +{ + if (fdt_magic(fdt) == FDT_MAGIC) { + /* Complete tree */ + if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) + return -FDT_ERR_BADVERSION; + if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) + return -FDT_ERR_BADVERSION; + } else if (fdt_magic(fdt) == SW_MAGIC) { + /* Unfinished sequential-write blob */ + if (fdt_size_dt_struct(fdt) == 0) + return -FDT_ERR_BADSTATE; + } else { + return -FDT_ERR_BADMAGIC; + } + + return 0; +} + +void *fdt_offset_ptr(const void *fdt, int offset, int len) +{ + void *p; + + if (fdt_version(fdt) >= 0x11) + if (((offset + len) < offset) + || ((offset + len) > fdt_size_dt_struct(fdt))) + return NULL; + + p = _fdt_offset_ptr(fdt, offset); + + if (p + len < p) + return NULL; + return p; +} + +uint32_t _fdt_next_tag(const void *fdt, int offset, int *nextoffset) +{ + const uint32_t *tagp, *lenp; + uint32_t tag; + const char *p; + + if (offset % FDT_TAGSIZE) + return -1; + + tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); + if (! tagp) + return FDT_END; /* premature end */ + tag = fdt32_to_cpu(*tagp); + offset += FDT_TAGSIZE; + + switch (tag) { + case FDT_BEGIN_NODE: + /* skip name */ + do { + p = fdt_offset_ptr(fdt, offset++, 1); + } while (p && (*p != '\0')); + if (! p) + return FDT_END; + break; + case FDT_PROP: + lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); + if (! lenp) + return FDT_END; + /* skip name offset, length and value */ + offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp); + break; + } + + if (nextoffset) + *nextoffset = ALIGN(offset, FDT_TAGSIZE); + + return tag; +} + +const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) +{ + int len = strlen(s) + 1; + const char *last = strtab + tabsize - len; + const char *p; + + for (p = strtab; p <= last; p++) + if (memeq(p, s, len)) + return p; + return NULL; +} + +int fdt_move(const void *fdt, void *buf, int bufsize) +{ + int err = _fdt_check_header(fdt); + + if (err) + return err; + + if (fdt_totalsize(fdt) > bufsize) + return -FDT_ERR_NOSPACE; + + memmove(buf, fdt, fdt_totalsize(fdt)); + return 0; +} diff --git a/libfdt/fdt_strerror.c b/libfdt/fdt_strerror.c new file mode 100644 index 0000000000..7f231ce460 --- /dev/null +++ b/libfdt/fdt_strerror.c @@ -0,0 +1,64 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +struct errtabent { + const char *str; +}; + +#define ERRTABENT(val) \ + [(val)] = { .str = #val, } + +static struct errtabent errtable[] = { + ERRTABENT(FDT_ERR_NOTFOUND), + ERRTABENT(FDT_ERR_EXISTS), + ERRTABENT(FDT_ERR_NOSPACE), + + ERRTABENT(FDT_ERR_BADOFFSET), + ERRTABENT(FDT_ERR_BADPATH), + ERRTABENT(FDT_ERR_BADSTATE), + + ERRTABENT(FDT_ERR_TRUNCATED), + ERRTABENT(FDT_ERR_BADMAGIC), + ERRTABENT(FDT_ERR_BADVERSION), + ERRTABENT(FDT_ERR_BADSTRUCTURE), + ERRTABENT(FDT_ERR_BADLAYOUT), +}; +#define ERRTABSIZE (sizeof(errtable) / sizeof(errtable[0])) + +const char *fdt_strerror(int errval) +{ + if (errval > 0) + return ""; + else if (errval == 0) + return ""; + else if (errval > -ERRTABSIZE) { + const char *s = errtable[-errval].str; + + if (s) + return s; + } + + return ""; +} diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h new file mode 100644 index 0000000000..124bef78e9 --- /dev/null +++ b/libfdt/libfdt_internal.h @@ -0,0 +1,41 @@ +#ifndef _LIBFDT_INTERNAL_H +#define _LIBFDT_INTERNAL_H +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include + +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) +#define PALIGN(p, a) ((void *)ALIGN((unsigned long)(p), (a))) + +#define memeq(p, q, n) (memcmp((p), (q), (n)) == 0) +#define streq(p, q) (strcmp((p), (q)) == 0) + +int _fdt_check_header(const void *fdt); +uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset); +const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); +int _fdt_node_end_offset(void *fdt, int nodeoffset); + +static inline void *_fdt_offset_ptr(const struct fdt_header *fdt, int offset) +{ + return (void *)fdt + fdt_off_dt_struct(fdt) + offset; +} + +#define SW_MAGIC (~FDT_MAGIC) + +#endif /* _LIBFDT_INTERNAL_H */ From 35748177c64a4a83a00057e93bb33e40278a2a96 Mon Sep 17 00:00:00 2001 From: Gerald Van Baren Date: Sat, 31 Mar 2007 12:00:56 -0400 Subject: [PATCH 08/17] libfdt: Import libfdt source (2 of 2) This adds the applicable libfdt source files (unmodified) and a README to explain where the source came from. --- libfdt/fdt_ro.c | 229 ++++++++++++++++++++++++++++++++++++ libfdt/fdt_rw.c | 293 +++++++++++++++++++++++++++++++++++++++++++++++ libfdt/fdt_sw.c | 226 ++++++++++++++++++++++++++++++++++++ libfdt/fdt_wip.c | 112 ++++++++++++++++++ 4 files changed, 860 insertions(+) create mode 100644 libfdt/fdt_ro.c create mode 100644 libfdt/fdt_rw.c create mode 100644 libfdt/fdt_sw.c create mode 100644 libfdt/fdt_wip.c diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c new file mode 100644 index 0000000000..9112c6a639 --- /dev/null +++ b/libfdt/fdt_ro.c @@ -0,0 +1,229 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +#define CHECK_HEADER(fdt) \ + { \ + int err; \ + if ((err = _fdt_check_header(fdt)) != 0) \ + return err; \ + } + +static int offset_streq(const void *fdt, int offset, + const char *s, int len) +{ + const char *p = fdt_offset_ptr(fdt, offset, len+1); + + if (! p) + /* short match */ + return 0; + + if (memcmp(p, s, len) != 0) + return 0; + + if (p[len] != '\0') + return 0; + + return 1; +} + +char *fdt_string(const void *fdt, int stroffset) +{ + return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset; +} + +int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, + const char *name, int namelen) +{ + int level = 0; + uint32_t tag; + int offset, nextoffset; + + CHECK_HEADER(fdt); + + tag = _fdt_next_tag(fdt, parentoffset, &nextoffset); + if (tag != FDT_BEGIN_NODE) + return -FDT_ERR_BADOFFSET; + + do { + offset = nextoffset; + tag = _fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_END: + return -FDT_ERR_TRUNCATED; + + case FDT_BEGIN_NODE: + level++; + if (level != 1) + continue; + if (offset_streq(fdt, offset+FDT_TAGSIZE, name, namelen)) + /* Found it! */ + return offset; + break; + + case FDT_END_NODE: + level--; + break; + + case FDT_PROP: + case FDT_NOP: + break; + + default: + return -FDT_ERR_BADSTRUCTURE; + } + } while (level >= 0); + + return -FDT_ERR_NOTFOUND; +} + +int fdt_subnode_offset(const void *fdt, int parentoffset, + const char *name) +{ + return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); +} + +int fdt_path_offset(const void *fdt, const char *path) +{ + const char *end = path + strlen(path); + const char *p = path; + int offset = 0; + + CHECK_HEADER(fdt); + + if (*path != '/') + return -FDT_ERR_BADPATH; + + while (*p) { + const char *q; + + while (*p == '/') + p++; + if (! *p) + return -FDT_ERR_BADPATH; + q = strchr(p, '/'); + if (! q) + q = end; + + offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); + if (offset < 0) + return offset; + + p = q; + } + + return offset; +} + +struct fdt_property *fdt_get_property(const void *fdt, + int nodeoffset, + const char *name, int *lenp) +{ + int level = 0; + uint32_t tag; + struct fdt_property *prop; + int namestroff; + int offset, nextoffset; + int err; + + if ((err = _fdt_check_header(fdt)) != 0) + goto fail; + + err = -FDT_ERR_BADOFFSET; + if (nodeoffset % FDT_TAGSIZE) + goto fail; + + tag = _fdt_next_tag(fdt, nodeoffset, &nextoffset); + if (tag != FDT_BEGIN_NODE) + goto fail; + + do { + offset = nextoffset; + + tag = _fdt_next_tag(fdt, offset, &nextoffset); + switch (tag) { + case FDT_END: + err = -FDT_ERR_TRUNCATED; + goto fail; + + case FDT_BEGIN_NODE: + level++; + break; + + case FDT_END_NODE: + level--; + break; + + case FDT_PROP: + if (level != 0) + continue; + + err = -FDT_ERR_BADSTRUCTURE; + prop = fdt_offset_ptr_typed(fdt, offset, prop); + if (! prop) + goto fail; + namestroff = fdt32_to_cpu(prop->nameoff); + if (streq(fdt_string(fdt, namestroff), name)) { + /* Found it! */ + int len = fdt32_to_cpu(prop->len); + prop = fdt_offset_ptr(fdt, offset, + sizeof(*prop)+len); + if (! prop) + goto fail; + + if (lenp) + *lenp = len; + + return prop; + } + break; + + case FDT_NOP: + break; + + default: + err = -FDT_ERR_BADSTRUCTURE; + goto fail; + } + } while (level >= 0); + + err = -FDT_ERR_NOTFOUND; + fail: + if (lenp) + *lenp = err; + return NULL; +} + +void *fdt_getprop(const void *fdt, int nodeoffset, + const char *name, int *lenp) +{ + const struct fdt_property *prop; + + prop = fdt_get_property(fdt, nodeoffset, name, lenp); + if (! prop) + return NULL; + + return prop->data; +} diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c new file mode 100644 index 0000000000..7396645a69 --- /dev/null +++ b/libfdt/fdt_rw.c @@ -0,0 +1,293 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +static int rw_check_header(void *fdt) +{ + int err; + + if ((err = _fdt_check_header(fdt))) + return err; + if (fdt_version(fdt) < 0x11) + return -FDT_ERR_BADVERSION; + if (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8)) + return -FDT_ERR_BADLAYOUT; + if (fdt_off_dt_struct(fdt) < + (fdt_off_mem_rsvmap(fdt) + sizeof(struct fdt_reserve_entry))) + return -FDT_ERR_BADLAYOUT; + if (fdt_off_dt_strings(fdt) < + (fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt))) + return -FDT_ERR_BADLAYOUT; + if (fdt_totalsize(fdt) < + (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))) + return -FDT_ERR_BADLAYOUT; + return 0; +} + +#define RW_CHECK_HEADER(fdt) \ + { \ + int err; \ + if ((err = rw_check_header(fdt)) != 0) \ + return err; \ + } + +static inline int _blob_data_size(void *fdt) +{ + return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); +} + +static int _blob_splice(void *fdt, void *p, int oldlen, int newlen) +{ + void *end = fdt + _blob_data_size(fdt); + + if (((p + oldlen) < p) || ((p + oldlen) > end)) + return -FDT_ERR_BADOFFSET; + if ((end - oldlen + newlen) > (fdt + fdt_totalsize(fdt))) + return -FDT_ERR_NOSPACE; + memmove(p + newlen, p + oldlen, end - p - oldlen); + return 0; +} + +static int _blob_splice_struct(void *fdt, void *p, + int oldlen, int newlen) +{ + int delta = newlen - oldlen; + int err; + + if ((err = _blob_splice(fdt, p, oldlen, newlen))) + return err; + + fdt_set_header(fdt, size_dt_struct, fdt_size_dt_struct(fdt) + delta); + fdt_set_header(fdt, off_dt_strings, fdt_off_dt_strings(fdt) + delta); + return 0; +} + +static int _blob_splice_string(void *fdt, int newlen) +{ + void *p = fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); + int err; + + if ((err = _blob_splice(fdt, p, 0, newlen))) + return err; + + fdt_set_header(fdt, size_dt_strings, fdt_size_dt_strings(fdt) + newlen); + return 0; +} + +static int _find_add_string(void *fdt, const char *s) +{ + char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); + const char *p; + char *new; + int len = strlen(s) + 1; + int err; + + p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s); + if (p) + /* found it */ + return (p - strtab); + + new = strtab + fdt_size_dt_strings(fdt); + err = _blob_splice_string(fdt, len); + if (err) + return err; + + memcpy(new, s, len); + return (new - strtab); +} + +static int _resize_property(void *fdt, int nodeoffset, const char *name, int len, + struct fdt_property **prop) +{ + int oldlen; + int err; + + *prop = fdt_get_property(fdt, nodeoffset, name, &oldlen); + if (! (*prop)) + return oldlen; + + if ((err = _blob_splice_struct(fdt, (*prop)->data, + ALIGN(oldlen, FDT_TAGSIZE), + ALIGN(len, FDT_TAGSIZE)))) + return err; + + (*prop)->len = cpu_to_fdt32(len); + return 0; +} + +static int _add_property(void *fdt, int nodeoffset, const char *name, int len, + struct fdt_property **prop) +{ + uint32_t tag; + int proplen; + int nextoffset; + int namestroff; + int err; + + tag = _fdt_next_tag(fdt, nodeoffset, &nextoffset); + if (tag != FDT_BEGIN_NODE) + return -FDT_ERR_BADOFFSET; + + namestroff = _find_add_string(fdt, name); + if (namestroff < 0) + return namestroff; + + *prop = _fdt_offset_ptr(fdt, nextoffset); + proplen = sizeof(**prop) + ALIGN(len, FDT_TAGSIZE); + + err = _blob_splice_struct(fdt, *prop, 0, proplen); + if (err) + return err; + + (*prop)->tag = cpu_to_fdt32(FDT_PROP); + (*prop)->nameoff = cpu_to_fdt32(namestroff); + (*prop)->len = cpu_to_fdt32(len); + return 0; +} + +int fdt_setprop(void *fdt, int nodeoffset, const char *name, + const void *val, int len) +{ + struct fdt_property *prop; + int err; + + if ((err = rw_check_header(fdt))) + return err; + + err = _resize_property(fdt, nodeoffset, name, len, &prop); + if (err == -FDT_ERR_NOTFOUND) + err = _add_property(fdt, nodeoffset, name, len, &prop); + if (err) + return err; + + memcpy(prop->data, val, len); + return 0; +} + +int fdt_delprop(void *fdt, int nodeoffset, const char *name) +{ + struct fdt_property *prop; + int len, proplen; + + RW_CHECK_HEADER(fdt); + + prop = fdt_get_property(fdt, nodeoffset, name, &len); + if (! prop) + return len; + + proplen = sizeof(*prop) + ALIGN(len, FDT_TAGSIZE); + return _blob_splice_struct(fdt, prop, proplen, 0); +} + +int fdt_add_subnode_namelen(void *fdt, int parentoffset, + const char *name, int namelen) +{ + struct fdt_node_header *nh; + int offset, nextoffset; + int nodelen; + int err; + uint32_t tag; + uint32_t *endtag; + + RW_CHECK_HEADER(fdt); + + offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); + if (offset >= 0) + return -FDT_ERR_EXISTS; + else if (offset != -FDT_ERR_NOTFOUND) + return offset; + + /* Try to place the new node after the parent's properties */ + _fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */ + do { + offset = nextoffset; + tag = _fdt_next_tag(fdt, offset, &nextoffset); + } while (tag == FDT_PROP); + + nh = _fdt_offset_ptr(fdt, offset); + nodelen = sizeof(*nh) + ALIGN(namelen+1, FDT_TAGSIZE) + FDT_TAGSIZE; + + err = _blob_splice_struct(fdt, nh, 0, nodelen); + if (err) + return err; + + nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); + memset(nh->name, 0, ALIGN(namelen+1, FDT_TAGSIZE)); + memcpy(nh->name, name, namelen); + endtag = (uint32_t *)((void *)nh + nodelen - FDT_TAGSIZE); + *endtag = cpu_to_fdt32(FDT_END_NODE); + + return offset; +} + +int fdt_add_subnode(void *fdt, int parentoffset, const char *name) +{ + return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name)); +} + +int fdt_del_node(void *fdt, int nodeoffset) +{ + int endoffset; + + endoffset = _fdt_node_end_offset(fdt, nodeoffset); + if (endoffset < 0) + return endoffset; + + return _blob_splice_struct(fdt, _fdt_offset_ptr(fdt, nodeoffset), + endoffset - nodeoffset, 0); +} + +int fdt_open_into(void *fdt, void *buf, int bufsize) +{ + int err; + + err = fdt_move(fdt, buf, bufsize); + if (err) + return err; + + fdt = buf; + + fdt_set_header(fdt, totalsize, bufsize); + + /* FIXME: re-order if necessary */ + + err = rw_check_header(fdt); + if (err) + return err; + + return 0; +} + +int fdt_pack(void *fdt) +{ + int err; + + err = rw_check_header(fdt); + if (err) + return err; + + /* FIXME: pack components */ + fdt_set_header(fdt, totalsize, _blob_data_size(fdt)); + return 0; +} diff --git a/libfdt/fdt_sw.c b/libfdt/fdt_sw.c new file mode 100644 index 0000000000..41d4891bb4 --- /dev/null +++ b/libfdt/fdt_sw.c @@ -0,0 +1,226 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +static int check_header_sw(void *fdt) +{ + if (fdt_magic(fdt) != SW_MAGIC) + return -FDT_ERR_BADMAGIC; + return 0; +} + +static void *grab_space(void *fdt, int len) +{ + int offset = fdt_size_dt_struct(fdt); + int spaceleft; + + spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) + - fdt_size_dt_strings(fdt); + + if ((offset + len < offset) || (offset + len > spaceleft)) + return NULL; + + fdt_set_header(fdt, size_dt_struct, offset + len); + return fdt_offset_ptr(fdt, offset, len); +} + +int fdt_create(void *buf, int bufsize) +{ + void *fdt = buf; + + if (bufsize < sizeof(struct fdt_header)) + return -FDT_ERR_NOSPACE; + + memset(buf, 0, bufsize); + + fdt_set_header(fdt, magic, SW_MAGIC); + fdt_set_header(fdt, version, FDT_LAST_SUPPORTED_VERSION); + fdt_set_header(fdt, last_comp_version, FDT_FIRST_SUPPORTED_VERSION); + fdt_set_header(fdt, totalsize, bufsize); + + fdt_set_header(fdt, off_mem_rsvmap, ALIGN(sizeof(struct fdt_header), + sizeof(struct fdt_reserve_entry))); + fdt_set_header(fdt, off_dt_struct, fdt_off_mem_rsvmap(fdt)); + fdt_set_header(fdt, off_dt_strings, bufsize); + + return 0; +} + +int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) +{ + struct fdt_reserve_entry *re; + int err = check_header_sw(fdt); + int offset; + + if (err) + return err; + if (fdt_size_dt_struct(fdt)) + return -FDT_ERR_BADSTATE; + + offset = fdt_off_dt_struct(fdt); + if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) + return -FDT_ERR_NOSPACE; + + re = (struct fdt_reserve_entry *)((void *)fdt + offset); + re->address = cpu_to_fdt64(addr); + re->size = cpu_to_fdt64(size); + + fdt_set_header(fdt, off_dt_struct, offset + sizeof(*re)); + + return 0; +} + +int fdt_finish_reservemap(void *fdt) +{ + return fdt_add_reservemap_entry(fdt, 0, 0); +} + +int fdt_begin_node(void *fdt, const char *name) +{ + struct fdt_node_header *nh; + int err = check_header_sw(fdt); + int namelen = strlen(name) + 1; + + if (err) + return err; + + nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE)); + if (! nh) + return -FDT_ERR_NOSPACE; + + nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); + memcpy(nh->name, name, namelen); + return 0; +} + +int fdt_end_node(void *fdt) +{ + uint32_t *en; + int err = check_header_sw(fdt); + + if (err) + return err; + + en = grab_space(fdt, FDT_TAGSIZE); + if (! en) + return -FDT_ERR_NOSPACE; + + *en = cpu_to_fdt32(FDT_END_NODE); + return 0; +} + +static int find_add_string(void *fdt, const char *s) +{ + char *strtab = (char *)fdt + fdt_totalsize(fdt); + const char *p; + int strtabsize = fdt_size_dt_strings(fdt); + int len = strlen(s) + 1; + int struct_top, offset; + + p = _fdt_find_string(strtab - strtabsize, strtabsize, s); + if (p) + return p - strtab; + + /* Add it */ + offset = -strtabsize - len; + struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); + if (fdt_totalsize(fdt) + offset < struct_top) + return 0; /* no more room :( */ + + memcpy(strtab + offset, s, len); + fdt_set_header(fdt, size_dt_strings, strtabsize + len); + return offset; +} + +int fdt_property(void *fdt, const char *name, const void *val, int len) +{ + struct fdt_property *prop; + int err = check_header_sw(fdt); + int nameoff; + + if (err) + return err; + + nameoff = find_add_string(fdt, name); + if (nameoff == 0) + return -FDT_ERR_NOSPACE; + + prop = grab_space(fdt, sizeof(*prop) + ALIGN(len, FDT_TAGSIZE)); + if (! prop) + return -FDT_ERR_NOSPACE; + + prop->tag = cpu_to_fdt32(FDT_PROP); + prop->nameoff = cpu_to_fdt32(nameoff); + prop->len = cpu_to_fdt32(len); + memcpy(prop->data, val, len); + return 0; +} + +int fdt_finish(void *fdt) +{ + int err = check_header_sw(fdt); + char *p = (char *)fdt; + uint32_t *end; + int oldstroffset, newstroffset; + uint32_t tag; + int offset, nextoffset; + + if (err) + return err; + + /* Add terminator */ + end = grab_space(fdt, sizeof(*end)); + if (! end) + return -FDT_ERR_NOSPACE; + *end = cpu_to_fdt32(FDT_END); + + /* Relocate the string table */ + oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt); + newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); + memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt)); + fdt_set_header(fdt, off_dt_strings, newstroffset); + + /* Walk the structure, correcting string offsets */ + offset = 0; + while ((tag = _fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { + if (tag == FDT_PROP) { + struct fdt_property *prop = fdt_offset_ptr(fdt, offset, + sizeof(*prop)); + int nameoff; + + if (! prop) + return -FDT_ERR_BADSTRUCTURE; + + nameoff = fdt32_to_cpu(prop->nameoff); + nameoff += fdt_size_dt_strings(fdt); + prop->nameoff = cpu_to_fdt32(nameoff); + } + offset = nextoffset; + } + + /* Finally, adjust the header */ + fdt_set_header(fdt, totalsize, newstroffset + fdt_size_dt_strings(fdt)); + fdt_set_header(fdt, magic, FDT_MAGIC); + return 0; +} diff --git a/libfdt/fdt_wip.c b/libfdt/fdt_wip.c new file mode 100644 index 0000000000..0db7d259f5 --- /dev/null +++ b/libfdt/fdt_wip.c @@ -0,0 +1,112 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, + const void *val, int len) +{ + void *propval; + int proplen; + + propval = fdt_getprop(fdt, nodeoffset, name, &proplen); + if (! propval) + return proplen; + + if (proplen != len) + return -FDT_ERR_NOSPACE; + + memcpy(propval, val, len); + return 0; +} + +static void nop_region(void *start, int len) +{ + uint32_t *p; + + for (p = start; (void *)p < (start + len); p++) + *p = cpu_to_fdt32(FDT_NOP); +} + +int fdt_nop_property(void *fdt, int nodeoffset, const char *name) +{ + struct fdt_property *prop; + int len; + + prop = fdt_get_property(fdt, nodeoffset, name, &len); + if (! prop) + return len; + + nop_region(prop, len + sizeof(*prop)); + + return 0; +} + +int _fdt_node_end_offset(void *fdt, int nodeoffset) +{ + int level = 0; + uint32_t tag; + int offset, nextoffset; + + tag = _fdt_next_tag(fdt, nodeoffset, &nextoffset); + if (tag != FDT_BEGIN_NODE) + return -FDT_ERR_BADOFFSET; + do { + offset = nextoffset; + tag = _fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_END: + return offset; + + case FDT_BEGIN_NODE: + level++; + break; + + case FDT_END_NODE: + level--; + break; + + case FDT_PROP: + case FDT_NOP: + break; + + default: + return -FDT_ERR_BADSTRUCTURE; + } + } while (level >= 0); + + return nextoffset; +} + +int fdt_nop_node(void *fdt, int nodeoffset) +{ + int endoffset; + + endoffset = _fdt_node_end_offset(fdt, nodeoffset); + if (endoffset < 0) + return endoffset; + + nop_region(fdt_offset_ptr(fdt, nodeoffset, 0), endoffset - nodeoffset); + return 0; +} From fa3a74cec73dfd06a5ae35a9a3368200273aaa71 Mon Sep 17 00:00:00 2001 From: Gerald Van Baren Date: Sat, 31 Mar 2007 12:05:39 -0400 Subject: [PATCH 09/17] libfdt: Customizations for use by u-boot. Changes to David Gibson's original source to fit into u-boot's environment. No functionality changes. --- include/libfdt_env.h | 24 ++++------ libfdt/Makefile | 111 ++++++++++++++----------------------------- 2 files changed, 44 insertions(+), 91 deletions(-) diff --git a/include/libfdt_env.h b/include/libfdt_env.h index 59f2536d28..6c77852540 100644 --- a/include/libfdt_env.h +++ b/include/libfdt_env.h @@ -2,21 +2,15 @@ #define _LIBFDT_ENV_H #include -#include -#include -#include -#include +#include +#include +#include -#if __BYTE_ORDER == __BIG_ENDIAN -#define fdt32_to_cpu(x) (x) -#define cpu_to_fdt32(x) (x) -#define fdt64_to_cpu(x) (x) -#define cpu_to_fdt64(x) (x) -#else -#define fdt32_to_cpu(x) (bswap_32((x))) -#define cpu_to_fdt32(x) (bswap_32((x))) -#define fdt64_to_cpu(x) (bswap_64((x))) -#define cpu_to_fdt64(x) (bswap_64((x))) -#endif +struct fdt_header *fdt; /* Pointer to the working fdt */ + +#define fdt32_to_cpu(x) __be32_to_cpu(x) +#define cpu_to_fdt32(x) __cpu_to_be32(x) +#define fdt64_to_cpu(x) __be64_to_cpu(x) +#define cpu_to_fdt64(x) __cpu_to_be64(x) #endif /* _LIBFDT_ENV_H */ diff --git a/libfdt/Makefile b/libfdt/Makefile index c8240bba3a..418ad6b5ab 100644 --- a/libfdt/Makefile +++ b/libfdt/Makefile @@ -1,88 +1,47 @@ -PREFIX = /usr/local -TARGETLIBS = libfdt.a -LIBOBJS = fdt.o fdt_ro.o fdt_wip.o fdt_sw.o fdt_rw.o fdt_strerror.o +# +# (C) Copyright 2000-2007 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# -SOURCE = $(shell find . -maxdepth 1 ! -name version.h -a -name '*.[h]') -SOURCE += *.c Makefile -NODEPTARGETS= +include $(TOPDIR)/config.mk -CPPFLAGS = -I. -CFLAGS = -Wall -g +LIB = $(obj)libfdt.a -LIBDIR = $(PREFIX)/$(LIB32) +SOBJS = -EXTRA_DIST = \ - README \ - HOWTO \ - LGPL-2.1 +COBJS = fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o -ifdef V -VECHO = : -else -VECHO = echo " " -ARFLAGS = rc -.SILENT: -endif -DEPFILES = $(LIBOBJS:%.o=%.d) +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -all: libs tests +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) -.PHONY: tests libs +######################################################################### -libs: $(TARGETLIBS) +# defines $(obj).depend target +include $(SRCTREE)/rules.mk -tests: tests/all +sinclude $(obj).depend -tests/%: libs - $(MAKE) -C tests $* +######################################################################### -check: all - cd tests; ./run_tests.sh - -checkv: all - cd tests; ./run_tests.sh -v - -func: all - cd tests; ./run_tests.sh -t func - -funcv: all - cd tests; ./run_tests.sh -t func -v - -stress: all - cd tests; ./run_tests.sh -t stress - -stressv: all - cd tests; ./run_tests.sh -t stress -v - -%.o: %.c - @$(VECHO) CC $@ - $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< - -libfdt.a: $(LIBOBJS) - @$(VECHO) AR $@ - $(AR) $(ARFLAGS) $@ $^ - -%.i: %.c - @$(VECHO) CPP $@ - $(CC) $(CPPFLAGS) -E $< > $@ - -%.s: %.c - @$(VECHO) CC -S $@ - $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -S $< - -clean: - @$(VECHO) CLEAN - rm -f *~ *.o *.so *.a *.d *.i *.s core a.out $(VERSION) - $(MAKE) -C tests clean - -%.d: %.c - @$(CC) $(CPPFLAGS) -MM -MT "$*.o $@" $< > $@ - -# Workaround: Don't build dependencies for certain targets -# When the include below is executed, make will use the %.d target above to -# generate missing files. For certain targets (clean, version.h, etc) we don't -# need or want these dependency files, so don't include them in this case. -ifeq (,$(findstring <$(MAKECMDGOALS)>,$(NODEPTARGETS))) --include $(DEPFILES) -endif From 3af0d587d93e0be5f96e1b30fa41e662f8b0803e Mon Sep 17 00:00:00 2001 From: Gerald Van Baren Date: Sat, 31 Mar 2007 12:13:43 -0400 Subject: [PATCH 10/17] libfdt: Enhanced and published fdt_next_tag() Enhanced the formerly private function _fdt_next_tag() to allow stepping through the tree, used to produce a human-readable dump, and made it part of the published interface. Also added some comments. --- include/libfdt.h | 3 + libfdt/fdt.c | 39 ------------- libfdt/fdt_ro.c | 116 +++++++++++++++++++++++++++++++++++++-- libfdt/fdt_rw.c | 6 +- libfdt/fdt_sw.c | 2 +- libfdt/fdt_wip.c | 4 +- libfdt/libfdt_internal.h | 1 - 7 files changed, 119 insertions(+), 52 deletions(-) diff --git a/include/libfdt.h b/include/libfdt.h index acdc72eac6..c4b3c249bf 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -81,6 +81,9 @@ struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, void *fdt_getprop(const void *fdt, int nodeoffset, const char *name, int *lenp); +uint32_t fdt_next_tag(const void *fdt, int offset, + int *nextoffset, char **namep); + /* Write-in-place functions */ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, const void *val, int len); diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 772da46a7e..4b1c8abf95 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -58,45 +58,6 @@ void *fdt_offset_ptr(const void *fdt, int offset, int len) return p; } -uint32_t _fdt_next_tag(const void *fdt, int offset, int *nextoffset) -{ - const uint32_t *tagp, *lenp; - uint32_t tag; - const char *p; - - if (offset % FDT_TAGSIZE) - return -1; - - tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); - if (! tagp) - return FDT_END; /* premature end */ - tag = fdt32_to_cpu(*tagp); - offset += FDT_TAGSIZE; - - switch (tag) { - case FDT_BEGIN_NODE: - /* skip name */ - do { - p = fdt_offset_ptr(fdt, offset++, 1); - } while (p && (*p != '\0')); - if (! p) - return FDT_END; - break; - case FDT_PROP: - lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); - if (! lenp) - return FDT_END; - /* skip name offset, length and value */ - offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp); - break; - } - - if (nextoffset) - *nextoffset = ALIGN(offset, FDT_TAGSIZE); - - return tag; -} - const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) { int len = strlen(s) + 1; diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 9112c6a639..f884083950 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -48,11 +48,24 @@ static int offset_streq(const void *fdt, int offset, return 1; } +/* + * Return a pointer to the string at the given string offset. + */ char *fdt_string(const void *fdt, int stroffset) { return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset; } +/* + * Return the node offset of the node specified by: + * parentoffset - starting place (0 to start at the root) + * name - name being searched for + * namelen - length of the name: typically strlen(name) + * + * Notes: + * If the start node has subnodes, the subnodes are _not_ searched for the + * requested name. + */ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, const char *name, int namelen) { @@ -62,13 +75,13 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, CHECK_HEADER(fdt); - tag = _fdt_next_tag(fdt, parentoffset, &nextoffset); + tag = fdt_next_tag(fdt, parentoffset, &nextoffset, NULL); if (tag != FDT_BEGIN_NODE) return -FDT_ERR_BADOFFSET; do { offset = nextoffset; - tag = _fdt_next_tag(fdt, offset, &nextoffset); + tag = fdt_next_tag(fdt, offset, &nextoffset, NULL); switch (tag) { case FDT_END: @@ -76,10 +89,15 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, case FDT_BEGIN_NODE: level++; + /* + * If we are nested down levels, ignore the strings + * until we get back to the proper level. + */ if (level != 1) continue; + + /* Return the offset if this is "our" string. */ if (offset_streq(fdt, offset+FDT_TAGSIZE, name, namelen)) - /* Found it! */ return offset; break; @@ -99,12 +117,19 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, return -FDT_ERR_NOTFOUND; } +/* + * See fdt_subnode_offset_namelen() + */ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name) { return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); } +/* + * Searches for the node corresponding to the given path and returns the + * offset of that node. + */ int fdt_path_offset(const void *fdt, const char *path) { const char *end = path + strlen(path); @@ -113,21 +138,33 @@ int fdt_path_offset(const void *fdt, const char *path) CHECK_HEADER(fdt); + /* Paths must be absolute */ if (*path != '/') return -FDT_ERR_BADPATH; while (*p) { const char *q; + /* Skip path separator(s) */ while (*p == '/') p++; if (! *p) return -FDT_ERR_BADPATH; + + /* + * Find the next path separator. The characters between + * p and q are the next segment of the the path to find. + */ q = strchr(p, '/'); if (! q) q = end; + /* + * Find the offset corresponding to the this path segment. + */ offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); + + /* Oops, error, abort abort abort */ if (offset < 0) return offset; @@ -137,6 +174,10 @@ int fdt_path_offset(const void *fdt, const char *path) return offset; } +/* + * Given the offset of a node and a name of a property in that node, return + * a pointer to the property struct. + */ struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, const char *name, int *lenp) @@ -155,14 +196,14 @@ struct fdt_property *fdt_get_property(const void *fdt, if (nodeoffset % FDT_TAGSIZE) goto fail; - tag = _fdt_next_tag(fdt, nodeoffset, &nextoffset); + tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, NULL); if (tag != FDT_BEGIN_NODE) goto fail; do { offset = nextoffset; - tag = _fdt_next_tag(fdt, offset, &nextoffset); + tag = fdt_next_tag(fdt, offset, &nextoffset, NULL); switch (tag) { case FDT_END: err = -FDT_ERR_TRUNCATED; @@ -177,6 +218,10 @@ struct fdt_property *fdt_get_property(const void *fdt, break; case FDT_PROP: + /* + * If we are nested down levels, ignore the strings + * until we get back to the proper level. + */ if (level != 0) continue; @@ -216,6 +261,10 @@ struct fdt_property *fdt_get_property(const void *fdt, return NULL; } +/* + * Given the offset of a node and a name of a property in that node, return + * a pointer to the property data (ONLY). + */ void *fdt_getprop(const void *fdt, int nodeoffset, const char *name, int *lenp) { @@ -225,5 +274,60 @@ void *fdt_getprop(const void *fdt, int nodeoffset, if (! prop) return NULL; - return prop->data; + return (void *)prop->data; } + + +uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset, char **namep) +{ + const uint32_t *tagp, *lenp; + uint32_t tag; + const char *p; + + if (offset % FDT_TAGSIZE) + return -1; + + tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); + if (! tagp) + return FDT_END; /* premature end */ + tag = fdt32_to_cpu(*tagp); + offset += FDT_TAGSIZE; + + switch (tag) { + case FDT_BEGIN_NODE: + if(namep) + *namep = fdt_offset_ptr(fdt, offset, 1); + + /* skip name */ + do { + p = fdt_offset_ptr(fdt, offset++, 1); + } while (p && (*p != '\0')); + if (! p) + return FDT_END; + break; + case FDT_PROP: + lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); + if (! lenp) + return FDT_END; + /* + * Get the property and set the namep to the name. + */ + if(namep) { + struct fdt_property *prop; + + prop = fdt_offset_ptr_typed(fdt, offset - FDT_TAGSIZE, prop); + if (! prop) + return -FDT_ERR_BADSTRUCTURE; + *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + } + /* skip name offset, length and value */ + offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp); + break; + } + + if (nextoffset) + *nextoffset = ALIGN(offset, FDT_TAGSIZE); + + return tag; +} + diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index 7396645a69..b33fbf45de 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -145,7 +145,7 @@ static int _add_property(void *fdt, int nodeoffset, const char *name, int len, int namestroff; int err; - tag = _fdt_next_tag(fdt, nodeoffset, &nextoffset); + tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, NULL); if (tag != FDT_BEGIN_NODE) return -FDT_ERR_BADOFFSET; @@ -219,10 +219,10 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, return offset; /* Try to place the new node after the parent's properties */ - _fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */ + fdt_next_tag(fdt, parentoffset, &nextoffset, NULL); /* skip the BEGIN_NODE */ do { offset = nextoffset; - tag = _fdt_next_tag(fdt, offset, &nextoffset); + tag = fdt_next_tag(fdt, offset, &nextoffset, NULL); } while (tag == FDT_PROP); nh = _fdt_offset_ptr(fdt, offset); diff --git a/libfdt/fdt_sw.c b/libfdt/fdt_sw.c index 41d4891bb4..672f4ddd94 100644 --- a/libfdt/fdt_sw.c +++ b/libfdt/fdt_sw.c @@ -203,7 +203,7 @@ int fdt_finish(void *fdt) /* Walk the structure, correcting string offsets */ offset = 0; - while ((tag = _fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { + while ((tag = fdt_next_tag(fdt, offset, &nextoffset, NULL)) != FDT_END) { if (tag == FDT_PROP) { struct fdt_property *prop = fdt_offset_ptr(fdt, offset, sizeof(*prop)); diff --git a/libfdt/fdt_wip.c b/libfdt/fdt_wip.c index 0db7d259f5..261b9b0dc9 100644 --- a/libfdt/fdt_wip.c +++ b/libfdt/fdt_wip.c @@ -68,12 +68,12 @@ int _fdt_node_end_offset(void *fdt, int nodeoffset) uint32_t tag; int offset, nextoffset; - tag = _fdt_next_tag(fdt, nodeoffset, &nextoffset); + tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, NULL); if (tag != FDT_BEGIN_NODE) return -FDT_ERR_BADOFFSET; do { offset = nextoffset; - tag = _fdt_next_tag(fdt, offset, &nextoffset); + tag = fdt_next_tag(fdt, offset, &nextoffset, NULL); switch (tag) { case FDT_END: diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h index 124bef78e9..cc9633c9e1 100644 --- a/libfdt/libfdt_internal.h +++ b/libfdt/libfdt_internal.h @@ -27,7 +27,6 @@ #define streq(p, q) (strcmp((p), (q)) == 0) int _fdt_check_header(const void *fdt); -uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset); const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); int _fdt_node_end_offset(void *fdt, int nodeoffset); From 781e09ee6e3e3e392ab362c1f0ef1068adc76e3e Mon Sep 17 00:00:00 2001 From: Gerald Van Baren Date: Sat, 31 Mar 2007 12:22:10 -0400 Subject: [PATCH 11/17] Add a flattened device tree (fdt) command (1 of 2) The fdt command uses David Gibson's libfdt library to manipulate as well as print the flattened device tree. This patch is the new command, the second part is the modifications to the existing code. --- common/cmd_fdt.c | 874 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 874 insertions(+) create mode 100644 common/cmd_fdt.c diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c new file mode 100644 index 0000000000..968bade626 --- /dev/null +++ b/common/cmd_fdt.c @@ -0,0 +1,874 @@ +/* + * (C) Copyright 2007 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com + * Based on code written by: + * Pantelis Antoniou and + * Matthew McClintock + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#ifdef CONFIG_OF_LIBFDT +#include +#include +#include + +#define MAX_LEVEL 32 /* how deeply nested we will go */ +#define SCRATCHPAD 1024 /* bytes of scratchpad memory */ + +/* + * Global data (for the gd->bd) + */ +DECLARE_GLOBAL_DATA_PTR; + +/* + * Scratchpad memory. + */ +static char data[SCRATCHPAD]; + + +/* + * Function prototypes/declarations. + */ +static int fdt_valid(void); +static void print_data(const void *data, int len); +static int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end); +static int fdt_env(void *fdt); +static int fdt_bd_t(void *fdt); + + +/* + * Flattened Device Tree command, see the help for parameter definitions. + */ +int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + char op; + + if (argc < 2) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + /* + * Figure out which subcommand was given + */ + op = argv[1][0]; + /******************************************************************** + * Set the address of the fdt + ********************************************************************/ + if (op == 'a') { + /* + * Set the address [and length] of the fdt. + */ + fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16); + + if (!fdt_valid()) { + return 1; + } + + if (argc >= 4) { + int len; + int err; + /* + * Optional new length + */ + len = simple_strtoul(argv[3], NULL, 16); + if (len < fdt_totalsize(fdt)) { + printf ("New length %d < existing length %d, ignoring.\n", + len, fdt_totalsize(fdt)); + } else { + /* + * Open in place with a new length. + */ + err = fdt_open_into(fdt, fdt, len); + if (err != 0) { + printf ("libfdt: %s\n", fdt_strerror(err)); + } + } + } + + /******************************************************************** + * Move the fdt + ********************************************************************/ + } else if (op == 'm') { + struct fdt_header *newaddr; + int len; + int err; + + if (argc != 5) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + /* + * Set the address and length of the fdt. + */ + fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16); + if (!fdt_valid()) { + return 1; + } + + newaddr = (struct fdt_header *)simple_strtoul(argv[3], NULL, 16); + len = simple_strtoul(argv[4], NULL, 16); + if (len < fdt_totalsize(fdt)) { + printf ("New length %d < existing length %d, aborting.\n", + len, fdt_totalsize(fdt)); + return 1; + } + + /* + * Copy to the new location. + */ + err = fdt_open_into(fdt, newaddr, len); + if (err != 0) { + printf ("libfdt: %s\n", fdt_strerror(err)); + return 1; + } + fdt = newaddr; + + /******************************************************************** + * Set the value of a node in the fdt. + ********************************************************************/ + } else if (op == 's') { + char *pathp; /* path */ + char *prop; /* property */ + struct fdt_property *nodep; /* node struct pointer */ + char *newval; /* value from the user (as a string) */ + char *vp; /* temporary value pointer */ + char *cp; /* temporary char pointer */ + int nodeoffset; /* node offset from libfdt */ + int len; /* new length of the property */ + int oldlen; /* original length of the property */ + unsigned long tmp; /* holds converted values */ + int ret; /* return value */ + + /* + * Parameters: Node path, property, value. + */ + if (argc < 5) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + pathp = argv[2]; + prop = argv[3]; + newval = argv[4]; + + if (strcmp(pathp, "/") == 0) { + nodeoffset = 0; + } else { + nodeoffset = fdt_path_offset (fdt, pathp); + if (nodeoffset < 0) { + /* + * Not found or something else bad happened. + */ + printf ("libfdt: %s\n", fdt_strerror(nodeoffset)); + return 1; + } + } + nodep = fdt_getprop (fdt, nodeoffset, prop, &oldlen); + if (oldlen < 0) { + printf ("libfdt %s\n", fdt_strerror(oldlen)); + return 1; + } else if (oldlen == 0) { + /* + * The specified property has no value + */ + printf("%s has no value, cannot set one (yet).\n", prop); + return 1; + } else { + /* + * Convert the new property + */ + vp = data; + if (*newval == '<') { + /* + * Bigger values than bytes. + */ + len = 0; + newval++; + while ((*newval != '>') && (*newval != '\0')) { + cp = newval; + tmp = simple_strtoul(cp, &newval, 16); + if ((newval - cp) <= 2) { + *vp = tmp & 0xFF; + vp += 1; + len += 1; + } else if ((newval - cp) <= 4) { + *(uint16_t *)vp = __cpu_to_be16(tmp); + vp += 2; + len += 2; + } else if ((newval - cp) <= 8) { + *(uint32_t *)vp = __cpu_to_be32(tmp); + vp += 4; + len += 4; + } else { + printf("Sorry, I could not convert \"%s\"\n", cp); + return 1; + } + while (*newval == ' ') + newval++; + } + if (*newval != '>') { + printf("Unexpected character '%c'\n", *newval); + return 1; + } + } else if (*newval == '[') { + /* + * Byte stream. Convert the values. + */ + len = 0; + newval++; + while ((*newval != ']') && (*newval != '\0')) { + tmp = simple_strtoul(newval, &newval, 16); + *vp++ = tmp & 0xFF; + len++; + while (*newval == ' ') + newval++; + } + if (*newval != ']') { + printf("Unexpected character '%c'\n", *newval); + return 1; + } + } else { + /* + * Assume it is a string. Copy it into our data area for + * convenience (including the terminating '\0'). + */ + len = strlen(newval) + 1; + strcpy(data, newval); + } + + ret = fdt_setprop(fdt, nodeoffset, prop, data, len); + if (ret < 0) { + printf ("libfdt %s\n", fdt_strerror(ret)); + return 1; + } + } + + /******************************************************************** + * Print (recursive) / List (single level) + ********************************************************************/ + } else if ((op == 'p') || (op == 'l')) { + /* + * Recursively print (a portion of) the fdt. + */ + static int offstack[MAX_LEVEL]; + static char tabs[MAX_LEVEL+1] = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; + int depth = MAX_LEVEL; /* how deep to print */ + char *pathp; /* path */ + char *prop; /* property */ + void *nodep; /* property node pointer */ + int nodeoffset; /* node offset from libfdt */ + int nextoffset; /* next node offset from libfdt */ + uint32_t tag; /* tag */ + int len; /* length of the property */ + int level = 0; /* keep track of nesting level */ + + /* + * list is an alias for print, but limited to 1 level + */ + if (op == 'l') { + depth = 1; + } + + /* + * Get the starting path. The root node is an oddball, + * the offset is zero and has no name. + */ + pathp = argv[2]; + if (argc > 3) + prop = argv[3]; + else + prop = NULL; + + if (strcmp(pathp, "/") == 0) { + nodeoffset = 0; + printf("/"); + } else { + nodeoffset = fdt_path_offset (fdt, pathp); + if (nodeoffset < 0) { + /* + * Not found or something else bad happened. + */ + printf ("libfdt %s\n", fdt_strerror(nodeoffset)); + return 1; + } + } + /* + * The user passed in a property as well as node path. Print only + * the given property and then return. + */ + if (prop) { + nodep = fdt_getprop (fdt, nodeoffset, prop, &len); + if (len == 0) { + printf("%s %s\n", pathp, prop); /* no property value */ + return 0; + } else if (len > 0) { + printf("%s=", prop); + print_data (nodep, len); + printf("\n"); + return 0; + } else { + printf ("libfdt %s\n", fdt_strerror(len)); + return 1; + } + } + + /* + * The user passed in a node path and no property, print the node + * and all subnodes. + */ + offstack[0] = nodeoffset; + + while(level >= 0) { + tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, &pathp); + switch(tag) { + case FDT_BEGIN_NODE: + if(level <= depth) + printf("%s%s {\n", &tabs[MAX_LEVEL - level], pathp); + level++; + offstack[level] = nodeoffset; + if (level >= MAX_LEVEL) { + printf("Aaaiii nested too deep.\n"); + return 1; + } + break; + case FDT_END_NODE: + level--; + if(level <= depth) + printf("%s};\n", &tabs[MAX_LEVEL - level]); + if (level == 0) { + level = -1; /* exit the loop */ + } + break; + case FDT_PROP: + nodep = fdt_getprop (fdt, offstack[level], pathp, &len); + if (len < 0) { + printf ("libfdt %s\n", fdt_strerror(len)); + return 1; + } else if (len == 0) { + /* the property has no value */ + if(level <= depth) + printf("%s%s;\n", &tabs[MAX_LEVEL - level], pathp); + } else { + if(level <= depth) { + printf("%s%s=", &tabs[MAX_LEVEL - level], pathp); + print_data (nodep, len); + printf(";\n"); + } + } + break; + case FDT_NOP: + break; + case FDT_END: + return 1; + default: + if(level <= depth) + printf("Unknown tag 0x%08X\n", tag); + return 1; + } + nodeoffset = nextoffset; + } + + /******************************************************************** + * Remove a property/node + ********************************************************************/ + } else if (op == 'r') { + int nodeoffset; /* node offset from libfdt */ + int err; + + /* + * Get the path. The root node is an oddball, the offset + * is zero and has no name. + */ + if (strcmp(argv[2], "/") == 0) { + nodeoffset = 0; + } else { + nodeoffset = fdt_path_offset (fdt, argv[2]); + if (nodeoffset < 0) { + /* + * Not found or something else bad happened. + */ + printf ("libfdt %s\n", fdt_strerror(nodeoffset)); + return 1; + } + } + /* + * Do the delete. A fourth parameter means delete a property, + * otherwise delete the node. + */ + if (argc > 3) { + err = fdt_delprop(fdt, nodeoffset, argv[3]); + if (err < 0) { + printf("fdt_delprop libfdt: %s\n", fdt_strerror(err)); + return err; + } + } else { + err = fdt_del_node(fdt, nodeoffset); + if (err < 0) { + printf("fdt_del_node libfdt: %s\n", fdt_strerror(err)); + return err; + } + } + + /******************************************************************** + * Create a chosen node + ********************************************************************/ + } else if (op == 'c') { + fdt_chosen(fdt, 0, 0); + + /******************************************************************** + * Create a u-boot-env node + ********************************************************************/ + } else if (op == 'e') { + fdt_env(fdt); + + /******************************************************************** + * Create a bd_t node + ********************************************************************/ + } else if (op == 'b') { + fdt_bd_t(fdt); + + /******************************************************************** + * Unrecognized command + ********************************************************************/ + } else { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + return 0; +} + +/********************************************************************/ + +static int fdt_valid(void) +{ + if (fdt == NULL) { + printf ("The address of the fdt is invalid.\n"); + return 0; + } + if (!fdt || (fdt_magic(fdt) != FDT_MAGIC)) { + fdt = NULL; + printf ("Unrecognized fdt: bad magic\n"); + return 0; + } + if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) { + printf ("Unsupported fdt version: $d < %d\n", + FDT_FIRST_SUPPORTED_VERSION, fdt_version(fdt)); + fdt = NULL; + return 0; + } + if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) { + printf ("Unsupported fdt version: $d > %d\n", + fdt_version(fdt), FDT_LAST_SUPPORTED_VERSION); + fdt = NULL; + return 0; + } + return 1; +} + +/********************************************************************/ + +/* + * OF flat tree handling + * Written by: Pantelis Antoniou + * Updated by: Matthew McClintock + * Converted to libfdt by: Gerald Van Baren + */ + +static int is_printable_string(const void *data, int len) +{ + const char *s = data; + + /* zero length is not */ + if (len == 0) + return 0; + + /* must terminate with zero */ + if (s[len - 1] != '\0') + return 0; + + /* printable or a null byte (concatenated strings) */ + while (((*s == '\0') || isprint(*s)) && (len > 0)) { + /* + * If we see a null, there are three possibilities: + * 1) If len == 1, it is the end of the string, printable + * 2) Next character also a null, not printable. + * 3) Next character not a null, continue to check. + */ + if (s[0] == '\0') { + if (len == 1) + return 1; + if (s[1] == '\0') + return 0; + } + s++; + len--; + } + + /* Not the null termination, or not done yet: not printable */ + if (*s != '\0' || (len != 0)) + return 0; + + return 1; +} + +static void print_data(const void *data, int len) +{ + int j; + const u8 *s; + + /* no data, don't print */ + if (len == 0) + return; + + /* + * It is a string, but it may have multiple strings (embedded '\0's). + */ + if (is_printable_string(data, len)) { + puts("\""); + j = 0; + while (j < len) { + if (j > 0) + puts("\", \""); + puts(data); + j += strlen(data) + 1; + data += strlen(data) + 1; + } + puts("\""); + return; + } + + switch (len) { + case 1: /* byte */ + printf("<%02x>", (*(u8 *) data) & 0xff); + break; + case 2: /* half-word */ + printf("<%04x>", be16_to_cpu(*(u16 *) data) & 0xffff); + break; + case 4: /* word */ + printf("<%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU); + break; + case 8: /* double-word */ +#if __WORDSIZE == 64 + printf("<%016llx>", be64_to_cpu(*(uint64_t *) data)); +#else + printf("<%08x ", be32_to_cpu(*(u32 *) data) & 0xffffffffU); + data += 4; + printf("%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU); +#endif + break; + default: /* anything else... hexdump */ + printf("["); + for (j = 0, s = data; j < len; j++) + printf("%02x%s", s[j], j < len - 1 ? " " : ""); + printf("]"); + + break; + } +} + +/********************************************************************/ + +static int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end) +{ + bd_t *bd = gd->bd; + int nodeoffset; + int err; + u32 tmp; /* used to set 32 bit integer properties */ + char *str; /* used to set string properties */ + ulong clock; + + if (initrd_start && initrd_end) { + err = fdt_add_reservemap_entry(fdt, + initrd_start, initrd_end - initrd_start + 1); + if (err < 0) { + printf("libfdt: %s\n", fdt_strerror(err)); + return err; + } + } + + /* + * See if we already have a "chosen" node, create it if not. + */ + nodeoffset = fdt_path_offset (fdt, "/chosen"); + if (nodeoffset < 0) { + /* + * Create a new node "/chosen" (offset 0 is root level) + */ + nodeoffset = fdt_add_subnode(fdt, 0, "chosen"); + if (nodeoffset < 0) { + printf("libfdt: %s\n", fdt_strerror(nodeoffset)); + return nodeoffset; + } + } + + str = getenv("bootargs"); + if (str != NULL) { + err = fdt_setprop(fdt, nodeoffset, "bootargs", str, strlen(str)+1); + if (err < 0) + printf("libfdt: %s\n", fdt_strerror(err)); + } + if (initrd_start && initrd_end) { + tmp = __cpu_to_be32(initrd_start); + err = fdt_setprop(fdt, nodeoffset, "linux,initrd-start", &tmp, sizeof(tmp)); + if (err < 0) + printf("libfdt: %s\n", fdt_strerror(err)); + tmp = __cpu_to_be32(initrd_end); + err = fdt_setprop(fdt, nodeoffset, "linux,initrd-end", &tmp, sizeof(tmp)); + if (err < 0) + printf("libfdt: %s\n", fdt_strerror(err)); + } +#ifdef OF_STDOUT_PATH + err = fdt_setprop(fdt, nodeoffset, "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1); + if (err < 0) + printf("libfdt: %s\n", fdt_strerror(err)); +#endif + + nodeoffset = fdt_path_offset (fdt, "/cpus"); + if (nodeoffset >= 0) { + clock = cpu_to_be32(bd->bi_intfreq); + err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4); + if (err < 0) + printf("libfdt: %s\n", fdt_strerror(err)); + } +#ifdef OF_TBCLK + nodeoffset = fdt_path_offset (fdt, "/cpus/" OF_CPU "/timebase-frequency"); + if (nodeoffset >= 0) { + clock = cpu_to_be32(OF_TBCLK); + err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4); + if (err < 0) + printf("libfdt: %s\n", fdt_strerror(err)); + } +#endif +} + +/********************************************************************/ + +#ifdef CONFIG_OF_HAS_BD_T + +/* Function that returns a character from the environment */ +extern uchar(*env_get_char) (int); + +#define BDM(x) { .name = #x, .offset = offsetof(bd_t, bi_ ##x ) } + +static const struct { + const char *name; + int offset; +} bd_map[] = { + BDM(memstart), + BDM(memsize), + BDM(flashstart), + BDM(flashsize), + BDM(flashoffset), + BDM(sramstart), + BDM(sramsize), +#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ + || defined(CONFIG_E500) + BDM(immr_base), +#endif +#if defined(CONFIG_MPC5xxx) + BDM(mbar_base), +#endif +#if defined(CONFIG_MPC83XX) + BDM(immrbar), +#endif +#if defined(CONFIG_MPC8220) + BDM(mbar_base), + BDM(inpfreq), + BDM(pcifreq), + BDM(pevfreq), + BDM(flbfreq), + BDM(vcofreq), +#endif + BDM(bootflags), + BDM(ip_addr), + BDM(intfreq), + BDM(busfreq), +#ifdef CONFIG_CPM2 + BDM(cpmfreq), + BDM(brgfreq), + BDM(sccfreq), + BDM(vco), +#endif +#if defined(CONFIG_MPC5xxx) + BDM(ipbfreq), + BDM(pcifreq), +#endif + BDM(baudrate), +}; + +static int fdt_env(void *fdt) +{ + int nodeoffset; + int err; + int k, nxt; + int i; + static char tmpenv[256]; + + /* + * See if we already have a "u-boot-env" node, delete it if so. + * Then create a new empty node. + */ + nodeoffset = fdt_path_offset (fdt, "/u-boot-env"); + if (nodeoffset >= 0) { + err = fdt_del_node(fdt, nodeoffset); + if (err < 0) { + printf("libfdt: %s\n", fdt_strerror(err)); + return err; + } + } + /* + * Create a new node "/u-boot-env" (offset 0 is root level) + */ + nodeoffset = fdt_add_subnode(fdt, 0, "u-boot-env"); + if (nodeoffset < 0) { + printf("libfdt: %s\n", fdt_strerror(nodeoffset)); + return nodeoffset; + } + + for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { + char *s, *lval, *rval; + + /* + * Find the end of the name=definition + */ + for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) + ; + s = tmpenv; + for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k) + *s++ = env_get_char(k); + *s++ = '\0'; + lval = tmpenv; + /* + * Find the first '=': it separates the name from the value + */ + s = strchr(tmpenv, '='); + if (s != NULL) { + *s++ = '\0'; + rval = s; + } else + continue; + err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1); + if (err < 0) { + printf("\"%s\" - libfdt: %s\n", lval, fdt_strerror(err)); + return err; + } + } + return 0; +} +#endif /* CONFIG_OF_HAS_UBOOT_ENV */ + +/********************************************************************/ + +#ifdef CONFIG_OF_HAS_BD_T +static int fdt_bd_t(void *fdt) +{ + bd_t *bd = gd->bd; + int nodeoffset; + int err; + u32 tmp; /* used to set 32 bit integer properties */ + int i; + + /* + * See if we already have a "bd_t" node, delete it if so. + * Then create a new empty node. + */ + nodeoffset = fdt_path_offset (fdt, "/bd_t"); + if (nodeoffset >= 0) { + err = fdt_del_node(fdt, nodeoffset); + if (err < 0) { + printf("libfdt: %s\n", fdt_strerror(err)); + return err; + } + } + /* + * Create a new node "/bd_t" (offset 0 is root level) + */ + nodeoffset = fdt_add_subnode(fdt, 0, "bd_t"); + if (nodeoffset < 0) { + printf("libfdt: %s\n", fdt_strerror(nodeoffset)); + return nodeoffset; + } + /* + * Use the string/pointer structure to create the entries... + */ + for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) { + tmp = cpu_to_be32(getenv("bootargs")); + err = fdt_setprop(fdt, nodeoffset, bd_map[i].name, &tmp, sizeof(tmp)); + if (err < 0) + printf("libfdt: %s\n", fdt_strerror(err)); + } + /* + * Add a couple of oddball entries... + */ + err = fdt_setprop(fdt, nodeoffset, "enetaddr", &bd->bi_enetaddr, 6); + if (err < 0) + printf("libfdt: %s\n", fdt_strerror(err)); + err = fdt_setprop(fdt, nodeoffset, "ethspeed", &bd->bi_ethspeed, 4); + if (err < 0) + printf("libfdt: %s\n", fdt_strerror(err)); + +#ifdef CONFIG_OF_BOARD_SETUP + ft_board_setup(fdt, bd); +#endif + + return 0; +} +#endif /* CONFIG_OF_HAS_BD_T */ + +/********************************************************************/ + +U_BOOT_CMD( + fdt, 5, 0, do_fdt, + "fdt - flattened device tree utility commands\n", + "addr [] - Set the fdt location to \n" + "fdt move - Copy the fdt to \n" + "fdt print [] - Recursive print starting at \n" + "fdt list [] - Print one level starting at \n" + "fdt set [] - Set [to ]\n" + "fdt mknode - Create a new node after \n" + "fdt rm [] - Delete the node or \n" + "fdt chosen - Add/update the \"/chosen\" branch in the tree\n" +#ifdef CONFIG_OF_HAS_UBOOT_ENV + "fdt env - Add/replace the \"/u-boot-env\" branch in the tree\n" +#endif +#ifdef CONFIG_OF_HAS_BD_T + "fdt bd_t - Add/replace the \"/bd_t\" branch in the tree\n" +#endif + "Hints:\n" + " * Set a larger length with the fdt addr command to add to the blob.\n" + " * If the property you are setting/printing has a '#' character,\n" + " you MUST escape it with a \\ character or quote it with \" or\n" + " it will be ignored as a comment.\n" + " * If the value has spaces in it, you MUST escape the spaces with\n" + " \\ characters or quote it with \"\"\n" + "Examples: fdt print / # print the whole tree\n" + " fdt print /cpus \"#address-cells\"\n" + " fdt set /cpus \"#address-cells\" \"[00 00 00 01]\"\n" +); + +#endif /* CONFIG_OF_FLAT_TREE */ From 213bf8c822de8eecaf69860684469cdaba2e9e6a Mon Sep 17 00:00:00 2001 From: Gerald Van Baren Date: Sat, 31 Mar 2007 12:23:51 -0400 Subject: [PATCH 12/17] Add a flattened device tree (fdt) command (2 of 2) Modifications to the existing code to support the new fdt command. --- README | 33 ++++++++--- board/mpc8360emds/config.mk | 6 ++ board/mpc8360emds/mpc8360emds.c | 30 ++++++++-- board/mpc8360emds/pci.c | 20 +++++++ common/Makefile | 2 +- common/cmd_bootm.c | 65 ++++++++++++++++---- cpu/mpc83xx/cpu.c | 102 +++++++++++++++++++++++++++++++- include/configs/MPC8360EMDS.h | 6 +- 8 files changed, 237 insertions(+), 27 deletions(-) diff --git a/README b/README index 15428643ed..87d6d10717 100644 --- a/README +++ b/README @@ -164,6 +164,7 @@ Directory Hierarchy: - lib_mips Files generic to MIPS architecture - lib_nios Files generic to NIOS architecture - lib_ppc Files generic to PowerPC architecture +- libfdt Library files to support flattened device trees - net Networking code - post Power On Self Test - rtc Real Time Clock drivers @@ -430,12 +431,23 @@ The following options need to be configured: expect it to be in bytes, others in MB. Define CONFIG_MEMSIZE_IN_BYTES to make it in bytes. - CONFIG_OF_FLAT_TREE + CONFIG_OF_LIBFDT / CONFIG_OF_FLAT_TREE New kernel versions are expecting firmware settings to be - passed using flat open firmware trees. - The environment variable "disable_of", when set, disables this - functionality. + passed using flattened device trees (based on open firmware + concepts). + + CONFIG_OF_LIBFDT + * New libfdt-based support + * Adds the "fdt" command + * The bootm command does _not_ modify the fdt + + CONFIG_OF_FLAT_TREE + * Deprecated, see CONFIG_OF_LIBFDT + * Original ft_build.c-based support + * Automatically modifies the dft as part of the bootm command + * The environment variable "disable_of", when set, + disables this functionality. CONFIG_OF_FLAT_TREE_MAX_SIZE @@ -448,13 +460,16 @@ The following options need to be configured: CONFIG_OF_HAS_BD_T - The resulting flat device tree will have a copy of the bd_t. - Space should be pre-allocated in the dts for the bd_t. + * CONFIG_OF_LIBFDT - enables the "fdt bd_t" command + * CONFIG_OF_FLAT_TREE - The resulting flat device tree + will have a copy of the bd_t. Space should be + pre-allocated in the dts for the bd_t. CONFIG_OF_HAS_UBOOT_ENV - The resulting flat device tree will have a copy of u-boot's - environment variables + * CONFIG_OF_LIBFDT - enables the "fdt bd_t" command + * CONFIG_OF_FLAT_TREE - The resulting flat device tree + will have a copy of u-boot's environment variables CONFIG_OF_BOARD_SETUP @@ -721,6 +736,8 @@ The following options need to be configured: #define CONFIG_COMMANDS (CFG_CMD_ALL & ~CFG_CMD_NET) + Other Commands: + fdt (flattened device tree) command: CONFIG_OF_LIBFDT Note: Don't enable the "icache" and "dcache" commands (configuration option CFG_CMD_CACHE) unless you know diff --git a/board/mpc8360emds/config.mk b/board/mpc8360emds/config.mk index 9ace8860cf..d2a9435828 100644 --- a/board/mpc8360emds/config.mk +++ b/board/mpc8360emds/config.mk @@ -26,3 +26,9 @@ # TEXT_BASE = 0xFE000000 + +# +# Additional board-specific libraries +# +BOARDLIBS = libfdt/libfdt.a + diff --git a/board/mpc8360emds/mpc8360emds.c b/board/mpc8360emds/mpc8360emds.c index 535884cb50..deadb5ffbe 100644 --- a/board/mpc8360emds/mpc8360emds.c +++ b/board/mpc8360emds/mpc8360emds.c @@ -31,6 +31,10 @@ #if defined(CONFIG_OF_FLAT_TREE) #include #endif +#if defined(CONFIG_OF_LIBFDT) +#include +#include +#endif const qe_iop_conf_t qe_iop_conf_tab[] = { /* GETH1 */ @@ -658,22 +662,36 @@ U_BOOT_CMD(ecc, 4, 0, do_ecc, " - disables injects\n" " - re-inits memory"); #endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */ -#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) +#if (defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)) \ + && defined(CONFIG_OF_BOARD_SETUP) void ft_board_setup(void *blob, bd_t *bd) { +#if defined(CONFIG_OF_LIBFDT) + int nodeoffset; + int err; + int tmp[2]; + + nodeoffset = fdt_path_offset (fdt, "/memory"); + if (nodeoffset >= 0) { + tmp[0] = cpu_to_be32(bd->bi_memstart); + tmp[1] = cpu_to_be32(bd->bi_memsize); + err = fdt_setprop(fdt, nodeoffset, "reg", tmp, sizeof(tmp)); + } +#else u32 *p; int len; -#ifdef CONFIG_PCI - ft_pci_setup(blob, bd); -#endif - ft_cpu_setup(blob, bd); - p = ft_get_prop(blob, "/memory/reg", &len); if (p != NULL) { *p++ = cpu_to_be32(bd->bi_memstart); *p = cpu_to_be32(bd->bi_memsize); } +#endif + +#ifdef CONFIG_PCI + ft_pci_setup(blob, bd); +#endif + ft_cpu_setup(blob, bd); } #endif diff --git a/board/mpc8360emds/pci.c b/board/mpc8360emds/pci.c index 67cd70981c..158effe0a9 100644 --- a/board/mpc8360emds/pci.c +++ b/board/mpc8360emds/pci.c @@ -21,6 +21,10 @@ #if defined(CONFIG_OF_FLAT_TREE) #include #endif +#if defined(CONFIG_OF_LIBFDT) +#include +#include +#endif #include @@ -299,6 +303,22 @@ void pci_init_board(void) } #endif /* CONFIG_PCISLAVE */ +#if defined(CONFIG_OF_LIBFDT) +void +ft_pci_setup(void *blob, bd_t *bd) +{ + int nodeoffset; + int err; + int tmp[2]; + + nodeoffset = fdt_path_offset (fdt, "/" OF_SOC "/pci@8500"); + if (nodeoffset >= 0) { + tmp[0] = cpu_to_be32(hose[0].first_busno); + tmp[1] = cpu_to_be32(hose[0].last_busno); + err = fdt_setprop(fdt, nodeoffset, "bus-range", tmp, sizeof(tmp)); + } +} +#endif /* CONFIG_OF_LIBFDT */ #ifdef CONFIG_OF_FLAT_TREE void ft_pci_setup(void *blob, bd_t *bd) diff --git a/common/Makefile b/common/Makefile index 6f81c4abcf..74a6af204e 100644 --- a/common/Makefile +++ b/common/Makefile @@ -32,7 +32,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o cmd_autoscript.o \ cmd_cache.o cmd_console.o \ cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \ cmd_eeprom.o cmd_elf.o cmd_ext2.o \ - cmd_fat.o cmd_fdc.o cmd_fdos.o cmd_flash.o cmd_fpga.o \ + cmd_fat.o cmd_fdc.o cmd_fdt.o cmd_fdos.o cmd_flash.o cmd_fpga.o \ cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \ cmd_load.o cmd_log.o \ cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \ diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index c0ed076bb9..ab8648fffc 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -34,7 +34,11 @@ #include #include -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_LIBFDT) +#include +#include +#endif +#if defined(CONFIG_OF_FLAT_TREE) #include #endif @@ -467,7 +471,7 @@ U_BOOT_CMD( "[addr [arg ...]]\n - boot application image stored in memory\n" "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n" "\t'arg' can be the address of an initrd image\n" -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) "\tWhen booting a Linux kernel which requires a flat device-tree\n" "\ta third argument is required which is the address of the of the\n" "\tdevice-tree blob. To boot that kernel without an initrd image,\n" @@ -529,7 +533,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, bd_t *kbd; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); image_header_t *hdr = &header; -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) char *of_flat_tree = NULL; ulong of_data = 0; #endif @@ -622,7 +626,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, * Check if there is an initrd image */ -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) /* Look for a '-' which indicates to ignore the ramdisk argument */ if (argc >= 3 && strcmp(argv[2], "-") == 0) { debug ("Skipping initrd\n"); @@ -739,12 +743,15 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, len = data = 0; } -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) if(argc > 3) { of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); hdr = (image_header_t *)of_flat_tree; - - if (*(ulong *)of_flat_tree == OF_DT_HEADER) { +#if defined(CONFIG_OF_LIBFDT) + if (be32_to_cpu(fdt_magic(of_flat_tree)) == FDT_MAGIC) { +#else + if (*(ulong *)of_flat_tree == OF_DT_HEADER) { +#endif #ifndef CFG_NO_FLASH if (addr2info((ulong)of_flat_tree) != NULL) of_data = (ulong)of_flat_tree; @@ -787,7 +794,11 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, printf("ERROR: uImage is not uncompressed\n"); return; } +#if defined(CONFIG_OF_LIBFDT) + if (be32_to_cpu(fdt_magic(of_flat_tree + sizeof(image_header_t))) != FDT_MAGIC) { +#else if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) { +#endif printf ("ERROR: uImage data is not a flat device tree\n"); return; } @@ -824,12 +835,20 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, of_data += 4 - tail; } +#if defined(CONFIG_OF_LIBFDT) + if (be32_to_cpu(fdt_magic(of_data)) != FDT_MAGIC) { +#else if (((struct boot_param_header *)of_data)->magic != OF_DT_HEADER) { +#endif printf ("ERROR: image is not a flat device tree\n"); return; } +#if defined(CONFIG_OF_LIBFDT) + if (be32_to_cpu(fdt_totalsize(of_data)) != ntohl(len_ptr[2])) { +#else if (((struct boot_param_header *)of_data)->totalsize != ntohl(len_ptr[2])) { +#endif printf ("ERROR: flat device tree size does not agree with image\n"); return; } @@ -913,7 +932,31 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, unlock_ram_in_cache(); #endif -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_LIBFDT) + /* move of_flat_tree if needed */ + if (of_data) { + int err; + ulong of_start, of_len; + of_len = be32_to_cpu(fdt_totalsize(of_data)); + /* provide extra 8k pad */ + if (initrd_start) + of_start = initrd_start - of_len - 8192; + else + of_start = (ulong)kbd - of_len - 8192; + of_start &= ~(4096 - 1); /* align on page */ + debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", + of_data, of_data + of_len - 1, of_len, of_len); + + + printf (" Loading Device Tree to %08lx, end %08lx ... ", + of_start, of_start + of_len - 1); + err = fdt_open_into(of_start, of_data, of_len); + if (err != 0) { + printf ("libfdt: %s\n", fdt_strerror(err)); + } + } +#endif +#if defined(CONFIG_OF_FLAT_TREE) /* move of_flat_tree if needed */ if (of_data) { ulong of_start, of_len; @@ -942,13 +985,13 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, * r6: Start of command line string * r7: End of command line string */ -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) if (!of_flat_tree) /* no device tree; boot old style */ #endif (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); /* does not return */ -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) /* * Linux Kernel Parameters (passing device tree): * r3: ptr to OF flat tree, followed by the board info data @@ -957,8 +1000,10 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, * r6: NULL * r7: NULL */ +#if defined(CONFIG_OF_FLAT_TREE) ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); /* ft_dump_blob(of_flat_tree); */ +#endif (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); #endif diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index e4bc4052db..851241adfb 100644 --- a/cpu/mpc83xx/cpu.c +++ b/cpu/mpc83xx/cpu.c @@ -30,8 +30,14 @@ #include #include #include -#include #include +#if defined(CONFIG_OF_FLAT_TREE) +#include +#endif +#if defined(CONFIG_OF_LIBFDT) +#include +#include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -291,6 +297,100 @@ void watchdog_reset (void) } #endif +#if defined(CONFIG_OF_LIBFDT) + +/* + * Fixups to the fdt. If "create" is TRUE, the node is created + * unconditionally. If "create" is FALSE, the node is updated + * only if it already exists. + */ +#define FT_UPDATE 0x00000000 /* update existing property only */ +#define FT_CREATE 0x00000001 /* create property if it doesn't exist */ +#define FT_BUSFREQ 0x00000002 /* source is bd->bi_busfreq */ +#define FT_ENETADDR 0x00000004 /* source is bd->bi_enetaddr */ +static const struct { + int createflags; + char *node; + char *prop; +} fixup_props[] = { + { FT_CREATE | FT_BUSFREQ, + "/cpus/" OF_CPU, + "bus-frequency", + }, + { FT_CREATE | FT_BUSFREQ, + "/cpus/" OF_SOC, + "bus-frequency" + }, + { FT_CREATE | FT_BUSFREQ, + "/" OF_SOC "/serial@4500/", + "clock-frequency" + }, + { FT_CREATE | FT_BUSFREQ, + "/" OF_SOC "/serial@4600/", + "clock-frequency" + }, +#ifdef CONFIG_MPC83XX_TSEC1 + { FT_UPDATE | FT_ENETADDR, + "/" OF_SOC "/ethernet@24000, + "mac-address", + }, + { FT_UPDATE | FT_ENETADDR, + "/" OF_SOC "/ethernet@24000, + "local-mac-address", + }, +#endif +#ifdef CONFIG_MPC83XX_TSEC2 + { FT_UPDATE | FT_ENETADDR, + "/" OF_SOC "/ethernet@25000, + "mac-address", + }, + { FT_UPDATE | FT_ENETADDR, + "/" OF_SOC "/ethernet@25000, + "local-mac-address", + }, +#endif +}; + +void +ft_cpu_setup(void *blob, bd_t *bd) +{ + int nodeoffset; + int err; + int j; + + for (j = 0; j < (sizeof(fixup_props) / sizeof(fixup_props[0])); j++) { + nodeoffset = fdt_path_offset (fdt, fixup_props[j].node); + if (nodeoffset >= 0) { + /* + * If unconditional create or the property already exists... + */ + if ((fixup_props[j].createflags & FT_CREATE) || + (fdt_get_property(fdt, nodeoffset, fixup_props[j].prop, 0))) { + if (fixup_props[j].createflags & FT_BUSFREQ) { + u32 tmp; + + tmp = cpu_to_be32(bd->bi_busfreq); + err = fdt_setprop(fdt, nodeoffset, + fixup_props[j].prop, &tmp, sizeof(tmp)); + } else if (fixup_props[j].createflags & FT_ENETADDR) { + err = fdt_setprop(fdt, nodeoffset, + fixup_props[j].prop, bd->bi_enetaddr, 6); + } else { + printf("ft_cpu_setup: %s %s has no flag for the value to set\n", + fixup_props[j].node, + fixup_props[j].prop); + } + if (err < 0) + printf("libfdt: %s %s returned %s\n", + fixup_props[j].node, + fixup_props[j].prop, + fdt_strerror(err)); + } + } + } +} +#endif + #if defined(CONFIG_OF_FLAT_TREE) void ft_cpu_setup(void *blob, bd_t *bd) diff --git a/include/configs/MPC8360EMDS.h b/include/configs/MPC8360EMDS.h index d2af0e1dfc..79937dcd8f 100644 --- a/include/configs/MPC8360EMDS.h +++ b/include/configs/MPC8360EMDS.h @@ -342,8 +342,12 @@ #endif /* pass open firmware flat tree */ -#define CONFIG_OF_FLAT_TREE 1 +#define CONFIG_OF_LIBFDT 1 +#undef CONFIG_OF_FLAT_TREE #define CONFIG_OF_BOARD_SETUP 1 +#define CONFIG_OF_HAS_BD_T 1 +#define CONFIG_OF_HAS_UBOOT_ENV 1 + /* maximum size of the flat tree (8K) */ #define OF_FLAT_TREE_MAX_SIZE 8192 From aea03c4e8c3a21ce43d3faf48a6e6d474c8bdf73 Mon Sep 17 00:00:00 2001 From: Gerald Van Baren Date: Sat, 31 Mar 2007 14:30:53 -0400 Subject: [PATCH 13/17] Fix some minor whitespace violations. --- common/cmd_bootm.c | 2 +- cpu/mpc83xx/cpu.c | 4 ++-- libfdt/fdt_ro.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index ab8648fffc..2721216bf3 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -38,7 +38,7 @@ #include #include #endif -#if defined(CONFIG_OF_FLAT_TREE) +#if defined(CONFIG_OF_FLAT_TREE) #include #endif diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index 851241adfb..21b16463cd 100644 --- a/cpu/mpc83xx/cpu.c +++ b/cpu/mpc83xx/cpu.c @@ -377,12 +377,12 @@ ft_cpu_setup(void *blob, bd_t *bd) fixup_props[j].prop, bd->bi_enetaddr, 6); } else { printf("ft_cpu_setup: %s %s has no flag for the value to set\n", - fixup_props[j].node, + fixup_props[j].node, fixup_props[j].prop); } if (err < 0) printf("libfdt: %s %s returned %s\n", - fixup_props[j].node, + fixup_props[j].node, fixup_props[j].prop, fdt_strerror(err)); } diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index f884083950..4b20553da0 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -171,7 +171,7 @@ int fdt_path_offset(const void *fdt, const char *path) p = q; } - return offset; + return offset; } /* @@ -240,7 +240,7 @@ struct fdt_property *fdt_get_property(const void *fdt, if (lenp) *lenp = len; - + return prop; } break; From 94abd7c0583ebe01e799b25f451201deeaab550d Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 4 Apr 2007 01:49:15 +0200 Subject: [PATCH 14/17] Minor cleanup. --- CHANGELOG | 118 ++++++++++++++++++++++++++++++++++++ board/mpc8360emds/config.mk | 1 - include/fdt.h | 30 ++++----- include/libfdt.h | 10 +-- libfdt/Makefile | 3 +- libfdt/fdt_ro.c | 14 ++--- 6 files changed, 145 insertions(+), 31 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 284ba76d89..0bff39eecc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,121 @@ +commit aea03c4e8c3a21ce43d3faf48a6e6d474c8bdf73 +Author: Gerald Van Baren +Date: Sat Mar 31 14:30:53 2007 -0400 + + Fix some minor whitespace violations. + +commit 213bf8c822de8eecaf69860684469cdaba2e9e6a +Author: Gerald Van Baren +Date: Sat Mar 31 12:23:51 2007 -0400 + + Add a flattened device tree (fdt) command (2 of 2) + + Modifications to the existing code to support the new fdt command. + +commit 781e09ee6e3e3e392ab362c1f0ef1068adc76e3e +Author: Gerald Van Baren +Date: Sat Mar 31 12:22:10 2007 -0400 + + Add a flattened device tree (fdt) command (1 of 2) + + The fdt command uses David Gibson's libfdt library to manipulate as well + as print the flattened device tree. This patch is the new command, + the second part is the modifications to the existing code. + +commit 3af0d587d93e0be5f96e1b30fa41e662f8b0803e +Author: Gerald Van Baren +Date: Sat Mar 31 12:13:43 2007 -0400 + + libfdt: Enhanced and published fdt_next_tag() + + Enhanced the formerly private function _fdt_next_tag() to allow stepping + through the tree, used to produce a human-readable dump, and made + it part of the published interface. + Also added some comments. + +commit fa3a74cec73dfd06a5ae35a9a3368200273aaa71 +Author: Gerald Van Baren +Date: Sat Mar 31 12:05:39 2007 -0400 + + libfdt: Customizations for use by u-boot. + + Changes to David Gibson's original source to fit into u-boot's + environment. No functionality changes. + +commit 35748177c64a4a83a00057e93bb33e40278a2a96 +Author: Gerald Van Baren +Date: Sat Mar 31 12:00:56 2007 -0400 + + libfdt: Import libfdt source (2 of 2) + + This adds the applicable libfdt source files (unmodified) and a README + to explain where the source came from. + +commit 7cd5da0fe877e7171a4cdd44880bce783132871a +Author: Gerald Van Baren +Date: Sat Mar 31 11:59:59 2007 -0400 + + libfdt: Import libfdt source (1 of 2) + + This adds the applicable libfdt source files (unmodified) and a README + to explain where the source came from. + +commit 6eb1df835191d8ce4b81d5af40fa8e0fbe78e997 +Author: Jon Loeliger +Date: Tue Dec 12 11:02:20 2006 -0600 + + Fix 8641HPCN problem with ld version 2.16 + + (Dot outside sections problem). + + This fix is in the spirit of 807d5d7319330e336ab34a5623c5e0d73b87d540. + + Signed-off-by: Jon Loeliger + +commit 9964a4dd0d4ef5a037febaebf1aa494b1a72991c +Author: Haiying Wang +Date: Thu Dec 7 10:35:55 2006 -0600 + + Set Rev 2.x 86xx PIC in mixed mode. + + Prevent false interrupt from hanging Linux as MSR[EE] is set + to enable interrupts by changing the PIC out of the default + pass through mode into mixed mode. + + Signed-off-by: Haiying Wang + Signed-off-by: Jon Loeliger + +commit 5a58a73ceb0a4059c42ef64cedbc1a45e0aaa00e +Author: Jason Jin +Date: Thu Dec 7 10:32:35 2006 -0600 + + Add flash cmd function to 8641HPCN ramboot + + Also fixes some commmand for 8641 HPCN ramboot case. + + Signed-off-by: Jason Jin + Signed-off-by: Jon Loeliger + +commit 2ccceacc04b009d923afb7c26189ba2f8a2a5d46 +Author: Ed Swarthout +Date: Thu Dec 7 10:34:14 2006 -0600 + + Add support for 8641 Rev 2 silicon. + + Without this patch, I am unable to get to the prompt on rev 2 silicon. + Only set ddrioovcr for rev1. + + Signed-off-by: Ed Swarthout + Signed-off-by: Jon Loeliger + +commit 44ba464b99001f8bd1c456a1e9d59726252f707a +Author: Wolfgang Denk +Date: Thu Mar 22 00:13:12 2007 +0100 + + Code cleanup / re-insert previous Copyright entries. + + Signed-off-by: Wolfgang Denk + commit 2a8dfe08359a1b663418b2faa1da1d7bce34d302 Author: Wolfgang Denk Date: Wed Mar 21 23:26:15 2007 +0100 diff --git a/board/mpc8360emds/config.mk b/board/mpc8360emds/config.mk index d2a9435828..5801a5f178 100644 --- a/board/mpc8360emds/config.mk +++ b/board/mpc8360emds/config.mk @@ -31,4 +31,3 @@ TEXT_BASE = 0xFE000000 # Additional board-specific libraries # BOARDLIBS = libfdt/libfdt.a - diff --git a/include/fdt.h b/include/fdt.h index e00559ad6d..48ccfd9100 100644 --- a/include/fdt.h +++ b/include/fdt.h @@ -4,22 +4,22 @@ #ifndef __ASSEMBLY__ struct fdt_header { - uint32_t magic; /* magic word FDT_MAGIC */ - uint32_t totalsize; /* total size of DT block */ - uint32_t off_dt_struct; /* offset to structure */ - uint32_t off_dt_strings; /* offset to strings */ - uint32_t off_mem_rsvmap; /* offset to memory reserve map */ - uint32_t version; /* format version */ - uint32_t last_comp_version; /* last compatible version */ + uint32_t magic; /* magic word FDT_MAGIC */ + uint32_t totalsize; /* total size of DT block */ + uint32_t off_dt_struct; /* offset to structure */ + uint32_t off_dt_strings; /* offset to strings */ + uint32_t off_mem_rsvmap; /* offset to memory reserve map */ + uint32_t version; /* format version */ + uint32_t last_comp_version; /* last compatible version */ - /* version 2 fields below */ - uint32_t boot_cpuid_phys; /* Which physical CPU id we're + /* version 2 fields below */ + uint32_t boot_cpuid_phys; /* Which physical CPU id we're booting on */ /* version 3 fields below */ - uint32_t size_dt_strings; /* size of the strings block */ + uint32_t size_dt_strings; /* size of the strings block */ /* version 17 fields below */ - uint32_t size_dt_struct; /* size of the structure block */ + uint32_t size_dt_struct; /* size of the structure block */ }; struct fdt_reserve_entry { @@ -41,12 +41,12 @@ struct fdt_property { #endif /* !__ASSEMBLY */ -#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ +#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ #define FDT_TAGSIZE sizeof(uint32_t) -#define FDT_BEGIN_NODE 0x1 /* Start node: full name */ -#define FDT_END_NODE 0x2 /* End node */ -#define FDT_PROP 0x3 /* Property: name off, +#define FDT_BEGIN_NODE 0x1 /* Start node: full name */ +#define FDT_END_NODE 0x2 /* End node */ +#define FDT_PROP 0x3 /* Property: name off, size, content */ #define FDT_NOP 0x4 /* nop */ #define FDT_END 0x9 diff --git a/include/libfdt.h b/include/libfdt.h index c4b3c249bf..a0b4d55034 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -46,15 +46,15 @@ #define fdt_get_header(fdt, field) \ (fdt32_to_cpu(((struct fdt_header *)(fdt))->field)) -#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) +#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) #define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) #define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) #define fdt_version(fdt) (fdt_get_header(fdt, version)) -#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) -#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) -#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) +#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) +#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) +#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) #define fdt_set_header(fdt, field, val) \ @@ -82,7 +82,7 @@ void *fdt_getprop(const void *fdt, int nodeoffset, const char *name, int *lenp); uint32_t fdt_next_tag(const void *fdt, int offset, - int *nextoffset, char **namep); + int *nextoffset, char **namep); /* Write-in-place functions */ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, diff --git a/libfdt/Makefile b/libfdt/Makefile index 418ad6b5ab..dc411370f5 100644 --- a/libfdt/Makefile +++ b/libfdt/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)libfdt.a -SOBJS = +SOBJS = COBJS = fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o @@ -44,4 +44,3 @@ include $(SRCTREE)/rules.mk sinclude $(obj).depend ######################################################################### - diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 4b20553da0..ce01dc700b 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -23,12 +23,11 @@ #include "libfdt_internal.h" -#define CHECK_HEADER(fdt) \ - { \ - int err; \ - if ((err = _fdt_check_header(fdt)) != 0) \ - return err; \ - } +#define CHECK_HEADER(fdt) { \ + int err; \ + if ((err = _fdt_check_header(fdt)) != 0) \ + return err; \ +} static int offset_streq(const void *fdt, int offset, const char *s, int len) @@ -255,7 +254,7 @@ struct fdt_property *fdt_get_property(const void *fdt, } while (level >= 0); err = -FDT_ERR_NOTFOUND; - fail: +fail: if (lenp) *lenp = err; return NULL; @@ -330,4 +329,3 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset, char **namep return tag; } - From 31c98a88228021b314c89ebb8104fb6473da4471 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 4 Apr 2007 02:09:30 +0200 Subject: [PATCH 15/17] Minor coding style cleanup. --- CHANGELOG | 64 +++++++++++++++++++++++ Makefile | 1 - board/xilinx/xilinx_enet/emac_adapter.c | 2 +- cpu/microblaze/start.S | 2 +- include/asm-microblaze/microblaze_intc.h | 1 - include/asm-microblaze/microblaze_timer.h | 1 - include/configs/ml401.h | 2 +- include/configs/xupv2p.h | 2 +- 8 files changed, 68 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0bff39eecc..7425ceb2a8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +commit 94abd7c0583ebe01e799b25f451201deeaab550d +Author: Wolfgang Denk +Date: Wed Apr 4 01:49:15 2007 +0200 + + Minor cleanup. + commit aea03c4e8c3a21ce43d3faf48a6e6d474c8bdf73 Author: Gerald Van Baren Date: Sat Mar 31 14:30:53 2007 -0400 @@ -60,6 +66,32 @@ Date: Sat Mar 31 11:59:59 2007 -0400 This adds the applicable libfdt source files (unmodified) and a README to explain where the source came from. +commit 342cd097be1e7affe82f42ab3da220959a699e64 +Author: Michal Simek +Date: Fri Mar 30 22:52:09 2007 +0200 + + [PATCH] Clean include dependence + +commit 6f934210fb293fde2cfb4251c6d96fdc58b6a906 +Author: Michal Simek +Date: Fri Mar 30 22:42:45 2007 +0200 + + [CLEAN] Remove inefficient Suzaku code + +commit 5da048adf44bea5e3b94080d02903c2e3fe7aa4a +Author: Michal Simek +Date: Tue Mar 27 00:32:16 2007 +0200 + + PATCH: Resolve GPL license problem + +commit 1798049522f594013aea29457d46794298c6ae15 +Author: Michal Simek +Date: Mon Mar 26 01:39:07 2007 +0200 + + Support for XUPV2P board + Reset support + BSP autoconfig support + commit 6eb1df835191d8ce4b81d5af40fa8e0fbe78e997 Author: Jon Loeliger Date: Tue Dec 12 11:02:20 2006 -0600 @@ -266,6 +298,38 @@ Date: Mon Mar 12 00:25:14 2007 +0800 [Blackfin][PATCH] code cleanup +commit cfc67116a706fd18b8f6a9c11a16753c5626d689 +Author: Michal Simek +Date: Sun Mar 11 13:48:24 2007 +0100 + + [Microblaze][PATCH] part 2 + timer support + interrupt controller support + flash support + ethernet support + cache support + board information support + env support + booting image support + + adding support for Xilinx ML401 + +commit 76316a318de91f6184e7c22a10e02d275ade2441 +Author: Michal Simek +Date: Sun Mar 11 13:42:58 2007 +0100 + + [Microblaze][PATCH] + timer support + interrupt controller support + flash support + ethernet support + cache support + board information support + env support + booting image support + + adding support for Xilinx ML401 + commit 8db13d63157811c839d15a313d9f2d2f5fd10af3 Author: Aubrey Li Date: Sat Mar 10 23:49:29 2007 +0800 diff --git a/Makefile b/Makefile index 92350500f4..29b6210ff7 100644 --- a/Makefile +++ b/Makefile @@ -2450,4 +2450,3 @@ backup: gtar --force-local -zcvf `date "+$$F-%Y-%m-%d-%T.tar.gz"` $$F ######################################################################### - diff --git a/board/xilinx/xilinx_enet/emac_adapter.c b/board/xilinx/xilinx_enet/emac_adapter.c index 5a7e59e634..d3403038e6 100644 --- a/board/xilinx/xilinx_enet/emac_adapter.c +++ b/board/xilinx/xilinx_enet/emac_adapter.c @@ -147,7 +147,7 @@ eth_rx(void) RecvFrameLength = PKTSIZE; Result = XEmac_PollRecv(&Emac, (u8 *) etherrxbuff, &RecvFrameLength); if (Result == XST_SUCCESS) { -#ifndef CONFIG_EMACLITE +#ifndef CONFIG_EMACLITE NetReceive((uchar *)etherrxbuff, RecvFrameLength); #else NetReceive(etherrxbuff, RecvFrameLength); diff --git a/cpu/microblaze/start.S b/cpu/microblaze/start.S index 29481af9ae..ca3befc24e 100644 --- a/cpu/microblaze/start.S +++ b/cpu/microblaze/start.S @@ -54,7 +54,7 @@ _start: lhu r7, r1, r0 shi r7, r0, 0x2 shi r6, r0, 0x6 -/* +/* * Copy U-Boot code to TEXT_BASE * solve problem with sbrk_base */ diff --git a/include/asm-microblaze/microblaze_intc.h b/include/asm-microblaze/microblaze_intc.h index 73f732c566..6635aeacba 100644 --- a/include/asm-microblaze/microblaze_intc.h +++ b/include/asm-microblaze/microblaze_intc.h @@ -38,4 +38,3 @@ struct irq_action { void *arg; int count; /* number of interrupt */ }; - diff --git a/include/asm-microblaze/microblaze_timer.h b/include/asm-microblaze/microblaze_timer.h index b3d194bd47..844c8db115 100644 --- a/include/asm-microblaze/microblaze_timer.h +++ b/include/asm-microblaze/microblaze_timer.h @@ -39,4 +39,3 @@ typedef volatile struct microblaze_timer_t { int loadreg; /* load register TLR */ int counter; /* timer/counter register */ } microblaze_timer_t; - diff --git a/include/configs/ml401.h b/include/configs/ml401.h index f4a8a1f228..cb159e79dc 100644 --- a/include/configs/ml401.h +++ b/include/configs/ml401.h @@ -66,7 +66,7 @@ * * CFG_GBL_DATA_OFFSET = 0x1000_0000 + 0x0400_0000 - 0x1000 = 0x13FF_F000 * CFG_MONITOR_BASE = 0x13FF_F000 - 0x40000 = 0x13FB_F000 - * CFG_MALLOC_BASE = 0x13FB_F000 - 0x40000 = 0x13F7_F000 + * CFG_MALLOC_BASE = 0x13FB_F000 - 0x40000 = 0x13F7_F000 * * 0x1000_0000 CFG_SDRAM_BASE * FREE diff --git a/include/configs/xupv2p.h b/include/configs/xupv2p.h index 224db5c8be..a2f48102f0 100644 --- a/include/configs/xupv2p.h +++ b/include/configs/xupv2p.h @@ -41,7 +41,7 @@ /* * setting reset address - * + * * TEXT_BASE is set to place, where the U-BOOT run in RAM, but * if you want to store U-BOOT in flash, set CFG_RESET_ADDRESS * to FLASH memory and after loading bitstream jump to FLASH. From 51056dd9863e6a1bc363afbbe1775c58cd967418 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 11 Apr 2007 17:22:55 +0200 Subject: [PATCH 16/17] Update for SC3 board * Make IDE timeout configurable through ide_reset_timeout variable. * Use Newline as "password" string * Use just a single partition in NAND flash --- common/cmd_ide.c | 13 +++++++------ include/configs/sc3.h | 10 +++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 2e185cc441..b4119f3072 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -513,9 +513,11 @@ void ide_init (void) #endif unsigned char c; int i, bus; +#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3) + unsigned int ata_reset_time; +#endif #ifdef CONFIG_AMIGAONEG3SE unsigned int max_bus_scan; - unsigned int ata_reset_time; char *s; #endif #ifdef CONFIG_IDE_8xx_PCCARD @@ -617,10 +619,9 @@ void ide_init (void) udelay (100000); /* 100 ms */ ide_outb (dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev)); udelay (100000); /* 100 ms */ -#ifdef CONFIG_AMIGAONEG3SE - ata_reset_time = ATA_RESET_TIME; - s = getenv("ide_reset_timeout"); - if (s) ata_reset_time = 2*simple_strtol(s, NULL, 10); +#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3) + if ((s = getenv("ide_reset_timeout")) != NULL) + ata_reset_time = simple_strtol(s, NULL, 10); #endif i = 0; do { @@ -628,7 +629,7 @@ void ide_init (void) c = ide_inb (dev, ATA_STATUS); i++; -#ifdef CONFIG_AMIGAONEG3SE +#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3) if (i > (ata_reset_time * 100)) { #else if (i > (ATA_RESET_TIME * 100)) { diff --git a/include/configs/sc3.h b/include/configs/sc3.h index 8298084f1e..6b6acfa875 100644 --- a/include/configs/sc3.h +++ b/include/configs/sc3.h @@ -133,8 +133,8 @@ #if 1 /* feel free to disable for development */ #define CONFIG_AUTOBOOT_KEYED /* Enable password protection */ -#define CONFIG_AUTOBOOT_PROMPT "\nSC3 - booting... stop with S\n" -#define CONFIG_AUTOBOOT_DELAY_STR "S" /* 1st "password" */ +#define CONFIG_AUTOBOOT_PROMPT "\nSC3 - booting... stop with ENTER\n" +#define CONFIG_AUTOBOOT_DELAY_STR "\n" /* 1st "password" */ #endif /* @@ -416,11 +416,11 @@ extern unsigned long offsetOfEnvironment; #define CONFIG_JFFS2_NAND 1 /* jffs2 on nand support */ -/* No command line, one static partition Partition 3 contains jffs2 rootfs */ +/* No command line, one static partition */ #undef CONFIG_JFFS2_CMDLINE #define CONFIG_JFFS2_DEV "nand0" -#define CONFIG_JFFS2_PART_SIZE 0x00400000 -#define CONFIG_JFFS2_PART_OFFSET 0x00c00000 +#define CONFIG_JFFS2_PART_SIZE 0x01000000 +#define CONFIG_JFFS2_PART_OFFSET 0x00000000 /*----------------------------------------------------------------------- * Cache Configuration From 6c9ba919375db977aaad9146bf320c7afd07ae7a Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 11 Apr 2007 17:25:01 +0200 Subject: [PATCH 17/17] Update CHANGELOG Signed-off-by: Wolfgang Denk --- CHANGELOG | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 7425ceb2a8..326732d4ed 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,19 @@ +commit 51056dd9863e6a1bc363afbbe1775c58cd967418 +Author: Wolfgang Denk +Date: Wed Apr 11 17:22:55 2007 +0200 + + Update for SC3 board + + * Make IDE timeout configurable through ide_reset_timeout variable. + * Use Newline as "password" string + * Use just a single partition in NAND flash + +commit 31c98a88228021b314c89ebb8104fb6473da4471 +Author: Wolfgang Denk +Date: Wed Apr 4 02:09:30 2007 +0200 + + Minor coding style cleanup. + commit 94abd7c0583ebe01e799b25f451201deeaab550d Author: Wolfgang Denk Date: Wed Apr 4 01:49:15 2007 +0200 @@ -66,6 +82,63 @@ Date: Sat Mar 31 11:59:59 2007 -0400 This adds the applicable libfdt source files (unmodified) and a README to explain where the source came from. +commit da6ebc1bc082cbe3b6bbde079cafe09f7ebbad4b +Author: Stefan Roese +Date: Sat Mar 31 13:16:23 2007 +0200 + + ppc4xx: Update Katmai bootstrap command + + Now the DDR2 frequency is also 2*PLB frequency when 166MHz PLB + is selected. + + Signed-off-by: Stefan Roese + +commit cabee756a6532986729477c3cc1ea16ef8517ad2 +Author: Stefan Roese +Date: Sat Mar 31 13:15:06 2007 +0200 + + ppc4xx: Update 44x_spd_ddr2 code (440SP/440SPe) + + Additional RAM information is now printed upon powerup, like + DDR2 frequency and CAS latency. + + Signed-off-by: Stefan Roese + +commit 60723803431ac75cad085690789e433d5ab9174e +Author: Stefan Roese +Date: Sat Mar 31 08:48:36 2007 +0200 + + ppc4xx: Change Yucca config file to support ECC + + With the updated 44x DDR2 driver the Yucca board now supports + ECC generation and checking. + + Signed-off-by: Stefan Roese + +commit 490e5730c674b20d708b783a2c5ffd7208f83873 +Author: Stefan Roese +Date: Sat Mar 31 08:47:34 2007 +0200 + + ppc4xx: Fix "bootstrap" command for Katmai board + + The board specific "bootstrap" command is now fixed and can + be used for the AMCC Katmai board to configure different + CPU/PLB/OPB frequencies. + + Signed-off-by: Stefan Roese + +commit 94f54703c3a776ec23e427ca2a16e0a79a5d50c1 +Author: Stefan Roese +Date: Sat Mar 31 08:46:08 2007 +0200 + + ppc4xx: Update 44x_spd_ddr2 code (440SP/440SPe) + + Fix a bug in the auto calibration routine. This driver now runs + more reliable with the tested modules. It's also tested with + 167MHz PLB frequency (667MHz DDR2 frequency) on the Katmai. + + Signed-off-by: Stefan Roese + commit 342cd097be1e7affe82f42ab3da220959a699e64 Author: Michal Simek Date: Fri Mar 30 22:52:09 2007 +0200 @@ -78,6 +151,26 @@ Date: Fri Mar 30 22:42:45 2007 +0200 [CLEAN] Remove inefficient Suzaku code +commit 430f1b0f9a670c2f13eaa52e66a10db96dd3647d +Author: Stefan Roese +Date: Wed Mar 28 15:03:16 2007 +0200 + + Merge some AMCC make targets to keep the top-level Makefile smaller + + Signed-off-by: Stefan Roese + +commit 0c75c9d84307a9f1cbe1ff0c4d8937ee3a96475e +Author: Stefan Roese +Date: Wed Mar 28 14:52:12 2007 +0200 + + i2c: Enable "old" i2c commands even when CONFIG_I2C_CMD_TREE is defined + + The "old" i2c commands (iprobe, imd...) are now compiled in again, + even when the i2c command tree is enabled via the CONFIG_I2C_CMD_TREE + config option. + + Signed-off-by: Stefan Roese + commit 5da048adf44bea5e3b94080d02903c2e3fe7aa4a Author: Michal Simek Date: Tue Mar 27 00:32:16 2007 +0200 @@ -92,6 +185,36 @@ Date: Mon Mar 26 01:39:07 2007 +0200 Reset support BSP autoconfig support +commit 0d974d5297349504a2ddfa09314be573b5df320a +Author: Stefan Roese +Date: Sat Mar 24 15:57:09 2007 +0100 + + [PATCH] Add 4xx GPIO functions + + This patch adds some 4xx GPIO functions. It also moves some of the + common code and defines into a common 4xx GPIO header file. + + Signed-off-by: Stefan Roese + +commit 2db633658bbf366ab0c8dad7a0727e1fb2ae6b11 +Author: Stefan Roese +Date: Sat Mar 24 15:55:58 2007 +0100 + + [PATCH] Small Sequoia cleanup + + Signed-off-by: Stefan Roese + +commit 3cb86f3e40d2a80356177434a99f75bc8baa9caf +Author: Stefan Roese +Date: Sat Mar 24 15:45:34 2007 +0100 + + [PATCH] Clean up 40EZ/Acadia support + + This patch cleans up all the open issue of the preliminary + Acadia support. + + Signed-off-by: Stefan Roese + commit 6eb1df835191d8ce4b81d5af40fa8e0fbe78e997 Author: Jon Loeliger Date: Tue Dec 12 11:02:20 2006 -0600