diff mbox

interrupts: Convert P8 IRQ assignment to functions

Message ID 1442213382-2528-1-git-send-email-alistair@popple.id.au
State Superseded
Headers show

Commit Message

Alistair Popple Sept. 14, 2015, 6:49 a.m. UTC
Interrupts on P8 are currently hard-coded using macros in
include/interrupts.h. The new P8NVL processor has an extra PHB meaning
it supports 4 PHBs in total which leads to the following assert fail
when booting P8NVL based systems:

[6614913194,3] register IRQ source overlap !
[6620562844,3]   new: 2000..27f7 old: 2000..27f7
[6870377440,0] Assert fail: core/interrupts.c:67:0

This patch converts the existing macros to function calls so that
different platforms can support extra PHBs at the expense of a reduced
maximum number of chips.

Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
 core/cpu.c           |  4 +++-
 core/interrupts.c    | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 hw/phb3.c            | 24 +++++++++++-----------
 include/interrupts.h | 44 ++++++++++++++++++++++-----------------
 include/phb3.h       |  6 +++---
 include/skiboot.h    |  4 +++-
 6 files changed, 102 insertions(+), 38 deletions(-)

Comments

Benjamin Herrenschmidt Sept. 14, 2015, 7:02 a.m. UTC | #1
On Mon, 2015-09-14 at 16:49 +1000, Alistair Popple wrote:
> Interrupts on P8 are currently hard-coded using macros in
> include/interrupts.h. The new P8NVL processor has an extra PHB
> meaning
> it supports 4 PHBs in total which leads to the following assert fail
> when booting P8NVL based systems:
> 
> [6614913194,3] register IRQ source overlap !
> [6620562844,3]   new: 2000..27f7 old: 2000..27f7
> [6870377440,0] Assert fail: core/interrupts.c:67:0
> 
> This patch converts the existing macros to function calls so that
> different platforms can support extra PHBs at the expense of a
> reduced
> maximum number of chips.
> 
> Signed-off-by: Alistair Popple <alistair@popple.id.au>
> ---
>  core/cpu.c           |  4 +++-
>  core/interrupts.c    | 58
> ++++++++++++++++++++++++++++++++++++++++++++++++++--
>  hw/phb3.c            | 24 +++++++++++-----------
>  include/interrupts.h | 44 ++++++++++++++++++++++-----------------
>  include/phb3.h       |  6 +++---
>  include/skiboot.h    |  4 +++-
>  6 files changed, 102 insertions(+), 38 deletions(-)
> 
> diff --git a/core/cpu.c b/core/cpu.c
> index 8b0f861..c9dcd8f 100644
> --- a/core/cpu.c
> +++ b/core/cpu.c
> @@ -403,10 +403,12 @@ void init_boot_cpu(void)
>  	case PVR_TYPE_P8:
>  		proc_gen = proc_gen_p8;
>  		hile_supported = PVR_VERS_MAJ(mfspr(SPR_PVR)) >= 2;
> +		p8_chip_id_bits = 6;
>  		break;
>  	case PVR_TYPE_P8NVL:
>  		proc_gen = proc_gen_p8;
>  		hile_supported = true;
> +		p8_chip_id_bits = 5;
>  		break;
>  	default:

I would keep that local to interrupts.c and static, or even just use
a get_chip_id_bits() helper that uses struct proc_chip -> type

>  		proc_gen = proc_gen_unknown;
> @@ -544,7 +546,7 @@ void cpu_bringup(void)
>  
>  	op_display(OP_LOG, OP_MOD_CPU, 0x0000);
>  
> -	/* Tell everybody to chime in ! */	
> +	/* Tell everybody to chime in ! */

Unrelated change ?

