From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=53217 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Pnzyu-00046D-2m for qemu-devel@nongnu.org; Fri, 11 Feb 2011 15:52:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Pnzyp-0002Bw-4p for qemu-devel@nongnu.org; Fri, 11 Feb 2011 15:52:43 -0500 Received: from mail-vw0-f45.google.com ([209.85.212.45]:49488) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Pnzyo-0002Bq-UX for qemu-devel@nongnu.org; Fri, 11 Feb 2011 15:52:39 -0500 Received: by vws12 with SMTP id 12so1927022vws.4 for ; Fri, 11 Feb 2011 12:52:38 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <1297379530-23487-13-git-send-email-michael@walle.cc> References: <1297379530-23487-1-git-send-email-michael@walle.cc> <1297379530-23487-13-git-send-email-michael@walle.cc> From: Blue Swirl Date: Fri, 11 Feb 2011 22:52:17 +0200 Message-ID: Subject: Re: [Qemu-devel] [PATCH 12/17] lm32: support for creating device tree Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Michael Walle Cc: "Edgar E. Iglesias" , Richard Henderson , qemu-devel@nongnu.org, Alexander Graf On Fri, Feb 11, 2011 at 1:12 AM, Michael Walle wrote: > This patch adds helper functions to create a ROM, which contains a hardwa= re > description of a board. This is used in Theobromas LM32 Linux port. > > Signed-off-by: Michael Walle > --- > =C2=A0hw/lm32_hwsetup.h | =C2=A0172 +++++++++++++++++++++++++++++++++++++= ++++++++++++++++ > =C2=A01 files changed, 172 insertions(+), 0 deletions(-) > =C2=A0create mode 100644 hw/lm32_hwsetup.h > > diff --git a/hw/lm32_hwsetup.h b/hw/lm32_hwsetup.h > new file mode 100644 > index 0000000..c7d4e05 > --- /dev/null > +++ b/hw/lm32_hwsetup.h > @@ -0,0 +1,172 @@ > +/* > + * =C2=A0LatticeMico32 hwsetup helper functions. > + * > + * =C2=A0Copyright (c) 2010 Michael Walle > + * > + * 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 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. =C2=A0See the GN= U > + * 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, see . > + */ > + > +/* > + * These are helper functions for creating the hardware description blob= used > + * in the Theobroma's uClinux port. > + */ Please add #ifndef QEMU_HW_LM32_HWSETUP_H etc. > + > +#include "qemu-common.h" > +#include "loader.h" > + > +struct hwsetup { > + =C2=A0 =C2=A0void *data; > + =C2=A0 =C2=A0void *ptr; > +}; HWSetup, with typedef. > + > +enum hwsetup_tag { > + =C2=A0 =C2=A0HWSETUP_TAG_EOL =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 0, > + =C2=A0 =C2=A0HWSETUP_TAG_CPU =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 1, > + =C2=A0 =C2=A0HWSETUP_TAG_ASRAM =C2=A0 =C2=A0 =C2=A0 =3D 2, > + =C2=A0 =C2=A0HWSETUP_TAG_FLASH =C2=A0 =C2=A0 =C2=A0 =3D 3, > + =C2=A0 =C2=A0HWSETUP_TAG_SDRAM =C2=A0 =C2=A0 =C2=A0 =3D 4, > + =C2=A0 =C2=A0HWSETUP_TAG_OCM =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 5, > + =C2=A0 =C2=A0HWSETUP_TAG_DDR_SDRAM =C2=A0 =3D 6, > + =C2=A0 =C2=A0HWSETUP_TAG_DDR2_SDRAM =C2=A0=3D 7, > + =C2=A0 =C2=A0HWSETUP_TAG_TIMER =C2=A0 =C2=A0 =C2=A0 =3D 8, > + =C2=A0 =C2=A0HWSETUP_TAG_UART =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 9, > + =C2=A0 =C2=A0HWSETUP_TAG_GPIO =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 10, > + =C2=A0 =C2=A0HWSETUP_TAG_TRISPEEDMAC =3D 11, > + =C2=A0 =C2=A0HWSETUP_TAG_I2CM =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 12, > + =C2=A0 =C2=A0HWSETUP_TAG_LEDS =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 13, > + =C2=A0 =C2=A0HWSETUP_TAG_7SEG =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 14, > + =C2=A0 =C2=A0HWSETUP_TAG_SPI_S =C2=A0 =C2=A0 =C2=A0 =3D 15, > + =C2=A0 =C2=A0HWSETUP_TAG_SPI_M =C2=A0 =C2=A0 =C2=A0 =3D 16, > +}; > + > +static inline struct hwsetup *hwsetup_init(void) > +{ > + =C2=A0 =C2=A0struct hwsetup *hw; > + > + =C2=A0 =C2=A0hw =3D qemu_malloc(sizeof(struct hwsetup)); > + =C2=A0 =C2=A0hw->data =3D qemu_mallocz(TARGET_PAGE_SIZE); > + =C2=A0 =C2=A0hw->ptr =3D hw->data; > + > + =C2=A0 =C2=A0return hw; > +} > + > +static inline void hwsetup_free(struct hwsetup *hw) > +{ > + =C2=A0 =C2=A0qemu_free(hw->data); > + =C2=A0 =C2=A0qemu_free(hw); > +} > + > +static inline void hwsetup_create_rom(struct hwsetup *hw, ram_addr_t bas= e) > +{ > + =C2=A0 =C2=A0rom_add_blob("hwsetup", hw->data, TARGET_PAGE_SIZE, base); > +} > + > +static inline void hwsetup_add_u8(struct hwsetup *hw, uint8_t u) > +{ > + =C2=A0 =C2=A0stb_p(hw->ptr, u); > + =C2=A0 =C2=A0hw->ptr +=3D 1; > +} > + > +static inline void hwsetup_add_u32(struct hwsetup *hw, uint32_t u) > +{ > + =C2=A0 =C2=A0stl_p(hw->ptr, u); > + =C2=A0 =C2=A0hw->ptr +=3D 4; > +} > + > +static inline void hwsetup_add_tag(struct hwsetup *hw, enum hwsetup_tag = t) > +{ > + =C2=A0 =C2=A0stl_p(hw->ptr, t); > + =C2=A0 =C2=A0hw->ptr +=3D 4; > +} > + > +static inline void hwsetup_add_str(struct hwsetup *hw, const char *str) > +{ > + =C2=A0 =C2=A0strncpy(hw->ptr, str, 31); /* make sure last byte is zero = */ > + =C2=A0 =C2=A0hw->ptr +=3D 32; > +} > + > +static inline void hwsetup_add_trailer(struct hwsetup *hw) > +{ > + =C2=A0 =C2=A0hwsetup_add_u32(hw, 8); /* size */ > + =C2=A0 =C2=A0hwsetup_add_tag(hw, HWSETUP_TAG_EOL); > +} > + > +static inline void hwsetup_add_cpu(struct hwsetup *hw, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *name, uint32_t frequency) > +{ > + =C2=A0 =C2=A0hwsetup_add_u32(hw, 44); /* size */ > + =C2=A0 =C2=A0hwsetup_add_tag(hw, HWSETUP_TAG_CPU); > + =C2=A0 =C2=A0hwsetup_add_str(hw, name); > + =C2=A0 =C2=A0hwsetup_add_u32(hw, frequency); > +} > + > +static inline void hwsetup_add_flash(struct hwsetup *hw, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *name, uint32_t base, uint32_t si= ze) > +{ > + =C2=A0 =C2=A0hwsetup_add_u32(hw, 52); /* size */ > + =C2=A0 =C2=A0hwsetup_add_tag(hw, HWSETUP_TAG_FLASH); > + =C2=A0 =C2=A0hwsetup_add_str(hw, name); > + =C2=A0 =C2=A0hwsetup_add_u32(hw, base); > + =C2=A0 =C2=A0hwsetup_add_u32(hw, size); > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 8); /* read latency */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 8); /* write latency */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 25); /* address width */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 32); /* data width */ > +} > + > +static inline void hwsetup_add_ddr_sdram(struct hwsetup *hw, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *name, uint32_t base, uint32_t si= ze) > +{ > + =C2=A0 =C2=A0hwsetup_add_u32(hw, 48); /* size */ > + =C2=A0 =C2=A0hwsetup_add_tag(hw, HWSETUP_TAG_DDR_SDRAM); > + =C2=A0 =C2=A0hwsetup_add_str(hw, name); > + =C2=A0 =C2=A0hwsetup_add_u32(hw, base); > + =C2=A0 =C2=A0hwsetup_add_u32(hw, size); > +} > + > +static inline void hwsetup_add_timer(struct hwsetup *hw, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *name, uint32_t base, uint32_t ir= q) > +{ > + =C2=A0 =C2=A0hwsetup_add_u32(hw, 56); /* size */ > + =C2=A0 =C2=A0hwsetup_add_tag(hw, HWSETUP_TAG_TIMER); > + =C2=A0 =C2=A0hwsetup_add_str(hw, name); > + =C2=A0 =C2=A0hwsetup_add_u32(hw, base); > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 1); /* wr_tickcount */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 1); /* rd_tickcount */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 1); /* start_stop_control */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 32); /* counter_width */ > + =C2=A0 =C2=A0hwsetup_add_u32(hw, 20); /* reload_ticks */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, irq); > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 0); /* padding */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 0); /* padding */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 0); /* padding */ > +} > + > +static inline void hwsetup_add_uart(struct hwsetup *hw, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *name, uint32_t base, uint32_t ir= q) > +{ > + =C2=A0 =C2=A0hwsetup_add_u32(hw, 56); /* size */ > + =C2=A0 =C2=A0hwsetup_add_tag(hw, HWSETUP_TAG_UART); > + =C2=A0 =C2=A0hwsetup_add_str(hw, name); > + =C2=A0 =C2=A0hwsetup_add_u32(hw, base); > + =C2=A0 =C2=A0hwsetup_add_u32(hw, 115200); /* baudrate */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 8); /* databits */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 1); /* stopbits */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 1); /* use_interrupt */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 1); /* block_on_transmit */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 1); /* block_on_receive */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 4); /* rx_buffer_size */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, 4); /* tx_buffer_size */ > + =C2=A0 =C2=A0hwsetup_add_u8(hw, irq); > +} Overall, this seems to replicate fw_cfg functions, does it match real HW or is this just for QEMU?