1/*	$NetBSD: sx.c,v 1.8 2023/12/20 05:33:18 thorpej Exp $	*/
2
3/*-
4 * Copyright (c) 2013 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Michael Lorenz.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: sx.c,v 1.8 2023/12/20 05:33:18 thorpej Exp $");
34
35#include "locators.h"
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/device.h>
40
41#include <uvm/uvm_extern.h>
42
43#include <sys/bus.h>
44#include <sparc/dev/sbusvar.h>
45#include <machine/autoconf.h>
46#include <machine/cpu.h>
47#include <machine/ctlreg.h>
48#include <sparc/sparc/asm.h>
49#include <sparc/dev/sxvar.h>
50#include <sparc/dev/sxreg.h>
51#include "opt_sx.h"
52
53/* autoconfiguration driver */
54static	int sx_match(device_t, struct cfdata *, void *);
55static	void sx_attach(device_t, device_t, void *);
56
57CFATTACH_DECL_NEW(sx, sizeof(struct sx_softc),
58    sx_match, sx_attach, NULL, NULL);
59
60static struct sx_softc *sx0 = NULL;
61
62static int
63sx_match(device_t parent, struct cfdata *cf, void *aux)
64{
65	struct mainbus_attach_args *ma = aux;
66
67	return (strcmp("SUNW,sx", ma->ma_name) == 0);
68}
69
70static void
71sx_attach(device_t parent, device_t self, void *aux)
72{
73	struct sx_softc *sc = device_private(self);
74	struct mainbus_attach_args *ma = aux;
75	uint32_t id;
76    	int i;
77#ifdef SX_DEBUG
78	int j;
79#endif
80
81	printf("\n");
82
83	sc->sc_dev = self;
84	sc->sc_tag = ma->ma_bustag;
85	sc->sc_uregs = ma->ma_paddr + 0x1000;
86	sc->sc_cnt = 0;
87
88	if (bus_space_map(sc->sc_tag, ma->ma_paddr, 0x1000, 0, &sc->sc_regh)) {
89		aprint_error_dev(self, "failed to map registers\n");
90		return;
91	}
92
93	id = sx_read(sc, SX_ID);
94	aprint_normal_dev(self, "architecture rev. %d chip rev. %d\n",
95	    (id & SX_ARCHITECTURE_MASK),
96	    (id & SX_CHIP_REVISION) >> 3);
97
98	/* stop the processor */
99	sx_write(sc, SX_CONTROL_STATUS, 0);
100	/* initialize control registers, clear errors etc. */
101	sx_write(sc, SX_R0_INIT, 0);
102	sx_write(sc, SX_ERROR, 0);
103	/* default, to be overridden once cgfourteen takes over */
104	sx_write(sc, SX_PAGE_BOUND_LOWER, 0xfc000000);
105	/* cg14 takes up the whole 64MB chunk */
106	sx_write(sc, SX_PAGE_BOUND_UPPER, 0xffffffff);
107	sx_write(sc, SX_DIAGNOSTICS, SX_DIAG_INIT);
108	sx_write(sc, SX_PLANEMASK, 0xffffffff);
109
110	/*
111	 * initialize all other registers
112	 * use the direct port since the processor is stopped
113	 */
114	for (i = 4; i < 0x200; i += 4)
115		sx_write(sc, SX_DIRECT_R0 + i, 0);
116
117	/* ... and start the processor again */
118	sx_write(sc, SX_CONTROL_STATUS, SX_PB | SX_GO);
119
120	sx0 = sc;
121
122#ifdef SX_DEBUG
123	sta(0xfc000000, ASI_SX, SX_LD(8, 31, 0));
124	for (i = 1; i < 60; i++)
125		sta(0xfc000000 + (i * 1280), ASI_SX, SX_ST(8, 31, 0));
126	for (i = 900; i < 1000; i++)
127		sta(0xfc000000 + (i * 1280) + 600, ASI_SX, SX_ST(0, 31, 0));
128
129    	for (i = 0; i < 0x30; i+= 16) {
130    		printf("%08x:", i);
131    		for (j = 0; j < 16; j += 4) {
132			if ((i + j) > 0x28) continue;
133    			printf(" %08x",
134    			    bus_space_read_4(sc->sc_tag, sc->sc_regh, i + j));
135		}
136		printf("\n");
137	}
138	printf("registers:\n");
139    	for (i = 0x300; i < 0x500; i+= 16) {
140    		printf("%08x:", i);
141    		for (j = 0; j < 16; j += 4) {
142    			printf(" %08x",
143    			    bus_space_read_4(sc->sc_tag, sc->sc_regh,
144    			        i + j));
145		}
146		printf("\n");
147	}
148#endif
149}
150
151void
152sx_dump(void)
153{
154	if (sx0 == NULL)
155		return;
156	printf("SX STATUS: %08x\n",
157	    bus_space_read_4(sx0->sc_tag, sx0->sc_regh, SX_CONTROL_STATUS));
158	printf("SX ERROR : %08x\n",
159	    bus_space_read_4(sx0->sc_tag, sx0->sc_regh, SX_ERROR));
160	printf("SX DIAG  : %08x\n",
161	    bus_space_read_4(sx0->sc_tag, sx0->sc_regh, SX_DIAGNOSTICS));
162}
163