>From c45432c0cec8241dbcd6ed6cf38c953b17a6f826 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 16 Jan 2008 18:43:11 -0200 Subject: [PATCH] RFC: qemu cpu hotplug Signed-off-by: Glauber de Oliveira Costa --- bios/acpi-dsdt.dsl | 87 +++++++++++++++++++++++++++++----- bios/rombios32.c | 2 + qemu/hw/acpi.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++ qemu/hw/pc.c | 4 +- qemu/monitor.c | 9 ++++ qemu/pc-bios/bios.bin | Bin 6 files changed, 214 insertions(+), 13 deletions(-) diff --git a/bios/acpi-dsdt.dsl b/bios/acpi-dsdt.dsl index df255ce..497b866 100755 --- a/bios/acpi-dsdt.dsl +++ b/bios/acpi-dsdt.dsl @@ -27,18 +27,35 @@ DefinitionBlock ( { Scope (_PR) { - Processor (CPU0, 0x00, 0x0000b010, 0x06) {} - Processor (CPU1, 0x01, 0x0000b010, 0x06) {} - Processor (CPU2, 0x02, 0x0000b010, 0x06) {} - Processor (CPU3, 0x03, 0x0000b010, 0x06) {} - Processor (CPU4, 0x04, 0x0000b010, 0x06) {} - Processor (CPU5, 0x05, 0x0000b010, 0x06) {} - Processor (CPU6, 0x06, 0x0000b010, 0x06) {} - Processor (CPU7, 0x07, 0x0000b010, 0x06) {} - Processor (CPU8, 0x08, 0x0000b010, 0x06) {} - Processor (CPU9, 0x09, 0x0000b010, 0x06) {} - Processor (CPUA, 0x0a, 0x0000b010, 0x06) {} - Processor (CPUB, 0x0b, 0x0000b010, 0x06) {} + OperationRegion( PRO, SystemIO, 0xaf00, 0x02) + Field (PRO, ByteAcc, NoLock, WriteAsZeros) + { + PR0U, 1, + PR1U, 1, + PR2U, 1, + PR3U, 1, + PR4U, 1, + PADU, 3, + + PR0D, 1, + PR1D, 1, + PR2D, 1, + PR3D, 1, + PR4D, 1, + PADD, 3, + } + Processor (CPU0, 0x00, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } + Processor (CPU1, 0x01, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } + Processor (CPU2, 0x02, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } + Processor (CPU3, 0x03, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } + Processor (CPU4, 0x04, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } + Processor (CPU5, 0x05, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } + Processor (CPU6, 0x06, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } + Processor (CPU7, 0x07, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } + Processor (CPU8, 0x08, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } + Processor (CPU9, 0x09, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } + Processor (CPUA, 0x0a, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } + Processor (CPUB, 0x0b, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } Processor (CPUC, 0x0c, 0x0000b010, 0x06) {} Processor (CPUD, 0x0d, 0x0000b010, 0x06) {} Processor (CPUE, 0x0e, 0x0000b010, 0x06) {} @@ -559,6 +576,51 @@ DefinitionBlock ( } } } + Scope(\_GPE) + { + Method(_L00) { + Return(0x01) + } + Method(_L01) { + If (\_PR.PR1U) { + Notify(\_PR.CPU1, 1) + } + If (\_PR.PR1D){ + Notify(\_PR.CPU1, 3) + } + Return(0x01) + } + + Method(_L02) { + If (\_PR.PR2U) { + Notify(\_PR.CPU2, 1) + } + If (\_PR.PR2D){ + Notify(\_PR.CPU2, 3) + } + Return(0x01) + } + + Method(_L03) { + If (\_PR.PR3U) { + Notify(\_PR.CPU3, 1) + } + If (\_PR.PR3D){ + Notify(\_PR.CPU3, 3) + } + Return(0x01) + } + + Method(_L04) { + If (\_PR.PR4U) { + Notify(\_PR.CPU4, 1) + } + IF (\_PR.PR4D) { + Notify(\_PR.CPU4, 3) + } + Return(0x01) + } + } /* S5 = power off state */ Name (_S5, Package (4) { @@ -567,4 +629,5 @@ DefinitionBlock ( 0x00, // reserved 0x00, // reserved }) + } diff --git a/bios/rombios32.c b/bios/rombios32.c index 967c119..4580462 100755 --- a/bios/rombios32.c +++ b/bios/rombios32.c @@ -1329,6 +1329,8 @@ void acpi_bios_init(void) fadt->pm_tmr_len = 4; fadt->plvl2_lat = cpu_to_le16(0x0fff); // C2 state not supported fadt->plvl3_lat = cpu_to_le16(0x0fff); // C3 state not supported + fadt->gpe0_blk = cpu_to_le32(0xafe0); + fadt->gpe0_blk_len = 4; /* WBINVD + PROC_C1 + SLP_BUTTON + FIX_RTC */ fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 6)); acpi_build_table_header((struct acpi_table_header *)fadt, "FACP", diff --git a/qemu/hw/acpi.c b/qemu/hw/acpi.c index b97b37d..6e1af9e 100644 --- a/qemu/hw/acpi.c +++ b/qemu/hw/acpi.c @@ -530,3 +530,128 @@ void qemu_system_powerdown(void) } } #endif + +struct gpe_things { + uint16_t sts; + uint16_t en; + uint8_t pru; + uint8_t prd; +}; + +static struct gpe_things gpe; +unsigned long gpe_base = 0xafe0; + +static uint32_t gpe_readb(void *opaque, uint32_t addr) +{ + struct gpe_things *g = opaque; + uint32_t val; + + switch (addr) { + case 0xaf00: + val = g->pru; + break; + case 0xaf01: + val = g->prd; + break; + case 0xafe0: + val = g->sts & 0xFF; + break; + case 0xafe1: + val = (g->sts >> 8) & 0xFF; + break; + case 0xafe0 + 2: + val = g->en & 0xFF; + break; + case 0xafe3: + val = (g->en >> 8) & 0xFF; + break; + default: + break; + } + printf("gpe read %lx == %lx\n", addr, val); + return val; + +} + +static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val) +{ + struct gpe_things *g = opaque; + + switch (addr) { + case 0xaf00: + break; + case 0xafe0: + g->sts = (g->sts & ~0xFFFF) | (val & 0xFFFF); + break; + case 0xafe1: + g->sts = (g->sts & 0xFFFF) | (val << 8); + break; + case 0xafe0 + 2: + g->en = (g->en & ~0xFFFF) | (val & 0xFFFF); + break; + case 0xafe3: + g->en = (g->en & 0xFFFF) | (val << 8); + break; + + default: + break; + } + + printf("gpe write %lx <== %d\n", addr, val); +} + +int current_cpus = 0; +void qemu_system_hot_add_init(void) +{ + int i; + for (i = 0; i < smp_cpus; i++) + gpe.pru |= (1 << i); + + current_cpus = smp_cpus; + + register_ioport_write(gpe_base, 4, 1, gpe_writeb, &gpe); + register_ioport_read(gpe_base, 4, 1, gpe_readb, &gpe); + + register_ioport_write(0xaf00, 4, 1, gpe_writeb, &gpe); + register_ioport_read(0xaf00, 4, 1, gpe_readb, &gpe); +} + +static void enable_processor(struct gpe_things *g, int cpu) +{ + g->sts |= (1 << cpu); + g->en |= (1 << cpu); + g->pru |= (1 << cpu); + g->prd &= ~(1 << cpu); +} + +static void disable_processor(struct gpe_things *g, int cpu) +{ + g->sts |= (1 << cpu); + g->en |= (1 << cpu); + g->pru &= ~(1 << cpu); + g->prd |= (1 << cpu); +} + +void qemu_system_cpu_hot_add(int cpus) +{ + int i; + + gpe.sts = 0; + gpe.en = 0; + gpe.pru = 0; + gpe.prd = 0; + + qemu_set_irq(pm_state->dev.irq[0], 1); + + for (i = current_cpus ; i < cpus; i++) { + enable_processor(&gpe, i); + printf("proc %i up (%d %d)\n", i, gpe.sts, gpe.en); + } + for (i = current_cpus - 1 ; i >= cpus; i--) { + disable_processor(&gpe, i); + printf("proc %i down (%d %d)\n", i, gpe.sts, gpe.en); + } + + qemu_set_irq(pm_state->dev.irq[0], 0); + +} diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c index 3972ab4..5ce28ab 100644 --- a/qemu/hw/pc.c +++ b/qemu/hw/pc.c @@ -1029,7 +1029,9 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, } } -#define USE_HYPERCALL + qemu_system_hot_add_init(); + +#undef USE_HYPERCALL #ifdef USE_HYPERCALL pci_hypercall_init(pci_bus); #endif diff --git a/qemu/monitor.c b/qemu/monitor.c index e03c473..effb696 100644 --- a/qemu/monitor.c +++ b/qemu/monitor.c @@ -346,6 +346,14 @@ static void do_cpu_set(int index) term_printf("Invalid CPU index\n"); } +static void do_cpu_set_nr(int value) +{ + if ((value < 1) || (value > 32)) /* second condition is possibly bogus. OS dependant */ + term_printf("value out of range\n"); + qemu_system_cpu_hot_add(value); + +} + static void do_info_jit(void) { dump_exec_info(NULL, monitor_fprintf); @@ -1339,6 +1347,7 @@ static term_cmd_t term_cmds[] = { "", "cancel the current VM migration" }, { "migrate_set_speed", "s", do_migrate_set_speed, "value", "set maximum speed (in bytes) for migrations" }, + { "cpu_set", "i", do_cpu_set_nr, "value", "number of cpus in the guest" }, { NULL, NULL, }, }; diff --git a/qemu/pc-bios/bios.bin b/qemu/pc-bios/bios.bin index 7462753c0462e6fc863c0669664d363788e08ff3..7599b8d8956141d3355616c12bad85ac3ee112ae 100644 GIT binary patch delta 1683 zc${riZ%i9y7=PdE6^^4w)eh>Wp>EBB0Z0EFShO>=S4K7lltS57aK-2@(Tm1KFZ&?U zVuy0+5R!}G(-H_KEShZ7E<;${TAV!$ewgut7{1iS#9Ls>qOz!k^L-1#IeQ4!Tv^{xa{Z$goxcN`%ptrK|o97yn{knK#QcPC~HwV}Ht)*96E{m)2 z;H}Z&xAub}IyMJmO5%O5nV=r$Ng$R~^NA^6l&G|zNY(>nK@uR3#2x^v2US%anWRv3 zhL-gdpJ;2!K(h_Sin5`qVtTm2D&C*Oz=VaDnhsm3O5_jBH55y49==&-LP45k?xoq< zRq<^rC$a}7T)fnBvZlUK`#m7Evurzs&xOMs_}P} z9EvWn&q~Fs8Z#nkRUXDvFcUAqZOdLO0GSQhTM1EGY_59n>;4*ha#SLl_txQr$l`Ek zsya=;8Juv<@(^my3k?&SVmv$~rtm$6yhLoyuuMt4&4Gf?vZ~6BCX&tPVFjLX?Dneo z-TkEtP%sVrjV7$So||ytb&{9*T7DqVgpRdV6J}l-Y<-q6@lvWaOc;1+Z(Ci70nff- zO;u$*!zWI)>7eNe1QD_xH-Xy{Do{UCpZ@~_9ftN+0xhPe{fH4SX)sxOmerwWJBYZe z?G=QLm%eZB!kIOJT6}PU2tIxeoWw^{NBYs+w&~whb#~-9dS|{w+mfBZ` z8YQDqG8!eLQ8HMG#!wr6B;kFf=))`Ur71f0vX#o7UqCPJ*lSa8Pn89IP;NqSrG7MW z;nr} zi;LaXaRYN%!%Ao|#H-9^G~Wn_mYax`~0#EGfp*WI*WR8HquTswrYkh@qgD=$1) zaA^LQ(DL(c1FGivUp1RJ&;1%&wzx}BxqbhZ6Xy|TxH1qvx%u>eF4%tB@~5v|fL}p9 j{-J^C$j5NuX;?qqya=D#55v>K20RN3>uYQ-kRAUA;utKq delta 1195 zc${UDT}%{L6vywKorT$D*WE-Eszy{MijgX`@}aJY?qCp>kKOGq;!1^9nK1oGFgjx5 z3bP$Zx!Gv0w{LtFa|a@7-3NwDWTA z@BHum-*e9yNn#|4v6pMN4+}K7-YNf`t z+i+zyEDbtn5N}*W4p!&?FpT&GJ)6ZJin2`n&>W&!eFIU#b8#mrC*x%Sm|MwsOCa7Q zPn8aQ(Yv!;Q{28S8;RaGlL)0s(-gc;^c$O20g(1W$7r{p_@VCh%dKq7a&I*VO0@Ai3P1TsQz_LUC<9G< zsWw4LHMLVALD|w==?sx(7CknMj5R8#oy``Q--%OH#!5;f1&KwZlBoYf3I|7^iNc+3 z3)H(w*9SCLKWD*@+K;tsfgAv<>kD@fpjeI)!8JWfLGYw6Y5@!5YjjLD%^ z{1beJ$ER!xeL#+W94aV|65Cm^%w?NAif{ikTi|<3csoIq!UXNrcF>`H9=*L3952UP|ZAtVt;s#%_JSPo4}iw1-1VTkx`f4a$Qp0Z(oJu z@I=xcJIOM5_QuHF;dhg8{f=Th7Y`*?r@nXd=pJ7_%iqTT=?0wTCzlHt{s{h+QaWQ&wc&*%T-P^_)gX`lL>ndI5_=FWd5MXf!%8V=T?cP`ClXR#U3ZN z+y2ZBP2-$vJl1~v`RkwFE&JgGPF%eVKZg_2NASy+Vbz3h25#R9J14{y*bj57c9m6w H4X& -- 1.5.0.6