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>
42 #include <asm/sn/sn_sal.h>
43 #include <asm/processor.h>
44 #include <asm/sn/sn_cpuid.h>
46 #include <asm/sn/sn2/addrs.h>
47 #include <asm/sn/sn2/shub_mmr.h>
49 #include <linux/acpi.h>
52 #define RSDP_NAME "RSDP"
53 #define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */
54 #define APIC_SIG "APIC" /* Multiple APIC Description Table */
55 #define DSDT_SIG "DSDT" /* Differentiated System Description Table */
56 #define FADT_SIG "FACP" /* Fixed ACPI Description Table */
57 #define FACS_SIG "FACS" /* Firmware ACPI Control Structure */
58 #define PSDT_SIG "PSDT" /* Persistent System Description Table */
59 #define RSDT_SIG "RSDT" /* Root System Description Table */
60 #define XSDT_SIG "XSDT" /* Extended System Description Table */
61 #define SSDT_SIG "SSDT" /* Secondary System Description Table */
62 #define SBST_SIG "SBST" /* Smart Battery Specification Table */
63 #define SPIC_SIG "SPIC" /* IOSAPIC table */
64 #define SRAT_SIG "SRAT" /* SRAT table */
65 #define SLIT_SIG "SLIT" /* SLIT table */
66 #define BOOT_SIG "BOOT" /* Boot table */
67 #define ACPI_SRAT_REVISION 1
68 #define ACPI_SLIT_REVISION 1
73 #define PROXIMITY_DOMAIN(nasid) (((nasid)>>1) & 255)
76 #define MB (1024*1024UL)
77 #define GB (MB*1024UL)
78 #define BOOT_PARAM_ADDR 0x40000
79 #define MAX(i,j) ((i) > (j) ? (i) : (j))
80 #define MIN(i,j) ((i) < (j) ? (i) : (j))
81 #define ABS(i) ((i) > 0 ? (i) : -(i))
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_get_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);
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)
232 register long r9 asm ("r9") = 0;
233 register long r10 asm ("r10") = 0;
234 register long r11 asm ("r11") = 0;
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));
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);