From ea0e38f6bc1e458b34b11b40c1092036db34f548 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 27 Apr 2011 09:43:00 -0700 Subject: Re-org for Clipper system. --- Makefile | 23 +++-- cia.h | 268 ------------------------------------------------- core-cia.h | 251 ++++++++++++++++++++++++++++++++++++++++++++++ core-typhoon.h | 163 ++++++++++++++++++++++++++++++ init.c | 28 ++++-- io.h | 18 ---- osf.h | 1 + pal.S | 312 ++++++++++++++++++--------------------------------------- pal.h | 134 +++++++++++++++++++++++++ protos.h | 42 ++++++++ sys-clipper.S | 90 +++++++++++++++++ sys-clipper.h | 10 ++ sys-sx164.h | 25 +++++ uart.c | 2 +- 14 files changed, 847 insertions(+), 520 deletions(-) delete mode 100644 cia.h create mode 100644 core-cia.h create mode 100644 core-typhoon.h delete mode 100644 io.h create mode 100644 pal.h create mode 100644 protos.h create mode 100644 sys-clipper.S create mode 100644 sys-clipper.h create mode 100644 sys-sx164.h diff --git a/Makefile b/Makefile index ea2eac2..f62888f 100644 --- a/Makefile +++ b/Makefile @@ -2,25 +2,28 @@ CROSS = alphaev67-linux- CC = $(CROSS)gcc LD = $(CROSS)ld +CORE = typhoon +SYSTEM = clipper + +ASFLAGS = -Wa,-m21264 -Wa,--noexecstack CFLAGS = -Os -g -Wall -fvisibility=hidden -fno-strict-aliasing \ -msmall-text -msmall-data -mno-fp-regs -mbuild-constants +CPPFLAGS = -DSYSTEM_H='"sys-$(SYSTEM).h"' -CFLAGS += -mcpu=pca56 +CFLAGS += -mcpu=ev67 -OBJS = pal.o init.o uart.o memset.o printf.o +OBJS = pal.o sys-$(SYSTEM).o init.o uart.o memset.o printf.o -all: palcode-sx164 +all: palcode-$(SYSTEM) -palcode-sx164: palcode.ld $(OBJS) +palcode-$(SYSTEM): palcode.ld $(OBJS) $(LD) -relax -o $@ -T palcode.ld -Map $@.map $(OBJS) clean: rm -f *.o - rm -f palcode palcode.map - -pal.o: pal.S osf.h uart.h - $(CC) $(CFLAGS) -c -Wa,-m21264 -Wa,--noexecstack -o $@ $< + rm -f palcode-* -init.o: init.c hwrpb.h osf.h uart.h +pal.o: pal.S osf.h sys-$(SYSTEM).h core-$(CORE).h +init.o: init.c hwrpb.h osf.h uart.h sys-$(SYSTEM).h core-$(CORE).h printf.o: printf.c uart.h -uart.o: uart.c uart.h io.h cia.h +uart.o: uart.c uart.h protos.h diff --git a/cia.h b/cia.h deleted file mode 100644 index cea81b6..0000000 --- a/cia.h +++ /dev/null @@ -1,268 +0,0 @@ -#ifndef __ALPHA_CIA__H__ -#define __ALPHA_CIA__H__ - -#define IDENT_ADDR 0xfffffc0000000000UL - -/* - * CIA is the internal name for the 21171 chipset which provides - * memory controller and PCI access for the 21164 chip based systems. - * Also supported here is the 21172 (CIA-2) and 21174 (PYXIS). - * - * The lineage is a bit confused, since the 21174 was reportedly started - * from the 21171 Pass 1 mask, and so is missing bug fixes that appear - * in 21171 Pass 2 and 21172, but it also contains additional features. - * - * This file is based on: - * - * DECchip 21171 Core Logic Chipset - * Technical Reference Manual - * - * EC-QE18B-TE - * - * david.rusling@reo.mts.dec.com Initial Version. - * - */ - -/* - * CIA ADDRESS BIT DEFINITIONS - * - * 3333 3333 3322 2222 2222 1111 1111 11 - * 9876 5432 1098 7654 3210 9876 5432 1098 7654 3210 - * ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- - * 1 000 - * ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- - * | |\| - * | Byte Enable --+ | - * | Transfer Length --+ - * +-- IO space, not cached - * - * Byte Transfer - * Enable Length Transfer Byte Address - * adr<6:5> adr<4:3> Length Enable Adder - * --------------------------------------------- - * 00 00 Byte 1110 0x000 - * 01 00 Byte 1101 0x020 - * 10 00 Byte 1011 0x040 - * 11 00 Byte 0111 0x060 - * - * 00 01 Word 1100 0x008 - * 01 01 Word 1001 0x028 <= Not supported in this code. - * 10 01 Word 0011 0x048 - * - * 00 10 Tribyte 1000 0x010 - * 01 10 Tribyte 0001 0x030 - * - * 10 11 Longword 0000 0x058 - * - * Note that byte enables are asserted low. - * - */ - -#define CIA_MEM_R1_MASK 0x1fffffff /* SPARSE Mem region 1 mask is 29 bits */ -#define CIA_MEM_R2_MASK 0x07ffffff /* SPARSE Mem region 2 mask is 27 bits */ -#define CIA_MEM_R3_MASK 0x03ffffff /* SPARSE Mem region 3 mask is 26 bits */ - -/* - * 21171-CA Control and Status Registers - */ -#define CIA_IOC_CIA_REV (IDENT_ADDR + 0x8740000080UL) -# define CIA_REV_MASK 0xff -#define CIA_IOC_PCI_LAT (IDENT_ADDR + 0x87400000C0UL) -#define CIA_IOC_CIA_CTRL (IDENT_ADDR + 0x8740000100UL) -# define CIA_CTRL_PCI_EN (1 << 0) -# define CIA_CTRL_PCI_LOCK_EN (1 << 1) -# define CIA_CTRL_PCI_LOOP_EN (1 << 2) -# define CIA_CTRL_FST_BB_EN (1 << 3) -# define CIA_CTRL_PCI_MST_EN (1 << 4) -# define CIA_CTRL_PCI_MEM_EN (1 << 5) -# define CIA_CTRL_PCI_REQ64_EN (1 << 6) -# define CIA_CTRL_PCI_ACK64_EN (1 << 7) -# define CIA_CTRL_ADDR_PE_EN (1 << 8) -# define CIA_CTRL_PERR_EN (1 << 9) -# define CIA_CTRL_FILL_ERR_EN (1 << 10) -# define CIA_CTRL_MCHK_ERR_EN (1 << 11) -# define CIA_CTRL_ECC_CHK_EN (1 << 12) -# define CIA_CTRL_ASSERT_IDLE_BC (1 << 13) -# define CIA_CTRL_COM_IDLE_BC (1 << 14) -# define CIA_CTRL_CSR_IOA_BYPASS (1 << 15) -# define CIA_CTRL_IO_FLUSHREQ_EN (1 << 16) -# define CIA_CTRL_CPU_FLUSHREQ_EN (1 << 17) -# define CIA_CTRL_ARB_CPU_EN (1 << 18) -# define CIA_CTRL_EN_ARB_LINK (1 << 19) -# define CIA_CTRL_RD_TYPE_SHIFT 20 -# define CIA_CTRL_RL_TYPE_SHIFT 24 -# define CIA_CTRL_RM_TYPE_SHIFT 28 -# define CIA_CTRL_EN_DMA_RD_PERF (1 << 31) -#define CIA_IOC_CIA_CNFG (IDENT_ADDR + 0x8740000140UL) -# define CIA_CNFG_IOA_BWEN (1 << 0) -# define CIA_CNFG_PCI_MWEN (1 << 4) -# define CIA_CNFG_PCI_DWEN (1 << 5) -# define CIA_CNFG_PCI_WLEN (1 << 8) -#define CIA_IOC_FLASH_CTRL (IDENT_ADDR + 0x8740000200UL) -#define CIA_IOC_HAE_MEM (IDENT_ADDR + 0x8740000400UL) -#define CIA_IOC_HAE_IO (IDENT_ADDR + 0x8740000440UL) -#define CIA_IOC_CFG (IDENT_ADDR + 0x8740000480UL) -#define CIA_IOC_CACK_EN (IDENT_ADDR + 0x8740000600UL) -# define CIA_CACK_EN_LOCK_EN (1 << 0) -# define CIA_CACK_EN_MB_EN (1 << 1) -# define CIA_CACK_EN_SET_DIRTY_EN (1 << 2) -# define CIA_CACK_EN_BC_VICTIM_EN (1 << 3) - - -/* - * 21171-CA Diagnostic Registers - */ -#define CIA_IOC_CIA_DIAG (IDENT_ADDR + 0x8740002000UL) -#define CIA_IOC_DIAG_CHECK (IDENT_ADDR + 0x8740003000UL) - -/* - * 21171-CA Performance Monitor registers - */ -#define CIA_IOC_PERF_MONITOR (IDENT_ADDR + 0x8740004000UL) -#define CIA_IOC_PERF_CONTROL (IDENT_ADDR + 0x8740004040UL) - -/* - * 21171-CA Error registers - */ -#define CIA_IOC_CPU_ERR0 (IDENT_ADDR + 0x8740008000UL) -#define CIA_IOC_CPU_ERR1 (IDENT_ADDR + 0x8740008040UL) -#define CIA_IOC_CIA_ERR (IDENT_ADDR + 0x8740008200UL) -# define CIA_ERR_COR_ERR (1 << 0) -# define CIA_ERR_UN_COR_ERR (1 << 1) -# define CIA_ERR_CPU_PE (1 << 2) -# define CIA_ERR_MEM_NEM (1 << 3) -# define CIA_ERR_PCI_SERR (1 << 4) -# define CIA_ERR_PERR (1 << 5) -# define CIA_ERR_PCI_ADDR_PE (1 << 6) -# define CIA_ERR_RCVD_MAS_ABT (1 << 7) -# define CIA_ERR_RCVD_TAR_ABT (1 << 8) -# define CIA_ERR_PA_PTE_INV (1 << 9) -# define CIA_ERR_FROM_WRT_ERR (1 << 10) -# define CIA_ERR_IOA_TIMEOUT (1 << 11) -# define CIA_ERR_LOST_CORR_ERR (1 << 16) -# define CIA_ERR_LOST_UN_CORR_ERR (1 << 17) -# define CIA_ERR_LOST_CPU_PE (1 << 18) -# define CIA_ERR_LOST_MEM_NEM (1 << 19) -# define CIA_ERR_LOST_PERR (1 << 21) -# define CIA_ERR_LOST_PCI_ADDR_PE (1 << 22) -# define CIA_ERR_LOST_RCVD_MAS_ABT (1 << 23) -# define CIA_ERR_LOST_RCVD_TAR_ABT (1 << 24) -# define CIA_ERR_LOST_PA_PTE_INV (1 << 25) -# define CIA_ERR_LOST_FROM_WRT_ERR (1 << 26) -# define CIA_ERR_LOST_IOA_TIMEOUT (1 << 27) -# define CIA_ERR_VALID (1 << 31) -#define CIA_IOC_CIA_STAT (IDENT_ADDR + 0x8740008240UL) -#define CIA_IOC_ERR_MASK (IDENT_ADDR + 0x8740008280UL) -#define CIA_IOC_CIA_SYN (IDENT_ADDR + 0x8740008300UL) -#define CIA_IOC_MEM_ERR0 (IDENT_ADDR + 0x8740008400UL) -#define CIA_IOC_MEM_ERR1 (IDENT_ADDR + 0x8740008440UL) -#define CIA_IOC_PCI_ERR0 (IDENT_ADDR + 0x8740008800UL) -#define CIA_IOC_PCI_ERR1 (IDENT_ADDR + 0x8740008840UL) -#define CIA_IOC_PCI_ERR3 (IDENT_ADDR + 0x8740008880UL) - -/* - * 21171-CA System configuration registers - */ -#define CIA_IOC_MCR (IDENT_ADDR + 0x8750000000UL) -#define CIA_IOC_MBA0 (IDENT_ADDR + 0x8750000600UL) -#define CIA_IOC_MBA2 (IDENT_ADDR + 0x8750000680UL) -#define CIA_IOC_MBA4 (IDENT_ADDR + 0x8750000700UL) -#define CIA_IOC_MBA6 (IDENT_ADDR + 0x8750000780UL) -#define CIA_IOC_MBA8 (IDENT_ADDR + 0x8750000800UL) -#define CIA_IOC_MBAA (IDENT_ADDR + 0x8750000880UL) -#define CIA_IOC_MBAC (IDENT_ADDR + 0x8750000900UL) -#define CIA_IOC_MBAE (IDENT_ADDR + 0x8750000980UL) -#define CIA_IOC_TMG0 (IDENT_ADDR + 0x8750000B00UL) -#define CIA_IOC_TMG1 (IDENT_ADDR + 0x8750000B40UL) -#define CIA_IOC_TMG2 (IDENT_ADDR + 0x8750000B80UL) - -/* - * 2117A-CA PCI Address and Scatter-Gather Registers. - */ -#define CIA_IOC_PCI_TBIA (IDENT_ADDR + 0x8760000100UL) - -#define CIA_IOC_PCI_W0_BASE (IDENT_ADDR + 0x8760000400UL) -#define CIA_IOC_PCI_W0_MASK (IDENT_ADDR + 0x8760000440UL) -#define CIA_IOC_PCI_T0_BASE (IDENT_ADDR + 0x8760000480UL) - -#define CIA_IOC_PCI_W1_BASE (IDENT_ADDR + 0x8760000500UL) -#define CIA_IOC_PCI_W1_MASK (IDENT_ADDR + 0x8760000540UL) -#define CIA_IOC_PCI_T1_BASE (IDENT_ADDR + 0x8760000580UL) - -#define CIA_IOC_PCI_W2_BASE (IDENT_ADDR + 0x8760000600UL) -#define CIA_IOC_PCI_W2_MASK (IDENT_ADDR + 0x8760000640UL) -#define CIA_IOC_PCI_T2_BASE (IDENT_ADDR + 0x8760000680UL) - -#define CIA_IOC_PCI_W3_BASE (IDENT_ADDR + 0x8760000700UL) -#define CIA_IOC_PCI_W3_MASK (IDENT_ADDR + 0x8760000740UL) -#define CIA_IOC_PCI_T3_BASE (IDENT_ADDR + 0x8760000780UL) - -#define CIA_IOC_PCI_Wn_BASE(N) (IDENT_ADDR + 0x8760000400UL + (N)*0x100) -#define CIA_IOC_PCI_Wn_MASK(N) (IDENT_ADDR + 0x8760000440UL + (N)*0x100) -#define CIA_IOC_PCI_Tn_BASE(N) (IDENT_ADDR + 0x8760000480UL + (N)*0x100) - -#define CIA_IOC_PCI_W_DAC (IDENT_ADDR + 0x87600007C0UL) - -/* - * 2117A-CA Address Translation Registers. - */ - -/* 8 tag registers, the first 4 of which are lockable. */ -#define CIA_IOC_TB_TAGn(n) \ - (IDENT_ADDR + 0x8760000800UL + (n)*0x40) - -/* 4 page registers per tag register. */ -#define CIA_IOC_TBn_PAGEm(n,m) \ - (IDENT_ADDR + 0x8760001000UL + (n)*0x100 + (m)*0x40) - -/* - * Memory spaces: - */ -#define CIA_IACK_SC (IDENT_ADDR + 0x8720000000UL) -#define CIA_CONF (IDENT_ADDR + 0x8700000000UL) -#define CIA_IO (IDENT_ADDR + 0x8580000000UL) -#define CIA_SPARSE_MEM (IDENT_ADDR + 0x8000000000UL) -#define CIA_SPARSE_MEM_R2 (IDENT_ADDR + 0x8400000000UL) -#define CIA_SPARSE_MEM_R3 (IDENT_ADDR + 0x8500000000UL) -#define CIA_DENSE_MEM (IDENT_ADDR + 0x8600000000UL) -#define CIA_BW_MEM (IDENT_ADDR + 0x8800000000UL) -#define CIA_BW_IO (IDENT_ADDR + 0x8900000000UL) -#define CIA_BW_CFG_0 (IDENT_ADDR + 0x8a00000000UL) -#define CIA_BW_CFG_1 (IDENT_ADDR + 0x8b00000000UL) - -/* - * ALCOR's GRU ASIC registers - */ -#define GRU_INT_REQ (IDENT_ADDR + 0x8780000000UL) -#define GRU_INT_MASK (IDENT_ADDR + 0x8780000040UL) -#define GRU_INT_EDGE (IDENT_ADDR + 0x8780000080UL) -#define GRU_INT_HILO (IDENT_ADDR + 0x87800000C0UL) -#define GRU_INT_CLEAR (IDENT_ADDR + 0x8780000100UL) - -#define GRU_CACHE_CNFG (IDENT_ADDR + 0x8780000200UL) -#define GRU_SCR (IDENT_ADDR + 0x8780000300UL) -#define GRU_LED (IDENT_ADDR + 0x8780000800UL) -#define GRU_RESET (IDENT_ADDR + 0x8780000900UL) - -#define ALCOR_GRU_INT_REQ_BITS 0x800fffffUL -#define XLT_GRU_INT_REQ_BITS 0x80003fffUL -#define GRU_INT_REQ_BITS (alpha_mv.sys.cia.gru_int_req_bits+0) - -/* - * PYXIS interrupt control registers - */ -#define PYXIS_INT_REQ (IDENT_ADDR + 0x87A0000000UL) -#define PYXIS_INT_MASK (IDENT_ADDR + 0x87A0000040UL) -#define PYXIS_INT_HILO (IDENT_ADDR + 0x87A00000C0UL) -#define PYXIS_INT_ROUTE (IDENT_ADDR + 0x87A0000140UL) -#define PYXIS_GPO (IDENT_ADDR + 0x87A0000180UL) -#define PYXIS_INT_CNFG (IDENT_ADDR + 0x87A00001C0UL) -#define PYXIS_RT_COUNT (IDENT_ADDR + 0x87A0000200UL) -#define PYXIS_INT_TIME (IDENT_ADDR + 0x87A0000240UL) -#define PYXIS_IIC_CTRL (IDENT_ADDR + 0x87A00002C0UL) -#define PYXIS_RESET (IDENT_ADDR + 0x8780000900UL) - -/* Offset between ram physical addresses and pci64 DAC bus addresses. */ -#define PYXIS_DAC_OFFSET (1UL << 40) - -#endif /* __ALPHA_CIA__H__ */ diff --git a/core-cia.h b/core-cia.h new file mode 100644 index 0000000..a42cea0 --- /dev/null +++ b/core-cia.h @@ -0,0 +1,251 @@ +#ifndef CIA_H +#define CIA_H + +#define IDENT_ADDR 0xfffffc0000000000UL + +#define CIA_MEM_R1_MASK 0x1fffffff /* SPARSE Mem region 1 mask is 29 bits */ +#define CIA_MEM_R2_MASK 0x07ffffff /* SPARSE Mem region 2 mask is 27 bits */ +#define CIA_MEM_R3_MASK 0x03ffffff /* SPARSE Mem region 3 mask is 26 bits */ + +/* + * 21171-CA Control and Status Registers + */ +#define CIA_IOC_CIA_REV (IDENT_ADDR + 0x8740000080UL) +# define CIA_REV_MASK 0xff +#define CIA_IOC_PCI_LAT (IDENT_ADDR + 0x87400000C0UL) +#define CIA_IOC_CIA_CTRL (IDENT_ADDR + 0x8740000100UL) +# define CIA_CTRL_PCI_EN (1 << 0) +# define CIA_CTRL_PCI_LOCK_EN (1 << 1) +# define CIA_CTRL_PCI_LOOP_EN (1 << 2) +# define CIA_CTRL_FST_BB_EN (1 << 3) +# define CIA_CTRL_PCI_MST_EN (1 << 4) +# define CIA_CTRL_PCI_MEM_EN (1 << 5) +# define CIA_CTRL_PCI_REQ64_EN (1 << 6) +# define CIA_CTRL_PCI_ACK64_EN (1 << 7) +# define CIA_CTRL_ADDR_PE_EN (1 << 8) +# define CIA_CTRL_PERR_EN (1 << 9) +# define CIA_CTRL_FILL_ERR_EN (1 << 10) +# define CIA_CTRL_MCHK_ERR_EN (1 << 11) +# define CIA_CTRL_ECC_CHK_EN (1 << 12) +# define CIA_CTRL_ASSERT_IDLE_BC (1 << 13) +# define CIA_CTRL_COM_IDLE_BC (1 << 14) +# define CIA_CTRL_CSR_IOA_BYPASS (1 << 15) +# define CIA_CTRL_IO_FLUSHREQ_EN (1 << 16) +# define CIA_CTRL_CPU_FLUSHREQ_EN (1 << 17) +# define CIA_CTRL_ARB_CPU_EN (1 << 18) +# define CIA_CTRL_EN_ARB_LINK (1 << 19) +# define CIA_CTRL_RD_TYPE_SHIFT 20 +# define CIA_CTRL_RL_TYPE_SHIFT 24 +# define CIA_CTRL_RM_TYPE_SHIFT 28 +# define CIA_CTRL_EN_DMA_RD_PERF (1 << 31) +#define CIA_IOC_CIA_CNFG (IDENT_ADDR + 0x8740000140UL) +# define CIA_CNFG_IOA_BWEN (1 << 0) +# define CIA_CNFG_PCI_MWEN (1 << 4) +# define CIA_CNFG_PCI_DWEN (1 << 5) +# define CIA_CNFG_PCI_WLEN (1 << 8) +#define CIA_IOC_FLASH_CTRL (IDENT_ADDR + 0x8740000200UL) +#define CIA_IOC_HAE_MEM (IDENT_ADDR + 0x8740000400UL) +#define CIA_IOC_HAE_IO (IDENT_ADDR + 0x8740000440UL) +#define CIA_IOC_CFG (IDENT_ADDR + 0x8740000480UL) +#define CIA_IOC_CACK_EN (IDENT_ADDR + 0x8740000600UL) +# define CIA_CACK_EN_LOCK_EN (1 << 0) +# define CIA_CACK_EN_MB_EN (1 << 1) +# define CIA_CACK_EN_SET_DIRTY_EN (1 << 2) +# define CIA_CACK_EN_BC_VICTIM_EN (1 << 3) + + +/* + * 21171-CA Diagnostic Registers + */ +#define CIA_IOC_CIA_DIAG (IDENT_ADDR + 0x8740002000UL) +#define CIA_IOC_DIAG_CHECK (IDENT_ADDR + 0x8740003000UL) + +/* + * 21171-CA Performance Monitor registers + */ +#define CIA_IOC_PERF_MONITOR (IDENT_ADDR + 0x8740004000UL) +#define CIA_IOC_PERF_CONTROL (IDENT_ADDR + 0x8740004040UL) + +/* + * 21171-CA Error registers + */ +#define CIA_IOC_CPU_ERR0 (IDENT_ADDR + 0x8740008000UL) +#define CIA_IOC_CPU_ERR1 (IDENT_ADDR + 0x8740008040UL) +#define CIA_IOC_CIA_ERR (IDENT_ADDR + 0x8740008200UL) +# define CIA_ERR_COR_ERR (1 << 0) +# define CIA_ERR_UN_COR_ERR (1 << 1) +# define CIA_ERR_CPU_PE (1 << 2) +# define CIA_ERR_MEM_NEM (1 << 3) +# define CIA_ERR_PCI_SERR (1 << 4) +# define CIA_ERR_PERR (1 << 5) +# define CIA_ERR_PCI_ADDR_PE (1 << 6) +# define CIA_ERR_RCVD_MAS_ABT (1 << 7) +# define CIA_ERR_RCVD_TAR_ABT (1 << 8) +# define CIA_ERR_PA_PTE_INV (1 << 9) +# define CIA_ERR_FROM_WRT_ERR (1 << 10) +# define CIA_ERR_IOA_TIMEOUT (1 << 11) +# define CIA_ERR_LOST_CORR_ERR (1 << 16) +# define CIA_ERR_LOST_UN_CORR_ERR (1 << 17) +# define CIA_ERR_LOST_CPU_PE (1 << 18) +# define CIA_ERR_LOST_MEM_NEM (1 << 19) +# define CIA_ERR_LOST_PERR (1 << 21) +# define CIA_ERR_LOST_PCI_ADDR_PE (1 << 22) +# define CIA_ERR_LOST_RCVD_MAS_ABT (1 << 23) +# define CIA_ERR_LOST_RCVD_TAR_ABT (1 << 24) +# define CIA_ERR_LOST_PA_PTE_INV (1 << 25) +# define CIA_ERR_LOST_FROM_WRT_ERR (1 << 26) +# define CIA_ERR_LOST_IOA_TIMEOUT (1 << 27) +# define CIA_ERR_VALID (1 << 31) +#define CIA_IOC_CIA_STAT (IDENT_ADDR + 0x8740008240UL) +#define CIA_IOC_ERR_MASK (IDENT_ADDR + 0x8740008280UL) +#define CIA_IOC_CIA_SYN (IDENT_ADDR + 0x8740008300UL) +#define CIA_IOC_MEM_ERR0 (IDENT_ADDR + 0x8740008400UL) +#define CIA_IOC_MEM_ERR1 (IDENT_ADDR + 0x8740008440UL) +#define CIA_IOC_PCI_ERR0 (IDENT_ADDR + 0x8740008800UL) +#define CIA_IOC_PCI_ERR1 (IDENT_ADDR + 0x8740008840UL) +#define CIA_IOC_PCI_ERR3 (IDENT_ADDR + 0x8740008880UL) + +/* + * 21171-CA System configuration registers + */ +#define CIA_IOC_MCR (IDENT_ADDR + 0x8750000000UL) +#define CIA_IOC_MBA0 (IDENT_ADDR + 0x8750000600UL) +#define CIA_IOC_MBA2 (IDENT_ADDR + 0x8750000680UL) +#define CIA_IOC_MBA4 (IDENT_ADDR + 0x8750000700UL) +#define CIA_IOC_MBA6 (IDENT_ADDR + 0x8750000780UL) +#define CIA_IOC_MBA8 (IDENT_ADDR + 0x8750000800UL) +#define CIA_IOC_MBAA (IDENT_ADDR + 0x8750000880UL) +#define CIA_IOC_MBAC (IDENT_ADDR + 0x8750000900UL) +#define CIA_IOC_MBAE (IDENT_ADDR + 0x8750000980UL) +#define CIA_IOC_TMG0 (IDENT_ADDR + 0x8750000B00UL) +#define CIA_IOC_TMG1 (IDENT_ADDR + 0x8750000B40UL) +#define CIA_IOC_TMG2 (IDENT_ADDR + 0x8750000B80UL) + +/* + * 2117A-CA PCI Address and Scatter-Gather Registers. + */ +#define CIA_IOC_PCI_TBIA (IDENT_ADDR + 0x8760000100UL) + +#define CIA_IOC_PCI_W0_BASE (IDENT_ADDR + 0x8760000400UL) +#define CIA_IOC_PCI_W0_MASK (IDENT_ADDR + 0x8760000440UL) +#define CIA_IOC_PCI_T0_BASE (IDENT_ADDR + 0x8760000480UL) + +#define CIA_IOC_PCI_W1_BASE (IDENT_ADDR + 0x8760000500UL) +#define CIA_IOC_PCI_W1_MASK (IDENT_ADDR + 0x8760000540UL) +#define CIA_IOC_PCI_T1_BASE (IDENT_ADDR + 0x8760000580UL) + +#define CIA_IOC_PCI_W2_BASE (IDENT_ADDR + 0x8760000600UL) +#define CIA_IOC_PCI_W2_MASK (IDENT_ADDR + 0x8760000640UL) +#define CIA_IOC_PCI_T2_BASE (IDENT_ADDR + 0x8760000680UL) + +#define CIA_IOC_PCI_W3_BASE (IDENT_ADDR + 0x8760000700UL) +#define CIA_IOC_PCI_W3_MASK (IDENT_ADDR + 0x8760000740UL) +#define CIA_IOC_PCI_T3_BASE (IDENT_ADDR + 0x8760000780UL) + +#define CIA_IOC_PCI_Wn_BASE(N) (IDENT_ADDR + 0x8760000400UL + (N)*0x100) +#define CIA_IOC_PCI_Wn_MASK(N) (IDENT_ADDR + 0x8760000440UL + (N)*0x100) +#define CIA_IOC_PCI_Tn_BASE(N) (IDENT_ADDR + 0x8760000480UL + (N)*0x100) + +#define CIA_IOC_PCI_W_DAC (IDENT_ADDR + 0x87600007C0UL) + +/* + * 2117A-CA Address Translation Registers. + */ + +/* 8 tag registers, the first 4 of which are lockable. */ +#define CIA_IOC_TB_TAGn(n) \ + (IDENT_ADDR + 0x8760000800UL + (n)*0x40) + +/* 4 page registers per tag register. */ +#define CIA_IOC_TBn_PAGEm(n,m) \ + (IDENT_ADDR + 0x8760001000UL + (n)*0x100 + (m)*0x40) + +/* + * Memory spaces: + */ +#define CIA_IACK_SC (IDENT_ADDR + 0x8720000000UL) +#define CIA_CONF (IDENT_ADDR + 0x8700000000UL) +#define CIA_IO (IDENT_ADDR + 0x8580000000UL) +#define CIA_SPARSE_MEM (IDENT_ADDR + 0x8000000000UL) +#define CIA_SPARSE_MEM_R2 (IDENT_ADDR + 0x8400000000UL) +#define CIA_SPARSE_MEM_R3 (IDENT_ADDR + 0x8500000000UL) +#define CIA_DENSE_MEM (IDENT_ADDR + 0x8600000000UL) +#define CIA_BW_MEM (IDENT_ADDR + 0x8800000000UL) +#define CIA_BW_IO (IDENT_ADDR + 0x8900000000UL) +#define CIA_BW_CFG_0 (IDENT_ADDR + 0x8a00000000UL) +#define CIA_BW_CFG_1 (IDENT_ADDR + 0x8b00000000UL) + +/* + * ALCOR's GRU ASIC registers + */ +#define GRU_INT_REQ (IDENT_ADDR + 0x8780000000UL) +#define GRU_INT_MASK (IDENT_ADDR + 0x8780000040UL) +#define GRU_INT_EDGE (IDENT_ADDR + 0x8780000080UL) +#define GRU_INT_HILO (IDENT_ADDR + 0x87800000C0UL) +#define GRU_INT_CLEAR (IDENT_ADDR + 0x8780000100UL) + +#define GRU_CACHE_CNFG (IDENT_ADDR + 0x8780000200UL) +#define GRU_SCR (IDENT_ADDR + 0x8780000300UL) +#define GRU_LED (IDENT_ADDR + 0x8780000800UL) +#define GRU_RESET (IDENT_ADDR + 0x8780000900UL) + +#define ALCOR_GRU_INT_REQ_BITS 0x800fffffUL +#define XLT_GRU_INT_REQ_BITS 0x80003fffUL +#define GRU_INT_REQ_BITS (alpha_mv.sys.cia.gru_int_req_bits+0) + +/* + * PYXIS interrupt control registers + */ +#define PYXIS_INT_REQ (IDENT_ADDR + 0x87A0000000UL) +#define PYXIS_INT_MASK (IDENT_ADDR + 0x87A0000040UL) +#define PYXIS_INT_HILO (IDENT_ADDR + 0x87A00000C0UL) +#define PYXIS_INT_ROUTE (IDENT_ADDR + 0x87A0000140UL) +#define PYXIS_GPO (IDENT_ADDR + 0x87A0000180UL) +#define PYXIS_INT_CNFG (IDENT_ADDR + 0x87A00001C0UL) +#define PYXIS_RT_COUNT (IDENT_ADDR + 0x87A0000200UL) +#define PYXIS_INT_TIME (IDENT_ADDR + 0x87A0000240UL) +#define PYXIS_IIC_CTRL (IDENT_ADDR + 0x87A00002C0UL) +#define PYXIS_RESET (IDENT_ADDR + 0x8780000900UL) + +/* Offset between ram physical addresses and pci64 DAC bus addresses. */ +#define PYXIS_DAC_OFFSET (1UL << 40) + +#ifdef __ASSEMBLER__ + +/* Unfortunately, GAS doesn't attempt any interesting constructions of + 64-bit constants, dropping them all into the .lit8 section. It is + better for us to build these by hand. */ +.macro LOAD_PHYS_PYXIS_INT ret + lda \ret, 0x87a + sll \ret, 28, \ret +.endm + +.macro LOAD_KSEG_PCI_IO ret + lda \ret, -887 + sll \ret, 32, \ret +.endm + +.macro SYS_WHAMI ret + mov 0, \ret +.endm + +.macro SYS_ACK_SMP t0, t1, t2 + br MchkBugCheck +.endm + +#else + +static inline unsigned long inb(unsigned long port) +{ + return *(volatile unsigned char *)(CIA_BW_IO + port); +} + +static inline void outb(unsigned long port, unsigned char val) +{ + *(volatile unsigned char *)(CIA_BW_IO + port) = val; +} + + +#endif + +#endif /* CIA_H */ diff --git a/core-typhoon.h b/core-typhoon.h new file mode 100644 index 0000000..70d85af --- /dev/null +++ b/core-typhoon.h @@ -0,0 +1,163 @@ +#ifndef TYPHOON_H +#define TYPHOON_H 1 + +/* Assume a 43-bit KSEG for now. */ +#define PIO_PHYS_ADDR 0x80000000000 +#define PIO_KSEG_ADDR (0xfffffc0000000000 + 0x10000000000) + +/* CCHIP REGISTERS */ + +#define TYPHOON_CCHIP 0x1a0000000 + +#define TYPHOON_CCHIP_CSC 0x0000 +#define TYPHOON_CCHIP_MTR 0x0040 +#define TYPHOON_CCHIP_MISC 0x0080 +#define TYPHOON_CCHIP_MPD 0x00c0 +#define TYPHOON_CCHIP_AAR0 0x0100 +#define TYPHOON_CCHIP_AAR1 0x0140 +#define TYPHOON_CCHIP_AAR2 0x0180 +#define TYPHOON_CCHIP_AAR3 0x01c0 +#define TYPHOON_CCHIP_DIM0 0x0200 +#define TYPHOON_CCHIP_DIM1 0x0240 +#define TYPHOON_CCHIP_DIR0 0x0280 +#define TYPHOON_CCHIP_DIR1 0x02c0 +#define TYPHOON_CCHIP_DRIR 0x0300 +#define TYPHOON_CCHIP_PRBEN 0x0340 +#define TYPHOON_CCHIP_IIC0 0x0380 +#define TYPHOON_CCHIP_IIC1 0x03c0 +#define TYPHOON_CCHIP_MPR0 0x0400 +#define TYPHOON_CCHIP_MPR1 0x0440 +#define TYPHOON_CCHIP_MPR2 0x0480 +#define TYPHOON_CCHIP_MPR3 0x04c0 +#define TYPHOON_CCHIP_TTR 0x0580 +#define TYPHOON_CCHIP_TDR 0x05c0 +#define TYPHOON_CCHIP_DIM2 0x0600 +#define TYPHOON_CCHIP_DIM3 0x0640 +#define TYPHOON_CCHIP_DIR2 0x0680 +#define TYPHOON_CCHIP_DIR3 0x06c0 +#define TYPHOON_CCHIP_IIC2 0x0700 +#define TYPHOON_CCHIP_IIC3 0x0740 +#define TYPHOON_CCHIP_PWR 0x0780 +#define TYPHOON_CCHIP_CMONCTLA 0x0c00 +#define TYPHOON_CCHIP_CMONCTLB 0x0c40 +#define TYPHOON_CCHIP_CMONCNT01 0x0c80 +#define TYPHOON_CCHIP_CMONCNT23 0x0cc0 + +/* DCHIP REGISTERS */ + +#define TYPHOON_DCHIP 0x1b0000000 + +#define TYPHOON_DCHIP_DSC 0x0800 +#define TYPHOON_DCHIP_STR 0x0840 +#define TYPHOON_DCHIP_DREV 0x0880 +#define TYPHOON_DCHIP_DSC2 0x08c0 + +/* PCHIP REGISTERS */ + +#define TYPHOON_PCHIP0 0x180000000 +#define TYPHOON_PCHIP1 0x380000000 + +#define TYPHOON_PCHIP_WSBA0 0x0000 +#define TYPHOON_PCHIP_WSBA1 0x0040 +#define TYPHOON_PCHIP_WSBA2 0x0080 +#define TYPHOON_PCHIP_WSBA3 0x00c0 +#define TYPHOON_PCHIP_WSM0 0x0100 +#define TYPHOON_PCHIP_WSM1 0x0140 +#define TYPHOON_PCHIP_WSM2 0x0180 +#define TYPHOON_PCHIP_WSM3 0x01c0 +#define TYPHOON_PCHIP_TBA0 0x0200 +#define TYPHOON_PCHIP_TBA1 0x0240 +#define TYPHOON_PCHIP_TBA2 0x0280 +#define TYPHOON_PCHIP_TBA3 0x02c0 +#define TYPHOON_PCHIP_PCTL 0x0300 +#define TYPHOON_PCHIP_PLAT 0x0340 +#define TYPHOON_PCHIP_PERROR 0x03c0 +#define TYPHOON_PCHIP_PERRMASK 0x0400 +#define TYPHOON_PCHIP_PERRSET 0x0440 +#define TYPHOON_PCHIP_TLBIV 0x0480 +#define TYPHOON_PCHIP_TLBIA 0x04c0 +#define TYPHOON_PCHIP_PMONCTL 0x0500 +#define TYPHOON_PCHIP_PMONCNT 0x0540 +#define TYPHOON_PCHIP_SPRST 0x0800 + +/* PCI ADDRESSES */ + +#define TYPHOON_PCHIP0_PCI_MEM 0 +#define TYPHOON_PCHIP0_PCI_IO 0x1fc000000 +#define TYPHOON_PCHIP0_PCI_CONF 0x1fe000000 + +#ifdef __ASSEMBLER__ + +#include "pal.h" + +#define ptCpuDIR ptSys0 +#define ptCpuIIC ptSys1 + +/* Unfortunately, GAS doesn't attempt any interesting constructions of + 64-bit constants, dropping them all into the .lit8 section. It is + better for us to build these by hand. */ +.macro LOAD_PHYS_CCHIP ret + lda \ret, 0x400d + sll \ret, 29, \ret +.endm + +.macro LOAD_PHYS_PCHIP0 ret + lda \ret, 0x400c + sll \ret, 29, \ret +.endm + +.macro LOAD_KSEG_PCI_IO ret + ldah \ret, -48 + lda \ret, 0x1fc0(\ret) + sll \ret, 20, \ret +.endm + +.macro SYS_WHAMI ret + LOAD_PHYS_CCHIP \ret + ldq_p \ret, TYPHOON_CCHIP_MISC(\ret) + and \ret, 3, \ret +.endm + +/* ACK the Interprocessor Interrupt. */ +.macro SYS_ACK_SMP t0, t1, t2 + LOAD_PHYS_CCHIP \t0 + ldq_p \t1, TYPHOON_CCHIP_MISC(\t0) + and \t1, 3, \t1 + addq \t1, 8, \t1 + lda \t2, 1 + sll \t2, \t1, \t2 + stq_p \t2, TYPHOON_CCHIP_MISC(\t0) +.endm + +/* ACK the Clock Interrupt. */ +.macro SYS_ACK_CLK t0, t1, t2 + LOAD_PHYS_CCHIP \t0 + ldq_p \t1, TYPHOON_CCHIP_MISC(\t0) + and \t1, 3, \t1 + addq \t1, 4, \t1 + lda \t2, 1 + sll \t2, \t1, \t2 + stq_p \t2, TYPHOON_CCHIP_MISC(\t0) +.endm + +/* Load the device interrupt vector. */ +.macro SYS_DEV_VECTOR ret + mfpr \ret, ptCpuDIR + ldq_p \ret, 0(\ret) + cttz \ret, \ret + sll \ret, 4, \ret + lda \ret, 0x800(\ret) +.endm + +/* Interrupt another CPU. */ +.macro SYS_WRIPIR target, t0, t1, t2 + LOAD_PHYS_CCHIP \t0 + mov 1, \t1 + and \target, 3, \t2 + addq \t2, 12, \t2 + sll \t1, \t2, \t1 + stq_p \t1, TYPHOON_CCHIP_MISC(\t0) +.endm + +#endif /* ASSEMBLER */ +#endif /* TYPHOON_H */ diff --git a/init.c b/init.c index 169ae07..535f92b 100644 --- a/init.c +++ b/init.c @@ -3,6 +3,7 @@ #include "hwrpb.h" #include "osf.h" #include "uart.h" +#include SYSTEM_H #define PAGE_SHIFT 13 #define PAGE_SIZE (1ul << PAGE_SHIFT) @@ -141,6 +142,7 @@ static void init_hwrpb (unsigned long memsize) { unsigned long pal_pages; + unsigned long cpu_type; hwrpb.hwrpb.phys_addr = PA(&hwrpb); @@ -167,14 +169,15 @@ init_hwrpb (unsigned long memsize) ((int *)hwrpb.hwrpb.ssn)[2] = ( 'U' << 0); /* For now, hard-code emulation of sx164. */ - hwrpb.hwrpb.cpuid = PCA56_CPU; + cpu_type = init_cpuid(); + hwrpb.hwrpb.cpuid = cpu_type; hwrpb.hwrpb.pagesize = PAGE_SIZE; hwrpb.hwrpb.pa_bits = 40; hwrpb.hwrpb.max_asn = 127; - hwrpb.hwrpb.sys_type = ST_DEC_EB164; - hwrpb.hwrpb.sys_variation = 15 << 10; - hwrpb.hwrpb.sys_revision = 0; - hwrpb.processor.type = PCA56_CPU; + hwrpb.hwrpb.sys_type = SYS_TYPE; + hwrpb.hwrpb.sys_variation = SYS_VARIATION; + hwrpb.hwrpb.sys_revision = SYS_REVISION; + hwrpb.processor.type = cpu_type; hwrpb.hwrpb.intr_freq = HZ * 4096; hwrpb.hwrpb.cycle_freq = 250000000; /* QEMU architects 250MHz. */ @@ -220,7 +223,7 @@ do_hello(void) } void -do_start(unsigned long memsize, void (*kernel_entry)(void)) +do_start(unsigned long memsize, void (*kernel_entry)(void), long cpus) { last_alloc = _end; @@ -242,3 +245,16 @@ do_start(unsigned long memsize, void (*kernel_entry)(void)) } __builtin_unreachable (); } + +void +do_start_wait(void) +{ + while (1) + { + // WtInt with interrupts off. Rely on the fact that QEMU will + // un-halt the CPU when an interrupt arrives. + asm("lda $16,-1\n\tcall_pal 0x3e" : : : "$0", "$16"); + + // FIXME do something with the IPI. + } +} diff --git a/io.h b/io.h deleted file mode 100644 index c58c271..0000000 --- a/io.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef IO_H -#define IO_H - -#include "cia.h" - -static inline unsigned long -inb(unsigned long port) -{ - return *(volatile unsigned char *)(CIA_BW_IO + port); -} - -static inline void -outb(unsigned char val, unsigned long port) -{ - *(volatile unsigned char *)(CIA_BW_IO + port) = val; -} - -#endif diff --git a/osf.h b/osf.h index c7e18c8..78e2e70 100644 --- a/osf.h +++ b/osf.h @@ -59,6 +59,7 @@ #define IPL_K_DEV0 0x3 #define IPL_K_DEV1 0x4 #define IPL_K_CLK 0x5 +#define IPL_K_IP 0x6 #define IPL_K_RT 0x6 #define IPL_K_PERF 0x6 #define IPL_K_PFAIL 0x6 diff --git a/pal.S b/pal.S index d604666..124763a 100644 --- a/pal.S +++ b/pal.S @@ -2,129 +2,9 @@ .set nomacro .text +#include "pal.h" #include "osf.h" -#include "uart.h" - -/* General Purpose Registers. */ -#define v0 $0 -#define t0 $1 -#define t1 $2 -#define t2 $3 -#define t3 $4 -#define t4 $5 -#define t5 $6 -#define a0 $16 -#define a1 $17 -#define a2 $18 -#define a3 $19 -#define a4 $20 -#define a5 $21 -#define t8 $22 -#define t9 $23 -#define t10 $24 - -/* PALcode Shadow Registers. These registers are swapped out when - QEMU is in PALmode. Unlike real hardware, there is no enable bit. - However, also unlike real hardware, the originals can be accessed - via MTPR/MFPR. */ -#define p0 $8 -#define p1 $9 -#define p2 $10 -#define p3 $11 -#define p4 $12 -#define p5 $13 -#define p6 $14 // Used to save exc_addr for machine check -#define p7 $25 - -/* QEMU Processor Registers. */ -#define qemu_ps 0 -#define qemu_fen 1 -#define qemu_pcc_ofs 2 -#define qemu_trap_arg0 3 -#define qemu_trap_arg1 4 -#define qemu_trap_arg2 5 -#define qemu_exc_addr 6 -#define qemu_palbr 7 -#define qemu_ptbr 8 -#define qemu_vptptr 9 -#define qemu_unique 10 -#define qemu_sysval 11 -#define qemu_usp 12 - -#define qemu_shadow0 32 -#define qemu_shadow1 33 -#define qemu_shadow2 34 -#define qemu_shadow3 35 -#define qemu_shadow4 36 -#define qemu_shadow5 37 -#define qemu_shadow6 38 -#define qemu_shadow7 39 - -/* PALcode Processor Register Private Storage. */ -#define pt0 40 -#define pt1 41 -#define pt2 42 -#define pt3 43 -#define pt4 44 -#define pt5 45 -#define pt6 46 -#define pt7 47 -#define pt8 48 -#define pt9 49 -#define pt10 50 -#define pt11 51 -#define pt12 52 -#define pt13 53 -#define pt14 54 -#define pt15 55 -#define pt16 56 -#define pt17 57 -#define pt18 58 -#define pt19 59 -#define pt20 60 -#define pt21 61 -#define pt22 62 -#define pt23 63 - -/* QEMU function calls, via mtpr. */ -#define qemu_tbia 255 -#define qemu_tbis 254 -#define qemu_wait 253 - -/* PALcode uses of the private storage slots. */ -#define ptEntUna pt0 -#define ptEntIF pt1 -#define ptEntSys pt2 -#define ptEntInt pt3 -#define ptEntArith pt4 -#define ptEntMM pt5 -#define ptMces pt6 -#define ptKsp pt7 -#define ptKgp pt8 -#define ptPcbb pt9 -#define ptPgp pt10 -#define ptMisc pt11 -#define ptMchk0 pt12 -#define ptMchk1 pt13 -#define ptMchk2 pt14 -#define ptMchk3 pt15 -#define ptMchk4 pt16 -#define ptMchk5 pt17 - -/* - * Shortcuts for various PALmode instructions. - */ -#define mtpr hw_mtpr -#define mfpr hw_mfpr -#define stq_p hw_stq/p -#define stl_p hw_stl/p -#define ldl_p hw_ldl/p -#define ldq_p hw_ldq/p - -/* QEMU recognizes the EV4/EV5 HW_REI instruction as a special case of - the EV6 HW_RET instruction. This pulls the destination address from - the EXC_ADDR processor register. */ -#define hw_rei hw_ret ($31) +#include SYSTEM_H /* * Create a standard kernel entry stack frame. @@ -158,11 +38,6 @@ stq a2, FRM_Q_A2($sp) .endm -.macro ENDFN function - .type \function, @function - .size \function, . - \function -.endm - /* * Allocate a 1 page stack for use by the console. */ @@ -183,26 +58,30 @@ .org 0x0000 .globl __start __start: - // Initialize GP and stack. + // Initialize GP. br $gp, .+4 ldah $gp, 0($gp) !gpdisp!1 lda $gp, 0($gp) !gpdisp!1 mtpr $gp, ptPgp - lda $sp, stack+STACK_SIZE($gp) !gprel - // Disable interrupts; kernel mode lda t0, IPL_K_HIGH mtpr t0, qemu_ps - // Make sure kernel entry points are invalid. - lda t0, -1 - mtpr t0, ptEntUna - mtpr t0, ptEntIF - mtpr t0, ptEntSys - mtpr t0, ptEntInt - mtpr t0, ptEntArith - mtpr t0, ptEntMM + // Initialize Stack. + SYS_WHAMI a0 + lda t0, STACK_SIZE + mull t0, a0, t0 + ldah t1, stack($gp) !gprelhigh + lda t1, stack(t1) !gprellow + addq t0, t1, $sp + + // Do any necessary system setup required for PALmode, + // e.g. setting up ptSys[01]. + bsr $26, Sys_Setup + + // Non-boot CPUs can go wait now. + bne a0, 1f // Load boot arguments mfpr a0, qemu_trap_arg0 @@ -213,6 +92,10 @@ __start: ldah $27, do_start($gp) !gprelhigh lda $27, do_start($27) !gprellow hw_ret ($27) + +1: ldah $27, do_start_wait($gp) !gprelhigh + lda $27, do_start_wait($27) !gprellow + hw_ret ($27) ENDFN __start /* @@ -242,7 +125,7 @@ Pal_Mchk: ENDFN Pal_Mchk /* - * Clock Interrupt + * Interprocessor Interrupt * * INPUT PARAMETERS: * @@ -250,26 +133,48 @@ ENDFN Pal_Mchk * trap_arg1 = * trap_arg2 = * - * The clock interrupt is special, in that PALcode is supposed + * The interprocessor interrupt is special, in that PALcode is supposed * to clear the interupt and not wait for the OS to do it. */ .org 0x0100 -Pal_Clk_Interrupt: +Pal_Smp_Interrupt: mfpr p6, qemu_exc_addr - // Load CIA_BW_IO. Note that this is the KSEG address, - // since there is no hw_stb with physical address access. - lda p0, -887 - sll p0, 32, p0 + SYS_ACK_SMP p0, p1, p2 + + mfpr p0, qemu_ps + + STACK_FRAME p0, p6, p2, 0 + + mov IPL_K_IP, p0 // Raise IPL + mtpr p0, qemu_ps - mov 0xc, p1 // Set RTCADD (0x70) to index register 0xC - stb p1, 0x70(p0) - ldbu p1, 0x71(p0) // Read RTCDAT to clear interrupt. + mfpr p6, ptEntInt + mfpr $gp, ptKgp + lda a0, INT_K_IP + lda a1, 0 + lda a2, 0 + + hw_ret (p6) +ENDFN Pal_Smp_Interrupt + +/* + * Clock Interrupt + * + * INPUT PARAMETERS: + * + * trap_arg0 = + * trap_arg1 = + * trap_arg2 = + * + * The clock interrupt is special, in that PALcode is supposed + * to clear the interupt and not wait for the OS to do it. + */ + .org 0x0180 +Pal_Clk_Interrupt: + mfpr p6, qemu_exc_addr -#if 0 - and p1, 0x40, p1 // Check for real interrupt. - bne p1, 9f // If not, exit now, no stack frame. -#endif + SYS_ACK_CLK p0, p1, p2 mfpr p0, qemu_ps @@ -296,7 +201,7 @@ ENDFN Pal_Clk_Interrupt * trap_arg1 = * trap_arg2 = */ - .org 0x0180 + .org 0x0200 Pal_Dev_Interrupt: mfpr p6, qemu_exc_addr mfpr p0, qemu_ps @@ -308,9 +213,12 @@ Pal_Dev_Interrupt: mfpr p7, ptEntInt mfpr $gp, ptKgp + lda a0, INT_K_DEV - lda a1, 0x800 lda a2, 0 + + SYS_DEV_VECTOR a1 + hw_ret (p7) ENDFN Pal_Dev_Interrupt @@ -323,7 +231,7 @@ ENDFN Pal_Dev_Interrupt * trap_arg1 = fault type (TNV, ACV, FOR, FOW, FOE) * trap_arg2 = access type (exec=-1, read=0, write=1) */ - .org 0x0200 + .org 0x0280 Pal_MMFault: mfpr p0, qemu_ps mfpr p6, qemu_exc_addr @@ -348,7 +256,7 @@ ENDFN Pal_MMFault * trap_arg1 = opcode of faulting insn * trap_arg2 = src/dst register number */ - .org 0x0280 + .org 0x0300 Pal_Unalign: mfpr p0, qemu_ps mfpr p6, qemu_exc_addr @@ -380,7 +288,7 @@ ENDFN Pal_Unalign * r17 (a1) = UNPREDICTABLE * r18 (a2) = UNPREDICTABLE */ - .org 0x0300 + .org 0x0380 Pal_OpcDec: mfpr p0, qemu_ps mfpr p6, qemu_exc_addr @@ -404,7 +312,7 @@ ENDFN Pal_OpcDec * trap_arg1 = register modification mask * trap_arg2 = UNDEFINED */ - .org 0x0380 + .org 0x0400 Pal_Arith: mfpr p0, qemu_ps mfpr p6, qemu_exc_addr @@ -434,7 +342,7 @@ ENDFN Pal_Arith * r17 (a1) = UNPREDICTABLE * r18 (a2) = UNPREDICTABLE */ - .org 0x0400 + .org 0x0480 Pal_Fen: mfpr p0, qemu_ps mfpr p6, qemu_exc_addr @@ -466,14 +374,9 @@ ENDFN Pal_Fen ORG_CALL_PAL_PRIV(0x00) CallPal_Halt: bsr p7, UpdatePCB // Save kernel data - lda v0, HLT_K_SW_HALT + lda v0, HLT_K_SW_HALT // FIXME store this somewhere. - ldah p0, 1 // Store 0xdead into CIA RESET reg - lda p0, -(0x10000 - 0xdead)(p0) - lda p1, 0x878 - sll p1, 28, p1 - lda p1, 0x900(p1) - stl_p p0, 0(p1) + mtpr $31, qemu_halt br Sys_EnterConsole ENDFN CallPal_Halt @@ -535,69 +438,40 @@ ENDFN CallPal_OpcDec08 * * r16 (a0) = Option selector * r17..r21 (a1..a5) = Implementation specific entry parameters - * + * * SIDE EFFECTS: * * Registers a0..a5, and v0 are UNPREDICTABLE upon return. */ ORG_CALL_PAL_PRIV(0x09) CallPal_Cserve: - cmpeq a0, 15, v0 - bne v0, Cserve_putc + // ??? For SRM compatibility, use 52/53 for these. Anyone know what + // other "standard" SRM Cserve entry points are? Certainly we don't + // want to be compatible with MILO, which puts the selector at A2. cmpeq a0, 52, v0 - bne v0, Cserve_ena + bne v0, Cserve_Ena cmpeq a0, 53, v0 - bne v0, Cserve_dis + bne v0, Cserve_Dis + + // All the rest of the Cserve entry points are compressed from 1. + cmpeq a0, 1, v0 + bne v0, Cserve_Ldqp + cmpeq a0, 2, v0 + bne v0, Cserve_Stqp + hw_rei ENDFN CallPal_Cserve .text 1 -Cserve_putc: - // Load CIA_BW_IO. Note that this is the KSEG address, - // since there is no hw_stb with physical address access. - lda p0, -887 - sll p0, 32, p0 - - ldbu v0, com1Lsr(p0) // Get Transmit Holding Register Empty - and v0, 0x20, v0 - beq v0, 1f - - stb a1, com1Thr(p0) // Output the byte - mov 1, v0 -1: hw_rei -ENDFN Cserve_putc - -Cserve_ena: - lda p0, 0x87a // Load PYXIS INT REG base. - sll p0, 28, p0 - - lda p1, 1 // Shift the interrupt line in place. - sll p1, a1, p1 - - ldq_p p2, 0x40(p0) // Load PYXIS_INT_MASK - sll p2, a1, v0 // Return the current setting - and v0, 1, v0 - andnot p2, p1, p2 // Clear the bit - stq_p p2, 0x40(p0) // Store PYXIS_INT_MASK - +Cserve_Ldqp: + ldq_p v0, 0(a1) hw_rei -ENDFN Cserve_ena - -Cserve_dis: - lda p0, 0x87a // Load PYXIS INT REG base. - sll p0, 28, p0 - - lda p1, 1 // Shift the interrupt line in place. - sll p1, a1, p1 - - ldq_p p2, 0x40(p0) // Load PYXIS_INT_MASK - sll p2, a1, v0 // Return the current setting - and v0, 1, v0 - or p2, p1, p2 // Set the bit - stq_p p2, 0x40(p0) // Store PYXIS_INT_MASK +ENDFN Cserve_Ldqp +Cserve_Stqp: + stq_p a2, 0(a1) hw_rei -ENDFN Cserve_dis +ENDFN Cserve_Stqp .previous /* @@ -717,7 +591,11 @@ ENDFN CallPal_OpcDec0C */ ORG_CALL_PAL_PRIV(0x0D) CallPal_WrIpir: - // We do not currently support more cpus + // Save a copy of the return address in case of machine check. + mfpr p6, qemu_exc_addr + + SYS_WRIPIR a0, p0, p1, p2 + hw_rei ENDFN CallPal_WrIpir @@ -1266,8 +1144,7 @@ ENDFN CallPal_OpcDec3B */ ORG_CALL_PAL_PRIV(0x3C) CallPal_Whami: - // We do not currently support more cpus - mov 0, v0 + SYS_WHAMI v0 hw_rei ENDFN CallPal_Whami @@ -2177,6 +2054,7 @@ laf_q_pci_err2: .quad 0 $laf_size = . - laf_base .size laf_base, . - laf_base + .section .bss .align 3 .globl stack .type stack,@object diff --git a/pal.h b/pal.h new file mode 100644 index 0000000..a2ee6cf --- /dev/null +++ b/pal.h @@ -0,0 +1,134 @@ +#ifndef PAL_H +#define PAL_H 1 + +/* General Purpose Registers. */ +#define v0 $0 +#define t0 $1 +#define t1 $2 +#define t2 $3 +#define t3 $4 +#define t4 $5 +#define t5 $6 +#define a0 $16 +#define a1 $17 +#define a2 $18 +#define a3 $19 +#define a4 $20 +#define a5 $21 +#define t8 $22 +#define t9 $23 +#define t10 $24 + +/* PALcode Shadow Registers. These registers are swapped out when + QEMU is in PALmode. Unlike real hardware, there is no enable bit. + However, also unlike real hardware, the originals can be accessed + via MTPR/MFPR. */ +#define p0 $8 +#define p1 $9 +#define p2 $10 +#define p3 $11 +#define p4 $12 +#define p5 $13 +#define p6 $14 // Used to save exc_addr for machine check +#define p7 $25 + +/* QEMU Processor Registers. */ +#define qemu_ps 0 +#define qemu_fen 1 +#define qemu_pcc_ofs 2 +#define qemu_trap_arg0 3 +#define qemu_trap_arg1 4 +#define qemu_trap_arg2 5 +#define qemu_exc_addr 6 +#define qemu_palbr 7 +#define qemu_ptbr 8 +#define qemu_vptptr 9 +#define qemu_unique 10 +#define qemu_sysval 11 +#define qemu_usp 12 + +#define qemu_shadow0 32 +#define qemu_shadow1 33 +#define qemu_shadow2 34 +#define qemu_shadow3 35 +#define qemu_shadow4 36 +#define qemu_shadow5 37 +#define qemu_shadow6 38 +#define qemu_shadow7 39 + +/* PALcode Processor Register Private Storage. */ +#define pt0 40 +#define pt1 41 +#define pt2 42 +#define pt3 43 +#define pt4 44 +#define pt5 45 +#define pt6 46 +#define pt7 47 +#define pt8 48 +#define pt9 49 +#define pt10 50 +#define pt11 51 +#define pt12 52 +#define pt13 53 +#define pt14 54 +#define pt15 55 +#define pt16 56 +#define pt17 57 +#define pt18 58 +#define pt19 59 +#define pt20 60 +#define pt21 61 +#define pt22 62 +#define pt23 63 + +/* QEMU function calls, via mtpr. */ +#define qemu_tbia 255 +#define qemu_tbis 254 +#define qemu_wait 253 +#define qemu_halt 252 + +/* PALcode uses of the private storage slots. */ +#define ptEntUna pt0 +#define ptEntIF pt1 +#define ptEntSys pt2 +#define ptEntInt pt3 +#define ptEntArith pt4 +#define ptEntMM pt5 +#define ptMces pt6 +#define ptKsp pt7 +#define ptKgp pt8 +#define ptPcbb pt9 +#define ptPgp pt10 +#define ptMisc pt11 +#define ptMchk0 pt12 +#define ptMchk1 pt13 +#define ptMchk2 pt14 +#define ptMchk3 pt15 +#define ptMchk4 pt16 +#define ptMchk5 pt17 +#define ptSys0 pt18 +#define ptSys1 pt19 + +/* + * Shortcuts for various PALmode instructions. + */ +#define mtpr hw_mtpr +#define mfpr hw_mfpr +#define stq_p hw_stq/p +#define stl_p hw_stl/p +#define ldl_p hw_ldl/p +#define ldq_p hw_ldq/p + +/* QEMU recognizes the EV4/EV5 HW_REI instruction as a special case of + the EV6 HW_RET instruction. This pulls the destination address from + the EXC_ADDR processor register. */ +#define hw_rei hw_ret ($31) + + +.macro ENDFN function + .type \function, @function + .size \function, . - \function +.endm + +#endif /* PAL_H */ diff --git a/protos.h b/protos.h new file mode 100644 index 0000000..6bff767 --- /dev/null +++ b/protos.h @@ -0,0 +1,42 @@ +#ifndef PROTOS_H +#define PROTOS_H 1 + +/* + * Cserve functions. + */ + +static inline unsigned long ldq_p(unsigned long addr) +{ + register unsigned long v0 __asm__("$0"); + register unsigned long a0 __asm__("$16") = 1; + register unsigned long a1 __asm__("$17") = addr; + + asm volatile ("call_pal 9" + : "=r"(v0), "+r"(a0), "+r"(a1) : + : "$18", "$19", "$20", "$21"); + + return v0; +} + +static inline unsigned long stq_p(unsigned long port, unsigned long val) +{ + register unsigned long v0 __asm__("$0"); + register unsigned long a0 __asm__("$16") = 4; + register unsigned long a1 __asm__("$17") = port; + register unsigned long a2 __asm__("$18") = val; + + asm volatile ("call_pal 9" + : "=r"(v0), "+r"(a0), "+r"(a1), "+r"(a2) : + : "$19", "$20", "$21"); + + return v0; +} + +/* + * I/O functions + */ + +extern unsigned long inb(unsigned long port); +extern unsigned long outb(unsigned char val, unsigned long port); + +#endif /* PROTOS_H */ diff --git a/sys-clipper.S b/sys-clipper.S new file mode 100644 index 0000000..e3fc6f5 --- /dev/null +++ b/sys-clipper.S @@ -0,0 +1,90 @@ +#include "pal.h" +#include SYSTEM_H + +/* + * Sys_Setup + * + * Do any system specific setup necessary. + * + * INPUT PARAMETERS + * + * r16 (a0) = whami + * r26 (ra) = return address + */ + .globl Sys_Setup + .ent Sys_Setup +Sys_Setup: + .frame $sp, 0, p7, 0 + lda t0, TYPHOON_CCHIP_DIM0 + lda t1, TYPHOON_CCHIP_DIM2 + lda t2, TYPHOON_CCHIP_IIC0 + lda t3, TYPHOON_CCHIP_IIC2 + and a0, 2, t4 + cmovne t4, t1, t0 + cmovne t4, t3, t2 + and a0, 1, t4 + sll t4, 6, t4 + addq t0, t4, t0 + addq t2, t4, t2 + LOAD_PHYS_CCHIP t4 + addq t0, t4, t0 + addq t2, t4, t2 + mtpr t0, ptCpuDIR + mtpr t2, ptCpuIIC + ret + .end Sys_Setup + +/* + * Cserve_Ena + * + * Unmask a PCI interrupt + */ + .globl Cserve_Ena +Cserve_Ena: + // FIXME + hw_rei +ENDFN Cserve_Ena + +/* + * Cserve_Dis + * + * Mask a PCI interrupt + */ + .globl Cserve_Dis +Cserve_Dis: + // FIXME + hw_rei +ENDFN Cserve_Dis + +/* + * inb + * + * Read a byte from the PCI I/O bus. + */ + .globl inb + .ent inb +inb: + .frame $sp, 0, $26, 0 + .prologue 0 + LOAD_KSEG_PCI_IO v0 + addq v0, a0, v0 + ldbu v0, 0(v0) + ret + .end inb + +/* + * outb + * + * Write a byte to the PCI I/O bus. + */ + .globl outb + .ent outb +outb: + .frame $sp, 0, $26, 0 + .prologue 0 + LOAD_KSEG_PCI_IO p0 + addq p0, a1, p0 + stb a0, 0(p0) + ret + .end outb + diff --git a/sys-clipper.h b/sys-clipper.h new file mode 100644 index 0000000..beea346 --- /dev/null +++ b/sys-clipper.h @@ -0,0 +1,10 @@ +#ifndef SYS_CLIPPER_H +#define SYS_CLIPPER_H 1 + +#include "core-typhoon.h" + +#define SYS_TYPE ST_DEC_TSUNAMI +#define SYS_VARIATION (5 << 10) +#define SYS_REVISION 0 + +#endif diff --git a/sys-sx164.h b/sys-sx164.h new file mode 100644 index 0000000..8198ae8 --- /dev/null +++ b/sys-sx164.h @@ -0,0 +1,25 @@ +#ifndef SYS_SX164_H +#define SYS_SX164_H 1 + +#include "core_cia.h" + +#ifdef __ASSEMBLER__ + +.macro SYS_ACK_CLK t0, t1, t2 + LOAD_KSEG_PCI_IO \t0 // Set RTCADD (0x70) to index reg 0xC + mov 0xc, \t1 + stb \t1, 0x70(\t0) + ldbu \t1, 0x71(\t0) // Read RTCDAT to clear interrupt +.endm + +.macro SYS_DEV_VECTOR ret + FIXME +.endm + +#endif /* ASSEMBLER */ + +#define SYS_TYPE ST_DEC_EB164 +#define SYS_VARIATION (15 << 10) +#define SYS_REVISION 0 + +#endif /* SYS_SX164_H */ diff --git a/uart.c b/uart.c index d3fd848..2e93482 100644 --- a/uart.c +++ b/uart.c @@ -30,7 +30,7 @@ your own risk. * Modified for QEMU PALcode by rth@twiddle.net. */ -#include "io.h" +#include "protos.h" #include "uart.h" #ifndef SERIAL_SPEED -- cgit v1.1