Run the MicroSPARC IIep PCI bus without endianness translation.

This allows us to run X without any additional code changes.
This commit is contained in:
macallan 2005-09-24 22:30:15 +00:00
parent c7f8eb7c46
commit 9a8bbeeb14
7 changed files with 144 additions and 83 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.c,v 1.211 2005/09/23 23:22:57 uwe Exp $ */
/* $NetBSD: autoconf.c,v 1.212 2005/09/24 22:30:15 macallan Exp $ */
/*
* Copyright (c) 1996
@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.211 2005/09/23 23:22:57 uwe Exp $");
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.212 2005/09/24 22:30:15 macallan Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@ -466,20 +466,12 @@ bootstrapIIep()
MSIIEP_PCIC_VA, &bh) != 0)
panic("bootstrap: unable to map ms-IIep pcic registers");
/* verify that it's PCIC (it's still little-endian at this point) */
id = le32toh(mspcic_read_4(pcic_id));
/* verify that it's PCIC */
id = mspcic_read_4(pcic_id);
if (PCI_VENDOR(id) != PCI_VENDOR_SUN
&& PCI_PRODUCT(id) != PCI_PRODUCT_SUN_MS_IIep)
panic("bootstrap: PCI id %08x", id);
/* turn on automagic endian-swapping for PCI accesses */
msiiep_swap_endian(1);
/* sanity check (it's big-endian now!) */
id = mspcic_read_4(pcic_id);
if (PCI_VENDOR(id) != PCI_VENDOR_SUN
&& PCI_PRODUCT(id) != PCI_PRODUCT_SUN_MS_IIep)
panic("bootstrap: PCI id %08x (big-endian mode)", id);
}
#undef msiiep
@ -1024,10 +1016,6 @@ void
sync_crash()
{
#if defined(MSIIEP)
/* we are back from prom */
msiiep_swap_endian(1);
#endif
panic("PROM sync command");
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.c,v 1.89 2005/09/23 23:22:57 uwe Exp $ */
/* $NetBSD: intr.c,v 1.90 2005/09/24 22:30:15 macallan Exp $ */
/*
* Copyright (c) 1992, 1993
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.89 2005/09/23 23:22:57 uwe Exp $");
__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.90 2005/09/24 22:30:15 macallan Exp $");
#include "opt_multiprocessor.h"
#include "opt_sparc_arch.h"
@ -434,8 +434,6 @@ nmi_hard_msiiep(void)
fatal = 0;
}
byteswap = mspcic_read_1(pcic_pio_ctrl) & MSIIEP_PIO_CTRL_BIG_ENDIAN;
if (si & MSIIEP_SYS_IPR_SERR) { /* XXX */
printf("serr#\n");
fatal = 0;
@ -444,9 +442,6 @@ nmi_hard_msiiep(void)
if (si & MSIIEP_SYS_IPR_DMA_ERR) {
uint32_t iotlb_err_addr = mspcic_read_4(pcic_iotlb_err_addr);
if (byteswap)
iotlb_err_addr = bswap32(iotlb_err_addr);
printf("dma: %08x\n", iotlb_err_addr);
fatal = 0;
}
@ -454,9 +449,6 @@ nmi_hard_msiiep(void)
if (si & MSIIEP_SYS_IPR_PIO_ERR) {
uint32_t pio_err_addr = mspcic_read_4(pcic_pio_err_addr);
if (byteswap)
pio_err_addr = bswap32(pio_err_addr);
printf("pio: addr=%08x, cmd=%x\n",
pio_err_addr, mspcic_read_1(pcic_pio_err_cmd));
fatal = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.217 2005/09/10 01:27:54 uwe Exp $ */
/* $NetBSD: locore.s,v 1.218 2005/09/24 22:30:15 macallan Exp $ */
/*
* Copyright (c) 1996 Paul Kranenburg
@ -2628,19 +2628,20 @@ _ENTRY(_C_LABEL(sparc_interrupt4m))
#else /* MSIIEP */
sethi %hi(MSIIEP_PCIC_VA), %l6
mov 1, %l4
xor %l3, 0x18, %l7 ! change endianness of the resulting bit mask
ld [%l6 + PCIC_PROC_IPR_REG], %l5 ! get pending interrupts
sll %l4, %l3, %l4 ! hw intr bits are in the lower halfword
sll %l4, %l7, %l4 ! hw intr bits are in the upper halfword
! because the register is little-endian
btst %l4, %l5 ! has pending hw intr at this level?
bnz sparc_interrupt_common
nop
srl %l4, 16, %l4 ! move the mask bit into the lower 16 bit
! so we can use it to clear a sw interrupt
#ifdef DIAGNOSTIC
! softint pending bits are in the upper halfword, but softint
! clear bits are in the lower halfword so we want the bit in %l4
! kept in the lower half and instead shift pending bits right
srl %l5, 16, %l7
btst %l4, %l7 ! make sure softint pending bit is set
! check if there's really a sw interrupt pending
btst %l4, %l5 ! make sure softint pending bit is set
bnz softintr_common
sth %l4, [%l6 + PCIC_SOFT_INTR_CLEAR_REG]
/* FALLTHROUGH to sparc_interrupt4m_bogus */
@ -3207,10 +3208,10 @@ nmi_sun4m:
* Level 15 interrupts are nonmaskable, so with traps off,
* disable all interrupts to prevent recursion.
*/
set MSIIEP_SYS_ITMR_ALL, %l4
mov 0x80, %l4 ! htole32(MSIIEP_SYS_ITMR_ALL)
st %l4, [%l6 + PCIC_SYS_ITMR_SET_REG]
set (1 << 15), %l4
set (1 << 23), %l4 ! htole32(1 << 15)
btst %l4, %l5 ! has pending level 15 hw intr?
bz 1f
nop
@ -3221,6 +3222,7 @@ nmi_sun4m:
or %o3, %lo(_C_LABEL(nmi_hard_msiiep)), %o3
1: /* soft level 15 interrupt */
set (1 << 7), %l4 ! htole16(1 << 15)
sth %l4, [%l6 + PCIC_SOFT_INTR_CLEAR_REG]
set _C_LABEL(nmi_soft_msiiep), %o3
2:
@ -3250,7 +3252,7 @@ nmi_sun4m:
! enable interrupts again (safe, we disabled traps again above)
sethi %hi(MSIIEP_PCIC_VA), %o0
set MSIIEP_SYS_ITMR_ALL, %o1
mov 0x80, %o1 ! htole32(MSIIEP_SYS_ITMR_ALL)
st %o1, [%o0 + PCIC_SYS_ITMR_CLR_REG]
b return_from_trap
@ -6406,6 +6408,7 @@ ENTRY(raise)
st %o2, [%o1]
#else /* MSIIEP - ignore %o0, only one CPU ever */
mov 1, %o2
xor %o1, 8, %o1 ! change 'endianness' of the shift distance
sethi %hi(MSIIEP_PCIC_VA), %o0
sll %o2, %o1, %o2
retl
@ -6600,22 +6603,38 @@ ENTRY(microtime)
2:
ldd [%g2+%lo(_C_LABEL(time))], %o2 ! time.tv_sec & time.tv_usec
ld [%g3], %o4 ! system (timer) counter
ld [%g3], %o4 ! system (timer) counter, little endian
ldd [%g2+%lo(_C_LABEL(time))], %g4 ! see if time values changed
cmp %g4, %o2
bne 2b ! if time.tv_sec changed
cmp %g5, %o3
bne 2b ! if time.tv_usec changed
tst %o4
btst 0x80, %o4 ! test overflow flag, LE
!! %o2 - time.tv_sec; %o3 - time.tv_usec; %o4 - timer counter
!!! BEGIN ms-IIep specific code
bpos 3f ! if limit not reached yet
bz 3f ! if limit not reached yet
clr %g4 ! then use timer as is
! now we're sure we need the timer value so let's endian-swap it
! %o4 = le32toh(%o4)
! since we're going to overwrite %g4 anyway we can use it
! for intermediate values here
mov %o4, %o2
set 0xff00ff, %g4
sll %o4, 16, %o4 ! first swap the upper and lower 16 bit
srl %o2, 16, %o2
or %o2, %o4, %o4 ! result in %o4
and %o4, %g4, %o2 ! now grab byte 0 and 2
andn %o4, %g4, %o4 ! %o4 now contains byte 1 and 3
srl %o4, 8, %o4 ! shift them so they swap positions
sll %o2, 8, %o2
or %o2, %o4, %o4 ! put them back together.
set 0x80000000, %g5
sethi %hi(_C_LABEL(tick)), %g4
bclr %g5, %o4 ! cleat limit reached flag
bclr %g5, %o4 ! clear limit reached flag
ld [%g4+%lo(_C_LABEL(tick))], %g4
!! %g4 - either 0 or tick (if timer has hit the limit)

View File

@ -1,4 +1,4 @@
/* $NetBSD: msiiep.c,v 1.27 2005/09/24 00:49:23 uwe Exp $ */
/* $NetBSD: msiiep.c,v 1.28 2005/09/24 22:30:15 macallan Exp $ */
/*
* Copyright (c) 2001 Valeriy E. Ushakov
@ -27,7 +27,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msiiep.c,v 1.27 2005/09/24 00:49:23 uwe Exp $");
__KERNEL_RCSID(0, "$NetBSD: msiiep.c,v 1.28 2005/09/24 22:30:15 macallan Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
@ -167,8 +167,18 @@ static struct sparc_bus_dma_tag mspcic_dma_tag = {
_bus_dmamem_mmap
};
static uint16_t mspcic_bus_read_2(bus_space_tag_t, bus_space_handle_t,
bus_size_t);
static uint32_t mspcic_bus_read_4(bus_space_tag_t, bus_space_handle_t,
bus_size_t);
static uint64_t mspcic_bus_read_8(bus_space_tag_t, bus_space_handle_t,
bus_size_t);
static void mspcic_bus_write_2(bus_space_tag_t, bus_space_handle_t,
bus_size_t, uint16_t);
static void mspcic_bus_write_4(bus_space_tag_t, bus_space_handle_t,
bus_size_t, uint32_t);
static void mspcic_bus_write_8(bus_space_tag_t, bus_space_handle_t,
bus_size_t, uint64_t);
static int
@ -184,8 +194,7 @@ msiiep_match(struct device *parent, struct cfdata *cf, void *aux)
/*
* Verify that PCIC was successfully mapped by bootstrap code.
* Since PCIC contains all the registers vital to the kernel,
* bootstrap code maps them at a fixed va, MSIIEP_PCIC_VA, and
* switches the endian-swapping mode on.
* bootstrap code maps them at a fixed va, MSIIEP_PCIC_VA
*/
id = mspcic_read_4(pcic_id);
if (PCI_VENDOR(id) != PCI_VENDOR_SUN
@ -201,7 +210,10 @@ msiiep_attach(struct device *parent, struct device *self, void *aux)
{
struct mainbus_attach_args *ma = aux;
struct msiiep_attach_args msa;
bus_space_handle_t hmid;
struct cpu_info *cur;
uint32_t mid;
aprint_normal("\n");
/* pass on real mainbus_attach_args */
@ -245,6 +257,56 @@ msiiep_swap_endian(int on)
*
* Real ms-IIep PCIC driver.
*/
static uint16_t
mspcic_bus_read_2(bus_space_tag_t space, bus_space_handle_t handle,
bus_size_t offset)
{
uint16_t val = *(volatile uint16_t *)(handle + offset);
return le16toh(val);
}
static uint32_t
mspcic_bus_read_4(bus_space_tag_t space, bus_space_handle_t handle,
bus_size_t offset)
{
uint32_t val = *(volatile uint32_t *)(handle + offset);
return le32toh(val);
}
static uint64_t
mspcic_bus_read_8(bus_space_tag_t space, bus_space_handle_t handle,
bus_size_t offset)
{
uint64_t val = *(volatile uint64_t *)(handle + offset);
return le64toh(val);
}
static void
mspcic_bus_write_2(bus_space_tag_t space, bus_space_handle_t handle,
bus_size_t offset, uint16_t value)
{
(*(volatile uint16_t *)(handle + offset)) = htole16(value);
}
static void
mspcic_bus_write_4(bus_space_tag_t space, bus_space_handle_t handle,
bus_size_t offset, uint32_t value)
{
(*(volatile uint32_t *)(handle + offset)) = htole32(value);
}
static void
mspcic_bus_write_8(bus_space_tag_t space, bus_space_handle_t handle,
bus_size_t offset, uint64_t value)
{
(*(volatile uint64_t *)(handle + offset)) = htole64(value);
}
static int
mspcic_match(struct device *parent, struct cfdata *cf, void *aux)
@ -289,6 +351,13 @@ mspcic_attach(struct device *parent, struct device *self, void *aux)
mspcic_io_tag.sparc_bus_mmap = mspcic_bus_mmap;
mspcic_io_tag.sparc_intr_establish = mspcic_intr_establish;
mspcic_io_tag.parent = sc->sc_bustag;
mspcic_io_tag.sparc_read_2 = mspcic_bus_read_2;
mspcic_io_tag.sparc_read_4 = mspcic_bus_read_4;
mspcic_io_tag.sparc_read_8 = mspcic_bus_read_8;
mspcic_io_tag.sparc_write_2 = mspcic_bus_write_2;
mspcic_io_tag.sparc_write_4 = mspcic_bus_write_4;
mspcic_io_tag.sparc_write_8 = mspcic_bus_write_8;
mspcic_mem_tag = *sc->sc_bustag;
mspcic_mem_tag.cookie = &mspcic_mem_cookie;
@ -299,6 +368,13 @@ mspcic_attach(struct device *parent, struct device *self, void *aux)
mspcic_mem_tag.sparc_intr_establish = mspcic_intr_establish;
mspcic_mem_tag.parent = sc->sc_bustag;
mspcic_mem_tag.sparc_read_2 = mspcic_bus_read_2;
mspcic_mem_tag.sparc_read_4 = mspcic_bus_read_4;
mspcic_mem_tag.sparc_read_8 = mspcic_bus_read_8;
mspcic_mem_tag.sparc_write_2 = mspcic_bus_write_2;
mspcic_mem_tag.sparc_write_4 = mspcic_bus_write_4;
mspcic_mem_tag.sparc_write_8 = mspcic_bus_write_8;
mspcic_dma_tag._cookie = sc;
mspcic_pc_tag.cookie = sc;
@ -401,7 +477,7 @@ mspcic_init_maps(void)
mspcic_read_1(pcic_iosize));
#endif
nmem = nio = 1;
m0 = &mspcic_pci_memmap[nmem];
mspcic_pci_map_from_reg(m0,
mspcic_read_1(pcic_smbar0), mspcic_read_1(pcic_pmbar0),

View File

@ -1,4 +1,4 @@
/* $NetBSD: msiiepreg.h,v 1.5 2005/09/24 00:12:20 uwe Exp $ */
/* $NetBSD: msiiepreg.h,v 1.6 2005/09/24 22:30:15 macallan Exp $ */
/*
* Copyright (c) 2001 Valeriy E. Ushakov
@ -49,6 +49,11 @@
*/
#define MSIIEP_PCIC_PA ((paddr_t)0x300c0000)
#define MSIIEP_MID_PA ((paddr_t)0x10002000)
#define MID_IOA_ENABLE 0x10000 /* IO arbitration */
#define MID_STANDBY 0x0800 /* put CPU into power saving mode */
#define MID_MASK 0x000108fc /* bits masked out are reserved */
struct msiiep_pcic_reg {
/* PCI_ID_REG */
@ -226,19 +231,20 @@ struct msiiep_pcic_reg {
};
/* XXX: these are temporary hacks to for the conversion of the sources */
#define mspcic_read_1(reg) \
(((volatile struct msiiep_pcic_reg *)MSIIEP_PCIC_VA)->reg)
#define mspcic_read_2(reg) \
(((volatile struct msiiep_pcic_reg *)MSIIEP_PCIC_VA)->reg)
(le16toh(((volatile struct msiiep_pcic_reg *)MSIIEP_PCIC_VA)->reg))
#define mspcic_read_4(reg) \
(((volatile struct msiiep_pcic_reg *)MSIIEP_PCIC_VA)->reg)
(le32toh(((volatile struct msiiep_pcic_reg *)MSIIEP_PCIC_VA)->reg))
#define mspcic_write_1(reg, val) \
(((volatile struct msiiep_pcic_reg *)MSIIEP_PCIC_VA)->reg) = (val)
#define mspcic_write_2(reg, val) \
(((volatile struct msiiep_pcic_reg *)MSIIEP_PCIC_VA)->reg) = (val)
(((volatile struct msiiep_pcic_reg *)MSIIEP_PCIC_VA)->reg) = (htole16(val))
#define mspcic_write_4(reg, val) \
(((volatile struct msiiep_pcic_reg *)MSIIEP_PCIC_VA)->reg) = (val)
(((volatile struct msiiep_pcic_reg *)MSIIEP_PCIC_VA)->reg) = (htole32(val))
#endif /* _SPARC_MSIIEP_REG_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: openfirm.c,v 1.10 2005/05/31 00:54:57 christos Exp $ */
/* $NetBSD: openfirm.c,v 1.11 2005/09/24 22:30:15 macallan Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: openfirm.c,v 1.10 2005/05/31 00:54:57 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: openfirm.c,v 1.11 2005/09/24 22:30:15 macallan Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -583,13 +583,7 @@ OF_enter(void)
args.name = ADR2CELL("enter");
args.nargs = 0;
args.nreturns = 0;
#if defined(MSIIEP)
msiiep_swap_endian(0);
#endif
openfirmware(&args);
#if defined(MSIIEP)
msiiep_swap_endian(1);
#endif
}
void
@ -604,13 +598,7 @@ OF_exit(void)
args.name = ADR2CELL("exit");
args.nargs = 0;
args.nreturns = 0;
#if defined(MSIIEP)
msiiep_swap_endian(0);
#endif
openfirmware(&args);
#if defined(MSIIEP)
msiiep_swap_endian(1);
#endif
panic("OF_exit failed");
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pci_machdep.c,v 1.10 2005/09/24 01:07:25 uwe Exp $ */
/* $NetBSD: pci_machdep.c,v 1.11 2005/09/24 22:30:15 macallan Exp $ */
/*
* Copyright (c) 1999, 2000 Matthew R. Green
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.10 2005/09/24 01:07:25 uwe Exp $");
__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.11 2005/09/24 22:30:15 macallan Exp $");
#if defined(DEBUG) && !defined(SPARC_PCI_DEBUG)
#define SPARC_PCI_DEBUG
@ -305,12 +305,8 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
mode1_data_reg_pa = PCI_MODE1_DATA_REG_PA
| (reg & PCI_MODE1_DATA_REG_MASK);
/*
* NB: we run in endian-swapping mode, so we don't need to
* convert mode1_addr and val.
*/
sta(PCI_MODE1_ADDRESS_REG_PA, ASI_BYPASS, mode1_addr);
val = lda(mode1_data_reg_pa, ASI_BYPASS);
sta(PCI_MODE1_ADDRESS_REG_PA, ASI_BYPASS, htole32(mode1_addr));
val = le32toh(lda(mode1_data_reg_pa, ASI_BYPASS));
DPRINTF(SPDB_CONF, ("reading %08x\n", val));
@ -348,12 +344,8 @@ pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
DPRINTF(SPDB_CONF, ("writing %08x\n", data));
/*
* NB: we run in endian-swapping mode, so we don't need to
* convert mode1_addr and data.
*/
sta(PCI_MODE1_ADDRESS_REG_PA, ASI_BYPASS, mode1_addr);
sta(mode1_data_reg_pa, ASI_BYPASS, data);
sta(PCI_MODE1_ADDRESS_REG_PA, ASI_BYPASS, htole32(mode1_addr));
sta(mode1_data_reg_pa, ASI_BYPASS, htole32(data));
}