1*8d564c5dSskrll /* $NetBSD: apple_platform.c,v 1.6 2023/04/07 08:55:29 skrll Exp $ */
2db7e12daSjmcneill
3db7e12daSjmcneill /*-
4db7e12daSjmcneill * Copyright (c) 2021 Jared McNeill <jmcneill@invisible.ca>
5db7e12daSjmcneill * All rights reserved.
6db7e12daSjmcneill *
7db7e12daSjmcneill * Redistribution and use in source and binary forms, with or without
8db7e12daSjmcneill * modification, are permitted provided that the following conditions
9db7e12daSjmcneill * are met:
10db7e12daSjmcneill * 1. Redistributions of source code must retain the above copyright
11db7e12daSjmcneill * notice, this list of conditions and the following disclaimer.
12db7e12daSjmcneill * 2. Redistributions in binary form must reproduce the above copyright
13db7e12daSjmcneill * notice, this list of conditions and the following disclaimer in the
14db7e12daSjmcneill * documentation and/or other materials provided with the distribution.
15db7e12daSjmcneill *
16db7e12daSjmcneill * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17db7e12daSjmcneill * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18db7e12daSjmcneill * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19db7e12daSjmcneill * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20db7e12daSjmcneill * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21db7e12daSjmcneill * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22db7e12daSjmcneill * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23db7e12daSjmcneill * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24db7e12daSjmcneill * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25db7e12daSjmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26db7e12daSjmcneill * SUCH DAMAGE.
27db7e12daSjmcneill */
28db7e12daSjmcneill
29db7e12daSjmcneill #include <sys/cdefs.h>
30*8d564c5dSskrll __KERNEL_RCSID(0, "$NetBSD: apple_platform.c,v 1.6 2023/04/07 08:55:29 skrll Exp $");
31db7e12daSjmcneill
32db7e12daSjmcneill #include <sys/param.h>
33db7e12daSjmcneill #include <sys/bus.h>
34db7e12daSjmcneill #include <sys/cpu.h>
35db7e12daSjmcneill #include <sys/device.h>
36db7e12daSjmcneill #include <sys/termios.h>
37db7e12daSjmcneill
38db7e12daSjmcneill #include <dev/fdt/fdtvar.h>
39*8d564c5dSskrll
40db7e12daSjmcneill #include <arm/fdt/arm_fdtvar.h>
41db7e12daSjmcneill
42db7e12daSjmcneill #include <uvm/uvm_extern.h>
43db7e12daSjmcneill
44db7e12daSjmcneill #include <machine/bootconfig.h>
45db7e12daSjmcneill
46db7e12daSjmcneill #include <net/if_ether.h>
47db7e12daSjmcneill
48db7e12daSjmcneill #include <dev/pci/pcivar.h>
49db7e12daSjmcneill #include <machine/pci_machdep.h>
50db7e12daSjmcneill
51db7e12daSjmcneill #include <arm/cpufunc.h>
52db7e12daSjmcneill
53db7e12daSjmcneill #include <arm/cortex/gtmr_var.h>
54db7e12daSjmcneill
55db7e12daSjmcneill #include <arm/arm/psci.h>
56db7e12daSjmcneill #include <arm/fdt/psci_fdtvar.h>
57db7e12daSjmcneill
58db7e12daSjmcneill #include <libfdt.h>
59db7e12daSjmcneill
60db7e12daSjmcneill #include <arch/evbarm/fdt/platform.h>
61db7e12daSjmcneill
62db7e12daSjmcneill extern struct bus_space arm_generic_bs_tag;
63db7e12daSjmcneill
64c0c3cbe3Sjmcneill static struct bus_space apple_nonposted_bs_tag;
65c0c3cbe3Sjmcneill
66db7e12daSjmcneill struct arm32_bus_dma_tag apple_coherent_dma_tag;
67db7e12daSjmcneill static struct arm32_dma_range apple_coherent_ranges[] = {
68db7e12daSjmcneill [0] = {
69db7e12daSjmcneill .dr_sysbase = 0,
70db7e12daSjmcneill .dr_busbase = 0,
71db7e12daSjmcneill .dr_len = UINTPTR_MAX,
72db7e12daSjmcneill .dr_flags = _BUS_DMAMAP_COHERENT,
73db7e12daSjmcneill }
74db7e12daSjmcneill };
75db7e12daSjmcneill
76c0c3cbe3Sjmcneill static int
apple_nonposted_bs_map(void * t,bus_addr_t bpa,bus_size_t size,int flag,bus_space_handle_t * bshp)77c0c3cbe3Sjmcneill apple_nonposted_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flag,
78c0c3cbe3Sjmcneill bus_space_handle_t *bshp)
79c0c3cbe3Sjmcneill {
80c0c3cbe3Sjmcneill if (flag == 0) {
815158b98cSjmcneill flag |= BUS_SPACE_MAP_NONPOSTED;
82c0c3cbe3Sjmcneill }
83c0c3cbe3Sjmcneill
84c0c3cbe3Sjmcneill return bus_space_map(&arm_generic_bs_tag, bpa, size, flag, bshp);
85c0c3cbe3Sjmcneill }
86c0c3cbe3Sjmcneill
87db7e12daSjmcneill static void
apple_platform_bootstrap(void)88db7e12daSjmcneill apple_platform_bootstrap(void)
89db7e12daSjmcneill {
90db7e12daSjmcneill extern struct arm32_bus_dma_tag arm_generic_dma_tag;
91db7e12daSjmcneill
92c0c3cbe3Sjmcneill apple_nonposted_bs_tag = arm_generic_bs_tag;
93c0c3cbe3Sjmcneill apple_nonposted_bs_tag.bs_map = apple_nonposted_bs_map;
94c0c3cbe3Sjmcneill
95db7e12daSjmcneill apple_coherent_dma_tag = arm_generic_dma_tag;
96db7e12daSjmcneill apple_coherent_dma_tag._ranges = apple_coherent_ranges;
97db7e12daSjmcneill apple_coherent_dma_tag._nranges = __arraycount(apple_coherent_ranges);
98db7e12daSjmcneill
99db7e12daSjmcneill arm_fdt_cpu_bootstrap();
100db7e12daSjmcneill }
101db7e12daSjmcneill
102db7e12daSjmcneill static void
apple_platform_init_attach_args(struct fdt_attach_args * faa)103db7e12daSjmcneill apple_platform_init_attach_args(struct fdt_attach_args *faa)
104db7e12daSjmcneill {
105c0c3cbe3Sjmcneill faa->faa_bst = &apple_nonposted_bs_tag;
106db7e12daSjmcneill faa->faa_dmat = &apple_coherent_dma_tag;
107db7e12daSjmcneill }
108db7e12daSjmcneill
109db7e12daSjmcneill static const struct pmap_devmap *
apple_platform_devmap(void)110db7e12daSjmcneill apple_platform_devmap(void)
111db7e12daSjmcneill {
112db7e12daSjmcneill /* Size this to hold possible entries for the UART and SMP spin-table */
113db7e12daSjmcneill static struct pmap_devmap devmap[] = {
114db7e12daSjmcneill DEVMAP_ENTRY_END,
115db7e12daSjmcneill DEVMAP_ENTRY_END,
116db7e12daSjmcneill DEVMAP_ENTRY_END
117db7e12daSjmcneill };
118db7e12daSjmcneill bus_addr_t uart_base;
119db7e12daSjmcneill vaddr_t devmap_va = KERNEL_IO_VBASE;
120db7e12daSjmcneill u_int devmap_index = 0;
121db7e12daSjmcneill uint64_t release_addr;
122db7e12daSjmcneill int phandle;
123db7e12daSjmcneill
124db7e12daSjmcneill phandle = fdtbus_get_stdout_phandle();
125db7e12daSjmcneill if (phandle > 0 && fdtbus_get_reg(phandle, 0, &uart_base, NULL) == 0) {
126db7e12daSjmcneill devmap[devmap_index].pd_pa = DEVMAP_ALIGN(uart_base);
127db7e12daSjmcneill devmap[devmap_index].pd_va = DEVMAP_ALIGN(devmap_va);
128db7e12daSjmcneill devmap[devmap_index].pd_size = DEVMAP_SIZE(L3_SIZE);
129db7e12daSjmcneill devmap[devmap_index].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
1305158b98cSjmcneill devmap[devmap_index].pd_flags = PMAP_DEV_NP;
131db7e12daSjmcneill devmap_va = DEVMAP_SIZE(devmap[devmap_index].pd_va +
132db7e12daSjmcneill devmap[devmap_index].pd_size);
133db7e12daSjmcneill devmap_index++;
134db7e12daSjmcneill }
135db7e12daSjmcneill
136db7e12daSjmcneill /* XXX hopefully all release addresses are in the same 2M */
137db7e12daSjmcneill phandle = OF_finddevice("/cpus/cpu@1");
138db7e12daSjmcneill if (phandle > 0 &&
139db7e12daSjmcneill of_getprop_uint64(phandle, "cpu-release-addr", &release_addr) == 0) {
140db7e12daSjmcneill devmap[devmap_index].pd_pa = DEVMAP_ALIGN(release_addr);
141db7e12daSjmcneill devmap[devmap_index].pd_va = DEVMAP_ALIGN(devmap_va);
142db7e12daSjmcneill devmap[devmap_index].pd_size = DEVMAP_SIZE(L2_SIZE);
143db7e12daSjmcneill devmap[devmap_index].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
144db7e12daSjmcneill devmap[devmap_index].pd_flags = PMAP_WRITE_BACK;
145db7e12daSjmcneill devmap_va = DEVMAP_SIZE(devmap[devmap_index].pd_va +
146db7e12daSjmcneill devmap[devmap_index].pd_size);
147db7e12daSjmcneill devmap_index++;
148db7e12daSjmcneill }
149db7e12daSjmcneill
150db7e12daSjmcneill return devmap;
151db7e12daSjmcneill }
152db7e12daSjmcneill
153db7e12daSjmcneill static u_int
apple_platform_uart_freq(void)154*8d564c5dSskrll apple_platform_uart_freq(void)
155db7e12daSjmcneill {
156db7e12daSjmcneill return 0;
157db7e12daSjmcneill }
158db7e12daSjmcneill
159db7e12daSjmcneill static int
apple_platform_get_mac_address(pci_chipset_tag_t pc,pcitag_t tag,uint8_t * eaddr)160db7e12daSjmcneill apple_platform_get_mac_address(pci_chipset_tag_t pc, pcitag_t tag,
161db7e12daSjmcneill uint8_t *eaddr)
162db7e12daSjmcneill {
163db7e12daSjmcneill int b, d, f;
164db7e12daSjmcneill int bridge, len;
165db7e12daSjmcneill u_int bdf;
166db7e12daSjmcneill
167db7e12daSjmcneill const int pcie = of_find_bycompat(OF_finddevice("/"), "apple,pcie");
168db7e12daSjmcneill if (pcie == -1) {
169db7e12daSjmcneill return -1;
170db7e12daSjmcneill }
171db7e12daSjmcneill
172db7e12daSjmcneill /* Convert PCI tag to encoding of phys.hi for PCI-PCI bridge regs */
173db7e12daSjmcneill pci_decompose_tag(pc, tag, &b, &d, &f);
174db7e12daSjmcneill bdf = (b << 16) | (d << 11) | (f << 8);
175db7e12daSjmcneill
176db7e12daSjmcneill for (bridge = OF_child(pcie); bridge; bridge = OF_peer(bridge)) {
177db7e12daSjmcneill const int ethernet =
178db7e12daSjmcneill of_find_firstchild_byname(bridge, "ethernet");
179db7e12daSjmcneill if (ethernet == -1) {
180db7e12daSjmcneill continue;
181db7e12daSjmcneill }
182db7e12daSjmcneill const u_int *data = fdtbus_get_prop(ethernet, "reg", &len);
183db7e12daSjmcneill if (data == NULL || len < 4) {
184db7e12daSjmcneill continue;
185db7e12daSjmcneill }
186db7e12daSjmcneill if (bdf != be32toh(data[0])) {
187db7e12daSjmcneill continue;
188db7e12daSjmcneill }
189db7e12daSjmcneill
190db7e12daSjmcneill return OF_getprop(ethernet, "local-mac-address",
191db7e12daSjmcneill eaddr, ETHER_ADDR_LEN);
192db7e12daSjmcneill }
193db7e12daSjmcneill
194db7e12daSjmcneill return -1;
195db7e12daSjmcneill }
196db7e12daSjmcneill
197db7e12daSjmcneill static void
apple_platform_device_register(device_t self,void * aux)198db7e12daSjmcneill apple_platform_device_register(device_t self, void *aux)
199db7e12daSjmcneill {
200db7e12daSjmcneill prop_dictionary_t prop = device_properties(self);
201db7e12daSjmcneill uint8_t eaddr[ETHER_ADDR_LEN];
202db7e12daSjmcneill int len;
203db7e12daSjmcneill
204920eacd3Sjmcneill if (device_is_a(self, "cpu")) {
205920eacd3Sjmcneill struct fdt_attach_args * const faa = aux;
206bf89bbcfSjmcneill bus_addr_t cpuid;
207920eacd3Sjmcneill
208bf89bbcfSjmcneill if (fdtbus_get_reg(faa->faa_phandle, 0, &cpuid, NULL) != 0) {
209bf89bbcfSjmcneill cpuid = 0;
210920eacd3Sjmcneill }
211bf89bbcfSjmcneill
212bf89bbcfSjmcneill /*
213bf89bbcfSjmcneill * On Apple M1 (and hopefully later models), AFF2 is 0 for
214bf89bbcfSjmcneill * efficiency and 1 for performance cores. Use this value
215bf89bbcfSjmcneill * to provide a fake DMIPS/MHz value -- the actual number
216bf89bbcfSjmcneill * only matters in relation to the value presented by other
217bf89bbcfSjmcneill * cores.
218bf89bbcfSjmcneill */
219bf89bbcfSjmcneill const u_int aff2 = __SHIFTOUT(cpuid, MPIDR_AFF2);
220bf89bbcfSjmcneill prop_dictionary_set_uint32(prop, "capacity_dmips_mhz", aff2);
221920eacd3Sjmcneill return;
222920eacd3Sjmcneill }
223920eacd3Sjmcneill
224db7e12daSjmcneill if (device_is_a(self, "bge") &&
225db7e12daSjmcneill device_is_a(device_parent(self), "pci")) {
226db7e12daSjmcneill struct pci_attach_args * const pa = aux;
227db7e12daSjmcneill
228db7e12daSjmcneill len = apple_platform_get_mac_address(pa->pa_pc, pa->pa_tag,
229db7e12daSjmcneill eaddr);
230db7e12daSjmcneill if (len == ETHER_ADDR_LEN) {
231db7e12daSjmcneill prop_dictionary_set_bool(prop, "without-seeprom", true);
232db7e12daSjmcneill prop_dictionary_set_data(prop, "mac-address", eaddr,
233db7e12daSjmcneill sizeof(eaddr));
234db7e12daSjmcneill }
235db7e12daSjmcneill return;
236db7e12daSjmcneill }
237db7e12daSjmcneill }
238db7e12daSjmcneill
239*8d564c5dSskrll static const struct fdt_platform apple_fdt_platform = {
240*8d564c5dSskrll .fp_devmap = apple_platform_devmap,
241*8d564c5dSskrll .fp_bootstrap = apple_platform_bootstrap,
242*8d564c5dSskrll .fp_init_attach_args = apple_platform_init_attach_args,
243*8d564c5dSskrll .fp_reset = psci_fdt_reset,
244*8d564c5dSskrll .fp_delay = gtmr_delay,
245*8d564c5dSskrll .fp_uart_freq = apple_platform_uart_freq,
246*8d564c5dSskrll .fp_device_register = apple_platform_device_register,
247*8d564c5dSskrll .fp_mpstart = arm_fdt_cpu_mpstart,
248db7e12daSjmcneill };
249db7e12daSjmcneill
250*8d564c5dSskrll FDT_PLATFORM(apple_arm, "apple,arm-platform", &apple_fdt_platform);
251