Add MIPS platform files for Netlogic XLP SoC.

Processor, UART, PIC and Messaging Network code. Also add
sys/mips/nlm/hal for on-chip device registers.

In collaboration with: Prabhath Raman <prabhathpr at netlogicmicro com>

Approved by:	bz(re), jmallett, imp(mips)
This commit is contained in:
Jayachandran C. 2011-07-16 19:35:44 +00:00
parent e25e006dc6
commit 4d91ecaf4c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=224110
30 changed files with 7112 additions and 0 deletions

80
sys/mips/nlm/board.c Normal file
View File

@ -0,0 +1,80 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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.
*
* NETLOGIC_BSD */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <mips/nlm/hal/mips-extns.h>
#include <mips/nlm/hal/mmio.h>
#include <mips/nlm/hal/iomap.h>
#include <mips/nlm/hal/fmn.h>
#include <mips/nlm/hal/pic.h>
#include <mips/nlm/hal/uart.h>
#include <mips/nlm/board.h>
struct xlp_board_info xlp_board_info;
int nlm_setup_xlp_board(void);
/*
* All our knowledge of chip and board that cannot be detected by probing
* at run-time goes here
*/
int
nlm_setup_xlp_board(void)
{
struct xlp_board_info *boardp;
int node;
/* start with a clean slate */
boardp = &xlp_board_info;
memset(boardp, 0, sizeof(xlp_board_info));
boardp->nodemask = 0x1; /* only node 0 */
for (node = 0; node < XLP_MAX_NODES; node++) {
if ((boardp->nodemask & (1 << node)) == 0)
continue;
}
return 0;
}
int nlm_board_info_setup()
{
nlm_setup_xlp_board();
return 0;
}

75
sys/mips/nlm/board.h Normal file
View File

@ -0,0 +1,75 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __NLM_BOARD_H__
#define __NLM_BOARD_H__
#define XLP_NAE_NBLOCKS 5
#define XLP_NAE_NPORTS 4
#define XLP_I2C_MAXDEVICES 8
struct xlp_i2c_devinfo {
u_int addr; /* keep first, for i2c ivars to work */
int bus;
char *device;
};
struct xlp_port_ivars {
int port;
int block;
int type;
int phy_addr;
};
struct xlp_block_ivars {
int block;
int type;
u_int portmask;
struct xlp_port_ivars port_ivars[XLP_NAE_NPORTS];
};
struct xlp_nae_ivars {
int node;
u_int blockmask;
struct xlp_block_ivars block_ivars[XLP_NAE_NBLOCKS];
};
struct xlp_board_info {
u_int nodemask;
struct xlp_node_info {
struct xlp_i2c_devinfo i2c_devs[XLP_I2C_MAXDEVICES];
struct xlp_nae_ivars nae_ivars;
} nodes[XLP_MAX_NODES];
};
extern struct xlp_board_info xlp_board_info;
int nlm_board_info_setup(void);
#endif

View File

@ -0,0 +1,688 @@
/*
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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.
*
* NETLOGIC_BSD */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/endian.h>
#include <sys/malloc.h>
#include <sys/ktr.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_kern.h>
#include <vm/vm_extern.h>
#include <machine/bus.h>
#include <machine/cache.h>
static int
rmi_bus_space_map(void *t, bus_addr_t addr,
bus_size_t size, int flags,
bus_space_handle_t *bshp);
static void
rmi_bus_space_unmap(void *t, bus_space_handle_t bsh,
bus_size_t size);
static int
rmi_bus_space_subregion(void *t,
bus_space_handle_t bsh,
bus_size_t offset, bus_size_t size,
bus_space_handle_t *nbshp);
static u_int8_t
rmi_bus_space_read_1(void *t,
bus_space_handle_t handle,
bus_size_t offset);
static u_int16_t
rmi_bus_space_read_2(void *t,
bus_space_handle_t handle,
bus_size_t offset);
static u_int32_t
rmi_bus_space_read_4(void *t,
bus_space_handle_t handle,
bus_size_t offset);
static void
rmi_bus_space_read_multi_1(void *t,
bus_space_handle_t handle,
bus_size_t offset, u_int8_t *addr,
size_t count);
static void
rmi_bus_space_read_multi_2(void *t,
bus_space_handle_t handle,
bus_size_t offset, u_int16_t *addr,
size_t count);
static void
rmi_bus_space_read_multi_4(void *t,
bus_space_handle_t handle,
bus_size_t offset, u_int32_t *addr,
size_t count);
static void
rmi_bus_space_read_region_1(void *t,
bus_space_handle_t bsh,
bus_size_t offset, u_int8_t *addr,
size_t count);
static void
rmi_bus_space_read_region_2(void *t,
bus_space_handle_t bsh,
bus_size_t offset, u_int16_t *addr,
size_t count);
static void
rmi_bus_space_read_region_4(void *t,
bus_space_handle_t bsh,
bus_size_t offset, u_int32_t *addr,
size_t count);
static void
rmi_bus_space_write_1(void *t,
bus_space_handle_t handle,
bus_size_t offset, u_int8_t value);
static void
rmi_bus_space_write_2(void *t,
bus_space_handle_t handle,
bus_size_t offset, u_int16_t value);
static void
rmi_bus_space_write_4(void *t,
bus_space_handle_t handle,
bus_size_t offset, u_int32_t value);
static void
rmi_bus_space_write_multi_1(void *t,
bus_space_handle_t handle,
bus_size_t offset,
const u_int8_t *addr,
size_t count);
static void
rmi_bus_space_write_multi_2(void *t,
bus_space_handle_t handle,
bus_size_t offset,
const u_int16_t *addr,
size_t count);
static void
rmi_bus_space_write_multi_4(void *t,
bus_space_handle_t handle,
bus_size_t offset,
const u_int32_t *addr,
size_t count);
static void
rmi_bus_space_write_region_2(void *t,
bus_space_handle_t bsh,
bus_size_t offset,
const u_int16_t *addr,
size_t count);
static void
rmi_bus_space_write_region_4(void *t,
bus_space_handle_t bsh,
bus_size_t offset,
const u_int32_t *addr,
size_t count);
static void
rmi_bus_space_set_region_2(void *t,
bus_space_handle_t bsh,
bus_size_t offset, u_int16_t value,
size_t count);
static void
rmi_bus_space_set_region_4(void *t,
bus_space_handle_t bsh,
bus_size_t offset, u_int32_t value,
size_t count);
static void
rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused,
bus_size_t offset __unused, bus_size_t len __unused, int flags);
static void
rmi_bus_space_copy_region_2(void *t,
bus_space_handle_t bsh1,
bus_size_t off1,
bus_space_handle_t bsh2,
bus_size_t off2, size_t count);
u_int8_t
rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle,
bus_size_t offset);
static u_int16_t
rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle,
bus_size_t offset);
static u_int32_t
rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle,
bus_size_t offset);
static void
rmi_bus_space_read_multi_stream_1(void *t,
bus_space_handle_t handle,
bus_size_t offset, u_int8_t *addr,
size_t count);
static void
rmi_bus_space_read_multi_stream_2(void *t,
bus_space_handle_t handle,
bus_size_t offset, u_int16_t *addr,
size_t count);
static void
rmi_bus_space_read_multi_stream_4(void *t,
bus_space_handle_t handle,
bus_size_t offset, u_int32_t *addr,
size_t count);
void
rmi_bus_space_write_stream_1(void *t, bus_space_handle_t bsh,
bus_size_t offset, u_int8_t value);
static void
rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle,
bus_size_t offset, u_int16_t value);
static void
rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle,
bus_size_t offset, u_int32_t value);
static void
rmi_bus_space_write_multi_stream_1(void *t,
bus_space_handle_t handle,
bus_size_t offset,
const u_int8_t *addr,
size_t count);
static void
rmi_bus_space_write_multi_stream_2(void *t,
bus_space_handle_t handle,
bus_size_t offset,
const u_int16_t *addr,
size_t count);
static void
rmi_bus_space_write_multi_stream_4(void *t,
bus_space_handle_t handle,
bus_size_t offset,
const u_int32_t *addr,
size_t count);
#define TODO() printf("XLP bus space: '%s' unimplemented\n", __func__)
static struct bus_space local_rmi_bus_space = {
/* cookie */
(void *)0,
/* mapping/unmapping */
rmi_bus_space_map,
rmi_bus_space_unmap,
rmi_bus_space_subregion,
/* allocation/deallocation */
NULL,
NULL,
/* barrier */
rmi_bus_space_barrier,
/* read (single) */
rmi_bus_space_read_1,
rmi_bus_space_read_2,
rmi_bus_space_read_4,
NULL,
/* read multiple */
rmi_bus_space_read_multi_1,
rmi_bus_space_read_multi_2,
rmi_bus_space_read_multi_4,
NULL,
/* read region */
rmi_bus_space_read_region_1,
rmi_bus_space_read_region_2,
rmi_bus_space_read_region_4,
NULL,
/* write (single) */
rmi_bus_space_write_1,
rmi_bus_space_write_2,
rmi_bus_space_write_4,
NULL,
/* write multiple */
rmi_bus_space_write_multi_1,
rmi_bus_space_write_multi_2,
rmi_bus_space_write_multi_4,
NULL,
/* write region */
NULL,
rmi_bus_space_write_region_2,
rmi_bus_space_write_region_4,
NULL,
/* set multiple */
NULL,
NULL,
NULL,
NULL,
/* set region */
NULL,
rmi_bus_space_set_region_2,
rmi_bus_space_set_region_4,
NULL,
/* copy */
NULL,
rmi_bus_space_copy_region_2,
NULL,
NULL,
/* read (single) stream */
rmi_bus_space_read_stream_1,
rmi_bus_space_read_stream_2,
rmi_bus_space_read_stream_4,
NULL,
/* read multiple stream */
rmi_bus_space_read_multi_stream_1,
rmi_bus_space_read_multi_stream_2,
rmi_bus_space_read_multi_stream_4,
NULL,
/* read region stream */
rmi_bus_space_read_region_1,
rmi_bus_space_read_region_2,
rmi_bus_space_read_region_4,
NULL,
/* write (single) stream */
rmi_bus_space_write_stream_1,
rmi_bus_space_write_stream_2,
rmi_bus_space_write_stream_4,
NULL,
/* write multiple stream */
rmi_bus_space_write_multi_stream_1,
rmi_bus_space_write_multi_stream_2,
rmi_bus_space_write_multi_stream_4,
NULL,
/* write region stream */
NULL,
rmi_bus_space_write_region_2,
rmi_bus_space_write_region_4,
NULL,
};
/* generic bus_space tag */
bus_space_tag_t rmi_bus_space = &local_rmi_bus_space;
/*
* Map a region of device bus space into CPU virtual address space.
*/
static int
rmi_bus_space_map(void *t __unused, bus_addr_t addr,
bus_size_t size __unused, int flags __unused,
bus_space_handle_t *bshp)
{
*bshp = addr;
return (0);
}
/*
* Unmap a region of device bus space.
*/
static void
rmi_bus_space_unmap(void *t __unused, bus_space_handle_t bsh __unused,
bus_size_t size __unused)
{
}
/*
* Get a new handle for a subregion of an already-mapped area of bus space.
*/
static int
rmi_bus_space_subregion(void *t __unused, bus_space_handle_t bsh,
bus_size_t offset, bus_size_t size __unused,
bus_space_handle_t *nbshp)
{
*nbshp = bsh + offset;
return (0);
}
/*
* Read a 1, 2, 4, or 8 byte quantity from bus space
* described by tag/handle/offset.
*/
static u_int8_t
rmi_bus_space_read_1(void *tag, bus_space_handle_t handle,
bus_size_t offset)
{
return (u_int8_t) (*(volatile u_int32_t *)(handle + offset));
}
static u_int16_t
rmi_bus_space_read_2(void *tag, bus_space_handle_t handle,
bus_size_t offset)
{
return (u_int16_t)(*(volatile u_int32_t *)(handle + offset));
}
static u_int32_t
rmi_bus_space_read_4(void *tag, bus_space_handle_t handle,
bus_size_t offset)
{
return (*(volatile u_int32_t *)(handle + offset));
}
/*
* Read `count' 1, 2, 4, or 8 byte quantities from bus space
* described by tag/handle/offset and copy into buffer provided.
*/
static void
rmi_bus_space_read_multi_1(void *tag, bus_space_handle_t handle,
bus_size_t offset, u_int8_t *addr, size_t count)
{
TODO();
}
static void
rmi_bus_space_read_multi_2(void *tag, bus_space_handle_t handle,
bus_size_t offset, u_int16_t *addr, size_t count)
{
TODO();
}
static void
rmi_bus_space_read_multi_4(void *tag, bus_space_handle_t handle,
bus_size_t offset, u_int32_t *addr, size_t count)
{
TODO();
}
/*
* Write the 1, 2, 4, or 8 byte value `value' to bus space
* described by tag/handle/offset.
*/
static void
rmi_bus_space_write_1(void *tag, bus_space_handle_t handle,
bus_size_t offset, u_int8_t value)
{
*(volatile u_int32_t *)(handle + offset) = (u_int32_t)value;
}
static void
rmi_bus_space_write_2(void *tag, bus_space_handle_t handle,
bus_size_t offset, u_int16_t value)
{
*(volatile u_int32_t *)(handle + offset) = (u_int32_t)value;
}
static void
rmi_bus_space_write_4(void *tag, bus_space_handle_t handle,
bus_size_t offset, u_int32_t value)
{
*(volatile u_int32_t *)(handle + offset) = value;
}
/*
* Write `count' 1, 2, 4, or 8 byte quantities from the buffer
* provided to bus space described by tag/handle/offset.
*/
static void
rmi_bus_space_write_multi_1(void *tag, bus_space_handle_t handle,
bus_size_t offset, const u_int8_t *addr, size_t count)
{
TODO();
}
static void
rmi_bus_space_write_multi_2(void *tag, bus_space_handle_t handle,
bus_size_t offset, const u_int16_t *addr, size_t count)
{
TODO();
}
static void
rmi_bus_space_write_multi_4(void *tag, bus_space_handle_t handle,
bus_size_t offset, const u_int32_t *addr, size_t count)
{
TODO();
}
/*
* Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
* by tag/handle starting at `offset'.
*/
static void
rmi_bus_space_set_region_2(void *t, bus_space_handle_t bsh,
bus_size_t offset, u_int16_t value, size_t count)
{
bus_addr_t addr = bsh + offset;
for (; count != 0; count--, addr += 2)
(*(volatile u_int32_t *)(addr)) = value;
}
static void
rmi_bus_space_set_region_4(void *t, bus_space_handle_t bsh,
bus_size_t offset, u_int32_t value, size_t count)
{
bus_addr_t addr = bsh + offset;
for (; count != 0; count--, addr += 4)
(*(volatile u_int32_t *)(addr)) = value;
}
/*
* Copy `count' 1, 2, 4, or 8 byte values from bus space starting
* at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
*/
static void
rmi_bus_space_copy_region_2(void *t, bus_space_handle_t bsh1,
bus_size_t off1, bus_space_handle_t bsh2,
bus_size_t off2, size_t count)
{
printf("bus_space_copy_region_2 - unimplemented\n");
}
/*
* Read `count' 1, 2, 4, or 8 byte quantities from bus space
* described by tag/handle/offset and copy into buffer provided.
*/
u_int8_t
rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle,
bus_size_t offset)
{
return *((volatile u_int8_t *)(handle + offset));
}
static u_int16_t
rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle,
bus_size_t offset)
{
return *(volatile u_int16_t *)(handle + offset);
}
static u_int32_t
rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle,
bus_size_t offset)
{
return (*(volatile u_int32_t *)(handle + offset));
}
static void
rmi_bus_space_read_multi_stream_1(void *tag, bus_space_handle_t handle,
bus_size_t offset, u_int8_t *addr, size_t count)
{
TODO();
}
static void
rmi_bus_space_read_multi_stream_2(void *tag, bus_space_handle_t handle,
bus_size_t offset, u_int16_t *addr, size_t count)
{
TODO();
}
static void
rmi_bus_space_read_multi_stream_4(void *tag, bus_space_handle_t handle,
bus_size_t offset, u_int32_t *addr, size_t count)
{
TODO();
}
/*
* Read `count' 1, 2, 4, or 8 byte quantities from bus space
* described by tag/handle and starting at `offset' and copy into
* buffer provided.
*/
void
rmi_bus_space_read_region_1(void *t, bus_space_handle_t bsh,
bus_size_t offset, u_int8_t *addr, size_t count)
{
TODO();
}
void
rmi_bus_space_read_region_2(void *t, bus_space_handle_t bsh,
bus_size_t offset, u_int16_t *addr, size_t count)
{
TODO();
}
void
rmi_bus_space_read_region_4(void *t, bus_space_handle_t bsh,
bus_size_t offset, u_int32_t *addr, size_t count)
{
bus_addr_t baddr = bsh + offset;
while (count--) {
*addr++ = (*(volatile u_int32_t *)(baddr));
baddr += 4;
}
}
void
rmi_bus_space_write_stream_1(void *t, bus_space_handle_t handle,
bus_size_t offset, u_int8_t value)
{
TODO();
}
static void
rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle,
bus_size_t offset, u_int16_t value)
{
TODO();
}
static void
rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle,
bus_size_t offset, u_int32_t value)
{
TODO();
}
static void
rmi_bus_space_write_multi_stream_1(void *tag, bus_space_handle_t handle,
bus_size_t offset, const u_int8_t *addr, size_t count)
{
TODO();
}
static void
rmi_bus_space_write_multi_stream_2(void *tag, bus_space_handle_t handle,
bus_size_t offset, const u_int16_t *addr, size_t count)
{
TODO();
}
static void
rmi_bus_space_write_multi_stream_4(void *tag, bus_space_handle_t handle,
bus_size_t offset, const u_int32_t *addr, size_t count)
{
TODO();
}
void
rmi_bus_space_write_region_2(void *t,
bus_space_handle_t bsh,
bus_size_t offset,
const u_int16_t *addr,
size_t count)
{
TODO();
}
void
rmi_bus_space_write_region_4(void *t, bus_space_handle_t bsh,
bus_size_t offset, const u_int32_t *addr, size_t count)
{
TODO();
}
static void
rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused,
bus_size_t offset __unused, bus_size_t len __unused, int flags)
{
}

41
sys/mips/nlm/clock.h Normal file
View File

@ -0,0 +1,41 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef _RMI_CLOCK_H_
#define _RMI_CLOCK_H_
#define XLP_PIC_HZ 133000000U
#define XLP_CPU_HZ (nlm_cpu_frequency)
void count_compare_clockhandler(struct trapframe *);
void pic_hardclockhandler(struct trapframe *);
void pic_timecounthandler(struct trapframe *);
#endif /* _RMI_CLOCK_H_ */

451
sys/mips/nlm/cms.c Normal file
View File

@ -0,0 +1,451 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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.
*
* NETLOGIC_BSD */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/limits.h>
#include <sys/bus.h>
#include <sys/ktr.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/sched.h>
#include <sys/unistd.h>
#include <sys/sysctl.h>
#include <sys/malloc.h>
#include <machine/reg.h>
#include <machine/cpu.h>
#include <machine/hwfunc.h>
#include <machine/mips_opcode.h>
#include <machine/param.h>
#include <machine/intr_machdep.h>
#include <mips/nlm/hal/mips-extns.h>
#include <mips/nlm/hal/mmio.h>
#include <mips/nlm/hal/iomap.h>
#include <mips/nlm/hal/cop0.h>
#include <mips/nlm/hal/cop2.h>
#include <mips/nlm/hal/fmn.h>
#include <mips/nlm/hal/pic.h>
#include <mips/nlm/msgring.h>
#include <mips/nlm/interrupt.h>
#include <mips/nlm/xlp.h>
#include <mips/nlm/board.h>
#define MSGRNG_NSTATIONS 1024
/*
* Keep track of our message ring handler threads, each core has a
* different message station. Ideally we will need to start a few
* message handling threads every core, and wake them up depending on
* load
*/
struct msgring_thread {
struct thread *thread; /* msgring handler threads */
int needed; /* thread needs to wake up */
};
static struct msgring_thread msgring_threads[XLP_MAX_CORES * XLP_MAX_THREADS];
static struct proc *msgring_proc; /* all threads are under a proc */
/*
* The device drivers can register a handler for the the messages sent
* from a station (corresponding to the device).
*/
struct tx_stn_handler {
msgring_handler action;
void *arg;
};
static struct tx_stn_handler msgmap[MSGRNG_NSTATIONS];
static struct mtx msgmap_lock;
uint64_t xlp_cms_base;
uint32_t xlp_msg_thread_mask;
static int xlp_msg_threads_per_core = 3; /* Make tunable */
static void create_msgring_thread(int hwtid);
static int msgring_process_fast_intr(void *arg);
/*
* Boot time init, called only once
*/
void
xlp_msgring_config(void)
{
unsigned int thrmask, mask;
int i;
/* TODO: Add other nodes */
xlp_cms_base = nlm_regbase_cms(0);
mtx_init(&msgmap_lock, "msgring", NULL, MTX_SPIN);
if (xlp_threads_per_core < xlp_msg_threads_per_core)
xlp_msg_threads_per_core = xlp_threads_per_core;
thrmask = ((1 << xlp_msg_threads_per_core) - 1);
/*thrmask <<= xlp_threads_per_core - xlp_msg_threads_per_core;*/
mask = 0;
for (i = 0; i < XLP_MAX_CORES; i++) {
mask <<= XLP_MAX_THREADS;
mask |= thrmask;
}
xlp_msg_thread_mask = xlp_hw_thread_mask & mask;
printf("Initializing CMS...@%jx, Message handler thread mask %#jx\n",
(uintmax_t)xlp_cms_base, (uintmax_t)xlp_msg_thread_mask);
}
/*
* Initialize the messaging subsystem.
*
* Message Stations are shared among all threads in a cpu core, this
* has to be called once from every core which is online.
*/
void
xlp_msgring_iodi_config(void)
{
void *cookie;
xlp_msgring_config();
/* nlm_cms_default_setup(0,0,0,0); */
nlm_cms_credit_setup(50);
create_msgring_thread(0);
cpu_establish_hardintr("msgring", msgring_process_fast_intr, NULL,
NULL, IRQ_MSGRING, INTR_TYPE_NET, &cookie);
}
void
nlm_cms_credit_setup(int credit)
{
int src, qid, i;
#if 0
/* there are a total of 18 src stations on XLP. */
printf("Setting up CMS credits!\n");
for(src=0; src<18; src++) {
for(qid=0; qid<1024; qid++) {
nlm_cms_setup_credits(xlp_cms_base, qid, src, credit);
}
}
#endif
printf("Setting up CMS credits!\n");
/* CPU Credits */
for(i = 1; i < 8; i++) {
src = (i << 4);
for(qid = 0; qid < 1024; qid++) {
nlm_cms_setup_credits(xlp_cms_base, qid, src, credit);
}
}
/* PCIE Credits */
for(i = 0; i < 4; i++) {
src = (256 + (i * 2));
for(qid = 0; qid < 1024; qid++) {
nlm_cms_setup_credits(xlp_cms_base, qid, src, credit);
}
}
/* DTE Credits */
src = 264;
for(qid = 0; qid < 1024; qid++) {
nlm_cms_setup_credits(xlp_cms_base, qid, src, credit);
}
/* RSA Credits */
src = 272;
for(qid = 0; qid < 1024; qid++) {
nlm_cms_setup_credits(xlp_cms_base, qid, src, credit);
}
/* Crypto Credits */
src = 281;
for(qid = 0; qid < 1024; qid++) {
nlm_cms_setup_credits(xlp_cms_base, qid, src, credit);
}
/* CMP Credits */
src = 298;
for(qid = 0; qid < 1024; qid++) {
nlm_cms_setup_credits(xlp_cms_base, qid, src, credit);
}
/* POE Credits */
src = 384;
for(qid = 0; qid < 1024; qid++) {
nlm_cms_setup_credits(xlp_cms_base, qid, src, credit);
}
/* NAE Credits */
src = 476;
for(qid = 0; qid < 1024; qid++) {
nlm_cms_setup_credits(xlp_cms_base, qid, src, credit);
}
}
void
xlp_msgring_cpu_init(uint32_t cpuid)
{
int queue,i;
queue = XLP_CMS_CPU_PUSHQ(0, ((cpuid >> 2) & 0x7), (cpuid & 0x3), 0);
/* temp allocate 4 segments to each output queue */
nlm_cms_alloc_onchip_q(xlp_cms_base, queue, 4);
/* Enable high watermark and non empty interrupt */
nlm_cms_per_queue_level_intr(xlp_cms_base, queue,2,0);
for(i=0;i<8;i++) {
/* temp distribute the credits to all CPU stations */
nlm_cms_setup_credits(xlp_cms_base, queue, i * 16, 8);
}
}
void
xlp_cpu_msgring_handler(int bucket, int size, int code, int stid,
struct nlm_fmn_msg *msg, void *data)
{
int i;
printf("vc:%d srcid:%d size:%d\n",bucket,stid,size);
for(i=0;i<size;i++) {
printf("msg->msg[%d]:0x%jx ", i, (uintmax_t)msg->msg[i]);
}
printf("\n");
}
/*
* Drain out max_messages for the buckets set in the bucket mask.
* Use max_msgs = 0 to drain out all messages.
*/
int
xlp_handle_msg_vc(int vc, int max_msgs)
{
struct nlm_fmn_msg msg;
int i, srcid = 0, size = 0, code = 0;
struct tx_stn_handler *he;
uint32_t mflags, status;
for (i = 0; i < max_msgs; i++) {
mflags = nlm_fmn_saveflags();
status = nlm_fmn_msgrcv(vc, &srcid, &size, &code, &msg);
nlm_fmn_restoreflags(mflags);
if (status != 0) /* If there is no msg or error */
break;
if (srcid < 0 && srcid >= 1024) {
printf("[%s]: bad src id %d\n", __func__, srcid);
continue;
}
he = &msgmap[srcid];
if(he->action == NULL) {
printf("[%s]: No Handler for message from stn_id=%d,"
" vc=%d, size=%d, msg0=%jx, dropping message\n",
__func__, srcid, vc, size, (uintmax_t)msg.msg[0]);
continue;
}
(he->action)(vc, size, code, srcid, &msg, he->arg);
}
return (i);
}
static int
msgring_process_fast_intr(void *arg)
{
struct msgring_thread *mthd;
struct thread *td;
int cpu;
cpu = nlm_cpuid();
mthd = &msgring_threads[cpu];
td = mthd->thread;
/* clear pending interrupts */
nlm_write_c0_eirr(1ULL << IRQ_MSGRING);
/* wake up the target thread */
mthd->needed = 1;
thread_lock(td);
if (TD_AWAITING_INTR(td)) {
TD_CLR_IWAIT(td);
sched_add(td, SRQ_INTR);
}
thread_unlock(td);
return (FILTER_HANDLED);
}
u_int fmn_msgcount[32][4];
u_int fmn_loops[32];
static void
msgring_process(void * arg)
{
volatile struct msgring_thread *mthd;
struct thread *td;
uint32_t mflags;
int hwtid, vc, handled, nmsgs;
hwtid = (intptr_t)arg;
mthd = &msgring_threads[hwtid];
td = mthd->thread;
KASSERT(curthread == td,
("%s:msg_ithread and proc linkage out of sync", __func__));
/* First bind this thread to the right CPU */
thread_lock(td);
sched_bind(td, xlp_hwtid_to_cpuid[hwtid]);
thread_unlock(td);
if (hwtid != nlm_cpuid())
printf("Misscheduled hwtid %d != cpuid %d\n", hwtid, nlm_cpuid());
mflags = nlm_fmn_saveflags();
nlm_fmn_cpu_init(IRQ_MSGRING, 0, 0, 0, 0, 0);
nlm_fmn_restoreflags(mflags);
/* start processing messages */
for( ; ; ) {
/*atomic_store_rel_int(&mthd->needed, 0);*/
/* enable cop2 access */
do {
handled = 0;
for (vc = 0; vc < 4; vc++) {
nmsgs = xlp_handle_msg_vc(vc, 1);
fmn_msgcount[hwtid][vc] += nmsgs;
handled += nmsgs;
}
} while (handled);
/* sleep */
#if 0
thread_lock(td);
if (mthd->needed) {
thread_unlock(td);
continue;
}
sched_class(td, PRI_ITHD);
TD_SET_IWAIT(td);
mi_switch(SW_VOL, NULL);
thread_unlock(td);
#else
pause("wmsg", 1);
#endif
fmn_loops[hwtid]++;
}
}
static void
create_msgring_thread(int hwtid)
{
struct msgring_thread *mthd;
struct thread *td;
int error;
mthd = &msgring_threads[hwtid];
error = kproc_kthread_add(msgring_process, (void *)(uintptr_t)hwtid,
&msgring_proc, &td, RFSTOPPED, 2, "msgrngproc",
"msgthr%d", hwtid);
if (error)
panic("kproc_kthread_add() failed with %d", error);
mthd->thread = td;
thread_lock(td);
sched_class(td, PRI_ITHD);
sched_add(td, SRQ_INTR);
thread_unlock(td);
CTR2(KTR_INTR, "%s: created %s", __func__, td->td_name);
}
int
register_msgring_handler(int startb, int endb, msgring_handler action,
void *arg)
{
int i;
printf("Register handler %d-%d %p(%p)\n", startb, endb, action, arg);
KASSERT(startb >= 0 && startb <= endb && endb < MSGRNG_NSTATIONS,
("Invalid value for for bucket range %d,%d", startb, endb));
mtx_lock_spin(&msgmap_lock);
for (i = startb; i <= endb; i++) {
KASSERT(msgmap[i].action == NULL,
("Bucket %d already used [action %p]", i, msgmap[i].action));
msgmap[i].action = action;
msgmap[i].arg = arg;
}
mtx_unlock_spin(&msgmap_lock);
return (0);
}
/*
* Start message ring processing threads on other CPUs, after SMP start
*/
static void
start_msgring_threads(void *arg)
{
int hwt;
for (hwt = 1; hwt < XLP_MAX_CORES * XLP_MAX_THREADS; hwt++) {
if ((xlp_msg_thread_mask & (1 << hwt)) == 0)
continue;
create_msgring_thread(hwt);
}
}
SYSINIT(start_msgring_threads, SI_SUB_SMP, SI_ORDER_MIDDLE,
start_msgring_threads, NULL);
/*
* DEBUG support, XXX: static buffer, not locked
*/
static int
sys_print_debug(SYSCTL_HANDLER_ARGS)
{
int error, nb, i, fs;
static char xprintb[4096], *buf;
buf = xprintb;
fs = sizeof(xprintb);
nb = snprintf(buf, fs,
"\nID vc0 vc1 vc2 vc3 loops\n");
buf += nb;
fs -= nb;
for (i = 0; i < 32; i++) {
if ((xlp_hw_thread_mask & (1 << i)) == 0)
continue;
nb = snprintf(buf, fs,
"%2d: %8d %8d %8d %8d %8d\n", i,
fmn_msgcount[i][0], fmn_msgcount[i][1],
fmn_msgcount[i][2], fmn_msgcount[i][3],
fmn_loops[i]);
buf += nb;
fs -= nb;
}
error = SYSCTL_OUT(req, xprintb, buf - xprintb);
return (error);
}
SYSCTL_PROC(_debug, OID_AUTO, msgring, CTLTYPE_STRING | CTLFLAG_RD, 0, 0,
sys_print_debug, "A", "msgring debug info");

