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>