Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Feb 2009 11:22:06 GMT
From:      Arnar Mar Sig <antab@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 157130 for review
Message-ID:  <200902041122.n14BM6KL005812@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=157130

Change 157130 by antab@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@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@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@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@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@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@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@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) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902041122.n14BM6KL005812>