184121Sdfr/*- 284121Sdfr * Copyright (c) 2001 Doug Rabson 384121Sdfr * All rights reserved. 484121Sdfr * 584121Sdfr * Redistribution and use in source and binary forms, with or without 684121Sdfr * modification, are permitted provided that the following conditions 784121Sdfr * are met: 884121Sdfr * 1. Redistributions of source code must retain the above copyright 984121Sdfr * notice, this list of conditions and the following disclaimer. 1084121Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1184121Sdfr * notice, this list of conditions and the following disclaimer in the 1284121Sdfr * documentation and/or other materials provided with the distribution. 1384121Sdfr * 1484121Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1584121Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1684121Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1784121Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1884121Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1984121Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2084121Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2184121Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2284121Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2384121Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2484121Sdfr * SUCH DAMAGE. 2584121Sdfr */ 2684121Sdfr 27135453Smarcel#include <sys/cdefs.h> 28135453Smarcel__FBSDID("$FreeBSD$"); 29135453Smarcel 3084121Sdfr#include <sys/param.h> 3184121Sdfr#include <sys/systm.h> 32205234Smarcel#include <sys/bus.h> 3395245Smarcel#include <sys/kernel.h> 3495245Smarcel#include <sys/malloc.h> 3595245Smarcel#include <vm/vm.h> 3695245Smarcel#include <vm/vm_kern.h> 37135453Smarcel#include <machine/efi.h> 38205234Smarcel#include <machine/intr.h> 3996061Smarcel#include <machine/md_var.h> 4084121Sdfr#include <machine/sal.h> 4185656Smarcel#include <machine/smp.h> 4284121Sdfr 43205234Smarcelint ia64_ipi_wakeup; 4496442Smarcel 4584121Sdfrstatic struct ia64_fdesc sal_fdesc; 4684121Sdfrstatic sal_entry_t fake_sal; 4784121Sdfr 4884121Sdfrextern u_int64_t ia64_pal_entry; 4984121Sdfrsal_entry_t *ia64_sal_entry = fake_sal; 5084121Sdfr 51135453Smarcelstatic struct uuid sal_table = EFI_TABLE_SAL; 52135453Smarcelstatic struct sal_system_table *sal_systbl; 53135453Smarcel 5484121Sdfrstatic struct ia64_sal_result 5584121Sdfrfake_sal(u_int64_t a1, u_int64_t a2, u_int64_t a3, u_int64_t a4, 5684121Sdfr u_int64_t a5, u_int64_t a6, u_int64_t a7, u_int64_t a8) 5784121Sdfr{ 5884121Sdfr struct ia64_sal_result res; 5984121Sdfr res.sal_status = -3; 6084121Sdfr res.sal_result[0] = 0; 6184121Sdfr res.sal_result[1] = 0; 6284121Sdfr res.sal_result[2] = 0; 6384121Sdfr return res; 6484121Sdfr} 6584121Sdfr 6684121Sdfrvoid 67135453Smarcelia64_sal_init(void) 6884121Sdfr{ 6984121Sdfr static int sizes[6] = { 7084121Sdfr 48, 32, 16, 32, 16, 16 7184121Sdfr }; 7284121Sdfr u_int8_t *p; 73205234Smarcel int error, i; 7484121Sdfr 75135453Smarcel sal_systbl = efi_get_table(&sal_table); 76135453Smarcel if (sal_systbl == NULL) 77135453Smarcel return; 78135453Smarcel 79183299Sobrien if (bcmp(sal_systbl->sal_signature, SAL_SIGNATURE, 4)) { 8084121Sdfr printf("Bad signature for SAL System Table\n"); 8184121Sdfr return; 8284121Sdfr } 8384121Sdfr 84135453Smarcel p = (u_int8_t *) (sal_systbl + 1); 85135453Smarcel for (i = 0; i < sal_systbl->sal_entry_count; i++) { 8685211Smarcel switch (*p) { 8785211Smarcel case 0: { 8884121Sdfr struct sal_entrypoint_descriptor *dp; 8985211Smarcel 9085211Smarcel dp = (struct sal_entrypoint_descriptor*)p; 9184121Sdfr ia64_pal_entry = IA64_PHYS_TO_RR7(dp->sale_pal_proc); 9284121Sdfr if (bootverbose) 9384121Sdfr printf("PAL Proc at 0x%lx\n", ia64_pal_entry); 9484121Sdfr sal_fdesc.func = IA64_PHYS_TO_RR7(dp->sale_sal_proc); 9584121Sdfr sal_fdesc.gp = IA64_PHYS_TO_RR7(dp->sale_sal_gp); 9684121Sdfr if (bootverbose) 9784121Sdfr printf("SAL Proc at 0x%lx, GP at 0x%lx\n", 9885211Smarcel sal_fdesc.func, sal_fdesc.gp); 9984121Sdfr ia64_sal_entry = (sal_entry_t *) &sal_fdesc; 10085211Smarcel break; 10184121Sdfr } 10285211Smarcel case 5: { 10385211Smarcel struct sal_ap_wakeup_descriptor *dp; 10485211Smarcel 10585211Smarcel dp = (struct sal_ap_wakeup_descriptor*)p; 10696442Smarcel if (dp->sale_mechanism != 0) { 10796442Smarcel printf("SAL: unsupported AP wake-up mechanism " 10896442Smarcel "(%d)\n", dp->sale_mechanism); 10996442Smarcel break; 11096442Smarcel } 11196442Smarcel 112205234Smarcel /* Reserve the XIV so that we won't use it. */ 113205234Smarcel error = ia64_xiv_reserve(dp->sale_vector, 114205234Smarcel IA64_XIV_PLAT, NULL); 115205234Smarcel if (error) { 116205234Smarcel printf("SAL: invalid AP wake-up XIV (%#lx)\n", 117205234Smarcel dp->sale_vector); 11896442Smarcel break; 11996442Smarcel } 12096442Smarcel 121205234Smarcel ia64_ipi_wakeup = dp->sale_vector; 12285211Smarcel if (bootverbose) 123205234Smarcel printf("SAL: AP wake-up XIV: %#x\n", 124205234Smarcel ia64_ipi_wakeup); 12585211Smarcel break; 12685211Smarcel } 12785211Smarcel } 12884121Sdfr p += sizes[*p]; 12984121Sdfr } 13084121Sdfr} 131