12
sys/mips/nlm/files.xlp Normal file
View File

@ -0,0 +1,12 @@
# $FreeBSD$
mips/nlm/hal/fmn.c standard
mips/nlm/xlp_machdep.c standard
mips/nlm/intr_machdep.c standard
mips/nlm/tick.c standard
mips/nlm/iodi.c standard
mips/nlm/board.c standard
mips/nlm/cms.c standard
mips/nlm/bus_space_rmi.c standard
mips/nlm/mpreset.S standard
mips/nlm/uart_bus_xlp_iodi.c optional uart
mips/nlm/uart_cpu_mips_xlp.c optional uart

177
sys/mips/nlm/hal/bridge.h Normal file
View File

@ -0,0 +1,177 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __NLM_BRIDGE_H__
#define __NLM_BRIDGE_H__
/**
* @file_name mio.h
* @author Netlogic Microsystems
* @brief Basic definitions of XLP memory and io subsystem
*/
/* BRIDGE specific registers */
#define XLP_BRIDGE_MODE_REG 0x40
#define XLP_BRIDGE_PCI_CFG_BASE_REG 0x41
#define XLP_BRIDGE_PCI_CFG_LIMIT_REG 0x42
#define XLP_BRIDGE_PCIE_CFG_BASE_REG 0x43
#define XLP_BRIDGE_PCIE_CFG_LIMIT_REG 0x44
#define XLP_BRIDGE_BUSNUM_BAR0_REG 0x45
#define XLP_BRIDGE_BUSNUM_BAR1_REG 0x46
#define XLP_BRIDGE_BUSNUM_BAR2_REG 0x47
#define XLP_BRIDGE_BUSNUM_BAR3_REG 0x48
#define XLP_BRIDGE_BUSNUM_BAR4_REG 0x49
#define XLP_BRIDGE_BUSNUM_BAR5_REG 0x4a
#define XLP_BRIDGE_BUSNUM_BAR6_REG 0x4b
#define XLP_BRIDGE_FLASH_BAR0_REG 0x4c
#define XLP_BRIDGE_FLASH_BAR1_REG 0x4d
#define XLP_BRIDGE_FLASH_BAR2_REG 0x4e
#define XLP_BRIDGE_FLASH_BAR3_REG 0x4f
#define XLP_BRIDGE_FLASH_LIMIT0_REG 0x50
#define XLP_BRIDGE_FLASH_LIMIT1_REG 0x51
#define XLP_BRIDGE_FLASH_LIMIT2_REG 0x52
#define XLP_BRIDGE_FLASH_LIMIT3_REG 0x53
#define XLP_BRIDGE_DRAM_BAR_REG(i) (0x54 + (i))
#define XLP_BRIDGE_DRAM_BAR0_REG 0x54
#define XLP_BRIDGE_DRAM_BAR1_REG 0x55
#define XLP_BRIDGE_DRAM_BAR2_REG 0x56
#define XLP_BRIDGE_DRAM_BAR3_REG 0x57
#define XLP_BRIDGE_DRAM_BAR4_REG 0x58
#define XLP_BRIDGE_DRAM_BAR5_REG 0x59
#define XLP_BRIDGE_DRAM_BAR6_REG 0x5a
#define XLP_BRIDGE_DRAM_BAR7_REG 0x5b
#define XLP_BRIDGE_DRAM_LIMIT_REG(i) (0x5c + (i))
#define XLP_BRIDGE_DRAM_LIMIT0_REG 0x5c
#define XLP_BRIDGE_DRAM_LIMIT1_REG 0x5d
#define XLP_BRIDGE_DRAM_LIMIT2_REG 0x5e
#define XLP_BRIDGE_DRAM_LIMIT3_REG 0x5f
#define XLP_BRIDGE_DRAM_LIMIT4_REG 0x60
#define XLP_BRIDGE_DRAM_LIMIT5_REG 0x61
#define XLP_BRIDGE_DRAM_LIMIT6_REG 0x62
#define XLP_BRIDGE_DRAM_LIMIT7_REG 0x63
#define XLP_BRIDGE_DRAM_NODE_TRANSLN0_REG 0x64
#define XLP_BRIDGE_DRAM_NODE_TRANSLN1_REG 0x65
#define XLP_BRIDGE_DRAM_NODE_TRANSLN2_REG 0x66
#define XLP_BRIDGE_DRAM_NODE_TRANSLN3_REG 0x67
#define XLP_BRIDGE_DRAM_NODE_TRANSLN4_REG 0x68
#define XLP_BRIDGE_DRAM_NODE_TRANSLN5_REG 0x69
#define XLP_BRIDGE_DRAM_NODE_TRANSLN6_REG 0x6a
#define XLP_BRIDGE_DRAM_NODE_TRANSLN7_REG 0x6b
#define XLP_BRIDGE_DRAM_CHNL_TRANSLN0_REG 0x6c
#define XLP_BRIDGE_DRAM_CHNL_TRANSLN1_REG 0x6d
#define XLP_BRIDGE_DRAM_CHNL_TRANSLN2_REG 0x6e
#define XLP_BRIDGE_DRAM_CHNL_TRANSLN3_REG 0x6f
#define XLP_BRIDGE_DRAM_CHNL_TRANSLN4_REG 0x70
#define XLP_BRIDGE_DRAM_CHNL_TRANSLN5_REG 0x71
#define XLP_BRIDGE_DRAM_CHNL_TRANSLN6_REG 0x72
#define XLP_BRIDGE_DRAM_CHNL_TRANSLN7_REG 0x73
#define XLP_BRIDGE_PCIEMEM_BASE0_REG 0x74
#define XLP_BRIDGE_PCIEMEM_BASE1_REG 0x75
#define XLP_BRIDGE_PCIEMEM_BASE2_REG 0x76
#define XLP_BRIDGE_PCIEMEM_BASE3_REG 0x77
#define XLP_BRIDGE_PCIEMEM_LIMIT0_REG 0x78
#define XLP_BRIDGE_PCIEMEM_LIMIT1_REG 0x79
#define XLP_BRIDGE_PCIEMEM_LIMIT2_REG 0x7a
#define XLP_BRIDGE_PCIEMEM_LIMIT3_REG 0x7b
#define XLP_BRIDGE_PCIEIO_BASE0_REG 0x7c
#define XLP_BRIDGE_PCIEIO_BASE1_REG 0x7d
#define XLP_BRIDGE_PCIEIO_BASE2_REG 0x7e
#define XLP_BRIDGE_PCIEIO_BASE3_REG 0x7f
#define XLP_BRIDGE_PCIEIO_LIMIT0_REG 0x80
#define XLP_BRIDGE_PCIEIO_LIMIT1_REG 0x81
#define XLP_BRIDGE_PCIEIO_LIMIT2_REG 0x82
#define XLP_BRIDGE_PCIEIO_LIMIT3_REG 0x83
#define XLP_BRIDGE_PCIEMEM_BASE4_REG 0x84
#define XLP_BRIDGE_PCIEMEM_BASE5_REG 0x85
#define XLP_BRIDGE_PCIEMEM_BASE6_REG 0x86
#define XLP_BRIDGE_PCIEMEM_LIMIT4_REG 0x87
#define XLP_BRIDGE_PCIEMEM_LIMIT5_REG 0x88
#define XLP_BRIDGE_PCIEMEM_LIMIT6_REG 0x89
#define XLP_BRIDGE_PCIEIO_BASE4_REG 0x8a
#define XLP_BRIDGE_PCIEIO_BASE5_REG 0x8b
#define XLP_BRIDGE_PCIEIO_BASE6_REG 0x8c
#define XLP_BRIDGE_PCIEIO_LIMIT4_REG 0x8d
#define XLP_BRIDGE_PCIEIO_LIMIT5_REG 0x8e
#define XLP_BRIDGE_PCIEIO_LIMIT6_REG 0x8f
#define XLP_BRIDGE_NBU_EVENT_CNT_CTL_REG 0x90
#define XLP_BRIDGE_EVNTCTR1_LOW_REG 0x91
#define XLP_BRIDGE_EVNTCTR1_HI_REG 0x92
#define XLP_BRIDGE_EVNT_CNT_CTL2_REG 0x93
#define XLP_BRIDGE_EVNTCTR2_LOW_REG 0x94
#define XLP_BRIDGE_EVNTCTR2_HI_REG 0x95
#define XLP_BRIDGE_TRACEBUF_MATCH_REG0 0x96
#define XLP_BRIDGE_TRACEBUF_MATCH_REG1 0x97
#define XLP_BRIDGE_TRACEBUF_MATCH_LOW_REG 0x98
#define XLP_BRIDGE_TRACEBUF_MATCH_HI_REG 0x99
#define XLP_BRIDGE_TRACEBUF_CTRL_REG 0x9a
#define XLP_BRIDGE_TRACEBUF_INIT_REG 0x9b
#define XLP_BRIDGE_TRACEBUF_ACCESS_REG 0x9c
#define XLP_BRIDGE_TRACEBUF_READ_DATA_REG0 0x9d
#define XLP_BRIDGE_TRACEBUF_READ_DATA_REG1 0x9d
#define XLP_BRIDGE_TRACEBUF_READ_DATA_REG2 0x9f
#define XLP_BRIDGE_TRACEBUF_READ_DATA_REG3 0xa0
#define XLP_BRIDGE_TRACEBUF_STATUS_REG 0xa1
#define XLP_BRIDGE_ADDRESS_ERROR0_REG 0xa2
#define XLP_BRIDGE_ADDRESS_ERROR1_REG 0xa3
#define XLP_BRIDGE_ADDRESS_ERROR2_REG 0xa4
#define XLP_BRIDGE_TAG_ECC_ADDR_ERROR0_REG 0xa5
#define XLP_BRIDGE_TAG_ECC_ADDR_ERROR1_REG 0xa6
#define XLP_BRIDGE_TAG_ECC_ADDR_ERROR2_REG 0xa7
#define XLP_BRIDGE_LINE_FLUSH_REG0 0xa8
#define XLP_BRIDGE_LINE_FLUSH_REG1 0xa9
#define XLP_BRIDGE_NODE_ID_REG 0xaa
#define XLP_BRIDGE_ERROR_INTERRUPT_EN_REG 0xab
#define XLP_BRIDGE_PCIE0_WEIGHT_REG 0x300
#define XLP_BRIDGE_PCIE1_WEIGHT_REG 0x301
#define XLP_BRIDGE_PCIE2_WEIGHT_REG 0x302
#define XLP_BRIDGE_PCIE3_WEIGHT_REG 0x303
#define XLP_BRIDGE_USB_WEIGHT_REG 0x304
#define XLP_BRIDGE_NET_WEIGHT_REG 0x305
#define XLP_BRIDGE_POE_WEIGHT_REG 0x306
#define XLP_BRIDGE_CMS_WEIGHT_REG 0x307
#define XLP_BRIDGE_DMAENG_WEIGHT_REG 0x308
#define XLP_BRIDGE_SEC_WEIGHT_REG 0x309
#define XLP_BRIDGE_COMP_WEIGHT_REG 0x30a
#define XLP_BRIDGE_GIO_WEIGHT_REG 0x30b
#define XLP_BRIDGE_FLASH_WEIGHT_REG 0x30c
#if !defined(LOCORE) && !defined(__ASSEMBLY__)
#define nlm_rdreg_bridge(b, r) nlm_read_reg_kseg(b, r)
#define nlm_wreg_bridge(b, r, v) nlm_write_reg_kseg(b, r, v)
#define nlm_pcibase_bridge(node) nlm_pcicfg_base(XLP_IO_BRIDGE_OFFSET(node))
#define nlm_regbase_bridge(node) nlm_pcibase_bridge(node)
#endif
#endif

280
sys/mips/nlm/hal/cop0.h Normal file
View File

@ -0,0 +1,280 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __NLM_COP0_H__
#define __NLM_COP0_H__
#define NLM_C0_INDEX 0
#define NLM_C0_RANDOM 1
#define NLM_C0_ENTRYLO0 2
#define NLM_C0_ENTRYLO1 3
#define NLM_C0_CONTEXT 4
#define NLM_C0_USERLOCAL 4
#define NLM_C0_PAGEMASK 5
#define NLM_C0_WIRED 6
#define NLM_C0_BADVADDR 8
#define NLM_C0_COUNT 9
#define NLM_C0_EIRR 9
#define NLM_C0_EIMR 9
#define NLM_C0_ENTRYHI 10
#define NLM_C0_COMPARE 11
#define NLM_C0_STATUS 12
#define NLM_C0_INTCTL 12
#define NLM_C0_SRSCTL 12
#define NLM_C0_CAUSE 13
#define NLM_C0_EPC 14
#define NLM_C0_PRID 15
#define NLM_C0_EBASE 15
#define NLM_C0_CONFIG 16
#define NLM_C0_CONFIG0 16
#define NLM_C0_CONFIG1 16
#define NLM_C0_CONFIG2 16
#define NLM_C0_CONFIG3 16
#define NLM_C0_CONFIG4 16
#define NLM_C0_CONFIG5 16
#define NLM_C0_CONFIG6 16
#define NLM_C0_CONFIG7 16
#define NLM_C0_WATCHLO 18
#define NLM_C0_WATCHHI 19
#define NLM_C0_XCONTEXT 20
#define NLM_C0_SCRATCH 22
#define NLM_C0_SCRATCH0 22
#define NLM_C0_SCRATCH1 22
#define NLM_C0_SCRATCH2 22
#define NLM_C0_SCRATCH3 22
#define NLM_C0_SCRATCH4 22
#define NLM_C0_SCRATCH5 22
#define NLM_C0_SCRATCH6 22
#define NLM_C0_SCRATCH7 22
#define NLM_C0_DEBUG 23
#define NLM_C0_DEPC 24
#define NLM_C0_PERFCNT 25
#define NLM_C0_PERFCNT0 25
#define NLM_C0_PERFCNT1 25
#define NLM_C0_TAGLO 28
#define NLM_C0_DATALO 28
#define NLM_C0_TAGHI 29
#define NLM_C0_DATAHI 29
#define NLM_C0_ERROREPC 30
#define NLM_C0_DESAVE 31
/* cop0 status bits */
#define NLM_STATUS_CP0_EN (1<<28)
#define NLM_STATUS_CP1_EN (1<<29)
#define NLM_STATUS_CP2_EN (1<<30)
#define NLM_STATUS_KX_EN (1<<7)
#define NLM_STATUS_UX_EN (1<<5)
#ifndef LOCORE
#define nlm_memory_barrier() \
__asm__ __volatile__( \
".set push\n\t" \
".set noreorder\n\t" \
" sync\n\t" \
".set pop" \
::: "memory")
#define NLM_DEFINE_ACCESSORS32(name, reg, sel) \
static __inline__ uint32_t nlm_read_c0_##name(void) \
{ \
uint32_t __rv; \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".set mips64\n" \
"mfc0 %0, $%1, %2\n" \
".set pop\n" \
: "=r" (__rv) \
: "i" (reg), "i" (sel) \
); \
return __rv; \
} \
\
static __inline__ void nlm_write_c0_##name(uint32_t val) \
{ \
__asm__ __volatile__( \
".set push\n" \
".set noreorder\n" \
".set mips64\n" \
"mtc0 %0, $%1, %2\n" \
".set pop\n" \
:: "r" (val), "i" (reg), "i" (sel) \
); \
} struct __hack
/* struct __hack above swallows a semicolon - otherwise the macro
* usage below cannot have the terminating semicolon */
#if (__mips == 64)
#define NLM_DEFINE_ACCESSORS64(name, reg, sel) \
static __inline__ uint64_t nlm_read_c0_##name(void) \
{ \
uint64_t __rv; \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".set mips64\n" \
"dmfc0 %0,$%1,%2\n" \
".set pop\n" \
: "=r" (__rv) \
: "i" (reg), "i" (sel) ); \
return __rv; \
} \
\
static __inline__ void nlm_write_c0_##name(uint64_t val) \
{ \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".set mips64\n" \
"dmtc0 %0,$%1,%2\n" \
".set pop\n" \
:: "r" (val), "i" (reg), "i" (sel) ); \
} struct __hack
#else
#define NLM_DEFINE_ACCESSORS64(name, reg, sel) \
static __inline__ uint64_t nlm_read_c0_##name(void) \
{ \
uint32_t __high, __low; \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".set mips64\n" \
"dmfc0 $8, $%2, %3\n" \
"dsra32 %0, $8, 0\n" \
"sll %1, $8, 0\n" \
".set pop\n" \
: "=r"(__high), "=r"(__low) \
: "i"(reg), "i"(sel) \
: "$8" ); \
\
return (((uint64_t)__high << 32) | __low); \
} \
\
static __inline__ void nlm_write_c0_##name(uint64_t val) \
{ \
uint32_t __high = val >> 32; \
uint32_t __low = val & 0xffffffff; \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".set mips64\n" \
"dsll32 $8, %1, 0\n" \
"dsll32 $9, %0, 0\n" \
"dsrl32 $8, $8, 0\n" \
"or $8, $8, $9\n" \
"dmtc0 $8, $%2, %3\n" \
".set pop\n" \
:: "r"(__high), "r"(__low), "i"(reg), "i"(sel) \
: "$8", "$9"); \
} struct __hack
#endif
NLM_DEFINE_ACCESSORS32(index, 0, 0);
NLM_DEFINE_ACCESSORS32(random, 1, 0);
NLM_DEFINE_ACCESSORS64(entrylo0, 2, 0);
NLM_DEFINE_ACCESSORS64(entrylo1, 3, 0);
NLM_DEFINE_ACCESSORS64(context, 4, 0);
NLM_DEFINE_ACCESSORS64(userlocal, 4, 0);
NLM_DEFINE_ACCESSORS32(pagemask, 5, 0);
NLM_DEFINE_ACCESSORS32(wired, 6, 0);
NLM_DEFINE_ACCESSORS64(badvaddr, 8, 0);
NLM_DEFINE_ACCESSORS32(count, 9, 0);
NLM_DEFINE_ACCESSORS64(eirr, 9, 6);
NLM_DEFINE_ACCESSORS64(eimr, 9, 7);
NLM_DEFINE_ACCESSORS64(entryhi, 10, 0);
NLM_DEFINE_ACCESSORS32(compare, 11, 0);
NLM_DEFINE_ACCESSORS32(status, 12, 0);
NLM_DEFINE_ACCESSORS32(intctl, 12, 1);
NLM_DEFINE_ACCESSORS32(srsctl, 12, 2);
NLM_DEFINE_ACCESSORS32(cause, 13, 0);
NLM_DEFINE_ACCESSORS64(epc, 14, 0);
NLM_DEFINE_ACCESSORS32(prid, 15, 0);
NLM_DEFINE_ACCESSORS32(ebase, 15, 1);
NLM_DEFINE_ACCESSORS32(config0, 16, 0);
NLM_DEFINE_ACCESSORS32(config1, 16, 1);
NLM_DEFINE_ACCESSORS32(config2, 16, 2);
NLM_DEFINE_ACCESSORS32(config3, 16, 3);
NLM_DEFINE_ACCESSORS32(config6, 16, 6);
NLM_DEFINE_ACCESSORS32(config7, 16, 7);
NLM_DEFINE_ACCESSORS64(watchlo0, 18, 0);
NLM_DEFINE_ACCESSORS32(watchhi0, 19, 0);
NLM_DEFINE_ACCESSORS64(xcontext, 20, 0);
NLM_DEFINE_ACCESSORS64(scratch0, 22, 0);
NLM_DEFINE_ACCESSORS64(scratch1, 22, 1);
NLM_DEFINE_ACCESSORS64(scratch2, 22, 2);
NLM_DEFINE_ACCESSORS64(scratch3, 22, 3);
NLM_DEFINE_ACCESSORS64(scratch4, 22, 4);
NLM_DEFINE_ACCESSORS64(scratch5, 22, 5);
NLM_DEFINE_ACCESSORS64(scratch6, 22, 6);
NLM_DEFINE_ACCESSORS64(scratch7, 22, 7);
NLM_DEFINE_ACCESSORS32(debug, 23, 0);
NLM_DEFINE_ACCESSORS32(depc, 24, 0);
NLM_DEFINE_ACCESSORS32(perfctrl0, 25, 0);
NLM_DEFINE_ACCESSORS64(perfcntr0, 25, 1);
NLM_DEFINE_ACCESSORS32(perfctrl1, 25, 2);
NLM_DEFINE_ACCESSORS64(perfcntr1, 25, 3);
NLM_DEFINE_ACCESSORS32(perfctrl2, 25, 4);
NLM_DEFINE_ACCESSORS64(perfcntr2, 25, 5);
NLM_DEFINE_ACCESSORS32(perfctrl3, 25, 6);
NLM_DEFINE_ACCESSORS64(perfcntr3, 25, 7);
NLM_DEFINE_ACCESSORS64(taglo0, 28, 0);
NLM_DEFINE_ACCESSORS64(taglo2, 28, 2);
NLM_DEFINE_ACCESSORS64(taghi0, 29, 0);
NLM_DEFINE_ACCESSORS64(taghi2, 29, 2);
NLM_DEFINE_ACCESSORS64(errorepc, 30, 0);
NLM_DEFINE_ACCESSORS64(desave, 31, 0);
static __inline__ int nlm_nodeid(void)
{
return (nlm_read_c0_ebase() >> 5) & 0x3;
}
static __inline__ int nlm_cpuid(void)
{
return nlm_read_c0_ebase() & 0x1f;
}
static __inline__ int nlm_threadid(void)
{
return nlm_read_c0_ebase() & 0x3;
}
static __inline__ int nlm_coreid(void)
{
return (nlm_read_c0_ebase() >> 2) & 0x7;
}
#endif
#endif

327
sys/mips/nlm/hal/cop2.h Normal file
View File

