Столкнулся с проблемой имеется плата с камнем МРС8377, на локальную шину повешена плисина и пытаюсь достучаться в плисину, что бы считать данные. Конструирую модуль и мне если не ошибки валятся так читается разная ерунда, пробовал разные способы (http://electronix.ru/forum/index.php?showtopic=97750), последний вариант, который тоже не работает:
Код
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <asm/prom.h>
#include <asm-powerpc/io.h>
#include <asm-powerpc/qe.h>
#define DRIVER_NAME "LocalBus"
#define DRIVER_MAJOR 242
static volatile u32 __iomem *p_local_bus;
static volatile u32 __iomem *immrbar2;
//***here FPGA1 base address is defined on LB (the same as FPGA base address in previous project)
#define CFG_FPGA1_BASE 0xF0000000
//***here FPGA2 base address is defined on LB (=FPGA1 base address + 512KB)
#define CFG_FPGA2_BASE 0xF0080000
#define IMMRBAR_BASE_ADDR 0xe0000000
#define MBAR_BASE IMMRBAR_BASE_ADDR /* #define IMMRBAR_BASE_ADDR 0xe0000000*/
#define LOCAL_BUS_PHYS_ADDR 0xe0005000
#define LOCAL_BUS_SIZE (64 * 1024 * 1024)
#define LBLAWBAR2 0x0030
#define LBLAWAR2 0x0034
#define LBLAWBAR3 0x0038
#define LBLAWAR3 0x003C
/* BR - Base Registers
*/
#define BR0 0x5000 /* Register offset to immr */
#define BR1 0x5008
#define BR2 0x5010
#define BR3 0x5018
#define BR4 0x5020
#define BR5 0x5028
#define BR6 0x5030
#define BR7 0x5038
/* OR - Option Registers
*/
#define OR0 0x5004 /* Register offset to immr */
#define OR1 0x500C
#define OR2 0x5014
#define OR3 0x501C
#define OR4 0x5024
#define OR5 0x502C
#define OR6 0x5034
#define OR7 0x503C
static unsigned int upm_data_array[] = {
0x00ff3c00, 0x00ff3c00, 0x00ff3c00, 0x00ff3c00, //Words 0 to 3
0x00ff3c00, 0x00ff3c00, 0x00ff3c00, 0x00ff7c05, //Words 4 to 7
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 8 to 11
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 12 to 15
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 16 to 19
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, //Words 20 to 23
0x00fffc00, 0x00fffc00, 0x00fffc00, 0x00fffc04, //Words 24 to 27
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, //Words 28 to 31
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 32 to 35
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 36 to 39
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 40 to 43
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, //Words 44 to 47
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 48 to 51
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 52 to 55
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, //Words 56 to 59
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01 //Words 60 to 63
};
// MPC83**E UPM setup code on CS3 and CS4.
/*----------------------------------------------------------------------------------------------------------------------------------*/
static struct file_operations fops = {
.owner= THIS_MODULE,
//.read= driver_read,
//.open= driver_open,
//.release= driver_close,
};
static int __init mod_init(void)
{
int ret = 0;
static u32 __iomem *adr1;
static u32 __iomem *adr2;
u32 size;
int i;
struct device_node *np;
struct resource r;
printk("driver_init called\n");
ret = register_chrdev(DRIVER_MAJOR,DRIVER_NAME,&fops);
if( ret != 0 ) {
printk("register_chrdev failed!\n");
return -EIO;
}
printk(KERN_NOTICE "Attempting to connect to MPC83XX Local Bus via UPM\n");
if ((np = of_find_node_by_type(NULL, "soc")) == NULL) {
printk(KERN_INFO "%s: No SOC node in device tree\n", __FUNCTION__);
return -EPERM;
}
memset(&r, 0, sizeof(r));
if (of_address_to_resource(np, 0, &r)) {
printk(KERN_INFO "%s: No SOC reg property in device tree\n", __FUNCTION__);
return -EPERM;
}
request_mem_region(MBAR_BASE, LOCAL_BUS_SIZE, DRIVER_NAME);
size = r.end - r.start;
printk(KERN_INFO "%s: r.start: 0x%x; r.end: 0x%x; size: %x\n", __FUNCTION__, r.start, r.end, size);
immrbar2 = ioremap(MBAR_BASE, LOCAL_BUS_SIZE);
printk(KERN_INFO "%s: immrbar2 to: 0x%04x; size: %d\n", __FUNCTION__, immrbar2, LOCAL_BUS_SIZE);
/*----------------------------------------------------------------------------------------------*/
adr1 = immrbar2;
adr2 = immrbar2;
adr1 = immrbar2 + LBLAWBAR2;
printk(KERN_INFO "%s: adr1: 0x%x;\n", __FUNCTION__, &adr1);
out_be32(&adr1, CFG_FPGA1_BASE);
adr2 = immrbar2 + LBLAWAR2;
printk(KERN_INFO "%s: adr2: 0x%x;\n", __FUNCTION__, &adr2);
out_be32(&adr2, 0x8000000E);
udelay(1000);
adr1 = immrbar2 + BR2;
printk(KERN_INFO "%s: adr1: 0x%x;\n", __FUNCTION__, &adr1);
out_be32(&adr1, CFG_FPGA1_BASE | 0x1881);
adr2 = immrbar2 + OR2;
printk(KERN_INFO "%s: adr2: 0x%x;\n", __FUNCTION__, &adr2);
out_be32(&adr2, 0xFFFF8000);
eieio();
udelay(1000);
adr1 = immrbar2 + LBLAWBAR2;
adr2 = immrbar2 + LBLAWAR2;
printk(KERN_INFO "%s: LBLAWBAR2: 0x%x; LBLAWAR2: 0x%x;\n", __FUNCTION__, in_be32(&adr1), in_be32(&adr2));
adr1 = immrbar2 + BR2;
adr2 = immrbar2 + OR2;
printk(KERN_INFO "%s: BR2: 0x%x; OR2: 0x%x;\n", __FUNCTION__, in_be32(&adr1), in_be32(&adr2));
adr1 = 0xe0005070; /*OP set to write to RAM array command MAMR*/
out_be32(&adr1, 0x10000000);
adr2 = 0xe0005088; /*UPM Data Register MDR*/
eieio();
udelay(1000);
/* Write word to RAM arrays */
for(i=0; i<64; i++)
{
out_be32(&adr2, upm_data_array[i]); /* UPM Data Register */
eieio();
};
udelay(1);
out_be32(&adr1, 0x00000000); /* UPMA Mode Register */
eieio();
udelay(1000);
printk(KERN_INFO "%s: MAMR: 0x%x; UPM: 0x%x;\n", __FUNCTION__, in_be32(&adr1), in_be32(&adr2));
printk(KERN_NOTICE "Connected to MPC83XX Local Bus via UPM\n");
//request_mem_region(MBAR_BASE, LOCAL_BUS_SIZE, DRIVER_NAME);
//p_local_bus = ioremap_nocache(CFG_FPGA2_BASE, 0x8000);
/*----------------------------------------------------------------------------------------------*/
return 0;
}
/*----------------------------------------------------------------------------------------------------------------------------------*/
static void __exit mod_exit(void)
{
printk("driver_exit called\n");
iounmap(p_local_bus);
iounmap(immrbar2);
unregister_chrdev(DRIVER_MAJOR,DRIVER_NAME);
}
module_init(mod_init);
module_exit(mod_exit);
MODULE_AUTHOR("none");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A generic local bus access device");
MODULE_SUPPORTED_DEVICE("none");
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <asm/prom.h>
#include <asm-powerpc/io.h>
#include <asm-powerpc/qe.h>
#define DRIVER_NAME "LocalBus"
#define DRIVER_MAJOR 242
static volatile u32 __iomem *p_local_bus;
static volatile u32 __iomem *immrbar2;
//***here FPGA1 base address is defined on LB (the same as FPGA base address in previous project)
#define CFG_FPGA1_BASE 0xF0000000
//***here FPGA2 base address is defined on LB (=FPGA1 base address + 512KB)
#define CFG_FPGA2_BASE 0xF0080000
#define IMMRBAR_BASE_ADDR 0xe0000000
#define MBAR_BASE IMMRBAR_BASE_ADDR /* #define IMMRBAR_BASE_ADDR 0xe0000000*/
#define LOCAL_BUS_PHYS_ADDR 0xe0005000
#define LOCAL_BUS_SIZE (64 * 1024 * 1024)
#define LBLAWBAR2 0x0030
#define LBLAWAR2 0x0034
#define LBLAWBAR3 0x0038
#define LBLAWAR3 0x003C
/* BR - Base Registers
*/
#define BR0 0x5000 /* Register offset to immr */
#define BR1 0x5008
#define BR2 0x5010
#define BR3 0x5018
#define BR4 0x5020
#define BR5 0x5028
#define BR6 0x5030
#define BR7 0x5038
/* OR - Option Registers
*/
#define OR0 0x5004 /* Register offset to immr */
#define OR1 0x500C
#define OR2 0x5014
#define OR3 0x501C
#define OR4 0x5024
#define OR5 0x502C
#define OR6 0x5034
#define OR7 0x503C
static unsigned int upm_data_array[] = {
0x00ff3c00, 0x00ff3c00, 0x00ff3c00, 0x00ff3c00, //Words 0 to 3
0x00ff3c00, 0x00ff3c00, 0x00ff3c00, 0x00ff7c05, //Words 4 to 7
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 8 to 11
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 12 to 15
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 16 to 19
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, //Words 20 to 23
0x00fffc00, 0x00fffc00, 0x00fffc00, 0x00fffc04, //Words 24 to 27
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, //Words 28 to 31
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 32 to 35
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 36 to 39
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 40 to 43
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, //Words 44 to 47
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 48 to 51
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, //Words 52 to 55
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, //Words 56 to 59
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01 //Words 60 to 63
};
// MPC83**E UPM setup code on CS3 and CS4.
/*----------------------------------------------------------------------------------------------------------------------------------*/
static struct file_operations fops = {
.owner= THIS_MODULE,
//.read= driver_read,
//.open= driver_open,
//.release= driver_close,
};
static int __init mod_init(void)
{
int ret = 0;
static u32 __iomem *adr1;
static u32 __iomem *adr2;
u32 size;
int i;
struct device_node *np;
struct resource r;
printk("driver_init called\n");
ret = register_chrdev(DRIVER_MAJOR,DRIVER_NAME,&fops);
if( ret != 0 ) {
printk("register_chrdev failed!\n");
return -EIO;
}
printk(KERN_NOTICE "Attempting to connect to MPC83XX Local Bus via UPM\n");
if ((np = of_find_node_by_type(NULL, "soc")) == NULL) {
printk(KERN_INFO "%s: No SOC node in device tree\n", __FUNCTION__);
return -EPERM;
}
memset(&r, 0, sizeof(r));
if (of_address_to_resource(np, 0, &r)) {
printk(KERN_INFO "%s: No SOC reg property in device tree\n", __FUNCTION__);
return -EPERM;
}
request_mem_region(MBAR_BASE, LOCAL_BUS_SIZE, DRIVER_NAME);
size = r.end - r.start;
printk(KERN_INFO "%s: r.start: 0x%x; r.end: 0x%x; size: %x\n", __FUNCTION__, r.start, r.end, size);
immrbar2 = ioremap(MBAR_BASE, LOCAL_BUS_SIZE);
printk(KERN_INFO "%s: immrbar2 to: 0x%04x; size: %d\n", __FUNCTION__, immrbar2, LOCAL_BUS_SIZE);
/*----------------------------------------------------------------------------------------------*/
adr1 = immrbar2;
adr2 = immrbar2;
adr1 = immrbar2 + LBLAWBAR2;
printk(KERN_INFO "%s: adr1: 0x%x;\n", __FUNCTION__, &adr1);
out_be32(&adr1, CFG_FPGA1_BASE);
adr2 = immrbar2 + LBLAWAR2;
printk(KERN_INFO "%s: adr2: 0x%x;\n", __FUNCTION__, &adr2);
out_be32(&adr2, 0x8000000E);
udelay(1000);
adr1 = immrbar2 + BR2;
printk(KERN_INFO "%s: adr1: 0x%x;\n", __FUNCTION__, &adr1);
out_be32(&adr1, CFG_FPGA1_BASE | 0x1881);
adr2 = immrbar2 + OR2;
printk(KERN_INFO "%s: adr2: 0x%x;\n", __FUNCTION__, &adr2);
out_be32(&adr2, 0xFFFF8000);
eieio();
udelay(1000);
adr1 = immrbar2 + LBLAWBAR2;
adr2 = immrbar2 + LBLAWAR2;
printk(KERN_INFO "%s: LBLAWBAR2: 0x%x; LBLAWAR2: 0x%x;\n", __FUNCTION__, in_be32(&adr1), in_be32(&adr2));
adr1 = immrbar2 + BR2;
adr2 = immrbar2 + OR2;
printk(KERN_INFO "%s: BR2: 0x%x; OR2: 0x%x;\n", __FUNCTION__, in_be32(&adr1), in_be32(&adr2));
adr1 = 0xe0005070; /*OP set to write to RAM array command MAMR*/
out_be32(&adr1, 0x10000000);
adr2 = 0xe0005088; /*UPM Data Register MDR*/
eieio();
udelay(1000);
/* Write word to RAM arrays */
for(i=0; i<64; i++)
{
out_be32(&adr2, upm_data_array[i]); /* UPM Data Register */
eieio();
};
udelay(1);
out_be32(&adr1, 0x00000000); /* UPMA Mode Register */
eieio();
udelay(1000);
printk(KERN_INFO "%s: MAMR: 0x%x; UPM: 0x%x;\n", __FUNCTION__, in_be32(&adr1), in_be32(&adr2));
printk(KERN_NOTICE "Connected to MPC83XX Local Bus via UPM\n");
//request_mem_region(MBAR_BASE, LOCAL_BUS_SIZE, DRIVER_NAME);
//p_local_bus = ioremap_nocache(CFG_FPGA2_BASE, 0x8000);
/*----------------------------------------------------------------------------------------------*/
return 0;
}
/*----------------------------------------------------------------------------------------------------------------------------------*/
static void __exit mod_exit(void)
{
printk("driver_exit called\n");
iounmap(p_local_bus);
iounmap(immrbar2);
unregister_chrdev(DRIVER_MAJOR,DRIVER_NAME);
}
module_init(mod_init);
module_exit(mod_exit);
MODULE_AUTHOR("none");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A generic local bus access device");
MODULE_SUPPORTED_DEVICE("none");
и при выводе комментариев получаю не верные данные!(((( или при использовании in_be32(adr1) получаю линуховую ошибку доступа к памяти!
Помогите кто уже с таким сталкивался как побороть!
Спасибо!