* Find out a few interesting information about the system (like CPU,
bus, and time base frequency) in the PPC boot loader, and propagate them to the kernel via kernel_args. * Now we use the correct time base frequency for timer calculations. * Implemented PPC specific system info stuff. Added a few PPC CPU types to <OS.h>. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15817 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1c33148d10
commit
716a16ce61
@ -379,13 +379,41 @@ typedef enum cpu_types {
|
||||
// ToDo: add latest models
|
||||
|
||||
/* Motorola/IBM */
|
||||
B_CPU_PPC_UNKNOWN = 0,
|
||||
B_CPU_PPC_601 = 1,
|
||||
B_CPU_PPC_602 = 7,
|
||||
B_CPU_PPC_603 = 2,
|
||||
B_CPU_PPC_603e = 3,
|
||||
B_CPU_PPC_603ev = 8,
|
||||
B_CPU_PPC_604 = 4,
|
||||
B_CPU_PPC_604e = 5,
|
||||
B_CPU_PPC_604ev = 9,
|
||||
B_CPU_PPC_620 = 10,
|
||||
B_CPU_PPC_750 = 6,
|
||||
B_CPU_PPC_686 = 13,
|
||||
B_CPU_PPC_860 = 25,
|
||||
B_CPU_PPC_7400 = 26,
|
||||
B_CPU_PPC_7410 = 27,
|
||||
B_CPU_PPC_7447A = 28,
|
||||
B_CPU_PPC_7448 = 29,
|
||||
B_CPU_PPC_7450 = 30,
|
||||
B_CPU_PPC_7455 = 31,
|
||||
B_CPU_PPC_7457 = 32,
|
||||
B_CPU_PPC_8240 = 33,
|
||||
B_CPU_PPC_8245 = 34,
|
||||
|
||||
B_CPU_PPC_IBM_401A1 = 35,
|
||||
B_CPU_PPC_IBM_401B2 = 36,
|
||||
B_CPU_PPC_IBM_401C2 = 37,
|
||||
B_CPU_PPC_IBM_401D2 = 38,
|
||||
B_CPU_PPC_IBM_401E2 = 39,
|
||||
B_CPU_PPC_IBM_401F2 = 40,
|
||||
B_CPU_PPC_IBM_401G2 = 41,
|
||||
B_CPU_PPC_IBM_403 = 42,
|
||||
B_CPU_PPC_IBM_405GP = 43,
|
||||
B_CPU_PPC_IBM_405L = 44,
|
||||
B_CPU_PPC_IBM_750FX = 45,
|
||||
B_CPU_PPC_IBM_POWER3 = 46,
|
||||
|
||||
/* Intel */
|
||||
|
||||
|
@ -77,6 +77,7 @@ extern uint32 get_sr(void *virtualAddress);
|
||||
extern void set_sr(void *virtualAddress, uint32 value);
|
||||
extern uint32 get_msr(void);
|
||||
extern uint32 set_msr(uint32 value);
|
||||
extern uint32 get_pvr(void);
|
||||
|
||||
extern void set_ibat0(struct block_address_translation *bat);
|
||||
extern void set_ibat1(struct block_address_translation *bat);
|
||||
@ -117,4 +118,40 @@ extern void ppc_context_switch(void **_oldStackPointer, void *newStackPointer);
|
||||
#define tlbia() asm volatile("tlbia")
|
||||
#define tlbie(addr) asm volatile("tlbie %0" :: "r" (addr))
|
||||
|
||||
|
||||
// PowerPC processor version (the upper 16 bits of the PVR).
|
||||
enum ppc_processor_version {
|
||||
MPC601 = 0x0001,
|
||||
MPC603 = 0x0003,
|
||||
MPC604 = 0x0004,
|
||||
MPC602 = 0x0005,
|
||||
MPC603e = 0x0006,
|
||||
MPC603ev = 0x0007,
|
||||
MPC750 = 0x0008,
|
||||
MPC604ev = 0x0009,
|
||||
MPC7400 = 0x000c,
|
||||
MPC620 = 0x0014,
|
||||
IBM403 = 0x0020,
|
||||
IBM401A1 = 0x0021,
|
||||
IBM401B2 = 0x0022,
|
||||
IBM401C2 = 0x0023,
|
||||
IBM401D2 = 0x0024,
|
||||
IBM401E2 = 0x0025,
|
||||
IBM401F2 = 0x0026,
|
||||
IBM401G2 = 0x0027,
|
||||
IBMPOWER3 = 0x0041,
|
||||
MPC860 = 0x0050,
|
||||
MPC8240 = 0x0081,
|
||||
IBM405GP = 0x4011,
|
||||
IBM405L = 0x4161,
|
||||
IBM750FX = 0x7000,
|
||||
MPC7450 = 0x8000,
|
||||
MPC7455 = 0x8001,
|
||||
MPC7457 = 0x8002,
|
||||
MPC7447A = 0x8003,
|
||||
MPC7448 = 0x8004,
|
||||
MPC7410 = 0x800c,
|
||||
MPC8245 = 0x8081,
|
||||
};
|
||||
|
||||
#endif /* _KERNEL_ARCH_PPC_CPU_H */
|
||||
|
@ -16,6 +16,10 @@
|
||||
// kernel args
|
||||
typedef struct {
|
||||
// architecture specific
|
||||
uint64 cpu_frequency;
|
||||
uint64 bus_frequency;
|
||||
uint64 time_base_frequency;
|
||||
|
||||
addr_range page_table; // virtual address and size of the page table
|
||||
addr_range exception_handlers;
|
||||
addr_range framebuffer; // maps where the framebuffer is located, in physical memory
|
||||
|
@ -30,7 +30,7 @@ boot_arch_cpu_init(void)
|
||||
// iterate through the "/cpus" node to find all CPUs
|
||||
int cpus = of_finddevice("/cpus");
|
||||
if (cpus == OF_FAILED) {
|
||||
printf("arch_cpu_init(): Failed to open \"/cpus\"!\n");
|
||||
printf("boot_arch_cpu_init(): Failed to open \"/cpus\"!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@ -41,11 +41,53 @@ boot_arch_cpu_init(void)
|
||||
sizeof(cpuPath)) == B_OK) {
|
||||
TRACE(("found CPU: %s\n", cpuPath));
|
||||
|
||||
// For the first CPU get the frequencies of CPU, bus, and time base.
|
||||
// We assume they are the same for all CPUs.
|
||||
if (cpuCount == 0) {
|
||||
int cpu = of_finddevice(cpuPath);
|
||||
if (cpu == OF_FAILED) {
|
||||
printf("boot_arch_cpu_init: Failed get CPU device node!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// TODO: Does encode-int really encode quadlet (32 bit numbers)
|
||||
// only?
|
||||
int32 clockFrequency;
|
||||
if (of_getprop(cpu, "clock-frequency", &clockFrequency, 4)
|
||||
== OF_FAILED) {
|
||||
printf("boot_arch_cpu_init: Failed to get CPU clock "
|
||||
"frequency!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
int32 busFrequency;
|
||||
if (of_getprop(cpu, "bus-frequency", &busFrequency, 4)
|
||||
== OF_FAILED) {
|
||||
printf("boot_arch_cpu_init: Failed to get bus clock "
|
||||
"frequency!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
int32 timeBaseFrequency;
|
||||
if (of_getprop(cpu, "timebase-frequency", &timeBaseFrequency, 4)
|
||||
== OF_FAILED) {
|
||||
printf("boot_arch_cpu_init: Failed to get time base "
|
||||
"frequency!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
gKernelArgs.arch_args.cpu_frequency = clockFrequency;
|
||||
gKernelArgs.arch_args.bus_frequency = busFrequency;
|
||||
gKernelArgs.arch_args.time_base_frequency = timeBaseFrequency;
|
||||
|
||||
TRACE((" CPU clock frequency: %ld\n", clockFrequency));
|
||||
TRACE((" bus clock frequency: %ld\n", busFrequency));
|
||||
TRACE((" time base frequency: %ld\n", timeBaseFrequency));
|
||||
}
|
||||
|
||||
cpuCount++;
|
||||
}
|
||||
|
||||
if (cpuCount == 0) {
|
||||
printf("arch_cpu_init(): Found no CPUs!\n");
|
||||
printf("boot_arch_cpu_init(): Found no CPUs!\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@ -56,7 +98,7 @@ boot_arch_cpu_init(void)
|
||||
addr_t stack = (addr_t)arch_mmu_allocate((void*)0x80000000,
|
||||
cpuCount * KERNEL_STACK_SIZE, B_READ_AREA | B_WRITE_AREA, false);
|
||||
if (!stack) {
|
||||
printf("arch_cpu_init(): Failed to allocate kernel stack(s)!\n");
|
||||
printf("boot_arch_cpu_init(): Failed to allocate kernel stack(s)!\n");
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -116,19 +116,6 @@ arch_cpu_user_TLB_invalidate(void)
|
||||
}
|
||||
|
||||
|
||||
// ToDo: doesn't belong here!
|
||||
#if 0
|
||||
long long
|
||||
system_time(void)
|
||||
{
|
||||
bigtime_t time_base = get_time_base();
|
||||
|
||||
return (time_base * 1000000) / ((66*1000*1000) / 4);
|
||||
// ToDo: remove hard coded
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
status_t
|
||||
arch_cpu_user_memcpy(void *to, const void *from, size_t size, addr_t *fault_handler)
|
||||
{
|
||||
@ -218,4 +205,3 @@ arch_cpu_idle(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Copyright 2003, Axel D<EFBFBD>fler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
@ -47,6 +47,12 @@ FUNCTION(set_msr):
|
||||
mtmsr %r3
|
||||
blr
|
||||
|
||||
/* uint32 get_pvr(void);
|
||||
*/
|
||||
FUNCTION(get_pvr):
|
||||
mfpvr %r3
|
||||
blr
|
||||
|
||||
|
||||
#define get_ibat(num) \
|
||||
mfibatu %r4, num; \
|
||||
|
@ -1,29 +1,71 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <OS.h>
|
||||
|
||||
#include <kernel.h>
|
||||
#include <smp.h>
|
||||
#include <arch_cpu.h>
|
||||
#include <arch/system_info.h>
|
||||
#include <boot/kernel_args.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static uint64 sCPUClockFrequency;
|
||||
static uint64 sBusClockFrequency;
|
||||
static enum cpu_types sCPUType;
|
||||
static uint16 sCPURevision;
|
||||
|
||||
struct cpu_model {
|
||||
uint16 version;
|
||||
enum cpu_types beos_type;
|
||||
};
|
||||
|
||||
// mapping of CPU versions to BeOS enum cpu_types
|
||||
struct cpu_model kCPUModels[] = {
|
||||
{ MPC601, B_CPU_PPC_601 },
|
||||
{ MPC603, B_CPU_PPC_603 },
|
||||
{ MPC604, B_CPU_PPC_604 },
|
||||
{ MPC602, B_CPU_PPC_603ev },
|
||||
{ MPC603e, B_CPU_PPC_603e },
|
||||
{ MPC603ev, B_CPU_PPC_603ev },
|
||||
{ MPC750, B_CPU_PPC_750 },
|
||||
{ MPC604ev, B_CPU_PPC_604ev },
|
||||
{ MPC7400, B_CPU_PPC_7400 },
|
||||
{ MPC620, B_CPU_PPC_620 },
|
||||
{ IBM403, B_CPU_PPC_IBM_403 },
|
||||
{ IBM401A1, B_CPU_PPC_IBM_401A1 },
|
||||
{ IBM401B2, B_CPU_PPC_IBM_401B2 },
|
||||
{ IBM401C2, B_CPU_PPC_IBM_401C2 },
|
||||
{ IBM401D2, B_CPU_PPC_IBM_401D2 },
|
||||
{ IBM401E2, B_CPU_PPC_IBM_401E2 },
|
||||
{ IBM401F2, B_CPU_PPC_IBM_401F2 },
|
||||
{ IBM401G2, B_CPU_PPC_IBM_401G2 },
|
||||
{ IBMPOWER3, B_CPU_PPC_IBM_POWER3 },
|
||||
{ MPC860, B_CPU_PPC_860 },
|
||||
{ MPC8240, B_CPU_PPC_8240 },
|
||||
{ IBM405GP, B_CPU_PPC_IBM_405GP },
|
||||
{ IBM405L, B_CPU_PPC_IBM_405L },
|
||||
{ IBM750FX, B_CPU_PPC_IBM_750FX },
|
||||
{ MPC7450, B_CPU_PPC_7450 },
|
||||
{ MPC7455, B_CPU_PPC_7455 },
|
||||
{ MPC7457, B_CPU_PPC_7457 },
|
||||
{ MPC7447A, B_CPU_PPC_7447A },
|
||||
{ MPC7448, B_CPU_PPC_7448 },
|
||||
{ MPC7410, B_CPU_PPC_7410 },
|
||||
{ MPC8245, B_CPU_PPC_8245 },
|
||||
{ 0, B_CPU_PPC_UNKNOWN }
|
||||
};
|
||||
|
||||
|
||||
status_t
|
||||
arch_get_system_info(system_info *info, size_t size)
|
||||
{
|
||||
//info->cpu_type = sCpuType;
|
||||
//info->cpu_revision = sCpuRevision;
|
||||
info->cpu_type = sCPUType;
|
||||
info->cpu_revision = sCPURevision;
|
||||
|
||||
info->cpu_clock_speed = sCPUClockFrequency;
|
||||
info->bus_clock_speed = sBusClockFrequency;
|
||||
|
||||
// - various cpu_info
|
||||
//info->cpu_clock_speed = sCpuClockSpeed;
|
||||
// - bus_clock_speed
|
||||
info->platform_type = B_MAC_PLATFORM;
|
||||
|
||||
return B_OK;
|
||||
@ -33,7 +75,25 @@ arch_get_system_info(system_info *info, size_t size)
|
||||
status_t
|
||||
arch_system_info_init(struct kernel_args *args)
|
||||
{
|
||||
//sCpuClockSpeed = args->arch_args.cpu_clock_speed;
|
||||
int i;
|
||||
|
||||
sCPUClockFrequency = args->arch_args.cpu_frequency;
|
||||
sBusClockFrequency = args->arch_args.bus_frequency;
|
||||
|
||||
// The PVR (processor version register) contains processor version and
|
||||
// revision.
|
||||
uint32 pvr = get_pvr();
|
||||
uint16 version = (uint16)(pvr >> 16);
|
||||
sCPURevision = (uint16)(pvr & 0xffff);
|
||||
|
||||
// translate the version to a BeOS cpu_types constant
|
||||
sCPUType = B_CPU_PPC_UNKNOWN;
|
||||
for (i = 0; kCPUModels[i].beos_type != B_CPU_PPC_UNKNOWN; i++) {
|
||||
if (version == kCPUModels[i].version) {
|
||||
sCPUType = kCPUModels[i].beos_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ arch_timer_clear_hardware_timer()
|
||||
int
|
||||
arch_init_timer(kernel_args *ka)
|
||||
{
|
||||
sTickRate = (66*1000*1000) / 4; // ToDo: fix
|
||||
sTickRate = ka->arch_args.time_base_frequency;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user