@ -0,0 +1,327 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __NLM_COP2_H__
#define __NLM_COP2_H__
#define XLP_COP2_TX_BUF_REG 0
#define XLP_COP2_RX_BUF_REG 1
#define XLP_COP2_TXMSGSTATUS_REG 2
#define XLP_COP2_RXMSGSTATUS_REG 3
#define XLP_COP2_MSGSTATUS1_REG 4
#define XLP_COP2_MSGCONFIG_REG 5
#define XLP_COP2_MSGCONFIG1_REG 6
#define CROSSTHR_POPQ_EN 0x01
#define VC0_POPQ_EN 0x02
#define VC1_POPQ_EN 0x04
#define VC2_POPQ_EN 0x08
#define VC3_POPQ_EN 0x10
#define ALL_VC_POPQ_EN 0x1E
#define ALL_VC_CT_POPQ_EN 0x1F
struct nlm_fmn_msg {
uint64_t msg[4];
};
#define NLM_DEFINE_COP2_ACCESSORS32(name, reg, sel) \
static inline uint32_t nlm_read_c2_##name(void) \
{ \
uint32_t __rv; \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".set mips64\n" \
"mfc2 %0, $%1, %2\n" \
".set pop\n" \
: "=r" (__rv) \
: "i" (reg), "i" (sel) \
); \
return __rv; \
} \
\
static inline void nlm_write_c2_##name(uint32_t val) \
{ \
__asm__ __volatile__( \
".set push\n" \
".set noreorder\n" \
".set mips64\n" \
"mtc2 %0, $%1, %2\n" \
".set pop\n" \
:: "r" (val), "i" (reg), "i" (sel) \
); \
} struct __hack
#if (__mips == 64)
#define NLM_DEFINE_COP2_ACCESSORS64(name, reg, sel) \
static inline uint64_t nlm_read_c2_##name(void) \
{ \
uint64_t __rv; \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".set mips64\n" \
"dmfc2 %0, $%1, %2\n" \
".set pop\n" \
: "=r" (__rv) \
: "i" (reg), "i" (sel) ); \
return __rv; \
} \
\
static inline void nlm_write_c2_##name(uint64_t val) \
{ \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".set mips64\n" \
"dmtc2 %0, $%1, %2\n" \
".set pop\n" \
:: "r" (val), "i" (reg), "i" (sel) ); \
} struct __hack
#else
#define NLM_DEFINE_COP2_ACCESSORS64(name, reg, sel) \
static inline uint64_t nlm_read_c2_##name(void) \
{ \
uint32_t __high, __low; \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".set mips64\n" \
"dmfc2 $8, $%2, %3\n" \
"dsra32 %0, $8, 0\n" \
"sll %1, $8, 0\n" \
".set pop\n" \
: "=r"(__high), "=r"(__low) \
: "i"(reg), "i"(sel) \
: "$8" ); \
\
return (((uint64_t)__high << 32) | __low); \
} \
\
static inline void nlm_write_c2_##name(uint64_t val) \
{ \
uint32_t __high = val >> 32; \
uint32_t __low = val & 0xffffffff; \
__asm__ __volatile__ ( \
".set push\n" \
".set noreorder\n" \
".set mips64\n" \
"dsll32 $8, %1, 0\n" \
"dsll32 $9, %0, 0\n" \
"dsrl32 $8, $8, 0\n" \
"or $8, $8, $9\n" \
"dmtc2 $8, $%2, %3\n" \
".set pop\n" \
:: "r"(__high), "r"(__low), "i"(reg), "i"(sel) \
:"$8", "$9"); \
} struct __hack
#endif
NLM_DEFINE_COP2_ACCESSORS64(txbuf0, XLP_COP2_TX_BUF_REG, 0);
NLM_DEFINE_COP2_ACCESSORS64(txbuf1, XLP_COP2_TX_BUF_REG, 1);
NLM_DEFINE_COP2_ACCESSORS64(txbuf2, XLP_COP2_TX_BUF_REG, 2);
NLM_DEFINE_COP2_ACCESSORS64(txbuf3, XLP_COP2_TX_BUF_REG, 3);
NLM_DEFINE_COP2_ACCESSORS64(rxbuf0, XLP_COP2_RX_BUF_REG, 0);
NLM_DEFINE_COP2_ACCESSORS64(rxbuf1, XLP_COP2_RX_BUF_REG, 1);
NLM_DEFINE_COP2_ACCESSORS64(rxbuf2, XLP_COP2_RX_BUF_REG, 2);
NLM_DEFINE_COP2_ACCESSORS64(rxbuf3, XLP_COP2_RX_BUF_REG, 3);
NLM_DEFINE_COP2_ACCESSORS32(txmsgstatus, XLP_COP2_TXMSGSTATUS_REG, 0);
NLM_DEFINE_COP2_ACCESSORS32(rxmsgstatus, XLP_COP2_RXMSGSTATUS_REG, 0);
NLM_DEFINE_COP2_ACCESSORS32(msgstatus1, XLP_COP2_MSGSTATUS1_REG, 0);
NLM_DEFINE_COP2_ACCESSORS32(msgconfig, XLP_COP2_MSGCONFIG_REG, 0);
NLM_DEFINE_COP2_ACCESSORS32(msgconfig1, XLP_COP2_MSGCONFIG1_REG, 0);
/* successful completion returns 1, else 0 */
static __inline__ int nlm_msgsend(int val)
{
int result;
__asm__ volatile (
".set push \n"
".set noreorder \n"
".set mips64 \n"
"move $8, %1 \n"
"sync \n"
"/* msgsnds $9, $8 */ \n"
".word 0x4a084801 \n"
"move %0, $9 \n"
".set pop \n"
: "=r" (result)
: "r" (val)
: "$8", "$9"
);
return result;
}
static __inline__ int nlm_msgld(int vc)
{
int val;
__asm__ volatile (
".set push \n"
".set noreorder \n"
".set mips64 \n"
"move $8, %1 \n"
"/* msgld $9, $8 */ \n"
".word 0x4a084802 \n"
"move %0, $9 \n"
".set pop \n"
: "=r" (val)
: "r" (vc)
: "$8", "$9"
);
return val;
}
static __inline__ void nlm_msgwait(int vc)
{
__asm__ volatile (
".set push \n"
".set noreorder \n"
".set mips64 \n"
"move $8, %0 \n"
"/* msgwait $8 */ \n"
".word 0x4a080003 \n"
".set pop \n"
:: "r" (vc)
: "$8"
);
}
/* TODO this is not needed in n32 and n64 */
static __inline uint32_t
nlm_fmn_saveflags(void)
{
uint32_t sr = mips_rd_status();
mips_wr_status((sr & ~MIPS_SR_INT_IE) | MIPS_SR_COP_2_BIT);
return (sr);
}
static __inline void
nlm_fmn_restoreflags(uint32_t sr)
{
mips_wr_status(sr);
}
static __inline__ int nlm_fmn_msgsend(int dstid, int size, int swcode,
struct nlm_fmn_msg *m)
{
uint32_t flags, status;
int rv;
size -= 1;
flags = nlm_fmn_saveflags();
switch(size) {
case 3: nlm_write_c2_txbuf3(m->msg[3]);
case 2: nlm_write_c2_txbuf2(m->msg[2]);
case 1: nlm_write_c2_txbuf1(m->msg[1]);
case 0: nlm_write_c2_txbuf0(m->msg[0]);
}
dstid |= ((swcode << 24) | (size << 16));
status = nlm_msgsend(dstid);
rv = !status;
if (rv != 0)
rv = nlm_read_c2_txmsgstatus();
nlm_fmn_restoreflags(flags);
return (rv);
}
static __inline__ int nlm_fmn_msgrcv(int vc, int *srcid, int *size, int *code,
struct nlm_fmn_msg *m)
{
uint32_t status;
uint32_t msg_status, flags;
int tmp_sz, rv;
flags = nlm_fmn_saveflags();
status = nlm_msgld(vc); /* will return 0, if error */
rv = !status;
if (rv == 0) {
msg_status = nlm_read_c2_rxmsgstatus();
*size = ((msg_status >> 26) & 0x3) + 1;
*code = (msg_status >> 18) & 0xff;
*srcid = (msg_status >> 4) & 0xfff;
tmp_sz = *size - 1;
switch(tmp_sz) {
case 3: m->msg[3] = nlm_read_c2_rxbuf3();
case 2: m->msg[2] = nlm_read_c2_rxbuf2();
case 1: m->msg[1] = nlm_read_c2_rxbuf1();
case 0: m->msg[0] = nlm_read_c2_rxbuf0();
}
}
nlm_fmn_restoreflags(flags);
return rv;
}
/**
* nlm_fmn_cpu_init() initializes the per-h/w thread cop2 w.r.t the following
* configuration parameters. It needs to be individually setup on each
* hardware thread.
*
* int_vec - interrupt vector getting placed into msgconfig reg
* ctpe - cross thread message pop enable. When set to 1, the thread (h/w cpu)
* associated where this cop2 register is setup, can pop messages
* intended for any other thread in the same core.
* v0pe - VC0 pop message request mode enable. When set to 1, the thread
* can send pop requests to vc0.
* v1pe - VC1 pop message request mode enable. When set to 1, the thread
* can send pop requests to vc1.
* v2pe - VC2 pop message request mode enable. When set to 1, the thread
* can send pop requests to vc2.
* v3pe - VC3 pop message request mode enable. When set to 1, the thread
* can send pop requests to vc3.
*/
static __inline__ void nlm_fmn_cpu_init(int int_vec, int ctpe, int v0pe,
int v1pe, int v2pe, int v3pe)
{
uint32_t val = nlm_read_c2_msgconfig();
/* Note: in XLP PRM 0.8.1, the int_vec bits are un-documented
* in msgconfig register of cop2.
* As per chip/cpu RTL, [16:20] bits consist of int_vec.
*/
val |= ((int_vec & 0x1f) << 16) |
((v3pe & 0x1) << 4) |
((v2pe & 0x1) << 3) |
((v1pe & 0x1) << 2) |
((v0pe & 0x1) << 1) |
(ctpe & 0x1);
nlm_write_c2_msgconfig(val);
}
#endif

View File

@ -0,0 +1,70 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __NLM_CPUCONTROL_H__
#define __NLM_CPUCONTROL_H__
#define XLP_CPU_BLOCKID_IFU 0
#define XLP_CPU_BLOCKID_ICU 1
#define XLP_CPU_BLOCKID_IEU 2
#define XLP_CPU_BLOCKID_LSU 3
#define XLP_LSU_DEFEATURE 0x304
#define XLP_LSU_CERRLOG_REGID 0x09
#define XLP_CPU_BLOCKID_MMU 4
#define XLP_CPU_BLOCKID_PRF 5
#define XLP_CPU_BLOCKID_SCH 7
#define XLP_SCHED_DEFEATURE 0x700
#define XLP_CPU_BLOCKID_SCU 8
#define XLP_CPU_BLOCKID_FPU 9
#define XLP_CPU_BLOCKID_MAP 10
/* Offsets of interest from the 'MAP' Block */
#define XLP_BLKID_MAP_THREADMODE 0x00
#define XLP_BLKID_MAP_EXT_EBASE_ENABLE 0x04
#define XLP_BLKID_MAP_CCDI_CONFIG 0x08
#define XLP_BLKID_MAP_THRD0_CCDI_STATUS 0x0c
#define XLP_BLKID_MAP_THRD1_CCDI_STATUS 0x10
#define XLP_BLKID_MAP_THRD2_CCDI_STATUS 0x14
#define XLP_BLKID_MAP_THRD3_CCDI_STATUS 0x18
#define XLP_BLKID_MAP_THRD0_DEBUG_MODE 0x1c
#define XLP_BLKID_MAP_THRD1_DEBUG_MODE 0x20
#define XLP_BLKID_MAP_THRD2_DEBUG_MODE 0x24
#define XLP_BLKID_MAP_THRD3_DEBUG_MODE 0x28
#define XLP_BLKID_MAP_MISC_STATE 0x60
#define XLP_BLKID_MAP_DEBUG_READ_CTL 0x64
#define XLP_BLKID_MAP_DEBUG_READ_REG0 0x68
#define XLP_BLKID_MAP_DEBUG_READ_REG1 0x6c
#endif /* __NLM_CPUCONTROL_H__ */

789
sys/mips/nlm/hal/fmn.c Normal file
View File

@ -0,0 +1,789 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <mips/nlm/hal/mips-extns.h>
#include <mips/nlm/hal/mmio.h>
#include <mips/nlm/hal/iomap.h>
#include <mips/nlm/hal/fmn.h>
#include <sys/systm.h>
uint32_t bad_xlp_num_nodes = 4;
/* XLP can take upto 16K of FMN messages per hardware queue, as spill.
* But, configuring all 16K causes the total spill memory to required
* to blow upto 192MB for single chip configuration, and 768MB in four
* chip configuration. Hence for now, we will setup the per queue spill
* as 1K FMN messages. With this, the total spill memory needed for 1024
* hardware queues (with 12bytes per single entry FMN message) becomes
* (1*1024)*12*1024queues = 12MB. For the four chip config, the memory
* needed = 12 * 4 = 48MB.
*/
uint64_t nlm_cms_spill_total_messages = 1 * 1024;
/* On a XLP832, we have the following FMN stations:
* CPU stations: 8
* PCIE0 stations: 1
* PCIE1 stations: 1
* PCIE2 stations: 1
* PCIE3 stations: 1
* GDX stations: 1
* CRYPTO stations: 1
* RSA stations: 1
* CMP stations: 1
* POE stations: 1
* NAE stations: 1
* ==================
* Total : 18 stations per chip
*
* For all 4 nodes, there are 18*4 = 72 FMN stations
*/
uint32_t nlm_cms_total_stations = 18 * 4 /*xlp_num_nodes*/;
uint32_t cms_onchip_seg_availability[XLP_CMS_ON_CHIP_PER_QUEUE_SPACE];
int nlm_cms_verify_credit_config (int spill_en, int tot_credit)
{
/* Note: In XLP there seem to be no mechanism to read back
* the credit count that has been programmed into a sid / did pair;
* since we have only one register 0x2000 to read.
* Hence it looks like all credit mgmt/verification needs to
* be done by software. Software could keep track of total credits
* getting programmed and verify it from this function.
*/
if (spill_en) {
/* TODO */
}
if (tot_credit > (XLP_CMS_ON_CHIP_MESG_SPACE*bad_xlp_num_nodes))
return 1; /* credits overflowed - should not happen */
return 0;
}
/**
* Takes inputs as node, queue_size and maximum number of queues.
* Calculates the base, start & end and returns the same for a
* defined qid.
*
* The output queues are maintained in the internal output buffer
* which is a on-chip SRAM structure. For the actial hardware
* internal implementation, It is a structure which consists
* of eight banks of 4096-entry x message-width SRAMs. The SRAM
* implementation is designed to run at 1GHz with a 1-cycle read/write
* access. A read/write transaction can be initiated for each bank
* every cycle for a total of eight accesses per cycle. Successive
* entries of the same output queue are placed in successive banks.
* This is done to spread different read & write accesses to same/different
* output queue over as many different banks as possible so that they
* can be scheduled concurrently. Spreading the accesses to as many banks
* as possible to maximize the concurrency internally is important for
* achieving the desired peak throughput. This is done by h/w implementation
* itself.
*
* Output queues are allocated from this internal output buffer by
* software. The total capacity of the output buffer is 32K-entry.
* Each output queue can be sized from 32-entry to 1024-entry in
* increments of 32-entry. This is done by specifying a Start & a
* End pointer: pointers to the first & last 32-entry chunks allocated
* to the output queue.
*
* To optimize the storage required for 1024 OQ pointers, the upper 5-bits
* are shared by the Start & the End pointer. The side-effect of this
* optimization is that an OQ can't cross a 1024-entry boundary. Also, the
* lower 5-bits don't need to be specified in the Start & the End pointer
* as the allocation is in increments of 32-entries.
*
* Queue occupancy is tracked by a Head & a Tail pointer. Tail pointer
* indicates the location to which next entry will be written & Head
* pointer indicates the location from which next entry will be read. When
* these pointers reach the top of the allocated space (indicated by the
* End pointer), they are reset to the bottom of the allocated space
* (indicated by the Start pointer).
*
* Output queue pointer information:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 14 10 9 5 4 0
* ------------------
* | base ptr |
* ------------------
* ----------------
* | start ptr |
* ----------------
* ----------------
* | end ptr |
* ----------------
* ------------------------------------
* | head ptr |
* ------------------------------------
* ------------------------------------
* | tail ptr |
* ------------------------------------
* Note:
* A total of 1024 segments can sit on one software-visible "bank"
* of internal SRAM. Each segment contains 32 entries. Also note
* that sw-visible "banks" are not the same as the actual internal
* 8-bank implementation of hardware. It is an optimization of
* internal access.
*
*/
void nlm_cms_setup_credits(uint64_t base, int destid, int srcid, int credit)
{
uint32_t val;
val = ((credit << 24) | (destid << 12) | (srcid << 0));
nlm_wreg_cms(base, XLP_CMS_OUTPUTQ_CREDIT_CFG_REG, val);
}
int nlm_cms_config_onchip_queue (uint64_t base, uint64_t spill_base,
int qid, int spill_en)
{
/* Configure 32 as onchip queue depth */
nlm_cms_alloc_onchip_q(base, qid, 1);
/* Spill configuration */
if (spill_en) {
/* Configure 4*4KB = 16K as spill size */
nlm_cms_alloc_spill_q(base, qid, spill_base, 4);
}
#if 0
/* configure credits for src cpu0, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_CPU0_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src cpu1, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_CPU1_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src cpu2, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_CPU2_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src cpu3, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_CPU3_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src cpu4, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_CPU4_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src cpu5, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_CPU5_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src cpu6, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_CPU6_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src cpu7, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_CPU7_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src pcie0, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_PCIE0_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src pcie1, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_PCIE1_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src pcie2, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_PCIE2_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src pcie3, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_PCIE3_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src dte, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_DTE_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src rsa_ecc, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_RSA_ECC_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src crypto, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_CRYPTO_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src cmp, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_CMP_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src poe, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_POE_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
/* configure credits for src nae, on this queue */
nlm_cms_setup_credits(base, qid, XLP_CMS_NAE_SRC_STID,
XLP_CMS_DEFAULT_CREDIT(nlm_cms_total_stations,
nlm_cms_spill_total_messages));
#endif
return 0;
}
/*
* base - CMS module base address for this node.
* qid - is the output queue id otherwise called as vc id
* spill_base - is the 40-bit physical address of spill memory. Must be
4KB aligned.
* nsegs - No of segments where a "1" indicates 4KB. Spill size must be
* a multiple of 4KB.
*/
int nlm_cms_alloc_spill_q(uint64_t base, int qid, uint64_t spill_base,
int nsegs)
{
uint64_t queue_config;
uint32_t spill_start;
if(nsegs > XLP_CMS_MAX_SPILL_SEGMENTS_PER_QUEUE) {
return 1;
}
queue_config = nlm_rdreg_cms(base,(XLP_CMS_OUTPUTQ_CONFIG_REG(qid)));
spill_start = ((spill_base >> 12) & 0x3F);
/* Spill configuration */
queue_config = (((uint64_t)XLP_CMS_SPILL_ENA << 62) |
(((spill_base >> 18) & 0x3FFFFF) << 27) |
(spill_start + nsegs - 1) << 21 |
(spill_start << 15));
nlm_wreg_cms(base,(XLP_CMS_OUTPUTQ_CONFIG_REG(qid)),queue_config);
return 0;
}
/*
* base - CMS module base address for this node.
* qid - is the output queue id otherwise called as vc id
* nsegs - No of segments where a "1" indicates 32 credits. On chip
* credits must be a multiple of 32.
*/
int nlm_cms_alloc_onchip_q(uint64_t base, int qid, int nsegs)
{
static uint32_t curr_end = 0;
uint64_t queue_config;
int onchipbase, start, last;
uint8_t i;
if( ((curr_end + nsegs) > XLP_CMS_MAX_ONCHIP_SEGMENTS) ||
(nsegs > XLP_CMS_ON_CHIP_PER_QUEUE_SPACE) ) {
/* Invalid configuration */
return 1;
}
if(((curr_end % 32) + nsegs - 1) <= 31) {
onchipbase = (curr_end / 32);
start = (curr_end % 32);
curr_end += nsegs;
} else {
onchipbase = (curr_end / 32) + 1;
start = 0;
curr_end = ((onchipbase * 32) + nsegs);
}
last = start + nsegs - 1;
for(i = start;i <= last;i++) {
if(cms_onchip_seg_availability[onchipbase] & (1 << i)) {
/* Conflict!!! segment is already allocated */
return 1;
}
}
/* Update the availability bitmap as consumed */
for(i = start; i <= last; i++) {
cms_onchip_seg_availability[onchipbase] |= (1 << i);
}
queue_config = nlm_rdreg_cms(base,(XLP_CMS_OUTPUTQ_CONFIG_REG(qid)));
/* On chip configuration */
queue_config = (((uint64_t)XLP_CMS_QUEUE_ENA << 63) |
((onchipbase & 0x1f) << 10) |
((last & 0x1f) << 5) |
(start & 0x1f));
nlm_wreg_cms(base,(XLP_CMS_OUTPUTQ_CONFIG_REG(qid)),queue_config);
return 0;
}
void nlm_cms_default_setup(int node, uint64_t spill_base, int spill_en,
int popq_en)
{
int j, k, vc;
int queue;
uint64_t base;
base = nlm_regbase_cms(node);
for(j=0; j<1024; j++) {
printf("Qid:0x%04d Val:0x%016jx\n",j, (uintmax_t)nlm_cms_get_onchip_queue (base, j));
}
/* Enable all cpu push queues */
for (j=0; j<XLP_MAX_CORES; j++)
for (k=0; k<XLP_MAX_THREADS; k++)
for (vc=0; vc<XLP_CMS_MAX_VCPU_VC; vc++) {
/* TODO : remove this once SMP works */
if( (j == 0) && (k == 0) )
continue;
queue = XLP_CMS_CPU_PUSHQ(node, j, k, vc);
nlm_cms_config_onchip_queue(base, spill_base, queue, spill_en);
}
/* Enable pcie 0 push queue */
for (j=XLP_CMS_PCIE0_QID(0); j<XLP_CMS_PCIE0_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_config_onchip_queue(base, spill_base, queue, spill_en);
}
/* Enable pcie 1 push queue */
for (j=XLP_CMS_PCIE1_QID(0); j<XLP_CMS_PCIE1_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_config_onchip_queue(base, spill_base, queue, spill_en);
}
/* Enable pcie 2 push queue */
for (j=XLP_CMS_PCIE2_QID(0); j<XLP_CMS_PCIE2_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_config_onchip_queue(base, spill_base, queue, spill_en);
}
/* Enable pcie 3 push queue */
for (j=XLP_CMS_PCIE3_QID(0); j<XLP_CMS_PCIE3_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_config_onchip_queue(base, spill_base, queue, spill_en);
}
/* Enable DTE push queue */
for (j=XLP_CMS_DTE_QID(0); j<XLP_CMS_DTE_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_config_onchip_queue(base, spill_base, queue, spill_en);
}
/* Enable RSA/ECC push queue */
for (j=XLP_CMS_RSA_ECC_QID(0); j<XLP_CMS_RSA_ECC_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_config_onchip_queue(base, spill_base, queue, spill_en);
}
/* Enable crypto push queue */
for (j=XLP_CMS_CRYPTO_QID(0); j<XLP_CMS_CRYPTO_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_config_onchip_queue(base, spill_base, queue, spill_en);
}
/* Enable CMP push queue */
for (j=XLP_CMS_CMP_QID(0); j<XLP_CMS_CMP_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_config_onchip_queue(base, spill_base, queue, spill_en);
}
/* Enable POE push queue */
for (j=XLP_CMS_POE_QID(0); j<XLP_CMS_POE_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_config_onchip_queue(base, spill_base, queue, spill_en);
}
/* Enable NAE push queue */
for (j=XLP_CMS_NAE_QID(0); j<XLP_CMS_NAE_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_config_onchip_queue(base, spill_base, queue, spill_en);
}
/* Enable all pop queues */
if (popq_en) {
for (j=XLP_CMS_POPQ_QID(0); j<XLP_CMS_POPQ_MAXQID; j++) {
queue = XLP_CMS_POPQ(node, j);
nlm_cms_config_onchip_queue(base, spill_base, queue,
spill_en);
}
}
}
uint64_t nlm_cms_get_onchip_queue (uint64_t base, int qid)
{
return nlm_rdreg_cms(base, XLP_CMS_OUTPUTQ_CONFIG_REG(qid));
}
void nlm_cms_set_onchip_queue (uint64_t base, int qid, uint64_t val)
{
uint64_t rdval;
rdval = nlm_rdreg_cms(base, XLP_CMS_OUTPUTQ_CONFIG_REG(qid));
rdval |= val;
nlm_wreg_cms(base, XLP_CMS_OUTPUTQ_CONFIG_REG(qid), rdval);
}
void nlm_cms_per_queue_level_intr(uint64_t base, int qid, int sub_type,
int intr_val)
{
uint64_t val;
val = nlm_rdreg_cms(base, XLP_CMS_OUTPUTQ_CONFIG_REG(qid));
val |= (((uint64_t)sub_type<<54) |
((uint64_t)intr_val<<56));
nlm_wreg_cms(base, XLP_CMS_OUTPUTQ_CONFIG_REG(qid), val);
}
void nlm_cms_level_intr(int node, int sub_type, int intr_val)
{
int j, k, vc;
int queue;
uint64_t base;
base = nlm_regbase_cms(node);
/* setup level intr config on all cpu push queues */
for (j=0; j<XLP_MAX_CORES; j++)
for (k=0; k<XLP_MAX_THREADS; k++)
for (vc=0; vc<XLP_CMS_MAX_VCPU_VC; vc++) {
queue = XLP_CMS_CPU_PUSHQ(node, j, k, vc);
nlm_cms_per_queue_level_intr(base, queue, sub_type, intr_val);
}
/* setup level intr config on all pcie 0 push queue */
for (j=XLP_CMS_PCIE0_QID(0); j<XLP_CMS_PCIE0_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_level_intr(base, queue, sub_type, intr_val);
}
/* setup level intr config on all pcie 1 push queue */
for (j=XLP_CMS_PCIE1_QID(0); j<XLP_CMS_PCIE1_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_level_intr(base, queue, sub_type, intr_val);
}
/* setup level intr config on all pcie 2 push queue */
for (j=XLP_CMS_PCIE2_QID(0); j<XLP_CMS_PCIE2_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_level_intr(base, queue, sub_type, intr_val);
}
/* setup level intr config on all pcie 3 push queue */
for (j=XLP_CMS_PCIE3_QID(0); j<XLP_CMS_PCIE3_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_level_intr(base, queue, sub_type, intr_val);
}
/* setup level intr config on all DTE push queue */
for (j=XLP_CMS_DTE_QID(0); j<XLP_CMS_DTE_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_level_intr(base, queue, sub_type, intr_val);
}
/* setup level intr config on all RSA/ECC push queue */
for (j=XLP_CMS_RSA_ECC_QID(0); j<XLP_CMS_RSA_ECC_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_level_intr(base, queue, sub_type, intr_val);
}
/* setup level intr config on all crypto push queue */
for (j=XLP_CMS_CRYPTO_QID(0); j<XLP_CMS_CRYPTO_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_level_intr(base, queue, sub_type, intr_val);
}
/* setup level intr config on all CMP push queue */
for (j=XLP_CMS_CMP_QID(0); j<XLP_CMS_CMP_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_level_intr(base, queue, sub_type, intr_val);
}
/* setup level intr config on all POE push queue */
for (j=XLP_CMS_POE_QID(0); j<XLP_CMS_POE_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_level_intr(base, queue, sub_type, intr_val);
}
/* setup level intr config on all NAE push queue */
for (j=XLP_CMS_NAE_QID(0); j<XLP_CMS_NAE_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_level_intr(base, queue, sub_type, intr_val);
}
/* setup level intr config on all pop queues */
for (j=XLP_CMS_POPQ_QID(0); j<XLP_CMS_POPQ_MAXQID; j++) {
queue = XLP_CMS_POPQ(node, j);
nlm_cms_per_queue_level_intr(base, queue, sub_type, intr_val);
}
}
void nlm_cms_per_queue_timer_intr(uint64_t base, int qid, int sub_type,
int intr_val)
{
uint64_t val;
val = nlm_rdreg_cms(base, XLP_CMS_OUTPUTQ_CONFIG_REG(qid));
val |= (((uint64_t)sub_type<<49) |
((uint64_t)intr_val<<51));
nlm_wreg_cms(base, XLP_CMS_OUTPUTQ_CONFIG_REG(qid), val);
}
void nlm_cms_timer_intr(int node, int en, int sub_type, int intr_val)
{
int j, k, vc;
int queue;
uint64_t base;
base = nlm_regbase_cms(node);
/* setup timer intr config on all cpu push queues */
for (j=0; j<XLP_MAX_CORES; j++)
for (k=0; k<XLP_MAX_THREADS; k++)
for (vc=0; vc<XLP_CMS_MAX_VCPU_VC; vc++) {
queue = XLP_CMS_CPU_PUSHQ(node, j, k, vc);
nlm_cms_per_queue_timer_intr(base, queue, sub_type, intr_val);
}
/* setup timer intr config on all pcie 0 push queue */
for (j=XLP_CMS_PCIE0_QID(0); j<XLP_CMS_PCIE0_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_timer_intr(base, queue, sub_type, intr_val);
}
/* setup timer intr config on all pcie 1 push queue */
for (j=XLP_CMS_PCIE1_QID(0); j<XLP_CMS_PCIE1_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_timer_intr(base, queue, sub_type, intr_val);
}
/* setup timer intr config on all pcie 2 push queue */
for (j=XLP_CMS_PCIE2_QID(0); j<XLP_CMS_PCIE2_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_timer_intr(base, queue, sub_type, intr_val);
}
/* setup timer intr config on all pcie 3 push queue */
for (j=XLP_CMS_PCIE3_QID(0); j<XLP_CMS_PCIE3_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_timer_intr(base, queue, sub_type, intr_val);
}
/* setup timer intr config on all DTE push queue */
for (j=XLP_CMS_DTE_QID(0); j<XLP_CMS_DTE_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_timer_intr(base, queue, sub_type, intr_val);
}
/* setup timer intr config on all RSA/ECC push queue */
for (j=XLP_CMS_RSA_ECC_QID(0); j<XLP_CMS_RSA_ECC_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_timer_intr(base, queue, sub_type, intr_val);
}
/* setup timer intr config on all crypto push queue */
for (j=XLP_CMS_CRYPTO_QID(0); j<XLP_CMS_CRYPTO_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_timer_intr(base, queue, sub_type, intr_val);
}
/* setup timer intr config on all CMP push queue */
for (j=XLP_CMS_CMP_QID(0); j<XLP_CMS_CMP_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_timer_intr(base, queue, sub_type, intr_val);
}
/* setup timer intr config on all POE push queue */
for (j=XLP_CMS_POE_QID(0); j<XLP_CMS_POE_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_timer_intr(base, queue, sub_type, intr_val);
}
/* setup timer intr config on all NAE push queue */
for (j=XLP_CMS_NAE_QID(0); j<XLP_CMS_NAE_MAXQID; j++) {
queue = XLP_CMS_IO_PUSHQ(node, j);
nlm_cms_per_queue_timer_intr(base, queue, sub_type, intr_val);
}
/* setup timer intr config on all pop queues */
for (j=XLP_CMS_POPQ_QID(0); j<XLP_CMS_POPQ_MAXQID; j++) {
queue = XLP_CMS_POPQ(node, j);
nlm_cms_per_queue_timer_intr(base, queue, sub_type, intr_val);
}
}
/* returns 1 if interrupt has been generated for this output queue */
int nlm_cms_outputq_intr_check(uint64_t base, int qid)
{
uint64_t val;
val = nlm_rdreg_cms(base, XLP_CMS_OUTPUTQ_CONFIG_REG(qid));
return ((val >> 59) & 0x1);
}
void nlm_cms_outputq_clr_intr(uint64_t base, int qid)
{
uint64_t val;
val = nlm_rdreg_cms(base, XLP_CMS_OUTPUTQ_CONFIG_REG(qid));
val |= (1ULL<<59);
nlm_wreg_cms(base, XLP_CMS_OUTPUTQ_CONFIG_REG(qid), val);
}
void nlm_cms_illegal_dst_error_intr(uint64_t base, int en)
{
uint64_t val;
val = nlm_rdreg_cms(base, XLP_CMS_MSG_CONFIG_REG);
val |= (en<<8);
nlm_wreg_cms(base, XLP_CMS_MSG_CONFIG_REG, val);
}
void nlm_cms_timeout_error_intr(uint64_t base, int en)
{
uint64_t val;
val = nlm_rdreg_cms(base, XLP_CMS_MSG_CONFIG_REG);
val |= (en<<7);
nlm_wreg_cms(base, XLP_CMS_MSG_CONFIG_REG, val);
}
void nlm_cms_biu_error_resp_intr(uint64_t base, int en)
{
uint64_t val;
val = nlm_rdreg_cms(base, XLP_CMS_MSG_CONFIG_REG);
val |= (en<<6);
nlm_wreg_cms(base, XLP_CMS_MSG_CONFIG_REG, val);
}
void nlm_cms_spill_uncorrectable_ecc_error_intr(uint64_t base, int en)
{
uint64_t val;
val = nlm_rdreg_cms(base, XLP_CMS_MSG_CONFIG_REG);
val |= (en<<5) | (en<<3);
nlm_wreg_cms(base, XLP_CMS_MSG_CONFIG_REG, val);
}
void nlm_cms_spill_correctable_ecc_error_intr(uint64_t base, int en)
{
uint64_t val;
val = nlm_rdreg_cms(base, XLP_CMS_MSG_CONFIG_REG);
val |= (en<<4) | (en<<2);
nlm_wreg_cms(base, XLP_CMS_MSG_CONFIG_REG, val);
}
void nlm_cms_outputq_uncorrectable_ecc_error_intr(uint64_t base, int en)
{
uint64_t val;
val = nlm_rdreg_cms(base, XLP_CMS_MSG_CONFIG_REG);
val |= (en<<1);
nlm_wreg_cms(base, XLP_CMS_MSG_CONFIG_REG, val);
}
void nlm_cms_outputq_correctable_ecc_error_intr(uint64_t base, int en)
{
uint64_t val;
val = nlm_rdreg_cms(base, XLP_CMS_MSG_CONFIG_REG);
val |= (en<<0);
nlm_wreg_cms(base, XLP_CMS_MSG_CONFIG_REG, val);
}
uint64_t nlm_cms_network_error_status(uint64_t base)
{
return nlm_rdreg_cms(base, XLP_CMS_MSG_ERR_REG);
}
int nlm_cms_get_net_error_code(uint64_t err)
{
return ((err >> 12) & 0xf);
}
int nlm_cms_get_net_error_syndrome(uint64_t err)
{
return ((err >> 32) & 0x1ff);
}
int nlm_cms_get_net_error_ramindex(uint64_t err)
{
return ((err >> 44) & 0x7fff);
}
int nlm_cms_get_net_error_outputq(uint64_t err)
{
return ((err >> 16) & 0xfff);
}
/*========================= FMN Tracing related APIs ================*/
void nlm_cms_trace_setup(uint64_t base, int en, uint64_t trace_base,
uint64_t trace_limit, int match_dstid_en,
int dst_id, int match_srcid_en, int src_id,
int wrap)
{
uint64_t val;
nlm_wreg_cms(base, XLP_CMS_TRACE_BASE_ADDR_REG, trace_base);
nlm_wreg_cms(base, XLP_CMS_TRACE_LIMIT_ADDR_REG, trace_limit);
val = nlm_rdreg_cms(base, XLP_CMS_TRACE_CONFIG_REG);
val |= (((uint64_t)match_dstid_en << 39) |
((dst_id & 0xfff) << 24) |
(match_srcid_en << 23) |
((src_id & 0xfff) << 8) |
(wrap << 1) |
(en << 0));
nlm_wreg_cms(base, XLP_CMS_MSG_CONFIG_REG, val);
}
void nlm_cms_endian_byte_swap (uint64_t base, int en)
{
nlm_wreg_cms(base, XLP_CMS_MSG_ENDIAN_SWAP_REG, en);
}

