16c8df582SJustin Hibbits /*-
26c8df582SJustin Hibbits * Copyright (C) 2006-2012 Semihalf
36c8df582SJustin Hibbits * All rights reserved.
46c8df582SJustin Hibbits *
56c8df582SJustin Hibbits * Redistribution and use in source and binary forms, with or without
66c8df582SJustin Hibbits * modification, are permitted provided that the following conditions
76c8df582SJustin Hibbits * are met:
86c8df582SJustin Hibbits * 1. Redistributions of source code must retain the above copyright
96c8df582SJustin Hibbits * notice, this list of conditions and the following disclaimer.
106c8df582SJustin Hibbits * 2. Redistributions in binary form must reproduce the above copyright
116c8df582SJustin Hibbits * notice, this list of conditions and the following disclaimer in the
126c8df582SJustin Hibbits * documentation and/or other materials provided with the distribution.
136c8df582SJustin Hibbits *
146c8df582SJustin Hibbits * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
156c8df582SJustin Hibbits * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
166c8df582SJustin Hibbits * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
176c8df582SJustin Hibbits * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
186c8df582SJustin Hibbits * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
196c8df582SJustin Hibbits * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
206c8df582SJustin Hibbits * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
216c8df582SJustin Hibbits * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
226c8df582SJustin Hibbits * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
236c8df582SJustin Hibbits * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
246c8df582SJustin Hibbits */
256c8df582SJustin Hibbits /*-
266c8df582SJustin Hibbits * Copyright (C) 2001 Benno Rice
276c8df582SJustin Hibbits * All rights reserved.
286c8df582SJustin Hibbits *
296c8df582SJustin Hibbits * Redistribution and use in source and binary forms, with or without
306c8df582SJustin Hibbits * modification, are permitted provided that the following conditions
316c8df582SJustin Hibbits * are met:
326c8df582SJustin Hibbits * 1. Redistributions of source code must retain the above copyright
336c8df582SJustin Hibbits * notice, this list of conditions and the following disclaimer.
346c8df582SJustin Hibbits * 2. Redistributions in binary form must reproduce the above copyright
356c8df582SJustin Hibbits * notice, this list of conditions and the following disclaimer in the
366c8df582SJustin Hibbits * documentation and/or other materials provided with the distribution.
376c8df582SJustin Hibbits *
386c8df582SJustin Hibbits * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
396c8df582SJustin Hibbits * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
406c8df582SJustin Hibbits * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
416c8df582SJustin Hibbits * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
426c8df582SJustin Hibbits * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
436c8df582SJustin Hibbits * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
446c8df582SJustin Hibbits * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
456c8df582SJustin Hibbits * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
466c8df582SJustin Hibbits * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
476c8df582SJustin Hibbits * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
486c8df582SJustin Hibbits * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $
496c8df582SJustin Hibbits */
506c8df582SJustin Hibbits /*-
516c8df582SJustin Hibbits * Copyright (C) 1995, 1996 Wolfgang Solfrank.
526c8df582SJustin Hibbits * Copyright (C) 1995, 1996 TooLs GmbH.
536c8df582SJustin Hibbits * All rights reserved.
546c8df582SJustin Hibbits *
556c8df582SJustin Hibbits * Redistribution and use in source and binary forms, with or without
566c8df582SJustin Hibbits * modification, are permitted provided that the following conditions
576c8df582SJustin Hibbits * are met:
586c8df582SJustin Hibbits * 1. Redistributions of source code must retain the above copyright
596c8df582SJustin Hibbits * notice, this list of conditions and the following disclaimer.
606c8df582SJustin Hibbits * 2. Redistributions in binary form must reproduce the above copyright
616c8df582SJustin Hibbits * notice, this list of conditions and the following disclaimer in the
626c8df582SJustin Hibbits * documentation and/or other materials provided with the distribution.
636c8df582SJustin Hibbits * 3. All advertising materials mentioning features or use of this software
646c8df582SJustin Hibbits * must display the following acknowledgement:
656c8df582SJustin Hibbits * This product includes software developed by TooLs GmbH.
666c8df582SJustin Hibbits * 4. The name of TooLs GmbH may not be used to endorse or promote products
676c8df582SJustin Hibbits * derived from this software without specific prior written permission.
686c8df582SJustin Hibbits *
696c8df582SJustin Hibbits * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
706c8df582SJustin Hibbits * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
716c8df582SJustin Hibbits * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
726c8df582SJustin Hibbits * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
736c8df582SJustin Hibbits * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
746c8df582SJustin Hibbits * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
756c8df582SJustin Hibbits * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
766c8df582SJustin Hibbits * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
776c8df582SJustin Hibbits * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
786c8df582SJustin Hibbits * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
796c8df582SJustin Hibbits */
806c8df582SJustin Hibbits
816c8df582SJustin Hibbits #include <sys/cdefs.h>
826c8df582SJustin Hibbits #include "opt_ddb.h"
836c8df582SJustin Hibbits #include "opt_hwpmc_hooks.h"
846c8df582SJustin Hibbits #include "opt_kstack_pages.h"
856c8df582SJustin Hibbits #include "opt_platform.h"
866c8df582SJustin Hibbits
876c8df582SJustin Hibbits #include <sys/types.h>
886c8df582SJustin Hibbits #include <sys/param.h>
896c8df582SJustin Hibbits #include <sys/proc.h>
906c8df582SJustin Hibbits #include <sys/systm.h>
916c8df582SJustin Hibbits #include <sys/time.h>
926c8df582SJustin Hibbits #include <sys/bio.h>
936c8df582SJustin Hibbits #include <sys/buf.h>
946c8df582SJustin Hibbits #include <sys/bus.h>
956c8df582SJustin Hibbits #include <sys/cons.h>
966c8df582SJustin Hibbits #include <sys/cpu.h>
976c8df582SJustin Hibbits #include <sys/kdb.h>
986c8df582SJustin Hibbits #include <sys/kernel.h>
996c8df582SJustin Hibbits #include <sys/lock.h>
1006c8df582SJustin Hibbits #include <sys/mutex.h>
1016c8df582SJustin Hibbits #include <sys/rwlock.h>
1026c8df582SJustin Hibbits #include <sys/sysctl.h>
1036c8df582SJustin Hibbits #include <sys/exec.h>
1046c8df582SJustin Hibbits #include <sys/ktr.h>
1056c8df582SJustin Hibbits #include <sys/syscallsubr.h>
1066c8df582SJustin Hibbits #include <sys/sysproto.h>
1076c8df582SJustin Hibbits #include <sys/signalvar.h>
1086c8df582SJustin Hibbits #include <sys/sysent.h>
1096c8df582SJustin Hibbits #include <sys/imgact.h>
1106c8df582SJustin Hibbits #include <sys/msgbuf.h>
1116c8df582SJustin Hibbits #include <sys/ptrace.h>
1126c8df582SJustin Hibbits
1136c8df582SJustin Hibbits #include <vm/vm.h>
1146c8df582SJustin Hibbits #include <vm/pmap.h>
115*45b69dd6SJustin Hibbits #include <vm/vm_extern.h>
1166c8df582SJustin Hibbits #include <vm/vm_page.h>
1176c8df582SJustin Hibbits #include <vm/vm_object.h>
1186c8df582SJustin Hibbits #include <vm/vm_pager.h>
1196c8df582SJustin Hibbits
1206c8df582SJustin Hibbits #include <machine/cpu.h>
1216c8df582SJustin Hibbits #include <machine/kdb.h>
1226c8df582SJustin Hibbits #include <machine/vmparam.h>
1236c8df582SJustin Hibbits #include <machine/spr.h>
1246c8df582SJustin Hibbits #include <machine/hid.h>
1256c8df582SJustin Hibbits #include <machine/psl.h>
1266c8df582SJustin Hibbits #include <machine/trap.h>
1276c8df582SJustin Hibbits #include <machine/md_var.h>
1286c8df582SJustin Hibbits #include <machine/mmuvar.h>
1296c8df582SJustin Hibbits #include <machine/sigframe.h>
1306c8df582SJustin Hibbits #include <machine/machdep.h>
1316c8df582SJustin Hibbits #include <machine/metadata.h>
1326c8df582SJustin Hibbits #include <machine/platform.h>
1336c8df582SJustin Hibbits
1346c8df582SJustin Hibbits #include <sys/linker.h>
1356c8df582SJustin Hibbits #include <sys/reboot.h>
1366c8df582SJustin Hibbits
1376c8df582SJustin Hibbits #include <contrib/libfdt/libfdt.h>
1386c8df582SJustin Hibbits #include <dev/fdt/fdt_common.h>
1396c8df582SJustin Hibbits #include <dev/ofw/openfirm.h>
1406c8df582SJustin Hibbits
1416c8df582SJustin Hibbits #ifdef DDB
1426c8df582SJustin Hibbits #include <ddb/ddb.h>
1436c8df582SJustin Hibbits #endif
1446c8df582SJustin Hibbits
1456c8df582SJustin Hibbits #ifdef DEBUG
1466c8df582SJustin Hibbits #define debugf(fmt, args...) printf(fmt, ##args)
1476c8df582SJustin Hibbits #else
1486c8df582SJustin Hibbits #define debugf(fmt, args...)
1496c8df582SJustin Hibbits #endif
1506c8df582SJustin Hibbits
1516c8df582SJustin Hibbits extern unsigned char _etext[];
1526c8df582SJustin Hibbits extern unsigned char _edata[];
1536c8df582SJustin Hibbits extern unsigned char __bss_start[];
1546c8df582SJustin Hibbits extern unsigned char __sbss_start[];
1556c8df582SJustin Hibbits extern unsigned char __sbss_end[];
1566c8df582SJustin Hibbits extern unsigned char _end[];
1576c8df582SJustin Hibbits extern vm_offset_t __endkernel;
1583c0b0819SJustin Hibbits extern vm_paddr_t kernload;
1596c8df582SJustin Hibbits
1606c8df582SJustin Hibbits /*
1616c8df582SJustin Hibbits * Bootinfo is passed to us by legacy loaders. Save the address of the
1626c8df582SJustin Hibbits * structure to handle backward compatibility.
1636c8df582SJustin Hibbits */
1646c8df582SJustin Hibbits uint32_t *bootinfo;
1656c8df582SJustin Hibbits
1666c8df582SJustin Hibbits void print_kernel_section_addr(void);
1676c8df582SJustin Hibbits void print_kenv(void);
1684717ada9SJustin Hibbits uintptr_t booke_init(u_long, u_long);
1696c8df582SJustin Hibbits void ivor_setup(void);
1706c8df582SJustin Hibbits
1716c8df582SJustin Hibbits extern void *interrupt_vector_base;
1726c8df582SJustin Hibbits extern void *int_critical_input;
1736c8df582SJustin Hibbits extern void *int_machine_check;
1746c8df582SJustin Hibbits extern void *int_data_storage;
1756c8df582SJustin Hibbits extern void *int_instr_storage;
1766c8df582SJustin Hibbits extern void *int_external_input;
1776c8df582SJustin Hibbits extern void *int_alignment;
178a39f1053SJustin Hibbits extern void *int_fpu;
1796c8df582SJustin Hibbits extern void *int_program;
1806c8df582SJustin Hibbits extern void *int_syscall;
1816c8df582SJustin Hibbits extern void *int_decrementer;
1826c8df582SJustin Hibbits extern void *int_fixed_interval_timer;
1836c8df582SJustin Hibbits extern void *int_watchdog;
1846c8df582SJustin Hibbits extern void *int_data_tlb_error;
1856c8df582SJustin Hibbits extern void *int_inst_tlb_error;
1866c8df582SJustin Hibbits extern void *int_debug;
18791722a2fSJustin Hibbits extern void *int_debug_ed;
188a39f1053SJustin Hibbits extern void *int_vec;
189a39f1053SJustin Hibbits extern void *int_vecast;
190289041e2SJustin Hibbits #ifdef __SPE__
191289041e2SJustin Hibbits extern void *int_spe_fpdata;
192289041e2SJustin Hibbits extern void *int_spe_fpround;
193289041e2SJustin Hibbits #endif
1946c8df582SJustin Hibbits #ifdef HWPMC_HOOKS
1956c8df582SJustin Hibbits extern void *int_performance_counter;
1966c8df582SJustin Hibbits #endif
1976c8df582SJustin Hibbits
1986c8df582SJustin Hibbits #define SET_TRAP(ivor, handler) \
1996c8df582SJustin Hibbits KASSERT(((uintptr_t)(&handler) & ~0xffffUL) == \
2006c8df582SJustin Hibbits ((uintptr_t)(&interrupt_vector_base) & ~0xffffUL), \
2016c8df582SJustin Hibbits ("Handler " #handler " too far from interrupt vector base")); \
2026c8df582SJustin Hibbits mtspr(ivor, (uintptr_t)(&handler) & 0xffffUL);
2036c8df582SJustin Hibbits
20447f69f4fSNathan Whitehorn uintptr_t powerpc_init(vm_offset_t fdt, vm_offset_t, vm_offset_t, void *mdp,
205d6716aa2SNathan Whitehorn uint32_t mdp_cookie);
2066c8df582SJustin Hibbits void booke_cpu_init(void);
2076c8df582SJustin Hibbits
2086c8df582SJustin Hibbits void
booke_cpu_init(void)2096c8df582SJustin Hibbits booke_cpu_init(void)
2106c8df582SJustin Hibbits {
2116c8df582SJustin Hibbits
212b0bf7fcdSNathan Whitehorn cpu_features |= PPC_FEATURE_BOOKE;
213b0bf7fcdSNathan Whitehorn
21461928298SNathan Whitehorn psl_kernset = PSL_CE | PSL_ME | PSL_EE;
21561928298SNathan Whitehorn #ifdef __powerpc64__
21661928298SNathan Whitehorn psl_kernset |= PSL_CM;
21761928298SNathan Whitehorn #endif
21861928298SNathan Whitehorn psl_userset = psl_kernset | PSL_PR;
21961928298SNathan Whitehorn #ifdef __powerpc64__
2205903f595SJustin Hibbits psl_userset32 = psl_userset & ~PSL_CM;
22161928298SNathan Whitehorn #endif
222d98eb707SBrandon Bergren /*
223d98eb707SBrandon Bergren * Zeroed bits in this variable signify that the value of the bit
224d98eb707SBrandon Bergren * in its position is allowed to vary between userspace contexts.
225d98eb707SBrandon Bergren *
226d98eb707SBrandon Bergren * All other bits are required to be identical for every userspace
227d98eb707SBrandon Bergren * context. The actual *value* of the bit is determined by
228d98eb707SBrandon Bergren * psl_userset and/or psl_userset32, and is not allowed to change.
229d98eb707SBrandon Bergren *
230d98eb707SBrandon Bergren * Remember to update this set when implementing support for
231d98eb707SBrandon Bergren * *conditionally* enabling a processor facility. Failing to do
232d98eb707SBrandon Bergren * this will cause swapcontext() in userspace to break when a
233d98eb707SBrandon Bergren * process uses a conditionally-enabled facility.
234d98eb707SBrandon Bergren *
235d98eb707SBrandon Bergren * When *unconditionally* implementing support for a processor
236d98eb707SBrandon Bergren * facility, update psl_userset / psl_userset32 instead.
237d98eb707SBrandon Bergren *
238d98eb707SBrandon Bergren * See the access control check in set_mcontext().
239d98eb707SBrandon Bergren */
24061928298SNathan Whitehorn psl_userstatic = ~(PSL_VEC | PSL_FP | PSL_FE0 | PSL_FE1);
24161928298SNathan Whitehorn
2426c8df582SJustin Hibbits pmap_mmu_install(MMU_TYPE_BOOKE, BUS_PROBE_GENERIC);
2436c8df582SJustin Hibbits }
2446c8df582SJustin Hibbits
2456c8df582SJustin Hibbits void
ivor_setup(void)2466c8df582SJustin Hibbits ivor_setup(void)
2476c8df582SJustin Hibbits {
2486c8df582SJustin Hibbits
249e683c328SJustin Hibbits mtspr(SPR_IVPR, ((uintptr_t)&interrupt_vector_base) & ~0xffffUL);
2506c8df582SJustin Hibbits
2516c8df582SJustin Hibbits SET_TRAP(SPR_IVOR0, int_critical_input);
2526c8df582SJustin Hibbits SET_TRAP(SPR_IVOR1, int_machine_check);
2536c8df582SJustin Hibbits SET_TRAP(SPR_IVOR2, int_data_storage);
2546c8df582SJustin Hibbits SET_TRAP(SPR_IVOR3, int_instr_storage);
2556c8df582SJustin Hibbits SET_TRAP(SPR_IVOR4, int_external_input);
2566c8df582SJustin Hibbits SET_TRAP(SPR_IVOR5, int_alignment);
2576c8df582SJustin Hibbits SET_TRAP(SPR_IVOR6, int_program);
2586c8df582SJustin Hibbits SET_TRAP(SPR_IVOR8, int_syscall);
2596c8df582SJustin Hibbits SET_TRAP(SPR_IVOR10, int_decrementer);
2606c8df582SJustin Hibbits SET_TRAP(SPR_IVOR11, int_fixed_interval_timer);
2616c8df582SJustin Hibbits SET_TRAP(SPR_IVOR12, int_watchdog);
2626c8df582SJustin Hibbits SET_TRAP(SPR_IVOR13, int_data_tlb_error);
2636c8df582SJustin Hibbits SET_TRAP(SPR_IVOR14, int_inst_tlb_error);
2646c8df582SJustin Hibbits SET_TRAP(SPR_IVOR15, int_debug);
2656c8df582SJustin Hibbits #ifdef HWPMC_HOOKS
2666c8df582SJustin Hibbits SET_TRAP(SPR_IVOR35, int_performance_counter);
2676c8df582SJustin Hibbits #endif
268a39f1053SJustin Hibbits switch ((mfpvr() >> 16) & 0xffff) {
269a39f1053SJustin Hibbits case FSL_E6500:
270a39f1053SJustin Hibbits SET_TRAP(SPR_IVOR32, int_vec);
271a39f1053SJustin Hibbits SET_TRAP(SPR_IVOR33, int_vecast);
272a39f1053SJustin Hibbits /* FALLTHROUGH */
273a39f1053SJustin Hibbits case FSL_E500mc:
274a39f1053SJustin Hibbits case FSL_E5500:
275a39f1053SJustin Hibbits SET_TRAP(SPR_IVOR7, int_fpu);
27691722a2fSJustin Hibbits SET_TRAP(SPR_IVOR15, int_debug_ed);
277dc9b124dSJustin Hibbits break;
278dc9b124dSJustin Hibbits case FSL_E500v1:
279dc9b124dSJustin Hibbits case FSL_E500v2:
280dc9b124dSJustin Hibbits SET_TRAP(SPR_IVOR32, int_vec);
281289041e2SJustin Hibbits #ifdef __SPE__
282289041e2SJustin Hibbits SET_TRAP(SPR_IVOR33, int_spe_fpdata);
283289041e2SJustin Hibbits SET_TRAP(SPR_IVOR34, int_spe_fpround);
284289041e2SJustin Hibbits #endif
285dc9b124dSJustin Hibbits break;
286a39f1053SJustin Hibbits }
287e683c328SJustin Hibbits
288e683c328SJustin Hibbits #ifdef __powerpc64__
289e683c328SJustin Hibbits /* Set 64-bit interrupt mode. */
290e683c328SJustin Hibbits mtspr(SPR_EPCR, mfspr(SPR_EPCR) | EPCR_ICM);
291e683c328SJustin Hibbits #endif
2926c8df582SJustin Hibbits }
2936c8df582SJustin Hibbits
2946c8df582SJustin Hibbits static int
booke_check_for_fdt(uint32_t arg1,vm_offset_t * dtbp)2956c8df582SJustin Hibbits booke_check_for_fdt(uint32_t arg1, vm_offset_t *dtbp)
2966c8df582SJustin Hibbits {
2976c8df582SJustin Hibbits void *ptr;
29860152a40SJustin Hibbits int fdt_size;
2996c8df582SJustin Hibbits
3006c8df582SJustin Hibbits if (arg1 % 8 != 0)
3016c8df582SJustin Hibbits return (-1);
3026c8df582SJustin Hibbits
3036c8df582SJustin Hibbits ptr = (void *)pmap_early_io_map(arg1, PAGE_SIZE);
3046c8df582SJustin Hibbits if (fdt_check_header(ptr) != 0)
3056c8df582SJustin Hibbits return (-1);
3066c8df582SJustin Hibbits
30760152a40SJustin Hibbits /*
30860152a40SJustin Hibbits * Read FDT total size from the header of FDT.
30960152a40SJustin Hibbits * This for sure hits within first page which is
31060152a40SJustin Hibbits * already mapped.
31160152a40SJustin Hibbits */
31260152a40SJustin Hibbits fdt_size = fdt_totalsize((void *)ptr);
31360152a40SJustin Hibbits
31460152a40SJustin Hibbits /*
31560152a40SJustin Hibbits * Ok, arg1 points to FDT, so we need to map it in.
31660152a40SJustin Hibbits * First, unmap this page and then map FDT again with full size
31760152a40SJustin Hibbits */
31860152a40SJustin Hibbits pmap_early_io_unmap((vm_offset_t)ptr, PAGE_SIZE);
31960152a40SJustin Hibbits ptr = (void *)pmap_early_io_map(arg1, fdt_size);
3206c8df582SJustin Hibbits *dtbp = (vm_offset_t)ptr;
3216c8df582SJustin Hibbits
3226c8df582SJustin Hibbits return (0);
3236c8df582SJustin Hibbits }
3246c8df582SJustin Hibbits
3256c8df582SJustin Hibbits uintptr_t
booke_init(u_long arg1,u_long arg2)3264717ada9SJustin Hibbits booke_init(u_long arg1, u_long arg2)
3276c8df582SJustin Hibbits {
3286c8df582SJustin Hibbits uintptr_t ret;
3296c8df582SJustin Hibbits void *mdp;
3306c8df582SJustin Hibbits vm_offset_t dtbp, end;
3316c8df582SJustin Hibbits
3326c8df582SJustin Hibbits end = (uintptr_t)_end;
3336c8df582SJustin Hibbits dtbp = (vm_offset_t)NULL;
3346c8df582SJustin Hibbits
3356c8df582SJustin Hibbits /* Set up TLB initially */
3366c8df582SJustin Hibbits bootinfo = NULL;
3376c8df582SJustin Hibbits bzero(__sbss_start, __sbss_end - __sbss_start);
3386c8df582SJustin Hibbits bzero(__bss_start, _end - __bss_start);
3396c8df582SJustin Hibbits tlb1_init();
3406c8df582SJustin Hibbits
3416c8df582SJustin Hibbits /*
3426c8df582SJustin Hibbits * Handle the various ways we can get loaded and started:
3436c8df582SJustin Hibbits * - FreeBSD's loader passes the pointer to the metadata
3446c8df582SJustin Hibbits * in arg1, with arg2 undefined. arg1 has a value that's
3456c8df582SJustin Hibbits * relative to the kernel's link address (i.e. larger
3466c8df582SJustin Hibbits * than 0xc0000000).
3476c8df582SJustin Hibbits * - Juniper's loader passes the metadata pointer in arg2
3486c8df582SJustin Hibbits * and sets arg1 to zero. This is to signal that the
3496c8df582SJustin Hibbits * loader maps the kernel and starts it at its link
3506c8df582SJustin Hibbits * address (unlike the FreeBSD loader).
3516c8df582SJustin Hibbits * - U-Boot passes the standard argc and argv parameters
3526c8df582SJustin Hibbits * in arg1 and arg2 (resp). arg1 is between 1 and some
3536c8df582SJustin Hibbits * relatively small number, such as 64K. arg2 is the
3546c8df582SJustin Hibbits * physical address of the argv vector.
3556c8df582SJustin Hibbits * - ePAPR loaders pass an FDT blob in r3 (arg1) and the magic hex
356777d81afSJustin Hibbits * string 0x45504150 ('EPAP') in r6 (which has been lost by now).
3576c8df582SJustin Hibbits * r4 (arg2) is supposed to be set to zero, but is not always.
3586c8df582SJustin Hibbits */
3596c8df582SJustin Hibbits
3606c8df582SJustin Hibbits if (arg1 == 0) /* Juniper loader */
3616c8df582SJustin Hibbits mdp = (void *)arg2;
3626c8df582SJustin Hibbits else if (booke_check_for_fdt(arg1, &dtbp) == 0) { /* ePAPR */
3636c8df582SJustin Hibbits end = roundup(end, 8);
3646c8df582SJustin Hibbits memmove((void *)end, (void *)dtbp, fdt_totalsize((void *)dtbp));
3656c8df582SJustin Hibbits dtbp = end;
3666c8df582SJustin Hibbits end += fdt_totalsize((void *)dtbp);
3676c8df582SJustin Hibbits __endkernel = end;
3686c8df582SJustin Hibbits mdp = NULL;
3693c0b0819SJustin Hibbits } else if (arg1 > (uintptr_t)kernload) /* FreeBSD loader */
3706c8df582SJustin Hibbits mdp = (void *)arg1;
3716c8df582SJustin Hibbits else /* U-Boot */
3726c8df582SJustin Hibbits mdp = NULL;
3736c8df582SJustin Hibbits
3743f068cbfSJustin Hibbits /* Default to 32 byte cache line size. */
3753f068cbfSJustin Hibbits switch ((mfpvr()) >> 16) {
3763f068cbfSJustin Hibbits case FSL_E500mc:
3773f068cbfSJustin Hibbits case FSL_E5500:
3783f068cbfSJustin Hibbits case FSL_E6500:
3793f068cbfSJustin Hibbits cacheline_size = 64;
3803f068cbfSJustin Hibbits break;
3813f068cbfSJustin Hibbits }
3823f068cbfSJustin Hibbits
38347f69f4fSNathan Whitehorn /*
38447f69f4fSNathan Whitehorn * Last element is a magic cookie that indicates that the metadata
38547f69f4fSNathan Whitehorn * pointer is meaningful.
38647f69f4fSNathan Whitehorn */
38747f69f4fSNathan Whitehorn ret = powerpc_init(dtbp, 0, 0, mdp, (mdp == NULL) ? 0 : 0xfb5d104d);
388a917f636SJustin Hibbits
3893f068cbfSJustin Hibbits /* Enable caches */
3906c8df582SJustin Hibbits booke_enable_l1_cache();
3913f068cbfSJustin Hibbits booke_enable_l2_cache();
3923f068cbfSJustin Hibbits
3933f068cbfSJustin Hibbits booke_enable_bpred();
3946c8df582SJustin Hibbits
3956c8df582SJustin Hibbits return (ret);
3966c8df582SJustin Hibbits }
3976c8df582SJustin Hibbits
3982d5320a8SJustin Hibbits #define RES_GRANULE cacheline_size
399e683c328SJustin Hibbits extern uintptr_t tlb0_miss_locks[];
4006c8df582SJustin Hibbits
4016c8df582SJustin Hibbits /* Initialise a struct pcpu. */
4026c8df582SJustin Hibbits void
cpu_pcpu_init(struct pcpu * pcpu,int cpuid,size_t sz)4036c8df582SJustin Hibbits cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
4046c8df582SJustin Hibbits {
4056c8df582SJustin Hibbits
406bce6d88bSJustin Hibbits pcpu->pc_booke.tid_next = TID_MIN;
4076c8df582SJustin Hibbits
4086c8df582SJustin Hibbits #ifdef SMP
409e683c328SJustin Hibbits uintptr_t *ptr;
410e683c328SJustin Hibbits int words_per_gran = RES_GRANULE / sizeof(uintptr_t);
4116c8df582SJustin Hibbits
4126c8df582SJustin Hibbits ptr = &tlb0_miss_locks[cpuid * words_per_gran];
413bce6d88bSJustin Hibbits pcpu->pc_booke.tlb_lock = ptr;
4146c8df582SJustin Hibbits *ptr = TLB_UNLOCKED;
4156c8df582SJustin Hibbits *(ptr + 1) = 0; /* recurse counter */
4166c8df582SJustin Hibbits #endif
4176c8df582SJustin Hibbits }
4186c8df582SJustin Hibbits
4196c8df582SJustin Hibbits /* Shutdown the CPU as much as possible. */
4206c8df582SJustin Hibbits void
cpu_halt(void)4216c8df582SJustin Hibbits cpu_halt(void)
4226c8df582SJustin Hibbits {
4236c8df582SJustin Hibbits
4246c8df582SJustin Hibbits mtmsr(mfmsr() & ~(PSL_CE | PSL_EE | PSL_ME | PSL_DE));
4256c8df582SJustin Hibbits while (1)
4266c8df582SJustin Hibbits ;
4276c8df582SJustin Hibbits }
4286c8df582SJustin Hibbits
4296c8df582SJustin Hibbits int
ptrace_single_step(struct thread * td)4306c8df582SJustin Hibbits ptrace_single_step(struct thread *td)
4316c8df582SJustin Hibbits {
4326c8df582SJustin Hibbits struct trapframe *tf;
4336c8df582SJustin Hibbits
4346c8df582SJustin Hibbits tf = td->td_frame;
4356c8df582SJustin Hibbits tf->srr1 |= PSL_DE;
4366c8df582SJustin Hibbits tf->cpu.booke.dbcr0 |= (DBCR0_IDM | DBCR0_IC);
4376c8df582SJustin Hibbits return (0);
4386c8df582SJustin Hibbits }
4396c8df582SJustin Hibbits
4406c8df582SJustin Hibbits int
ptrace_clear_single_step(struct thread * td)4416c8df582SJustin Hibbits ptrace_clear_single_step(struct thread *td)
4426c8df582SJustin Hibbits {
4436c8df582SJustin Hibbits struct trapframe *tf;
4446c8df582SJustin Hibbits
4456c8df582SJustin Hibbits tf = td->td_frame;
4466c8df582SJustin Hibbits tf->srr1 &= ~PSL_DE;
4476c8df582SJustin Hibbits tf->cpu.booke.dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
4486c8df582SJustin Hibbits return (0);
4496c8df582SJustin Hibbits }
4506c8df582SJustin Hibbits
4516c8df582SJustin Hibbits void
kdb_cpu_clear_singlestep(void)4526c8df582SJustin Hibbits kdb_cpu_clear_singlestep(void)
4536c8df582SJustin Hibbits {
4546c8df582SJustin Hibbits register_t r;
4556c8df582SJustin Hibbits
4566c8df582SJustin Hibbits r = mfspr(SPR_DBCR0);
4576c8df582SJustin Hibbits mtspr(SPR_DBCR0, r & ~DBCR0_IC);
4586c8df582SJustin Hibbits kdb_frame->srr1 &= ~PSL_DE;
4596c8df582SJustin Hibbits }
4606c8df582SJustin Hibbits
4616c8df582SJustin Hibbits void
kdb_cpu_set_singlestep(void)4626c8df582SJustin Hibbits kdb_cpu_set_singlestep(void)
4636c8df582SJustin Hibbits {
4646c8df582SJustin Hibbits register_t r;
4656c8df582SJustin Hibbits
4666c8df582SJustin Hibbits r = mfspr(SPR_DBCR0);
4676c8df582SJustin Hibbits mtspr(SPR_DBCR0, r | DBCR0_IC | DBCR0_IDM);
4686c8df582SJustin Hibbits kdb_frame->srr1 |= PSL_DE;
4696c8df582SJustin Hibbits }
470