Commit f79fb591 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/sparc-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 950addfa 6c5e2480
...@@ -202,10 +202,33 @@ Utilizing Execution History and Thread Monitoring" ...@@ -202,10 +202,33 @@ Utilizing Execution History and Thread Monitoring"
,institution="US Patent and Trademark Office" ,institution="US Patent and Trademark Office"
,address="Washington, DC" ,address="Washington, DC"
,year="1995" ,year="1995"
,number="US Patent 5,442,758" ,number="US Patent 5,442,758 (contributed under GPL)"
,month="August" ,month="August"
} }
@techreport{Slingwine97
,author="John D. Slingwine and Paul E. McKenney"
,title="Method for maintaining data coherency using thread
activity summaries in a multicomputer system"
,institution="US Patent and Trademark Office"
,address="Washington, DC"
,year="1997"
,number="US Patent 5,608,893 (contributed under GPL)"
,month="March"
}
@techreport{Slingwine98
,author="John D. Slingwine and Paul E. McKenney"
,title="Apparatus and method for achieving reduced overhead
mutual exclusion and maintaining coherency in a multiprocessor
system utilizing execution history and thread monitoring"
,institution="US Patent and Trademark Office"
,address="Washington, DC"
,year="1998"
,number="US Patent 5,727,209 (contributed under GPL)"
,month="March"
}
@Conference{McKenney98 @Conference{McKenney98
,Author="Paul E. McKenney and John D. Slingwine" ,Author="Paul E. McKenney and John D. Slingwine"
,Title="Read-Copy Update: Using Execution History to Solve Concurrency ,Title="Read-Copy Update: Using Execution History to Solve Concurrency
...@@ -229,6 +252,18 @@ Operating System Design and Implementation}" ...@@ -229,6 +252,18 @@ Operating System Design and Implementation}"
,Address="New Orleans, LA" ,Address="New Orleans, LA"
} }
@techreport{Slingwine01
,author="John D. Slingwine and Paul E. McKenney"
,title="Apparatus and method for achieving reduced overhead
mutual exclusion and maintaining coherency in a multiprocessor
system utilizing execution history and thread monitoring"
,institution="US Patent and Trademark Office"
,address="Washington, DC"
,year="2001"
,number="US Patent 5,219,690 (contributed under GPL)"
,month="April"
}
@Conference{McKenney01a @Conference{McKenney01a
,Author="Paul E. McKenney and Jonathan Appavoo and Andi Kleen and ,Author="Paul E. McKenney and Jonathan Appavoo and Andi Kleen and
Orran Krieger and Rusty Russell and Dipankar Sarma and Maneesh Soni" Orran Krieger and Rusty Russell and Dipankar Sarma and Maneesh Soni"
......
...@@ -50,8 +50,8 @@ this case? ...@@ -50,8 +50,8 @@ this case?
Summary Summary
Permitting call_rcu() to immediatly invoke its arguments or permitting Permitting call_rcu() to immediately invoke its arguments or permitting
synchronize_kernel() to immediatly return breaks RCU, even on a UP system. synchronize_kernel() to immediately return breaks RCU, even on a UP system.
So do not do it! Even on a UP system, the RCU infrastructure -must- So do not do it! Even on a UP system, the RCU infrastructure -must-
respect grace periods. respect grace periods.
......
Using RCU to Protect Read-Mostly Arrays
Although RCU is more commonly used to protect linked lists, it can
also be used to protect arrays. Three situations are as follows:
1. Hash Tables
2. Static Arrays
3. Resizeable Arrays
Each of these situations are discussed below.
Situation 1: Hash Tables
Hash tables are often implemented as an array, where each array entry
has a linked-list hash chain. Each hash chain can be protected by RCU
as described in the listRCU.txt document. This approach also applies
to other array-of-list situations, such as radix trees.
Situation 2: Static Arrays
Static arrays, where the data (rather than a pointer to the data) is
located in each array element, and where the array is never resized,
have not been used with RCU. Rik van Riel recommends using seqlock in
this situation, which would also have minimal read-side overhead as long
as updates are rare.
Quick Quiz: Why is it so important that updates be rare when
using seqlock?
Situation 3: Resizeable Arrays
Use of RCU for resizeable arrays is demonstrated by the grow_ary()
function used by the System V IPC code. The array is used to map from
semaphore, message-queue, and shared-memory IDs to the data structure
that represents the corresponding IPC construct. The grow_ary()
function does not acquire any locks; instead its caller must hold the
ids->sem semaphore.
The grow_ary() function, shown below, does some limit checks, allocates a
new ipc_id_ary, copies the old to the new portion of the new, initializes
the remainder of the new, updates the ids->entries pointer to point to
the new array, and invokes ipc_rcu_putref() to free up the old array.
Note that rcu_assign_pointer() is used to update the ids->entries pointer,
which includes any memory barriers required on whatever architecture
you are running on.
static int grow_ary(struct ipc_ids* ids, int newsize)
{
struct ipc_id_ary* new;
struct ipc_id_ary* old;
int i;
int size = ids->entries->size;
if(newsize > IPCMNI)
newsize = IPCMNI;
if(newsize <= size)
return newsize;
new = ipc_rcu_alloc(sizeof(struct kern_ipc_perm *)*newsize +
sizeof(struct ipc_id_ary));
if(new == NULL)
return size;
new->size = newsize;
memcpy(new->p, ids->entries->p,
sizeof(struct kern_ipc_perm *)*size +
sizeof(struct ipc_id_ary));
for(i=size;i<newsize;i++) {
new->p[i] = NULL;
}
old = ids->entries;
/*
* Use rcu_assign_pointer() to make sure the memcpyed
* contents of the new array are visible before the new
* array becomes visible.
*/
rcu_assign_pointer(ids->entries, new);
ipc_rcu_putref(old);
return newsize;
}
The ipc_rcu_putref() function decrements the array's reference count
and then, if the reference count has dropped to zero, uses call_rcu()
to free the array after a grace period has elapsed.
The array is traversed by the ipc_lock() function. This function
indexes into the array under the protection of rcu_read_lock(),
using rcu_dereference() to pick up the pointer to the array so
that it may later safely be dereferenced -- memory barriers are
required on the Alpha CPU. Since the size of the array is stored
with the array itself, there can be no array-size mismatches, so
a simple check suffices. The pointer to the structure corresponding
to the desired IPC object is placed in "out", with NULL indicating
a non-existent entry. After acquiring "out->lock", the "out->deleted"
flag indicates whether the IPC object is in the process of being
deleted, and, if not, the pointer is returned.
struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id)
{
struct kern_ipc_perm* out;
int lid = id % SEQ_MULTIPLIER;
struct ipc_id_ary* entries;
rcu_read_lock();
entries = rcu_dereference(ids->entries);
if(lid >= entries->size) {
rcu_read_unlock();
return NULL;
}
out = entries->p[lid];
if(out == NULL) {
rcu_read_unlock();
return NULL;
}
spin_lock(&out->lock);
/* ipc_rmid() may have already freed the ID while ipc_lock
* was spinning: here verify that the structure is still valid
*/
if (out->deleted) {
spin_unlock(&out->lock);
rcu_read_unlock();
return NULL;
}
return out;
}
Answer to Quick Quiz:
The reason that it is important that updates be rare when
using seqlock is that frequent updates can livelock readers.
One way to avoid this problem is to assign a seqlock for
each array entry rather than to the entire array.
...@@ -18,8 +18,8 @@ equipment outside of the computer, it will at times contain stale data. ...@@ -18,8 +18,8 @@ equipment outside of the computer, it will at times contain stale data.
Therefore, once the route has been computed, there is no need to hold Therefore, once the route has been computed, there is no need to hold
the routing table static during transmission of the packet. After all, the routing table static during transmission of the packet. After all,
you can hold the routing table static all you want, but that won't keep you can hold the routing table static all you want, but that won't keep
the external internet from changing, and it is the state of the external the external Internet from changing, and it is the state of the external
internet that really matters. In addition, routing entries are typically Internet that really matters. In addition, routing entries are typically
added or deleted, rather than being modified in place. added or deleted, rather than being modified in place.
A straightforward example of this use of RCU may be found in the A straightforward example of this use of RCU may be found in the
...@@ -195,7 +195,7 @@ RCU ("read-copy update") its name. The RCU code is as follows: ...@@ -195,7 +195,7 @@ RCU ("read-copy update") its name. The RCU code is as follows:
if (!audit_compare_rule(rule, &e->rule)) { if (!audit_compare_rule(rule, &e->rule)) {
ne = kmalloc(sizeof(*entry), GFP_ATOMIC); ne = kmalloc(sizeof(*entry), GFP_ATOMIC);
if (ne == NULL) if (ne == NULL)
return _ENOMEM; return -ENOMEM;
audit_copy_rule(&ne->rule, &e->rule); audit_copy_rule(&ne->rule, &e->rule);
ne->rule.action = newaction; ne->rule.action = newaction;
ne->rule.file_count = newfield_count; ne->rule.file_count = newfield_count;
...@@ -256,6 +256,12 @@ as follows: ...@@ -256,6 +256,12 @@ as follows:
return AUDIT_BUILD_CONTEXT; return AUDIT_BUILD_CONTEXT;
} }
Note that this example assumes that entries are only added and deleted.
Additional mechanism is required to deal correctly with the
update-in-place performed by audit_upd_rule(). For one thing,
audit_upd_rule() would need additional memory barriers to ensure
that the list_add_rcu() was really executed before the list_del_rcu().
The audit_del_rule() function would need to set the "deleted" The audit_del_rule() function would need to set the "deleted"
flag under the spinlock as follows: flag under the spinlock as follows:
......
RCU Concepts RCU Concepts
The basic idea behind RCU is to split destructive operations into two The basic idea behind RCU (read-copy update) is to split destructive
parts, one that makes anyone from seeing the data item being destroyed, operations into two parts, one that prevents anyone from seeing the data
and one that actually carries out the destruction. A "grace period" item being destroyed, and one that actually carries out the destruction.
must elapse between the two parts, and this grace period must be long A "grace period" must elapse between the two parts, and this grace period
enough that any readers accessing the item being deleted have since must be long enough that any readers accessing the item being deleted have
dropped their references. For example, an RCU-protected deletion from a since dropped their references. For example, an RCU-protected deletion
linked list would first remove the item from the list, wait for a grace from a linked list would first remove the item from the list, wait for
period to elapse, then free the element. See the listRCU.txt file for a grace period to elapse, then free the element. See the listRCU.txt
more information on using RCU with linked lists. file for more information on using RCU with linked lists.
Frequently Asked Questions Frequently Asked Questions
o Why would anyone want to use RCU? o Why would anyone want to use RCU?
The advantage of RCU's two-part approach is that RCU readers need The advantage of RCU's two-part approach is that RCU readers need
...@@ -25,7 +24,6 @@ o Why would anyone want to use RCU? ...@@ -25,7 +24,6 @@ o Why would anyone want to use RCU?
in read-mostly situations. The fact that RCU readers need not in read-mostly situations. The fact that RCU readers need not
acquire locks can also greatly simplify deadlock-avoidance code. acquire locks can also greatly simplify deadlock-avoidance code.
o How can the updater tell when a grace period has completed o How can the updater tell when a grace period has completed
if the RCU readers give no indication when they are done? if the RCU readers give no indication when they are done?
...@@ -51,6 +49,19 @@ o What guidelines should I follow when writing code that uses RCU? ...@@ -51,6 +49,19 @@ o What guidelines should I follow when writing code that uses RCU?
See the checklist.txt file in this directory. See the checklist.txt file in this directory.
o Why the name "RCU"?
"RCU" stands for "read-copy update". The file listRCU.txt has
more information on where this name came from, search for
"read-copy update" to find it.
o I hear that RCU is patented? What is with that?
Yes, it is. There are several known patents related to RCU,
search for the string "Patent" in RTFP.txt to find them.
Of these, one was allowed to lapse by the assignee, and the
others have been contributed to the Linux kernel under GPL.
o Where can I find more information on RCU? o Where can I find more information on RCU?
See the RTFP.txt file in this directory. See the RTFP.txt file in this directory.
...@@ -90,7 +90,7 @@ prototypes: ...@@ -90,7 +90,7 @@ prototypes:
void (*destroy_inode)(struct inode *); void (*destroy_inode)(struct inode *);
void (*read_inode) (struct inode *); void (*read_inode) (struct inode *);
void (*dirty_inode) (struct inode *); void (*dirty_inode) (struct inode *);
void (*write_inode) (struct inode *, int); int (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *); void (*put_inode) (struct inode *);
void (*drop_inode) (struct inode *); void (*drop_inode) (struct inode *);
void (*delete_inode) (struct inode *); void (*delete_inode) (struct inode *);
......
...@@ -176,7 +176,7 @@ filesystem. As of kernel 2.1.99, the following members are defined: ...@@ -176,7 +176,7 @@ filesystem. As of kernel 2.1.99, the following members are defined:
struct super_operations { struct super_operations {
void (*read_inode) (struct inode *); void (*read_inode) (struct inode *);
void (*write_inode) (struct inode *, int); int (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *); void (*put_inode) (struct inode *);
void (*drop_inode) (struct inode *); void (*drop_inode) (struct inode *);
void (*delete_inode) (struct inode *); void (*delete_inode) (struct inode *);
......
...@@ -453,6 +453,11 @@ running once the system is up. ...@@ -453,6 +453,11 @@ running once the system is up.
hd?= [HW] (E)IDE subsystem hd?= [HW] (E)IDE subsystem
hd?lun= See Documentation/ide.txt. hd?lun= See Documentation/ide.txt.
highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact
size of <nn>. This works even on boxes that have no
highmem otherwise. This also works to reduce highmem
size on bigger boxes.
hisax= [HW,ISDN] hisax= [HW,ISDN]
See Documentation/isdn/README.HiSax. See Documentation/isdn/README.HiSax.
...@@ -885,6 +890,13 @@ running once the system is up. ...@@ -885,6 +890,13 @@ running once the system is up.
noacpi [IA-32] Do not use ACPI for IRQ routing noacpi [IA-32] Do not use ACPI for IRQ routing
or for PCI scanning. or for PCI scanning.
firmware [ARM] Do not re-enumerate the bus but
instead just use the configuration
from the bootloader. This is currently
used on IXP2000 systems where the
bus has to be configured a certain way
for adjunct CPUs.
pcmv= [HW,PCMCIA] BadgePAD 4 pcmv= [HW,PCMCIA] BadgePAD 4
pd. [PARIDE] pd. [PARIDE]
...@@ -1286,6 +1298,12 @@ running once the system is up. ...@@ -1286,6 +1298,12 @@ running once the system is up.
This is actually a boot loader parameter; the value is This is actually a boot loader parameter; the value is
passed to the kernel using a special protocol. passed to the kernel using a special protocol.
vmalloc=nn[KMG] [KNL,BOOT] forces the vmalloc area to have an exact
size of <nn>. This can be used to increase the
minimum size (128MB on x86). It can also be used to
decrease the size and leave more room for directly
mapped kernel RAM.
vmhalt= [KNL,S390] vmhalt= [KNL,S390]
vmpoff= [KNL,S390] vmpoff= [KNL,S390]
......
...@@ -156,7 +156,7 @@ cmd_line_ptr: .long 0 # (Header version 0x0202 or later) ...@@ -156,7 +156,7 @@ cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
# can be located anywhere in # can be located anywhere in
# low memory 0x10000 or higher. # low memory 0x10000 or higher.
ramdisk_max: .long (MAXMEM-1) & 0x7fffffff ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
# (Header version 0x0203 or later) # (Header version 0x0203 or later)
# The highest safe address for # The highest safe address for
# the contents of an initrd # the contents of an initrd
......
...@@ -2362,8 +2362,15 @@ static void __exit apm_exit(void) ...@@ -2362,8 +2362,15 @@ static void __exit apm_exit(void)
{ {
int error; int error;
if (set_pm_idle) if (set_pm_idle) {
pm_idle = original_pm_idle; pm_idle = original_pm_idle;
/*
* We are about to unload the current idle thread pm callback
* (pm_idle), Wait for all processors to update cached/local
* copies of pm_idle before proceeding.
*/
synchronize_kernel();
}
if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0) if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0)
&& (apm_info.connection_version > 0x0100)) { && (apm_info.connection_version > 0x0100)) {
error = apm_engage_power_management(APM_DEVICE_ALL, 0); error = apm_engage_power_management(APM_DEVICE_ALL, 0);
......
...@@ -56,7 +56,7 @@ static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int ex ...@@ -56,7 +56,7 @@ static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int ex
*/ */
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{ {
unsigned int i, max_long, bytes, bytes_updated; unsigned long i, max_long, bytes, bytes_updated;
struct thread_struct * t = &current->thread; struct thread_struct * t = &current->thread;
struct tss_struct * tss; struct tss_struct * tss;
unsigned long *bitmap; unsigned long *bitmap;
...@@ -105,8 +105,11 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) ...@@ -105,8 +105,11 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
t->io_bitmap_max = bytes; t->io_bitmap_max = bytes;
/* Update the TSS: */ /*
memcpy(tss->io_bitmap, t->io_bitmap_ptr, bytes_updated); * Sets the lazy trigger so that the next I/O operation will
* reload the correct bitmap.
*/
tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
put_cpu(); put_cpu();
......
...@@ -142,13 +142,21 @@ void cpu_idle (void) ...@@ -142,13 +142,21 @@ void cpu_idle (void)
/* endless idle loop with no priority at all */ /* endless idle loop with no priority at all */
while (1) { while (1) {
while (!need_resched()) { while (!need_resched()) {
void (*idle)(void) = pm_idle; void (*idle)(void);
/*
* Mark this as an RCU critical section so that
* synchronize_kernel() in the unload path waits
* for our completion.
*/
rcu_read_lock();
idle = pm_idle;
if (!idle) if (!idle)
idle = default_idle; idle = default_idle;
irq_stat[smp_processor_id()].idle_timestamp = jiffies; irq_stat[smp_processor_id()].idle_timestamp = jiffies;
idle(); idle();
rcu_read_unlock();
} }
schedule(); schedule();
} }
...@@ -301,8 +309,11 @@ void exit_thread(void) ...@@ -301,8 +309,11 @@ void exit_thread(void)
/* /*
* Careful, clear this in the TSS too: * Careful, clear this in the TSS too:
*/ */
memset(tss->io_bitmap, 0xff, t->io_bitmap_max); memset(tss->io_bitmap, 0xff, tss->io_bitmap_max);
t->io_bitmap_max = 0; t->io_bitmap_max = 0;
tss->io_bitmap_owner = NULL;
tss->io_bitmap_max = 0;
tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
put_cpu(); put_cpu();
} }
} }
...@@ -472,6 +483,37 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) ...@@ -472,6 +483,37 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
return 1; return 1;
} }
static inline void
handle_io_bitmap(struct thread_struct *next, struct tss_struct *tss)
{
if (!next->io_bitmap_ptr) {
/*
* Disable the bitmap via an invalid offset. We still cache
* the previous bitmap owner and the IO bitmap contents:
*/
tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
return;
}
if (likely(next == tss->io_bitmap_owner)) {
/*
* Previous owner of the bitmap (hence the bitmap content)
* matches the next task, we dont have to do anything but
* to set a valid offset in the TSS:
*/
tss->io_bitmap_base = IO_BITMAP_OFFSET;
return;
}
/*
* Lazy TSS's I/O bitmap copy. We set an invalid offset here
* and we let the task to get a GPF in case an I/O instruction
* is performed. The handler of the GPF will verify that the
* faulting task has a valid I/O bitmap and, it true, does the
* real copy and restart the instruction. This will save us
* redundant copies when the currently switched task does not
* perform any I/O during its timeslice.
*/
tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
}
/* /*
* This special macro can be used to load a debugging register * This special macro can be used to load a debugging register
*/ */
...@@ -556,20 +598,9 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas ...@@ -556,20 +598,9 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
loaddebug(next, 7); loaddebug(next, 7);
} }
if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) { if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr))
if (next->io_bitmap_ptr) handle_io_bitmap(next, tss);
/*
* Copy the relevant range of the IO bitmap.
* Normally this is 128 bytes or less:
*/
memcpy(tss->io_bitmap, next->io_bitmap_ptr,
max(prev->io_bitmap_max, next->io_bitmap_max));
else
/*
* Clear any possible leftover bits:
*/
memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
}
return prev_p; return prev_p;
} }
......
...@@ -815,6 +815,14 @@ static void __init parse_cmdline_early (char ** cmdline_p) ...@@ -815,6 +815,14 @@ static void __init parse_cmdline_early (char ** cmdline_p)
if (c == ' ' && !memcmp(from, "highmem=", 8)) if (c == ' ' && !memcmp(from, "highmem=", 8))
highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT; highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
/*
* vmalloc=size forces the vmalloc area to be exactly 'size'
* bytes. This can be used to increase (or decrease) the
* vmalloc area - the default is 128m.
*/
if (c == ' ' && !memcmp(from, "vmalloc=", 8))
__VMALLOC_RESERVE = memparse(from+8, &from);
c = *(from++); c = *(from++);
if (!c) if (!c)
break; break;
......
...@@ -475,10 +475,40 @@ DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun ...@@ -475,10 +475,40 @@ DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun
DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
DO_ERROR(12, SIGBUS, "stack segment", stack_segment) DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr2()) DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
{ {
int cpu = get_cpu();
struct tss_struct *tss = &per_cpu(init_tss, cpu);
struct thread_struct *thread = &current->thread;
/*
* Perform the lazy TSS's I/O bitmap copy. If the TSS has an
* invalid offset set (the LAZY one) and the faulting thread has
* a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS
* and we set the offset field correctly. Then we let the CPU to
* restart the faulting instruction.
*/
if (tss->io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY &&
thread->io_bitmap_ptr) {
memcpy(tss->io_bitmap, thread->io_bitmap_ptr,
thread->io_bitmap_max);
/*
* If the previously set map was extending to higher ports
* than the current one, pad extra space with 0xff (no access).
*/
if (thread->io_bitmap_max < tss->io_bitmap_max)
memset((char *) tss->io_bitmap +
thread->io_bitmap_max, 0xff,
tss->io_bitmap_max - thread->io_bitmap_max);
tss->io_bitmap_max = thread->io_bitmap_max;
tss->io_bitmap_base = IO_BITMAP_OFFSET;
put_cpu();
return;
}
put_cpu();
if (regs->eflags & VM_MASK) if (regs->eflags & VM_MASK)
goto gp_in_vm86; goto gp_in_vm86;
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/sections.h> #include <asm/sections.h>
unsigned int __VMALLOC_RESERVE = 128 << 20;
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
unsigned long highstart_pfn, highend_pfn; unsigned long highstart_pfn, highend_pfn;
......
...@@ -228,18 +228,26 @@ cpu_idle (void *unused) ...@@ -228,18 +228,26 @@ cpu_idle (void *unused)
/* endless idle loop with no priority at all */ /* endless idle loop with no priority at all */
while (1) { while (1) {
void (*idle)(void) = pm_idle;
if (!idle)
idle = default_idle;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
if (!need_resched()) if (!need_resched())
min_xtp(); min_xtp();
#endif #endif
while (!need_resched()) { while (!need_resched()) {
void (*idle)(void);
if (mark_idle) if (mark_idle)
(*mark_idle)(1); (*mark_idle)(1);
/*
* Mark this as an RCU critical section so that
* synchronize_kernel() in the unload path waits
* for our completion.
*/
rcu_read_lock();
idle = pm_idle;
if (!idle)
idle = default_idle;
(*idle)(); (*idle)();
rcu_read_unlock();
} }
if (mark_idle) if (mark_idle)
......
...@@ -64,6 +64,8 @@ extern unsigned char acpi_kbd_controller_present; ...@@ -64,6 +64,8 @@ extern unsigned char acpi_kbd_controller_present;
unsigned long sn_rtc_cycles_per_second; unsigned long sn_rtc_cycles_per_second;
EXPORT_SYMBOL(sn_rtc_cycles_per_second);
partid_t sn_partid = -1; partid_t sn_partid = -1;
char sn_system_serial_number_string[128]; char sn_system_serial_number_string[128];
u64 sn_partition_serial_number; u64 sn_partition_serial_number;
......
This diff is collapsed.
#
# m32r/Makefile
#
LDFLAGS :=
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
LDFLAGS_vmlinux := -e startup_32
LDFLAGS_BLOB := --format binary --oformat elf32-m32r
CFLAGS += -pipe -fno-schedule-insns
CFLAGS_KERNEL += -mmodel=medium
CFLAGS_MODULE += -mmodel=large
ifdef CONFIG_CHIP_VDEC2
cflags-$(CONFIG_ISA_M32R2) += -DNO_FPU -Wa,-bitinst
aflags-$(CONFIG_ISA_M32R2) += -DNO_FPU -Wa,-bitinst
else
cflags-$(CONFIG_ISA_M32R2) += -DNO_FPU -m32r2
aflags-$(CONFIG_ISA_M32R2) += -DNO_FPU -m32r2
endif
cflags-$(CONFIG_ISA_M32R) += -DNO_FPU
aflags-$(CONFIG_ISA_M32R) += -DNO_FPU -Wa,-no-bitinst
CFLAGS += $(cflags-y)
AFLAGS += $(aflags-y)
CHECK := $(CHECK) -D__m32r__=1
head-y := arch/m32r/kernel/head.o arch/m32r/kernel/init_task.o
LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
libs-y += arch/m32r/lib/ $(LIBGCC)
core-y += arch/m32r/kernel/ \
arch/m32r/mm/ \
arch/m32r/boot/
drivers-y += arch/m32r/drivers/
drivers-$(CONFIG_OPROFILE) += arch/m32r/oprofile/
boot := arch/m32r/boot
.PHONY: zImage
zImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
compressed: zImage
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
define archhelp
@echo ' zImage - Compressed kernel image (arch/m32r/boot/zImage)'
endef
#
# arch/m32r/boot/Makefile
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
targets := zImage
subdir- := compressed
obj-y := setup.o
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
@echo 'Kernel: $@ is ready'
$(obj)/compressed/vmlinux: FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
#
# linux/arch/sh/boot/compressed/Makefile
#
# create a compressed vmlinux image from the original vmlinux
#
targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o \
m32r-sio.o piggy.o vmlinux.lds
EXTRA_AFLAGS := -traditional
OBJECTS = $(obj)/head.o $(obj)/misc.o $(obj)/m32r_sio.o
#
# IMAGE_OFFSET is the load offset of the compression loader
#
#IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_MEMORY_START)+0x2000])
#IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_MEMORY_START)+0x00400000])
LDFLAGS_vmlinux := -T
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(obj)/piggy.o FORCE
$(call if_changed,ld)
@:
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.S FORCE
$(CPP) $(EXTRA_AFLAGS) -C -P -I include $< >$@
LDFLAGS_piggy.o := -r --format binary --oformat elf32-m32r-linux -T
OBJCOPYFLAGS += -R .empty_zero_page
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
$(call if_changed,ld)
/*
* 1. load vmlinuz
*
* CONFIG_MEMORY_START +-----------------------+
* | vmlinuz |
* +-----------------------+
* 2. decompressed
*
* CONFIG_MEMORY_START +-----------------------+
* | vmlinuz |
* +-----------------------+
* | |
* BOOT_RELOC_ADDR +-----------------------+
* | |
* KERNEL_DECOMPRESS_ADDR +-----------------------+
* | vmlinux |
* +-----------------------+
*
* 3. relocate copy & jump code
*
* CONFIG_MEMORY_START +-----------------------+
* | vmlinuz |
* +-----------------------+
* | |
* BOOT_RELOC_ADDR +-----------------------+
* | boot(copy&jump) |
* KERNEL_DECOMPRESS_ADDR +-----------------------+
* | vmlinux |
* +-----------------------+
*
* 4. relocate decompressed kernel
*
* CONFIG_MEMORY_START +-----------------------+
* | vmlinux |
* +-----------------------+
* | |
* BOOT_RELOC_ADDR +-----------------------+
* | boot(copy&jump) |
* KERNEL_DECOMPRESS_ADDR +-----------------------+
* | |
* +-----------------------+
*
*/
#ifdef __ASSEMBLY__
#define __val(x) x
#else
#define __val(x) (x)
#endif
#define DECOMPRESS_OFFSET_BASE __val(0x00900000)
#define BOOT_RELOC_SIZE __val(0x00001000)
#define KERNEL_EXEC_ADDR __val(CONFIG_MEMORY_START)
#define KERNEL_DECOMPRESS_ADDR __val(CONFIG_MEMORY_START + \
DECOMPRESS_OFFSET_BASE + BOOT_RELOC_SIZE)
#define KERNEL_ENTRY __val(CONFIG_MEMORY_START + 0x1000)
#define BOOT_EXEC_ADDR __val(CONFIG_MEMORY_START)
#define BOOT_RELOC_ADDR __val(CONFIG_MEMORY_START + DECOMPRESS_OFFSET_BASE)
/*
* linux/arch/m32r/boot/compressed/head.S
*
* Copyright (c) 2001-2003 Hiroyuki Kondo, Hirokazu Takata,
* Hitoshi Yamamoto, Takeo Takahashi
* Copyright (c) 2004 Hirokazu Takata
*/
.text
#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/addrspace.h>
#include <asm/page.h>
#include <asm/assembler.h>
.global startup
__ALIGN
startup:
ldi r0, #0x0000 /* SPI, disable EI */
mvtc r0, psw
/*
* Clear BSS first so that there are no surprises...
*/
#ifdef CONFIG_ISA_DUAL_ISSUE
LDIMM (r2, __bss_start)
LDIMM (r3, _end)
sub r3, r2 ; BSS size in bytes
; R4 = BSS size in longwords (rounded down)
mv r4, r3 || ldi r1, #0
srli r4, #4 || addi r2, #-4
beqz r4, .Lendloop1
.Lloop1:
#ifndef CONFIG_CHIP_M32310
; Touch memory for the no-write-allocating cache.
ld r0, @(4,r2)
#endif
st r1, @+r2 || addi r4, #-1
st r1, @+r2
st r1, @+r2
st r1, @+r2 || cmpeq r1, r4 ; R4 = 0?
bnc .Lloop1
.Lendloop1:
and3 r4, r3, #15
addi r2, #4
beqz r4, .Lendloop2
.Lloop2:
stb r1, @r2 || addi r4, #-1
addi r2, #1
bnez r4, .Lloop2
.Lendloop2:
#else /* not CONFIG_ISA_DUAL_ISSUE */
LDIMM (r2, __bss_start)
LDIMM (r3, _end)
sub r3, r2 ; BSS size in bytes
mv r4, r3
srli r4, #2 ; R4 = BSS size in longwords (rounded down)
ldi r1, #0 ; clear R1 for longwords store
addi r2, #-4 ; account for pre-inc store
beqz r4, .Lendloop1 ; any more to go?
.Lloop1:
st r1, @+r2 ; yep, zero out another longword
addi r4, #-1 ; decrement count
bnez r4, .Lloop1 ; go do some more
.Lendloop1:
and3 r4, r3, #3 ; get no. of remaining BSS bytes to clear
addi r2, #4 ; account for pre-inc store
beqz r4, .Lendloop2 ; any more to go?
.Lloop2:
stb r1, @r2 ; yep, zero out another byte
addi r2, #1 ; bump address
addi r4, #-1 ; decrement count
bnez r4, .Lloop2 ; go do some more
.Lendloop2:
#endif /* not CONFIG_ISA_DUAL_ISSUE */
seth r0, #shigh(stack_start)
ld sp, @(r0, low(stack_start)) /* set stack point */
/*
* decompress the kernel
*/
bl decompress_kernel
#if defined(CONFIG_CHIP_M32700)
/* Cache flush */
ldi r0, -1
ldi r1, 0xd0 ; invalidate i-cache, copy back d-cache
stb r1, @r0
#else
#error "put your cache flush function, please"
#endif
seth r0, #high(CONFIG_MEMORY_START)
or3 r0, r0, #0x2000
jmp r0
.balign 512
fake_headers_as_bzImage:
.short 0
.ascii "HdrS"
.short 0x0202
.short 0
.short 0
.byte 0x00, 0x10
.short 0
.byte 0
.byte 1
.byte 0x00, 0x80
.long 0
.long 0
#!/bin/sh
#
# arch/sh/boot/install.sh
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1995 by Linus Torvalds
#
# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
# Adapted from code in arch/i386/boot/install.sh by Russell King
# Adapted from code in arch/arm/boot/install.sh by Stuart Menefy
# Adapted from code in arch/sh/boot/install.sh by Takeo Takahashi
#
# "make install" script for sh architecture
#
# Arguments:
# $1 - kernel version
# $2 - kernel image file
# $3 - kernel map file
# $4 - default install path (blank if root directory)
#
# User may have a custom install script
if [ -x /sbin/installkernel ]; then
exec /sbin/installkernel "$@"
fi
if [ "$2" = "zImage" ]; then
# Compressed install
echo "Installing compressed kernel"
if [ -f $4/vmlinuz-$1 ]; then
mv $4/vmlinuz-$1 $4/vmlinuz.old
fi
if [ -f $4/System.map-$1 ]; then
mv $4/System.map-$1 $4/System.old
fi
cat $2 > $4/vmlinuz-$1
cp $3 $4/System.map-$1
else
# Normal install
echo "Installing normal kernel"
if [ -f $4/vmlinux-$1 ]; then
mv $4/vmlinux-$1 $4/vmlinux.old
fi
if [ -f $4/System.map ]; then
mv $4/System.map $4/System.old
fi
cat $2 > $4/vmlinux-$1
cp $3 $4/System.map
fi
/*
* arch/m32r/boot/compressed/m32r_sio.c
*
* 2003-02-12: Takeo Takahashi
*
*/
#include <linux/config.h>
#include <asm/m32r.h>
#include <asm/io.h>
void putc(char c);
int puts(const char *s)
{
char c;
while ((c = *s++)) putc(c);
return 0;
}
#if defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_M32700UT)
#define USE_FPGA_MAP 0
#if USE_FPGA_MAP
/*
* fpga configuration program uses MMU, and define map as same as
* M32104 uT-Engine board.
*/
#define BOOT_SIO0STS (volatile unsigned short *)(0x02c00000 + 0x20006)
#define BOOT_SIO0TXB (volatile unsigned short *)(0x02c00000 + 0x2000c)
#else
#undef PLD_BASE
#define PLD_BASE 0xa4c00000
#define BOOT_SIO0STS PLD_ESIO0STS
#define BOOT_SIO0TXB PLD_ESIO0TXB
#endif
void putc(char c)
{
while ((*BOOT_SIO0STS & 0x3) != 0x3) ;
if (c == '\n') {
*BOOT_SIO0TXB = '\r';
while ((*BOOT_SIO0STS & 0x3) != 0x3) ;
}
*BOOT_SIO0TXB = c;
}
#else
void putc(char c)
{
/* do nothing */
}
#endif
/*
* arch/m32r/boot/compressed/misc.c
*
* This is a collection of several routines from gzip-1.0.3
* adapted for Linux.
*
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
*
* Adapted for SH by Stuart Menefy, Aug 1999
*
* Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
*
* 2003-02-12: Support M32R by Takeo Takahashi
* This is based on arch/sh/boot/compressed/misc.c.
*/
#include <linux/config.h>
#include <linux/string.h>
/*
* gzip declarations
*/
#define OF(args) args
#define STATIC static
#undef memset
#undef memcpy
#define memzero(s, n) memset ((s), 0, (n))
typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;
#define WSIZE 0x8000 /* Window size must be at least 32k, */
/* and a power of two */
static uch *inbuf; /* input buffer */
static uch window[WSIZE]; /* Sliding window buffer */
static unsigned insize; /* valid bytes in inbuf */
static unsigned inptr; /* index of next byte to be processed in inbuf */
static unsigned outcnt; /* bytes in output buffer */
/* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
#define COMMENT 0x10 /* bit 4 set: file comment present */
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
#define RESERVED 0xC0 /* bit 6,7: reserved */
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
/* Diagnostic functions */
#ifdef DEBUG
# define Assert(cond,msg) {if(!(cond)) error(msg);}
# define Trace(x) fprintf x
# define Tracev(x) {if (verbose) fprintf x ;}
# define Tracevv(x) {if (verbose>1) fprintf x ;}
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
# define Tracec(c,x)
# define Tracecv(c,x)
#endif
static int fill_inbuf(void);
static void flush_window(void);
static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
extern char input_data[];
extern int input_len;
static long bytes_out;
static uch *output_data;
static unsigned long output_ptr;
static void *malloc(int size);
static void free(void *where);
static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
extern int puts(const char *);
extern int _text; /* Defined in vmlinux.lds.S */
extern int _end;
static unsigned long free_mem_ptr;
static unsigned long free_mem_end_ptr;
#define HEAP_SIZE 0x10000
#include "../../../../lib/inflate.c"
static void *malloc(int size)
{
void *p;
if (size <0) error("Malloc error\n");
if (free_mem_ptr == 0) error("Memory error\n");
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *)free_mem_ptr;
free_mem_ptr += size;
if (free_mem_ptr >= free_mem_end_ptr)
error("\nOut of memory\n");
return p;
}
static void free(void *where)
{ /* Don't care */
}
static void gzip_mark(void **ptr)
{
*ptr = (void *) free_mem_ptr;
}
static void gzip_release(void **ptr)
{
free_mem_ptr = (long) *ptr;
}
void* memset(void* s, int c, size_t n)
{
int i;
char *ss = (char*)s;
for (i=0;i<n;i++) ss[i] = c;
return s;
}
void* memcpy(void* __dest, __const void* __src,
size_t __n)
{
int i;
char *d = (char *)__dest, *s = (char *)__src;
for (i=0;i<__n;i++) d[i] = s[i];
return __dest;
}
/* ===========================================================================
* Fill the input buffer. This is called only when the buffer is empty
* and at least one byte is really needed.
*/
static int fill_inbuf(void)
{
if (insize != 0) {
error("ran out of input data\n");
}
inbuf = input_data;
insize = input_len;
inptr = 1;
return inbuf[0];
}
/* ===========================================================================
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
* (Used for the decompressed data only.)
*/
static void flush_window(void)
{
ulg c = crc; /* temporary variable */
unsigned n;
uch *in, *out, ch;
in = window;
out = &output_data[output_ptr];
for (n = 0; n < outcnt; n++) {
ch = *out++ = *in++;
c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
}
crc = c;
bytes_out += (ulg)outcnt;
output_ptr += (ulg)outcnt;
outcnt = 0;
}
static void error(char *x)
{
puts("\n\n");
puts(x);
puts("\n\n -- System halted");
while(1); /* Halt */
}
#define STACK_SIZE (4096)
long user_stack [STACK_SIZE];
long* stack_start = &user_stack[STACK_SIZE];
/* return decompressed size */
long decompress_kernel(void)
{
insize = 0;
inptr = 0;
bytes_out = 0;
outcnt = 0;
output_data = 0;
output_ptr = CONFIG_MEMORY_START + 0x2000;
free_mem_ptr = (unsigned long)&_end;
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
makecrc();
puts("Uncompressing Linux... ");
gunzip();
puts("Ok, booting the kernel.\n");
return bytes_out;
}
#include <linux/config.h>
OUTPUT_ARCH(m32r)
ENTRY(startup)
SECTIONS
{
. = CONFIG_MEMORY_START + 0x00400000;
_text = .;
.text : { *(.text) } = 0
.rodata : { *(.rodata) }
_etext = .;
. = ALIGN(32) + (. & (32 - 1));
.data : { *(.data) }
_edata = .;
. = ALIGN(32 / 8);
__bss_start = .;
.bss : { *(.bss) }
. = ALIGN(32 / 8);
_end = . ;
}
SECTIONS
{
.data : {
input_len = .;
LONG(input_data_end - input_data) input_data = .;
*(.data)
input_data_end = .;
}
}
/*
* linux/arch/m32r/boot/setup.S -- A setup code.
*
* Copyright (C) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata,
* and Hitoshi Yamamoto
*
*/
/* $Id$ */
#include <linux/linkage.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <linux/config.h>
#include <asm/assembler.h>
#include <asm/mmu_context.h>
#include <asm/m32r.h>
/*
* References to members of the boot_cpu_data structure.
*/
#define CPU_PARAMS boot_cpu_data
#define M32R_MCICAR 0xfffffff0
#define M32R_MCDCAR 0xfffffff4
#define M32R_MCCR 0xfffffffc
#define M32R_BSCR0 0xffffffd2
;BSEL
#define BSEL0CR0 0x00ef5000
#define BSEL0CR1 0x00ef5004
#define BSEL1CR0 0x00ef5100
#define BSEL1CR1 0x00ef5104
#define BSEL0CR0_VAL 0x00000000
#define BSEL0CR1_VAL 0x01200100
#define BSEL1CR0_VAL 0x01018000
#define BSEL1CR1_VAL 0x00200001
;SDRAMC
#define SDRAMC_SDRF0 0x00ef6000
#define SDRAMC_SDRF1 0x00ef6004
#define SDRAMC_SDIR0 0x00ef6008
#define SDRAMC_SDIR1 0x00ef600c
#define SDRAMC_SD0ADR 0x00ef6020
#define SDRAMC_SD0ER 0x00ef6024
#define SDRAMC_SD0TR 0x00ef6028
#define SDRAMC_SD0MOD 0x00ef602c
#define SDRAMC_SD1ADR 0x00ef6040
#define SDRAMC_SD1ER 0x00ef6044
#define SDRAMC_SD1TR 0x00ef6048
#define SDRAMC_SD1MOD 0x00ef604c
#define SDRAM0 0x18000000
#define SDRAM1 0x1c000000
/*------------------------------------------------------------------------
* start up
*/
/*------------------------------------------------------------------------
* Kernel entry
*/
.section .boot, "ax"
ENTRY(boot)
/* Set cache mode */
#if defined(CONFIG_CHIP_XNUX2)
ldi r0, #-2 ;LDIMM (r0, M32R_MCCR)
ldi r1, #0x0101 ; cache on (with invalidation)
; ldi r1, #0x00 ; cache off
sth r1, @r0
#elif defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_VDEC2) \
|| defined(CONFIG_CHIP_OPSP)
ldi r0, #-4 ;LDIMM (r0, M32R_MCCR)
ldi r1, #0x73 ; cache on (with invalidation)
; ldi r1, #0x00 ; cache off
st r1, @r0
#else
#error unknown chip configuration
#endif
#ifdef CONFIG_SMP
;; if not BSP (CPU#0) goto AP_loop
seth r5, #shigh(M32R_CPUID_PORTL)
ld r5, @(low(M32R_CPUID_PORTL), r5)
bnez r5, AP_loop
#if !defined(CONFIG_PLAT_USRV)
;; boot AP
ld24 r5, #0xeff2f8 ; IPICR7
ldi r6, #0x2 ; IPI to CPU1
st r6, @r5
#endif
#endif
/*
* Now, Jump to stext
* if with MMU, TLB on.
* if with no MMU, only jump.
*/
.global eit_vector
mmu_on:
LDIMM (r13, stext)
#ifdef CONFIG_MMU
bl init_tlb
LDIMM (r2, eit_vector) ; set EVB(cr5)
mvtc r2, cr5
seth r0, #high(MMU_REG_BASE) ; Set MMU_REG_BASE higher
or3 r0, r0, #low(MMU_REG_BASE) ; Set MMU_REG_BASE lower
ldi r1, #0x01
st r1, @(MATM_offset,r0) ; Set MATM (T bit ON)
ld r0, @(MATM_offset,r0) ; Check
#else
seth r0,#high(M32R_MCDCAR)
or3 r0,r0,#low(M32R_MCDCAR)
ld24 r1,#0x8080
st r1,@r0
#endif /* CONFIG_MMU */
jmp r13
nop
nop
#ifdef CONFIG_SMP
/*
* AP wait loop
*/
ENTRY(AP_loop)
;; disable interrupt
clrpsw #0x40
;; reset EVB
LDIMM (r4, _AP_RE)
seth r5, #high(__PAGE_OFFSET)
or3 r5, r5, #low(__PAGE_OFFSET)
not r5, r5
and r4, r5
mvtc r4, cr5
;; disable maskable interrupt
seth r4, #high(M32R_ICU_IMASK_PORTL)
or3 r4, r4, #low(M32R_ICU_IMASK_PORTL)
ldi r5, #0
st r5, @r4
ld r5, @r4
;; enable only IPI
setpsw #0x40
;; LOOOOOOOOOOOOOOP!!!
.fillinsn
2:
nop
nop
bra 2b
nop
nop
#ifdef CONFIG_CHIP_M32700_TS1
.global dcache_dummy
.balign 16, 0
dcache_dummy:
.byte 16
#endif /* CONFIG_CHIP_M32700_TS1 */
#endif /* CONFIG_SMP */
.end
This diff is collapsed.
#
# For a description of the syntax of this configuration file,
# see Documentation/kbuild/kconfig-language.txt.
#
menu "M32R drivers"
config M32RPCC
bool "M32R PCMCIA I/F"
depends on CHIP_M32700
config M32R_CFC
bool "CF I/F Controller"
depends on PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_OPSPUT
config M32700UT_CFC
bool
depends on M32R_CFC
default y
config CFC_NUM
int "CF I/F number"
depends on PLAT_USRV || PLAT_M32700UT
default "1" if PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_OPSPUT
config MTD_M32R
bool "Flash device mapped on M32R"
depends on PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2
config M32700UT_DS1302
bool "DS1302 Real Time Clock support"
depends on PLAT_M32700UT || PLAT_OPSPUT
endmenu
#
# Makefile for the Linux/M32R driver
#
obj-$(CONFIG_M32RPCC) += m32r_pcc.o
obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
obj-$(CONFIG_M32700UT_DS1302) += ds1302.o
#include "../../../drivers/pcmcia/cs_internal.h"
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* $Id$
*
* Copyright (C) 2001 by Hiroyuki Kondo
*/
#if !defined(CONFIG_PLAT_USRV)
#define M32R_MAX_PCC 2
#else /* CONFIG_PLAT_USRV */
#define M32R_MAX_PCC CONFIG_CFC_NUM
#endif /* CONFIG_PLAT_USRV */
/*
* M32R PC Card Controler
*/
#define M32R_PCC0_BASE 0x00ef7000
#define M32R_PCC1_BASE 0x00ef7020
/*
* Register offsets
*/
#define PCCR 0x00
#define PCADR 0x04
#define PCMOD 0x08
#define PCIRC 0x0c
#define PCCSIGCR 0x10
#define PCATCR 0x14
/*
* PCCR
*/
#define PCCR_PCEN (1UL<<(31-31))
/*
* PCIRC
*/
#define PCIRC_BWERR (1UL<<(31-7))
#define PCIRC_CDIN1 (1UL<<(31-14))
#define PCIRC_CDIN2 (1UL<<(31-15))
#define PCIRC_BEIEN (1UL<<(31-23))
#define PCIRC_CIIEN (1UL<<(31-30))
#define PCIRC_COIEN (1UL<<(31-31))
/*
* PCCSIGCR
*/
#define PCCSIGCR_SEN (1UL<<(31-3))
#define PCCSIGCR_VEN (1UL<<(31-7))
#define PCCSIGCR_CRST (1UL<<(31-15))
#define PCCSIGCR_COCR (1UL<<(31-31))
/*
*
*/
#define PCMOD_AS_ATTRIB (1UL<<(31-19))
#define PCMOD_AS_IO (1UL<<(31-18))
#define PCMOD_CBSZ (1UL<<(31-23)) /* set for 8bit */
#define PCMOD_DBEX (1UL<<(31-31)) /* set for excahnge */
/*
* M32R PCC Map addr
*/
#define M32R_PCC0_MAPBASE 0x14000000
#define M32R_PCC1_MAPBASE 0x16000000
#define M32R_PCC_MAPMAX 0x02000000
#define M32R_PCC_MAPSIZE 0x00001000 /* XXX */
#define M32R_PCC_MAPMASK (~(M32R_PCC_MAPMAX-1))
#define CFC_IOPORT_BASE 0x1000
#if !defined(CONFIG_PLAT_USRV)
#define CFC_ATTR_MAPBASE 0x0c014000
#define CFC_IO_MAPBASE_BYTE 0xac012000
#define CFC_IO_MAPBASE_WORD 0xac002000
#else /* CONFIG_PLAT_USRV */
#define CFC_ATTR_MAPBASE 0x04014000
#define CFC_IO_MAPBASE_BYTE 0xa4012000
#define CFC_IO_MAPBASE_WORD 0xa4002000
#endif /* CONFIG_PLAT_USRV */
This diff is collapsed.
/*
* $Id$
*
* Copyright (C) 2001 by Hiroyuki Kondo
*/
#define M32R_MAX_PCC 2
/*
* M32R PC Card Controler
*/
#define M32R_PCC0_BASE 0x00ef7000
#define M32R_PCC1_BASE 0x00ef7020
/*
* Register offsets
*/
#define PCCR 0x00
#define PCADR 0x04
#define PCMOD 0x08
#define PCIRC 0x0c
#define PCCSIGCR 0x10
#define PCATCR 0x14
/*
* PCCR
*/
#define PCCR_PCEN (1UL<<(31-31))
/*
* PCIRC
*/
#define PCIRC_BWERR (1UL<<(31-7))
#define PCIRC_CDIN1 (1UL<<(31-14))
#define PCIRC_CDIN2 (1UL<<(31-15))
#define PCIRC_BEIEN (1UL<<(31-23))
#define PCIRC_CIIEN (1UL<<(31-30))
#define PCIRC_COIEN (1UL<<(31-31))
/*
* PCCSIGCR
*/
#define PCCSIGCR_SEN (1UL<<(31-3))
#define PCCSIGCR_VEN (1UL<<(31-7))
#define PCCSIGCR_CRST (1UL<<(31-15))
#define PCCSIGCR_COCR (1UL<<(31-31))
/*
*
*/
#define PCMOD_AS_ATTRIB (1UL<<(31-19))
#define PCMOD_AS_IO (1UL<<(31-18))
#define PCMOD_CBSZ (1UL<<(31-23)) /* set for 8bit */
#define PCMOD_DBEX (1UL<<(31-31)) /* set for excahnge */
/*
* M32R PCC Map addr
*/
#define M32R_PCC0_MAPBASE 0x14000000
#define M32R_PCC1_MAPBASE 0x16000000
#define M32R_PCC_MAPMAX 0x02000000
#define M32R_PCC_MAPSIZE 0x00001000 /* XXX */
#define M32R_PCC_MAPMASK (~(M32R_PCC_MAPMAX-1))
This diff is collapsed.
/*
* Flash Memory Driver for M32700UT-CPU
*
* Copyright 2003 (C) Takeo Takahashi
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* 2003-02-01: Takeo Takahashi, support M5M29GT320VP.
*/
#include <asm/m32r.h>
#ifdef __KERNEL__
#undef DEBUG
/* debug routine:
* 0x00000001: print debug information
*/
# define DEBUG(n, args...) if ((n) & debug) \
printk(KERN_DEBUG args)
#endif /* __KERNEL__ */
/*
* data type to access flash memory
*/
typedef volatile unsigned short m5_t;
/*
* - Page program buffer size in byte
* - block size in byte
* - number of block
*/
#define M5_PAGE_SIZE (256)
#define M5_BLOCK_SIZE8 (8*1024)
#define M5_BLOCK_SIZE64 (64*1024)
#define MAX_BLOCK_NUM 70
/*
* Software commands
*/
#define M5_CMD_READ_ARRAY 0xff
#define M5_CMD_DEVICE_IDENT 0x90
#define M5_CMD_READ_STATUS 0x70
#define M5_CMD_CLEAR_STATUS 0x50
#define M5_CMD_BLOCK_ERASE 0x20
#define M5_CMD_CONFIRM 0xd0
#define M5_CMD_PROGRAM_BYTE 0x40
#define M5_CMD_PROGRAM_WORD M5_CMD_PROGRAM_BYTE
#define M5_CMD_PROGRAM_PAGE 0x41
#define M5_CMD_SINGLE_LOAD_DATA 0x74
#define M5_CMD_BUFF2FLASH 0x0e
#define M5_CMD_FLASH2BUFF 0xf1
#define M5_CMD_CLEAR_BUFF 0x55
#define M5_CMD_SUSPEND 0xb0
#define M5_CMD_RESUME 0xd0
/*
* Status
*/
#define M5_STATUS_READY 0x80 /* 0:busy 1:ready */
#define M5_STATUS_SUSPEND 0x40 /* 0:progress/complete 1:suspend */
#define M5_STATUS_ERASE 0x20 /* 0:pass 1:error */
#define M5_STATUS_PROGRAM 0x10 /* 0:pass 1:error */
#define M5_STATUS_BLOCK 0x08 /* 0:pass 1:error */
/*
* Device Code
*/
#define M5_MAKER (0x1c)
#define M5_M5M29GT320VP (0x20)
#define M5_M5M29GB320VP (0x21)
This diff is collapsed.
#
# Makefile for the Linux/M32R kernel.
#
extra-y := head.o init_task.o vmlinux.lds
obj-y := process.o entry.o traps.o align.o irq.o setup.o time.o \
m32r_ksyms.o sys_m32r.o semaphore.o signal.o ptrace.o
obj-$(CONFIG_SMP) += smp.o smpboot.o
obj-$(CONFIG_PLAT_MAPPI) += setup_mappi.o io_mappi.o
obj-$(CONFIG_PLAT_MAPPI2) += setup_mappi2.o io_mappi2.o
obj-$(CONFIG_PLAT_USRV) += setup_usrv.o io_usrv.o
obj-$(CONFIG_PLAT_M32700UT) += setup_m32700ut.o io_m32700ut.o
obj-$(CONFIG_PLAT_OPSPUT) += setup_opsput.o io_opsput.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_PLAT_OAKS32R) += setup_oaks32r.o io_oaks32r.o
EXTRA_AFLAGS := -traditional
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* orig : i386 init_task.c */
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/fs.h>
#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);
EXPORT_SYMBOL(init_mm);
/*
* Initial thread structure.
*
* We need to make sure that this is 8192-byte aligned due to the
* way process stacks are handled. This is done by having a special
* "init_task" linker map entry..
*/
union thread_union init_thread_union
__attribute__((__section__(".data.init_task"))) =
{ INIT_THREAD_INFO(init_task) };
/*
* Initial task structure.
*
* All other task structs will be allocated on slabs in fork.c
*/
struct task_struct init_task = INIT_TASK(init_task);
EXPORT_SYMBOL(init_task);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#
# Makefile for M32R-specific library files..
#
lib-y := checksum.o ashxdi3.o memset.o memcpy.o getuser.o \
putuser.o delay.o strlen.o usercopy.o csum_partial_copy.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#
# Makefile for the Linux M32R-specific parts of the memory manager.
#
ifdef CONFIG_MMU
obj-y := init.o fault.o mmu.o extable.o ioremap.o cache.o page.o
else
obj-y := init.o fault-nommu.o mmu.o extable.o ioremap-nommu.o cache.o page.o
endif
obj-$(CONFIG_DISCONTIGMEM) += discontig.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment