|
|
|
Модуль обращения к LocalBus, MPC8377 |
|
|
|
Dec 20 2011, 10:34
|
Группа: Участник
Сообщений: 13
Регистрация: 20-12-11
Пользователь №: 68 986
|
Здравствуйте уважаемые Знатоки! Прошу вашей помощи! только познакомился с продукцией Freecale, а именно с процессором MPC8377. и пытаюсь написать модуль доступа к LocalBus, возникла ошибка: Цитата Kernle: module startup... Kernel: Device registered. Major number is 252 Kernel: mmio =0xd1064000 Machine check in kernel mode. Caused by (from SRR1=49030): Transfer error ack signal Oops: Machine check, sig: 7 [#1] MPC837x RDB Modules linked in: LocalBus(+) [last unloaded: LocalBus] NIP: d1084118 LR: d10840f8 CTR: c0208f24 REGS: cfba5dc0 TRAP: 0200 Not tainted (2.6.25) MSR: 00049030 <EE,ME,IR,DR> CR: 24004428 XER: 00000000 TASK = cf8b4810[1442] 'insmod' THREAD: cfba4000 GPR00: 00000001 cfba5e70 cf8b4810 d1084338 00000000 ffffffff c020c048 00004000 GPR08: 00000034 d1064000 00001ca1 d1002500 24004422 10018d88 0000001d d108246c GPR16: cf9feb80 d1079254 00000000 0000002d 0000002d d1078cad c003dd7c d1064000 GPR24: 0000001f 0000001f d1078dcc d1084960 00000000 d1084960 cfb34800 d1080000 NIP [d1084118] _init_module+0x9c/0x174 [LocalBus] LR [d10840f8] _init_module+0x7c/0x174 [LocalBus] Call Trace: [cfba5e70] [d10840f8] _init_module+0x7c/0x174 [LocalBus] (unreliable) [cfba5e80] [c003e6f4] sys_init_module+0x130/0x17b8 [cfba5f40] [c000f70c] ret_from_syscall+0x0/0x38 --- Exception: c01 at 0xff6f218 LR = 0x10000950 Instruction dump: 386342e0 7c040378 901f4ae4 4800009d 813f4ae4 2f890000 419e0074 38000001 3c60d108 98090010 38634338 88890001 <48000079> 813f4ae4 3c60d108 38634344 ---[ end trace 8933fae98ac0b4a5 ]--- Bus error объясняли, что необходимо еще сделать некоторые операции по настройке чипселектов, до меня не дошло! Кто сталкивался с такой штукой подскажите что и как?! Модуль выглядит так: Код #define MODULE #define __KERNEL__
//#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/errno.h> #include <linux/slab.h> #include <linux/stddef.h> #include <linux/interrupt.h> #include <linux/err.h> #include <linux/module.h> #include <linux/of.h> #include <linux/proc_fs.h>
#include <asm/io.h> #include <asm/immap_qe.h> #include <asm/qe.h>
#define DEV_NAME "my_dev"
#define _MBAR_BASE 0xe0000000
#define _CS0_BASE 0xf0000000 #define _CS0_COUNT 0x30
#define _OR0_CFG_VAL 0xFFF00000
#define SUCCESS 0
static int major; struct file_operations fops; int _immr_pa;
//unsigned volatile char *mmio; byte *mmio; //__be32 __iomem *reg_map;
int _init_module(void ) { printk("Kernle: module startup...\n"); major = register_chrdev(0, DEV_NAME, &fops); if (major < 0) { // Проверка успешности регистрации printk("Kernel: Register failed\n"); return major; }; printk("Kernel: Device registered. Major number is %d\n",major);
if(!request_mem_region(_CS0_BASE/*базовый адрес*/, _CS0_COUNT/*размер*/, DEV_NAME)); { //тут ругаемся на то, что ядро не дает память printk("Kernel: request_mem_region"); return 0; };
//reg_map = ioremap_nocache(_CS0_BASE/*базовый адрес*/, _CS0_COUNT/*размер*/); mmio = (byte*)ioremap(_CS0_BASE/*базовый адрес*/, _CS0_COUNT/*размер*/); printk ("Kernel: mmio =0x%p\n", mmio);
if (mmio == NULL) { printk ("Kernel: Could not map base registers at beggining of address=0x%X\n", _CS0_BASE); return -ENOMEM; }; unsigned int val = 0;
mmio[0x10] = 1; /*пишем по адресу*/ printk("Write 0x%p\n", mmio[0x01]);
val = mmio[0x10]; printk("Read %d\n", val);
iounmap(mmio); }
void _stop_module() { // Снимаем захват памяти release_mem_region(_CS0_BASE, _CS0_COUNT); printk("Kernel: release memio ports\n"); // Снимаем регистрацию устройства if (unregister_chrdev(major, DEV_NAME) < 0){ printk("Kernel: unregister device failed\n"); }; printk("Kernel: device unregistered\n"); printk("Kernel: module3 is dead \n"); return; }
module_init(_init_module); module_exit(_stop_module);
MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Driver CS"); Спасибо!!!
|
|
|
|
|
Dec 22 2011, 05:25
|
Участник
Группа: Участник
Сообщений: 54
Регистрация: 10-10-07
Из: Новосибирск
Пользователь №: 31 240
|
Ну да, по-хорошему нада бы еще че-то с железом поделать, т.е. если это LCS[0], то надо прописать регистры BR0 и OR0. Плюс не забыть сделать local bus window в регистрах LBLAWBAR и LBLAWAR
"Transfer error ack" это софт попытался полезть по адресу, который не назначен ни на один из мем контролеров, и не получил transfer acknowledge в положенное время.
|
|
|
|
|
Dec 23 2011, 10:50
|
Группа: Участник
Сообщений: 13
Регистрация: 20-12-11
Пользователь №: 68 986
|
Спасибо!!! Делаю драйвер через символьное устройство, нашел подходящий файл структур: immap_83xx.h, и вот теперь опять вопрос возникнул, как правильно заполнить эти структуры: пробую так, но чет делаю не то: Код // MPC83**E UPM setup code on CS3.
//***here FPGA1 base address is defined on LB (the same as FPGA base address in previous project)
#define CFG_FPGA1_BASE 0xF0000000
#define MBAR_BASE IMMRBAR_BASE_ADDR /* #define IMMRBAR_BASE_ADDR 0xe0000000*/
#define LOCAL_BUS_PHYS_ADDR 0xe0005000
#define LOCAL_BUS_SIZE (64 * 1024 * 1024) ....
// MPC83**E UPM setup code on CS3. int mpc83xx_local_bus_upm_setup(void)
{
unsigned i;
volatile immap_t *immrmap;
printk("mpc83xx_local_bus_upm_setup...\n");
immrmap = immrbar2;
printk(KERN_INFO "%s: immrmap->sysconf.immrbar %08x\n", __FUNCTION__, (unsigned int)immrmap->sysconf.immrbar);
//immrmap->sysconf.immrbar = MBAR_BASE; /* Internal memory map base address register */
immrmap->sysconf.lblaw[2].bar = CFG_FPGA1_BASE; // присвоение физического устройства... /* LBIU local access window base address register */
immrmap->sysconf.lblaw[2].ar = 0x8000000E; //0x80000019; // 64MB /* LBIU local access window attribute register */
immrmap->lbus.bank[4].br = LOCAL_BUS_PHYS_ADDR | 0x19c1; // 32-bit, no crc check, read-only, UPMA /* Base Register */
immrmap->lbus.bank[4].or = 0xfc000001; // 64MB, /* Option Register */
immrmap->lbus.mamr = 0x10000000; /* UPMA Mode Register */
printk(KERN_INFO "%s: immrmap->lbus.mamr %08x\n", __FUNCTION__, (unsigned int)immrmap->lbus.mamr);
eieio();
udelay(1);
// Write word to RAM arrays
for(i=0; i<64; i++)
{
immrmap->lbus.mdr = upm_data_array;/* UPM Data Register */
eieio();
}
udelay(1);
immrmap->lbus.mamr = 0x0; /* UPMA Mode Register */
eieio();
udelay(1000);
return i;
} обьясните: в файле immap_83xx.h есть структура : Код typedef struct lbus_bank { u32 br; /* Base Register */ u32 or; /* Option Register */ } lbus_bank_t; ... lbus_bank_t bank[8]; что она делает и что туда писать?
|
|
|
|
|
Dec 23 2011, 17:54
|
Группа: Участник
Сообщений: 13
Регистрация: 20-12-11
Пользователь №: 68 986
|
а и столкнулся с такой какой как mmu, что с ней делать? как ее проинициализировать?
|
|
|
|
|
Dec 24 2011, 16:22
|
Группа: Участник
Сообщений: 13
Регистрация: 20-12-11
Пользователь №: 68 986
|
посидев в гугле и с книгами выкрутил модуль, но в нем есть ошибка - не хочет писать и читать или даже не так эти операции проходят не верно при тестировании (test_FPGA1_64regs()), не пойму какая, а можит с инициализациией накрутил (mpc83xx_local_bus_upm_setup()), ПОМОГИТЕ найти: Код #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/immap_83xx.h>
#include <asm-powerpc/io.h> #include <asm-powerpc/qe.h>
#define DRIVER_NAME "LocalBus" #define DRIVER_MAJOR 242
static volatile __be32 __iomem *p_local_bus; static volatile immap_t *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 MBAR_BASE IMMRBAR_BASE_ADDR /* #define IMMRBAR_BASE_ADDR 0xe0000000*/
#define LOCAL_BUS_PHYS_ADDR 0xe0005000 #define LOCAL_BUS_SIZE (64 * 1024 * 1024)
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. int mpc83xx_local_bus_upm_setup(void) { unsigned i; volatile immap_t *immrmap;
printk("mpc83xx_local_bus_upm_setup...\n"); immrmap = immrbar2; printk(KERN_INFO "%s: immrmap->sysconf.immrbar %08x\n", __FUNCTION__, (unsigned int)immrmap->sysconf.immrbar); //immrmap->sysconf.immrbar = MBAR_BASE; /* Internal memory map base address register */ immrmap->sysconf.lblaw[2].bar = CFG_FPGA1_BASE; // присвоение физического устройства... /* LBIU local access window base address register */ immrmap->sysconf.lblaw[2].ar = 0x8000000E; //0x80000019; // 64MB /* LBIU local access window attribute register */ immrmap->sysconf.lblaw[3].bar = CFG_FPGA2_BASE; // присвоение физического устройства... /* LBIU local access window base address register */ immrmap->sysconf.lblaw[3].ar = 0x8000000E; //0x80000019; // 64MB /* LBIU local access window attribute register */ //*** Base Adress of the FPGA1; 32bit port; UPMA; "V=>This bank is valid." immrmap->lbus.bank[2].br = CFG_FPGA1_BASE | 0x1881; // 32-bit, no crc check, read-only, UPMA /* Base Register */ //*** 32KB; EHTR(?); EAD(?); <-two attribute bits from old project immrmap->lbus.bank[2].or = 0xFFFF8000; /* Option Register */ //*** Base Adress of the FPGA2; 32bit port; UPMA; "V=>This bank is valid." immrmap->lbus.bank[3].br = CFG_FPGA2_BASE | 0x1881; // 32-bit, no crc check, read-only, UPMA /* Base Register */ //*** 32KB; EHTR(?); EAD(?); <-two attribute bits from old project immrmap->lbus.bank[3].or = 0xFFFF8000; /* Option Register */
immrmap->lbus.mamr = 0x10000000; /* UPMA Mode Register */ eieio(); udelay(1); // Write word to RAM arrays for(i=0; i<64; i++) { immrmap->lbus.mdr = upm_data_array[i]; /* UPM Data Register */ eieio(); } udelay(1); immrmap->lbus.mamr = 0x00000000; /* UPMA Mode Register */ eieio(); udelay(1000); return i; }
int test_driver_open(void) { int i; printk("driver_open called\n"); for(i = 0; i < 4; i++) { printk(KERN_INFO "%s: immrmap->sysconf.lblaw[%d].bar %08x\n", __FUNCTION__, i, (unsigned int)immrbar2->sysconf.lblaw[i].bar); //tbdrow printk(KERN_INFO "%s: immrmap->sysconf.lblaw[%d].ar %08x\n", __FUNCTION__, i, (unsigned int)immrbar2->sysconf.lblaw[i].ar); //tbdrow } for(i = 0; i < 8; i++) { printk(KERN_INFO "%s: immrmap->lbus.bank[%d].br %08x\n", __FUNCTION__, i, (unsigned int)immrbar2->lbus.bank[i].br); //tbdrow printk(KERN_INFO "%s: immrmap->lbus.bank[%d].or %08x\n", __FUNCTION__, i, (unsigned int)immrbar2->lbus.bank[i].or); //tbdrow }
printk(KERN_INFO "%s: immrmap->lbus.mamr %08x\n", __FUNCTION__, (unsigned int)immrbar2->lbus.mamr); //tbdrow printk(KERN_INFO "%s: immrmap->lbus.lbcr %08x\n", __FUNCTION__, (unsigned int)immrbar2->lbus.lbcr); //tbdrow request_mem_region(LOCAL_BUS_PHYS_ADDR, LOCAL_BUS_SIZE, DRIVER_NAME); /* remap the Local Bus data address */ // p_local_bus = ioremap_nocache(LOCAL_BUS_PHYS_ADDR, LOCAL_BUS_SIZE); p_local_bus = ioremap_nocache(CFG_FPGA1_BASE, 8000);
return 0; }
int test_driver_close(void) { printk("driver_close called\n"); /* Unmap */ //release_mem_region(LOCAL_BUS_PHYS_ADDR, LOCAL_BUS_SIZE); //iounmap ((void *)p_local_bus); iounmap((void *)p_local_bus); release_mem_region(LOCAL_BUS_PHYS_ADDR, LOCAL_BUS_SIZE);
return 0; }
/*----------------------------------------------------------------------------------------------------------------------------------*/ void test_FPGA1_64regs(void) { u32 tempFPGA_wr=0, tempFPGA_rd=0; u32 i=0, j=0; volatile __be32 __iomem *_adr; for(j=0; j<64;j++) //*** ADDRESS test { //***write 4 hi-bits of address to FPGA1 (address of FPGA's AddressRegister on LB =0xF000001C) //*(u32*)(CFG_FPGA1_BASE | 0x1C) = (j<<2)&0xF0; _adr = p_local_bus + 0x1C; out_be32(_adr, (j<<2)&0xF0); i = ((j <<2) & 0xC); //*(u32*)(CFG_FPGA1_BASE | i ) = i; _adr = p_local_bus + i; out_be32(_adr, i); //tempFPGA_rd=*(u32*)(CFG_FPGA1_BASE | i ); tempFPGA_rd = in_be32(_adr); eieio(); if( tempFPGA_rd != i ) printk("FPGA1:[%d] WriteCode = %04x ReadCode = %04x \r\n", j, i, tempFPGA_rd); }
tempFPGA_wr=0; //additional operator for looking the content of tempFPGA1_rd at the screen
iounmap(_adr); } /*----------------------------------------------------------------------------------------------------------------------------------*/
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; int lburet = -1; 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; }
immrbar2 = ioremap_nocache(r.start, sizeof(*immrbar2));
/*------------ MPC83**E UPM setup code on CS3 and CS4 ---------------------------------------*/ lburet = mpc83xx_local_bus_upm_setup(); printk(KERN_INFO "%s: local_bus_upm_ret: %#08x\n", __FUNCTION__, lburet); printk(KERN_NOTICE "Connected to MPC83XX Local Bus via UPM\n"); /*----------------------------------------------------------------------------------------------*/ printk(KERN_NOTICE "TEST...\n"); test_driver_open(); test_FPGA1_64regs();// test_driver_close(); return 0; }
static void __exit mod_exit(void) { printk("driver_exit called\n"); 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"); Спасибо!
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|