📄 firmware.c
字号:
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_stable_read - Read data from Stable Storage. * @staddr: Stable Storage address to access. * @memaddr: The memory address where Stable Storage data shall be copied. * @count: number of bytes to transfert. count is multiple of 4. * * This PDC call reads from the Stable Storage address supplied in staddr * and copies count bytes to the memory address memaddr. * The call will fail if staddr+count > PDC_STABLE size. */int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_READ, staddr, __pa(pdc_result), count); convert_to_wide(pdc_result); memcpy(memaddr, pdc_result, count); spin_unlock_irq(&pdc_lock); return retval;}EXPORT_SYMBOL(pdc_stable_read);/** * pdc_stable_write - Write data to Stable Storage. * @staddr: Stable Storage address to access. * @memaddr: The memory address where Stable Storage data shall be read from. * @count: number of bytes to transfert. count is multiple of 4. * * This PDC call reads count bytes from the supplied memaddr address, * and copies count bytes to the Stable Storage address staddr. * The call will fail if staddr+count > PDC_STABLE size. */int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count){ int retval; spin_lock_irq(&pdc_lock); memcpy(pdc_result, memaddr, count); convert_to_wide(pdc_result); retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_WRITE, staddr, __pa(pdc_result), count); spin_unlock_irq(&pdc_lock); return retval;}EXPORT_SYMBOL(pdc_stable_write);/** * pdc_stable_get_size - Get Stable Storage size in bytes. * @size: pointer where the size will be stored. * * This PDC call returns the number of bytes in the processor's Stable * Storage, which is the number of contiguous bytes implemented in Stable * Storage starting from staddr=0. size in an unsigned 64-bit integer * which is a multiple of four. */int pdc_stable_get_size(unsigned long *size){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_RETURN_SIZE, __pa(pdc_result)); *size = pdc_result[0]; spin_unlock_irq(&pdc_lock); return retval;}EXPORT_SYMBOL(pdc_stable_get_size);/** * pdc_stable_verify_contents - Checks that Stable Storage contents are valid. * * This PDC call is meant to be used to check the integrity of the current * contents of Stable Storage. */int pdc_stable_verify_contents(void){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_VERIFY_CONTENTS); spin_unlock_irq(&pdc_lock); return retval;}EXPORT_SYMBOL(pdc_stable_verify_contents);/** * pdc_stable_initialize - Sets Stable Storage contents to zero and initialize * the validity indicator. * * This PDC call will erase all contents of Stable Storage. Use with care! */int pdc_stable_initialize(void){ int retval; spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_INITIALIZE); spin_unlock_irq(&pdc_lock); return retval;}EXPORT_SYMBOL(pdc_stable_initialize);/** * pdc_get_initiator - Get the SCSI Interface Card params (SCSI ID, SDTR, SE or LVD) * @hwpath: fully bc.mod style path to the device. * @initiator: the array to return the result into * * 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, struct pdc_initiator *initiator){ 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 out; if (pdc_result[0] < 16) { initiator->host_id = pdc_result[0]; } else { initiator->host_id = -1; } /* * Sprockets and Piranha return 20 or 40 (MT/s). Prelude returns * 1, 2, 5 or 10 for 5, 10, 20 or 40 MT/s, respectively */ switch (pdc_result[1]) { case 1: initiator->factor = 50; break; case 2: initiator->factor = 25; break; case 5: initiator->factor = 12; break; case 25: initiator->factor = 10; break; case 20: initiator->factor = 12; break; case 40: initiator->factor = 10; break; default: initiator->factor = -1; break; } if (IS_SPROCKETS()) { initiator->width = pdc_result[4]; initiator->mode = pdc_result[5]; } else { initiator->width = -1; initiator->mode = -1; } out: 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; BUG_ON((unsigned long)tbl & 0x7); 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(void){ 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -