-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Michal Simek
committed
Mar 27, 2009
1 parent
8e0ee43
commit 406107d
Showing
4 changed files
with
433 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* Generic support for queying CPU info | ||
* | ||
* Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
* Copyright (C) 2007-2009 PetaLogix | ||
* Copyright (C) 2007 John Williams <jwilliams@itee.uq.edu.au> | ||
* | ||
* This file is subject to the terms and conditions of the GNU General | ||
* Public License. See the file COPYING in the main directory of this | ||
* archive for more details. | ||
*/ | ||
|
||
#ifndef _ASM_MICROBLAZE_CPUINFO_H | ||
#define _ASM_MICROBLAZE_CPUINFO_H | ||
|
||
#include <asm/prom.h> | ||
|
||
/* CPU Version and FPGA Family code conversion table type */ | ||
struct cpu_ver_key { | ||
const char *s; | ||
const unsigned k; | ||
}; | ||
|
||
extern const struct cpu_ver_key cpu_ver_lookup[]; | ||
|
||
struct family_string_key { | ||
const char *s; | ||
const unsigned k; | ||
}; | ||
|
||
extern const struct family_string_key family_string_lookup[]; | ||
|
||
struct cpuinfo { | ||
/* Core CPU configuration */ | ||
u32 use_instr; | ||
u32 use_mult; | ||
u32 use_fpu; | ||
u32 use_exc; | ||
u32 ver_code; | ||
u32 mmu; | ||
|
||
/* CPU caches */ | ||
u32 use_icache; | ||
u32 icache_tagbits; | ||
u32 icache_write; | ||
u32 icache_line; | ||
u32 icache_size; | ||
unsigned long icache_base; | ||
unsigned long icache_high; | ||
|
||
u32 use_dcache; | ||
u32 dcache_tagbits; | ||
u32 dcache_write; | ||
u32 dcache_line; | ||
u32 dcache_size; | ||
unsigned long dcache_base; | ||
unsigned long dcache_high; | ||
|
||
/* Bus connections */ | ||
u32 use_dopb; | ||
u32 use_iopb; | ||
u32 use_dlmb; | ||
u32 use_ilmb; | ||
u32 num_fsl; | ||
|
||
/* CPU interrupt line info */ | ||
u32 irq_edge; | ||
u32 irq_positive; | ||
|
||
u32 area_optimised; | ||
|
||
/* HW debug support */ | ||
u32 hw_debug; | ||
u32 num_pc_brk; | ||
u32 num_rd_brk; | ||
u32 num_wr_brk; | ||
u32 cpu_clock_freq; /* store real freq of cpu */ | ||
u32 freq_div_hz; /* store freq/HZ */ | ||
|
||
/* FPGA family */ | ||
u32 fpga_family_code; | ||
|
||
/* User define */ | ||
u32 pvr_user1; | ||
u32 pvr_user2; | ||
}; | ||
|
||
extern struct cpuinfo cpuinfo; | ||
|
||
/* fwd declarations of the various CPUinfo populators */ | ||
void setup_cpuinfo(void); | ||
|
||
void set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu); | ||
void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu); | ||
|
||
static inline unsigned int fcpu(struct device_node *cpu, char *n) | ||
{ | ||
int *val; | ||
return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0; | ||
} | ||
|
||
#endif /* _ASM_MICROBLAZE_CPUINFO_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
* Support for MicroBlaze PVR (processor version register) | ||
* | ||
* Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
* Copyright (C) 2007-2009 PetaLogix | ||
* Copyright (C) 2007 John Williams <john.williams@petalogix.com> | ||
* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file "COPYING" in the main directory of this archive | ||
* for more details. | ||
*/ | ||
|
||
#include <linux/init.h> | ||
#include <linux/string.h> | ||
#include <asm/pvr.h> | ||
#include <asm/cpuinfo.h> | ||
|
||
/* | ||
* Helper macro to map between fields in our struct cpuinfo, and | ||
* the PVR macros in pvr.h. | ||
*/ | ||
|
||
#define CI(c, p) { ci->c = PVR_##p(pvr); } | ||
#define err_printk(x) \ | ||
early_printk("ERROR: Microblaze " x " - different for PVR and DTS\n"); | ||
|
||
void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu) | ||
{ | ||
struct pvr_s pvr; | ||
int temp; /* for saving temp value */ | ||
get_pvr(&pvr); | ||
|
||
temp = PVR_USE_BARREL(pvr) | PVR_USE_MSR_INSTR(pvr) |\ | ||
PVR_USE_PCMP_INSTR(pvr) | PVR_USE_DIV(pvr); | ||
if (ci->use_instr != temp) | ||
err_printk("BARREL, MSR, PCMP or DIV"); | ||
ci->use_instr = temp; | ||
|
||
temp = PVR_USE_HW_MUL(pvr) | PVR_USE_MUL64(pvr); | ||
if (ci->use_mult != temp) | ||
err_printk("HW_MUL"); | ||
ci->use_mult = temp; | ||
|
||
temp = PVR_USE_FPU(pvr) | PVR_USE_FPU2(pvr); | ||
if (ci->use_fpu != temp) | ||
err_printk("HW_FPU"); | ||
ci->use_fpu = temp; | ||
|
||
ci->use_exc = PVR_OPCODE_0x0_ILLEGAL(pvr) |\ | ||
PVR_UNALIGNED_EXCEPTION(pvr) |\ | ||
PVR_ILL_OPCODE_EXCEPTION(pvr) |\ | ||
PVR_IOPB_BUS_EXCEPTION(pvr) |\ | ||
PVR_DOPB_BUS_EXCEPTION(pvr) |\ | ||
PVR_DIV_ZERO_EXCEPTION(pvr) |\ | ||
PVR_FPU_EXCEPTION(pvr) |\ | ||
PVR_FSL_EXCEPTION(pvr); | ||
|
||
CI(pvr_user1, USER1); | ||
CI(pvr_user2, USER2); | ||
|
||
CI(mmu, USE_MMU); | ||
|
||
CI(ver_code, VERSION); | ||
|
||
CI(use_icache, USE_ICACHE); | ||
CI(icache_tagbits, ICACHE_ADDR_TAG_BITS); | ||
CI(icache_write, ICACHE_ALLOW_WR); | ||
CI(icache_line, ICACHE_LINE_LEN); | ||
CI(icache_size, ICACHE_BYTE_SIZE); | ||
CI(icache_base, ICACHE_BASEADDR); | ||
CI(icache_high, ICACHE_HIGHADDR); | ||
|
||
CI(use_dcache, USE_DCACHE); | ||
CI(dcache_tagbits, DCACHE_ADDR_TAG_BITS); | ||
CI(dcache_write, DCACHE_ALLOW_WR); | ||
CI(dcache_line, DCACHE_LINE_LEN); | ||
CI(dcache_size, DCACHE_BYTE_SIZE); | ||
CI(dcache_base, DCACHE_BASEADDR); | ||
CI(dcache_high, DCACHE_HIGHADDR); | ||
|
||
CI(use_dopb, D_OPB); | ||
CI(use_iopb, I_OPB); | ||
CI(use_dlmb, D_LMB); | ||
CI(use_ilmb, I_LMB); | ||
CI(num_fsl, FSL_LINKS); | ||
|
||
CI(irq_edge, INTERRUPT_IS_EDGE); | ||
CI(irq_positive, EDGE_IS_POSITIVE); | ||
|
||
CI(area_optimised, AREA_OPTIMISED); | ||
|
||
CI(hw_debug, DEBUG_ENABLED); | ||
CI(num_pc_brk, NUMBER_OF_PC_BRK); | ||
CI(num_rd_brk, NUMBER_OF_RD_ADDR_BRK); | ||
CI(num_wr_brk, NUMBER_OF_WR_ADDR_BRK); | ||
|
||
CI(fpga_family_code, TARGET_FAMILY); | ||
|
||
/* take timebase-frequency from DTS */ | ||
ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/* | ||
* Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
* Copyright (C) 2007-2009 PetaLogix | ||
* Copyright (C) 2007 John Williams <john.williams@petalogix.com> | ||
* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file "COPYING" in the main directory of this archive | ||
* for more details. | ||
*/ | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/init.h> | ||
#include <linux/string.h> | ||
#include <asm/cpuinfo.h> | ||
#include <asm/pvr.h> | ||
|
||
const static char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY; | ||
const static char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER; | ||
|
||
#define err_printk(x) \ | ||
early_printk("ERROR: Microblaze " x "- different for kernel and DTS\n"); | ||
|
||
void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu) | ||
{ | ||
int i = 0; | ||
|
||
ci->use_instr = | ||
(fcpu(cpu, "xlnx,use-barrel") ? PVR0_USE_BARREL_MASK : 0) | | ||
(fcpu(cpu, "xlnx,use-msr-instr") ? PVR2_USE_MSR_INSTR : 0) | | ||
(fcpu(cpu, "xlnx,use-pcmp-instr") ? PVR2_USE_PCMP_INSTR : 0) | | ||
(fcpu(cpu, "xlnx,use-div") ? PVR0_USE_DIV_MASK : 0); | ||
if (CONFIG_XILINX_MICROBLAZE0_USE_BARREL) | ||
i |= PVR0_USE_BARREL_MASK; | ||
if (CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR) | ||
i |= PVR2_USE_MSR_INSTR; | ||
if (CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR) | ||
i |= PVR2_USE_PCMP_INSTR; | ||
if (CONFIG_XILINX_MICROBLAZE0_USE_DIV) | ||
i |= PVR0_USE_DIV_MASK; | ||
if (ci->use_instr != i) | ||
err_printk("BARREL, MSR, PCMP or DIV"); | ||
|
||
ci->use_mult = fcpu(cpu, "xlnx,use-hw-mul"); | ||
if (ci->use_mult != CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL) | ||
err_printk("HW_MUL"); | ||
ci->use_mult = | ||
(ci->use_mult > 1 ? | ||
(PVR2_USE_MUL64_MASK | PVR0_USE_HW_MUL_MASK) : | ||
(ci->use_mult == 1 ? PVR0_USE_HW_MUL_MASK : 0)); | ||
|
||
ci->use_fpu = fcpu(cpu, "xlnx,use-fpu"); | ||
if (ci->use_fpu != CONFIG_XILINX_MICROBLAZE0_USE_FPU) | ||
err_printk("HW_FPU"); | ||
ci->use_fpu = (ci->use_fpu > 1 ? | ||
(PVR2_USE_FPU2_MASK | PVR0_USE_FPU_MASK) : | ||
(ci->use_fpu == 1 ? PVR0_USE_FPU_MASK : 0)); | ||
|
||
ci->use_exc = | ||
(fcpu(cpu, "xlnx,unaligned-exceptions") ? | ||
PVR2_UNALIGNED_EXC_MASK : 0) | | ||
(fcpu(cpu, "xlnx,ill-opcode-exception") ? | ||
PVR2_ILL_OPCODE_EXC_MASK : 0) | | ||
(fcpu(cpu, "xlnx,iopb-bus-exception") ? | ||
PVR2_IOPB_BUS_EXC_MASK : 0) | | ||
(fcpu(cpu, "xlnx,dopb-bus-exception") ? | ||
PVR2_DOPB_BUS_EXC_MASK : 0) | | ||
(fcpu(cpu, "xlnx,div-zero-exception") ? | ||
PVR2_DIV_ZERO_EXC_MASK : 0) | | ||
(fcpu(cpu, "xlnx,fpu-exception") ? PVR2_FPU_EXC_MASK : 0) | | ||
(fcpu(cpu, "xlnx,fsl-exception") ? PVR2_USE_EXTEND_FSL : 0); | ||
|
||
ci->use_icache = fcpu(cpu, "xlnx,use-icache"); | ||
ci->icache_tagbits = fcpu(cpu, "xlnx,addr-tag-bits"); | ||
ci->icache_write = fcpu(cpu, "xlnx,allow-icache-wr"); | ||
ci->icache_line = fcpu(cpu, "xlnx,icache-line-len") << 2; | ||
if (!ci->icache_line) { | ||
if (fcpu(cpu, "xlnx,icache-use-fsl")) | ||
ci->icache_line = 4 << 2; | ||
else | ||
ci->icache_line = 1 << 2; | ||
} | ||
ci->icache_size = fcpu(cpu, "i-cache-size"); | ||
ci->icache_base = fcpu(cpu, "i-cache-baseaddr"); | ||
ci->icache_high = fcpu(cpu, "i-cache-highaddr"); | ||
|
||
ci->use_dcache = fcpu(cpu, "xlnx,use-dcache"); | ||
ci->dcache_tagbits = fcpu(cpu, "xlnx,dcache-addr-tag"); | ||
ci->dcache_write = fcpu(cpu, "xlnx,allow-dcache-wr"); | ||
ci->dcache_line = fcpu(cpu, "xlnx,dcache-line-len") << 2; | ||
if (!ci->dcache_line) { | ||
if (fcpu(cpu, "xlnx,dcache-use-fsl")) | ||
ci->dcache_line = 4 << 2; | ||
else | ||
ci->dcache_line = 1 << 2; | ||
} | ||
ci->dcache_size = fcpu(cpu, "d-cache-size"); | ||
ci->dcache_base = fcpu(cpu, "d-cache-baseaddr"); | ||
ci->dcache_high = fcpu(cpu, "d-cache-highaddr"); | ||
|
||
ci->use_dopb = fcpu(cpu, "xlnx,d-opb"); | ||
ci->use_iopb = fcpu(cpu, "xlnx,i-opb"); | ||
ci->use_dlmb = fcpu(cpu, "xlnx,d-lmb"); | ||
ci->use_ilmb = fcpu(cpu, "xlnx,i-lmb"); | ||
|
||
ci->num_fsl = fcpu(cpu, "xlnx,fsl-links"); | ||
ci->irq_edge = fcpu(cpu, "xlnx,interrupt-is-edge"); | ||
ci->irq_positive = fcpu(cpu, "xlnx,edge-is-positive"); | ||
ci->area_optimised = 0; | ||
|
||
ci->hw_debug = fcpu(cpu, "xlnx,debug-enabled"); | ||
ci->num_pc_brk = fcpu(cpu, "xlnx,number-of-pc-brk"); | ||
ci->num_rd_brk = fcpu(cpu, "xlnx,number-of-rd-addr-brk"); | ||
ci->num_wr_brk = fcpu(cpu, "xlnx,number-of-wr-addr-brk"); | ||
|
||
ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency"); | ||
|
||
ci->pvr_user1 = fcpu(cpu, "xlnx,pvr-user1"); | ||
ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2"); | ||
|
||
ci->mmu = fcpu(cpu, "xlnx,use-mmu"); | ||
|
||
ci->ver_code = 0; | ||
ci->fpga_family_code = 0; | ||
|
||
/* Do various fixups based on CPU version and FPGA family strings */ | ||
|
||
/* Resolved the CPU version code */ | ||
for (i = 0; cpu_ver_lookup[i].s != NULL; i++) { | ||
if (strcmp(cpu_ver_lookup[i].s, cpu_ver_string) == 0) | ||
ci->ver_code = cpu_ver_lookup[i].k; | ||
} | ||
|
||
/* Resolved the fpga family code */ | ||
for (i = 0; family_string_lookup[i].s != NULL; i++) { | ||
if (strcmp(family_string_lookup[i].s, family_string) == 0) | ||
ci->fpga_family_code = family_string_lookup[i].k; | ||
} | ||
|
||
/* FIXME - mb3 and spartan2 do not exist in PVR */ | ||
/* This is mb3 and on a non Spartan2 */ | ||
if (ci->ver_code == 0x20 && ci->fpga_family_code != 0xf0) | ||
/* Hardware Multiplier in use */ | ||
ci->use_mult = 1; | ||
} |
Oops, something went wrong.