Commit 25a9b765 authored by Helge Deller's avatar Helge Deller
Browse files

parisc: Add function to return DIMM slot of physical address



Add a firmware wrapper function, which asks PDC firmware for the DIMM slot of a
physical address. This is needed to show users which DIMM module needs
replacement in case a broken DIMM was encountered.

Signed-off-by: default avatarHelge Deller <deller@gmx.de>
parent f520e552
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -228,6 +228,17 @@ struct pdc_pat_mem_read_pd_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_READ */
	unsigned long pdt_entries;
};

struct pdc_pat_mem_phys_mem_location { /* PDC_PAT_MEM/PDC_PAT_MEM_ADDRESS */
	u64 cabinet:8;
	u64 ign1:8;
	u64 ign2:8;
	u64 cell_slot:8;
	u64 ign3:8;
	u64 dimm_slot:8; /* DIMM slot, e.g. 0x1A, 0x2B, show user hex value! */
	u64 ign4:8;
	u64 source:4; /* for mem: always 0x07 */
	u64 source_detail:4; /* for mem: always 0x04 (SIMM or DIMM) */
};

struct pdc_pat_pd_addr_map_entry {
	unsigned char entry_type;       /* 1 = Memory Descriptor Entry Type */
@@ -319,6 +330,9 @@ extern int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
extern int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
		unsigned long *pdt_entries_ptr, unsigned long count,
		unsigned long offset);
extern int pdc_pat_mem_get_dimm_phys_location(
                struct pdc_pat_mem_phys_mem_location *pret,
                unsigned long phys_addr);

#endif /* __ASSEMBLY__ */

+25 −0
Original line number Diff line number Diff line
@@ -1498,6 +1498,31 @@ int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,

	return retval;
}

/**
 * pdc_pat_mem_get_dimm_phys_location - Get physical DIMM slot via PAT firmware
 * @pret: ptr to hold returned information
 * @phys_addr: physical address to examine
 *
 */
int pdc_pat_mem_get_dimm_phys_location(
		struct pdc_pat_mem_phys_mem_location *pret,
		unsigned long phys_addr)
{
	int retval;
	unsigned long flags;

	spin_lock_irqsave(&pdc_lock, flags);
	retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_ADDRESS,
		__pa(&pdc_result), phys_addr);

	if (retval == PDC_OK)
		memcpy(pret, &pdc_result, sizeof(*pret));

	spin_unlock_irqrestore(&pdc_lock, flags);

	return retval;
}
#endif /* CONFIG_64BIT */