⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fw-emu.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * PAL & SAL emulation. * * Copyright (C) 1998-2000 Hewlett-Packard Co * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com> * * * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved. *  * This program is free software; you can redistribute it and/or modify it  * under the terms of version 2 of the GNU General Public License  * as published by the Free Software Foundation. *  * This program is distributed in the hope that it would be useful, but  * WITHOUT ANY WARRANTY; without even the implied warranty of  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  *  * Further, this software is distributed without any warranty that it is  * free of the rightful claim of any third person regarding infringement  * or the like.  Any license provided herein, whether implied or  * otherwise, applies only to this software file.  Patent licenses, if  * any, provided herein do not apply to combinations of this program with  * other software, or any other product whatsoever. *  * You should have received a copy of the GNU General Public  * License along with this program; if not, write the Free Software  * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. *  * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,  * Mountain View, CA  94043, or: *  * http://www.sgi.com  *  * For further information regarding this notice, see:  *  * http://oss.sgi.com/projects/GenInfo/NoticeExplan */#include <linux/config.h>#include <asm/efi.h>#include <asm/pal.h>#include <asm/sal.h>#include <asm/sn/sn_sal.h>#include <asm/processor.h>#include <asm/sn/sn_cpuid.h>#ifdef CONFIG_IA64_SGI_SN2#include <asm/sn/sn2/addrs.h>#include <asm/sn/sn2/shub_mmr.h>#endif#include <asm/acpi-ext.h>#include "fpmem.h"#define zzACPI_1_0	1		/* Include ACPI 1.0 tables */#define OEMID			"SGI"#ifdef CONFIG_IA64_SGI_SN1#define PRODUCT			"SN1"#define PROXIMITY_DOMAIN(nasid)	(nasid)#else#define PRODUCT			"SN2"#define PROXIMITY_DOMAIN(nasid)	(((nasid)>>1) & 255)#endif#define MB	(1024*1024UL)#define GB	(MB*1024UL)#define BOOT_PARAM_ADDR 0x40000#define MAX(i,j)		((i) > (j) ? (i) : (j))#define MIN(i,j)		((i) < (j) ? (i) : (j))#define ABS(i)			((i) > 0   ? (i) : -(i))#define ALIGN8(p)		(((long)(p) +7) & ~7)#define FPROM_BUG()		do {while (1);} while (0)#define MAX_SN_NODES		128#define MAX_LSAPICS		512#define MAX_CPUS		512#define MAX_CPUS_NODE		4#define CPUS_PER_NODE		4#define CPUS_PER_FSB		2#define CPUS_PER_FSB_MASK	(CPUS_PER_FSB-1)#ifdef ACPI_1_0#define NUM_EFI_DESCS		3#else#define NUM_EFI_DESCS		2#endif#define RSDP_CHECKSUM_LENGTH	20typedef union ia64_nasid_va {        struct {#if defined(CONFIG_IA64_SGI_SN1)                unsigned long off   : 33;       /* intra-region offset */		unsigned long nasid :  7;	/* NASID */		unsigned long off2  : 21;	/* fill */                unsigned long reg   :  3;       /* region number */#elif defined(CONFIG_IA64_SGI_SN2)                unsigned long off   : 36;       /* intra-region offset */		unsigned long attr  :  2;		unsigned long nasid : 11;	/* NASID */		unsigned long off2  : 12;	/* fill */                unsigned long reg   :  3;       /* region number */#endif        } f;        unsigned long l;        void *p;} ia64_nasid_va;typedef struct {	unsigned long	pc;	unsigned long	gp;} func_ptr_t; #define IS_VIRTUAL_MODE() 	 ({struct ia64_psr psr; asm("mov %0=psr" : "=r"(psr)); psr.dt;})#define ADDR_OF(p)		(IS_VIRTUAL_MODE() ? ((void*)((long)(p)+PAGE_OFFSET)) : ((void*) (p)))#if defined(CONFIG_IA64_SGI_SN1)#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;})#elif defined(CONFIG_IA64_SGI_SN2)#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;})#endif/* * The following variables are passed thru registersfrom the configuration file and * are set via the _start function. */long		base_nasid;long		num_cpus;long		bsp_entry_pc=0;long		num_nodes;long		app_entry_pc;int		bsp_lid;func_ptr_t	ap_entry;extern void pal_emulator(void);static efi_runtime_services_t    *efi_runtime_p;static char fw_mem[(  sizeof(efi_system_table_t)		    + sizeof(efi_runtime_services_t)		    + NUM_EFI_DESCS*sizeof(efi_config_table_t)		    + sizeof(struct ia64_sal_systab)		    + sizeof(struct ia64_sal_desc_entry_point)		    + sizeof(struct ia64_sal_desc_ap_wakeup)#ifdef ACPI_1_0		    + sizeof(acpi_rsdp_t)		    + sizeof(acpi_rsdt_t)		    + sizeof(acpi_sapic_t)		    + MAX_LSAPICS*(sizeof(acpi_entry_lsapic_t))#endif		    + sizeof(acpi20_rsdp_t)		    + sizeof(acpi_xsdt_t)		    + sizeof(acpi_slit_t)		    +   MAX_SN_NODES*MAX_SN_NODES+8		    + sizeof(acpi_madt_t)		    +   16*MAX_CPUS		    + (1+8*MAX_SN_NODES)*(sizeof(efi_memory_desc_t))		    + sizeof(acpi_srat_t)		    +   MAX_CPUS*sizeof(srat_cpu_affinity_t)		    +   MAX_SN_NODES*sizeof(srat_memory_affinity_t)		    + sizeof(ia64_sal_desc_ptc_t) +		    + MAX_SN_NODES*sizeof(ia64_sal_ptc_domain_info_t) +		    + MAX_CPUS*sizeof(ia64_sal_ptc_domain_proc_entry_t) +		    + 1024)] __attribute__ ((aligned (8)));static efi_status_tefi_get_time (efi_time_t *tm, efi_time_cap_t *tc){	if (tm) {		memset(tm, 0, sizeof(*tm));		tm->year = 2000;		tm->month = 2;		tm->day = 13;		tm->hour = 10;		tm->minute = 11;		tm->second = 12;	}	if (tc) {		tc->resolution = 10;		tc->accuracy = 12;		tc->sets_to_zero = 1;	}	return EFI_SUCCESS;}static voidefi_reset_system (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data){	while(1);	/* Is there a pseudo-op to stop medusa */}static efi_status_tefi_success (void){	return EFI_SUCCESS;}static efi_status_tefi_unimplemented (void){	return EFI_UNSUPPORTED;}#ifdef CONFIG_IA64_SGI_SN2#undef cpu_physical_id#define cpu_physical_id(cpuid)                  ((ia64_get_lid() >> 16) & 0xffff)voidfprom_send_cpei(void) {        long            *p, val;        long            physid;        long            nasid, slice;        physid = cpu_physical_id(0);        nasid = cpu_physical_id_to_nasid(physid);        slice = cpu_physical_id_to_slice(physid);        p = (long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT);        val =   (1UL<<SH_IPI_INT_SEND_SHFT) |                (physid<<SH_IPI_INT_PID_SHFT) |                ((long)0<<SH_IPI_INT_TYPE_SHFT) |                ((long)0x1e<<SH_IPI_INT_IDX_SHFT) |                (0x000feeUL<<SH_IPI_INT_BASE_SHFT);        *p = val;}#endifstatic longsal_emulator (long index, unsigned long in1, unsigned long in2,	      unsigned long in3, unsigned long in4, unsigned long in5,	      unsigned long in6, unsigned long in7){	register long r9 asm ("r9") = 0;	register long r10 asm ("r10") = 0;	register long r11 asm ("r11") = 0;	long status;	/*	 * Don't do a "switch" here since that gives us code that	 * isn't self-relocatable.	 */	status = 0;	if (index == SAL_FREQ_BASE) {		switch (in1) {		      case SAL_FREQ_BASE_PLATFORM:			r9 = 500000000;			break;		      case SAL_FREQ_BASE_INTERVAL_TIMER:			/*			 * Is this supposed to be the cr.itc frequency			 * or something platform specific?  The SAL			 * doc ain't exactly clear on this...			 */			r9 = 700000000;			break;		      case SAL_FREQ_BASE_REALTIME_CLOCK:			r9 = 50000000;			break;		      default:			status = -1;			break;		}	} else if (index == SAL_SET_VECTORS) {		if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) {			func_ptr_t	*fp;			fp = ADDR_OF(&ap_entry);			fp->pc = in2;			fp->gp = in3;		} else if (in1 == SAL_VECTOR_OS_MCA || in1 == SAL_VECTOR_OS_INIT) {		} else {			status = -1;		}		;	} else if (index == SAL_GET_STATE_INFO) {		;	} else if (index == SAL_GET_STATE_INFO_SIZE) {		;	} else if (index == SAL_CLEAR_STATE_INFO) {		;	} else if (index == SAL_MC_RENDEZ) {		;	} else if (index == SAL_MC_SET_PARAMS) {		;	} else if (index == SAL_CACHE_FLUSH) {		;	} else if (index == SAL_CACHE_INIT) {		;	} else if (index == SAL_UPDATE_PAL) {		;#ifdef CONFIG_IA64_SGI_SN2	} else if (index == SN_SAL_LOG_CE) {#ifdef ajmtestcpei		fprom_send_cpei();#else /* ajmtestcpei */		;#endif /* ajmtestcpei */#endif	} else if (index == SN_SAL_PROBE) {		r9 = 0UL;		if (in2 == 4) {			r9 = *(unsigned *)in1;			if (r9 == -1) {				status = 1;			}		} else if (in2 == 2) {			r9 = *(unsigned short *)in1;			if (r9 == -1) {				status = 1;			}		} else if (in2 == 1) {			r9 = *(unsigned char *)in1;			if (r9 == -1) {				status = 1;			}		} else if (in2 == 8) {			r9 = *(unsigned long *)in1;			if (r9 == -1) {				status = 1;			}		} else {			status = 2;		}	} else if (index == SN_SAL_GET_KLCONFIG_ADDR) {		r9 = 0x30000;	} else if (index == SN_SAL_CONSOLE_PUTC) {		status = -1;	} else if (index == SN_SAL_CONSOLE_GETC) {		status = -1;	} else if (index == SN_SAL_CONSOLE_POLL) {		status = -1;	} else {		status = -1;	}	asm volatile ("" :: "r"(r9), "r"(r10), "r"(r11));	return status;}/* * This is here to work around a bug in egcs-1.1.1b that causes the * compiler to crash (seems like a bug in the new alias analysis code. */void *id (long addr){	return (void *) addr;}/* * Fix the addresses in a function pointer by adding base node address * to pc & gp. */voidfix_function_pointer(void *fp){	func_ptr_t	*_fp;	_fp = fp;	_fp->pc = __fwtab_pa(base_nasid, _fp->pc);	_fp->gp = __fwtab_pa(base_nasid, _fp->gp);}voidfix_virt_function_pointer(void **fptr){        func_ptr_t      *fp;	long		*p;	p = (long*)fptr;        fp = *fptr;        fp->pc = fp->pc | PAGE_OFFSET;        fp->gp = fp->gp | PAGE_OFFSET;	*p |= PAGE_OFFSET;}intefi_set_virtual_address_map(void){        efi_runtime_services_t            *runtime;        runtime = efi_runtime_p;        fix_virt_function_pointer((void**)&runtime->get_time);        fix_virt_function_pointer((void**)&runtime->set_time);        fix_virt_function_pointer((void**)&runtime->get_wakeup_time);        fix_virt_function_pointer((void**)&runtime->set_wakeup_time);        fix_virt_function_pointer((void**)&runtime->set_virtual_address_map);        fix_virt_function_pointer((void**)&runtime->get_variable);        fix_virt_function_pointer((void**)&runtime->get_next_variable);        fix_virt_function_pointer((void**)&runtime->set_variable);        fix_virt_function_pointer((void**)&runtime->get_next_high_mono_count);        fix_virt_function_pointer((void**)&runtime->reset_system);        return EFI_SUCCESS;;}voidacpi_table_init(acpi_desc_table_hdr_t *p, char *sig, int siglen, int revision, int oem_revision){	memcpy(p->signature, sig, siglen);	memcpy(p->oem_id, OEMID, 6);	memcpy(p->oem_table_id, sig, 4);	memcpy(p->oem_table_id+4, PRODUCT, 4);	p->revision = revision;	p->oem_revision = (revision<<16) + oem_revision;	p->creator_id = 1;	p->creator_revision = 1;}voidacpi_checksum(acpi_desc_table_hdr_t *p, int length){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -