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.
of arbitrary user pages (f.e. for ptrace()) it will use
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
that need to occur should happen here. If the processor's
instruction cache does not snoop cpu stores, it is very
......
......@@ -417,7 +417,12 @@ salinfo_log_new_read(int cpu, struct salinfo_data *data)
if (!data->saved_num)
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
......
......@@ -33,6 +33,7 @@
unsigned long isa_io_base = 0;
unsigned long isa_mem_base = 0;
unsigned long pci_dram_offset = 0;
int pcibios_assign_bus_offset = 1;
void pcibios_make_OF_bus_map(void);
......@@ -411,7 +412,7 @@ probe_resource(struct pci_bus *parent, struct resource *pr,
r = &dev->resource[i];
if (!r->flags || (r->flags & IORESOURCE_UNSET))
continue;
if (pci_find_parent_resource(bus->self, r) != pr)
if (pci_find_parent_resource(dev, r) != pr)
continue;
if (r->end >= res->start && res->end >= r->start) {
*conflict = r;
......@@ -1263,7 +1264,7 @@ pcibios_init(void)
bus = pci_scan_bus(hose->first_busno, hose->ops, hose);
hose->last_busno = bus->subordinate;
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;
......
......@@ -375,7 +375,7 @@ void __init chrp_init_IRQ(void)
{
struct device_node *np;
int i;
unsigned long chrp_int_ack;
unsigned long chrp_int_ack = 0;
unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
struct device_node *kbd;
......
......@@ -301,7 +301,6 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
static int __pmac do_set_cpu_speed(int speed_mode)
{
struct cpufreq_freqs freqs;
int rc;
freqs.old = cur_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)
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
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)
......
......@@ -2665,7 +2665,7 @@ set_initial_features(void)
struct device_node *p = of_get_parent(ui2c);
if (p && !strcmp(p->name, "uni-n"))
break;
ui2c = of_find_node_by_type(np, "i2c");
ui2c = of_find_node_by_type(ui2c, "i2c");
}
if (ui2c == NULL)
break;
......
......@@ -50,6 +50,7 @@ static struct pci_controller *u3_agp;
#endif /* CONFIG_POWER4 */
extern u8 pci_cache_line_size;
extern int pcibios_assign_bus_offset;
struct pci_dev *k2_skiplist[2];
......@@ -565,6 +566,14 @@ pmac_find_bridges(void)
init_p2pbridge();
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
/* 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
......
......@@ -115,11 +115,11 @@ prom_entry prom __initdata;
ihandle prom_chosen __initdata;
ihandle prom_stdout __initdata;
char *prom_display_paths[FB_MAX] __initdata;
phandle prom_display_nodes[FB_MAX] __initdata;
unsigned int prom_num_displays __initdata;
char *of_stdout_device __initdata;
static char *prom_display_paths[FB_MAX] __initdata;
static phandle prom_display_nodes[FB_MAX] __initdata;
static unsigned int prom_num_displays __initdata;
static ihandle prom_disp_node __initdata;
char *of_stdout_device __initdata;
unsigned int rtas_data; /* physical pointer */
unsigned int rtas_entry; /* physical pointer */
......@@ -403,6 +403,7 @@ check_display(unsigned long mem)
for (j=0; j<prom_num_displays; j++) {
path = prom_display_paths[j];
node = prom_display_nodes[j];
prom_print("opening display ");
prom_print(path);
ih = call_prom("open", 1, 1, path);
......@@ -420,6 +421,8 @@ check_display(unsigned long mem)
continue;
} else {
prom_print("... ok\n");
call_prom("setprop", 4, 1, node, "linux,opened", 0, NULL);
/*
* Setup a usable color table when the appropriate
* method is available.
......@@ -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);
}
......
......@@ -58,16 +58,27 @@ menu "Platform support"
choice
prompt "Platform Type"
default PPC_PSERIES
default PPC_MULTIPLATFORM
config PPC_ISERIES
bool "iSeries"
bool "IBM Legacy iSeries"
config PPC_PSERIES
bool "pSeries / PowerMac G5"
config PPC_MULTIPLATFORM
bool "Generic"
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
bool
default y
......@@ -77,7 +88,7 @@ config PPC64
default y
config PPC_OF
depends on PPC_PSERIES
depends on PPC_MULTIPLATFORM
bool
default y
......@@ -85,14 +96,9 @@ config PPC_OF
# exception vectors for it
config ALTIVEC
bool "Support for VMX (Altivec) vector unit"
depends on PPC_PSERIES
depends on PPC_MULTIPLATFORM
default y
config PPC_PMAC
depends on PPC_PSERIES
bool "Apple PowerMac G5 support"
select ADB_PMU
config PPC_SPLPAR
depends on PPC_PSERIES
bool "Support for shared-processor logical partitions"
......@@ -163,7 +169,7 @@ config SMP
config IRQ_ALL_CPUS
bool "Distribute interrupts on all CPUs by default"
depends on SMP && PPC_PSERIES
depends on SMP && PPC_MULTIPLATFORM
help
This option gives the kernel permission to distribute IRQs across
multiple CPUs. Saying N here will route all IRQs to the first
......
......@@ -31,6 +31,7 @@ BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional
BOOTLD := $(CROSS32_COMPILE)ld
BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds
BOOTOBJCOPY := $(CROSS32_COMPILE)objcopy
BOOTSTRIP := $(CROSS32_COMPILE)strip
OBJCOPYFLAGS := contents,alloc,load,readonly,data
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
#-----------------------------------------------------------
# ELF sections within the zImage bootloader/wrapper
#-----------------------------------------------------------
required := vmlinux .config System.map
required := vmlinux.strip
initrd := initrd
obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section)))
src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(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 \
$(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
$(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
$(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
vmlinux.sm vmlinux.initrd vmlinux.sminitrd
extra-y := sysmap.o 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)
vmlinux.initrd
extra-y := initrd.o
quiet_cmd_ramdisk = RAMDISK $@
cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz System.map $< $@
$(obj)/vmlinux.initrd: vmlinux $(obj)/addRamDisk $(obj)/ramdisk.image.gz System.map FORCE
$(call if_changed,ramdisk)
cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@
$(obj)/vmlinux.sminitrd: $(obj)/vmlinux.sm $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE
$(call if_changed,ramdisk)
quiet_cmd_stripvm = STRIP $@
cmd_stripvm = $(BOOTSTRIP) -s $< -o $@
$(obj)/sysmap.o: System.map $(obj)/piggyback FORCE
$(call if_changed,piggy)
vmlinux.strip: vmlinux FORCE
$(call if_changed,stripvm)
$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE
$(call if_changed,ramdisk)
addsection = $(BOOTOBJCOPY) $(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))
$(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE
$(call if_changed,addnote)
$(obj)/imagesize.c: vmlinux
$(obj)/imagesize.c: vmlinux.strip
@echo Generating $@
ls -l vmlinux | \
ls -l vmlinux.strip | \
awk '{printf "/* generated -- do not edit! */\n" \
"unsigned long vmlinux_filesize = %d;\n", $$5}' > $(obj)/imagesize.c
$(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
......@@ -123,6 +119,6 @@ $(obj)/imagesize.c: vmlinux
>> $(obj)/imagesize.c
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))
#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);
void *memmove(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 */
#define PROG_START 0x01400000
#define RAM_END (256<<20) // Fixme: use OF */
char *avail_ram;
char *begin_avail, *end_avail;
......@@ -48,8 +44,6 @@ unsigned int heap_max;
extern char _start[];
extern char _vmlinux_start[];
extern char _vmlinux_end[];
extern char _sysmap_start[];
extern char _sysmap_end[];
extern char _initrd_start[];
extern char _initrd_end[];
extern unsigned long vmlinux_filesize;
......@@ -62,7 +56,6 @@ struct addr_range {
};
struct addr_range vmlinux = {0, 0, 0};
struct addr_range vmlinuz = {0, 0, 0};
struct addr_range sysmap = {0, 0, 0};
struct addr_range initrd = {0, 0, 0};
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,
unsigned long,
void *,
struct bi_record *);
void *);
int (*prom)(void *);
......@@ -80,12 +73,31 @@ void *stdin;
void *stdout;
void *stderr;
#define DEBUG
void
start(unsigned long a1, unsigned long a2, void *promptr)
static unsigned long claim_base = PROG_START;
static unsigned long try_claim(unsigned long size)
{
unsigned long i, claim_addr, claim_size;
struct bi_record *bi_recs;
unsigned long addr = 0;
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;
Elf64_Ehdr *elf64;
Elf64_Phdr *elf64ph;
......@@ -102,61 +114,59 @@ start(unsigned long a1, unsigned long a2, void *promptr)
printf("zImage starting: loaded at 0x%x\n\r", (unsigned)_start);
#if 0
sysmap.size = (unsigned long)(_sysmap_end - _sysmap_start);
sysmap.memsize = sysmap.size;
if ( sysmap.size > 0 ) {
sysmap.addr = (RAM_END - sysmap.size) & ~0xFFF;
claim(sysmap.addr, RAM_END - sysmap.addr, 0);
printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
sysmap.addr, (unsigned long)_sysmap_start, sysmap.size);
memcpy((void *)sysmap.addr, (void *)_sysmap_start, sysmap.size);
}
#endif
initrd.size = (unsigned long)(_initrd_end - _initrd_start);
initrd.memsize = initrd.size;
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);
/*
* Now we try to claim some memory for the kernel itself
* our "vmlinux_memsize" is the memory footprint in RAM, _HOWEVER_, what
* our Makefile stuffs in is an image containing all sort of junk including
* an ELF header. We need to do some calculations here to find the right
* size... In practice we add 1Mb, that is enough, but we should really
* consider fixing the Makefile to put a _raw_ kernel in there !
*/
vmlinux_memsize += 0x100000;
printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize);
vmlinux.addr = try_claim(vmlinux_memsize);
if (vmlinux.addr == 0) {
printf("Can't allocate memory for kernel image !\n\r");
exit();
}
vmlinuz.addr = (unsigned long)_vmlinux_start;
vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
vmlinux.addr = (unsigned long)(void *)-1;
vmlinux.size = PAGE_ALIGN(vmlinux_filesize);
vmlinux.memsize = vmlinux_memsize;
claim_size = vmlinux.memsize /* PPPBBB: + fudge for bi_recs */;
for(claim_addr = PROG_START;
claim_addr <= PROG_START * 8;
claim_addr += 0x100000) {
#ifdef DEBUG
printf(" trying: 0x%08lx\n\r", claim_addr);
#endif
vmlinux.addr = (unsigned long)claim(claim_addr, claim_size, 0);
if ((void *)vmlinux.addr != (void *)-1) break;
}
if ((void *)vmlinux.addr == (void *)-1) {
printf("claim error, can't allocate kernel memory\n\r");
/*
* Now we try to claim memory for the initrd (and copy it there)
*/
initrd.size = (unsigned long)(_initrd_end - _initrd_start);
initrd.memsize = initrd.size;
if ( initrd.size > 0 ) {
printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size);
initrd.addr = try_claim(initrd.size);
if (initrd.addr == 0) {
printf("Can't allocate memory for initial ramdisk !\n\r");
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) {
int len;
avail_ram = scratch;
begin_avail = avail_high = avail_ram;
end_avail = scratch + sizeof(scratch);
printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...",
vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size);
len = vmlinuz.size;
gunzip((void *)vmlinux.addr, vmlinux.size,
(unsigned char *)vmlinuz.addr, (int *)&vmlinuz.size);
printf("done %lu bytes\n\r", vmlinuz.size);
printf("%u bytes of heap consumed, max in use %u\n\r",
(unsigned char *)vmlinuz.addr, &len);
printf("done 0x%lx bytes\n\r", len);
printf("0x%x bytes of heap consumed, max in use 0x%\n\r",
(unsigned)(avail_high - begin_avail), heap_max);
} else {
memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size);
......@@ -192,7 +202,8 @@ start(unsigned long a1, unsigned long a2, void *promptr)
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;
#ifdef DEBUG
......@@ -203,65 +214,16 @@ start(unsigned long a1, unsigned long a2, void *promptr)
" prom = 0x%lx,\n\r"
" bi_recs = 0x%lx,\n\r",
(unsigned long)kernel_entry, a1, a2,
(unsigned long)prom, (unsigned long)bi_recs);
(unsigned long)prom, NULL);
#endif
kernel_entry( a1, a2, prom, bi_recs );
kernel_entry( a1, a2, prom, NULL );
printf("Error: Linux kernel returned to zImage bootloader!\n\r");
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 {
unsigned int size;
unsigned int pad;
......
......@@ -61,19 +61,9 @@ SECTIONS
. = ALIGN(4096);
_vmlinux_start = .;
.kernel:vmlinux : { *(.kernel:vmlinux) }
.kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) }
_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);
_initrd_start = .;
.kernel:initrd : { *(.kernel:initrd) }
......
This diff is collapsed.
#
# 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_MMU=y
......@@ -20,6 +22,7 @@ CONFIG_CLEAN_COMPILE=y
#
# General setup
#
CONFIG_LOCALVERSION=""
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
......@@ -61,12 +64,13 @@ CONFIG_SYSVIPC_COMPAT=y
# Platform support
#
# CONFIG_PPC_ISERIES is not set
CONFIG_PPC_MULTIPLATFORM=y
CONFIG_PPC_PSERIES=y
# CONFIG_PPC_PMAC is not set
CONFIG_PPC=y
CONFIG_PPC64=y
CONFIG_PPC_OF=y
CONFIG_ALTIVEC=y
# CONFIG_PPC_PMAC is not set
CONFIG_PPC_SPLPAR=y
# CONFIG_BOOTX_TEXT is not set
# CONFIG_POWER4_ONLY is not set
......@@ -189,7 +193,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
CONFIG_BLK_DEV_ADMA=y
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
CONFIG_BLK_DEV_AMD74XX=y
......@@ -365,6 +368,8 @@ CONFIG_NETFILTER=y
# IP: Netfilter Configuration
#
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_IRC=m
CONFIG_IP_NF_TFTP=m
......@@ -389,8 +394,14 @@ CONFIG_IP_NF_MATCH_HELPER=m
CONFIG_IP_NF_MATCH_STATE=m
CONFIG_IP_NF_MATCH_CONNTRACK=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_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_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
......@@ -409,21 +420,13 @@ CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_TARGET_NOTRACK=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_IP_NF_COMPAT_IPCHAINS=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_USER=m
......@@ -604,6 +607,7 @@ CONFIG_SERIO_I8042=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set
# CONFIG_SERIO_RAW is not set
#
# Input Device Drivers
......@@ -621,6 +625,7 @@ CONFIG_MOUSE_PS2=y
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_PCSPKR is not set
# CONFIG_INPUT_UINPUT is not set
#
......
......@@ -17,7 +17,7 @@ obj-$(CONFIG_PPC_OF) += of_device.o
pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_pci_reset.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)
......@@ -28,10 +28,11 @@ obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o \
mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.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 \
eeh.o nvram.o pSeries_nvram.o rtasd.o ras.o \
open_pic.o xics.o pSeries_htab.o rtas.o \
chrp_setup.o i8259.o prom.o pSeries_iommu.o
eeh.o pSeries_nvram.o rtasd.o ras.o \
xics.o rtas.o pSeries_setup.o pSeries_iommu.o
obj-$(CONFIG_PROC_FS) += proc_ppc64.o
obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
......
......@@ -33,7 +33,6 @@
#include <asm/iSeries/ItLpPaca.h>
#include <asm/iSeries/ItLpQueue.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/prom.h>
#include <asm/rtas.h>
#include <asm/cputable.h>
......@@ -108,7 +107,6 @@ int main(void)
DEFINE(LPPACASRR1, offsetof(struct ItLpPaca, xSavedSrr1));
DEFINE(LPPACAANYINT, offsetof(struct ItLpPaca, xIntDword.xAnyInt));
DEFINE(LPPACADECRINT, offsetof(struct ItLpPaca, xIntDword.xFields.xDecrInt));
DEFINE(PROMENTRY, offsetof(struct prom_t, entry));
/* RTAS */
DEFINE(RTASBASE, offsetof(struct rtas_t, base));
......
This diff is collapsed.
......@@ -746,6 +746,10 @@ _STATIC(rtas_restore_regs)
mtlr r0
blr /* return to caller */
#endif /* CONFIG_PPC_PSERIES */
#ifdef CONFIG_PPC_MULTIPLATFORM
_GLOBAL(enter_prom)
mflr r0
std r0,16(r1)
......@@ -777,11 +781,8 @@ _GLOBAL(enter_prom)
std r11,_MSR(r1)
/* Get the PROM entrypoint */
bl .reloc_offset
LOADADDR(r12,prom)
sub r12,r12,r3
ld r12,PROMENTRY(r12)
mtlr r12
ld r0,GPR4(r1)
mtlr r0
/* Switch MSR to 32 bits mode
*/
......@@ -834,4 +835,4 @@ _GLOBAL(enter_prom)
mtlr r0
blr
#endif /* defined(CONFIG_PPC_PSERIES) */
#endif /* CONFIG_PPC_MULTIPLATFORM */
......@@ -83,13 +83,14 @@
.text
.globl _stext
_stext:
#ifdef CONFIG_PPC_PSERIES
_STATIC(__start)
#ifdef CONFIG_PPC_MULTIPLATFORM
_GLOBAL(__start)
/* NOP this out unconditionally */
BEGIN_FTR_SECTION
b .__start_initialization_pSeries
b .__start_initialization_multiplatform
END_FTR_SECTION(0, 1)
#endif
#endif /* CONFIG_PPC_MULTIPLATFORM */
/* Catch branch to 0 in real mode */
trap
#ifdef CONFIG_PPC_ISERIES
......@@ -117,7 +118,8 @@ embedded_sysmap_start:
.globl embedded_sysmap_end
embedded_sysmap_end:
.llong 0
#else
#else /* CONFIG_PPC_ISERIES */
/* Secondary processors spin on this value until it goes to 1. */
.globl __secondary_hold_spinloop
......@@ -1223,12 +1225,10 @@ _GLOBAL(pseries_secondary_smp_init)
#endif
b 1b /* Loop until told to go */
#ifdef CONFIG_PPC_ISERIES
_GLOBAL(__start_initialization_iSeries)
_STATIC(__start_initialization_iSeries)
/* Clear out the BSS */
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 */
......@@ -1265,32 +1265,73 @@ _GLOBAL(__start_initialization_iSeries)
ld r6,PACA(r4) /* Get the base paca pointer */
ld r4,PACASTABVIRT(r6)
bl .iSeries_fixup_klimit
bl .iSeries_early_setup
/* relocation is on at this point */
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
andi. r0,r3,MSR_IR|MSR_DR
beqlr
andc r3,r3,r0
mtspr SRR0,r4
mtspr SRR1,r3
mtspr SPRN_SRR0,r4
mtspr SPRN_SRR1,r3
sync
rfid
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 r29,r5
mr r28,r6
mr r27,r7
/* Make sure we are running in 64 bits mode */
bl .enable_64b_mode
/* put a relocation offset into r3 */
......@@ -1303,7 +1344,7 @@ _GLOBAL(__start_initialization_pSeries)
/* Relocate the TOC from a virt addr to a real addr */
sub r2,r2,r3
/* Save parameters */
/* Restore parameters */
mr r3,r31
mr r4,r30
mr r5,r29
......@@ -1312,17 +1353,8 @@ _GLOBAL(__start_initialization_pSeries)
/* Do all of the interaction with OF client interface */
bl .prom_init
mr r23,r3 /* Save phys address we are running at */
/* 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
/* We never return */
trap
/*
* At this point, r3 contains the physical address we are running at,
......@@ -1348,7 +1380,7 @@ _STATIC(__after_prom_start)
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 */
/* current address of _start */
/* i.e. where we are running */
......@@ -1373,8 +1405,9 @@ _STATIC(__after_prom_start)
ld r5,0(r5) /* get the value of klimit */
sub r5,r5,r27
bl .copy_and_flush /* copy the rest */
b .start_here_pSeries
#endif
b .start_here_multiplatform
#endif /* CONFIG_PPC_MULTIPLATFORM */
/*
* Copy routine used to copy the kernel to start at physical address 0
......@@ -1794,15 +1827,33 @@ _GLOBAL(enable_64b_mode)
isync
blr
#ifdef CONFIG_PPC_PSERIES
#ifdef CONFIG_PPC_MULTIPLATFORM
/*
* 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. */
bl .reloc_offset
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
ori r6,r6,MSR_RI
mtmsrd r6 /* RI on */
......@@ -1875,8 +1926,11 @@ _STATIC(start_here_pSeries)
mr r5,r26
bl .identify_cpu
/* Get the pointer to the segment table which is used by */
/* stab_initialize */
/* Setup a valid physical PACA pointer in SPRG3 for early_setup
* 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)
sub r27,r27,r26
lwz r27,0(r27)
......@@ -1885,12 +1939,18 @@ _STATIC(start_here_pSeries)
mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r24 /* for this processor. */
sub r13,r13,r26 /* convert to physical addr */
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 */
ld r3,PACASTABREAL(r13)
ori r4,r3,1 /* turn on valid bit */
li r3,SYSTEMCFG_PHYS_ADDR /* r3 = ptr to systemcfg */
lwz r3,PLATFORM(r3) /* r3 = platform flags */
cmpldi r3,PLATFORM_PSERIES_LPAR
......@@ -1909,13 +1969,7 @@ _STATIC(start_here_pSeries)
98: /* !(rpa hypervisor) || !(star) */
mtasr r4 /* set the stab location */
99:
mfspr r6,SPRG3
ld r3,PACASTABREAL(r6) /* restore r3 for stab_initialize */
/* Initialize an initial memory mapping and turn on relocation. */
bl .stab_initialize
bl .htab_initialize
/* Set SDR1 (hash table pointer) */
li r3,SYSTEMCFG_PHYS_ADDR /* r3 = ptr to systemcfg */
lwz r3,PLATFORM(r3) /* r3 = platform flags */
/* Test if bit 0 is set (LPAR bit) */
......@@ -1932,7 +1986,7 @@ _STATIC(start_here_pSeries)
mtspr SRR1,r4
rfid
b . /* prevent speculative execution */
#endif /* CONFIG_PPC_PSERIES */
#endif /* CONFIG_PPC_MULTIPLATFORM */
/* This is where all platforms converge execution */
_STATIC(start_here_common)
......@@ -1980,13 +2034,6 @@ _STATIC(start_here_common)
ld r2,PACATOC(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
/* Load up the kernel context */
......
......@@ -233,4 +233,6 @@ void hpte_init_iSeries(void)
ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
ppc_md.hpte_insert = iSeries_hpte_insert;
ppc_md.hpte_remove = iSeries_hpte_remove;
htab_finish_init();
}
......@@ -16,6 +16,8 @@
* 2 of the License, or (at your option) any later version.
*/
#undef DEBUG
#include <linux/config.h>
#include <linux/init.h>
#include <linux/threads.h>
......@@ -54,6 +56,14 @@
#include <asm/iSeries/iSeries_proc.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 */
extern void ppcdbg_initialize(void);
extern void tce_init_iSeries(void);
......@@ -75,8 +85,6 @@ static unsigned long tbFreqMhzHundreths;
int piranha_simulator;
int boot_cpuid;
extern int rd_size; /* Defined in drivers/block/rd.c */
extern unsigned long klimit;
extern unsigned long embedded_sysmap_start;
......@@ -275,8 +283,28 @@ unsigned long iSeries_process_mainstore_vpd(struct MemoryBlock *mb_array,
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();
#if defined(CONFIG_BLK_DEV_INITRD)
......@@ -300,25 +328,20 @@ void __init iSeries_init_early(void)
iSeries_recal_tb = get_tb();
iSeries_recal_titan = HvCallXm_loadTod();
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 = NULL;
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;
/*
* Cache sizes must be initialized before hpte_init_iSeries is called
* as the later need them for flush_icache_range()
*/
setup_iSeries_cache_sizes();
/*
* Initialize the hash table management pointers
*/
hpte_init_iSeries();
/*
* Initialize the DMA/TCE management
*/
tce_init_iSeries();
/*
......@@ -326,7 +349,7 @@ void __init iSeries_init_early(void)
* AS/400 absolute addresses
*/
build_iSeries_Memory_Map();
setup_iSeries_cache_sizes();
/* Initialize machine-dependency vectors */
#ifdef CONFIG_SMP
smp_init_iSeries();
......@@ -340,24 +363,22 @@ void __init iSeries_init_early(void)
mf_init();
mf_initialized = 1;
mb();
}
void __init iSeries_parse_cmdline(void)
{
char *p, *q;
/* If we were passed an initrd, set the ROOT_DEV properly if the values
* look sensible. If not, clear initrd reference.
*/
#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;
q = cmd_line + 255;
while(p < q) {
if (!*p || *p == '\n')
break;
++p;
}
*p = 0;
iSeries_parse_cmdline();
DBG(" <- iSeries_init_early()\n");
}
/*
......@@ -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
......@@ -810,3 +831,27 @@ int __init iSeries_src_init(void)
}
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 @@
#ifndef __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_residual(struct seq_file *m, int cpu_id);
extern void iSeries_get_cpuinfo(struct seq_file *m);
......
......@@ -30,9 +30,8 @@
#include <asm/time.h>
#include <asm/iSeries/HvCall.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);
static int (*idle_loop)(void);
......@@ -153,6 +152,8 @@ static int default_idle(void)
return 0;
}
#ifdef CONFIG_PPC_PSERIES
DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
int dedicated_idle(void)
......@@ -280,9 +281,12 @@ static int shared_idle(void)
return 0;
}
static int powermac_idle(void)
#endif /* CONFIG_PPC_PSERIES */
static int native_idle(void)
{
while(1) {
/* check CPU type here */
if (!need_resched())
power4_idle();
if (need_resched())
......@@ -290,7 +294,8 @@ static int powermac_idle(void)
}
return 0;
}
#endif
#endif /* CONFIG_PPC_ISERIES */
int cpu_idle(void)
{
......@@ -332,30 +337,38 @@ __initcall(register_powersave_nap_sysctl);
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
idle_loop = iSeries_idle;
return 1;
#else
idle_loop = default_idle;
#endif
#ifdef CONFIG_PPC_PSERIES
if (systemcfg->platform & PLATFORM_PSERIES) {
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
if (get_paca()->lppaca.xSharedProc) {
printk("idle = shared_idle\n");
printk(KERN_INFO "Using shared processor idle loop\n");
idle_loop = shared_idle;
} else {
printk("idle = dedicated_idle\n");
printk(KERN_INFO "Using dedicated idle loop\n");
idle_loop = dedicated_idle;
}
} else {
printk("idle = default_idle\n");
printk(KERN_INFO "Using default idle loop\n");
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;
}
......@@ -22,6 +22,43 @@
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
lmb_addrs_overlap(unsigned long base1, unsigned long size1,
unsigned long base2, unsigned long size2)
......@@ -71,8 +108,7 @@ lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
void __init
lmb_init(void)
{
unsigned long offset = reloc_offset();
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb *_lmb = &lmb;
/* Create a dummy zero size LMB which will get coalesced away later.
* This simplifies the lmb_add() code below...
......@@ -94,8 +130,7 @@ lmb_analyze(void)
unsigned long i;
unsigned long mem_size = 0;
unsigned long size_mask = 0;
unsigned long offset = reloc_offset();
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb *_lmb = &lmb;
#ifdef CONFIG_MSCHUNKS
unsigned long physbase = 0;
#endif
......@@ -178,8 +213,7 @@ lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
long __init
lmb_add(unsigned long base, unsigned long size)
{
unsigned long offset = reloc_offset();
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb *_lmb = &lmb;
struct lmb_region *_rgn = &(_lmb->memory);
/* On pSeries LPAR systems, the first LMB is our RMO region. */
......@@ -193,8 +227,7 @@ lmb_add(unsigned long base, unsigned long size)
long __init
lmb_reserve(unsigned long base, unsigned long size)
{
unsigned long offset = reloc_offset();
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb *_lmb = &lmb;
struct lmb_region *_rgn = &(_lmb->reserved);
return lmb_add_region(_rgn, base, size);
......@@ -227,8 +260,7 @@ lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr)
{
long i, j;
unsigned long base = 0;
unsigned long offset = reloc_offset();
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb *_lmb = &lmb;
struct lmb_region *_mem = &(_lmb->memory);
struct lmb_region *_rsv = &(_lmb->reserved);
......@@ -263,8 +295,7 @@ lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr)
unsigned long __init
lmb_phys_mem_size(void)
{
unsigned long offset = reloc_offset();
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb *_lmb = &lmb;
#ifdef CONFIG_MSCHUNKS
return _lmb->memory.size;
#else
......@@ -282,8 +313,7 @@ lmb_phys_mem_size(void)
unsigned long __init
lmb_end_of_DRAM(void)
{
unsigned long offset = reloc_offset();
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb *_lmb = &lmb;
struct lmb_region *_mem = &(_lmb->memory);
int idx = _mem->cnt - 1;
......@@ -300,8 +330,7 @@ unsigned long __init
lmb_abs_to_phys(unsigned long aa)
{
unsigned long i, pa = aa;
unsigned long offset = reloc_offset();
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb *_lmb = &lmb;
struct lmb_region *_mem = &(_lmb->memory);
for (i=0; i < _mem->cnt; i++) {
......
......@@ -127,6 +127,47 @@ _GLOBAL(call_handle_irq_event)
blr
#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.
*/
......@@ -454,17 +495,6 @@ _GLOBAL(_outsl_ns)
sync
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)
lfd 0,0(r5) /* load up fpscr value */
......@@ -561,6 +591,69 @@ _GLOBAL(do_cpu_ftr_fixups)
isync
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
......@@ -594,7 +687,7 @@ _GLOBAL(kernel_thread)
ld r30,-16(r1)
blr
#ifdef CONFIG_PPC_ISERIES /* hack hack hack */
#ifndef CONFIG_PPC_PSERIE /* hack hack hack */
#define ppc_rtas sys_ni_syscall
#endif
......
......@@ -603,6 +603,7 @@ void __exit nvram_cleanup(void)
}
#ifdef CONFIG_PPC_PSERIES
/* nvram_write_error_log
*
......@@ -727,6 +728,7 @@ int nvram_clear_error_log()
return 0;
}
#endif /* CONFIG_PPC_PSERIES */
module_init(nvram_init);
module_exit(nvram_cleanup);
......
......@@ -362,7 +362,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
find_ISUs();
/* Initialize timer interrupts */
ppc64_boot_msg(0x21, "OpenPic Timer");
for (i = 0; i < OPENPIC_NUM_TIMERS; i++) {
/* Disabled, Priority 0 */
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,
#ifdef CONFIG_SMP
/* Initialize IPI interrupts */
ppc64_boot_msg(0x22, "OpenPic IPI");
openpic_test_broken_IPI();
for (i = 0; i < OPENPIC_NUM_IPI; i++) {
/* Disabled, Priority 10..13 */
......@@ -384,8 +382,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
#endif
/* Initialize external interrupts */
ppc64_boot_msg(0x23, "OpenPic Ext");
openpic_set_priority(0xf);
/* SIOint (8259 cascade) is special */
......@@ -420,7 +416,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
irq_desc[i].handler = &open_pic;
/* Initialize the spurious interrupt */
ppc64_boot_msg(0x24, "OpenPic Spurious");
openpic_set_spurious(openpic_vec_spurious);
openpic_set_priority(0);
......
......@@ -344,5 +344,5 @@ void __init openpic2_init(int offset)
openpic2_set_priority(0);
openpic2_disable_8259_pass_through();
ppc64_boot_msg(0x25, "OpenPic2 Done");
ppc64_boot_msg(0x25, "OpenPic U3 Done");
}
......@@ -42,6 +42,7 @@
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#include <asm/abs_addr.h>
#include <asm/plpar_wrappers.h>
#include "pci.h"
......@@ -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)
{
struct pci_controller *phb, *tmp;
......@@ -166,24 +311,25 @@ static void iommu_table_setparms(struct pci_controller *phb,
struct device_node *dn,
struct iommu_table *tbl)
{
phandle node;
unsigned long i;
struct of_tce_table *oft;
node = ((struct device_node *)(phb->arch_data))->node;
struct device_node *node;
unsigned long *basep;
unsigned int *sizep;
oft = NULL;
node = (struct device_node *)phb->arch_data;
for (i=0; of_tce_table[i].node; i++)
if(of_tce_table[i].node == node) {
oft = &of_tce_table[i];
break;
if (get_property(node, "linux,has-tce-table", NULL) == NULL) {
printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has no tce table !\n",
dn->full_name);
return;
}
if (!oft)
panic("PCI_DMA: iommu_table_setparms: Can't find phb named '%s' in of_tce_table\n", dn->full_name);
memset((void *)oft->base, 0, oft->size);
basep = (unsigned long *)get_property(node, "linux,tce-base", NULL);
sizep = (unsigned int *)get_property(node, "linux,tce-size", NULL);
if (basep == NULL || sizep == NULL) {
printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has missing tce"
" entries !\n", dn->full_name);
return;
}
memset((void *)(*basep), 0, *sizep);
tbl->it_busno = phb->bus->number;
......@@ -207,7 +353,7 @@ static void iommu_table_setparms(struct pci_controller *phb,
if (phb->dma_window_base_cur > (1 << 19))
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_entrysize = sizeof(union tce_entry);
tbl->it_blocksize = 16;
......@@ -295,8 +441,16 @@ void iommu_setup_pSeries(void)
/* These are called very early. */
void tce_init_pSeries(void)
{
if (!(systemcfg->platform & PLATFORM_LPAR)) {
ppc_md.tce_build = tce_build_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();
}
......
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)
return ISERIES_DEVNODE(dev)->iommu_table;
#endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_PPC_PSERIES
#ifdef CONFIG_PPC_MULTIPLATFORM
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,
extern void pmac_nvram_init(void);
extern void pmac_iommu_alloc(void);
#endif /* __PMAC_H__ */
......@@ -44,9 +44,9 @@
#undef DEBUG_FEATURE
#ifdef DEBUG_FEATURE
#define DBG(fmt,...) printk(KERN_DEBUG fmt)
#define DBG(fmt...) printk(KERN_DEBUG fmt)
#else
#define DBG(fmt,...)
#define DBG(fmt...)
#endif
/*
......
......@@ -37,13 +37,14 @@
#include <linux/vmalloc.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/rtas.h>
#include <asm/ppcdebug.h>
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#include <asm/abs_addr.h>
#include <asm/cacheflush.h>
#include <asm/lmb.h>
#include "pci.h"
......@@ -76,8 +77,8 @@
#define DARTMAP_RPNMASK 0x00ffffff
/* Physical base address and size of the DART table */
unsigned long dart_tablebase;
unsigned long dart_tablesize;
unsigned long dart_tablebase; /* exported to htab_initialize */
static unsigned long dart_tablesize;
/* Virtual base address of the DART table */
static u32 *dart_vbase;
......@@ -263,7 +264,6 @@ static int dart_init(struct device_node *dart_node)
return 0;
}
void iommu_setup_pmac(void)
{
struct pci_dev *dev = NULL;
......@@ -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)
* the exception of U3/AGP (hook into pci_set_mwi)
*/
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);
EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(flush_instruction_cache);
EXPORT_SYMBOL(_get_PVR);
EXPORT_SYMBOL(giveup_fpu);
#ifdef CONFIG_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];
spinlock_t rtas_data_buf_lock = SPIN_LOCK_UNLOCKED;
char rtas_data_buf[RTAS_DATA_BUF_SIZE]__page_aligned;
unsigned long rtas_rmo_buf;
void
call_rtas_display_status(char c)
call_rtas_display_status(unsigned char c)
{
struct rtas_args *args = &rtas.args;
unsigned long s;
if (!rtas.base)
return;
spin_lock_irqsave(&rtas.lock, s);
args->token = 10;
......@@ -62,6 +65,31 @@ call_rtas_display_status(char c)
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
rtas_token(const char *service)
{
......@@ -425,7 +453,6 @@ void rtas_os_term(char *str)
} while (status == RTAS_BUSY);
}
unsigned long rtas_rmo_buf = 0;
asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
{
......@@ -536,6 +563,53 @@ int rtas_get_error_log_max(void)
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_token);
EXPORT_SYMBOL(rtas_call);
......
This diff is collapsed.
......@@ -15,6 +15,8 @@
* 2 of the License, or (at your option) any later version.
*/
#undef DEBUG
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
......@@ -52,6 +54,13 @@
#include <asm/cputable.h>
#include <asm/system.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;
unsigned long cache_decay_ticks;
......@@ -75,10 +84,13 @@ extern long register_vpa(unsigned long flags, unsigned long proc,
unsigned long vpa);
int smt_enabled_at_boot = 1;
int boot_cpuid = 0;
/* Low level assembly function used to backup CPU 0 state */
extern void __save_cpu_setup(void);
extern void pseries_secondary_smp_init(unsigned long);
#ifdef CONFIG_PPC_ISERIES
static unsigned long iSeries_smp_message[NR_CPUS];
......@@ -182,7 +194,7 @@ void __init smp_init_iSeries(void)
}
#endif
#ifdef CONFIG_PPC_PSERIES
#ifdef CONFIG_PPC_MULTIPLATFORM
void smp_openpic_message_pass(int target, int msg)
{
/* make sure we're sending something that translates to an IPI */
......@@ -223,6 +235,10 @@ static void __devinit smp_openpic_setup_cpu(int cpu)
do_openpic_setup_cpu();
}
#endif /* CONFIG_PPC_MULTIPLATFORM */
#ifdef CONFIG_PPC_PSERIES
/* Get state of physical CPU.
* Return codes:
* 0 - The processor is in the RTAS stopped state
......@@ -236,6 +252,7 @@ int query_cpu_stopped(unsigned int pcpu)
int cpu_status;
int status, qcss_tok;
DBG(" -> query_cpu_stopped(%d)\n", pcpu);
qcss_tok = rtas_token("query-cpu-stopped-state");
if (qcss_tok == RTAS_UNKNOWN_SERVICE)
return -1;
......@@ -246,6 +263,8 @@ int query_cpu_stopped(unsigned int pcpu)
return status;
}
DBG(" <- query_cpu_stopped(), status: %d\n", cpu_status);
return cpu_status;
}
......@@ -275,8 +294,7 @@ void __cpu_die(unsigned int cpu)
for (tries = 0; tries < 25; tries++) {
cpu_status = query_cpu_stopped(pcpu);
if (cpu_status == 0)
if (cpu_status == 0 || cpu_status == -1)
break;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/5);
......@@ -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)
{
int status;
extern void (*pseries_secondary_smp_init)(unsigned int cpu);
unsigned long start_here = __pa(pseries_secondary_smp_init);
unsigned int pcpu;
......@@ -441,7 +458,7 @@ static void __init smp_space_timers(unsigned int max_cpus)
}
#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);
......@@ -532,19 +549,43 @@ static struct smp_ops_t pSeries_xics_smp_ops = {
/* This is called very early */
void __init smp_init_pSeries(void)
{
int ret, i;
DBG(" -> smp_init_pSeries()\n");
if (naca->interrupt_controller == IC_OPEN_PIC)
smp_ops = &pSeries_openpic_smp_ops;
else
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 */
if (systemcfg->platform == PLATFORM_PSERIES) {
smp_ops->give_timebase = pSeries_give_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)
{
......@@ -749,7 +790,7 @@ DECLARE_PER_CPU(unsigned int, pvr);
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)
......
......@@ -102,8 +102,9 @@ void ppc64_enable_pmcs(void)
{
/* XXX Implement for iseries */
}
#else
#endif
#ifdef CONFIG_PPC_MULTIPLATFORM
/*
* Enabling PMCs will slow partition context switch times so we only do
* it the first time we write to the PMCs.
......@@ -114,9 +115,11 @@ static DEFINE_PER_CPU(char, pmcs_enabled);
void ppc64_enable_pmcs(void)
{
unsigned long hid0;
#ifdef CONFIG_PPC_PSERIES
unsigned long set, reset;
int ret;
unsigned int ctrl;
#endif /* CONFIG_PPC_PSERIES */
/* Only need to enable them once */
if (__get_cpu_var(pmcs_enabled))
......@@ -126,6 +129,7 @@ void ppc64_enable_pmcs(void)
switch (systemcfg->platform) {
case PLATFORM_PSERIES:
case PLATFORM_POWERMAC:
hid0 = mfspr(HID0);
hid0 |= 1UL << (63 - 20);
......@@ -143,6 +147,7 @@ void ppc64_enable_pmcs(void)
"memory");
break;
#ifdef CONFIG_PPC_PSERIES
case PLATFORM_PSERIES_LPAR:
set = 1UL << 63;
reset = 0;
......@@ -152,11 +157,13 @@ void ppc64_enable_pmcs(void)
"returned %d\n",
smp_processor_id(), ret);
break;
#endif /* CONFIG_PPC_PSERIES */
default:
break;
}
#ifdef CONFIG_PPC_PSERIES
/* instruct hypervisor to maintain PMCs */
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
char *ptr = (char *)&paca[smp_processor_id()].lppaca;
......@@ -172,8 +179,9 @@ void ppc64_enable_pmcs(void)
ctrl |= RUNLATCH;
mtspr(CTRLT, ctrl);
}
#endif /* CONFIG_PPC_PSERIES */
}
#endif
#endif /* CONFIG_PPC_MULTIPLATFORM */
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 \
slb_low.o slb.o stab.o mmap.o
obj-$(CONFIG_DISCONTIGMEM) += numa.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