2 * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
3 * Copyright (C) 2007-2009 PetaLogix
4 * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/string.h>
14 #include <asm/cpuinfo.h>
17 static const char family_string
[] = CONFIG_XILINX_MICROBLAZE0_FAMILY
;
18 static const char cpu_ver_string
[] = CONFIG_XILINX_MICROBLAZE0_HW_VER
;
20 #define err_printk(x) \
21 early_printk("ERROR: Microblaze " x "-different for kernel and DTS\n");
23 void __init
set_cpuinfo_static(struct cpuinfo
*ci
, struct device_node
*cpu
)
28 (fcpu(cpu
, "xlnx,use-barrel") ? PVR0_USE_BARREL_MASK
: 0) |
29 (fcpu(cpu
, "xlnx,use-msr-instr") ? PVR2_USE_MSR_INSTR
: 0) |
30 (fcpu(cpu
, "xlnx,use-pcmp-instr") ? PVR2_USE_PCMP_INSTR
: 0) |
31 (fcpu(cpu
, "xlnx,use-div") ? PVR0_USE_DIV_MASK
: 0);
32 if (CONFIG_XILINX_MICROBLAZE0_USE_BARREL
)
33 i
|= PVR0_USE_BARREL_MASK
;
34 if (CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
)
35 i
|= PVR2_USE_MSR_INSTR
;
36 if (CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR
)
37 i
|= PVR2_USE_PCMP_INSTR
;
38 if (CONFIG_XILINX_MICROBLAZE0_USE_DIV
)
39 i
|= PVR0_USE_DIV_MASK
;
40 if (ci
->use_instr
!= i
)
41 err_printk("BARREL, MSR, PCMP or DIV");
43 ci
->use_mult
= fcpu(cpu
, "xlnx,use-hw-mul");
44 if (ci
->use_mult
!= CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL
)
48 (PVR2_USE_MUL64_MASK
| PVR0_USE_HW_MUL_MASK
) :
49 (ci
->use_mult
== 1 ? PVR0_USE_HW_MUL_MASK
: 0));
51 ci
->use_fpu
= fcpu(cpu
, "xlnx,use-fpu");
52 if (ci
->use_fpu
!= CONFIG_XILINX_MICROBLAZE0_USE_FPU
)
54 ci
->use_fpu
= (ci
->use_fpu
> 1 ?
55 (PVR2_USE_FPU2_MASK
| PVR0_USE_FPU_MASK
) :
56 (ci
->use_fpu
== 1 ? PVR0_USE_FPU_MASK
: 0));
59 (fcpu(cpu
, "xlnx,unaligned-exceptions") ?
60 PVR2_UNALIGNED_EXC_MASK
: 0) |
61 (fcpu(cpu
, "xlnx,ill-opcode-exception") ?
62 PVR2_ILL_OPCODE_EXC_MASK
: 0) |
63 (fcpu(cpu
, "xlnx,iopb-bus-exception") ?
64 PVR2_IOPB_BUS_EXC_MASK
: 0) |
65 (fcpu(cpu
, "xlnx,dopb-bus-exception") ?
66 PVR2_DOPB_BUS_EXC_MASK
: 0) |
67 (fcpu(cpu
, "xlnx,div-zero-exception") ?
68 PVR2_DIV_ZERO_EXC_MASK
: 0) |
69 (fcpu(cpu
, "xlnx,fpu-exception") ? PVR2_FPU_EXC_MASK
: 0) |
70 (fcpu(cpu
, "xlnx,fsl-exception") ? PVR2_USE_EXTEND_FSL
: 0);
72 ci
->use_icache
= fcpu(cpu
, "xlnx,use-icache");
73 ci
->icache_tagbits
= fcpu(cpu
, "xlnx,addr-tag-bits");
74 ci
->icache_write
= fcpu(cpu
, "xlnx,allow-icache-wr");
75 ci
->icache_line_length
= fcpu(cpu
, "xlnx,icache-line-len") << 2;
76 if (!ci
->icache_line_length
) {
77 if (fcpu(cpu
, "xlnx,icache-use-fsl"))
78 ci
->icache_line_length
= 4 << 2;
80 ci
->icache_line_length
= 1 << 2;
82 ci
->icache_size
= fcpu(cpu
, "i-cache-size");
83 ci
->icache_base
= fcpu(cpu
, "i-cache-baseaddr");
84 ci
->icache_high
= fcpu(cpu
, "i-cache-highaddr");
86 ci
->use_dcache
= fcpu(cpu
, "xlnx,use-dcache");
87 ci
->dcache_tagbits
= fcpu(cpu
, "xlnx,dcache-addr-tag");
88 ci
->dcache_write
= fcpu(cpu
, "xlnx,allow-dcache-wr");
89 ci
->dcache_line_length
= fcpu(cpu
, "xlnx,dcache-line-len") << 2;
90 if (!ci
->dcache_line_length
) {
91 if (fcpu(cpu
, "xlnx,dcache-use-fsl"))
92 ci
->dcache_line_length
= 4 << 2;
94 ci
->dcache_line_length
= 1 << 2;
96 ci
->dcache_size
= fcpu(cpu
, "d-cache-size");
97 ci
->dcache_base
= fcpu(cpu
, "d-cache-baseaddr");
98 ci
->dcache_high
= fcpu(cpu
, "d-cache-highaddr");
99 ci
->dcache_wb
= fcpu(cpu
, "xlnx,dcache-use-writeback");
101 ci
->use_dopb
= fcpu(cpu
, "xlnx,d-opb");
102 ci
->use_iopb
= fcpu(cpu
, "xlnx,i-opb");
103 ci
->use_dlmb
= fcpu(cpu
, "xlnx,d-lmb");
104 ci
->use_ilmb
= fcpu(cpu
, "xlnx,i-lmb");
106 ci
->num_fsl
= fcpu(cpu
, "xlnx,fsl-links");
107 ci
->irq_edge
= fcpu(cpu
, "xlnx,interrupt-is-edge");
108 ci
->irq_positive
= fcpu(cpu
, "xlnx,edge-is-positive");
109 ci
->area_optimised
= 0;
111 ci
->hw_debug
= fcpu(cpu
, "xlnx,debug-enabled");
112 ci
->num_pc_brk
= fcpu(cpu
, "xlnx,number-of-pc-brk");
113 ci
->num_rd_brk
= fcpu(cpu
, "xlnx,number-of-rd-addr-brk");
114 ci
->num_wr_brk
= fcpu(cpu
, "xlnx,number-of-wr-addr-brk");
116 ci
->cpu_clock_freq
= fcpu(cpu
, "timebase-frequency");
118 ci
->pvr_user1
= fcpu(cpu
, "xlnx,pvr-user1");
119 ci
->pvr_user2
= fcpu(cpu
, "xlnx,pvr-user2");
121 ci
->mmu
= fcpu(cpu
, "xlnx,use-mmu");
122 ci
->mmu_privins
= fcpu(cpu
, "xlnx,mmu-privileged-instr");
123 ci
->endian
= fcpu(cpu
, "xlnx,endianness");
126 ci
->fpga_family_code
= 0;
128 /* Do various fixups based on CPU version and FPGA family strings */
130 /* Resolved the CPU version code */
131 for (i
= 0; cpu_ver_lookup
[i
].s
!= NULL
; i
++) {
132 if (strcmp(cpu_ver_lookup
[i
].s
, cpu_ver_string
) == 0)
133 ci
->ver_code
= cpu_ver_lookup
[i
].k
;
136 /* Resolved the fpga family code */
137 for (i
= 0; family_string_lookup
[i
].s
!= NULL
; i
++) {
138 if (strcmp(family_string_lookup
[i
].s
, family_string
) == 0)
139 ci
->fpga_family_code
= family_string_lookup
[i
].k
;
142 /* FIXME - mb3 and spartan2 do not exist in PVR */
143 /* This is mb3 and on a non Spartan2 */
144 if (ci
->ver_code
== 0x20 && ci
->fpga_family_code
!= 0xf0)
145 /* Hardware Multiplier in use */