PERFORCE change 157130 for review
Arnar Mar Sig
antab at FreeBSD.org
Wed Feb 4 03:22:08 PST 2009
http://perforce.freebsd.org/chv.cgi?CH=157130
Change 157130 by antab at antab_farm on 2009/02/04 11:22:04
Update to AVR32, stops at cpu_switch now.
Added at32_rtc and at32_pio (pio code could be shared with at91) drivers to test at32bus and resource managment, looks like its working at last uart,at32_pio and at32_rtc gets probed and attached at the right places.
Added more placeholder functions to uart_atmel to get it to register, later share code with at91.
Misc other changes all over.
Affected files ...
.. //depot/projects/avr32/src/sys/avr32/avr32/at32.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/at32_pio.c#1 add
.. //depot/projects/avr32/src/sys/avr32/avr32/at32_rtc.c#1 add
.. //depot/projects/avr32/src/sys/avr32/avr32/at32ap700x.c#1 add
.. //depot/projects/avr32/src/sys/avr32/avr32/autoconf.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/clock.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/cpu.c#3 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/db_disasm.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/db_interface.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/elf_machdep.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/exception.S#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/intr.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#3 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/nexus.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/pm_machdep.c#3 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/pmap.c#3 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/support.S#3 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/switch.S#1 add
.. //depot/projects/avr32/src/sys/avr32/avr32/trap.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/uboot.c#3 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/vm_machdep.c#3 edit
.. //depot/projects/avr32/src/sys/avr32/conf/NGW100#3 edit
.. //depot/projects/avr32/src/sys/avr32/include/at32.h#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/at32ap700x.h#1 add
.. //depot/projects/avr32/src/sys/avr32/include/cpu.h#3 edit
.. //depot/projects/avr32/src/sys/avr32/include/frame.h#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/intr.h#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/pcb.h#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/pcpu.h#3 edit
.. //depot/projects/avr32/src/sys/avr32/include/proc.h#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/pte.h#3 edit
.. //depot/projects/avr32/src/sys/avr32/include/reg.h#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/reg_intc.h#1 add
.. //depot/projects/avr32/src/sys/avr32/include/reg_pio.h#1 add
.. //depot/projects/avr32/src/sys/avr32/include/reg_rtc.h#1 add
.. //depot/projects/avr32/src/sys/avr32/include/reg_sys.h#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/reg_usart.h#2 edit
.. //depot/projects/avr32/src/sys/avr32/include/reg_wdt.h#1 add
.. //depot/projects/avr32/src/sys/conf/files.avr32#3 edit
.. //depot/projects/avr32/src/sys/conf/ldscript.avr32#2 edit
.. //depot/projects/avr32/src/sys/conf/options.avr32#2 edit
.. //depot/projects/avr32/src/sys/dev/uart/uart_bus_atmel.c#2 edit
.. //depot/projects/avr32/src/sys/dev/uart/uart_dev_atmel.c#2 edit
Differences ...
==== //depot/projects/avr32/src/sys/avr32/avr32/at32.c#2 (text+ko) ====
@@ -40,11 +40,53 @@
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
+#include <machine/cpu.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <machine/at32.h>
+#include <machine/at32ap700x.h>
#include <machine/debug.h>
+/* Prototypes */
+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_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);
+
+/* Driver variables and private data */
+static device_method_t at32_methods[] = {
+ DEVMETHOD(device_probe, at32_probe),
+ DEVMETHOD(device_attach, at32_attach),
+ DEVMETHOD(device_identify, at32_identify),
+
+ 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_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),
+ {0, 0},
+};
+static driver_t at32_driver = {
+ "at32bus",
+ at32_methods,
+ sizeof(struct at32_softc),
+};
+static devclass_t at32_devclass;
+DRIVER_MODULE(at32bus, nexus, at32_driver, at32_devclass, 0, 0);
+
+/* Code */
static int
at32_probe(device_t dev)
{
@@ -55,18 +97,82 @@
static void
at32_identify(driver_t *drv, device_t parent)
{
- BUS_ADD_CHILD(parent, 0, "at32", 0);
+ BUS_ADD_CHILD(parent, 0, "at32bus", 0);
}
-static device_t
-at32_add_child(device_t dev, int prio, const char *name, int unit)
+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)
{
- return device_add_child_ordered(dev, prio, name, unit);
+ 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;
+ 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
+ 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");
+ }
+
+ // Resource list for system memory
+ 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) {
+ 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");
+ }
+
+
+ // 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);
+ };
+
+ bus_generic_probe(dev);
bus_generic_attach(dev);
return 0;
}
@@ -75,85 +181,127 @@
at32_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
- avr32_impl();
- return (0);
+ struct at32_softc *sc = device_get_softc(dev);
+ struct resource_list_entry *rle;
+ struct at32_ivar *ivar = device_get_ivars(child);
+ struct resource_list *rl = &ivar->resources;
+
+ if (device_get_parent(child) != dev) {
+ return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+ type, rid, start, end, count, flags));
+ }
+ rle = resource_list_find(rl, type, *rid);
+ if (rle == NULL) {
+ return (NULL);
+ }
+ if (rle->res) {
+ panic("Resource rid %d type %d already in use", *rid, type);
+ }
+ if (start == 0UL && end == ~0UL) {
+ start = rle->start;
+ count = ulmax(count, rle->count);
+ end = ulmax(rle->end, start + count - 1);
+ }
+ switch (type) {
+ case SYS_RES_IRQ:
+ rle->res = rman_reserve_resource(&sc->sc_irq_rman,
+ start, end, count, flags, child);
+ break;
+ case SYS_RES_MEMORY:
+ rle->res = rman_reserve_resource(&sc->sc_mem_rman,
+ start, end, count, flags, child);
+ if (rle->res != NULL) {
+ rman_set_bustag(rle->res, 0);
+ rman_set_bushandle(rle->res, start);
+ }
+ break;
+ }
+ if (rle->res) {
+ rle->start = rman_get_start(rle->res);
+ rle->end = rman_get_end(rle->res);
+ rle->count = count;
+ rman_set_rid(rle->res, *rid);
+ }
+ return (rle->res);
}
static int
-at32_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r) {
- int error;
+at32_release_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct resource_list *rl;
+ struct resource_list_entry *rle;
- if (rman_get_flags(r) & RF_ACTIVE) {
- error = bus_deactivate_resource(child, type, rid, r);
- if (error)
- return error;
+ rl = at32_get_resource_list(dev, child);
+ if (rl == NULL) {
+ return (EINVAL);
+ }
+ rle = resource_list_find(rl, type, rid);
+ if (rle == NULL) {
+ return (EINVAL);
}
- return (rman_release_resource(r));
-
+ rman_release_resource(r);
+ rle->res = NULL;
+ return (0);
}
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) {
- avr32_impl();
+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)
+{
+ if ((rman_get_flags(ires) & RF_SHAREABLE) == 0) {
+ flags |= INTR_EXCL;
+ }
- return 0;
+ avr32_setup_irqhandler(device_get_nameunit(child),
+ filt, intr, arg, rman_get_start(ires), flags, cookiep);
+ return (0);
}
static int
at32_teardown_intr(device_t dev, device_t child, struct resource *res,
void *cookie)
{
- avr32_impl();
-
- return 0;
+ return (avr32_remove_irqhandler(rman_get_start(res), cookie));
}
static int
at32_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
- avr32_impl();
-
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)
{
- int retval;
+ struct at32_ivar *ivars;
+ struct resource_list *rl;
+ int retval = 0;
+
+ ivars = device_get_ivars(child);
+ rl = &ivars->resources;
retval += bus_print_child_header(dev, child);
- retval += printf(" on at32\n");
+
+ 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)) {
+ retval += printf(" flags %#x", device_get_flags(dev));
+ }
+ retval += bus_print_child_footer(dev, child);
return (retval);
}
-static device_method_t at32_methods[] = {
- DEVMETHOD(device_probe, at32_probe),
- DEVMETHOD(device_attach, at32_attach),
- DEVMETHOD(device_identify, at32_identify),
+static struct resource_list *
+at32_get_resource_list(device_t dev, device_t child)
+{
+ struct at32_ivar *ivar;
- DEVMETHOD(bus_alloc_resource, at32_alloc_resource),
- DEVMETHOD(bus_release_resource, at32_release_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, at32_deactivate_resource),
- DEVMETHOD(bus_release_resource, at32_release_resource),
+ ivar = device_get_ivars(child);
+ return (&(ivar->resources));
+}
- {0, 0},
-};
-static driver_t at32_driver = {
- "at32",
- at32_methods,
- sizeof(struct at32_softc),
-};
-static devclass_t at32_devclass;
-
-DRIVER_MODULE(at32, nexus, at32_driver, at32_devclass, 0, 0);
==== //depot/projects/avr32/src/sys/avr32/avr32/autoconf.c#2 (text+ko) ====
@@ -62,9 +62,9 @@
#include <sys/mount.h>
#include <sys/cons.h>
-static void configure_first (void *);
-static void configure (void *);
-static void configure_final (void *);
+static void configure_first(void *);
+static void configure(void *);
+static void configure_final(void *);
SYSINIT(configure1, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure_first, NULL);
/* SI_ORDER_SECOND is hookable */
@@ -72,8 +72,6 @@
/* SI_ORDER_MIDDLE is hookable */
SYSINIT(configure3, SI_SUB_CONFIGURE, SI_ORDER_ANY, configure_final, NULL);
-device_t nexus_dev;
-
/*
* Determine i/o configuration for a machine.
@@ -81,21 +79,21 @@
static void
configure_first(void *dummy)
{
-
device_add_child(root_bus, "nexus", 0);
}
static void
configure(void *dummy)
{
-
root_bus_configure();
}
static void
configure_final(void *dummy)
{
-
cninit_finish();
+ if (bootverbose) {
+ printf("Device configuration finished.\n");
+ }
cold = 0;
}
==== //depot/projects/avr32/src/sys/avr32/avr32/clock.c#2 (text+ko) ====
@@ -2,10 +2,6 @@
* Copyright (c) 2008 Arnar Mar Sig <antab at antab.is>
* All rights reserved.
*
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department, and William Jolitz.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -44,29 +40,91 @@
#include <sys/timetc.h>
#include <machine/clock.h>
+#include <machine/reg.h>
+#include <machine/reg_sys.h>
#include <machine/debug.h>
-void cpu_initclocks(void) {
+/* Prototypes */
+static unsigned count_get_timecount(struct timecounter *);
+
+/* Variable and private data */
+uint64_t clock_cpu_frequency; /* Finzd batter way for this */
+static uint64_t cycles_per_usec;
+static uint64_t cycles_per_hz;
+static struct timecounter count_timecounter = {
+ count_get_timecount, /* get_timecount */
+ 0, /* no poll_pps */
+ 0xffffffffu, /* counter_mask */
+ 0, /* frequency */
+ "AVR32", /* name */
+ 1000, /* quality (adjusted in code) */
+};
+
+/* Code */
+void
+cpu_startprofclock(void)
+{
avr32_impl();
}
-void cpu_startprofclock(void) {
+void
+cpu_stopprofclock(void)
+{
avr32_impl();
}
-void cpu_stopprofclock(void) {
+int
+cpu_est_clockrate(int cpu_id, uint64_t *rate)
+{
avr32_impl();
+ return (ENXIO);
}
-int cpu_est_clockrate(int cpu_id, uint64_t *rate) {
- avr32_impl();
- return (ENXIO);
+void
+cpu_initclocks(void)
+{
+ count_timecounter.tc_frequency = clock_cpu_frequency;
+ cycles_per_hz = clock_cpu_frequency / hz;
+ cycles_per_usec = (clock_cpu_frequency / (1000 * 1000));
+ tc_init(&count_timecounter);
}
+static unsigned
+count_get_timecount(struct timecounter *tc)
+{
+ return sysreg_read(COUNT);
+}
/*
* Wait for about n microseconds (at least!).
*/
-void DELAY(int n) {
- avr32_impl();
+void
+DELAY(int n)
+{
+ uint32_t cur, last, delta, usecs;
+
+ /*
+ * This works by polling the timer and counting the number of
+ * microseconds that go by.
+ */
+ last = sysreg_read(COUNT);
+ delta = usecs = 0;
+
+ while (n > usecs) {
+ cur = sysreg_read(COUNT);
+
+ /* Check to see if the timer has wrapped around. */
+ if (cur < last) {
+ delta += (cur + (cycles_per_hz - last));
+ } else {
+ delta += (cur - last);
+ }
+
+ last = cur;
+
+ if (delta >= cycles_per_usec) {
+ usecs += delta / cycles_per_usec;
+ delta %= cycles_per_usec;
+ }
+ }
}
==== //depot/projects/avr32/src/sys/avr32/avr32/cpu.c#3 (text+ko) ====
@@ -2,10 +2,6 @@
* Copyright (c) 2008 Arnar Mar Sig <antab at antab.is>
* All rights reserved.
*
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department, and William Jolitz.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -60,31 +56,53 @@
#include <machine/cpu.h>
#include <machine/pmap.h>
#include <machine/debug.h>
+#include <machine/intr.h>
#include <machine/reg.h>
#include <machine/reg_sys.h>
+#include <machine/reg_intc.h>
#include <machine/reg_usart.h>
+#include <machine/at32ap700x.h>
extern vm_offset_t _evba;
+extern vm_offset_t _evba_irq;
-void cpu_init(void) {
- // Set exception vector
+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 cpu_idle(int busy) {
+void
+cpu_idle(int busy)
+{
avr32_impl();
}
-void cpu_halt(void) {
+void
+cpu_halt(void)
+{
avr32_impl();
}
-void cpu_reset(void) {
+void
+cpu_reset(void)
+{
avr32_impl();
}
-
/**
* Debugging code for avr32, this is here so i can do writes to usart1 without going thru all the
* tty code
==== //depot/projects/avr32/src/sys/avr32/avr32/db_disasm.c#2 (text+ko) ====
@@ -1,11 +1,39 @@
+/*-
+ * Copyright (c) 2009 Arnar Mar Sig <antab at antab.is>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: $");
#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
#include <vm/vm_param.h>
#include <vm/vm.h>
#include <vm/pmap.h>
-#include <sys/systm.h>
+
#include <ddb/ddb.h>
#include <ddb/db_output.h>
==== //depot/projects/avr32/src/sys/avr32/avr32/db_interface.c#2 (text+ko) ====
@@ -2,10 +2,6 @@
* Copyright (c) 2009 Arnar Mar Sig <antab at antab.is>
* All rights reserved.
*
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department, and William Jolitz.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
==== //depot/projects/avr32/src/sys/avr32/avr32/elf_machdep.c#2 (text+ko) ====
@@ -2,10 +2,6 @@
* Copyright (c) 2008 Arnar Mar Sig <antab at antab.is>
* All rights reserved.
*
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department, and William Jolitz.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
==== //depot/projects/avr32/src/sys/avr32/avr32/exception.S#2 (text+ko) ====
@@ -159,3 +159,10 @@
rcall trap_handle_breakpoint
POP_TRAPFRAME
rete
+
+.section .text.evba.irq
+ENTRY(handle_irq)
+ sub r12, pc, (. - 2f)
+ bral panic
+ rete
+2: .asciz "Interrupt handler needed"
==== //depot/projects/avr32/src/sys/avr32/avr32/intr.c#2 (text+ko) ====
@@ -2,10 +2,6 @@
* Copyright (c) 2008 Arnar Mar Sig <antab at antab.is>
* All rights reserved.
*
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department, and William Jolitz.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -44,26 +40,97 @@
#include <machine/debug.h>
#include <machine/reg.h>
#include <machine/reg_sys.h>
+#include <machine/reg_intc.h>
+#include <machine/at32ap700x.h>
+/* Private data */
+static struct intr_event *intr_events[IRQ_COUNT];
-register_t intr_disable(void) {
+/* Code */
+register_t
+intr_disable(void)
+{
register_t s;
s = sysreg_read(SR);
- // Mask all interrupts
- sysreg_write(SR, s & ~(bit_offset(SYS, SR, GM) |
- bit_offset(SYS, SR, I0M) |
- bit_offset(SYS, SR, I1M) |
- bit_offset(SYS, SR, I2M) |
- bit_offset(SYS, SR, I3M)));
+ __asm__ __volatile__ ("ssrf %0" : : "i"(AT32_SYS_SR_GM));
+ return (s);
+}
+
+void
+intr_restore(register_t s)
+{
+ __asm__ __volatile__ ("csrf %0" : : "i"(AT32_SYS_SR_GM));
+}
- return (s);
+void
+intr_handle_mni(void)
+{
+ avr32_impl();
}
-void intr_restore(register_t s) {
- sysreg_write(SR, s);
+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));
+ sysreg_write(SR, sysreg_read(SR) | (bit_offset(SYS, SR, I0M) << pri));
}
-void intr_handle_mni() {
+void
+avr32_unmask_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));
+ sysreg_write(SR, sysreg_read(SR) | ~(bit_offset(SYS, SR, I0M) << pri));
+
+}
+
+void
+avr32_setup_irqhandler(const char *name, driver_filter_t *filt,
+ void (*hand)(void*), void *arg, int irq, int flags, void **cookiep)
+{
+ struct intr_event *event;
+ int error;
+
+ if (irq < 0 || irq >= IRQ_COUNT) {
+ return;
+ }
+
+ event = intr_events[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);
+ if (error) {
+ return;
+ }
+ intr_events[irq] = event;
+ }
+ intr_event_add_handler(event, name, filt, hand, arg,
+ intr_priority(flags), flags, cookiep);
+}
+int
+avr32_remove_irqhandler(int irq, void *cookie)
+{
+ struct intr_event *event;
+ int error;
+
+ event = intr_events[irq];
+ avr32_mask_irq(irq);
+
+ error = intr_event_remove_handler(cookie);
+
+ if (!TAILQ_EMPTY(&event->ie_handlers)) {
+ avr32_unmask_irq(irq);
+ }
+ return (error);
}
==== //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#3 (text+ko) ====
@@ -2,10 +2,6 @@
* Copyright (c) 2008 Arnar Mar Sig <antab at antab.is>
* All rights reserved.
*
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department, and William Jolitz.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -77,6 +73,7 @@
struct pcpu *pcpup = &__pcpu;
struct pcb proc0_pcb;
extern vm_offset_t proc0_stack_end;
+extern uint64_t clock_cpu_frequency;
vm_offset_t phys_avail[10];
long realmem;
@@ -118,16 +115,61 @@
}
static void cpu_startup(void *dummy) {
+ uint32_t config;
+ char arch_type;
+
if (boothowto & RB_VERBOSE) {
bootverbose++;
}
- bootverbose++;
- printf("real memory = %u (%u MB)\n", ptoa(realmem),
- ptoa(realmem) / 1048576);
+ bootverbose++;
+
+ vm_ksubmap_init(&kmi);
+
+ config = sysreg_read(CONFIG0);
+ switch (bit_value(SYS, CONFIG0, AT, config)) {
+ case 0:
+ arch_type = 'A';
+ break;
+ case 1:
+ arch_type = 'B';
+ break;
+ default:
+ arch_type = 'x';
+ break;
+ }
+ printf("CPU: AVR32%c (ID %d, Rev %d) (%ju MHz)\n Features: "
+ , arch_type
+ , bit_value(SYS, CONFIG0, PROCESSORID, config)
+ , bit_value(SYS, CONFIG0, AR, config)
+ , clock_cpu_frequency / 1000000
+ );
- vm_ksubmap_init(&kmi);
+ if (bit_value(SYS, CONFIG0, F, config)) {
+ printf("FPU ");
+ }
+ if (bit_value(SYS, CONFIG0, J, config)) {
+ printf("JAVA ");
+ }
+ if (bit_value(SYS, CONFIG0, P, config)) {
+ printf("PC ");
+ }
+ if (bit_value(SYS, CONFIG0, O, config)) {
+ printf("OCD ");
+ }
+ if (bit_value(SYS, CONFIG0, S, config)) {
+ printf("SIMD ");
+ }
+ if (bit_value(SYS, CONFIG0, D, config)) {
+ printf("DSP ");
+ }
+ if (bit_value(SYS, CONFIG0, R, config)) {
+ printf("RMW");
+ }
+ printf("\n");
+ printf("real memory = %u (%u MB)\n", ptoa(realmem),
+ ptoa(realmem) / 1048576);
printf("avail memory = %u (%uMB)\n", ptoa(cnt.v_free_count),
ptoa(cnt.v_free_count) / 1048576);
==== //depot/projects/avr32/src/sys/avr32/avr32/nexus.c#2 (text+ko) ====
@@ -67,11 +67,16 @@
static int nexus_attach(device_t);
static int nexus_print_child(device_t, device_t);
static device_t nexus_add_child(device_t, int, const char *, int);
-static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int);
-static int nexus_release_resource(device_t, device_t, int, int, struct resource *);
-static int nexus_activate_resource(device_t, device_t, int, int, struct resource *);
-static int nexus_deactivate_resource(device_t, device_t, int, int, struct resource *);
-static int nexus_setup_intr(device_t, device_t, struct resource *, int flags, driver_filter_t filter, void (*)(void *), void *, void **);
+static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
+ u_long, u_long, u_long, u_int);
+static int nexus_release_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_activate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_deactivate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_setup_intr(device_t, device_t, struct resource *, int flags,
+ driver_filter_t filter, void (*)(void *), void *, void **);
static int nexus_teardown_intr(device_t, device_t, struct resource *, void *);
/* Nexus data */
@@ -96,70 +101,42 @@
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
{ 0, 0 }
};
-
static devclass_t nexus_devclass;
DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, 1);
DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
-static struct rman rman_irq; /**< IRQs */
-static struct rman rman_mem; /**< Memory addresses */
-
-static int nexus_probe(device_t dev) {
+/* Code */
+static int
+nexus_probe(device_t dev)
+{
device_set_desc(dev, "AVR32 root nexus");
- rman_mem.rm_start = 0;
- rman_mem.rm_end = ~0u;
- rman_mem.rm_type = RMAN_ARRAY;
- rman_mem.rm_descr = "Memory addresses";
- if (rman_init(&rman_mem) != 0 || rman_manage_region(&rman_mem, 0, ~0) != 0) {
- panic("%s: mem_rman", __func__);
- }
-
-/* rman_irq.rm_start = 0;
- rman_irq.rm_end = XXX;
- rman_irq.rm_type = RMAN_ARRAY;
- rman_irq.rm_descr = "Hardware IRQs";
- if (rman_init(&rman_irq) != 0 || rman_manage_region(&rman_irq, 0, XXX) != 0) {
- panic("%s: irq_rman", __func__);
- } */
-
- return 0;
+ return (0);
}
-static int nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) {
+static int
+nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
+ driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
+{
avr32_impl();
-/* int irq;
-
- if ((rman_get_flags(res) & RF_SHAREABLE) == 0)
- flags |= INTR_EXCL;
-
- for (i = rman_get_start(res); i <= rman_get_end(res); i++) {
- avr32_setup_irqhandler(device_get_nameunit(child), filt, intr, arg, i, flags, cookiep);
- }*/
- return 0;
+ return (0);
}
static int
nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
{
avr32_impl();
-/* int error;
- int i;
-
- error = avr32_remove_irqhandler(ih);
- return (error);*/
+ return (0);
}
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list