📄 firmware.c
字号:
}/** * pdc_model_cpuid - Returns the CPU_ID. * @cpu_id: The return buffer. * * Returns the CPU_ID value which uniquely identifies the cpu portion of * the processor module. */int pdc_model_cpuid(unsigned long *cpu_id){ int retval; spin_lock_irq(&pdc_lock); pdc_result[0] = 0; /* preset zero (call may not be implemented!) */ retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CPU_ID, __pa(pdc_result), 0); convert_to_wide(pdc_result); *cpu_id = pdc_result[0]; spin_unlock_irq(&pdc_lock); return retval;}/** * pdc_model_capabilities - Returns the platform capabilities. * @capabilities: The return buffer. * * Returns information about platform support for 32- and/or 64-bit * OSes, IO-PDIR coherency, and virtual aliasing. */int pdc_model_capabilities(unsigned long *capabilities){ int retval; spin_lock_irq(&pdc_lock); pdc_result[0] = 0; /* preset zero (call may not be implemented!) */ retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0); convert_to_wide(pdc_result); *capabilities = pdc_result[0]; spin_unlock_irq(&pdc_lock); return retval;}/** * pdc_cache_info - Return cache and TLB information. * @cache_info: The return buffer. * * Returns information about the processor's cache and TLB. */int pdc_cache_info(struct pdc_cache_info *cache_info){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_INFO, __pa(pdc_result), 0); convert_to_wide(pdc_result); memcpy(cache_info, pdc_result, sizeof(*cache_info)); spin_unlock_irq(&pdc_lock); return retval;}#ifndef CONFIG_PA20/** * pdc_btlb_info - Return block TLB information. * @btlb: The return buffer. * * Returns information about the hardware Block TLB. */int pdc_btlb_info(struct pdc_btlb_info *btlb) { int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(pdc_result), 0); memcpy(btlb, pdc_result, sizeof(*btlb)); spin_unlock_irq(&pdc_lock); if(retval < 0) { btlb->max_size = 0; } return retval;}/** * pdc_mem_map_hpa - Find fixed module information. * @address: The return buffer * @mod_path: pointer to dev path structure. * * This call was developed for S700 workstations to allow the kernel to find * the I/O devices (Core I/O). In the future (Kittyhawk and beyond) this * call will be replaced (on workstations) by the architected PDC_SYSTEM_MAP * call. * * This call is supported by all existing S700 workstations (up to Gecko). */int pdc_mem_map_hpa(struct pdc_memory_map *address, struct pdc_module_path *mod_path){ int retval; spin_lock_irq(&pdc_lock); memcpy(pdc_result2, mod_path, sizeof(*mod_path)); retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(pdc_result), __pa(pdc_result2)); memcpy(address, pdc_result, sizeof(*address)); spin_unlock_irq(&pdc_lock); return retval;}#endif /* !CONFIG_PA20 *//** * pdc_lan_station_id - Get the LAN address. * @lan_addr: The return buffer. * @hpa: The network device HPA. * * Get the LAN station address when it is not directly available from the LAN hardware. */int pdc_lan_station_id(char *lan_addr, unsigned long hpa){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ, __pa(pdc_result), hpa); if (retval < 0) { /* FIXME: else read MAC from NVRAM */ memset(lan_addr, 0, PDC_LAN_STATION_ID_SIZE); } else { memcpy(lan_addr, pdc_result, PDC_LAN_STATION_ID_SIZE); } spin_unlock_irq(&pdc_lock); return retval;}EXPORT_SYMBOL(pdc_lan_station_id);/** * pdc_get_initiator - Get the SCSI Interface Card params (SCSI ID, SDTR, SE or LVD) * @hwpath: fully bc.mod style path to the device. * @scsi_id: what someone told firmware the ID should be. * @period: time in cycles * @width: 8 or 16-bit wide bus * @mode: 0,1,2 -> SE,HVD,LVD signalling mode * * Get the SCSI operational parameters from PDC. * Needed since HPUX never used BIOS or symbios card NVRAM. * Most ncr/sym cards won't have an entry and just use whatever * capabilities of the card are (eg Ultra, LVD). But there are * several cases where it's useful: * o set SCSI id for Multi-initiator clusters, * o cable too long (ie SE scsi 10Mhz won't support 6m length), * o bus width exported is less than what the interface chip supports. */int pdc_get_initiator(struct hardware_path *hwpath, unsigned char *scsi_id, unsigned long *period, char *width, char *mode){ int retval; spin_lock_irq(&pdc_lock);/* BCJ-XXXX series boxes. E.G. "9000/785/C3000" */#define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \ strncmp(boot_cpu_data.pdc.sys_model_name, "9000/785", 8) == 0) retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR, __pa(pdc_result), __pa(hwpath)); if (retval < PDC_OK) goto fail; *scsi_id = (unsigned char) pdc_result[0]; /* convert Bus speed in Mhz to period (in 1/10 ns) */ switch (pdc_result[1]) { /* * case 0: driver determines rate * case -1: Settings are uninitialized. */ case 5: *period = 2000; break; case 10: *period = 1000; break; case 20: *period = 500; break; case 40: *period = 250; break; case 80: *period = 125; break; default: /* Do nothing */ break; } /* * pdc_result[2] PDC suggested SCSI id * pdc_result[3] PDC suggested SCSI rate */ if (IS_SPROCKETS()) { /* 0 == 8-bit, 1 == 16-bit */ *width = (char) pdc_result[4]; /* ...in case someone needs it in the future. * sym53c8xx.c comments say it can't autodetect * for 825/825A/875 chips. * 0 == SE, 1 == HVD, 2 == LVD */ *mode = (char) pdc_result[5]; } fail: spin_unlock_irq(&pdc_lock); return (retval >= PDC_OK);}EXPORT_SYMBOL(pdc_get_initiator);/** * pdc_pci_irt_size - Get the number of entries in the interrupt routing table. * @num_entries: The return value. * @hpa: The HPA for the device. * * This PDC function returns the number of entries in the specified cell's * interrupt table. * Similar to PDC_PAT stuff - but added for Forte/Allegro boxes */ int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE, __pa(pdc_result), hpa); convert_to_wide(pdc_result); *num_entries = pdc_result[0]; spin_unlock_irq(&pdc_lock); return retval;}/** * pdc_pci_irt - Get the PCI interrupt routing table. * @num_entries: The number of entries in the table. * @hpa: The Hard Physical Address of the device. * @tbl: * * Get the PCI interrupt routing table for the device at the given HPA. * Similar to PDC_PAT stuff - but added for Forte/Allegro boxes */int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl){ int retval; spin_lock_irq(&pdc_lock); pdc_result[0] = num_entries; retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL, __pa(pdc_result), hpa, __pa(tbl)); spin_unlock_irq(&pdc_lock); return retval;}#if 0 /* UNTEST CODE - left here in case someone needs it *//** * pdc_pci_config_read - read PCI config space. * @hpa token from PDC to indicate which PCI device * @pci_addr configuration space address to read from * * Read PCI Configuration space *before* linux PCI subsystem is running. */unsigned int pdc_pci_config_read(void *hpa, unsigned long cfg_addr){ int retval; spin_lock_irq(&pdc_lock); pdc_result[0] = 0; pdc_result[1] = 0; retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_READ_CONFIG, __pa(pdc_result), hpa, cfg_addr&~3UL, 4UL); spin_unlock_irq(&pdc_lock); return retval ? ~0 : (unsigned int) pdc_result[0];}/** * pdc_pci_config_write - read PCI config space. * @hpa token from PDC to indicate which PCI device * @pci_addr configuration space address to write * @val value we want in the 32-bit register * * Write PCI Configuration space *before* linux PCI subsystem is running. */void pdc_pci_config_write(void *hpa, unsigned long cfg_addr, unsigned int val){ int retval; spin_lock_irq(&pdc_lock); pdc_result[0] = 0; retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_WRITE_CONFIG, __pa(pdc_result), hpa, cfg_addr&~3UL, 4UL, (unsigned long) val); spin_unlock_irq(&pdc_lock); return retval;}#endif /* UNTESTED CODE *//** * pdc_tod_read - Read the Time-Of-Day clock. * @tod: The return buffer: * * Read the Time-Of-Day clock */int pdc_tod_read(struct pdc_tod *tod){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(pdc_result), 0); convert_to_wide(pdc_result); memcpy(tod, pdc_result, sizeof(*tod)); spin_unlock_irq(&pdc_lock); return retval;}EXPORT_SYMBOL(pdc_tod_read);/** * pdc_tod_set - Set the Time-Of-Day clock. * @sec: The number of seconds since epoch. * @usec: The number of micro seconds. * * Set the Time-Of-Day clock. */ int pdc_tod_set(unsigned long sec, unsigned long usec){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec); spin_unlock_irq(&pdc_lock); return retval;}EXPORT_SYMBOL(pdc_tod_set);#ifdef __LP64__int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr, struct pdc_memory_table *tbl, unsigned long entries){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_MEM, PDC_MEM_TABLE, __pa(pdc_result), __pa(pdc_result2), entries); convert_to_wide(pdc_result); memcpy(r_addr, pdc_result, sizeof(*r_addr)); memcpy(tbl, pdc_result2, entries * sizeof(*tbl)); spin_unlock_irq(&pdc_lock); return retval;}#endif /* __LP64__ *//* FIXME: Is this pdc used? I could not find type reference to ftc_bitmap * so I guessed at unsigned long. Someone who knows what this does, can fix * it later. :) */int pdc_do_firm_test_reset(unsigned long ftc_bitmap){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_FIRM_TEST_RESET, PDC_FIRM_TEST_MAGIC, ftc_bitmap); spin_unlock_irq(&pdc_lock); return retval;}/* * pdc_do_reset - Reset the system. * * Reset the system. */int pdc_do_reset(){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_RESET); spin_unlock_irq(&pdc_lock); return retval;}/* * pdc_soft_power_info - Enable soft power switch. * @power_reg: address of soft power register * * Return the absolute address of the soft power switch register */int __init pdc_soft_power_info(unsigned long *power_reg){ int retval; *power_reg = (unsigned long) (-1); spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_INFO, __pa(pdc_result), 0); if (retval == PDC_OK) { convert_to_wide(pdc_result); *power_reg = f_extend(pdc_result[0]); } spin_unlock_irq(&pdc_lock); return retval;}/* * pdc_soft_power_button - Control the soft power button behaviour * @sw_control: 0 for hardware control, 1 for software control * * * This PDC function places the soft power button under software or * hardware control. * Under software control the OS may control to when to allow to shut * down the system. Under hardware control pressing the power button * powers off the system immediately. */int pdc_soft_power_button(int sw_control){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control); spin_unlock_irq(&pdc_lock); return retval;}/* * pdc_io_reset - Hack to avoid overlapping range registers of Bridges devices.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -