Changeset View
Changeset View
Standalone View
Standalone View
head/sys/powerpc/powernv/platform_powernv.c
Show First 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
void (*powernv_smp_ap_extra_init)(void); | void (*powernv_smp_ap_extra_init)(void); | ||||
static int powernv_probe(platform_t); | static int powernv_probe(platform_t); | ||||
static int powernv_attach(platform_t); | static int powernv_attach(platform_t); | ||||
void powernv_mem_regions(platform_t, struct mem_region *phys, int *physsz, | void powernv_mem_regions(platform_t, struct mem_region *phys, int *physsz, | ||||
struct mem_region *avail, int *availsz); | struct mem_region *avail, int *availsz); | ||||
static void powernv_numa_mem_regions(platform_t plat, struct numa_mem_region *phys, int *physsz); | |||||
static u_long powernv_timebase_freq(platform_t, struct cpuref *cpuref); | static u_long powernv_timebase_freq(platform_t, struct cpuref *cpuref); | ||||
static int powernv_smp_first_cpu(platform_t, struct cpuref *cpuref); | static int powernv_smp_first_cpu(platform_t, struct cpuref *cpuref); | ||||
static int powernv_smp_next_cpu(platform_t, struct cpuref *cpuref); | static int powernv_smp_next_cpu(platform_t, struct cpuref *cpuref); | ||||
static int powernv_smp_get_bsp(platform_t, struct cpuref *cpuref); | static int powernv_smp_get_bsp(platform_t, struct cpuref *cpuref); | ||||
static void powernv_smp_ap_init(platform_t); | static void powernv_smp_ap_init(platform_t); | ||||
#ifdef SMP | #ifdef SMP | ||||
static int powernv_smp_start_cpu(platform_t, struct pcpu *cpu); | static int powernv_smp_start_cpu(platform_t, struct pcpu *cpu); | ||||
static void powernv_smp_probe_threads(platform_t); | static void powernv_smp_probe_threads(platform_t); | ||||
static struct cpu_group *powernv_smp_topo(platform_t plat); | static struct cpu_group *powernv_smp_topo(platform_t plat); | ||||
#endif | #endif | ||||
static void powernv_reset(platform_t); | static void powernv_reset(platform_t); | ||||
static void powernv_cpu_idle(sbintime_t sbt); | static void powernv_cpu_idle(sbintime_t sbt); | ||||
static int powernv_cpuref_init(void); | static int powernv_cpuref_init(void); | ||||
static platform_method_t powernv_methods[] = { | static platform_method_t powernv_methods[] = { | ||||
PLATFORMMETHOD(platform_probe, powernv_probe), | PLATFORMMETHOD(platform_probe, powernv_probe), | ||||
PLATFORMMETHOD(platform_attach, powernv_attach), | PLATFORMMETHOD(platform_attach, powernv_attach), | ||||
PLATFORMMETHOD(platform_mem_regions, powernv_mem_regions), | PLATFORMMETHOD(platform_mem_regions, powernv_mem_regions), | ||||
PLATFORMMETHOD(platform_numa_mem_regions, powernv_numa_mem_regions), | |||||
PLATFORMMETHOD(platform_timebase_freq, powernv_timebase_freq), | PLATFORMMETHOD(platform_timebase_freq, powernv_timebase_freq), | ||||
PLATFORMMETHOD(platform_smp_ap_init, powernv_smp_ap_init), | PLATFORMMETHOD(platform_smp_ap_init, powernv_smp_ap_init), | ||||
PLATFORMMETHOD(platform_smp_first_cpu, powernv_smp_first_cpu), | PLATFORMMETHOD(platform_smp_first_cpu, powernv_smp_first_cpu), | ||||
PLATFORMMETHOD(platform_smp_next_cpu, powernv_smp_next_cpu), | PLATFORMMETHOD(platform_smp_next_cpu, powernv_smp_next_cpu), | ||||
PLATFORMMETHOD(platform_smp_get_bsp, powernv_smp_get_bsp), | PLATFORMMETHOD(platform_smp_get_bsp, powernv_smp_get_bsp), | ||||
#ifdef SMP | #ifdef SMP | ||||
PLATFORMMETHOD(platform_smp_start_cpu, powernv_smp_start_cpu), | PLATFORMMETHOD(platform_smp_start_cpu, powernv_smp_start_cpu), | ||||
▲ Show 20 Lines • Show All 151 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
powernv_mem_regions(platform_t plat, struct mem_region *phys, int *physsz, | powernv_mem_regions(platform_t plat, struct mem_region *phys, int *physsz, | ||||
struct mem_region *avail, int *availsz) | struct mem_region *avail, int *availsz) | ||||
{ | { | ||||
ofw_mem_regions(phys, physsz, avail, availsz); | ofw_mem_regions(phys, physsz, avail, availsz); | ||||
} | } | ||||
static void | |||||
powernv_numa_mem_regions(platform_t plat, struct numa_mem_region *phys, int *physsz) | |||||
{ | |||||
ofw_numa_mem_regions(phys, physsz); | |||||
} | |||||
static u_long | static u_long | ||||
powernv_timebase_freq(platform_t plat, struct cpuref *cpuref) | powernv_timebase_freq(platform_t plat, struct cpuref *cpuref) | ||||
{ | { | ||||
char buf[8]; | char buf[8]; | ||||
phandle_t cpu, dev, root; | phandle_t cpu, dev, root; | ||||
int res; | int res; | ||||
int32_t ticks = -1; | int32_t ticks = -1; | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | powernv_cpuref_init(void) | ||||
bsp = 0; | bsp = 0; | ||||
tmp_cpuref_cnt = 0; | tmp_cpuref_cnt = 0; | ||||
for (cpu = OF_child(dev); cpu != 0; cpu = OF_peer(cpu)) { | for (cpu = OF_child(dev); cpu != 0; cpu = OF_peer(cpu)) { | ||||
res = OF_getprop(cpu, "device_type", buf, sizeof(buf)); | res = OF_getprop(cpu, "device_type", buf, sizeof(buf)); | ||||
if (res > 0 && strcmp(buf, "cpu") == 0) { | if (res > 0 && strcmp(buf, "cpu") == 0) { | ||||
res = OF_getproplen(cpu, "ibm,ppc-interrupt-server#s"); | res = OF_getproplen(cpu, "ibm,ppc-interrupt-server#s"); | ||||
if (res > 0) { | if (res > 0) { | ||||
OF_getencprop(cpu, "ibm,ppc-interrupt-server#s", | OF_getencprop(cpu, "ibm,ppc-interrupt-server#s", | ||||
interrupt_servers, res); | interrupt_servers, res); | ||||
for (a = 0; a < res/sizeof(cell_t); a++) { | for (a = 0; a < res/sizeof(cell_t); a++) { | ||||
tmp_cpuref[tmp_cpuref_cnt].cr_hwref = interrupt_servers[a]; | tmp_cpuref[tmp_cpuref_cnt].cr_hwref = interrupt_servers[a]; | ||||
tmp_cpuref[tmp_cpuref_cnt].cr_cpuid = tmp_cpuref_cnt; | tmp_cpuref[tmp_cpuref_cnt].cr_cpuid = tmp_cpuref_cnt; | ||||
tmp_cpuref[tmp_cpuref_cnt].cr_domain = interrupt_servers[a] >> 11; | |||||
if (interrupt_servers[a] == (uint32_t)powernv_boot_pir) | if (interrupt_servers[a] == (uint32_t)powernv_boot_pir) | ||||
bsp = tmp_cpuref_cnt; | bsp = tmp_cpuref_cnt; | ||||
tmp_cpuref_cnt++; | tmp_cpuref_cnt++; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/* Map IDs, so BSP has CPUID 0 regardless of hwref */ | /* Map IDs, so BSP has CPUID 0 regardless of hwref */ | ||||
for (a = bsp; a < tmp_cpuref_cnt; a++) { | for (a = bsp; a < tmp_cpuref_cnt; a++) { | ||||
platform_cpuref[platform_cpuref_cnt].cr_hwref = tmp_cpuref[a].cr_hwref; | platform_cpuref[platform_cpuref_cnt].cr_hwref = tmp_cpuref[a].cr_hwref; | ||||
platform_cpuref[platform_cpuref_cnt].cr_cpuid = platform_cpuref_cnt; | platform_cpuref[platform_cpuref_cnt].cr_cpuid = platform_cpuref_cnt; | ||||
platform_cpuref[platform_cpuref_cnt].cr_domain = tmp_cpuref[a].cr_domain; | |||||
platform_cpuref_cnt++; | platform_cpuref_cnt++; | ||||
} | } | ||||
for (a = 0; a < bsp; a++) { | for (a = 0; a < bsp; a++) { | ||||
platform_cpuref[platform_cpuref_cnt].cr_hwref = tmp_cpuref[a].cr_hwref; | platform_cpuref[platform_cpuref_cnt].cr_hwref = tmp_cpuref[a].cr_hwref; | ||||
platform_cpuref[platform_cpuref_cnt].cr_cpuid = platform_cpuref_cnt; | platform_cpuref[platform_cpuref_cnt].cr_cpuid = platform_cpuref_cnt; | ||||
platform_cpuref[platform_cpuref_cnt].cr_domain = tmp_cpuref[a].cr_domain; | |||||
platform_cpuref_cnt++; | platform_cpuref_cnt++; | ||||
} | } | ||||
platform_cpuref_valid = 1; | platform_cpuref_valid = 1; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
powernv_smp_first_cpu(platform_t plat, struct cpuref *cpuref) | powernv_smp_first_cpu(platform_t plat, struct cpuref *cpuref) | ||||
{ | { | ||||
if (platform_cpuref_valid == 0) | if (platform_cpuref_valid == 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
cpuref->cr_cpuid = 0; | cpuref->cr_cpuid = 0; | ||||
cpuref->cr_hwref = platform_cpuref[0].cr_hwref; | cpuref->cr_hwref = platform_cpuref[0].cr_hwref; | ||||
cpuref->cr_domain = platform_cpuref[0].cr_domain; | |||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
powernv_smp_next_cpu(platform_t plat, struct cpuref *cpuref) | powernv_smp_next_cpu(platform_t plat, struct cpuref *cpuref) | ||||
{ | { | ||||
int id; | int id; | ||||
if (platform_cpuref_valid == 0) | if (platform_cpuref_valid == 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
id = cpuref->cr_cpuid + 1; | id = cpuref->cr_cpuid + 1; | ||||
if (id >= platform_cpuref_cnt) | if (id >= platform_cpuref_cnt) | ||||
return (ENOENT); | return (ENOENT); | ||||
cpuref->cr_cpuid = platform_cpuref[id].cr_cpuid; | cpuref->cr_cpuid = platform_cpuref[id].cr_cpuid; | ||||
cpuref->cr_hwref = platform_cpuref[id].cr_hwref; | cpuref->cr_hwref = platform_cpuref[id].cr_hwref; | ||||
cpuref->cr_domain = platform_cpuref[id].cr_domain; | |||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
powernv_smp_get_bsp(platform_t plat, struct cpuref *cpuref) | powernv_smp_get_bsp(platform_t plat, struct cpuref *cpuref) | ||||
{ | { | ||||
cpuref->cr_cpuid = platform_cpuref[0].cr_cpuid; | cpuref->cr_cpuid = platform_cpuref[0].cr_cpuid; | ||||
cpuref->cr_hwref = platform_cpuref[0].cr_hwref; | cpuref->cr_hwref = platform_cpuref[0].cr_hwref; | ||||
cpuref->cr_domain = platform_cpuref[0].cr_domain; | |||||
return (0); | return (0); | ||||
} | } | ||||
#ifdef SMP | #ifdef SMP | ||||
static int | static int | ||||
powernv_smp_start_cpu(platform_t plat, struct pcpu *pc) | powernv_smp_start_cpu(platform_t plat, struct pcpu *pc) | ||||
{ | { | ||||
int result; | int result; | ||||
▲ Show 20 Lines • Show All 90 Lines • Show Last 20 Lines |