From: Masahiro A. <m-...@aa...> - 2001-06-09 08:35:54
|
Hi all, I'm porting linux-sh to our SH4(7750S) based system, and found that current kernel may not support CompactFlash connected to SH4 CPU directly. On SH4, PCMCIA interface can't be accessed through P1/2/4 area. Following Sugioka-san's and Sakawa-san's suggestions, I've tried to add support for that, and assembled following patch. This is loosely excerpted code from Mr. Greg Banks' hd65545_ss.c. I tried to make this patch as generic as possible so that it can be used on other machines. First two hunk and if block of third hunk of config.in is for adding support for our board, and not needed for this support. Please ignore that part. I don't want to touch linux/mm/memory.c but couldn't come up with better idea than this. With this change, I could boot our machine from directly connected CompactFlash (somehow it MUST be SanDisk CF. Other CF don't work properly yet). I appreciate all comments on this. I wish this change(with all of your comments applied) will get merged into future kernel. --------------------------------------------------------------------- diff -ruN linux-2.4.4-sh.orig/arch/sh/config.in linux-2.4.4-adx/arch/sh/config.in --- linux-2.4.4-sh.orig/arch/sh/config.in Thu May 3 15:00:35 2001 +++ linux-2.4.4-adx/arch/sh/config.in Sat Jun 9 16:32:35 2001 @@ -38,6 +38,7 @@ DMIDA CONFIG_SH_DMIDA \ EC3104 CONFIG_SH_EC3104 \ Dreamcast CONFIG_SH_DREAMCAST \ + A&D-ADX CONFIG_SH_ADX \ BareCPU CONFIG_SH_UNKNOWN" Generic define_bool CONFIG_SH_RTC y @@ -73,7 +74,11 @@ "$CONFIG_SH_OVERDRIVE" = "y" ]; then define_hex CONFIG_MEMORY_START 0c000000 else + if [ "$CONFIG_SH_ADX" = "y" ]; then + define_hex CONFIG_MEMORY_START 08000000 + else hex 'Physical memory start address' CONFIG_MEMORY_START 08000000 + fi fi endmenu @@ -90,8 +95,21 @@ bool 'Networking support' CONFIG_NET -if [ "$CONFIG_SH_GENERIC" = "y" -o "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o "$CONFIG_SH_UNKNOWN" = "y" ]; then +if [ "$CONFIG_SH_GENERIC" = "y" -o "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o \ + "$CONFIG_SH_ADX" = "y" -o "$CONFIG_SH_UNKNOWN" = "y" ]; then bool 'Compact Flash Enabler support' CONFIG_CF_ENABLER +fi + +if [ "$CONFIG_CF_ENABLER" = "y" ]; then + choice 'Compact Flash Area' \ + "Area5(H'b4000000) CONFIG_CF_AREA5 \ + Area6(H'b8000000) CONFIG_CF_AREA6" Area6(H'b8000000) + if [ "$CONFIG_CF_AREA5" = "y" ]; then + define_hex CONFIG_CF_BASE_ADDR b4000000 + fi + if [ "$CONFIG_CF_AREA6" = "y" ]; then + define_hex CONFIG_CF_BASE_ADDR b8000000 + fi fi bool 'Hitachi HD64461 companion chip support' CONFIG_HD64461 diff -ruN linux-2.4.4-sh.orig/arch/sh/kernel/cf-enabler.c linux-2.4.4-adx/arch/sh/kernel/cf-enabler.c --- linux-2.4.4-sh.orig/arch/sh/kernel/cf-enabler.c Thu May 3 14:33:25 2001 +++ linux-2.4.4-adx/arch/sh/kernel/cf-enabler.c Sat Jun 9 16:28:06 2001 @@ -14,7 +14,8 @@ #include <asm/io.h> #include <asm/irq.h> -#define CF_CIS_BASE 0xb8000000 +/* this must be done in boot-loader - Masahiro Abe +#define CF_CIS_BASE 0xb8000000 */ /* * You can connect Compact Flash directly to the bus of SuperH. * This is the enabler for that. @@ -29,12 +30,54 @@ * 0xB8001000 : Common Memory * 0xBA000000 : I/O */ +#if defined(CONFIG_IDE) && defined(__SH4__) +/* SH4 can't access PCMCIA interface through P2 area. + * we must remap it with appropreate attribute bit of the page set. + * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */ +#include <linux/mm.h> +#include <linux/vmalloc.h> + +#if defined(CONFIG_CF_AREA6) +#define slot_no 0 +#else +#define slot_no 1 +#endif + +struct vm_struct *cf_io_vma; + +static int allocate_cf_area(void) +{ + pgprot_t prot; + unsigned long paddrbase, vaddrbase, psize; + +/* open I/O area window */ + psize = PAGE_SIZE; + if ((cf_io_vma = get_vm_area(psize, VM_IOREMAP)) == 0) { + printk("allocate_cf_area : can't open CF I/O window!\n"); + return -ENOMEM; + } + vaddrbase = (unsigned long)cf_io_vma->addr; + paddrbase = virt_to_phys((void*)CONFIG_CF_BASE_ADDR); + prot = PAGE_KERNEL_PCC(slot_no, _PAGE_PCC_IO16); +/* printk("remap_page_range(vaddr=0x%08lx, paddr=0x%08lx, psize=0x08lx, prot=0x%08lx)\n", + vaddrbase, paddrbase, psize, prot.pgprot);*/ + remap_page_range(vaddrbase, paddrbase, psize, prot); + + /* XXX : do we need attribute and common-memory area also? */ + + return 0; +} +#endif static int __init cf_init_default(void) { #ifdef CONFIG_IDE +#if defined(CONFIG_IDE) && defined(__SH4__) + allocate_cf_area(); +#endif /* Enable the card, and set the level interrupt */ - ctrl_outw(0x0042, CF_CIS_BASE+0x0200); +/* this must be done in boot-loader - Masahiro Abe + ctrl_outw(0x0042, CF_CIS_BASE+0x0200);*/ #endif make_imask_irq(14); disable_irq(14); diff -ruN linux-2.4.4-sh.orig/mm/memory.c linux-2.4.4-adx/mm/memory.c --- linux-2.4.4-sh.orig/mm/memory.c Thu May 3 14:33:18 2001 +++ linux-2.4.4-adx/mm/memory.c Sat Jun 9 15:55:26 2001 @@ -821,6 +821,11 @@ unsigned long end = from + size; struct mm_struct *mm = current->mm; +#if defined(__sh__) && defined(CONFIG_IDE) && defined(__SH4__) + if (from >= VMALLOC_START && from < VMALLOC_END) + mm = &init_mm; +#endif + phys_addr -= from; dir = pgd_offset(mm, from); flush_cache_range(mm, beg, end); --------------------------------------------------------------------- +-------------------------------------+ | Masahiro Abe, Software Engineer | | A&D Co., Ltd. of Tokyo, Japan | | mailto:m-...@aa... | +-------------------------------------+ |This is my opinion, not my employer's| +-------------------------------------+ |