275
sys/mips/nlm/hal/fmn.h Normal file
View File

@ -0,0 +1,275 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __NLM_FMNV2_H__
#define __NLM_FMNV2_H__
/**
* @file_name fmn.h
* @author Netlogic Microsystems
* @brief HAL for Fast message network V2
*/
/* FMN configuration registers */
#define XLP_CMS_OUTPUTQ_CONFIG_REG(i) ((i)*2)
#define XLP_CMS_MAX_OUTPUTQ 1024
#define XLP_CMS_OUTPUTQ_CREDIT_CFG_REG (0x2000/4)
#define XLP_CMS_MSG_CONFIG_REG (0x2008/4)
#define XLP_CMS_MSG_ERR_REG (0x2010/4)
#define XLP_CMS_TRACE_CONFIG_REG (0x2018/4)
#define XLP_CMS_TRACE_BASE_ADDR_REG (0x2020/4)
#define XLP_CMS_TRACE_LIMIT_ADDR_REG (0x2028/4)
#define XLP_CMS_TRACE_CURRENT_ADDR_REG (0x2030/4)
#define XLP_CMS_MSG_ENDIAN_SWAP_REG (0x2038/4)
#define XLP_CMS_CPU_PUSHQ(node, core, thread, vc) \
(((node)<<10) | ((core)<<4) | ((thread)<<2) | ((vc)<<0))
#define XLP_CMS_POPQ(node, queue) (((node)<<10) | (queue))
#define XLP_CMS_IO_PUSHQ(node, queue) (((node)<<10) | (queue))
#define XLP_CMS_POPQ_QID(i) (128+(i))
#define XLP_CMS_POPQ_MAXQID 255
#define XLP_CMS_PCIE0_QID(i) (256+(i))
#define XLP_CMS_PCIE0_MAXQID 257
#define XLP_CMS_PCIE1_QID(i) (258+(i))
#define XLP_CMS_PCIE1_MAXQID 259
#define XLP_CMS_PCIE2_QID(i) (260+(i))
#define XLP_CMS_PCIE2_MAXQID 261
#define XLP_CMS_PCIE3_QID(i) (262+(i))
#define XLP_CMS_PCIE3_MAXQID 263
#define XLP_CMS_DTE_QID(i) (264+(i))
#define XLP_CMS_DTE_MAXQID 267
#define XLP_CMS_RSA_ECC_QID(i) (272+(i))
#define XLP_CMS_RSA_ECC_MAXQID 280
#define XLP_CMS_CRYPTO_QID(i) (281+(i))
#define XLP_CMS_CRYPTO_MAXQID 296
/* TODO PCI header register 0x3C says CMP starts at 297(0x129) VERIFY */
#define XLP_CMS_CMP_QID(i) (298+(i))
#define XLP_CMS_CMP_MAXQID 305
#define XLP_CMS_POE_QID(i) (384+(i))
#define XLP_CMS_POE_MAXQID 391
#define XLP_CMS_NAE_QID(i) (476+(i))
#define XLP_CMS_NAE_MAXQID 1023
#define XLP_CMS_NAE_TX_VC_BASE 476
#define XLP_CMS_NAE_TX_VC_LIMIT 999
#define XLP_CMS_NAE_RX_VC_BASE 1000
#define XLP_CMS_NAE_RX_VC_LIMIT 1019
#define XLP_MAX_CMS_QUEUES 1024
/* FMN Level Interrupt Type */
#define XLP_CMS_LVL_INTR_DISABLE 0
#define XLP_CMS_LVL_LOW_WATERMARK 1
#define XLP_CMS_LVL_HI_WATERMARK 2
/* FMN Level interrupt trigger values */
#define XLP_CMS_QUEUE_NON_EMPTY 0
#define XLP_CMS_QUEUE_QUARTER_FULL 1
#define XLP_CMS_QUEUE_HALF_FULL 2
#define XLP_CMS_QUEUE_THREE_QUARTER_FULL 3
#define XLP_CMS_QUEUE_FULL 4
/* FMN Timer Interrupt Type */
#define XLP_CMS_TIMER_INTR_DISABLE 0
#define XLP_CMS_TIMER_CONSUMER 1
#define XLP_CMS_TIMER_PRODUCER 1
/* FMN timer interrupt trigger values */
#define XLP_CMS_TWO_POW_EIGHT_CYCLES 0
#define XLP_CMS_TWO_POW_TEN_CYCLES 1
#define XLP_CMS_TWO_POW_TWELVE_CYCLES 2
#define XLP_CMS_TWO_POW_FOURTEEN_CYCLES 3
#define XLP_CMS_TWO_POW_SIXTEEN_CYCLES 4
#define XLP_CMS_TWO_POW_EIGHTTEEN_CYCLES 5
#define XLP_CMS_TWO_POW_TWENTY_CYCLES 6
#define XLP_CMS_TWO_POW_TWENTYTWO_CYCLES 7
#define XLP_CMS_QUEUE_ENA 1ULL
#define XLP_CMS_QUEUE_DIS 0
#define XLP_CMS_SPILL_ENA 1ULL
#define XLP_CMS_SPILL_DIS 0
#define XLP_CMS_MAX_VCPU_VC 4
/* Each XLP chip can hold upto 32K messages on the chip itself */
#define XLP_CMS_ON_CHIP_MESG_SPACE (32*1024)
#define XLP_CMS_ON_CHIP_PER_QUEUE_SPACE \
((XLP_CMS_ON_CHIP_MESG_SPACE)/(XLP_MAX_CMS_QUEUES))
#define XLP_CMS_MAX_ONCHIP_SEGMENTS 1024
#define XLP_CMS_MAX_SPILL_SEGMENTS_PER_QUEUE 64
/* FMN Network error */
#define XLP_CMS_ILLEGAL_DST_ERROR 0x100
#define XLP_CMS_BIU_TIMEOUT_ERROR 0x080
#define XLP_CMS_BIU_ERROR 0x040
#define XLP_CMS_SPILL_FILL_UNCORRECT_ECC_ERROR 0x020
#define XLP_CMS_SPILL_FILL_CORRECT_ECC_ERROR 0x010
#define XLP_CMS_SPILL_UNCORRECT_ECC_ERROR 0x008
#define XLP_CMS_SPILL_CORRECT_ECC_ERROR 0x004
#define XLP_CMS_OUTPUTQ_UNCORRECT_ECC_ERROR 0x002
#define XLP_CMS_OUTPUTQ_CORRECT_ECC_ERROR 0x001
/* worst case, a single entry message consists of a 4 byte header
* and an 8-byte entry = 12 bytes in total
*/
#define XLP_CMS_SINGLE_ENTRY_MSG_SIZE 12
/* total spill memory needed for one FMN queue */
#define XLP_CMS_PER_QUEUE_SPILL_MEM(spilltotmsgs) \
((spilltotmsgs) * (XLP_CMS_SINGLE_ENTRY_MSG_SIZE))
/* total spill memory needed */
#define XLP_CMS_TOTAL_SPILL_MEM(spilltotmsgs) \
((XLP_CMS_PER_QUEUE_SPILL_MEM(spilltotmsgs)) * \
(XLP_MAX_CMS_QUEUES))
/* total number of FMN messages possible in a queue */
#define XLP_CMS_TOTAL_QUEUE_SIZE(spilltotmsgs) \
((spilltotmsgs) + (XLP_CMS_ON_CHIP_PER_QUEUE_SPACE))
/* FMN Src station id's */
#define XLP_CMS_CPU0_SRC_STID (0 << 4)
#define XLP_CMS_CPU1_SRC_STID (1 << 4)
#define XLP_CMS_CPU2_SRC_STID (2 << 4)
#define XLP_CMS_CPU3_SRC_STID (3 << 4)
#define XLP_CMS_CPU4_SRC_STID (4 << 4)
#define XLP_CMS_CPU5_SRC_STID (5 << 4)
#define XLP_CMS_CPU6_SRC_STID (6 << 4)
#define XLP_CMS_CPU7_SRC_STID (7 << 4)
#define XLP_CMS_PCIE0_SRC_STID 256
#define XLP_CMS_PCIE1_SRC_STID 258
#define XLP_CMS_PCIE2_SRC_STID 260
#define XLP_CMS_PCIE3_SRC_STID 262
#define XLP_CMS_DTE_SRC_STID 264
#define XLP_CMS_RSA_ECC_SRC_STID 272
#define XLP_CMS_CRYPTO_SRC_STID 281
#define XLP_CMS_CMP_SRC_STID 298
#define XLP_CMS_POE_SRC_STID 384
#define XLP_CMS_NAE_SRC_STID 476
#if 0
#define XLP_CMS_DEFAULT_CREDIT(cmstotstns,spilltotmsgs) \
((XLP_CMS_TOTAL_QUEUE_SIZE(spilltotmsgs)) / \
(cmstotstns))
#endif
#define XLP_CMS_DEFAULT_CREDIT(cmstotstns,spilltotmsgs) 8
/* POPQ related defines */
#define XLP_CMS_POPQID_START 128
#define XLP_CMS_POPQID_END 255
#define XLP_CMS_INT_RCVD 0x800000000000000ULL
#define nlm_rdreg_cms(b, r) nlm_read_reg64_xkseg(b,r)
#define nlm_wreg_cms(b, r, v) nlm_write_reg64_xkseg(b,r,v)
#define nlm_pcibase_cms(node) nlm_pcicfg_base(XLP_IO_CMS_OFFSET(node))
#define nlm_regbase_cms(node) nlm_pcibar0_base_xkphys(nlm_pcibase_cms(node))
enum fmn_swcode {
FMN_SWCODE_CPU0=1,
FMN_SWCODE_CPU1,
FMN_SWCODE_CPU2,
FMN_SWCODE_CPU3,
FMN_SWCODE_CPU4,
FMN_SWCODE_CPU5,
FMN_SWCODE_CPU6,
FMN_SWCODE_CPU7,
FMN_SWCODE_CPU8,
FMN_SWCODE_CPU9,
FMN_SWCODE_CPU10,
FMN_SWCODE_CPU11,
FMN_SWCODE_CPU12,
FMN_SWCODE_CPU13,
FMN_SWCODE_CPU14,
FMN_SWCODE_CPU15,
FMN_SWCODE_CPU16,
FMN_SWCODE_CPU17,
FMN_SWCODE_CPU18,
FMN_SWCODE_CPU19,
FMN_SWCODE_CPU20,
FMN_SWCODE_CPU21,
FMN_SWCODE_CPU22,
FMN_SWCODE_CPU23,
FMN_SWCODE_CPU24,
FMN_SWCODE_CPU25,
FMN_SWCODE_CPU26,
FMN_SWCODE_CPU27,
FMN_SWCODE_CPU28,
FMN_SWCODE_CPU29,
FMN_SWCODE_CPU30,
FMN_SWCODE_CPU31,
FMN_SWCODE_CPU32,
FMN_SWCODE_PCIE0,
FMN_SWCODE_PCIE1,
FMN_SWCODE_PCIE2,
FMN_SWCODE_PCIE3,
FMN_SWCODE_DTE,
FMN_SWCODE_CRYPTO,
FMN_SWCODE_RSA,
FMN_SWCODE_CMP,
FMN_SWCODE_POE,
FMN_SWCODE_NAE,
};
extern uint64_t nlm_cms_spill_total_messages;
extern uint32_t nlm_cms_total_stations;
extern uint32_t cms_onchip_seg_availability[XLP_CMS_ON_CHIP_PER_QUEUE_SPACE];
extern uint64_t cms_base_addr(int node);
extern int nlm_cms_verify_credit_config (int spill_en, int tot_credit);
extern int nlm_cms_get_oc_space(int qsize, int max_queues, int qid, int *ocbase, int *ocstart, int *ocend);
extern void nlm_cms_setup_credits (uint64_t base, int destid, int srcid, int credit);
extern int nlm_cms_config_onchip_queue (uint64_t base, uint64_t cms_spill_base, int qid, int spill_en);
extern void nlm_cms_default_setup(int node, uint64_t spill_base, int spill_en, int popq_en);
extern uint64_t nlm_cms_get_onchip_queue (uint64_t base, int qid);
extern void nlm_cms_set_onchip_queue (uint64_t base, int qid, uint64_t val);
extern void nlm_cms_per_queue_level_intr(uint64_t base, int qid, int sub_type, int intr_val);
extern void nlm_cms_level_intr(int node, int sub_type, int intr_val);
extern void nlm_cms_per_queue_timer_intr(uint64_t base, int qid, int sub_type, int intr_val);
extern void nlm_cms_timer_intr(int node, int en, int sub_type, int intr_val);
extern int nlm_cms_outputq_intr_check(uint64_t base, int qid);
extern void nlm_cms_outputq_clr_intr(uint64_t base, int qid);
extern void nlm_cms_illegal_dst_error_intr(uint64_t base, int en);
extern void nlm_cms_timeout_error_intr(uint64_t base, int en);
extern void nlm_cms_biu_error_resp_intr(uint64_t base, int en);
extern void nlm_cms_spill_uncorrectable_ecc_error_intr(uint64_t base, int en);
extern void nlm_cms_spill_correctable_ecc_error_intr(uint64_t base, int en);
extern void nlm_cms_outputq_uncorrectable_ecc_error_intr(uint64_t base, int en);
extern void nlm_cms_outputq_correctable_ecc_error_intr(uint64_t base, int en);
extern uint64_t nlm_cms_network_error_status(uint64_t base);
extern int nlm_cms_get_net_error_code(uint64_t err);
extern int nlm_cms_get_net_error_syndrome(uint64_t err);
extern int nlm_cms_get_net_error_ramindex(uint64_t err);
extern int nlm_cms_get_net_error_outputq(uint64_t err);
extern void nlm_cms_trace_setup(uint64_t base, int en, uint64_t trace_base, uint64_t trace_limit, int match_dstid_en, int dst_id, int match_srcid_en, int src_id, int wrap);
extern void nlm_cms_endian_byte_swap (uint64_t base, int en);
extern uint8_t xlp_msg_send(uint8_t vc, uint8_t size);
extern int nlm_cms_alloc_spill_q(uint64_t base, int qid, uint64_t spill_base,
int nsegs);
extern int nlm_cms_alloc_onchip_q(uint64_t base, int qid, int nsegs);
#endif

237
sys/mips/nlm/hal/iomap.h Normal file
View File

@ -0,0 +1,237 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __NLM_IOMAP_H__
#define __NLM_IOMAP_H__
/**
* @file_name xlpiomap.h
* @author Netlogic Microsystems
* @brief Basic definitions Netlogic XLP IO BASEs
*/
/* ----------------------------------
* XLP RESET Physical Address Map
* ----------------------------------
* PCI ECFG : 0x18000000 - 0x1bffffff
* PCI CFG : 0x1c000000 - 0x1cffffff
* FLASH : 0x1fc00000 - 0x1fffffff
* ----------------------------------
*/
#define XLP_DEFAULT_IO_BASE 0x18000000
#define XLP_DEFAULT_IO_BASE_KSEG1 0xb8000000
#define XLP_IO_SIZE (64 << 20) /* Size of the ECFG Space */
#define XLP_IO_PCI_HDRSZ 0x100
#define XLP_IO_DEV(node, dev) ((dev) + (node) * 8)
#define XLP_HDR_OFFSET(node, bus, dev, fn) (((bus) << 20) | \
((XLP_IO_DEV(node, dev)) << 15) | ((fn) << 12))
#define XLP_IO_BRIDGE_OFFSET(node) XLP_HDR_OFFSET(node,0,0,0)
/* coherent inter chip */
#define XLP_IO_CIC0_OFFSET(node) XLP_HDR_OFFSET(node,0,0,1)
#define XLP_IO_CIC1_OFFSET(node) XLP_HDR_OFFSET(node,0,0,2)
#define XLP_IO_CIC2_OFFSET(node) XLP_HDR_OFFSET(node,0,0,3)
#define XLP_IO_PIC_OFFSET(node) XLP_HDR_OFFSET(node,0,0,4)
#define XLP_IO_PCIE_OFFSET(node,i) XLP_HDR_OFFSET(node,0,1,i)
#define XLP_IO_PCIE0_OFFSET(node) XLP_HDR_OFFSET(node,0,1,0)
#define XLP_IO_PCIE1_OFFSET(node) XLP_HDR_OFFSET(node,0,1,1)
#define XLP_IO_PCIE2_OFFSET(node) XLP_HDR_OFFSET(node,0,1,2)
#define XLP_IO_PCIE3_OFFSET(node) XLP_HDR_OFFSET(node,0,1,3)
#define XLP_IO_USB_OFFSET(node, i) XLP_HDR_OFFSET(node,0,2,i)
#define XLP_IO_USB_EHCI0_OFFSET(node) XLP_HDR_OFFSET(node,0,2,0)
#define XLP_IO_USB_OHCI0_OFFSET(node) XLP_HDR_OFFSET(node,0,2,1)
#define XLP_IO_USB_OHCI1_OFFSET(node) XLP_HDR_OFFSET(node,0,2,2)
#define XLP_IO_USB_EHCI1_OFFSET(node) XLP_HDR_OFFSET(node,0,2,3)
#define XLP_IO_USB_OHCI2_OFFSET(node) XLP_HDR_OFFSET(node,0,2,4)
#define XLP_IO_USB_OHCI3_OFFSET(node) XLP_HDR_OFFSET(node,0,2,5)
#define XLP_IO_NAE_OFFSET(node) XLP_HDR_OFFSET(node,0,3,0)
#define XLP_IO_POE_OFFSET(node) XLP_HDR_OFFSET(node,0,3,1)
#define XLP_IO_CMS_OFFSET(node) XLP_HDR_OFFSET(node,0,4,0)
#define XLP_IO_DMA_OFFSET(node) XLP_HDR_OFFSET(node,0,5,1)
#define XLP_IO_SEC_OFFSET(node) XLP_HDR_OFFSET(node,0,5,2)
#define XLP_IO_CMP_OFFSET(node) XLP_HDR_OFFSET(node,0,5,3)
#define XLP_IO_UART_OFFSET(node, i) XLP_HDR_OFFSET(node,0,6,i)
#define XLP_IO_UART0_OFFSET(node) XLP_HDR_OFFSET(node,0,6,0)
#define XLP_IO_UART1_OFFSET(node) XLP_HDR_OFFSET(node,0,6,1)
#define XLP_IO_I2C_OFFSET(node, i) XLP_HDR_OFFSET(node,0,6,2+i)
#define XLP_IO_I2C0_OFFSET(node) XLP_HDR_OFFSET(node,0,6,2)
#define XLP_IO_I2C1_OFFSET(node) XLP_HDR_OFFSET(node,0,6,3)
#define XLP_IO_GPIO_OFFSET(node) XLP_HDR_OFFSET(node,0,6,4)
/* system management */
#define XLP_IO_SYS_OFFSET(node) XLP_HDR_OFFSET(node,0,6,5)
#define XLP_IO_JTAG_OFFSET(node) XLP_HDR_OFFSET(node,0,6,6)
#define XLP_IO_NOR_OFFSET(node) XLP_HDR_OFFSET(node,0,7,0)
#define XLP_IO_NAND_OFFSET(node) XLP_HDR_OFFSET(node,0,7,1)
#define XLP_IO_SPI_OFFSET(node) XLP_HDR_OFFSET(node,0,7,2)
/* SD flash */
#define XLP_IO_SD_OFFSET(node) XLP_HDR_OFFSET(node,0,7,3)
#define XLP_IO_MMC_OFFSET(node, slot) ((XLP_IO_SD_OFFSET(node))+(slot*0x100)+XLP_IO_PCI_HDRSZ)
/* PCI config header register id's */
#define XLP_PCI_CFGREG0 0x00
#define XLP_PCI_CFGREG1 0x01
#define XLP_PCI_CFGREG2 0x02
#define XLP_PCI_CFGREG3 0x03
#define XLP_PCI_CFGREG4 0x04
#define XLP_PCI_CFGREG5 0x05
#define XLP_PCI_DEVINFO_REG0 0x30
#define XLP_PCI_DEVINFO_REG1 0x31
#define XLP_PCI_DEVINFO_REG2 0x32
#define XLP_PCI_DEVINFO_REG3 0x33
#define XLP_PCI_DEVINFO_REG4 0x34
#define XLP_PCI_DEVINFO_REG5 0x35
#define XLP_PCI_DEVINFO_REG6 0x36
#define XLP_PCI_DEVINFO_REG7 0x37
#define XLP_PCI_DEVSCRATCH_REG0 0x38
#define XLP_PCI_DEVSCRATCH_REG1 0x39
#define XLP_PCI_DEVSCRATCH_REG2 0x3a
#define XLP_PCI_DEVSCRATCH_REG3 0x3b
#define XLP_PCI_MSGSTN_REG 0x3c
#define XLP_PCI_IRTINFO_REG 0x3d
#define XLP_PCI_UCODEINFO_REG 0x3e
#define XLP_PCI_SBB_WT_REG 0x3f
#if !defined(LOCORE) && !defined(__ASSEMBLY__)
#ifndef __NLM_NLMIO_H__
#error iomap.h needs mmio.h to be included
#endif
static __inline__ uint32_t
nlm_read_reg_kseg(uint64_t base, uint32_t reg)
{
volatile uint32_t *addr = (volatile uint32_t *)(intptr_t)base + reg;
return (*addr);
}
static __inline__ void
nlm_write_reg_kseg(uint64_t base, uint32_t reg, uint32_t val)
{
volatile uint32_t *addr = (volatile uint32_t *)(intptr_t)base + reg;
*addr = val;
}
static __inline__ uint64_t
nlm_read_reg64_kseg(uint64_t base, uint32_t reg)
{
volatile uint64_t *addr = (volatile uint64_t *)(intptr_t)base + (reg >> 1);
return (nlm_load_dword(addr));
}
static __inline__ void
nlm_write_reg64_kseg(uint64_t base, uint32_t reg, uint64_t val)
{
volatile uint64_t *addr = (volatile uint64_t *)(intptr_t)base + (reg >> 1);
return (nlm_store_dword(addr, val));
}
/*
* Routines to store 32/64 bit values to 64 bit addresses,
* used when going thru XKPHYS to access registers
*/
static __inline__ uint32_t
nlm_read_reg_xkseg(uint64_t base, uint32_t reg)
{
uint64_t addr = base + reg * sizeof(uint32_t);
return (nlm_load_word_daddr(addr));
}
static __inline__ void
nlm_write_reg_xkseg(uint64_t base, uint32_t reg, uint32_t val)
{
uint64_t addr = base + reg * sizeof(uint32_t);
return (nlm_store_word_daddr(addr, val));
}
static __inline__ uint64_t
nlm_read_reg64_xkseg(uint64_t base, uint32_t reg)
{
uint64_t addr = base + (reg >> 1) * sizeof(uint64_t);
return (nlm_load_dword_daddr(addr));
}
static __inline__ void
nlm_write_reg64_xkseg(uint64_t base, uint32_t reg, uint64_t val)
{
uint64_t addr = base + (reg >> 1) * sizeof(uint64_t);
return (nlm_store_dword_daddr(addr, val));
}
/* Location where IO base is mapped */
extern uint64_t nlm_pcicfg_baseaddr;
static __inline__ uint64_t
nlm_pcicfg_base(uint32_t devoffset)
{
return (nlm_pcicfg_baseaddr + devoffset);
}
static __inline__ uint64_t
nlm_pcibar0_base_xkphys(uint64_t pcibase)
{
uint64_t paddr;
paddr = nlm_read_reg_kseg(pcibase, XLP_PCI_CFGREG4) & ~0xfu;
return (0x9000000000000000 | paddr);
}
#define nlm_pci_rdreg(b, r) nlm_read_reg_kseg(b, r)
#define nlm_pci_wreg(b, r, v) nlm_write_reg_kseg(b, r, v)
#endif /* !LOCORE && !__ASSEMBLY__*/
/* COMPAT stuff - TODO remove */
#define bit_set(p, m) ((p) |= (m))
#define bit_clear(p, m) ((p) &= ~(m))
#define bit_get(p,m) ((p) & (m))
#define BIT(x) (0x01 << (x))
#define XLP_MAX_NODES 4
#define XLP_MAX_CORES 8
#define XLP_MAX_THREADS 4
#define XLP_CACHELINE_SIZE 64
#define XLP_NUM_NODES 1 /* we support only one now */
#endif

