1 /*
2  * PAL & SAL emulation.
3  *
4  * Copyright (C) 1998-2000 Hewlett-Packard Co
5  * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
6  *
7  *
8  * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
9  *
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.
13  *
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.
17  *
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.
24  *
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.
28  *
29  * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
30  * Mountain View, CA  94043, or:
31  *
32  * http://www.sgi.com
33  *
34  * For further information regarding this notice, see:
35  *
36  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
37  */
38 #include <linux/config.h>
39 #include <linux/efi.h>
40 #include <asm/pal.h>
41 #include <asm/sal.h>
42 #include <asm/sn/sn_sal.h>
43 #include <asm/processor.h>
44 #include <asm/sn/sn_cpuid.h>
45 #ifdef SGI_SN2
46 #include <asm/sn/sn2/addrs.h>
47 #include <asm/sn/sn2/shub_mmr.h>
48 #endif
49 #include <linux/acpi.h>
50 #include <acpi/acpi.h>
51 #include <acpi/actbl.h>
52 #include "fpmem.h"
53 
54 #define RSDP_NAME               "RSDP"
55 #define RSDP_SIG                "RSD PTR "  /* RSDT Pointer signature */
56 #define APIC_SIG                "APIC"      /* Multiple APIC Description Table */
57 #define DSDT_SIG                "DSDT"      /* Differentiated System Description Table */
58 #define FADT_SIG                "FACP"      /* Fixed ACPI Description Table */
59 #define FACS_SIG                "FACS"      /* Firmware ACPI Control Structure */
60 #define PSDT_SIG                "PSDT"      /* Persistent System Description Table */
61 #define RSDT_SIG                "RSDT"      /* Root System Description Table */
62 #define XSDT_SIG                "XSDT"      /* Extended  System Description Table */
63 #define SSDT_SIG                "SSDT"      /* Secondary System Description Table */
64 #define SBST_SIG                "SBST"      /* Smart Battery Specification Table */
65 #define SPIC_SIG                "SPIC"      /* IOSAPIC table */
66 #define SRAT_SIG                "SRAT"      /* SRAT table */
67 #define SLIT_SIG                "SLIT"      /* SLIT table */
68 #define BOOT_SIG                "BOOT"      /* Boot table */
69 #define ACPI_SRAT_REVISION 1
70 #define ACPI_SLIT_REVISION 1
71 #define ACPI_FADT_REVISION 3
72 #define ACPI_DSDT_REVISION 1
73 
74 #define OEMID			"SGI"
75 #ifdef SGI_SN2
76 #define PRODUCT			"SN2"
77 #endif
78 
79 #define MB	(1024*1024UL)
80 #define GB	(MB*1024UL)
81 #define BOOT_PARAM_ADDR 0x40000
82 #define MAX(i,j)		((i) > (j) ? (i) : (j))
83 #define MIN(i,j)		((i) < (j) ? (i) : (j))
84 #define ABS(i)			((i) > 0   ? (i) : -(i))
85 #define ALIGN8(p)		(((long)(p) +7) & ~7)
86 
87 #define NUM_EFI_DESCS		2
88 
89 #define RSDP_CHECKSUM_LENGTH	20
90 
91 typedef union ia64_nasid_va {
92         struct {
93 #if defined(SGI_SN2)
94                 unsigned long off   : 36;       /* intra-region offset */
95 		unsigned long attr  :  2;
96 		unsigned long nasid : 11;	/* NASID */
97 		unsigned long off2  : 12;	/* fill */
98                 unsigned long reg   :  3;       /* region number */
99 #endif
100         } f;
101         unsigned long l;
102         void *p;
103 } ia64_nasid_va;
104 
105 typedef struct {
106 	unsigned long	pc;
107 	unsigned long	gp;
108 } func_ptr_t;
109 
110 #define IS_VIRTUAL_MODE() 	 ({struct ia64_psr psr; asm("mov %0=psr" : "=r"(psr)); psr.dt;})
111 #define ADDR_OF(p)		(IS_VIRTUAL_MODE() ? ((void*)((long)(p)+PAGE_OFFSET)) : ((void*) (p)))
112 
113 #if defined(SGI_SN2)
114 #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;})
115 #endif
116 
117 /*
118  * The following variables are passed thru registersfrom the configuration file and
119  * are set via the _start function.
120  */
121 long		base_nasid;
122 long		num_cpus;
123 long		bsp_entry_pc;
124 long		num_nodes;
125 func_ptr_t	ap_entry;
126 char		nasid_present[MAX_NASID];
127 
128 
129 extern void pal_emulator(void);
130 static efi_runtime_services_t    *efi_runtime_p;
131 static char fw_mem[(  sizeof(efi_system_table_t)
132 		    + sizeof(efi_runtime_services_t)
133 		    + NUM_EFI_DESCS*sizeof(efi_config_table_t)
134 		    + sizeof(struct ia64_sal_systab)
135 		    + sizeof(struct ia64_sal_desc_entry_point)
136 		    + sizeof(struct ia64_sal_desc_ap_wakeup)
137 		    + sizeof(struct ia64_sal_desc_platform_feature)
138 		    + sizeof(struct acpi20_table_rsdp)
139 		    + sizeof(struct acpi_table_xsdt)
140 		    + sizeof(struct acpi_table_header) /* dummy DSDT */
141 		    + sizeof(struct fadt_descriptor_rev2)
142 		    + sizeof(struct acpi_table_slit)
143 		    +   MAX_SN_NODES*MAX_SN_NODES+8
144 		    + sizeof(struct acpi_table_madt)
145 		    +   16*MAX_CPUS
146 		    + (1+8*MAX_SN_NODES)*(sizeof(efi_memory_desc_t))
147 		    + sizeof(struct acpi_table_srat)
148 		    +   MAX_CPUS*sizeof(struct acpi_table_processor_affinity)
149 		    +   MAX_SN_NODES*sizeof(struct acpi_table_memory_affinity)
150 		    + sizeof(ia64_sal_desc_ptc_t) +
151 		    + MAX_SN_NODES*sizeof(ia64_sal_ptc_domain_info_t) +
152 		    + MAX_CPUS*sizeof(ia64_sal_ptc_domain_proc_entry_t) +
153 		    + 1024)] __attribute__ ((aligned (8)));
154 
155 
156 static efi_status_t
efi_get_time(efi_time_t * tm,efi_time_cap_t * tc)157 efi_get_time (efi_time_t *tm, efi_time_cap_t *tc)
158 {
159 	if (tm) {
160 		memset(tm, 0, sizeof(*tm));
161 		tm->year = 2000;
162 		tm->month = 2;
163 		tm->day = 13;
164 		tm->hour = 10;
165 		tm->minute = 11;
166 		tm->second = 12;
167 	}
168 
169 	if (tc) {
170 		tc->resolution = 10;
171 		tc->accuracy = 12;
172 		tc->sets_to_zero = 1;
173 	}
174 
175 	return EFI_SUCCESS;
176 }
177 
178 static void
efi_reset_system(int reset_type,efi_status_t status,unsigned long data_size,efi_char16_t * data)179 efi_reset_system (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data)
180 {
181 	while(1);	/* Is there a pseudo-op to stop medusa */
182 }
183 
184 static efi_status_t
efi_success(void)185 efi_success (void)
186 {
187 	return EFI_SUCCESS;
188 }
189 
190 static efi_status_t
efi_unimplemented(void)191 efi_unimplemented (void)
192 {
193 	return EFI_UNSUPPORTED;
194 }
195 
196 #ifdef SGI_SN2
197 
198 #undef cpu_physical_id
199 #define cpu_physical_id(cpuid)                  ((ia64_get_lid() >> 16) & 0xffff)
200 
201 void
fprom_send_cpei(void)202 fprom_send_cpei(void) {
203         long            *p, val;
204         long            physid;
205         long            nasid, slice;
206 
207         physid = cpu_physical_id(0);
208         nasid = cpu_physical_id_to_nasid(physid);
209         slice = cpu_physical_id_to_slice(physid);
210 
211         p = (long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT);
212         val =   (1UL<<SH_IPI_INT_SEND_SHFT) |
213                 (physid<<SH_IPI_INT_PID_SHFT) |
214                 ((long)0<<SH_IPI_INT_TYPE_SHFT) |
215                 ((long)0x1e<<SH_IPI_INT_IDX_SHFT) |
216                 (0x000feeUL<<SH_IPI_INT_BASE_SHFT);
217         *p = val;
218 
219 }
220 #endif
221 
222 
223 static long
sal_emulator(long index,unsigned long in1,unsigned long in2,unsigned long in3,unsigned long in4,unsigned long in5,unsigned long in6,unsigned long in7)224 sal_emulator (long index, unsigned long in1, unsigned long in2,
225 	      unsigned long in3, unsigned long in4, unsigned long in5,
226 	      unsigned long in6, unsigned long in7)
227 {
228 	register long r9 asm ("r9") = 0;
229 	register long r10 asm ("r10") = 0;
230 	register long r11 asm ("r11") = 0;
231 	long status;
232 
233 	/*
234 	 * Don't do a "switch" here since that gives us code that
235 	 * isn't self-relocatable.
236 	 */
237 	status = 0;
238 	if (index == SAL_FREQ_BASE) {
239 		switch (in1) {
240 		      case SAL_FREQ_BASE_PLATFORM:
241 			     /* slow down the clock on large systems to reduce the interrupt rate */
242 			if (num_cpus < 32)
243 				r9 = 500000000UL;
244 			else
245 				r9 = 5000000000UL;
246 			break;
247 
248 		      case SAL_FREQ_BASE_INTERVAL_TIMER:
249 			/*
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...
253 			 */
254 			r9 = 700000000;
255 			break;
256 
257 		      case SAL_FREQ_BASE_REALTIME_CLOCK:
258 			r9 = 50000000;
259 			break;
260 
261 		      default:
262 			status = -1;
263 			break;
264 		}
265 	} else if (index == SAL_SET_VECTORS) {
266 		if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) {
267 			func_ptr_t	*fp;
268 			fp = ADDR_OF(&ap_entry);
269 			fp->pc = in2;
270 			fp->gp = in3;
271 		} else if (in1 == SAL_VECTOR_OS_MCA || in1 == SAL_VECTOR_OS_INIT) {
272 		} else {
273 			status = -1;
274 		}
275 		;
276 	} else if (index == SAL_GET_STATE_INFO) {
277 		;
278 	} else if (index == SAL_GET_STATE_INFO_SIZE) {
279 		r9 = 10000;
280 		;
281 	} else if (index == SAL_CLEAR_STATE_INFO) {
282 		;
283 	} else if (index == SAL_MC_RENDEZ) {
284 		;
285 	} else if (index == SAL_MC_SET_PARAMS) {
286 		;
287 	} else if (index == SAL_CACHE_FLUSH) {
288 		;
289 	} else if (index == SAL_CACHE_INIT) {
290 		;
291 	} else if (index == SAL_UPDATE_PAL) {
292 		;
293 #ifdef SGI_SN2
294 	} else if (index == SN_SAL_LOG_CE) {
295 #ifdef ajmtestcpei
296 		fprom_send_cpei();
297 #else /* ajmtestcpei */
298 		;
299 #endif /* ajmtestcpei */
300 #endif
301 	} else if (index == SN_SAL_PROBE) {
302 		r9 = 0UL;
303 		if (in2 == 4) {
304 			r9 = *(unsigned *)in1;
305 			if (r9 == -1) {
306 				status = 1;
307 			}
308 		} else if (in2 == 2) {
309 			r9 = *(unsigned short *)in1;
310 			if (r9 == -1) {
311 				status = 1;
312 			}
313 		} else if (in2 == 1) {
314 			r9 = *(unsigned char *)in1;
315 			if (r9 == -1) {
316 				status = 1;
317 			}
318 		} else if (in2 == 8) {
319 			r9 = *(unsigned long *)in1;
320 			if (r9 == -1) {
321 				status = 1;
322 			}
323 		} else {
324 			status = 2;
325 		}
326 	} else if (index == SN_SAL_GET_KLCONFIG_ADDR) {
327 		r9 = 0x30000;
328 	} else if (index == SN_SAL_CONSOLE_PUTC) {
329 		status = -1;
330 	} else if (index == SN_SAL_CONSOLE_GETC) {
331 		status = -1;
332 	} else if (index == SN_SAL_CONSOLE_POLL) {
333 		status = -1;
334 	} else if (index == SN_SAL_SYSCTL_IOBRICK_MODULE_GET) {
335 		status = -1;
336 	} else {
337 		status = -1;
338 	}
339 
340 	asm volatile ("" :: "r"(r9), "r"(r10), "r"(r11));
341 	return status;
342 }
343 
344 
345 /*
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.
348  */
349 void *
id(long addr)350 id (long addr)
351 {
352 	return (void *) addr;
353 }
354 
355 
356 /*
357  * Fix the addresses in a function pointer by adding base node address
358  * to pc & gp.
359  */
360 void
fix_function_pointer(void * fp)361 fix_function_pointer(void *fp)
362 {
363 	func_ptr_t	*_fp;
364 
365 	_fp = fp;
366 	_fp->pc = __fwtab_pa(base_nasid, _fp->pc);
367 	_fp->gp = __fwtab_pa(base_nasid, _fp->gp);
368 }
369 
370 void
fix_virt_function_pointer(void ** fptr)371 fix_virt_function_pointer(void **fptr)
372 {
373         func_ptr_t      *fp;
374 	long		*p;
375 
376 	p = (long*)fptr;
377         fp = *fptr;
378         fp->pc = fp->pc | PAGE_OFFSET;
379         fp->gp = fp->gp | PAGE_OFFSET;
380 	*p |= PAGE_OFFSET;
381 }
382 
383 
384 int
efi_set_virtual_address_map(void)385 efi_set_virtual_address_map(void)
386 {
387         efi_runtime_services_t            *runtime;
388 
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);
400         return EFI_SUCCESS;;
401 }
402 
403 void
acpi_table_initx(struct acpi_table_header * p,char * sig,int siglen,int revision,int oem_revision)404 acpi_table_initx(struct acpi_table_header *p, char *sig, int siglen, int revision, int oem_revision)
405 {
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;
414 }
415 
416 void
acpi_checksum(struct acpi_table_header * p,int length)417 acpi_checksum(struct acpi_table_header *p, int length)
418 {
419 	u8	*cp, *cpe, checksum;
420 
421 	p->checksum = 0;
422 	p->length = length;
423 	checksum = 0;
424 	for (cp=(u8*)p, cpe=cp+p->length; cp<cpe; cp++)
425 		checksum += *cp;
426 	p->checksum = -checksum;
427 }
428 
429 void
acpi_checksum_rsdp20(struct acpi20_table_rsdp * p,int length)430 acpi_checksum_rsdp20(struct acpi20_table_rsdp *p, int length)
431 {
432 	u8	*cp, *cpe, checksum;
433 
434 	p->checksum = 0;
435 	p->ext_checksum = 0;
436 	p->length = length;
437 	checksum = 0;
438 	for (cp=(u8*)p, cpe=cp+20; cp<cpe; cp++)
439 		checksum += *cp;
440 	p->checksum = -checksum;
441 
442 	checksum = 0;
443 	for (cp=(u8*)p, cpe=cp+length; cp<cpe; cp++)
444 		checksum += *cp;
445 	p->ext_checksum = -checksum;
446 }
447 
448 int
is_nasid_present(int nasid)449 is_nasid_present(int nasid)
450 {
451 	int	cnode;
452 	for (cnode=0; cnode<num_nodes; cnode++)
453 		if (GetNasid(cnode) == nasid)
454 			return 1;
455 	return 0;
456 }
457 
458 void
sys_fw_init(const char * args,int arglen)459 sys_fw_init (const char *args, int arglen)
460 {
461 	/*
462 	 * Use static variables to keep from overflowing the RSE stack
463 	 */
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 acpi_table_header *acpi_dsdt;
476 	static struct fadt_descriptor_rev2 *acpi_fadt;
477 	static struct ia64_sal_systab *sal_systab;
478 	static struct acpi_table_srat *acpi_srat;
479 	static struct acpi_table_processor_affinity *srat_cpu_affinity;
480 	static efi_memory_desc_t *efi_memmap, *md;
481 	static unsigned long *pal_desc, *sal_desc;
482 	static struct ia64_sal_desc_entry_point *sal_ed;
483 	static struct ia64_boot_param *bp;
484 	static struct ia64_sal_desc_ap_wakeup *sal_apwake;
485 	static struct ia64_sal_desc_platform_feature *sal_feature;
486 	static unsigned char checksum;
487 	static char *cp, *cmd_line, *vendor;
488 	static void *ptr;
489 	static int mdsize, domain, last_domain ;
490 	static int i, j, cnode, max_nasid, nasid, cpu, num_memmd, cpus_found;
491 
492 	num_nodes = GetNumNodes();
493 	num_cpus = GetNumCpus();
494 	for (max_nasid=0, cnode=0; cnode<num_nodes; cnode++)
495 		max_nasid = MAX(max_nasid, GetNasid(cnode));
496 
497 	//max_nasid = 0;
498 	//num_nodes = 1;
499 
500 	memset(fw_mem, 0, sizeof(fw_mem));
501 
502 	pal_desc = (unsigned long *) &pal_emulator;
503 	sal_desc = (unsigned long *) &sal_emulator;
504 	fix_function_pointer(&pal_emulator);
505 	fix_function_pointer(&sal_emulator);
506 
507 	/* Align this to 16 bytes, probably EFI does this  */
508 	mdsize = (sizeof(efi_memory_desc_t) + 15) & ~15 ;
509 
510 	cp = fw_mem;
511 	efi_systab  = (void *) cp; cp += ALIGN8(sizeof(*efi_systab));
512 	efi_runtime_p = efi_runtime = (void *) cp; cp += ALIGN8(sizeof(*efi_runtime));
513 	efi_tables  = (void *) cp; cp += ALIGN8(NUM_EFI_DESCS*sizeof(*efi_tables));
514 	sal_systab  = (void *) cp; cp += ALIGN8(sizeof(*sal_systab));
515 	sal_ed      = (void *) cp; cp += ALIGN8(sizeof(*sal_ed));
516 	sal_ptc     = (void *) cp; cp += ALIGN8(sizeof(*sal_ptc));
517 	sal_apwake  = (void *) cp; cp += ALIGN8(sizeof(*sal_apwake));
518 	sal_feature = (void *) cp; cp += ALIGN8(sizeof(*sal_feature));
519 	acpi20_rsdp = (void *) cp; cp += ALIGN8(sizeof(*acpi20_rsdp));
520 	acpi_xsdt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_xsdt) + 64);
521 			/* save space for more OS defined table pointers. */
522 
523 	acpi_dsdt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_dsdt));
524 	acpi_fadt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_fadt));
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;
534 
535 	if (args) {
536 		if (arglen >= 1024)
537 			arglen = 1023;
538 		memcpy(cmd_line, args, arglen);
539 	} else {
540 		arglen = 0;
541 	}
542 	cmd_line[arglen] = '\0';
543 	/*
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.
548 	 */
549 	strcpy(cmd_line, "init=/bin/bash console=ttyS0");
550 
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);
561 
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);
575 
576 	efi_tables->guid = SAL_SYSTEM_TABLE_GUID;
577 	efi_tables->table = __fwtab_pa(base_nasid, sal_systab);
578 	efi_tables++;
579 	efi_tables->guid = ACPI_20_TABLE_GUID;
580 	efi_tables->table = __fwtab_pa(base_nasid, acpi20_rsdp);
581 	efi_tables++;
582 
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);
588 
589 
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));
595 
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_xsdt->entry[3] = __fwtab_pa(base_nasid, acpi_fadt);
602 	acpi_xsdt->entry[4] = __fwtab_pa(base_nasid, acpi_dsdt);
603 	acpi_checksum(&acpi_xsdt->header, sizeof(struct acpi_table_xsdt) + 32);
604 
605 	/* Set up the APIC table */
606 	acpi_table_initx(&acpi_madt->header, APIC_SIG, 4, 1, 1);
607 	lsapic20 = (struct acpi_table_lsapic*) (acpi_madt + 1);
608 	for (cnode=0; cnode<num_nodes; cnode++) {
609 		nasid = GetNasid(cnode);
610 		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
611 			if (!IsCpuPresent(cnode, cpu))
612 				continue;
613 			lsapic20->header.type = ACPI_MADT_LSAPIC;
614 			lsapic20->header.length = sizeof(struct acpi_table_lsapic);
615 			lsapic20->acpi_id = cnode*4+cpu;
616 			lsapic20->flags.enabled = 1;
617 #if defined(SGI_SN2)
618 			lsapic20->eid = nasid&0xffff;
619 			lsapic20->id = (cpu<<4) | (nasid>>8);
620 #endif
621 			lsapic20 = (struct acpi_table_lsapic*) ((long)lsapic20+sizeof(struct acpi_table_lsapic));
622 		}
623 	}
624 	acpi_checksum(&acpi_madt->header, (char*)lsapic20 - (char*)acpi_madt);
625 
626 	/* Set up the SRAT table */
627 	acpi_table_initx(&acpi_srat->header, SRAT_SIG, 4, ACPI_SRAT_REVISION, 1);
628 	ptr = acpi_srat+1;
629 
630 	ptr = build_memory_srat(ptr);
631 
632 	/* Build processor SRAT */
633 	for (cnode=0; cnode<num_nodes; cnode++) {
634 		nasid = GetNasid(cnode);
635 		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
636 			if (!IsCpuPresent(cnode, cpu))
637 				continue;
638 			srat_cpu_affinity = ptr;
639 			ptr = srat_cpu_affinity + 1;
640 			srat_cpu_affinity->header.type = ACPI_SRAT_PROCESSOR_AFFINITY;
641 			srat_cpu_affinity->header.length = sizeof(struct acpi_table_processor_affinity);
642 			srat_cpu_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
643 			srat_cpu_affinity->flags.enabled = 1;
644 #if defined(SGI_SN2)
645 			srat_cpu_affinity->lsapic_eid = nasid&0xffff;
646 			srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>8);
647 #endif
648 		}
649 	}
650 	acpi_checksum(&acpi_srat->header, (char*)ptr - (char*)acpi_srat);
651 
652 	acpi_table_initx(acpi_dsdt, DSDT_SIG, 4, ACPI_DSDT_REVISION, 1);
653 	acpi_checksum(acpi_dsdt, sizeof(*acpi_dsdt));
654 
655 	/* Set up the FADT table */
656 	acpi_table_initx((struct acpi_table_header *)&acpi_fadt->header, FADT_SIG, 4, ACPI_FADT_REVISION, 1);
657 	/*
658 	 * We don't have legacy PC keyboard support etc.
659 	 */
660 	acpi_fadt->iapc_boot_arch = 0;
661 	acpi_fadt->Xdsdt = (u64)__fwtab_pa(base_nasid, acpi_dsdt);
662 	acpi_checksum((struct acpi_table_header *)&acpi_fadt->header,
663 		      sizeof(*acpi_fadt));
664 
665 	/* Set up the SLIT table */
666 	acpi_table_initx(&acpi_slit->header, SLIT_SIG, 4, ACPI_SLIT_REVISION, 1);
667 	acpi_slit->localities = PROXIMITY_DOMAIN(max_nasid)+1;
668 	cp=acpi_slit->entry;
669 	memset(cp, 255, acpi_slit->localities*acpi_slit->localities);
670 
671 	for (i=0; i<=max_nasid; i++)
672 		nasid_present[i] = is_nasid_present(i);
673 	for (i=0; i<=max_nasid; i++)
674 		for (j=0; j<=max_nasid; j++)
675 			if (nasid_present[i] && nasid_present[j])
676 				*(cp+PROXIMITY_DOMAIN(i)*acpi_slit->localities+PROXIMITY_DOMAIN(j)) = 10 + MIN(254, 5*ABS(i-j));
677 
678 	cp = acpi_slit->entry + acpi_slit->localities*acpi_slit->localities;
679 	acpi_checksum(&acpi_slit->header, cp - (char*)acpi_slit);
680 
681 
682 	/* fill in the SAL system table: */
683 	memcpy(sal_systab->signature, "SST_", 4);
684 	sal_systab->size = sizeof(*sal_systab);
685 	sal_systab->sal_rev_minor = 1;
686 	sal_systab->sal_rev_major = 0;
687 	sal_systab->entry_count = 4;
688 	sal_systab->sal_b_rev_major = 0x1; /* set the SN SAL rev to */
689 	sal_systab->sal_b_rev_minor = 0x0; /* 1.00 */
690 
691 	strcpy(sal_systab->oem_id, "SGI");
692 	strcpy(sal_systab->product_id, "SN2");
693 
694 	/* fill in an entry point: */
695 	sal_ed->type = SAL_DESC_ENTRY_POINT;
696 	sal_ed->pal_proc = __fwtab_pa(base_nasid, pal_desc[0]);
697 	sal_ed->sal_proc = __fwtab_pa(base_nasid, sal_desc[0]);
698 	sal_ed->gp = __fwtab_pa(base_nasid, sal_desc[1]);
699 
700 	/* kludge the PTC domain info */
701 	sal_ptc->type = SAL_DESC_PTC;
702 	sal_ptc->num_domains = 0;
703 	sal_ptc->domain_info = __fwtab_pa(base_nasid, sal_ptcdi);
704 	cpus_found = 0;
705 	last_domain = -1;
706 	sal_ptcdi--;
707 	for (cnode=0; cnode<num_nodes; cnode++) {
708 		nasid = GetNasid(cnode);
709 		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
710 			if (IsCpuPresent(cnode, cpu)) {
711 				domain = cnode*CPUS_PER_NODE + cpu/CPUS_PER_FSB;
712 				if (domain != last_domain) {
713 					sal_ptc->num_domains++;
714 					sal_ptcdi++;
715 					sal_ptcdi->proc_count = 0;
716 					sal_ptcdi->proc_list = __fwtab_pa(base_nasid, sal_ptclid);
717 					last_domain = domain;
718 				}
719 				sal_ptcdi->proc_count++;
720 				sal_ptclid->id = nasid;
721 				sal_ptclid->eid = cpu;
722 				sal_ptclid++;
723 				cpus_found++;
724 			}
725 		}
726 	}
727 
728 	if (cpus_found != num_cpus)
729 		FPROM_BUG();
730 
731 	/* Make the AP WAKEUP entry */
732 	sal_apwake->type = SAL_DESC_AP_WAKEUP;
733 	sal_apwake->mechanism = IA64_SAL_AP_EXTERNAL_INT;
734 	sal_apwake->vector = 18;
735 
736 	/* Setup the SAL feature descriptor */
737 	sal_feature->type = SAL_DESC_PLATFORM_FEATURE;
738 	sal_feature->feature_mask = IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT;
739 
740 	for (checksum=0, cp=(char*)sal_systab; cp < (char *)efi_memmap; ++cp)
741 		checksum += *cp;
742 	sal_systab->checksum = -checksum;
743 
744 	/* If the checksum is correct, the kernel tries to use the
745 	 * table. We dont build enough table & the kernel aborts.
746 	 * Note that the PROM hasd thhhe same problem!!
747 	 */
748 
749 	md = &efi_memmap[0];
750 	num_memmd = build_efi_memmap((void *)md, mdsize) ;
751 
752 	bp = (struct ia64_boot_param*) __fwtab_pa(base_nasid, BOOT_PARAM_ADDR);
753 	bp->efi_systab = __fwtab_pa(base_nasid, &fw_mem);
754 	bp->efi_memmap = __fwtab_pa(base_nasid, efi_memmap);
755 	bp->efi_memmap_size = num_memmd*mdsize;
756 	bp->efi_memdesc_size = mdsize;
757 	bp->efi_memdesc_version = 0x101;
758 	bp->command_line = __fwtab_pa(base_nasid, cmd_line);
759 	bp->console_info.num_cols = 80;
760 	bp->console_info.num_rows = 25;
761 	bp->console_info.orig_x = 0;
762 	bp->console_info.orig_y = 24;
763 	bp->fpswa = 0;
764 }
765