>  	prlog(PR_INFO, "CPU: Calling in all processors...\n");
>  	cpu_secondary_start = 1;
>  	sync();
> diff --git a/core/interrupts.c b/core/interrupts.c
> index 32f43ef..d2e5096 100644
> --- a/core/interrupts.c
> +++ b/core/interrupts.c
> @@ -30,6 +30,9 @@
>  #define ICP_CPPR		0x4	/* 8-bit access */
>  #define ICP_MFRR		0xc	/* 8-bit access */
>  
> +/* Number of bits to use for the chips ids. */
> +uint32_t p8_chip_id_bits;
> +
>  struct irq_source {
>  	uint32_t			start;
>  	uint32_t			end;
> @@ -121,7 +124,7 @@ uint32_t get_psi_interrupt(uint32_t chip_id)
>  		irq |= P7_PSI_IRQ_BUID << 4;
>  		break;
>  	case proc_gen_p8:
> -		irq = P8_CHIP_IRQ_BLOCK_BASE(chip_id,
> P8_IRQ_BLOCK_MISC);
> +		irq = p8_chip_irq_block_base(chip_id,
> P8_IRQ_BLOCK_MISC);
>  		irq += P8_IRQ_MISC_PSI_BASE;
>  		break;
>  	default:
> @@ -253,6 +256,58 @@ void icp_kick_cpu(struct cpu_thread *cpu)
>  	out_8(icp + ICP_MFRR, 0);
>  }
>  
> +/* The chip id mask is the upper p8_chip_id_bits of the irq number
> */
> +static uint32_t chip_id_mask(void)
> +{
> +	uint32_t chip_id_mask = ((1 << p8_chip_id_bits) - 1);
> +	chip_id_mask <<= P8_IRQ_BITS - p8_chip_id_bits;
> +	return chip_id_mask;
> +}
> +
> +/* The block mask is what remains of the 19 bit irq number after
> + * removing the upper 5 or 6 bits for the chip# and the lower 11
> bits
> + * for the number of bits per block. */
> +static uint32_t block_mask(void)
> +{
> +	uint32_t irq_block_mask = P8_IRQ_BITS - p8_chip_id_bits -
> P8_IVE_BITS;
> +	irq_block_mask = ((1 << irq_block_mask) - 1) << P8_IVE_BITS;
> +	return irq_block_mask;
> +}
> +
> +uint32_t p8_chip_irq_block_base(uint32_t chip, uint32_t block)
> +{
> +	uint32_t irq;
> +
> +	assert(chip < (1 << p8_chip_id_bits));
> +	irq = SETFIELD(chip_id_mask(), 0, chip);
> +	irq = SETFIELD(block_mask(), irq, block);
> +
> +	return irq;
> +}
> +
> +uint32_t p8_chip_irq_phb_base(uint32_t chip, uint32_t phb)
> +{
> +	assert(chip < (1 << p8_chip_id_bits));
> +
> +	return p8_chip_irq_block_base(chip, phb +
> P8_IRQ_BLOCK_PHB_BASE);
> +}
> +
> +uint32_t p8_irq_to_chip(uint32_t irq)
> +{
> +	return GETFIELD(chip_id_mask(), irq);
> +}
> +
> +uint32_t p8_irq_to_block(uint32_t irq)
> +{
> +
> +	return GETFIELD(block_mask(), irq);
> +}
> +
> +uint32_t p8_irq_to_phb(uint32_t irq)
> +{
> +	return p8_irq_to_block(irq) - P8_IRQ_BLOCK_PHB_BASE;
> +}
> +
>  static struct irq_source *irq_find_source(uint32_t isn)
>  {
>  	struct irq_source *is;
> @@ -340,4 +395,3 @@ void init_interrupts(void)
>  		}
>  	}
>  }
> -
> diff --git a/hw/phb3.c b/hw/phb3.c
> index 5fd0130..77a84ed 100644
> --- a/hw/phb3.c
> +++ b/hw/phb3.c
> @@ -1550,8 +1550,8 @@ static int64_t phb3_msi_get_xive(void *data,
>  	uint32_t chip, index, irq;
>  	uint64_t ive;
>  
> -	chip = P8_IRQ_TO_CHIP(isn);
> -	index = P8_IRQ_TO_PHB(isn);
> +	chip = p8_irq_to_chip(isn);
> +	index = p8_irq_to_phb(isn);
>  	irq = PHB3_IRQ_NUM(isn);
>  
>  	if (chip != p->chip_id ||
> @@ -1580,8 +1580,8 @@ static int64_t phb3_msi_set_xive(void *data,
>  	uint64_t *cache, ive_num, data64, m_server, m_prio;
>  	uint32_t *ive;
>  
> -	chip = P8_IRQ_TO_CHIP(isn);
> -	index = P8_IRQ_TO_PHB(isn);
> +	chip = p8_irq_to_chip(isn);
> +	index = p8_irq_to_phb(isn);
>  	ive_num = PHB3_IRQ_NUM(isn);
>  
>  	if (p->state == PHB3_STATE_BROKEN || !p->tbl_rtt)
> @@ -1642,8 +1642,8 @@ static int64_t phb3_lsi_get_xive(void *data,
>  	uint32_t chip, index, irq;
>  	uint64_t lxive;
>  
> -	chip = P8_IRQ_TO_CHIP(isn);
> -	index = P8_IRQ_TO_PHB(isn);
> +	chip = p8_irq_to_chip(isn);
> +	index = p8_irq_to_phb(isn);
>  	irq = PHB3_IRQ_NUM(isn);
>  
>  	if (chip != p->chip_id	||
> @@ -1668,8 +1668,8 @@ static int64_t phb3_lsi_set_xive(void *data,
>  	uint32_t chip, index, irq, entry;
>  	uint64_t lxive;
>  
> -	chip = P8_IRQ_TO_CHIP(isn);
> -	index = P8_IRQ_TO_PHB(isn);
> +	chip = p8_irq_to_chip(isn);
> +	index = p8_irq_to_phb(isn);
>  	irq = PHB3_IRQ_NUM(isn);
>  
>  	if (p->state == PHB3_STATE_BROKEN)
> @@ -1935,7 +1935,7 @@ static void phb3_setup_for_link_down(struct
> phb3 *p)
>  static void phb3_setup_for_link_up(struct phb3 *p)
>  {
>  	uint32_t reg32;
> -	
> +
>  	/* Clear AER receiver error status */
>  	phb3_pcicfg_write32(&p->phb, 0, p->aercap +
> PCIECAP_AER_CE_STATUS,
>  			    PCIECAP_AER_CE_RECVR_ERR);
> @@ -3041,7 +3041,7 @@ static int64_t phb3_err_inject_dma64(struct
> phb3 *p, uint32_t pe_no,
>  				     uint64_t addr, uint64_t mask,
>  				     bool is_write)
>  {
> -	return phb3_err_inject_dma(p, pe_no, addr, mask, is_write,
> true);	
> +	return phb3_err_inject_dma(p, pe_no, addr, mask, is_write,
> true);
>  }
>  
>  static int64_t phb3_err_inject(struct phb *phb, uint32_t pe_no,
> @@ -3443,7 +3443,7 @@ static void phb3_setup_aib(struct phb3 *p)
>  		phb3_write_reg_asb(p, PHB_AIB_RX_CMD_CRED,	0x
> 0020000100020001);
>  	else
>  		phb3_write_reg_asb(p, PHB_AIB_RX_CMD_CRED,	0x
> 0020000100010001);
> -	
> +
>  	/* Init_4 - AIB rx data credit register */
>  	if (p->rev >= PHB3_REV_VENICE_DD20)
>  		phb3_write_reg_asb(p, PHB_AIB_RX_DATA_CRED,	0
> x0020002000010001);
> @@ -4444,7 +4444,7 @@ static void phb3_probe_pbcq(struct dt_node
> *pbcq)
>  	/* Set the interrupt routing stuff, 8 relevant bits in mask
>  	 * (11 bits per PHB)
>  	 */
> -	val = P8_CHIP_IRQ_PHB_BASE(gcid, pno);
> +	val = p8_chip_irq_phb_base(gcid, pno);
>  	val = (val << 45);
>  	xscom_write(gcid, pe_xscom + 0x1a, val);
>  	xscom_write(gcid, pe_xscom + 0x1b, 0xff00000000000000ul);
> diff --git a/include/interrupts.h b/include/interrupts.h
> index 9239b86..276a936 100644
> --- a/include/interrupts.h
> +++ b/include/interrupts.h
> @@ -78,7 +78,7 @@
>   *
>   * TBD
>   *
> - * 
> + *
>   * Additional note about routing of interrupts in P7 and P7+
>   * =========================================================
>   *
> @@ -152,19 +152,26 @@
>   * are naturally power-of-two aligned
>   *
>   * Our P8 Interrupt map consits thus of dividing the chip space
> - * into 4 "blocks" of 2048 interrupts. Block 0 is for random chip
> + * into "blocks" of 2048 interrupts. Block 0 is for random chip
>   * interrupt sources (NX, PSI, OCC, ...) and keeps sources 0..15
> - * clear to avoid conflits with IPIs etc.... Block 1..3 are assigned
> - * to PHB 0..2 respectively.
> + * clear to avoid conflits with IPIs etc.... Block 1..n are assigned
> + * to PHB 0..n respectively. The number of blocks is determined by
> the
> + * number of bits assigned to chips.
>   *
>   * That gives us an interrupt number made of:
> - *  18                13 12  11  10                         0
> + *  18               n+1 n   11  10                         0
>   *  |                  | |    | |                           |
>   * +--------------------+------+-----------------------------+
>   * |        Chip#       | PHB# |             IVE#            |
>   * +--------------------+------+-----------------------------+
>   *
> - * We can thus support a max of 2^6 = 64 chips
> + * Where n = 18 - p8_chip_id_bits
> + *
> + * For P8 we have 6 bits for Chip# as defined by p8_chip_id_bits. We
> + * therefore support a max of 2^6 = 64 chips.
> + *
> + * For P8NVL we have an extra PHB and so we assign 5 bits for Chip#
> + * and therefore support a max of 32 chips.
>   *
>   * Each PHB supports 2K interrupt sources, which is shared by
>   * LSI and MSI. With default configuration, MSI would use range
> @@ -174,21 +181,20 @@
>   *
>   */
>  
> -#define P8_CHIP_IRQ_BASE(chip)			((chip) << 13)
> -#define P8_CHIP_IRQ_BLOCK_BASE(chip, block)	(P8_CHIP_IRQ_BASE
> (chip) \
> -						 | ((block) << 11))
> -#define P8_IRQ_BLOCK_MISC	0
> -#define P8_IRQ_BLOCK_PHB0	1
> -#define P8_IRQ_BLOCK_PHB1	2
> -#define P8_IRQ_BLOCK_PHB2	3
> +uint32_t p8_chip_irq_block_base(uint32_t chip, uint32_t block);
> +uint32_t p8_chip_irq_phb_base(uint32_t chip, uint32_t phb);
> +uint32_t p8_irq_to_chip(uint32_t irq);
> +uint32_t p8_irq_to_block(uint32_t irq);
> +uint32_t p8_irq_to_phb(uint32_t irq);
> +
> +/* Total number of bits in the P8 interrupt space */
> +#define P8_IRQ_BITS		19
>  
> -#define P8_CHIP_IRQ_PHB_BASE(chip, phb)		(P8_CHIP_IRQ_
> BLOCK_BASE(chip,\
> -						  (phb) +
> P8_IRQ_BLOCK_PHB0))
> +/* Number of bits per block */
> +#define P8_IVE_BITS		11
>  
> -#define P8_IRQ_TO_CHIP(irq)			(((irq) >> 13) &
> 0x3f)
> -#define P8_IRQ_TO_BLOCK(irq)			(((irq) >> 11) &
> 0x03)
> -#define P8_IRQ_TO_PHB(irq)			(P8_IRQ_TO_BLOCK(i
> rq) - \
> -						 P8_IRQ_BLOCK_PHB0)
> +#define P8_IRQ_BLOCK_MISC	0
> +#define P8_IRQ_BLOCK_PHB_BASE	1
>  
>  /* Assignment of the "MISC" block:
>   * -------------------------------
> diff --git a/include/phb3.h b/include/phb3.h
> index 3accd9e..982f847 100644
> --- a/include/phb3.h
> +++ b/include/phb3.h
> @@ -52,9 +52,9 @@
>  #define PHB3_LSI_IRQ_COUNT		8
>  #define PHB3_LSI_IRQ_MAX		(PHB3_LSI_IRQ_MIN+PHB3_LSI_I
> RQ_COUNT-1)
>  
> -#define PHB3_MSI_IRQ_BASE(chip, phb)	(P8_CHIP_IRQ_PHB_BASE(ch
> ip, phb) | \
> +#define PHB3_MSI_IRQ_BASE(chip, phb)	(p8_chip_irq_phb_base(ch
> ip, phb) | \
>  					 PHB3_MSI_IRQ_MIN)
> -#define PHB3_LSI_IRQ_BASE(chip, phb)	(P8_CHIP_IRQ_PHB_BASE(ch
> ip, phb) | \
> +#define PHB3_LSI_IRQ_BASE(chip, phb)	(p8_chip_irq_phb_base(ch
> ip, phb) | \
>  					 PHB3_LSI_IRQ_MIN)
>  #define PHB3_IRQ_NUM(irq)		(irq & 0x7FF)
>  
> @@ -94,7 +94,7 @@
>   * All those tables have to be naturally aligned
>   */
>  
> -/* RTT Table : 128KB - Maps RID to PE# 
> +/* RTT Table : 128KB - Maps RID to PE#
>   *
>   * Entries are 2 bytes indexed by PCIe RID
>   */
> diff --git a/include/skiboot.h b/include/skiboot.h
> index 4b58597..cdc5a10 100644
> --- a/include/skiboot.h
> +++ b/include/skiboot.h
> @@ -125,6 +125,9 @@ enum proc_gen {
>  };
>  extern enum proc_gen proc_gen;
>  
> +/* Number of chip id bits available */
> +extern uint32_t p8_chip_id_bits;
> +
>  /* Convert a 4-bit number to a hex char */
>  extern char __attrconst tohex(uint8_t nibble);
>  
> @@ -263,4 +266,3 @@ extern bool slw_timer_ok(void);
>  extern void fake_rtc_init(void);
>  
>  #endif /* __SKIBOOT_H */
> -
Alistair Popple Sept. 14, 2015, 7:15 a.m. UTC | #2
On Mon, 14 Sep 2015 17:02:34 Benjamin Herrenschmidt wrote:
> On Mon, 2015-09-14 at 16:49 +1000, Alistair Popple wrote:

snip

> > ---
> >  core/cpu.c           |  4 +++-
> >  core/interrupts.c    | 58
> > ++++++++++++++++++++++++++++++++++++++++++++++++++--
> >  hw/phb3.c            | 24 +++++++++++-----------
> >  include/interrupts.h | 44 ++++++++++++++++++++++-----------------
> >  include/phb3.h       |  6 +++---
> >  include/skiboot.h    |  4 +++-
> >  6 files changed, 102 insertions(+), 38 deletions(-)
> > 
> > diff --git a/core/cpu.c b/core/cpu.c
> > index 8b0f861..c9dcd8f 100644
> > --- a/core/cpu.c
> > +++ b/core/cpu.c
> > @@ -403,10 +403,12 @@ void init_boot_cpu(void)
> >  	case PVR_TYPE_P8:
> >  		proc_gen = proc_gen_p8;
> >  		hile_supported = PVR_VERS_MAJ(mfspr(SPR_PVR)) >= 2;
> > +		p8_chip_id_bits = 6;
> >  		break;
> >  	case PVR_TYPE_P8NVL:
> >  		proc_gen = proc_gen_p8;
> >  		hile_supported = true;
> > +		p8_chip_id_bits = 5;
> >  		break;
> >  	default:
> 
> I would keep that local to interrupts.c and static, or even just use
> a get_chip_id_bits() helper that uses struct proc_chip -> type

Are you suggesting we add a proc_gen_p8vnl to the proc_gen enum used for 
struct proc_chip -> type or just reading the PVR again in get_chip_id_bits()? 
It looked like adding another processor to the enum would be a pain hence the 
ugliness above, but reading the PVR is easy enough.

> >  		proc_gen = proc_gen_unknown;
> > @@ -544,7 +546,7 @@ void cpu_bringup(void)
> >  
> >  	op_display(OP_LOG, OP_MOD_CPU, 0x0000);
> >  
> > -	/* Tell everybody to chime in ! */	
> > +	/* Tell everybody to chime in ! */
> 
> Unrelated change ?

Sorry, missed that one. It's due to having (add-hook 'before-save-hook 
'delete-trailing-whitespace) in my .emacs ;)

> >  	prlog(PR_INFO, "CPU: Calling in all processors...\n");
> >  	cpu_secondary_start = 1;
> >  	sync();
> > diff --git a/core/interrupts.c b/core/interrupts.c
> > index 32f43ef..d2e5096 100644
> > --- a/core/interrupts.c
> > +++ b/core/interrupts.c
> > @@ -30,6 +30,9 @@
> >  #define ICP_CPPR		0x4	/* 8-bit access */
> >  #define ICP_MFRR		0xc	/* 8-bit access */
> >  
> > +/* Number of bits to use for the chips ids. */
> > +uint32_t p8_chip_id_bits;
> > +
> >  struct irq_source {
> >  	uint32_t			start;
> >  	uint32_t			end;
> > @@ -121,7 +124,7 @@ uint32_t get_psi_interrupt(uint32_t chip_id)
> >  		irq |= P7_PSI_IRQ_BUID << 4;
> >  		break;
> >  	case proc_gen_p8:
> > -		irq = P8_CHIP_IRQ_BLOCK_BASE(chip_id,
> > P8_IRQ_BLOCK_MISC);
> > +		irq = p8_chip_irq_block_base(chip_id,
> > P8_IRQ_BLOCK_MISC);
> >  		irq += P8_IRQ_MISC_PSI_BASE;
> >  		break;
> >  	default:
> > @@ -253,6 +256,58 @@ void icp_kick_cpu(struct cpu_thread *cpu)
> >  	out_8(icp + ICP_MFRR, 0);
> >  }
> >  
> > +/* The chip id mask is the upper p8_chip_id_bits of the irq number
> > */
> > +static uint32_t chip_id_mask(void)
> > +{
> > +	uint32_t chip_id_mask = ((1 << p8_chip_id_bits) - 1);
> > +	chip_id_mask <<= P8_IRQ_BITS - p8_chip_id_bits;
> > +	return chip_id_mask;
> > +}
> > +
> > +/* The block mask is what remains of the 19 bit irq number after
> > + * removing the upper 5 or 6 bits for the chip# and the lower 11
> > bits
> > + * for the number of bits per block. */
> > +static uint32_t block_mask(void)
> > +{
> > +	uint32_t irq_block_mask = P8_IRQ_BITS - p8_chip_id_bits -
> > P8_IVE_BITS;
> > +	irq_block_mask = ((1 << irq_block_mask) - 1) << P8_IVE_BITS;
> > +	return irq_block_mask;
> > +}
> > +
> > +uint32_t p8_chip_irq_block_base(uint32_t chip, uint32_t block)
> > +{
> > +	uint32_t irq;
> > +
> > +	assert(chip < (1 << p8_chip_id_bits));
> > +	irq = SETFIELD(chip_id_mask(), 0, chip);
> > +	irq = SETFIELD(block_mask(), irq, block);
> > +
> > +	return irq;
> > +}
> > +
> > +uint32_t p8_chip_irq_phb_base(uint32_t chip, uint32_t phb)
> > +{
> > +	assert(chip < (1 << p8_chip_id_bits));
> > +
> > +	return p8_chip_irq_block_base(chip, phb +
> > P8_IRQ_BLOCK_PHB_BASE);
> > +}
> > +
> > +uint32_t p8_irq_to_chip(uint32_t irq)
> > +{
> > +	return GETFIELD(chip_id_mask(), irq);
> > +}
> > +
> > +uint32_t p8_irq_to_block(uint32_t irq)
> > +{
> > +
> > +	return GETFIELD(block_mask(), irq);
> > +}
> > +
> > +uint32_t p8_irq_to_phb(uint32_t irq)
> > +{
> > +	return p8_irq_to_block(irq) - P8_IRQ_BLOCK_PHB_BASE;
> > +}
> > +
> >  static struct irq_source *irq_find_source(uint32_t isn)
> >  {
> >  	struct irq_source *is;
> > @@ -340,4 +395,3 @@ void init_interrupts(void)
> >  		}
> >  	}
> >  }
> > -
> > diff --git a/hw/phb3.c b/hw/phb3.c
> > index 5fd0130..77a84ed 100644
> > --- a/hw/phb3.c
> > +++ b/hw/phb3.c
> > @@ -1550,8 +1550,8 @@ static int64_t phb3_msi_get_xive(void *data,
> >  	uint32_t chip, index, irq;
> >  	uint64_t ive;
> >  
> > -	chip = P8_IRQ_TO_CHIP(isn);
> > -	index = P8_IRQ_TO_PHB(isn);
> > +	chip = p8_irq_to_chip(isn);
> > +	index = p8_irq_to_phb(isn);
> >  	irq = PHB3_IRQ_NUM(isn);
> >  
> >  	if (chip != p->chip_id ||
> > @@ -1580,8 +1580,8 @@ static int64_t phb3_msi_set_xive(void *data,
> >  	uint64_t *cache, ive_num, data64, m_server, m_prio;
> >  	uint32_t *ive;
> >  
> > -	chip = P8_IRQ_TO_CHIP(isn);
> > -	index = P8_IRQ_TO_PHB(isn);
> > +	chip = p8_irq_to_chip(isn);
> > +	index = p8_irq_to_phb(isn);
> >  	ive_num = PHB3_IRQ_NUM(isn);
> >  
> >  	if (p->state == PHB3_STATE_BROKEN || !p->tbl_rtt)
> > @@ -1642,8 +1642,8 @@ static int64_t phb3_lsi_get_xive(void *data,
> >  	uint32_t chip, index, irq;
> >  	uint64_t lxive;
> >  
> > -	chip = P8_IRQ_TO_CHIP(isn);
> > -	index = P8_IRQ_TO_PHB(isn);
> > +	chip = p8_irq_to_chip(isn);
> > +	index = p8_irq_to_phb(isn);
> >  	irq = PHB3_IRQ_NUM(isn);
> >  
> >  	if (chip != p->chip_id	||
> > @@ -1668,8 +1668,8 @@ static int64_t phb3_lsi_set_xive(void *data,
> >  	uint32_t chip, index, irq, entry;
> >  	uint64_t lxive;
> >  
> > -	chip = P8_IRQ_TO_CHIP(isn);
> > -	index = P8_IRQ_TO_PHB(isn);
> > +	chip = p8_irq_to_chip(isn);
> > +	index = p8_irq_to_phb(isn);
> >  	irq = PHB3_IRQ_NUM(isn);
> >  
> >  	if (p->state == PHB3_STATE_BROKEN)
> > @@ -1935,7 +1935,7 @@ static void phb3_setup_for_link_down(struct
> > phb3 *p)
> >  static void phb3_setup_for_link_up(struct phb3 *p)
> >  {
> >  	uint32_t reg32;
> > -	
> > +
> >  	/* Clear AER receiver error status */
> >  	phb3_pcicfg_write32(&p->phb, 0, p->aercap +
> > PCIECAP_AER_CE_STATUS,
> >  			    PCIECAP_AER_CE_RECVR_ERR);
> > @@ -3041,7 +3041,7 @@ static int64_t phb3_err_inject_dma64(struct
> > phb3 *p, uint32_t pe_no,
> >  				     uint64_t addr, uint64_t mask,
> >  				     bool is_write)
> >  {
> > -	return phb3_err_inject_dma(p, pe_no, addr, mask, is_write,
> > true);	
> > +	return phb3_err_inject_dma(p, pe_no, addr, mask, is_write,
> > true);
> >  }
> >  
> >  static int64_t phb3_err_inject(struct phb *phb, uint32_t pe_no,
> > @@ -3443,7 +3443,7 @@ static void phb3_setup_aib(struct phb3 *p)
> >  		phb3_write_reg_asb(p, PHB_AIB_RX_CMD_CRED,	0x
> > 0020000100020001);
> >  	else
> >  		phb3_write_reg_asb(p, PHB_AIB_RX_CMD_CRED,	0x
> > 0020000100010001);
> > -	
> > +
> >  	/* Init_4 - AIB rx data credit register */
> >  	if (p->rev >= PHB3_REV_VENICE_DD20)
> >  		phb3_write_reg_asb(p, PHB_AIB_RX_DATA_CRED,	0
> > x0020002000010001);
> > @@ -4444,7 +4444,7 @@ static void phb3_probe_pbcq(struct dt_node
> > *pbcq)
> >  	/* Set the interrupt routing stuff, 8 relevant bits in mask
> >  	 * (11 bits per PHB)
> >  	 */
> > -	val = P8_CHIP_IRQ_PHB_BASE(gcid, pno);
> > +	val = p8_chip_irq_phb_base(gcid, pno);
> >  	val = (val << 45);
> >  	xscom_write(gcid, pe_xscom + 0x1a, val);
> >  	xscom_write(gcid, pe_xscom + 0x1b, 0xff00000000000000ul);
> > diff --git a/include/interrupts.h b/include/interrupts.h
> > index 9239b86..276a936 100644
> > --- a/include/interrupts.h
> > +++ b/include/interrupts.h
> > @@ -78,7 +78,7 @@
> >   *
> >   * TBD
> >   *
> > - * 
> > + *
> >   * Additional note about routing of interrupts in P7 and P7+
> >   * =========================================================
> >   *
> > @@ -152,19 +152,26 @@
> >   * are naturally power-of-two aligned
> >   *
> >   * Our P8 Interrupt map consits thus of dividing the chip space
> > - * into 4 "blocks" of 2048 interrupts. Block 0 is for random chip
> > + * into "blocks" of 2048 interrupts. Block 0 is for random chip
> >   * interrupt sources (NX, PSI, OCC, ...) and keeps sources 0..15
> > - * clear to avoid conflits with IPIs etc.... Block 1..3 are assigned
> > - * to PHB 0..2 respectively.
> > + * clear to avoid conflits with IPIs etc.... Block 1..n are assigned
> > + * to PHB 0..n respectively. The number of blocks is determined by
> > the
> > + * number of bits assigned to chips.
> >   *
> >   * That gives us an interrupt number made of:
> > - *  18                13 12  11  10                         0
> > + *  18               n+1 n   11  10                         0
> >   *  |                  | |    | |                           |
> >   * +--------------------+------+-----------------------------+
> >   * |        Chip#       | PHB# |             IVE#            |
> >   * +--------------------+------+-----------------------------+
> >   *
> > - * We can thus support a max of 2^6 = 64 chips
> > + * Where n = 18 - p8_chip_id_bits
> > + *
> > + * For P8 we have 6 bits for Chip# as defined by p8_chip_id_bits. We
> > + * therefore support a max of 2^6 = 64 chips.
> > + *
> > + * For P8NVL we have an extra PHB and so we assign 5 bits for Chip#
> > + * and therefore support a max of 32 chips.
> >   *
> >   * Each PHB supports 2K interrupt sources, which is shared by
> >   * LSI and MSI. With default configuration, MSI would use range
> > @@ -174,21 +181,20 @@
> >   *
> >   */
> >  
> > -#define P8_CHIP_IRQ_BASE(chip)			((chip) << 13)
> > -#define P8_CHIP_IRQ_BLOCK_BASE(chip, block)	(P8_CHIP_IRQ_BASE
> > (chip) \
> > -						 | ((block) << 11))
> > -#define P8_IRQ_BLOCK_MISC	0
> > -#define P8_IRQ_BLOCK_PHB0	1
> > -#define P8_IRQ_BLOCK_PHB1	2
> > -#define P8_IRQ_BLOCK_PHB2	3
> > +uint32_t p8_chip_irq_block_base(uint32_t chip, uint32_t block);
> > +uint32_t p8_chip_irq_phb_base(uint32_t chip, uint32_t phb);
> > +uint32_t p8_irq_to_chip(uint32_t irq);
> > +uint32_t p8_irq_to_block(uint32_t irq);
> > +uint32_t p8_irq_to_phb(uint32_t irq);
> > +
> > +/* Total number of bits in the P8 interrupt space */
> > +#define P8_IRQ_BITS		19
> >  
> > -#define P8_CHIP_IRQ_PHB_BASE(chip, phb)		(P8_CHIP_IRQ_
> > BLOCK_BASE(chip,\
> > -						  (phb) +
> > P8_IRQ_BLOCK_PHB0))
> > +/* Number of bits per block */
> > +#define P8_IVE_BITS		11
> >  
> > -#define P8_IRQ_TO_CHIP(irq)			(((irq) >> 13) &
> > 0x3f)
> > -#define P8_IRQ_TO_BLOCK(irq)			(((irq) >> 11) &
> > 0x03)
> > -#define P8_IRQ_TO_PHB(irq)			(P8_IRQ_TO_BLOCK(i
> > rq) - \
> > -						 P8_IRQ_BLOCK_PHB0)
> > +#define P8_IRQ_BLOCK_MISC	0
> > +#define P8_IRQ_BLOCK_PHB_BASE	1
> >  
> >  /* Assignment of the "MISC" block:
> >   * -------------------------------
> > diff --git a/include/phb3.h b/include/phb3.h
> > index 3accd9e..982f847 100644
> > --- a/include/phb3.h
> > +++ b/include/phb3.h
> > @@ -52,9 +52,9 @@
> >  #define PHB3_LSI_IRQ_COUNT		8
> >  #define PHB3_LSI_IRQ_MAX		(PHB3_LSI_IRQ_MIN+PHB3_LSI_I
> > RQ_COUNT-1)
> >  
> > -#define PHB3_MSI_IRQ_BASE(chip, phb)	(P8_CHIP_IRQ_PHB_BASE(ch
> > ip, phb) | \
> > +#define PHB3_MSI_IRQ_BASE(chip, phb)	(p8_chip_irq_phb_base(ch
> > ip, phb) | \
> >  					 PHB3_MSI_IRQ_MIN)
> > -#define PHB3_LSI_IRQ_BASE(chip, phb)	(P8_CHIP_IRQ_PHB_BASE(ch
> > ip, phb) | \
> > +#define PHB3_LSI_IRQ_BASE(chip, phb)	(p8_chip_irq_phb_base(ch
> > ip, phb) | \
> >  					 PHB3_LSI_IRQ_MIN)
> >  #define PHB3_IRQ_NUM(irq)		(irq & 0x7FF)
> >  
> > @@ -94,7 +94,7 @@
> >   * All those tables have to be naturally aligned
> >   */
> >  
> > -/* RTT Table : 128KB - Maps RID to PE# 
> > +/* RTT Table : 128KB - Maps RID to PE#
> >   *
> >   * Entries are 2 bytes indexed by PCIe RID
> >   */
> > diff --git a/include/skiboot.h b/include/skiboot.h
> > index 4b58597..cdc5a10 100644
> > --- a/include/skiboot.h
> > +++ b/include/skiboot.h
> > @@ -125,6 +125,9 @@ enum proc_gen {
> >  };
> >  extern enum proc_gen proc_gen;
> >  
> > +/* Number of chip id bits available */
> > +extern uint32_t p8_chip_id_bits;
> > +
> >  /* Convert a 4-bit number to a hex char */
> >  extern char __attrconst tohex(uint8_t nibble);
> >  
> > @@ -263,4 +266,3 @@ extern bool slw_timer_ok(void);
> >  extern void fake_rtc_init(void);
> >  
> >  #endif /* __SKIBOOT_H */
> > -
Benjamin Herrenschmidt Sept. 14, 2015, 7:44 a.m. UTC | #3
On Mon, 2015-09-14 at 17:15 +1000, Alistair Popple wrote:

> Are you suggesting we add a proc_gen_p8vnl to the proc_gen enum used
> for 
> struct proc_chip -> type or just reading the PVR again in
> get_chip_id_bits()? 
> It looked like adding another processor to the enum would be a pain
> hence the 
> ugliness above, but reading the PVR is easy enough.


No, we already have this:

/* Chip type */
enum proc_chip_type {
	PROC_CHIP_UNKNOWN,
	PROC_CHIP_P7,
	PROC_CHIP_P7P,
	PROC_CHIP_P8_MURANO,
	PROC_CHIP_P8_VENICE,
	PROC_CHIP_P8_NAPLES,
};
diff mbox

Patch

diff --git a/core/cpu.c b/core/cpu.c
index 8b0f861..c9dcd8f 100644
--- a/core/cpu.c
+++ b/core/cpu.c
@@ -403,10 +403,12 @@  void init_boot_cpu(void)
 	case PVR_TYPE_P8:
 		proc_gen = proc_gen_p8;
 		hile_supported = PVR_VERS_MAJ(mfspr(SPR_PVR)) >= 2;
+		p8_chip_id_bits = 6;
 		break;
 	case PVR_TYPE_P8NVL:
 		proc_gen = proc_gen_p8;
 		hile_supported = true;
+		p8_chip_id_bits = 5;
 		break;
 	default:
 		proc_gen = proc_gen_unknown;
@@ -544,7 +546,7 @@  void cpu_bringup(void)
 
 	op_display(OP_LOG, OP_MOD_CPU, 0x0000);
 
-	/* Tell everybody to chime in ! */	
+	/* Tell everybody to chime in ! */
 	prlog(PR_INFO, "CPU: Calling in all processors...\n");
 	cpu_secondary_start = 1;
 	sync();
diff --git a/core/interrupts.c b/core/interrupts.c
index 32f43ef..d2e5096 100644
--- a/core/interrupts.c
+++ b/core/interrupts.c
@@ -30,6 +30,9 @@ 
 #define ICP_CPPR		0x4	/* 8-bit access */
 #define ICP_MFRR		0xc	/* 8-bit access */
 
+/* Number of bits to use for the chips ids. */
+uint32_t p8_chip_id_bits;
+
 struct irq_source {
 	uint32_t			start;
 	uint32_t			end;
@@ -121,7 +124,7 @@  uint32_t get_psi_interrupt(uint32_t chip_id)
 		irq |= P7_PSI_IRQ_BUID << 4;
 		break;
 	case proc_gen_p8:
-		irq = P8_CHIP_IRQ_BLOCK_BASE(chip_id, P8_IRQ_BLOCK_MISC);
+		irq = p8_chip_irq_block_base(chip_id, P8_IRQ_BLOCK_MISC);
 		irq += P8_IRQ_MISC_PSI_BASE;
 		break;
 	default:
@@ -253,6 +256,58 @@  void icp_kick_cpu(struct cpu_thread *cpu)
 	out_8(icp + ICP_MFRR, 0);
 }
 
+/* The chip id mask is the upper p8_chip_id_bits of the irq number */
+static uint32_t chip_id_mask(void)
+{
+	uint32_t chip_id_mask = ((1 << p8_chip_id_bits) - 1);
+	chip_id_mask <<= P8_IRQ_BITS - p8_chip_id_bits;
+	return chip_id_mask;
+}
+
+/* The block mask is what remains of the 19 bit irq number after
+ * removing the upper 5 or 6 bits for the chip# and the lower 11 bits
+ * for the number of bits per block. */
+static uint32_t block_mask(void)
+{
+	uint32_t irq_block_mask = P8_IRQ_BITS - p8_chip_id_bits - P8_IVE_BITS;
+	irq_block_mask = ((1 << irq_block_mask) - 1) << P8_IVE_BITS;
+	return irq_block_mask;
+}
+
+uint32_t p8_chip_irq_block_base(uint32_t chip, uint32_t block)
+{
+	uint32_t irq;
+
+	assert(chip < (1 << p8_chip_id_bits));
+	irq = SETFIELD(chip_id_mask(), 0, chip);
+	irq = SETFIELD(block_mask(), irq, block);
+
+	return irq;
+}
+
+uint32_t p8_chip_irq_phb_base(uint32_t chip, uint32_t phb)
+{
+	assert(chip < (1 << p8_chip_id_bits));
+
+	return p8_chip_irq_block_base(chip, phb + P8_IRQ_BLOCK_PHB_BASE);
+}
+
+uint32_t p8_irq_to_chip(uint32_t irq)
+{
+	return GETFIELD(chip_id_mask(), irq);
+}
+
+uint32_t p8_irq_to_block(uint32_t irq)
+{
+
+	return GETFIELD(block_mask(), irq);
+}
+
+uint32_t p8_irq_to_phb(uint32_t irq)
+{
+	return p8_irq_to_block(irq) - P8_IRQ_BLOCK_PHB_BASE;
+}
+
 static struct irq_source *irq_find_source(uint32_t isn)
 {
 	struct irq_source *is;
@@ -340,4 +395,3 @@  void init_interrupts(void)
 		}
 	}
 }
