fw-emu.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:25k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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-2002 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 CONFIG_IA64_SGI_SN2
  46. #include <asm/sn/sn2/addrs.h>
  47. #include <asm/sn/sn2/shub_mmr.h>
  48. #endif
  49. #include <asm/acpi-ext.h>
  50. #include "fpmem.h"
  51. #define zzACPI_1_0 1 /* Include ACPI 1.0 tables */
  52. #define OEMID "SGI"
  53. #ifdef CONFIG_IA64_SGI_SN1
  54. #define PRODUCT "SN1"
  55. #define PROXIMITY_DOMAIN(nasid) (nasid)
  56. #else
  57. #define PRODUCT "SN2"
  58. #define PROXIMITY_DOMAIN(nasid) (((nasid)>>1) & 255)
  59. #endif
  60. #define MB (1024*1024UL)
  61. #define GB (MB*1024UL)
  62. #define BOOT_PARAM_ADDR 0x40000
  63. #define MAX(i,j) ((i) > (j) ? (i) : (j))
  64. #define MIN(i,j) ((i) < (j) ? (i) : (j))
  65. #define ABS(i) ((i) > 0   ? (i) : -(i))
  66. #define ALIGN8(p) (((long)(p) +7) & ~7)
  67. #define FPROM_BUG() do {while (1);} while (0)
  68. #define MAX_SN_NODES 128
  69. #define MAX_LSAPICS 512
  70. #define MAX_CPUS 512
  71. #define MAX_CPUS_NODE 4
  72. #define CPUS_PER_NODE 4
  73. #define CPUS_PER_FSB 2
  74. #define CPUS_PER_FSB_MASK (CPUS_PER_FSB-1)
  75. #ifdef ACPI_1_0
  76. #define NUM_EFI_DESCS 3
  77. #else
  78. #define NUM_EFI_DESCS 2
  79. #endif
  80. #define RSDP_CHECKSUM_LENGTH 20
  81. typedef union ia64_nasid_va {
  82.         struct {
  83. #if defined(CONFIG_IA64_SGI_SN1)
  84.                 unsigned long off   : 33;       /* intra-region offset */
  85. unsigned long nasid :  7; /* NASID */
  86. unsigned long off2  : 21; /* fill */
  87.                 unsigned long reg   :  3;       /* region number */
  88. #elif defined(CONFIG_IA64_SGI_SN2)
  89.                 unsigned long off   : 36;       /* intra-region offset */
  90. unsigned long attr  :  2;
  91. unsigned long nasid : 11; /* NASID */
  92. unsigned long off2  : 12; /* fill */
  93.                 unsigned long reg   :  3;       /* region number */
  94. #endif
  95.         } f;
  96.         unsigned long l;
  97.         void *p;
  98. } ia64_nasid_va;
  99. typedef struct {
  100. unsigned long pc;
  101. unsigned long gp;
  102. } func_ptr_t;
  103.  
  104. #define IS_VIRTUAL_MODE()   ({struct ia64_psr psr; asm("mov %0=psr" : "=r"(psr)); psr.dt;})
  105. #define ADDR_OF(p) (IS_VIRTUAL_MODE() ? ((void*)((long)(p)+PAGE_OFFSET)) : ((void*) (p)))
  106. #if defined(CONFIG_IA64_SGI_SN1)
  107. #define __fwtab_pa(n,x) ({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.l;})
  108. #elif defined(CONFIG_IA64_SGI_SN2)
  109. #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;})
  110. #endif
  111. /*
  112.  * The following variables are passed thru registersfrom the configuration file and
  113.  * are set via the _start function.
  114.  */
  115. long base_nasid;
  116. long num_cpus;
  117. long bsp_entry_pc=0;
  118. long num_nodes;
  119. long app_entry_pc;
  120. int bsp_lid;
  121. func_ptr_t ap_entry;
  122. extern void pal_emulator(void);
  123. static efi_runtime_services_t    *efi_runtime_p;
  124. static char fw_mem[(  sizeof(efi_system_table_t)
  125.     + sizeof(efi_runtime_services_t)
  126.     + NUM_EFI_DESCS*sizeof(efi_config_table_t)
  127.     + sizeof(struct ia64_sal_systab)
  128.     + sizeof(struct ia64_sal_desc_entry_point)
  129.     + sizeof(struct ia64_sal_desc_ap_wakeup)
  130. #ifdef ACPI_1_0
  131.     + sizeof(acpi_rsdp_t)
  132.     + sizeof(acpi_rsdt_t)
  133.     + sizeof(acpi_sapic_t)
  134.     + MAX_LSAPICS*(sizeof(acpi_entry_lsapic_t))
  135. #endif
  136.     + sizeof(acpi20_rsdp_t)
  137.     + sizeof(acpi_xsdt_t)
  138.     + sizeof(acpi_slit_t)
  139.     +   MAX_SN_NODES*MAX_SN_NODES+8
  140.     + sizeof(acpi_madt_t)
  141.     +   16*MAX_CPUS
  142.     + (1+8*MAX_SN_NODES)*(sizeof(efi_memory_desc_t))
  143.     + sizeof(acpi_srat_t)
  144.     +   MAX_CPUS*sizeof(srat_cpu_affinity_t)
  145.     +   MAX_SN_NODES*sizeof(srat_memory_affinity_t)
  146.     + sizeof(ia64_sal_desc_ptc_t) +
  147.     + MAX_SN_NODES*sizeof(ia64_sal_ptc_domain_info_t) +
  148.     + MAX_CPUS*sizeof(ia64_sal_ptc_domain_proc_entry_t) +
  149.     + 1024)] __attribute__ ((aligned (8)));
  150. static efi_status_t
  151. efi_get_time (efi_time_t *tm, efi_time_cap_t *tc)
  152. {
  153. if (tm) {
  154. memset(tm, 0, sizeof(*tm));
  155. tm->year = 2000;
  156. tm->month = 2;
  157. tm->day = 13;
  158. tm->hour = 10;
  159. tm->minute = 11;
  160. tm->second = 12;
  161. }
  162. if (tc) {
  163. tc->resolution = 10;
  164. tc->accuracy = 12;
  165. tc->sets_to_zero = 1;
  166. }
  167. return EFI_SUCCESS;
  168. }
  169. static void
  170. efi_reset_system (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data)
  171. {
  172. while(1); /* Is there a pseudo-op to stop medusa */
  173. }
  174. static efi_status_t
  175. efi_success (void)
  176. {
  177. return EFI_SUCCESS;
  178. }
  179. static efi_status_t
  180. efi_unimplemented (void)
  181. {
  182. return EFI_UNSUPPORTED;
  183. }
  184. #ifdef CONFIG_IA64_SGI_SN2
  185. #undef cpu_physical_id
  186. #define cpu_physical_id(cpuid)                  ((ia64_get_lid() >> 16) & 0xffff)
  187. void
  188. fprom_send_cpei(void) {
  189.         long            *p, val;
  190.         long            physid;
  191.         long            nasid, slice;
  192.         physid = cpu_physical_id(0);
  193.         nasid = cpu_physical_id_to_nasid(physid);
  194.         slice = cpu_physical_id_to_slice(physid);
  195.         p = (long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT);
  196.         val =   (1UL<<SH_IPI_INT_SEND_SHFT) |
  197.                 (physid<<SH_IPI_INT_PID_SHFT) |
  198.                 ((long)0<<SH_IPI_INT_TYPE_SHFT) |
  199.                 ((long)0x1e<<SH_IPI_INT_IDX_SHFT) |
  200.                 (0x000feeUL<<SH_IPI_INT_BASE_SHFT);
  201.         *p = val;
  202. }
  203. #endif
  204. static long
  205. sal_emulator (long index, unsigned long in1, unsigned long in2,
  206.       unsigned long in3, unsigned long in4, unsigned long in5,
  207.       unsigned long in6, unsigned long in7)
  208. {
  209. register long r9 asm ("r9") = 0;
  210. register long r10 asm ("r10") = 0;
  211. register long r11 asm ("r11") = 0;
  212. long status;
  213. /*
  214.  * Don't do a "switch" here since that gives us code that
  215.  * isn't self-relocatable.
  216.  */
  217. status = 0;
  218. if (index == SAL_FREQ_BASE) {
  219. switch (in1) {
  220.       case SAL_FREQ_BASE_PLATFORM:
  221. r9 = 500000000;
  222. break;
  223.       case SAL_FREQ_BASE_INTERVAL_TIMER:
  224. /*
  225.  * Is this supposed to be the cr.itc frequency
  226.  * or something platform specific?  The SAL
  227.  * doc ain't exactly clear on this...
  228.  */
  229. r9 = 700000000;
  230. break;
  231.       case SAL_FREQ_BASE_REALTIME_CLOCK:
  232. r9 = 50000000;
  233. break;
  234.       default:
  235. status = -1;
  236. break;
  237. }
  238. } else if (index == SAL_SET_VECTORS) {
  239. if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) {
  240. func_ptr_t *fp;
  241. fp = ADDR_OF(&ap_entry);
  242. fp->pc = in2;
  243. fp->gp = in3;
  244. } else if (in1 == SAL_VECTOR_OS_MCA || in1 == SAL_VECTOR_OS_INIT) {
  245. } else {
  246. status = -1;
  247. }
  248. ;
  249. } else if (index == SAL_GET_STATE_INFO) {
  250. ;
  251. } else if (index == SAL_GET_STATE_INFO_SIZE) {
  252. ;
  253. } else if (index == SAL_CLEAR_STATE_INFO) {
  254. ;
  255. } else if (index == SAL_MC_RENDEZ) {
  256. ;
  257. } else if (index == SAL_MC_SET_PARAMS) {
  258. ;
  259. } else if (index == SAL_CACHE_FLUSH) {
  260. ;
  261. } else if (index == SAL_CACHE_INIT) {
  262. ;
  263. } else if (index == SAL_UPDATE_PAL) {
  264. ;
  265. #ifdef CONFIG_IA64_SGI_SN2
  266. } else if (index == SN_SAL_LOG_CE) {
  267. #ifdef ajmtestcpei
  268. fprom_send_cpei();
  269. #else /* ajmtestcpei */
  270. ;
  271. #endif /* ajmtestcpei */
  272. #endif
  273. } else if (index == SN_SAL_PROBE) {
  274. r9 = 0UL;
  275. if (in2 == 4) {
  276. r9 = *(unsigned *)in1;
  277. if (r9 == -1) {
  278. status = 1;
  279. }
  280. } else if (in2 == 2) {
  281. r9 = *(unsigned short *)in1;
  282. if (r9 == -1) {
  283. status = 1;
  284. }
  285. } else if (in2 == 1) {
  286. r9 = *(unsigned char *)in1;
  287. if (r9 == -1) {
  288. status = 1;
  289. }
  290. } else if (in2 == 8) {
  291. r9 = *(unsigned long *)in1;
  292. if (r9 == -1) {
  293. status = 1;
  294. }
  295. } else {
  296. status = 2;
  297. }
  298. } else if (index == SN_SAL_GET_KLCONFIG_ADDR) {
  299. r9 = 0x30000;
  300. } else if (index == SN_SAL_CONSOLE_PUTC) {
  301. status = -1;
  302. } else if (index == SN_SAL_CONSOLE_GETC) {
  303. status = -1;
  304. } else if (index == SN_SAL_CONSOLE_POLL) {
  305. status = -1;
  306. } else {
  307. status = -1;
  308. }
  309. asm volatile ("" :: "r"(r9), "r"(r10), "r"(r11));
  310. return status;
  311. }
  312. /*
  313.  * This is here to work around a bug in egcs-1.1.1b that causes the
  314.  * compiler to crash (seems like a bug in the new alias analysis code.
  315.  */
  316. void *
  317. id (long addr)
  318. {
  319. return (void *) addr;
  320. }
  321. /*
  322.  * Fix the addresses in a function pointer by adding base node address
  323.  * to pc & gp.
  324.  */
  325. void
  326. fix_function_pointer(void *fp)
  327. {
  328. func_ptr_t *_fp;
  329. _fp = fp;
  330. _fp->pc = __fwtab_pa(base_nasid, _fp->pc);
  331. _fp->gp = __fwtab_pa(base_nasid, _fp->gp);
  332. }
  333. void
  334. fix_virt_function_pointer(void **fptr)
  335. {
  336.         func_ptr_t      *fp;
  337. long *p;
  338. p = (long*)fptr;
  339.         fp = *fptr;
  340.         fp->pc = fp->pc | PAGE_OFFSET;
  341.         fp->gp = fp->gp | PAGE_OFFSET;
  342. *p |= PAGE_OFFSET;
  343. }
  344. int
  345. efi_set_virtual_address_map(void)
  346. {
  347.         efi_runtime_services_t            *runtime;
  348.         runtime = efi_runtime_p;
  349.         fix_virt_function_pointer((void**)&runtime->get_time);
  350.         fix_virt_function_pointer((void**)&runtime->set_time);
  351.         fix_virt_function_pointer((void**)&runtime->get_wakeup_time);
  352.         fix_virt_function_pointer((void**)&runtime->set_wakeup_time);
  353.         fix_virt_function_pointer((void**)&runtime->set_virtual_address_map);
  354.         fix_virt_function_pointer((void**)&runtime->get_variable);
  355.         fix_virt_function_pointer((void**)&runtime->get_next_variable);
  356.         fix_virt_function_pointer((void**)&runtime->set_variable);
  357.         fix_virt_function_pointer((void**)&runtime->get_next_high_mono_count);
  358.         fix_virt_function_pointer((void**)&runtime->reset_system);
  359.         return EFI_SUCCESS;;
  360. }
  361. void
  362. acpi_table_init(acpi_desc_table_hdr_t *p, char *sig, int siglen, int revision, int oem_revision)
  363. {
  364. memcpy(p->signature, sig, siglen);
  365. memcpy(p->oem_id, OEMID, 6);
  366. memcpy(p->oem_table_id, sig, 4);
  367. memcpy(p->oem_table_id+4, PRODUCT, 4);
  368. p->revision = revision;
  369. p->oem_revision = (revision<<16) + oem_revision;
  370. p->creator_id = 1;
  371. p->creator_revision = 1;
  372. }
  373. void
  374. acpi_checksum(acpi_desc_table_hdr_t *p, int length)
  375. {
  376. u8 *cp, *cpe, checksum;
  377. p->checksum = 0;
  378. p->length = length;
  379. checksum = 0;
  380. for (cp=(u8*)p, cpe=cp+p->length; cp<cpe; cp++)
  381. checksum += *cp;
  382. p->checksum = -checksum;
  383. }
  384. void
  385. acpi_checksum_rsdp20(acpi20_rsdp_t *p, int length)
  386. {
  387. u8 *cp, *cpe, checksum;
  388. p->checksum = 0;
  389. p->length = length;
  390. checksum = 0;
  391. for (cp=(u8*)p, cpe=cp+RSDP_CHECKSUM_LENGTH; cp<cpe; cp++)
  392. checksum += *cp;
  393. p->checksum = -checksum;
  394. }
  395. int
  396. nasid_present(int nasid)
  397. {
  398. int cnode;
  399. for (cnode=0; cnode<num_nodes; cnode++)
  400. if (GetNasid(cnode) == nasid)
  401. return 1;
  402. return 0;
  403. }
  404. void
  405. sys_fw_init (const char *args, int arglen, int bsp)
  406. {
  407. /*
  408.  * Use static variables to keep from overflowing the RSE stack
  409.  */
  410. static efi_system_table_t *efi_systab;
  411. static efi_runtime_services_t *efi_runtime;
  412. static efi_config_table_t *efi_tables;
  413. static ia64_sal_desc_ptc_t *sal_ptc;
  414. static ia64_sal_ptc_domain_info_t *sal_ptcdi;
  415. static ia64_sal_ptc_domain_proc_entry_t *sal_ptclid;
  416. #ifdef ACPI_1_0
  417. static acpi_rsdp_t *acpi_rsdp;
  418. static acpi_rsdt_t *acpi_rsdt;
  419. static acpi_sapic_t *acpi_sapic;
  420. static acpi_entry_lsapic_t *acpi_lsapic;
  421. #endif
  422. static acpi20_rsdp_t *acpi20_rsdp;
  423. static acpi_xsdt_t *acpi_xsdt;
  424. static acpi_slit_t *acpi_slit;
  425. static acpi_madt_t *acpi_madt;
  426. static acpi20_entry_lsapic_t *lsapic20;
  427. static struct ia64_sal_systab *sal_systab;
  428. static acpi_srat_t *acpi_srat;
  429. static srat_cpu_affinity_t *srat_cpu_affinity;
  430. static srat_memory_affinity_t *srat_memory_affinity;
  431. static efi_memory_desc_t *efi_memmap, *md;
  432. static unsigned long *pal_desc, *sal_desc;
  433. static struct ia64_sal_desc_entry_point *sal_ed;
  434. static struct ia64_boot_param *bp;
  435. static struct ia64_sal_desc_ap_wakeup *sal_apwake;
  436. static unsigned char checksum;
  437. static char *cp, *cmd_line, *vendor;
  438. static void *ptr;
  439. static int mdsize, domain, last_domain ;
  440. static int i, j, cnode, max_nasid, nasid, cpu, num_memmd, cpus_found;
  441. /*
  442.  * Pass the parameter base address to the build_efi_xxx routines.
  443.  */
  444. #if defined(CONFIG_IA64_SGI_SN1)
  445. build_init(8LL*GB*base_nasid);
  446. #else
  447. build_init(0x3000000000UL | ((long)base_nasid<<38));
  448. #endif
  449. num_nodes = GetNumNodes();
  450. num_cpus = GetNumCpus();
  451. for (max_nasid=0, cnode=0; cnode<num_nodes; cnode++)
  452. max_nasid = MAX(max_nasid, GetNasid(cnode));
  453. memset(fw_mem, 0, sizeof(fw_mem));
  454. pal_desc = (unsigned long *) &pal_emulator;
  455. sal_desc = (unsigned long *) &sal_emulator;
  456. fix_function_pointer(&pal_emulator);
  457. fix_function_pointer(&sal_emulator);
  458. /* Align this to 16 bytes, probably EFI does this  */
  459. mdsize = (sizeof(efi_memory_desc_t) + 15) & ~15 ;
  460. cp = fw_mem;
  461. efi_systab  = (void *) cp; cp += ALIGN8(sizeof(*efi_systab));
  462. efi_runtime_p = efi_runtime = (void *) cp; cp += ALIGN8(sizeof(*efi_runtime));
  463. efi_tables  = (void *) cp; cp += ALIGN8(NUM_EFI_DESCS*sizeof(*efi_tables));
  464. sal_systab  = (void *) cp; cp += ALIGN8(sizeof(*sal_systab));
  465. sal_ed      = (void *) cp; cp += ALIGN8(sizeof(*sal_ed));
  466. sal_ptc     = (void *) cp; cp += ALIGN8(sizeof(*sal_ptc));
  467. sal_apwake  = (void *) cp; cp += ALIGN8(sizeof(*sal_apwake));
  468. acpi20_rsdp = (void *) cp; cp += ALIGN8(sizeof(*acpi20_rsdp));
  469. acpi_xsdt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_xsdt) + 64); 
  470. /* save space for more OS defined table pointers. */
  471. #ifdef ACPI_1_0
  472. acpi_rsdp   = (void *) cp; cp += ALIGN8(sizeof(*acpi_rsdp));
  473. acpi_rsdt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_rsdt));
  474. acpi_sapic  = (void *) cp; cp += sizeof(*acpi_sapic);
  475. acpi_lsapic = (void *) cp; cp += num_cpus*sizeof(*acpi_lsapic);
  476. #endif
  477. acpi_slit   = (void *) cp; cp += ALIGN8(sizeof(*acpi_slit) + 8 + (max_nasid+1)*(max_nasid+1));
  478. acpi_madt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_madt) + 8 * num_cpus+ 8);
  479. acpi_srat   = (void *) cp; cp += ALIGN8(sizeof(acpi_srat_t));
  480. cp         += sizeof(srat_cpu_affinity_t)*num_cpus + sizeof(srat_memory_affinity_t)*num_nodes;
  481. vendor      = (char *) cp; cp += ALIGN8(40);
  482. efi_memmap  = (void *) cp; cp += ALIGN8(8*32*sizeof(*efi_memmap));
  483. sal_ptcdi   = (void *) cp; cp += ALIGN8(CPUS_PER_FSB*(1+num_nodes)*sizeof(*sal_ptcdi));
  484. sal_ptclid  = (void *) cp; cp += ALIGN8(((3+num_cpus)*sizeof(*sal_ptclid)+7)/8*8);
  485. cmd_line    = (void *) cp;
  486. if (args) {
  487. if (arglen >= 1024)
  488. arglen = 1023;
  489. memcpy(cmd_line, args, arglen);
  490. } else {
  491. arglen = 0;
  492. }
  493. cmd_line[arglen] = '';
  494. /* 
  495.  * For now, just bring up bash.
  496.  * If you want to execute all the startup scripts, delete the "init=..".
  497.  * You can also edit this line to pass other arguments to the kernel.
  498.  *    Note: disable kernel text replication.
  499.  */
  500. strcpy(cmd_line, "init=/bin/bash ktreplicate=0");
  501. memset(efi_systab, 0, sizeof(efi_systab));
  502. efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
  503. efi_systab->hdr.revision  = EFI_SYSTEM_TABLE_REVISION;
  504. efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
  505. efi_systab->fw_vendor = __fwtab_pa(base_nasid, vendor);
  506. efi_systab->fw_revision = 1;
  507. efi_systab->runtime = __fwtab_pa(base_nasid, efi_runtime);
  508. efi_systab->nr_tables = 2;
  509. efi_systab->tables = __fwtab_pa(base_nasid, efi_tables);
  510. memcpy(vendor, "Silicon-Graphics", 40);
  511. efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
  512. efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
  513. efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
  514. efi_runtime->get_time = __fwtab_pa(base_nasid, &efi_get_time);
  515. efi_runtime->set_time = __fwtab_pa(base_nasid, &efi_unimplemented);
  516. efi_runtime->get_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented);
  517. efi_runtime->set_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented);
  518. efi_runtime->set_virtual_address_map = __fwtab_pa(base_nasid, &efi_set_virtual_address_map);
  519. efi_runtime->get_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
  520. efi_runtime->get_next_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
  521. efi_runtime->set_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
  522. efi_runtime->get_next_high_mono_count = __fwtab_pa(base_nasid, &efi_unimplemented);
  523. efi_runtime->reset_system = __fwtab_pa(base_nasid, &efi_reset_system);
  524. efi_tables->guid = SAL_SYSTEM_TABLE_GUID;
  525. efi_tables->table = __fwtab_pa(base_nasid, sal_systab);
  526. efi_tables++;
  527. #ifdef ACPI_1_0
  528. efi_tables->guid = ACPI_TABLE_GUID;
  529. efi_tables->table = __fwtab_pa(base_nasid, acpi_rsdp);
  530. efi_tables++;
  531. #endif
  532. efi_tables->guid = ACPI_20_TABLE_GUID;
  533. efi_tables->table = __fwtab_pa(base_nasid, acpi20_rsdp);
  534. efi_tables++;
  535. fix_function_pointer(&efi_unimplemented);
  536. fix_function_pointer(&efi_get_time);
  537. fix_function_pointer(&efi_success);
  538. fix_function_pointer(&efi_reset_system);
  539. fix_function_pointer(&efi_set_virtual_address_map);
  540. #ifdef ACPI_1_0
  541. /* fill in the ACPI system table - has a pointer to the ACPI table header */
  542. memcpy(acpi_rsdp->signature, "RSD PTR ", 8);
  543. acpi_rsdp->rsdt = (struct acpi_rsdt*)__fwtab_pa(base_nasid, acpi_rsdt);
  544. acpi_table_init(&acpi_rsdt->header, ACPI_RSDT_SIG, ACPI_RSDT_SIG_LEN, 1, 1);
  545. acpi_rsdt->header.length = sizeof(acpi_rsdt_t);
  546. acpi_rsdt->entry_ptrs[0] = __fwtab_pa(base_nasid, acpi_sapic);
  547. memcpy(acpi_sapic->header.signature, "SPIC ", 4);
  548. acpi_sapic->header.length = sizeof(acpi_sapic_t)+num_cpus*sizeof(acpi_entry_lsapic_t);
  549. for (cnode=0; cnode<num_nodes; cnode++) {
  550. nasid = GetNasid(cnode);
  551. for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
  552. if (!IsCpuPresent(cnode, cpu))
  553. continue;
  554. acpi_lsapic->type = ACPI_ENTRY_LOCAL_SAPIC;
  555. acpi_lsapic->length = sizeof(acpi_entry_lsapic_t);
  556. acpi_lsapic->acpi_processor_id = cnode*4+cpu;
  557. acpi_lsapic->flags = LSAPIC_ENABLED|LSAPIC_PRESENT;
  558. #if defined(CONFIG_IA64_SGI_SN1)
  559. acpi_lsapic->eid = cpu;
  560. acpi_lsapic->id = nasid;
  561. #else
  562. acpi_lsapic->eid = nasid&0xffff;
  563. acpi_lsapic->id = (cpu<<4) | (nasid>>16);
  564. #endif
  565. acpi_lsapic++;
  566. }
  567. }
  568. #endif
  569. /* fill in the ACPI20 system table - has a pointer to the ACPI table header */
  570. memcpy(acpi20_rsdp->signature, "RSD PTR ", 8);
  571. acpi20_rsdp->xsdt = (struct acpi_xsdt*)__fwtab_pa(base_nasid, acpi_xsdt);
  572. acpi20_rsdp->revision = 2;
  573. acpi_checksum_rsdp20(acpi20_rsdp, sizeof(acpi20_rsdp_t));
  574. /* Set up the XSDT table  - contains pointers to the other ACPI tables */
  575. acpi_table_init(&acpi_xsdt->header, ACPI_XSDT_SIG, ACPI_XSDT_SIG_LEN, 1, 1);
  576. acpi_xsdt->entry_ptrs[0] = __fwtab_pa(base_nasid, acpi_madt);
  577. acpi_xsdt->entry_ptrs[1] = __fwtab_pa(base_nasid, acpi_slit);
  578. acpi_xsdt->entry_ptrs[2] = __fwtab_pa(base_nasid, acpi_srat);
  579. acpi_checksum(&acpi_xsdt->header, sizeof(acpi_xsdt_t) + 16);
  580. /* Set up the MADT table */
  581. acpi_table_init(&acpi_madt->header, ACPI_MADT_SIG, ACPI_MADT_SIG_LEN, 1, 1);
  582. lsapic20 = (acpi20_entry_lsapic_t*) (acpi_madt + 1);
  583. for (cnode=0; cnode<num_nodes; cnode++) {
  584. nasid = GetNasid(cnode);
  585. for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
  586. if (!IsCpuPresent(cnode, cpu))
  587. continue;
  588. lsapic20->type = ACPI20_ENTRY_LOCAL_SAPIC;
  589. lsapic20->length = sizeof(acpi_entry_lsapic_t);
  590. lsapic20->acpi_processor_id = cnode*4+cpu;
  591. lsapic20->flags = LSAPIC_ENABLED|LSAPIC_PRESENT;
  592. #if defined(CONFIG_IA64_SGI_SN1)
  593. lsapic20->eid = cpu;
  594. lsapic20->id = nasid;
  595. #else
  596. lsapic20->eid = nasid&0xffff;
  597. lsapic20->id = (cpu<<4) | (nasid>>16);
  598. #endif
  599. lsapic20 = (acpi20_entry_lsapic_t*) ((long)lsapic20+sizeof(acpi_entry_lsapic_t));
  600. }
  601. }
  602. acpi_checksum(&acpi_madt->header, (char*)lsapic20 - (char*)acpi_madt);
  603. /* Set up the SRAT table */
  604. acpi_table_init(&acpi_srat->header, ACPI_SRAT_SIG, ACPI_SRAT_SIG_LEN, ACPI_SRAT_REVISION, 1);
  605. ptr = acpi_srat+1;
  606. for (cnode=0; cnode<num_nodes; cnode++) {
  607. nasid = GetNasid(cnode);
  608. srat_memory_affinity = ptr;
  609. ptr = srat_memory_affinity+1;
  610. srat_memory_affinity->type = SRAT_MEMORY_STRUCTURE;
  611. srat_memory_affinity->length = sizeof(srat_memory_affinity_t);
  612. srat_memory_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
  613. srat_memory_affinity->base_addr_lo = 0;
  614. srat_memory_affinity->length_lo = 0;
  615. #if defined(CONFIG_IA64_SGI_SN1)
  616. srat_memory_affinity->base_addr_hi = nasid<<1;
  617. srat_memory_affinity->length_hi = SN1_NODE_SIZE>>32;
  618. #else
  619. srat_memory_affinity->base_addr_hi = (nasid<<6) | (3<<4);
  620. srat_memory_affinity->length_hi = SN2_NODE_SIZE>>32;
  621. #endif
  622. srat_memory_affinity->memory_type = ACPI_ADDRESS_RANGE_MEMORY;
  623. srat_memory_affinity->flags = SRAT_MEMORY_FLAGS_ENABLED;
  624. }
  625. for (cnode=0; cnode<num_nodes; cnode++) {
  626. nasid = GetNasid(cnode);
  627. for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
  628. if (!IsCpuPresent(cnode, cpu))
  629. continue;
  630. srat_cpu_affinity = ptr;
  631. ptr = srat_cpu_affinity + 1;
  632. srat_cpu_affinity->type = SRAT_CPU_STRUCTURE;
  633. srat_cpu_affinity->length = sizeof(srat_cpu_affinity_t);
  634. srat_cpu_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
  635. srat_cpu_affinity->flags = SRAT_CPU_FLAGS_ENABLED;
  636. #if defined(CONFIG_IA64_SGI_SN1)
  637. srat_cpu_affinity->apic_id = nasid;
  638. srat_cpu_affinity->local_sapic_eid = cpu;
  639. #else
  640. srat_cpu_affinity->local_sapic_eid = nasid&0xffff;
  641. srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>16);
  642. #endif
  643. }
  644. }
  645. acpi_checksum(&acpi_srat->header, (char*)ptr - (char*)acpi_srat);
  646. /* Set up the SLIT table */
  647. acpi_table_init(&acpi_slit->header, ACPI_SLIT_SIG, ACPI_SLIT_SIG_LEN, ACPI_SLIT_REVISION, 1);
  648. acpi_slit->localities = PROXIMITY_DOMAIN(max_nasid)+1;
  649. cp=acpi_slit->entries;
  650. memset(cp, 255, acpi_slit->localities*acpi_slit->localities);
  651. for (i=0; i<=max_nasid; i++)
  652. for (j=0; j<=max_nasid; j++)
  653. if (nasid_present(i) && nasid_present(j))
  654. *(cp+PROXIMITY_DOMAIN(i)*acpi_slit->localities+PROXIMITY_DOMAIN(j)) = 10 + MIN(254, 5*ABS(i-j));
  655. cp = acpi_slit->entries + acpi_slit->localities*acpi_slit->localities;
  656. acpi_checksum(&acpi_slit->header, cp - (char*)acpi_slit);
  657. /* fill in the SAL system table: */
  658. memcpy(sal_systab->signature, "SST_", 4);
  659. sal_systab->size = sizeof(*sal_systab);
  660. sal_systab->sal_rev_minor = 1;
  661. sal_systab->sal_rev_major = 0;
  662. sal_systab->entry_count = 3;
  663. strcpy(sal_systab->oem_id, "SGI");
  664. strcpy(sal_systab->product_id, "SN1");
  665. /* fill in an entry point: */
  666. sal_ed->type = SAL_DESC_ENTRY_POINT;
  667. sal_ed->pal_proc = __fwtab_pa(base_nasid, pal_desc[0]);
  668. sal_ed->sal_proc = __fwtab_pa(base_nasid, sal_desc[0]);
  669. sal_ed->gp = __fwtab_pa(base_nasid, sal_desc[1]);
  670. /* kludge the PTC domain info */
  671. sal_ptc->type = SAL_DESC_PTC;
  672. sal_ptc->num_domains = 0;
  673. sal_ptc->domain_info = __fwtab_pa(base_nasid, sal_ptcdi);
  674. cpus_found = 0;
  675. last_domain = -1;
  676. sal_ptcdi--;
  677. for (cnode=0; cnode<num_nodes; cnode++) {
  678. nasid = GetNasid(cnode);
  679. for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
  680. if (IsCpuPresent(cnode, cpu)) {
  681. domain = cnode*CPUS_PER_NODE + cpu/CPUS_PER_FSB;
  682. if (domain != last_domain) {
  683. sal_ptc->num_domains++;
  684. sal_ptcdi++;
  685. sal_ptcdi->proc_count = 0;
  686. sal_ptcdi->proc_list = __fwtab_pa(base_nasid, sal_ptclid);
  687. last_domain = domain;
  688. }
  689. sal_ptcdi->proc_count++;
  690. sal_ptclid->id = nasid;
  691. sal_ptclid->eid = cpu;
  692. sal_ptclid++;
  693. cpus_found++;
  694. }
  695. }
  696. }
  697. if (cpus_found != num_cpus)
  698. FPROM_BUG();
  699. /* Make the AP WAKEUP entry */
  700. sal_apwake->type = SAL_DESC_AP_WAKEUP;
  701. sal_apwake->mechanism = IA64_SAL_AP_EXTERNAL_INT;
  702. sal_apwake->vector = 18;
  703. for (checksum=0, cp=(char*)sal_systab; cp < (char *)efi_memmap; ++cp)
  704. checksum += *cp;
  705. sal_systab->checksum = -checksum;
  706. /* If the checksum is correct, the kernel tries to use the
  707.  * table. We dont build enough table & the kernel aborts.
  708.  * Note that the PROM hasd thhhe same problem!!
  709.  */
  710. #ifdef DOESNT_WORK
  711. for (checksum=0, cp=(char*)acpi_rsdp, cpe=cp+RSDP_CHECKSUM_LENGTH; cp<cpe; ++cp)
  712. checksum += *cp;
  713. acpi_rsdp->checksum = -checksum;
  714. #endif
  715. md = &efi_memmap[0];
  716. num_memmd = build_efi_memmap((void *)md, mdsize) ;
  717. bp = (struct ia64_boot_param*) __fwtab_pa(base_nasid, BOOT_PARAM_ADDR);
  718. bp->efi_systab = __fwtab_pa(base_nasid, &fw_mem);
  719. bp->efi_memmap = __fwtab_pa(base_nasid, efi_memmap);
  720. bp->efi_memmap_size = num_memmd*mdsize;
  721. bp->efi_memdesc_size = mdsize;
  722. bp->efi_memdesc_version = 0x101;
  723. bp->command_line = __fwtab_pa(base_nasid, cmd_line);
  724. bp->console_info.num_cols = 80;
  725. bp->console_info.num_rows = 25;
  726. bp->console_info.orig_x = 0;
  727. bp->console_info.orig_y = 24;
  728. bp->fpswa = 0;
  729. /*
  730.  * Now pick the BSP & store it LID value in
  731.  * a global variable. Note if BSP is greater than last cpu,
  732.  * pick the last cpu.
  733.  */
  734. for (cnode=0; cnode<num_nodes; cnode++) {
  735. for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
  736. if (!IsCpuPresent(cnode, cpu))
  737. continue;
  738. #ifdef CONFIG_IA64_SGI_SN1
  739. bsp_lid = (GetNasid(cnode)<<24) | (cpu<<16);
  740. #else
  741. bsp_lid = (GetNasid(cnode)<<16) | (cpu<<28);
  742. #endif
  743. if (bsp-- > 0)
  744. continue;
  745. return;
  746. }
  747. }
  748. }