View File

@ -0,0 +1,200 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __NLM_MIPS_EXTNS_H__
#define __NLM_MIPS_EXTNS_H__
#if !defined(LOCORE) && !defined(__ASSEMBLY__)
static __inline__ int32_t nlm_swapw(int32_t *loc, int32_t val)
{
int32_t oldval = 0;
__asm__ __volatile__ (
".set push\n"
".set noreorder\n"
"move $9, %2\n"
"move $8, %3\n"
".word 0x71280014\n" /* "swapw $8, $9\n" */
"move %1, $8\n"
".set pop\n"
: "+m" (*loc), "=r" (oldval)
: "r" (loc), "r" (val)
: "$8", "$9" );
return oldval;
}
static __inline__ uint32_t nlm_swapwu(int32_t *loc, uint32_t val)
{
uint32_t oldval;
__asm__ __volatile__ (
".set push\n"
".set noreorder\n"
"move $9, %2\n"
"move $8, %3\n"
".word 0x71280015\n" /* "swapwu $8, $9\n" */
"move %1, $8\n"
".set pop\n"
: "+m" (*loc), "=r" (oldval)
: "r" (loc), "r" (val)
: "$8", "$9" );
return oldval;
}
#if (__mips == 64)
static __inline__ uint64_t nlm_swapd(int32_t *loc, uint64_t val)
{
uint64_t oldval;
__asm__ __volatile__ (
".set push\n"
".set noreorder\n"
"move $9, %2\n"
"move $8, %3\n"
".word 0x71280014\n" /* "swapw $8, $9\n" */
"move %1, $8\n"
".set pop\n"
: "+m" (*loc), "=r" (oldval)
: "r" (loc), "r" (val)
: "$8", "$9" );
return oldval;
}
#endif
#if defined(__mips_n64) || defined(__mips_n32)
static __inline uint64_t
nlm_mfcr(uint32_t reg)
{
uint64_t res;
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
"move $9, %1\n\t"
".word 0x71280018\n\t" /* mfcr $8, $9 */
"move %0, $8\n\t"
".set pop\n"
: "=r" (res) : "r"(reg)
: "$8", "$9"
);
return (res);
}
static __inline void
nlm_mtcr(uint32_t reg, uint64_t value)
{
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
"move $8, %0\n"
"move $9, %1\n"
".word 0x71280019\n" /* mtcr $8, $9 */
".set pop\n"
:
: "r" (value), "r" (reg)
: "$8", "$9"
);
}
#else /* !(defined(__mips_n64) || defined(__mips_n32)) */
static __inline__ uint64_t
nlm_mfcr(uint32_t reg)
{
uint64_t hi;
uint64_t lo;
__asm__ __volatile__ (
".set push\n"
".set mips64\n"
"move $8, %2\n"
".word 0x71090018\n"
"nop \n"
"dsra32 %0, $9, 0\n"
"sll %1, $9, 0\n"
".set pop\n"
: "=r"(hi), "=r"(lo)
: "r"(reg) : "$8", "$9");
return (((uint64_t)hi) << 32) | lo;
}
static __inline__ void
nlm_mtcr(uint32_t reg, uint64_t val)
{
uint32_t hi, lo;
hi = val >> 32;
lo = val & 0xffffffff;
__asm__ __volatile__ (
".set push\n"
".set mips64\n"
"move $9, %0\n"
"dsll32 $9, %1, 0\n"
"dsll32 $8, %0, 0\n"
"dsrl32 $9, $9, 0\n"
"or $9, $9, $8\n"
"move $8, %2\n"
".word 0x71090019\n"
"nop \n"
".set pop\n"
::"r"(hi), "r"(lo), "r"(reg)
: "$8", "$9");
}
#endif /* (defined(__mips_n64) || defined(__mips_n32)) */
/* dcrc2 */
/* XLP additional instructions */
/*
* Atomic increment a unsigned int
*/
static __inline unsigned int
nlm_ldaddwu(unsigned int value, unsigned int *addr)
{
__asm__ __volatile__(
".set push\n"
".set noreorder\n"
"move $8, %2\n"
"move $9, %3\n"
".word 0x71280011\n" /* ldaddwu $8, $9 */
"move %0, $8\n"
".set pop\n"
: "=&r"(value), "+m"(*addr)
: "0"(value), "r" ((unsigned long)addr)
: "$8", "$9");
return (value);
}
#endif
#endif

338
sys/mips/nlm/hal/mmio.h Normal file
View File

@ -0,0 +1,338 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __NLM_NLMIO_H__
#define __NLM_NLMIO_H__
#if !defined(__mips_n32) && !defined(__mips_n64)
/*
* For o32 compilation, we have to disable interrupts and enable KX bit to
* access 64 bit addresses or data.
*
* We need to disable interrupts because we save just the lower 32 bits of
* registers in interrupt handling. So if we get hit by an interrupt while
* using the upper 32 bits of a register, we lose.
*/
static __inline__ uint32_t nlm_enable_kx(void)
{
uint32_t sr;
__asm__ __volatile__(
"mfc0 %0, $12 \n\t" /* read status reg */
"move $8, %0 \n\t"
"ori $8, $8, 0x81 \n\t" /* set KX, and IE */
"xori $8, $8, 0x1 \n\t" /* flip IE */
"mtc0 $8, $12 \n\t" /* update status reg */
: "=r"(sr)
: : "$8");
return (sr);
}
static __inline__ void nlm_restore_kx(uint32_t sr)
{
__asm__ __volatile__("mtc0 %0, $12" : : "r"(sr));
}
#endif
static __inline__ uint32_t
nlm_load_word(volatile uint32_t *addr)
{
return (*addr);
}
static __inline__ void
nlm_store_word(volatile uint32_t *addr, uint32_t val)
{
*addr = val;
}
#if defined(__mips_n64) || defined(__mips_n32)
static __inline__ uint64_t
nlm_load_dword(volatile uint64_t *addr)
{
return (*addr);
}
static __inline__ void
nlm_store_dword(volatile uint64_t *addr, uint64_t val)
{
*addr = val;
}
#else /* o32 */
static __inline__ uint64_t
nlm_load_dword(volatile uint64_t *addr)
{
uint32_t valhi, vallo, sr;
sr = nlm_enable_kx();
__asm__ __volatile__(
".set push \n\t"
".set mips64 \n\t"
"ld $8, 0(%2) \n\t"
"dsra32 %0, $8, 0 \n\t"
"sll %1, $8, 0 \n\t"
".set pop \n"
: "=r"(valhi), "=r"(vallo)
: "r"(addr)
: "$8" );
nlm_restore_kx(sr);
return (((uint64_t)valhi << 32) | vallo);
}
static __inline__ void
nlm_store_dword(volatile uint64_t *addr, uint64_t val)
{
uint32_t valhi, vallo, sr;
valhi = val >> 32;
vallo = val & 0xffffffff;
sr = nlm_enable_kx();
__asm__ __volatile__(
".set push \n\t"
".set mips64 \n\t"
"dsll32 $8, %1, 0 \n\t"
"dsll32 $9, %2, 0 \n\t" /* get rid of the */
"dsrl32 $9, $9, 0 \n\t" /* sign extend */
"or $9, $9, $8 \n\t"
"sd $9, 0(%0) \n\t"
".set pop \n"
: : "r"(addr), "r"(valhi), "r"(vallo)
: "$8", "$9", "memory");
nlm_restore_kx(sr);
}
#endif
#if defined(__mips_n64)
static __inline__ uint64_t
nlm_load_word_daddr(uint64_t addr)
{
volatile uint32_t *p = (volatile uint32_t *)(intptr_t)addr;
return (*p);
}
static __inline__ void
nlm_store_word_daddr(uint64_t addr, uint32_t val)
{
volatile uint32_t *p = (volatile uint32_t *)(intptr_t)addr;
*p = val;
}
static __inline__ uint64_t
nlm_load_dword_daddr(uint64_t addr)
{
volatile uint64_t *p = (volatile uint64_t *)(intptr_t)addr;
return (*p);
}
static __inline__ void
nlm_store_dword_daddr(uint64_t addr, uint64_t val)
{
volatile uint64_t *p = (volatile uint64_t *)(intptr_t)addr;
*p = val;
}
#elif defined(__mips_n32)
static __inline__ uint64_t
nlm_load_word_daddr(uint64_t addr)
{
uint32_t val;
__asm__ __volatile__(
".set push \n\t"
".set mips64 \n\t"
"lw %0, 0(%1) \n\t"
".set pop \n"
: "=r"(val)
: "r"(addr));
return (val);
}
static __inline__ void
nlm_store_word_daddr(uint64_t addr, uint32_t val)
{
__asm__ __volatile__(
".set push \n\t"
".set mips64 \n\t"
"sw %0, 0(%1) \n\t"
".set pop \n"
: : "r"(val), "r"(addr)
: "memory");
}
static __inline__ uint64_t
nlm_load_dword_daddr(uint64_t addr)
{
uint64_t val;
__asm__ __volatile__(
".set push \n\t"
".set mips64 \n\t"
"ld %0, 0(%1) \n\t"
".set pop \n"
: "=r"(val)
: "r"(addr));
return (val);
}
static __inline__ void
nlm_store_dword_daddr(uint64_t addr, uint64_t val)
{
__asm__ __volatile__(
".set push \n\t"
".set mips64 \n\t"
"sd %0, 0(%1) \n\t"
".set pop \n"
: : "r"(val), "r"(addr)
: "memory");
}
#else /* o32 */
static __inline__ uint64_t
nlm_load_word_daddr(uint64_t addr)
{
uint32_t val, addrhi, addrlo, sr;
addrhi = addr >> 32;
addrlo = addr & 0xffffffff;
sr = nlm_enable_kx();
__asm__ __volatile__(
".set push \n\t"
".set mips64 \n\t"
"dsll32 $8, %1, 0 \n\t"
"dsll32 $9, %2, 0 \n\t" /* get rid of the */
"dsrl32 $9, $9, 0 \n\t" /* sign extend */
"or $9, $9, $8 \n\t"
"lw %0, 0($9) \n\t"
".set pop \n"
: "=r"(val)
: "r"(addrhi), "r"(addrlo)
: "$8", "$9");
nlm_restore_kx(sr);
return (val);
}
static __inline__ void
nlm_store_word_daddr(uint64_t addr, uint32_t val)
{
uint32_t addrhi, addrlo, sr;
addrhi = addr >> 32;
addrlo = addr & 0xffffffff;
sr = nlm_enable_kx();
__asm__ __volatile__(
".set push \n\t"
".set mips64 \n\t"
"dsll32 $8, %1, 0 \n\t"
"dsll32 $9, %2, 0 \n\t" /* get rid of the */
"dsrl32 $9, $9, 0 \n\t" /* sign extend */
"or $9, $9, $8 \n\t"
"sw %0, 0($9) \n\t"
".set pop \n"
:: "r"(val), "r"(addrhi), "r"(addrlo)
: "$8", "$9", "memory");
nlm_restore_kx(sr);
}
static __inline__ uint64_t
nlm_load_dword_daddr(uint64_t addr)
{
uint32_t addrh, addrl, sr;
uint32_t valh, vall;
addrh = addr >> 32;
addrl = addr & 0xffffffff;
sr = nlm_enable_kx();
__asm__ __volatile__(
".set push \n\t"
".set mips64 \n\t"
"dsll32 $8, %2, 0 \n\t"
"dsll32 $9, %3, 0 \n\t" /* get rid of the */
"dsrl32 $9, $9, 0 \n\t" /* sign extend */
"or $9, $9, $8 \n\t"
"ld $8, 0($9) \n\t"
"dsra32 %0, $8, 0 \n\t"
"sll %1, $8, 0 \n\t"
".set pop \n"
: "=r"(valh), "=r"(vall)
: "r"(addrh), "r"(addrl)
: "$8", "$9");
nlm_restore_kx(sr);
return (((uint64_t)valh << 32) | vall);
}
static __inline__ void
nlm_store_dword_daddr(uint64_t addr, uint64_t val)
{
uint32_t addrh, addrl, sr;
uint32_t valh, vall;
addrh = addr >> 32;
addrl = addr & 0xffffffff;
valh = val >> 32;
vall = val & 0xffffffff;
sr = nlm_enable_kx();
__asm__ __volatile__(
".set push \n\t"
".set mips64 \n\t"
"dsll32 $8, %2, 0 \n\t"
"dsll32 $9, %3, 0 \n\t" /* get rid of the */
"dsrl32 $9, $9, 0 \n\t" /* sign extend */
"or $9, $9, $8 \n\t"
"dsll32 $8, %0, 0 \n\t"
"dsll32 $10, %1, 0 \n\t" /* get rid of the */
"dsrl32 $10, $10, 0 \n\t" /* sign extend */
"or $8, $8, $10 \n\t"
"sd $8, 0($9) \n\t"
".set pop \n"
: : "r"(valh), "r"(vall), "r"(addrh), "r"(addrl)
: "$8", "$9", "memory");
nlm_restore_kx(sr);
}
#endif /* __mips_n64 */
#endif

204
sys/mips/nlm/hal/mmu.h Normal file
View File

@ -0,0 +1,204 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __XLP_MMU_H__
#define __XLP_MMU_H__
#include <mips/nlm/hal/cop0.h>
#include <mips/nlm/hal/mips-extns.h>
#define XLP_MMU_SETUP_REG 0x400
#define XLP_MMU_LFSRSEED_REG 0x401
#define XLP_MMU_HPW_NUM_PAGE_LVL_REG 0x410
#define XLP_MMU_PGWKR_PGDBASE_REG 0x411
#define XLP_MMU_PGWKR_PGDSHFT_REG 0x412
#define XLP_MMU_PGWKR_PGDMASK_REG 0x413
#define XLP_MMU_PGWKR_PUDSHFT_REG 0x414
#define XLP_MMU_PGWKR_PUDMASK_REG 0x415
#define XLP_MMU_PGWKR_PMDSHFT_REG 0x416
#define XLP_MMU_PGWKR_PMDMASK_REG 0x417
#define XLP_MMU_PGWKR_PTESHFT_REG 0x418
#define XLP_MMU_PGWKR_PTEMASK_REG 0x419
typedef struct hw_pagewalker {
int pgd_present;
int pud_present;
int pmd_present;
int pte_present;
uint64_t pgd_baseaddr;
uint32_t pgd_shift;
uint32_t pgd_mask;
uint32_t pud_shift;
uint32_t pud_mask;
uint32_t pmd_shift;
uint32_t pmd_mask;
uint32_t pte_shift;
uint32_t pte_mask;
} nlm_pagewalker;
/**
* On power on reset, XLP comes up with 64 TLBs.
* Large-variable-tlb's (ELVT) and extended TLB is disabled.
* Enabling large-variable-tlb's sets up the standard
* TLB size from 64 to 128 TLBs.
* Enabling fixed TLB (EFT) sets up an additional 2048 tlbs.
* ELVT + EFT = 128 + 2048 = 2176 TLB entries.
* threads 64-entry-standard-tlb 128-entry-standard-tlb
* per std-tlb-only| std+EFT | std-tlb-only| std+EFT
* core | | |
* --------------------------------------------------------
* 1 64 64+2048 128 128+2048
* 2 64 64+1024 64 64+1024
* 4 32 32+512 32 32+512
*
* 1(G) 64 64+2048 128 128+2048
* 2(G) 128 128+2048 128 128+2048
* 4(G) 128 128+2048 128 128+2048
* (G) = Global mode
*/
/* en = 1 to enable
* en = 0 to disable
*/
static __inline__ void nlm_large_variable_tlb_en (int en)
{
unsigned int val;
val = nlm_read_c0_config6();
val |= (en << 5);
nlm_write_c0_config6(val);
return;
}
/* en = 1 to enable
* en = 0 to disable
*/
static __inline__ void nlm_pagewalker_en (int en)
{
unsigned int val;
val = nlm_read_c0_config6();
val |= (en << 3);
nlm_write_c0_config6(val);
return;
}
/* en = 1 to enable
* en = 0 to disable
*/
static __inline__ void nlm_extended_tlb_en (int en)
{
unsigned int val;
val = nlm_read_c0_config6();
val |= (en << 2);
nlm_write_c0_config6(val);
return;
}
static __inline__ int nlm_get_num_combined_tlbs(void)
{
return (((nlm_read_c0_config6() >> 16) & 0xffff) + 1);
}
/* get number of variable TLB entries */
static __inline__ int nlm_get_num_vtlbs(void)
{
return (((nlm_read_c0_config6() >> 6) & 0x3ff) + 1);
}
static __inline__ void nlm_setup_extended_pagemask (int mask)
{
nlm_write_c0_config7(mask);
}
/* hashindex_en = 1 to enable hash mode, hashindex_en=0 to disable
* global_mode = 1 to enable global mode, global_mode=0 to disable
* clk_gating = 0 to enable clock gating, clk_gating=1 to disable
*/
static __inline__ void nlm_mmu_setup(int hashindex_en, int global_mode,
int clk_gating)
{
/*uint32_t mmusetup = nlm_mfcr(XLP_MMU_SETUP_REG);*/
uint32_t mmusetup = 0;
mmusetup |= (hashindex_en << 13);
mmusetup |= (clk_gating << 3);
mmusetup |= (global_mode << 0);
nlm_mtcr(XLP_MMU_SETUP_REG, mmusetup);
}
static __inline__ void nlm_mmu_lfsr_seed (int thr0_seed, int thr1_seed,
int thr2_seed, int thr3_seed)
{
uint32_t seed = nlm_mfcr(XLP_MMU_LFSRSEED_REG);
seed |= ((thr3_seed & 0x7f) << 23);
seed |= ((thr2_seed & 0x7f) << 16);
seed |= ((thr1_seed & 0x7f) << 7);
seed |= ((thr0_seed & 0x7f) << 0);
nlm_mtcr(XLP_MMU_LFSRSEED_REG, seed);
}
static __inline__ void nlm_pagewalker_setup (nlm_pagewalker *walker)
{
uint64_t val;
if (!walker->pgd_present)
return;
val = nlm_mfcr(XLP_MMU_HPW_NUM_PAGE_LVL_REG);
if (walker->pgd_present)
val |= (1 << 3);
if (walker->pud_present)
val |= (1 << 2);
if (walker->pmd_present)
val |= (1 << 1);
if (walker->pte_present)
val |= (1 << 0);
nlm_mtcr(XLP_MMU_HPW_NUM_PAGE_LVL_REG, val);
nlm_mtcr(XLP_MMU_PGWKR_PGDBASE_REG, walker->pgd_baseaddr);
nlm_mtcr(XLP_MMU_PGWKR_PGDSHFT_REG, walker->pgd_shift);
nlm_mtcr(XLP_MMU_PGWKR_PGDMASK_REG, walker->pgd_mask);
nlm_mtcr(XLP_MMU_PGWKR_PUDSHFT_REG, walker->pud_shift);
nlm_mtcr(XLP_MMU_PGWKR_PUDMASK_REG, walker->pud_mask);
nlm_mtcr(XLP_MMU_PGWKR_PMDSHFT_REG, walker->pmd_shift);
nlm_mtcr(XLP_MMU_PGWKR_PMDMASK_REG, walker->pmd_mask);
nlm_mtcr(XLP_MMU_PGWKR_PTESHFT_REG, walker->pte_shift);
nlm_mtcr(XLP_MMU_PGWKR_PTEMASK_REG, walker->pte_mask);
}
#endif

427
sys/mips/nlm/hal/pic.h Normal file
View File

