CP0 EntryLo
Hello List,
I am attempting to access a peripheral device over the Au1500 static bus.
According to the Au1500 Databook, Whenever I set the Chip Select config Register DTY bits to 1 (for "I/O Device"), I must also set Bits 29:26 of CoProcessor 0 to 0xD, to represent bits 35:32 of the Physical address.
My question is, if anyone can answer it, is how do I setup The CoProcessor0 registers 29:26 in my driver?
I have noticed a set of functions called write/read_c0_entrylo[0,1], But I keep getting random values when invoking these from my driver.
Thanks,
Gilad.
Quoted 7 lines · Gilad Rom
I am attempting to access a peripheral device over the Au1500 static bus.
According to the Au1500 Databook, Whenever I set the Chip Select config Register DTY bits to 1 (for "I/O Device").
I must also set Bits 29:26 of CoProcessor 0 to
0xD, to represent bits 35:32 of the Physical address.
"CoProcessor 0" is a kind of fiction represented by a whole bunch of registers, so you've wandered a long way into the weeds here.
Quoted 2 lines
My question is, if anyone can answer it, is how do I setup The CoProcessor0 registers 29:26 in my driver?
I think you are referring to the "EntryLo0-1" register pair. These are used as staging registers when reading or writing entries in the TLB, which is the address translation table.
The manual is implying is that you need to set up a TLB entry to access these high physical addresses.
In Linux most of the TLB is maintained by the kernel as a cache of the translations used by user programs. That's probably why you see "random values" from the staging registers; the kernel is busy taking exceptions when required translations aren't in the TLB and fixing them up.
However, the Au1500 hardware permits a small number of TLB entries to be "wired", for fixed functions like your I/O accesses.
I'm not enough of an expert on the Linux kernel to tell you how to set up a wired entry: but grep through the sources and you'll turn something up!
Quoted 2 lines
I have noticed a set of functions called write/read_c0_entrylo[0,1], But I keep getting random values when invoking these from my driver.
I think those are way too low-level for your purposes.
--
Dominic Sweetman
MIPS Technologies
So, what I need to do, if I understand correctly, is to create a fixed mapping
Quoted 11 lines · Gilad Rom
So, what I need to do, if I understand correctly, is to create a fixed mapping
Quoted 1 line
From a virtual address to a physical address on the tlb, and use this
Virtual address to change the values of EntryLo to
0xDin order to Access the device on the address range I mapped Chip-select 1 to?(Excuse my poor phrasing, I've been googling all day...)
Any idea on how I might accomplish that from a driver? I've found a function called
add_wired_entry(...), is this What I should be using?
ioremap()
Maciej
Quoted 8 lines · Maciej W. Rozycki
Quoted 5 lines · Gilad Rom
So, what I need to do, if I understand correctly, is to create a fixed mapping
Quoted 1 line
From a virtual address to a physical address on the tlb, and use this
Virtual address to change the values of EntryLo to
0xDin order to Access the device on the address range I mapped Chip-select 1 to?
Quoted 8 lines
Quoted 5 lines
(Excuse my poor phrasing, I've been googling all day...)
Any idea on how I might accomplish that from a driver? I've found a function called
add_wired_entry(...), is this What I should be using?
ioremap()
Exactly. You program the CS with a physical address. Make sure that address does not overlap with anything else. Then you call ioremap from your driver and you get back a virtual address. You use that virtual address to access the peripheral.
At this stage I would say that probably reading something like the Linux Kernel book or Linux Device Drivers both by Oreilly will really help you.
Pete
Quoted 29 lines
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Pete Popov
Sent: Tuesday, November 30, 2004 8:01 PM
To: Gilad Rom
Cc: Maciej W. Rozycki; [email protected]
Subject: Re: CP0 EntryLoQuoted 4 lines · Maciej W. Rozycki
Quoted 1 line · Gilad Rom
So, what I need to do, if I understand correctly, is to
create a fixed
Quoted 2 lines
Quoted 2 lines
mapping
Quoted 1 line
From a virtual address to a physical address on the tlb,
and use this
Quoted 10 lines
Quoted 8 lines
Virtual address to change the values of EntryLo to
0xDin order to Access the device on the address range I mapped Chip-select 1 to?(Excuse my poor phrasing, I've been googling all day...)
Any idea on how I might accomplish that from a driver? I've found a function called
add_wired_entry(...), is this What I should be using?
Quoted 6 lines
Quoted 1 line
ioremap()Exactly. You program the CS with a physical address. Make sure that address does not overlap with anything else. Then you call ioremap from your driver and you get back a virtual address. You use that virtual address to access the peripheral.
Okay. I've pretty much figured out that part. What I'm puzzled About now is how do change the values of the CP0 EntryLo0/1 Registers, since I've changed the DTY bits to "1" on the MEM_STCFG1 Register (in order to set it to work in "I/O Device" mode) , I need to "change bits 29:26 of CoProcessor 0 to 0xD" (Au1500 Databook quote)
since the Databook doesn't specify an offset
To these registers, I assume they're not like the other Registers I've been dealing with (Chip Select and GPIO).
Quoted 4 lines
At this stage I would say that probably reading something like the Linux Kernel book or Linux Device Drivers both by Oreilly will really help you.
Thanks. Already been doing just that all day... ;)
Quoted 9 lines
Okay. I've pretty much figured out that part. What I'm puzzled
About now is how do change the values of the CP0 EntryLo0/1
Registers, since I've changed the DTY bits to "1" on theMEM_STCFG1
Register (in order to set it to work in "I/O Device" mode) , I need to "change bits 29:26 of CoProcessor 0 to0xD" (Au1500 Databook quote)
since the Databook doesn't specify an offset
To these registers, I assume they're not like the other
Registers I've been dealing with (Chip Select and GPIO).
The reason for the 0XD is because the CS is on a 36 bit physical address. You're in luck because the 36 bit address support went in the 2.6 tree a couple of days ago (I don't remember if you're using 2.4 or 2.6, but 2.4 has the 36 bit support as well). You don't mess with the tlb registers yourself -- you let ioremap do its work. Take a look at drivers/pcmcia/au1000_generic.c and you'll see how the pcmcia CS is remapped. You simply pass the 36 bit phys address and ioremap will do its job.
If there was no 36 bit address support in the kernel, your only option would have been to use a wired tlb, and then you would end up programming the tlb registers directly. In this case there is no reason to do that because ioremap will handle the 36 bit phys address.
Pete