/*
 * Copyright 1991-2002 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SYS_PROM_PLAT_H
#define	_SYS_PROM_PLAT_H

#pragma ident	"@(#)prom_plat.h	1.37	02/12/11 SMI"

#include <sys/cpuvar.h>

#ifdef	__cplusplus
extern "C" {
#endif

#if defined(_NO_LONGLONG)
#error "This header won't work with _NO_LONGLONG"
#endif

/*
 * This file contains external platform-specific promif interface definitions.
 * There may be none.  This file is included by reference in <sys/promif.h>
 *
 * This version of the file is for the IEEE 1275-1994 compliant sun4u prom.
 */

/*
 * Memory allocation plus memory/mmu interfaces:
 *
 * Routines with fine-grained memory and MMU control are platform-dependent.
 *
 * MMU node virtualized "mode" arguments and results for Spitfire MMU:
 *
 * The default virtualized "mode" for client program mappings created
 * by the firmware is as follows:
 *
 * G (global)		Clear
 * L (locked)		Clear
 * W (write)		Set
 * R (read - soft)	Set (Prom is not required to implement soft bits)
 * X (exec - soft)	Set (Prom is not required to implement soft bits)
 * CV,CP (Cacheable)	Set if memory page, Clear if IO page
 * E (side effects)	Clear if memory page; Set if IO page
 * IE (Invert endian.)	Clear
 *
 * The following fields are initialized as follows in the TTE-data for any
 * mappings created by the firmware on behalf of the client program:
 *
 * P (Priviledged)	Set
 * V (Valid)		Set
 * NFO (No Fault Only)	Clear
 * Context		0
 * Soft bits		< private to the firmware implementation >
 *
 * Page size of Prom mappings are typically 8k, "modify" cannot change
 * page sizes. Mappings created by "map" are 8k pages.
 *
 * If the virtualized "mode" is -1, the defaults as shown above are used,
 * otherwise the virtualized "mode" is set (and returned) based on the
 * following virtualized "mode" abstractions. The mmu node "translations"
 * property contains the actual tte-data, not the virtualized "mode".
 *
 * Note that client programs may not create locked mappings by setting
 * the LOCKED bit. There are Spitfire specific client interfaces to create
 * and remove locked mappings. (SUNW,{i,d}tlb-load).
 * The LOCKED bit is defined here since it may be returned by the
 * "translate" method.
 *
 * The PROM is not required to implement the Read and eXecute soft bits,
 * and is not required to track them for the client program. They may be
 * set on calls to "map" and "modfify" and may be ignored by the firmware,
 * and are not necessarily returned from "translate".
 *
 * The TTE soft bits are private to the firmware.  No assumptions may
 * be made regarding the contents of the TTE soft bits.
 *
 * Changing a mapping from cacheable to non-cacheable implies a flush
 * or invalidate operation, if necessary.
 *
 * NB: The "map" MMU node method should NOT be used to create IO device
 * mappings. The correct way to do this is to call the device's parent
 * "map-in" method using the CALL-METHOD client interface service.
 */

#define	PROM_MMU_MODE_DEFAULT	((int)-1)	/* Default "mode", see above */

/*
 * NB: These are not implemented in PROM version P1.0 ...
 */
#define	PROM_MMU_MODE_WRITE	0x0001	/* Translation is Writable */
#define	PROM_MMU_MODE_READ	0x0002	/* Soft: Readable, See above */
#define	PROM_MMU_MODE_EXEC	0x0004	/* Soft: eXecutable, See above */
#define	PROM_MMU_MODE_RWX_MASK	0x0007	/* Mask for R-W-X bits */

#define	PROM_MMU_MODE_LOCKED	0x0010	/* Read-only: Locked; see above */
#define	PROM_MMU_MODE_CACHED	0x0020	/* Set means both CV,CP bits */
#define	PROM_MMU_MODE_EFFECTS	0x0040	/* side Effects bit in MMU */
#define	PROM_MMU_MODE_GLOBAL	0x0080	/* Global bit */
#define	PROM_MMU_MODE_INVERT	0x0100	/* Invert Endianness */

/*
 * resource allocation group: OBP only. (mapping functions are platform
 * dependent because they use physical address arguments.)
 */
extern	caddr_t		prom_map(caddr_t virthint,
			    unsigned long long physaddr, uint_t size);

/*
 * prom_alloc is platform dependent and has historical semantics
 * associated with the align argument and the return value.
 * prom_malloc is the generic memory allocator.
 */
extern	caddr_t		prom_malloc(caddr_t virt, size_t size, uint_t align);

extern	caddr_t		prom_allocate_virt(uint_t align, size_t size);
extern	caddr_t		prom_claim_virt(size_t size, caddr_t virt);
extern	void		prom_free_virt(size_t size, caddr_t virt);

extern	int		prom_allocate_phys(size_t size, uint_t align,
			    unsigned long long *physaddr);