@ -0,0 +1,427 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __XLP_PIC_H__
#define __XLP_PIC_H__
/* PIC Specific registers */
#define XLP_PIC_CTRL_REG 0x40
#define XLP_PIC_BYTESWAP_REG 0x42
#define XLP_PIC_STATUS_REG 0x44
#define XLP_PIC_INTR_TIMEOUT 0x46
#define XLP_PIC_ICI0_INTR_TIMEOUT 0x48
#define XLP_PIC_ICI1_INTR_TIMEOUT 0x4a
#define XLP_PIC_ICI2_INTR_TIMEOUT 0x4c
#define XLP_PIC_IPI_CTRL_REG 0x4e
#define XLP_PIC_INT_ACK_REG 0x50
#define XLP_PIC_INT_PENDING0_REG 0x52
#define XLP_PIC_INT_PENDING1_REG 0x54
#define XLP_PIC_INT_PENDING2_REG 0x56
#define XLP_PIC_WDOG0_MAXVAL_REG 0x58
#define XLP_PIC_WDOG0_COUNT_REG 0x5a
#define XLP_PIC_WDOG0_ENABLE0_REG 0x5c
#define XLP_PIC_WDOG0_ENABLE1_REG 0x5e
#define XLP_PIC_WDOG0_BEATCMD_REG 0x60
#define XLP_PIC_WDOG0_BEAT0_REG 0x62
#define XLP_PIC_WDOG0_BEAT1_REG 0x64
#define XLP_PIC_WDOG1_MAXVAL_REG 0x66
#define XLP_PIC_WDOG1_COUNT_REG 0x68
#define XLP_PIC_WDOG1_ENABLE0_REG 0x6a
#define XLP_PIC_WDOG1_ENABLE1_REG 0x6c
#define XLP_PIC_WDOG1_BEATCMD_REG 0x6e
#define XLP_PIC_WDOG1_BEAT0_REG 0x70
#define XLP_PIC_WDOG1_BEAT1_REG 0x72
#define XLP_PIC_WDOG_MAXVAL_REG(i) (XLP_PIC_WDOG0_MAXVAL_REG + ((i) ? 7 : 0))
#define XLP_PIC_WDOG_COUNT_REG(i) (XLP_PIC_WDOG0_COUNT_REG + ((i) ? 7 : 0))
#define XLP_PIC_WDOG_ENABLE0_REG(i) (XLP_PIC_WDOG0_ENABLE0_REG + ((i) ? 7 : 0))
#define XLP_PIC_WDOG_ENABLE1_REG(i) (XLP_PIC_WDOG0_ENABLE1_REG + ((i) ? 7 : 0))
#define XLP_PIC_WDOG_BEATCMD_REG(i) (XLP_PIC_WDOG0_BEATCMD_REG + ((i) ? 7 : 0))
#define XLP_PIC_WDOG_BEAT0_REG(i) (XLP_PIC_WDOG0_BEAT0_REG + ((i) ? 7 : 0))
#define XLP_PIC_WDOG_BEAT1_REG(i) (XLP_PIC_WDOG0_BEAT1_REG + ((i) ? 7 : 0))
#define XLP_PIC_SYSTIMER0_MAXVAL_REG 0x74
#define XLP_PIC_SYSTIMER1_MAXVAL_REG 0x76
#define XLP_PIC_SYSTIMER2_MAXVAL_REG 0x78
#define XLP_PIC_SYSTIMER3_MAXVAL_REG 0x7a
#define XLP_PIC_SYSTIMER4_MAXVAL_REG 0x7c
#define XLP_PIC_SYSTIMER5_MAXVAL_REG 0x7e
#define XLP_PIC_SYSTIMER6_MAXVAL_REG 0x80
#define XLP_PIC_SYSTIMER7_MAXVAL_REG 0x82
#define XLP_PIC_SYSTIMER_MAXVAL_REG(i) (XLP_PIC_SYSTIMER0_MAXVAL_REG + ((i)*2))
#define XLP_PIC_SYSTIMER0_COUNT_REG 0x84
#define XLP_PIC_SYSTIMER1_COUNT_REG 0x86
#define XLP_PIC_SYSTIMER2_COUNT_REG 0x88
#define XLP_PIC_SYSTIMER3_COUNT_REG 0x8a
#define XLP_PIC_SYSTIMER4_COUNT_REG 0x8c
#define XLP_PIC_SYSTIMER5_COUNT_REG 0x8e
#define XLP_PIC_SYSTIMER6_COUNT_REG 0x90
#define XLP_PIC_SYSTIMER7_COUNT_REG 0x92
#define XLP_PIC_SYSTIMER_COUNT_REG(i) (XLP_PIC_SYSTIMER0_COUNT_REG + ((i)*2))
#define XLP_PIC_ITE0_N0_N1_REG 0x94
#define XLP_PIC_ITE1_N0_N1_REG 0x98
#define XLP_PIC_ITE2_N0_N1_REG 0x9c
#define XLP_PIC_ITE3_N0_N1_REG 0xa0
#define XLP_PIC_ITE4_N0_N1_REG 0xa4
#define XLP_PIC_ITE5_N0_N1_REG 0xa8
#define XLP_PIC_ITE6_N0_N1_REG 0xac
#define XLP_PIC_ITE7_N0_N1_REG 0xb0
#define XLP_PIC_ITE_N0_N1_REG(i) (XLP_PIC_ITE0_N0_N1_REG + ((i)*4))
#define XLP_PIC_ITE0_N2_N3_REG 0x96
#define XLP_PIC_ITE1_N2_N3_REG 0x9a
#define XLP_PIC_ITE2_N2_N3_REG 0x9e
#define XLP_PIC_ITE3_N2_N3_REG 0xa2
#define XLP_PIC_ITE4_N2_N3_REG 0xa6
#define XLP_PIC_ITE5_N2_N3_REG 0xaa
#define XLP_PIC_ITE6_N2_N3_REG 0xae
#define XLP_PIC_ITE7_N2_N3_REG 0xb2
#define XLP_PIC_ITE_N2_N3_REG(i) (XLP_PIC_ITE0_N2_N3_REG + ((i)*4))
#define XLP_PIC_IRT0_REG 0xb4
#define XLP_PIC_IRT_REG(i) (XLP_PIC_IRT0_REG + ((i)*2))
/* PIC IRT indices */
#define XLP_PIC_IRT_WD0_INDEX 0
#define XLP_PIC_IRT_WD1_INDEX 1
#define XLP_PIC_IRT_WD_NMI0_INDEX 2
#define XLP_PIC_IRT_WD_NMI1_INDEX 3
#define XLP_PIC_IRT_TIMER0_INDEX 4
#define XLP_PIC_IRT_TIMER1_INDEX 5
#define XLP_PIC_IRT_TIMER2_INDEX 6
#define XLP_PIC_IRT_TIMER3_INDEX 7
#define XLP_PIC_IRT_TIMER4_INDEX 8
#define XLP_PIC_IRT_TIMER5_INDEX 9
#define XLP_PIC_IRT_TIMER6_INDEX 10
#define XLP_PIC_IRT_TIMER7_INDEX 11
#define XLP_PIC_IRT_TIMER_INDEX(i) (XLP_PIC_IRT_TIMER0_INDEX + (i))
#define XLP_PIC_IRT_MSGQ0_INDEX 12
#define XLP_PIC_IRT_MSGQ_INDEX(i) (XLP_PIC_IRT_MSGQ0_INDEX + (i))
/* 12 to 43 */
#define XLP_PIC_IRT_MSG0_INDEX 44
#define XLP_PIC_IRT_MSG1_INDEX 45
#define XLP_PIC_IRT_PCIE_MSIX0_INDEX 46
#define XLP_PIC_IRT_PCIE_MSIX_INDEX(i) (XLP_PIC_IRT_PCIE_MSIX0_INDEX + (i))
/* 46 to 77 */
#define XLP_PIC_IRT_PCIE_LINK0_INDEX 78
#define XLP_PIC_IRT_PCIE_LINK1_INDEX 79
#define XLP_PIC_IRT_PCIE_LINK2_INDEX 80
#define XLP_PIC_IRT_PCIE_LINK3_INDEX 81
#define XLP_PIC_IRT_PCIE_LINK_INDEX(i) (XLP_PIC_IRT_PCIE_LINK0_INDEX + (i))
/* 78 to 81 */
#define XLP_PIC_IRT_NA0_INDEX 82
#define XLP_PIC_IRT_NA_INDEX(i) (XLP_PIC_IRT_NA0_INDEX + (i))
/* 82 to 113 */
#define XLP_PIC_IRT_POE_INDEX 114
#define XLP_PIC_IRT_USB0_INDEX 115
#define XLP_PIC_IRT_EHCI0_INDEX 115
#define XLP_PIC_IRT_EHCI1_INDEX 118
#define XLP_PIC_IRT_USB_INDEX(i) (XLP_PIC_IRT_USB0_INDEX + (i))
/* 115 to 120 */
#define XLP_PIC_IRT_GDX_INDEX 121
#define XLP_PIC_IRT_SEC_INDEX 122
#define XLP_PIC_IRT_RSA_INDEX 123
#define XLP_PIC_IRT_COMP0_INDEX 124
#define XLP_PIC_IRT_COMP_INDEX(i) (XLP_PIC_IRT_COMP0_INDEX + (i))
/* 124 to 127 */
#define XLP_PIC_IRT_GBU_INDEX 128
/* coherent inter chip */
#define XLP_PIC_IRT_CIC0_INDEX 129
#define XLP_PIC_IRT_CIC1_INDEX 130
#define XLP_PIC_IRT_CIC2_INDEX 131
#define XLP_PIC_IRT_CAM_INDEX 132
#define XLP_PIC_IRT_UART0_INDEX 133
#define XLP_PIC_IRT_UART1_INDEX 134
#define XLP_PIC_IRT_I2C0_INDEX 135
#define XLP_PIC_IRT_I2C1_INDEX 136
#define XLP_PIC_IRT_SYS0_INDEX 137
#define XLP_PIC_IRT_SYS1_INDEX 138
#define XLP_PIC_IRT_JTAG_INDEX 139
#define XLP_PIC_IRT_PIC_INDEX 140
#define XLP_PIC_IRT_NBU_INDEX 141
#define XLP_PIC_IRT_TCU_INDEX 142
/* global coherency */
#define XLP_PIC_IRT_GCU_INDEX 143
#define XLP_PIC_IRT_DMC0_INDEX 144
#define XLP_PIC_IRT_DMC1_INDEX 145
#define XLP_PIC_IRT_GPIO0_INDEX 146
#define XLP_PIC_IRT_GPIO_INDEX(i) (XLP_PIC_IRT_GPIO0_INDEX + (i))
/* 146 to 149 */
#define XLP_PIC_IRT_NOR_INDEX 150
#define XLP_PIC_IRT_NAND_INDEX 151
#define XLP_PIC_IRT_SPI_INDEX 152
#define XLP_PIC_IRT_MMC_INDEX 153
/* PIC control register defines */
#define XLP_PIC_ITV_OFFSET 32 /* interrupt timeout value */
#define XLP_PIC_ICI_OFFSET 19 /* ICI interrupt timeout enable */
#define XLP_PIC_ITE_OFFSET 18 /* interrupt timeout enable */
#define XLP_PIC_STE_OFFSET 10 /* system timer interrupt enable */
#define XLP_PIC_WWR1_OFFSET 8 /* watchdog timer 1 wraparound count for reset */
#define XLP_PIC_WWR0_OFFSET 6 /* watchdog timer 0 wraparound count for reset */
#define XLP_PIC_WWN1_OFFSET 4 /* watchdog timer 1 wraparound count for NMI */
#define XLP_PIC_WWN0_OFFSET 2 /* watchdog timer 0 wraparound count for NMI */
#define XLP_PIC_WTE_OFFSET 0 /* watchdog timer enable */
/* PIC Status register defines */
#define XLP_PIC_ICI_STATUS_OFFSET 33 /* ICI interrupt timeout interrupt status */
#define XLP_PIC_ITE_STATUS_OFFSET 32 /* interrupt timeout interrupt status */
#define XLP_PIC_STS_STATUS_OFFSET 4 /* System timer interrupt status */
#define XLP_PIC_WNS_STATUS_OFFSET 2 /* NMI interrupt status for watchdog timers */
#define XLP_PIC_WIS_STATUS_OFFSET 0 /* Interrupt status for watchdog timers */
/* PIC IPI control register offsets */
#define XLP_PIC_IPICTRL_NMI_OFFSET 32
#define XLP_PIC_IPICTRL_RIV_OFFSET 20 /* received interrupt vector */
#define XLP_PIC_IPICTRL_IDB_OFFSET 16 /* interrupt destination base */
#define XLP_PIC_IPICTRL_DTE_OFFSET 16 /* interrupt destination thread enables */
/* PIC IRT register offsets */
#define XLP_PIC_IRT_ENABLE_OFFSET 31
#define XLP_PIC_IRT_NMI_OFFSET 29
#define XLP_PIC_IRT_SCH_OFFSET 28 /* Scheduling scheme */
#define XLP_PIC_IRT_RVEC_OFFSET 20 /* Interrupt receive vectors */
#define XLP_PIC_IRT_DT_OFFSET 19 /* Destination type */
#define XLP_PIC_IRT_DB_OFFSET 16 /* Destination base */
#define XLP_PIC_IRT_DTE_OFFSET 0 /* Destination thread enables */
#define XLP_PIC_MAX_IRQ 64
#define XLP_PIC_MAX_IRT 160
#define XLP_PIC_TIMER_FREQ 133000000
#if !defined(LOCORE) && !defined(__ASSEMBLY__)
#define nlm_rdreg_pic(b, r) nlm_read_reg64_kseg(b,r)
#define nlm_wreg_pic(b, r, v) nlm_write_reg64_kseg(b,r,v)
#define nlm_pcibase_pic(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node))
#define nlm_regbase_pic(node) nlm_pcibase_pic(node)
/* IRT and h/w interrupt routines */
static __inline__ int
nlm_pic_get_numirts(uint64_t pcibase)
{
return (nlm_pci_rdreg(pcibase, XLP_PCI_IRTINFO_REG) >> 16);
}
static __inline__ int
nlm_pic_get_startirt(uint64_t base)
{
return (nlm_pci_rdreg(base, XLP_PCI_IRTINFO_REG) & 0xff);
}
static __inline__ int
nlm_pic_read_irt(uint64_t base, int irt_index)
{
return nlm_rdreg_pic(base, XLP_PIC_IRT_REG(irt_index));
}
/* IRT's can be written into in two modes
* ITE mode - Here the destination of the interrupt is one of the
* eight interrupt-thread-enable groups, allowing the interrupt
* to be distributed to any thread on any node
* ID mode - In ID mode, the IRT has the DB and DTE fields.
* DB[18:17] hold the node select and DB[16], if set to 0 selects
* cpu-cores 0-3, and if set to 1 selects cpu-cores 4-7.
* The DTE[15:0] field is a thread mask, allowing the PIC to broadcast
* the interrupt to 1-16 threads selectable from that mask
*/
static __inline__ void
nlm_pic_write_irt_raw(uint64_t base, int irt_index, int en, int nmi, int sch,
int vec, int dt, int db, int dte)
{
uint64_t val =
(((en & 0x1) << XLP_PIC_IRT_ENABLE_OFFSET) |
((nmi & 0x1) << XLP_PIC_IRT_NMI_OFFSET) |
((sch & 0x1) << XLP_PIC_IRT_SCH_OFFSET) |
((vec & 0x3f) << XLP_PIC_IRT_RVEC_OFFSET) |
((dt & 0x1 ) << XLP_PIC_IRT_DT_OFFSET) |
((db & 0x7) << XLP_PIC_IRT_DB_OFFSET) |
(dte & 0xffff));
nlm_wreg_pic(base, XLP_PIC_IRT_REG(irt_index), val);
}
/* write IRT in ID mode */
static __inline__ void
nlm_pic_write_irt_id(uint64_t base, int irt_index, int en, int nmi, int vec,
int node, int cpugroup, uint32_t cpu_mask)
{
nlm_pic_write_irt_raw(base, irt_index, en, nmi, 1, vec, 1,
(node << 1) | cpugroup , cpu_mask);
}
/* write IRT in ITE mode */
static __inline__ void
nlm_pic_write_ite(uint64_t base, int ite, uint32_t node0_thrmask,
uint32_t node1_thrmask, uint32_t node2_thrmask, uint32_t node3_thrmask)
{
uint64_t tm10 = ((uint64_t)node1_thrmask << 32) | node0_thrmask;
uint64_t tm32 = ((uint64_t)node1_thrmask << 32) | node0_thrmask;
/* Enable the ITE register for all nodes */
nlm_wreg_pic(base, XLP_PIC_ITE_N0_N1_REG(ite), tm10);
nlm_wreg_pic(base, XLP_PIC_ITE_N2_N3_REG(ite), tm32);
}
static __inline__ void
nlm_pic_write_irt_ite(uint64_t base, int irt_index, int ite, int en, int nmi,
int sch, int vec)
{
nlm_pic_write_irt_raw(base, irt_index, en, nmi, sch, vec, 0, ite, 0);
}
/* Goto PIC on that node, and ack the interrupt */
static __inline__ void nlm_pic_ack(uint64_t src_base, int irt)
{
nlm_wreg_pic(src_base, XLP_PIC_INT_ACK_REG, irt);
/* ack in the status registers for watchdog and system timers */
if (irt < 12)
nlm_wreg_pic(src_base, XLP_PIC_STATUS_REG, (1 << irt));
}
/* IPI routines */
static __inline__ void
nlm_pic_send_ipi(uint64_t local_base, int target_node, int vcpu, int vec, int nmi)
{
uint64_t ipi =
(((uint64_t)nmi << XLP_PIC_IPICTRL_NMI_OFFSET) |
(vec << XLP_PIC_IPICTRL_RIV_OFFSET) |
(target_node << 17) |
(1 << (vcpu & 0xf)));
if (vcpu > 15)
ipi |= 0x10000; /* set bit 16 to select cpus 16-31 */
nlm_wreg_pic(local_base, XLP_PIC_IPI_CTRL_REG, ipi);
}
/* System Timer routines -- broadcasts systemtimer to 16 vcpus defined in cpu_mask */
static __inline__ void
nlm_pic_set_systimer(uint64_t base, int timer, uint64_t value, int irq, int node,
int cpugroup, uint32_t cpumask)
{
uint64_t pic_ctrl = nlm_rdreg_pic(base, XLP_PIC_CTRL_REG);
int en;
en = (cpumask != 0);
nlm_wreg_pic(base, XLP_PIC_SYSTIMER_MAXVAL_REG(timer), value);
nlm_pic_write_irt_id(base, XLP_PIC_IRT_TIMER_INDEX(timer),
en, 0, irq, node, cpugroup, cpumask);
/* enable the timer */
pic_ctrl |= (1 << (XLP_PIC_STE_OFFSET+timer));
nlm_wreg_pic(base, XLP_PIC_CTRL_REG, pic_ctrl);
}
static __inline__ uint64_t
nlm_pic_read_systimer(uint64_t base, int timer)
{
return nlm_rdreg_pic(base, XLP_PIC_SYSTIMER_COUNT_REG(timer));
}
/* Watchdog timer routines */
/* node - XLP node
* timer - watchdog timer. valid values are 0 and 1
* wrap_around_count - defines the number of times the watchdog timer can wrap-around
* after which the reset / NMI gets generated to the threads defined in thread-enable-masks.
* value - the vatchdog timer max value, upto which the timer will count down
*/
static __inline__ void
nlm_pic_set_wdogtimer(uint64_t base, int timer, int wrap_around_count, int nmi,
uint32_t node0_thrmask, uint32_t node1_thrmask,
uint32_t node2_thrmask, uint32_t node3_thrmask, uint64_t value)
{
uint64_t pic_ctrl = nlm_rdreg_pic(base, XLP_PIC_CTRL_REG);
uint64_t mask0, mask1;
if (timer > 1 || wrap_around_count > 3)
return;
/* enable watchdog timer interrupt */
pic_ctrl |= (((1 << timer) & 0xf));
if (timer) {
if (nmi)
pic_ctrl |= (wrap_around_count << XLP_PIC_WWN1_OFFSET);
else
pic_ctrl |= (wrap_around_count << XLP_PIC_WWN0_OFFSET);
} else {
if (nmi)
pic_ctrl |= (wrap_around_count << XLP_PIC_WWR1_OFFSET);
else
pic_ctrl |= (wrap_around_count << XLP_PIC_WWR0_OFFSET);
}
mask0 = ((unsigned long long)node1_thrmask << 32) | node0_thrmask;
mask1 = ((unsigned long long)node3_thrmask << 32) | node2_thrmask;
nlm_wreg_pic(base, XLP_PIC_WDOG_MAXVAL_REG(timer), value);
nlm_wreg_pic(base, XLP_PIC_WDOG_ENABLE0_REG(timer), mask0);
nlm_wreg_pic(base, XLP_PIC_WDOG_ENABLE1_REG(timer), mask1);
nlm_wreg_pic(base, XLP_PIC_CTRL_REG, pic_ctrl);
}
/* watchdog's need to be "stroked" by heartbeats from vcpus.
* On XLP, the heartbeat bit for a specific cpu thread on a specific
* node is set according to the following formula:
* 32N + 4C + T
* where N = node, C=cpu-core number, T=thread number
*
* src_node = source node of watchdog timer interrupts. These interrupts
* get generated from the PIC on src_node.
* timer = watchdog timer 0 or 1
* node = node for which the hearbeat is being done
* cpu = cpu-core for which the hearbeat is being done
* thread = h/w thread for which the hearbeat is being done
*/
static __inline__ void
nlm_pic_set_wdog_heartbeat(uint64_t base, int timer, int node, int cpu,
int thread)
{
int val = 32 * node + 4 * cpu + thread;
nlm_wreg_pic(base, XLP_PIC_WDOG_BEATCMD_REG(timer), val);
}
#endif /* !LOCORE && !__ASSEMBLY__ */
#endif

125
sys/mips/nlm/hal/sys.h Normal file
View File

@ -0,0 +1,125 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __NLM_SYS_H__
#define __NLM_SYS_H__
/**
* @file_name sys.h
* @author Netlogic Microsystems
* @brief HAL for System configuration registers
*/
#define XLP_SYS_CHIP_RESET_REG 0x40
#define XLP_SYS_POWER_ON_RESET_REG 0x41
#define XLP_SYS_EFUSE_DEVICE_CFG_STATUS0_REG 0x42
#define XLP_SYS_EFUSE_DEVICE_CFG_STATUS1_REG 0x43
#define XLP_SYS_EFUSE_DEVICE_CFG_STATUS2_REG 0x44
#define XLP_SYS_EFUSE_DEVICE_CFG3_REG 0x45
#define XLP_SYS_EFUSE_DEVICE_CFG4_REG 0x46
#define XLP_SYS_EFUSE_DEVICE_CFG5_REG 0x47
#define XLP_SYS_EFUSE_DEVICE_CFG6_REG 0x48
#define XLP_SYS_EFUSE_DEVICE_CFG7_REG 0x49
#define XLP_SYS_PLL_CTRL_REG 0x4a
#define XLP_SYS_CPU_RESET_REG 0x4b
#define XLP_SYS_CPU_NONCOHERENT_MODE_REG 0x4d
#define XLP_SYS_CORE_DFS_DIS_CTRL_REG 0x4e
#define XLP_SYS_CORE_DFS_RST_CTRL_REG 0x4f
#define XLP_SYS_CORE_DFS_BYP_CTRL_REG 0x50
#define XLP_SYS_CORE_DFS_PHA_CTRL_REG 0x51
#define XLP_SYS_CORE_DFS_DIV_INC_CTRL_REG 0x52
#define XLP_SYS_CORE_DFS_DIV_DEC_CTRL_REG 0x53
#define XLP_SYS_CORE_DFS_DIV_VALUE_REG 0x54
#define XLP_SYS_RESET_REG 0x55
#define XLP_SYS_DFS_DIS_CTRL_REG 0x56
#define XLP_SYS_DFS_RST_CTRL_REG 0x57
#define XLP_SYS_DFS_BYP_CTRL_REG 0x58
#define XLP_SYS_DFS_DIV_INC_CTRL_REG 0x59
#define XLP_SYS_DFS_DIV_DEC_CTRL_REG 0x5a
#define XLP_SYS_DFS_DIV_VALUE0_REG 0x5b
#define XLP_SYS_DFS_DIV_VALUE1_REG 0x5c
#define XLP_SYS_SENSE_AMP_DLY_REG 0x5d
#define XLP_SYS_SOC_SENSE_AMP_DLY_REG 0x5e
#define XLP_SYS_CTRL0_REG 0x5f
#define XLP_SYS_CTRL1_REG 0x60
#define XLP_SYS_TIMEOUT_BS1_REG 0x61
#define XLP_SYS_BYTE_SWAP_REG 0x62
#define XLP_SYS_VRM_VID_REG 0x63
#define XLP_SYS_PWR_RAM_CMD_REG 0x64
#define XLP_SYS_PWR_RAM_ADDR_REG 0x65
#define XLP_SYS_PWR_RAM_DATA0_REG 0x66
#define XLP_SYS_PWR_RAM_DATA1_REG 0x67
#define XLP_SYS_PWR_RAM_DATA2_REG 0x68
#define XLP_SYS_PWR_UCODE_REG 0x69
#define XLP_SYS_CPU0_PWR_STATUS_REG 0x6a
#define XLP_SYS_CPU1_PWR_STATUS_REG 0x6b
#define XLP_SYS_CPU2_PWR_STATUS_REG 0x6c
#define XLP_SYS_CPU3_PWR_STATUS_REG 0x6d
#define XLP_SYS_CPU4_PWR_STATUS_REG 0x6e
#define XLP_SYS_CPU5_PWR_STATUS_REG 0x6f
#define XLP_SYS_CPU6_PWR_STATUS_REG 0x70
#define XLP_SYS_CPU7_PWR_STATUS_REG 0x71
#define XLP_SYS_STATUS_REG 0x72
#define XLP_SYS_INT_POL_REG 0x73
#define XLP_SYS_INT_TYPE_REG 0x74
#define XLP_SYS_INT_STATUS_REG 0x75
#define XLP_SYS_INT_MASK0_REG 0x76
#define XLP_SYS_INT_MASK1_REG 0x77
#define XLP_SYS_UCO_S_ECC_REG 0x78
#define XLP_SYS_UCO_M_ECC_REG 0x79
#define XLP_SYS_UCO_ADDR_REG 0x7a
#define XLP_SYS_UCO_INSTR_REG 0x7b
#define XLP_SYS_MEM_BIST0_REG 0x7c
#define XLP_SYS_MEM_BIST1_REG 0x7d
#define XLP_SYS_MEM_BIST2_REG 0x7e
#define XLP_SYS_MEM_BIST3_REG 0x7f
#define XLP_SYS_MEM_BIST4_REG 0x80
#define XLP_SYS_MEM_BIST5_REG 0x81
#define XLP_SYS_MEM_BIST6_REG 0x82
#define XLP_SYS_MEM_BIST7_REG 0x83
#define XLP_SYS_MEM_BIST8_REG 0x84
#define XLP_SYS_MEM_BIST9_REG 0x85
#define XLP_SYS_MEM_BIST10_REG 0x86
#define XLP_SYS_MEM_BIST11_REG 0x87
#define XLP_SYS_MEM_BIST12_REG 0x88
#define XLP_SYS_SCRTCH0_REG 0x89
#define XLP_SYS_SCRTCH1_REG 0x8a
#define XLP_SYS_SCRTCH2_REG 0x8b
#define XLP_SYS_SCRTCH3_REG 0x8c
#if !defined(LOCORE) && !defined(__ASSEMBLY__)
#define nlm_rdreg_sys(b, r) nlm_read_reg_kseg(b,r)
#define nlm_wreg_sys(b, r, v) nlm_write_reg_kseg(b,r,v)
#define nlm_pcibase_sys(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node))
#define nlm_regbase_sys(node) nlm_pcibase_sys(node)
#endif
#endif

196
sys/mips/nlm/hal/uart.h Normal file
View File

@ -0,0 +1,196 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __XLP_UART_H__
#define __XLP_UART_H__
/* UART Specific registers */
#define XLP_UART_RX_DATA_REG 0x40
#define XLP_UART_TX_DATA_REG 0x40
#define XLP_UART_INT_EN_REG 0x41
#define XLP_UART_INT_ID_REG 0x42
#define XLP_UART_FIFO_CTL_REG 0x42
#define XLP_UART_LINE_CTL_REG 0x43
#define XLP_UART_MODEM_CTL_REG 0x44
#define XLP_UART_LINE_STS_REG 0x45
#define XLP_UART_MODEM_STS_REG 0x46
#define XLP_UART_DIVISOR0_REG 0x40
#define XLP_UART_DIVISOR1_REG 0x41
#define XLP_UART_BASE_BAUD (133000000/16)
#define XLP_UART_BAUD_DIVISOR(baud) (XLP_UART_BASE_BAUD / baud)
/* LCR mask values */
#define LCR_5BITS 0x00
#define LCR_6BITS 0x01
#define LCR_7BITS 0x02
#define LCR_8BITS 0x03
#define LCR_STOPB 0x04
#define LCR_PENAB 0x08
#define LCR_PODD 0x00
#define LCR_PEVEN 0x10
#define LCR_PONE 0x20
#define LCR_PZERO 0x30
#define LCR_SBREAK 0x40
#define LCR_EFR_ENABLE 0xbf
#define LCR_DLAB 0x80
/* MCR mask values */
#define MCR_DTR 0x01
#define MCR_RTS 0x02
#define MCR_DRS 0x04
#define MCR_IE 0x08
#define MCR_LOOPBACK 0x10
/* FCR mask values */
#define FCR_RCV_RST 0x02
#define FCR_XMT_RST 0x04
#define FCR_RX_LOW 0x00
#define FCR_RX_MEDL 0x40
#define FCR_RX_MEDH 0x80
#define FCR_RX_HIGH 0xc0
/* IER mask values */
#define IER_ERXRDY 0x1
#define IER_ETXRDY 0x2
#define IER_ERLS 0x4
#define IER_EMSC 0x8
/* uart IRQ info */
#define XLP_NODE0_UART0_IRQ 17
#define XLP_NODE1_UART0_IRQ 18
#define XLP_NODE2_UART0_IRQ 19
#define XLP_NODE3_UART0_IRQ 20
#define XLP_NODE0_UART1_IRQ 21
#define XLP_NODE1_UART1_IRQ 22
#define XLP_NODE2_UART1_IRQ 23
#define XLP_NODE3_UART1_IRQ 24
#if !defined(LOCORE) && !defined(__ASSEMBLY__)
#define nlm_rdreg_uart(b, r) nlm_read_reg_kseg(b,r)
#define nlm_wreg_uart(b, r, v) nlm_write_reg_kseg(b,r,v)
#define nlm_pcibase_uart(node, inst) nlm_pcicfg_base(XLP_IO_UART_OFFSET(node, inst))
#define nlm_regbase_uart(node, inst) nlm_pcibase_uart(node, inst)
static __inline__ void
nlm_uart_set_baudrate(uint64_t base, int baud)
{
uint32_t lcr;
lcr = nlm_rdreg_uart(base, XLP_UART_LINE_CTL_REG);
/* enable divisor register, and write baud values */
nlm_wreg_uart(base, XLP_UART_LINE_CTL_REG, lcr | (1 << 7));
nlm_wreg_uart(base, XLP_UART_DIVISOR0_REG,
(XLP_UART_BAUD_DIVISOR(baud) & 0xff));
nlm_wreg_uart(base, XLP_UART_DIVISOR1_REG,
((XLP_UART_BAUD_DIVISOR(baud) >> 8) & 0xff));
/* restore default lcr */
nlm_wreg_uart(base, XLP_UART_LINE_CTL_REG, lcr);
}
static __inline__ void
nlm_outbyte (uint64_t base, char c)
{
uint32_t lsr;
for (;;) {
lsr = nlm_rdreg_uart(base, XLP_UART_LINE_STS_REG);
if (lsr & 0x20) break;
}
nlm_wreg_uart(base, XLP_UART_TX_DATA_REG, (int)c);
}
static __inline__ char
nlm_inbyte (uint64_t base)
{
int data, lsr;
for(;;) {
lsr = nlm_rdreg_uart(base, XLP_UART_LINE_STS_REG);
if (lsr & 0x80) { /* parity/frame/break-error - push a zero */
data = 0;
break;
}
if (lsr & 0x01) { /* Rx data */
data = nlm_rdreg_uart(base, XLP_UART_RX_DATA_REG);
break;
}
}
return (char)data;
}
static __inline__ int
nlm_uart_init(uint64_t base, int baud, int databits, int stopbits,
int parity, int int_en, int loopback)
{
uint32_t lcr;
lcr = 0;
if (databits >= 8)
lcr |= LCR_8BITS;
else if (databits == 7)
lcr |= LCR_7BITS;
else if (databits == 6)
lcr |= LCR_6BITS;
else
lcr |= LCR_5BITS;
if (stopbits > 1)
lcr |= LCR_STOPB;
lcr |= parity << 3;
/* setup default lcr */
nlm_wreg_uart(base, XLP_UART_LINE_CTL_REG, lcr);
/* Reset the FIFOs */
nlm_wreg_uart(base, XLP_UART_LINE_CTL_REG, FCR_RCV_RST | FCR_XMT_RST);
nlm_uart_set_baudrate(base, baud);
if (loopback)
nlm_wreg_uart(base, XLP_UART_MODEM_CTL_REG, 0x1f);
if (int_en)
nlm_wreg_uart(base, XLP_UART_INT_EN_REG, IER_ERXRDY | IER_ETXRDY);
return 0;
}
#endif /* !LOCORE && !__ASSEMBLY__ */
#endif /* __XLP_UART_H__ */

