mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-29 06:42:45 +00:00
- Use the name returned by device_get_nameunit(9) for the name of the
counter-timer timecounter so the associated SYSCTL nodes don't clash on machines having multiple U2P and U2S bridges as well as establishing a clear mapping between these bridges and their timecounter device. - Don't bother setting up a "nice" name for the IOMMU, just use the name returned by device_get_nameunit(9), too. - Fix some minor style(9) bugs. - Use __FBSDID in counter.c MFC after: 1 week
This commit is contained in:
parent
0f0e3d5f39
commit
083b2bd41a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=178840
@ -65,7 +65,7 @@
|
||||
((inr) & INTMAP_INR_MASK))
|
||||
|
||||
/* counter-timer support. */
|
||||
void sparc64_counter_init(bus_space_tag_t tag, bus_space_handle_t handle,
|
||||
bus_addr_t offset);
|
||||
void sparc64_counter_init(const char *name, bus_space_tag_t tag,
|
||||
bus_space_handle_t handle, bus_addr_t offset);
|
||||
|
||||
#endif /* !_MACHINE_BUS_COMMON_H_ */
|
||||
|
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_IOMMUVAR_H_
|
||||
#define _MACHINE_IOMMUVAR_H_
|
||||
#define _MACHINE_IOMMUVAR_H_
|
||||
|
||||
#define IO_PAGE_SIZE PAGE_SIZE_8K
|
||||
#define IO_PAGE_MASK PAGE_MASK_8K
|
||||
@ -62,10 +62,10 @@ struct iommu_state {
|
||||
struct rman is_dvma_rman; /* DVMA space rman */
|
||||
struct iommu_maplruq_head is_maplruq; /* (i) LRU queue */
|
||||
vm_paddr_t is_ptsb; /* (r) TSB physical address */
|
||||
u_int64_t *is_tsb; /* (*i) TSB virtual address */
|
||||
uint64_t *is_tsb; /* (*i) TSB virtual address */
|
||||
int is_tsbsize; /* (r) 0 = 8K, ... */
|
||||
u_int64_t is_pmaxaddr; /* (r) max. physical address */
|
||||
u_int64_t is_dvmabase; /* (r) */
|
||||
uint64_t is_pmaxaddr; /* (r) max. physical address */
|
||||
uint64_t is_dvmabase; /* (r) */
|
||||
int64_t is_cr; /* (r) Control reg value */
|
||||
|
||||
vm_paddr_t is_flushpa[2]; /* (r) */
|
||||
@ -99,9 +99,10 @@ struct iommu_state {
|
||||
};
|
||||
|
||||
/* interfaces for PCI/SBus code */
|
||||
void iommu_init(char *, struct iommu_state *, int, u_int32_t, int);
|
||||
void iommu_reset(struct iommu_state *);
|
||||
void iommu_decode_fault(struct iommu_state *, vm_offset_t);
|
||||
void iommu_init(const char *name, struct iommu_state *is, int tsbsize,
|
||||
uint32_t iovabase, int resvpg);
|
||||
void iommu_reset(struct iommu_state *is);
|
||||
void iommu_decode_fault(struct iommu_state *is, vm_offset_t phys);
|
||||
|
||||
extern struct bus_dma_methods iommu_dma_methods;
|
||||
|
||||
|
@ -345,7 +345,7 @@ psycho_attach(device_t dev)
|
||||
|
||||
/*
|
||||
* Match other Psycho's that are already configured against
|
||||
* the base physical address. This will be the same for a
|
||||
* the base physical address. This will be the same for a
|
||||
* pair of devices that share register space.
|
||||
*/
|
||||
osc = NULL;
|
||||
@ -464,8 +464,8 @@ psycho_attach(device_t dev)
|
||||
nrange = OF_getprop_alloc(node, "ranges", sizeof(*range),
|
||||
(void **)&range);
|
||||
/*
|
||||
* Make sure that the expected ranges are present. The OFW_PCI_CS_MEM64
|
||||
* one is not currently used though.
|
||||
* Make sure that the expected ranges are present. The
|
||||
* OFW_PCI_CS_MEM64 one is not currently used though.
|
||||
*/
|
||||
if (nrange != PSYCHO_NRANGE)
|
||||
panic("%s: unsupported number of ranges", __func__);
|
||||
@ -510,7 +510,7 @@ psycho_attach(device_t dev)
|
||||
#ifdef PSYCHO_DEBUG
|
||||
/*
|
||||
* Enable all interrupts and clear all interrupt
|
||||
* states. This aids the debugging of interrupt
|
||||
* states. This aids the debugging of interrupt
|
||||
* routing problems.
|
||||
*/
|
||||
device_printf(dev,
|
||||
@ -571,7 +571,8 @@ psycho_attach(device_t dev)
|
||||
#endif /* PSYCHO_MAP_WAKEUP */
|
||||
|
||||
/* Initialize the counter-timer. */
|
||||
sparc64_counter_init(rman_get_bustag(sc->sc_mem_res),
|
||||
sparc64_counter_init(device_get_nameunit(dev),
|
||||
rman_get_bustag(sc->sc_mem_res),
|
||||
rman_get_bushandle(sc->sc_mem_res), PSR_TC0);
|
||||
}
|
||||
|
||||
@ -610,7 +611,7 @@ psycho_attach(device_t dev)
|
||||
|
||||
/*
|
||||
* Register a PCI bus error interrupt handler according to which
|
||||
* half this is. Hummingbird/Sabre don't have a PCI bus B error
|
||||
* half this is. Hummingbird/Sabre don't have a PCI bus B error
|
||||
* interrupt but they are also only used for PCI bus A.
|
||||
*/
|
||||
psycho_set_intr(sc, 0, sc->sc_half == 0 ? PSR_PCIAERR_INT_MAP :
|
||||
@ -666,8 +667,8 @@ psycho_attach(device_t dev)
|
||||
/*
|
||||
* On E250 the interrupt map entry for the EBus bridge is wrong,
|
||||
* causing incorrect interrupts to be assigned to some devices on
|
||||
* the EBus. Work around it by changing our copy of the interrupt
|
||||
* map mask to perform a full comparison of the INO. That way
|
||||
* the EBus. Work around it by changing our copy of the interrupt
|
||||
* map mask to perform a full comparison of the INO. That way
|
||||
* the interrupt map entry for the EBus bridge won't match at all
|
||||
* and the INOs specified in the "interrupts" properties of the
|
||||
* EBus devices will be used directly instead.
|
||||
@ -782,7 +783,7 @@ psycho_ue(void *arg)
|
||||
/*
|
||||
* On the UltraSPARC-IIi/IIe, IOMMU misses/protection faults cause
|
||||
* the AFAR to be set to the physical address of the TTE entry that
|
||||
* was invalid/write protected. Call into the iommu code to have
|
||||
* was invalid/write protected. Call into the IOMMU code to have
|
||||
* them decoded to virtual I/O addresses.
|
||||
*/
|
||||
if ((afsr & UEAFSR_P_DTE) != 0)
|
||||
@ -871,7 +872,6 @@ psycho_wakeup(void *arg)
|
||||
static void
|
||||
psycho_iommu_init(struct psycho_softc *sc, int tsbsize, uint32_t dvmabase)
|
||||
{
|
||||
char *name;
|
||||
struct iommu_state *is = sc->sc_is;
|
||||
|
||||
/* Punch in our copies. */
|
||||
@ -884,13 +884,7 @@ psycho_iommu_init(struct psycho_softc *sc, int tsbsize, uint32_t dvmabase)
|
||||
is->is_dva = PSR_IOMMU_SVADIAG;
|
||||
is->is_dtcmp = PSR_IOMMU_TLB_CMP_DIAG;
|
||||
|
||||
/* Give us a nice name... */
|
||||
name = malloc(32, M_DEVBUF, M_NOWAIT);
|
||||
if (name == NULL)
|
||||
panic("%s: could not malloc iommu name", __func__);
|
||||
snprintf(name, 32, "%s dvma", device_get_nameunit(sc->sc_dev));
|
||||
|
||||
iommu_init(name, is, tsbsize, dvmabase, 0);
|
||||
iommu_init(device_get_nameunit(sc->sc_dev), is, tsbsize, dvmabase, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -921,10 +915,10 @@ psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
|
||||
* only allow their config space to be accessed using the
|
||||
* "native" width of the respective register being accessed
|
||||
* and return semi-random other content of their config space
|
||||
* otherwise. Given that the PCI specs don't say anything
|
||||
* otherwise. Given that the PCI specs don't say anything
|
||||
* about such a (unusual) limitation and lots of stuff expects
|
||||
* to be able to access the contents of the config space at
|
||||
* any width we allow just that. We do this by using a copy
|
||||
* any width we allow just that. We do this by using a copy
|
||||
* of the header of the bridge (the rest is all zero anyway)
|
||||
* read during attach (expect for PCIR_STATUS) in order to
|
||||
* simplify things.
|
||||
@ -1027,7 +1021,7 @@ psycho_route_interrupt(device_t bridge, device_t dev, int pin)
|
||||
/*
|
||||
* If this is outside of the range for an intpin, it's likely a full
|
||||
* INO, and no mapping is required at all; this happens on the U30,
|
||||
* where there's no interrupt map at the Psycho node. Fortunately,
|
||||
* where there's no interrupt map at the Psycho node. Fortunately,
|
||||
* there seem to be no INOs in the intpin range on this boxen, so
|
||||
* this easy heuristics will do.
|
||||
*/
|
||||
@ -1035,7 +1029,7 @@ psycho_route_interrupt(device_t bridge, device_t dev, int pin)
|
||||
return (pin);
|
||||
/*
|
||||
* Guess the INO; we always assume that this is a non-OBIO
|
||||
* device, and that pin is a "real" intpin number. Determine
|
||||
* device, and that pin is a "real" intpin number. Determine
|
||||
* the mapping register to be used by the slot number.
|
||||
* We only need to do this on E450s, it seems; here, the slot numbers
|
||||
* for bus A are one-based, while those for bus B seemingly have an
|
||||
@ -1146,7 +1140,7 @@ psycho_setup_intr(device_t dev, device_t child, struct resource *ires,
|
||||
/*
|
||||
* The Sabre-APB-combination has a bug where it does not drain
|
||||
* DMA write data for devices behind additional PCI-PCI bridges
|
||||
* underneath the APB PCI-PCI bridge. The workaround is to do
|
||||
* underneath the APB PCI-PCI bridge. The workaround is to do
|
||||
* a read on the farest PCI-PCI bridge followed by a read of the
|
||||
* PCI DMA write sync register of the Sabre.
|
||||
* XXX installing the wrapper for an affected device and the
|
||||
@ -1260,10 +1254,10 @@ psycho_alloc_resource(device_t bus, device_t child, int type, int *rid,
|
||||
if (type == SYS_RES_IRQ) {
|
||||
/*
|
||||
* XXX: Don't accept blank ranges for now, only single
|
||||
* interrupts. The other case should not happen with the
|
||||
* MI PCI code...
|
||||
* interrupts. The other case should not happen with
|
||||
* the MI PCI code...
|
||||
* XXX: This may return a resource that is out of the
|
||||
* range that was specified. Is this correct...?
|
||||
* range that was specified. Is this correct...?
|
||||
*/
|
||||
if (start != end)
|
||||
panic("%s: XXX: interrupt range", __func__);
|
||||
|
@ -309,7 +309,6 @@ sbus_attach(device_t dev)
|
||||
device_t cdev;
|
||||
bus_addr_t intrclr, intrmap, phys;
|
||||
bus_size_t size;
|
||||
char *name;
|
||||
u_long vec;
|
||||
phandle_t child, node;
|
||||
int clock, i, intr, rid;
|
||||
@ -401,18 +400,12 @@ sbus_attach(device_t dev)
|
||||
sc->sc_is.is_sb[0] = SBR_STRBUF;
|
||||
sc->sc_is.is_sb[1] = 0;
|
||||
|
||||
/* give us a nice name.. */
|
||||
name = (char *)malloc(32, M_DEVBUF, M_NOWAIT);
|
||||
if (name == NULL)
|
||||
panic("%s: cannot malloc iommu name", __func__);
|
||||
snprintf(name, 32, "%s dvma", device_get_name(dev));
|
||||
|
||||
/*
|
||||
* Note: the SBus IOMMU ignores the high bits of an address, so a NULL
|
||||
* DMA pointer will be translated by the first page of the IOTSB.
|
||||
* To detect bugs we'll allocate and ignore the first entry.
|
||||
*/
|
||||
iommu_init(name, &sc->sc_is, 3, -1, 1);
|
||||
iommu_init(device_get_nameunit(dev), &sc->sc_is, 3, -1, 1);
|
||||
|
||||
/* Create the DMA tag. */
|
||||
if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
|
||||
@ -473,7 +466,8 @@ sbus_attach(device_t dev)
|
||||
panic("%s: failed to set up power fail interrupt", __func__);
|
||||
|
||||
/* Initialize the counter-timer. */
|
||||
sparc64_counter_init(rman_get_bustag(sc->sc_sysio_res),
|
||||
sparc64_counter_init(device_get_nameunit(dev),
|
||||
rman_get_bustag(sc->sc_sysio_res),
|
||||
rman_get_bushandle(sc->sc_sysio_res), SBR_TC0);
|
||||
|
||||
/*
|
||||
|
@ -21,10 +21,11 @@
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/malloc.h>
|
||||
@ -53,7 +54,7 @@
|
||||
#define CTR_LIMIT 0x08
|
||||
|
||||
|
||||
static unsigned int counter_get_timecount(struct timecounter *tc);
|
||||
static timecounter_get_t counter_get_timecount;
|
||||
|
||||
struct ct_softc {
|
||||
bus_space_tag_t sc_tag;
|
||||
@ -63,21 +64,22 @@ struct ct_softc {
|
||||
|
||||
|
||||
/*
|
||||
* This is called from the psycho and sbus drivers. It does not directly attach
|
||||
* to the nexus because it shares register space with the bridge in question.
|
||||
* This is called from the psycho and sbus drivers. It does not directly
|
||||
* attach to the nexus because it shares register space with the bridge in
|
||||
* question.
|
||||
*/
|
||||
void
|
||||
sparc64_counter_init(bus_space_tag_t tag, bus_space_handle_t handle,
|
||||
bus_addr_t offset)
|
||||
sparc64_counter_init(const char *name, bus_space_tag_t tag,
|
||||
bus_space_handle_t handle, bus_addr_t offset)
|
||||
{
|
||||
struct timecounter *tc;
|
||||
struct ct_softc *sc;
|
||||
|
||||
printf("initializing counter-timer\n");
|
||||
/*
|
||||
* Turn off interrupts from both counters. Set the limit to the maximum
|
||||
* value (although that should not change anything with CTLR_INTEN and
|
||||
* CTLR_PERIODIC off).
|
||||
* Turn off interrupts from both counters. Set the limit to the
|
||||
* maximum value (although that should not change anything with
|
||||
* CTLR_INTEN and CTLR_PERIODIC off).
|
||||
*/
|
||||
bus_space_write_8(tag, handle, offset + CTR_CT0 + CTR_LIMIT,
|
||||
COUNTER_MASK);
|
||||
@ -93,7 +95,7 @@ sparc64_counter_init(bus_space_tag_t tag, bus_space_handle_t handle,
|
||||
tc->tc_poll_pps = NULL;
|
||||
tc->tc_counter_mask = COUNTER_MASK;
|
||||
tc->tc_frequency = COUNTER_FREQ;
|
||||
tc->tc_name = "counter-timer";
|
||||
tc->tc_name = strdup(name, M_DEVBUF);
|
||||
tc->tc_priv = sc;
|
||||
tc->tc_quality = COUNTER_QUALITY;
|
||||
tc_init(tc);
|
||||
|
@ -283,12 +283,12 @@ iommu_map_remq(struct iommu_state *is, bus_dmamap_t map)
|
||||
* - create a private DVMA map.
|
||||
*/
|
||||
void
|
||||
iommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase,
|
||||
int resvpg)
|
||||
iommu_init(const char *name, struct iommu_state *is, int tsbsize,
|
||||
uint32_t iovabase, int resvpg)
|
||||
{
|
||||
vm_size_t size;
|
||||
vm_offset_t offs;
|
||||
u_int64_t end;
|
||||
uint64_t end;
|
||||
int i;
|
||||
|
||||
/*
|
||||
@ -1177,7 +1177,7 @@ static void
|
||||
iommu_diag(struct iommu_state *is, vm_offset_t va)
|
||||
{
|
||||
int i;
|
||||
u_int64_t tag, data;
|
||||
uint64_t data, tag;
|
||||
|
||||
IS_LOCK_ASSERT(is);
|
||||
IOMMU_WRITE8(is, is_dva, 0, trunc_io_page(va));
|
||||
|
Loading…
Reference in New Issue
Block a user