PERFORCE change 157407 for review
Arnar Mar Sig
antab at FreeBSD.org
Sun Feb 8 15:42:03 PST 2009
http://perforce.freebsd.org/chv.cgi?CH=157407
Change 157407 by antab at antab_farm on 2009/02/08 23:41:58
Change nexus and at32bus to use hints instead of builtin list.
Add interrupt handling, seems to be working but need to test more.
Add at32_pm, at32_intc and at32_sdramc driver skeletons for testing.
First draft of clock handling, just a api skeleton for device drivers
to call to enable/disable and get/set rate.
Affected files ...
.. //depot/projects/avr32/src/sys/avr32/avr32/at32.c#3 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/at32_intc.c#1 add
.. //depot/projects/avr32/src/sys/avr32/avr32/at32_pio.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/at32_pm.c#1 add
.. //depot/projects/avr32/src/sys/avr32/avr32/at32_rtc.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/at32_sdramc.c#1 add
.. //depot/projects/avr32/src/sys/avr32/avr32/at32ap700x.c#2 delete
.. //depot/projects/avr32/src/sys/avr32/avr32/clock.c#3 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/cpu.c#4 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/exception.S#3 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/intr.c#3 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#4 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/nexus.c#3 edit
.. //depot/projects/avr32/src/sys/avr32/conf/NGW100#4 edit
.. //depot/projects/avr32/src/sys/avr32/conf/cpu/at32ap7000.hints#1 add
.. //depot/projects/avr32/src/sys/avr32/conf/cpu/at32ap7002.hints#1 add
.. //depot/projects/avr32/src/sys/avr32/conf/cpu/at32ap700x.hints#1 add
.. //depot/projects/avr32/src/sys/avr32/include/at32.h#3 delete
.. //depot/projects/avr32/src/sys/avr32/include/at32ap700x.h#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/cpu.h#4 edit
.. //depot/projects/avr32/src/sys/avr32/include/intr.h#3 edit
.. //depot/projects/avr32/src/sys/avr32/include/reg.h#3 edit
.. //depot/projects/avr32/src/sys/avr32/include/reg_intc.h#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/reg_pm.h#1 add
.. //depot/projects/avr32/src/sys/avr32/include/reg_rtc.h#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/reg_sdramc.h#1 add
.. //depot/projects/avr32/src/sys/conf/files#2 edit
.. //depot/projects/avr32/src/sys/conf/files.avr32#4 edit
.. //depot/projects/avr32/src/sys/conf/ldscript.avr32#3 edit
.. //depot/projects/avr32/src/sys/dev/uart/uart_dev_atmel.c#3 edit
.. //depot/projects/avr32/src/sys/sys/devclk.h#1 add
Differences ...
==== //depot/projects/avr32/src/sys/avr32/avr32/at32.c#3 (text+ko) ====
@@ -29,6 +29,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
+#include <sys/devclk.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
@@ -43,39 +44,66 @@
#include <machine/cpu.h>
#include <machine/bus.h>
#include <machine/intr.h>
-#include <machine/at32.h>
+#include <machine/reg.h>
+#include <machine/reg_pm.h>
#include <machine/at32ap700x.h>
#include <machine/debug.h>
/* Prototypes */
+static int at32_probe(device_t);
+static int at32_attach(device_t);
+static device_t at32_add_child(device_t, int, const char *, int);
+static void at32_hinted_child(device_t, const char *, int);
static struct resource_list *at32_get_resource_list(device_t, device_t);
static int at32_print_child(device_t, device_t);
-static int at32_activate_resource(device_t, device_t, int, int, struct resource *);
+static int at32_activate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int at32_deactivate_resource(device_t, device_t, int, int,
+ struct resource *);
static int at32_teardown_intr(device_t, device_t, struct resource *, void *);
-static int at32_setup_intr(device_t, device_t, struct resource *, int, driver_filter_t *, driver_intr_t *, void *, void **);
-static int at32_release_resource(device_t, device_t, int, int, struct resource *);
-static struct resource *at32_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int);
-static int at32_attach(device_t);
-static void at32_add_child(device_t, int, const char *, int, bus_addr_t, bus_size_t, int);
-static void at32_identify(driver_t *, device_t);
-static int at32_probe(device_t);
+static int at32_setup_intr(device_t, device_t, struct resource *, int,
+ driver_filter_t *, driver_intr_t *, void *, void **);
+static int at32_release_resource(device_t, device_t, int, int,
+ struct resource *);
+static struct resource *at32_alloc_resource(device_t, device_t, int, int *,
+ u_long, u_long, u_long, u_int);
+static uint64_t at32_clk_get_rate(device_t, device_t);
+static int at32_clk_set_rate(device_t, device_t, uint64_t);
+static void at32_clk_enable(device_t, device_t);
+static void at32_clk_disable(device_t, device_t);
/* Driver variables and private data */
+struct at32_softc {
+ struct rman sc_irq_rman;
+ struct resource *sc_mem_res;
+ struct rman sc_mem_rman;
+};
+struct at32_ivar {
+ struct resource_list resources;
+ int clk_bus;
+ int clk_index;
+};
static device_method_t at32_methods[] = {
DEVMETHOD(device_probe, at32_probe),
DEVMETHOD(device_attach, at32_attach),
- DEVMETHOD(device_identify, at32_identify),
+ DEVMETHOD(bus_add_child, at32_add_child),
+ DEVMETHOD(bus_hinted_child, at32_hinted_child),
+ DEVMETHOD(bus_print_child, at32_print_child),
DEVMETHOD(bus_alloc_resource, at32_alloc_resource),
DEVMETHOD(bus_setup_intr, at32_setup_intr),
DEVMETHOD(bus_teardown_intr, at32_teardown_intr),
DEVMETHOD(bus_activate_resource, at32_activate_resource),
- DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_deactivate_resource, at32_deactivate_resource),
DEVMETHOD(bus_get_resource_list, at32_get_resource_list),
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_release_resource, at32_release_resource),
- DEVMETHOD(bus_print_child, at32_print_child),
+
+ DEVMETHOD(devclk_get_rate, at32_clk_get_rate),
+ DEVMETHOD(devclk_set_rate, at32_clk_set_rate),
+ DEVMETHOD(devclk_enable, at32_clk_enable),
+ DEVMETHOD(devclk_disable, at32_clk_disable),
{0, 0},
};
static driver_t at32_driver = {
@@ -94,87 +122,94 @@
return (0);
}
-static void
-at32_identify(driver_t *drv, device_t parent)
-{
- BUS_ADD_CHILD(parent, 0, "at32bus", 0);
-}
-
-static void
-at32_add_child(device_t dev, int prio, const char *name, int unit,
- bus_addr_t addr, bus_size_t size, int irq)
-{
- device_t kid;
- struct at32_ivar *ivar;
-
- kid = device_add_child_ordered(dev, prio, name, unit);
- if (kid == NULL) {
- printf("Can't add child %s%d ordered\n", name, unit);
- return;
- }
- ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (ivar == NULL) {
- device_delete_child(dev, kid);
- printf("Can't add alloc ivar\n");
- return;
- }
- device_set_ivars(kid, ivar);
- resource_list_init(&ivar->resources);
- if (addr != 0) {
- bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
- }
- if (irq != -1) {
- bus_set_resource(kid, SYS_RES_IRQ, 0, irq, 1);
- }
-}
-
static int
at32_attach(device_t dev)
{
- int i;
+ int rid;
struct at32_softc *sc = device_get_softc(dev);
- struct at32_cpu_device *walker;
- sc->sc_st = 0;
- sc->sc_sh = AT32AP700X_BASE;
- sc->dev = dev;
-
- // Resource list for IRQ
+ /* Resource list for IRQ */
+ /* Reserve irqs from nexus ? */
sc->sc_irq_rman.rm_type = RMAN_ARRAY;
sc->sc_irq_rman.rm_descr = "AT32 IRQs";
if (rman_init(&sc->sc_irq_rman) != 0 ||
- rman_manage_region(&sc->sc_irq_rman, 1, IRQ_COUNT) != 0) {
- panic("at32_attach: failed to set up IRQ rman");
+ rman_manage_region(&sc->sc_irq_rman, 1, IRQ_COUNT) != 0) {
+ panic("at32_attach: failed to set up IRQ rman\n");
}
- // Resource list for system memory
+ /* Resource list for system memory */
+ rid = 0;
+ sc->sc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+ AVR32_SEG_P4, 0xfffffffful, 0, RF_ACTIVE);
+ if (sc->sc_mem_res == NULL) {
+ panic("at32_attach: failed to alloc bus memory\n");
+ }
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
sc->sc_mem_rman.rm_descr = "AT32 Memory";
if (rman_init(&sc->sc_mem_rman) != 0 ||
- rman_manage_region(&sc->sc_mem_rman, AVR32_SEG_P4,
- 0xfffffffful) != 0) {
+ rman_manage_region(&sc->sc_mem_rman, AVR32_SEG_P4,
+ 0xfffffffful) != 0) {
panic("at32_attach: fail to set up memory rman\n");
}
- /* Reserve memory range for INTC, we will handle access to it */
- sc->sc_intc_res = rman_reserve_resource(&sc->sc_mem_rman,
- AT32AP700X_BASE + AT32AP700X_INTC_OFFSET,
- AT32AP700X_BASE + AT32AP700X_INTC_OFFSET + AT32AP700X_INTC_SIZE,
- AT32AP700X_INTC_SIZE, 0, dev);
- if (!sc->sc_intc_res) {
- panic("at32_attach: unable to reserve INTC memory\n");
+ bus_generic_probe(dev);
+ bus_enumerate_hinted_children(dev);
+ bus_generic_attach(dev);
+ return 0;
+}
+
+static device_t
+at32_add_child(device_t bus, int order, const char *name, int unit)
+{
+ device_t child;
+ struct at32_ivar *ivar;
+
+ ivar = malloc(sizeof(struct at32_ivar), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (ivar == NULL) {
+ device_printf(bus, "Failed to allocate ivar\n");
+ return (0);
+ }
+ resource_list_init(&ivar->resources);
+
+ child = device_add_child_ordered(bus, order, name, unit);
+ if (child == NULL) {
+ device_printf(bus, "Can't add child %s%d ordered\n", name, unit);
+ return (0);
}
+ device_set_ivars(child, ivar);
+
+ return (child);
+}
+
+static void
+at32_hinted_child(device_t bus, const char *dname, int dunit)
+{
+ device_t child;
+ long maddr;
+ int msize, irq, result;
+
+ child = BUS_ADD_CHILD(bus, 0, dname, dunit);
+
+ /*
+ * Set hard-wired resources for hinted child using
+ * specific RIDs.
+ */
+ resource_long_value(dname, dunit, "maddr", &maddr);
+ resource_int_value(dname, dunit, "msize", &msize);
- // Add buildin devices
- for (i = 0, walker = at32_cpu_devices; walker->name; i++, walker++) {
- at32_add_child(dev, i, walker->name, walker->unit,
- walker->mem_base, walker->mem_len, walker->irq);
- };
+ result = bus_set_resource(child, SYS_RES_MEMORY, 0, maddr, msize);
+ if (result != 0) {
+ device_printf(bus, "warning: bus_set_resource() failed\n");
+ }
- bus_generic_probe(dev);
- bus_generic_attach(dev);
- return 0;
+ if (resource_int_value(dname, dunit, "irq", &irq) == 0) {
+ result = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
+ if (result != 0) {
+ device_printf(bus,
+ "warning: bus_set_resource() failed\n");
+ }
+ }
}
static struct resource *
@@ -247,32 +282,38 @@
static int
at32_setup_intr(device_t dev, device_t child, struct resource *ires, int flags,
- driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
+ driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
{
if ((rman_get_flags(ires) & RF_SHAREABLE) == 0) {
flags |= INTR_EXCL;
}
-
- avr32_setup_irqhandler(device_get_nameunit(child),
- filt, intr, arg, rman_get_start(ires), flags, cookiep);
+ BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt,
+ intr, arg, cookiep);
return (0);
}
static int
at32_teardown_intr(device_t dev, device_t child, struct resource *res,
- void *cookie)
+ void *cookie)
{
- return (avr32_remove_irqhandler(rman_get_start(res), cookie));
+ return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
}
static int
at32_activate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
+ struct resource *r)
{
return (rman_activate_resource(r));
}
static int
+at32_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_deactivate_resource(r));
+}
+
+static int
at32_print_child(device_t dev, device_t child)
{
struct at32_ivar *ivars;
@@ -284,7 +325,6 @@
retval += bus_print_child_header(dev, child);
- retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
if (device_get_flags(dev)) {
@@ -304,4 +344,28 @@
return (&(ivar->resources));
}
+static uint64_t
+at32_clk_get_rate(device_t dev, device_t child)
+{
+ avr32_impl();
+ return (0);
+}
+
+static int
+at32_clk_set_rate(device_t dev, device_t child, uint64_t rate)
+{
+ avr32_impl();
+ return (0);
+}
+
+static void
+at32_clk_enable(device_t dev, device_t child)
+{
+ /* TODO: Implement */
+}
+static void
+at32_clk_disable(device_t dev, device_t child)
+{
+ /* TODO: Implement */
+}
==== //depot/projects/avr32/src/sys/avr32/avr32/at32_pio.c#2 (text+ko) ====
@@ -33,6 +33,7 @@
#include <sys/module.h>
#include <sys/time.h>
#include <sys/bus.h>
+#include <sys/devclk.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/timetc.h>
@@ -42,7 +43,6 @@
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/resource.h>
-#include <machine/at32.h>
#include <machine/reg.h>
#include <machine/reg_pio.h>
#include <machine/debug.h>
@@ -105,8 +105,10 @@
at32_pio_attach(device_t dev)
{
struct at32_pio_softc *sc = device_get_softc(dev);
+ sc->dev = dev;
- sc->dev = dev;
+ /* Make sure clock is active before doing anything */
+ devclk_enable(dev);
return 0;
}
==== //depot/projects/avr32/src/sys/avr32/avr32/at32_rtc.c#2 (text+ko) ====
@@ -30,7 +30,7 @@
* fRTC = 2 ^ -(PSEL + 1) * 32KHz
* The datasheet also says we should set PSEL to at last 2 to ensure no ticks
* are missed when entering sleep modes.
- * So we will set PSEL to 14 giving us a 1Hz clock
+ * So we will set PSEL to 14 giving us a 1Hz
*/
#include <sys/cdefs.h>
@@ -42,6 +42,7 @@
#include <sys/module.h>
#include <sys/time.h>
#include <sys/bus.h>
+#include <sys/devclk.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/clock.h>
@@ -49,16 +50,15 @@
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/resource.h>
-#include <machine/at32.h>
#include <machine/reg.h>
#include <machine/reg_rtc.h>
#include "clock_if.h"
#define RD4(off) \
- bus_space_read_4(sc->sc_bst, sc->sc_bsh, (off))
+ bus_space_read_4(sc->bst, sc->bsh, (off))
#define WR4(off, val) \
- bus_space_write_4(sc->sc_bst, sc->sc_bsh, (off), (val))
+ bus_space_write_4(sc->bst, sc->bsh, (off), (val))
/* Prototypes */
static int at32_rtc_probe(device_t);
@@ -66,14 +66,16 @@
static int at32_rtc_detach(device_t);
static int at32_rtc_gettime(device_t, struct timespec *);
static int at32_rtc_settime(device_t, struct timespec *);
+static int at32_rtc_activate(device_t);
+static void at32_rtc_deactivate(device_t);
/* Driver variables and private data */
-static struct at32_rtc_softc {
- struct resource *sc_regs_res;
- int sc_regs_rid;
- bus_space_tag_t sc_bst;
- bus_space_handle_t sc_bsh;
-} *rtc_softc;
+struct at32_rtc_softc {
+ struct resource *regs_res;
+ int regs_rid;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+};
static device_method_t at32_rtc_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, at32_rtc_probe),
@@ -104,29 +106,23 @@
at32_rtc_attach(device_t dev)
{
struct at32_rtc_softc *sc = device_get_softc(dev);
+ int err;
- /* Global Pointer to private data, (cant i get with passed in
- * timecounter callback? */
- rtc_softc = sc;
-
- /* Set private data and map register space */
- sc->sc_regs_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->sc_regs_rid, 0,
- ~0, 0, RF_ACTIVE);
- if (!sc->sc_regs_res) {
- return (ENOMEM);
+ err = at32_rtc_activate(dev);
+ if (err) {
+ return (err);
}
- sc->sc_bsh = rman_get_bushandle(sc->sc_regs_res);
- sc->sc_bst = rman_get_bustag(sc->sc_regs_res);
- /* Enable RTC and set prescaler to 14 */
+ /* Enable RTC and set prescaler to 2 */
WR4(AT32_RTC_CTRL,
- 2 << bit_shift(RTC, CTRL, PSEL) |
- bit_offset(RTC, CTRL, PCLR) |
- bit_offset(RTC, CTRL, EN));
+ 2 << bit_shift(RTC, CTRL, PSEL) |
+ bit_offset(RTC, CTRL, PCLR) |
+ bit_offset(RTC, CTRL, EN));
+
+ /* Enable interrupt on TOP */
+ WR4(AT32_RTC_IER, bit_offset(RTC, IER, TOPI));
clock_register(dev, 1000000);
-
-
return (0);
}
@@ -134,7 +130,12 @@
at32_rtc_detach(device_t dev)
{
struct at32_rtc_softc *sc = device_get_softc(dev);
- bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_regs_rid, sc->sc_regs_res);
+
+ /* Disable interrupt */
+ WR4(AT32_RTC_IER, bit_offset(RTC, IER, TOPI));
+
+ at32_rtc_deactivate(dev);
+ return (0);
}
static int
@@ -153,3 +154,42 @@
WR4(AT32_RTC_VAL, ts->tv_sec);
return (0);
}
+
+static int
+at32_rtc_activate(device_t dev)
+{
+ struct at32_rtc_softc *sc = device_get_softc(dev);
+ int rid, err = ENOMEM;
+
+ /* Make sure device clock is enabled before writing */
+ devclk_enable(dev);
+
+ /* Set private data and map register space */
+ sc->regs_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->regs_rid, 0,
+ ~0, 0, RF_ACTIVE);
+ if (!sc->regs_res) {
+ goto err;
+ }
+ sc->bsh = rman_get_bushandle(sc->regs_res);
+ sc->bst = rman_get_bustag(sc->regs_res);
+
+ return (0);
+
+err:
+ at32_rtc_deactivate(dev);
+ return (err);
+}
+
+static void
+at32_rtc_deactivate(device_t dev)
+{
+ struct at32_rtc_softc *sc = device_get_softc(dev);
+
+ if (sc->regs_res) {
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ rman_get_rid(sc->regs_res), sc->regs_res);
+ }
+
+ /* Turn off device clock */
+ devclk_disable(dev);
+}
==== //depot/projects/avr32/src/sys/avr32/avr32/clock.c#3 (text+ko) ====
@@ -38,6 +38,7 @@
#include <sys/smp.h>
#include <sys/time.h>
#include <sys/timetc.h>
+#include <sys/cpu.h>
#include <machine/clock.h>
#include <machine/reg.h>
==== //depot/projects/avr32/src/sys/avr32/avr32/cpu.c#4 (text+ko) ====
@@ -64,25 +64,13 @@
#include <machine/at32ap700x.h>
extern vm_offset_t _evba;
-extern vm_offset_t _evba_irq;
void
cpu_init(void)
{
- int i;
-
/* Set exception vector */
sysreg_write(EVBA, (uint32_t)&_evba);
__asm__ __volatile__ ("csrf %0" : : "i"(AT32_SYS_SR_EM));
-
-
- /* Setup INTC, every interrupt is at priority 0 */
-/* for (i = 0; i < IRQ_COUNT; i++) {
- reg_write(AT32AP700X_BASE + AT32AP700X_INTC_OFFSET +
- (i * sizeof(register_t)), INTC, IPR,
- (_evba_irq - _evba));
- }
-*/
}
void
==== //depot/projects/avr32/src/sys/avr32/avr32/exception.S#3 (text+ko) ====
@@ -26,27 +26,52 @@
*/
#include <machine/asm.h>
+#include <machine/at32ap700x.h>
#include <machine/reg_sys.h>
+#include <machine/reg_intc.h>
#include "assym.s"
__FBSDID("$FreeBSD: $");
/* Save a trapfrome to stack */
-#define PUSH_TRAPFRAME \
- sub sp, 4; \
- stmts --sp, r0-lr; \
- mfsr r11, AT32_SYS_RAR_EX; \
- mfsr r12, AT32_SYS_RSR_EX; \
+#define PUSH_TRAPFRAME(context) \
+ sub sp, 4; \
+ stmts --sp, r0-lr; \
+ mfsr r11, AT32_SYS_RAR_##context; \
+ mfsr r12, AT32_SYS_RSR_##context; \
pushm r11-r12;
/* Restore trapframe from stack */
-#define POP_TRAPFRAME \
+#define POP_TRAPFRAME(context) \
popm r11-r12; \
- mtsr AT32_SYS_RAR_EX, r11; \
- mtsr AT32_SYS_RSR_EX, r12; \
- ldmts sp++, r0-lr; \
- sub sp, -4
+ mtsr AT32_SYS_RAR_##context, r11; \
+ mtsr AT32_SYS_RSR_##context, r12; \
+ ldmts sp++, r0-lr; \
+ sub sp, -4;
+
+/* Handle IRQ */
+#define IRQ(num) \
+ GLOBAL(intr_handle##num); \
+ PUSH_TRAPFRAME(INT##num); \
+ mov r10, num; \
+ lddpc r12, intr_cause_offset##num; \
+ ld.w r11, r12; \
+ mov r12, sp; \
+ call intr_handle; \
+ POP_TRAPFRAME(INT##num); \
+ rete; \
+intr_cause_offset##num:; \
+ .long AT32AP700X_BASE + AT32AP700X_INTC_OFFSET + \
+ AT32_INTC_ICR0 - (4 * num);
+
+#if 0
+#define IRQ(num) \
+ GLOBAL(intr_handle##num); \
+ sub r12, pc, (. - i##num); \
+ bral panic; \
+i##num: .asciz "IRQ!";
+#endif
.section .text.evba,"ax", at progbits
.align 2
@@ -110,12 +135,12 @@
/* later this should be done in assembly, but using C for now */
tlb_miss:
- PUSH_TRAPFRAME
+ PUSH_TRAPFRAME(EX)
mfsr r12, AT32_SYS_ECR
mfsr r11, AT32_SYS_TLBEAR
mfsr r10, AT32_SYS_TLBEHI
rcall pmap_tlb_miss
- POP_TRAPFRAME
+ POP_TRAPFRAME(EX)
rete
handle_critical:
@@ -126,26 +151,26 @@
rete
handle_illegal_opcode:
- PUSH_TRAPFRAME
+ PUSH_TRAPFRAME(EX)
mfsr r12, AT32_SYS_ECR
- mov r11, sp
+ mov r11, sp
rcall trap_handle_illegal_opcode
rete
handle_address_fault:
- PUSH_TRAPFRAME
+ PUSH_TRAPFRAME(EX)
mfsr r12, AT32_SYS_ECR
- mov r11, sp
+ mov r11, sp
rcall trap_handle_address_fault
- POP_TRAPFRAME
+ POP_TRAPFRAME(EX)
rete
handle_protection_fault:
- PUSH_TRAPFRAME
+ PUSH_TRAPFRAME(EX)
mfsr r12, AT32_SYS_ECR
- mov r11, sp
+ mov r11, sp
rcall trap_handle_protection_fault
- POP_TRAPFRAME
+ POP_TRAPFRAME(EX)
rete
handle_dtlb_modified:
@@ -153,16 +178,14 @@
rete
handle_breakpoint:
- PUSH_TRAPFRAME
- mov r12, AT32_SYS_ECR
- mov r11, sp
+ PUSH_TRAPFRAME(EX)
+ mov r12, AT32_SYS_ECR
+ mov r11, sp
rcall trap_handle_breakpoint
- POP_TRAPFRAME
+ POP_TRAPFRAME(EX)
rete
-.section .text.evba.irq
-ENTRY(handle_irq)
- sub r12, pc, (. - 2f)
- bral panic
- rete
-2: .asciz "Interrupt handler needed"
+IRQ(0)
+IRQ(1)
+IRQ(2)
+IRQ(3)
==== //depot/projects/avr32/src/sys/avr32/avr32/intr.c#3 (text+ko) ====
@@ -41,10 +41,12 @@
#include <machine/reg.h>
#include <machine/reg_sys.h>
#include <machine/reg_intc.h>
+#include <machine/reg_pm.h>
#include <machine/at32ap700x.h>
/* Private data */
-static struct intr_event *intr_events[IRQ_COUNT];
+static struct intr_event *intr_event[IRQ_COUNT];
+extern vm_offset_t _evba;
/* Code */
register_t
@@ -70,14 +72,46 @@
}
void
+intr_init()
+{
+ size_t offset;
+ int i;
+
+ /* Setup INTC, every interrupt is at priority 0 */
+ for (i = 0; i < IRQ_COUNT; i++) {
+ offset = AT32AP700X_BASE + AT32AP700X_INTC_OFFSET +
+ (i * sizeof(register_t));
+
+ reg_write(offset, INTC, IPR,
+ (vm_offset_t)intr_handle0 - (vm_offset_t)&_evba);
+ }
+
+ /* Enable interrupts */
+ sysreg_write(COMPARE, 0);
+ sysreg_write(SR, sysreg_read(SR) & ~INTR_MASK);
+}
+
+void
+intr_handle(struct trapframe *tf, int irq, int pri)
+{
+ if (!intr_event[irq] || TAILQ_EMPTY(&intr_event[irq]->ie_handlers)) {
+ printf("stray interrupt %d, priority %d\n", irq, pri);
+ return;
+ }
+
+ if (intr_event_handle(intr_event[irq], tf) != 0) {
+ panic("stray interrupt %d, priority %d\n", irq, pri);
+ }
+}
+
+void
avr32_mask_irq(uintptr_t irq)
{
int pri;
- avr32_impl();
pri = bit_value(INTC, IPR, INTLEVEL,
- reg_read(AT32AP700X_BASE + AT32AP700X_INTC_OFFSET +
- (irq * sizeof(register_t)), INTC, IPR));
+ reg_read(AT32AP700X_BASE + AT32AP700X_INTC_OFFSET +
+ (irq * sizeof(register_t)), INTC, IPR));
sysreg_write(SR, sysreg_read(SR) | (bit_offset(SYS, SR, I0M) << pri));
}
@@ -86,12 +120,10 @@
{
int pri;
- avr32_impl();
pri = bit_value(INTC, IPR, INTLEVEL,
- reg_read(AT32AP700X_BASE + AT32AP700X_INTC_OFFSET +
- (irq * sizeof(register_t)), INTC, IPR));
+ reg_read(AT32AP700X_BASE + AT32AP700X_INTC_OFFSET +
+ (irq * sizeof(register_t)), INTC, IPR));
sysreg_write(SR, sysreg_read(SR) | ~(bit_offset(SYS, SR, I0M) << pri));
-
}
void
@@ -105,18 +137,18 @@
return;
}
- event = intr_events[irq];
+ event = intr_event[irq];
if (event == NULL) {
error = intr_event_create(&event, (void *)irq, 0, irq,
- (mask_fn)avr32_mask_irq, (mask_fn)avr32_unmask_irq,
- NULL, NULL, "intr%d:", irq);
+ (mask_fn)avr32_mask_irq, (mask_fn)avr32_unmask_irq,
+ NULL, NULL, "intr%d:", irq);
if (error) {
return;
}
- intr_events[irq] = event;
+ intr_event[irq] = event;
}
intr_event_add_handler(event, name, filt, hand, arg,
- intr_priority(flags), flags, cookiep);
+ intr_priority(flags), flags, cookiep);
}
int
avr32_remove_irqhandler(int irq, void *cookie)
@@ -124,7 +156,8 @@
struct intr_event *event;
int error;
- event = intr_events[irq];
+
+ event = intr_event[irq];
avr32_mask_irq(irq);
error = intr_event_remove_handler(cookie);
==== //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#4 (text+ko) ====
@@ -65,10 +65,16 @@
#include <machine/uboot.h>
#include <machine/debug.h>
#include <machine/pte.h>
+#include <machine/intr.h>
+
+/* Prototypes */
+void mi_startup(void);
+void avr32_init(void);
+static void avr32_init_proc0(void);
+/* Misc variables and private data */
struct msgbuf *msgbufp = NULL;
int cold = 1;
-
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
struct pcb proc0_pcb;
@@ -82,14 +88,13 @@
static void cpu_startup(void *);
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
-// Prototypes (Should be in headers!)
-void mi_startup(void);
-void avr32_init(void);
-void avr32_init_proc0(void);
-
-void avr32_init() {
- cninit(); // Init console
- cpu_init(); // Init needed cpu things (evb and irq)
+/* Code */
+void
+avr32_init()
+{
+ cninit(); // Init console
+ cpu_init(); // Init needed cpu things (evb and irq)
+ intr_init(); // Init interrupt handling
uboot_parse_tags(); // Parse uboot tags
realmem = btoc(phys_avail[1] - phys_avail[0]);
@@ -102,7 +107,9 @@
mi_startup(); // Call machine independent part
}
-void avr32_init_proc0() {
+static void
+avr32_init_proc0()
+{
proc_linkup(&proc0, &thread0);
thread0.td_kstack = proc0_stack_end;
thread0.td_kstack_pages = KSTACK_PAGES - 1;
@@ -114,14 +121,16 @@
PCPU_SET(curpcb, thread0.td_pcb);
}
-static void cpu_startup(void *dummy) {
+static void
+cpu_startup(void *dummy)
+{
uint32_t config;
char arch_type;
if (boothowto & RB_VERBOSE) {
bootverbose++;
}
- bootverbose++;
+// bootverbose++;
vm_ksubmap_init(&kmi);
@@ -170,7 +179,7 @@
printf("real memory = %u (%u MB)\n", ptoa(realmem),
ptoa(realmem) / 1048576);
- printf("avail memory = %u (%uMB)\n", ptoa(cnt.v_free_count),
+ printf("avail memory = %u (%u MB)\n", ptoa(cnt.v_free_count),
ptoa(cnt.v_free_count) / 1048576);
/*
@@ -180,41 +189,57 @@
vm_pager_bufferinit();
}
-void cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) {
+void
+cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
+{
pcpu->pc_asid_next = 1;
pcpu->pc_asid_generation = 1;
}
-int fill_regs(struct thread *td, struct reg *regs) {
+int
+fill_regs(struct thread *td, struct reg *regs)
+{
memcpy(regs, &td->td_frame->regs, sizeof(struct reg));
return (0);
}
-int fill_fpregs(struct thread *td, struct fpreg *regs) {
+int
+fill_fpregs(struct thread *td, struct fpreg *regs)
+{
/* No FPU on avr32 */
memset(regs, 0, sizeof(struct fpreg));
return (0);
}
-int set_regs(struct thread *td, struct reg *regs) {
+int
+set_regs(struct thread *td, struct reg *regs)
+{
memcpy(&td->td_frame->regs, regs, sizeof(struct reg));
return (0);
}
-int set_fpregs(struct thread *td, struct fpreg *regs) {
+int
+set_fpregs(struct thread *td, struct fpreg *regs)
+{
/* No FPU on avr32 */
return (0);
}
-int fill_dbregs(struct thread *td, struct dbreg *regs) {
+int
+fill_dbregs(struct thread *td, struct dbreg *regs)
+{
return (0);
}
-int set_dbregs(struct thread *td, struct dbreg *regs) {
+int
+set_dbregs(struct thread *td, struct dbreg *regs)
+{
return (0);
}
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list