You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
(12) |
May
(82) |
Jun
(72) |
Jul
(39) |
Aug
(104) |
Sep
(61) |
Oct
(55) |
Nov
(101) |
Dec
(48) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(52) |
Feb
(67) |
Mar
(18) |
Apr
(16) |
May
(33) |
Jun
(12) |
Jul
(102) |
Aug
(168) |
Sep
(65) |
Oct
(60) |
Nov
(43) |
Dec
(121) |
2002 |
Jan
(69) |
Feb
(32) |
Mar
(90) |
Apr
(59) |
May
(45) |
Jun
(43) |
Jul
(33) |
Aug
(21) |
Sep
(11) |
Oct
(20) |
Nov
(26) |
Dec
(3) |
2003 |
Jan
(12) |
Feb
(18) |
Mar
(11) |
Apr
(11) |
May
(41) |
Jun
(76) |
Jul
(77) |
Aug
(15) |
Sep
(38) |
Oct
(56) |
Nov
(19) |
Dec
(39) |
2004 |
Jan
(17) |
Feb
(52) |
Mar
(36) |
Apr
(34) |
May
(48) |
Jun
(85) |
Jul
(38) |
Aug
(42) |
Sep
(41) |
Oct
(77) |
Nov
(27) |
Dec
(19) |
2005 |
Jan
(32) |
Feb
(35) |
Mar
(29) |
Apr
(8) |
May
(7) |
Jun
(31) |
Jul
(46) |
Aug
(93) |
Sep
(65) |
Oct
(85) |
Nov
(219) |
Dec
(47) |
2006 |
Jan
(170) |
Feb
(103) |
Mar
(49) |
Apr
(43) |
May
(45) |
Jun
(29) |
Jul
(77) |
Aug
(82) |
Sep
(43) |
Oct
(45) |
Nov
(26) |
Dec
(85) |
2007 |
Jan
(42) |
Feb
(48) |
Mar
(64) |
Apr
(31) |
May
(88) |
Jun
(53) |
Jul
(175) |
Aug
(212) |
Sep
(91) |
Oct
(103) |
Nov
(110) |
Dec
(5) |
2008 |
Jan
(20) |
Feb
(11) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(5) |
Sep
(3) |
Oct
(12) |
Nov
|
Dec
|
From: <bar...@ya...> - 2001-07-04 17:58:00
|
Hi Doug: Thanks for your help, you are a life saver. I went through the following pins and tried different settings. Unfortunately, the address line still does not advance from reset address 0x00000000. >First a couple of questions; > 1. What is the state of /RDY? This pin is pulled high, and sits on high. > 2. What is the state of /MRESET? This pin is also pulled high and sits on high. > 3. What is the state of /TRST? This pin is pulled low. If this pin is pulled high, the CPU stays in reset status. > 4. During power up reset and operation what was >the mode pin settings, and was the correct timing >observed? The mod pins are as followed: MOD0 high MOD1 low MOD2 high (for 6:3:3/2 clock setting) MOD3 high MOD4 low (8 bit for Area 0 - 8 bit Flash memory) MOD5 high little endian MOD6 high normal memory MOD7 high master MOD8 high crystal resonator Orignally, the 1.95 is brought up around 200ms after 3.3V, the reset line becomes high at the same time as the 1.95V. The reset circuit was modified, now, the reset line comes up 150ms after 1.95V is up. > 5. What type of memory and in what configuration >is the memory configured? Area 0 1MB FLASH memory 10MHz (8bit data bus) Area 3 8MB SDRAM 100MHz (32bit data bus) Area 4 512kB SRAM 100MHz (32bit data bus) >Getting the board to read the reset vector is the >first hurdle. The second hurdle with the SH4 is the >proper start timing configuration for DRAM/SDRAM! Is there anything else I should look out for??? I suppose that this can only be a hardware problem (pin settings). Since that bus should read at least 2 8-bit data from the Flash memory before the first instruction is fetched for execution. Is this true?? Thanks again, Mark --- Doug Martens <mar...@sy...> wrote: > First a couple of questions; > 1. What is the state of /RDY? > 2. What is the state of /MRESET? > 3. What is the state of /TRST? > 4. During power up reset and operation what was > the mode pin settings, and was the correct timing > observed? > 5. What type of memory and in what configuration > is the memory configured? > > Getting the board to read the reset vector is the > first hurdle. The second hurdle with the SH4 is the > proper start timing configuration for DRAM/SDRAM! > > Doug Martens > Senior Design Engineer > mar...@sy... > 1000 Waverley St. > Winnipeg, MB, Canada > R3T 0P3 > Symbol Technologies, Winnipeg > Ph: (204) 478-8046 > www.symbol.com > > > >>> Barkuson <bar...@ya...> 07/04/01 08:42AM > >>> > > Hi, > > Firstly, my apologies for sending this mail if this > is > not relevent to the mailing list. However, this is > quite urgent, sorry. Could any hardware people help > me > out please? > > I have a custom Sh4 (SH7750) board which has not > been > able to run :(. Everything looks alright except that > the board boots up and sits at address 0x00000000 > (the > data at this address in the flash memory is on the > data bus). The CPU seems to halt at this point with > the following board status, > > - both main crystal and rtc crystal running > - both status pin at low level > - all NMI and IRL pins pulled up > - BREQ pulled up > - address sits at 0x00000000 and does not increments > - CS0 low > - RD low > - all WE high > > Is there anything else that I should check?? or any > setting that I could be missing?? > > Can anyone direct me to a right place?? > > All helps are greatly appreciated. > > Mark > > > _____________________________________________________________________________ > http://messenger.yahoo.com.au - Yahoo! Messenger > - Voice chat, mail alerts, stock quotes and > favourite news and lots more! > _____________________________________________________________________________ http://messenger.yahoo.com.au - Yahoo! Messenger - Voice chat, mail alerts, stock quotes and favourite news and lots more! |
From: David M. <Dav...@st...> - 2001-07-04 17:09:38
|
On Jul 4, 10:10pm, m-...@aa... wrote: > Subject: [linuxsh-dev] Strange behavior when accessing mmap'd framebuffer > > Hello all, > > Today I would like to get comments/suggestions on my problem, if you > have. I'll really appreciate any info you would provide. > > I'm running custom SH4 machine with LCD controller (Epson s1d13706) with > monochrome LCD, using it as framebuffer device. It can be accessed as > /dev/fb0 now. > When I access mmap'd framebuffer memory area from user program (by > memcpy, for example), sometimes it takes very long time to complete. > Writing (unsigned char)0x00 to the area sometimes took more than 700 > microseconds. Usually it takes just about 10 microseconds. > We have seen exactly this behaviour. It is caused by the TLB handler code (Pre the latest patches). What happens is the dcache aliasing code kicks in, causing all TLB entries to be scanned. As a quick hack, what I did was change the code in update_mmu_cache() to instead of if(pte_shared(pte)) to if(pte_shared(pte) && pte_cacheable(pte)) Dcache aliasing can't happen if the memory is uncached. Anyway, this provided a big performance increase for me. We actually were going to rewrite the whole of the way the dcache aliasing was done, but as usual Niibe beat us to it:-) That's another bug chunk of work gone from our project plan! The latest kernel should fix this problem I think, but I haven't tested it yet, for framebuffer access, although it appears stable to me for other purposes. Hope this helps! -- Dave McKay Software Engineer STMicroelectronics Email: dav...@st... |
From: Dustin M. <du...@se...> - 2001-07-04 16:05:58
|
Hi Mark, I don't know about the SH7750, but the SH7751 has a RDY# pin that forces the processor to stall indefinately waiting for the bus cycle to complete. You may want to check this and make sure it is not asserted (ie make sure it is logic high). There should be and external pullup resistor on this pin as well. Dustin. -----Original Message----- From: lin...@li... [mailto:lin...@li...]On Behalf Of Barkuson Sent: Wednesday, July 04, 2001 6:43 AM To: lin...@m1...; lin...@li... Subject: [linuxsh-dev] SH4 hardware problem Hi, Firstly, my apologies for sending this mail if this is not relevent to the mailing list. However, this is quite urgent, sorry. Could any hardware people help me out please? I have a custom Sh4 (SH7750) board which has not been able to run :(. Everything looks alright except that the board boots up and sits at address 0x00000000 (the data at this address in the flash memory is on the data bus). The CPU seems to halt at this point with the following board status, - both main crystal and rtc crystal running - both status pin at low level - all NMI and IRL pins pulled up - BREQ pulled up - address sits at 0x00000000 and does not increments - CS0 low - RD low - all WE high Is there anything else that I should check?? or any setting that I could be missing?? Can anyone direct me to a right place?? All helps are greatly appreciated. Mark ____________________________________________________________________________ _ http://messenger.yahoo.com.au - Yahoo! Messenger - Voice chat, mail alerts, stock quotes and favourite news and lots more! _______________________________________________ linuxsh-dev mailing list lin...@li... http://lists.sourceforge.net/lists/listinfo/linuxsh-dev |
From: Doug M. <mar...@sy...> - 2001-07-04 14:19:51
|
First a couple of questions; 1. What is the state of /RDY? 2. What is the state of /MRESET? 3. What is the state of /TRST? 4. During power up reset and operation what was the mode pin settings, = and was the correct timing observed? 5. What type of memory and in what configuration is the memory = configured? Getting the board to read the reset vector is the first hurdle. The = second hurdle with the SH4 is the proper start timing configuration for = DRAM/SDRAM! Doug Martens Senior Design Engineer mar...@sy... 1000 Waverley St. Winnipeg, MB, Canada R3T 0P3 Symbol Technologies, Winnipeg Ph: (204) 478-8046 www.symbol.com >>> Barkuson <bar...@ya...> 07/04/01 08:42AM >>> Hi, Firstly, my apologies for sending this mail if this is not relevent to the mailing list. However, this is quite urgent, sorry. Could any hardware people help me out please? I have a custom Sh4 (SH7750) board which has not been able to run :(. Everything looks alright except that the board boots up and sits at address 0x00000000 (the data at this address in the flash memory is on the data bus). The CPU seems to halt at this point with the following board status, - both main crystal and rtc crystal running - both status pin at low level - all NMI and IRL pins pulled up - BREQ pulled up - address sits at 0x00000000 and does not increments - CS0 low=20 - RD low - all WE high Is there anything else that I should check?? or any setting that I could be missing?? Can anyone direct me to a right place?? All helps are greatly appreciated.=20 Mark ___________________________________________________________________________= __ http://messenger.yahoo.com.au - Yahoo! Messenger - Voice chat, mail alerts, stock quotes and favourite news and lots more! |
From: <bar...@ya...> - 2001-07-04 13:42:32
|
Hi, Firstly, my apologies for sending this mail if this is not relevent to the mailing list. However, this is quite urgent, sorry. Could any hardware people help me out please? I have a custom Sh4 (SH7750) board which has not been able to run :(. Everything looks alright except that the board boots up and sits at address 0x00000000 (the data at this address in the flash memory is on the data bus). The CPU seems to halt at this point with the following board status, - both main crystal and rtc crystal running - both status pin at low level - all NMI and IRL pins pulled up - BREQ pulled up - address sits at 0x00000000 and does not increments - CS0 low - RD low - all WE high Is there anything else that I should check?? or any setting that I could be missing?? Can anyone direct me to a right place?? All helps are greatly appreciated. Mark _____________________________________________________________________________ http://messenger.yahoo.com.au - Yahoo! Messenger - Voice chat, mail alerts, stock quotes and favourite news and lots more! |
From: Masahiro A. <m-...@aa...> - 2001-07-04 13:10:32
|
Hello all, Today I would like to get comments/suggestions on my problem, if you have. I'll really appreciate any info you would provide. I'm running custom SH4 machine with LCD controller (Epson s1d13706) with monochrome LCD, using it as framebuffer device. It can be accessed as /dev/fb0 now. When I access mmap'd framebuffer memory area from user program (by memcpy, for example), sometimes it takes very long time to complete. Writing (unsigned char)0x00 to the area sometimes took more than 700 microseconds. Usually it takes just about 10 microseconds. This long period gives bad effect to RTLinux task. RTTask wake-up jitter takes about the same time. Has anybody experienced this kind of behavior, when using framebuffer device, or using mmap call in user program? I would appreciate your any input. Here I summarize what I've found out so far. - Hardware access to the SRAM inside LCD controller completes within a few seconds range. I've confirmed it using oscilloscope. - Writing to the framebuffer memory directly within kernel space won't take such a long time. - redirecting file to /dev/fb0 won't cause this problem - redirecting text to /dev/tty0 (associated with LCD) won't cause this problem - This happens 2 to 3 times per 10000 write. Not often. - Interrupts are not disabled, but RTTask wake-up is delayed. So, I suspect that there might be some exception happening. Unfortunately I have very little knowledge about memory management of linux kernel. So, I can't find out what happens when accessing mmap'd memory area from user space, and what kind of exception can occur. I'm using Epson's driver, downloaded from their site, and modified for 2.4 kernel and monochrome LCD. If something has come to your thoughts, please let me know. I'm scratching my head now;-) Thank you for reading this. +-------------------------------------+ | Masahiro Abe, Software Engineer | | A&D Co., Ltd. of Tokyo, Japan | | mailto:m-...@aa... | +-------------------------------------+ |This is my opinion, not my employer's| +-------------------------------------+ |
From: David W. <dw...@in...> - 2001-07-04 12:32:24
|
#ifdefs confuse me. As there's almost nothing common between the SH3 and SH4 code in cache.c, it looks like it makes sense to split them into separate files. --- arch/sh/mm/Makefile.orig Wed Jul 4 13:09:07 2001 +++ arch/sh/mm/Makefile Wed Jul 4 13:09:45 2001 @@ -8,6 +8,9 @@ # Note 2! The CFLAGS definition is now in the main makefile... O_TARGET := mm.o -obj-y := init.o fault.o extable.o cache.o ioremap.o +obj-y := init.o fault.o extable.o ioremap.o + +obj-$(CONFIG_CPU_SH4) += cache-sh4.o +obj-$(CONFIG_CPU_SH3) += cache-sh3.o include $(TOPDIR)/Rules.make --- arch/sh/mm/cache-sh3.c.orig Wed Jul 4 13:09:24 2001 +++ arch/sh/mm/cache-sh3.c Wed Jul 4 13:04:25 2001 @@ -0,0 +1,143 @@ +/* $Id$ + * + * linux/arch/sh/mm/cache-sh3.c + * + * Copyright (C) 1999, 2000 Niibe Yutaka + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/mman.h> +#include <linux/mm.h> +#include <linux/threads.h> +#include <asm/addrspace.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/processor.h> +#include <asm/cache.h> +#include <asm/io.h> +#include <asm/uaccess.h> + +#define CCR 0xffffffec /* Address of Cache Control Register */ +#define CCR_CACHE_VAL 0x00000005 /* 8k-byte cache, P1-wb, enable */ +#define CCR_CACHE_INIT 0x0000000d /* 8k-byte cache, CF, P1-wb, enable */ +#define CCR_CACHE_ENABLE 1 + +#define CACHE_IC_ADDRESS_ARRAY 0xf0000000 /* SH-3 has unified cache system */ +#define CACHE_OC_ADDRESS_ARRAY 0xf0000000 +#define CACHE_VALID 1 +#define CACHE_UPDATED 2 + +/* 7709A/7729 has 16K cache (256-entry), while 7702 has only 2K(direct) + 7702 is not supported (yet) */ +struct _cache_system_info { + int way_shift; + int entry_mask; + int num_entries; +}; + +/* Data at BSS is cleared after setting this variable. + So, we Should not placed this variable at BSS section. + Initialize this, it is placed at data section. */ +static struct _cache_system_info cache_system_info = {0,}; + +#define CACHE_OC_WAY_SHIFT (cache_system_info.way_shift) +#define CACHE_IC_WAY_SHIFT (cache_system_info.way_shift) +#define CACHE_OC_ENTRY_SHIFT 4 +#define CACHE_OC_ENTRY_MASK (cache_system_info.entry_mask) +#define CACHE_IC_ENTRY_MASK (cache_system_info.entry_mask) +#define CACHE_OC_NUM_ENTRIES (cache_system_info.num_entries) +#define CACHE_OC_NUM_WAYS 4 +#define CACHE_IC_NUM_WAYS 4 + +/* + * Write back all the cache. + * + * For SH-4, we only need to flush (write back) Operand Cache, + * as Instruction Cache doesn't have "updated" data. + * + * Assumes that this is called in interrupt disabled context, and P2. + * Should be INLINE function. + */ +static inline void cache_wback_all(void) +{ + unsigned long addr, data, i, j; + + for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { + for (j=0; j<CACHE_OC_NUM_WAYS; j++) { + addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)| + (i<<CACHE_OC_ENTRY_SHIFT); + data = ctrl_inl(addr); + if ((data & (CACHE_UPDATED|CACHE_VALID)) + == (CACHE_UPDATED|CACHE_VALID)) + ctrl_outl(data & ~CACHE_UPDATED, addr); + } + } +} + +static void __init +detect_cpu_and_cache_system(void) +{ + unsigned long addr0, addr1, data0, data1, data2, data3; + + jump_to_P2(); + /* + * Check if the entry shadows or not. + * When shadowed, it's 128-entry system. + * Otherwise, it's 256-entry system. + */ + addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12); + addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12); + + /* First, write back & invalidate */ + data0 = ctrl_inl(addr0); + ctrl_outl(data0&~(CACHE_VALID|CACHE_UPDATED), addr0); + data1 = ctrl_inl(addr1); + ctrl_outl(data1&~(CACHE_VALID|CACHE_UPDATED), addr1); + + /* Next, check if there's shadow or not */ + data0 = ctrl_inl(addr0); + data0 ^= CACHE_VALID; + ctrl_outl(data0, addr0); + data1 = ctrl_inl(addr1); + data2 = data1 ^ CACHE_VALID; + ctrl_outl(data2, addr1); + data3 = ctrl_inl(addr0); + + /* Lastly, invaliate them. */ + ctrl_outl(data0&~CACHE_VALID, addr0); + ctrl_outl(data1&~CACHE_VALID, addr1); + back_to_P1(); + + if (data0 == data1 && data2 == data3) { /* Shadow */ + cache_system_info.way_shift = 11; + cache_system_info.entry_mask = 0x7f0; + cache_system_info.num_entries = 128; + cpu_data->type = CPU_SH7708; + } else { /* 7709A or 7729 */ + cache_system_info.way_shift = 12; + cache_system_info.entry_mask = 0xff0; + cache_system_info.num_entries = 256; + cpu_data->type = CPU_SH7729; + } +} + +void __init cache_init(void) +{ + unsigned long ccr; + + detect_cpu_and_cache_system(); + + ccr = ctrl_inl(CCR); + jump_to_P2(); + if (ccr & CCR_CACHE_ENABLE) + /* + * XXX: Should check RA here. + * If RA was 1, we only need to flush the half of the caches. + */ + cache_wback_all(); + + ctrl_outl(CCR_CACHE_INIT, CCR); + back_to_P1(); +} --- arch/sh/mm/cache-sh4.c.orig Wed Jul 4 13:09:28 2001 +++ arch/sh/mm/cache-sh4.c Wed Jul 4 13:05:36 2001 @@ -0,0 +1,510 @@ +/* $Id$ + * + * linux/arch/sh/mm/cache-sh4.c + * + * Copyright (C) 1999, 2000 Niibe Yutaka + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/mman.h> +#include <linux/mm.h> +#include <linux/threads.h> +#include <asm/addrspace.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/processor.h> +#include <asm/cache.h> +#include <asm/io.h> +#include <asm/uaccess.h> + +#define CCR 0xff00001c /* Address of Cache Control Register */ +#define CCR_CACHE_VAL 0x00000105 /* 8k+16k-byte cache,P1-wb,enable */ +#define CCR_CACHE_INIT 0x0000090d /* ICI,ICE(8k), OCI,P1-wb,OCE(16k) */ +#define CCR_CACHE_ENABLE 0x00000101 + +#define CACHE_IC_ADDRESS_ARRAY 0xf0000000 +#define CACHE_OC_ADDRESS_ARRAY 0xf4000000 +#define CACHE_VALID 1 +#define CACHE_UPDATED 2 + +#define CACHE_OC_WAY_SHIFT 13 +#define CACHE_IC_WAY_SHIFT 13 +#define CACHE_OC_ENTRY_SHIFT 5 +#define CACHE_IC_ENTRY_SHIFT 5 +#define CACHE_OC_ENTRY_MASK 0x3fe0 +#define CACHE_OC_ENTRY_PHYS_MASK 0x0fe0 +#define CACHE_IC_ENTRY_MASK 0x1fe0 +#define CACHE_IC_NUM_ENTRIES 256 +#define CACHE_OC_NUM_ENTRIES 512 +#define CACHE_OC_NUM_WAYS 1 +#define CACHE_IC_NUM_WAYS 1 + + +/* + * Write back all the cache. + * + * For SH-4, we only need to flush (write back) Operand Cache, + * as Instruction Cache doesn't have "updated" data. + * + * Assumes that this is called in interrupt disabled context, and P2. + * Shuld be INLINE function. + */ +static inline void cache_wback_all(void) +{ + unsigned long addr, data, i, j; + + for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { + for (j=0; j<CACHE_OC_NUM_WAYS; j++) { + addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)| + (i<<CACHE_OC_ENTRY_SHIFT); + data = ctrl_inl(addr); + if ((data & (CACHE_UPDATED|CACHE_VALID)) + == (CACHE_UPDATED|CACHE_VALID)) + ctrl_outl(data & ~CACHE_UPDATED, addr); + } + } +} + +static void __init +detect_cpu_and_cache_system(void) +{ +#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 + cpu_data->type = CPU_ST40STB1; +#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) + cpu_data->type = CPU_SH7750; +#else +#error Unknown SH4 CPU type +#endif +#endif +} + +void __init cache_init(void) +{ + unsigned long ccr; + + detect_cpu_and_cache_system(); + + ccr = ctrl_inl(CCR); + jump_to_P2(); + if (ccr & CCR_CACHE_ENABLE) + /* + * XXX: Should check RA here. + * If RA was 1, we only need to flush the half of the caches. + */ + cache_wback_all(); + + ctrl_outl(CCR_CACHE_INIT, CCR); + back_to_P1(); +} + +/* + * SH-4 has virtually indexed and physically tagged cache. + */ + +void __init p3_cache_init(void) +{ + /* In ioremap.c */ + extern int remap_area_pages(unsigned long address, + unsigned long phys_addr, + unsigned long size, unsigned long flags); + + if (remap_area_pages(P3SEG, 0, PAGE_SIZE*4, _PAGE_CACHABLE)) + panic("p3_cachie_init failed."); +} + +/* + * Write back the dirty D-caches, but not invalidate them. + * + * START, END: Virtual Address (U0, P1, or P3) + */ +void __flush_dcache_region(unsigned long start, unsigned long end) +{ + unsigned long v; + + start &= ~(L1_CACHE_BYTES-1); + for (v = start; v < end; v+=L1_CACHE_BYTES) { + asm volatile("ocbwb %0" + : /* no output */ + : "m" (__m(v))); + } +} + +/* + * No write back please + */ +static void __flush_invalidate_region(unsigned long start, unsigned long end) +{ + unsigned long v; + + start &= ~(L1_CACHE_BYTES-1); + for (v = start; v < end; v+=L1_CACHE_BYTES) { + asm volatile("ocbi %0" + : /* no output */ + : "m" (__m(v))); + } +} + +/* + * Write back the range of D-cache, and purge the I-cache. + * + * Called from kernel/module.c:sys_init_module and routine for a.out format. + */ +void flush_icache_range(unsigned long start, unsigned long end) +{ + flush_cache_all(); +} + +/* + * Write back the D-cache and purge the I-cache for signal trampoline. + */ +void flush_cache_sigtramp(unsigned long addr) +{ + unsigned long v, index; + + v = addr & ~(L1_CACHE_BYTES-1); + asm volatile("ocbwb %0" + : /* no output */ + : "m" (__m(v))); + + index = CACHE_IC_ADDRESS_ARRAY| (v&CACHE_IC_ENTRY_MASK); + ctrl_outl(0, index); /* Clear out Valid-bit */ +} + +/* + * Writeback&Invalidate the D-cache of the page + * Invalidate the I-cache of the page, if needed + */ +void __flush_cache_page(unsigned long phys, int exec) +{ + unsigned long addr, data; + unsigned long flags; + + phys|=CACHE_VALID; + save_and_cli(flags); + jump_to_P2(); + /* Loop all the D-cache */ + for (addr = CACHE_OC_ADDRESS_ARRAY; + addr < (CACHE_OC_ADDRESS_ARRAY + +(CACHE_OC_NUM_ENTRIES<< CACHE_OC_ENTRY_SHIFT)); + addr += (1<<CACHE_OC_ENTRY_SHIFT)) { + data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); + if (data == phys) + ctrl_outl(0, addr); + } + + if (exec) + /* Loop all the I-cache */ + for (addr = CACHE_IC_ADDRESS_ARRAY; + addr < (CACHE_IC_ADDRESS_ARRAY + +(CACHE_IC_NUM_ENTRIES<< CACHE_IC_ENTRY_SHIFT)); + addr += (1<<CACHE_IC_ENTRY_SHIFT)) { + data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); + if (data == phys) + ctrl_outl(0, addr); + } + back_to_P1(); + restore_flags(flags); +} + +#if 0 +/* + * Invalidate the I-cache of the page (don't need to write back D-cache). + * + * Called from kernel/ptrace.c, mm/memory.c after flush_page_to_ram is called. + */ +void flush_icache_page(struct vm_area_struct *vma, struct page *pg) +{ + unsigned long phys, addr, data, i; + + /* Physical address of this page */ + phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; + + jump_to_P2(); + /* Loop all the I-cache */ + for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) { + addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT); + data = ctrl_inl(addr); + if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) { + data &= ~CACHE_VALID; + ctrl_outl(data, addr); + } + } + back_to_P1(); +} +#endif + +/* + * Write back & invalidate the I/D-cache of the page. + * (To avoid "alias" issues) + */ +void flush_dcache_page(struct page *pg) +{ + if (!pg->mapping + || pg->mapping->i_mmap || pg->mapping->i_mmap_shared) { + int exec; + unsigned long phys; + + if (!pg->mapping) + exec = 0; + else + exec = 1; + + /* Physical address of this page */ + phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; + __flush_cache_page(phys, exec); + } else + set_bit(PG_dcache_dirty, &pg->flags); +} + +void flush_cache_all(void) +{ + unsigned long flags; + unsigned long addr; + + save_and_cli(flags); + jump_to_P2(); + + /* Loop all the D-cache */ + for (addr = CACHE_OC_ADDRESS_ARRAY; + addr < (CACHE_OC_ADDRESS_ARRAY + +(CACHE_OC_NUM_ENTRIES<< CACHE_OC_ENTRY_SHIFT)); + addr += (1<<CACHE_OC_ENTRY_SHIFT)) + ctrl_outl(0, addr); + + /* Loop all the I-cache */ + for (addr = CACHE_IC_ADDRESS_ARRAY; + addr < (CACHE_IC_ADDRESS_ARRAY + +(CACHE_IC_NUM_ENTRIES<< CACHE_IC_ENTRY_SHIFT)); + addr += (1<<CACHE_IC_ENTRY_SHIFT)) + ctrl_outl(0, addr); + + back_to_P1(); + restore_flags(flags); +} + +void flush_cache_mm(struct mm_struct *mm) +{ + /* Is there any good way? */ + /* XXX: possibly call flush_cache_range for each vm area */ + flush_cache_all(); +} + +/* + * Write back and invalidate D-caches. + * + * START, END: Virtual Address (U0 address) + * + * NOTE: We need to flush the _physical_ page entry. + * Flushing the cache lines for U0 only isn't enough. + * We need to flush for P1 too, which may contain aliases. + */ +void flush_cache_range(struct mm_struct *mm, unsigned long start, + unsigned long end) +{ + /* + * We could call flush_cache_page for the pages of these range, + * but it's not efficient (scan the caches all the time...). + * + * We can't use A-bit magic, as there's the case we don't have + * valid entry on TLB. + */ + flush_cache_all(); +} + +/* + * Write back and invalidate I/D-caches for the page. + * + * ADDR: Virtual Address (U0 address) + */ +void flush_cache_page(struct vm_area_struct *vma, unsigned long addr) +{ + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + unsigned long phys; + + dir = pgd_offset(vma->vm_mm, addr); + pmd = pmd_offset(dir, addr); + if (pmd_none(*pmd)) + return; + if (pmd_bad(*pmd)) + return; + pte = pte_offset(pmd, addr); + entry = *pte; + if (pte_none(entry) || !pte_present(entry)) + return; + phys = PHYSADDR(pte_val(entry))&PAGE_MASK; + __flush_cache_page(phys, (vma->vm_flags & VM_EXEC)); +} + +#if 0 +/* + * Write-back & invalidate the cache. + * + * After accessing the memory from kernel space (P1-area), we need to + * write back the cache line. + * + * We search the D-cache to see if we have the entries corresponding to + * the page, and if found, write back them. + */ +static void __flush_page_to_ram(void *kaddr) +{ + unsigned long phys, addr, data, i; + + /* Physical address of this page */ + phys = PHYSADDR(kaddr); + + jump_to_P2(); + /* Loop all the D-cache */ + for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { + addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT); + data = ctrl_inl(addr); + if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) { + data &= ~(CACHE_UPDATED|CACHE_VALID); + ctrl_outl(data, addr); + } + } + back_to_P1(); +} + +void flush_page_to_ram(struct page *pg) +{ + unsigned long phys; + + /* Physical address of this page */ + phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; + __flush_page_to_ram(phys_to_virt(phys)); +} +#endif + +/* + * Check entries of the I-cache & D-cache of the page. + * (To see "alias" issues) + */ +void check_cache_page(struct page *pg) +{ + unsigned long phys, addr, data, i; + unsigned long kaddr; + unsigned long cache_line_index; + int bingo = 0; + + /* Physical address of this page */ + phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; + kaddr = phys + PAGE_OFFSET; + cache_line_index = (kaddr&CACHE_OC_ENTRY_MASK)>>CACHE_OC_ENTRY_SHIFT; + + jump_to_P2(); + /* Loop all the D-cache */ + for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { + addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT); + data = ctrl_inl(addr); + if ((data & (CACHE_UPDATED|CACHE_VALID)) + == (CACHE_UPDATED|CACHE_VALID) + && (data&PAGE_MASK) == phys) { + data &= ~(CACHE_VALID|CACHE_UPDATED); + ctrl_outl(data, addr); + if ((i^cache_line_index)&0x180) + bingo = 1; + } + } + + cache_line_index &= 0xff; + /* Loop all the I-cache */ + for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) { + addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT); + data = ctrl_inl(addr); + if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) { + data &= ~CACHE_VALID; + ctrl_outl(data, addr); + if (((i^cache_line_index)&0x80)) + bingo = 2; + } + } + back_to_P1(); + + if (bingo) { + extern void dump_stack(void); + + if (bingo ==1) + printk("BINGO!\n"); + else + printk("Bingo!\n"); + dump_stack(); + printk("--------------------\n"); + } +} + +/* Page is 4K, OC size is 16K, there are four lines. */ +#define CACHE_ALIAS 0x00003000 + +/* + * clear_user_page + * @to: P1 address + * @address: U0 address to be mapped + */ +void clear_user_page(void *to, unsigned long address) +{ + if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) + clear_page(to); + else { + unsigned long flags; + pgprot_t pgprot = __pgprot(_PAGE_PRESENT | + _PAGE_RW | _PAGE_CACHABLE | + _PAGE_DIRTY | _PAGE_ACCESSED | + _PAGE_HW_SHARED | _PAGE_FLAGS_HARD); + unsigned long phys_addr = PHYSADDR(to); + unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); + pgd_t *dir = pgd_offset_k(p3_addr); + pmd_t *pmd = pmd_offset(dir, p3_addr); + pte_t *pte = pte_offset(pmd, p3_addr); + pte_t entry; + + __flush_invalidate_region((unsigned long)to, + (unsigned long)to+PAGE_SIZE); + + save_and_cli(flags); + entry = mk_pte_phys(phys_addr, pgprot); + set_pte(pte, entry); + update_mmu_cache(NULL, p3_addr, entry); + clear_page((void *)p3_addr); + restore_flags(flags); + } +} + +/* + * copy_user_page + * @to: P1 address + * @from: P1 address + * @address: U0 address to be mapped + */ +void copy_user_page(void *to, void *from, unsigned long address) +{ + if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) + copy_page(to, from); + else { + unsigned long flags; + pgprot_t pgprot = __pgprot(_PAGE_PRESENT | + _PAGE_RW | _PAGE_CACHABLE | + _PAGE_DIRTY | _PAGE_ACCESSED | + _PAGE_HW_SHARED | _PAGE_FLAGS_HARD); + unsigned long phys_addr = PHYSADDR(to); + unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); + pgd_t *dir = pgd_offset_k(p3_addr); + pmd_t *pmd = pmd_offset(dir, p3_addr); + pte_t *pte = pte_offset(pmd, p3_addr); + pte_t entry; + + __flush_invalidate_region((unsigned long)to, + (unsigned long)to+PAGE_SIZE); + + save_and_cli(flags); + entry = mk_pte_phys(phys_addr, pgprot); + set_pte(pte, entry); + update_mmu_cache(NULL, p3_addr, entry); + copy_page((void *)p3_addr, from); + restore_flags(flags); + } +} --- arch/sh/mm/cache.c.orig Wed Jul 4 12:56:49 2001 +++ arch/sh/mm/cache.c Wed Jul 4 13:09:40 2001 @@ -1,590 +0,0 @@ -/* $Id: cache.c,v 1.10 2000/03/07 11:58:34 gniibe Exp $ - * - * linux/arch/sh/mm/cache.c - * - * Copyright (C) 1999, 2000 Niibe Yutaka - * - */ - -#include <linux/config.h> -#include <linux/init.h> -#include <linux/mman.h> -#include <linux/mm.h> -#include <linux/threads.h> -#include <asm/addrspace.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/processor.h> -#include <asm/cache.h> -#include <asm/io.h> -#include <asm/uaccess.h> - -#if defined(__sh3__) -#define CCR 0xffffffec /* Address of Cache Control Register */ -#define CCR_CACHE_VAL 0x00000005 /* 8k-byte cache, P1-wb, enable */ -#define CCR_CACHE_INIT 0x0000000d /* 8k-byte cache, CF, P1-wb, enable */ -#define CCR_CACHE_ENABLE 1 - -#define CACHE_IC_ADDRESS_ARRAY 0xf0000000 /* SH-3 has unified cache system */ -#define CACHE_OC_ADDRESS_ARRAY 0xf0000000 -#define CACHE_VALID 1 -#define CACHE_UPDATED 2 - -/* 7709A/7729 has 16K cache (256-entry), while 7702 has only 2K(direct) - 7702 is not supported (yet) */ -struct _cache_system_info { - int way_shift; - int entry_mask; - int num_entries; -}; - -/* Data at BSS is cleared after setting this variable. - So, we Should not placed this variable at BSS section. - Initialize this, it is placed at data section. */ -static struct _cache_system_info cache_system_info = {0,}; - -#define CACHE_OC_WAY_SHIFT (cache_system_info.way_shift) -#define CACHE_IC_WAY_SHIFT (cache_system_info.way_shift) -#define CACHE_OC_ENTRY_SHIFT 4 -#define CACHE_OC_ENTRY_MASK (cache_system_info.entry_mask) -#define CACHE_IC_ENTRY_MASK (cache_system_info.entry_mask) -#define CACHE_OC_NUM_ENTRIES (cache_system_info.num_entries) -#define CACHE_OC_NUM_WAYS 4 -#define CACHE_IC_NUM_WAYS 4 -#elif defined(__SH4__) -#define CCR 0xff00001c /* Address of Cache Control Register */ -#define CCR_CACHE_VAL 0x00000105 /* 8k+16k-byte cache,P1-wb,enable */ -#define CCR_CACHE_INIT 0x0000090d /* ICI,ICE(8k), OCI,P1-wb,OCE(16k) */ -#define CCR_CACHE_ENABLE 0x00000101 - -#define CACHE_IC_ADDRESS_ARRAY 0xf0000000 -#define CACHE_OC_ADDRESS_ARRAY 0xf4000000 -#define CACHE_VALID 1 -#define CACHE_UPDATED 2 - -#define CACHE_OC_WAY_SHIFT 13 -#define CACHE_IC_WAY_SHIFT 13 -#define CACHE_OC_ENTRY_SHIFT 5 -#define CACHE_IC_ENTRY_SHIFT 5 -#define CACHE_OC_ENTRY_MASK 0x3fe0 -#define CACHE_OC_ENTRY_PHYS_MASK 0x0fe0 -#define CACHE_IC_ENTRY_MASK 0x1fe0 -#define CACHE_IC_NUM_ENTRIES 256 -#define CACHE_OC_NUM_ENTRIES 512 -#define CACHE_OC_NUM_WAYS 1 -#define CACHE_IC_NUM_WAYS 1 -#endif - - -/* - * Write back all the cache. - * - * For SH-4, we only need to flush (write back) Operand Cache, - * as Instruction Cache doesn't have "updated" data. - * - * Assumes that this is called in interrupt disabled context, and P2. - * Shuld be INLINE function. - */ -static inline void cache_wback_all(void) -{ - unsigned long addr, data, i, j; - - for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { - for (j=0; j<CACHE_OC_NUM_WAYS; j++) { - addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)| - (i<<CACHE_OC_ENTRY_SHIFT); - data = ctrl_inl(addr); - if ((data & (CACHE_UPDATED|CACHE_VALID)) - == (CACHE_UPDATED|CACHE_VALID)) - ctrl_outl(data & ~CACHE_UPDATED, addr); - } - } -} - -static void __init -detect_cpu_and_cache_system(void) -{ -#if defined(__sh3__) - unsigned long addr0, addr1, data0, data1, data2, data3; - - jump_to_P2(); - /* - * Check if the entry shadows or not. - * When shadowed, it's 128-entry system. - * Otherwise, it's 256-entry system. - */ - addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12); - addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12); - - /* First, write back & invalidate */ - data0 = ctrl_inl(addr0); - ctrl_outl(data0&~(CACHE_VALID|CACHE_UPDATED), addr0); - data1 = ctrl_inl(addr1); - ctrl_outl(data1&~(CACHE_VALID|CACHE_UPDATED), addr1); - - /* Next, check if there's shadow or not */ - data0 = ctrl_inl(addr0); - data0 ^= CACHE_VALID; - ctrl_outl(data0, addr0); - data1 = ctrl_inl(addr1); - data2 = data1 ^ CACHE_VALID; - ctrl_outl(data2, addr1); - data3 = ctrl_inl(addr0); - - /* Lastly, invaliate them. */ - ctrl_outl(data0&~CACHE_VALID, addr0); - ctrl_outl(data1&~CACHE_VALID, addr1); - back_to_P1(); - - if (data0 == data1 && data2 == data3) { /* Shadow */ - cache_system_info.way_shift = 11; - cache_system_info.entry_mask = 0x7f0; - cache_system_info.num_entries = 128; - cpu_data->type = CPU_SH7708; - } else { /* 7709A or 7729 */ - cache_system_info.way_shift = 12; - cache_system_info.entry_mask = 0xff0; - cache_system_info.num_entries = 256; - cpu_data->type = CPU_SH7729; - } -#elif defined(__SH4__) -#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 - cpu_data->type = CPU_ST40STB1; -#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) - cpu_data->type = CPU_SH7750; -#else -#error Unknown SH4 CPU type -#endif -#endif -} - -void __init cache_init(void) -{ - unsigned long ccr; - - detect_cpu_and_cache_system(); - - ccr = ctrl_inl(CCR); - jump_to_P2(); - if (ccr & CCR_CACHE_ENABLE) - /* - * XXX: Should check RA here. - * If RA was 1, we only need to flush the half of the caches. - */ - cache_wback_all(); - - ctrl_outl(CCR_CACHE_INIT, CCR); - back_to_P1(); -} - -#if defined(__SH4__) -/* - * SH-4 has virtually indexed and physically tagged cache. - */ - -void __init p3_cache_init(void) -{ - /* In ioremap.c */ - extern int remap_area_pages(unsigned long address, - unsigned long phys_addr, - unsigned long size, unsigned long flags); - - if (remap_area_pages(P3SEG, 0, PAGE_SIZE*4, _PAGE_CACHABLE)) - panic("p3_cachie_init failed."); -} - -/* - * Write back the dirty D-caches, but not invalidate them. - * - * START, END: Virtual Address (U0, P1, or P3) - */ -void __flush_dcache_region(unsigned long start, unsigned long end) -{ - unsigned long v; - - start &= ~(L1_CACHE_BYTES-1); - for (v = start; v < end; v+=L1_CACHE_BYTES) { - asm volatile("ocbwb %0" - : /* no output */ - : "m" (__m(v))); - } -} - -/* - * No write back please - */ -static void __flush_invalidate_region(unsigned long start, unsigned long end) -{ - unsigned long v; - - start &= ~(L1_CACHE_BYTES-1); - for (v = start; v < end; v+=L1_CACHE_BYTES) { - asm volatile("ocbi %0" - : /* no output */ - : "m" (__m(v))); - } -} - -/* - * Write back the range of D-cache, and purge the I-cache. - * - * Called from kernel/module.c:sys_init_module and routine for a.out format. - */ -void flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); -} - -/* - * Write back the D-cache and purge the I-cache for signal trampoline. - */ -void flush_cache_sigtramp(unsigned long addr) -{ - unsigned long v, index; - - v = addr & ~(L1_CACHE_BYTES-1); - asm volatile("ocbwb %0" - : /* no output */ - : "m" (__m(v))); - - index = CACHE_IC_ADDRESS_ARRAY| (v&CACHE_IC_ENTRY_MASK); - ctrl_outl(0, index); /* Clear out Valid-bit */ -} - -/* - * Writeback&Invalidate the D-cache of the page - * Invalidate the I-cache of the page, if needed - */ -void __flush_cache_page(unsigned long phys, int exec) -{ - unsigned long addr, data; - unsigned long flags; - - phys|=CACHE_VALID; - save_and_cli(flags); - jump_to_P2(); - /* Loop all the D-cache */ - for (addr = CACHE_OC_ADDRESS_ARRAY; - addr < (CACHE_OC_ADDRESS_ARRAY - +(CACHE_OC_NUM_ENTRIES<< CACHE_OC_ENTRY_SHIFT)); - addr += (1<<CACHE_OC_ENTRY_SHIFT)) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } - - if (exec) - /* Loop all the I-cache */ - for (addr = CACHE_IC_ADDRESS_ARRAY; - addr < (CACHE_IC_ADDRESS_ARRAY - +(CACHE_IC_NUM_ENTRIES<< CACHE_IC_ENTRY_SHIFT)); - addr += (1<<CACHE_IC_ENTRY_SHIFT)) { - data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID); - if (data == phys) - ctrl_outl(0, addr); - } - back_to_P1(); - restore_flags(flags); -} - -#if 0 -/* - * Invalidate the I-cache of the page (don't need to write back D-cache). - * - * Called from kernel/ptrace.c, mm/memory.c after flush_page_to_ram is called. - */ -void flush_icache_page(struct vm_area_struct *vma, struct page *pg) -{ - unsigned long phys, addr, data, i; - - /* Physical address of this page */ - phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; - - jump_to_P2(); - /* Loop all the I-cache */ - for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) { - addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT); - data = ctrl_inl(addr); - if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) { - data &= ~CACHE_VALID; - ctrl_outl(data, addr); - } - } - back_to_P1(); -} -#endif - -/* - * Write back & invalidate the I/D-cache of the page. - * (To avoid "alias" issues) - */ -void flush_dcache_page(struct page *pg) -{ - if (!pg->mapping - || pg->mapping->i_mmap || pg->mapping->i_mmap_shared) { - int exec; - unsigned long phys; - - if (!pg->mapping) - exec = 0; - else - exec = 1; - - /* Physical address of this page */ - phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; - __flush_cache_page(phys, exec); - } else - set_bit(PG_dcache_dirty, &pg->flags); -} - -void flush_cache_all(void) -{ - unsigned long flags; - unsigned long addr; - - save_and_cli(flags); - jump_to_P2(); - - /* Loop all the D-cache */ - for (addr = CACHE_OC_ADDRESS_ARRAY; - addr < (CACHE_OC_ADDRESS_ARRAY - +(CACHE_OC_NUM_ENTRIES<< CACHE_OC_ENTRY_SHIFT)); - addr += (1<<CACHE_OC_ENTRY_SHIFT)) - ctrl_outl(0, addr); - - /* Loop all the I-cache */ - for (addr = CACHE_IC_ADDRESS_ARRAY; - addr < (CACHE_IC_ADDRESS_ARRAY - +(CACHE_IC_NUM_ENTRIES<< CACHE_IC_ENTRY_SHIFT)); - addr += (1<<CACHE_IC_ENTRY_SHIFT)) - ctrl_outl(0, addr); - - back_to_P1(); - restore_flags(flags); -} - -void flush_cache_mm(struct mm_struct *mm) -{ - /* Is there any good way? */ - /* XXX: possibly call flush_cache_range for each vm area */ - flush_cache_all(); -} - -/* - * Write back and invalidate D-caches. - * - * START, END: Virtual Address (U0 address) - * - * NOTE: We need to flush the _physical_ page entry. - * Flushing the cache lines for U0 only isn't enough. - * We need to flush for P1 too, which may contain aliases. - */ -void flush_cache_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - /* - * We could call flush_cache_page for the pages of these range, - * but it's not efficient (scan the caches all the time...). - * - * We can't use A-bit magic, as there's the case we don't have - * valid entry on TLB. - */ - flush_cache_all(); -} - -/* - * Write back and invalidate I/D-caches for the page. - * - * ADDR: Virtual Address (U0 address) - */ -void flush_cache_page(struct vm_area_struct *vma, unsigned long addr) -{ - pgd_t *dir; - pmd_t *pmd; - pte_t *pte; - pte_t entry; - unsigned long phys; - - dir = pgd_offset(vma->vm_mm, addr); - pmd = pmd_offset(dir, addr); - if (pmd_none(*pmd)) - return; - if (pmd_bad(*pmd)) - return; - pte = pte_offset(pmd, addr); - entry = *pte; - if (pte_none(entry) || !pte_present(entry)) - return; - phys = PHYSADDR(pte_val(entry))&PAGE_MASK; - __flush_cache_page(phys, (vma->vm_flags & VM_EXEC)); -} - -#if 0 -/* - * Write-back & invalidate the cache. - * - * After accessing the memory from kernel space (P1-area), we need to - * write back the cache line. - * - * We search the D-cache to see if we have the entries corresponding to - * the page, and if found, write back them. - */ -static void __flush_page_to_ram(void *kaddr) -{ - unsigned long phys, addr, data, i; - - /* Physical address of this page */ - phys = PHYSADDR(kaddr); - - jump_to_P2(); - /* Loop all the D-cache */ - for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { - addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT); - data = ctrl_inl(addr); - if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) { - data &= ~(CACHE_UPDATED|CACHE_VALID); - ctrl_outl(data, addr); - } - } - back_to_P1(); -} - -void flush_page_to_ram(struct page *pg) -{ - unsigned long phys; - - /* Physical address of this page */ - phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; - __flush_page_to_ram(phys_to_virt(phys)); -} -#endif - -/* - * Check entries of the I-cache & D-cache of the page. - * (To see "alias" issues) - */ -void check_cache_page(struct page *pg) -{ - unsigned long phys, addr, data, i; - unsigned long kaddr; - unsigned long cache_line_index; - int bingo = 0; - - /* Physical address of this page */ - phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; - kaddr = phys + PAGE_OFFSET; - cache_line_index = (kaddr&CACHE_OC_ENTRY_MASK)>>CACHE_OC_ENTRY_SHIFT; - - jump_to_P2(); - /* Loop all the D-cache */ - for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { - addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT); - data = ctrl_inl(addr); - if ((data & (CACHE_UPDATED|CACHE_VALID)) - == (CACHE_UPDATED|CACHE_VALID) - && (data&PAGE_MASK) == phys) { - data &= ~(CACHE_VALID|CACHE_UPDATED); - ctrl_outl(data, addr); - if ((i^cache_line_index)&0x180) - bingo = 1; - } - } - - cache_line_index &= 0xff; - /* Loop all the I-cache */ - for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) { - addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT); - data = ctrl_inl(addr); - if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) { - data &= ~CACHE_VALID; - ctrl_outl(data, addr); - if (((i^cache_line_index)&0x80)) - bingo = 2; - } - } - back_to_P1(); - - if (bingo) { - extern void dump_stack(void); - - if (bingo ==1) - printk("BINGO!\n"); - else - printk("Bingo!\n"); - dump_stack(); - printk("--------------------\n"); - } -} - -/* Page is 4K, OC size is 16K, there are four lines. */ -#define CACHE_ALIAS 0x00003000 - -/* - * clear_user_page - * @to: P1 address - * @address: U0 address to be mapped - */ -void clear_user_page(void *to, unsigned long address) -{ - if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) - clear_page(to); - else { - unsigned long flags; - pgprot_t pgprot = __pgprot(_PAGE_PRESENT | - _PAGE_RW | _PAGE_CACHABLE | - _PAGE_DIRTY | _PAGE_ACCESSED | - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD); - unsigned long phys_addr = PHYSADDR(to); - unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); - pgd_t *dir = pgd_offset_k(p3_addr); - pmd_t *pmd = pmd_offset(dir, p3_addr); - pte_t *pte = pte_offset(pmd, p3_addr); - pte_t entry; - - __flush_invalidate_region((unsigned long)to, - (unsigned long)to+PAGE_SIZE); - - save_and_cli(flags); - entry = mk_pte_phys(phys_addr, pgprot); - set_pte(pte, entry); - update_mmu_cache(NULL, p3_addr, entry); - clear_page((void *)p3_addr); - restore_flags(flags); - } -} - -/* - * copy_user_page - * @to: P1 address - * @from: P1 address - * @address: U0 address to be mapped - */ -void copy_user_page(void *to, void *from, unsigned long address) -{ - if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) - copy_page(to, from); - else { - unsigned long flags; - pgprot_t pgprot = __pgprot(_PAGE_PRESENT | - _PAGE_RW | _PAGE_CACHABLE | - _PAGE_DIRTY | _PAGE_ACCESSED | - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD); - unsigned long phys_addr = PHYSADDR(to); - unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); - pgd_t *dir = pgd_offset_k(p3_addr); - pmd_t *pmd = pmd_offset(dir, p3_addr); - pte_t *pte = pte_offset(pmd, p3_addr); - pte_t entry; - - __flush_invalidate_region((unsigned long)to, - (unsigned long)to+PAGE_SIZE); - - save_and_cli(flags); - entry = mk_pte_phys(phys_addr, pgprot); - set_pte(pte, entry); - update_mmu_cache(NULL, p3_addr, entry); - copy_page((void *)p3_addr, from); - restore_flags(flags); - } -} -#endif -- dwmw2 |
From: David W. <dw...@in...> - 2001-07-04 08:52:38
|
js...@mv... said: > In case you don't already have a different fix, maybe the following > takes care of it? I didn't. It does. Thanks. -- dwmw2 |
From: Jeremy S. <js...@mv...> - 2001-07-03 20:28:48
|
David Woodhouse wrote: > The current checksum routines appear to break on certain 2-byte aligned > data. > This wasn't introduced by the latest change to checksum.S on the 27th of > June - it looks like it's been there for a while. In case you don't already have a different fix, maybe the following takes care of it? |
From: David W. <dw...@in...> - 2001-07-03 15:12:37
|
The current checksum routines appear to break on certain 2-byte aligned data. This wasn't introduced by the latest change to checksum.S on the 27th of June - it looks like it's been there for a while. See attached testcase, which produces the following output: Checksum of testcase at 8c110214 is 0x0 Checksum of testcase at 8c110215 is 0x0 Checksum of testcase at 8c110216 is 0x695a Checksum of testcase at 8c110217 is 0x695a Checksum of testcase at 8c110218 is 0x0 Now perhaps you can forgive it for getting the 8c110215 and 8c110217 versions wrong - I'm not sure other architectures will get that right either. But the 8c110216 case should work. -- dwmw2 |
From: Brian K. W. <br...@al...> - 2001-07-01 23:00:49
|
Hi, What is the state of the art of linux-sh on the HP Jornada? specifically the 540 series, more specifically, the 548, more more specifically, assume plenty of room via a 256 meg CF card. If I assume that the precompiled kernel for 240x320 devices and boot loader work, that leaves the question of, does anyone have distribution cabbled together? perhaps something like tomsrtbt, where everything is tiny and most utilities are just tiny awk scripts, nc scripts, and busybox? Now the really ludicrous question... what is the possibility of the video ever being supported by Xfree86? (secretly hoping the video is the same or similar to the yopy or the agenda...) Brian K. White -- br...@al... -- http://www.aljex.com/bkw/ +++++[>+++[>+++++>+++++++<<-]<-]>>+.>.+++++.+++++++.-.[>+<---]>++. filePro BBx Linux SCO Prosper/FACTS AutoCAD #callahans Satriani |
From: Masahiro A. <m-...@aa...> - 2001-06-30 09:59:53
|
Hello all, I've updated "Cross development" and "RTLinux" patch & documents. Those are in the same places as I've last notified: Building Cross Development Environment: <ftp://ftp.aandd.co.jp/pub/linuxsh/buildproc/> RTLinux: <ftp://ftp.aandd.co.jp/pub/linuxsh/rtlinux/current/> Changes are: -based on kernel 2.4.5 -uses ext3 patch -added instruction to cross compile e2fsprogs-1.22 Until now, ext3 file system is working on my target machine as root without any problem so far. I can reset the target and it is repaired at boot time very quickly. +-------------------------------------+ | Masahiro Abe, Software Engineer | | A&D Co., Ltd. of Tokyo, Japan | | mailto:m-...@aa... | +-------------------------------------+ |This is my opinion, not my employer's| +-------------------------------------+ |
From: Masahiro A. <m-...@aa...> - 2001-06-26 00:31:34
|
Hello all, We at A&D have been porting RTLinux 3.0 to Linux-sh, especially to SH4. We think it's ready for review by wider audience, and put patches and documents at the following place. <ftp://ftp.aandd.co.jp/pub/linuxsh/rtlinux/current/> Please read "README_..." file in the directory for instruction. They are provided "as is", and "WITHOUT ANY WARRANTY", but we welcome your comments, suggestions, bug reports and alike. We can't assure you to respond to everything but we will do what we can. At this time, we would like to show our appreciation to the efforts put into Linux-sh and RTLinux projects by many people. Especially Mr. Nobuhiro Sakawa provided us great help. We couldn't achieve this state without YOU ALL. Thanks everybody! For those of you interested, here is the summary of status: - based on Linux kernel 2.4.4 + Open RTLinux 3.0 - measured interrupt latency < 60usec, RTTask startup jitter < +/-70usec (we don't guarantee these numbers, you know) - Basic modules(rtl, rtl_time, rtl_sched, rtl_posixio, rtl_fifo) functioning without noticeable problem - Math with FPU within RTTask supported - mbuff may not be working properly? needs further investigation - psc and rtl_tracer can be built but not verified - rtl_debug not ported (yet) - works on SH4(7750S). Not yet on SH3? As I said, we welcome your comments. +-------------------------------------+ | Masahiro Abe, Software Engineer | | A&D Co., Ltd. of Tokyo, Japan | | mailto:m-...@aa... | +-------------------------------------+ |This is my opinion, not my employer's| +-------------------------------------+ |
From: kaz K. <kk...@rr...> - 2001-06-20 02:51:52
|
Hi, Bryan Rittmeyer <br...@ix...> wrote: > Is anyone successfully using gcc-3.0 with the sh4? I have > tried building several toolchains based on it, and they > all compile the 2.4.5 kernel succesfully (after a minor > xtime patch which I've included below). However, I can't > get gcc-3.0 to produce ANY working user code (not even > hello1-20000824!) I don't try 3.0, but I've put an experimental patch http://dodo.nurs.or.jp/~kkojima/gnu-on-sh/gcc-cvs-010514.diff http://dodo.nurs.or.jp/~kkojima/gnu-on-sh/gcc-cvs-010515-2add.tar.gz for 3.1 branch. It was relatively stable for 20000504 version of 3.1 CVS tree. Unfortunately, now 3.1 can't even bootstrap. You can configure gcc like as /xxx/gcc/configure --host=... --target=sh4-unknown-linux-gnu --enable-languages=c --enable-shared under this patch. The option --enable-shared makes the shared libgcc which is new in 3.x release. It needs some manual operations to make the shared libgcc in the cross environment. The above patch uses the shared libgcc libgcc_s.so as default. If you don't like it, specs file must be modified. kaz |
From: NIIBE Y. <gn...@m1...> - 2001-06-20 01:30:00
|
Ian da Silva wrote: > We agree that the 7751 support needs to be separated from the other > SolutionEngine boards. It has been on the back of our minds, but we just > haven't gotten around to doing it. If you are short of time, we can make > the changes; the files at issue are io_se.c, mach_se.c and setup_se.c. > Do you think we are missing anything? > > If you've already done it, we'll pick up your changes. :) No, I haven't done yet. Please do the changes, we could arrange rw-access of CVS, if you have account on SourceForge. > By the way, we would like to include sh-ipl+g and sh-ethboot in our > distribution. Is that okay with you? Yes, of course. It's Free Software, you know. As I wrote in README, it's under LGPL, but some of code (memcpy and such) are taken from Linux, which is under GPL. I'm not sure the consequence, but my intention is to let it be used in many cases, provided it doesn't break cooperative development of the software. -- |
From: Ian da S. <ida...@mv...> - 2001-06-20 01:18:13
|
Niibe, We agree that the 7751 support needs to be separated from the other SolutionEngine boards. It has been on the back of our minds, but we just haven't gotten around to doing it. If you are short of time, we can make the changes; the files at issue are io_se.c, mach_se.c and setup_se.c. Do you think we are missing anything? If you've already done it, we'll pick up your changes. :) By the way, we would like to include sh-ipl+g and sh-ethboot in our distribution. Is that okay with you? Ian and Jeremy. NIIBE Yutaka wrote: > NIIBE Yutaka wrote: > > Looking the specification of SolutionEngine 7751, I'd prefer having > > separate machine vector or I/O routines for that. It looks for me > > that there's almost no common parts between SolutionEngine > > 7709A/7750/7750S and 7751. Well, the name is common, I know... ;-) > > I'll separate out SolutionEngine 7751 support from 7709A/7750/7750S. > As the target SolutionEngine 7751 is different beast, there's no merit > to put the support of that target to io-se.c and others. > > Ian, if you have any opinion or patches, please let me know. > -- > > _______________________________________________ > linuxsh-dev mailing list > lin...@li... > http://lists.sourceforge.net/lists/listinfo/linuxsh-dev |
From: NIIBE Y. <gn...@m1...> - 2001-06-19 23:45:42
|
NIIBE Yutaka wrote: > Looking the specification of SolutionEngine 7751, I'd prefer having > separate machine vector or I/O routines for that. It looks for me > that there's almost no common parts between SolutionEngine > 7709A/7750/7750S and 7751. Well, the name is common, I know... ;-) I'll separate out SolutionEngine 7751 support from 7709A/7750/7750S. As the target SolutionEngine 7751 is different beast, there's no merit to put the support of that target to io-se.c and others. Ian, if you have any opinion or patches, please let me know. -- |
From: Bryan R. <br...@ix...> - 2001-06-19 04:53:34
|
Hello, Is anyone successfully using gcc-3.0 with the sh4? I have tried building several toolchains based on it, and they all compile the 2.4.5 kernel succesfully (after a minor xtime patch which I've included below). However, I can't get gcc-3.0 to produce ANY working user code (not even hello1-20000824!) If you are using gcc-3.0 stable, or a recent gcc-3.0pre snapshot with the sh4, I would GREATLY appreciate build instructions, as well as what version of binutils, the kernel, and glibc you are using. Lots of patches are used in the instructions here: http://linuxsh.sourceforge.net/docs/abe/20010320-gcc2.97/README_E.php3 and most of them won't apply to 3.0. Based on the 2.97 patches, I've created a very minimal gcc-3.0 patch: --- gcc.orig/gcc/config/sh/linux.h Mon Jun 11 20:13:39 2001 +++ gcc/gcc/config/sh/linux.h Mon Jun 11 20:17:00 2001 @@ -43,9 +43,9 @@ #define CPP_SPEC \ "%{mb:-D__BIG_ENDIAN__} \ %{!mb:-D__LITTLE_ENDIAN__} \ - %{m3e:-D__SH3E__} \ %{m4:-D__SH4__} \ - %{!m3e:%{!m4:-D__SH3__ -D__sh3__}} \ + %{!m4:%{m4-nofpu:-D__SH4__ -D__SH4_NOFPU__}} \ + %{!m4:%{!m4-nofpu:-D__SH3__ -D__sh3__}} \ %{fPIC:-D__PIC__ -D__pic__} \ %{fpic:-D__PIC__ -D__pic__} \ %{posix:-D_POSIX_SOURCE} \ @@ -59,11 +59,11 @@ #undef CC1_SPEC #define CC1_SPEC \ - "-musermode %{!mb:-ml} %{!m3e:%{!m4:-m3}}" + "-musermode %{!mb:-ml} %{!m4:%{!m4-nofpu:-m3}}" #undef CC1PLUS_SPEC #define CC1PLUS_SPEC \ - "-musermode %{!mb:-ml} %{!m3e:%{!m4:-m3}}" + "-musermode %{!mb:-ml} %{!m4:%{!m4-nofpu:-m3}}" #undef LINK_SPEC #define LINK_SPEC \ @@ -71,7 +71,7 @@ %{shared:-shared} \ %{!static: \ %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker /lib/ld.so.1} \ + %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2} \ %{!rpath:-rpath /lib}} \ %{static:-static}" --- gcc.orig/gcc/config/sh/t-linux Mon Jun 11 21:27:46 2001 +++ gcc/gcc/config/sh/t-linux Mon Jun 11 21:29:05 2001 @@ -4,7 +4,7 @@ _movstr_i4 _mulsi3 _sdivsi3 _sdivsi3_i4 _udivsi3 _udivsi3_i4 _set_fpscr \ _ic_invalidate -MULTILIB_OPTIONS= mb m3e/m4 +MULTILIB_OPTIONS= m4 MULTILIB_DIRNAMES= MULTILIB_MATCHES = But it doesn't work for user-mode stuff. :( And here's the minor gcc-3.0 build patch for Linux 2.4.5: --- include/linux/sched-orig.h Mon Jun 18 18:45:18 2001 +++ include/linux/sched.h Mon Jun 18 18:45:27 2001 @@ -537,7 +537,7 @@ extern unsigned long volatile jiffies; extern unsigned long itimer_ticks; extern unsigned long itimer_next; -extern struct timeval xtime; +extern volatile struct timeval xtime; extern void do_timer(struct pt_regs *); extern unsigned int * prof_buffer; Suggestions? (Thanks in advance) Regards, Bryan -- Bryan Rittmeyer mailto:br...@ix... |
From: Masahiro A. <m-...@aa...> - 2001-06-12 05:50:10
|
Hi all, I've written code fragments to support simple irq mask register located in our own SH4 board. Each bit of word size register works as a "mask" for each interrupt, and each interrupt can be masked independently. I thought this is pretty simple, general in concept and not only for our board, so I submit code here for review and possible inclusion into linux-sh kernel. (Is this the right way to submit patches/changes?) Any comments/suggestions will be appreciated. ----------------------------------------------------------------------- diff -ruN linux-2.4.4-sh.orig/arch/sh/kernel/irq_maskreg.c linux-2.4.4-adx/arch/sh/kernel/irq_maskreg.c --- linux-2.4.4-sh.orig/arch/sh/kernel/irq_maskreg.c Thu Jan 1 09:00:00 1970 +++ linux-2.4.4-adx/arch/sh/kernel/irq_maskreg.c Tue Jun 12 14:35:14 2001 @@ -0,0 +1,106 @@ +/* + * linux/arch/sh/kernel/irq_maskreg.c + * + * Copyright (C) 2001 A&D Co., Ltd. <http://www.aandd.co.jp> + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Interrupt handling for Simple external interrupt mask register + * + * This is for the machine which have single 16 bit register + * for masking external IRQ individually. + * Each bit of the register is for masking each interrupt. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/irq.h> + +#include <asm/system.h> +#include <asm/io.h> +#include <asm/machvec.h> + +/* address of external interrupt mask register + * address must be set prior to use these (maybe in init_XXX_irq()) + * XXX : is it better to use .config than specifying it in code? */ +unsigned short *irq_mask_register = 0; + +/* forward declaration */ +static unsigned int startup_maskreg_irq(unsigned int irq); +static void shutdown_maskreg_irq(unsigned int irq); +static void enable_maskreg_irq(unsigned int irq); +static void disable_maskreg_irq(unsigned int irq); +static void mask_and_ack_maskreg(unsigned int); +static void end_maskreg_irq(unsigned int irq); + +/* hw_interrupt_type */ +static struct hw_interrupt_type maskreg_irq_type = { + " Mask Register", + startup_maskreg_irq, + shutdown_maskreg_irq, + enable_maskreg_irq, + disable_maskreg_irq, + mask_and_ack_maskreg, + end_maskreg_irq +}; + +/* actual implementatin */ +static unsigned int startup_maskreg_irq(unsigned int irq) +{ + enable_maskreg_irq(irq); + return 0; /* never anything pending */ +} + +static void shutdown_maskreg_irq(unsigned int irq) +{ + disable_maskreg_irq(irq); +} + +static void disable_maskreg_irq(unsigned int irq) +{ + if (irq_mask_register) { + unsigned long flags; + unsigned short val, mask = 0x01 << irq; + + /* Set "irq"th bit */ + save_and_cli(flags); + val = ctrl_inw((unsigned long)irq_mask_register); + val |= mask; + ctrl_outw(val, (unsigned long)irq_mask_register); + restore_flags(flags); + } +} + +static void enable_maskreg_irq(unsigned int irq) +{ + if (irq_mask_register) { + unsigned long flags; + unsigned short val, mask = ~(0x01 << irq); + + /* Clear "irq"th bit */ + save_and_cli(flags); + val = ctrl_inw((unsigned long)irq_mask_register); + val &= mask; + ctrl_outw(val, (unsigned long)irq_mask_register); + restore_flags(flags); + } +} + +static void mask_and_ack_maskreg(unsigned int irq) +{ + disable_maskreg_irq(irq); +} + +static void end_maskreg_irq(unsigned int irq) +{ + enable_maskreg_irq(irq); +} + +void make_maskreg_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &maskreg_irq_type; + enable_irq(irq); +} diff -ruN linux-2.4.4-sh.orig/include/asm-sh/irq.h linux-2.4.4-adx/include/asm-sh/irq.h --- linux-2.4.4-sh.orig/include/asm-sh/irq.h Thu May 3 15:10:17 2001 +++ linux-2.4.4-adx/include/asm-sh/irq.h Tue Jun 12 14:36:37 2001 @@ -167,6 +167,8 @@ extern void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority); extern void make_imask_irq(unsigned int irq); +extern void make_maskreg_irq(unsigned int irq); +extern unsigned short *irq_mask_register; #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) #define INTC_IRR0 0xa4000004UL ----------------------------------------------------------------------- +-------------------------------------+ | Masahiro Abe, Software Engineer | | A&D Co., Ltd. of Tokyo, Japan | | mailto:m-...@aa... | +-------------------------------------+ |This is my opinion, not my employer's| +-------------------------------------+ |
From: Masahiro A. <m-...@aa...> - 2001-06-11 07:32:14
|
On Sun, 10 Jun 2001 14:36:50 +1000 Greg Banks <gn...@al...> wrote: > Masahiro Abe wrote: > > > I don't want to touch linux/mm/memory.c but couldn't come up with better > > idea than this. > > The correct solution would be to compile in the existing but unused > ioremap() code, but rename it to something else like ioremap_real(). > Sadly I am unable to fix this. Well, I've tried the way Greg suggested. It is working. Which is preferred modification? (I prefer this one over the previous patch.), Or, much better way out there than those? Some notes: -Same as the previous patch, config.in needs the later half of last hunk only. -I removed "make_imask_irq/disable_irq" call from cf_init_default and put "make_imask_irq" call only into init_adx_irq. Calling "disable_irq" in cf_init_default causes "lost interrupt" at Partition check. This may be because startup_imask_irq doesn't do anything. I guess it should call enable_imask_irq. --------------------------------------------------------------------- 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 Mon Jun 11 16:00:08 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,15 +30,58 @@ * 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 + +extern void * ioremap_real(unsigned long phys_addr, unsigned long size, unsigned long flags); + +void *cf_io_base; + +static int __init allocate_cf_area(void) +{ + pgprot_t prot; + unsigned long paddrbase, psize; + +/* open I/O area window */ + paddrbase = virt_to_phys((void*)CONFIG_CF_BASE_ADDR); + psize = PAGE_SIZE; + prot = PAGE_KERNEL_PCC(slot_no, _PAGE_PCC_IO16); + cf_io_base = ioremap_real(paddrbase, psize, prot.pgprot); + if (!cf_io_base) { + printk("allocate_cf_area : can't open CF I/O window!\n"); + return -ENOMEM; + } +/* printk("ioremap_real(paddr=0x%08lx, psize=0x%08lx, prot=0x%08lx)=0x%08lx\n", + paddrbase, psize, prot.pgprot, cf_io_base);*/ + + /* 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); +/* make_imask_irq(14); + disable_irq(14);*/ return 0; } diff -ruN linux-2.4.4-sh.orig/arch/sh/mm/Makefile linux-2.4.4-adx/arch/sh/mm/Makefile --- linux-2.4.4-sh.orig/arch/sh/mm/Makefile Thu May 3 14:33:25 2001 +++ linux-2.4.4-adx/arch/sh/mm/Makefile Mon Jun 11 15:33:56 2001 @@ -8,6 +8,7 @@ # Note 2! The CFLAGS definition is now in the main makefile... O_TARGET := mm.o -obj-y := init.o fault.o extable.o cache.o # ioremap.o +#obj-y := init.o fault.o extable.o cache.o # ioremap.o +obj-y := init.o fault.o extable.o cache.o ioremap.o include $(TOPDIR)/Rules.make diff -ruN linux-2.4.4-sh.orig/arch/sh/mm/ioremap.c linux-2.4.4-adx/arch/sh/mm/ioremap.c --- linux-2.4.4-sh.orig/arch/sh/mm/ioremap.c Thu May 3 14:33:25 2001 +++ linux-2.4.4-adx/arch/sh/mm/ioremap.c Mon Jun 11 15:33:43 2001 @@ -106,7 +106,8 @@ * have to convert them into an offset in a page-aligned mapping, but the * caller shouldn't need to know that small detail. */ -void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) +/*void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)*/ +void * ioremap_real(unsigned long phys_addr, unsigned long size, unsigned long flags) { void * addr; struct vm_struct * area; @@ -150,7 +151,8 @@ return (void *) (offset + (char *)addr); } -void iounmap(void *addr) +/*void iounmap(void *addr)*/ +void iounmap_real(void *addr) { if (addr > high_memory) return vfree((void *) (PAGE_MASK & (unsigned long) addr)); --------------------------------------------------------------------- +-------------------------------------+ | Masahiro Abe, Software Engineer | | A&D Co., Ltd. of Tokyo, Japan | | mailto:m-...@aa... | +-------------------------------------+ |This is my opinion, not my employer's| +-------------------------------------+ |
From: Masahiro A. <m-...@aa...> - 2001-06-11 00:11:29
|
On Sun, 10 Jun 2001 14:36:50 +1000 Greg Banks <gn...@al...> wrote: > The rest of the code looks fine to me. > > > I don't want to touch linux/mm/memory.c but couldn't come up with better > > idea than this. > > The reason this seems to be needed is that the hd64465_ss.c code > (which you have copied) uses remap_page_range() to do the job of > ioremap() without having an ioremap(). The ioremap() call is > defined as a null operation on SuperH for good reasons, but it's > actually needed in this case. > > The correct solution would be to compile in the existing but unused > ioremap() code, but rename it to something else like ioremap_real(). > Sadly I am unable to fix this. Thank you for your comment, Greg. I tried to use arch/sh/mm/ioremap.c but it failed to compile since it #includes <asm/io.h> and __ioremap redefinition occurs. I don't know the current state of ioremap.c, why it is not linked into kernel, whether it's still maintained or not, whether it is ok to modify it so that it can be used for this particular case. So, this time I chose the way around. If ioremap.c was created exactly in the way this case needs, then I can try to modify ioremap.c and use it for this case (actually I prefer this). I would like to get advice/opinion about this case from someone who have more insight about this (Niibe-san?), if possible. +-------------------------------------+ | Masahiro Abe, Software Engineer | | A&D Co., Ltd. of Tokyo, Japan | | mailto:m-...@aa... | +-------------------------------------+ |This is my opinion, not my employer's| +-------------------------------------+ |
From: Greg B. <gn...@al...> - 2001-06-10 04:26:51
|
Masahiro Abe wrote: > The rest of the code looks fine to me. > I don't want to touch linux/mm/memory.c but couldn't come up with better > idea than this. > 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; The reason this seems to be needed is that the hd64465_ss.c code (which you have copied) uses remap_page_range() to do the job of ioremap() without having an ioremap(). The ioremap() call is defined as a null operation on SuperH for good reasons, but it's actually needed in this case. The correct solution would be to compile in the existing but unused ioremap() code, but rename it to something else like ioremap_real(). Sadly I am unable to fix this. Greg. -- If it's a choice between being a paranoid, hyper-suspicious global village idiot, or a gullible, mega-trusting sheep, I don't look good in mint sauce. - jd, slashdot, 11Feb2000. |
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| +-------------------------------------+ |
From: Masahiro A. <m-...@aa...> - 2001-05-28 01:18:54
|
I've made one correction in the procedure (gcc patch file name was wrong) and uploaded here: <ftp://ftp.aandd.co.jp/pub/linuxsh/buildproc/> This is a link to the most current set of patches and procedure documents. This will not change for each update. +-------------------------------------+ | Masahiro Abe, Software Engineer | | A&D Co., Ltd. of Tokyo, Japan | | mailto:m-...@aa... | +-------------------------------------+ |This is my opinion, not my employer's| +-------------------------------------+ |
From: Stuart M. <Stu...@st...> - 2001-05-25 22:47:13
|
Folks As promised a while ago, attached is a driver for the PS/2 keyboard and mouse ports on the HD64465. This also adds support for general keyboard remapping (using the setkeycodes utility from the console-tools package) to all the SuperH keyboard drivers. All comments welcome. Stuart |