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:
parent
e25e006dc6
commit
4d91ecaf4c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=224110
80
sys/mips/nlm/board.c
Normal file
80
sys/mips/nlm/board.c
Normal 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
75
sys/mips/nlm/board.h
Normal 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
|
688
sys/mips/nlm/bus_space_rmi.c
Normal file
688
sys/mips/nlm/bus_space_rmi.c
Normal 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
41
sys/mips/nlm/clock.h
Normal 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
451
sys/mips/nlm/cms.c
Normal 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
12
sys/mips/nlm/files.xlp
Normal 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
177
sys/mips/nlm/hal/bridge.h
Normal 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
280
sys/mips/nlm/hal/cop0.h
Normal 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
327
sys/mips/nlm/hal/cop2.h
Normal 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
|
70
sys/mips/nlm/hal/cpucontrol.h
Normal file
70
sys/mips/nlm/hal/cpucontrol.h
Normal 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
789
sys/mips/nlm/hal/fmn.c
Normal 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
275
sys/mips/nlm/hal/fmn.h
Normal 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
237
sys/mips/nlm/hal/iomap.h
Normal 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
|
200
sys/mips/nlm/hal/mips-extns.h
Normal file
200
sys/mips/nlm/hal/mips-extns.h
Normal 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
338
sys/mips/nlm/hal/mmio.h
Normal 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
204
sys/mips/nlm/hal/mmu.h
Normal 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
427
sys/mips/nlm/hal/pic.h
Normal 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
125
sys/mips/nlm/hal/sys.h
Normal 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
196
sys/mips/nlm/hal/uart.h
Normal 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
49
sys/mips/nlm/interrupt.h
Normal 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
253
sys/mips/nlm/intr_machdep.c
Normal 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
233
sys/mips/nlm/iodi.c
Normal 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
159
sys/mips/nlm/mpreset.S
Normal 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
44
sys/mips/nlm/msgring.h
Normal 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
12
sys/mips/nlm/std.xlp
Normal 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
393
sys/mips/nlm/tick.c
Normal 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);
|
88
sys/mips/nlm/uart_bus_xlp_iodi.c
Normal file
88
sys/mips/nlm/uart_bus_xlp_iodi.c
Normal 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);
|
89
sys/mips/nlm/uart_cpu_mips_xlp.c
Normal file
89
sys/mips/nlm/uart_cpu_mips_xlp.c
Normal 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
133
sys/mips/nlm/xlp.h
Normal 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
667
sys/mips/nlm/xlp_machdep.c
Normal 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
|
Loading…
Reference in New Issue
Block a user