From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NAKX8-0002dp-S9 for qemu-devel@nongnu.org; Tue, 17 Nov 2009 04:39:35 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NAKX4-0002bN-9P for qemu-devel@nongnu.org; Tue, 17 Nov 2009 04:39:34 -0500 Received: from [199.232.76.173] (port=54086 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NAKX3-0002b7-O5 for qemu-devel@nongnu.org; Tue, 17 Nov 2009 04:39:30 -0500 Received: from mail-bw0-f212.google.com ([209.85.218.212]:40130) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NAKX2-0007NO-N4 for qemu-devel@nongnu.org; Tue, 17 Nov 2009 04:39:29 -0500 Received: by bwz4 with SMTP id 4so7219213bwz.2 for ; Tue, 17 Nov 2009 01:39:27 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <20091115204930.GA25677@rain> References: <20091115204930.GA25677@rain> Date: Tue, 17 Nov 2009 10:39:27 +0100 Message-ID: <5b31733c0911170139p5cea3594xf15ddfc2cf057e9b@mail.gmail.com> Subject: Re: [Qemu-devel] [PATCH 2/2] [RFC] add emulation of at91sam9263 cpu From: Filip Navara Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Evgeniy Dushistov Cc: qemu-devel@nongnu.org I'd say it is preferable to split the individual devices and model them using the QDEV infrastructure instead of putting it all together into one "system controller" device. I've QDEV-based implementation of these devices already: PMC, DBGU, PIO, PITC, AIC. That leaves the "bus matrix", SDRAM controller and USART (which is very similar to DBGU) to be split up. Best regards, Filip Navara On Sun, Nov 15, 2009 at 9:49 PM, Evgeniy Dushistov wrot= e: > add emulation of at91sam9263 cpu, plus sdram, plus nor flash connected to= this cpu > > > Signed-off-by: Evgeniy Dushistov > --- > =A0Makefile.target =A0 =A0 =A0 | =A0 =A02 +- > =A0hw/at91sam9.c =A0 =A0 =A0 =A0 | =A0695 +++++++++++++++++++++++++++++++= ++++++++++++++++++ > =A0hw/at91sam9263_defs.h | =A0144 ++++++++++ > =A03 files changed, 840 insertions(+), 1 deletions(-) > =A0create mode 100644 hw/at91sam9.c > =A0create mode 100644 hw/at91sam9263_defs.h > > diff --git a/Makefile.target b/Makefile.target > index 7542199..67f441d 100644 > --- a/Makefile.target > +++ b/Makefile.target > @@ -268,7 +268,7 @@ obj-sparc-y +=3D cs4231.o eccmemctl.o sbi.o sun4c_int= ctl.o > =A0endif > > =A0obj-arm-y =3D integratorcp.o versatilepb.o smc91c111.o arm_pic.o arm_t= imer.o > -obj-arm-y +=3D pflash_atmel.o > +obj-arm-y +=3D pflash_atmel.o at91sam9.o > =A0obj-arm-y +=3D arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl18= 1.o pl190.o > =A0obj-arm-y +=3D versatile_pci.o > =A0obj-arm-y +=3D realview_gic.o realview.o arm_sysctl.o mpcore.o > diff --git a/hw/at91sam9.c b/hw/at91sam9.c > new file mode 100644 > index 0000000..7ac60d9 > --- /dev/null > +++ b/hw/at91sam9.c > @@ -0,0 +1,695 @@ > +/* > + * Atmel at91sam9263 cpu + NOR flash + SDRAM emulation > + * Written by Evgeniy Dushistov > + * This code is licenced under the GPL. > + */ > + > +#include > +#include > + > +#include "hw.h" > +#include "arm-misc.h" > +#include "primecell.h" > +#include "devices.h" > +#include "net.h" > +#include "sysemu.h" > +#include "flash.h" > +#include "boards.h" > +#include "qemu-char.h" > +#include "qemu-timer.h" > + > +#include "at91sam9263_defs.h" > + > +//#define AT91_TRACE_ON > +//#define AT91_DEBUG_ON > + > +#define ARM_AIC_CPU_IRQ 0 > +#define ARM_AIC_CPU_FIQ 1 > + > +#define NOR_FLASH_SIZE (1024 * 1024 * 8) > +#define AT91SAM9263EK_SDRAM_SIZE (1024 * 1024 * 64) > +#define AT91SAM9263EK_SDRAM_OFF 0x20000000 > +#define AT91SAM9263EK_NORFLASH_OFF 0x10000000 > + > +#ifdef AT91_DEBUG_ON > +# =A0 =A0 =A0 define DEBUG(f, a...) =A0 =A0{ =A0 =A0 =A0 =A0 =A0 =A0 =A0= \ > + =A0 =A0 =A0 =A0printf ("at91 (%s, %d): %s:", =A0 =A0 =A0 =A0 =A0 \ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0__FILE__, __LINE__, __func__); =A0\ > + =A0 =A0 =A0 =A0printf (f, ## a); =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 \ > + =A0 =A0} > +#else > +# =A0 =A0 =A0 define DEBUG(f, a...) do { } while (0) > +#endif > + > +#ifdef AT91_TRACE_ON > +static FILE *trace_file; > +# =A0 =A0 =A0 define TRACE(f, a...) =A0 =A0do { =A0 =A0 =A0 =A0 =A0 \ > + =A0 =A0 =A0 =A0fprintf (trace_file, f, ## a); =A0 =A0 =A0 =A0 =A0\ > + =A0 =A0} while (0) > +#else > +# =A0 =A0 =A0 define TRACE(f, a...) do { } while (0) > +#endif > + > + > +struct dbgu_state { > + =A0 =A0CharDriverState *chr; > +}; > + > +struct at91sam9_state { > + =A0 =A0uint32_t pmc_regs[28]; > + =A0 =A0uint32_t dbgu_regs[0x124 / 4]; > + =A0 =A0uint32_t bus_matrix_regs[0x100 / 4]; > + =A0 =A0uint32_t ccfg_regs[(0x01FC - 0x0110 + 1) / sizeof(uint32_t)]; > + =A0 =A0uint32_t pio_regs[(AT91_PMC_BASE - AT91_PIO_BASE) / sizeof(uint3= 2_t)]; > + =A0 =A0uint32_t sdramc0_regs[(AT91_SMC0_BASE - AT91_SDRAMC0_BASE) / siz= eof(uint32_t)]; > + =A0 =A0uint32_t smc0_regs[(AT91_ECC1_BASE - AT91_SMC0_BASE) / sizeof(ui= nt32_t)]; > + =A0 =A0uint32_t pitc_regs[80]; > + =A0 =A0uint32_t aic_regs[(AT91_PIO_BASE - AT91_AIC_BASE) / sizeof(uint3= 2_t)]; > + =A0 =A0uint32_t usart0_regs[0x1000 / sizeof(uint32_t)]; > + =A0 =A0struct dbgu_state dbgu; > + =A0 =A0pflash_t *norflash; > + =A0 =A0ram_addr_t internal_sram; > + =A0 =A0QEMUTimer *dbgu_tr_timer; > + =A0 =A0ptimer_state *pitc_timer; > + =A0 =A0int timer_active; > + =A0 =A0CPUState *env; > + =A0 =A0qemu_irq *qirq; > + =A0 =A0uint64_t char_transmit_time; > +}; > + > +static uint32_t at91_pmc_read(void *opaque, target_phys_addr_t offset) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + =A0 =A0TRACE("pmc read offset %X\n", offset); > + =A0 =A0return sam9->pmc_regs[offset / 4]; > +} > + > +static void at91_pmc_write(void *opaque, target_phys_addr_t offset, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 uint32_t value) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0TRACE("pmc write offset %X, value %X\n", offset, value); > + =A0 =A0switch (offset / 4) { > + =A0 =A0case AT91_PMC_MCKR: > + =A0 =A0 =A0 =A0sam9->pmc_regs[AT91_PMC_MCKR] =3D value; > + =A0 =A0 =A0 =A0switch (value & AT91_PMC_CSS) { > + =A0 =A0 =A0 =A0case 1: > + =A0 =A0 =A0 =A0 =A0 =A0//Main clock is selected > + =A0 =A0 =A0 =A0 =A0 =A0sam9->pmc_regs[AT91_PMC_SR] |=3D AT91_PMC_MCKRDY= | AT91_PMC_MOSCS; > + =A0 =A0 =A0 =A0 =A0 =A0break; > + =A0 =A0 =A0 =A0default: > + =A0 =A0 =A0 =A0 =A0 =A0DEBUG("unimplemented\n"); > + =A0 =A0 =A0 =A0 =A0 =A0break; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0break; > + =A0 =A0case AT91_PMC_MOR: > + =A0 =A0 =A0 =A0sam9->pmc_regs[AT91_PMC_MOR] =3D value; > + =A0 =A0 =A0 =A0if (value & 1) { > + =A0 =A0 =A0 =A0 =A0 =A0sam9->pmc_regs[AT91_PMC_SR] |=3D AT91_PMC_MOSCS; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0break; > + =A0 =A0case AT91_PMC_PLLAR: > + =A0 =A0 =A0 =A0sam9->pmc_regs[AT91_PMC_PLLAR] =3D value; > + =A0 =A0 =A0 =A0sam9->pmc_regs[AT91_PMC_SR] |=3D AT91_PMC_LOCKA; > + =A0 =A0 =A0 =A0break; > + =A0 =A0case AT91_PMC_PLLBR: > + =A0 =A0 =A0 =A0sam9->pmc_regs[AT91_PMC_PLLBR] =3D value; > + =A0 =A0 =A0 =A0sam9->pmc_regs[AT91_PMC_SR] |=3D AT91_PMC_LOCKB; > + =A0 =A0 =A0 =A0break; > + =A0 =A0case AT91_PMC_PCER: > + =A0 =A0 =A0 =A0sam9->pmc_regs[AT91_PMC_PCER] |=3D value; > + =A0 =A0 =A0 =A0break; > + =A0 =A0default: > + =A0 =A0 =A0 =A0//DEBUG("unimplemented, offset %X\n", offset); > + =A0 =A0 =A0 =A0break; > + =A0 =A0} > +} > + > +static uint32_t at91_dbgu_read(void *opaque, target_phys_addr_t offset) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0offset /=3D 4; > + =A0 =A0if (offset =3D=3D AT91_DBGU_RHR) { > + =A0 =A0 =A0 =A0sam9->dbgu_regs[AT91_DBGU_SR] &=3D (uint32_t)~1; > + =A0 =A0}/* else if (offset =3D=3D AT91_DBGU_SR)*/ > + > + =A0 =A0return sam9->dbgu_regs[offset]; > +} > + > +static void at91_dbgu_state_changed(struct at91sam9_state *sam9) > +{ > + =A0 =A0if ((sam9->aic_regs[AT91_AIC_IECR] & (1 << AT91_PERIPH_SYS_ID)) = && > + =A0 =A0 =A0 =A0(sam9->dbgu_regs[AT91_DBGU_IMR] & sam9->dbgu_regs[AT91_D= BGU_SR])) { > + =A0 =A0 =A0 =A0sam9->aic_regs[AT91_AIC_ISR] =3D AT91_PERIPH_SYS_ID; > + =A0 =A0 =A0 =A0sam9->aic_regs[AT91_AIC_IVR] =3D sam9->aic_regs[AT91_AIC= _SVR0 + AT91_PERIPH_SYS_ID]; > + =A0 =A0 =A0 =A0qemu_irq_raise(sam9->qirq[0]); > + =A0 =A0} > +} > + > +static void dbgu_serial_end_xmit(void *opaque) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + =A0 =A0sam9->dbgu_regs[AT91_DBGU_SR] |=3D (AT91_US_TXEMPTY | AT91_US_TX= RDY); > + =A0 =A0at91_dbgu_state_changed(sam9); > +} > + > +static void at91_dbgu_write(void *opaque, target_phys_addr_t offset, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uint32_t value) > +{ > + =A0 =A0unsigned char ch; > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0switch (offset / 4) { > + =A0 =A0case AT91_DBGU_CR: > + =A0 =A0 =A0 =A0sam9->dbgu_regs[AT91_DBGU_CR] =3D value; > + =A0 =A0 =A0 =A0if (value & AT91_US_TXEN) > + =A0 =A0 =A0 =A0 =A0 =A0sam9->dbgu_regs[AT91_DBGU_SR] |=3D AT91_US_TXRDY= | AT91_US_TXEMPTY; > + =A0 =A0 =A0 =A0if (value & AT91_US_TXDIS) > + =A0 =A0 =A0 =A0 =A0 =A0sam9->dbgu_regs[AT91_DBGU_SR] &=3D ~(AT91_US_TXR= DY | AT91_US_TXEMPTY); > + =A0 =A0 =A0 =A0break; > + =A0 =A0case AT91_DBGU_IER: > + =A0 =A0 =A0 =A0sam9->dbgu_regs[AT91_DBGU_IMR] |=3D value; > + =A0 =A0 =A0 =A0at91_dbgu_state_changed(sam9); > + =A0 =A0 =A0 =A0break; > + =A0 =A0case AT91_DBGU_IDR: > + =A0 =A0 =A0 =A0sam9->dbgu_regs[AT91_DBGU_IMR] &=3D ~value; > + =A0 =A0 =A0 =A0break; > + =A0 =A0case AT91_DBGU_THR: > + =A0 =A0 =A0 =A0sam9->dbgu_regs[AT91_DBGU_THR] =3D value; > + =A0 =A0 =A0 =A0sam9->dbgu_regs[AT91_DBGU_SR] &=3D ~(AT91_US_TXEMPTY | A= T91_US_TXRDY); > + =A0 =A0 =A0 =A0ch =3D value; > + =A0 =A0 =A0 =A0if (sam9->dbgu.chr) > + =A0 =A0 =A0 =A0 =A0 =A0qemu_chr_write(sam9->dbgu.chr, &ch, 1); > + =A0 =A0 =A0 =A0qemu_mod_timer(sam9->dbgu_tr_timer , qemu_get_clock(vm_c= lock) + sam9->char_transmit_time); > + =A0 =A0 =A0 =A0break; > + =A0 =A0default: > + =A0 =A0 =A0 =A0//DEBUG("unimplemented\n"); > + =A0 =A0 =A0 =A0break; > + =A0 =A0} > +} > + > +static int at91_dbgu_can_receive(void *opaque) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0return (sam9->dbgu_regs[AT91_DBGU_SR] & AT91_US_RXRDY) =3D=3D 0; > +} > + > +static void at91_dbgu_receive(void *opaque, const uint8_t *buf, int size= ) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + =A0 =A0int i; > + =A0 =A0/*! \todo if not one character we need wait before irq handled, > + =A0 =A0 =A0but from other hand at91_dbgu_can_receive should prevent thi= s > + =A0 =A0 */ > + =A0 =A0for (i =3D 0; i < size; ++i) { > + =A0 =A0 =A0 =A0sam9->dbgu_regs[AT91_DBGU_RHR] =3D buf[i]; > + =A0 =A0 =A0 =A0sam9->dbgu_regs[AT91_DBGU_SR] |=3D AT91_US_RXRDY; > + =A0 =A0 =A0 =A0at91_dbgu_state_changed(sam9); > + =A0 =A0} > +} > + > +static void at91_dbgu_event(void *opaque, int event) > +{ > + =A0 =A0DEBUG("begin\n"); > +} > + > +static uint32_t at91_bus_matrix_read(void *opaque, target_phys_addr_t of= fset) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0TRACE("bus_matrix read offset %X\n", offset); > + =A0 =A0return sam9->bus_matrix_regs[offset / 4]; > +} > + > +static void at91_bus_matrix_write(void *opaque, target_phys_addr_t offse= t, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uint= 32_t value) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0TRACE("bus_matrix write offset %X, value %X\n", offset, value); > + =A0 =A0switch (offset) { > + =A0 =A0case MATRIX_MRCR: > + =A0 =A0 =A0 =A0DEBUG("write to MATRIX mrcr reg\n"); > + =A0 =A0 =A0 =A0if (value & (AT91C_MATRIX_RCA926I | AT91C_MATRIX_RCA926D= )) { > + =A0 =A0 =A0 =A0 =A0 =A0cpu_register_physical_memory(0x0, 80 * 1024, sam= 9->internal_sram | IO_MEM_RAM); > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0break; > + =A0 =A0default: > + =A0 =A0 =A0 =A0DEBUG("unimplemented\n"); > + =A0 =A0 =A0 =A0break; > + =A0 =A0} > +} > + > +static void at91_init_pmc(struct at91sam9_state *sam9) > +{ > + =A0 =A0DEBUG("begin\n"); > + =A0 =A0sam9->pmc_regs[AT91_PMC_MCKR] =3D 0; > + =A0 =A0sam9->pmc_regs[AT91_PMC_MOR] =3D 0; > + =A0 =A0sam9->pmc_regs[AT91_PMC_SR] =3D 0x08; > + =A0 =A0sam9->pmc_regs[AT91_PMC_PLLAR] =3D 0x3F00; > + =A0 =A0sam9->pmc_regs[AT91_PMC_PLLAR] =3D 0x3F00; > +} > + > +static void at91_init_bus_matrix(struct at91sam9_state *sam9) > +{ > + =A0 =A0DEBUG("begin\n"); > + =A0 =A0memset(&sam9->bus_matrix_regs, 0, sizeof(sam9->bus_matrix_regs))= ; > +} > + > +static void at91_init_dbgu(struct at91sam9_state *sam9, CharDriverState = *chr) > +{ > + =A0 =A0DEBUG("begin\n"); > + > + =A0 =A0memset(&sam9->dbgu_regs, 0, sizeof(sam9->dbgu_regs)); > + =A0 =A0sam9->dbgu_regs[AT91_DBGU_SR] =3D AT91_US_TXEMPTY | AT91_US_TXRD= Y; > + > + =A0 =A0sam9->dbgu.chr =3D chr; > + =A0 =A0sam9->dbgu_tr_timer =3D qemu_new_timer(vm_clock, (QEMUTimerCB *)= dbgu_serial_end_xmit, sam9); > + =A0 =A0sam9->char_transmit_time =3D (get_ticks_per_sec() / 115200) * 10= ; > + =A0 =A0if (chr) > + =A0 =A0 =A0 =A0qemu_chr_add_handlers(chr, at91_dbgu_can_receive, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0at91_dbgu_re= ceive, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0at91_dbgu_ev= ent, sam9); > +} > + > +static uint32_t at91_ccfg_read(void *opaque, target_phys_addr_t offset) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0TRACE("ccfg read offset %X\n", offset); > + =A0 =A0return sam9->ccfg_regs[offset / sizeof(sam9->ccfg_regs[0])]; > +} > + > +static void at91_ccfg_write(void *opaque, target_phys_addr_t offset, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uint32_t value) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0TRACE("ccfg write offset %X, value %X\n", offset, value); > + =A0 =A0sam9->ccfg_regs[offset / sizeof(sam9->ccfg_regs[0])] =3D value; > +} > + > +static uint32_t at91_pio_read(void *opaque, target_phys_addr_t offset) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0TRACE("pio read offset %X\n", offset); > + =A0 =A0return sam9->pio_regs[offset / sizeof(sam9->pio_regs[0])]; > +} > + > +static void at91_pio_write(void *opaque, target_phys_addr_t offset, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 uint32_t value) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0TRACE("pio write offset %X, value %X\n", offset, value); > + =A0 =A0sam9->pio_regs[offset / sizeof(sam9->pio_regs[0])] =3D value; > +} > + > +static uint32_t at91_sdramc0_read(void *opaque, target_phys_addr_t offse= t) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0TRACE("sdramc0 read offset %X\n", offset); > + =A0 =A0return sam9->sdramc0_regs[offset / sizeof(sam9->sdramc0_regs[0])= ]; > +} > + > +static void at91_sdramc0_write(void *opaque, target_phys_addr_t offset, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 uint32_t va= lue) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0TRACE("sdramc0 write offset %X, value %X\n", offset, value); > + =A0 =A0sam9->sdramc0_regs[offset / sizeof(sam9->sdramc0_regs[0])] =3D v= alue; > +} > + > +static uint32_t at91_smc0_read(void *opaque, target_phys_addr_t offset) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0TRACE("smc0 read offset %X\n", offset); > + =A0 =A0return sam9->smc0_regs[offset / sizeof(sam9->smc0_regs[0])]; > +} > + > +static void at91_smc0_write(void *opaque, target_phys_addr_t offset, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uint32_t value) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0TRACE("smc0 write offset %X, value %X\n", offset, value); > + =A0 =A0sam9->smc0_regs[offset / sizeof(sam9->smc0_regs[0])] =3D value; > +} > + > +static void at91_pitc_timer_tick(void * opaque) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + =A0 =A0uint64_t val =3D ptimer_get_count(sam9->pitc_timer); > + > + =A0 =A0unsigned int tick =3D (sam9->pitc_regs[AT91_PITC_PIIR] >> 20) + = 1; > + =A0 =A0sam9->pitc_regs[AT91_PITC_PIIR] =3D (val & ((1 << 21) - 1)) | (t= ick << 20); > + =A0 =A0sam9->pitc_regs[AT91_PITC_PIVR] =3D sam9->pitc_regs[AT91_PITC_PI= IR]; > + > + =A0 =A0if ((sam9->pitc_regs[AT91_PITC_MR] & AT91_PTIC_MR_PITIEN) && > + =A0 =A0 =A0 =A0(sam9->aic_regs[AT91_AIC_IECR] & (1 << AT91_PERIPH_SYS_I= D)) && > + =A0 =A0 =A0 =A0!sam9->pitc_regs[AT91_PITC_SR]) { > + =A0 =A0 =A0 =A0sam9->aic_regs[AT91_AIC_ISR] =3D AT91_PERIPH_SYS_ID; > + =A0 =A0 =A0 =A0sam9->aic_regs[AT91_AIC_IVR] =3D sam9->aic_regs[AT91_AIC= _SVR0 + AT91_PERIPH_SYS_ID]; > + > + =A0 =A0 =A0 =A0sam9->pitc_regs[AT91_PITC_SR] =3D 1; > + =A0 =A0 =A0 =A0qemu_irq_raise(sam9->qirq[0]); > + =A0 =A0} > +} > + > +static uint32_t at91_pitc_read(void *opaque, target_phys_addr_t offset) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + =A0 =A0int pitc_enable =3D !!(sam9->pitc_regs[AT91_PITC_MR] & AT91_PTIC= _MR_PITEN); > + =A0 =A0int idx; > + > + =A0 =A0idx =3D offset / sizeof(sam9->pitc_regs[0]); > + =A0 =A0switch (idx) { > + =A0 =A0case AT91_PITC_SR: > +// =A0 =A0 =A0 =A0DEBUG("read sr: %X\n", sam9->pitc_regs[idx]); > + =A0 =A0 =A0 =A0break; > + =A0 =A0case AT91_PITC_PIVR: > + =A0 =A0 =A0 =A0if (pitc_enable) { > +// =A0 =A0 =A0 =A0 =A0 =A0DEBUG("clear sr\n"); > + =A0 =A0 =A0 =A0 =A0 =A0sam9->pitc_regs[AT91_PITC_SR] =3D 0; > + =A0 =A0 =A0 =A0} else { > +// =A0 =A0 =A0 =A0 =A0 =A0DEBUG("pitc disabled\n"); > + =A0 =A0 =A0 =A0 =A0 =A0break; > + =A0 =A0 =A0 =A0} > + =A0 =A0case AT91_PITC_PIIR: > + =A0 =A0 =A0 =A0if (pitc_enable) { > + =A0 =A0 =A0 =A0 =A0 =A0uint64_t val =3D ptimer_get_count(sam9->pitc_tim= er); > + =A0 =A0 =A0 =A0 =A0 =A0unsigned int tick =3D (sam9->pitc_regs[AT91_PITC= _PIIR] >> 20); > + =A0 =A0 =A0 =A0 =A0 =A0uint32_t res =3D (tick << 20) | (val & ((1 << 21= ) - 1)); > + > + =A0 =A0 =A0 =A0 =A0 =A0if (idx =3D=3D AT91_PITC_PIVR) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0tick =3D 0; > + =A0 =A0 =A0 =A0 =A0 =A0sam9->pitc_regs[AT91_PITC_PIIR] =3D (tick << 20)= | (val & ((1 << 21) - 1)); > + =A0 =A0 =A0 =A0 =A0 =A0sam9->pitc_regs[AT91_PITC_PIVR] =3D sam9->pitc_r= egs[AT91_PITC_PIIR]; > + =A0 =A0 =A0 =A0 =A0 =A0TRACE("pitc read offset %X, value %X\n", offset,= res); > + =A0 =A0 =A0 =A0 =A0 =A0return res; > + =A0 =A0 =A0 =A0} else { > +// =A0 =A0 =A0 =A0 =A0 =A0DEBUG("pitc disabled\n"); > + =A0 =A0 =A0 =A0 =A0 =A0break; > + =A0 =A0 =A0 =A0} > + > + =A0 =A0default: > + =A0 =A0 =A0 =A0/*nothing*/break; > + =A0 =A0} > + =A0 =A0TRACE("pitc read offset %X, value %X\n", offset, sam9->pitc_regs= [idx]); > + > + =A0 =A0return sam9->pitc_regs[idx]; > +} > + > +static void at91_pitc_write(void *opaque, target_phys_addr_t offset, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uint32_t value) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + > + =A0 =A0TRACE("pitc write offset %X, value %X\n", offset, value); > + =A0 =A0int idx =3D offset / sizeof(sam9->pitc_regs[0]); > + =A0 =A0switch (idx) { > + =A0 =A0case AT91_PITC_MR: { > + =A0 =A0 =A0 =A0int pitc_enable =3D !!(value & AT91_PTIC_MR_PITEN); > + =A0 =A0 =A0 =A0unsigned int period =3D value & 0xFFFFF; > + > + =A0 =A0 =A0 =A0//DEBUG("set period %u, int enabled? %d\n", period, !!(v= alue & AT91_PTIC_MR_PITIEN)); > + > + =A0 =A0 =A0 =A0if (pitc_enable && period !=3D 0) { > + =A0 =A0 =A0 =A0 =A0 =A0sam9->timer_active =3D 1; > + =A0 =A0 =A0 =A0 =A0 =A0//! \todo get real value from PLL > + =A0 =A0 =A0 =A0 =A0 =A0ptimer_set_freq(sam9->pitc_timer, (100 * 1000 * = 1000) / 16); > + =A0 =A0 =A0 =A0 =A0 =A0ptimer_set_limit(sam9->pitc_timer, period, 1); > + =A0 =A0 =A0 =A0 =A0 =A0ptimer_run(sam9->pitc_timer, 0); > + =A0 =A0 =A0 =A0} else if (sam9->timer_active) { > + =A0 =A0 =A0 =A0 =A0 =A0TRACE("disable timer\n"); > + =A0 =A0 =A0 =A0 =A0 =A0sam9->pitc_regs[AT91_PITC_PIVR] =3D 0; > + =A0 =A0 =A0 =A0 =A0 =A0ptimer_stop(sam9->pitc_timer); > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + =A0 =A0 =A0 =A0break; > + =A0 =A0default: > + =A0 =A0 =A0 =A0TRACE("unhandled register %d\n", idx); > + =A0 =A0 =A0 =A0break; > + =A0 =A0} > + =A0 =A0sam9->pitc_regs[idx] =3D value; > +} > + > +static void at91_init_pitc(struct at91sam9_state *sam9) > +{ > + =A0 =A0QEMUBH *bh; > + > + =A0 =A0DEBUG("begin\n"); > + =A0 =A0memset(&sam9->pitc_regs, 0, sizeof(sam9->pitc_regs)); > + =A0 =A0sam9->pitc_regs[AT91_PITC_MR] =3D 0xFFFFF; > + =A0 =A0bh =3D qemu_bh_new(at91_pitc_timer_tick, sam9); > + =A0 =A0sam9->pitc_timer =3D ptimer_init(bh); > +} > + > +static uint32_t at91_aic_read(void *opaque, target_phys_addr_t offset) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + =A0 =A0unsigned int idx =3D offset / sizeof(sam9->aic_regs[0]); > + =A0 =A0if (idx =3D=3D AT91_AIC_IVR) { > + =A0 =A0 =A0 =A0qemu_irq_lower(sam9->qirq[0]); > + =A0 =A0} else if (idx =3D=3D AT91_AIC_ISR) { > + =A0 =A0 =A0 =A0uint32_t val =3D sam9->aic_regs[idx]; > + =A0 =A0 =A0 =A0sam9->aic_regs[idx] =3D 0; > + =A0 =A0 =A0 =A0return val; > + =A0 =A0} > + > + =A0 =A0return sam9->aic_regs[idx]; > +} > + > +static void at91_aic_write(void *opaque, target_phys_addr_t offset, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 uint32_t value) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + =A0 =A0unsigned int idx =3D offset / sizeof(sam9->aic_regs[0]); > + > + =A0 =A0switch (idx) { > + =A0 =A0case AT91_AIC_IECR: > + =A0 =A0 =A0 =A0sam9->aic_regs[idx] |=3D value; > + =A0 =A0 =A0 =A0break; > + =A0 =A0case AT91_AIC_IDCR: > + =A0 =A0 =A0 =A0sam9->aic_regs[idx] |=3D value; > + =A0 =A0 =A0 =A0sam9->aic_regs[AT91_AIC_IECR] &=3D ~value; > + =A0 =A0 =A0 =A0break; > + =A0 =A0case AT91_AIC_IVR://ignore write > + =A0 =A0 =A0 =A0break; > + =A0 =A0case AT91_AIC_EOICR: > +// =A0 =A0 =A0 =A0DEBUG("we write to end of interrupt reg\n"); > + =A0 =A0 =A0 =A0break; > + =A0 =A0default: > + =A0 =A0 =A0 =A0sam9->aic_regs[idx] =3D value; > + =A0 =A0 =A0 =A0break; > + =A0 =A0} > +} > + > +static uint32_t at91_usart_read(void *opaque, target_phys_addr_t offset) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + =A0 =A0DEBUG("we read from %X\n", offset); > + =A0 =A0return sam9->usart0_regs[offset / sizeof(uint32_t)]; > +} > + > +static void at91_usart_write(void *opaque, target_phys_addr_t offset, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 uint32_t value) > +{ > + =A0 =A0struct at91sam9_state *sam9 =3D (struct at91sam9_state *)opaque; > + =A0 =A0DEBUG("we write to %X: %X\n", offset, value); > + =A0 =A0sam9->usart0_regs[offset / sizeof(uint32_t)] =3D value; > +} > + > + > +struct ip_block { > + =A0 =A0target_phys_addr_t offset; > + =A0 =A0target_phys_addr_t end_offset; > + =A0 =A0uint32_t (*read_func)(void *, target_phys_addr_t); > + =A0 =A0void (*write_func)(void *, target_phys_addr_t, uint32_t); > +}; > + > +static struct ip_block ip_blocks[] =3D { > + =A0 =A0{AT91_USART0_BASE - AT91_PERIPH_BASE, AT91_USART0_BASE - AT91_PE= RIPH_BASE + 0x1000, at91_usart_read, at91_usart_write}, > + =A0 =A0{AT91_SDRAMC0_BASE - AT91_PERIPH_BASE, AT91_SMC0_BASE - AT91_PER= IPH_BASE, at91_sdramc0_read, at91_sdramc0_write}, > + =A0 =A0{AT91_SMC0_BASE - AT91_PERIPH_BASE, AT91_ECC1_BASE - AT91_PERIPH= _BASE, at91_smc0_read, at91_smc0_write}, > + =A0 =A0{AT91_BUS_MATRIX_BASE - AT91_PERIPH_BASE, AT91_CCFG_BASE - AT91_= PERIPH_BASE, at91_bus_matrix_read, at91_bus_matrix_write}, > + =A0 =A0{AT91_CCFG_BASE - AT91_PERIPH_BASE, AT91_DBGU_BASE - AT91_PERIPH= _BASE, at91_ccfg_read, at91_ccfg_write}, > + =A0 =A0{AT91_DBGU_BASE - AT91_PERIPH_BASE, AT91_AIC_BASE - AT91_PERIPH_= BASE, at91_dbgu_read, at91_dbgu_write}, > + =A0 =A0{AT91_AIC_BASE - AT91_PERIPH_BASE, AT91_PIO_BASE - AT91_PERIPH_B= ASE, at91_aic_read, at91_aic_write}, > + =A0 =A0{AT91_PIO_BASE - AT91_PERIPH_BASE, AT91_PMC_BASE - AT91_PERIPH_B= ASE, at91_pio_read, at91_pio_write}, > + =A0 =A0{AT91_PMC_BASE - AT91_PERIPH_BASE, AT91_RSTC_BASE - AT91_PERIPH_= BASE, at91_pmc_read, at91_pmc_write}, > + =A0 =A0{AT91_PITC_BASE - AT91_PERIPH_BASE, AT91_WDT_BASE - AT91_PERIPH_= BASE, at91_pitc_read, at91_pitc_write}, > +}; > + > +static uint32_t at91_periph_read(void *opaque, target_phys_addr_t offset= ) > +{ > + =A0 =A0int i; > + > + =A0 =A0for (i =3D 0; i < ARRAY_SIZE(ip_blocks); ++i) > + =A0 =A0 =A0 =A0if (offset >=3D ip_blocks[i].offset && offset < ip_block= s[i].end_offset) > + =A0 =A0 =A0 =A0 =A0 =A0return ip_blocks[i].read_func(opaque, offset - i= p_blocks[i].offset); > + =A0 =A0DEBUG("read from unsupported periph addr %X\n", offset); > + =A0 =A0return 0xFFFFFFFFUL; > +} > + > +static void at91_periph_write(void *opaque, target_phys_addr_t offset, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uint32_t val= ue) > +{ > + =A0 =A0int i; > + > + =A0 =A0for (i =3D 0; i < ARRAY_SIZE(ip_blocks); ++i) > + =A0 =A0 =A0 =A0if (offset >=3D ip_blocks[i].offset && offset < ip_block= s[i].end_offset) { > + =A0 =A0 =A0 =A0 =A0 =A0ip_blocks[i].write_func(opaque, offset - ip_bloc= ks[i].offset, value); > + =A0 =A0 =A0 =A0 =A0 =A0return; > + =A0 =A0 =A0 =A0} > + =A0 =A0DEBUG("write to unsupported periph: addr %X, val %X\n", offset, = value); > +} > + > +/* Input 0 is IRQ and input 1 is FIQ. =A0*/ > +static void arm_aic_cpu_handler(void *opaque, int irq, int level) > +{ > + =A0 =A0CPUState *env =3D (CPUState *)opaque; > + =A0 =A0switch (irq) { > + =A0 =A0case ARM_AIC_CPU_IRQ: > + =A0 =A0 =A0 =A0if (level) > + =A0 =A0 =A0 =A0 =A0 =A0cpu_interrupt(env, CPU_INTERRUPT_HARD); > + =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0 =A0cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); > + =A0 =A0 =A0 =A0break; > + =A0 =A0case ARM_AIC_CPU_FIQ: > + =A0 =A0 =A0 =A0if (level) > + =A0 =A0 =A0 =A0 =A0 =A0cpu_interrupt(env, CPU_INTERRUPT_FIQ); > + =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0 =A0cpu_reset_interrupt(env, CPU_INTERRUPT_FIQ); > + =A0 =A0 =A0 =A0break; > + =A0 =A0default: > + =A0 =A0 =A0 =A0hw_error("arm_pic_cpu_handler: Bad interrput line %d\n",= irq); > + =A0 =A0} > +} > + > +static void at91_aic_init(struct at91sam9_state *sam9) > +{ > + =A0 =A0memset(&sam9->aic_regs[0], 0, sizeof(sam9->aic_regs)); > + =A0 =A0sam9->qirq =3D qemu_allocate_irqs(arm_aic_cpu_handler, sam9->env= , 2); > +} > + > +static CPUReadMemoryFunc *at91_periph_readfn[] =3D { > + =A0 =A0at91_periph_read, > + =A0 =A0at91_periph_read, > + =A0 =A0at91_periph_read > +}; > + > +static CPUWriteMemoryFunc *at91_periph_writefn[] =3D { > + =A0 =A0at91_periph_write, > + =A0 =A0at91_periph_write, > + =A0 =A0at91_periph_write > +}; > + > + > +static void at91sam9_init(ram_addr_t ram_size, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0const char *boot_dev= ice, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0const char *kernel_f= ilename, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0const char *kernel_c= mdline, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0const char *initrd_f= ilename, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0const char *cpu_mode= l) > +{ > + =A0 =A0CPUState *env; > + =A0 =A0DriveInfo *dinfo; > + =A0 =A0struct at91sam9_state *sam9; > + =A0 =A0int iomemtype; > + > + =A0 =A0DEBUG("begin, ram_size %llu\n", (unsigned long long)ram_size); > +#ifdef TRACE_ON > + =A0 =A0trace_file =3D fopen("/tmp/trace.log", "w"); > +#endif > + =A0 =A0if (!cpu_model) > + =A0 =A0 =A0 =A0cpu_model =3D "arm926"; > + =A0 =A0env =3D cpu_init(cpu_model); > + =A0 =A0if (!env) { > + =A0 =A0 =A0 =A0fprintf(stderr, "Unable to find CPU definition\n"); > + =A0 =A0 =A0 =A0exit(EXIT_FAILURE); > + =A0 =A0} > + =A0 =A0/* SDRAM at chipselect 1. =A0*/ > + =A0 =A0cpu_register_physical_memory(AT91SAM9263EK_SDRAM_OFF, AT91SAM926= 3EK_SDRAM_SIZE, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 qemu_ra= m_alloc(AT91SAM9263EK_SDRAM_SIZE) | IO_MEM_RAM); > + > + =A0 =A0sam9 =3D (struct at91sam9_state *)qemu_mallocz(sizeof(*sam9)); > + =A0 =A0if (!sam9) { > + =A0 =A0 =A0 =A0fprintf(stderr, "allocation failed\n"); > + =A0 =A0 =A0 =A0exit(EXIT_FAILURE); > + =A0 =A0} > + =A0 =A0sam9->env =3D env; > + =A0 =A0/* Internal SRAM */ > + =A0 =A0sam9->internal_sram =3D qemu_ram_alloc(80 * 1024); > + =A0 =A0cpu_register_physical_memory(0x00300000, 80 * 1024, sam9->intern= al_sram | IO_MEM_RAM); > + > + =A0 =A0/*Internal Peripherals */ > + =A0 =A0iomemtype =3D cpu_register_io_memory(at91_periph_readfn, at91_pe= riph_writefn, sam9); > + =A0 =A0cpu_register_physical_memory(0xF0000000, 0xFFFFFFFF - 0xF0000000= , iomemtype); > + > + =A0 =A0at91_init_pmc(sam9); > + =A0 =A0at91_init_bus_matrix(sam9); > + =A0 =A0memset(&sam9->ccfg_regs, 0, sizeof(sam9->ccfg_regs)); > + =A0 =A0memset(&sam9->pio_regs, 0, sizeof(sam9->pio_regs)); > + =A0 =A0memset(&sam9->sdramc0_regs, 0, sizeof(sam9->sdramc0_regs)); > + =A0 =A0memset(&sam9->smc0_regs, 0, sizeof(sam9->smc0_regs)); > + =A0 =A0at91_init_dbgu(sam9, serial_hds[0]); > + =A0 =A0at91_init_pitc(sam9); > + =A0 =A0at91_aic_init(sam9); > + =A0 =A0memset(sam9->usart0_regs, 0, sizeof(sam9->usart0_regs)); > + > + =A0 =A0/* > + =A0 =A0 =A0we use variant of booting from external memory (NOR FLASH), > + =A0 =A0 =A0it mapped to 0x0 at start, and also it is accessable from 0x= 10000000 address > + =A0 =A0*/ > + =A0 =A0dinfo =3D drive_get(IF_PFLASH, 0, 0); > + =A0 =A0if (dinfo) { > + =A0 =A0 =A0 =A0ram_addr_t nor_flash_mem =3D qemu_ram_alloc(NOR_FLASH_SI= ZE); > + =A0 =A0 =A0 =A0if (!nor_flash_mem) { > + =A0 =A0 =A0 =A0 =A0 =A0fprintf(stderr, "allocation failed\n"); > + =A0 =A0 =A0 =A0 =A0 =A0exit(EXIT_FAILURE); > + =A0 =A0 =A0 =A0} > + > + =A0 =A0 =A0 =A0sam9->norflash =3D pflash_cfi_atmel_register(AT91SAM9263= EK_NORFLASH_OFF, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 nor_flash_mem, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 dinfo->bdrv, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 4 * 1024 * 2, 8, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 32 * 1024 * 2, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 (135 - 8), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 2, 0x001F, 0x01D6, 0, 0); > + > + =A0 =A0 =A0 =A0if (!sam9->norflash) { > + =A0 =A0 =A0 =A0 =A0 =A0fprintf(stderr, "qemu: error registering flash m= emory.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0exit(EXIT_FAILURE); > + =A0 =A0 =A0 =A0} > + > + =A0 =A0 =A0 =A0DEBUG("register flash at 0x0\n"); > + =A0 =A0 =A0 =A0//register only part of flash, to prevent conflict with = internal sram > + =A0 =A0 =A0 =A0cpu_register_physical_memory(0x0, 100 * 1024 /*NOR_FLASH= _SIZE*/, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= nor_flash_mem | IO_MEM_ROMD); > + =A0 =A0} else { > + =A0 =A0 =A0 =A0fprintf(stderr, "qemu: can not start without flash.\n"); > + =A0 =A0 =A0 =A0exit(EXIT_FAILURE); > + =A0 =A0} > + =A0 =A0env->regs[15] =3D 0x0; > +} > + > +static QEMUMachine at91sam9263ek_machine =3D { > + =A0 =A0.name =3D "at91sam9263ek", > + =A0 =A0.desc =3D "Atmel at91sam9263ek board (ARM926EJ-S)", > + =A0 =A0.init =3D at91sam9_init, > +}; > + > +static void at91sam9_machine_init(void) > +{ > + =A0 =A0qemu_register_machine(&at91sam9263ek_machine); > +} > + > +machine_init(at91sam9_machine_init) > diff --git a/hw/at91sam9263_defs.h b/hw/at91sam9263_defs.h > new file mode 100644 > index 0000000..c7136c3 > --- /dev/null > +++ b/hw/at91sam9263_defs.h > @@ -0,0 +1,144 @@ > +#ifndef _HW_AT91SAM9263_DEFS_H_ > +#define _HW_AT91SAM9263_DEFS_H_ > + > +/* base periph addresses */ > +#define AT91_PERIPH_BASE =A0 =A0 0xF0000000 > +#define AT91_USART0_BASE =A0 =A0 0xFFF8C000 > +#define AT91_SDRAMC0_BASE =A0 =A00xFFFFE200 > +#define AT91_SMC0_BASE =A0 =A0 =A0 0xFFFFE400 > +#define AT91_ECC1_BASE =A0 =A0 =A0 0xFFFFE600 > +#define AT91_BUS_MATRIX_BASE 0xFFFFEC00 > +#define AT91_CCFG_BASE =A0 =A0 =A0 0xFFFFED10 > +#define AT91_DBGU_BASE =A0 =A0 =A0 0xFFFFEE00 > +#define AT91_AIC_BASE =A0 =A0 =A0 =A00xFFFFF000 > +#define AT91_PIO_BASE =A0 =A0 =A0 =A00xFFFFF200 > +#define AT91_PMC_BASE =A0 =A0 =A0 =A00xFFFFFC00 > +#define AT91_RSTC_BASE =A0 =A0 =A0 0xFFFFFD00 > +#define AT91_PITC_BASE =A0 =A0 =A0 0xFFFFFD30 > +#define AT91_WDT_BASE =A0 =A0 =A0 =A00xFFFFFD40 > + > +/* PMC registers */ > +#define AT91_PMC_SR (0x68 / sizeof(uint32_t)) > +#define AT91_PMC_MCKR (0x0020 / sizeof(uint32_t)) > +#define AT91_PMC_MOR (0x30 / sizeof(uint32_t)) > +#define AT91_PMC_CSS =A0 =A0 =A0 =A0 =A0 =A0 (0x3 << =A00) // (PMC) Prog= rammable Clock Selection > +#define AT91_PMC_MCKRDY =A0 =A0 =A0 =A0 =A0(0x1 << =A03) // (PMC) Master= Clock Status/Enable/Disable/Mask > +#define AT91_PMC_MOSCS =A0 =A0 =A0 =A0 =A0 (0x1 << =A00) // (PMC) MOSC S= tatus/Enable/Disable/Mask > +#define AT91_CKGR_MOSCEN =A0 =A0 =A0 =A0 (0x1 << =A00) // (CKGR) Main Os= cillator Enable > +#define AT91_PMC_PLLAR (0x0028 / sizeof(uint32_t)) > +#define AT91_PMC_PLLBR (0x002C / sizeof(uint32_t)) > +#define AT91_PMC_LOCKA =A0 =A0 =A0 =A0 =A0 (0x1 << =A01) // (PMC) PLL A = Status/Enable/Disable/Mask > +#define AT91_PMC_LOCKB =A0 =A0 =A0 =A0 =A0 (0x1 << =A02) // (PMC) PLL B = Status/Enable/Disable/Mask > +#define AT91_PMC_PCER (0x10 / sizeof(uint32_t)) > + > +/*dbgu registers */ > +#define AT91_DBGU_CR =A0 0x0 > +#define AT91_DBGU_MR =A0 (4 / sizeof(uint32_t)) > +#define AT91_DBGU_IER =A0(8 / sizeof(uint32_t)) > +#define AT91_DBGU_IDR =A0(0xC / sizeof(uint32_t)) > +#define AT91_DBGU_IMR =A0(0x10 / sizeof(uint32_t)) > +#define AT91_DBGU_SR =A0 (0x14 / sizeof(uint32_t)) > +#define AT91_DBGU_RHR =A0(0x18 / sizeof(uint32_t)) > +#define AT91_DBGU_THR =A0(0x001C / sizeof(uint32_t)) > +#define AT91_DBGU_BRGR (0x0020 / sizeof(uint32_t)) > + > + > +// -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register ---= ----- > +#define AT91_US_RSTRX =A0 =A0 =A0 =A0 =A0 =A0(0x1 << =A02) // (DBGU) Res= et Receiver > +#define AT91_US_RSTTX =A0 =A0 =A0 =A0 =A0 =A0(0x1 << =A03) // (DBGU) Res= et Transmitter > +#define AT91_US_RXEN =A0 =A0 =A0 =A0 =A0 =A0 (0x1 << =A04) // (DBGU) Rec= eiver Enable > +#define AT91_US_RXDIS =A0 =A0 =A0 =A0 =A0 =A0(0x1 << =A05) // (DBGU) Rec= eiver Disable > +#define AT91_US_TXEN =A0 =A0 =A0 =A0 =A0 =A0 (0x1 << =A06) // (DBGU) Tra= nsmitter Enable > +#define AT91_US_TXDIS =A0 =A0 =A0 =A0 =A0 =A0(0x1 << =A07) // (DBGU) Tra= nsmitter Disable > +#define AT91_US_RSTSTA =A0 =A0 =A0 =A0 =A0 (0x1 << =A08) // (DBGU) Reset= Status Bits > +// -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Re= gister -------- > +#define AT91_US_RXRDY =A0 =A0 =A0 =A0 =A0 =A0(0x1 << =A00) // (DBGU) RXR= DY Interrupt > +#define AT91_US_TXRDY =A0 =A0 =A0 =A0 =A0 =A0(0x1 << =A01) // (DBGU) TXR= DY Interrupt > +#define AT91_US_ENDRX =A0 =A0 =A0 =A0 =A0 =A0(0x1 << =A03) // (DBGU) End= of Receive Transfer Interrupt > +#define AT91_US_ENDTX =A0 =A0 =A0 =A0 =A0 =A0(0x1 << =A04) // (DBGU) End= of Transmit Interrupt > +#define AT91_US_OVRE =A0 =A0 =A0 =A0 =A0 =A0 (0x1 << =A05) // (DBGU) Ove= rrun Interrupt > +#define AT91_US_FRAME =A0 =A0 =A0 =A0 =A0 =A0(0x1 << =A06) // (DBGU) Fra= ming Error Interrupt > +#define AT91_US_PARE =A0 =A0 =A0 =A0 =A0 =A0 (0x1 << =A07) // (DBGU) Par= ity Error Interrupt > +#define AT91_US_TXEMPTY =A0 =A0 =A0 =A0 =A0(0x1 << =A09) // (DBGU) TXEMP= TY Interrupt > +#define AT91_US_TXBUFE =A0 =A0 =A0 =A0 =A0 (0x1 << 11) // (DBGU) TXBUFE = Interrupt > +#define AT91_US_RXBUFF =A0 =A0 =A0 =A0 =A0 (0x1 << 12) // (DBGU) RXBUFF = Interrupt > +#define AT91_US_COMM_TX =A0 =A0 =A0 =A0 =A0(0x1 << 30) // (DBGU) COMM_TX= Interrupt > +#define AT91_US_COMM_RX =A0 =A0 =A0 =A0 =A0(0x1 << 31) // (DBGU) COMM_RX= Interrupt > + > +/* US registers */ > +#define AT91_US_CR =A0(0) > +#define AT91_US_MR =A0(4 / sizeof(uint32_t)) > +#define AT91_US_IER (8 / sizeof(uint32_t)) > +#define AT91_US_IDR (0xC / sizeof(uint32_t)) > +#define AT91_US_IMR (0x10 / sizeof(uint32_t)) > + > +/* matrix */ > + > +// *********************************************************************= ******** > +// =A0 =A0 =A0 =A0 =A0 =A0 =A0SOFTWARE API DEFINITION =A0FOR AHB Matrix = Interface > +// *********************************************************************= ******** > +// *** Register offset in AT91S_MATRIX structure *** > +#define MATRIX_MCFG0 =A0 =A0( 0) // =A0Master Configuration Register 0 > +#define MATRIX_MCFG1 =A0 =A0( 4) // =A0Master Configuration Register 1 > +#define MATRIX_MCFG2 =A0 =A0( 8) // =A0Master Configuration Register 2 > +#define MATRIX_MCFG3 =A0 =A0(12) // =A0Master Configuration Register 3 > +#define MATRIX_MCFG4 =A0 =A0(16) // =A0Master Configuration Register 4 > +#define MATRIX_MCFG5 =A0 =A0(20) // =A0Master Configuration Register 5 > +#define MATRIX_MCFG6 =A0 =A0(24) // =A0Master Configuration Register 6 > +#define MATRIX_MCFG7 =A0 =A0(28) // =A0Master Configuration Register 7 > +#define MATRIX_MCFG8 =A0 =A0(32) // =A0Master Configuration Register 8 > +#define MATRIX_SCFG0 =A0 =A0(64) // =A0Slave Configuration Register 0 > +#define MATRIX_SCFG1 =A0 =A0(68) // =A0Slave Configuration Register 1 > +#define MATRIX_SCFG2 =A0 =A0(72) // =A0Slave Configuration Register 2 > +#define MATRIX_SCFG3 =A0 =A0(76) // =A0Slave Configuration Register 3 > +#define MATRIX_SCFG4 =A0 =A0(80) // =A0Slave Configuration Register 4 > +#define MATRIX_SCFG5 =A0 =A0(84) // =A0Slave Configuration Register 5 > +#define MATRIX_SCFG6 =A0 =A0(88) // =A0Slave Configuration Register 6 > +#define MATRIX_SCFG7 =A0 =A0(92) // =A0Slave Configuration Register 7 > +#define MATRIX_PRAS0 =A0 =A0(128) // =A0PRAS0 > +#define MATRIX_PRBS0 =A0 =A0(132) // =A0PRBS0 > +#define MATRIX_PRAS1 =A0 =A0(136) // =A0PRAS1 > +#define MATRIX_PRBS1 =A0 =A0(140) // =A0PRBS1 > +#define MATRIX_PRAS2 =A0 =A0(144) // =A0PRAS2 > +#define MATRIX_PRBS2 =A0 =A0(148) // =A0PRBS2 > +#define MATRIX_PRAS3 =A0 =A0(152) // =A0PRAS3 > +#define MATRIX_PRBS3 =A0 =A0(156) // =A0PRBS3 > +#define MATRIX_PRAS4 =A0 =A0(160) // =A0PRAS4 > +#define MATRIX_PRBS4 =A0 =A0(164) // =A0PRBS4 > +#define MATRIX_PRAS5 =A0 =A0(168) // =A0PRAS5 > +#define MATRIX_PRBS5 =A0 =A0(172) // =A0PRBS5 > +#define MATRIX_PRAS6 =A0 =A0(176) // =A0PRAS6 > +#define MATRIX_PRBS6 =A0 =A0(180) // =A0PRBS6 > +#define MATRIX_PRAS7 =A0 =A0(184) // =A0PRAS7 > +#define MATRIX_PRBS7 =A0 =A0(188) // =A0PRBS7 > +#define MATRIX_MRCR =A0 =A0 (256) // =A0Master Remp Control Register > + > +#define AT91C_MATRIX_RCA926I =A0 =A0 =A0(0x1 << =A00) // (MATRIX) Remap = Command Bit for ARM926EJ-S Instruction > +#define AT91C_MATRIX_RCA926D =A0 =A0 =A0(0x1 << =A01) // (MATRIX) Remap = Command Bit for ARM926EJ-S Data > +#define AT91C_MATRIX_RCB2 =A0 =A0 =A0 =A0 (0x1 << =A02) // (MATRIX) Rema= p Command Bit for PDC > +#define AT91C_MATRIX_RCB3 =A0 =A0 =A0 =A0 (0x1 << =A03) // (MATRIX) Rema= p Command Bit for LCD > +#define AT91C_MATRIX_RCB4 =A0 =A0 =A0 =A0 (0x1 << =A04) // (MATRIX) Rema= p Command Bit for 2DGC > +#define AT91C_MATRIX_RCB5 =A0 =A0 =A0 =A0 (0x1 << =A05) // (MATRIX) Rema= p Command Bit for ISI > +#define AT91C_MATRIX_RCB6 =A0 =A0 =A0 =A0 (0x1 << =A06) // (MATRIX) Rema= p Command Bit for DMA > +#define AT91C_MATRIX_RCB7 =A0 =A0 =A0 =A0 (0x1 << =A07) // (MATRIX) Rema= p Command Bit for EMAC > +#define AT91C_MATRIX_RCB8 =A0 =A0 =A0 =A0 (0x1 << =A08) // (MATRIX) Rema= p Command Bit for USB > + > +/*pitc */ > +#define AT91_PTIC_MR_PITEN =A0(1 << 24) > +#define AT91_PTIC_MR_PITIEN (1 << 25) > +#define AT91_PITC_MR =A0 =A0 =A00 > +#define AT91_PITC_SR =A0 (0x4 / sizeof(uint32_t)) > +#define AT91_PITC_PIVR (0x8 / sizeof(uint32_t)) > +#define AT91_PITC_PIIR (0xC / sizeof(uint32_t)) > + > +/*AIC registers*/ > +#define AT91_AIC_SVR0 =A0(0x80 =A0/ sizeof(uint32_t)) > +#define AT91_AIC_ISR =A0 (0x108 / sizeof(uint32_t)) > +#define AT91_AIC_IECR =A0(0x120 / sizeof(uint32_t)) > +#define AT91_AIC_EOICR (0x130 / sizeof(uint32_t)) > +#define AT91_AIC_IVR =A0 (0x100 / sizeof(uint32_t)) > +#define AT91_AIC_IDCR =A0(0x124 / sizeof(uint32_t)) > + > +#define AT91_PERIPH_SYS_ID 1 > + > +#endif//!_HW_AT91SAM9263_DEFS_H_ > -- > 1.6.5.2 > > -- > /Evgeniy > > > >