-
diff --git a/hw/phb3.c b/hw/phb3.c
index 5fd0130..77a84ed 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -1550,8 +1550,8 @@  static int64_t phb3_msi_get_xive(void *data,
 	uint32_t chip, index, irq;
 	uint64_t ive;
 
-	chip = P8_IRQ_TO_CHIP(isn);
-	index = P8_IRQ_TO_PHB(isn);
+	chip = p8_irq_to_chip(isn);
+	index = p8_irq_to_phb(isn);
 	irq = PHB3_IRQ_NUM(isn);
 
 	if (chip != p->chip_id ||
@@ -1580,8 +1580,8 @@  static int64_t phb3_msi_set_xive(void *data,
 	uint64_t *cache, ive_num, data64, m_server, m_prio;
 	uint32_t *ive;
 
-	chip = P8_IRQ_TO_CHIP(isn);
-	index = P8_IRQ_TO_PHB(isn);
+	chip = p8_irq_to_chip(isn);
+	index = p8_irq_to_phb(isn);
 	ive_num = PHB3_IRQ_NUM(isn);
 
 	if (p->state == PHB3_STATE_BROKEN || !p->tbl_rtt)
@@ -1642,8 +1642,8 @@  static int64_t phb3_lsi_get_xive(void *data,
 	uint32_t chip, index, irq;
 	uint64_t lxive;
 
-	chip = P8_IRQ_TO_CHIP(isn);
-	index = P8_IRQ_TO_PHB(isn);
+	chip = p8_irq_to_chip(isn);
+	index = p8_irq_to_phb(isn);
 	irq = PHB3_IRQ_NUM(isn);
 
 	if (chip != p->chip_id	||
@@ -1668,8 +1668,8 @@  static int64_t phb3_lsi_set_xive(void *data,
 	uint32_t chip, index, irq, entry;
 	uint64_t lxive;
 
-	chip = P8_IRQ_TO_CHIP(isn);
-	index = P8_IRQ_TO_PHB(isn);
+	chip = p8_irq_to_chip(isn);
+	index = p8_irq_to_phb(isn);
 	irq = PHB3_IRQ_NUM(isn);
 
 	if (p->state == PHB3_STATE_BROKEN)
@@ -1935,7 +1935,7 @@  static void phb3_setup_for_link_down(struct phb3 *p)
 static void phb3_setup_for_link_up(struct phb3 *p)
 {
 	uint32_t reg32;
-	
+
 	/* Clear AER receiver error status */
 	phb3_pcicfg_write32(&p->phb, 0, p->aercap + PCIECAP_AER_CE_STATUS,
 			    PCIECAP_AER_CE_RECVR_ERR);
@@ -3041,7 +3041,7 @@  static int64_t phb3_err_inject_dma64(struct phb3 *p, uint32_t pe_no,
 				     uint64_t addr, uint64_t mask,
 				     bool is_write)
 {
-	return phb3_err_inject_dma(p, pe_no, addr, mask, is_write, true);	
+	return phb3_err_inject_dma(p, pe_no, addr, mask, is_write, true);
 }
 
 static int64_t phb3_err_inject(struct phb *phb, uint32_t pe_no,
@@ -3443,7 +3443,7 @@  static void phb3_setup_aib(struct phb3 *p)
 		phb3_write_reg_asb(p, PHB_AIB_RX_CMD_CRED,	0x0020000100020001);
 	else
 		phb3_write_reg_asb(p, PHB_AIB_RX_CMD_CRED,	0x0020000100010001);
-	
+
 	/* Init_4 - AIB rx data credit register */
 	if (p->rev >= PHB3_REV_VENICE_DD20)
 		phb3_write_reg_asb(p, PHB_AIB_RX_DATA_CRED,	0x0020002000010001);
@@ -4444,7 +4444,7 @@  static void phb3_probe_pbcq(struct dt_node *pbcq)
 	/* Set the interrupt routing stuff, 8 relevant bits in mask
 	 * (11 bits per PHB)
 	 */
-	val = P8_CHIP_IRQ_PHB_BASE(gcid, pno);
+	val = p8_chip_irq_phb_base(gcid, pno);
 	val = (val << 45);
 	xscom_write(gcid, pe_xscom + 0x1a, val);
 	xscom_write(gcid, pe_xscom + 0x1b, 0xff00000000000000ul);
diff --git a/include/interrupts.h b/include/interrupts.h
index 9239b86..276a936 100644
--- a/include/interrupts.h
+++ b/include/interrupts.h
@@ -78,7 +78,7 @@ 
  *
  * TBD
  *
- * 
+ *
  * Additional note about routing of interrupts in P7 and P7+
  * =========================================================
  *
@@ -152,19 +152,26 @@ 
  * are naturally power-of-two aligned
  *
  * Our P8 Interrupt map consits thus of dividing the chip space
- * into 4 "blocks" of 2048 interrupts. Block 0 is for random chip
+ * into "blocks" of 2048 interrupts. Block 0 is for random chip
  * interrupt sources (NX, PSI, OCC, ...) and keeps sources 0..15
- * clear to avoid conflits with IPIs etc.... Block 1..3 are assigned
- * to PHB 0..2 respectively.
+ * clear to avoid conflits with IPIs etc.... Block 1..n are assigned
+ * to PHB 0..n respectively. The number of blocks is determined by the
+ * number of bits assigned to chips.
  *
  * That gives us an interrupt number made of:
- *  18                13 12  11  10                         0
+ *  18               n+1 n   11  10                         0
  *  |                  | |    | |                           |
  * +--------------------+------+-----------------------------+
  * |        Chip#       | PHB# |             IVE#            |
  * +--------------------+------+-----------------------------+
  *
- * We can thus support a max of 2^6 = 64 chips
+ * Where n = 18 - p8_chip_id_bits
+ *
+ * For P8 we have 6 bits for Chip# as defined by p8_chip_id_bits. We
+ * therefore support a max of 2^6 = 64 chips.
+ *
+ * For P8NVL we have an extra PHB and so we assign 5 bits for Chip#
+ * and therefore support a max of 32 chips.
  *
  * Each PHB supports 2K interrupt sources, which is shared by
  * LSI and MSI. With default configuration, MSI would use range
@@ -174,21 +181,20 @@ 
  *
  */
 
-#define P8_CHIP_IRQ_BASE(chip)			((chip) << 13)
-#define P8_CHIP_IRQ_BLOCK_BASE(chip, block)	(P8_CHIP_IRQ_BASE(chip) \
-						 | ((block) << 11))
-#define P8_IRQ_BLOCK_MISC	0
-#define P8_IRQ_BLOCK_PHB0	1
-#define P8_IRQ_BLOCK_PHB1	2
-#define P8_IRQ_BLOCK_PHB2	3
+uint32_t p8_chip_irq_block_base(uint32_t chip, uint32_t block);
+uint32_t p8_chip_irq_phb_base(uint32_t chip, uint32_t phb);
+uint32_t p8_irq_to_chip(uint32_t irq);
+uint32_t p8_irq_to_block(uint32_t irq);
+uint32_t p8_irq_to_phb(uint32_t irq);
+
+/* Total number of bits in the P8 interrupt space */
+#define P8_IRQ_BITS		19
 
-#define P8_CHIP_IRQ_PHB_BASE(chip, phb)		(P8_CHIP_IRQ_BLOCK_BASE(chip,\
-						  (phb) + P8_IRQ_BLOCK_PHB0))
+/* Number of bits per block */
+#define P8_IVE_BITS		11
 
-#define P8_IRQ_TO_CHIP(irq)			(((irq) >> 13) & 0x3f)
-#define P8_IRQ_TO_BLOCK(irq)			(((irq) >> 11) & 0x03)
-#define P8_IRQ_TO_PHB(irq)			(P8_IRQ_TO_BLOCK(irq) - \
-						 P8_IRQ_BLOCK_PHB0)
+#define P8_IRQ_BLOCK_MISC	0
+#define P8_IRQ_BLOCK_PHB_BASE	1
 
 /* Assignment of the "MISC" block:
  * -------------------------------
diff --git a/include/phb3.h b/include/phb3.h
index 3accd9e..982f847 100644
--- a/include/phb3.h
+++ b/include/phb3.h
@@ -52,9 +52,9 @@ 
 #define PHB3_LSI_IRQ_COUNT		8
 #define PHB3_LSI_IRQ_MAX		(PHB3_LSI_IRQ_MIN+PHB3_LSI_IRQ_COUNT-1)
 
-#define PHB3_MSI_IRQ_BASE(chip, phb)	(P8_CHIP_IRQ_PHB_BASE(chip, phb) | \
+#define PHB3_MSI_IRQ_BASE(chip, phb)	(p8_chip_irq_phb_base(chip, phb) | \
 					 PHB3_MSI_IRQ_MIN)
-#define PHB3_LSI_IRQ_BASE(chip, phb)	(P8_CHIP_IRQ_PHB_BASE(chip, phb) | \
+#define PHB3_LSI_IRQ_BASE(chip, phb)	(p8_chip_irq_phb_base(chip, phb) | \
 					 PHB3_LSI_IRQ_MIN)
 #define PHB3_IRQ_NUM(irq)		(irq & 0x7FF)
 
@@ -94,7 +94,7 @@ 
  * All those tables have to be naturally aligned
  */
 
-/* RTT Table : 128KB - Maps RID to PE# 
+/* RTT Table : 128KB - Maps RID to PE#
  *
  * Entries are 2 bytes indexed by PCIe RID
  */
diff --git a/include/skiboot.h b/include/skiboot.h
index 4b58597..cdc5a10 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -125,6 +125,9 @@  enum proc_gen {
 };
 extern enum proc_gen proc_gen;
 
+/* Number of chip id bits available */
+extern uint32_t p8_chip_id_bits;
+
 /* Convert a 4-bit number to a hex char */
 extern char __attrconst tohex(uint8_t nibble);
 
@@ -263,4 +266,3 @@  extern bool slw_timer_ok(void);
 extern void fake_rtc_init(void);
 
 #endif /* __SKIBOOT_H */
-