1/*- 2 * Initial implementation: 3 * Copyright (c) 2001 Robert Drehmel 4 * All rights reserved. 5 * 6 * As long as the above copyright statement and this notice remain 7 * unchanged, you can do what ever you want with this file. 8 */ --- 19 unchanged lines hidden (view full) --- 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35#include <sys/cdefs.h> |
36__FBSDID("$FreeBSD: head/sys/boot/sparc64/loader/main.c 203829 2010-02-13 14:13:39Z marius $"); |
37 38/* 39 * FreeBSD/sparc64 kernel loader - machine dependent part 40 * 41 * - implements copyin and readin functions that map kernel 42 * pages on demand. The machine independent code does not 43 * know the size of the kernel early enough to pre-enter 44 * TTEs and install just one 4MB mapping seemed to limiting 45 * to me. 46 */ 47 48#include <stand.h> |
49#include <sys/param.h> |
50#include <sys/exec.h> |
51#include <sys/linker.h> |
52#include <sys/queue.h> |
53#include <sys/types.h> 54 55#include <vm/vm.h> 56#include <machine/asi.h> |
57#include <machine/cmt.h> |
58#include <machine/cpufunc.h> 59#include <machine/elf.h> |
60#include <machine/fireplane.h> 61#include <machine/jbus.h> |
62#include <machine/lsu.h> 63#include <machine/metadata.h> 64#include <machine/tte.h> 65#include <machine/tlb.h> 66#include <machine/upa.h> 67#include <machine/ver.h> 68#include <machine/vmparam.h> 69 70#include "bootstrap.h" 71#include "libofw.h" 72#include "dev_net.h" 73 |
74#ifndef CTASSERT 75#define CTASSERT(x) _CTASSERT(x, __LINE__) 76#define _CTASSERT(x, y) __CTASSERT(x, y) 77#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] 78#endif 79 |
80extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[]; 81 82enum { 83 HEAPVA = 0x800000, 84 HEAPSZ = 0x1000000, 85 LOADSZ = 0x1000000 /* for kernel and modules */ 86}; 87 |
88/* At least Sun Fire V1280 require page sized allocations to be claimed. */ 89CTASSERT(HEAPSZ % PAGE_SIZE == 0); 90 |
91static struct mmu_ops { 92 void (*tlb_init)(void); 93 int (*mmu_mapin)(vm_offset_t va, vm_size_t len); 94} *mmu_ops; 95 96typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3, 97 void *openfirmware); 98 |
99static inline u_long dtlb_get_data_sun4u(u_int); 100static void dtlb_enter_sun4u(u_long, u_long); |
101static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t); |
102static inline u_long itlb_get_data_sun4u(u_int); 103static void itlb_enter_sun4u(u_long, u_long); |
104static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t); 105static void itlb_relocate_locked0_sun4u(void); 106extern vm_offset_t md_load(char *, vm_offset_t *); 107static int sparc64_autoload(void); 108static ssize_t sparc64_readin(const int, vm_offset_t, const size_t); 109static ssize_t sparc64_copyin(const void *, vm_offset_t, size_t); 110static void sparc64_maphint(vm_offset_t, size_t); 111static vm_offset_t claim_virt(vm_offset_t, size_t, int); 112static vm_offset_t alloc_phys(size_t, int); 113static int map_phys(int, size_t, vm_offset_t, vm_offset_t); 114static void release_phys(vm_offset_t, u_int); 115static int __elfN(exec)(struct preloaded_file *); 116static int mmu_mapin_sun4u(vm_offset_t, vm_size_t); 117static int mmu_mapin_sun4v(vm_offset_t, vm_size_t); 118static vm_offset_t init_heap(void); |
119static phandle_t find_bsp_sun4u(phandle_t, uint32_t); 120const char *cpu_cpuid_prop_sun4u(void); 121uint32_t cpu_get_mid_sun4u(void); |
122static void tlb_init_sun4u(void); 123static void tlb_init_sun4v(void); 124 125#ifdef LOADER_DEBUG 126typedef u_int64_t tte_t; 127 128static void pmap_print_tlb_sun4u(void); 129static void pmap_print_tte_sun4u(tte_t, tte_t); 130#endif 131 132static struct mmu_ops mmu_ops_sun4u = { tlb_init_sun4u, mmu_mapin_sun4u }; 133static struct mmu_ops mmu_ops_sun4v = { tlb_init_sun4v, mmu_mapin_sun4v }; 134 135/* sun4u */ 136struct tlb_entry *dtlb_store; 137struct tlb_entry *itlb_store; |
138u_int dtlb_slot; 139u_int itlb_slot; |
140int cpu_impl; |
141static u_int dtlb_slot_max; 142static u_int itlb_slot_max; |
143 144/* sun4v */ 145static struct tlb_entry *tlb_store; 146static int is_sun4v = 0; 147/* 148 * no direct TLB access on sun4v 149 * we somewhat arbitrarily declare enough 150 * slots to cover a 4GB AS with 4MB pages --- 257 unchanged lines hidden (view full) --- 408 OF_release((void *)heapva, HEAPSZ); 409 410 ((kernel_entry_t *)entry)(mdp, 0, 0, 0, openfirmware); 411 412 panic("%s: exec returned", __func__); 413} 414 415static inline u_long |
416dtlb_get_data_sun4u(u_int slot) |
417{ 418 419 /* 420 * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work 421 * around errata of USIII and beyond. 422 */ 423 (void)ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG); 424 return (ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG)); 425} 426 427static inline u_long |
428itlb_get_data_sun4u(u_int slot) |
429{ 430 431 /* 432 * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work 433 * around errata of USIII and beyond. 434 */ 435 (void)ldxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG); 436 return (ldxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG)); --- 241 unchanged lines hidden (view full) --- 678init_heap(void) 679{ 680 681 /* There is no need for continuous physical heap memory. */ 682 heapva = (vm_offset_t)OF_claim((void *)HEAPVA, HEAPSZ, 32); 683 return (heapva); 684} 685 |
686static phandle_t 687find_bsp_sun4u(phandle_t node, uint32_t bspid) 688{ 689 char type[sizeof("cpu")]; 690 phandle_t child; 691 uint32_t cpuid; 692 693 for (; node > 0; node = OF_peer(node)) { 694 child = OF_child(node); 695 if (child > 0) { 696 child = find_bsp_sun4u(child, bspid); 697 if (child > 0) 698 return (child); 699 } else { 700 if (OF_getprop(node, "device_type", type, 701 sizeof(type)) <= 0) 702 continue; 703 if (strcmp(type, "cpu") != 0) 704 continue; 705 if (OF_getprop(node, cpu_cpuid_prop_sun4u(), &cpuid, 706 sizeof(cpuid)) <= 0) 707 continue; 708 if (cpuid == bspid) 709 return (node); 710 } 711 } 712 return (0); 713} 714 715const char * 716cpu_cpuid_prop_sun4u(void) 717{ 718 719 switch (cpu_impl) { 720 case CPU_IMPL_SPARC64: 721 case CPU_IMPL_ULTRASPARCI: 722 case CPU_IMPL_ULTRASPARCII: 723 case CPU_IMPL_ULTRASPARCIIi: 724 case CPU_IMPL_ULTRASPARCIIe: 725 return ("upa-portid"); 726 case CPU_IMPL_ULTRASPARCIII: 727 case CPU_IMPL_ULTRASPARCIIIp: 728 case CPU_IMPL_ULTRASPARCIIIi: 729 case CPU_IMPL_ULTRASPARCIIIip: 730 return ("portid"); 731 case CPU_IMPL_ULTRASPARCIV: 732 case CPU_IMPL_ULTRASPARCIVp: 733 return ("cpuid"); 734 default: 735 return (""); 736 } 737} 738 739uint32_t 740cpu_get_mid_sun4u(void) 741{ 742 743 switch (cpu_impl) { 744 case CPU_IMPL_SPARC64: 745 case CPU_IMPL_ULTRASPARCI: 746 case CPU_IMPL_ULTRASPARCII: 747 case CPU_IMPL_ULTRASPARCIIi: 748 case CPU_IMPL_ULTRASPARCIIe: 749 return (UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG))); 750 case CPU_IMPL_ULTRASPARCIII: 751 case CPU_IMPL_ULTRASPARCIIIp: 752 return (FIREPLANE_CR_GET_AID(ldxa(AA_FIREPLANE_CONFIG, 753 ASI_FIREPLANE_CONFIG_REG))); 754 case CPU_IMPL_ULTRASPARCIIIi: 755 case CPU_IMPL_ULTRASPARCIIIip: 756 return (JBUS_CR_GET_JID(ldxa(0, ASI_JBUS_CONFIG_REG))); 757 case CPU_IMPL_ULTRASPARCIV: 758 case CPU_IMPL_ULTRASPARCIVp: 759 return (INTR_ID_GET_ID(ldxa(AA_INTR_ID, ASI_INTR_ID))); 760 default: 761 return (0); 762 } 763} 764 |
765static void 766tlb_init_sun4u(void) 767{ |
768 phandle_t bsp; |
769 770 cpu_impl = VER_IMPL(rdpr(ver)); |
771 bsp = find_bsp_sun4u(OF_child(root), cpu_get_mid_sun4u()); 772 if (bsp == 0) |
773 panic("%s: no node for bootcpu?!?!", __func__); 774 |
775 if (OF_getprop(bsp, "#dtlb-entries", &dtlb_slot_max, |
776 sizeof(dtlb_slot_max)) == -1 || |
777 OF_getprop(bsp, "#itlb-entries", &itlb_slot_max, |
778 sizeof(itlb_slot_max)) == -1) 779 panic("%s: can't get TLB slot max.", __func__); 780 781 if (cpu_impl == CPU_IMPL_ULTRASPARCIIIp) { 782#ifdef LOADER_DEBUG 783 printf("pre fixup:\n"); 784 pmap_print_tlb_sun4u(); 785#endif --- 38 unchanged lines hidden (view full) --- 824 825 archsw.arch_getdev = ofw_getdev; 826 archsw.arch_copyin = sparc64_copyin; 827 archsw.arch_copyout = ofw_copyout; 828 archsw.arch_readin = sparc64_readin; 829 archsw.arch_autoload = sparc64_autoload; 830 archsw.arch_maphint = sparc64_maphint; 831 |
832 /* 833 * Probe for a console. 834 */ 835 cons_probe(); 836 |
837 if (init_heap() == (vm_offset_t)-1) 838 panic("%s: can't claim heap", __func__); 839 setheap((void *)heapva, (void *)(heapva + HEAPSZ)); 840 |
841 if ((root = OF_peer(0)) == -1) 842 panic("%s: can't get root phandle", __func__); 843 OF_getprop(root, "compatible", compatible, sizeof(compatible)); 844 if (!strcmp(compatible, "sun4v")) { 845 printf("\nBooting with sun4v support.\n"); 846 mmu_ops = &mmu_ops_sun4v; 847 is_sun4v = 1; 848 } else { --- 128 unchanged lines hidden --- |