49
sys/mips/nlm/interrupt.h Normal file
View File

@ -0,0 +1,49 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef _RMI_INTERRUPT_H_
#define _RMI_INTERRUPT_H_
/* Defines for the IRQ numbers */
#define IRQ_IPI 41 /* 8-39 are mapped by PIC intr 0-31 */
#define IRQ_MSGRING 6
#define IRQ_TIMER 7
/*
* XLR needs custom pre and post handlers for PCI/PCI-e interrupts
* XXX: maybe follow i386 intsrc model
*/
void xlp_establish_intr(const char *name, driver_filter_t filt,
driver_intr_t handler, void *arg, int irq, int flags,
void **cookiep, void (*busack)(int));
void xlp_enable_irq(int irq);
#endif /* _RMI_INTERRUPT_H_ */

253
sys/mips/nlm/intr_machdep.c Normal file
View File

@ -0,0 +1,253 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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.
*
* NETLOGIC_BSD */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <sys/kernel.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/cpuinfo.h>
#include <machine/cpuregs.h>
#include <machine/frame.h>
#include <machine/intr_machdep.h>
#include <machine/md_var.h>
#include <machine/trap.h>
#include <machine/hwfunc.h>
#include <mips/nlm/hal/mmio.h>
#include <mips/nlm/hal/iomap.h>
#include <mips/nlm/hal/cop0.h>
#include <mips/nlm/interrupt.h>
#include <mips/nlm/hal/pic.h>
#include <mips/nlm/xlp.h>
struct xlp_intrsrc {
void (*busack)(int); /* Additional ack */
struct intr_event *ie; /* event corresponding to intr */
int irq;
};
static struct xlp_intrsrc xlp_interrupts[XLR_MAX_INTR];
static mips_intrcnt_t mips_intr_counters[XLR_MAX_INTR];
static int intrcnt_index;
void
xlp_enable_irq(int irq)
{
uint64_t eimr;
eimr = nlm_read_c0_eimr();
nlm_write_c0_eimr(eimr | (1ULL << irq));
}
void
cpu_establish_softintr(const char *name, driver_filter_t * filt,
void (*handler) (void *), void *arg, int irq, int flags,
void **cookiep)
{
panic("Soft interrupts unsupported!\n");
}
void
cpu_establish_hardintr(const char *name, driver_filter_t * filt,
void (*handler) (void *), void *arg, int irq, int flags,
void **cookiep)
{
xlp_establish_intr(name, filt, handler, arg, irq, flags,
cookiep, NULL);
}
static void
xlp_post_filter(void *source)
{
struct xlp_intrsrc *src = source;
if (src->busack)
src->busack(src->irq);
nlm_pic_ack(xlp_pic_base, xlp_irq_to_irt(src->irq));
}
static void
xlp_pre_ithread(void *source)
{
struct xlp_intrsrc *src = source;
if (src->busack)
src->busack(src->irq);
}
static void
xlp_post_ithread(void *source)
{
struct xlp_intrsrc *src = source;
nlm_pic_ack(xlp_pic_base, xlp_irq_to_irt(src->irq));
}
void
xlp_establish_intr(const char *name, driver_filter_t filt,
driver_intr_t handler, void *arg, int irq, int flags,
void **cookiep, void (*busack)(int))
{
struct intr_event *ie; /* descriptor for the IRQ */
struct xlp_intrsrc *src = NULL;
int errcode;
if (irq < 0 || irq > XLR_MAX_INTR)
panic("%s called for unknown hard intr %d", __func__, irq);
/*
* FIXME locking - not needed now, because we do this only on
* startup from CPU0
*/
src = &xlp_interrupts[irq];
ie = src->ie;
if (ie == NULL) {
/*
* PIC based interrupts need ack in PIC, and some SoC
* components need additional acks (e.g. PCI)
*/
if (xlp_irq_is_picintr(irq))
errcode = intr_event_create(&ie, src, 0, irq,
xlp_pre_ithread, xlp_post_ithread, xlp_post_filter,
NULL, "hard intr%d:", irq);
else {
if (filt == NULL)
panic("Not supported - non filter percpu intr");
errcode = intr_event_create(&ie, src, 0, irq,
NULL, NULL, NULL, NULL, "hard intr%d:", irq);
}
if (errcode) {
printf("Could not create event for intr %d\n", irq);
return;
}
src->irq = irq;
src->busack = busack;
src->ie = ie;
}
intr_event_add_handler(ie, name, filt, handler, arg,
intr_priority(flags), flags, cookiep);
xlp_enable_irq(irq);
}
void
cpu_intr(struct trapframe *tf)
{
struct intr_event *ie;
uint64_t eirr, eimr;
int i;
critical_enter();
/* find a list of enabled interrupts */
eirr = nlm_read_c0_eirr();
eimr = nlm_read_c0_eimr();
eirr &= eimr;
if (eirr == 0) {
critical_exit();
return;
}
/*
* No need to clear the EIRR here as the handler writes to
* compare which ACKs the interrupt.
*/
if (eirr & (1 << IRQ_TIMER)) {
intr_event_handle(xlp_interrupts[IRQ_TIMER].ie, tf);
critical_exit();
return;
}
/* FIXME sched pin >? LOCK>? */
for (i = sizeof(eirr) * 8 - 1; i >= 0; i--) {
if ((eirr & (1ULL << i)) == 0)
continue;
ie = xlp_interrupts[i].ie;
/* Don't account special IRQs */
switch (i) {
case IRQ_IPI:
case IRQ_MSGRING:
break;
default:
mips_intrcnt_inc(mips_intr_counters[i]);
}
/* Ack the IRQ on the CPU */
nlm_write_c0_eirr(1ULL << i);
if (intr_event_handle(ie, tf) != 0) {
printf("stray interrupt %d\n", i);
}
}
critical_exit();
}
void
mips_intrcnt_setname(mips_intrcnt_t counter, const char *name)
{
int idx = counter - intrcnt;
KASSERT(counter != NULL, ("mips_intrcnt_setname: NULL counter"));
snprintf(intrnames + (MAXCOMLEN + 1) * idx,
MAXCOMLEN + 1, "%-*s", MAXCOMLEN, name);
}
mips_intrcnt_t
mips_intrcnt_create(const char* name)
{
mips_intrcnt_t counter = &intrcnt[intrcnt_index++];
mips_intrcnt_setname(counter, name);
return counter;
}
void
cpu_init_interrupts()
{
int i;
char name[MAXCOMLEN + 1];
/*
* Initialize all available vectors so spare IRQ
* would show up in systat output
*/
for (i = 0; i < XLR_MAX_INTR; i++) {
snprintf(name, MAXCOMLEN + 1, "int%d:", i);
mips_intr_counters[i] = mips_intrcnt_create(name);
}
}

233
sys/mips/nlm/iodi.c Normal file
View File

@ -0,0 +1,233 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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.
*
* NETLOGIC_BSD */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define __RMAN_RESOURCE_VISIBLE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/reboot.h>
#include <sys/rman.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <machine/cpu.h>
#include <machine/bus.h>
#include <machine/intr_machdep.h>
#include <mips/nlm/hal/mmio.h>
#include <mips/nlm/hal/iomap.h>
#include <mips/nlm/hal/pic.h>
#include <mips/nlm/hal/uart.h>
#include <mips/nlm/hal/cop2.h>
#include <mips/nlm/hal/fmn.h>
#include <mips/nlm/msgring.h>
#include <mips/nlm/xlp.h>
#include <mips/nlm/board.h>
extern void iodi_activateirqs(void);
extern bus_space_tag_t uart_bus_space_mem;
static struct resource *iodi_alloc_resource(device_t, device_t, int, int *,
u_long, u_long, u_long, u_int);
static int iodi_activate_resource(device_t, device_t, int, int,
struct resource *);
struct iodi_softc *iodi_softc; /* There can be only one. */
static int
iodi_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)
{
const char *name = device_get_name(child);
int unit = device_get_unit(child);
if (strcmp(name, "uart") == 0) {
/* Note: in xlp, all pic interrupts are level triggered */
nlm_pic_write_irt_id(xlp_pic_base, XLP_PIC_IRT_UART0_INDEX, 1, 0,
xlp_irt_to_irq(XLP_PIC_IRT_UART0_INDEX), 0, 0, 0x1);
cpu_establish_hardintr("uart", filt, intr, arg,
xlp_irt_to_irq(XLP_PIC_IRT_UART0_INDEX), flags, cookiep);
} else if (strcmp(name, "ehci") == 0) {
if (unit == 0) {
nlm_pic_write_irt_id(xlp_pic_base, XLP_PIC_IRT_EHCI0_INDEX, 1, 0,
xlp_irt_to_irq(XLP_PIC_IRT_EHCI0_INDEX), 0, 0, 0x1);
cpu_establish_hardintr("ehci0", filt, intr, arg,
xlp_irt_to_irq(XLP_PIC_IRT_EHCI0_INDEX), flags, cookiep);
} else if (unit == 1) {
nlm_pic_write_irt_id(xlp_pic_base, XLP_PIC_IRT_EHCI1_INDEX, 1, 0,
xlp_irt_to_irq(XLP_PIC_IRT_EHCI1_INDEX), 0, 0, 0x1);
cpu_establish_hardintr("ehci1", filt, intr, arg,
xlp_irt_to_irq(XLP_PIC_IRT_EHCI1_INDEX), flags, cookiep);
}
} else if (strcmp(name, "xlp_sdhci") == 0) {
nlm_pic_write_irt_id(xlp_pic_base, XLP_PIC_IRT_MMC_INDEX, 1, 0,
xlp_irt_to_irq(XLP_PIC_IRT_MMC_INDEX), 0, 0, 0x1);
cpu_establish_hardintr("xlp_sdhci", filt, intr, arg,
xlp_irt_to_irq(XLP_PIC_IRT_MMC_INDEX), flags, cookiep);
}
return (0);
}
static struct resource *
iodi_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct resource *res = malloc(sizeof(*res), M_DEVBUF, M_WAITOK);
const char *name = device_get_name(child);
int unit;
switch (type) {
case SYS_RES_IRQ:
device_printf(bus, "IRQ resource - for %s %lx-%lx\n",
device_get_nameunit(child), start, end);
break;
case SYS_RES_IOPORT:
device_printf(bus, "IOPORT resource - for %s %lx-%lx\n",
device_get_nameunit(child), start, end);
break;
case SYS_RES_MEMORY:
device_printf(bus, "MEMORY resource - for %s %lx-%lx\n",
device_get_nameunit(child), start, end);
break;
}
unit = device_get_unit(child);
if (strcmp(name, "uart") == 0) {
if (unit == 0) {
res->r_bushandle = nlm_regbase_uart(0, 0) + XLP_IO_PCI_HDRSZ;
} else if ( unit == 1) {
res->r_bushandle = nlm_regbase_uart(0, 1) + XLP_IO_PCI_HDRSZ;
} else
printf("%s: Unknown uart unit\n", __FUNCTION__);
res->r_bustag = uart_bus_space_mem;
}
return (res);
}
static int
iodi_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
return (0);
}
/* prototypes */
static int iodi_probe(device_t);
static int iodi_attach(device_t);
static void iodi_identify(driver_t *, device_t);
int
iodi_probe(device_t dev)
{
return 0;
}
void
iodi_identify(driver_t *driver, device_t parent)
{
BUS_ADD_CHILD(parent, 0, "iodi", 0);
}
int
iodi_attach(device_t dev)
{
device_t tmpd;
char desc[32];
int i;
device_printf(dev, "IODI - Initialize message ring.\n");
xlp_msgring_iodi_config();
/*
* Attach each devices
*/
device_add_child(dev, "uart", 0);
device_add_child(dev, "xlp_i2c", 0);
device_add_child(dev, "xlp_i2c", 1);
device_add_child(dev, "ehci", 0);
device_add_child(dev, "ehci", 1);
device_add_child(dev, "xlp_sdhci", 0);
for (i=0; i < XLP_NUM_NODES; i++) {
tmpd = device_add_child(dev, "xlpnae", i);
device_set_ivars(tmpd, &xlp_board_info.nodes[i].nae_ivars);
snprintf(desc, sizeof(desc), "XLP NAE %d", i);
device_set_desc_copy(tmpd, desc);
}
bus_generic_probe(dev);
bus_generic_attach(dev);
return 0;
}
static device_method_t iodi_methods[] = {
DEVMETHOD(device_probe, iodi_probe),
DEVMETHOD(device_attach, iodi_attach),
DEVMETHOD(device_identify, iodi_identify),
DEVMETHOD(bus_alloc_resource, iodi_alloc_resource),
DEVMETHOD(bus_activate_resource, iodi_activate_resource),
DEVMETHOD(bus_add_child, bus_generic_add_child),
DEVMETHOD(bus_setup_intr, iodi_setup_intr),
{0, 0},
};
static driver_t iodi_driver = {
"iodi",
iodi_methods,
1 /* no softc */
};
static devclass_t iodi_devclass;
DRIVER_MODULE(iodi, nexus, iodi_driver, iodi_devclass, 0, 0);

159
sys/mips/nlm/mpreset.S Normal file
View File

@ -0,0 +1,159 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#include <machine/asm.h>
#include <machine/cpu.h>
#include <machine/cpuregs.h>
#include <mips/nlm/hal/iomap.h>
#include <mips/nlm/hal/sys.h>
#include <mips/nlm/hal/cpucontrol.h>
#include "assym.s"
.text
.set noat
.set noreorder
.set mips64
VECTOR(XLPResetEntry, unknown)
mfc0 t0, MIPS_COP_0_STATUS
li t1, 0x80000
and t1, t0, t1
bnez t1, nmi_handler
nop
#ifdef SMP
/* Reset entry for secordary cores */
mfc0 t0, MIPS_COP_0_PRID, 1
srl t0, t0, 2 /* discard thread id */
andi t0, t0, 0x7 /* core id */
li t1, 1
sll t0, t1, t0
nor t0, t0, zero /* mask with core id bit clear */
/* clear CPU non-coherent bit */
li t2, XLP_DEFAULT_IO_BASE_KSEG1 + XLP_IO_SYS_OFFSET(0) + XLP_SYS_CPU_NONCOHERENT_MODE_REG * 4
lw t1, 0(t2)
and t1, t1, t0
sw t1, 0(t2)
lw t1, 0(t2) /* read-back ensures operation complete */
sync
dla t2, mpentry
jr t2
nop
#endif
nop
/* NOT REACHED */
VECTOR_END(XLPResetEntry)
/* Not yet */
nmi_handler:
nop
nop
j nmi_handler
#ifdef SMP
/*
* Enable other threads in the core, called from thread 0
* of the core
*/
LEAF(xlp_enable_threads)
/*
* Save and restore callee saved registers of all ABIs
* Enabling threads trashes the registers
*/
dmtc0 sp, $4, 2 /* SP saved in UserLocal */
ori sp, sp, 0x7
xori sp, sp, 0x7 /* align 64 bit */
addiu sp, sp, -128
mfc0 t1, MIPS_COP_0_STATUS
sd s0, 0(sp)
sd s1, 8(sp)
sd s2, 16(sp)
sd s3, 24(sp)
sd s4, 32(sp)
sd s5, 40(sp)
sd s6, 48(sp)
sd s7, 56(sp)
sd s8, 64(sp)
sd t1, 72(sp)
sd gp, 80(sp)
sd ra, 88(sp)
/* Use register number to work in o32 and n32 */
li $9, ((XLP_CPU_BLOCKID_MAP << 8) | XLP_BLKID_MAP_THREADMODE)
move $8, a0
sync
.word 0x71280019 /* mtcr t0, t1*/
mfc0 t0, MIPS_COP_0_PRID, 1
andi t0, 0x3
beqz t0, 2f
nop
dla t1, mpentry /* child thread, go to hardware init */
jr t1
nop
2: /*
* Parent hardware thread, restore registers, return
*/
#if 1
/*
* A0 Errata - Write MMU_SETUP after changing thread mode register.
*/
li $9, 0x400
li $8, 0
.word 0x71280019 /* mtcr $8, $9*/
.word 0x000000c0 /* ehb */
#endif
dmfc0 t0, $4, 2 /* SP saved in UserLocal */
ori sp, t0, 0x7
xori sp, sp, 0x7 /* align 64 bit */
addiu sp, sp, -128
ld s0, 0(sp)
ld s1, 8(sp)
ld s2, 16(sp)
ld s3, 24(sp)
ld s4, 32(sp)
ld s5, 40(sp)
ld s6, 48(sp)
ld s7, 56(sp)
ld s8, 64(sp)
ld t1, 72(sp)
ld gp, 80(sp)
ld ra, 88(sp)
mfc0 t1, MIPS_COP_0_STATUS
move sp, t0 /* Restore the real SP */
jr ra
nop
END(xlp_enable_threads)
#endif

44
sys/mips/nlm/msgring.h Normal file
View File

@ -0,0 +1,44 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
/** FIXME **/
extern uint32_t xlp_msg_thread_mask;
typedef void (*msgring_handler)(int, int, int, int, struct nlm_fmn_msg *, void *);
int register_msgring_handler(int startb, int endb, msgring_handler action,
void *arg);
int xlp_handle_msg_vc(int vc, int max_msgs);
void xlp_msgring_cpu_init(uint32_t);
void xlp_msgring_config(void);
void xlp_cpu_msgring_handler(int bucket, int size, int code, int stid,
struct nlm_fmn_msg *msg, void *data);
void nlm_cms_credit_setup(int credit);
void xlp_msgring_iodi_config(void);

12
sys/mips/nlm/std.xlp Normal file
View File

@ -0,0 +1,12 @@
# $FreeBSD$
files "../nlm/files.xlp"
cpu CPU_NLMXLP
#
# XXXMIPS: It's a stub, isn't it?
#
#option HW_PAGEWALKER
#option MMU_HASH_MODE # enables hash based lookup into extended TLBs
#option MMU_CLOCK_GATING # enables clock gating on MMU
#option MMU_GLOBAL_MODE # enables global mode of sharing all TLBs with all h/w threads
#option NOFPU

393
sys/mips/nlm/tick.c Normal file
View File

@ -0,0 +1,393 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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.
*
* NETLOGIC_BSD */
/*
* Simple driver for the 32-bit interval counter built in to all
* MIPS32 CPUs.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_cputype.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/power.h>
#include <sys/smp.h>
#include <sys/time.h>
#include <sys/timeet.h>
#include <sys/timetc.h>
#include <machine/hwfunc.h>
#include <machine/clock.h>
#include <machine/locore.h>
#include <machine/md_var.h>
#include <machine/intr_machdep.h>
#include <mips/nlm/interrupt.h>
uint64_t counter_freq;
struct timecounter *platform_timecounter;
static DPCPU_DEFINE(uint32_t, cycles_per_tick);
static uint32_t cycles_per_usec;
static DPCPU_DEFINE(volatile uint32_t, counter_upper);
static DPCPU_DEFINE(volatile uint32_t, counter_lower_last);
static DPCPU_DEFINE(uint32_t, compare_ticks);
static DPCPU_DEFINE(uint32_t, lost_ticks);
struct clock_softc {
int intr_rid;
struct resource *intr_res;
void *intr_handler;
struct timecounter tc;
struct eventtimer et;
};
static struct clock_softc *softc;
/*
* Device methods
*/
static int clock_probe(device_t);
static void clock_identify(driver_t *, device_t);
static int clock_attach(device_t);
static unsigned counter_get_timecount(struct timecounter *tc);
void
mips_timer_early_init(uint64_t clock_hz)
{
/* Initialize clock early so that we can use DELAY sooner */
counter_freq = clock_hz;
cycles_per_usec = (clock_hz / (1000 * 1000));
}
void
platform_initclocks(void)
{
if (platform_timecounter != NULL)
tc_init(platform_timecounter);
}
static uint64_t
tick_ticker(void)
{
uint64_t ret;
uint32_t ticktock;
uint32_t t_lower_last, t_upper;
/*
* Disable preemption because we are working with cpu specific data.
*/
critical_enter();
/*
* Note that even though preemption is disabled, interrupts are
* still enabled. In particular there is a race with clock_intr()
* reading the values of 'counter_upper' and 'counter_lower_last'.
*
* XXX this depends on clock_intr() being executed periodically
* so that 'counter_upper' and 'counter_lower_last' are not stale.
*/
do {
t_upper = DPCPU_GET(counter_upper);
t_lower_last = DPCPU_GET(counter_lower_last);
} while (t_upper != DPCPU_GET(counter_upper));
ticktock = mips_rd_count();
critical_exit();
/* COUNT register wrapped around */
if (ticktock < t_lower_last)
t_upper++;
ret = ((uint64_t)t_upper << 32) | ticktock;
return (ret);
}
void
mips_timer_init_params(uint64_t platform_counter_freq, int double_count)
{
/*
* XXX: Do not use printf here: uart code 8250 may use DELAY so this
* function should be called before cninit.
*/
counter_freq = platform_counter_freq;
/*
* XXX: Some MIPS32 cores update the Count register only every two
* pipeline cycles.
* We know this because of status registers in CP0, make it automatic.
*/
if (double_count != 0)
counter_freq /= 2;
cycles_per_usec = counter_freq / (1 * 1000 * 1000);
set_cputicker(tick_ticker, counter_freq, 1);
}
static int
sysctl_machdep_counter_freq(SYSCTL_HANDLER_ARGS)
{
int error;
uint64_t freq;
if (softc == NULL)
return (EOPNOTSUPP);
freq = counter_freq;
error = sysctl_handle_64(oidp, &freq, sizeof(freq), req);
if (error == 0 && req->newptr != NULL) {
counter_freq = freq;
softc->et.et_frequency = counter_freq;
softc->tc.tc_frequency = counter_freq;
}
return (error);
}
SYSCTL_PROC(_machdep, OID_AUTO, counter_freq, CTLTYPE_U64 | CTLFLAG_RW,
NULL, 0, sysctl_machdep_counter_freq, "QU",
"Timecounter frequency in Hz");
static unsigned
counter_get_timecount(struct timecounter *tc)
{
return (mips_rd_count());
}
/*
* Wait for about n microseconds (at least!).
*/
void
DELAY(int n)
{
uint32_t cur, last, delta, usecs;
/*
* This works by polling the timer and counting the number of
* microseconds that go by.
*/
last = mips_rd_count();
delta = usecs = 0;
while (n > usecs) {
cur = mips_rd_count();
/* Check to see if the timer has wrapped around. */
if (cur < last)
delta += cur + (0xffffffff - last) + 1;
else
delta += cur - last;
last = cur;
if (delta >= cycles_per_usec) {
usecs += delta / cycles_per_usec;
delta %= cycles_per_usec;
}
}
}
static int
clock_start(struct eventtimer *et,
struct bintime *first, struct bintime *period)
{
uint32_t fdiv, div, next;
if (period != NULL) {
div = (et->et_frequency * (period->frac >> 32)) >> 32;
if (period->sec != 0)
div += et->et_frequency * period->sec;
} else
div = 0;
if (first != NULL) {
fdiv = (et->et_frequency * (first->frac >> 32)) >> 32;
if (first->sec != 0)
fdiv += et->et_frequency * first->sec;
} else
fdiv = div;
DPCPU_SET(cycles_per_tick, div);
next = mips_rd_count() + fdiv;
DPCPU_SET(compare_ticks, next);
mips_wr_compare(next);
return (0);
}
static int
clock_stop(struct eventtimer *et)
{
DPCPU_SET(cycles_per_tick, 0);
mips_wr_compare(0xffffffff);
return (0);
}
/*
* Device section of file below
*/
static int
clock_intr(void *arg)
{
struct clock_softc *sc = (struct clock_softc *)arg;
uint32_t cycles_per_tick;
uint32_t count, compare_last, compare_next, lost_ticks;
cycles_per_tick = DPCPU_GET(cycles_per_tick);
/*
* Set next clock edge.
*/
count = mips_rd_count();
compare_last = DPCPU_GET(compare_ticks);
if (cycles_per_tick > 0) {
compare_next = count + cycles_per_tick;
DPCPU_SET(compare_ticks, compare_next);
mips_wr_compare(compare_next);
} else /* In one-shot mode timer should be stopped after the event. */
mips_wr_compare(0xffffffff);
/* COUNT register wrapped around */
if (count < DPCPU_GET(counter_lower_last)) {
DPCPU_SET(counter_upper, DPCPU_GET(counter_upper) + 1);
}
DPCPU_SET(counter_lower_last, count);
if (cycles_per_tick > 0) {
/*
* Account for the "lost time" between when the timer interrupt
* fired and when 'clock_intr' actually started executing.
*/
lost_ticks = DPCPU_GET(lost_ticks);
lost_ticks += count - compare_last;
/*
* If the COUNT and COMPARE registers are no longer in sync
* then make up some reasonable value for the 'lost_ticks'.
*
* This could happen, for e.g., after we resume normal
* operations after exiting the debugger.
*/
if (lost_ticks > 2 * cycles_per_tick)
lost_ticks = cycles_per_tick;
while (lost_ticks >= cycles_per_tick) {
if (sc->et.et_active)
sc->et.et_event_cb(&sc->et, sc->et.et_arg);
lost_ticks -= cycles_per_tick;
}
DPCPU_SET(lost_ticks, lost_ticks);
}
if (sc->et.et_active)
sc->et.et_event_cb(&sc->et, sc->et.et_arg);
return (FILTER_HANDLED);
}
static int
clock_probe(device_t dev)
{
if (device_get_unit(dev) != 0)
panic("can't attach more clocks");
device_set_desc(dev, "Generic MIPS32 ticker");
return (0);
}
static void
clock_identify(driver_t * drv, device_t parent)
{
BUS_ADD_CHILD(parent, 0, "clock", 0);
}
static int
clock_attach(device_t dev)
{
struct clock_softc *sc;
softc = sc = device_get_softc(dev);
cpu_establish_hardintr("compare", clock_intr, NULL,
sc, IRQ_TIMER, INTR_TYPE_CLK, &sc->intr_handler);
sc->tc.tc_get_timecount = counter_get_timecount;
sc->tc.tc_counter_mask = 0xffffffff;
sc->tc.tc_frequency = counter_freq;
sc->tc.tc_name = "MIPS32";
sc->tc.tc_quality = 800;
sc->tc.tc_priv = sc;
tc_init(&sc->tc);
sc->et.et_name = "MIPS32";
#if 0
sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT |
ET_FLAGS_PERCPU;
#endif
sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_PERCPU;
sc->et.et_quality = 800;
sc->et.et_frequency = counter_freq;
sc->et.et_min_period.sec = 0;
sc->et.et_min_period.frac = 0x00004000LLU << 32; /* To be safe. */
sc->et.et_max_period.sec = 0xfffffffeU / sc->et.et_frequency;
sc->et.et_max_period.frac =
((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32;
sc->et.et_start = clock_start;
sc->et.et_stop = clock_stop;
sc->et.et_priv = sc;
et_register(&sc->et);
return (0);
}
static device_method_t clock_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, clock_probe),
DEVMETHOD(device_identify, clock_identify),
DEVMETHOD(device_attach, clock_attach),
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{0, 0}
};
static driver_t clock_driver = {
"clock",
clock_methods,
sizeof(struct clock_softc),
};
static devclass_t clock_devclass;
DRIVER_MODULE(clock, nexus, clock_driver, clock_devclass, 0, 0);