extern	int		prom_claim_phys(size_t size,
			    unsigned long long physaddr);
extern	void		prom_free_phys(size_t size,
			    unsigned long long physaddr);

extern	int		prom_map_phys(int mode, size_t size, caddr_t virt,
			    unsigned long long physaddr);
extern	void		prom_unmap_phys(size_t size, caddr_t virt);
extern	void		prom_unmap_virt(size_t size, caddr_t virt);

/*
 * prom_retain allocates or returns retained physical memory
 * identified by the arguments of name string "id", "size" and "align".
 */
extern	int		prom_retain(char *id, size_t size, uint_t align,
			    unsigned long long *physaddr);

/*
 * prom_translate_virt returns the physical address and virtualized "mode"
 * for the given virtual address. After the call, if *valid is non-zero,
 * a mapping to 'virt' exists and the physical address and virtualized
 * "mode" were returned to the caller.
 */
extern	int		prom_translate_virt(caddr_t virt, int *valid,
			    unsigned long long *physaddr, int *mode);

/*
 * prom_modify_mapping changes the "mode" of an existing mapping or
 * repeated mappings. virt is the virtual address whose "mode" is to
 * be changed; size is some multiple of the fundamental pagesize.
 * This method cannot be used to change the pagesize of an MMU mapping,
 * nor can it be used to Lock a translation into the i or d tlb.
 */
extern	int	prom_modify_mapping(caddr_t virt, size_t size, int mode);

/*
 * Client interfaces for managing the {i,d}tlb handoff to client programs.
 */
extern	int		prom_itlb_load(int index,
			    unsigned long long tte_data, caddr_t virt);

extern	int		prom_dtlb_load(int index,
			    unsigned long long tte_data, caddr_t virt);

#ifdef STINGRAY
/* FJC:3:MMU.PROM */
extern	int		prom_itlb_load_locked(int index,
			    unsigned long long tte_data, caddr_t virt);

extern	int		prom_dtlb_load_locked(int index,
			    unsigned long long tte_data, caddr_t virt);
#endif

/*
 * Used for locking entries in the MTLB.
 */

#ifdef _KAISER
/* FJC:3:MMU.PROM */
extern	int		prom_fjsv_get_tlb_locked(void);
extern	int		prom_fjsv_set_tlb_locked(u_int num);
#else
#ifdef LATER
extern	int		prom_mtlb_get_lockcnt(void);
extern	int		prom_mtlb_set_lockcnt(int index);
#endif
#endif /* _KAISER */

/*
 * Administrative group: OBP only and SMCC platform specific.
 * XXX: IDPROM related stuff should be replaced with specific data-oriented
 * XXX: functions.
 */

extern	int		prom_heartbeat(int msecs);
extern	int		prom_get_unum(int syn_code, unsigned long long physaddr,
				char *buf, uint_t buflen, int *ustrlen);
extern	int		prom_serengeti_get_ecacheunum(int cpuid,
			    unsigned long long physaddr, char *buf,
			    uint_t buflen, int *ustrlen);

extern	int		prom_getidprom(caddr_t addr, int size);
extern	int		prom_getmacaddr(ihandle_t hd, caddr_t ea);

#ifdef _KAISER
/* FJC:17:PROM */
extern	int		prom_fjsv_get_unum(int syn_code,
					   unsigned long long physaddr,
					   char *buf, uint_t buflen,
					   int *ustrlen);
extern	int		prom_fjsv_get_unum_high(int syn_code,
						unsigned long long physaddr,
						char *buf, uint_t buflen,
						int *ustrlen);
extern	int		prom_fjsv_get_component_name(u_longlong_t physaddr,
						     char *buf,
						     uint_t buflen,
						     int *ustrlen);
extern	int		prom_fjsv_get_component_name_high(u_longlong_t physaddr,
						     char *buf,
						     uint_t buflen,
						     int *ustrlen);
/* type for prom_fjsv_isolate_failure_XX */
#define	PROM_FJSV_ISOLATE	0x00
#define PROM_FJSV_ISO_MEM	0x01
extern	int		prom_fjsv_isolate_failure(int type, u_longlong_t arg);
extern	int		prom_fjsv_isolate_failure_high(int type,
						       u_longlong_t arg);
extern	int		prom_fjsv_scf_date(int64_t *scfdate1,
					   int64_t *scfdate2,
					   u_longlong_t *tinck);
#endif /* _KAISER */

/*
 * CPU Control Group: MP's only.
 */
