4 * Copyright (C) 1998-2000 Hewlett-Packard Co
5 * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
8 * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of version 2 of the GNU General Public License
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it would be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 * Further, this software is distributed without any warranty that it is
19 * free of the rightful claim of any third person regarding infringement
20 * or the like. Any license provided herein, whether implied or
21 * otherwise, applies only to this software file. Patent licenses, if
22 * any, provided herein do not apply to combinations of this program with
23 * other software, or any other product whatsoever.
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
29 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
30 * Mountain View, CA 94043, or:
34 * For further information regarding this notice, see:
36 * http://oss.sgi.com/projects/GenInfo/NoticeExplan
38 #include <linux/config.h>
39 #include <linux/efi.h>
40 #include <linux/kernel.h>
43 #include <asm/sn/sn_sal.h>
44 #include <asm/processor.h>
45 #include <asm/sn/sn_cpuid.h>
47 #include <asm/sn/sn2/addrs.h>
48 #include <asm/sn/sn2/shub_mmr.h>
50 #include <linux/acpi.h>
53 #define RSDP_NAME "RSDP"
54 #define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */
55 #define APIC_SIG "APIC" /* Multiple APIC Description Table */
56 #define DSDT_SIG "DSDT" /* Differentiated System Description Table */
57 #define FADT_SIG "FACP" /* Fixed ACPI Description Table */
58 #define FACS_SIG "FACS" /* Firmware ACPI Control Structure */
59 #define PSDT_SIG "PSDT" /* Persistent System Description Table */
60 #define RSDT_SIG "RSDT" /* Root System Description Table */
61 #define XSDT_SIG "XSDT" /* Extended System Description Table */
62 #define SSDT_SIG "SSDT" /* Secondary System Description Table */
63 #define SBST_SIG "SBST" /* Smart Battery Specification Table */
64 #define SPIC_SIG "SPIC" /* IOSAPIC table */
65 #define SRAT_SIG "SRAT" /* SRAT table */
66 #define SLIT_SIG "SLIT" /* SLIT table */
67 #define BOOT_SIG "BOOT" /* Boot table */
68 #define ACPI_SRAT_REVISION 1
69 #define ACPI_SLIT_REVISION 1
74 #define PROXIMITY_DOMAIN(nasid) (((nasid)>>1) & 255)
77 #define MB (1024*1024UL)
78 #define GB (MB*1024UL)
79 #define BOOT_PARAM_ADDR 0x40000
80 #define MAX(i,j) ((i) > (j) ? (i) : (j))
81 #define MIN(i,j) ((i) < (j) ? (i) : (j))
82 #define ALIGN8(p) (((long)(p) +7) & ~7)
84 #define FPROM_BUG() do {while (1);} while (0)
85 #define MAX_SN_NODES 128
86 #define MAX_LSAPICS 512
88 #define MAX_CPUS_NODE 4
89 #define CPUS_PER_NODE 4
90 #define CPUS_PER_FSB 2
91 #define CPUS_PER_FSB_MASK (CPUS_PER_FSB-1)
93 #define NUM_EFI_DESCS 2
95 #define RSDP_CHECKSUM_LENGTH 20
97 typedef union ia64_nasid_va {
100 unsigned long off : 36; /* intra-region offset */
101 unsigned long attr : 2;
102 unsigned long nasid : 11; /* NASID */
103 unsigned long off2 : 12; /* fill */
104 unsigned long reg : 3; /* region number */
116 #define IS_VIRTUAL_MODE() ({struct ia64_psr psr; asm("mov %0=psr" : "=r"(psr)); psr.dt;})
117 #define ADDR_OF(p) (IS_VIRTUAL_MODE() ? ((void*)((long)(p)+PAGE_OFFSET)) : ((void*) (p)))
120 #define __fwtab_pa(n,x) ({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.f.attr = 3; _v.l;})
124 * The following variables are passed thru registersfrom the configuration file and
125 * are set via the _start function.
136 extern void pal_emulator(void);
137 static efi_runtime_services_t *efi_runtime_p;
138 static char fw_mem[( sizeof(efi_system_table_t)
139 + sizeof(efi_runtime_services_t)
140 + NUM_EFI_DESCS*sizeof(efi_config_table_t)
141 + sizeof(struct ia64_sal_systab)
142 + sizeof(struct ia64_sal_desc_entry_point)
143 + sizeof(struct ia64_sal_desc_ap_wakeup)
144 + sizeof(struct acpi20_table_rsdp)
145 + sizeof(struct acpi_table_xsdt)
146 + sizeof(struct acpi_table_slit)
147 + MAX_SN_NODES*MAX_SN_NODES+8
148 + sizeof(struct acpi_table_madt)
150 + (1+8*MAX_SN_NODES)*(sizeof(efi_memory_desc_t))
151 + sizeof(struct acpi_table_srat)
152 + MAX_CPUS*sizeof(struct acpi_table_processor_affinity)
153 + MAX_SN_NODES*sizeof(struct acpi_table_memory_affinity)
154 + sizeof(ia64_sal_desc_ptc_t) +
155 + MAX_SN_NODES*sizeof(ia64_sal_ptc_domain_info_t) +
156 + MAX_CPUS*sizeof(ia64_sal_ptc_domain_proc_entry_t) +
157 + 1024)] __attribute__ ((aligned (8)));
161 efi_get_time (efi_time_t *tm, efi_time_cap_t *tc)
164 memset(tm, 0, sizeof(*tm));
176 tc->sets_to_zero = 1;
183 efi_reset_system (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data)
185 while(1); /* Is there a pseudo-op to stop medusa */
195 efi_unimplemented (void)
197 return EFI_UNSUPPORTED;
202 #undef cpu_physical_id
203 #define cpu_physical_id(cpuid) ((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff)
206 fprom_send_cpei(void) {
211 physid = cpu_physical_id(0);
212 nasid = cpu_physical_id_to_nasid(physid);
213 slice = cpu_physical_id_to_slice(physid);
215 p = (long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT);
216 val = (1UL<<SH_IPI_INT_SEND_SHFT) |
217 (physid<<SH_IPI_INT_PID_SHFT) |
218 ((long)0<<SH_IPI_INT_TYPE_SHFT) |
219 ((long)0x1e<<SH_IPI_INT_IDX_SHFT) |
220 (0x000feeUL<<SH_IPI_INT_BASE_SHFT);
227 static struct sal_ret_values
228 sal_emulator (long index, unsigned long in1, unsigned long in2,
229 unsigned long in3, unsigned long in4, unsigned long in5,
230 unsigned long in6, unsigned long in7)
238 * Don't do a "switch" here since that gives us code that
239 * isn't self-relocatable.
242 if (index == SAL_FREQ_BASE) {
244 case SAL_FREQ_BASE_PLATFORM:
248 case SAL_FREQ_BASE_INTERVAL_TIMER:
250 * Is this supposed to be the cr.itc frequency
251 * or something platform specific? The SAL
252 * doc ain't exactly clear on this...
257 case SAL_FREQ_BASE_REALTIME_CLOCK:
265 } else if (index == SAL_SET_VECTORS) {
266 if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) {
268 fp = ADDR_OF(&ap_entry);
271 } else if (in1 == SAL_VECTOR_OS_MCA || in1 == SAL_VECTOR_OS_INIT) {
276 } else if (index == SAL_GET_STATE_INFO) {
278 } else if (index == SAL_GET_STATE_INFO_SIZE) {
281 } else if (index == SAL_CLEAR_STATE_INFO) {
283 } else if (index == SAL_MC_RENDEZ) {
285 } else if (index == SAL_MC_SET_PARAMS) {
287 } else if (index == SAL_CACHE_FLUSH) {
289 } else if (index == SAL_CACHE_INIT) {
291 } else if (index == SAL_UPDATE_PAL) {
294 } else if (index == SN_SAL_LOG_CE) {
297 #else /* ajmtestcpei */
299 #endif /* ajmtestcpei */
301 } else if (index == SN_SAL_PROBE) {
304 r9 = *(unsigned *)in1;
308 } else if (in2 == 2) {
309 r9 = *(unsigned short *)in1;
313 } else if (in2 == 1) {
314 r9 = *(unsigned char *)in1;
318 } else if (in2 == 8) {
319 r9 = *(unsigned long *)in1;
326 } else if (index == SN_SAL_GET_KLCONFIG_ADDR) {
328 } else if (index == SN_SAL_CONSOLE_PUTC) {
330 } else if (index == SN_SAL_CONSOLE_GETC) {
332 } else if (index == SN_SAL_CONSOLE_POLL) {
334 } else if (index == SN_SAL_SYSCTL_IOBRICK_MODULE_GET) {
340 asm volatile ("" :: "r"(r9), "r"(r10), "r"(r11));
341 return ((struct sal_ret_values) {status, r9, r10, r11});
346 * This is here to work around a bug in egcs-1.1.1b that causes the
347 * compiler to crash (seems like a bug in the new alias analysis code.
352 return (void *) addr;
357 * Fix the addresses in a function pointer by adding base node address
361 fix_function_pointer(void *fp)
366 _fp->pc = __fwtab_pa(base_nasid, _fp->pc);
367 _fp->gp = __fwtab_pa(base_nasid, _fp->gp);
371 fix_virt_function_pointer(void **fptr)
378 fp->pc = fp->pc | PAGE_OFFSET;
379 fp->gp = fp->gp | PAGE_OFFSET;
385 efi_set_virtual_address_map(void)
387 efi_runtime_services_t *runtime;
389 runtime = efi_runtime_p;
390 fix_virt_function_pointer((void**)&runtime->get_time);
391 fix_virt_function_pointer((void**)&runtime->set_time);
392 fix_virt_function_pointer((void**)&runtime->get_wakeup_time);
393 fix_virt_function_pointer((void**)&runtime->set_wakeup_time);
394 fix_virt_function_pointer((void**)&runtime->set_virtual_address_map);
395 fix_virt_function_pointer((void**)&runtime->get_variable);
396 fix_virt_function_pointer((void**)&runtime->get_next_variable);
397 fix_virt_function_pointer((void**)&runtime->set_variable);
398 fix_virt_function_pointer((void**)&runtime->get_next_high_mono_count);
399 fix_virt_function_pointer((void**)&runtime->reset_system);
404 acpi_table_initx(struct acpi_table_header *p, char *sig, int siglen, int revision, int oem_revision)
406 memcpy(p->signature, sig, siglen);
407 memcpy(p->oem_id, OEMID, 6);
408 memcpy(p->oem_table_id, sig, 4);
409 memcpy(p->oem_table_id+4, PRODUCT, 4);
410 p->revision = revision;
411 p->oem_revision = (revision<<16) + oem_revision;
412 memcpy(p->asl_compiler_id, "FPRM", 4);
413 p->asl_compiler_revision = 1;
417 acpi_checksum(struct acpi_table_header *p, int length)
419 u8 *cp, *cpe, checksum;
424 for (cp=(u8*)p, cpe=cp+p->length; cp<cpe; cp++)
426 p->checksum = -checksum;
430 acpi_checksum_rsdp20(struct acpi20_table_rsdp *p, int length)
432 u8 *cp, *cpe, checksum;
438 for (cp=(u8*)p, cpe=cp+20; cp<cpe; cp++)
440 p->checksum = -checksum;
443 for (cp=(u8*)p, cpe=cp+length; cp<cpe; cp++)
445 p->ext_checksum = -checksum;
449 nasid_present(int nasid)
452 for (cnode=0; cnode<num_nodes; cnode++)
453 if (GetNasid(cnode) == nasid)
459 sys_fw_init (const char *args, int arglen, int bsp)
462 * Use static variables to keep from overflowing the RSE stack
464 static efi_system_table_t *efi_systab;
465 static efi_runtime_services_t *efi_runtime;
466 static efi_config_table_t *efi_tables;
467 static ia64_sal_desc_ptc_t *sal_ptc;
468 static ia64_sal_ptc_domain_info_t *sal_ptcdi;
469 static ia64_sal_ptc_domain_proc_entry_t *sal_ptclid;
470 static struct acpi20_table_rsdp *acpi20_rsdp;
471 static struct acpi_table_xsdt *acpi_xsdt;
472 static struct acpi_table_slit *acpi_slit;
473 static struct acpi_table_madt *acpi_madt;
474 static struct acpi_table_lsapic *lsapic20;
475 static struct ia64_sal_systab *sal_systab;
476 static struct acpi_table_srat *acpi_srat;
477 static struct acpi_table_processor_affinity *srat_cpu_affinity;
478 static struct acpi_table_memory_affinity *srat_memory_affinity;
479 static efi_memory_desc_t *efi_memmap, *md;
480 static unsigned long *pal_desc, *sal_desc;
481 static struct ia64_sal_desc_entry_point *sal_ed;
482 static struct ia64_boot_param *bp;
483 static struct ia64_sal_desc_ap_wakeup *sal_apwake;
484 static unsigned char checksum;
485 static char *cp, *cmd_line, *vendor;
487 static int mdsize, domain, last_domain ;
488 static int i, j, cnode, max_nasid, nasid, cpu, num_memmd, cpus_found;
491 * Pass the parameter base address to the build_efi_xxx routines.
494 build_init(0x3000000000UL | ((long)base_nasid<<38));
497 num_nodes = GetNumNodes();
498 num_cpus = GetNumCpus();
499 for (max_nasid=0, cnode=0; cnode<num_nodes; cnode++)
500 max_nasid = MAX(max_nasid, GetNasid(cnode));
503 memset(fw_mem, 0, sizeof(fw_mem));
505 pal_desc = (unsigned long *) &pal_emulator;
506 sal_desc = (unsigned long *) &sal_emulator;
507 fix_function_pointer(&pal_emulator);
508 fix_function_pointer(&sal_emulator);
510 /* Align this to 16 bytes, probably EFI does this */
511 mdsize = (sizeof(efi_memory_desc_t) + 15) & ~15 ;
514 efi_systab = (void *) cp; cp += ALIGN8(sizeof(*efi_systab));
515 efi_runtime_p = efi_runtime = (void *) cp; cp += ALIGN8(sizeof(*efi_runtime));
516 efi_tables = (void *) cp; cp += ALIGN8(NUM_EFI_DESCS*sizeof(*efi_tables));
517 sal_systab = (void *) cp; cp += ALIGN8(sizeof(*sal_systab));
518 sal_ed = (void *) cp; cp += ALIGN8(sizeof(*sal_ed));
519 sal_ptc = (void *) cp; cp += ALIGN8(sizeof(*sal_ptc));
520 sal_apwake = (void *) cp; cp += ALIGN8(sizeof(*sal_apwake));
521 acpi20_rsdp = (void *) cp; cp += ALIGN8(sizeof(*acpi20_rsdp));
522 acpi_xsdt = (void *) cp; cp += ALIGN8(sizeof(*acpi_xsdt) + 64);
523 /* save space for more OS defined table pointers. */
525 acpi_slit = (void *) cp; cp += ALIGN8(sizeof(*acpi_slit) + 8 + (max_nasid+1)*(max_nasid+1));
526 acpi_madt = (void *) cp; cp += ALIGN8(sizeof(*acpi_madt) + sizeof(struct acpi_table_lsapic) * (num_cpus+1));
527 acpi_srat = (void *) cp; cp += ALIGN8(sizeof(struct acpi_table_srat));
528 cp += sizeof(struct acpi_table_processor_affinity)*num_cpus + sizeof(struct acpi_table_memory_affinity)*num_nodes;
529 vendor = (char *) cp; cp += ALIGN8(40);
530 efi_memmap = (void *) cp; cp += ALIGN8(8*32*sizeof(*efi_memmap));
531 sal_ptcdi = (void *) cp; cp += ALIGN8(CPUS_PER_FSB*(1+num_nodes)*sizeof(*sal_ptcdi));
532 sal_ptclid = (void *) cp; cp += ALIGN8(((3+num_cpus)*sizeof(*sal_ptclid)+7)/8*8);
533 cmd_line = (void *) cp;
538 memcpy(cmd_line, args, arglen);
542 cmd_line[arglen] = '\0';
544 * For now, just bring up bash.
545 * If you want to execute all the startup scripts, delete the "init=..".
546 * You can also edit this line to pass other arguments to the kernel.
547 * Note: disable kernel text replication.
549 strcpy(cmd_line, "init=/bin/bash console=ttyS0");
551 memset(efi_systab, 0, sizeof(efi_systab));
552 efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
553 efi_systab->hdr.revision = EFI_SYSTEM_TABLE_REVISION;
554 efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
555 efi_systab->fw_vendor = __fwtab_pa(base_nasid, vendor);
556 efi_systab->fw_revision = 1;
557 efi_systab->runtime = __fwtab_pa(base_nasid, efi_runtime);
558 efi_systab->nr_tables = 2;
559 efi_systab->tables = __fwtab_pa(base_nasid, efi_tables);
560 memcpy(vendor, "S\0i\0l\0i\0c\0o\0n\0-\0G\0r\0a\0p\0h\0i\0c\0s\0\0", 40);
562 efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
563 efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
564 efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
565 efi_runtime->get_time = __fwtab_pa(base_nasid, &efi_get_time);
566 efi_runtime->set_time = __fwtab_pa(base_nasid, &efi_unimplemented);
567 efi_runtime->get_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented);
568 efi_runtime->set_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented);
569 efi_runtime->set_virtual_address_map = __fwtab_pa(base_nasid, &efi_set_virtual_address_map);
570 efi_runtime->get_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
571 efi_runtime->get_next_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
572 efi_runtime->set_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
573 efi_runtime->get_next_high_mono_count = __fwtab_pa(base_nasid, &efi_unimplemented);
574 efi_runtime->reset_system = __fwtab_pa(base_nasid, &efi_reset_system);
576 efi_tables->guid = SAL_SYSTEM_TABLE_GUID;
577 efi_tables->table = __fwtab_pa(base_nasid, sal_systab);
579 efi_tables->guid = ACPI_20_TABLE_GUID;
580 efi_tables->table = __fwtab_pa(base_nasid, acpi20_rsdp);
583 fix_function_pointer(&efi_unimplemented);
584 fix_function_pointer(&efi_get_time);
585 fix_function_pointer(&efi_success);
586 fix_function_pointer(&efi_reset_system);
587 fix_function_pointer(&efi_set_virtual_address_map);
590 /* fill in the ACPI20 system table - has a pointer to the ACPI table header */
591 memcpy(acpi20_rsdp->signature, "RSD PTR ", 8);
592 acpi20_rsdp->xsdt_address = (u64)__fwtab_pa(base_nasid, acpi_xsdt);
593 acpi20_rsdp->revision = 2;
594 acpi_checksum_rsdp20(acpi20_rsdp, sizeof(struct acpi20_table_rsdp));
596 /* Set up the XSDT table - contains pointers to the other ACPI tables */
597 acpi_table_initx(&acpi_xsdt->header, XSDT_SIG, 4, 1, 1);
598 acpi_xsdt->entry[0] = __fwtab_pa(base_nasid, acpi_madt);
599 acpi_xsdt->entry[1] = __fwtab_pa(base_nasid, acpi_slit);
600 acpi_xsdt->entry[2] = __fwtab_pa(base_nasid, acpi_srat);
601 acpi_checksum(&acpi_xsdt->header, sizeof(struct acpi_table_xsdt) + 16);
603 /* Set up the APIC table */
604 acpi_table_initx(&acpi_madt->header, APIC_SIG, 4, 1, 1);
605 lsapic20 = (struct acpi_table_lsapic*) (acpi_madt + 1);
606 for (cnode=0; cnode<num_nodes; cnode++) {
607 nasid = GetNasid(cnode);
608 for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
609 if (!IsCpuPresent(cnode, cpu))
611 lsapic20->header.type = ACPI_MADT_LSAPIC;
612 lsapic20->header.length = sizeof(struct acpi_table_lsapic);
613 lsapic20->acpi_id = cnode*4+cpu;
614 lsapic20->flags.enabled = 1;
616 lsapic20->eid = nasid&0xffff;
617 lsapic20->id = (cpu<<4) | (nasid>>16);
619 lsapic20 = (struct acpi_table_lsapic*) ((long)lsapic20+sizeof(struct acpi_table_lsapic));
622 acpi_checksum(&acpi_madt->header, (char*)lsapic20 - (char*)acpi_madt);
624 /* Set up the SRAT table */
625 acpi_table_initx(&acpi_srat->header, SRAT_SIG, 4, ACPI_SRAT_REVISION, 1);
627 for (cnode=0; cnode<num_nodes; cnode++) {
628 nasid = GetNasid(cnode);
629 srat_memory_affinity = ptr;
630 ptr = srat_memory_affinity+1;
631 srat_memory_affinity->header.type = ACPI_SRAT_MEMORY_AFFINITY;
632 srat_memory_affinity->header.length = sizeof(struct acpi_table_memory_affinity);
633 srat_memory_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
634 srat_memory_affinity->base_addr_lo = 0;
635 srat_memory_affinity->length_lo = 0;
637 srat_memory_affinity->base_addr_hi = (nasid<<6) | (3<<4);
638 srat_memory_affinity->length_hi = (MD_BANKSIZE*MD_BANKS_PER_NODE)>>32;
640 srat_memory_affinity->memory_type = ACPI_ADDRESS_RANGE_MEMORY;
641 srat_memory_affinity->flags.enabled = 1;
644 for (cnode=0; cnode<num_nodes; cnode++) {
645 nasid = GetNasid(cnode);
646 for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
647 if (!IsCpuPresent(cnode, cpu))
649 srat_cpu_affinity = ptr;
650 ptr = srat_cpu_affinity + 1;
651 srat_cpu_affinity->header.type = ACPI_SRAT_PROCESSOR_AFFINITY;
652 srat_cpu_affinity->header.length = sizeof(struct acpi_table_processor_affinity);
653 srat_cpu_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
654 srat_cpu_affinity->flags.enabled = 1;
656 srat_cpu_affinity->lsapic_eid = nasid&0xffff;
657 srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>16);
661 acpi_checksum(&acpi_srat->header, (char*)ptr - (char*)acpi_srat);
664 /* Set up the SLIT table */
665 acpi_table_initx(&acpi_slit->header, SLIT_SIG, 4, ACPI_SLIT_REVISION, 1);
666 acpi_slit->localities = PROXIMITY_DOMAIN(max_nasid)+1;
668 memset(cp, 255, acpi_slit->localities*acpi_slit->localities);
670 for (i=0; i<=max_nasid; i++)
671 for (j=0; j<=max_nasid; j++)
672 if (nasid_present(i) && nasid_present(j))
673 *(cp+PROXIMITY_DOMAIN(i)*acpi_slit->localities+PROXIMITY_DOMAIN(j)) = 10 + MIN(254, 5*abs(i-j));
675 cp = acpi_slit->entry + acpi_slit->localities*acpi_slit->localities;
676 acpi_checksum(&acpi_slit->header, cp - (char*)acpi_slit);
679 /* fill in the SAL system table: */
680 memcpy(sal_systab->signature, "SST_", 4);
681 sal_systab->size = sizeof(*sal_systab);
682 sal_systab->sal_rev_minor = 1;
683 sal_systab->sal_rev_major = 0;
684 sal_systab->entry_count = 3;
685 sal_systab->sal_b_rev_major = 0x1; /* set the SN SAL rev to */
686 sal_systab->sal_b_rev_minor = 0x0; /* 1.00 */
688 strcpy(sal_systab->oem_id, "SGI");
689 strcpy(sal_systab->product_id, "SN2");
691 /* fill in an entry point: */
692 sal_ed->type = SAL_DESC_ENTRY_POINT;
693 sal_ed->pal_proc = __fwtab_pa(base_nasid, pal_desc[0]);
694 sal_ed->sal_proc = __fwtab_pa(base_nasid, sal_desc[0]);
695 sal_ed->gp = __fwtab_pa(base_nasid, sal_desc[1]);
697 /* kludge the PTC domain info */
698 sal_ptc->type = SAL_DESC_PTC;
699 sal_ptc->num_domains = 0;
700 sal_ptc->domain_info = __fwtab_pa(base_nasid, sal_ptcdi);
704 for (cnode=0; cnode<num_nodes; cnode++) {
705 nasid = GetNasid(cnode);
706 for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
707 if (IsCpuPresent(cnode, cpu)) {
708 domain = cnode*CPUS_PER_NODE + cpu/CPUS_PER_FSB;
709 if (domain != last_domain) {
710 sal_ptc->num_domains++;
712 sal_ptcdi->proc_count = 0;
713 sal_ptcdi->proc_list = __fwtab_pa(base_nasid, sal_ptclid);
714 last_domain = domain;
716 sal_ptcdi->proc_count++;
717 sal_ptclid->id = nasid;
718 sal_ptclid->eid = cpu;
725 if (cpus_found != num_cpus)
728 /* Make the AP WAKEUP entry */
729 sal_apwake->type = SAL_DESC_AP_WAKEUP;
730 sal_apwake->mechanism = IA64_SAL_AP_EXTERNAL_INT;
731 sal_apwake->vector = 18;
733 for (checksum=0, cp=(char*)sal_systab; cp < (char *)efi_memmap; ++cp)
735 sal_systab->checksum = -checksum;
737 /* If the checksum is correct, the kernel tries to use the
738 * table. We dont build enough table & the kernel aborts.
739 * Note that the PROM hasd thhhe same problem!!
743 num_memmd = build_efi_memmap((void *)md, mdsize) ;
745 bp = (struct ia64_boot_param*) __fwtab_pa(base_nasid, BOOT_PARAM_ADDR);
746 bp->efi_systab = __fwtab_pa(base_nasid, &fw_mem);
747 bp->efi_memmap = __fwtab_pa(base_nasid, efi_memmap);
748 bp->efi_memmap_size = num_memmd*mdsize;
749 bp->efi_memdesc_size = mdsize;
750 bp->efi_memdesc_version = 0x101;
751 bp->command_line = __fwtab_pa(base_nasid, cmd_line);
752 bp->console_info.num_cols = 80;
753 bp->console_info.num_rows = 25;
754 bp->console_info.orig_x = 0;
755 bp->console_info.orig_y = 24;
759 * Now pick the BSP & store it LID value in
760 * a global variable. Note if BSP is greater than last cpu,
763 for (cnode=0; cnode<num_nodes; cnode++) {
764 for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
765 if (!IsCpuPresent(cnode, cpu))
768 bsp_lid = (GetNasid(cnode)<<16) | (cpu<<28);