Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Jan 2015 00:44:35 -0800
From:      Adrian Chadd <adrian@freebsd.org>
To:        John Baldwin <jhb@freebsd.org>, Ian Lepore <ian@freebsd.org>, Warner Losh <imp@freebsd.org>,  "freebsd-mips@freebsd.org" <freebsd-mips@freebsd.org>
Subject:   interrupt muxes, bus memory space and other fun amusing things
Message-ID:  <CAJ-Vmo=LqZ6Z9oYU5Usv4rHY4AffZPy4QBqwN4onr2STq5OfMg@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
Hi,

I have FreeBSD-HEAD booting on the newer Atheros MIPS SoC (QCA955x
series) but now I have to sort out the mess which is how the memory
and IRQs are routed. I'd appreciate some help with this.

Unlike something hierarchical like PCI, there's a mostly-flat device
memory layout. Ie, things behind each interrupt "mux" aren't grouped
into some contiguous memory region.

On earlier chips the only interrupt multiplexer is the atheros
peripheral bus, and it has things like USB 1, UART, hwpmc, etc. The
wifi, EHCI USB, PCI, ethernet were assigned normal MIPS CPU interrupts
and those devices hung off of nexus0.

Now with the AR934x the on-board wifi hides behind one level of
interrupt mux, which I'm currently getting wrong by referencing IP2
(nexus irq0) directly. Now, that's good enough for this, but not for
what the QCA955x does.

The QCA955x has:

* IP6 - the APB mux - it has a mask and status register pair for
interrupts for peripheral devices;
* IP2 - PCIE root complex 1, WMAC
* IP3 - PCIE root complex 2, USB1, USB2.

The more annoying thing is that IP6 has its own status/mask registers,
but IP2/IP3 have a shared status register for multiplexing. (Ie, half
the bits are for IP2, half the bits are for IP3.)

So if I were Linux, I'd just implement a mux that pretends to trigger
interrupts in a much bigger IRQ space. Ie, they map IP0..IP7 to
irq0..7, then they pick another IRQ range for the AHB interrupts, and
another IRQ range for the IP2/IP3 interrupt mux. They have a
hard-coded mux that takes care of triggering the software IRQ based on
the hardware interrupt and mux register contents.

So, how should I approach this?

The other thing - right now mips/atheros/apb.c registers for a memory
region that happens to be big enough to cover the vast majority of
devices in the system. However, now I have regions covered by the APB,
the IP2 mux and the IP3 mux.

If I were evil, and I've thought about it, I've thought about just
extending apb.c to include registering for three nexus0 interrupts and
doing the muxing itself. That way only one bus thing is covering the
entirety of peripheral memory. But it seems .. inelegant.

Thanks!

The QCA955x is pretty sweet btw - 600MHz DDR3, 720MHz CPU clock,
dual-issue out of order pipeline. It's pretty freaking fast.

ath> go 0x80050100
## Starting application at 0x80050100 ...
CPU platform: Atheros AR9558 rev 0
CPU Frequency=720 MHz
CPU DDR Frequency=600 MHz
CPU AHB Frequency=200 MHz
platform frequency: 720 MHz
CPU reference clock: 40 MHz
CPU MDIO clock: 40 MHz

..



-adrian



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-Vmo=LqZ6Z9oYU5Usv4rHY4AffZPy4QBqwN4onr2STq5OfMg>