Commit 87292b19 authored by Richard Russon's avatar Richard Russon

Merge flatcap.org:/home/flatcap/backup/bk/ntfs-2.6

into flatcap.org:/home/flatcap/backup/bk/ntfs-2.6-devel
parents 17647b1d 0dd3a3bc
...@@ -354,10 +354,6 @@ maps this page at its virtual address. ...@@ -354,10 +354,6 @@ maps this page at its virtual address.
of arbitrary user pages (f.e. for ptrace()) it will use of arbitrary user pages (f.e. for ptrace()) it will use
these two routines. these two routines.
The page has been kmap()'d, and flush_cache_page() has
just been called for the user mapping of this page (if
necessary).
Any necessary cache flushing or other coherency operations Any necessary cache flushing or other coherency operations
that need to occur should happen here. If the processor's that need to occur should happen here. If the processor's
instruction cache does not snoop cpu stores, it is very instruction cache does not snoop cpu stores, it is very
......
...@@ -417,7 +417,12 @@ salinfo_log_new_read(int cpu, struct salinfo_data *data) ...@@ -417,7 +417,12 @@ salinfo_log_new_read(int cpu, struct salinfo_data *data)
if (!data->saved_num) if (!data->saved_num)
call_on_cpu(cpu, salinfo_log_read_cpu, data); call_on_cpu(cpu, salinfo_log_read_cpu, data);
data->state = data->log_size ? STATE_LOG_RECORD : STATE_NO_DATA; if (!data->log_size) {
data->state = STATE_NO_DATA;
clear_bit(cpu, &data->cpu_event);
} else {
data->state = STATE_LOG_RECORD;
}
} }
static ssize_t static ssize_t
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
unsigned long isa_io_base = 0; unsigned long isa_io_base = 0;
unsigned long isa_mem_base = 0; unsigned long isa_mem_base = 0;
unsigned long pci_dram_offset = 0; unsigned long pci_dram_offset = 0;
int pcibios_assign_bus_offset = 1;
void pcibios_make_OF_bus_map(void); void pcibios_make_OF_bus_map(void);
...@@ -411,7 +412,7 @@ probe_resource(struct pci_bus *parent, struct resource *pr, ...@@ -411,7 +412,7 @@ probe_resource(struct pci_bus *parent, struct resource *pr,
r = &dev->resource[i]; r = &dev->resource[i];
if (!r->flags || (r->flags & IORESOURCE_UNSET)) if (!r->flags || (r->flags & IORESOURCE_UNSET))
continue; continue;
if (pci_find_parent_resource(bus->self, r) != pr) if (pci_find_parent_resource(dev, r) != pr)
continue; continue;
if (r->end >= res->start && res->end >= r->start) { if (r->end >= res->start && res->end >= r->start) {
*conflict = r; *conflict = r;
...@@ -1263,7 +1264,7 @@ pcibios_init(void) ...@@ -1263,7 +1264,7 @@ pcibios_init(void)
bus = pci_scan_bus(hose->first_busno, hose->ops, hose); bus = pci_scan_bus(hose->first_busno, hose->ops, hose);
hose->last_busno = bus->subordinate; hose->last_busno = bus->subordinate;
if (pci_assign_all_busses || next_busno <= hose->last_busno) if (pci_assign_all_busses || next_busno <= hose->last_busno)
next_busno = hose->last_busno+1; next_busno = hose->last_busno + pcibios_assign_bus_offset;
} }
pci_bus_count = next_busno; pci_bus_count = next_busno;
......
...@@ -375,7 +375,7 @@ void __init chrp_init_IRQ(void) ...@@ -375,7 +375,7 @@ void __init chrp_init_IRQ(void)
{ {
struct device_node *np; struct device_node *np;
int i; int i;
unsigned long chrp_int_ack; unsigned long chrp_int_ack = 0;
unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
struct device_node *kbd; struct device_node *kbd;
......
...@@ -301,7 +301,6 @@ static int __pmac pmu_set_cpu_speed(int low_speed) ...@@ -301,7 +301,6 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
static int __pmac do_set_cpu_speed(int speed_mode) static int __pmac do_set_cpu_speed(int speed_mode)
{ {
struct cpufreq_freqs freqs; struct cpufreq_freqs freqs;
int rc;
freqs.old = cur_freq; freqs.old = cur_freq;
freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
...@@ -315,7 +314,7 @@ static int __pmac do_set_cpu_speed(int speed_mode) ...@@ -315,7 +314,7 @@ static int __pmac do_set_cpu_speed(int speed_mode)
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
return rc; return 0;
} }
static int __pmac pmac_cpufreq_verify(struct cpufreq_policy *policy) static int __pmac pmac_cpufreq_verify(struct cpufreq_policy *policy)
......
...@@ -2665,7 +2665,7 @@ set_initial_features(void) ...@@ -2665,7 +2665,7 @@ set_initial_features(void)
struct device_node *p = of_get_parent(ui2c); struct device_node *p = of_get_parent(ui2c);
if (p && !strcmp(p->name, "uni-n")) if (p && !strcmp(p->name, "uni-n"))
break; break;
ui2c = of_find_node_by_type(np, "i2c"); ui2c = of_find_node_by_type(ui2c, "i2c");
} }
if (ui2c == NULL) if (ui2c == NULL)
break; break;
......
...@@ -50,6 +50,7 @@ static struct pci_controller *u3_agp; ...@@ -50,6 +50,7 @@ static struct pci_controller *u3_agp;
#endif /* CONFIG_POWER4 */ #endif /* CONFIG_POWER4 */
extern u8 pci_cache_line_size; extern u8 pci_cache_line_size;
extern int pcibios_assign_bus_offset;
struct pci_dev *k2_skiplist[2]; struct pci_dev *k2_skiplist[2];
...@@ -565,6 +566,14 @@ pmac_find_bridges(void) ...@@ -565,6 +566,14 @@ pmac_find_bridges(void)
init_p2pbridge(); init_p2pbridge();
fixup_nec_usb2(); fixup_nec_usb2();
/* We are still having some issues with the Xserve G4, enabling
* some offset between bus number and domains for now when we
* assign all busses should help for now
*/
if (pci_assign_all_busses)
pcibios_assign_bus_offset = 0x10;
#ifdef CONFIG_POWER4 #ifdef CONFIG_POWER4
/* There is something wrong with DMA on U3/HT. I haven't figured out /* There is something wrong with DMA on U3/HT. I haven't figured out
* the details yet, but if I set the cache line size to 128 bytes like * the details yet, but if I set the cache line size to 128 bytes like
......
...@@ -115,11 +115,11 @@ prom_entry prom __initdata; ...@@ -115,11 +115,11 @@ prom_entry prom __initdata;
ihandle prom_chosen __initdata; ihandle prom_chosen __initdata;
ihandle prom_stdout __initdata; ihandle prom_stdout __initdata;
char *prom_display_paths[FB_MAX] __initdata; static char *prom_display_paths[FB_MAX] __initdata;
phandle prom_display_nodes[FB_MAX] __initdata; static phandle prom_display_nodes[FB_MAX] __initdata;
unsigned int prom_num_displays __initdata; static unsigned int prom_num_displays __initdata;
char *of_stdout_device __initdata;
static ihandle prom_disp_node __initdata; static ihandle prom_disp_node __initdata;
char *of_stdout_device __initdata;
unsigned int rtas_data; /* physical pointer */ unsigned int rtas_data; /* physical pointer */
unsigned int rtas_entry; /* physical pointer */ unsigned int rtas_entry; /* physical pointer */
...@@ -403,6 +403,7 @@ check_display(unsigned long mem) ...@@ -403,6 +403,7 @@ check_display(unsigned long mem)
for (j=0; j<prom_num_displays; j++) { for (j=0; j<prom_num_displays; j++) {
path = prom_display_paths[j]; path = prom_display_paths[j];
node = prom_display_nodes[j];
prom_print("opening display "); prom_print("opening display ");
prom_print(path); prom_print(path);
ih = call_prom("open", 1, 1, path); ih = call_prom("open", 1, 1, path);
...@@ -420,6 +421,8 @@ check_display(unsigned long mem) ...@@ -420,6 +421,8 @@ check_display(unsigned long mem)
continue; continue;
} else { } else {
prom_print("... ok\n"); prom_print("... ok\n");
call_prom("setprop", 4, 1, node, "linux,opened", 0, NULL);
/* /*
* Setup a usable color table when the appropriate * Setup a usable color table when the appropriate
* method is available. * method is available.
...@@ -442,6 +445,19 @@ check_display(unsigned long mem) ...@@ -442,6 +445,19 @@ check_display(unsigned long mem)
} }
} }
if (prom_stdout) {
phandle p;
p = call_prom("instance-to-package", 1, 1, prom_stdout);
if (p && (int)p != -1) {
type[0] = 0;
call_prom("getprop", 4, 1, p, "device_type",
type, sizeof(type));
if (strcmp(type, "display") == 0)
call_prom("setprop", 4, 1, p, "linux,boot-display",
0, NULL);
}
}
return ALIGNUL(mem); return ALIGNUL(mem);
} }
......
...@@ -58,16 +58,27 @@ menu "Platform support" ...@@ -58,16 +58,27 @@ menu "Platform support"
choice choice
prompt "Platform Type" prompt "Platform Type"
default PPC_PSERIES default PPC_MULTIPLATFORM
config PPC_ISERIES config PPC_ISERIES
bool "iSeries" bool "IBM Legacy iSeries"
config PPC_PSERIES config PPC_MULTIPLATFORM
bool "pSeries / PowerMac G5" bool "Generic"
endchoice endchoice
config PPC_PSERIES
depends on PPC_MULTIPLATFORM
bool " IBM pSeries & new iSeries"
default y
config PPC_PMAC
depends on PPC_MULTIPLATFORM
bool " Apple G5 based machines"
default y
select ADB_PMU
config PPC config PPC
bool bool
default y default y
...@@ -77,7 +88,7 @@ config PPC64 ...@@ -77,7 +88,7 @@ config PPC64
default y default y
config PPC_OF config PPC_OF
depends on PPC_PSERIES depends on PPC_MULTIPLATFORM
bool bool
default y default y
...@@ -85,14 +96,9 @@ config PPC_OF ...@@ -85,14 +96,9 @@ config PPC_OF
# exception vectors for it # exception vectors for it
config ALTIVEC config ALTIVEC
bool "Support for VMX (Altivec) vector unit" bool "Support for VMX (Altivec) vector unit"
depends on PPC_PSERIES depends on PPC_MULTIPLATFORM
default y default y
config PPC_PMAC
depends on PPC_PSERIES
bool "Apple PowerMac G5 support"
select ADB_PMU
config PPC_SPLPAR config PPC_SPLPAR
depends on PPC_PSERIES depends on PPC_PSERIES
bool "Support for shared-processor logical partitions" bool "Support for shared-processor logical partitions"
...@@ -163,7 +169,7 @@ config SMP ...@@ -163,7 +169,7 @@ config SMP
config IRQ_ALL_CPUS config IRQ_ALL_CPUS
bool "Distribute interrupts on all CPUs by default" bool "Distribute interrupts on all CPUs by default"
depends on SMP && PPC_PSERIES depends on SMP && PPC_MULTIPLATFORM
help help
This option gives the kernel permission to distribute IRQs across This option gives the kernel permission to distribute IRQs across
multiple CPUs. Saying N here will route all IRQs to the first multiple CPUs. Saying N here will route all IRQs to the first
......
...@@ -31,6 +31,7 @@ BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional ...@@ -31,6 +31,7 @@ BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional
BOOTLD := $(CROSS32_COMPILE)ld BOOTLD := $(CROSS32_COMPILE)ld
BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds
BOOTOBJCOPY := $(CROSS32_COMPILE)objcopy BOOTOBJCOPY := $(CROSS32_COMPILE)objcopy
BOOTSTRIP := $(CROSS32_COMPILE)strip
OBJCOPYFLAGS := contents,alloc,load,readonly,data OBJCOPYFLAGS := contents,alloc,load,readonly,data
src-boot := crt0.S string.S prom.c main.c zlib.c imagesize.c div64.S src-boot := crt0.S string.S prom.c main.c zlib.c imagesize.c div64.S
...@@ -51,36 +52,31 @@ $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S ...@@ -51,36 +52,31 @@ $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S
#----------------------------------------------------------- #-----------------------------------------------------------
# ELF sections within the zImage bootloader/wrapper # ELF sections within the zImage bootloader/wrapper
#----------------------------------------------------------- #-----------------------------------------------------------
required := vmlinux .config System.map required := vmlinux.strip
initrd := initrd initrd := initrd
obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section))) obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section)))
src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
hostprogs-y := piggy addnote addSystemMap addRamDisk hostprogs-y := piggy addnote addRamDisk
targets += zImage zImage.initrd imagesize.c \ targets += zImage zImage.initrd imagesize.c \
$(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
$(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
$(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
vmlinux.sm vmlinux.initrd vmlinux.sminitrd vmlinux.initrd
extra-y := sysmap.o initrd.o extra-y := initrd.o
quiet_cmd_sysmap = SYSMAP $@
cmd_sysmap = $(obj)/addSystemMap System.map $< $@
$(obj)/vmlinux.sm: vmlinux $(obj)/addSystemMap System.map FORCE
$(call if_changed,sysmap)
quiet_cmd_ramdisk = RAMDISK $@ quiet_cmd_ramdisk = RAMDISK $@
cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz System.map $< $@ cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@
$(obj)/vmlinux.initrd: vmlinux $(obj)/addRamDisk $(obj)/ramdisk.image.gz System.map FORCE
$(call if_changed,ramdisk)
$(obj)/vmlinux.sminitrd: $(obj)/vmlinux.sm $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE quiet_cmd_stripvm = STRIP $@
$(call if_changed,ramdisk) cmd_stripvm = $(BOOTSTRIP) -s $< -o $@
$(obj)/sysmap.o: System.map $(obj)/piggyback FORCE vmlinux.strip: vmlinux FORCE
$(call if_changed,piggy) $(call if_changed,stripvm)
$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE
$(call if_changed,ramdisk)
addsection = $(BOOTOBJCOPY) $(1) \ addsection = $(BOOTOBJCOPY) $(1) \
--add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \ --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \
...@@ -113,9 +109,9 @@ $(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd)) ...@@ -113,9 +109,9 @@ $(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd))
$(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE $(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE
$(call if_changed,addnote) $(call if_changed,addnote)
$(obj)/imagesize.c: vmlinux $(obj)/imagesize.c: vmlinux.strip
@echo Generating $@ @echo Generating $@
ls -l vmlinux | \ ls -l vmlinux.strip | \
awk '{printf "/* generated -- do not edit! */\n" \ awk '{printf "/* generated -- do not edit! */\n" \
"unsigned long vmlinux_filesize = %d;\n", $$5}' > $(obj)/imagesize.c "unsigned long vmlinux_filesize = %d;\n", $$5}' > $(obj)/imagesize.c
$(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \ $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
...@@ -123,6 +119,6 @@ $(obj)/imagesize.c: vmlinux ...@@ -123,6 +119,6 @@ $(obj)/imagesize.c: vmlinux
>> $(obj)/imagesize.c >> $(obj)/imagesize.c
install: $(CONFIGURE) $(obj)/$(BOOTIMAGE) install: $(CONFIGURE) $(obj)/$(BOOTIMAGE)
sh -x $(src)/install.sh "$(KERNELRELEASE)" "$(obj)/$(BOOTIMAGE)" "$(TOPDIR)/System.map" "$(INSTALL_PATH)" sh -x $(src)/install.sh "$(KERNELRELEASE)" "$(obj)/$(BOOTIMAGE)" "$(INSTALL_PATH)"
clean-files := $(patsubst $(obj)/%,%, $(obj-boot)) clean-files := $(patsubst $(obj)/%,%, $(obj-boot))
#include <stdio.h>
#include <stdlib.h>
#include <byteswap.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
void xlate( char * inb, char * trb, unsigned len )
{
unsigned i;
for ( i=0; i<len; ++i )
{
char c = *inb++;
char c1 = c >> 4;
char c2 = c & 0xf;
if ( c1 > 9 )
c1 = c1 + 'A' - 10;
else
c1 = c1 + '0';
if ( c2 > 9 )
c2 = c2 + 'A' - 10;
else
c2 = c2 + '0';
*trb++ = c1;
*trb++ = c2;
}
*trb = 0;
}
#define ElfHeaderSize (64 * 1024)
#define ElfPages (ElfHeaderSize / 4096)
void get4k( /*istream *inf*/FILE *file, char *buf )
{
unsigned j;
unsigned num = fread(buf, 1, 4096, file);
for ( j=num; j<4096; ++j )
buf[j] = 0;
}
void put4k( /*ostream *outf*/FILE *file, char *buf )
{
fwrite(buf, 1, 4096, file);
}
int main(int argc, char **argv)
{
char inbuf[4096];
FILE *sysmap = NULL;
char* ptr_end = NULL;
FILE *inputVmlinux = NULL;
FILE *outputVmlinux = NULL;
long i = 0;
unsigned long sysmapFileLen = 0;
unsigned long sysmapLen = 0;
unsigned long roundR = 0;
unsigned long kernelLen = 0;
unsigned long actualKernelLen = 0;
unsigned long round = 0;
unsigned long roundedKernelLen = 0;
unsigned long sysmapStartOffs = 0;
unsigned long sysmapPages = 0;
unsigned long roundedKernelPages = 0;
long padPages = 0;
if ( argc < 2 )
{
fprintf(stderr, "Name of System Map file missing.\n");
exit(1);
}
if ( argc < 3 )
{
fprintf(stderr, "Name of vmlinux file missing.\n");
exit(1);
}
if ( argc < 4 )
{
fprintf(stderr, "Name of vmlinux output file missing.\n");
exit(1);
}
sysmap = fopen(argv[1], "r");
if ( ! sysmap )
{
fprintf(stderr, "System Map file \"%s\" failed to open.\n", argv[1]);
exit(1);
}
inputVmlinux = fopen(argv[2], "r");
if ( ! inputVmlinux )
{
fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", argv[2]);
exit(1);
}
outputVmlinux = fopen(argv[3], "w");
if ( ! outputVmlinux )
{
fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", argv[3]);
exit(1);
}
fseek(inputVmlinux, 0, SEEK_END);
kernelLen = ftell(inputVmlinux);
fseek(inputVmlinux, 0, SEEK_SET);
printf("kernel file size = %ld\n", kernelLen);
if ( kernelLen == 0 )
{
fprintf(stderr, "You must have a linux kernel specified as argv[2]\n");
exit(1);
}
actualKernelLen = kernelLen - ElfHeaderSize;
printf("actual kernel length (minus ELF header) = %ld/%lxx \n", actualKernelLen, actualKernelLen);
round = actualKernelLen % 4096;
roundedKernelLen = actualKernelLen;
if ( round )
roundedKernelLen += (4096 - round);
printf("Kernel length rounded up to a 4k multiple = %ld/%lxx \n", roundedKernelLen, roundedKernelLen);
roundedKernelPages = roundedKernelLen / 4096;
printf("Kernel pages to copy = %ld/%lxx\n", roundedKernelPages, roundedKernelPages);
/* Sysmap file */
fseek(sysmap, 0, SEEK_END);
sysmapFileLen = ftell(sysmap);
fseek(sysmap, 0, SEEK_SET);
printf("%s file size = %ld\n", argv[1], sysmapFileLen);
sysmapLen = sysmapFileLen;
roundR = 4096 - (sysmapLen % 4096);
if (roundR)
{
printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR);
sysmapLen += roundR;
}
printf("Rounded System Map size is %ld\n", sysmapLen);
/* Process the Sysmap file to determine the true end of the kernel */
sysmapPages = sysmapLen / 4096;
printf("System map pages to copy = %ld\n", sysmapPages);
/* read the whole file line by line, expect that it doesn't fail */
while ( fgets(inbuf, 4096, sysmap) ) ;
/* search for _end in the last page of the system map */
ptr_end = strstr(inbuf, " _end");
if (!ptr_end)
{
fprintf(stderr, "Unable to find _end in the sysmap file \n");
fprintf(stderr, "inbuf: \n");
fprintf(stderr, "%s \n", inbuf);
exit(1);
}
printf("Found _end in the last page of the sysmap - backing up 10 characters it looks like %s", ptr_end-10);
sysmapStartOffs = (unsigned int)strtol(ptr_end-10, NULL, 16);
/* calc how many pages we need to insert between the vmlinux and the start of the sysmap */
padPages = sysmapStartOffs/4096 - roundedKernelPages;
/* Check and see if the vmlinux is larger than _end in System.map */
if (padPages < 0)
{ /* vmlinux is larger than _end - adjust the offset to start the embedded system map */
sysmapStartOffs = roundedKernelLen;
printf("vmlinux is larger than _end indicates it needs to be - sysmapStartOffs = %lx \n", sysmapStartOffs);
padPages = 0;
printf("will insert %lx pages between the vmlinux and the start of the sysmap \n", padPages);
}
else
{ /* _end is larger than vmlinux - use the sysmapStartOffs we calculated from the system map */
printf("vmlinux is smaller than _end indicates is needed - sysmapStartOffs = %lx \n", sysmapStartOffs);
printf("will insert %lx pages between the vmlinux and the start of the sysmap \n", padPages);
}
/* Copy 64K ELF header */
for (i=0; i<(ElfPages); ++i)
{
get4k( inputVmlinux, inbuf );
put4k( outputVmlinux, inbuf );
}
/* Copy the vmlinux (as full pages). */
fseek(inputVmlinux, ElfHeaderSize, SEEK_SET);
for ( i=0; i<roundedKernelPages; ++i )
{
get4k( inputVmlinux, inbuf );
/* Set the offsets (of the start and end) of the embedded sysmap so it is set in the vmlinux.sm */
if ( i == 0 )
{
unsigned long * p;
printf("Storing embedded_sysmap_start at 0x3c\n");
p = (unsigned long *)(inbuf + 0x3c);
#if (BYTE_ORDER == __BIG_ENDIAN)
*p = sysmapStartOffs;
#else
*p = bswap_32(sysmapStartOffs);
#endif
printf("Storing embedded_sysmap_end at 0x44\n");
p = (unsigned long *)(inbuf + 0x44);
#if (BYTE_ORDER == __BIG_ENDIAN)
*p = sysmapStartOffs + sysmapFileLen;
#else
*p = bswap_32(sysmapStartOffs + sysmapFileLen);
#endif
}
put4k( outputVmlinux, inbuf );
}
/* Insert any pad pages between the end of the vmlinux and where the system map needs to be. */
for (i=0; i<padPages; ++i)
{
memset(inbuf, 0, 4096);
put4k(outputVmlinux, inbuf);
}
/* Copy the system map (as full pages). */
fseek(sysmap, 0, SEEK_SET); /* start reading from begining of the system map */
for ( i=0; i<sysmapPages; ++i )
{
get4k( sysmap, inbuf );
put4k( outputVmlinux, inbuf );
}
fclose(sysmap);
fclose(inputVmlinux);
fclose(outputVmlinux);
/* Set permission to executable */
chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
return 0;
}
...@@ -31,13 +31,9 @@ unsigned long strlen(const char *s); ...@@ -31,13 +31,9 @@ unsigned long strlen(const char *s);
void *memmove(void *dest, const void *src, unsigned long n); void *memmove(void *dest, const void *src, unsigned long n);
void *memcpy(void *dest, const void *src, unsigned long n); void *memcpy(void *dest, const void *src, unsigned long n);
static struct bi_record *make_bi_recs(unsigned long);
#define RAM_START 0x00000000
#define RAM_END (64<<20)
/* Value picked to match that used by yaboot */ /* Value picked to match that used by yaboot */
#define PROG_START 0x01400000 #define PROG_START 0x01400000
#define RAM_END (256<<20) // Fixme: use OF */
char *avail_ram; char *avail_ram;
char *begin_avail, *end_avail; char *begin_avail, *end_avail;
...@@ -48,8 +44,6 @@ unsigned int heap_max; ...@@ -48,8 +44,6 @@ unsigned int heap_max;
extern char _start[]; extern char _start[];
extern char _vmlinux_start[]; extern char _vmlinux_start[];
extern char _vmlinux_end[]; extern char _vmlinux_end[];
extern char _sysmap_start[];
extern char _sysmap_end[];
extern char _initrd_start[]; extern char _initrd_start[];
extern char _initrd_end[]; extern char _initrd_end[];
extern unsigned long vmlinux_filesize; extern unsigned long vmlinux_filesize;
...@@ -62,7 +56,6 @@ struct addr_range { ...@@ -62,7 +56,6 @@ struct addr_range {
}; };
struct addr_range vmlinux = {0, 0, 0}; struct addr_range vmlinux = {0, 0, 0};
struct addr_range vmlinuz = {0, 0, 0}; struct addr_range vmlinuz = {0, 0, 0};
struct addr_range sysmap = {0, 0, 0};
struct addr_range initrd = {0, 0, 0}; struct addr_range initrd = {0, 0, 0};
static char scratch[128<<10]; /* 128kB of scratch space for gunzip */ static char scratch[128<<10]; /* 128kB of scratch space for gunzip */
...@@ -70,7 +63,7 @@ static char scratch[128<<10]; /* 128kB of scratch space for gunzip */ ...@@ -70,7 +63,7 @@ static char scratch[128<<10]; /* 128kB of scratch space for gunzip */
typedef void (*kernel_entry_t)( unsigned long, typedef void (*kernel_entry_t)( unsigned long,
unsigned long, unsigned long,
void *, void *,
struct bi_record *); void *);
int (*prom)(void *); int (*prom)(void *);
...@@ -80,12 +73,31 @@ void *stdin; ...@@ -80,12 +73,31 @@ void *stdin;
void *stdout; void *stdout;
void *stderr; void *stderr;
#define DEBUG
void static unsigned long claim_base = PROG_START;
start(unsigned long a1, unsigned long a2, void *promptr)
static unsigned long try_claim(unsigned long size)
{ {
unsigned long i, claim_addr, claim_size; unsigned long addr = 0;
struct bi_record *bi_recs;
for(; claim_base < RAM_END; claim_base += 0x100000) {
#ifdef DEBUG
printf(" trying: 0x%08lx\n\r", claim_base);
#endif
addr = (unsigned long)claim(claim_base, size, 0);
if ((void *)addr != (void *)-1)
break;
}
if (addr == 0)
return 0;
claim_base = PAGE_ALIGN(claim_base + size);
return addr;
}
void start(unsigned long a1, unsigned long a2, void *promptr)
{
unsigned long i;
kernel_entry_t kernel_entry; kernel_entry_t kernel_entry;
Elf64_Ehdr *elf64; Elf64_Ehdr *elf64;
Elf64_Phdr *elf64ph; Elf64_Phdr *elf64ph;
...@@ -102,61 +114,59 @@ start(unsigned long a1, unsigned long a2, void *promptr) ...@@ -102,61 +114,59 @@ start(unsigned long a1, unsigned long a2, void *promptr)
printf("zImage starting: loaded at 0x%x\n\r", (unsigned)_start); printf("zImage starting: loaded at 0x%x\n\r", (unsigned)_start);
#if 0 /*
sysmap.size = (unsigned long)(_sysmap_end - _sysmap_start); * Now we try to claim some memory for the kernel itself
sysmap.memsize = sysmap.size; * our "vmlinux_memsize" is the memory footprint in RAM, _HOWEVER_, what
if ( sysmap.size > 0 ) { * our Makefile stuffs in is an image containing all sort of junk including
sysmap.addr = (RAM_END - sysmap.size) & ~0xFFF; * an ELF header. We need to do some calculations here to find the right
claim(sysmap.addr, RAM_END - sysmap.addr, 0); * size... In practice we add 1Mb, that is enough, but we should really
printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r", * consider fixing the Makefile to put a _raw_ kernel in there !
sysmap.addr, (unsigned long)_sysmap_start, sysmap.size); */
memcpy((void *)sysmap.addr, (void *)_sysmap_start, sysmap.size); vmlinux_memsize += 0x100000;
} printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize);
#endif vmlinux.addr = try_claim(vmlinux_memsize);
if (vmlinux.addr == 0) {
initrd.size = (unsigned long)(_initrd_end - _initrd_start); printf("Can't allocate memory for kernel image !\n\r");
initrd.memsize = initrd.size; exit();
if ( initrd.size > 0 ) {
initrd.addr = (RAM_END - initrd.size) & ~0xFFF;
a1 = a2 = 0;
claim(initrd.addr, RAM_END - initrd.addr, 0);
printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
initrd.addr, (unsigned long)_initrd_start, initrd.size);
memcpy((void *)initrd.addr, (void *)_initrd_start, initrd.size);
} }
vmlinuz.addr = (unsigned long)_vmlinux_start; vmlinuz.addr = (unsigned long)_vmlinux_start;
vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
vmlinux.addr = (unsigned long)(void *)-1;
vmlinux.size = PAGE_ALIGN(vmlinux_filesize); vmlinux.size = PAGE_ALIGN(vmlinux_filesize);
vmlinux.memsize = vmlinux_memsize; vmlinux.memsize = vmlinux_memsize;
claim_size = vmlinux.memsize /* PPPBBB: + fudge for bi_recs */; /*
for(claim_addr = PROG_START; * Now we try to claim memory for the initrd (and copy it there)
claim_addr <= PROG_START * 8; */
claim_addr += 0x100000) { initrd.size = (unsigned long)(_initrd_end - _initrd_start);
#ifdef DEBUG initrd.memsize = initrd.size;
printf(" trying: 0x%08lx\n\r", claim_addr); if ( initrd.size > 0 ) {
#endif printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size);
vmlinux.addr = (unsigned long)claim(claim_addr, claim_size, 0); initrd.addr = try_claim(initrd.size);
if ((void *)vmlinux.addr != (void *)-1) break; if (initrd.addr == 0) {
} printf("Can't allocate memory for initial ramdisk !\n\r");
if ((void *)vmlinux.addr == (void *)-1) {
printf("claim error, can't allocate kernel memory\n\r");
exit(); exit();
} }
a1 = initrd.addr;
a2 = initrd.size;
printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
initrd.addr, (unsigned long)_initrd_start, initrd.size);
memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size);
printf("initrd head: 0x%lx\n", *((u32 *)initrd.addr));
}
/* PPPBBB: should kernel always be gziped? */ /* Eventually gunzip the kernel */
if (*(unsigned short *)vmlinuz.addr == 0x1f8b) { if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
int len;
avail_ram = scratch; avail_ram = scratch;
begin_avail = avail_high = avail_ram; begin_avail = avail_high = avail_ram;
end_avail = scratch + sizeof(scratch); end_avail = scratch + sizeof(scratch);
printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...", printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...",
vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size); vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size);
len = vmlinuz.size;
gunzip((void *)vmlinux.addr, vmlinux.size, gunzip((void *)vmlinux.addr, vmlinux.size,
(unsigned char *)vmlinuz.addr, (int *)&vmlinuz.size); (unsigned char *)vmlinuz.addr, &len);
printf("done %lu bytes\n\r", vmlinuz.size); printf("done 0x%lx bytes\n\r", len);
printf("%u bytes of heap consumed, max in use %u\n\r", printf("0x%x bytes of heap consumed, max in use 0x%\n\r",
(unsigned)(avail_high - begin_avail), heap_max); (unsigned)(avail_high - begin_avail), heap_max);
} else { } else {
memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size); memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size);
...@@ -192,7 +202,8 @@ start(unsigned long a1, unsigned long a2, void *promptr) ...@@ -192,7 +202,8 @@ start(unsigned long a1, unsigned long a2, void *promptr)
flush_cache((void *)vmlinux.addr, vmlinux.memsize); flush_cache((void *)vmlinux.addr, vmlinux.memsize);
bi_recs = make_bi_recs(vmlinux.addr + vmlinux.memsize); if (a1)
printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr));
kernel_entry = (kernel_entry_t)vmlinux.addr; kernel_entry = (kernel_entry_t)vmlinux.addr;
#ifdef DEBUG #ifdef DEBUG
...@@ -203,65 +214,16 @@ start(unsigned long a1, unsigned long a2, void *promptr) ...@@ -203,65 +214,16 @@ start(unsigned long a1, unsigned long a2, void *promptr)
" prom = 0x%lx,\n\r" " prom = 0x%lx,\n\r"
" bi_recs = 0x%lx,\n\r", " bi_recs = 0x%lx,\n\r",
(unsigned long)kernel_entry, a1, a2, (unsigned long)kernel_entry, a1, a2,
(unsigned long)prom, (unsigned long)bi_recs); (unsigned long)prom, NULL);
#endif #endif
kernel_entry( a1, a2, prom, bi_recs ); kernel_entry( a1, a2, prom, NULL );
printf("Error: Linux kernel returned to zImage bootloader!\n\r"); printf("Error: Linux kernel returned to zImage bootloader!\n\r");
exit(); exit();
} }
static struct bi_record *
make_bi_recs(unsigned long addr)
{
struct bi_record *bi_recs;
struct bi_record *rec;
bi_recs = rec = bi_rec_init(addr);
rec = bi_rec_alloc(rec, 2);
rec->tag = BI_FIRST;
/* rec->data[0] = ...; # Written below before return */
/* rec->data[1] = ...; # Written below before return */
rec = bi_rec_alloc_bytes(rec, strlen("chrpboot")+1);
rec->tag = BI_BOOTLOADER_ID;
sprintf( (char *)rec->data, "chrpboot");
rec = bi_rec_alloc(rec, 2);
rec->tag = BI_MACHTYPE;
rec->data[0] = PLATFORM_PSERIES;
rec->data[1] = 1;
if ( initrd.size > 0 ) {
rec = bi_rec_alloc(rec, 2);
rec->tag = BI_INITRD;
rec->data[0] = initrd.addr;
rec->data[1] = initrd.size;
}
if ( sysmap.size > 0 ) {
rec = bi_rec_alloc(rec, 2);
rec->tag = BI_SYSMAP;
rec->data[0] = (unsigned long)sysmap.addr;
rec->data[1] = (unsigned long)sysmap.size;
}
rec = bi_rec_alloc(rec, 1);
rec->tag = BI_LAST;
rec->data[0] = (bi_rec_field)bi_recs;
/* Save the _end_ address of the bi_rec's in the first bi_rec
* data field for easy access by the kernel.
*/
bi_recs->data[0] = (bi_rec_field)rec;
bi_recs->data[1] = (bi_rec_field)rec + rec->size - (bi_rec_field)bi_recs;
return bi_recs;
}
struct memchunk { struct memchunk {
unsigned int size; unsigned int size;
unsigned int pad; unsigned int pad;
......
...@@ -61,19 +61,9 @@ SECTIONS ...@@ -61,19 +61,9 @@ SECTIONS
. = ALIGN(4096); . = ALIGN(4096);
_vmlinux_start = .; _vmlinux_start = .;
.kernel:vmlinux : { *(.kernel:vmlinux) } .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) }
_vmlinux_end = .; _vmlinux_end = .;
. = ALIGN(4096);
_dotconfig_start = .;
.kernel:.config : { *(.kernel:.config) }
_dotconfig_end = .;
. = ALIGN(4096);
_sysmap_start = .;
.kernel:System.map : { *(.kernel:System.map) }
_sysmap_end = .;
. = ALIGN(4096); . = ALIGN(4096);
_initrd_start = .; _initrd_start = .;
.kernel:initrd : { *(.kernel:initrd) } .kernel:initrd : { *(.kernel:initrd) }
......
This diff is collapsed.
# #
# Automatically generated make config: don't edit # Automatically generated make config: don't edit
# Linux kernel version: 2.6.9-rc2
# Thu Sep 23 16:45:05 2004
# #
CONFIG_64BIT=y CONFIG_64BIT=y
CONFIG_MMU=y CONFIG_MMU=y
...@@ -20,6 +22,7 @@ CONFIG_CLEAN_COMPILE=y ...@@ -20,6 +22,7 @@ CONFIG_CLEAN_COMPILE=y
# #
# General setup # General setup
# #
CONFIG_LOCALVERSION=""
CONFIG_SWAP=y CONFIG_SWAP=y
CONFIG_SYSVIPC=y CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE=y
...@@ -61,12 +64,13 @@ CONFIG_SYSVIPC_COMPAT=y ...@@ -61,12 +64,13 @@ CONFIG_SYSVIPC_COMPAT=y
# Platform support # Platform support
# #
# CONFIG_PPC_ISERIES is not set # CONFIG_PPC_ISERIES is not set
CONFIG_PPC_MULTIPLATFORM=y
CONFIG_PPC_PSERIES=y CONFIG_PPC_PSERIES=y
# CONFIG_PPC_PMAC is not set
CONFIG_PPC=y CONFIG_PPC=y
CONFIG_PPC64=y CONFIG_PPC64=y
CONFIG_PPC_OF=y CONFIG_PPC_OF=y
CONFIG_ALTIVEC=y CONFIG_ALTIVEC=y
# CONFIG_PPC_PMAC is not set
CONFIG_PPC_SPLPAR=y CONFIG_PPC_SPLPAR=y
# CONFIG_BOOTX_TEXT is not set # CONFIG_BOOTX_TEXT is not set
# CONFIG_POWER4_ONLY is not set # CONFIG_POWER4_ONLY is not set
...@@ -189,7 +193,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y ...@@ -189,7 +193,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_IDEDMA_ONLYDISK is not set
CONFIG_BLK_DEV_ADMA=y
# CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_BLK_DEV_ALI15X3 is not set
CONFIG_BLK_DEV_AMD74XX=y CONFIG_BLK_DEV_AMD74XX=y
...@@ -365,6 +368,8 @@ CONFIG_NETFILTER=y ...@@ -365,6 +368,8 @@ CONFIG_NETFILTER=y
# IP: Netfilter Configuration # IP: Netfilter Configuration
# #
CONFIG_IP_NF_CONNTRACK=m CONFIG_IP_NF_CONNTRACK=m
# CONFIG_IP_NF_CT_ACCT is not set
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m CONFIG_IP_NF_IRC=m
CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_TFTP=m
...@@ -389,8 +394,14 @@ CONFIG_IP_NF_MATCH_HELPER=m ...@@ -389,8 +394,14 @@ CONFIG_IP_NF_MATCH_HELPER=m
CONFIG_IP_NF_MATCH_STATE=m CONFIG_IP_NF_MATCH_STATE=m
CONFIG_IP_NF_MATCH_CONNTRACK=m CONFIG_IP_NF_MATCH_CONNTRACK=m
CONFIG_IP_NF_MATCH_OWNER=m CONFIG_IP_NF_MATCH_OWNER=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_MASQUERADE=m
...@@ -409,21 +420,13 @@ CONFIG_IP_NF_TARGET_ECN=m ...@@ -409,21 +420,13 @@ CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m CONFIG_IP_NF_TARGET_CLASSIFY=m
CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_TARGET_NOTRACK=m
CONFIG_IP_NF_TARGET_TCPMSS=m
CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_IP_NF_COMPAT_IPCHAINS=m CONFIG_IP_NF_COMPAT_IPCHAINS=m
CONFIG_IP_NF_COMPAT_IPFWADM=m CONFIG_IP_NF_COMPAT_IPFWADM=m
CONFIG_IP_NF_TARGET_NOTRACK=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
# CONFIG_IP_NF_CT_ACCT is not set
CONFIG_IP_NF_MATCH_SCTP=m
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_XFRM=y CONFIG_XFRM=y
CONFIG_XFRM_USER=m CONFIG_XFRM_USER=m
...@@ -604,6 +607,7 @@ CONFIG_SERIO_I8042=y ...@@ -604,6 +607,7 @@ CONFIG_SERIO_I8042=y
# CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_SERPORT is not set
# CONFIG_SERIO_CT82C710 is not set # CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set # CONFIG_SERIO_PCIPS2 is not set
# CONFIG_SERIO_RAW is not set
# #
# Input Device Drivers # Input Device Drivers
...@@ -621,6 +625,7 @@ CONFIG_MOUSE_PS2=y ...@@ -621,6 +625,7 @@ CONFIG_MOUSE_PS2=y
# CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_TOUCHSCREEN is not set
CONFIG_INPUT_MISC=y CONFIG_INPUT_MISC=y
# CONFIG_INPUT_PCSPKR is not set
# CONFIG_INPUT_UINPUT is not set # CONFIG_INPUT_UINPUT is not set
# #
......
...@@ -17,7 +17,7 @@ obj-$(CONFIG_PPC_OF) += of_device.o ...@@ -17,7 +17,7 @@ obj-$(CONFIG_PPC_OF) += of_device.o
pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_pci_reset.o \ pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_pci_reset.o \
iSeries_IoMmTable.o iSeries_IoMmTable.o
pci-obj-$(CONFIG_PPC_PSERIES) += pci_dn.o pci_dma_direct.o pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_dma_direct.o
obj-$(CONFIG_PCI) += pci.o pci_iommu.o $(pci-obj-y) obj-$(CONFIG_PCI) += pci.o pci_iommu.o $(pci-obj-y)
...@@ -28,10 +28,11 @@ obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o \ ...@@ -28,10 +28,11 @@ obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o \
mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \
iSeries_iommu.o iSeries_iommu.o
obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o open_pic.o i8259.o prom_init.o prom.o
obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \ obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
eeh.o nvram.o pSeries_nvram.o rtasd.o ras.o \ eeh.o pSeries_nvram.o rtasd.o ras.o \
open_pic.o xics.o pSeries_htab.o rtas.o \ xics.o rtas.o pSeries_setup.o pSeries_iommu.o
chrp_setup.o i8259.o prom.o pSeries_iommu.o
obj-$(CONFIG_PROC_FS) += proc_ppc64.o obj-$(CONFIG_PROC_FS) += proc_ppc64.o
obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <asm/iSeries/ItLpPaca.h> #include <asm/iSeries/ItLpPaca.h>
#include <asm/iSeries/ItLpQueue.h> #include <asm/iSeries/ItLpQueue.h>
#include <asm/iSeries/HvLpEvent.h> #include <asm/iSeries/HvLpEvent.h>
#include <asm/prom.h>
#include <asm/rtas.h> #include <asm/rtas.h>
#include <asm/cputable.h> #include <asm/cputable.h>
...@@ -108,7 +107,6 @@ int main(void) ...@@ -108,7 +107,6 @@ int main(void)
DEFINE(LPPACASRR1, offsetof(struct ItLpPaca, xSavedSrr1)); DEFINE(LPPACASRR1, offsetof(struct ItLpPaca, xSavedSrr1));
DEFINE(LPPACAANYINT, offsetof(struct ItLpPaca, xIntDword.xAnyInt)); DEFINE(LPPACAANYINT, offsetof(struct ItLpPaca, xIntDword.xAnyInt));
DEFINE(LPPACADECRINT, offsetof(struct ItLpPaca, xIntDword.xFields.xDecrInt)); DEFINE(LPPACADECRINT, offsetof(struct ItLpPaca, xIntDword.xFields.xDecrInt));
DEFINE(PROMENTRY, offsetof(struct prom_t, entry));
/* RTAS */ /* RTAS */
DEFINE(RTASBASE, offsetof(struct rtas_t, base)); DEFINE(RTASBASE, offsetof(struct rtas_t, base));
......
This diff is collapsed.
...@@ -746,6 +746,10 @@ _STATIC(rtas_restore_regs) ...@@ -746,6 +746,10 @@ _STATIC(rtas_restore_regs)
mtlr r0 mtlr r0
blr /* return to caller */ blr /* return to caller */
#endif /* CONFIG_PPC_PSERIES */
#ifdef CONFIG_PPC_MULTIPLATFORM
_GLOBAL(enter_prom) _GLOBAL(enter_prom)
mflr r0 mflr r0
std r0,16(r1) std r0,16(r1)
...@@ -777,11 +781,8 @@ _GLOBAL(enter_prom) ...@@ -777,11 +781,8 @@ _GLOBAL(enter_prom)
std r11,_MSR(r1) std r11,_MSR(r1)
/* Get the PROM entrypoint */ /* Get the PROM entrypoint */
bl .reloc_offset ld r0,GPR4(r1)
LOADADDR(r12,prom) mtlr r0
sub r12,r12,r3
ld r12,PROMENTRY(r12)
mtlr r12
/* Switch MSR to 32 bits mode /* Switch MSR to 32 bits mode
*/ */
...@@ -834,4 +835,4 @@ _GLOBAL(enter_prom) ...@@ -834,4 +835,4 @@ _GLOBAL(enter_prom)
mtlr r0 mtlr r0
blr blr
#endif /* defined(CONFIG_PPC_PSERIES) */ #endif /* CONFIG_PPC_MULTIPLATFORM */
...@@ -83,13 +83,14 @@ ...@@ -83,13 +83,14 @@
.text .text
.globl _stext .globl _stext
_stext: _stext:
#ifdef CONFIG_PPC_PSERIES #ifdef CONFIG_PPC_MULTIPLATFORM
_STATIC(__start) _GLOBAL(__start)
/* NOP this out unconditionally */ /* NOP this out unconditionally */
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
b .__start_initialization_pSeries b .__start_initialization_multiplatform
END_FTR_SECTION(0, 1) END_FTR_SECTION(0, 1)
#endif #endif /* CONFIG_PPC_MULTIPLATFORM */
/* Catch branch to 0 in real mode */ /* Catch branch to 0 in real mode */
trap trap
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
...@@ -117,7 +118,8 @@ embedded_sysmap_start: ...@@ -117,7 +118,8 @@ embedded_sysmap_start:
.globl embedded_sysmap_end .globl embedded_sysmap_end
embedded_sysmap_end: embedded_sysmap_end:
.llong 0 .llong 0
#else
#else /* CONFIG_PPC_ISERIES */
/* Secondary processors spin on this value until it goes to 1. */ /* Secondary processors spin on this value until it goes to 1. */
.globl __secondary_hold_spinloop .globl __secondary_hold_spinloop
...@@ -1223,12 +1225,10 @@ _GLOBAL(pseries_secondary_smp_init) ...@@ -1223,12 +1225,10 @@ _GLOBAL(pseries_secondary_smp_init)
#endif #endif
b 1b /* Loop until told to go */ b 1b /* Loop until told to go */
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
_GLOBAL(__start_initialization_iSeries) _STATIC(__start_initialization_iSeries)
/* Clear out the BSS */ /* Clear out the BSS */
LOADADDR(r11,__bss_stop) LOADADDR(r11,__bss_stop)
LOADADDR(r8,__bss_start) LOADADDR(r8,__bss_start)
sub r11,r11,r8 /* bss size */ sub r11,r11,r8 /* bss size */
addi r11,r11,7 /* round up to an even double word */ addi r11,r11,7 /* round up to an even double word */
rldicl. r11,r11,61,3 /* shift right by 3 */ rldicl. r11,r11,61,3 /* shift right by 3 */
...@@ -1265,32 +1265,73 @@ _GLOBAL(__start_initialization_iSeries) ...@@ -1265,32 +1265,73 @@ _GLOBAL(__start_initialization_iSeries)
ld r6,PACA(r4) /* Get the base paca pointer */ ld r6,PACA(r4) /* Get the base paca pointer */
ld r4,PACASTABVIRT(r6) ld r4,PACASTABVIRT(r6)
bl .iSeries_fixup_klimit bl .iSeries_early_setup
/* relocation is on at this point */ /* relocation is on at this point */
b .start_here_common b .start_here_common
#endif #endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_PPC_PSERIES #ifdef CONFIG_PPC_MULTIPLATFORM
_STATIC(mmu_off) _STATIC(__mmu_off)
mfmsr r3 mfmsr r3
andi. r0,r3,MSR_IR|MSR_DR andi. r0,r3,MSR_IR|MSR_DR
beqlr beqlr
andc r3,r3,r0 andc r3,r3,r0
mtspr SRR0,r4 mtspr SPRN_SRR0,r4
mtspr SRR1,r3 mtspr SPRN_SRR1,r3
sync sync
rfid rfid
b . /* prevent speculative execution */ b . /* prevent speculative execution */
_GLOBAL(__start_initialization_pSeries)
mr r31,r3 /* save parameters */
/*
* Here is our main kernel entry point. We support currently 2 kind of entries
* depending on the value of r5.
*
* r5 != NULL -> OF entry, we go to prom_init, "legacy" parameter content
* in r3...r7
*
* r5 == NULL -> kexec style entry. r3 is a physical pointer to the
* DT block, r4 is a physical pointer to the kernel itself
*
*/
_GLOBAL(__start_initialization_multiplatform)
/*
* Are we booted from a PROM Of-type client-interface ?
*/
cmpldi cr0,r5,0
bne .__boot_from_prom /* yes -> prom */
/* Save parameters */
mr r31,r3
mr r30,r4
/* Make sure we are running in 64 bits mode */
bl .enable_64b_mode
/* Setup some critical 970 SPRs before switching MMU off */
bl .__970_cpu_preinit
/* cpu # */
li r24,0
/* Switch off MMU if not already */
LOADADDR(r4, .__after_prom_start - KERNELBASE)
add r4,r4,r30
bl .__mmu_off
b .__after_prom_start
_STATIC(__boot_from_prom)
/* Save parameters */
mr r31,r3
mr r30,r4 mr r30,r4
mr r29,r5 mr r29,r5
mr r28,r6 mr r28,r6
mr r27,r7 mr r27,r7
/* Make sure we are running in 64 bits mode */
bl .enable_64b_mode bl .enable_64b_mode
/* put a relocation offset into r3 */ /* put a relocation offset into r3 */
...@@ -1303,7 +1344,7 @@ _GLOBAL(__start_initialization_pSeries) ...@@ -1303,7 +1344,7 @@ _GLOBAL(__start_initialization_pSeries)
/* Relocate the TOC from a virt addr to a real addr */ /* Relocate the TOC from a virt addr to a real addr */
sub r2,r2,r3 sub r2,r2,r3
/* Save parameters */ /* Restore parameters */
mr r3,r31 mr r3,r31
mr r4,r30 mr r4,r30
mr r5,r29 mr r5,r29
...@@ -1312,17 +1353,8 @@ _GLOBAL(__start_initialization_pSeries) ...@@ -1312,17 +1353,8 @@ _GLOBAL(__start_initialization_pSeries)
/* Do all of the interaction with OF client interface */ /* Do all of the interaction with OF client interface */
bl .prom_init bl .prom_init
mr r23,r3 /* Save phys address we are running at */ /* We never return */
trap
/* Setup some critical 970 SPRs before switching MMU off */
bl .__970_cpu_preinit
li r24,0 /* cpu # */
/* Switch off MMU if not already */
LOADADDR(r4, .__after_prom_start - KERNELBASE)
add r4,r4,r23
bl .mmu_off
/* /*
* At this point, r3 contains the physical address we are running at, * At this point, r3 contains the physical address we are running at,
...@@ -1348,7 +1380,7 @@ _STATIC(__after_prom_start) ...@@ -1348,7 +1380,7 @@ _STATIC(__after_prom_start)
li r3,0 /* target addr */ li r3,0 /* target addr */
// XXX FIXME: Use phys returned by OF (r23) // XXX FIXME: Use phys returned by OF (r30)
sub r4,r27,r26 /* source addr */ sub r4,r27,r26 /* source addr */
/* current address of _start */ /* current address of _start */
/* i.e. where we are running */ /* i.e. where we are running */
...@@ -1373,8 +1405,9 @@ _STATIC(__after_prom_start) ...@@ -1373,8 +1405,9 @@ _STATIC(__after_prom_start)
ld r5,0(r5) /* get the value of klimit */ ld r5,0(r5) /* get the value of klimit */
sub r5,r5,r27 sub r5,r5,r27
bl .copy_and_flush /* copy the rest */ bl .copy_and_flush /* copy the rest */
b .start_here_pSeries b .start_here_multiplatform
#endif
#endif /* CONFIG_PPC_MULTIPLATFORM */
/* /*
* Copy routine used to copy the kernel to start at physical address 0 * Copy routine used to copy the kernel to start at physical address 0
...@@ -1794,15 +1827,33 @@ _GLOBAL(enable_64b_mode) ...@@ -1794,15 +1827,33 @@ _GLOBAL(enable_64b_mode)
isync isync
blr blr
#ifdef CONFIG_PPC_PSERIES #ifdef CONFIG_PPC_MULTIPLATFORM
/* /*
* This is where the main kernel code starts. * This is where the main kernel code starts.
*/ */
_STATIC(start_here_pSeries) _STATIC(start_here_multiplatform)
/* get a new offset, now that the kernel has moved. */ /* get a new offset, now that the kernel has moved. */
bl .reloc_offset bl .reloc_offset
mr r26,r3 mr r26,r3
/* Clear out the BSS. It may have been done in prom_init,
* already but that's irrelevant since prom_init will soon
* be detached from the kernel completely. Besides, we need
* to clear it now for kexec-style entry.
*/
LOADADDR(r11,__bss_stop)
LOADADDR(r8,__bss_start)
sub r11,r11,r8 /* bss size */
addi r11,r11,7 /* round up to an even double word */
rldicl. r11,r11,61,3 /* shift right by 3 */
beq 4f
addi r8,r8,-8
li r0,0
mtctr r11 /* zero this many doublewords */
3: stdu r0,8(r8)
bdnz 3b
4:
mfmsr r6 mfmsr r6
ori r6,r6,MSR_RI ori r6,r6,MSR_RI
mtmsrd r6 /* RI on */ mtmsrd r6 /* RI on */
...@@ -1875,8 +1926,11 @@ _STATIC(start_here_pSeries) ...@@ -1875,8 +1926,11 @@ _STATIC(start_here_pSeries)
mr r5,r26 mr r5,r26
bl .identify_cpu bl .identify_cpu
/* Get the pointer to the segment table which is used by */ /* Setup a valid physical PACA pointer in SPRG3 for early_setup
/* stab_initialize */ * note that boot_cpuid can always be 0 nowadays since there is
* nowhere it can be initialized differently before we reach this
* code
*/
LOADADDR(r27, boot_cpuid) LOADADDR(r27, boot_cpuid)
sub r27,r27,r26 sub r27,r27,r26
lwz r27,0(r27) lwz r27,0(r27)
...@@ -1885,12 +1939,18 @@ _STATIC(start_here_pSeries) ...@@ -1885,12 +1939,18 @@ _STATIC(start_here_pSeries)
mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r24 /* for this processor. */ add r13,r13,r24 /* for this processor. */
sub r13,r13,r26 /* convert to physical addr */ sub r13,r13,r26 /* convert to physical addr */
mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */ mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */
ld r3,PACASTABREAL(r13)
ori r4,r3,1 /* turn on valid bit */ /* Do very early kernel initializations, including initial hash table,
* stab and slb setup before we turn on relocation. */
/* Restore parameters passed from prom_init/kexec */
mr r3,r31
bl .early_setup
/* set the ASR */ /* set the ASR */
ld r3,PACASTABREAL(r13)
ori r4,r3,1 /* turn on valid bit */
li r3,SYSTEMCFG_PHYS_ADDR /* r3 = ptr to systemcfg */ li r3,SYSTEMCFG_PHYS_ADDR /* r3 = ptr to systemcfg */
lwz r3,PLATFORM(r3) /* r3 = platform flags */ lwz r3,PLATFORM(r3) /* r3 = platform flags */
cmpldi r3,PLATFORM_PSERIES_LPAR cmpldi r3,PLATFORM_PSERIES_LPAR
...@@ -1909,13 +1969,7 @@ _STATIC(start_here_pSeries) ...@@ -1909,13 +1969,7 @@ _STATIC(start_here_pSeries)
98: /* !(rpa hypervisor) || !(star) */ 98: /* !(rpa hypervisor) || !(star) */
mtasr r4 /* set the stab location */ mtasr r4 /* set the stab location */
99: 99:
mfspr r6,SPRG3 /* Set SDR1 (hash table pointer) */
ld r3,PACASTABREAL(r6) /* restore r3 for stab_initialize */
/* Initialize an initial memory mapping and turn on relocation. */
bl .stab_initialize
bl .htab_initialize
li r3,SYSTEMCFG_PHYS_ADDR /* r3 = ptr to systemcfg */ li r3,SYSTEMCFG_PHYS_ADDR /* r3 = ptr to systemcfg */
lwz r3,PLATFORM(r3) /* r3 = platform flags */ lwz r3,PLATFORM(r3) /* r3 = platform flags */
/* Test if bit 0 is set (LPAR bit) */ /* Test if bit 0 is set (LPAR bit) */
...@@ -1932,7 +1986,7 @@ _STATIC(start_here_pSeries) ...@@ -1932,7 +1986,7 @@ _STATIC(start_here_pSeries)
mtspr SRR1,r4 mtspr SRR1,r4
rfid rfid
b . /* prevent speculative execution */ b . /* prevent speculative execution */
#endif /* CONFIG_PPC_PSERIES */ #endif /* CONFIG_PPC_MULTIPLATFORM */
/* This is where all platforms converge execution */ /* This is where all platforms converge execution */
_STATIC(start_here_common) _STATIC(start_here_common)
...@@ -1980,13 +2034,6 @@ _STATIC(start_here_common) ...@@ -1980,13 +2034,6 @@ _STATIC(start_here_common)
ld r2,PACATOC(r13) ld r2,PACATOC(r13)
std r1,PACAKSAVE(r13) std r1,PACAKSAVE(r13)
/* Restore the parms passed in from the bootloader. */
mr r3,r31
mr r4,r30
mr r5,r29
mr r6,r28
mr r7,r27
bl .setup_system bl .setup_system
/* Load up the kernel context */ /* Load up the kernel context */
......
...@@ -233,4 +233,6 @@ void hpte_init_iSeries(void) ...@@ -233,4 +233,6 @@ void hpte_init_iSeries(void)
ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp; ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
ppc_md.hpte_insert = iSeries_hpte_insert; ppc_md.hpte_insert = iSeries_hpte_insert;
ppc_md.hpte_remove = iSeries_hpte_remove; ppc_md.hpte_remove = iSeries_hpte_remove;
htab_finish_init();
} }
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#undef DEBUG
#include <linux/config.h> #include <linux/config.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/threads.h> #include <linux/threads.h>
...@@ -54,6 +56,14 @@ ...@@ -54,6 +56,14 @@
#include <asm/iSeries/iSeries_proc.h> #include <asm/iSeries/iSeries_proc.h>
#include <asm/iSeries/mf.h> #include <asm/iSeries/mf.h>
extern void hvlog(char *fmt, ...);
#ifdef DEBUG
#define DBG(fmt...) hvlog(fmt)
#else
#define DBG(fmt...)
#endif
/* Function Prototypes */ /* Function Prototypes */
extern void ppcdbg_initialize(void); extern void ppcdbg_initialize(void);
extern void tce_init_iSeries(void); extern void tce_init_iSeries(void);
...@@ -75,8 +85,6 @@ static unsigned long tbFreqMhzHundreths; ...@@ -75,8 +85,6 @@ static unsigned long tbFreqMhzHundreths;
int piranha_simulator; int piranha_simulator;
int boot_cpuid;
extern int rd_size; /* Defined in drivers/block/rd.c */ extern int rd_size; /* Defined in drivers/block/rd.c */
extern unsigned long klimit; extern unsigned long klimit;
extern unsigned long embedded_sysmap_start; extern unsigned long embedded_sysmap_start;
...@@ -275,8 +283,28 @@ unsigned long iSeries_process_mainstore_vpd(struct MemoryBlock *mb_array, ...@@ -275,8 +283,28 @@ unsigned long iSeries_process_mainstore_vpd(struct MemoryBlock *mb_array,
return mem_blocks; return mem_blocks;
} }
void __init iSeries_init_early(void) static void __init iSeries_parse_cmdline(void)
{ {
char *p, *q;
/* copy the command line parameter from the primary VSP */
HvCallEvent_dmaToSp(cmd_line, 2 * 64* 1024, 256,
HvLpDma_Direction_RemoteToLocal);
p = cmd_line;
q = cmd_line + 255;
while(p < q) {
if (!*p || *p == '\n')
break;
++p;
}
*p = 0;
}
/*static*/ void __init iSeries_init_early(void)
{
DBG(" -> iSeries_init_early()\n");
ppcdbg_initialize(); ppcdbg_initialize();
#if defined(CONFIG_BLK_DEV_INITRD) #if defined(CONFIG_BLK_DEV_INITRD)
...@@ -300,25 +328,20 @@ void __init iSeries_init_early(void) ...@@ -300,25 +328,20 @@ void __init iSeries_init_early(void)
iSeries_recal_tb = get_tb(); iSeries_recal_tb = get_tb();
iSeries_recal_titan = HvCallXm_loadTod(); iSeries_recal_titan = HvCallXm_loadTod();
ppc_md.setup_arch = iSeries_setup_arch; /*
ppc_md.get_cpuinfo = iSeries_get_cpuinfo; * Cache sizes must be initialized before hpte_init_iSeries is called
ppc_md.init_IRQ = iSeries_init_IRQ; * as the later need them for flush_icache_range()
ppc_md.get_irq = iSeries_get_irq; */
ppc_md.init = NULL; setup_iSeries_cache_sizes();
ppc_md.pcibios_fixup = iSeries_pci_final_fixup;
ppc_md.restart = iSeries_restart;
ppc_md.power_off = iSeries_power_off;
ppc_md.halt = iSeries_halt;
ppc_md.get_boot_time = iSeries_get_boot_time;
ppc_md.set_rtc_time = iSeries_set_rtc_time;
ppc_md.get_rtc_time = iSeries_get_rtc_time;
ppc_md.calibrate_decr = iSeries_calibrate_decr;
ppc_md.progress = iSeries_progress;
/*
* Initialize the hash table management pointers
*/
hpte_init_iSeries(); hpte_init_iSeries();
/*
* Initialize the DMA/TCE management
*/
tce_init_iSeries(); tce_init_iSeries();
/* /*
...@@ -326,7 +349,7 @@ void __init iSeries_init_early(void) ...@@ -326,7 +349,7 @@ void __init iSeries_init_early(void)
* AS/400 absolute addresses * AS/400 absolute addresses
*/ */
build_iSeries_Memory_Map(); build_iSeries_Memory_Map();
setup_iSeries_cache_sizes();
/* Initialize machine-dependency vectors */ /* Initialize machine-dependency vectors */
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
smp_init_iSeries(); smp_init_iSeries();
...@@ -340,24 +363,22 @@ void __init iSeries_init_early(void) ...@@ -340,24 +363,22 @@ void __init iSeries_init_early(void)
mf_init(); mf_init();
mf_initialized = 1; mf_initialized = 1;
mb(); mb();
}
void __init iSeries_parse_cmdline(void) /* If we were passed an initrd, set the ROOT_DEV properly if the values
{ * look sensible. If not, clear initrd reference.
char *p, *q; */
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE &&
initrd_end > initrd_start)
ROOT_DEV = Root_RAM0;
else
initrd_start = initrd_end = 0;
#endif /* CONFIG_BLK_DEV_INITRD */
/* copy the command line parameter from the primary VSP */
HvCallEvent_dmaToSp(cmd_line, 2 * 64* 1024, 256,
HvLpDma_Direction_RemoteToLocal);
p = cmd_line; iSeries_parse_cmdline();
q = cmd_line + 255;
while(p < q) { DBG(" <- iSeries_init_early()\n");
if (!*p || *p == '\n')
break;
++p;
}
*p = 0;
} }
/* /*
...@@ -781,7 +802,7 @@ void __init iSeries_progress(char * st, unsigned short code) ...@@ -781,7 +802,7 @@ void __init iSeries_progress(char * st, unsigned short code)
} }
} }
void iSeries_fixup_klimit(void) static void __init iSeries_fixup_klimit(void)
{ {
/* /*
* Change klimit to take into account any ram disk * Change klimit to take into account any ram disk
...@@ -810,3 +831,27 @@ int __init iSeries_src_init(void) ...@@ -810,3 +831,27 @@ int __init iSeries_src_init(void)
} }
late_initcall(iSeries_src_init); late_initcall(iSeries_src_init);
void __init iSeries_early_setup(void)
{
iSeries_fixup_klimit();
ppc_md.setup_arch = iSeries_setup_arch;
ppc_md.get_cpuinfo = iSeries_get_cpuinfo;
ppc_md.init_IRQ = iSeries_init_IRQ;
ppc_md.get_irq = iSeries_get_irq;
ppc_md.init_early = iSeries_init_early,
ppc_md.pcibios_fixup = iSeries_pci_final_fixup;
ppc_md.restart = iSeries_restart;
ppc_md.power_off = iSeries_power_off;
ppc_md.halt = iSeries_halt;
ppc_md.get_boot_time = iSeries_get_boot_time;
ppc_md.set_rtc_time = iSeries_set_rtc_time;
ppc_md.get_rtc_time = iSeries_get_rtc_time;
ppc_md.calibrate_decr = iSeries_calibrate_decr;
ppc_md.progress = iSeries_progress;
}
...@@ -19,10 +19,6 @@ ...@@ -19,10 +19,6 @@
#ifndef __ISERIES_SETUP_H__ #ifndef __ISERIES_SETUP_H__
#define __ISERIES_SETUP_H__ #define __ISERIES_SETUP_H__
extern void iSeries_init_early(void);
extern void iSeries_init(unsigned long r3, unsigned long ird_start,
unsigned long ird_end, unsigned long cline_start,
unsigned long cline_end);
extern void iSeries_setup_arch(void); extern void iSeries_setup_arch(void);
extern void iSeries_setup_residual(struct seq_file *m, int cpu_id); extern void iSeries_setup_residual(struct seq_file *m, int cpu_id);
extern void iSeries_get_cpuinfo(struct seq_file *m); extern void iSeries_get_cpuinfo(struct seq_file *m);
......
...@@ -30,9 +30,8 @@ ...@@ -30,9 +30,8 @@
#include <asm/time.h> #include <asm/time.h>
#include <asm/iSeries/HvCall.h> #include <asm/iSeries/HvCall.h>
#include <asm/iSeries/ItLpQueue.h> #include <asm/iSeries/ItLpQueue.h>
#include <asm/plpar_wrappers.h>
extern long cede_processor(void);
extern long poll_pending(void);
extern void power4_idle(void); extern void power4_idle(void);
static int (*idle_loop)(void); static int (*idle_loop)(void);
...@@ -153,6 +152,8 @@ static int default_idle(void) ...@@ -153,6 +152,8 @@ static int default_idle(void)
return 0; return 0;
} }
#ifdef CONFIG_PPC_PSERIES
DECLARE_PER_CPU(unsigned long, smt_snooze_delay); DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
int dedicated_idle(void) int dedicated_idle(void)
...@@ -280,9 +281,12 @@ static int shared_idle(void) ...@@ -280,9 +281,12 @@ static int shared_idle(void)
return 0; return 0;
} }
static int powermac_idle(void) #endif /* CONFIG_PPC_PSERIES */
static int native_idle(void)
{ {
while(1) { while(1) {
/* check CPU type here */
if (!need_resched()) if (!need_resched())
power4_idle(); power4_idle();
if (need_resched()) if (need_resched())
...@@ -290,7 +294,8 @@ static int powermac_idle(void) ...@@ -290,7 +294,8 @@ static int powermac_idle(void)
} }
return 0; return 0;
} }
#endif
#endif /* CONFIG_PPC_ISERIES */
int cpu_idle(void) int cpu_idle(void)
{ {
...@@ -332,30 +337,38 @@ __initcall(register_powersave_nap_sysctl); ...@@ -332,30 +337,38 @@ __initcall(register_powersave_nap_sysctl);
int idle_setup(void) int idle_setup(void)
{ {
/*
* Move that junk to each platform specific file, eventually define
* a pSeries_idle for shared processor stuff
*/
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
idle_loop = iSeries_idle; idle_loop = iSeries_idle;
return 1;
#else #else
idle_loop = default_idle;
#endif
#ifdef CONFIG_PPC_PSERIES
if (systemcfg->platform & PLATFORM_PSERIES) { if (systemcfg->platform & PLATFORM_PSERIES) {
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
if (get_paca()->lppaca.xSharedProc) { if (get_paca()->lppaca.xSharedProc) {
printk("idle = shared_idle\n"); printk(KERN_INFO "Using shared processor idle loop\n");
idle_loop = shared_idle; idle_loop = shared_idle;
} else { } else {
printk("idle = dedicated_idle\n"); printk(KERN_INFO "Using dedicated idle loop\n");
idle_loop = dedicated_idle; idle_loop = dedicated_idle;
} }
} else { } else {
printk("idle = default_idle\n"); printk(KERN_INFO "Using default idle loop\n");
idle_loop = default_idle; idle_loop = default_idle;
} }
} else if (systemcfg->platform == PLATFORM_POWERMAC) {
printk("idle = powermac_idle\n");
idle_loop = powermac_idle;
} else {
printk("idle_setup: unknown platform, use default_idle\n");
idle_loop = default_idle;
} }
#endif #endif /* CONFIG_PPC_PSERIES */
#ifdef CONFIG_PPC_PMAC
if (systemcfg->platform == PLATFORM_POWERMAC) {
printk(KERN_INFO "Using native/NAP idle loop\n");
idle_loop = native_idle;
}
#endif /* CONFIG_PPC_PMAC */
return 1; return 1;
} }
...@@ -22,6 +22,43 @@ ...@@ -22,6 +22,43 @@
struct lmb lmb; struct lmb lmb;
#undef DEBUG
void lmb_dump_all(void)
{
#ifdef DEBUG
unsigned long i;
struct lmb *_lmb = &lmb;
udbg_printf("lmb_dump_all:\n");
udbg_printf(" memory.cnt = 0x%lx\n",
_lmb->memory.cnt);
udbg_printf(" memory.size = 0x%lx\n",
_lmb->memory.size);
for (i=0; i < _lmb->memory.cnt ;i++) {
udbg_printf(" memory.region[0x%x].base = 0x%lx\n",
i, _lmb->memory.region[i].base);
udbg_printf(" .physbase = 0x%lx\n",
_lmb->memory.region[i].physbase);
udbg_printf(" .size = 0x%lx\n",
_lmb->memory.region[i].size);
}
udbg_printf("\n reserved.cnt = 0x%lx\n",
_lmb->reserved.cnt);
udbg_printf(" reserved.size = 0x%lx\n",
_lmb->reserved.size);
for (i=0; i < _lmb->reserved.cnt ;i++) {
udbg_printf(" reserved.region[0x%x].base = 0x%lx\n",
i, _lmb->reserved.region[i].base);
udbg_printf(" .physbase = 0x%lx\n",
_lmb->reserved.region[i].physbase);
udbg_printf(" .size = 0x%lx\n",
_lmb->reserved.region[i].size);
}
#endif /* DEBUG */
}
static unsigned long __init static unsigned long __init
lmb_addrs_overlap(unsigned long base1, unsigned long size1, lmb_addrs_overlap(unsigned long base1, unsigned long size1,
unsigned long base2, unsigned long size2) unsigned long base2, unsigned long size2)
...@@ -71,8 +108,7 @@ lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, unsigned long r2) ...@@ -71,8 +108,7 @@ lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
void __init void __init
lmb_init(void) lmb_init(void)
{ {
unsigned long offset = reloc_offset(); struct lmb *_lmb = &lmb;
struct lmb *_lmb = PTRRELOC(&lmb);
/* Create a dummy zero size LMB which will get coalesced away later. /* Create a dummy zero size LMB which will get coalesced away later.
* This simplifies the lmb_add() code below... * This simplifies the lmb_add() code below...
...@@ -94,8 +130,7 @@ lmb_analyze(void) ...@@ -94,8 +130,7 @@ lmb_analyze(void)
unsigned long i; unsigned long i;
unsigned long mem_size = 0; unsigned long mem_size = 0;
unsigned long size_mask = 0; unsigned long size_mask = 0;
unsigned long offset = reloc_offset(); struct lmb *_lmb = &lmb;
struct lmb *_lmb = PTRRELOC(&lmb);
#ifdef CONFIG_MSCHUNKS #ifdef CONFIG_MSCHUNKS
unsigned long physbase = 0; unsigned long physbase = 0;
#endif #endif
...@@ -178,8 +213,7 @@ lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size) ...@@ -178,8 +213,7 @@ lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
long __init long __init
lmb_add(unsigned long base, unsigned long size) lmb_add(unsigned long base, unsigned long size)
{ {
unsigned long offset = reloc_offset(); struct lmb *_lmb = &lmb;
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb_region *_rgn = &(_lmb->memory); struct lmb_region *_rgn = &(_lmb->memory);
/* On pSeries LPAR systems, the first LMB is our RMO region. */ /* On pSeries LPAR systems, the first LMB is our RMO region. */
...@@ -193,8 +227,7 @@ lmb_add(unsigned long base, unsigned long size) ...@@ -193,8 +227,7 @@ lmb_add(unsigned long base, unsigned long size)
long __init long __init
lmb_reserve(unsigned long base, unsigned long size) lmb_reserve(unsigned long base, unsigned long size)
{ {
unsigned long offset = reloc_offset(); struct lmb *_lmb = &lmb;
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb_region *_rgn = &(_lmb->reserved); struct lmb_region *_rgn = &(_lmb->reserved);
return lmb_add_region(_rgn, base, size); return lmb_add_region(_rgn, base, size);
...@@ -227,8 +260,7 @@ lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr) ...@@ -227,8 +260,7 @@ lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr)
{ {
long i, j; long i, j;
unsigned long base = 0; unsigned long base = 0;
unsigned long offset = reloc_offset(); struct lmb *_lmb = &lmb;
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb_region *_mem = &(_lmb->memory); struct lmb_region *_mem = &(_lmb->memory);
struct lmb_region *_rsv = &(_lmb->reserved); struct lmb_region *_rsv = &(_lmb->reserved);
...@@ -263,8 +295,7 @@ lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr) ...@@ -263,8 +295,7 @@ lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr)
unsigned long __init unsigned long __init
lmb_phys_mem_size(void) lmb_phys_mem_size(void)
{ {
unsigned long offset = reloc_offset(); struct lmb *_lmb = &lmb;
struct lmb *_lmb = PTRRELOC(&lmb);
#ifdef CONFIG_MSCHUNKS #ifdef CONFIG_MSCHUNKS
return _lmb->memory.size; return _lmb->memory.size;
#else #else
...@@ -282,8 +313,7 @@ lmb_phys_mem_size(void) ...@@ -282,8 +313,7 @@ lmb_phys_mem_size(void)
unsigned long __init unsigned long __init
lmb_end_of_DRAM(void) lmb_end_of_DRAM(void)
{ {
unsigned long offset = reloc_offset(); struct lmb *_lmb = &lmb;
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb_region *_mem = &(_lmb->memory); struct lmb_region *_mem = &(_lmb->memory);
int idx = _mem->cnt - 1; int idx = _mem->cnt - 1;
...@@ -300,8 +330,7 @@ unsigned long __init ...@@ -300,8 +330,7 @@ unsigned long __init
lmb_abs_to_phys(unsigned long aa) lmb_abs_to_phys(unsigned long aa)
{ {
unsigned long i, pa = aa; unsigned long i, pa = aa;
unsigned long offset = reloc_offset(); struct lmb *_lmb = &lmb;
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb_region *_mem = &(_lmb->memory); struct lmb_region *_mem = &(_lmb->memory);
for (i=0; i < _mem->cnt; i++) { for (i=0; i < _mem->cnt; i++) {
......
...@@ -127,6 +127,47 @@ _GLOBAL(call_handle_irq_event) ...@@ -127,6 +127,47 @@ _GLOBAL(call_handle_irq_event)
blr blr
#endif /* CONFIG_IRQSTACKS */ #endif /* CONFIG_IRQSTACKS */
/*
* To be called by C code which needs to do some operations with MMU
* disabled. Note that interrupts have to be disabled by the caller
* prior to calling us. The code called _MUST_ be in the RMO of course
* and part of the linear mapping as we don't attempt to translate the
* stack pointer at all. The function is called with the stack switched
* to this CPU emergency stack
*
* prototype is void *call_with_mmu_off(void *func, void *data);
*
* the called function is expected to be of the form
*
* void *called(void *data);
*/
_GLOBAL(call_with_mmu_off)
mflr r0 /* get link, save it on stackframe */
std r0,16(r1)
mr r1,r5 /* save old stack ptr */
ld r1,PACAEMERGSP(r13) /* get emerg. stack */
subi r1,r1,STACK_FRAME_OVERHEAD
std r0,16(r1) /* save link on emerg. stack */
std r5,0(r1) /* save old stack ptr in backchain */
ld r3,0(r3) /* get to real function ptr (assume same TOC) */
bl 2f /* we need LR to return, continue at label 2 */
ld r0,16(r1) /* we return here from the call, get LR and */
ld r1,0(r1) /* .. old stack ptr */
mtspr SPRN_SRR0,r0 /* and get back to virtual mode with these */
mfmsr r4
ori r4,r4,MSR_IR|MSR_DR
mtspr SPRN_SRR1,r4
rfid
2: mtspr SPRN_SRR0,r3 /* coming from above, enter real mode */
mr r3,r4 /* get parameter */
mfmsr r0
ori r0,r0,MSR_IR|MSR_DR
xori r0,r0,MSR_IR|MSR_DR
mtspr SPRN_SRR1,r0
rfid
/* /*
* Flush instruction cache. * Flush instruction cache.
*/ */
...@@ -454,17 +495,6 @@ _GLOBAL(_outsl_ns) ...@@ -454,17 +495,6 @@ _GLOBAL(_outsl_ns)
sync sync
blr blr
_GLOBAL(_get_PVR)
mfspr r3,PVR
blr
_GLOBAL(_get_PIR)
mfspr r3,PIR
blr
_GLOBAL(_get_HID0)
mfspr r3,HID0
blr
_GLOBAL(cvt_fd) _GLOBAL(cvt_fd)
lfd 0,0(r5) /* load up fpscr value */ lfd 0,0(r5) /* load up fpscr value */
...@@ -561,6 +591,69 @@ _GLOBAL(do_cpu_ftr_fixups) ...@@ -561,6 +591,69 @@ _GLOBAL(do_cpu_ftr_fixups)
isync isync
b 1b b 1b
#ifdef CONFIG_PPC_PMAC
/*
* Do an IO access in real mode
*/
_GLOBAL(real_readb)
mfmsr r7
ori r0,r7,MSR_DR
xori r0,r0,MSR_DR
sync
mtmsrd r0
sync
isync
mfspr r6,SPRN_HID4
rldicl r5,r6,32,0
ori r5,r5,0x100
rldicl r5,r5,32,0
sync
mtspr SPRN_HID4,r5
isync
slbia
isync
lbz r3,0(r3)
sync
mtspr SPRN_HID4,r6
isync
slbia
isync
mtmsrd r7
sync
isync
blr
/*
* Do an IO access in real mode
*/
_GLOBAL(real_writeb)
mfmsr r7
ori r0,r7,MSR_DR
xori r0,r0,MSR_DR
sync
mtmsrd r0
sync
isync
mfspr r6,SPRN_HID4
rldicl r5,r6,32,0
ori r5,r5,0x100
rldicl r5,r5,32,0
sync
mtspr SPRN_HID4,r5
isync
slbia
isync
stb r3,0(r4)
sync
mtspr SPRN_HID4,r6
isync
slbia
isync
mtmsrd r7
sync
isync
blr
#endif /* CONFIG_PPC_PMAC */
/* /*
* Create a kernel thread * Create a kernel thread
...@@ -594,7 +687,7 @@ _GLOBAL(kernel_thread) ...@@ -594,7 +687,7 @@ _GLOBAL(kernel_thread)
ld r30,-16(r1) ld r30,-16(r1)
blr blr
#ifdef CONFIG_PPC_ISERIES /* hack hack hack */ #ifndef CONFIG_PPC_PSERIE /* hack hack hack */
#define ppc_rtas sys_ni_syscall #define ppc_rtas sys_ni_syscall
#endif #endif
......
...@@ -603,6 +603,7 @@ void __exit nvram_cleanup(void) ...@@ -603,6 +603,7 @@ void __exit nvram_cleanup(void)
} }
#ifdef CONFIG_PPC_PSERIES
/* nvram_write_error_log /* nvram_write_error_log
* *
...@@ -727,6 +728,7 @@ int nvram_clear_error_log() ...@@ -727,6 +728,7 @@ int nvram_clear_error_log()
return 0; return 0;
} }
#endif /* CONFIG_PPC_PSERIES */
module_init(nvram_init); module_init(nvram_init);
module_exit(nvram_cleanup); module_exit(nvram_cleanup);
......
...@@ -362,7 +362,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, ...@@ -362,7 +362,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
find_ISUs(); find_ISUs();
/* Initialize timer interrupts */ /* Initialize timer interrupts */
ppc64_boot_msg(0x21, "OpenPic Timer");
for (i = 0; i < OPENPIC_NUM_TIMERS; i++) { for (i = 0; i < OPENPIC_NUM_TIMERS; i++) {
/* Disabled, Priority 0 */ /* Disabled, Priority 0 */
openpic_inittimer(i, 0, openpic_vec_timer+i); openpic_inittimer(i, 0, openpic_vec_timer+i);
...@@ -372,7 +371,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, ...@@ -372,7 +371,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Initialize IPI interrupts */ /* Initialize IPI interrupts */
ppc64_boot_msg(0x22, "OpenPic IPI");
openpic_test_broken_IPI(); openpic_test_broken_IPI();
for (i = 0; i < OPENPIC_NUM_IPI; i++) { for (i = 0; i < OPENPIC_NUM_IPI; i++) {
/* Disabled, Priority 10..13 */ /* Disabled, Priority 10..13 */
...@@ -384,8 +382,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, ...@@ -384,8 +382,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
#endif #endif
/* Initialize external interrupts */ /* Initialize external interrupts */
ppc64_boot_msg(0x23, "OpenPic Ext");
openpic_set_priority(0xf); openpic_set_priority(0xf);
/* SIOint (8259 cascade) is special */ /* SIOint (8259 cascade) is special */
...@@ -420,7 +416,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, ...@@ -420,7 +416,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
irq_desc[i].handler = &open_pic; irq_desc[i].handler = &open_pic;
/* Initialize the spurious interrupt */ /* Initialize the spurious interrupt */
ppc64_boot_msg(0x24, "OpenPic Spurious");
openpic_set_spurious(openpic_vec_spurious); openpic_set_spurious(openpic_vec_spurious);
openpic_set_priority(0); openpic_set_priority(0);
......
...@@ -344,5 +344,5 @@ void __init openpic2_init(int offset) ...@@ -344,5 +344,5 @@ void __init openpic2_init(int offset)
openpic2_set_priority(0); openpic2_set_priority(0);
openpic2_disable_8259_pass_through(); openpic2_disable_8259_pass_through();
ppc64_boot_msg(0x25, "OpenPic2 Done"); ppc64_boot_msg(0x25, "OpenPic U3 Done");
} }
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <asm/pci-bridge.h> #include <asm/pci-bridge.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/abs_addr.h> #include <asm/abs_addr.h>
#include <asm/plpar_wrappers.h>
#include "pci.h" #include "pci.h"
...@@ -88,6 +89,150 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) ...@@ -88,6 +89,150 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
} }
static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
long npages, unsigned long uaddr,
enum dma_data_direction direction)
{
u64 rc;
union tce_entry tce;
tce.te_word = 0;
tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
tce.te_rdwr = 1;
if (direction != DMA_TO_DEVICE)
tce.te_pciwr = 1;
while (npages--) {
rc = plpar_tce_put((u64)tbl->it_index,
(u64)tcenum << 12,
tce.te_word );
if (rc && printk_ratelimit()) {
printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
printk("\tindex = 0x%lx\n", (u64)tbl->it_index);
printk("\ttcenum = 0x%lx\n", (u64)tcenum);
printk("\ttce val = 0x%lx\n", tce.te_word );
show_stack(current, (unsigned long *)__get_SP());
}
tcenum++;
tce.te_rpn++;
}
}
DEFINE_PER_CPU(void *, tce_page) = NULL;
static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
long npages, unsigned long uaddr,
enum dma_data_direction direction)
{
u64 rc;
union tce_entry tce, *tcep;
long l, limit;
if (npages == 1)
return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
direction);
tcep = __get_cpu_var(tce_page);
/* This is safe to do since interrupts are off when we're called
* from iommu_alloc{,_sg}()
*/
if (!tcep) {
tcep = (void *)__get_free_page(GFP_ATOMIC);
/* If allocation fails, fall back to the loop implementation */
if (!tcep)
return tce_build_pSeriesLP(tbl, tcenum, npages,
uaddr, direction);
__get_cpu_var(tce_page) = tcep;
}
tce.te_word = 0;
tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
tce.te_rdwr = 1;
if (direction != DMA_TO_DEVICE)
tce.te_pciwr = 1;
/* We can map max one pageful of TCEs at a time */
do {
/*
* Set up the page with TCE data, looping through and setting
* the values.
*/
limit = min_t(long, npages, PAGE_SIZE/sizeof(union tce_entry));
for (l = 0; l < limit; l++) {
tcep[l] = tce;
tce.te_rpn++;
}
rc = plpar_tce_put_indirect((u64)tbl->it_index,
(u64)tcenum << 12,
(u64)virt_to_abs(tcep),
limit);
npages -= limit;
tcenum += limit;
} while (npages > 0 && !rc);
if (rc && printk_ratelimit()) {
printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
printk("\tindex = 0x%lx\n", (u64)tbl->it_index);
printk("\tnpages = 0x%lx\n", (u64)npages);
printk("\ttce[0] val = 0x%lx\n", tcep[0].te_word);
show_stack(current, (unsigned long *)__get_SP());
}
}
static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
{
u64 rc;
union tce_entry tce;
tce.te_word = 0;
while (npages--) {
rc = plpar_tce_put((u64)tbl->it_index,
(u64)tcenum << 12,
tce.te_word);
if (rc && printk_ratelimit()) {
printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
printk("\tindex = 0x%lx\n", (u64)tbl->it_index);
printk("\ttcenum = 0x%lx\n", (u64)tcenum);
printk("\ttce val = 0x%lx\n", tce.te_word );
show_stack(current, (unsigned long *)__get_SP());
}
tcenum++;
}
}
static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
{
u64 rc;
union tce_entry tce;
tce.te_word = 0;
rc = plpar_tce_stuff((u64)tbl->it_index,
(u64)tcenum << 12,
tce.te_word,
npages);
if (rc && printk_ratelimit()) {
printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n");
printk("\trc = %ld\n", rc);
printk("\tindex = 0x%lx\n", (u64)tbl->it_index);
printk("\tnpages = 0x%lx\n", (u64)npages);
printk("\ttce val = 0x%lx\n", tce.te_word );
show_stack(current, (unsigned long *)__get_SP());
}
}
static void iommu_buses_init(void) static void iommu_buses_init(void)
{ {
struct pci_controller *phb, *tmp; struct pci_controller *phb, *tmp;
...@@ -166,24 +311,25 @@ static void iommu_table_setparms(struct pci_controller *phb, ...@@ -166,24 +311,25 @@ static void iommu_table_setparms(struct pci_controller *phb,
struct device_node *dn, struct device_node *dn,
struct iommu_table *tbl) struct iommu_table *tbl)
{ {
phandle node; struct device_node *node;
unsigned long i; unsigned long *basep;
struct of_tce_table *oft; unsigned int *sizep;
node = ((struct device_node *)(phb->arch_data))->node;
oft = NULL; node = (struct device_node *)phb->arch_data;
for (i=0; of_tce_table[i].node; i++) if (get_property(node, "linux,has-tce-table", NULL) == NULL) {
if(of_tce_table[i].node == node) { printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has no tce table !\n",
oft = &of_tce_table[i]; dn->full_name);
break; return;
} }
basep = (unsigned long *)get_property(node, "linux,tce-base", NULL);
if (!oft) sizep = (unsigned int *)get_property(node, "linux,tce-size", NULL);
panic("PCI_DMA: iommu_table_setparms: Can't find phb named '%s' in of_tce_table\n", dn->full_name); if (basep == NULL || sizep == NULL) {
printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has missing tce"
memset((void *)oft->base, 0, oft->size); " entries !\n", dn->full_name);
return;
}
memset((void *)(*basep), 0, *sizep);
tbl->it_busno = phb->bus->number; tbl->it_busno = phb->bus->number;
...@@ -207,7 +353,7 @@ static void iommu_table_setparms(struct pci_controller *phb, ...@@ -207,7 +353,7 @@ static void iommu_table_setparms(struct pci_controller *phb,
if (phb->dma_window_base_cur > (1 << 19)) if (phb->dma_window_base_cur > (1 << 19))
panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
tbl->it_base = oft->base; tbl->it_base = *basep;
tbl->it_index = 0; tbl->it_index = 0;
tbl->it_entrysize = sizeof(union tce_entry); tbl->it_entrysize = sizeof(union tce_entry);
tbl->it_blocksize = 16; tbl->it_blocksize = 16;
...@@ -295,8 +441,16 @@ void iommu_setup_pSeries(void) ...@@ -295,8 +441,16 @@ void iommu_setup_pSeries(void)
/* These are called very early. */ /* These are called very early. */
void tce_init_pSeries(void) void tce_init_pSeries(void)
{ {
if (!(systemcfg->platform & PLATFORM_LPAR)) {
ppc_md.tce_build = tce_build_pSeries; ppc_md.tce_build = tce_build_pSeries;
ppc_md.tce_free = tce_free_pSeries; ppc_md.tce_free = tce_free_pSeries;
} else if (cur_cpu_spec->firmware_features & FW_FEATURE_MULTITCE) {
ppc_md.tce_build = tce_buildmulti_pSeriesLP;
ppc_md.tce_free = tce_freemulti_pSeriesLP;
} else {
ppc_md.tce_build = tce_build_pSeriesLP;
ppc_md.tce_free = tce_free_pSeriesLP;
}
pci_iommu_init(); pci_iommu_init();
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -54,9 +54,9 @@ static inline struct iommu_table *devnode_table(struct pci_dev *dev) ...@@ -54,9 +54,9 @@ static inline struct iommu_table *devnode_table(struct pci_dev *dev)
return ISERIES_DEVNODE(dev)->iommu_table; return ISERIES_DEVNODE(dev)->iommu_table;
#endif /* CONFIG_PPC_ISERIES */ #endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_PPC_PSERIES #ifdef CONFIG_PPC_MULTIPLATFORM
return PCI_GET_DN(dev)->iommu_table; return PCI_GET_DN(dev)->iommu_table;
#endif /* CONFIG_PPC_PSERIES */ #endif /* CONFIG_PPC_MULTIPLATFORM */
} }
......
...@@ -29,4 +29,6 @@ extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, ...@@ -29,4 +29,6 @@ extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
extern void pmac_nvram_init(void); extern void pmac_nvram_init(void);
extern void pmac_iommu_alloc(void);
#endif /* __PMAC_H__ */ #endif /* __PMAC_H__ */
...@@ -44,9 +44,9 @@ ...@@ -44,9 +44,9 @@
#undef DEBUG_FEATURE #undef DEBUG_FEATURE
#ifdef DEBUG_FEATURE #ifdef DEBUG_FEATURE
#define DBG(fmt,...) printk(KERN_DEBUG fmt) #define DBG(fmt...) printk(KERN_DEBUG fmt)
#else #else
#define DBG(fmt,...) #define DBG(fmt...)
#endif #endif
/* /*
......
...@@ -37,13 +37,14 @@ ...@@ -37,13 +37,14 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/rtas.h>
#include <asm/ppcdebug.h> #include <asm/ppcdebug.h>
#include <asm/iommu.h> #include <asm/iommu.h>
#include <asm/pci-bridge.h> #include <asm/pci-bridge.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/abs_addr.h> #include <asm/abs_addr.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/lmb.h>
#include "pci.h" #include "pci.h"
...@@ -76,8 +77,8 @@ ...@@ -76,8 +77,8 @@
#define DARTMAP_RPNMASK 0x00ffffff #define DARTMAP_RPNMASK 0x00ffffff
/* Physical base address and size of the DART table */ /* Physical base address and size of the DART table */
unsigned long dart_tablebase; unsigned long dart_tablebase; /* exported to htab_initialize */
unsigned long dart_tablesize; static unsigned long dart_tablesize;
/* Virtual base address of the DART table */ /* Virtual base address of the DART table */
static u32 *dart_vbase; static u32 *dart_vbase;
...@@ -263,7 +264,6 @@ static int dart_init(struct device_node *dart_node) ...@@ -263,7 +264,6 @@ static int dart_init(struct device_node *dart_node)
return 0; return 0;
} }
void iommu_setup_pmac(void) void iommu_setup_pmac(void)
{ {
struct pci_dev *dev = NULL; struct pci_dev *dev = NULL;
...@@ -300,6 +300,22 @@ void iommu_setup_pmac(void) ...@@ -300,6 +300,22 @@ void iommu_setup_pmac(void)
} }
} }
void __init pmac_iommu_alloc(void)
{
/* Only reserve DART space if machine has more than 2GB of RAM
* or if requested with iommu=on on cmdline.
*/
if (lmb_end_of_DRAM() <= 0x80000000ull &&
get_property(of_chosen, "linux,iommu-force-on", NULL) == NULL)
return;
/* 512 pages (2MB) is max DART tablesize. */
dart_tablesize = 1UL << 21;
/* 16MB (1 << 24) alignment. We allocate a full 16Mb chuck since we
* will blow up an entire large page anyway in the kernel mapping
*/
dart_tablebase = (unsigned long)
abs_to_virt(lmb_alloc_base(1UL<<24, 1UL<<24, 0x80000000L));
printk(KERN_INFO "U3-DART allocated at: %lx\n", dart_tablebase);
}
...@@ -746,6 +746,9 @@ void __init pmac_pci_init(void) ...@@ -746,6 +746,9 @@ void __init pmac_pci_init(void)
* the exception of U3/AGP (hook into pci_set_mwi) * the exception of U3/AGP (hook into pci_set_mwi)
*/ */
pci_cache_line_size = 16; /* 64 bytes */ pci_cache_line_size = 16; /* 64 bytes */
/* Allow all IO */
io_page_mask = -1;
} }
/* /*
......
This diff is collapsed.
...@@ -119,7 +119,6 @@ EXPORT_SYMBOL(start_thread); ...@@ -119,7 +119,6 @@ EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(flush_instruction_cache); EXPORT_SYMBOL(flush_instruction_cache);
EXPORT_SYMBOL(_get_PVR);
EXPORT_SYMBOL(giveup_fpu); EXPORT_SYMBOL(giveup_fpu);
#ifdef CONFIG_ALTIVEC #ifdef CONFIG_ALTIVEC
EXPORT_SYMBOL(giveup_altivec); EXPORT_SYMBOL(giveup_altivec);
......
This diff is collapsed.
This diff is collapsed.
...@@ -42,13 +42,16 @@ char rtas_err_buf[RTAS_ERROR_LOG_MAX]; ...@@ -42,13 +42,16 @@ char rtas_err_buf[RTAS_ERROR_LOG_MAX];
spinlock_t rtas_data_buf_lock = SPIN_LOCK_UNLOCKED; spinlock_t rtas_data_buf_lock = SPIN_LOCK_UNLOCKED;
char rtas_data_buf[RTAS_DATA_BUF_SIZE]__page_aligned; char rtas_data_buf[RTAS_DATA_BUF_SIZE]__page_aligned;
unsigned long rtas_rmo_buf;
void void
call_rtas_display_status(char c) call_rtas_display_status(unsigned char c)
{ {
struct rtas_args *args = &rtas.args; struct rtas_args *args = &rtas.args;
unsigned long s; unsigned long s;
if (!rtas.base)
return;
spin_lock_irqsave(&rtas.lock, s); spin_lock_irqsave(&rtas.lock, s);
args->token = 10; args->token = 10;
...@@ -62,6 +65,31 @@ call_rtas_display_status(char c) ...@@ -62,6 +65,31 @@ call_rtas_display_status(char c)
spin_unlock_irqrestore(&rtas.lock, s); spin_unlock_irqrestore(&rtas.lock, s);
} }
void
call_rtas_display_status_delay(unsigned char c)
{
static int pending_newline = 0; /* did last write end with unprinted newline? */
static int width = 16;
if (c == '\n') {
while (width-- > 0)
call_rtas_display_status(' ');
width = 16;
udelay(500000);
pending_newline = 1;
} else {
if (pending_newline) {
call_rtas_display_status('\r');
call_rtas_display_status('\n');
}
pending_newline = 0;
if (width--) {
call_rtas_display_status(c);
udelay(10000);
}
}
}
int int
rtas_token(const char *service) rtas_token(const char *service)
{ {
...@@ -425,7 +453,6 @@ void rtas_os_term(char *str) ...@@ -425,7 +453,6 @@ void rtas_os_term(char *str)
} while (status == RTAS_BUSY); } while (status == RTAS_BUSY);
} }
unsigned long rtas_rmo_buf = 0;
asmlinkage int ppc_rtas(struct rtas_args __user *uargs) asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
{ {
...@@ -536,6 +563,53 @@ int rtas_get_error_log_max(void) ...@@ -536,6 +563,53 @@ int rtas_get_error_log_max(void)
return rtas_error_log_max; return rtas_error_log_max;
} }
/*
* Call early during boot, before mem init or bootmem, to retreive the RTAS
* informations from the device-tree and allocate the RMO buffer for userland
* accesses.
*/
void __init rtas_initialize(void)
{
/* Get RTAS dev node and fill up our "rtas" structure with infos
* about it.
*/
rtas.dev = of_find_node_by_name(NULL, "rtas");
if (rtas.dev) {
u64 *basep, *entryp;
u32 *sizep;
basep = (u64 *)get_property(of_chosen, "linux,rtas-base", NULL);
sizep = (u32 *)get_property(of_chosen, "linux,rtas-size", NULL);
if (basep != NULL && sizep != NULL) {
rtas.base = *basep;
rtas.size = *sizep;
entryp = (u64 *)get_property(of_chosen, "linux,rtas-entry", NULL);
if (entryp == NULL) /* Ugh */
rtas.entry = rtas.base;
else
rtas.entry = *entryp;
} else
rtas.dev = NULL;
}
/* If RTAS was found, allocate the RMO buffer for it and look for
* the stop-self token if any
*/
if (rtas.dev) {
unsigned long rtas_region = RTAS_INSTANTIATE_MAX;
if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE,
rtas_region);
#ifdef CONFIG_HOTPLUG_CPU
rtas_stop_self_args.token = rtas_token("stop-self");
#endif /* CONFIG_HOTPLUG_CPU */
}
}
EXPORT_SYMBOL(rtas_firmware_flash_list); EXPORT_SYMBOL(rtas_firmware_flash_list);
EXPORT_SYMBOL(rtas_token); EXPORT_SYMBOL(rtas_token);
EXPORT_SYMBOL(rtas_call); EXPORT_SYMBOL(rtas_call);
......
This diff is collapsed.
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#undef DEBUG
#include <linux/config.h> #include <linux/config.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -52,6 +54,13 @@ ...@@ -52,6 +54,13 @@
#include <asm/cputable.h> #include <asm/cputable.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/rtas.h> #include <asm/rtas.h>
#include <asm/plpar_wrappers.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
#else
#define DBG(fmt...)
#endif
int smp_threads_ready; int smp_threads_ready;
unsigned long cache_decay_ticks; unsigned long cache_decay_ticks;
...@@ -75,10 +84,13 @@ extern long register_vpa(unsigned long flags, unsigned long proc, ...@@ -75,10 +84,13 @@ extern long register_vpa(unsigned long flags, unsigned long proc,
unsigned long vpa); unsigned long vpa);
int smt_enabled_at_boot = 1; int smt_enabled_at_boot = 1;
int boot_cpuid = 0;
/* Low level assembly function used to backup CPU 0 state */ /* Low level assembly function used to backup CPU 0 state */
extern void __save_cpu_setup(void); extern void __save_cpu_setup(void);
extern void pseries_secondary_smp_init(unsigned long);
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
static unsigned long iSeries_smp_message[NR_CPUS]; static unsigned long iSeries_smp_message[NR_CPUS];
...@@ -182,7 +194,7 @@ void __init smp_init_iSeries(void) ...@@ -182,7 +194,7 @@ void __init smp_init_iSeries(void)
} }
#endif #endif
#ifdef CONFIG_PPC_PSERIES #ifdef CONFIG_PPC_MULTIPLATFORM
void smp_openpic_message_pass(int target, int msg) void smp_openpic_message_pass(int target, int msg)
{ {
/* make sure we're sending something that translates to an IPI */ /* make sure we're sending something that translates to an IPI */
...@@ -223,6 +235,10 @@ static void __devinit smp_openpic_setup_cpu(int cpu) ...@@ -223,6 +235,10 @@ static void __devinit smp_openpic_setup_cpu(int cpu)
do_openpic_setup_cpu(); do_openpic_setup_cpu();
} }
#endif /* CONFIG_PPC_MULTIPLATFORM */
#ifdef CONFIG_PPC_PSERIES
/* Get state of physical CPU. /* Get state of physical CPU.
* Return codes: * Return codes:
* 0 - The processor is in the RTAS stopped state * 0 - The processor is in the RTAS stopped state
...@@ -236,6 +252,7 @@ int query_cpu_stopped(unsigned int pcpu) ...@@ -236,6 +252,7 @@ int query_cpu_stopped(unsigned int pcpu)
int cpu_status; int cpu_status;
int status, qcss_tok; int status, qcss_tok;
DBG(" -> query_cpu_stopped(%d)\n", pcpu);
qcss_tok = rtas_token("query-cpu-stopped-state"); qcss_tok = rtas_token("query-cpu-stopped-state");
if (qcss_tok == RTAS_UNKNOWN_SERVICE) if (qcss_tok == RTAS_UNKNOWN_SERVICE)
return -1; return -1;
...@@ -246,6 +263,8 @@ int query_cpu_stopped(unsigned int pcpu) ...@@ -246,6 +263,8 @@ int query_cpu_stopped(unsigned int pcpu)
return status; return status;
} }
DBG(" <- query_cpu_stopped(), status: %d\n", cpu_status);
return cpu_status; return cpu_status;
} }
...@@ -275,8 +294,7 @@ void __cpu_die(unsigned int cpu) ...@@ -275,8 +294,7 @@ void __cpu_die(unsigned int cpu)
for (tries = 0; tries < 25; tries++) { for (tries = 0; tries < 25; tries++) {
cpu_status = query_cpu_stopped(pcpu); cpu_status = query_cpu_stopped(pcpu);
if (cpu_status == 0 || cpu_status == -1)
if (cpu_status == 0)
break; break;
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/5); schedule_timeout(HZ/5);
...@@ -373,7 +391,6 @@ static unsigned int find_physical_cpu_to_start(unsigned int old_hwindex) ...@@ -373,7 +391,6 @@ static unsigned int find_physical_cpu_to_start(unsigned int old_hwindex)
static inline int __devinit smp_startup_cpu(unsigned int lcpu) static inline int __devinit smp_startup_cpu(unsigned int lcpu)
{ {
int status; int status;
extern void (*pseries_secondary_smp_init)(unsigned int cpu);
unsigned long start_here = __pa(pseries_secondary_smp_init); unsigned long start_here = __pa(pseries_secondary_smp_init);
unsigned int pcpu; unsigned int pcpu;
...@@ -441,7 +458,7 @@ static void __init smp_space_timers(unsigned int max_cpus) ...@@ -441,7 +458,7 @@ static void __init smp_space_timers(unsigned int max_cpus)
} }
#ifdef CONFIG_PPC_PSERIES #ifdef CONFIG_PPC_PSERIES
void vpa_init(int cpu) static void vpa_init(int cpu)
{ {
unsigned long flags, pcpu = get_hard_smp_processor_id(cpu); unsigned long flags, pcpu = get_hard_smp_processor_id(cpu);
...@@ -532,19 +549,43 @@ static struct smp_ops_t pSeries_xics_smp_ops = { ...@@ -532,19 +549,43 @@ static struct smp_ops_t pSeries_xics_smp_ops = {
/* This is called very early */ /* This is called very early */
void __init smp_init_pSeries(void) void __init smp_init_pSeries(void)
{ {
int ret, i;
DBG(" -> smp_init_pSeries()\n");
if (naca->interrupt_controller == IC_OPEN_PIC) if (naca->interrupt_controller == IC_OPEN_PIC)
smp_ops = &pSeries_openpic_smp_ops; smp_ops = &pSeries_openpic_smp_ops;
else else
smp_ops = &pSeries_xics_smp_ops; smp_ops = &pSeries_xics_smp_ops;
/* Start secondary threads on SMT systems; primary threads
* are already in the running state.
*/
for_each_present_cpu(i) {
if (query_cpu_stopped(get_hard_smp_processor_id(i)) == 0) {
printk("%16.16x : starting thread\n", i);
DBG("%16.16x : starting thread\n", i);
rtas_call(rtas_token("start-cpu"), 3, 1, &ret,
get_hard_smp_processor_id(i),
__pa((u32)*((unsigned long *)
pseries_secondary_smp_init)),
i);
}
}
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
vpa_init(boot_cpuid);
/* Non-lpar has additional take/give timebase */ /* Non-lpar has additional take/give timebase */
if (systemcfg->platform == PLATFORM_PSERIES) { if (systemcfg->platform == PLATFORM_PSERIES) {
smp_ops->give_timebase = pSeries_give_timebase; smp_ops->give_timebase = pSeries_give_timebase;
smp_ops->take_timebase = pSeries_take_timebase; smp_ops->take_timebase = pSeries_take_timebase;
} }
DBG(" <- smp_init_pSeries()\n");
} }
#endif #endif /* CONFIG_PPC_PSERIES */
void smp_local_timer_interrupt(struct pt_regs * regs) void smp_local_timer_interrupt(struct pt_regs * regs)
{ {
...@@ -749,7 +790,7 @@ DECLARE_PER_CPU(unsigned int, pvr); ...@@ -749,7 +790,7 @@ DECLARE_PER_CPU(unsigned int, pvr);
static void __devinit smp_store_cpu_info(int id) static void __devinit smp_store_cpu_info(int id)
{ {
per_cpu(pvr, id) = _get_PVR(); per_cpu(pvr, id) = mfspr(SPRN_PVR);
} }
static void __init smp_create_idle(unsigned int cpu) static void __init smp_create_idle(unsigned int cpu)
......
...@@ -102,8 +102,9 @@ void ppc64_enable_pmcs(void) ...@@ -102,8 +102,9 @@ void ppc64_enable_pmcs(void)
{ {
/* XXX Implement for iseries */ /* XXX Implement for iseries */
} }
#else #endif
#ifdef CONFIG_PPC_MULTIPLATFORM
/* /*
* Enabling PMCs will slow partition context switch times so we only do * Enabling PMCs will slow partition context switch times so we only do
* it the first time we write to the PMCs. * it the first time we write to the PMCs.
...@@ -114,9 +115,11 @@ static DEFINE_PER_CPU(char, pmcs_enabled); ...@@ -114,9 +115,11 @@ static DEFINE_PER_CPU(char, pmcs_enabled);
void ppc64_enable_pmcs(void) void ppc64_enable_pmcs(void)
{ {
unsigned long hid0; unsigned long hid0;
#ifdef CONFIG_PPC_PSERIES
unsigned long set, reset; unsigned long set, reset;
int ret; int ret;
unsigned int ctrl; unsigned int ctrl;
#endif /* CONFIG_PPC_PSERIES */
/* Only need to enable them once */ /* Only need to enable them once */
if (__get_cpu_var(pmcs_enabled)) if (__get_cpu_var(pmcs_enabled))
...@@ -126,6 +129,7 @@ void ppc64_enable_pmcs(void) ...@@ -126,6 +129,7 @@ void ppc64_enable_pmcs(void)
switch (systemcfg->platform) { switch (systemcfg->platform) {
case PLATFORM_PSERIES: case PLATFORM_PSERIES:
case PLATFORM_POWERMAC:
hid0 = mfspr(HID0); hid0 = mfspr(HID0);
hid0 |= 1UL << (63 - 20); hid0 |= 1UL << (63 - 20);
...@@ -143,6 +147,7 @@ void ppc64_enable_pmcs(void) ...@@ -143,6 +147,7 @@ void ppc64_enable_pmcs(void)
"memory"); "memory");
break; break;
#ifdef CONFIG_PPC_PSERIES
case PLATFORM_PSERIES_LPAR: case PLATFORM_PSERIES_LPAR:
set = 1UL << 63; set = 1UL << 63;
reset = 0; reset = 0;
...@@ -152,11 +157,13 @@ void ppc64_enable_pmcs(void) ...@@ -152,11 +157,13 @@ void ppc64_enable_pmcs(void)
"returned %d\n", "returned %d\n",
smp_processor_id(), ret); smp_processor_id(), ret);
break; break;
#endif /* CONFIG_PPC_PSERIES */
default: default:
break; break;
} }
#ifdef CONFIG_PPC_PSERIES
/* instruct hypervisor to maintain PMCs */ /* instruct hypervisor to maintain PMCs */
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
char *ptr = (char *)&paca[smp_processor_id()].lppaca; char *ptr = (char *)&paca[smp_processor_id()].lppaca;
...@@ -172,8 +179,9 @@ void ppc64_enable_pmcs(void) ...@@ -172,8 +179,9 @@ void ppc64_enable_pmcs(void)
ctrl |= RUNLATCH; ctrl |= RUNLATCH;
mtspr(CTRLT, ctrl); mtspr(CTRLT, ctrl);
} }
#endif /* CONFIG_PPC_PSERIES */
} }
#endif #endif /* CONFIG_PPC_MULTIPLATFORM */
EXPORT_SYMBOL(ppc64_enable_pmcs); EXPORT_SYMBOL(ppc64_enable_pmcs);
......
This diff is collapsed.
This diff is collapsed.
...@@ -8,3 +8,4 @@ obj-y := fault.o init.o imalloc.o hash_utils.o hash_low.o tlb.o \ ...@@ -8,3 +8,4 @@ obj-y := fault.o init.o imalloc.o hash_utils.o hash_low.o tlb.o \
slb_low.o slb.o stab.o mmap.o slb_low.o slb.o stab.o mmap.o
obj-$(CONFIG_DISCONTIGMEM) += numa.o obj-$(CONFIG_DISCONTIGMEM) += numa.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_native.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.
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