📄 hubspc.c
字号:
/* $Id$ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. *//* * hubspc.c - Hub Memory Space Management Driver * This driver implements the managers for the following * memory resources: * 1) reference counters */#include <linux/types.h>#include <linux/config.h>#include <linux/slab.h>#include <asm/sn/sgi.h>#include <asm/sn/io.h>#include <asm/sn/sn_cpuid.h>#include <linux/devfs_fs.h>#include <linux/devfs_fs_kernel.h>#include <asm/io.h>#include <asm/sn/iograph.h>#include <asm/sn/invent.h>#include <asm/sn/hcl.h>#include <asm/sn/labelcl.h>#include <asm/sn/sn1/mem_refcnt.h>#include <asm/sn/addrs.h>#include <asm/sn/snconfig.h>#include <asm/sn/sn1/hubspc.h>#include <asm/sn/ksys/elsc.h>#include <asm/sn/simulator.h>/* Uncomment the following line for tracing *//* #define HUBSPC_DEBUG 1 */int hubspc_devflag = D_MP;/***********************************************************************//* CPU Prom Space *//***********************************************************************/typedef struct cpuprom_info { devfs_handle_t prom_dev; devfs_handle_t nodevrtx; struct cpuprom_info *next;}cpuprom_info_t;static cpuprom_info_t *cpuprom_head;static spinlock_t cpuprom_spinlock;#define PROM_LOCK() mutex_spinlock(&cpuprom_spinlock)#define PROM_UNLOCK(s) mutex_spinunlock(&cpuprom_spinlock, (s))/* * Add prominfo to the linked list maintained. */voidprominfo_add(devfs_handle_t hub, devfs_handle_t prom){ cpuprom_info_t *info; unsigned long s; info = kmalloc(sizeof(cpuprom_info_t), GFP_KERNEL); ASSERT(info); info->prom_dev = prom; info->nodevrtx = hub; s = PROM_LOCK(); info->next = cpuprom_head; cpuprom_head = info; PROM_UNLOCK(s);}voidprominfo_del(devfs_handle_t prom){ unsigned long s; cpuprom_info_t *info; cpuprom_info_t **prev; s = PROM_LOCK(); prev = &cpuprom_head; while ( (info = *prev) ) { if (info->prom_dev == prom) { *prev = info->next; PROM_UNLOCK(s); return; } prev = &info->next; } PROM_UNLOCK(s); ASSERT(0);}devfs_handle_tprominfo_nodeget(devfs_handle_t prom){ unsigned long s; cpuprom_info_t *info; s = PROM_LOCK(); info = cpuprom_head; while (info) { if(info->prom_dev == prom) { PROM_UNLOCK(s); return info->nodevrtx; } info = info->next; } PROM_UNLOCK(s); return 0;}#if defined(CONFIG_IA64_SGI_SN1)#define SN_PROMVERSION INV_IP35PROM/* Add "detailed" labelled inventory information to the * prom vertex */voidcpuprom_detailed_inventory_info_add(devfs_handle_t prom_dev,devfs_handle_t node){ invent_miscinfo_t *cpuprom_inventory_info; extern invent_generic_t *klhwg_invent_alloc(cnodeid_t cnode, int class, int size); cnodeid_t cnode = hubdev_cnodeid_get(node); /* Allocate memory for the extra inventory information * for the prom */ cpuprom_inventory_info = (invent_miscinfo_t *) klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t)); ASSERT(cpuprom_inventory_info); /* Set the enabled flag so that the hinv interprets this * information */ cpuprom_inventory_info->im_gen.ig_flag = INVENT_ENABLED; cpuprom_inventory_info->im_type = SN_PROMVERSION; /* Store prom revision into inventory information */ cpuprom_inventory_info->im_rev = IP27CONFIG.pvers_rev; cpuprom_inventory_info->im_version = IP27CONFIG.pvers_vers; /* Store this info as labelled information hanging off the * prom device vertex */ hwgraph_info_add_LBL(prom_dev, INFO_LBL_DETAIL_INVENT, (arbitrary_info_t) cpuprom_inventory_info); /* Export this information so that user programs can get to * this by using attr_get() */ hwgraph_info_export_LBL(prom_dev, INFO_LBL_DETAIL_INVENT, sizeof(invent_miscinfo_t));}#define FPROM_CONFIG_ADDR MD_JUNK_BUS_TIMING#define FPROM_ENABLE_MASK MJT_FPROM_ENABLE_MASK#define FPROM_ENABLE_SHFT MJT_FPROM_ENABLE_SHFT#define FPROM_SETUP_MASK MJT_FPROM_SETUP_MASK#define FPROM_SETUP_SHFT MJT_FPROM_SETUP_SHFT/*ARGSUSED*/intcpuprom_map(devfs_handle_t dev, vhandl_t *vt, off_t addr, size_t len){ int errcode = 0; caddr_t kvaddr; devfs_handle_t node; cnodeid_t cnode; node = prominfo_nodeget(dev); if (!node) return EIO; kvaddr = hubdev_prombase_get(node); cnode = hubdev_cnodeid_get(node);#ifdef HUBSPC_DEBUG printk("cpuprom_map: hubnode %d kvaddr 0x%x\n", node, kvaddr);#endif if (len > RBOOT_SIZE) len = RBOOT_SIZE; /* * Map in the prom space */ errcode = v_mapphys(vt, kvaddr, len); if (errcode == 0 ){ /* * Set the MD configuration registers suitably. */ nasid_t nasid; uint64_t value; volatile hubreg_t *regaddr; nasid = COMPACT_TO_NASID_NODEID(cnode); regaddr = REMOTE_HUB_ADDR(nasid, FPROM_CONFIG_ADDR); value = HUB_L(regaddr); value &= ~(FPROM_SETUP_MASK | FPROM_ENABLE_MASK); { value |= (((long)CONFIG_FPROM_SETUP << FPROM_SETUP_SHFT) | ((long)CONFIG_FPROM_ENABLE << FPROM_ENABLE_SHFT)); } HUB_S(regaddr, value); } return (errcode);}#endif /* CONFIG_IA64_SGI_SN1 *//*ARGSUSED*/intcpuprom_unmap(devfs_handle_t dev, vhandl_t *vt){ return 0;}/***********************************************************************//* Base Hub Space Driver *//***********************************************************************//* * hubspc_init * Registration of the hubspc devices with the hub manager */voidhubspc_init(void){ /* * Register with the hub manager */ /* The reference counters */#if defined(CONFIG_IA64_SGI_SN1) hubdev_register(mem_refcnt_attach);#endif /* L1 system controller link */ if ( !IS_RUNNING_ON_SIMULATOR() ) { /* initialize the L1 link */ extern void l1_init(void); l1_init(); }#ifdef HUBSPC_DEBUG printk("hubspc_init: Completed\n");#endif /* HUBSPC_DEBUG */ /* Initialize spinlocks */ mutex_spinlock_init(&cpuprom_spinlock);}/* ARGSUSED */inthubspc_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp){ return (0);}/* ARGSUSED */inthubspc_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp){ return (0);}/* ARGSUSED */inthubspc_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot){ /*REFERENCED*/ int errcode = 0; /* check validity of request */ if( len == 0 ) { return ENXIO; } return errcode;}/* ARGSUSED */inthubspc_unmap(devfs_handle_t dev, vhandl_t *vt){ return (0);}/* ARGSUSED */inthubspc_ioctl(devfs_handle_t dev, int cmd, void *arg, int mode, cred_t *cred_p, int *rvalp){ return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -