From owner-p4-projects@FreeBSD.ORG Sun Feb 8 23:42:02 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0BC4E1065672; Sun, 8 Feb 2009 23:42:02 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BE8F8106566C for ; Sun, 8 Feb 2009 23:42:01 +0000 (UTC) (envelope-from antab@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id ABBA18FC12 for ; Sun, 8 Feb 2009 23:42:01 +0000 (UTC) (envelope-from antab@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n18Ng18T053175 for ; Sun, 8 Feb 2009 23:42:01 GMT (envelope-from antab@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n18Ng1en053173 for perforce@freebsd.org; Sun, 8 Feb 2009 23:42:01 GMT (envelope-from antab@FreeBSD.org) Date: Sun, 8 Feb 2009 23:42:01 GMT Message-Id: <200902082342.n18Ng1en053173@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to antab@FreeBSD.org using -f From: Arnar Mar Sig To: Perforce Change Reviews Cc: Subject: PERFORCE change 157407 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 08 Feb 2009 23:42:03 -0000 http://perforce.freebsd.org/chv.cgi?CH=157407 Change 157407 by antab@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 #include #include +#include #include #include #include @@ -43,39 +44,66 @@ #include #include #include -#include +#include +#include #include #include /* 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 #include #include +#include #include #include #include @@ -42,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -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 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -49,16 +50,15 @@ #include #include #include -#include #include #include #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 #include #include +#include #include #include ==== //depot/projects/avr32/src/sys/avr32/avr32/cpu.c#4 (text+ko) ==== @@ -64,25 +64,13 @@ #include 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 +#include #include +#include #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",@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 #include #include +#include #include /* 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 #include #include +#include + +/* 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) <<<