View File

@ -0,0 +1,88 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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.
*
* NETLOGIC_BSD */
#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/lock.h>
#include <sys/mutex.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <mips/nlm/hal/mmio.h>
#include <mips/nlm/hal/iomap.h>
#include <mips/nlm/hal/uart.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
static int uart_iodi_probe(device_t dev);
static device_method_t uart_iodi_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, uart_iodi_probe),
DEVMETHOD(device_attach, uart_bus_attach),
DEVMETHOD(device_detach, uart_bus_detach),
{0, 0}
};
static driver_t uart_iodi_driver = {
uart_driver_name,
uart_iodi_methods,
sizeof(struct uart_softc),
};
extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
static int
uart_iodi_probe(device_t dev)
{
struct uart_softc *sc;
sc = device_get_softc(dev);
sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
sc->sc_class = &uart_ns8250_class;
bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
sc->sc_sysdev->bas.bst = rmi_bus_space;
sc->sc_sysdev->bas.bsh = nlm_regbase_uart(0, 0) + XLP_IO_PCI_HDRSZ;
sc->sc_bas.bst = rmi_bus_space;
sc->sc_bas.bsh = nlm_regbase_uart(0, 0) + XLP_IO_PCI_HDRSZ;
/* regshft = 2, rclk = 66000000, rid = 0, chan = 0 */
return (uart_bus_probe(dev, 2, 133000000, 0, 0));
}
DRIVER_MODULE(uart, iodi, uart_iodi_driver, uart_devclass, 0, 0);

View File

@ -0,0 +1,89 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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.
*
* NETLOGIC_BSD */
/*
* Skeleton of this file was based on respective code for ARM
* code written by Olivier Houchard.
*/
/*
* XLRMIPS: This file is hacked from arm/...
*/
#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 <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <machine/bus.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
#include <mips/nlm/hal/mmio.h>
#include <mips/nlm/hal/iomap.h>
#include <mips/nlm/hal/uart.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)
{
di->ops = uart_getops(&uart_ns8250_class);
di->bas.chan = 0;
di->bas.bst = rmi_bus_space;
di->bas.bsh = nlm_regbase_uart(0, 0) + XLP_IO_PCI_HDRSZ;
di->bas.regshft = 2;
/* divisor = rclk / (baudrate * 16); */
di->bas.rclk = 133000000;
di->baudrate = 115200;
di->databits = 8;
di->stopbits = 1;
di->parity = UART_PARITY_NONE;
uart_bus_space_io = NULL;
uart_bus_space_mem = rmi_bus_space;
return (0);
}

133
sys/mips/nlm/xlp.h Normal file
View File

@ -0,0 +1,133 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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$
* NETLOGIC_BSD */
#ifndef __NLM_XLP_H__
#define __NLM_XLP_H__
#include <mips/nlm/hal/pic.h>
#define XLP_PIC_IRT_UART0_IRQ 9
#define XLP_PIC_IRT_UART1_IRQ 10
#define XLP_PIC_IRT_PCIE0_IRQ 11
#define XLP_PIC_IRT_PCIE1_IRQ 12
#define XLP_PIC_IRT_PCIE2_IRQ 13
#define XLP_PIC_IRT_PCIE3_IRQ 14
#define XLP_PIC_IRT_EHCI0_IRQ 39
#define XLP_PIC_IRT_EHCI1_IRQ 42
#define XLP_PIC_IRT_MMC_IRQ 43
#ifndef LOCORE
/*
* FreeBSD can be started with few threads and cores turned off,
* so have a hardware thread id to FreeBSD cpuid mapping.
*/
extern int xlp_ncores;
extern int xlp_threads_per_core;
extern uint32_t xlp_hw_thread_mask;
extern int xlp_cpuid_to_hwtid[];
extern int xlp_hwtid_to_cpuid[];
#ifdef SMP
extern void xlp_enable_threads(int code);
#endif
extern uint64_t xlp_pic_base; /* TODO just for node 0 now */
static __inline__ int
xlp_irt_to_irq(int irt)
{
switch (irt) {
case XLP_PIC_IRT_MMC_INDEX :
return XLP_PIC_IRT_MMC_IRQ;
case XLP_PIC_IRT_EHCI0_INDEX :
return XLP_PIC_IRT_EHCI0_IRQ;
case XLP_PIC_IRT_EHCI1_INDEX :
return XLP_PIC_IRT_EHCI1_IRQ;
case XLP_PIC_IRT_UART0_INDEX :
return XLP_PIC_IRT_UART0_IRQ;
case XLP_PIC_IRT_UART1_INDEX :
return XLP_PIC_IRT_UART1_IRQ;
case XLP_PIC_IRT_PCIE_LINK0_INDEX :
return XLP_PIC_IRT_PCIE0_IRQ;
case XLP_PIC_IRT_PCIE_LINK1_INDEX :
return XLP_PIC_IRT_PCIE1_IRQ;
case XLP_PIC_IRT_PCIE_LINK2_INDEX :
return XLP_PIC_IRT_PCIE2_IRQ;
case XLP_PIC_IRT_PCIE_LINK3_INDEX :
return XLP_PIC_IRT_PCIE3_IRQ;
default: panic("Bad IRT %d\n", irt);
}
}
static __inline__ int
xlp_irq_to_irt(int irq)
{
switch (irq) {
case XLP_PIC_IRT_MMC_IRQ :
return XLP_PIC_IRT_MMC_INDEX;
case XLP_PIC_IRT_EHCI0_IRQ :
return XLP_PIC_IRT_EHCI0_INDEX;
case XLP_PIC_IRT_EHCI1_IRQ :
return XLP_PIC_IRT_EHCI1_INDEX;
case XLP_PIC_IRT_UART0_IRQ :
return XLP_PIC_IRT_UART0_INDEX;
case XLP_PIC_IRT_UART1_IRQ :
return XLP_PIC_IRT_UART1_INDEX;
case XLP_PIC_IRT_PCIE0_IRQ :
return XLP_PIC_IRT_PCIE_LINK0_INDEX;
case XLP_PIC_IRT_PCIE1_IRQ :
return XLP_PIC_IRT_PCIE_LINK1_INDEX;
case XLP_PIC_IRT_PCIE2_IRQ :
return XLP_PIC_IRT_PCIE_LINK2_INDEX;
case XLP_PIC_IRT_PCIE3_IRQ :
return XLP_PIC_IRT_PCIE_LINK3_INDEX;
default: panic("Bad IRQ %d\n", irq);
}
}
static __inline__ int
xlp_irq_is_picintr(int irq)
{
switch (irq) {
case XLP_PIC_IRT_MMC_IRQ : return 1;
case XLP_PIC_IRT_EHCI0_IRQ : return 1;
case XLP_PIC_IRT_EHCI1_IRQ : return 1;
case XLP_PIC_IRT_UART0_IRQ : return 1;
case XLP_PIC_IRT_UART1_IRQ : return 1;
case XLP_PIC_IRT_PCIE0_IRQ : return 1;
case XLP_PIC_IRT_PCIE1_IRQ : return 1;
case XLP_PIC_IRT_PCIE2_IRQ : return 1;
case XLP_PIC_IRT_PCIE3_IRQ : return 1;
default: return 0;
}
}
#endif /* LOCORE */
#endif /* __NLM_XLP_H__ */

667
sys/mips/nlm/xlp_machdep.c Normal file
View File

@ -0,0 +1,667 @@
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). 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 Netlogic Microsystems ``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 NETLOGIC 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.
*
* NETLOGIC_BSD */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/rtprio.h>
#include <sys/systm.h>
#include <sys/interrupt.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/random.h>
#include <sys/cons.h> /* cinit() */
#include <sys/kdb.h>
#include <sys/reboot.h>
#include <sys/queue.h>
#include <sys/smp.h>
#include <sys/timetc.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/cpuinfo.h>
#include <machine/tlb.h>
#include <machine/cpuregs.h>
#include <machine/frame.h>
#include <machine/hwfunc.h>
#include <machine/md_var.h>
#include <machine/asm.h>
#include <machine/pmap.h>
#include <machine/trap.h>
#include <machine/clock.h>
#include <machine/fls64.h>
#include <machine/intr_machdep.h>
#include <machine/smp.h>
#include <mips/nlm/hal/mips-extns.h>
#include <mips/nlm/hal/mmio.h>
#include <mips/nlm/hal/iomap.h>
#include <mips/nlm/hal/cop0.h>
#include <mips/nlm/hal/sys.h>
#include <mips/nlm/hal/pic.h>
#include <mips/nlm/hal/uart.h>
#include <mips/nlm/hal/mmu.h>
#include <mips/nlm/hal/bridge.h>
#include <mips/nlm/hal/cpucontrol.h>
#include <mips/nlm/clock.h>
#include <mips/nlm/interrupt.h>
#include <mips/nlm/board.h>
#include <mips/nlm/xlp.h>
/* 4KB static data aread to keep a copy of the bootload env until
the dynamic kenv is setup */
char boot1_env[4096];
int xlp_argc;
char **xlp_argv, **xlp_envp;
uint64_t xlp_cpu_frequency;
uint64_t nlm_pcicfg_baseaddr = MIPS_PHYS_TO_KSEG1(XLP_DEFAULT_IO_BASE);
int xlp_ncores;
int xlp_threads_per_core;
uint32_t xlp_hw_thread_mask;
int xlp_cpuid_to_hwtid[MAXCPU];
int xlp_hwtid_to_cpuid[MAXCPU];
uint64_t xlp_pic_base;
static int xlp_mmuval;
extern uint32_t _end;
extern char XLPResetEntry[], XLPResetEntryEnd[];
static void
xlp_setup_core(void)
{
uint64_t reg;
reg = nlm_mfcr(XLP_LSU_DEFEATURE);
/* Enable Unaligned and L2HPE */
reg |= (1 << 30) | (1 << 23);
/*
* Experimental : Enable SUE
* Speculative Unmap Enable. Enable speculative L2 cache request for
* unmapped access.
*/
reg |= (1ull << 31);
/* Clear S1RCM - A0 errata */
reg &= ~0xeull;
nlm_mtcr(XLP_LSU_DEFEATURE, reg);
reg = nlm_mfcr(XLP_SCHED_DEFEATURE);
/* Experimental: Disable BRU accepting ALU ops - A0 errata */
reg |= (1 << 24);
nlm_mtcr(XLP_SCHED_DEFEATURE, reg);
}
static void
xlp_setup_mmu(void)
{
nlm_setup_extended_pagemask(0); /* pagemask = 0 for 4K pages */
nlm_large_variable_tlb_en(0);
nlm_extended_tlb_en(1);
nlm_mmu_setup(0, 0, 0);
}
static void
xlp_parse_mmu_options(void)
{
int i, j, k;
uint32_t cpu_map = xlp_hw_thread_mask;
uint32_t core0_thr_mask, core_thr_mask;
#ifndef SMP /* Uniprocessor! */
if (cpu_map != 0x1) {
printf("WARNING: Starting uniprocessor kernel on cpumask [0x%lx]!\n"
"WARNING: Other CPUs will be unused.\n", (u_long)cpu_map);
cpu_map = 0x1;
}
#endif
xlp_ncores = 1;
core0_thr_mask = cpu_map & 0xf;
switch (core0_thr_mask) {
case 1:
xlp_threads_per_core = 1;
xlp_mmuval = 0;
break;
case 3:
xlp_threads_per_core = 2;
xlp_mmuval = 2;
break;
case 0xf:
xlp_threads_per_core = 4;
xlp_mmuval = 3;
break;
default:
goto unsupp;
}
/* Verify other cores CPU masks */
for (i = 1; i < XLP_MAX_CORES; i++) {
core_thr_mask = (cpu_map >> (i*4)) & 0xf;
if (core_thr_mask) {
if (core_thr_mask != core0_thr_mask)
goto unsupp;
xlp_ncores++;
}
}
xlp_hw_thread_mask = cpu_map;
/* setup hardware processor id to cpu id mapping */
for (i = 0; i< MAXCPU; i++)
xlp_cpuid_to_hwtid[i] =
xlp_hwtid_to_cpuid [i] = -1;
for (i = 0, k = 0; i < XLP_MAX_CORES; i++) {
if (((cpu_map >> (i*4)) & 0xf) == 0)
continue;
for (j = 0; j < xlp_threads_per_core; j++) {
xlp_cpuid_to_hwtid[k] = i*4 + j;
xlp_hwtid_to_cpuid[i*4 + j] = k;
k++;
}
}
#ifdef SMP
/*
* We will enable the other threads in core 0 here
* so that the TLB and cache info is correct when
* mips_init runs
*/
xlp_enable_threads(xlp_mmuval);
#endif
/* setup for the startup core */
xlp_setup_mmu();
return;
unsupp:
printf("ERROR : Unsupported CPU mask [use 1,2 or 4 threads per core].\n"
"\tcore0 thread mask [%lx], boot cpu mask [%lx]\n"
"\tUsing default, 16 TLB entries per CPU, split mode\n",
(u_long)core0_thr_mask, (u_long)cpu_map);
panic("Invalid CPU mask - halting.\n");
return;
}
static void
xlp_set_boot_flags(void)
{
char *p;
p = getenv("bootflags");
if (p == NULL)
return;
for (; p && *p != '\0'; p++) {
switch (*p) {
case 'd':
case 'D':
boothowto |= RB_KDB;
break;
case 'g':
case 'G':
boothowto |= RB_GDB;
break;
case 'v':
case 'V':
boothowto |= RB_VERBOSE;
break;
case 's': /* single-user (default, supported for sanity) */
case 'S':
boothowto |= RB_SINGLE;
break;
default:
printf("Unrecognized boot flag '%c'.\n", *p);
break;
}
}
freeenv(p);
return;
}
static void
mips_init(void)
{
init_param1();
init_param2(physmem);
mips_cpu_init();
cpuinfo.cache_coherent_dma = TRUE;
pmap_bootstrap();
#ifdef DDB
kdb_init();
if (boothowto & RB_KDB) {
kdb_enter("Boot flags requested debugger", NULL);
}
#endif
mips_proc0_init();
mutex_init();
}
unsigned int
platform_get_timecount(struct timecounter *tc __unused)
{
return ((unsigned int)~nlm_pic_read_systimer(xlp_pic_base, 7));
}
static void
xlp_pic_init(void)
{
struct timecounter pic_timecounter = {
platform_get_timecount, /* get_timecount */
0, /* no poll_pps */
~0U, /* counter_mask */
XLP_PIC_TIMER_FREQ, /* frequency */
"XLRPIC", /* name */
2000, /* quality (adjusted in code) */
};
int i;
xlp_pic_base = nlm_regbase_pic(0); /* TOOD: Add other nodes */
printf("Initializing PIC...@%jx\n", (uintmax_t)xlp_pic_base);
/* Bind all PIC irqs to cpu 0 */
for(i = 0; i < XLP_PIC_MAX_IRT; i++) {
nlm_pic_write_irt_raw(xlp_pic_base, i, 0, 0, 1, 0,
1, 0, 0x1);
}
nlm_pic_set_systimer(xlp_pic_base, 7, ~0ULL, 0, 0, 0, 0);
platform_timecounter = &pic_timecounter;
}
#if defined(__mips_n32) || defined(__mips_n64) /* PHYSADDR_64_BIT */
#ifdef XLP_SIM
#define XLP_MEM_LIM 0x200000000ULL
#else
#define XLP_MEM_LIM 0x10000000000ULL
#endif
#else
#define XLP_MEM_LIM 0xfffff000UL
#endif
static void
xlp_mem_init(void)
{
uint64_t bridgebase = nlm_regbase_bridge(0); /* TOOD: Add other nodes */
vm_size_t physsz = 0;
uint64_t base, lim, val;
int i, j;
for (i = 0, j = 0; i < 8; i++) {
val = nlm_rdreg_bridge(bridgebase, XLP_BRIDGE_DRAM_BAR_REG(i));
base = ((val >> 12) & 0xfffff) << 20;
val = nlm_rdreg_bridge(bridgebase, XLP_BRIDGE_DRAM_LIMIT_REG(i));
lim = ((val >> 12) & 0xfffff) << 20;
/* BAR not enabled */
if (lim == 0)
continue;
/* first bar, start a bit after end */
if (base == 0) {
base = (vm_paddr_t)MIPS_KSEG0_TO_PHYS(&_end) + 0x20000;
lim = 0x0c000000; /* TODO : hack to avoid uboot packet mem */
}
if (base >= XLP_MEM_LIM) {
printf("Mem [%d]: Ignore %#jx - %#jx\n", i,
(intmax_t)base, (intmax_t)lim);
continue;
}
if (lim > XLP_MEM_LIM) {
printf("Mem [%d]: Restrict %#jx -> %#jx\n", i,
(intmax_t)lim, (intmax_t)XLP_MEM_LIM);
lim = XLP_MEM_LIM;
}
if (lim <= base) {
printf("Mem[%d]: Malformed %#jx -> %#jx\n", i,
(intmax_t)base, (intmax_t)lim);
continue;
}
/*
* Exclude reset entry memory range 0x1fc00000 - 0x20000000
* from free memory
*/
if (base <= 0x1fc00000 && (base + lim) > 0x1fc00000) {
uint64_t base0, lim0, base1, lim1;
base0 = base;
lim0 = 0x1fc00000;
base1 = 0x20000000;
lim1 = lim;
if (lim0 > base0) {
phys_avail[j++] = (vm_paddr_t)base0;
phys_avail[j++] = (vm_paddr_t)lim0;
physsz += lim0 - base0;
printf("Mem[%d]: %#jx - %#jx (excl reset)\n", i,
(intmax_t)base0, (intmax_t)lim0);
}
if (lim1 > base1) {
phys_avail[j++] = (vm_paddr_t)base1;
phys_avail[j++] = (vm_paddr_t)lim1;
physsz += lim1 - base1;
printf("Mem[%d]: %#jx - %#jx (excl reset)\n", i,
(intmax_t)base1, (intmax_t)lim1);
}
} else {
phys_avail[j++] = (vm_paddr_t)base;
phys_avail[j++] = (vm_paddr_t)lim;
physsz += lim - base;
printf("Mem[%d]: %#jx - %#jx\n", i,
(intmax_t)base, (intmax_t)lim);
}
}
/* setup final entry with 0 */
phys_avail[j] = phys_avail[j + 1] = 0;
realmem = physmem = btoc(physsz);
}
static uint32_t
xlp_get_cpu_frequency(void)
{
uint64_t sysbase = nlm_regbase_sys(0);
unsigned int pll_divf, pll_divr, dfs_div, num, denom;
uint32_t val;
val = nlm_rdreg_sys(sysbase, XLP_SYS_POWER_ON_RESET_REG);
pll_divf = (val >> 10) & 0x7f;
pll_divr = (val >> 8) & 0x3;
dfs_div = (val >> 17) & 0x3;
num = pll_divf + 1;
denom = 3 * (pll_divr + 1) * (1<< (dfs_div + 1));
val = 800000000ULL * num / denom;
return (val);
}
void
platform_start(__register_t a0 __unused,
__register_t a1 __unused,
__register_t a2 __unused,
__register_t a3 __unused)
{
int i;
xlp_argc = 1;
/*
* argv and envp are passed in array of 32bit pointers
*/
xlp_argv = NULL;
xlp_envp = NULL;
/* Initialize pcpu stuff */
mips_pcpu0_init();
/* initialize console so that we have printf */
boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */
/* For now */
boothowto |= RB_VERBOSE;
boothowto |= RB_SINGLE;
bootverbose++;
/* clockrate used by delay, so initialize it here */
xlp_cpu_frequency = xlp_get_cpu_frequency();
cpu_clock = xlp_cpu_frequency / 1000000;
mips_timer_early_init(xlp_cpu_frequency);
/* Init console please */
cninit();
/* Environment */
printf("Args %#jx %#jx %#jx %#jx:\n", (intmax_t)a0,
(intmax_t)a1, (intmax_t)a2, (intmax_t)a3);
xlp_hw_thread_mask = a0;
init_static_kenv(boot1_env, sizeof(boot1_env));
printf("Environment (from %d args):\n", xlp_argc - 1);
if (xlp_argc == 1)
printf("\tNone\n");
for (i = 1; i < xlp_argc; i++) {
char *n, *arg;
arg = (char *)(intptr_t)xlp_argv[i];
printf("\t%s\n", arg);
n = strsep(&arg, "=");
if (arg == NULL)
setenv(n, "1");
else
setenv(n, arg);
}
/* Early core init and fixes for errata */
xlp_setup_core();
xlp_set_boot_flags();
xlp_parse_mmu_options();
xlp_mem_init();
bcopy(XLPResetEntry, (void *)MIPS_RESET_EXC_VEC,
XLPResetEntryEnd - XLPResetEntry);
/*
* MIPS generic init
*/
mips_init();
/*
* XLP specific post initialization
* initialize other on chip stuff
*/
nlm_board_info_setup();
xlp_pic_init();
mips_timer_init_params(xlp_cpu_frequency, 0);
printf("Platform specific startup now completes\n");
}
void
platform_cpu_init()
{
}
void
platform_identify(void)
{
printf("XLP Eval Board\n");
}
/*
* XXX Maybe return the state of the watchdog in enter, and pass it to
* exit? Like spl().
*/
void
platform_trap_enter(void)
{
}
void
platform_reset(void)
{
uint64_t sysbase = nlm_regbase_sys(0);
nlm_wreg_sys(sysbase, XLP_SYS_CHIP_RESET_REG, 1);
for(;;)
__asm __volatile("wait");
}
void
platform_trap_exit(void)
{
}
#ifdef SMP
/*
* XLP threads are started simultaneously when we enable threads, this will
* ensure that the threads are blocked in platform_init_ap, until they are
* ready to proceed to smp_init_secondary()
*/
static volatile int thr_unblock[4];
int
platform_start_ap(int cpuid)
{
uint32_t coremask, val;
uint64_t sysbase = nlm_regbase_sys(0);
int hwtid = xlp_cpuid_to_hwtid[cpuid];
int core, thr;
core = hwtid / 4;
thr = hwtid % 4;
if (thr == 0) {
/* First thread in core, do core wake up */
coremask = 1u << core;
/* Enable core clock */
val = nlm_rdreg_sys(sysbase, XLP_SYS_CORE_DFS_DIS_CTRL_REG);
val &= ~coremask;
nlm_wreg_sys(sysbase, XLP_SYS_CORE_DFS_DIS_CTRL_REG, val);
/* Remove CPU Reset */
val = nlm_rdreg_sys(sysbase, XLP_SYS_CPU_RESET_REG);
val &= ~coremask & 0xff;
nlm_wreg_sys(sysbase, XLP_SYS_CPU_RESET_REG, val);
if (bootverbose)
printf("Waking up core %d ...", core);
/* Poll for CPU to mark itself coherent */
do {
val = nlm_rdreg_sys(sysbase, XLP_SYS_CPU_NONCOHERENT_MODE_REG);
} while ((val & coremask) != 0);
if (bootverbose)
printf("Done\n");
} else {
/* otherwise release the threads stuck in platform_init_ap */
thr_unblock[thr] = 1;
}
return (0);
}
void
platform_init_ap(int cpuid)
{
uint32_t stat;
int thr;
/* The first thread has to setup the MMU and enable other threads */
thr = nlm_threadid();
if (thr == 0) {
xlp_setup_core();
xlp_enable_threads(xlp_mmuval);
xlp_setup_mmu();
} else {
/*
* FIXME busy wait here eats too many cycles, especially
* in the core 0 while bootup
*/
while (thr_unblock[thr] == 0)
__asm__ __volatile__ ("nop;nop;nop;nop");
thr_unblock[thr] = 0;
}
stat = mips_rd_status();
KASSERT((stat & MIPS_SR_INT_IE) == 0,
("Interrupts enabled in %s!", __func__));
stat |= MIPS_SR_COP_2_BIT | MIPS_SR_COP_0_BIT;
mips_wr_status(stat);
nlm_write_c0_eimr(0ull);
xlp_enable_irq(IRQ_IPI);
xlp_enable_irq(IRQ_TIMER);
xlp_enable_irq(IRQ_MSGRING);
return;
}
int
platform_ipi_intrnum(void)
{
return (IRQ_IPI);
}
void
platform_ipi_send(int cpuid)
{
nlm_pic_send_ipi(xlp_pic_base, 0, xlp_cpuid_to_hwtid[cpuid],
platform_ipi_intrnum(), 0);
}
void
platform_ipi_clear(void)
{
}
int
platform_processor_id(void)
{
return (xlp_hwtid_to_cpuid[nlm_cpuid()]);
}
void
platform_cpu_mask(cpuset_t *mask)
{
int i, s;
CPU_ZERO(mask);
s = xlp_ncores * xlp_threads_per_core;
for (i = 0; i < s; i++)
CPU_SET(i, mask);
}
struct cpu_group *
platform_smp_topo()
{
return (smp_topo_2level(CG_SHARE_L2, xlp_ncores, CG_SHARE_L1,
xlp_threads_per_core, CG_FLAG_THREAD));
}
#endif