extern	int		prom_startcpu(dnode_t node, caddr_t pc, int arg);
extern	int		prom_startcpu_bycpuid(int cpuid, caddr_t pc, int arg);
extern	int		prom_stop_self(void);
extern  int		prom_stopcpu_bycpuid(int);
extern	int		prom_sunfire_cpu_off(void);	/* SunFire only */
extern	int		prom_serengeti_cpu_off(dnode_t node);
extern	int		prom_wakeupcpu(dnode_t node);
extern	int		prom_serengeti_wakeupcpu(dnode_t node);
extern	int		prom_hotaddcpu(int cpuid);
extern	int		prom_hotremovecpu(int cpuid);
extern	void		promsafe_pause_cpus(void);
extern	void		promsafe_xc_attention(cpuset_t cpuset);

#ifdef _KAISER
/* FJC:17:PROM.PLAT */
extern	int		prom_fjsv_stop_self(int *flag);	/* Kaiser only */
extern	int		prom_fjsv_cpu_off(int cpuid);	/* Kaiser only */
#endif /* _KAISER */

/*
 * Set trap table
 */
extern	void		prom_set_traptable(void *tba_addr);

/*
 * Power-off
 */
extern	void		prom_power_off(void);

#ifdef	_KAISER_DR
extern	int		prom_fj_getproplen(dnode_t nodeid, caddr_t name);
extern	int		prom_fj_getprop(dnode_t nodeid, caddr_t name,
					caddr_t value);
extern	void		prom_fjsv_mmu_ihandle_init(void);
extern	ihandle_t	prom_mmu_ihandle_nolock(void);
extern	phandle_t	prom_getphandle_nolock(ihandle_t i);
#endif /* _KAISER_DR */

/*
 * sunfire attach/detach
 */
extern	int		prom_sunfire_attach_board(uint_t board);
extern	int		prom_sunfire_detach_board(uint_t board);

#ifdef _KAISER
/* FJC:17:PROM.PLAT */
/*
 * Kaiser attach/detach
 */
extern	int		prom_fjsv_attach_board2(uint_t board, int *flag);
extern	int		prom_fjsv_detach_board(uint_t board);

#ifdef _COLUMBUS
extern	int	prom_fjsv_detach_board2(uint_t board);
extern 	int 	prom_fjsv_fma_start(uint_t, uint_t);
extern 	int 	prom_fjsv_fma_cancel(void);
extern 	int 	prom_fjsv_fma_end(void);
#endif /* _COLUMBUS */
/*
 * New function
 */
extern	int		prom_fjsv_obp_console(dnode_t nodeid);
extern	int		prom_fjsv_catchflt_addr(u_longlong_t *addr);
#endif /* _KAISER */

/*
 * Serengeti console switch
 */
extern	char		*prom_serengeti_set_console_input(char *new_value);

/*
 * Serengeti attach/detach
 */
extern	int		prom_serengeti_attach_board(uint_t node, uint_t board);
extern	int		prom_serengeti_detach_board(uint_t node, uint_t board);
extern	int		prom_serengeti_tunnel_switch(uint_t node, uint_t board);

/*
 * Starcat-specific routines
 */
extern	int		prom_starcat_switch_tunnel(uint_t portid,
			    uint_t msgtype);
extern	int		prom_starcat_iosram_read(uint32_t key, uint32_t offset,
			    uint32_t len, caddr_t buf);
extern	int		prom_starcat_iosram_write(uint32_t key, uint32_t offset,
			    uint32_t len, caddr_t buf);

/*
 * Starfire-specific routines
 */
extern	int		prom_starfire_add_brd(uint_t cpuid);
extern	int		prom_starfire_rm_brd(uint_t brdnum);
extern	void		prom_starfire_add_cpu(uint_t cpuid);
extern	void		prom_starfire_rm_cpu(uint_t cpuid);
extern	int		prom_starfire_move_cpu0(uint_t cpuid);
extern	void		prom_starfire_init_console(uint_t cpuid);

/*
 * The client program implementation is required to provide a wrapper
 * to the client handler, for the 32 bit client program to 64 bit cell-sized
 * client interface handler (switch stack, etc.).  This function is not
 * to be used externally!
 */

extern	int		client_handler(void *cif_handler, void *arg_array);

/*
 * The 'format' of the "translations" property in the 'mmu' node ...
 */

struct translation {
	uint32_t virt_hi;	/* upper 32 bits of vaddr */
	uint32_t virt_lo;	/* lower 32 bits of vaddr */
	uint32_t size_hi;	/* upper 32 bits of size in bytes */
	uint32_t size_lo;	/* lower 32 bits of size in bytes */
	uint32_t tte_hi;	/* higher 32 bites of tte */
	uint32_t tte_lo;	/* lower 32 bits of tte */
};

#ifdef	_KAISER_DR
struct obp_translations {
	uint32_t	index_hi;
	uint32_t	index_lo;
	uint32_t	ttetag_hi;
	uint32_t	ttetag_lo;
	uint32_t	tte_hi;
	uint32_t	tte_lo;
};
#endif /* _KAISER_DR */

#ifdef	__cplusplus
}
#endif

#endif /* _SYS_PROM_PLAT_H */
