Remove Cavium/Econa CNS11xx support.
This port hasn't been updated since it was committed, apart from housekeeping. There's no known users, and the known hardware for this port is too thin to run FreeBSD/arm these days well. This also removes the last armv4 port. We've had no reports of armv4 systems working since FreeBSD 8. All the kernel support for armv4 has not been removed since it's too intertwined with armv5 support (which remains in the tree). RelNotes: Yes No objection from: arm@
This commit is contained in:
parent
58d5c51106
commit
848c22d7b1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=336771
@ -1,67 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Yohanes Nugroho <yohanes@gmail.com>
|
||||
* 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 AUTHOR ``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 AUTHOR 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/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/cfi/cfi_var.h>
|
||||
|
||||
#include <arm/cavium/cns11xx/econa_reg.h>
|
||||
#include <arm/cavium/cns11xx/econa_var.h>
|
||||
|
||||
static int
|
||||
cfi_econa_probe(device_t dev)
|
||||
{
|
||||
|
||||
return cfi_probe(dev);
|
||||
}
|
||||
|
||||
static device_method_t cfi_econa_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, cfi_econa_probe),
|
||||
DEVMETHOD(device_attach, cfi_attach),
|
||||
DEVMETHOD(device_detach, cfi_detach),
|
||||
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static driver_t cfi_econa_driver = {
|
||||
cfi_driver_name,
|
||||
cfi_econa_methods,
|
||||
sizeof(struct cfi_softc),
|
||||
};
|
||||
DRIVER_MODULE(cfi, econaarm, cfi_econa_driver, cfi_devclass, 0, 0);
|
@ -1,652 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Yohanes Nugroho <yohanes@gmail.com>
|
||||
* 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 AUTHOR 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 AUTHOR 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/bus.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#define _ARM32_BUS_DMA_PRIVATE
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/intr.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include "econa_reg.h"
|
||||
#include "econa_var.h"
|
||||
|
||||
static struct econa_softc *econa_softc;
|
||||
|
||||
unsigned int CPU_clock = 200000000;
|
||||
unsigned int AHB_clock;
|
||||
unsigned int APB_clock;
|
||||
|
||||
bus_space_tag_t obio_tag;
|
||||
|
||||
static int
|
||||
econa_probe(device_t dev)
|
||||
{
|
||||
|
||||
device_set_desc(dev, "ECONA device bus");
|
||||
return (BUS_PROBE_NOWILDCARD);
|
||||
}
|
||||
|
||||
static void
|
||||
econa_identify(driver_t *drv, device_t parent)
|
||||
{
|
||||
|
||||
BUS_ADD_CHILD(parent, 0, "econaarm", 0);
|
||||
}
|
||||
|
||||
struct arm32_dma_range *
|
||||
bus_dma_get_range(void)
|
||||
{
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
bus_dma_get_range_nb(void)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
extern void irq_entry(void);
|
||||
|
||||
static void
|
||||
econa_add_child(device_t dev, int prio, const char *name, int unit,
|
||||
bus_addr_t addr, bus_size_t size,
|
||||
int irq0, int irq1,
|
||||
int irq2, int irq3, int irq4)
|
||||
{
|
||||
device_t kid;
|
||||
struct econa_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);
|
||||
return;
|
||||
}
|
||||
device_set_ivars(kid, ivar);
|
||||
resource_list_init(&ivar->resources);
|
||||
if (irq0 != -1)
|
||||
bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
|
||||
if (irq1 != 0)
|
||||
bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
|
||||
if (irq2 != 0)
|
||||
bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
|
||||
if (irq3 != 0)
|
||||
bus_set_resource(kid, SYS_RES_IRQ, 3, irq3, 1);
|
||||
if (irq4 != 0)
|
||||
bus_set_resource(kid, SYS_RES_IRQ, 4, irq4, 1);
|
||||
|
||||
if (addr != 0)
|
||||
bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
|
||||
|
||||
}
|
||||
|
||||
struct cpu_devs
|
||||
{
|
||||
const char *name;
|
||||
int unit;
|
||||
bus_addr_t mem_base;
|
||||
bus_size_t mem_len;
|
||||
int irq0;
|
||||
int irq1;
|
||||
int irq2;
|
||||
int irq3;
|
||||
int irq4;
|
||||
};
|
||||
|
||||
struct cpu_devs econarm_devs[] =
|
||||
{
|
||||
{
|
||||
"econa_ic", 0,
|
||||
ECONA_IO_BASE + ECONA_PIC_BASE, ECONA_PIC_SIZE,
|
||||
0
|
||||
},
|
||||
{
|
||||
"system", 0,
|
||||
ECONA_IO_BASE + ECONA_SYSTEM_BASE, ECONA_SYSTEM_SIZE,
|
||||
0
|
||||
},
|
||||
{
|
||||
"uart", 0,
|
||||
ECONA_IO_BASE + ECONA_UART_BASE, ECONA_UART_SIZE,
|
||||
ECONA_IRQ_UART
|
||||
},
|
||||
{
|
||||
"timer", 0,
|
||||
ECONA_IO_BASE + ECONA_TIMER_BASE, ECONA_TIMER_SIZE,
|
||||
ECONA_IRQ_TIMER_1, ECONA_IRQ_TIMER_2
|
||||
},
|
||||
{
|
||||
"ohci", 0,
|
||||
ECONA_OHCI_VBASE, ECONA_OHCI_SIZE,
|
||||
ECONA_IRQ_OHCI
|
||||
},
|
||||
{
|
||||
"ehci", 0,
|
||||
ECONA_EHCI_VBASE, ECONA_EHCI_SIZE,
|
||||
ECONA_IRQ_EHCI
|
||||
},
|
||||
{
|
||||
"cfi", 0,
|
||||
ECONA_CFI_VBASE, ECONA_CFI_SIZE,
|
||||
0
|
||||
},
|
||||
{
|
||||
"ece", 0,
|
||||
ECONA_IO_BASE + ECONA_NET_BASE, ECONA_NET_SIZE,
|
||||
ECONA_IRQ_STATUS,
|
||||
ECONA_IRQ_TSTC, ECONA_IRQ_FSRC,
|
||||
ECONA_IRQ_TSQE, ECONA_IRQ_FSQF,
|
||||
},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static void
|
||||
econa_cpu_add_builtin_children(device_t dev, struct econa_softc *sc)
|
||||
{
|
||||
int i;
|
||||
struct cpu_devs *walker;
|
||||
|
||||
for (i = 0, walker = econarm_devs; walker->name; i++, walker++) {
|
||||
econa_add_child(dev, i, walker->name, walker->unit,
|
||||
walker->mem_base, walker->mem_len,
|
||||
walker->irq0,walker->irq1, walker->irq2,
|
||||
walker->irq3, walker->irq4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct intc_trigger_t {
|
||||
int mode;
|
||||
int level;
|
||||
};
|
||||
|
||||
static struct intc_trigger_t intc_trigger_table[] = {
|
||||
{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
|
||||
{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
|
||||
{INTC_EDGE_TRIGGER, INTC_FALLING_EDGE},
|
||||
{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
|
||||
{INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
|
||||
{INTC_LEVEL_TRIGGER, INTC_ACTIVE_LOW},
|
||||
{INTC_LEVEL_TRIGGER, INTC_ACTIVE_LOW},
|
||||
{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
|
||||
{INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
|
||||
{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
|
||||
{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
|
||||
{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
|
||||
{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
|
||||
{INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
|
||||
{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
|
||||
{INTC_EDGE_TRIGGER, INTC_FALLING_EDGE},
|
||||
{INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
|
||||
{INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
|
||||
{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
|
||||
{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
|
||||
{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
|
||||
{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
|
||||
{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
|
||||
{INTC_LEVEL_TRIGGER, INTC_ACTIVE_LOW},
|
||||
{INTC_LEVEL_TRIGGER, INTC_ACTIVE_LOW},
|
||||
};
|
||||
|
||||
static inline uint32_t
|
||||
read_4(struct econa_softc *sc, bus_size_t off)
|
||||
{
|
||||
|
||||
return bus_space_read_4(sc->ec_st, sc->ec_sys_sh, off);
|
||||
}
|
||||
|
||||
static inline void
|
||||
write_4(struct econa_softc *sc, bus_size_t off, uint32_t val)
|
||||
{
|
||||
|
||||
return bus_space_write_4(sc->ec_st, sc->ec_sys_sh, off, val);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
system_read_4(struct econa_softc *sc, bus_size_t off)
|
||||
{
|
||||
|
||||
return bus_space_read_4(sc->ec_st, sc->ec_system_sh, off);
|
||||
}
|
||||
|
||||
static inline void
|
||||
system_write_4(struct econa_softc *sc, bus_size_t off, uint32_t val)
|
||||
{
|
||||
|
||||
return bus_space_write_4(sc->ec_st, sc->ec_system_sh, off, val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline void
|
||||
econa_set_irq_mode(struct econa_softc * sc, unsigned int irq,
|
||||
unsigned int mode)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
if ((mode != INTC_LEVEL_TRIGGER) && (mode != INTC_EDGE_TRIGGER))
|
||||
return;
|
||||
|
||||
val = read_4(sc, INTC_INTERRUPT_TRIGGER_MODE_REG_OFFSET);
|
||||
|
||||
if (mode == INTC_LEVEL_TRIGGER) {
|
||||
if (val & (1UL << irq)) {
|
||||
val &= ~(1UL << irq);
|
||||
write_4(sc, INTC_INTERRUPT_TRIGGER_MODE_REG_OFFSET,
|
||||
val);
|
||||
}
|
||||
} else {
|
||||
if (!(val & (1UL << irq))) {
|
||||
val |= (1UL << irq);
|
||||
write_4(sc, INTC_INTERRUPT_TRIGGER_MODE_REG_OFFSET,
|
||||
val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure interrupt trigger level to be Active High/Low
|
||||
* or Rising/Falling Edge
|
||||
*/
|
||||
static inline void
|
||||
econa_set_irq_level(struct econa_softc * sc,
|
||||
unsigned int irq, unsigned int level)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
if ((level != INTC_ACTIVE_HIGH) &&
|
||||
(level != INTC_ACTIVE_LOW) &&
|
||||
(level != INTC_RISING_EDGE) &&
|
||||
(level != INTC_FALLING_EDGE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
val = read_4(sc, INTC_INTERRUPT_TRIGGER_LEVEL_REG_OFFSET);
|
||||
|
||||
if ((level == INTC_ACTIVE_HIGH) || (level == INTC_RISING_EDGE)) {
|
||||
if (val & (1UL << irq)) {
|
||||
val &= ~(1UL << irq);
|
||||
write_4(sc, INTC_INTERRUPT_TRIGGER_LEVEL_REG_OFFSET,
|
||||
val);
|
||||
}
|
||||
} else {
|
||||
if (!(val & (1UL << irq))) {
|
||||
val |= (1UL << irq);
|
||||
write_4(sc, INTC_INTERRUPT_TRIGGER_LEVEL_REG_OFFSET,
|
||||
val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_system_clock(void)
|
||||
{
|
||||
uint32_t sclock = system_read_4(econa_softc, SYSTEM_CLOCK);
|
||||
|
||||
sclock = (sclock >> 6) & 0x03;
|
||||
|
||||
switch (sclock) {
|
||||
case 0:
|
||||
CPU_clock = 175000000;
|
||||
break;
|
||||
case 1:
|
||||
CPU_clock = 200000000;
|
||||
break;
|
||||
case 2:
|
||||
CPU_clock = 225000000;
|
||||
break;
|
||||
case 3:
|
||||
CPU_clock = 250000000;
|
||||
break;
|
||||
}
|
||||
AHB_clock = CPU_clock >> 1;
|
||||
APB_clock = AHB_clock >> 1;
|
||||
}
|
||||
|
||||
static int
|
||||
econa_attach(device_t dev)
|
||||
{
|
||||
struct econa_softc *sc = device_get_softc(dev);
|
||||
int i;
|
||||
|
||||
obio_tag = arm_base_bs_tag;
|
||||
|
||||
econa_softc = sc;
|
||||
sc->ec_st = arm_base_bs_tag;
|
||||
sc->ec_sh = ECONA_IO_BASE;
|
||||
sc->dev = dev;
|
||||
if (bus_space_subregion(sc->ec_st, sc->ec_sh, ECONA_PIC_BASE,
|
||||
ECONA_PIC_SIZE, &sc->ec_sys_sh) != 0)
|
||||
panic("Unable to map IRQ registers");
|
||||
|
||||
if (bus_space_subregion(sc->ec_st, sc->ec_sh, ECONA_SYSTEM_BASE,
|
||||
ECONA_SYSTEM_SIZE, &sc->ec_system_sh) != 0)
|
||||
panic("Unable to map IRQ registers");
|
||||
|
||||
sc->ec_irq_rman.rm_type = RMAN_ARRAY;
|
||||
sc->ec_irq_rman.rm_descr = "ECONA IRQs";
|
||||
sc->ec_mem_rman.rm_type = RMAN_ARRAY;
|
||||
sc->ec_mem_rman.rm_descr = "ECONA Memory";
|
||||
if (rman_init(&sc->ec_irq_rman) != 0 ||
|
||||
rman_manage_region(&sc->ec_irq_rman, 0, 31) != 0)
|
||||
panic("econa_attach: failed to set up IRQ rman");
|
||||
if (rman_init(&sc->ec_mem_rman) != 0 ||
|
||||
rman_manage_region(&sc->ec_mem_rman, 0,
|
||||
~0) != 0)
|
||||
panic("econa_attach: failed to set up memory rman");
|
||||
|
||||
write_4(sc, INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG_OFFSET, 0xffffffff);
|
||||
|
||||
write_4(sc, INTC_INTERRUPT_MASK_REG_OFFSET, 0xffffffff);
|
||||
|
||||
write_4(sc, INTC_FIQ_MODE_SELECT_REG_OFFSET, 0);
|
||||
|
||||
/*initialize irq*/
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (intc_trigger_table[i].mode != INTC_TRIGGER_UNKNOWN) {
|
||||
econa_set_irq_mode(sc,i, intc_trigger_table[i].mode);
|
||||
econa_set_irq_level(sc, i, intc_trigger_table[i].level);
|
||||
}
|
||||
}
|
||||
|
||||
get_system_clock();
|
||||
|
||||
econa_cpu_add_builtin_children(dev, sc);
|
||||
|
||||
bus_generic_probe(dev);
|
||||
bus_generic_attach(dev);
|
||||
enable_interrupts(PSR_I | PSR_F);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct resource *
|
||||
econa_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
|
||||
{
|
||||
struct econa_softc *sc = device_get_softc(dev);
|
||||
struct resource_list_entry *rle;
|
||||
struct econa_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 (RMAN_IS_DEFAULT_RANGE(start, end)) {
|
||||
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->ec_irq_rman,
|
||||
start, end, count, flags, child);
|
||||
break;
|
||||
case SYS_RES_MEMORY:
|
||||
rle->res = rman_reserve_resource(&sc->ec_mem_rman,
|
||||
start, end, count, flags, child);
|
||||
if (rle->res != NULL) {
|
||||
rman_set_bustag(rle->res, arm_base_bs_tag);
|
||||
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 struct resource_list *
|
||||
econa_get_resource_list(device_t dev, device_t child)
|
||||
{
|
||||
struct econa_ivar *ivar;
|
||||
ivar = device_get_ivars(child);
|
||||
return (&(ivar->resources));
|
||||
}
|
||||
|
||||
static int
|
||||
econa_release_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct resource *r)
|
||||
{
|
||||
struct resource_list *rl;
|
||||
struct resource_list_entry *rle;
|
||||
|
||||
rl = econa_get_resource_list(dev, child);
|
||||
if (rl == NULL)
|
||||
return (EINVAL);
|
||||
rle = resource_list_find(rl, type, rid);
|
||||
if (rle == NULL)
|
||||
return (EINVAL);
|
||||
rman_release_resource(r);
|
||||
rle->res = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
econa_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)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (rman_get_start(ires) == ECONA_IRQ_SYSTEM && filt == NULL)
|
||||
panic("All system interrupt ISRs must be FILTER");
|
||||
|
||||
error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
|
||||
filt, intr, arg, cookiep);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
econa_teardown_intr(device_t dev, device_t child, struct resource *res,
|
||||
void *cookie)
|
||||
{
|
||||
|
||||
return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
|
||||
}
|
||||
|
||||
static int
|
||||
econa_activate_resource(device_t bus, device_t child, int type, int rid,
|
||||
struct resource *r)
|
||||
{
|
||||
|
||||
return (rman_activate_resource(r));
|
||||
}
|
||||
|
||||
static int
|
||||
econa_print_child(device_t dev, device_t child)
|
||||
{
|
||||
struct econa_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 += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#jx");
|
||||
retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
|
||||
retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd");
|
||||
if (device_get_flags(dev))
|
||||
retval += printf(" flags %#x", device_get_flags(dev));
|
||||
|
||||
retval += bus_print_child_footer(dev, child);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
void
|
||||
arm_mask_irq(uintptr_t nb)
|
||||
{
|
||||
unsigned int value;
|
||||
|
||||
value = read_4(econa_softc,INTC_INTERRUPT_MASK_REG_OFFSET) | 1<<nb;
|
||||
write_4(econa_softc, INTC_INTERRUPT_MASK_REG_OFFSET, value);
|
||||
}
|
||||
|
||||
void
|
||||
arm_unmask_irq(uintptr_t nb)
|
||||
{
|
||||
unsigned int value;
|
||||
|
||||
value = read_4(econa_softc,
|
||||
INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG_OFFSET) | (1 << nb);
|
||||
write_4(econa_softc,
|
||||
INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG_OFFSET, value);
|
||||
value = read_4(econa_softc, INTC_INTERRUPT_MASK_REG_OFFSET)& ~(1 << nb);
|
||||
write_4(econa_softc, INTC_INTERRUPT_MASK_REG_OFFSET, value);
|
||||
}
|
||||
|
||||
int
|
||||
arm_get_next_irq(int x)
|
||||
{
|
||||
int irq;
|
||||
|
||||
irq = read_4(econa_softc, INTC_INTERRUPT_STATUS_REG_OFFSET) &
|
||||
~(read_4(econa_softc, INTC_INTERRUPT_MASK_REG_OFFSET));
|
||||
|
||||
if (irq!=0) {
|
||||
return (ffs(irq) - 1);
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_reset(void)
|
||||
{
|
||||
uint32_t control;
|
||||
|
||||
control = system_read_4(econa_softc, RESET_CONTROL);
|
||||
control |= GLOBAL_RESET;
|
||||
system_write_4(econa_softc, RESET_CONTROL, control);
|
||||
control = system_read_4(econa_softc, RESET_CONTROL);
|
||||
control &= (~(GLOBAL_RESET));
|
||||
system_write_4(econa_softc, RESET_CONTROL, control);
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
power_on_network_interface(void)
|
||||
{
|
||||
uint32_t cfg_reg;
|
||||
int ii;
|
||||
|
||||
cfg_reg = system_read_4(econa_softc, RESET_CONTROL);
|
||||
cfg_reg |= NET_INTERFACE_RESET;
|
||||
/* set reset bit to HIGH active; */
|
||||
system_write_4(econa_softc, RESET_CONTROL, cfg_reg);
|
||||
|
||||
/*pulse delay */
|
||||
for (ii = 0; ii < 0xFFF; ii++)
|
||||
DELAY(100);
|
||||
/* set reset bit to LOW active; */
|
||||
cfg_reg = system_read_4(econa_softc, RESET_CONTROL);
|
||||
cfg_reg &= ~(NET_INTERFACE_RESET);
|
||||
system_write_4(econa_softc, RESET_CONTROL, cfg_reg);
|
||||
|
||||
/*pulse delay */
|
||||
for (ii = 0; ii < 0xFFF; ii++)
|
||||
DELAY(100);
|
||||
cfg_reg = system_read_4(econa_softc, RESET_CONTROL);
|
||||
cfg_reg |= NET_INTERFACE_RESET;
|
||||
/* set reset bit to HIGH active; */
|
||||
system_write_4(econa_softc, RESET_CONTROL, cfg_reg);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
get_tclk(void)
|
||||
{
|
||||
|
||||
return CPU_clock;
|
||||
}
|
||||
|
||||
static device_method_t econa_methods[] = {
|
||||
DEVMETHOD(device_probe, econa_probe),
|
||||
DEVMETHOD(device_attach, econa_attach),
|
||||
DEVMETHOD(device_identify, econa_identify),
|
||||
DEVMETHOD(bus_alloc_resource, econa_alloc_resource),
|
||||
DEVMETHOD(bus_setup_intr, econa_setup_intr),
|
||||
DEVMETHOD(bus_teardown_intr, econa_teardown_intr),
|
||||
DEVMETHOD(bus_activate_resource, econa_activate_resource),
|
||||
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
|
||||
DEVMETHOD(bus_get_resource_list, econa_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, econa_release_resource),
|
||||
DEVMETHOD(bus_print_child, econa_print_child),
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static driver_t econa_driver = {
|
||||
"econaarm",
|
||||
econa_methods,
|
||||
sizeof(struct econa_softc),
|
||||
};
|
||||
static devclass_t econa_devclass;
|
||||
|
||||
DRIVER_MODULE(econaarm, nexus, econa_driver, econa_devclass, 0, 0);
|
@ -1,336 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Yohanes Nugroho <yohanes@gmail.com>
|
||||
* Copyright (c) 1994-1998 Mark Brinicombe.
|
||||
* Copyright (c) 1994 Brini.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software written for Brini by Mark Brinicombe
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Brini.
|
||||
* 4. The name of the company nor the name of the author may be used to
|
||||
* endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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 "opt_kstack_pages.h"
|
||||
|
||||
#define _ARM32_BUS_DMA_PRIVATE
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/imgact.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/ktr.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/msgbuf.h>
|
||||
#include <sys/devmap.h>
|
||||
#include <machine/physmem.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_object.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <machine/vmparam.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/undefined.h>
|
||||
#include <machine/machdep.h>
|
||||
#include <machine/metadata.h>
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/bus.h>
|
||||
#include <sys/reboot.h>
|
||||
#include "econa_reg.h"
|
||||
|
||||
/* Page table for mapping proc0 zero page */
|
||||
#define KERNEL_PT_SYS 0
|
||||
#define KERNEL_PT_KERN 1
|
||||
#define KERNEL_PT_KERN_NUM 22
|
||||
/* L2 table for mapping after kernel */
|
||||
#define KERNEL_PT_AFKERNEL KERNEL_PT_KERN + KERNEL_PT_KERN_NUM
|
||||
#define KERNEL_PT_AFKERNEL_NUM 5
|
||||
|
||||
/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
|
||||
#define NUM_KERNEL_PTS (KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
|
||||
|
||||
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
|
||||
|
||||
/* Physical and virtual addresses for some global pages */
|
||||
|
||||
struct pv_addr systempage;
|
||||
struct pv_addr msgbufpv;
|
||||
struct pv_addr irqstack;
|
||||
struct pv_addr undstack;
|
||||
struct pv_addr abtstack;
|
||||
struct pv_addr kernelstack;
|
||||
|
||||
/* Static device mappings. */
|
||||
static const struct devmap_entry econa_devmap[] = {
|
||||
{
|
||||
/*
|
||||
* This maps DDR SDRAM
|
||||
*/
|
||||
ECONA_SDRAM_BASE, /*virtual*/
|
||||
ECONA_SDRAM_BASE, /*physical*/
|
||||
ECONA_SDRAM_SIZE, /*size*/
|
||||
},
|
||||
/*
|
||||
* Map the on-board devices VA == PA so that we can access them
|
||||
* with the MMU on or off.
|
||||
*/
|
||||
{
|
||||
/*
|
||||
* This maps the interrupt controller, the UART
|
||||
* and the timer.
|
||||
*/
|
||||
ECONA_IO_BASE, /*virtual*/
|
||||
ECONA_IO_BASE, /*physical*/
|
||||
ECONA_IO_SIZE, /*size*/
|
||||
},
|
||||
{
|
||||
/*
|
||||
* OHCI + EHCI
|
||||
*/
|
||||
ECONA_OHCI_VBASE, /*virtual*/
|
||||
ECONA_OHCI_PBASE, /*physical*/
|
||||
ECONA_USB_SIZE, /*size*/
|
||||
},
|
||||
{
|
||||
/*
|
||||
* CFI
|
||||
*/
|
||||
ECONA_CFI_VBASE, /*virtual*/
|
||||
ECONA_CFI_PBASE, /*physical*/
|
||||
ECONA_CFI_SIZE,
|
||||
},
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void *
|
||||
initarm(struct arm_boot_params *abp)
|
||||
{
|
||||
struct pv_addr kernel_l1pt;
|
||||
volatile uint32_t * ddr = (uint32_t *)0x4000000C;
|
||||
int loop, i;
|
||||
u_int l1pagetable;
|
||||
vm_offset_t afterkern;
|
||||
vm_offset_t freemempos;
|
||||
vm_offset_t lastaddr;
|
||||
uint32_t memsize;
|
||||
int mem_info;
|
||||
|
||||
boothowto = RB_VERBOSE;
|
||||
lastaddr = parse_boot_param(abp);
|
||||
arm_physmem_kernaddr = abp->abp_physaddr;
|
||||
set_cpufuncs();
|
||||
pcpu0_init();
|
||||
|
||||
/* Do basic tuning, hz etc */
|
||||
init_param1();
|
||||
|
||||
|
||||
freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK;
|
||||
/* Define a macro to simplify memory allocation */
|
||||
#define valloc_pages(var, np) \
|
||||
alloc_pages((var).pv_va, (np)); \
|
||||
(var).pv_pa = (var).pv_va + (abp->abp_physaddr - KERNVIRTADDR);
|
||||
|
||||
#define alloc_pages(var, np) \
|
||||
(var) = freemempos; \
|
||||
freemempos += (np * PAGE_SIZE); \
|
||||
memset((char *)(var), 0, ((np) * PAGE_SIZE));
|
||||
|
||||
while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
|
||||
freemempos += PAGE_SIZE;
|
||||
valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
|
||||
for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
|
||||
if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
|
||||
valloc_pages(kernel_pt_table[loop],
|
||||
L2_TABLE_SIZE / PAGE_SIZE);
|
||||
} else {
|
||||
kernel_pt_table[loop].pv_va = freemempos -
|
||||
(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
|
||||
L2_TABLE_SIZE_REAL;
|
||||
kernel_pt_table[loop].pv_pa =
|
||||
kernel_pt_table[loop].pv_va - KERNVIRTADDR +
|
||||
abp->abp_physaddr;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Allocate a page for the system page mapped to V0x00000000
|
||||
* This page will just contain the system vectors and can be
|
||||
* shared by all processes.
|
||||
*/
|
||||
valloc_pages(systempage, 1);
|
||||
|
||||
/* Allocate stacks for all modes */
|
||||
valloc_pages(irqstack, IRQ_STACK_SIZE);
|
||||
valloc_pages(abtstack, ABT_STACK_SIZE);
|
||||
valloc_pages(undstack, UND_STACK_SIZE);
|
||||
valloc_pages(kernelstack, kstack_pages);
|
||||
valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
|
||||
|
||||
/*
|
||||
* Now we start construction of the L1 page table
|
||||
* We start by mapping the L2 page tables into the L1.
|
||||
* This means that we can replace L1 mappings later on if necessary
|
||||
*/
|
||||
l1pagetable = kernel_l1pt.pv_va;
|
||||
|
||||
/* Map the L2 pages tables in the L1 page table */
|
||||
pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH,
|
||||
&kernel_pt_table[KERNEL_PT_SYS]);
|
||||
for (i = 0; i < KERNEL_PT_KERN_NUM; i++)
|
||||
pmap_link_l2pt(l1pagetable, KERNBASE + i * L1_S_SIZE,
|
||||
&kernel_pt_table[KERNEL_PT_KERN + i]);
|
||||
pmap_map_chunk(l1pagetable, KERNBASE, PHYSADDR,
|
||||
rounddown2(((uint32_t)lastaddr - KERNBASE) + PAGE_SIZE, PAGE_SIZE),
|
||||
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
afterkern = round_page(rounddown2(lastaddr + L1_S_SIZE, L1_S_SIZE));
|
||||
for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
|
||||
pmap_link_l2pt(l1pagetable, afterkern + i * L1_S_SIZE,
|
||||
&kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
|
||||
}
|
||||
|
||||
/* Map the vector page. */
|
||||
pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
|
||||
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
|
||||
/* Map the stack pages */
|
||||
pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
|
||||
IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
|
||||
ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
|
||||
UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
|
||||
kstack_pages * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
|
||||
L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
|
||||
pmap_map_chunk(l1pagetable, msgbufpv.pv_va, msgbufpv.pv_pa,
|
||||
msgbufsize, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
|
||||
pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
|
||||
kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
|
||||
VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
|
||||
}
|
||||
|
||||
devmap_bootstrap(l1pagetable, econa_devmap);
|
||||
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
|
||||
cpu_setttb(kernel_l1pt.pv_pa);
|
||||
cpu_tlb_flushID();
|
||||
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
|
||||
cninit();
|
||||
mem_info = ((*ddr) >> 4) & 0x3;
|
||||
memsize = (8<<mem_info)*1024*1024;
|
||||
|
||||
/* Enable MMU in system control register (SCTLR). */
|
||||
cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
|
||||
|
||||
/*
|
||||
* Pages were allocated during the secondary bootstrap for the
|
||||
* stacks for different CPU modes.
|
||||
* We must now set the r13 registers in the different CPU modes to
|
||||
* point to these stacks.
|
||||
* Since the ARM stacks use STMFD etc. we must set r13 to the top end
|
||||
* of the stack memory.
|
||||
*/
|
||||
set_stackptrs(0);
|
||||
|
||||
/*
|
||||
* We must now clean the cache again....
|
||||
* Cleaning may be done by reading new data to displace any
|
||||
* dirty data in the cache. This will have happened in cpu_setttb()
|
||||
* but since we are boot strapping the addresses used for the read
|
||||
* may have just been remapped and thus the cache could be out
|
||||
* of sync. A re-clean after the switch will cure this.
|
||||
* After booting there are no gross relocations of the kernel thus
|
||||
* this problem will not occur after initarm().
|
||||
*/
|
||||
cpu_idcache_wbinv_all();
|
||||
cpu_setup();
|
||||
|
||||
undefined_init();
|
||||
|
||||
init_proc0(kernelstack.pv_va);
|
||||
|
||||
arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
|
||||
|
||||
pmap_curmaxkvaddr = afterkern + L1_S_SIZE * (KERNEL_PT_KERN_NUM - 1);
|
||||
vm_max_kernel_address = KERNVIRTADDR + 3 * memsize;
|
||||
pmap_bootstrap(freemempos, &kernel_l1pt);
|
||||
|
||||
msgbufp = (void*)msgbufpv.pv_va;
|
||||
msgbufinit(msgbufp, msgbufsize);
|
||||
|
||||
mutex_init();
|
||||
|
||||
/*
|
||||
* Add the physical ram we have available.
|
||||
*
|
||||
* Exclude the kernel, and all the things we allocated which immediately
|
||||
* follow the kernel, from the VM allocation pool but not from crash
|
||||
* dumps. virtual_avail is a global variable which tracks the kva we've
|
||||
* "allocated" while setting up pmaps.
|
||||
*
|
||||
* Prepare the list of physical memory available to the vm subsystem.
|
||||
*/
|
||||
arm_physmem_hardware_region(PHYSADDR, memsize);
|
||||
arm_physmem_exclude_region(abp->abp_physaddr,
|
||||
virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC);
|
||||
arm_physmem_init_kernel_globals();
|
||||
|
||||
init_param2(physmem);
|
||||
kdb_init();
|
||||
|
||||
return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
|
||||
sizeof(struct pcb)));
|
||||
}
|
@ -1,180 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Yohanes Nugroho <yohanes@gmail.com>
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _ARM_ECONA_REG_H
|
||||
#define _ARM_ECONA_REG_H
|
||||
|
||||
#define ECONA_SRAM_SIZE 0x10000000
|
||||
#define ECONA_DRAM_BASE 0x00000000 /* DRAM (via DDR Control Module) */
|
||||
|
||||
#define ECONA_SDRAM_BASE 0x40000000
|
||||
#define ECONA_SDRAM_SIZE 0x1000000
|
||||
|
||||
|
||||
#define ECONA_IO_BASE 0x70000000
|
||||
#define ECONA_IO_SIZE 0x0E000000
|
||||
#define ECONA_PIC_BASE 0x0D000000
|
||||
#define ECONA_PIC_SIZE 0x01000000
|
||||
|
||||
#define ECONA_UART_BASE 0x08000000
|
||||
#define ECONA_UART_SIZE 0x01000000
|
||||
#define ECONA_IRQ_UART 0xA
|
||||
|
||||
#define ECONA_TIMER_BASE 0x09000000
|
||||
#define ECONA_TIMER_SIZE 0x01000000
|
||||
#define ECONA_IRQ_TIMER_1 0
|
||||
#define ECONA_IRQ_TIMER_2 1
|
||||
#define ECONA_IRQ_OHCI 23
|
||||
#define ECONA_IRQ_EHCI 24
|
||||
|
||||
#define ECONA_NET_BASE 0x00000000
|
||||
|
||||
#define ECONA_SYSTEM_BASE 0x07000000
|
||||
#define ECONA_SYSTEM_SIZE 0x01000000
|
||||
|
||||
#define ECONA_NET_SIZE 0x01000000
|
||||
|
||||
#define ECONA_CFI_PBASE 0x10000000
|
||||
#define ECONA_CFI_VBASE 0xD0000000
|
||||
#define ECONA_CFI_SIZE 0x10000000
|
||||
|
||||
#define ECONA_IRQ_STATUS 18
|
||||
#define ECONA_IRQ_TSTC 19
|
||||
#define ECONA_IRQ_FSRC 20
|
||||
#define ECONA_IRQ_TSQE 21
|
||||
#define ECONA_IRQ_FSQF 22
|
||||
|
||||
#define ECONA_IRQ_SYSTEM 0
|
||||
|
||||
#define ECONA_EHCI_PBASE 0xC8000000
|
||||
#define ECONA_EHCI_VBASE 0xF8000000
|
||||
#define ECONA_EHCI_SIZE 0x8000000
|
||||
|
||||
#define ECONA_OHCI_PBASE 0xC0000000
|
||||
#define ECONA_OHCI_VBASE 0xF0000000
|
||||
#define ECONA_OHCI_SIZE 0x8000000
|
||||
|
||||
#define ECONA_USB_SIZE 0xf000000
|
||||
|
||||
/*Interrupt controller*/
|
||||
#define INTC_LEVEL_TRIGGER 0
|
||||
#define INTC_EDGE_TRIGGER 1
|
||||
#define INTC_ACTIVE_HIGH 0
|
||||
#define INTC_ACTIVE_LOW 1
|
||||
/*
|
||||
* define rising/falling edge for edge trigger mode
|
||||
*/
|
||||
#define INTC_RISING_EDGE 0
|
||||
#define INTC_FALLING_EDGE 1
|
||||
|
||||
#define INTC_INTERRUPT_SOURCE_REG_OFFSET 0x00
|
||||
#define INTC_INTERRUPT_MASK_REG_OFFSET 0x04
|
||||
#define INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG_OFFSET 0x08
|
||||
#define INTC_INTERRUPT_TRIGGER_MODE_REG_OFFSET 0x0C
|
||||
#define INTC_INTERRUPT_TRIGGER_LEVEL_REG_OFFSET 0x10
|
||||
#define INTC_INTERRUPT_STATUS_REG_OFFSET 0x14
|
||||
#define INTC_FIQ_MODE_SELECT_REG_OFFSET 0x18
|
||||
#define INTC_SOFTWARE_INTERRUPT_REG_OFFSET 0x1C
|
||||
|
||||
|
||||
/*
|
||||
* define rising/falling edge for edge trigger mode
|
||||
*/
|
||||
#define INTC_RISING_EDGE 0
|
||||
#define INTC_FALLING_EDGE 1
|
||||
|
||||
|
||||
#define TIMER_TM1_COUNTER_REG 0x00
|
||||
#define TIMER_TM1_LOAD_REG 0x04
|
||||
#define TIMER_TM1_MATCH1_REG 0x08
|
||||
#define TIMER_TM1_MATCH2_REG 0x0C
|
||||
|
||||
#define TIMER_TM2_COUNTER_REG 0x10
|
||||
#define TIMER_TM2_LOAD_REG 0x14
|
||||
#define TIMER_TM2_MATCH1_REG 0x18
|
||||
#define TIMER_TM2_MATCH2_REG 0x1C
|
||||
|
||||
#define TIMER_TM_CR_REG 0x30
|
||||
#define TIMER_TM_INTR_STATUS_REG 0x34
|
||||
#define TIMER_TM_INTR_MASK_REG 0x38
|
||||
|
||||
#define TIMER_TM_REVISION_REG 0x3C
|
||||
|
||||
|
||||
#define INTC_TIMER1_BIT_INDEX 0
|
||||
|
||||
#define TIMER1_UP_DOWN_COUNT (1<<9)
|
||||
#define TIMER2_UP_DOWN_COUNT (1<<10)
|
||||
|
||||
#define TIMER1_MATCH1_INTR (1<<0)
|
||||
#define TIMER1_MATCH2_INTR (1<<1)
|
||||
#define TIMER1_OVERFLOW_INTR (1<<2)
|
||||
|
||||
|
||||
#define TIMER2_MATCH1_INTR (1<<3)
|
||||
#define TIMER2_MATCH2_INTR (1<<4)
|
||||
#define TIMER2_OVERFLOW_INTR (1<<5)
|
||||
|
||||
|
||||
#define TIMER_CLOCK_SOURCE_PCLK 0
|
||||
#define TIMER_CLOCK_SOURCE_EXT_CLK 1
|
||||
|
||||
/*
|
||||
* define interrupt trigger mode
|
||||
*/
|
||||
#define INTC_LEVEL_TRIGGER 0
|
||||
#define INTC_EDGE_TRIGGER 1
|
||||
|
||||
|
||||
#define INTC_TRIGGER_UNKNOWN -1
|
||||
|
||||
#define TIMER1_OVERFLOW_INTERRUPT (1<<2)
|
||||
#define TIMER2_OVERFLOW_INTERRUPT (1<<5)
|
||||
#define TIMER_INTERRUPT_STATUS_REG 0x34
|
||||
|
||||
|
||||
#define TIMER1_ENABLE (1<<0)
|
||||
#define TIMER1_CLOCK_SOURCE (1<<1)
|
||||
#define TIMER1_OVERFLOW_ENABLE (1<<2)
|
||||
|
||||
|
||||
#define TIMER2_ENABLE (1<<3)
|
||||
#define TIMER2_CLOCK_SOURCE (1<<4)
|
||||
#define TIMER2_OVERFLOW_ENABLE (1<<5)
|
||||
|
||||
|
||||
#define TIMER_1 1
|
||||
|
||||
#define EC_UART_CLOCK 14769200
|
||||
#define EC_UART_REGSHIFT 2
|
||||
|
||||
#define SYSTEM_CLOCK 0x14
|
||||
#define RESET_CONTROL 0x4
|
||||
#define GLOBAL_RESET 0x1
|
||||
#define NET_INTERFACE_RESET (0x1 << 4)
|
||||
|
||||
#endif
|
@ -1,52 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Yohanes Nugroho <yohanes@gmail.com>.
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ARM_ECONA_VAR_H
|
||||
#define _ARM_ECONA_VAR_H
|
||||
|
||||
extern bus_space_tag_t obio_tag;
|
||||
|
||||
struct econa_softc {
|
||||
device_t dev;
|
||||
bus_space_tag_t ec_st;
|
||||
bus_space_handle_t ec_sh;
|
||||
bus_space_handle_t ec_sys_sh;
|
||||
bus_space_handle_t ec_system_sh;
|
||||
struct rman ec_irq_rman;
|
||||
struct rman ec_mem_rman;
|
||||
};
|
||||
|
||||
struct econa_ivar {
|
||||
struct resource_list resources;
|
||||
};
|
||||
|
||||
void power_on_network_interface (void);
|
||||
unsigned int get_tclk (void);
|
||||
|
||||
|
||||
#endif
|
@ -1,248 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2009 Yohanes Nugroho <yohanes@gmail.com>
|
||||
* based on ehci_mbus.c
|
||||
* Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
|
||||
* 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.
|
||||
* 3. Neither the name of MARVELL nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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 "opt_bus.h"
|
||||
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <sys/stdint.h>
|
||||
#include <sys/stddef.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/priv.h>
|
||||
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbdi.h>
|
||||
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_busdma.h>
|
||||
#include <dev/usb/usb_process.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#include <dev/usb/usb_controller.h>
|
||||
#include <dev/usb/usb_bus.h>
|
||||
#include <dev/usb/controller/ehci.h>
|
||||
#include <dev/usb/controller/ehcireg.h>
|
||||
|
||||
|
||||
static device_attach_t ehci_ebus_attach;
|
||||
static device_detach_t ehci_ebus_detach;
|
||||
|
||||
static void *ih_err;
|
||||
|
||||
#define EHCI_HC_DEVSTR "CNS11XX USB EHCI"
|
||||
#define USB_BRIDGE_INTR_MASK 0x214
|
||||
|
||||
static int
|
||||
ehci_ebus_probe(device_t self)
|
||||
{
|
||||
|
||||
device_set_desc(self, EHCI_HC_DEVSTR);
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
ehci_ebus_attach(device_t self)
|
||||
{
|
||||
ehci_softc_t *sc = device_get_softc(self);
|
||||
bus_space_handle_t bsh;
|
||||
int err;
|
||||
int rid;
|
||||
|
||||
/* initialise some bus fields */
|
||||
sc->sc_bus.parent = self;
|
||||
sc->sc_bus.devices = sc->sc_devices;
|
||||
sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
|
||||
sc->sc_bus.dma_bits = 32;
|
||||
|
||||
/* get all DMA memory */
|
||||
if (usb_bus_mem_alloc_all(&sc->sc_bus,
|
||||
USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
sc->sc_bus.usbrev = USB_REV_2_0;
|
||||
|
||||
rid = 0;
|
||||
sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY,
|
||||
&rid, RF_ACTIVE);
|
||||
if (!sc->sc_io_res) {
|
||||
device_printf(self, "Could not map memory\n");
|
||||
goto error;
|
||||
}
|
||||
sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
|
||||
bsh = rman_get_bushandle(sc->sc_io_res);
|
||||
|
||||
/*magic, undocumented initialization*/
|
||||
bus_space_write_4((sc)->sc_io_tag, bsh, 0x04, 0x106);
|
||||
|
||||
bus_space_write_4((sc)->sc_io_tag, bsh, 0x40, (3 << 5)|0x2000);
|
||||
|
||||
DELAY(1000);
|
||||
|
||||
sc->sc_io_size = 4096;
|
||||
|
||||
if (bus_space_subregion(sc->sc_io_tag, bsh, 0x4000000,
|
||||
sc->sc_io_size, &sc->sc_io_hdl) != 0)
|
||||
panic("%s: unable to subregion USB host registers",
|
||||
device_get_name(self));
|
||||
|
||||
rid = 0;
|
||||
sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
if (sc->sc_irq_res == NULL) {
|
||||
device_printf(self, "Could not allocate irq\n");
|
||||
ehci_ebus_detach(self);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
|
||||
if (!sc->sc_bus.bdev) {
|
||||
device_printf(self, "Could not add USB device\n");
|
||||
goto error;
|
||||
}
|
||||
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
|
||||
device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);
|
||||
|
||||
sprintf(sc->sc_vendor, "Cavium");
|
||||
|
||||
err = bus_setup_intr(self,sc->sc_irq_res,
|
||||
INTR_TYPE_BIO | INTR_MPSAFE, NULL,
|
||||
(driver_intr_t *)ehci_interrupt, sc,
|
||||
&sc->sc_intr_hdl);
|
||||
if (err) {
|
||||
device_printf(self, "Could not setup error irq, %d\n", err);
|
||||
ih_err = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = ehci_init(sc);
|
||||
if (!err) {
|
||||
err = device_probe_and_attach(sc->sc_bus.bdev);
|
||||
}
|
||||
if (err) {
|
||||
device_printf(self, "USB init failed err=%d\n", err);
|
||||
goto error;
|
||||
}
|
||||
return (0);
|
||||
|
||||
error:
|
||||
ehci_ebus_detach(self);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
ehci_ebus_detach(device_t self)
|
||||
{
|
||||
ehci_softc_t *sc = device_get_softc(self);
|
||||
int err;
|
||||
|
||||
/* during module unload there are lots of children leftover */
|
||||
device_delete_children(self);
|
||||
|
||||
/*
|
||||
* disable interrupts that might have been switched on in
|
||||
* ehci_ebus_attach()
|
||||
*/
|
||||
if (sc->sc_io_res) {
|
||||
EWRITE4(sc, USB_BRIDGE_INTR_MASK, 0);
|
||||
}
|
||||
if (sc->sc_irq_res && sc->sc_intr_hdl) {
|
||||
/*
|
||||
* only call ehci_detach() after ehci_init()
|
||||
*/
|
||||
ehci_detach(sc);
|
||||
|
||||
err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
|
||||
|
||||
if (err)
|
||||
/* XXX or should we panic? */
|
||||
device_printf(self, "Could not tear down irq, %d\n",
|
||||
err);
|
||||
sc->sc_intr_hdl = NULL;
|
||||
}
|
||||
if (sc->sc_irq_res) {
|
||||
bus_release_resource(self, SYS_RES_IRQ, 1, sc->sc_irq_res);
|
||||
sc->sc_irq_res = NULL;
|
||||
}
|
||||
if (sc->sc_io_res) {
|
||||
bus_release_resource(self, SYS_RES_MEMORY, 0,
|
||||
sc->sc_io_res);
|
||||
sc->sc_io_res = NULL;
|
||||
}
|
||||
usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t ehci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, ehci_ebus_probe),
|
||||
DEVMETHOD(device_attach, ehci_ebus_attach),
|
||||
DEVMETHOD(device_detach, ehci_ebus_detach),
|
||||
DEVMETHOD(device_suspend, bus_generic_suspend),
|
||||
DEVMETHOD(device_resume, bus_generic_resume),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t ehci_driver = {
|
||||
.name = "ehci",
|
||||
.methods = ehci_methods,
|
||||
.size = sizeof(ehci_softc_t),
|
||||
};
|
||||
|
||||
static devclass_t ehci_devclass;
|
||||
|
||||
DRIVER_MODULE(ebus_ehci, econaarm, ehci_driver, ehci_devclass, 0, 0);
|
||||
MODULE_DEPEND(ebus_ehci, usb, 1, 1, 1);
|
@ -1,12 +0,0 @@
|
||||
# $FreeBSD$
|
||||
arm/cavium/cns11xx/econa_machdep.c standard
|
||||
arm/cavium/cns11xx/econa.c standard
|
||||
arm/cavium/cns11xx/timer.c standard
|
||||
arm/cavium/cns11xx/uart_bus_ec.c optional uart
|
||||
arm/cavium/cns11xx/uart_cpu_ec.c optional uart
|
||||
dev/uart/uart_dev_ns8250.c optional uart
|
||||
arm/arm/bus_space_base.c standard
|
||||
arm/cavium/cns11xx/ehci_ebus.c optional ehci
|
||||
arm/cavium/cns11xx/ohci_ec.c optional ohci
|
||||
arm/cavium/cns11xx/if_ece.c standard
|
||||
arm/cavium/cns11xx/cfi_bus_econa.c optional cfi
|
File diff suppressed because it is too large
Load Diff
@ -1,154 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2009, Yohanes Nugroho <yohanes@gmail.com>
|
||||
* 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 unmodified, 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 AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _IF_ECEREG_H
|
||||
#define _IF_ECEREG_H
|
||||
|
||||
#define ETH_CFG 0x08
|
||||
#define ETH_CFG_RMII (1 << 15)
|
||||
#define PHY_CONTROL 0x00
|
||||
#define PHY_RW_OK (1<<15)
|
||||
|
||||
#define PHY_ADDRESS(x) ((x) & 0x1)
|
||||
#define PHY_REGISTER(r) (((r) & 0x1F) << 8)
|
||||
#define PHY_WRITE_COMMAND (1<<13)
|
||||
#define PHY_READ_COMMAND (1<<14)
|
||||
#define PHY_GET_DATA(d) (((d) >> 16) & 0xFFFF)
|
||||
#define PHY_DATA(d) (((d) & 0xFFFF) << 16)
|
||||
|
||||
#define PORT_0_CONFIG 0x08
|
||||
|
||||
#define ARL_TABLE_ACCESS_CONTROL_0 0x050
|
||||
#define ARL_TABLE_ACCESS_CONTROL_1 0x054
|
||||
#define ARL_TABLE_ACCESS_CONTROL_2 0x058
|
||||
|
||||
#define ARL_WRITE_COMMAND (1<<3)
|
||||
#define ARL_LOOKUP_COMMAND (1<<2)
|
||||
#define ARL_COMMAND_COMPLETE (1)
|
||||
|
||||
|
||||
#define PORT0 (1 << 0)
|
||||
#define PORT1 (1 << 1)
|
||||
#define CPU_PORT (1 << 2)
|
||||
|
||||
|
||||
#define VLAN0_GROUP_ID (0)
|
||||
#define VLAN1_GROUP_ID (1)
|
||||
#define VLAN2_GROUP_ID (2)
|
||||
#define VLAN3_GROUP_ID (3)
|
||||
#define VLAN4_GROUP_ID (4)
|
||||
#define VLAN5_GROUP_ID (5)
|
||||
#define VLAN6_GROUP_ID (6)
|
||||
#define VLAN7_GROUP_ID (7)
|
||||
|
||||
#define PORT0_PVID (VLAN1_GROUP_ID)
|
||||
#define PORT1_PVID (VLAN2_GROUP_ID)
|
||||
#define CPU_PORT_PVID (VLAN0_GROUP_ID)
|
||||
|
||||
#define VLAN0_VID (0x111)
|
||||
#define VLAN1_VID (0x222)
|
||||
#define VLAN2_VID (0x333)
|
||||
#define VLAN3_VID (0x444)
|
||||
#define VLAN4_VID (0x555)
|
||||
#define VLAN5_VID (0x666)
|
||||
#define VLAN6_VID (0x777)
|
||||
#define VLAN7_VID (0x888)
|
||||
|
||||
#define VLAN0_GROUP (PORT0 | PORT1 | CPU_PORT)
|
||||
#define VLAN1_GROUP (PORT0 | CPU_PORT)
|
||||
#define VLAN2_GROUP (PORT1 | CPU_PORT)
|
||||
#define VLAN3_GROUP (0)
|
||||
#define VLAN4_GROUP (0)
|
||||
#define VLAN5_GROUP (0)
|
||||
#define VLAN6_GROUP (0)
|
||||
#define VLAN7_GROUP (0)
|
||||
|
||||
#define SWITCH_CONFIG 0x004
|
||||
#define MAC_PORT_0_CONFIG 0x008
|
||||
#define MAC_PORT_1_CONFIG 0x00C
|
||||
#define CPU_PORT_CONFIG 0x010
|
||||
#define BIST_RESULT_TEST_0 0x094
|
||||
|
||||
#define FS_DMA_CONTROL 0x104
|
||||
#define TS_DMA_CONTROL 0x100
|
||||
|
||||
#define INTERRUPT_MASK 0x08C
|
||||
#define INTERRUPT_STATUS 0x088
|
||||
|
||||
#define TS_DESCRIPTOR_POINTER 0x108
|
||||
#define TS_DESCRIPTOR_BASE_ADDR 0x110
|
||||
#define FS_DESCRIPTOR_POINTER 0x10C
|
||||
#define FS_DESCRIPTOR_BASE_ADDR 0x114
|
||||
|
||||
|
||||
#define VLAN_VID_0_1 0x060
|
||||
#define VLAN_VID_2_3 0x064
|
||||
#define VLAN_VID_4_5 0x068
|
||||
#define VLAN_VID_6_7 0x06C
|
||||
|
||||
#define VLAN_PORT_PVID 0x05C
|
||||
#define VLAN_MEMBER_PORT_MAP 0x070
|
||||
#define VLAN_TAG_PORT_MAP 0x074
|
||||
|
||||
|
||||
#define ASIX_GIGA_PHY 1
|
||||
#define TWO_SINGLE_PHY 2
|
||||
#define AGERE_GIGA_PHY 3
|
||||
#define VSC8601_GIGA_PHY 4
|
||||
#define IC_PLUS_PHY 5
|
||||
#define NOT_FOUND_PHY (-1)
|
||||
|
||||
#define MAX_PACKET_LEN (1536)
|
||||
|
||||
#define INVALID_ENTRY 0
|
||||
#define NEW_ENTRY 0x1
|
||||
#define STATIC_ENTRY 0x7
|
||||
|
||||
/*mask status except for link change*/
|
||||
#define ERROR_MASK 0xFFFFFF7F
|
||||
|
||||
/*hardware interface flags*/
|
||||
|
||||
#define FAST_AGING (0xf)
|
||||
#define IVL_LEARNING (0x1 << 22)
|
||||
/*hardware NAT accelerator*/
|
||||
#define HARDWARE_NAT (0x1 << 23)
|
||||
/*aging time setting*/
|
||||
|
||||
/*skip lookup*/
|
||||
#define SKIP_L2_LOOKUP_PORT_1 (1 << 29)
|
||||
#define SKIP_L2_LOOKUP_PORT_0 (1 << 28)
|
||||
|
||||
#define NIC_MODE (1 << 30)
|
||||
#define PORT_DISABLE (1 << 18)
|
||||
#define SA_LEARNING_DISABLE (1 << 19)
|
||||
#define DISABLE_BROADCAST_PACKET (1 << 27)
|
||||
#define DISABLE_MULTICAST_PACKET ( 1 << 26)
|
||||
|
||||
#endif
|
@ -1,193 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Yohanes Nugroho <yohanes@gmail.com>
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _IFECEVAR_H
|
||||
#define _IFECEVAR_H
|
||||
|
||||
#define ECE_MAX_TX_BUFFERS 128
|
||||
#define ECE_MAX_RX_BUFFERS 128
|
||||
#define MAX_FRAGMENT 32
|
||||
|
||||
typedef struct {
|
||||
/* 1st 32Bits */
|
||||
uint32_t data_ptr;
|
||||
/* 2nd 32Bits*/
|
||||
uint32_t length:16;
|
||||
|
||||
uint32_t tco:1; /*tcp checksum offload*/
|
||||
uint32_t uco:1; /*udp checksum offload*/
|
||||
uint32_t ico:1; /*ip checksum offload*/
|
||||
/* force_route_port_map*/
|
||||
uint32_t pmap:3;
|
||||
/* force_route */
|
||||
uint32_t fr:1;
|
||||
/* force_priority_value */
|
||||
uint32_t pri:3;
|
||||
/* force_priority */
|
||||
uint32_t fp:1;
|
||||
/*interrupt_bit*/
|
||||
uint32_t interrupt:1;
|
||||
/*last_seg*/
|
||||
uint32_t ls:1;
|
||||
/*first_seg*/
|
||||
uint32_t fs:1;
|
||||
/* end_bit */
|
||||
uint32_t eor:1;
|
||||
/* c_bit */
|
||||
uint32_t cown:1;
|
||||
/* 3rd 32Bits*/
|
||||
/*vid_index*/
|
||||
uint32_t vid:3;
|
||||
/*insert_vid_tag*/
|
||||
uint32_t insv:1;
|
||||
/*pppoe_section_index*/
|
||||
uint32_t sid:3;
|
||||
/*insert_pppoe_section*/
|
||||
uint32_t inss:1;
|
||||
uint32_t unused:24;
|
||||
/* 4th 32Bits*/
|
||||
uint32_t unused2;
|
||||
|
||||
} eth_tx_desc_t;
|
||||
|
||||
typedef struct{
|
||||
uint32_t data_ptr;
|
||||
uint32_t length:16;
|
||||
uint32_t l4f:1;
|
||||
uint32_t ipf:1;
|
||||
uint32_t prot:2;
|
||||
uint32_t hr:6;
|
||||
uint32_t sp:2;
|
||||
uint32_t ls:1;
|
||||
uint32_t fs:1;
|
||||
uint32_t eor:1;
|
||||
uint32_t cown:1;
|
||||
uint32_t unused;
|
||||
uint32_t unused2;
|
||||
} eth_rx_desc_t;
|
||||
|
||||
|
||||
struct rx_desc_info {
|
||||
struct mbuf*buff;
|
||||
bus_dmamap_t dmamap;
|
||||
eth_rx_desc_t *desc;
|
||||
};
|
||||
|
||||
struct tx_desc_info {
|
||||
struct mbuf*buff;
|
||||
bus_dmamap_t dmamap;
|
||||
eth_tx_desc_t *desc;
|
||||
};
|
||||
|
||||
|
||||
struct ece_softc
|
||||
{
|
||||
struct ifnet *ifp; /* ifnet pointer */
|
||||
struct mtx sc_mtx; /* global mutex */
|
||||
struct mtx sc_mtx_tx; /* tx mutex */
|
||||
struct mtx sc_mtx_rx; /* rx mutex */
|
||||
struct mtx sc_mtx_cleanup; /* rx mutex */
|
||||
|
||||
bus_dma_tag_t sc_parent_tag; /* parent bus DMA tag */
|
||||
|
||||
device_t dev; /* Myself */
|
||||
device_t miibus; /* My child miibus */
|
||||
void *intrhand; /* Interrupt handle */
|
||||
void *intrhand_qf; /* queue full */
|
||||
void *intrhand_tx; /* tx complete */
|
||||
void *intrhand_status; /* error status */
|
||||
|
||||
struct resource *irq_res_tx; /* transmit */
|
||||
struct resource *irq_res_rec; /* receive */
|
||||
struct resource *irq_res_qf; /* queue full */
|
||||
struct resource *irq_res_status; /* status */
|
||||
|
||||
struct resource *mem_res; /* Memory resource */
|
||||
|
||||
struct callout tick_ch; /* Tick callout */
|
||||
|
||||
struct taskqueue *sc_tq;
|
||||
struct task sc_intr_task;
|
||||
struct task sc_cleanup_task;
|
||||
struct task sc_tx_task;
|
||||
|
||||
bus_dmamap_t dmamap_ring_tx;
|
||||
bus_dmamap_t dmamap_ring_rx;
|
||||
bus_dmamap_t rx_sparemap;
|
||||
|
||||
/*dma tag for ring*/
|
||||
bus_dma_tag_t dmatag_ring_tx;
|
||||
bus_dma_tag_t dmatag_ring_rx;
|
||||
|
||||
/*dma tag for data*/
|
||||
bus_dma_tag_t dmatag_data_tx;
|
||||
bus_dma_tag_t dmatag_data_rx;
|
||||
|
||||
/*the ring*/
|
||||
eth_tx_desc_t* desc_tx;
|
||||
eth_rx_desc_t* desc_rx;
|
||||
|
||||
/*ring physical address*/
|
||||
bus_addr_t ring_paddr_tx;
|
||||
bus_addr_t ring_paddr_rx;
|
||||
|
||||
/*index of last received descriptor*/
|
||||
uint32_t last_rx;
|
||||
struct rx_desc_info rx_desc[ECE_MAX_RX_BUFFERS];
|
||||
|
||||
/* tx producer index */
|
||||
uint32_t tx_prod;
|
||||
/* tx consumer index */
|
||||
uint32_t tx_cons;
|
||||
/* tx ring index*/
|
||||
uint32_t desc_curr_tx;
|
||||
|
||||
struct tx_desc_info tx_desc[ECE_MAX_TX_BUFFERS];
|
||||
};
|
||||
|
||||
|
||||
struct arl_table_entry_t {
|
||||
uint32_t cmd_complete: 1;
|
||||
uint32_t table_end: 1;
|
||||
uint32_t search_match: 1;
|
||||
uint32_t filter:1; /*if set, packet will be dropped */
|
||||
uint32_t vlan_mac:1; /*indicates that this is the gateway mac address*/
|
||||
uint32_t vlan_gid:3; /*vlan id*/
|
||||
uint32_t age_field:3;
|
||||
uint32_t port_map:3;
|
||||
/*48 bit mac address*/
|
||||
uint8_t mac_addr[6];
|
||||
uint8_t pad[2];
|
||||
};
|
||||
|
||||
struct mac_list{
|
||||
char mac_addr[6];
|
||||
struct mac_list *next;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,234 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Yohanes Nugroho <yohanes@gmail.com>
|
||||
* 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 AUTHOR ``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 AUTHOR 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/stdint.h>
|
||||
#include <sys/stddef.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/priv.h>
|
||||
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbdi.h>
|
||||
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_busdma.h>
|
||||
#include <dev/usb/usb_process.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#include <dev/usb/usb_controller.h>
|
||||
#include <dev/usb/usb_bus.h>
|
||||
#include <dev/usb/controller/ohci.h>
|
||||
#include <dev/usb/controller/ohcireg.h>
|
||||
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <arm/cavium/cns11xx/econa_reg.h>
|
||||
|
||||
#define MEM_RID 0
|
||||
|
||||
static device_probe_t ohci_ec_probe;
|
||||
static device_attach_t ohci_ec_attach;
|
||||
static device_detach_t ohci_ec_detach;
|
||||
|
||||
struct ec_ohci_softc {
|
||||
struct ohci_softc sc_ohci; /* must be first */
|
||||
};
|
||||
|
||||
static int
|
||||
ohci_ec_probe(device_t dev)
|
||||
{
|
||||
device_set_desc(dev, "Econa integrated OHCI controller");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
ohci_ec_attach(device_t dev)
|
||||
{
|
||||
struct ec_ohci_softc *sc = device_get_softc(dev);
|
||||
bus_space_handle_t bsh;
|
||||
int err;
|
||||
int rid;
|
||||
|
||||
/* initialise some bus fields */
|
||||
sc->sc_ohci.sc_bus.parent = dev;
|
||||
sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices;
|
||||
sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES;
|
||||
sc->sc_ohci.sc_bus.dma_bits = 32;
|
||||
|
||||
/* get all DMA memory */
|
||||
if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus,
|
||||
USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
|
||||
return (ENOMEM);
|
||||
}
|
||||
sc->sc_ohci.sc_dev = dev;
|
||||
|
||||
rid = MEM_RID;
|
||||
|
||||
sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&rid, RF_ACTIVE);
|
||||
|
||||
if (!(sc->sc_ohci.sc_io_res)) {
|
||||
err = ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res);
|
||||
bsh = rman_get_bushandle(sc->sc_ohci.sc_io_res);
|
||||
/* Undocumented magic initialization */
|
||||
bus_space_write_4((sc)->sc_ohci.sc_io_tag, bsh,0x04, 0x146);
|
||||
|
||||
bus_space_write_4((sc)->sc_ohci.sc_io_tag, bsh,0x44, 0x0200);
|
||||
|
||||
DELAY(1000);
|
||||
|
||||
sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res);
|
||||
|
||||
if (bus_space_subregion(sc->sc_ohci.sc_io_tag, bsh, 0x4000000,
|
||||
sc->sc_ohci.sc_io_size, &sc->sc_ohci.sc_io_hdl) != 0)
|
||||
panic("%s: unable to subregion USB host registers",
|
||||
device_get_name(dev));
|
||||
|
||||
rid = 0;
|
||||
sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
|
||||
RF_ACTIVE);
|
||||
if (!(sc->sc_ohci.sc_irq_res)) {
|
||||
goto error;
|
||||
}
|
||||
sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
|
||||
if (!(sc->sc_ohci.sc_bus.bdev)) {
|
||||
goto error;
|
||||
}
|
||||
device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus);
|
||||
|
||||
strlcpy(sc->sc_ohci.sc_vendor, "Cavium",
|
||||
sizeof(sc->sc_ohci.sc_vendor));
|
||||
|
||||
#if (__FreeBSD_version >= 700031)
|
||||
err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res,
|
||||
INTR_TYPE_BIO | INTR_MPSAFE, NULL,
|
||||
(driver_intr_t *)ohci_interrupt, sc,
|
||||
&sc->sc_ohci.sc_intr_hdl);
|
||||
#else
|
||||
err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res,
|
||||
INTR_TYPE_BIO | INTR_MPSAFE,
|
||||
(driver_intr_t *)ohci_interrupt, sc,
|
||||
&sc->sc_ohci.sc_intr_hdl);
|
||||
#endif
|
||||
if (err) {
|
||||
sc->sc_ohci.sc_intr_hdl = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
|
||||
OHCI_CONTROL, 0);
|
||||
|
||||
err = ohci_init(&sc->sc_ohci);
|
||||
if (!err) {
|
||||
err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev);
|
||||
}
|
||||
if (err) {
|
||||
goto error;
|
||||
}
|
||||
return (0);
|
||||
|
||||
error:
|
||||
ohci_ec_detach(dev);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
ohci_ec_detach(device_t dev)
|
||||
{
|
||||
struct ec_ohci_softc *sc = device_get_softc(dev);
|
||||
int err;
|
||||
|
||||
/* during module unload there are lots of children leftover */
|
||||
device_delete_children(dev);
|
||||
|
||||
bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
|
||||
OHCI_CONTROL, 0);
|
||||
|
||||
if (sc->sc_ohci.sc_irq_res && sc->sc_ohci.sc_intr_hdl) {
|
||||
/*
|
||||
* only call ohci_detach() after ohci_init()
|
||||
*/
|
||||
ohci_detach(&sc->sc_ohci);
|
||||
|
||||
err = bus_teardown_intr(dev, sc->sc_ohci.sc_irq_res,
|
||||
sc->sc_ohci.sc_intr_hdl);
|
||||
sc->sc_ohci.sc_intr_hdl = NULL;
|
||||
}
|
||||
if (sc->sc_ohci.sc_irq_res) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0,
|
||||
sc->sc_ohci.sc_irq_res);
|
||||
sc->sc_ohci.sc_irq_res = NULL;
|
||||
}
|
||||
if (sc->sc_ohci.sc_io_res) {
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID,
|
||||
sc->sc_ohci.sc_io_res);
|
||||
sc->sc_ohci.sc_io_res = NULL;
|
||||
}
|
||||
usb_bus_mem_free_all(&sc->sc_ohci.sc_bus, &ohci_iterate_hw_softc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t ohci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, ohci_ec_probe),
|
||||
DEVMETHOD(device_attach, ohci_ec_attach),
|
||||
DEVMETHOD(device_detach, ohci_ec_detach),
|
||||
DEVMETHOD(device_resume, bus_generic_resume),
|
||||
DEVMETHOD(device_suspend, bus_generic_suspend),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t ohci_driver = {
|
||||
.name = "ohci",
|
||||
.methods = ohci_methods,
|
||||
.size = sizeof(struct ec_ohci_softc),
|
||||
};
|
||||
|
||||
static devclass_t ohci_devclass;
|
||||
|
||||
DRIVER_MODULE(ohci, econaarm, ohci_driver, ohci_devclass, 0, 0);
|
||||
MODULE_DEPEND(ohci, usb, 1, 1, 1);
|
@ -1,15 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
files "../cavium/cns11xx/files.econa"
|
||||
cpu CPU_FA526
|
||||
machine arm
|
||||
makeoptions CONF_CFLAGS=-march=armv4
|
||||
options PHYSADDR=0x00000000
|
||||
makeoptions KERNPHYSADDR=0x01000000
|
||||
makeoptions KERNVIRTADDR=0xc1000000
|
||||
|
||||
options KERNVIRTADDR=0xc1000000 # Used in ldscript.arm
|
||||
options FLASHADDR=0xD0000000
|
||||
options LOADERRAMADDR=0x00000000
|
||||
|
||||
options NO_EVENTTIMERS
|
@ -1,382 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Yohanes Nugroho <yohanes@gmail.com>.
|
||||
* 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 AUTHOR 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 AUTHOR 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/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/timetc.h>
|
||||
#include <sys/watchdog.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/intr.h>
|
||||
|
||||
#include "econa_reg.h"
|
||||
#include "econa_var.h"
|
||||
|
||||
#define INITIAL_TIMECOUNTER (0xffffffff)
|
||||
|
||||
static int timers_initialized = 0;
|
||||
|
||||
#define HZ 100
|
||||
|
||||
extern unsigned int CPU_clock;
|
||||
extern unsigned int AHB_clock;
|
||||
extern unsigned int APB_clock;
|
||||
|
||||
static unsigned long timer_counter = 0;
|
||||
|
||||
struct ec_timer_softc {
|
||||
struct resource * timer_res[3];
|
||||
bus_space_tag_t timer_bst;
|
||||
bus_space_handle_t timer_bsh;
|
||||
struct mtx timer_mtx;
|
||||
};
|
||||
|
||||
static struct resource_spec ec_timer_spec[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 1, RF_ACTIVE },
|
||||
{ -1, 0 }
|
||||
};
|
||||
|
||||
static unsigned ec_timer_get_timecount(struct timecounter *);
|
||||
|
||||
static struct timecounter ec_timecounter = {
|
||||
.tc_get_timecount = ec_timer_get_timecount,
|
||||
.tc_name = "CPU Timer",
|
||||
/* This is assigned on the fly in the init sequence */
|
||||
.tc_frequency = 0,
|
||||
.tc_counter_mask = ~0u,
|
||||
.tc_quality = 1000,
|
||||
};
|
||||
|
||||
static struct ec_timer_softc *timer_softc = NULL;
|
||||
|
||||
static inline
|
||||
void write_4(unsigned int val, unsigned int addr)
|
||||
{
|
||||
bus_space_write_4(timer_softc->timer_bst,
|
||||
timer_softc->timer_bsh, addr, val);
|
||||
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned int read_4(unsigned int addr)
|
||||
{
|
||||
|
||||
return bus_space_read_4(timer_softc->timer_bst,
|
||||
timer_softc->timer_bsh, addr);
|
||||
}
|
||||
|
||||
#define uSECS_PER_TICK (1000000 / APB_clock)
|
||||
#define TICKS2USECS(x) ((x) * uSECS_PER_TICK)
|
||||
|
||||
static unsigned
|
||||
read_timer_counter_noint(void)
|
||||
{
|
||||
|
||||
arm_mask_irq(0);
|
||||
unsigned int v = read_4(TIMER_TM1_COUNTER_REG);
|
||||
arm_unmask_irq(0);
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
DELAY(int usec)
|
||||
{
|
||||
uint32_t val, val_temp;
|
||||
int nticks;
|
||||
|
||||
if (!timers_initialized) {
|
||||
for (; usec > 0; usec--)
|
||||
for (val = 100; val > 0; val--)
|
||||
;
|
||||
return;
|
||||
}
|
||||
TSENTER();
|
||||
|
||||
val = read_timer_counter_noint();
|
||||
nticks = (((APB_clock / 1000) * usec) / 1000) + 100;
|
||||
|
||||
while (nticks > 0) {
|
||||
val_temp = read_timer_counter_noint();
|
||||
if (val > val_temp)
|
||||
nticks -= (val - val_temp);
|
||||
else
|
||||
nticks -= (val + (timer_counter - val_temp));
|
||||
|
||||
val = val_temp;
|
||||
}
|
||||
TSEXIT();
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup timer
|
||||
*/
|
||||
static inline void
|
||||
setup_timer(unsigned int counter_value)
|
||||
{
|
||||
unsigned int control_value;
|
||||
unsigned int mask_value;
|
||||
|
||||
control_value = read_4(TIMER_TM_CR_REG);
|
||||
|
||||
mask_value = read_4(TIMER_TM_INTR_MASK_REG);
|
||||
write_4(counter_value, TIMER_TM1_COUNTER_REG);
|
||||
write_4(counter_value, TIMER_TM1_LOAD_REG);
|
||||
write_4(0, TIMER_TM1_MATCH1_REG);
|
||||
write_4(0,TIMER_TM1_MATCH2_REG);
|
||||
|
||||
control_value &= ~(TIMER1_CLOCK_SOURCE);
|
||||
control_value |= TIMER1_UP_DOWN_COUNT;
|
||||
|
||||
write_4(0, TIMER_TM2_COUNTER_REG);
|
||||
write_4(0, TIMER_TM2_LOAD_REG);
|
||||
write_4(~0u, TIMER_TM2_MATCH1_REG);
|
||||
write_4(~0u,TIMER_TM2_MATCH2_REG);
|
||||
|
||||
control_value &= ~(TIMER2_CLOCK_SOURCE);
|
||||
control_value &= ~(TIMER2_UP_DOWN_COUNT);
|
||||
|
||||
mask_value &= ~(63);
|
||||
|
||||
write_4(control_value, TIMER_TM_CR_REG);
|
||||
write_4(mask_value, TIMER_TM_INTR_MASK_REG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable timer
|
||||
*/
|
||||
static inline void
|
||||
timer_enable(void)
|
||||
{
|
||||
unsigned int control_value;
|
||||
|
||||
control_value = read_4(TIMER_TM_CR_REG);
|
||||
|
||||
control_value |= TIMER1_OVERFLOW_ENABLE;
|
||||
control_value |= TIMER1_ENABLE;
|
||||
control_value |= TIMER2_OVERFLOW_ENABLE;
|
||||
control_value |= TIMER2_ENABLE;
|
||||
|
||||
write_4(control_value, TIMER_TM_CR_REG);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
read_second_timer_counter(void)
|
||||
{
|
||||
|
||||
return read_4(TIMER_TM2_COUNTER_REG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get timer interrupt status
|
||||
*/
|
||||
static inline unsigned int
|
||||
read_timer_interrupt_status(void)
|
||||
{
|
||||
|
||||
return read_4(TIMER_TM_INTR_STATUS_REG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear timer interrupt status
|
||||
*/
|
||||
static inline void
|
||||
clear_timer_interrupt_status(unsigned int irq)
|
||||
{
|
||||
unsigned int interrupt_status;
|
||||
|
||||
interrupt_status = read_4(TIMER_TM_INTR_STATUS_REG);
|
||||
if (irq == 0) {
|
||||
if (interrupt_status & (TIMER1_MATCH1_INTR))
|
||||
interrupt_status &= ~(TIMER1_MATCH1_INTR);
|
||||
if (interrupt_status & (TIMER1_MATCH2_INTR))
|
||||
interrupt_status &= ~(TIMER1_MATCH2_INTR);
|
||||
if (interrupt_status & (TIMER1_OVERFLOW_INTR))
|
||||
interrupt_status &= ~(TIMER1_OVERFLOW_INTR);
|
||||
}
|
||||
if (irq == 1) {
|
||||
if (interrupt_status & (TIMER2_MATCH1_INTR))
|
||||
interrupt_status &= ~(TIMER2_MATCH1_INTR);
|
||||
if (interrupt_status & (TIMER2_MATCH2_INTR))
|
||||
interrupt_status &= ~(TIMER2_MATCH2_INTR);
|
||||
if (interrupt_status & (TIMER2_OVERFLOW_INTR))
|
||||
interrupt_status &= ~(TIMER2_OVERFLOW_INTR);
|
||||
}
|
||||
|
||||
write_4(interrupt_status, TIMER_TM_INTR_STATUS_REG);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
ec_timer_get_timecount(struct timecounter *a)
|
||||
{
|
||||
unsigned int ticks1;
|
||||
arm_mask_irq(1);
|
||||
ticks1 = read_second_timer_counter();
|
||||
arm_unmask_irq(1);
|
||||
return ticks1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup timer
|
||||
*/
|
||||
static inline void
|
||||
do_setup_timer(void)
|
||||
{
|
||||
|
||||
timer_counter = APB_clock/HZ;
|
||||
/*
|
||||
* setup timer-related values
|
||||
*/
|
||||
setup_timer(timer_counter);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_initclocks(void)
|
||||
{
|
||||
|
||||
ec_timecounter.tc_frequency = APB_clock;
|
||||
tc_init(&ec_timecounter);
|
||||
timer_enable();
|
||||
timers_initialized = 1;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
ec_timer_probe(device_t dev)
|
||||
{
|
||||
|
||||
device_set_desc(dev, "Econa CPU Timer");
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ec_reset(void *arg)
|
||||
{
|
||||
|
||||
arm_mask_irq(1);
|
||||
clear_timer_interrupt_status(1);
|
||||
arm_unmask_irq(1);
|
||||
return (FILTER_HANDLED);
|
||||
}
|
||||
|
||||
static int
|
||||
ec_hardclock(void *arg)
|
||||
{
|
||||
struct trapframe *frame;
|
||||
unsigned int val;
|
||||
/*clear timer interrupt status*/
|
||||
|
||||
arm_mask_irq(0);
|
||||
|
||||
val = read_4(TIMER_INTERRUPT_STATUS_REG);
|
||||
val &= ~(TIMER1_OVERFLOW_INTERRUPT);
|
||||
write_4(val, TIMER_INTERRUPT_STATUS_REG);
|
||||
|
||||
frame = (struct trapframe *)arg;
|
||||
hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
|
||||
|
||||
arm_unmask_irq(0);
|
||||
|
||||
return (FILTER_HANDLED);
|
||||
}
|
||||
|
||||
static int
|
||||
ec_timer_attach(device_t dev)
|
||||
{
|
||||
struct ec_timer_softc *sc;
|
||||
int error;
|
||||
void *ihl;
|
||||
|
||||
|
||||
if (timer_softc != NULL)
|
||||
return (ENXIO);
|
||||
|
||||
sc = (struct ec_timer_softc *)device_get_softc(dev);
|
||||
|
||||
timer_softc = sc;
|
||||
|
||||
error = bus_alloc_resources(dev, ec_timer_spec, sc->timer_res);
|
||||
if (error) {
|
||||
device_printf(dev, "could not allocate resources\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
sc->timer_bst = rman_get_bustag(sc->timer_res[0]);
|
||||
sc->timer_bsh = rman_get_bushandle(sc->timer_res[0]);
|
||||
|
||||
do_setup_timer();
|
||||
|
||||
if (bus_setup_intr(dev, sc->timer_res[1], INTR_TYPE_CLK,
|
||||
ec_hardclock, NULL, NULL, &ihl) != 0) {
|
||||
bus_release_resources(dev, ec_timer_spec, sc->timer_res);
|
||||
device_printf(dev, "could not setup hardclock interrupt\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
if (bus_setup_intr(dev, sc->timer_res[2], INTR_TYPE_CLK,
|
||||
ec_reset, NULL, NULL, &ihl) != 0) {
|
||||
bus_release_resources(dev, ec_timer_spec, sc->timer_res);
|
||||
device_printf(dev, "could not setup timer interrupt\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t ec_timer_methods[] = {
|
||||
DEVMETHOD(device_probe, ec_timer_probe),
|
||||
DEVMETHOD(device_attach, ec_timer_attach),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t ec_timer_driver = {
|
||||
"timer",
|
||||
ec_timer_methods,
|
||||
sizeof(struct ec_timer_softc),
|
||||
};
|
||||
|
||||
static devclass_t ec_timer_devclass;
|
||||
|
||||
DRIVER_MODULE(timer, econaarm, ec_timer_driver, ec_timer_devclass, 0, 0);
|
@ -1,76 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2009 Yohanes Nugroho <yohanes@gmail.com>
|
||||
* 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 AUTHOR 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 AUTHOR 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/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <sys/rman.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/uart/uart.h>
|
||||
#include <dev/uart/uart_bus.h>
|
||||
#include <dev/uart/uart_cpu.h>
|
||||
|
||||
#include <arm/cavium/cns11xx/econa_reg.h>
|
||||
|
||||
static int uart_ec_probe(device_t dev);
|
||||
|
||||
static device_method_t uart_ec_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, uart_ec_probe),
|
||||
DEVMETHOD(device_attach, uart_bus_attach),
|
||||
DEVMETHOD(device_detach, uart_bus_detach),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t uart_ec_driver = {
|
||||
uart_driver_name,
|
||||
uart_ec_methods,
|
||||
sizeof(struct uart_softc),
|
||||
};
|
||||
|
||||
static int
|
||||
uart_ec_probe(device_t dev)
|
||||
{
|
||||
struct uart_softc *sc;
|
||||
int status;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->sc_class = &uart_ns8250_class;
|
||||
status = uart_bus_probe(dev, EC_UART_REGSHIFT, 0, EC_UART_CLOCK, 0, 0);
|
||||
return (status);
|
||||
}
|
||||
|
||||
DRIVER_MODULE(uart, econaarm, uart_ec_driver, uart_devclass, 0, 0);
|
@ -1,84 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2009 Yohanes Nugroho <yohanes@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by Semihalf.
|
||||
*
|
||||
* 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 AUTHOR 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 AUTHOR 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 "opt_uart.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cons.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/uart/uart.h>
|
||||
#include <dev/uart/uart_cpu.h>
|
||||
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <arm/cavium/cns11xx/econa_reg.h>
|
||||
#include <arm/cavium/cns11xx//econa_var.h>
|
||||
|
||||
bus_space_tag_t uart_bus_space_io;
|
||||
bus_space_tag_t uart_bus_space_mem;
|
||||
|
||||
int
|
||||
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
|
||||
{
|
||||
|
||||
return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
|
||||
}
|
||||
|
||||
int
|
||||
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
|
||||
{
|
||||
struct uart_class *class = &uart_ns8250_class;
|
||||
|
||||
di->ops = uart_getops(class);
|
||||
di->bas.chan = 0;
|
||||
di->bas.bst = obio_tag;
|
||||
|
||||
if (bus_space_map(di->bas.bst, ECONA_IO_BASE + ECONA_UART_BASE,
|
||||
ECONA_UART_SIZE,
|
||||
0, &di->bas.bsh) != 0) {
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
di->baudrate = 0;
|
||||
di->bas.regshft = EC_UART_REGSHIFT;
|
||||
di->bas.rclk = EC_UART_CLOCK ;
|
||||
di->databits = 8;
|
||||
di->stopbits = 1;
|
||||
di->parity = UART_PARITY_NONE;
|
||||
uart_bus_space_mem = obio_tag;
|
||||
uart_bus_space_io = NULL;
|
||||
|
||||
return (0);
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
# CNS11XXNAS - StarSemi STR9104/Cavium CNS1102 NAS
|
||||
# kernel configuration file for FreeBSD/arm
|
||||
#
|
||||
# For more information on this file, please read the handbook section on
|
||||
# Kernel Configuration Files:
|
||||
#
|
||||
# https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
|
||||
#
|
||||
# The handbook is also available locally in /usr/share/doc/handbook
|
||||
# if you've installed the doc distribution, otherwise always see the
|
||||
# FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the
|
||||
# latest information.
|
||||
#
|
||||
# An exhaustive list of options and more detailed explanations of the
|
||||
# device lines is also present in the ../../conf/NOTES and NOTES files.
|
||||
# If you are in doubt as to the purpose or necessity of a line, check first
|
||||
# in NOTES.
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
ident CNS11XXNAS
|
||||
|
||||
include "std.arm"
|
||||
#options PHYSADDR=0x10000000
|
||||
#options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
|
||||
#options FLASHADDR=0x50000000
|
||||
#options LOADERRAMADDR=0x00000000
|
||||
|
||||
include "../cavium/cns11xx/std.econa"
|
||||
|
||||
makeoptions MODULES_OVERRIDE=""
|
||||
|
||||
options HZ=100
|
||||
options DEVICE_POLLING
|
||||
|
||||
|
||||
options SCHED_ULE # ULE scheduler
|
||||
#options SCHED_4BSD # 4BSD scheduler
|
||||
options GEOM_PART_BSD # BSD partition scheme
|
||||
options GEOM_PART_MBR # MBR partition scheme
|
||||
options GEOM_PART_GPT # GUID Partition Tables.
|
||||
#options GEOM_PART_EBR
|
||||
#options GEOM_PART_EBR_COMPAT
|
||||
options GEOM_LABEL # Provides labelization
|
||||
|
||||
|
||||
options INET # InterNETworking
|
||||
options INET6 # IPv6 communications protocols
|
||||
options TCP_HHOOK # hhook(9) framework for TCP
|
||||
options FFS # Berkeley Fast Filesystem
|
||||
options SOFTUPDATES # Enable FFS soft updates support
|
||||
options UFS_ACL # Support for access control lists
|
||||
options UFS_DIRHASH # Improve performance on big directories
|
||||
options NFSCL # Network Filesystem Client
|
||||
#options NFSD # Network Filesystem Server
|
||||
#options NFSLOCKD # Network Lock Manager
|
||||
options NFS_ROOT # NFS usable as /, requires NFSCL
|
||||
options TMPFS # Efficient memory filesystem
|
||||
options MSDOSFS # MSDOS Filesystem
|
||||
#options CD9660 # ISO 9660 Filesystem
|
||||
#options PROCFS # Process filesystem (requires PSEUDOFS)
|
||||
options PSEUDOFS # Pseudo-filesystem framework
|
||||
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
|
||||
options KTRACE # ktrace(1) support
|
||||
options SYSVSHM # SYSV-style shared memory
|
||||
options SYSVMSG # SYSV-style message queues
|
||||
options SYSVSEM # SYSV-style semaphores
|
||||
options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
|
||||
options MUTEX_NOINLINE # Mutex inlines are space hogs
|
||||
options RWLOCK_NOINLINE # rwlock inlines are space hogs
|
||||
options SX_NOINLINE # sx inliens are space hogs
|
||||
#options BOOTP
|
||||
#options BOOTP_NFSROOT
|
||||
#options BOOTP_NFSV3
|
||||
#options BOOTP_WIRED_TO=npe0
|
||||
#options BOOTP_COMPAT
|
||||
|
||||
#device pci
|
||||
device uart
|
||||
|
||||
|
||||
device firmware
|
||||
device mii # Minimal mii routines
|
||||
device ether
|
||||
device bpf
|
||||
|
||||
device loop
|
||||
|
||||
device md
|
||||
device random # Entropy device
|
||||
|
||||
|
||||
device usb
|
||||
device ohci
|
||||
device ehci
|
||||
device umass
|
||||
device scbus # SCSI bus (required for ATA/SCSI)
|
||||
device da # Direct Access (disks)
|
||||
device pass
|
||||
device cfi
|
||||
|
||||
#device udav # Davicom DM9601E USB
|
||||
|
||||
device geom_label
|
||||
device geom_journal
|
||||
device geom_part_bsd
|
||||
|
||||
options ROOTDEVNAME=\"ufs:da0s1a\"
|
@ -8,7 +8,6 @@ cpu CPU_FA526
|
||||
cpu CPU_XSCALE_81342
|
||||
cpu CPU_XSCALE_PXA2X0
|
||||
|
||||
files "../cavium/cns11xx/files.econa"
|
||||
files "../mv/files.mv"
|
||||
files "../mv/discovery/files.db78xxx"
|
||||
files "../mv/kirkwood/files.kirkwood"
|
||||
|
Loading…
Reference in New Issue
Block a user