aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2009-03-27 09:25:18 -0400
committerMichal Simek <monstr@monstr.eu>2009-03-27 09:25:18 -0400
commitb0c62724a52a4f541bfe77c678a0229d7a7c6844 (patch)
treed281231c4a17978762fe587c409e084db375047d
parent93139b1cf85924a3cc758c9a83b8c7b689987729 (diff)
microblaze_v8: PVR support, cpuinfo support
Reviewed-by: Ingo Molnar <mingo@elte.hu> Acked-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com> Acked-by: John Linn <john.linn@xilinx.com> Acked-by: John Williams <john.williams@petalogix.com> Signed-off-by: Michal Simek <monstr@monstr.eu>
-rw-r--r--arch/microblaze/include/asm/pvr.h209
-rw-r--r--arch/microblaze/kernel/cpu/mb.c148
-rw-r--r--arch/microblaze/kernel/cpu/pvr.c81
3 files changed, 438 insertions, 0 deletions
diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h
new file mode 100644
index 000000000000..66f1b30dd097
--- /dev/null
+++ b/arch/microblaze/include/asm/pvr.h
@@ -0,0 +1,209 @@
1/*
2 * Support for the MicroBlaze PVR (Processor Version Register)
3 *
4 * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
5 * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
6 * Copyright (C) 2007 - 2009 PetaLogix
7 *
8 * This file is subject to the terms and conditions of the GNU General
9 * Public License. See the file COPYING in the main directory of this
10 * archive for more details.
11 */
12
13#ifndef _ASM_MICROBLAZE_PVR_H
14#define _ASM_MICROBLAZE_PVR_H
15
16#define PVR_MSR_BIT 0x400
17
18struct pvr_s {
19 unsigned pvr[16];
20};
21
22/* The following taken from Xilinx's standalone BSP pvr.h */
23
24/* Basic PVR mask */
25#define PVR0_PVR_FULL_MASK 0x80000000
26#define PVR0_USE_BARREL_MASK 0x40000000
27#define PVR0_USE_DIV_MASK 0x20000000
28#define PVR0_USE_HW_MUL_MASK 0x10000000
29#define PVR0_USE_FPU_MASK 0x08000000
30#define PVR0_USE_EXC_MASK 0x04000000
31#define PVR0_USE_ICACHE_MASK 0x02000000
32#define PVR0_USE_DCACHE_MASK 0x01000000
33#define PVR0_USE_MMU 0x00800000 /* new */
34#define PVR0_VERSION_MASK 0x0000FF00
35#define PVR0_USER1_MASK 0x000000FF
36
37/* User 2 PVR mask */
38#define PVR1_USER2_MASK 0xFFFFFFFF
39
40/* Configuration PVR masks */
41#define PVR2_D_OPB_MASK 0x80000000
42#define PVR2_D_LMB_MASK 0x40000000
43#define PVR2_I_OPB_MASK 0x20000000
44#define PVR2_I_LMB_MASK 0x10000000
45#define PVR2_INTERRUPT_IS_EDGE_MASK 0x08000000
46#define PVR2_EDGE_IS_POSITIVE_MASK 0x04000000
47#define PVR2_D_PLB_MASK 0x02000000 /* new */
48#define PVR2_I_PLB_MASK 0x01000000 /* new */
49#define PVR2_INTERCONNECT 0x00800000 /* new */
50#define PVR2_USE_EXTEND_FSL 0x00080000 /* new */
51#define PVR2_USE_FSL_EXC 0x00040000 /* new */
52#define PVR2_USE_MSR_INSTR 0x00020000
53#define PVR2_USE_PCMP_INSTR 0x00010000
54#define PVR2_AREA_OPTIMISED 0x00008000
55#define PVR2_USE_BARREL_MASK 0x00004000
56#define PVR2_USE_DIV_MASK 0x00002000
57#define PVR2_USE_HW_MUL_MASK 0x00001000
58#define PVR2_USE_FPU_MASK 0x00000800
59#define PVR2_USE_MUL64_MASK 0x00000400
60#define PVR2_USE_FPU2_MASK 0x00000200 /* new */
61#define PVR2_USE_IPLBEXC 0x00000100
62#define PVR2_USE_DPLBEXC 0x00000080
63#define PVR2_OPCODE_0x0_ILL_MASK 0x00000040
64#define PVR2_UNALIGNED_EXC_MASK 0x00000020
65#define PVR2_ILL_OPCODE_EXC_MASK 0x00000010
66#define PVR2_IOPB_BUS_EXC_MASK 0x00000008
67#define PVR2_DOPB_BUS_EXC_MASK 0x00000004
68#define PVR2_DIV_ZERO_EXC_MASK 0x00000002
69#define PVR2_FPU_EXC_MASK 0x00000001
70
71/* Debug and exception PVR masks */
72#define PVR3_DEBUG_ENABLED_MASK 0x80000000
73#define PVR3_NUMBER_OF_PC_BRK_MASK 0x1E000000
74#define PVR3_NUMBER_OF_RD_ADDR_BRK_MASK 0x00380000
75#define PVR3_NUMBER_OF_WR_ADDR_BRK_MASK 0x0000E000
76#define PVR3_FSL_LINKS_MASK 0x00000380
77
78/* ICache config PVR masks */
79#define PVR4_USE_ICACHE_MASK 0x80000000
80#define PVR4_ICACHE_ADDR_TAG_BITS_MASK 0x7C000000
81#define PVR4_ICACHE_USE_FSL_MASK 0x02000000
82#define PVR4_ICACHE_ALLOW_WR_MASK 0x01000000
83#define PVR4_ICACHE_LINE_LEN_MASK 0x00E00000
84#define PVR4_ICACHE_BYTE_SIZE_MASK 0x001F0000
85
86/* DCache config PVR masks */
87#define PVR5_USE_DCACHE_MASK 0x80000000
88#define PVR5_DCACHE_ADDR_TAG_BITS_MASK 0x7C000000
89#define PVR5_DCACHE_USE_FSL_MASK 0x02000000
90#define PVR5_DCACHE_ALLOW_WR_MASK 0x01000000
91#define PVR5_DCACHE_LINE_LEN_MASK 0x00E00000
92#define PVR5_DCACHE_BYTE_SIZE_MASK 0x001F0000
93
94/* ICache base address PVR mask */
95#define PVR6_ICACHE_BASEADDR_MASK 0xFFFFFFFF
96
97/* ICache high address PVR mask */
98#define PVR7_ICACHE_HIGHADDR_MASK 0xFFFFFFFF
99
100/* DCache base address PVR mask */
101#define PVR8_DCACHE_BASEADDR_MASK 0xFFFFFFFF
102
103/* DCache high address PVR mask */
104#define PVR9_DCACHE_HIGHADDR_MASK 0xFFFFFFFF
105
106/* Target family PVR mask */
107#define PVR10_TARGET_FAMILY_MASK 0xFF000000
108
109/* MMU descrtiption */
110#define PVR11_USE_MMU 0xC0000000
111#define PVR11_MMU_ITLB_SIZE 0x38000000
112#define PVR11_MMU_DTLB_SIZE 0x07000000
113#define PVR11_MMU_TLB_ACCESS 0x00C00000
114#define PVR11_MMU_ZONES 0x003C0000
115/* MSR Reset value PVR mask */
116#define PVR11_MSR_RESET_VALUE_MASK 0x000007FF
117
118
119/* PVR access macros */
120#define PVR_IS_FULL(pvr) (pvr.pvr[0] & PVR0_PVR_FULL_MASK)
121#define PVR_USE_BARREL(pvr) (pvr.pvr[0] & PVR0_USE_BARREL_MASK)
122#define PVR_USE_DIV(pvr) (pvr.pvr[0] & PVR0_USE_DIV_MASK)
123#define PVR_USE_HW_MUL(pvr) (pvr.pvr[0] & PVR0_USE_HW_MUL_MASK)
124#define PVR_USE_FPU(pvr) (pvr.pvr[0] & PVR0_USE_FPU_MASK)
125#define PVR_USE_FPU2(pvr) (pvr.pvr[2] & PVR2_USE_FPU2_MASK)
126#define PVR_USE_ICACHE(pvr) (pvr.pvr[0] & PVR0_USE_ICACHE_MASK)
127#define PVR_USE_DCACHE(pvr) (pvr.pvr[0] & PVR0_USE_DCACHE_MASK)
128#define PVR_VERSION(pvr) ((pvr.pvr[0] & PVR0_VERSION_MASK) >> 8)
129#define PVR_USER1(pvr) (pvr.pvr[0] & PVR0_USER1_MASK)
130#define PVR_USER2(pvr) (pvr.pvr[1] & PVR1_USER2_MASK)
131
132#define PVR_D_OPB(pvr) (pvr.pvr[2] & PVR2_D_OPB_MASK)
133#define PVR_D_LMB(pvr) (pvr.pvr[2] & PVR2_D_LMB_MASK)
134#define PVR_I_OPB(pvr) (pvr.pvr[2] & PVR2_I_OPB_MASK)
135#define PVR_I_LMB(pvr) (pvr.pvr[2] & PVR2_I_LMB_MASK)
136#define PVR_INTERRUPT_IS_EDGE(pvr) \
137 (pvr.pvr[2] & PVR2_INTERRUPT_IS_EDGE_MASK)
138#define PVR_EDGE_IS_POSITIVE(pvr) \
139 (pvr.pvr[2] & PVR2_EDGE_IS_POSITIVE_MASK)
140#define PVR_USE_MSR_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_MSR_INSTR)
141#define PVR_USE_PCMP_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_PCMP_INSTR)
142#define PVR_AREA_OPTIMISED(pvr) (pvr.pvr[2] & PVR2_AREA_OPTIMISED)
143#define PVR_USE_MUL64(pvr) (pvr.pvr[2] & PVR2_USE_MUL64_MASK)
144#define PVR_OPCODE_0x0_ILLEGAL(pvr) \
145 (pvr.pvr[2] & PVR2_OPCODE_0x0_ILL_MASK)
146#define PVR_UNALIGNED_EXCEPTION(pvr) \
147 (pvr.pvr[2] & PVR2_UNALIGNED_EXC_MASK)
148#define PVR_ILL_OPCODE_EXCEPTION(pvr) \
149 (pvr.pvr[2] & PVR2_ILL_OPCODE_EXC_MASK)
150#define PVR_IOPB_BUS_EXCEPTION(pvr) \
151 (pvr.pvr[2] & PVR2_IOPB_BUS_EXC_MASK)
152#define PVR_DOPB_BUS_EXCEPTION(pvr) \
153 (pvr.pvr[2] & PVR2_DOPB_BUS_EXC_MASK)
154#define PVR_DIV_ZERO_EXCEPTION(pvr) \
155 (pvr.pvr[2] & PVR2_DIV_ZERO_EXC_MASK)
156#define PVR_FPU_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_FPU_EXC_MASK)
157#define PVR_FSL_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_USE_EXTEND_FSL)
158
159#define PVR_DEBUG_ENABLED(pvr) (pvr.pvr[3] & PVR3_DEBUG_ENABLED_MASK)
160#define PVR_NUMBER_OF_PC_BRK(pvr) \
161 ((pvr.pvr[3] & PVR3_NUMBER_OF_PC_BRK_MASK) >> 25)
162#define PVR_NUMBER_OF_RD_ADDR_BRK(pvr) \
163 ((pvr.pvr[3] & PVR3_NUMBER_OF_RD_ADDR_BRK_MASK) >> 19)
164#define PVR_NUMBER_OF_WR_ADDR_BRK(pvr) \
165 ((pvr.pvr[3] & PVR3_NUMBER_OF_WR_ADDR_BRK_MASK) >> 13)
166#define PVR_FSL_LINKS(pvr) ((pvr.pvr[3] & PVR3_FSL_LINKS_MASK) >> 7)
167
168#define PVR_ICACHE_ADDR_TAG_BITS(pvr) \
169 ((pvr.pvr[4] & PVR4_ICACHE_ADDR_TAG_BITS_MASK) >> 26)
170#define PVR_ICACHE_USE_FSL(pvr) (pvr.pvr[4] & PVR4_ICACHE_USE_FSL_MASK)
171#define PVR_ICACHE_ALLOW_WR(pvr) (pvr.pvr[4] & PVR4_ICACHE_ALLOW_WR_MASK)
172#define PVR_ICACHE_LINE_LEN(pvr) \
173 (1 << ((pvr.pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21))
174#define PVR_ICACHE_BYTE_SIZE(pvr) \
175 (1 << ((pvr.pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16))
176
177#define PVR_DCACHE_ADDR_TAG_BITS(pvr) \
178 ((pvr.pvr[5] & PVR5_DCACHE_ADDR_TAG_BITS_MASK) >> 26)
179#define PVR_DCACHE_USE_FSL(pvr) (pvr.pvr[5] & PVR5_DCACHE_USE_FSL_MASK)
180#define PVR_DCACHE_ALLOW_WR(pvr) (pvr.pvr[5] & PVR5_DCACHE_ALLOW_WR_MASK)
181#define PVR_DCACHE_LINE_LEN(pvr) \
182 (1 << ((pvr.pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21))
183#define PVR_DCACHE_BYTE_SIZE(pvr) \
184 (1 << ((pvr.pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16))
185
186
187#define PVR_ICACHE_BASEADDR(pvr) (pvr.pvr[6] & PVR6_ICACHE_BASEADDR_MASK)
188#define PVR_ICACHE_HIGHADDR(pvr) (pvr.pvr[7] & PVR7_ICACHE_HIGHADDR_MASK)
189
190#define PVR_DCACHE_BASEADDR(pvr) (pvr.pvr[8] & PVR8_DCACHE_BASEADDR_MASK)
191#define PVR_DCACHE_HIGHADDR(pvr) (pvr.pvr[9] & PVR9_DCACHE_HIGHADDR_MASK)
192
193#define PVR_TARGET_FAMILY(pvr) ((pvr.pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24)
194
195#define PVR_MSR_RESET_VALUE(pvr) \
196 (pvr.pvr[11] & PVR11_MSR_RESET_VALUE_MASK)
197
198/* mmu */
199#define PVR_USE_MMU(pvr) ((pvr.pvr[11] & PVR11_USE_MMU) >> 30)
200#define PVR_MMU_ITLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_ITLB_SIZE)
201#define PVR_MMU_DTLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_DTLB_SIZE)
202#define PVR_MMU_TLB_ACCESS(pvr) (pvr.pvr[11] & PVR11_MMU_TLB_ACCESS)
203#define PVR_MMU_ZONES(pvr) (pvr.pvr[11] & PVR11_MMU_ZONES)
204
205
206int cpu_has_pvr(void);
207void get_pvr(struct pvr_s *pvr);
208
209#endif /* _ASM_MICROBLAZE_PVR_H */
diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c
new file mode 100644
index 000000000000..3b6212bdc8dc
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/mb.c
@@ -0,0 +1,148 @@
1/*
2 * CPU-version specific code
3 *
4 * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
5 * Copyright (C) 2006-2009 PetaLogix
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11
12#include <linux/init.h>
13#include <linux/string.h>
14#include <linux/seq_file.h>
15#include <linux/cpu.h>
16#include <linux/initrd.h>
17
18#include <linux/bug.h>
19#include <asm/cpuinfo.h>
20#include <linux/delay.h>
21#include <linux/io.h>
22#include <asm/page.h>
23#include <linux/param.h>
24#include <asm/pvr.h>
25#include <asm/sections.h>
26#include <asm/setup.h>
27
28static int show_cpuinfo(struct seq_file *m, void *v)
29{
30 int count = 0;
31 char *fpga_family = "Unknown";
32 char *cpu_ver = "Unknown";
33 int i;
34
35 /* Denormalised to get the fpga family string */
36 for (i = 0; family_string_lookup[i].s != NULL; i++) {
37 if (cpuinfo.fpga_family_code == family_string_lookup[i].k) {
38 fpga_family = (char *)family_string_lookup[i].s;
39 break;
40 }
41 }
42
43 /* Denormalised to get the hw version string */
44 for (i = 0; cpu_ver_lookup[i].s != NULL; i++) {
45 if (cpuinfo.ver_code == cpu_ver_lookup[i].k) {
46 cpu_ver = (char *)cpu_ver_lookup[i].s;
47 break;
48 }
49 }
50
51 count = seq_printf(m,
52 "CPU-Family: MicroBlaze\n"
53 "FPGA-Arch: %s\n"
54 "CPU-Ver: %s\n"
55 "CPU-MHz: %d.%02d\n"
56 "BogoMips: %lu.%02lu\n",
57 fpga_family,
58 cpu_ver,
59 cpuinfo.cpu_clock_freq /
60 1000000,
61 cpuinfo.cpu_clock_freq %
62 1000000,
63 loops_per_jiffy / (500000 / HZ),
64 (loops_per_jiffy / (5000 / HZ)) % 100);
65
66 count += seq_printf(m,
67 "HW:\n Shift:\t\t%s\n"
68 " MSR:\t\t%s\n"
69 " PCMP:\t\t%s\n"
70 " DIV:\t\t%s\n",
71 (cpuinfo.use_instr & PVR0_USE_BARREL_MASK) ? "yes" : "no",
72 (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) ? "yes" : "no",
73 (cpuinfo.use_instr & PVR2_USE_PCMP_INSTR) ? "yes" : "no",
74 (cpuinfo.use_instr & PVR0_USE_DIV_MASK) ? "yes" : "no");
75
76 count += seq_printf(m,
77 " MMU:\t\t%x\n",
78 cpuinfo.mmu);
79
80 count += seq_printf(m,
81 " MUL:\t\t%s\n"
82 " FPU:\t\t%s\n",
83 (cpuinfo.use_mult & PVR2_USE_MUL64_MASK) ? "v2" :
84 (cpuinfo.use_mult & PVR0_USE_HW_MUL_MASK) ? "v1" : "no",
85 (cpuinfo.use_fpu & PVR2_USE_FPU2_MASK) ? "v2" :
86 (cpuinfo.use_fpu & PVR0_USE_FPU_MASK) ? "v1" : "no");
87
88 count += seq_printf(m,
89 " Exc:\t\t%s%s%s%s%s%s%s%s\n",
90 (cpuinfo.use_exc & PVR2_OPCODE_0x0_ILL_MASK) ? "op0x0 " : "",
91 (cpuinfo.use_exc & PVR2_UNALIGNED_EXC_MASK) ? "unal " : "",
92 (cpuinfo.use_exc & PVR2_ILL_OPCODE_EXC_MASK) ? "ill " : "",
93 (cpuinfo.use_exc & PVR2_IOPB_BUS_EXC_MASK) ? "iopb " : "",
94 (cpuinfo.use_exc & PVR2_DOPB_BUS_EXC_MASK) ? "dopb " : "",
95 (cpuinfo.use_exc & PVR2_DIV_ZERO_EXC_MASK) ? "zero " : "",
96 (cpuinfo.use_exc & PVR2_FPU_EXC_MASK) ? "fpu " : "",
97 (cpuinfo.use_exc & PVR2_USE_FSL_EXC) ? "fsl " : "");
98
99 if (cpuinfo.use_icache)
100 count += seq_printf(m,
101 "Icache:\t\t%ukB\n",
102 cpuinfo.icache_size >> 10);
103 else
104 count += seq_printf(m, "Icache:\t\tno\n");
105
106 if (cpuinfo.use_dcache)
107 count += seq_printf(m,
108 "Dcache:\t\t%ukB\n",
109 cpuinfo.dcache_size >> 10);
110 else
111 count += seq_printf(m, "Dcache:\t\tno\n");
112
113 count += seq_printf(m,
114 "HW-Debug:\t%s\n",
115 cpuinfo.hw_debug ? "yes" : "no");
116
117 count += seq_printf(m,
118 "PVR-USR1:\t%x\n"
119 "PVR-USR2:\t%x\n",
120 cpuinfo.pvr_user1,
121 cpuinfo.pvr_user2);
122
123 return 0;
124}
125
126static void *c_start(struct seq_file *m, loff_t *pos)
127{
128 int i = *pos;
129
130 return i < NR_CPUS ? (void *) (i + 1) : NULL;
131}
132
133static void *c_next(struct seq_file *m, void *v, loff_t *pos)
134{
135 ++*pos;
136 return c_start(m, pos);
137}
138
139static void c_stop(struct seq_file *m, void *v)
140{
141}
142
143const struct seq_operations cpuinfo_op = {
144 .start = c_start,
145 .next = c_next,
146 .stop = c_stop,
147 .show = show_cpuinfo,
148};
diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c
new file mode 100644
index 000000000000..c9a4340ddd53
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/pvr.c
@@ -0,0 +1,81 @@
1/*
2 * Support for MicroBlaze PVR (processor version register)
3 *
4 * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
5 * Copyright (C) 2007-2009 PetaLogix
6 * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/compiler.h>
15#include <asm/system.h>
16#include <asm/exceptions.h>
17#include <asm/pvr.h>
18
19/*
20 * Until we get an assembler that knows about the pvr registers,
21 * this horrible cruft will have to do.
22 * That hardcoded opcode is mfs r3, rpvrNN
23 */
24
25#define get_single_pvr(pvrid, val) \
26{ \
27 register unsigned tmp __asm__("r3"); \
28 tmp = 0x0; /* Prevent warning about unused */ \
29 __asm__ __volatile__ ( \
30 ".byte 0x94,0x60,0xa0, " #pvrid "\n\t" \
31 : "=r" (tmp) : : "memory"); \
32 val = tmp; \
33}
34
35/*
36 * Does the CPU support the PVR register?
37 * return value:
38 * 0: no PVR
39 * 1: simple PVR
40 * 2: full PVR
41 *
42 * This must work on all CPU versions, including those before the
43 * PVR was even an option.
44 */
45
46int cpu_has_pvr(void)
47{
48 unsigned flags;
49 unsigned pvr0;
50
51 local_save_flags(flags);
52
53 /* PVR bit in MSR tells us if there is any support */
54 if (!(flags & PVR_MSR_BIT))
55 return 0;
56
57 get_single_pvr(0x00, pvr0);
58 pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0);
59
60 if (pvr0 & PVR0_PVR_FULL_MASK)
61 return 1;
62
63 /* for partial PVR use static cpuinfo */
64 return 2;
65}
66
67void get_pvr(struct pvr_s *p)
68{
69 get_single_pvr(0, p->pvr[0]);
70 get_single_pvr(1, p->pvr[1]);
71 get_single_pvr(2, p->pvr[2]);
72 get_single_pvr(3, p->pvr[3]);
73 get_single_pvr(4, p->pvr[4]);
74 get_single_pvr(5, p->pvr[5]);
75 get_single_pvr(6, p->pvr[6]);
76 get_single_pvr(7, p->pvr[7]);
77 get_single_pvr(8, p->pvr[8]);
78 get_single_pvr(9, p->pvr[9]);
79 get_single_pvr(10, p->pvr[10]);
80 get_single_pvr(11, p->pvr[11]);
81}