ppc: Add "native" POWER8 platform
Re: [Qemu-devel] [Qemu-ppc] [PATCH 33/77] ppc/xics: Make the ICSState a list
In reply to Benjamin HerrenschmidtQuoted 90 lines · Benjamin Herrenschmidt
Instead of an array of fixed sized blocks, use a list, as we will need to have sources with variable number of interrupts. SPAPR only uses a single entry. Native will create more. If performance becomes an issue we can add some hashed lookup but for now this will do fine.
Signed-off-by Benjamin Herrenschmidt <[email protected]>--- hw/intc/xics.c | 86 +++++++++++++++++++++++++++++++-------------------- hw/intc/xics_kvm.c | 28 +++++++++-------- hw/intc/xics_spapr.c | 75 ++++++++++++++++++++++++-------------------- hw/ppc/spapr_events.c | 2 +- hw/ppc/spapr_pci.c | 4 +-- hw/ppc/spapr_vio.c | 2 +- include/hw/ppc/xics.h | 10 +++--- 7 files changed, 118 insertions(+), 89 deletions(-)hw/intc/xics.c +13
-9@@ -79,13 +79,16 @@ void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)static void xics_common_reset (DeviceState *d) {XICSState *xics =XICS_COMMON (d); +ICSState *ics;int i;for (i =0 ; i < xics->nr_servers; i++) {device_reset (DEVICE (&xics->ss[i])); } -device_reset (DEVICE (xics->ics)); + QLIST_FOREACH(ics, &xics->ics, list) { +device_reset (DEVICE (ics)); + } } static void xics_prop_get_nr_irqs(Object *obj, Visitor *v,@@ -117,7 +120,6 @@ static void xics_prop_set_nr_irqs(Object *obj, Visitor *v, }assert (info->set_nr_irqs); -assert (xics->ics); info->set_nr_irqs (xics, value, errp); }@@ -195,33 +197,35 @@ static void ics_reject(ICSState *ics, int nr);static void ics_resend (ICSState *ics);static void ics_eoi (ICSState *ics,int nr); -static void icp_check_ipi (XICSState *xics,int server) +static void icp_check_ipi (ICPState *ss,int server) { -ICPState *ss = xics->ss + server; -if (XISR (ss) && (ss->pending_priority <= ss->mfrr)) {return ; }trace_xics_icp_check_ipi (server, ss->mfrr); -if (XISR (ss)) { -ics_reject (xics->ics,XISR (ss)); +if (XISR (ss) && ss->xirr_owner) { +ics_reject (ss->xirr_owner,XISR (ss)); } ss->xirr = (ss->xirr & ~XISR_MASK ) |XICS_IPI ; ss->pending_priority = ss->mfrr; + ss->xirr_owner =NULL ;qemu_irq_raise (ss->output); }static void icp_resend (XICSState *xics,int server) {ICPState *ss = xics->ss + server; +ICSState *ics;if (ss->mfrr <CPPR (ss)) { -icp_check_ipi (xics, server); +icp_check_ipi (ss, server); + } + QLIST_FOREACH(ics, &xics->ics, list) { +ics_resend (ics); } -ics_resend (xics->ics); }void icp_set_cppr (XICSState *xics,int server,uint8_t cppr)
hw/intc/xics.c void icp_set_cppr(XICSState *xics, int server, uint8_t cppr) · line 249
Quoted 8 lines
hw/intc/xics.c +4
-1@@ -239,7 +243,10 @@ void icp_set_cppr(XICSState *xics, int server, uint8_t cppr) ss->xirr &= ~XISR_MASK ;/* Clear XISR */ ss->pending_priority =0xff ;qemu_irq_lower (ss->output); -ics_reject (xics->ics, old_xisr); +if (ss->xirr_owner) { +ics_reject (ss->xirr_owner, old_xisr); + ss->xirr_owner =NULL ; + }
To match the layour of the rest of things, this little fragment should probably go into an icp_reject() function.
Quoted 48 lines
hw/intc/xics.c +12
-3} }else {if (!XISR (ss)) {@@ -254,7 +261,7 @@ void icp_set_mfrr(XICSState *xics, int server, uint8_t mfrr) ss->mfrr = mfrr;if (mfrr <CPPR (ss)) { -icp_check_ipi (xics, server); +icp_check_ipi (ss, server); } }@@ -265,6 +272,7 @@ uint32_t icp_accept(ICPState *ss)qemu_irq_lower (ss->output); ss->xirr = ss->pending_priority <<24 ; ss->pending_priority =0xff ; + ss->xirr_owner =NULL ;trace_xics_icp_accept (xirr, ss->xirr);@@ -282,30 +290,40 @@ uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr)void icp_eoi (XICSState *xics,int server,uint32_t xirr) {ICPState *ss = xics->ss + server; +ICSState *ics; +uint32_t irq;/* Send EOI -> ICS */ ss->xirr = (ss->xirr & ~CPPR_MASK ) | (xirr &CPPR_MASK );trace_xics_icp_eoi (server, xirr, ss->xirr); -ics_eoi (xics->ics, xirr &XISR_MASK ); + irq = xirr &XISR_MASK ; + QLIST_FOREACH(ics, &xics->ics, list) { +if (ics_valid_irq (ics, irq)) { +ics_eoi (ics, irq); + } + }if (!XISR (ss)) {icp_resend (xics, server); } } -static void icp_irq (XICSState *xics,int server,int nr,uint8_t priority) +static void icp_irq (ICSState *ics,int server,int nr,uint8_t priority) { +XICSState *xics = ics->xics;ICPState *ss = xics->ss + server;
hw/intc/xics.c uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr) · line 321
Quoted 10 lines
hw/intc/xics.c +2
-3trace_xics_icp_irq (server, nr, priority);if ((priority >=CPPR (ss)) || (XISR (ss) && (ss->pending_priority <= priority))) { -ics_reject (xics->ics, nr); +ics_reject (ics, nr); }else { -if (XISR (ss)) { -ics_reject (xics->ics,XISR (ss)); +if (XISR (ss) && ss->xirr_owner) {
I'm guessing the only case where we should get XISR(ss) && !ss->xirr_owner will be an IPI, is that right?
Quoted 82 lines
hw/intc/xics.c +14
-17+ics_reject (ss->xirr_owner,XISR (ss)); + ss->xirr_owner =NULL ; } ss->xirr = (ss->xirr & ~XISR_MASK ) | (nr &XISR_MASK ); + ss->xirr_owner = ics; ss->pending_priority = priority;trace_xics_icp_raise (ss->xirr, ss->pending_priority);qemu_irq_raise (ss->output);@@ -388,8 +406,7 @@ static void resend_msi(ICSState *ics, int srcno)if (irq->status &XICS_STATUS_REJECTED ) { irq->status &= ~XICS_STATUS_REJECTED ;if (irq->priority !=0xff ) { -icp_irq (ics->xics, irq->server, srcno + ics->offset, - irq->priority); +icp_irq (ics, irq->server, srcno + ics->offset, irq->priority); } } }@@ -402,7 +419,7 @@ static void resend_lsi(ICSState *ics, int srcno) && (irq->status & XICS_STATUS_ASSERTED) && !(irq->status & XICS_STATUS_SENT)) { irq->status |=XICS_STATUS_SENT ; -icp_irq (ics->xics, irq->server, srcno + ics->offset, irq->priority); +icp_irq (ics, irq->server, srcno + ics->offset, irq->priority); } }@@ -417,7 +434,7 @@ static void set_irq_msi(ICSState *ics, int srcno, int val) irq->status |=XICS_STATUS_MASKED_PENDING ;trace_xics_masked_pending (); }else { -icp_irq (ics->xics, irq->server, srcno + ics->offset, irq->priority); +icp_irq (ics, irq->server, srcno + ics->offset, irq->priority); } } }@@ -456,7 +473,7 @@ static void write_xive_msi(ICSState *ics, int srcno) } irq->status &= ~XICS_STATUS_MASKED_PENDING ; -icp_irq (ics->xics, irq->server, srcno + ics->offset, irq->priority); +icp_irq (ics, irq->server, srcno + ics->offset, irq->priority); }static void write_xive_lsi (ICSState *ics,int srcno)@@ -642,28 +659,23 @@ static const TypeInfo ics_info = {/* * Exported functions */ -int xics_find_source (XICSState *xics,int irq) +ICSState *xics_find_source (XICSState *xics,int irq) { -int sources =1 ; -int src; +ICSState *ics; -/* FIXME: implement multiple sources */ -for (src =0 ; src < sources; ++src) { -ICSState *ics = &xics->ics[src]; + QLIST_FOREACH(ics, &xics->ics, list) {if (ics_valid_irq (ics, irq)) { -return src; +return ics; } } - -return -1 ; +return NULL ; }qemu_irq xics_get_qirq (XICSState *xics,int irq) { -int src =xics_find_source (xics, irq); +ICSState *ics =xics_find_source (xics, irq); -if (src >=0 ) { -ICSState *ics = &xics->ics[src]; +if (ics) {return ics->qirqs[irq - ics->offset]; }
hw/intc/xics.c void ics_set_irq_type(ICSState *ics, int srcno, bool lsi) · line 701
Quoted 7 lines
hw/intc/xics.c +3
-1@@ -684,7 +696,13 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)void xics_set_nr_irqs (XICSState *xics,uint32_t nr_irqs,Error **errp) { - xics->nr_irqs = xics->ics->nr_irqs = nr_irqs; +ICSState *ics =QLIST_FIRST (&xics->ics); + +/* This needs to be deprecated ... */
Yeah..
I can't even remember what this was really for. We probably need to move it to a property on the ics objects, with a backwards compat shim for PAPR to copy the xics "master" object value to the single ics.
Quoted 67 lines
hw/intc/xics.c +4
-0+ xics->nr_irqs = nr_irqs; +if (ics) { + ics->nr_irqs = nr_irqs; + } }void xics_set_nr_servers (XICSState *xics,uint32_t nr_servers,Error **errp)hw/intc/xics_kvm.c +14
-12@@ -356,11 +356,6 @@ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu) } } -static void xics_kvm_set_nr_irqs (XICSState *xics,uint32_t nr_irqs,Error **errp) -{ - xics->nr_irqs = xics->ics->nr_irqs = nr_irqs; -} -static void xics_kvm_set_nr_servers (XICSState *xics,uint32_t nr_servers,Error **errp) {@@ -391,6 +386,7 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp) {KVMXICSState *xicskvm =KVM_XICS (dev);XICSState *xics =XICS_COMMON (dev); +ICSState *ics;int i, rc;Error *error =NULL ;struct kvm_create_device xics_create_device = {@@ -442,10 +438,12 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp) xicskvm->kernel_xics_fd = xics_create_device.fd; -object_property_set_bool (OBJECT (xics->ics), true,"realized" , &error); -if (error) { -error_propagate (errp, error); - goto fail; + QLIST_FOREACH(ics, &xics->ics, list) { +object_property_set_bool (OBJECT (ics), true,"realized" , &error); +if (error) { +error_propagate (errp, error); + goto fail; + } }assert (xics->nr_servers);@@ -473,10 +471,14 @@ fail:static void xics_kvm_initfn (Object *obj) {XICSState *xics =XICS_COMMON (obj); +ICSState *ics; + +QLIST_INIT (&xics->ics); - xics->ics =ICS (object_new (TYPE_KVM_ICS )); -object_property_add_child (obj,"ics" ,OBJECT (xics->ics),NULL ); - xics->ics->xics = xics; + ics =ICS (object_new (TYPE_KVM_ICS )); +object_property_add_child (obj,"ics" ,OBJECT (ics),NULL ); + ics->xics = xics; +QLIST_INSERT_HEAD (&xics->ics, ics, list); }static void xics_kvm_class_init (ObjectClass *oc,void *data)
hw/intc/xics_kvm.c static void xics_kvm_class_init(ObjectClass *oc, void *data) · line 491
Quoted 5 lines
hw/intc/xics_kvm.c +1
-1@@ -486,7 +488,7 @@ static void xics_kvm_class_init(ObjectClass *oc, void *data) dc->realize = xics_kvm_realize; xsc->cpu_setup = xics_kvm_cpu_setup; - xsc->set_nr_irqs = xics_kvm_set_nr_irqs; + xsc->set_nr_irqs = xics_set_nr_irqs;
Wow.. why were xics_kvm_set_nr_irqs and xics_set_nr_irqs ever separate, I wonder.
Quoted 10 lines
hw/intc/xics_kvm.c +0
-0xsc->set_nr_servers = xics_kvm_set_nr_servers; }hw/intc/xics_spapr.c +0
-0@@ -111,10 +111,10 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets)
hw/intc/xics_spapr.c static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, · line 120
Quoted 10 lines
hw/intc/xics_spapr.c +2
-2{ -ICSState *ics = spapr->xics->ics; +ICSState *ics =QLIST_FIRST (&spapr->xics->ics);uint32_t nr, server, priority; -if ((nargs !=3 ) || (nret !=1 )) { +if ((nargs !=3 ) || (nret !=1 ) || !ics) {rtas_st (rets,0 ,RTAS_OUT_PARAM_ERROR );return ; }
!ics should probably be a HW_ERROR (or even an assert).
Quoted 107 lines
hw/intc/xics_spapr.c +26
-17@@ -139,10 +139,10 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { - ICSState *ics = spapr->xics->ics; + ICSState *ics = QLIST_FIRST(&spapr->xics->ics);uint32_t nr; -if ((nargs !=1 ) || (nret !=3 )) { +if ((nargs !=1 ) || (nret !=3 ) || !ics) {rtas_st (rets,0 ,RTAS_OUT_PARAM_ERROR );return ; }@@ -164,10 +164,10 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { - ICSState *ics = spapr->xics->ics; + ICSState *ics = QLIST_FIRST(&spapr->xics->ics);uint32_t nr; -if ((nargs !=1 ) || (nret !=1 )) { +if ((nargs !=1 ) || (nret !=1 ) || !ics) {rtas_st (rets,0 ,RTAS_OUT_PARAM_ERROR );return ; }@@ -190,10 +190,10 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { - ICSState *ics = spapr->xics->ics; + ICSState *ics = QLIST_FIRST(&spapr->xics->ics);uint32_t nr; -if ((nargs !=1 ) || (nret !=1 )) { +if ((nargs !=1 ) || (nret !=1 ) || !ics) {rtas_st (rets,0 ,RTAS_OUT_PARAM_ERROR );return ; }@@ -215,6 +215,7 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,static void xics_spapr_realize (DeviceState *dev,Error **errp) {XICSState *xics =XICS (dev); +ICSState *ics;Error *error =NULL ;int i;@@ -236,10 +237,12 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)spapr_register_hypercall (H_EOI , h_eoi);spapr_register_hypercall (H_IPOLL , h_ipoll); -object_property_set_bool (OBJECT (xics->ics), true,"realized" , &error); -if (error) { -error_propagate (errp, error); -return ; + QLIST_FOREACH(ics, &xics->ics, list) { +object_property_set_bool (OBJECT (ics), true,"realized" , &error); +if (error) { +error_propagate (errp, error); +return ; + } }for (i =0 ; i < xics->nr_servers; i++) {@@ -254,10 +257,14 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)static void xics_spapr_initfn (Object *obj) {XICSState *xics =XICS (obj); +ICSState *ics; + +QLIST_INIT (&xics->ics); - xics->ics =ICS (object_new (TYPE_ICS )); -object_property_add_child (obj,"ics" ,OBJECT (xics->ics),NULL ); - xics->ics->xics = xics; + ics =ICS (object_new (TYPE_ICS )); +object_property_add_child (obj,"ics" ,OBJECT (ics),NULL ); + ics->xics = xics; +QLIST_INSERT_HEAD (&xics->ics, ics, list); }static void xics_spapr_class_init (ObjectClass *oc,void *data)@@ -303,29 +310,31 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum)return -1 ; } -int xics_spapr_alloc (XICSState *xics,int src,int irq_hint,bool lsi) +int xics_spapr_alloc (XICSState *xics,int irq_hint,bool lsi) { -ICSState *ics = &xics->ics[src]; +ICSState *ics =QLIST_FIRST (&xics->ics);int irq; +if (!ics) { +return -1 ; + }if (irq_hint) { -assert (src ==xics_find_source (xics, irq_hint));if (!ICS_IRQ_FREE (ics, irq_hint - ics->offset)) { -trace_xics_alloc_failed_hint (src, irq_hint); +trace_xics_alloc_failed_hint (0 , irq_hint);return -1 ; } irq = irq_hint; }else { irq =ics_find_free_block (ics,1 ,1 );if (irq <0 ) {
hw/intc/xics_spapr.c static int ics_find_free_block(ICSState *ics, int num, int alignnum) · line 337
Quoted 10 lines
hw/intc/xics_spapr.c +2
-2-trace_xics_alloc_failed_no_left (src); +trace_xics_alloc_failed_no_left (0 );return -1 ; } irq += ics->offset; }ics_set_irq_type (ics, irq - ics->offset, lsi); -trace_xics_alloc (src, irq); +trace_xics_alloc (0 , irq);
Actually we should really deprecate xics_spapr_alloc(). I hadn't realised it at the time, but dynamically allocating resources like this is a PITA for migration and cross-version compatibility. So we should avoid it, instead having the caller explicitly assign numbers based on explicit parameters.
Quoted 120 lines
hw/intc/xics_spapr.c +11
-13return irq; }@@ -334,12 +343,15 @@ int xics_spapr_alloc(XICSState *xics, int src, int irq_hint, bool lsi)* Allocate block of consecutive IRQs, and return the number of the first IRQ in the block. * If align==true, aligns the first IRQ number to num. */ -int xics_spapr_alloc_block (XICSState *xics,int src,int num,bool lsi,bool align) +int xics_spapr_alloc_block (XICSState *xics,int num,bool lsi,bool align) { +ICSState *ics =QLIST_FIRST (&xics->ics);int i, first =-1 ; -ICSState *ics = &xics->ics[src]; -assert (src ==0 ); +if (!ics) { +return -1 ; + } +/* * MSIMesage::data is used for storing VIRQ so * it has to be aligned to num to support multiple @@ -362,7 +374,7 @@ int xics_spapr_alloc_block(XICSState *xics, int src, int num, bool lsi, bool ali } first += ics->offset; -trace_xics_alloc_block (src, first, num, lsi, align); +trace_xics_alloc_block (0 , first, num, lsi, align);return first; }@@ -373,7 +385,7 @@ static void ics_free(ICSState *ics, int srcno, int num)for (i = srcno; i < srcno + num; ++i) {if (ICS_IRQ_FREE (ics, i)) { -trace_xics_ics_free_warn (ics - ics->xics->ics, i + ics->offset); +trace_xics_ics_free_warn (0 , i + ics->offset); }memset (&ics->irqs[i],0 ,sizeof (ICSIRQState)); }@@ -381,15 +393,10 @@ static void ics_free(ICSState *ics, int srcno, int num)void xics_spapr_free (XICSState *xics,int irq,int num) { -int src =xics_find_source (xics, irq); - -if (src >=0 ) { -ICSState *ics = &xics->ics[src]; - -/* FIXME: implement multiple sources */ -assert (src ==0 ); +ICSState *ics =xics_find_source (xics, irq); -trace_xics_ics_free (ics - xics->ics, irq, num); +if (ics) { +trace_xics_ics_free (0 , irq, num);ics_free (ics, irq - ics->offset, num); } }hw/ppc/spapr_events.c +1
-1@@ -587,7 +587,7 @@ out_no_events:void spapr_events_init (sPAPRMachineState *spapr) {QTAILQ_INIT (&spapr->pending_events); - spapr->check_exception_irq =xics_spapr_alloc (spapr->xics,0 ,0 , false); + spapr->check_exception_irq =xics_spapr_alloc (spapr->xics,0 , false); spapr->epow_notifier.notify = spapr_powerdown_req;qemu_register_powerdown_notifier (&spapr->epow_notifier); spapr_rtas_register(RTAS_CHECK_EXCEPTION, "check-exception",hw/ppc/spapr_pci.c +2
-2@@ -351,7 +351,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, }/* Allocate MSIs */ - irq =xics_spapr_alloc_block (spapr->xics,0 , req_num, false, + irq =xics_spapr_alloc_block (spapr->xics, req_num, false, ret_intr_type ==RTAS_TYPE_MSI );if (!irq) {error_report ("Cannot allocate MSIs for device %x" , config_addr);@@ -1360,7 +1360,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)for (i =0 ; i <PCI_NUM_PINS ; i++) {uint32_t irq; - irq =xics_spapr_alloc_block (spapr->xics,0 ,1 , true, false); + irq =xics_spapr_alloc_block (spapr->xics,1 , true, false);if (!irq) {error_setg (errp,"spapr_allocate_lsi failed" );return ;hw/ppc/spapr_vio.c +1
-1@@ -462,7 +462,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp) dev->qdev.id = id; } - dev->irq =xics_spapr_alloc (spapr->xics,0 , dev->irq, false); + dev->irq =xics_spapr_alloc (spapr->xics, dev->irq, false);if (!dev->irq) {error_setg (errp,"can't allocate IRQ" );return ;include/hw/ppc/xics.h +1
-1@@ -79,7 +79,7 @@ struct XICSState {uint32_t nr_servers;uint32_t nr_irqs;ICPState *ss; -ICSState *ics; + QLIST_HEAD(, ICSState) ics; };#define TYPE_ICP "icp"
include/hw/ppc/xics.h struct ICPState { · line 108
Quoted 4 lines
include/hw/ppc/xics.h +1
-0@@ -105,6 +105,7 @@ struct ICPState {DeviceState parent_obj;/*< public >*/ CPUState *cs; +ICSState *xirr_owner;
Currently xirr_owner will be lost across migration, which will break things.
Am I right in thinking that it's basically an optimization, and could be reconstructed from the XISR value and list of ICS ranges? If so we can do that easily enough in a post_load function.
Quoted 30 lines
include/hw/ppc/xics.h +4
-3uint32_t xirr;uint8_t pending_priority;uint8_t mfrr;@@ -139,6 +140,7 @@ struct ICSState {qemu_irq *qirqs;ICSIRQState *irqs;XICSState *xics; +QLIST_ENTRY (ICSState) list; };static inline bool ics_valid_irq (ICSState *ics,uint32_t nr)@@ -167,8 +169,8 @@ struct ICSIRQState {qemu_irq xics_get_qirq (XICSState *icp,int irq); -int xics_spapr_alloc (XICSState *icp,int src,int irq_hint,bool lsi); -int xics_spapr_alloc_block (XICSState *icp,int src,int num,bool lsi,bool align); +int xics_spapr_alloc (XICSState *icp,int irq_hint,bool lsi); +int xics_spapr_alloc_block (XICSState *icp,int num,bool lsi,bool align);void xics_spapr_free (XICSState *icp,int irq,int num);void xics_cpu_setup (XICSState *icp,PowerPCCPU *cpu);@@ -189,6 +191,6 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);void xics_set_nr_irqs (XICSState *icp,uint32_t nr_irqs,Error **errp);void xics_set_nr_servers (XICSState *icp,uint32_t nr_servers,Error **errp); -int xics_find_source (XICSState *icp,int irq); +ICSState *xics_find_source (XICSState *icp,int irq);#endif /* __XICS_H__ */
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH 34/77 ppc/xics: An ICS with offset 0 is assumed to be uninitialized
In reply to Benjamin HerrenschmidtThis will make life easier for dealing with dynamically configured ICSes such as PHB3
--- include/hw/ppc/xics.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/hw/ppc/xics.h +1 -1
@@ -145,7 +145,7 @@ struct ICSState {static inline bool ics_valid_irq (ICSState *ics,uint32_t nr) { -return (nr >= ics->offset) +return (ics->offset !=0 ) && (nr >= ics->offset) && (nr < (ics->offset + ics->nr_irqs)); }
Signature · 1 line
2.5.0
Re: [Qemu-devel] [Qemu-ppc] [PATCH 34/77] ppc/xics: An ICS with offset 0 is assumed to be uninitialized
Quoted 4 lines · Benjamin Herrenschmidt
This will make life easier for dealing with dynamically configured ICSes such as PHB3
Signed-off-by Benjamin Herrenschmidt <[email protected]>
Quoted 17 lines
--- include/hw/ppc/xics.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)include/hw/ppc/xics.h +1
-1@@ -145,7 +145,7 @@ struct ICSState {static inline bool ics_valid_irq (ICSState *ics,uint32_t nr) { -return (nr >= ics->offset) +return (ics->offset !=0 ) && (nr >= ics->offset) && (nr < (ics->offset + ics->nr_irqs)); }
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH 35/77 ppc/xics: Move xics_set_nr_irqs() to xics_spapr.c and xics_kvm.c
In reply to Benjamin HerrenschmidtIt will not be used by the native implementation. This allows us to also remove the include of spapr.h from the common code
--- hw/intc/xics.c | 12 ------------ hw/intc/xics_kvm.c | 13 ++++++++++++- hw/intc/xics_spapr.c | 13 ++++++++++++- include/hw/ppc/xics.h | 1 - 4 files changed, 24 insertions(+), 15 deletions(-)
hw/intc/xics.c +0 -12
@@ -28,7 +28,6 @@#include "hw/hw.h" #include "trace.h" #include "qemu/timer.h" -#include "hw/ppc/spapr.h" #include "hw/ppc/xics.h" #include "qemu/error-report.h" #include "qapi/visitor.h"
@@ -694,17 +693,6 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)* XICS */ -void xics_set_nr_irqs (XICSState *xics,uint32_t nr_irqs,Error **errp) -{ -ICSState *ics =QLIST_FIRST (&xics->ics); - -/* This needs to be deprecated ... */ - xics->nr_irqs = nr_irqs; -if (ics) { - ics->nr_irqs = nr_irqs; - } -} -void xics_set_nr_servers (XICSState *xics,uint32_t nr_servers,Error **errp) {int i;
hw/intc/xics_kvm.c +12 -1
@@ -468,6 +468,17 @@ fail:kvmppc_define_rtas_kernel_token (0 ,"ibm,int-off" ); } +static void xics_kvm_set_nr_irqs (XICSState *xics,uint32_t nr_irqs,Error **errp) +{ +ICSState *ics =QLIST_FIRST (&xics->ics); + +/* This needs to be deprecated ... */ + xics->nr_irqs = nr_irqs; +if (ics) { + ics->nr_irqs = nr_irqs; + } +} +static void xics_kvm_initfn (Object *obj) {XICSState *xics =XICS_COMMON (obj);
@@ -488,7 +499,7 @@ static void xics_kvm_class_init(ObjectClass *oc, void *data) dc->realize = xics_kvm_realize; xsc->cpu_setup = xics_kvm_cpu_setup; - xsc->set_nr_irqs = xics_set_nr_irqs; + xsc->set_nr_irqs = xics_kvm_set_nr_irqs; xsc->set_nr_servers = xics_kvm_set_nr_servers; }
hw/intc/xics_spapr.c +12 -1
@@ -267,13 +267,24 @@ static void xics_spapr_initfn(Object *obj)QLIST_INSERT_HEAD (&xics->ics, ics, list); } +static void xics_spapr_set_nr_irqs (XICSState *xics,uint32_t nr_irqs,Error **errp) +{ +ICSState *ics =QLIST_FIRST (&xics->ics); + +/* This needs to be deprecated ... */ + xics->nr_irqs = nr_irqs; +if (ics) { + ics->nr_irqs = nr_irqs; + } +} +static void xics_spapr_class_init (ObjectClass *oc,void *data) {DeviceClass *dc =DEVICE_CLASS (oc);XICSStateClass *xsc =XICS_SPAPR_CLASS (oc); dc->realize = xics_spapr_realize; - xsc->set_nr_irqs = xics_set_nr_irqs; + xsc->set_nr_irqs = xics_spapr_set_nr_irqs; xsc->set_nr_servers = xics_set_nr_servers; }
include/hw/ppc/xics.h +0 -1
@@ -189,7 +189,6 @@ void ics_write_xive(ICSState *ics, int nr, int server,void ics_set_irq_type (ICSState *ics,int srcno,bool lsi); -void xics_set_nr_irqs (XICSState *icp,uint32_t nr_irqs,Error **errp);void xics_set_nr_servers (XICSState *icp,uint32_t nr_servers,Error **errp);ICSState *xics_find_source (XICSState *icp,int irq);
Signature · 1 line
2.5.0
Re: [Qemu-devel] [Qemu-ppc] [PATCH 35/77] ppc/xics: Move xics_set_nr_irqs() to xics_spapr.c and xics_kvm.c
Quoted 50 lines · Benjamin Herrenschmidt
It will not be used by the native implementation. This allows us to also remove the include of
spapr.hfrom the common codeSigned-off-by Benjamin Herrenschmidt <[email protected]>--- hw/intc/xics.c | 12 ------------ hw/intc/xics_kvm.c | 13 ++++++++++++- hw/intc/xics_spapr.c | 13 ++++++++++++- include/hw/ppc/xics.h | 1 - 4 files changed, 24 insertions(+), 15 deletions(-)hw/intc/xics.c +0
-12@@ -28,7 +28,6 @@#include "hw/hw.h" #include "trace.h" #include "qemu/timer.h" -#include "hw/ppc/spapr.h" #include "hw/ppc/xics.h" #include "qemu/error-report.h" #include "qapi/visitor.h" @@ -694,17 +693,6 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)* XICS */ -void xics_set_nr_irqs (XICSState *xics,uint32_t nr_irqs,Error **errp) -{ -ICSState *ics =QLIST_FIRST (&xics->ics); - -/* This needs to be deprecated ... */ - xics->nr_irqs = nr_irqs; -if (ics) { - ics->nr_irqs = nr_irqs; - } -} -void xics_set_nr_servers (XICSState *xics,uint32_t nr_servers,Error **errp) {int i;hw/intc/xics_kvm.c +1
-0@@ -468,6 +468,17 @@ fail:kvmppc_define_rtas_kernel_token (0 ,"ibm,int-off" ); } +static void xics_kvm_set_nr_irqs (XICSState *xics,uint32_t nr_irqs,Error **errp)
hw/intc/xics_kvm.c fail: · line 481
Quoted 10 lines
hw/intc/xics_kvm.c +10
-0+{ +ICSState *ics =QLIST_FIRST (&xics->ics); + +/* This needs to be deprecated ... */ + xics->nr_irqs = nr_irqs; +if (ics) { + ics->nr_irqs = nr_irqs; + } +} +
Looks like you have a bit of unnecessary churn here, since you unified xics_kvm_set_nr_irqs() with xics_set_nr_irqs() earlier in the series only to split them again here.
Quoted 54 lines
hw/intc/xics_kvm.c +1
-1static void xics_kvm_initfn (Object *obj) {XICSState *xics =XICS_COMMON (obj);@@ -488,7 +499,7 @@ static void xics_kvm_class_init(ObjectClass *oc, void *data) dc->realize = xics_kvm_realize; xsc->cpu_setup = xics_kvm_cpu_setup; - xsc->set_nr_irqs = xics_set_nr_irqs; + xsc->set_nr_irqs = xics_kvm_set_nr_irqs; xsc->set_nr_servers = xics_kvm_set_nr_servers; }hw/intc/xics_spapr.c +12
-1@@ -267,13 +267,24 @@ static void xics_spapr_initfn(Object *obj)QLIST_INSERT_HEAD (&xics->ics, ics, list); } +static void xics_spapr_set_nr_irqs (XICSState *xics,uint32_t nr_irqs,Error **errp) +{ +ICSState *ics =QLIST_FIRST (&xics->ics); + +/* This needs to be deprecated ... */ + xics->nr_irqs = nr_irqs; +if (ics) { + ics->nr_irqs = nr_irqs; + } +} +static void xics_spapr_class_init (ObjectClass *oc,void *data) {DeviceClass *dc =DEVICE_CLASS (oc);XICSStateClass *xsc =XICS_SPAPR_CLASS (oc); dc->realize = xics_spapr_realize; - xsc->set_nr_irqs = xics_set_nr_irqs; + xsc->set_nr_irqs = xics_spapr_set_nr_irqs; xsc->set_nr_servers = xics_set_nr_servers; }include/hw/ppc/xics.h +0
-1@@ -189,7 +189,6 @@ void ics_write_xive(ICSState *ics, int nr, int server,void ics_set_irq_type (ICSState *ics,int srcno,bool lsi); -void xics_set_nr_irqs (XICSState *icp,uint32_t nr_irqs,Error **errp);void xics_set_nr_servers (XICSState *icp,uint32_t nr_servers,Error **errp);ICSState *xics_find_source (XICSState *icp,int irq);
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH 36/77 ppc/xics: Use a helper to add a new ICS
In reply to Benjamin Herrenschmidt--- hw/intc/xics.c | 6 ++++++ hw/intc/xics_spapr.c | 3 +-- include/hw/ppc/xics.h | 1 + 3 files changed, 8 insertions(+), 2 deletions(-)
hw/intc/xics.c +6 -0
@@ -90,6 +90,12 @@ static void xics_common_reset(DeviceState *d) } } +void xics_add_ics (XICSState *xics,ICSState *ics) +{ + ics->xics = xics; +QLIST_INSERT_HEAD (&xics->ics, ics, list); +} +static void xics_prop_get_nr_irqs (Object *obj,Visitor *v,void *opaque,const char *name,Error **errp) {
hw/intc/xics_spapr.c +1 -2
@@ -263,8 +263,7 @@ static void xics_spapr_initfn(Object *obj) ics =ICS (object_new (TYPE_ICS ));object_property_add_child (obj,"ics" ,OBJECT (ics),NULL ); - ics->xics = xics; -QLIST_INSERT_HEAD (&xics->ics, ics, list); +xics_add_ics (xics, ics); }static void xics_spapr_set_nr_irqs (XICSState *xics,uint32_t nr_irqs,Error **errp)
include/hw/ppc/xics.h +1 -0
@@ -191,5 +191,6 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);void xics_set_nr_servers (XICSState *icp,uint32_t nr_servers,Error **errp);ICSState *xics_find_source (XICSState *icp,int irq); +void xics_add_ics (XICSState *xics,ICSState *ics);#endif /* __XICS_H__ */
Signature · 1 line
2.5.0
Re: [Qemu-devel] [Qemu-ppc] [PATCH 36/77] ppc/xics: Use a helper to add a new ICS
Quoted 1 line · Benjamin Herrenschmidt
Signed-off-by Benjamin Herrenschmidt <[email protected]>
Hmm.. does it make sense for the helper to do the object_new() and add_child() as well?
Quoted 48 lines
--- hw/intc/xics.c | 6 ++++++ hw/intc/xics_spapr.c | 3 +-- include/hw/ppc/xics.h | 1 + 3 files changed, 8 insertions(+), 2 deletions(-)hw/intc/xics.c +6
-0@@ -90,6 +90,12 @@ static void xics_common_reset(DeviceState *d) } } +void xics_add_ics (XICSState *xics,ICSState *ics) +{ + ics->xics = xics; +QLIST_INSERT_HEAD (&xics->ics, ics, list); +} +static void xics_prop_get_nr_irqs (Object *obj,Visitor *v,void *opaque,const char *name,Error **errp) {hw/intc/xics_spapr.c +1
-2@@ -263,8 +263,7 @@ static void xics_spapr_initfn(Object *obj) ics =ICS (object_new (TYPE_ICS ));object_property_add_child (obj,"ics" ,OBJECT (ics),NULL ); - ics->xics = xics; -QLIST_INSERT_HEAD (&xics->ics, ics, list); +xics_add_ics (xics, ics); }static void xics_spapr_set_nr_irqs (XICSState *xics,uint32_t nr_irqs,Error **errp)include/hw/ppc/xics.h +1
-0@@ -191,5 +191,6 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);void xics_set_nr_servers (XICSState *icp,uint32_t nr_servers,Error **errp);ICSState *xics_find_source (XICSState *icp,int irq); +void xics_add_ics (XICSState *xics,ICSState *ics);#endif /* __XICS_H__ */
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH 37/77 ppc/xics: Split ICS into base class and "simple" implementation
In reply to Benjamin HerrenschmidtThe existing implementation becomes the "ics-simple" subclass of ICS, so there should be no change in behaviour for SPAPR.
This will allow different implementations for the source controllers such as the MSI support of PHB3 on Power8 which uses in-memory state tables for example.
--- hw/intc/xics.c | 123 ++++++++++++++++++++++++++++++++------------------ hw/intc/xics_kvm.c | 2 +- hw/intc/xics_spapr.c | 34 ++++++++------ include/hw/ppc/xics.h | 12 +++-- 4 files changed, 108 insertions(+), 63 deletions(-)
hw/intc/xics.c +79 -44
@@ -198,9 +198,32 @@ static const TypeInfo xics_common_info = {#define XISR (ss) (((ss)->xirr) & XISR_MASK)#define CPPR (ss) (((ss)->xirr) >> 24) -static void ics_reject (ICSState *ics,int nr); -static void ics_resend (ICSState *ics); -static void ics_eoi (ICSState *ics,int nr); +static void ics_reject (ICSState *ics,uint32_t nr) +{ +ICSStateClass *k =ICS_GET_CLASS (ics); + +if (k->reject) { + k->reject (ics, nr); + } +} + +static void ics_resend (ICSState *ics) +{ +ICSStateClass *k =ICS_GET_CLASS (ics); + +if (k->resend) { + k->resend (ics); + } +} + +static void ics_eoi (ICSState *ics,int nr) +{ +ICSStateClass *k =ICS_GET_CLASS (ics); + +if (k->eoi) { + k->eoi (ics, nr); + } +}static void icp_check_ipi (ICPState *ss,int server) {
@@ -403,7 +426,7 @@ static const TypeInfo icp_info = {/* * ICS: Source layer */ -static void resend_msi (ICSState *ics,int srcno) +static void ics_simple_resend_msi (ICSState *ics,int srcno) {ICSIRQState *irq = ics->irqs + srcno;
@@ -416,7 +439,7 @@ static void resend_msi(ICSState *ics, int srcno) } } -static void resend_lsi (ICSState *ics,int srcno) +static void ics_simple_resend_lsi (ICSState *ics,int srcno) {ICSIRQState *irq = ics->irqs + srcno;
@@ -428,7 +451,7 @@ static void resend_lsi(ICSState *ics, int srcno) } } -static void set_irq_msi (ICSState *ics,int srcno,int val) +static void ics_simple_set_irq_msi (ICSState *ics,int srcno,int val) {ICSIRQState *irq = ics->irqs + srcno;
@@ -444,7 +467,7 @@ static void set_irq_msi(ICSState *ics, int srcno, int val) } } -static void set_irq_lsi (ICSState *ics,int srcno,int val) +static void ics_simple_set_irq_lsi (ICSState *ics,int srcno,int val) {ICSIRQState *irq = ics->irqs + srcno;
@@ -454,21 +477,21 @@ static void set_irq_lsi(ICSState *ics, int srcno, int val) }else { irq->status &= ~XICS_STATUS_ASSERTED ; } -resend_lsi (ics, srcno); +ics_simple_resend_lsi (ics, srcno); } -static void ics_set_irq (void *opaque,int srcno,int val) +static void ics_simple_set_irq (void *opaque,int srcno,int val) {ICSState *ics = (ICSState *)opaque;if (ics->irqs[srcno].flags &XICS_FLAGS_IRQ_LSI ) { -set_irq_lsi (ics, srcno, val); +ics_simple_set_irq_lsi (ics, srcno, val); }else { -set_irq_msi (ics, srcno, val); +ics_simple_set_irq_msi (ics, srcno, val); } } -static void write_xive_msi (ICSState *ics,int srcno) +static void ics_simple_write_xive_msi (ICSState *ics,int srcno) {ICSIRQState *irq = ics->irqs + srcno;
@@ -481,31 +504,30 @@ static void write_xive_msi(ICSState *ics, int srcno)icp_irq (ics, irq->server, srcno + ics->offset, irq->priority); } -static void write_xive_lsi (ICSState *ics,int srcno) +static void ics_simple_write_xive_lsi (ICSState *ics,int srcno) { -resend_lsi (ics, srcno); +ics_simple_resend_lsi (ics, srcno); } -void ics_write_xive (ICSState *ics,int nr,int server, -uint8_t priority,uint8_t saved_priority) +void ics_simple_write_xive (ICSState *ics,int srcno,int server, +uint8_t priority,uint8_t saved_priority) { -int srcno = nr - ics->offset;ICSIRQState *irq = ics->irqs + srcno; irq->server = server; irq->priority = priority; irq->saved_priority = saved_priority; -trace_xics_ics_write_xive (nr, srcno, server, priority); +trace_xics_ics_write_xive (ics->offset + srcno, srcno, server, priority);if (ics->irqs[srcno].flags &XICS_FLAGS_IRQ_LSI ) { -write_xive_lsi (ics, srcno); +ics_simple_write_xive_lsi (ics, srcno); }else { -write_xive_msi (ics, srcno); +ics_simple_write_xive_msi (ics, srcno); } } -static void ics_reject (ICSState *ics,int nr) +static void ics_simple_reject (ICSState *ics,uint32_t nr) {ICSIRQState *irq = ics->irqs + nr - ics->offset;
@@ -514,21 +536,21 @@ static void ics_reject(ICSState *ics, int nr) irq->status &= ~XICS_STATUS_SENT ;/* Irrelevant but harmless for MSI */ } -static void ics_resend (ICSState *ics) +static void ics_simple_resend (ICSState *ics) {int i;for (i =0 ; i < ics->nr_irqs; i++) {/* FIXME: filter by server#? */ if (ics->irqs[i].flags &XICS_FLAGS_IRQ_LSI ) { -resend_lsi (ics, i); +ics_simple_resend_lsi (ics, i); }else { -resend_msi (ics, i); +ics_simple_resend_msi (ics, i); } } } -static void ics_eoi (ICSState *ics,int nr) +static void ics_simple_eoi (ICSState *ics,uint32_t nr) {int srcno = nr - ics->offset;ICSIRQState *irq = ics->irqs + srcno;
@@ -540,9 +562,9 @@ static void ics_eoi(ICSState *ics, int nr) } } -static void ics_reset (DeviceState *dev) +static void ics_simple_reset (DeviceState *dev) { -ICSState *ics =ICS (dev); +ICSState *ics =ICS_SIMPLE (dev);int i;uint8_t flags[ics->nr_irqs];
@@ -559,7 +581,7 @@ static void ics_reset(DeviceState *dev) } } -static int ics_post_load (ICSState *ics,int version_id) +static int ics_simple_post_load (ICSState *ics,int version_id) {int i;
@@ -592,7 +614,7 @@ static int ics_dispatch_post_load(void *opaque, int version_id)return 0 ; } -static const VMStateDescription vmstate_ics_irq = { +static const VMStateDescription vmstate_ics_simple_irq = { .name ="ics/irq" , .version_id =2 , .minimum_version_id =1 ,
@@ -606,7 +628,7 @@ static const VMStateDescription vmstate_ics_irq = { }, }; -static const VMStateDescription vmstate_ics = { +static const VMStateDescription vmstate_ics_simple = { .name ="ics" , .version_id =1 , .minimum_version_id =1 ,
@@ -617,48 +639,60 @@ static const VMStateDescription vmstate_ics = { VMSTATE_UINT32_EQUAL(nr_irqs, ICSState), VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs, - vmstate_ics_irq, ICSIRQState), + vmstate_ics_simple_irq, + ICSIRQState),VMSTATE_END_OF_LIST () }, }; -static void ics_initfn (Object *obj) +static void ics_simple_initfn (Object *obj) { -ICSState *ics =ICS (obj); +ICSState *ics =ICS_SIMPLE (obj); ics->offset =XICS_IRQ_BASE ; } -static void ics_realize (DeviceState *dev,Error **errp) +static void ics_simple_realize (DeviceState *dev,Error **errp) { -ICSState *ics =ICS (dev); +ICSState *ics =ICS_SIMPLE (dev);if (!ics->nr_irqs) {error_setg (errp,"Number of interrupts needs to be greater 0" );return ; } ics->irqs =g_malloc0 (ics->nr_irqs *sizeof (ICSIRQState)); - ics->qirqs =qemu_allocate_irqs (ics_set_irq, ics, ics->nr_irqs); + ics->qirqs =qemu_allocate_irqs (ics_simple_set_irq, ics, ics->nr_irqs); } -static void ics_class_init (ObjectClass *klass,void *data) +static void ics_simple_class_init (ObjectClass *klass,void *data) {DeviceClass *dc =DEVICE_CLASS (klass);ICSStateClass *isc =ICS_CLASS (klass); - dc->realize = ics_realize; - dc->vmsd = &vmstate_ics; - dc->reset = ics_reset; - isc->post_load = ics_post_load; + dc->realize = ics_simple_realize; + dc->vmsd = &vmstate_ics_simple; + dc->reset = ics_simple_reset; + isc->post_load = ics_simple_post_load; + isc->reject = ics_simple_reject; + isc->resend = ics_simple_resend; + isc->eoi = ics_simple_eoi; } +static const TypeInfo ics_simple_info = { + .name =TYPE_ICS_SIMPLE , + .parent =TYPE_ICS , + .instance_size =sizeof (ICSState), + .class_init = ics_simple_class_init, + .class_size =sizeof (ICSStateClass), + .instance_init = ics_simple_initfn, +}; +static const TypeInfo ics_info = { .name =TYPE_ICS , .parent =TYPE_DEVICE , + .abstract = true, .instance_size =sizeof (ICSState), - .class_init = ics_class_init, .class_size =sizeof (ICSStateClass), - .instance_init = ics_initfn, };/*
@@ -687,7 +721,7 @@ qemu_irq xics_get_qirq(XICSState *xics, int irq)return NULL ; } -void ics_set_irq_type (ICSState *ics,int srcno,bool lsi) +void ics_simple_set_irq_type (ICSState *ics,int srcno,bool lsi) {assert (!(ics->irqs[srcno].flags &XICS_FLAGS_IRQ_MASK ));
@@ -718,6 +752,7 @@ void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers, Error **errp)static void xics_register_types (void ) {type_register_static (&xics_common_info); +type_register_static (&ics_simple_info);type_register_static (&ics_info);type_register_static (&icp_info); }
hw/intc/xics_kvm.c +1 -1
@@ -309,7 +309,7 @@ static void ics_kvm_class_init(ObjectClass *klass, void *data)static const TypeInfo ics_kvm_info = { .name =TYPE_KVM_ICS , - .parent =TYPE_ICS , + .parent =TYPE_ICS_SIMPLE , .instance_size =sizeof (ICSState), .class_init = ics_kvm_class_init, };
hw/intc/xics_spapr.c +19 -15
@@ -112,7 +112,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t nret, target_ulong rets) {ICSState *ics =QLIST_FIRST (&spapr->xics->ics); -uint32_t nr, server, priority; +uint32_t nr, src_no, server, priority;if ((nargs !=3 ) || (nret !=1 ) || !ics) {rtas_st (rets,0 ,RTAS_OUT_PARAM_ERROR );
@@ -129,7 +129,8 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,return ; } -ics_write_xive (ics, nr, server, priority, priority); + src_no = nr - ics->offset; +ics_simple_write_xive (ics, src_no, server, priority, priority);rtas_st (rets,0 ,RTAS_OUT_SUCCESS ); }
@@ -140,7 +141,7 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t nret, target_ulong rets) {ICSState *ics =QLIST_FIRST (&spapr->xics->ics); -uint32_t nr; +uint32_t nr, src_no;if ((nargs !=1 ) || (nret !=3 ) || !ics) {rtas_st (rets,0 ,RTAS_OUT_PARAM_ERROR );
@@ -155,8 +156,9 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, }rtas_st (rets,0 ,RTAS_OUT_SUCCESS ); -rtas_st (rets,1 , ics->irqs[nr - ics->offset].server); -rtas_st (rets,2 , ics->irqs[nr - ics->offset].priority); + src_no = nr - ics->offset; +rtas_st (rets,1 , ics->irqs[src_no].server); +rtas_st (rets,2 , ics->irqs[src_no].priority); } static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
@@ -165,7 +167,7 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t nret, target_ulong rets) {ICSState *ics =QLIST_FIRST (&spapr->xics->ics); -uint32_t nr; +uint32_t nr, src_no;if ((nargs !=1 ) || (nret !=1 ) || !ics) {rtas_st (rets,0 ,RTAS_OUT_PARAM_ERROR );
@@ -179,8 +181,9 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,return ; } -ics_write_xive (ics, nr, ics->irqs[nr - ics->offset].server,0xff , - ics->irqs[nr - ics->offset].priority); + src_no = nr - ics->offset; +ics_simple_write_xive (ics, src_no, ics->irqs[src_no].server,0xff , + ics->irqs[src_no].priority);rtas_st (rets,0 ,RTAS_OUT_SUCCESS ); }
@@ -191,7 +194,7 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t nret, target_ulong rets) {ICSState *ics =QLIST_FIRST (&spapr->xics->ics); -uint32_t nr; +uint32_t nr, src_no;if ((nargs !=1 ) || (nret !=1 ) || !ics) {rtas_st (rets,0 ,RTAS_OUT_PARAM_ERROR );
@@ -205,9 +208,10 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,return ; } -ics_write_xive (ics, nr, ics->irqs[nr - ics->offset].server, - ics->irqs[nr - ics->offset].saved_priority, - ics->irqs[nr - ics->offset].saved_priority); + src_no = nr - ics->offset; +ics_simple_write_xive (ics, src_no, ics->irqs[src_no].server, + ics->irqs[src_no].saved_priority, + ics->irqs[src_no].saved_priority);rtas_st (rets,0 ,RTAS_OUT_SUCCESS ); }
@@ -261,7 +265,7 @@ static void xics_spapr_initfn(Object *obj)QLIST_INIT (&xics->ics); - ics =ICS (object_new (TYPE_ICS )); + ics =ICS (object_new (TYPE_ICS_SIMPLE ));object_property_add_child (obj,"ics" ,OBJECT (ics),NULL );xics_add_ics (xics, ics); }
@@ -343,7 +347,7 @@ int xics_spapr_alloc(XICSState *xics, int irq_hint, bool lsi) irq += ics->offset; } -ics_set_irq_type (ics, irq - ics->offset, lsi); +ics_simple_set_irq_type (ics, irq - ics->offset, lsi);trace_xics_alloc (0 , irq);return irq;
@@ -379,7 +383,7 @@ int xics_spapr_alloc_block(XICSState *xics, int num, bool lsi, bool align)if (first >=0 ) {for (i = first; i < first + num; ++i) { -ics_set_irq_type (ics, i, lsi); +ics_simple_set_irq_type (ics, i, lsi); } } first += ics->offset;
include/hw/ppc/xics.h +9 -3
@@ -116,6 +116,9 @@ struct ICPState {#define TYPE_ICS "ics"#define ICS (obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS) +#define TYPE_ICS_SIMPLE "ics-simple" +#define ICS_SIMPLE (obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SIMPLE) +#define TYPE_KVM_ICS "icskvm"#define KVM_ICS (obj) OBJECT_CHECK(ICSState, (obj), TYPE_KVM_ICS)
@@ -129,6 +132,9 @@ struct ICSStateClass {void (*pre_save)(ICSState *s);int (*post_load)(ICSState *s,int version_id); +void (*reject)(ICSState *s,uint32_t irq); +void (*resend)(ICSState *s); +void (*eoi)(ICSState *s,uint32_t irq); };struct ICSState {
@@ -184,10 +190,10 @@ uint32_t icp_accept(ICPState *ss);uint32_t icp_ipoll (ICPState *ss,uint32_t *mfrr);void icp_eoi (XICSState *icp,int server,uint32_t xirr); -void ics_write_xive (ICSState *ics,int nr,int server, -uint8_t priority,uint8_t saved_priority); +void ics_simple_write_xive (ICSState *ics,int nr,int server, +uint8_t priority,uint8_t saved_priority); -void ics_set_irq_type (ICSState *ics,int srcno,bool lsi); +void ics_simple_set_irq_type (ICSState *ics,int srcno,bool lsi);void xics_set_nr_servers (XICSState *icp,uint32_t nr_servers,Error **errp);ICSState *xics_find_source (XICSState *icp,int irq);
Signature · 1 line
2.5.0
Re: [Qemu-devel] [Qemu-ppc] [PATCH 37/77] ppc/xics: Split ICS into base class and "simple" implementation
Quoted 8 lines · Benjamin Herrenschmidt
The existing implementation becomes the "ics-simple" subclass of ICS, so there should be no change in behaviour for SPAPR.
This will allow different implementations for the source controllers such as the MSI support of PHB3 on Power8 which uses in-memory state tables for example.
Signed-off-by Benjamin Herrenschmidt <[email protected]>
[snip]
hw/intc/xics_spapr.c static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, · line 115
Quoted 10 lines
hw/intc/xics_spapr.c +1
-1@@ -112,7 +112,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t nret, target_ulong rets) {ICSState *ics =QLIST_FIRST (&spapr->xics->ics); -uint32_t nr, server, priority; +uint32_t nr, src_no, server, priority;
Nit: elsewhere I use srcno without a _ for this value.
[snip]
include/hw/ppc/xics.h struct ICPState { · line 120
Quoted 10 lines
include/hw/ppc/xics.h +2
-0@@ -116,6 +116,9 @@ struct ICPState {#define TYPE_ICS "ics"#define ICS (obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS) +#define TYPE_ICS_SIMPLE "ics-simple" +#define ICS_SIMPLE (obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SIMPLE)
Again, changing type names will break migration, I believe. So better to leave this as ics and add "ics-base" and "ics-native" or similar.
Quoted 28 lines
include/hw/ppc/xics.h +7
-3+#define TYPE_KVM_ICS "icskvm"#define KVM_ICS (obj) OBJECT_CHECK(ICSState, (obj), TYPE_KVM_ICS)@@ -129,6 +132,9 @@ struct ICSStateClass {void (*pre_save)(ICSState *s);int (*post_load)(ICSState *s,int version_id); +void (*reject)(ICSState *s,uint32_t irq); +void (*resend)(ICSState *s); +void (*eoi)(ICSState *s,uint32_t irq); };struct ICSState {@@ -184,10 +190,10 @@ uint32_t icp_accept(ICPState *ss);uint32_t icp_ipoll (ICPState *ss,uint32_t *mfrr);void icp_eoi (XICSState *icp,int server,uint32_t xirr); -void ics_write_xive (ICSState *ics,int nr,int server, -uint8_t priority,uint8_t saved_priority); +void ics_simple_write_xive (ICSState *ics,int nr,int server, +uint8_t priority,uint8_t saved_priority); -void ics_set_irq_type (ICSState *ics,int srcno,bool lsi); +void ics_simple_set_irq_type (ICSState *ics,int srcno,bool lsi);void xics_set_nr_servers (XICSState *icp,uint32_t nr_servers,Error **errp);ICSState *xics_find_source (XICSState *icp,int irq);
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH 38/77 ppc/xics: Add "native" XICS subclass
In reply to Benjamin HerrenschmidtThis provides MMIO based ICP access as found on POWER8
--- default-configs/ppc64-softmmu.mak | 3 +- hw/intc/Makefile.objs | 1 + hw/intc/xics_native.c | 294 ++++++++++++++++++++++++++++++++++++++ include/hw/ppc/xics.h | 14 ++ 4 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 hw/intc/xics_native.c
default-configs/ppc64-softmmu.mak +2 -1
@@ -49,8 +49,9 @@ CONFIG_PLATFORM_BUS=y CONFIG_ETSEC=y CONFIG_LIBDECNUMBER=y # For pSeries -CONFIG_XICS=$(CONFIG_PSERIES) +CONFIG_XICS=$(or $(CONFIG_PSERIES),$(CONFIG_POWERNV)) CONFIG_XICS_SPAPR=$(CONFIG_PSERIES) +CONFIG_XICS_NATIVE=$(CONFIG_POWERNV) CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM)) # For PReP CONFIG_MC146818RTC=y
hw/intc/Makefile.objs +1 -0
@@ -27,6 +27,7 @@ obj-$(CONFIG_OPENPIC_KVM) += openpic_kvm.o obj-$(CONFIG_SH4) += sh_intc.o obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_XICS_SPAPR) += xics_spapr.o +obj-$(CONFIG_XICS_NATIVE) += xics_native.o obj-$(CONFIG_XICS_KVM) += xics_kvm.o obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o obj-$(CONFIG_S390_FLIC) += s390_flic.o
hw/intc/xics_native.c new file +294 -0
294 lines not on this page · raw message
include/hw/ppc/xics.h +14 -0
@@ -38,6 +38,9 @@#define TYPE_XICS_SPAPR_KVM "xics-spapr-kvm"#define KVM_XICS (obj) OBJECT_CHECK(KVMXICSState, (obj), TYPE_XICS_SPAPR_KVM) +#define TYPE_XICS_NATIVE "xics-native" +#define XICS_NATIVE (obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_NATIVE) +#define XICS_COMMON_CLASS (klass) \ OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_COMMON)#define XICS_SPAPR_CLASS (klass) \
@@ -46,6 +49,8 @@ OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_COMMON)#define XICS_SPAPR_GET_CLASS (obj) \ OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_SPAPR) +#define XICS_NATIVE_CLASS (klass) \ + OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_NATIVE)#define XICS_IPI 0x2#define XICS_BUID 0x1
@@ -80,6 +85,7 @@ struct XICSState {uint32_t nr_irqs;ICPState *ss; QLIST_HEAD(, ICSState) ics; +MemoryRegion icp_mmio; };#define TYPE_ICP "icp"
@@ -111,8 +117,13 @@ struct ICPState {uint8_t mfrr;qemu_irq output;bool cap_irq_xics_enabled; +uint32_t links[3 ]; }; +/* This should be an XSCOM BAR ... the size is arbitrary as well */ +#define ICP_MM_BASE 0x0003FFFF80000000 +#define ICP_MM_SIZE 0x0000000010000000 +#define TYPE_ICS "ics"#define ICS (obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS)
@@ -181,6 +192,9 @@ void xics_spapr_free(XICSState *icp, int irq, int num);void xics_cpu_setup (XICSState *icp,PowerPCCPU *cpu); +void xics_create_native_icp_node (XICSState *s,void *fdt, +uint32_t base,uint32_t count); +/* Internal XICS interfaces */ int get_cpu_index_by_dt_id (int cpu_dt_id);
Signature · 1 line
2.5.0
Re: [Qemu-devel] [Qemu-ppc] [PATCH 38/77] ppc/xics: Add "native" XICS subclass
Quoted 1 line · Benjamin Herrenschmidt
This provides MMIO based ICP access as found on POWER8
Mostly looks sound.
I note that the links registers don't actually do anything at this point, I assume thats intentional. It probably deserves a comment somewhere (in the commit message at least).
Quoted 42 lines
Signed-off-by Benjamin Herrenschmidt <[email protected]>--- default-configs/ppc64-softmmu.mak | 3 +- hw/intc/Makefile.objs | 1 + hw/intc/xics_native.c | 294 ++++++++++++++++++++++++++++++++++++++ include/hw/ppc/xics.h | 14 ++ 4 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 hw/intc/xics_native.cdefault-configs/ppc64-softmmu.mak +2
-1@@ -49,8 +49,9 @@ CONFIG_PLATFORM_BUS=y CONFIG_ETSEC=y CONFIG_LIBDECNUMBER=y # For pSeries -CONFIG_XICS=$(CONFIG_PSERIES) +CONFIG_XICS=$(or $(CONFIG_PSERIES),$(CONFIG_POWERNV)) CONFIG_XICS_SPAPR=$(CONFIG_PSERIES) +CONFIG_XICS_NATIVE=$(CONFIG_POWERNV) CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM)) # For PReP CONFIG_MC146818RTC=yhw/intc/Makefile.objs +1
-0@@ -27,6 +27,7 @@ obj-$(CONFIG_OPENPIC_KVM) += openpic_kvm.o obj-$(CONFIG_SH4) += sh_intc.o obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_XICS_SPAPR) += xics_spapr.o +obj-$(CONFIG_XICS_NATIVE) += xics_native.o obj-$(CONFIG_XICS_KVM) += xics_kvm.o obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o obj-$(CONFIG_S390_FLIC) += s390_flic.ohw/intc/xics_native.c new file +0
-0
hw/intc/xics_native.c line 6
Quoted 6 lines
hw/intc/xics_native.c new file +6
-0@@ -0,0 +1,294 @@ +/* +* QEMU PowerPC hardware System Emulator +* +* Native version of ICS/ICP +* +* Copyright (c) 2010,2011 David Gibson, IBM Corporation.
It should probably have your copyright too; I'm pretty sure this is not all my code ;).
Quoted 244 lines
hw/intc/xics_native.c new file +244
-0+* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +*/ + +#include "hw/hw.h" +#include "trace.h" +#include "qemu/timer.h" +#include "hw/ppc/xics.h" +#include "qemu/error-report.h" +#include "qapi/visitor.h" + +#include <libfdt.h> + +//#define DEBUG_MM(fmt...) printf(fmt) +#define DEBUG_MM(fmt...) do { } while(0) + +static void xics_native_initfn (Object *obj) +{ +XICSState *xics =XICS_NATIVE (obj); + +QLIST_INIT (&xics->ics); +} + +static uint64_t icp_mm_read (void *opaque,hwaddr addr,unsigned width) +{ +XICSState *s = opaque; +int32_t cpu_id, server; +uint32_t val; +ICPState *ss; +bool byte0 = (width ==1 && (addr &0x3 ) ==0 ); + + cpu_id = (addr & (ICP_MM_SIZE -1 )) >>12 ; + server =get_cpu_index_by_dt_id (cpu_id); +if (server <0 ) { +fprintf (stderr,"XICS: Bad ICP server %d\n" , server); + goto bad_access; + } + ss = &s->ss[server]; + +switch (addr &0xffc ) { +case 0 :/* poll */ + val =icp_ipoll (ss,NULL ); +if (byte0) { + val >>=24 ; + }else if (width !=4 ) { + goto bad_access; + } +break ; +case 4 :/* xirr */ +if (byte0) { + val =icp_ipoll (ss,NULL ) >>24 ; + }else if (width ==4 ) { + val =icp_accept (ss); + }else { + goto bad_access; + } +break ; +case 12 : +if (byte0) { + val = ss->mfrr; + }else { + goto bad_access; + } +break ; +case 16 : +if (width ==4 ) { + val = ss->links[0 ]; + }else { + goto bad_access; + } +break ; +case 20 : +if (width ==4 ) { + val = ss->links[1 ]; + }else { + goto bad_access; + } +break ; +case 24 : +if (width ==4 ) { + val = ss->links[2 ]; + }else { + goto bad_access; + } +break ; +default : +bad_access: +fprintf (stderr,"XICS: Bad ICP access %llx/%d\n" , + (unsigned long long )addr, width); + val =0xffffffff ; + } +DEBUG_MM ("icp_mm_read(addr=%016llx,serv=0x%x/%d,off=%d,w=%d,val=0x%08x)\n" , + (unsigned long long )addr, cpu_id, server, (int )(addr &0xffc ), + width, val); + +return val; +} + +static void icp_mm_write (void *opaque,hwaddr addr,uint64_t val, +unsigned width) +{ +XICSState *s = opaque; +int32_t cpu_id, server; +ICPState *ss; +bool byte0 = (width ==1 && (addr &0x3 ) ==0 ); + + cpu_id = (addr & (ICP_MM_SIZE -1 )) >>12 ; + server =get_cpu_index_by_dt_id (cpu_id); +if (server <0 ) { +fprintf (stderr,"XICS: Bad ICP server %d\n" , server); + goto bad_access; + } + ss = &s->ss[server]; + +DEBUG_MM ("icp_mm_write(addr=%016llx,serv=0x%x/%d,off=%d,w=%d,val=0x%08x)\n" , + (unsigned long long )addr, cpu_id, server, + (int )(addr &0xffc ), width, (uint32_t )val); + +switch (addr &0xffc ) { +case 4 :/* xirr */ +if (byte0) { +icp_set_cppr (s, server, val); + }else if (width ==4 ) { +icp_eoi (s, server, val); + }else { + goto bad_access; + } +break ; +case 12 : +if (byte0) { +icp_set_mfrr (s, server, val); + }else { + goto bad_access; + } +break ; +case 16 : +if (width ==4 ) { + ss->links[0 ] = val; + }else { + goto bad_access; + } +break ; +case 20 : +if (width ==4 ) { + ss->links[1 ] = val; + }else { + goto bad_access; + } +break ; +case 24 : +if (width ==4 ) { + ss->links[2 ] = val; + }else { + goto bad_access; + } +break ; +default : + bad_access: + val =0xffffffff ; + } +} + +static const MemoryRegionOps icp_mm_ops = { + .read = icp_mm_read, + .write = icp_mm_write, + .valid.min_access_size =1 , + .valid.max_access_size =4 , + .impl.min_access_size =1 , + .impl.max_access_size =4 , + .endianness =DEVICE_BIG_ENDIAN , +}; + +#define _FDT (exp) \ + do { \ + int ret = (exp); \ + if (ret < 0) { \ + fprintf(stderr, "qemu: error creating device tree: %s: %s\n", \ + #exp, fdt_strerror(ret)); \ + exit(1); \ + } \ + } while (0) + +void xics_create_native_icp_node (XICSState *s,void *fdt, +uint32_t base,uint32_t count) +{ +uint64_t addr; +char *name; +const char compat[] ="IBM,power8-icp\0IBM,ppc-xicp" ; +uint32_t irange[2 ], i, rsize; +uint64_t *reg; + + addr =ICP_MM_BASE | (base <<12 ); + + irange[0 ] =cpu_to_be32 (base); + irange[1 ] =cpu_to_be32 (count); + + rsize =sizeof (uint64_t ) *2 * count; + reg =g_malloc (rsize); +for (i =0 ; i < count; i++) { + reg[i *2 ] =cpu_to_be64 (addr | ((base + i) *0x1000 )); + reg[i *2 +1 ] =cpu_to_be64 (0x1000 ); + } + + name =g_strdup_printf ("interrupt-controller@%" PRIX64 , addr); + +/* interrupt controller */ +_FDT ((fdt_begin_node (fdt, name))); +g_free (name); + +_FDT ((fdt_property (fdt,"compatible" , compat,sizeof (compat)))); +_FDT ((fdt_property (fdt,"reg" , reg, rsize))); +_FDT ((fdt_property_string (fdt,"device_type" , +"PowerPC-External-Interrupt-Presentation" ))); +_FDT ((fdt_property (fdt,"interrupt-controller" ,NULL ,0 ))); +_FDT ((fdt_property (fdt,"ibm,interrupt-server-ranges" , + irange,sizeof (irange)))); +_FDT ((fdt_property_cell (fdt,"#interrupt-cells" ,1 ))); +_FDT ((fdt_property_cell (fdt,"#address-cells" ,0 ))); +_FDT ((fdt_end_node (fdt))); +} + +static void xics_native_realize (DeviceState *dev,Error **errp) +{ +XICSState *s =XICS_NATIVE (dev); +SysBusDevice *sbd =SYS_BUS_DEVICE (dev); +Error *error =NULL ; +int i; +
hw/intc/xics_native.c line 261
Quoted 10 lines
hw/intc/xics_native.c new file +10
-0+if (!s->nr_servers) { +error_setg (errp,"Number of servers needs to be greater 0" ); +return ; + } + +/* Register MMIO regions */ +memory_region_init_io (&s->icp_mmio,OBJECT (s), &icp_mm_ops, s,"icp" , +ICP_MM_SIZE ); +sysbus_init_mmio (sbd, &s->icp_mmio); +sysbus_mmio_map (sbd,0 ,ICP_MM_BASE );
As a rule it's better to have MMIO addresses of things as a property and have the thing creating them assign it, rather than having the knowledge of the address internally.
Quoted 7 lines
hw/intc/xics_native.c new file +7
-0+ +for (i =0 ; i < s->nr_servers; i++) { +object_property_set_bool (OBJECT (&s->ss[i]), true,"realized" , &error); +if (error) { +error_propagate (errp, error); +return ; + }
hw/intc/xics_native.c line 278
Quoted 10 lines
hw/intc/xics_native.c new file +10
-0+ } +} + +static void xics_native_class_init (ObjectClass *oc,void *data) +{ +DeviceClass *dc =DEVICE_CLASS (oc); +XICSStateClass *xsc =XICS_NATIVE_CLASS (oc); + + dc->realize = xics_native_realize; + xsc->set_nr_servers = xics_set_nr_servers;
I thought you weren't going to be using the set_nr_servers stuff in the native mode xics?
Quoted 71 lines
hw/intc/xics_native.c new file +16
-0+} + +static const TypeInfo xics_native_info = { + .name =TYPE_XICS_NATIVE , + .parent =TYPE_XICS_COMMON , + .instance_size =sizeof (XICSState), + .class_size =sizeof (XICSStateClass), + .class_init = xics_native_class_init, + .instance_init = xics_native_initfn, +}; + +static void xics_native_register_types (void ) +{ +type_register_static (&xics_native_info); +} +type_init (xics_native_register_types)include/hw/ppc/xics.h +14
-0@@ -38,6 +38,9 @@#define TYPE_XICS_SPAPR_KVM "xics-spapr-kvm"#define KVM_XICS (obj) OBJECT_CHECK(KVMXICSState, (obj), TYPE_XICS_SPAPR_KVM) +#define TYPE_XICS_NATIVE "xics-native" +#define XICS_NATIVE (obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_NATIVE) +#define XICS_COMMON_CLASS (klass) \ OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_COMMON)#define XICS_SPAPR_CLASS (klass) \@@ -46,6 +49,8 @@ OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_COMMON)#define XICS_SPAPR_GET_CLASS (obj) \ OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_SPAPR) +#define XICS_NATIVE_CLASS (klass) \ + OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_NATIVE)#define XICS_IPI 0x2#define XICS_BUID 0x1@@ -80,6 +85,7 @@ struct XICSState {uint32_t nr_irqs;ICPState *ss; QLIST_HEAD(, ICSState) ics; +MemoryRegion icp_mmio; };#define TYPE_ICP "icp"@@ -111,8 +117,13 @@ struct ICPState {uint8_t mfrr;qemu_irq output;bool cap_irq_xics_enabled; +uint32_t links[3 ]; }; +/* This should be an XSCOM BAR ... the size is arbitrary as well */ +#define ICP_MM_BASE 0x0003FFFF80000000 +#define ICP_MM_SIZE 0x0000000010000000 +#define TYPE_ICS "ics"#define ICS (obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS)@@ -181,6 +192,9 @@ void xics_spapr_free(XICSState *icp, int irq, int num);void xics_cpu_setup (XICSState *icp,PowerPCCPU *cpu); +void xics_create_native_icp_node (XICSState *s,void *fdt, +uint32_t base,uint32_t count); +/* Internal XICS interfaces */ int get_cpu_index_by_dt_id (int cpu_dt_id);
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
Re: [Qemu-devel] [Qemu-ppc] [PATCH 38/77] ppc/xics: Add "native" XICS subclass
In reply to Benjamin HerrenschmidtQuoted 3 lines · Benjamin Herrenschmidt
This provides MMIO based ICP access as found on POWER8
Signed-off-by Benjamin Herrenschmidt <[email protected]>
[snip]
hw/intc/xics_native.c line 248
Quoted 4 lines
hw/intc/xics_native.c new file +4
-0+static void xics_native_realize (DeviceState *dev,Error **errp) +{ +XICSState *s =XICS_NATIVE (dev); +SysBusDevice *sbd =SYS_BUS_DEVICE (dev);
Ah.. here's another wrinkle. So the current XICS is defined as a SysBusDevice, but that's not actually correct because it doesn't have MMIO. But your xics native does have MMIO, so my understanding is that SysBusDevice is appropriate. Not sure how to handle that
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH 39/77 ppc/xics: Add xics to the monitor "info pic" command
In reply to Benjamin HerrenschmidtUseful to debug interrupt problems.
--- hmp-commands-info.hx | 2 ++ hw/intc/xics.c | 38 ++++++++++++++++++++++++++++++++++++++ hw/ppc/ppc.c | 14 ++++++++++++++ include/hw/ppc/ppc.h | 2 ++ include/hw/ppc/xics.h | 2 ++ monitor.c | 3 +++ 6 files changed, 61 insertions(+)
hmp-commands-info.hx +2 -0
@@ -203,6 +203,8 @@ ETEXI .mhandler.cmd = sun4m_hmp_info_pic, #elif defined(TARGET_LM32) .mhandler.cmd = lm32_hmp_info_pic, +#elif defined(TARGET_PPC) + .mhandler.cmd = ppc_hmp_info_pic, #else .mhandler.cmd = hmp_info_pic, #endif
hw/intc/xics.c +38 -0
@@ -31,6 +31,9 @@#include "hw/ppc/xics.h" #include "qemu/error-report.h" #include "qapi/visitor.h" +#include "monitor/monitor.h" + +static XICSState *g_xics;int get_cpu_index_by_dt_id (int cpu_dt_id) {
@@ -170,6 +173,9 @@ static void xics_common_initfn(Object *obj)object_property_add (obj,"nr_servers" ,"int" , xics_prop_get_nr_servers, xics_prop_set_nr_servers,NULL ,NULL ,NULL ); + +/* For exclusive use of monitor command */ + g_xics =XICS_COMMON (obj); }static void xics_common_class_init (ObjectClass *oc,void *data)
@@ -614,6 +620,38 @@ static int ics_dispatch_post_load(void *opaque, int version_id)return 0 ; } +void xics_hmp_info_pic (Monitor *mon,const QDict *qdict) +{ +ICSState *ics; +uint32_t i; + +for (i =0 ; i < g_xics->nr_servers; i++) { +ICPState *icp = &g_xics->ss[i]; + +if (!icp->output) { +continue ; + } +monitor_printf (mon,"CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n" , + i, icp->xirr, icp->xirr_owner, + icp->pending_priority, icp->mfrr); + } + QLIST_FOREACH(ics, &g_xics->ics, list) { +monitor_printf (mon,"ICS %4x..%4x %p\n" , + ics->offset, ics->offset + ics->nr_irqs -1 , ics); +for (i =0 ; i < ics->nr_irqs; i++) { +ICSIRQState *irq = ics->irqs + i; + +if (!(irq->flags &XICS_FLAGS_IRQ_MASK )) { +continue ; + } +monitor_printf (mon," %4x %s %02x %02x\n" , + ics->offset + i, + (irq->flags &XICS_FLAGS_IRQ_LSI ) ?"LSI" :"MSI" , + irq->priority, irq->status); + } + } +} +static const VMStateDescription vmstate_ics_simple_irq = { .name ="ics/irq" , .version_id =2 ,
hw/ppc/ppc.c +14 -0
@@ -24,6 +24,7 @@#include "hw/hw.h" #include "hw/ppc/ppc.h" #include "hw/ppc/ppc_e500.h" +#include "hw/i386/pc.h" #include "qemu/timer.h" #include "sysemu/sysemu.h" #include "sysemu/cpus.h"
@@ -35,6 +36,10 @@#include "kvm_ppc.h" #include "trace.h" +#if defined(TARGET_PPC64 ) +#include "hw/ppc/xics.h" +#endif +//#define PPC_DEBUG_IRQ //#define PPC_DEBUG_TB
@@ -1337,3 +1342,12 @@ PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)return NULL ; } + +void ppc_hmp_info_pic (Monitor *mon,const QDict *qdict) +{ +/* Call in turn every PIC around. OpenPIC doesn't have one yet */ +#ifdef TARGET_PPC64 +xics_hmp_info_pic (mon, qdict); +#endif +hmp_info_pic (mon, qdict); +}
include/hw/ppc/ppc.h +2 -0
@@ -1,6 +1,8 @@#ifndef HW_PPC_H #define HW_PPC_H 1 +void ppc_hmp_info_pic (Monitor *mon,const QDict *qdict); +void ppc_set_irq (PowerPCCPU *cpu,int n_IRQ,int level);/* PowerPC hardware exceptions management helpers */
include/hw/ppc/xics.h +2 -0
@@ -213,4 +213,6 @@ void xics_set_nr_servers(XICSState *icp, uint32_t nr_servers, Error **errp);ICSState *xics_find_source (XICSState *icp,int irq);void xics_add_ics (XICSState *xics,ICSState *ics); +void xics_hmp_info_pic (Monitor *mon,const QDict *qdict); +#endif /* __XICS_H__ */
monitor.c +3 -0
@@ -76,6 +76,9 @@#include "qapi-event.h" #include "qmp-introspect.h" #include "sysemu/block-backend.h" +#if defined(TARGET_PPC ) +#include "hw/ppc/ppc.h" +#endif /* for hmp_info_irq/pic */ #if defined(TARGET_SPARC )
Signature · 1 line
2.5.0
Re: [Qemu-devel] [Qemu-ppc] [PATCH 39/77] ppc/xics: Add xics to the monitor "info pic" command
Quoted 1 line · Benjamin Herrenschmidt
Useful to debug interrupt problems.
Ugh.. I can see the use of this, but we really want to just deprecate info pic entirely, it's an awful, awful interface.
I think the right way to do this is to allow some state introspection via the QOM interfaces on the xics devices themselves, but I'm not immediately sure how to go about that.
Quoted 161 lines
Signed-off-by Benjamin Herrenschmidt <[email protected]>--- hmp-commands-info.hx | 2 ++ hw/intc/xics.c | 38 ++++++++++++++++++++++++++++++++++++++ hw/ppc/ppc.c | 14 ++++++++++++++ include/hw/ppc/ppc.h | 2 ++ include/hw/ppc/xics.h | 2 ++ monitor.c | 3 +++ 6 files changed, 61 insertions(+)hmp-commands-info.hx +2
-0@@ -203,6 +203,8 @@ ETEXI .mhandler.cmd = sun4m_hmp_info_pic, #elif defined(TARGET_LM32) .mhandler.cmd = lm32_hmp_info_pic, +#elif defined(TARGET_PPC) + .mhandler.cmd = ppc_hmp_info_pic, #else .mhandler.cmd = hmp_info_pic, #endifhw/intc/xics.c +38
-0@@ -31,6 +31,9 @@#include "hw/ppc/xics.h" #include "qemu/error-report.h" #include "qapi/visitor.h" +#include "monitor/monitor.h" + +static XICSState *g_xics;int get_cpu_index_by_dt_id (int cpu_dt_id) {@@ -170,6 +173,9 @@ static void xics_common_initfn(Object *obj)object_property_add (obj,"nr_servers" ,"int" , xics_prop_get_nr_servers, xics_prop_set_nr_servers,NULL ,NULL ,NULL ); + +/* For exclusive use of monitor command */ + g_xics =XICS_COMMON (obj); }static void xics_common_class_init (ObjectClass *oc,void *data)@@ -614,6 +620,38 @@ static int ics_dispatch_post_load(void *opaque, int version_id)return 0 ; } +void xics_hmp_info_pic (Monitor *mon,const QDict *qdict) +{ +ICSState *ics; +uint32_t i; + +for (i =0 ; i < g_xics->nr_servers; i++) { +ICPState *icp = &g_xics->ss[i]; + +if (!icp->output) { +continue ; + } +monitor_printf (mon,"CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n" , + i, icp->xirr, icp->xirr_owner, + icp->pending_priority, icp->mfrr); + } + QLIST_FOREACH(ics, &g_xics->ics, list) { +monitor_printf (mon,"ICS %4x..%4x %p\n" , + ics->offset, ics->offset + ics->nr_irqs -1 , ics); +for (i =0 ; i < ics->nr_irqs; i++) { +ICSIRQState *irq = ics->irqs + i; + +if (!(irq->flags &XICS_FLAGS_IRQ_MASK )) { +continue ; + } +monitor_printf (mon," %4x %s %02x %02x\n" , + ics->offset + i, + (irq->flags &XICS_FLAGS_IRQ_LSI ) ?"LSI" :"MSI" , + irq->priority, irq->status); + } + } +} +static const VMStateDescription vmstate_ics_simple_irq = { .name ="ics/irq" , .version_id =2 ,hw/ppc/ppc.c +14
-0@@ -24,6 +24,7 @@#include "hw/hw.h" #include "hw/ppc/ppc.h" #include "hw/ppc/ppc_e500.h" +#include "hw/i386/pc.h" #include "qemu/timer.h" #include "sysemu/sysemu.h" #include "sysemu/cpus.h" @@ -35,6 +36,10 @@#include "kvm_ppc.h" #include "trace.h" +#if defined(TARGET_PPC64 ) +#include "hw/ppc/xics.h" +#endif +//#define PPC_DEBUG_IRQ //#define PPC_DEBUG_TB @@ -1337,3 +1342,12 @@ PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)return NULL ; } + +void ppc_hmp_info_pic (Monitor *mon,const QDict *qdict) +{ +/* Call in turn every PIC around. OpenPIC doesn't have one yet */ +#ifdef TARGET_PPC64 +xics_hmp_info_pic (mon, qdict); +#endif +hmp_info_pic (mon, qdict); +}include/hw/ppc/ppc.h +2
-0@@ -1,6 +1,8 @@#ifndef HW_PPC_H #define HW_PPC_H 1 +void ppc_hmp_info_pic (Monitor *mon,const QDict *qdict); +void ppc_set_irq (PowerPCCPU *cpu,int n_IRQ,int level);/* PowerPC hardware exceptions management helpers */ include/hw/ppc/xics.h +2
-0@@ -213,4 +213,6 @@ void xics_set_nr_servers(XICSState *icp, uint32_t nr_servers, Error **errp);ICSState *xics_find_source (XICSState *icp,int irq);void xics_add_ics (XICSState *xics,ICSState *ics); +void xics_hmp_info_pic (Monitor *mon,const QDict *qdict); +#endif /* __XICS_H__ */ monitor.c +3
-0@@ -76,6 +76,9 @@#include "qapi-event.h" #include "qmp-introspect.h" #include "sysemu/block-backend.h" +#if defined(TARGET_PPC ) +#include "hw/ppc/ppc.h" +#endif /* for hmp_info_irq/pic */ #if defined(TARGET_SPARC )
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH 40/77 ppc/pnv: Wire up XICS native with PowerNV platform
In reply to Benjamin Herrenschmidt--- hw/ppc/pnv.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/pnv.h | 2 ++ include/hw/ppc/xics.h | 2 ++ 3 files changed, 73 insertions(+)
hw/ppc/pnv.c +69 -0
@@ -41,6 +41,7 @@#include "hw/ppc/ppc.h" #include "hw/ppc/pnv.h" #include "hw/loader.h" +#include "hw/ppc/xics.h" #include "hw/ppc/pnv_xscom.h" #include "exec/address-spaces.h"
@@ -81,6 +82,59 @@ struct sPowerNVMachineState {PnvSystem sys; }; +static XICSState *try_create_xics (const char *type,int nr_servers, +int nr_irqs,Error **errp) +{ +Error *err =NULL ; +DeviceState *dev; + + dev =qdev_create (NULL , type); +qdev_prop_set_uint32 (dev,"nr_servers" , nr_servers); +object_property_set_bool (OBJECT (dev), true,"realized" , &err); +if (err) { +error_propagate (errp, err); +object_unparent (OBJECT (dev)); +return NULL ; + } + +return XICS_COMMON (dev); +} + +static XICSState *xics_system_init (int nr_servers,int nr_irqs) +{ +XICSState *xics =NULL ; + +#if 0 /* Some fixing needed to handle native ICS in KVM mode */ +if (kvm_enabled ()) { +QemuOpts *machine_opts =qemu_get_machine_opts (); +bool irqchip_allowed =qemu_opt_get_bool (machine_opts, +"kernel_irqchip" , true); +bool irqchip_required =qemu_opt_get_bool (machine_opts, +"kernel_irqchip" , false); +if (irqchip_allowed) { + icp =try_create_xics (TYPE_KVM_XICS , nr_servers, nr_irqs, + &error_abort); + } + +if (irqchip_required && !icp) { +perror ("Failed to create in-kernel XICS\n" ); +abort (); + } + } +#endif + +if (!xics) { + xics =try_create_xics (TYPE_XICS_NATIVE , nr_servers, nr_irqs, + &error_abort); + } + +if (!xics) { +perror ("Failed to create XICS\n" ); +abort (); + } +return xics; +} +static size_t create_page_sizes_prop (CPUPPCState *env,uint32_t *prop,size_t maxsize) {
@@ -366,6 +420,13 @@ static void *powernv_create_fdt(PnvSystem *sys, uint32_t initrd_base, uint32_t i_FDT ((fdt_end_node (fdt))); +/* ICPs */ +CPU_FOREACH (cs) { +PowerPCCPU *cpu =POWERPC_CPU (cs); +uint32_t base_server =ppc_get_vcpu_dt_id (cpu); +xics_create_native_icp_node (sys->xics, fdt, base_server, smt); + } +/* Memory */ _FDT ((powernv_populate_memory (fdt)));
@@ -451,11 +512,17 @@ static void ppc_powernv_init(MachineState *machine)MemoryRegion *ram =g_new (MemoryRegion,1 );sPowerNVMachineState *pnv_machine =POWERNV_MACHINE (machine);PnvSystem *sys = &pnv_machine->sys; +XICSState *xics;long fw_size;char *filename;void *fdt;int i; +/* Set up Interrupt Controller before we create the VCPUs */ + xics =xics_system_init (smp_cpus *kvmppc_smt_threads () / smp_threads, +XICS_IRQS_POWERNV ); + sys->xics = xics; +/* init CPUs */ if (cpu_model ==NULL ) { cpu_model =kvm_enabled () ?"host" :"POWER8" ;
@@ -475,6 +542,8 @@ static void ppc_powernv_init(MachineState *machine)/* MSR[IP] doesn't exist nowadays */ env->msr_mask &= ~(1 <<6 ); +xics_cpu_setup (xics, cpu); +qemu_register_reset (powernv_cpu_reset, cpu); }
include/hw/ppc/pnv.h +2 -0
@@ -21,6 +21,7 @@#include "hw/hw.h" typedef struct XScomBus XScomBus ; +typedef struct XICSState XICSState ;/* Should we turn that into a QOjb of some sort ? */ typedef struct PnvChip {
@@ -29,6 +30,7 @@ typedef struct PnvChip { } PnvChip; typedef struct PnvSystem { + XICSState *xics; uint32_t num_chips; #define PNV_MAX_CHIPS 1 PnvChip chips[PNV_MAX_CHIPS];
include/hw/ppc/xics.h +2 -0
@@ -183,6 +183,8 @@ struct ICSIRQState { };#define XICS_IRQS_SPAPR 1024 +#define XICS_IRQS_POWERNV (1 << 19) +qemu_irq xics_get_qirq (XICSState *icp,int irq);
Signature · 1 line
2.5.0
Re: [Qemu-devel] [Qemu-ppc] [PATCH 40/77] ppc/pnv: Wire up XICS native with PowerNV platform
Quoted 1 line · Benjamin Herrenschmidt
Signed-off-by Benjamin Herrenschmidt <[email protected]>
Looks sound enough, but will probably need some rework due to other suggested changes in the new xics stuff.
Quoted 152 lines
--- hw/ppc/pnv.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/pnv.h | 2 ++ include/hw/ppc/xics.h | 2 ++ 3 files changed, 73 insertions(+)hw/ppc/pnv.c +69
-0@@ -41,6 +41,7 @@#include "hw/ppc/ppc.h" #include "hw/ppc/pnv.h" #include "hw/loader.h" +#include "hw/ppc/xics.h" #include "hw/ppc/pnv_xscom.h" #include "exec/address-spaces.h" @@ -81,6 +82,59 @@ struct sPowerNVMachineState {PnvSystem sys; }; +static XICSState *try_create_xics (const char *type,int nr_servers, +int nr_irqs,Error **errp) +{ +Error *err =NULL ; +DeviceState *dev; + + dev =qdev_create (NULL , type); +qdev_prop_set_uint32 (dev,"nr_servers" , nr_servers); +object_property_set_bool (OBJECT (dev), true,"realized" , &err); +if (err) { +error_propagate (errp, err); +object_unparent (OBJECT (dev)); +return NULL ; + } + +return XICS_COMMON (dev); +} + +static XICSState *xics_system_init (int nr_servers,int nr_irqs) +{ +XICSState *xics =NULL ; + +#if 0 /* Some fixing needed to handle native ICS in KVM mode */ +if (kvm_enabled ()) { +QemuOpts *machine_opts =qemu_get_machine_opts (); +bool irqchip_allowed =qemu_opt_get_bool (machine_opts, +"kernel_irqchip" , true); +bool irqchip_required =qemu_opt_get_bool (machine_opts, +"kernel_irqchip" , false); +if (irqchip_allowed) { + icp =try_create_xics (TYPE_KVM_XICS , nr_servers, nr_irqs, + &error_abort); + } + +if (irqchip_required && !icp) { +perror ("Failed to create in-kernel XICS\n" ); +abort (); + } + } +#endif + +if (!xics) { + xics =try_create_xics (TYPE_XICS_NATIVE , nr_servers, nr_irqs, + &error_abort); + } + +if (!xics) { +perror ("Failed to create XICS\n" ); +abort (); + } +return xics; +} +static size_t create_page_sizes_prop (CPUPPCState *env,uint32_t *prop,size_t maxsize) {@@ -366,6 +420,13 @@ static void *powernv_create_fdt(PnvSystem *sys, uint32_t initrd_base, uint32_t i_FDT ((fdt_end_node (fdt))); +/* ICPs */ +CPU_FOREACH (cs) { +PowerPCCPU *cpu =POWERPC_CPU (cs); +uint32_t base_server =ppc_get_vcpu_dt_id (cpu); +xics_create_native_icp_node (sys->xics, fdt, base_server, smt); + } +/* Memory */ _FDT ((powernv_populate_memory (fdt)));@@ -451,11 +512,17 @@ static void ppc_powernv_init(MachineState *machine)MemoryRegion *ram =g_new (MemoryRegion,1 );sPowerNVMachineState *pnv_machine =POWERNV_MACHINE (machine);PnvSystem *sys = &pnv_machine->sys; +XICSState *xics;long fw_size;char *filename;void *fdt;int i; +/* Set up Interrupt Controller before we create the VCPUs */ + xics =xics_system_init (smp_cpus *kvmppc_smt_threads () / smp_threads, +XICS_IRQS_POWERNV ); + sys->xics = xics; +/* init CPUs */ if (cpu_model ==NULL ) { cpu_model =kvm_enabled () ?"host" :"POWER8" ;@@ -475,6 +542,8 @@ static void ppc_powernv_init(MachineState *machine)/* MSR[IP] doesn't exist nowadays */ env->msr_mask &= ~(1 <<6 ); +xics_cpu_setup (xics, cpu); +qemu_register_reset (powernv_cpu_reset, cpu); }include/hw/ppc/pnv.h +2
-0@@ -21,6 +21,7 @@#include "hw/hw.h" typedef struct XScomBus XScomBus ; +typedef struct XICSState XICSState ;/* Should we turn that into a QOjb of some sort ? */ typedef struct PnvChip {@@ -29,6 +30,7 @@ typedef struct PnvChip { } PnvChip; typedef struct PnvSystem { + XICSState *xics; uint32_t num_chips; #define PNV_MAX_CHIPS 1 PnvChip chips[PNV_MAX_CHIPS];include/hw/ppc/xics.h +2
-0@@ -183,6 +183,8 @@ struct ICSIRQState { };#define XICS_IRQS_SPAPR 1024 +#define XICS_IRQS_POWERNV (1 << 19) +qemu_irq xics_get_qirq (XICSState *icp,int irq);
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH 41/77 ppc/pnv: Add LPC controller and hook it up with a UART and RTC
In reply to Benjamin HerrenschmidtThis adds a model of the POWER8 LPC controller. It is then used by the PowerNV code to attach a UART and RTC, which, with the right version of OPAL firmware, will provide a working console.
This version of the LPC controller model doesn't yet implement support for the SerIRQ deserializer present in the Naples version of the chip though some preliminary work is there.
--- hw/ppc/Makefile.objs | 2 +- hw/ppc/pnv.c | 49 ++++- hw/ppc/pnv_lpc.c | 527 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/pnv.h | 5 + 4 files changed, 578 insertions(+), 5 deletions(-) create mode 100644 hw/ppc/pnv_lpc.c
hw/ppc/Makefile.objs +1 -1
@@ -5,7 +5,7 @@ obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o # IBM PowerNV -obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o +obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_lpc.o ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy) obj-y += spapr_pci_vfio.o endif
hw/ppc/pnv.c +45 -4
80 lines not on this page · raw message
hw/ppc/pnv_lpc.c new file +527 -0
527 lines not on this page · raw message
include/hw/ppc/pnv.h +5 -0
@@ -21,12 +21,16 @@#include "hw/hw.h" typedef struct XScomBus XScomBus ; +typedef struct ISABus ISABus ; +typedef struct PnvLpcController PnvLpcController ;typedef struct XICSState XICSState ;/* Should we turn that into a QOjb of some sort ? */ typedef struct PnvChip {uint32_t chip_id;XScomBus *xscom; +PnvLpcController *lpc; +ISABus *lpc_bus; }PnvChip ; typedef struct PnvSystem {
@@ -36,5 +40,6 @@ typedef struct PnvSystem { PnvChip chips[PNV_MAX_CHIPS]; } PnvSystem; +extern void pnv_lpc_create (PnvChip *chip,bool has_serirq);#endif /* _HW_PNV_LPC_H */
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH 41/77] ppc/pnv: Add LPC controller and hook it up with a UART and RTC
Quoted 8 lines · Benjamin Herrenschmidt
This adds a model of the POWER8 LPC controller. It is then used by the PowerNV code to attach a UART and RTC, which, with the right version of OPAL firmware, will provide a working console.
This version of the LPC controller model doesn't yet implement support for the SerIRQ deserializer present in the Naples version of the chip though some preliminary work is there.
Is this LPC controller one per a chip or per a machine?
In general it is quite nice when "-nodefaults" does not create neither PHB nor LPC so the user can add them manually with parameters different than defaults.
Signature · 1 line
Alexey
Re: [Qemu-devel] [PATCH 41/77] ppc/pnv: Add LPC controller and hook it up with a UART and RTC
Quoted 11 lines · Alexey Kardashevskiy
Quoted 8 lines · Benjamin Herrenschmidt
This adds a model of the POWER8 LPC controller. It is then used by the PowerNV code to attach a UART and RTC, which, with the right version of OPAL firmware, will provide a working console.
This version of the LPC controller model doesn't yet implement support for the SerIRQ deserializer present in the Naples version of the chip though some preliminary work is there.
Is this LPC controller one per a chip or per a machine?
Per chip but we usually only wire one up per machine.
Quoted 3 lines
In general it is quite nice when "-nodefaults" does not create neither PHB nor LPC so the user can add them manually with parameters different than defaults.
In this case though, PHB and LPC bridges are all part of the P8 chip, and I'm trying to represent that topology as best as possible.
I think "-nodefaults" for Pnv should only be about the devices we attach to the LPC/PHB not the busses themselves.
Cheers,
Ben.
Re: [Qemu-devel] [Qemu-ppc] [PATCH 41/77] ppc/pnv: Add LPC controller and hook it up with a UART and RTC
Quoted 19 lines · Benjamin Herrenschmidt
Quoted 11 lines · Alexey Kardashevskiy
Quoted 8 lines · Benjamin Herrenschmidt
This adds a model of the POWER8 LPC controller. It is then used by the PowerNV code to attach a UART and RTC, which, with the right version of OPAL firmware, will provide a working console.
This version of the LPC controller model doesn't yet implement support for the SerIRQ deserializer present in the Naples version of the chip though some preliminary work is there.
Is this LPC controller one per a chip or per a machine?
Per chip but we usually only wire one up per machine.
Quoted 3 lines
In general it is quite nice when "-nodefaults" does not create neither PHB nor LPC so the user can add them manually with parameters different than defaults.
Quoted 5 lines
In this case though, PHB and LPC bridges are all part of the P8 chip, and I'm trying to represent that topology as best as possible.
I think "-nodefaults" for Pnv should only be about the devices we attach to the LPC/PHB not the busses themselves.
Exactly what is and isn't covered by -nodefaults is a bit of a mess - part of the topic of my talk at KVM Forum.
But on the whole I agree with you, since the LPC is part of the P8 chip, I think it makes sense to include it even with -nodefaults.
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
Re: [Qemu-devel] [Qemu-ppc] [PATCH 41/77] ppc/pnv: Add LPC controller and hook it up with a UART and RTC
Quoted 23 lines · David Gibson
Quoted 22 lines · Benjamin Herrenschmidt
Quoted 11 lines · Alexey Kardashevskiy
Quoted 8 lines · Benjamin Herrenschmidt
This adds a model of the POWER8 LPC controller. It is then used by the PowerNV code to attach a UART and RTC, which, with the right version of OPAL firmware, will provide a working console.
This version of the LPC controller model doesn't yet implement support for the SerIRQ deserializer present in the Naples version of the chip though some preliminary work is there.
Is this LPC controller one per a chip or per a machine?
Per chip but we usually only wire one up per machine.
Quoted 3 lines
In general it is quite nice when "-nodefaults" does not create neither PHB nor LPC so the user can add them manually with parameters different than defaults.
In this case though, PHB and LPC bridges are all part of the P8 chip, and I'm trying to represent that topology as best as possible.
Quoted 8 lines
Quoted 2 lines
I think "-nodefaults" for Pnv should only be about the devices we attach to the LPC/PHB not the busses themselves.
Exactly what is and isn't covered by -nodefaults is a bit of a mess - part of the topic of my talk at KVM Forum.
But on the whole I agree with you, since the LPC is part of the P8 chip, I think it makes sense to include it even with -nodefaults.
POWER8 chips all have 8 threads per core but we do not always assume -smt ...,threads=8, how are LPC or PHB different? PHB is more interesting - how is the user supposed to add more? And there always will be the default one which properties are set in a separate way (via -global, not -device). I found it sometime really annoying to debug the existing pseries which always adds a default PHB (I know, this was to make libvirt happy but this is not the case here).
Out of curiosity - if we have 2 chips, will the system work if the second chip does not get any LPC or PHB attached?
Signature · 1 line
Alexey
Re: [Qemu-devel] [Qemu-ppc] [PATCH 41/77] ppc/pnv: Add LPC controller and hook it up with a UART and RTC
Quoted 5 lines · Alexey Kardashevskiy
Quoted 2 lines
But on the whole I agree with you, since the LPC is part of the P8 chip, I think it makes sense to include it even with -nodefaults.
POWER8 chips all have 8 threads per core but we do not always assume -smt ...,threads=8, how are LPC or PHB different?
First, for pseries which is paravirtualized it's a different can of worms completely. For powernv, we *should* represent all 8 threads, we just can't yet due to TCG limitations.
Quoted 1 line
PHB is more interesting - how is the user supposed to add more?
That's an open question. Since we model a real P8 chip we can only model the PHBs as they exist on it, which is up to 3 per chip at very specific XSCOM addresses. We could try to model some non-existing P8 chip with more but bad things will happen when the FW try to assign interrupt numbers for example.
We simulate a machine that has been primed by HostBoot before OPAL starts. So we rely on what the device-tree tells us of what PHB were enabled but appart from that, we have to stick to the limitations.
Quoted 8 lines
And there always will be the default one
which properties are set in a separate way (via -global, not -device). I found it sometime really annoying to debug the existing pseries which always adds a default PHB (I know, this was to make libvirt happy but this is not the case here).Out of curiosity - if we have 2 chips, will the system work if the second chip does not get any LPC or PHB attached?
This is something I need to look into, there's a lot of work needed to properly model "chips" that I haven't done yet, but what is there is sufficient for a lot of usages already.
Cheers,
Ben.
Re: [Qemu-devel] [Qemu-ppc] [PATCH 41/77] ppc/pnv: Add LPC controller and hook it up with a UART and RTC
Quoted 10 lines · Benjamin Herrenschmidt
Quoted 5 lines · Alexey Kardashevskiy
Quoted 2 lines
But on the whole I agree with you, since the LPC is part of the P8 chip, I think it makes sense to include it even with -nodefaults.
POWER8 chips all have 8 threads per core but we do not always assume -smt ...,threads=8, how are LPC or PHB different?
First, for pseries which is paravirtualized it's a different can of worms completely. For powernv, we *should* represent all 8 threads, we just can't yet due to TCG limitations.
Out of curiosity - for pseries we should not? I know it works with various numbers of threads but is not that because we also control guest linux kernel and, for example, the Other OS (AIX) might be upset on non-multiply-of-2 number of threads?
Quoted 18 lines
Quoted 1 line
PHB is more interesting - how is the user supposed to add more?
That's an open question. Since we model a real P8 chip we can only model the PHBs as they exist on it, which is up to 3 per chip at very specific XSCOM addresses. We could try to model some non-existing P8 chip with more but bad things will happen when the FW try to assign interrupt numbers for example.
We simulate a machine that has been primed by HostBoot before OPAL starts. So we rely on what the device-tree tells us of what PHB were enabled but appart from that, we have to stick to the limitations.
Quoted 6 lines
And there always will be the default one
which properties are set in a separate way (via -global, not -device). I found it sometime really annoying to debug the existing pseries which always adds a default PHB (I know, this was to make libvirt happy but this is not the case here).
Quoted 6 lines
Quoted 2 lines
Out of curiosity - if we have 2 chips, will the system work if the second chip does not get any LPC or PHB attached?
This is something I need to look into, there's a lot of work needed to properly model "chips" that I haven't done yet, but what is there is sufficient for a lot of usages already.
For now, if possible, I'd suggest implementing -nodefaults with no defaults whatsoever and create a config somewhere in the qemu tree to pass it via -readconfig to get reasonably configured machine so people will know what is expected to work but there will still be possibility for experiments (do not we secretly hope that other vendors will start designing/manufacturing their ppc64 chips?). It could be a config file per an actual POWER8 chip (we have two already).
Signature · 1 line
Alexey
Re: [Qemu-devel] [Qemu-ppc] [PATCH 41/77] ppc/pnv: Add LPC controller and hook it up with a UART and RTC
Quoted 8 lines · Alexey Kardashevskiy
Quoted 7 lines · Benjamin Herrenschmidt
Quoted 5 lines · Alexey Kardashevskiy
Quoted 2 lines
But on the whole I agree with you, since the LPC is part of the P8 chip, I think it makes sense to include it even with -nodefaults.
POWER8 chips all have 8 threads per core but we do not always assume -smt ...,threads=8, how are LPC or PHB different?
Quoted 8 lines
Quoted 3 lines
First, for pseries which is paravirtualized it's a different can of worms completely. For powernv, we *should* represent all 8 threads, we just can't yet due to TCG limitations.
Out of curiosity - for pseries we should not? I know it works with various numbers of threads but is not that because we also control guest linux kernel and, for example, the Other OS (AIX) might be upset on non-multiply-of-2 number of threads?
There are several different cases here and I'm not sure which you're thinking about.
1) Guest has different number of threads-per-core than the host
This one is just fine - PAPR defines how the guest should get the number of threads from the device tree, and qemu sets that correctly.
2) Guest threads-per-core not a power of two
The PAPR thread mechanism allows this to be communicated to the guest, and I don't know if PAPR explicitly permits or prohibitis this situation. Guests could get confused by it, although that's arguably a guest bug.
2) "Partially filled core", e.g. guest has 8 threads-per-core declared but only one vcpu available
This is the only one I can see as relying on Linux guest behaviour. We kind of get away with this by accident with a Linux guest - it will try to bring up all 8 threads, but fail non fatally. We shouldn't allow this situation, although we do right now. Bharata posted a patch which would prevent this in qemu, and I have a BZ to make libvirt not allow this construction either.
Quoted 25 lines
Quoted 18 lines
Quoted 1 line
PHB is more interesting - how is the user supposed to add more?
That's an open question. Since we model a real P8 chip we can only model the PHBs as they exist on it, which is up to 3 per chip at very specific XSCOM addresses. We could try to model some non-existing P8 chip with more but bad things will happen when the FW try to assign interrupt numbers for example.
We simulate a machine that has been primed by HostBoot before OPAL starts. So we rely on what the device-tree tells us of what PHB were enabled but appart from that, we have to stick to the limitations.
Quoted 6 lines
And there always will be the default one
which properties are set in a separate way (via -global, not -device). I found it sometime really annoying to debug the existing pseries which always adds a default PHB (I know, this was to make libvirt happy but this is not the case here).Quoted 6 lines
Quoted 2 lines
Out of curiosity - if we have 2 chips, will the system work if the second chip does not get any LPC or PHB attached?
This is something I need to look into, there's a lot of work needed to properly model "chips" that I haven't done yet, but what is there is sufficient for a lot of usages already.
Quoted 7 lines
For now, if possible, I'd suggest implementing -nodefaults with no defaults whatsoever and create a config somewhere in the qemu tree to pass it via -readconfig to get reasonably configured machine so people will know what is expected to work but there will still be possibility for experiments (do not we secretly hope that other vendors will start designing/manufacturing their ppc64 chips?). It could be a config file per an actual POWER8 chip (we have two already).
I can see some benefit to that approach, but it does stray away from current qemu practice (in general, not just compared to spapr). Hmm.. not sure.
What I do think would be a good idea is to represent a POWER8 "chip" as a instantiable qdev device, which will create the scoms and PHBs under itself as per the hardware. We can add device properties as needed to make that construction more flexible.
We probably don't want to link the number of CPUs to the chip qdevs, partly because that doesn't really fit the qemu model, but also because we'll probably want some extra flexibility. e.g. making a UP system for experimentation, even though a single chip would have multiple cores (IIUC) - SMP TCG is super slow, so we probably want that.
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
Re: [Qemu-devel] [Qemu-ppc] [PATCH 41/77] ppc/pnv: Add LPC controller and hook it up with a UART and RTC
Quoted 9 lines · David Gibson
There are several different cases here and I'm not sure which you're thinking about.
1) Guest has different number of threads-per-core than the host
This one is just fine - PAPR defines how the guest should get the number of threads from the device tree, and qemu sets that correctly.
Quoted 6 lines
2) Guest threads-per-core not a power of two
The PAPR thread mechanism allows this to be communicated to the guest, and I don't know if PAPR explicitly permits or prohibitis this situation. Guests could get confused by it, although that's arguably a guest bug.
Linux only supports powers of 2
.../...
Quoted 11 lines
Quoted 7 lines
For now, if possible, I'd suggest implementing -nodefaults with no defaults whatsoever and create a config somewhere in the qemu tree to pass it via -readconfig to get reasonably configured machine so people will know what is expected to work but there will still be possibility for experiments (do not we secretly hope that other vendors will start designing/manufacturing their ppc64 chips?). It could be a config file per an actual POWER8 chip (we have two already).
I can see some benefit to that approach, but it does stray away from current qemu practice (in general, not just compared to spapr). Hmm.. not sure.
I don't see an urgent need. We can do that in a separate series if we want to. As I said in another email, I don't want powernv to be "set in stone" in term of ABIs & migration for a while, so we have latitude to play with the model for a while before we lock things down. At least until after P9.
Quoted 4 lines
What I do think would be a good idea is to represent a POWER8 "chip" as a instantiable qdev device, which will create the scoms and PHBs under itself as per the hardware. We can add device properties as needed to make that construction more flexible.
It would also instanciate the CPUs. I want to change that in the current model, just haven't got to it yet.
Quoted 5 lines
We probably don't want to link the number of CPUs to the chip qdevs, partly because that doesn't really fit the qemu model, but also because we'll probably want some extra flexibility. e.g. making a UP system for experimentation, even though a single chip would have multiple cores (IIUC) - SMP TCG is super slow, so we probably want that.
We want to eventually represent the EX units properly on XSCOM (the cores). So we will need that tie between chip and CPU. But we don't have to mark all cores in a chip as "enabled". It's ok to have chips with only one good core for example.
Cheers,
Ben.
Re: [Qemu-devel] [Qemu-ppc] [PATCH 41/77] ppc/pnv: Add LPC controller and hook it up with a UART and RTC
In reply to Alexey KardashevskiyQuoted 5 lines · Alexey Kardashevskiy
Quoted 4 lines · Benjamin Herrenschmidt
Quoted 3 lines · Alexey Kardashevskiy
Quoted 2 lines
But on the whole I agree with you, since the LPC is part of the P8 chip, I think it makes sense to include it even with -nodefaults.
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
POWER8 chips all have 8 threads per core but we do not always assume -smt ...,threads=8, how are LPC or PHB different?
First, for pseries which is paravirtualized it's a different can of worms completely. For powernv, we *should* represent all 8 threads, we just can't yet due to TCG limitations.
Out of curiosity - for pseries we should not?
Not that we should not, more like, it makes sense to offer whatever choice, it would be indeed better to have the ability to support them however.
Quoted 4 lines
I know it works with various
numbers of threads but is not that because we also control guest linux kernel and, for example, the Other OS (AIX) might be upset on non-multiply-of-2 number of threads?
Quite possibly. I have some plans to add threads support, just haven't got to it yet :-)
Quoted 26 lines
Quoted 8 lines
Quoted 2 lines
PHB is more interesting - how is the user supposed to add more?
That's an open question. Since we model a real P8 chip we can only model the PHBs as they exist on it, which is up to 3 per chip at very specific XSCOM addresses. We could try to model some non-existing P8 chip with more but bad things will happen when the FW try to assign interrupt numbers for example.
>
Quoted 3 lines
We simulate a machine that has been primed by HostBoot before OPAL starts. So we rely on what the device-tree tells us of what PHB were enabled but appart from that, we have to stick to the limitations.
>
Quoted 6 lines
Quoted 6 lines
And there always will be the default one
which properties are set in a separate way (via -global, not -device). I found it sometime really annoying to debug the existing pseries which always adds a default PHB (I know, this was to make libvirt happy but this is not the case here).Quoted 6 lines
Quoted 2 lines
Out of curiosity - if we have 2 chips, will the system work if the second chip does not get any LPC or PHB attached?
This is something I need to look into, there's a lot of work needed to properly model "chips" that I haven't done yet, but what is there is sufficient for a lot of usages already.
Quoted 7 lines
For now, if possible, I'd suggest implementing -nodefaults with no defaults whatsoever and create a config somewhere in the qemu tree to pass it via -readconfig to get reasonably configured machine so people will know what is expected to work but there will still be possibility for experiments (do not we secretly hope that other vendors will start designing/manufacturing their ppc64 chips?). It could be a config file per an actual POWER8 chip (we have two already).
There could be, but we'd need ways to specify a bunch of things, it's not that trivial. IE, the xscom addresses of the 3 ranges for each PHB for example etc.. For now let's keep things simple.
I also am in no hurry to support migration with powernv, so we have quite a bit of flexibility to change things.
Cheers,
Ben.
PATCH 42/77 ppc/pnv: Add cut down PSI bridge model and hookup external interrupt
In reply to Benjamin HerrenschmidtThis adds just enough of the PSI bridge to handle various on-chip and the one external interrupt. The rest of PSI has to do with the link to the IBM FSP service processor which we don't plan to emulate (not used on OpenPower machines).
--- hw/ppc/Makefile.objs | 2 +- hw/ppc/pnv.c | 28 ++- hw/ppc/pnv_psi.c | 594 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/pnv.h | 16 ++ 4 files changed, 632 insertions(+), 8 deletions(-) create mode 100644 hw/ppc/pnv_psi.c
hw/ppc/Makefile.objs +1 -1
@@ -5,7 +5,7 @@ obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o # IBM PowerNV -obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_lpc.o +obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_lpc.o pnv_psi.o ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy) obj-y += spapr_pci_vfio.o endif
hw/ppc/pnv.c +21 -7
@@ -488,9 +488,22 @@ static const VMStateDescription vmstate_powernv = {static void pnv_lpc_irq_handler_cpld (void *opaque,int n,int level) { -/* We don't yet emulate the PSI bridge which provides the external -* interrupt, so just drop interrupts on the floor -*/ +#define MAX_ISA_IRQ 16 +static uint32_t irqstate; +uint32_t old_state = irqstate; +PnvPsiController *psi = opaque; + +if (n >=MAX_ISA_IRQ ) { +return ; + } +if (level) { + irqstate |=1u << n; + }else { + irqstate &= ~(1u << n); + } +if (irqstate != old_state) { +pnv_psi_irq_set (psi,PSIHB_IRQ_EXTERNAL , irqstate !=0 ); + } } static void pnv_create_chip(PnvSystem *sys, unsigned int chip_no,
@@ -508,6 +521,9 @@ static void pnv_create_chip(PnvSystem *sys, unsigned int chip_no,/* Set up XSCOM bus */ xscom_create (chip); +/* Create PSI */ +pnv_psi_create (chip, sys->xics); +/* Create LPC controller */ if (has_lpc) {pnv_lpc_create (chip, has_lpc_irq);
@@ -519,13 +535,11 @@ static void pnv_create_chip(PnvSystem *sys, unsigned int chip_no,* have a CPLD that will collect the SerIRQ and shoot them as a * single level interrupt to the P8 chip. So let's setup a hook * for doing just that. -* -* Note: The actual interrupt input isn't emulated yet, this will -* come with the PSI bridge model. */ if (!has_lpc_irq) {isa_bus_irqs (chip->lpc_bus, -qemu_allocate_irqs (pnv_lpc_irq_handler_cpld,NULL ,16 )); +qemu_allocate_irqs (pnv_lpc_irq_handler_cpld, + chip->psi,16 )); } } }
hw/ppc/pnv_psi.c new file +594 -0
594 lines not on this page · raw message
include/hw/ppc/pnv.h +16 -0
@@ -23,6 +23,7 @@typedef struct XScomBus XScomBus ;typedef struct ISABus ISABus ;typedef struct PnvLpcController PnvLpcController ; +typedef struct PnvPsiController PnvPsiController ;typedef struct XICSState XICSState ;/* Should we turn that into a QOjb of some sort ? */
@@ -31,6 +32,7 @@ typedef struct PnvChip {XScomBus *xscom;PnvLpcController *lpc;ISABus *lpc_bus; +PnvPsiController *psi; } PnvChip; typedef struct PnvSystem {
@@ -41,5 +43,19 @@ typedef struct PnvSystem { } PnvSystem;extern void pnv_lpc_create (PnvChip *chip,bool has_serirq); +extern void pnv_psi_create (PnvChip *chip,XICSState *xics); + +typedef enum PnvPsiIrq { +PSIHB_IRQ_PSI ,/* internal use only */ +PSIHB_IRQ_FSP ,/* internal use only */ +PSIHB_IRQ_OCC , +PSIHB_IRQ_FSI , +PSIHB_IRQ_LPC_I2C , +PSIHB_IRQ_LOCAL_ERR , +PSIHB_IRQ_EXTERNAL , +}PnvPsiIrq ; + +extern void pnv_psi_irq_set (PnvPsiController *psi,PnvPsiIrq irq,bool state); +#endif /* _HW_PNV_LPC_H */
Signature · 1 line
2.5.0
PATCH 43/77 ppc/pnv: Add OCC model stub with interrupt support
In reply to Benjamin HerrenschmidtThe OCC is an on-chip microcontroller based on a ppc405 core used for various power management tasks. It comes with a pile of additional hardware sitting on the PIB (aka XSCOM bus). At this point we don't emulate it (nor plan to do so). However there is one facility which is provided by the surrounding hardware that we do need, which is the interrupt generation facility. OPAL uses it to send itself interrupts under some circumstances and there are other uses around the corner.
So this implement just enough to support this.
--- hw/ppc/Makefile.objs | 2 +- hw/ppc/pnv.c | 3 ++ hw/ppc/pnv_occ.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/pnv.h | 3 ++ 4 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 hw/ppc/pnv_occ.c
hw/ppc/Makefile.objs +1 -1
@@ -5,7 +5,7 @@ obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o # IBM PowerNV -obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_lpc.o pnv_psi.o +obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_lpc.o pnv_psi.o pnv_occ.o ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy) obj-y += spapr_pci_vfio.o endif
hw/ppc/pnv.c +3 -0
@@ -542,6 +542,9 @@ static void pnv_create_chip(PnvSystem *sys, unsigned int chip_no, chip->psi, 16)); } } + +/* Create the simplified OCC model */ +pnv_occ_create (chip); }static void ppc_powernv_init (MachineState *machine)
hw/ppc/pnv_occ.c new file +125 -0
125 lines not on this page · raw message
include/hw/ppc/pnv.h +3 -0
@@ -25,6 +25,7 @@ typedef struct ISABus ISABus;typedef struct PnvLpcController PnvLpcController ;typedef struct PnvPsiController PnvPsiController ;typedef struct XICSState XICSState ; +typedef struct PnvOCCState PnvOCCState ;/* Should we turn that into a QOjb of some sort ? */ typedef struct PnvChip {
@@ -33,6 +34,7 @@ typedef struct PnvChip {PnvLpcController *lpc;ISABus *lpc_bus;PnvPsiController *psi; +PnvOCCState *occ; } PnvChip; typedef struct PnvSystem {
@@ -44,6 +46,7 @@ typedef struct PnvSystem {extern void pnv_lpc_create (PnvChip *chip,bool has_serirq);extern void pnv_psi_create (PnvChip *chip,XICSState *xics); +extern void pnv_occ_create (PnvChip *chip); typedef enum PnvPsiIrq { PSIHB_IRQ_PSI, /* internal use only */
Signature · 1 line
2.5.0
PATCH 44/77 pci-bridge: Set a supported devfn_min for bridge
In reply to Benjamin HerrenschmidtOtherwise QEMU might add a device at slot 0 which isn't supported by the SHPC controller.
--- hw/pci-bridge/pci_bridge_dev.c | 3 +++ 1 file changed, 3 insertions(+)
hw/pci-bridge/pci_bridge_dev.c +3 -0
@@ -1,3 +1,4 @@ +/* * Standard PCI Bridge Device *
@@ -57,6 +58,8 @@ static int pci_bridge_dev_initfn(PCIDevice *dev) goto bridge_error; }if (bridge_dev->flags & (1 <<PCI_BRIDGE_DEV_F_SHPC_REQ )) { +/* SHCP gets upset if we try to use slot 0 */ + br->sec_bus.devfn_min =PCI_FUNC_MAX ; dev->config[PCI_INTERRUPT_PIN ] =0x1 ;memory_region_init (&bridge_dev->bar,OBJECT (dev),"shpc-bar" ,shpc_bar_size (dev));
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH 44/77] pci-bridge: Set a supported devfn_min for bridge
hw/pci-bridge/pci_bridge_dev.c static int pci_bridge_dev_initfn(PCIDevice *dev) · line 65
Quoted 6 lines · Benjamin Herrenschmidt
if (bridge_dev->flags & (1 << PCI_BRIDGE_DEV_F_SHPC_REQ)) {hw/pci-bridge/pci_bridge_dev.c +2
-0+/* SHCP gets upset if we try to use slot 0 */ + br->sec_bus.devfn_min =PCI_FUNC_MAX ; dev->config[PCI_INTERRUPT_PIN ] =0x1 ;memory_region_init (&bridge_dev->bar,OBJECT (dev),"shpc-bar" ,shpc_bar_size (dev));
This needs backwards compatibility gunk unfortunately. However we should fix it in 2.5 because it's a bug. I'll send a patch.
Paolo
Re: [Qemu-devel] [PATCH for-2.5 44/77] pci-bridge: Set a supported devfn_min for bridge
Quoted 10 lines · Paolo Bonzini
hw/pci-bridge/pci_bridge_dev.c static int pci_bridge_dev_initfn(PCIDevice *dev) · line 65
Quoted 6 lines · Benjamin Herrenschmidt
if (bridge_dev->flags & (1 << PCI_BRIDGE_DEV_F_SHPC_REQ)) {hw/pci-bridge/pci_bridge_dev.c +2
-0+/* SHCP gets upset if we try to use slot 0 */ + br->sec_bus.devfn_min =PCI_FUNC_MAX ; dev->config[PCI_INTERRUPT_PIN ] =0x1 ;memory_region_init (&bridge_dev->bar,OBJECT (dev),"shpc-bar" ,shpc_bar_size (dev));
Quoted 2 lines
This needs backwards compatibility gunk unfortunately. However we should fix it in 2.5 because it's a bug. I'll send a patch.
Actually it turns out that the forbidden configuration is blocked elsewhere:
$ x86_64-softmmu/qemu-system-x86_64 \ -device pci-bridge,id=foo,chassis_nr=1 \ -device virtio-scsi-pci,bus=foo qemu-system-x86_64: -device virtio-scsi-pci,bus=foo: Unsupported PCI slot 0 for standard hotplug controller. Valid slots are between 1 and 31.
so this patch is just allowing the above command line to work. There's no effect with or without the patch if addr=0, so the patch is good for 2.5 IMO.
Michael, can you queue it?
Paolo
Re: [Qemu-devel] [PATCH for-2.5 44/77] pci-bridge: Set a supported devfn_min for bridge
Quoted 22 lines · Paolo Bonzini
Quoted 10 lines · Paolo Bonzini
hw/pci-bridge/pci_bridge_dev.c static int pci_bridge_dev_initfn(PCIDevice *dev) · line 65
Quoted 6 lines · Benjamin Herrenschmidt
if (bridge_dev->flags & (1 << PCI_BRIDGE_DEV_F_SHPC_REQ)) {hw/pci-bridge/pci_bridge_dev.c +2
-0+/* SHCP gets upset if we try to use slot 0 */ + br->sec_bus.devfn_min =PCI_FUNC_MAX ; dev->config[PCI_INTERRUPT_PIN ] =0x1 ;memory_region_init (&bridge_dev->bar,OBJECT (dev),"shpc-bar" ,shpc_bar_size (dev));Quoted 2 lines
This needs backwards compatibility gunk unfortunately. However we should fix it in 2.5 because it's a bug. I'll send a patch.
Actually it turns out that the forbidden configuration is blocked elsewhere:
$ x86_64-softmmu/qemu-system-x86_64 \ -device pci-bridge,id=foo,chassis_nr=1 \ -device virtio-scsi-pci,bus=foo qemu-system-x86_64: -device virtio-scsi-pci,bus=foo: Unsupported PCI slot 0 for standard hotplug controller. Valid slots are between 1 and 31.
Quoted 7 lines
so this patch is just allowing the above command line to work. There's no effect with or without the patch if addr=0, so the patch is good for 2.5 IMO.
Michael, can you queue it?
Paolo
This depends on the devfn_min thing, right? I'm yet to review it, generally I'd prefer to avoid changing device allocation rules since that makes it so easy to break compatibility.
Assuming addresses are all explicitly stated, is there even a problem?
If not, maybe we can defer everything to after 2.5.
Signature · 1 line
MST
Re: [Qemu-devel] [PATCH for-2.5 44/77] pci-bridge: Set a supported devfn_min for bridge
Quoted 7 lines · Michael S. Tsirkin
This depends on the
devfn_minthing, right? I'm yet to review it, generally I'd prefer to avoid changing device allocation rules since that makes it so easy to break compatibility.Assuming addresses are all explicitly stated, is there even a problem?
It makes it a bit easier to use pci-bridge; it is a bug, albeit one that only affects direct usage through the command line of PCI bridges.
Paolo
Re: [Qemu-devel] [PATCH for-2.5 44/77] pci-bridge: Set a supported devfn_min for bridge
Quoted 8 lines · Paolo Bonzini
Quoted 5 lines · Michael S. Tsirkin
This depends on the
devfn_minthing, right? I'm yet to review it, generally I'd prefer to avoid changing device allocation rules since that makes it so easy to break compatibility.
Quoted 7 lines
Quoted 2 lines
Assuming addresses are all explicitly stated, is there even a problem?
It makes it a bit easier to use pci-bridge; it is a bug, albeit one that only affects direct usage through the command line of PCI bridges.
Paolo
Yes but not a regression ... I'll look at how
invasive the change it depends on is.
PATCH 45/77 qdev: Add a hook for a bus to device if it can add devices
In reply to Benjamin HerrenschmidtThis allows a bus class to tell whether a given bus has room for any new device. max_dev isn't sufficient as the rules can depend on some arguments or can differ between instances of a bus. This will be used by PCI in subsequent patches
--- include/hw/qdev-core.h | 1 + qdev-monitor.c | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-)
include/hw/qdev-core.h +1 -0
@@ -202,6 +202,7 @@ struct BusClass {*/ char *(*get_fw_dev_path)(DeviceState *dev);void (*reset)(BusState *bus); +bool (*can_add_device)(BusState *bus,QemuOpts *opts);BusRealize realize;BusUnrealize unrealize;
qdev-monitor.c +8 -5
@@ -384,7 +384,7 @@ static inline bool qbus_is_full(BusState *bus)* Return the bus if found, else %NULL. */ static BusState *qbus_find_recursive (BusState *bus,const char *name, -const char *bus_typename) +const char *bus_typename,QemuOpts *opts) {BusChild *kid;BusState *pick, *child, *ret;
@@ -398,7 +398,10 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name, }if (match && !qbus_is_full (bus)) { -return bus;/* root matches and isn't full */ +BusClass *bc =BUS_GET_CLASS (bus); +if (!bc->can_add_device || bc->can_add_device (bus, opts)) { +return bus;/* root matches and isn't full */ + } } pick = match ? bus :NULL ;
@@ -406,7 +409,7 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name, QTAILQ_FOREACH(kid, &bus->children, sibling) {DeviceState *dev = kid->child; QLIST_FOREACH(child, &dev->child_bus, sibling) { - ret =qbus_find_recursive (child, name, bus_typename); + ret =qbus_find_recursive (child, name, bus_typename, opts);if (ret && !qbus_is_full (ret)) {return ret;/* a descendant matches and isn't full */ }
@@ -436,7 +439,7 @@ static BusState *qbus_find(const char *path, Error **errp)assert (!path[0 ]); elem[0 ] = len =0 ; } - bus =qbus_find_recursive (sysbus_get_default (), elem,NULL ); + bus =qbus_find_recursive (sysbus_get_default (), elem,NULL ,NULL );if (!bus) {error_setg (errp,"Bus '%s' not found" , elem);return NULL ;
@@ -542,7 +545,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)return NULL ; } }else if (dc->bus_type !=NULL ) { - bus =qbus_find_recursive (sysbus_get_default (),NULL , dc->bus_type); + bus =qbus_find_recursive (sysbus_get_default (),NULL , dc->bus_type, opts);if (!bus ||qbus_is_full (bus)) {error_setg (errp,"No '%s' bus found for device '%s'" , dc->bus_type, driver);
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH 45/77] qdev: Add a hook for a bus to device if it can add devices
Quoted 49 lines · Benjamin Herrenschmidt
This allows a bus class to tell whether a given bus has room for any new device.
max_devisn't sufficient as the rules can depend on some arguments or can differ between instances of a bus. This will be used by PCI in subsequent patchesSigned-off-by Benjamin Herrenschmidt <[email protected]>--- include/hw/qdev-core.h | 1 + qdev-monitor.c | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-)include/hw/qdev-core.h +1
-0@@ -202,6 +202,7 @@ struct BusClass {*/ char *(*get_fw_dev_path)(DeviceState *dev);void (*reset)(BusState *bus); +bool (*can_add_device)(BusState *bus,QemuOpts *opts);BusRealize realize;BusUnrealize unrealize;qdev-monitor.c +5
-2@@ -384,7 +384,7 @@ static inline bool qbus_is_full(BusState *bus)* Return the bus if found, else %NULL. */ static BusState *qbus_find_recursive (BusState *bus,const char *name, -const char *bus_typename) +const char *bus_typename,QemuOpts *opts) {BusChild *kid;BusState *pick, *child, *ret;@@ -398,7 +398,10 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name, }if (match && !qbus_is_full (bus)) { -return bus;/* root matches and isn't full */ +BusClass *bc =BUS_GET_CLASS (bus); +if (!bc->can_add_device || bc->can_add_device (bus, opts)) { +return bus;/* root matches and isn't full */ + } } pick = match ? bus :NULL ;
qdev-monitor.c static BusState *qbus_find_recursive(BusState *bus, const char *name, · line 412
Quoted 5 lines
qdev-monitor.c +1
-1@@ -406,7 +409,7 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name, QTAILQ_FOREACH(kid, &bus->children, sibling) {DeviceState *dev = kid->child; QLIST_FOREACH(child, &dev->child_bus, sibling) { - ret =qbus_find_recursive (child, name, bus_typename); + ret =qbus_find_recursive (child, name, bus_typename, opts);
Tabs for indentation. There are other occurrences in the patch.
Apart from this,
Quoted 22 lines
qdev-monitor.c +2
-2if (ret && !qbus_is_full (ret)) {return ret;/* a descendant matches and isn't full */ }@@ -436,7 +439,7 @@ static BusState *qbus_find(const char *path, Error **errp)assert (!path[0 ]); elem[0 ] = len =0 ; } - bus =qbus_find_recursive (sysbus_get_default (), elem,NULL ); + bus =qbus_find_recursive (sysbus_get_default (), elem,NULL ,NULL );if (!bus) {error_setg (errp,"Bus '%s' not found" , elem);return NULL ;@@ -542,7 +545,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)return NULL ; } }else if (dc->bus_type !=NULL ) { - bus =qbus_find_recursive (sysbus_get_default (),NULL , dc->bus_type); + bus =qbus_find_recursive (sysbus_get_default (),NULL , dc->bus_type, opts);if (!bus ||qbus_is_full (bus)) {error_setg (errp,"No '%s' bus found for device '%s'" , dc->bus_type, driver);
Re: [Qemu-devel] [PATCH 45/77] qdev: Add a hook for a bus to device if it can add devices
On Wed, 2015-11-18 at 13:34 +0100, Paolo Bonzini wrote:
../..
Quoted 1 line
Tabs for indentation. There are other occurrences in the patch.
Ooops. sorry, missed those. Do you need a respin ?
Quoted 34 lines
Apart from this,
Reviewed-by Paolo Bonzini <[email protected]>Acked-by Paolo Bonzini <[email protected]>Quoted 29 lines
if (ret && !qbus_is_full(ret)) {
return ret; /* a descendant matches and isn't full */
}(quoted diff) +1
-1@@ -436,7 +439,7 @@ static BusState *qbus_find(const char *path, Error **errp) assert(!path[0]); elem[0] = len = 0; } - bus = qbus_find_recursive(sysbus_get_default(), elem, NULL); + bus = qbus_find_recursive(sysbus_get_default(), elem, NULL, NULL);if (!bus) {
error_setg(errp, "Bus '%s' not found", elem); return NULL;(quoted diff) +1
-1@@ -542,7 +545,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp) return NULL; } } else if (dc->bus_type != NULL) { - bus = qbus_find_recursive(sysbus_get_default(), NULL, dc- >bus_type); + bus = qbus_find_recursive(sysbus_get_default(), NULL, dc->bus_type, opts);if (!bus ||
qbus_is_full(bus)) {error_setg(errp, "No '%s' bus found for device '%s'", dc->bus_type, driver);
PATCH 46/77 pci: Use the new pci_can_add_device() to enforce devfn_min/max
In reply to Benjamin HerrenschmidtThis adds a devfn_max field to PCIBus and adds a pci_can_add_device() function which, if no "addr" (aka devfn) is specified, will tell whether there is any slot free between devfn_min and devfn_max.
This will be used by some PCI root complex implementations that support only one direct child to avoid having qemu put dumb devices at different slot numbers.
--- hw/pci/pci.c | 22 ++++++++++++++++++++++ include/hw/pci/pci_bus.h | 1 + 2 files changed, 23 insertions(+)
hw/pci/pci.c +22 -0
@@ -108,6 +108,27 @@ static uint16_t pcibus_numa_node(PCIBus *bus)return NUMA_NODE_UNASSIGNED ; } +static bool pci_can_add_device (BusState *bus,QemuOpts *opts) +{ +unsigned int devfn, max; +PCIBus *pbus =PCI_BUS (bus); + +/* If address is specified, say yes and let it fail if that doesn't work */ +if (qemu_opt_get (opts,"addr" ) !=NULL ) { +return true; + } + max =ARRAY_SIZE (pbus->devices); +if (pbus->devfn_max && pbus->devfn_max < max) { + max = pbus->devfn_max; + } +for (devfn = pbus->devfn_min ; devfn < max; devfn +=PCI_FUNC_MAX ) { +if (!pbus->devices[devfn]) { +break ; + } + } +return devfn < max; +} +static void pci_bus_class_init (ObjectClass *klass,void *data) {BusClass *k =BUS_CLASS (klass);
@@ -119,6 +140,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data) k->realize = pci_bus_realize; k->unrealize = pci_bus_unrealize; k->reset = pcibus_reset; + k->can_add_device = pci_can_add_device; pbc->is_root = pcibus_is_root; pbc->bus_num = pcibus_num;
include/hw/pci/pci_bus.h +1 -0
@@ -23,6 +23,7 @@ struct PCIBus {PCIIOMMUFunc iommu_fn;void *iommu_opaque;uint8_t devfn_min; +uint8_t devfn_max;pci_set_irq_fn set_irq;pci_map_irq_fn map_irq;pci_route_irq_fn route_intx_to_irq;
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH 46/77] pci: Use the new pci_can_add_device() to enforce devfn_min/max
Quoted 9 lines · Benjamin Herrenschmidt
This adds a
devfn_maxfield to PCIBus and adds apci_can_add_device()function which, if no "addr" (aka devfn) is specified, will tell whether there is any slot free betweendevfn_minanddevfn_max.This will be used by some PCI root complex implementations that support only one direct child to avoid having qemu put dumb devices at different slot numbers.
Signed-off-by Benjamin Herrenschmidt <[email protected]>
CCing maintainer.
Paolo
Quoted 58 lines
--- hw/pci/pci.c | 22 ++++++++++++++++++++++ include/hw/pci/pci_bus.h | 1 + 2 files changed, 23 insertions(+)hw/pci/pci.c +22
-0@@ -108,6 +108,27 @@ static uint16_t pcibus_numa_node(PCIBus *bus)return NUMA_NODE_UNASSIGNED ; } +static bool pci_can_add_device (BusState *bus,QemuOpts *opts) +{ +unsigned int devfn, max; +PCIBus *pbus =PCI_BUS (bus); + +/* If address is specified, say yes and let it fail if that doesn't work */ +if (qemu_opt_get (opts,"addr" ) !=NULL ) { +return true; + } + max =ARRAY_SIZE (pbus->devices); +if (pbus->devfn_max && pbus->devfn_max < max) { + max = pbus->devfn_max; + } +for (devfn = pbus->devfn_min ; devfn < max; devfn +=PCI_FUNC_MAX ) { +if (!pbus->devices[devfn]) { +break ; + } + } +return devfn < max; +} +static void pci_bus_class_init (ObjectClass *klass,void *data) {BusClass *k =BUS_CLASS (klass);@@ -119,6 +140,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data) k->realize = pci_bus_realize; k->unrealize = pci_bus_unrealize; k->reset = pcibus_reset; + k->can_add_device = pci_can_add_device; pbc->is_root = pcibus_is_root; pbc->bus_num = pcibus_num;include/hw/pci/pci_bus.h +1
-0@@ -23,6 +23,7 @@ struct PCIBus {PCIIOMMUFunc iommu_fn;void *iommu_opaque;uint8_t devfn_min; +uint8_t devfn_max;pci_set_irq_fn set_irq;pci_map_irq_fn map_irq;pci_route_irq_fn route_intx_to_irq;
PATCH 47/77 pci: Don't call pci_irq_handler() for a negative intx
In reply to Benjamin HerrenschmidtUnder some circumstances, pci_intx() can return -1 (when the interrupt pin in the config space is 0 which normally means no interrupt).
I have seen cases of pci_set_irq() being called on such devices, in turn causing pci_irq_handler() to be called with "-1" as an argument which doesn't seem like a terribly good idea.
--- hw/pci/pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
hw/pci/pci.c +3 -1
@@ -1298,7 +1298,9 @@ qemu_irq pci_allocate_irq(PCIDevice *pci_dev)void pci_set_irq (PCIDevice *pci_dev,int level) {int intx =pci_intx (pci_dev); -pci_irq_handler (pci_dev, intx, level); +if (intx >=0 ) { +pci_irq_handler (pci_dev, intx, level); + } }/* Special hooks used by device assignment */
Signature · 1 line
2.5.0
PATCH 48/77 ppc/pnv: Add model for Power8 PHB3 PCIe Host bridge
In reply to Benjamin HerrenschmidtThis is a model of the PCIe host bridge found on Power8 chips, including IOMMU support, PCIe root complex etc...
This implementation doesn't emulate the EEH error handling (and may never do).
--- hw/intc/xics.c | 2 +- hw/pci-host/Makefile.objs | 2 + hw/pci-host/pnv_phb3.c | 1083 +++++++++++++++++++++++++++++++++++ hw/pci-host/pnv_phb3_msi.c | 338 +++++++++++ hw/pci-host/pnv_phb3_pbcq.c | 314 ++++++++++ hw/pci-host/pnv_phb3_rc.c | 132 +++++ hw/ppc/pnv.c | 22 +- include/hw/pci-host/pnv_phb3.h | 145 +++++ include/hw/pci-host/pnv_phb3_regs.h | 505 ++++++++++++++++ include/hw/ppc/pnv.h | 3 + include/hw/ppc/xics.h | 1 + 11 files changed, 2543 insertions(+), 4 deletions(-) create mode 100644 hw/pci-host/pnv_phb3.c create mode 100644 hw/pci-host/pnv_phb3_msi.c create mode 100644 hw/pci-host/pnv_phb3_pbcq.c create mode 100644 hw/pci-host/pnv_phb3_rc.c create mode 100644 include/hw/pci-host/pnv_phb3.h create mode 100644 include/hw/pci-host/pnv_phb3_regs.h
hw/intc/xics.c +1 -1
@@ -341,7 +341,7 @@ void icp_eoi(XICSState *xics, int server, uint32_t xirr) } } -static void icp_irq (ICSState *ics,int server,int nr,uint8_t priority) +void icp_irq (ICSState *ics,int server,int nr,uint8_t priority) {XICSState *xics = ics->xics;ICPState *ss = xics->ss + server;
hw/pci-host/Makefile.objs +2 -0
@@ -16,3 +16,5 @@ common-obj-$(CONFIG_FULONG) += bonito.o common-obj-$(CONFIG_PCI_PIIX) += piix.o common-obj-$(CONFIG_PCI_Q35) += q35.o common-obj-$(CONFIG_PCI_GENERIC) += gpex.o + +obj-$(CONFIG_POWERNV) += pnv_phb3.o pnv_phb3_pbcq.o pnv_phb3_rc.o pnv_phb3_msi.o
hw/pci-host/pnv_phb3.c new file +1083 -0
1,083 lines not on this page · raw message
hw/pci-host/pnv_phb3_msi.c new file +338 -0
338 lines not on this page · raw message
hw/pci-host/pnv_phb3_pbcq.c new file +314 -0
314 lines not on this page · raw message
hw/pci-host/pnv_phb3_rc.c new file +132 -0
132 lines not on this page · raw message
hw/ppc/pnv.c +19 -3
@@ -44,9 +44,15 @@#include "hw/ppc/xics.h" #include "hw/ppc/pnv_xscom.h" +#include "hw/pci/pci.h" +#include "hw/pci/pci_bus.h" +#include "hw/pci/pci_bridge.h" +#include "hw/pci/msi.h" #include "hw/isa/isa.h" #include "hw/char/serial.h" #include "hw/timer/mc146818rtc.h" +#include "hw/pci-host/pnv_phb3.h" +#include "exec/address-spaces.h" #include "qemu/config-file.h" #include "qemu/error-report.h"
@@ -507,9 +513,11 @@ static void pnv_lpc_irq_handler_cpld(void *opaque, int n, int level) }static void pnv_create_chip (PnvSystem *sys,unsigned int chip_no, -bool has_lpc,bool has_lpc_irq) +bool has_lpc,bool has_lpc_irq, +unsigned int num_phbs) {PnvChip *chip = &sys->chips[chip_no]; +unsigned int i;if (chip_no >=PNV_MAX_CHIPS ) {return ;
@@ -545,6 +553,11 @@ static void pnv_create_chip(PnvSystem *sys, unsigned int chip_no,/* Create the simplified OCC model */ pnv_occ_create (chip); + +/* Create a PCI, for now do one chip with 2 PHBs */ +for (i =0 ; i < num_phbs; i++) { +pnv_phb3_create (chip, sys->xics, i); + } }static void ppc_powernv_init (MachineState *machine)
@@ -568,6 +581,9 @@ static void ppc_powernv_init(MachineState *machine)void *fdt;int i; +/* MSIs are supported on this platform */ + msi_supported = true; +/* Set up Interrupt Controller before we create the VCPUs */ xics =xics_system_init (smp_cpus *kvmppc_smt_threads () / smp_threads,XICS_IRQS_POWERNV );
@@ -607,9 +623,9 @@ static void ppc_powernv_init(MachineState *machine)*/ sys->num_chips =1 ; -/* Create only one chip for now with an LPC bus +/* Create only one chip for now with an LPC bus and one PHB */ -pnv_create_chip (sys,0 , true, false); +pnv_create_chip (sys,0 , true, false,1 );/* Grab chip 0's ISA bus */ isa_bus = sys->chips[0 ].lpc_bus;
include/hw/pci-host/pnv_phb3.h new file +145 -0
145 lines not on this page · raw message
include/hw/pci-host/pnv_phb3_regs.h new file +505 -0
505 lines not on this page · raw message
include/hw/ppc/pnv.h +3 -0
@@ -26,6 +26,7 @@ typedef struct PnvLpcController PnvLpcController;typedef struct PnvPsiController PnvPsiController ;typedef struct XICSState XICSState ;typedef struct PnvOCCState PnvOCCState ; +typedef struct PCIBus PCIBus ;/* Should we turn that into a QOjb of some sort ? */ typedef struct PnvChip {
@@ -35,6 +36,8 @@ typedef struct PnvChip {ISABus *lpc_bus;PnvPsiController *psi;PnvOCCState *occ; +#define PNV_MAX_CHIP_PHB 4 +PCIBus *phb[PNV_MAX_CHIP_PHB ]; } PnvChip; typedef struct PnvSystem {
include/hw/ppc/xics.h +1 -0
@@ -205,6 +205,7 @@ void icp_set_mfrr(XICSState *icp, int server, uint8_t mfrr);uint32_t icp_accept (ICPState *ss);uint32_t icp_ipoll (ICPState *ss,uint32_t *mfrr);void icp_eoi (XICSState *icp,int server,uint32_t xirr); +void icp_irq (ICSState *ics,int server,int nr,uint8_t priority);void ics_simple_write_xive (ICSState *ics,int nr,int server,uint8_t priority,uint8_t saved_priority);
Signature · 1 line
2.5.0
Re: [Qemu-devel] [Qemu-ppc] [PATCH 48/77] ppc/pnv: Add model for Power8 PHB3 PCIe Host bridge
Ben,
Quick question,
Quoted 48 lines
hw/pci-host/pnv_phb3.c new file +48
-0+/* This is called whenever the PHB LSI, MSI source ID register or +* the PBCQ irq filters are written. +*/ +void pnv_phb3_remap_irqs (PnvPhb3State *phb) +{ +uint32_t local, global, count, mask, comp; +uint64_t baren; + +/* First check if we are enabled. Unlike real HW we don't separate TX and RX +* so we enable if both are set +*/ + baren = phb->pbcq->nest_regs[PBCQ_NEST_BAR_EN ]; +if (!(baren &PBCQ_NEST_BAR_EN_IRSN_RX ) || + !(baren &PBCQ_NEST_BAR_EN_IRSN_TX )) { + phb->lsi_ics->offset =0 ; +return ; + } + +/* Grab local LSI source ID */ + local =GETFIELD (PHB_LSI_SRC_ID , phb->regs[PHB_LSI_SOURCE_ID >>3 ]) <<3 ; + +/* Grab global one and compare */ + global =GETFIELD (PBCQ_NEST_LSI_SRC , + phb->pbcq->nest_regs[PBCQ_NEST_LSI_SRC_ID ]) <<3 ; +if (global != local) { +/* This happens during initialization, let's come back when we +* are properly configured +*/ + phb->lsi_ics->offset =0 ; +return ; + } + +/* Get the base on the powerbus */ + comp =GETFIELD (PBCQ_NEST_IRSN_COMP , + phb->pbcq->nest_regs[PBCQ_NEST_IRSN_COMPARE ]); + mask =GETFIELD (PBCQ_NEST_IRSN_COMP , + phb->pbcq->nest_regs[PBCQ_NEST_IRSN_MASK ]); + count = ((~mask) +1 ) &0x7ffff ; + phb->total_irq = count; + +/* Sanity checks */ +if ((global +8 ) > count) { +DBG_MAP (phb,"LSIs out of reach: LSI base=%d total irq=%d" , + global, count); + } +if (count >2048 ) { +DBG_MAP (phb,"More interrupts than supported: %d" , count); + }
hw/pci-host/pnv_phb3.c line 420
Quoted 10 lines
hw/pci-host/pnv_phb3.c new file +10
-0+if ((comp & mask) != comp) { +DBG_MAP (phb,"IRQ compare bits not in mask: comp=0x%x mask=0x%x" , + comp, mask); + comp &= mask; + } +/* Setup LSI offset */ + phb->lsi_ics->offset = comp + global; + +/* Setup MSI offset */ +pnv_phb3_msi_update_config (phb->msis, comp, count);
I changed that to :
pnv_phb3_msi_update_config(phb->msis, comp, count - PHB_NUM_LSI);
else the IRQ numbers overlap with the LSI and I think this why we were uselessly looping on the EOI.
Correct ?
C.
Quoted 5 lines
hw/pci-host/pnv_phb3.c new file +5
-0+ +DBG_MAP (phb,"Initialized for %d interrupts @0x%x, LSI off=%d" , + count, comp, global); +} +
Re: [Qemu-devel] [Qemu-ppc] [PATCH 48/77] ppc/pnv: Add model for Power8 PHB3 PCIe Host bridge
Quoted 9 lines · Cédric Le Goater
I changed that to :
pnv_phb3_msi_update_config(phb->msis, comp, count - PHB_NUM_LSI);else the IRQ numbers overlap with the LSI and I think this why we were
uselessly looping on the EOI.Correct ?
Quite possibly though to be honest, I have swapped out a lot of that out of my brain :-)
Cheers,
Ben.
PATCH 49/77 ppc/pnv: Create a default PCI layout
In reply to Benjamin HerrenschmidtThis creates a legacy PCIe->PCI bridge under the PHB by default to which a bunch of standard devices are attached. Currently:
- VGA (as specified by -vga)
- USB (with keyboard and mouse if graphcis is enabled)
- AHCI
- e1000
This gives us something close to a standard OpenPower platform.
--- hw/ppc/pnv.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-)
hw/ppc/pnv.c +98 -1
@@ -52,6 +52,9 @@#include "hw/char/serial.h" #include "hw/timer/mc146818rtc.h" #include "hw/pci-host/pnv_phb3.h" +#include "hw/usb.h" +#include "hw/ide/pci.h" +#include "hw/ide/ahci.h" #include "exec/address-spaces.h" #include "qemu/config-file.h"
@@ -85,6 +88,9 @@ typedef struct sPowerNVMachineState sPowerNVMachineState;/** * sPowerNVMachineState: */ + +#define MAX_SATA_PORTS 6 +struct sPowerNVMachineState {/*< private >*/ MachineState parent_obj;
@@ -492,6 +498,71 @@ static const VMStateDescription vmstate_powernv = { .minimum_version_id = 1, }; +/* Returns whether we want to use VGA or not */ +static int pnv_vga_init (PCIBus *pci_bus) +{ +switch (vga_interface_type) { +case VGA_NONE : +return false; +case VGA_DEVICE : +return true; +case VGA_STD : +case VGA_VIRTIO : +return pci_vga_init (pci_bus) !=NULL ; +default : +fprintf (stderr,"This vga model is not supported," +"currently it only supports -vga std\n" ); +exit (0 ); + } +} + +static void pnv_nic_init (PCIBus *pci_bus) +{ +int i; + +for (i =0 ; i < nb_nics; i++) { +NICInfo *nd = &nd_table[i]; +DeviceState *dev; +PCIDevice *pdev; +Error *err =NULL ; + + pdev =pci_create (pci_bus,-1 ,"e1000" ); + dev = &pdev->qdev; +qdev_set_nic_properties (dev, nd); +object_property_set_bool (OBJECT (dev), true,"realized" , &err); +if (err) { +error_report_err (err); +object_unparent (OBJECT (dev)); +exit (1 ); + } + } +} + +static void pnv_storage_init (PCIBus *pci_bus) +{ +DriveInfo *hd[MAX_SATA_PORTS ]; +PCIDevice *ahci; + +/* Add an AHCI device. We use an ICH9 since that's all we have +* at hand for PCI AHCI but it shouldn't really matter +*/ + ahci =pci_create_simple (pci_bus,-1 ,"ich9-ahci" ); +g_assert (MAX_SATA_PORTS ==ICH_AHCI (ahci)->ahci.ports); +ide_drive_get (hd,ICH_AHCI (ahci)->ahci.ports); +ahci_ide_create_devs (ahci, hd); +} + +static PCIBus *pnv_create_pci_legacy_bridge (PCIBus *parent,uint8_t chassis_nr) +{ +PCIDevice *dev; + + dev =pci_create_multifunction (parent,0 , false,"pci-bridge" ); +qdev_prop_set_uint8 (&dev->qdev,"chassis_nr" , chassis_nr); + dev->qdev.id ="pci" ; +qdev_init_nofail (&dev->qdev); +return pci_bridge_get_sec_bus (PCI_BRIDGE (dev)); +} +static void pnv_lpc_irq_handler_cpld (void *opaque,int n,int level) {#define MAX_ISA_IRQ 16
@@ -575,7 +646,9 @@ static void ppc_powernv_init(MachineState *machine)sPowerNVMachineState *pnv_machine =POWERNV_MACHINE (machine);PnvSystem *sys = &pnv_machine->sys;XICSState *xics; +PCIBus *pbus;ISABus *isa_bus; +bool has_gfx = false;long fw_size;char *filename;void *fdt;
@@ -636,6 +709,30 @@ static void ppc_powernv_init(MachineState *machine)/* Create an RTC ISA device too */ rtc_init (isa_bus,2000 ,NULL ); +/* Add a PCI switch */ + pbus =pnv_create_pci_legacy_bridge (sys->chips[0 ].phb[0 ],128 ); + +/* Graphics */ +if (pnv_vga_init (pbus)) { + has_gfx = true; + machine->usb |=defaults_enabled () && !machine->usb_disabled; + } +if (machine->usb) { +pci_create_simple (pbus,-1 ,"nec-usb-xhci" ); +if (has_gfx) { +USBBus *usb_bus =usb_bus_find (-1 ); + +usb_create_simple (usb_bus,"usb-kbd" ); +usb_create_simple (usb_bus,"usb-mouse" ); + } + } + +/* Add NIC */ +pnv_nic_init (pbus); + +/* Add storage */ +pnv_storage_init (pbus); +if (bios_name ==NULL ) { bios_name =FW_FILE_NAME ; }
@@ -709,7 +806,7 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data)NMIClass *nc =NMI_CLASS (oc); mc->init = ppc_powernv_init; - mc->block_default_type =IF_SCSI ; + mc->block_default_type =IF_IDE ; mc->max_cpus =MAX_CPUS ; mc->no_parallel =1 ; mc->default_boot_order =NULL ;
Signature · 1 line
2.5.0
PATCH 50/77 ppc: Update LPCR definitions
In reply to Benjamin HerrenschmidtIncludes all the bits up to ISA 2.07
--- target-ppc/cpu.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
target-ppc/cpu.h +13 -3
@@ -493,12 +493,16 @@ struct ppc_slb_t {#define LPCR_VPM1 (1ull << (63-1))#define LPCR_ISL (1ull << (63-2))#define LPCR_KBV (1ull << (63-3)) +#define LPCR_DPFD_SHIFT (63-11) +#define LPCR_DPFD (0x3ull << LPCR_DPFD_SHIFT) +#define LPCR_VRMASD_SHIFT (63-16) +#define LPCR_VRMASD (0x1full << LPCR_VRMASD_SHIFT) +#define LPCR_RMLS_SHIFT (63-37) +#define LPCR_RMLS (0xfull << LPCR_RMLS_SHIFT)#define LPCR_ILE (1ull << (63-38)) -#define LPCR_MER (1ull << (63-52)) -#define LPCR_LPES0 (1ull << (63-60)) -#define LPCR_LPES1 (1ull << (63-61))#define LPCR_AIL_SHIFT (63-40)/* Alternate interrupt location */ #define LPCR_AIL (3ull << LPCR_AIL_SHIFT) +#define LPCR_ONL (1ull << (63-45))#define LPCR_P7_PECE0 (1ull << (63-49))#define LPCR_P7_PECE1 (1ull << (63-50))#define LPCR_P7_PECE2 (1ull << (63-51))
@@ -507,6 +511,12 @@ struct ppc_slb_t {#define LPCR_P8_PECE2 (1ull << (63-49))#define LPCR_P8_PECE3 (1ull << (63-50))#define LPCR_P8_PECE4 (1ull << (63-51)) +#define LPCR_MER (1ull << (63-52)) +#define LPCR_TC (1ull << (63-54)) +#define LPCR_LPES0 (1ull << (63-60)) +#define LPCR_LPES1 (1ull << (63-61)) +#define LPCR_RMI (1ull << (63-62)) +#define LPCR_HDICE (1ull << (63-63))#define msr_sf ((env->msr >> MSR_SF) & 1)#define msr_isf ((env->msr >> MSR_ISF) & 1)
Signature · 1 line
2.5.0
PATCH 51/77 ppc: Use a helper to filter writes to LPCR
In reply to Benjamin HerrenschmidtThis handles filtering bits based on what is implemented by a given architecture version. We also use it to copy to LPCR some of the relevant 970 HID4 bits.
--- target-ppc/helper.h | 1 + target-ppc/mmu-hash64.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ target-ppc/translate_init.c | 56 ++++++++++++++++++++++++++++--------------- 3 files changed, 96 insertions(+), 19 deletions(-)
target-ppc/helper.h +1 -0
@@ -16,6 +16,7 @@ DEF_HELPER_1(rfmci, void, env) DEF_HELPER_2(pminsn, void, env, i32) DEF_HELPER_1(rfid, void, env) DEF_HELPER_1(hrfid, void, env) +DEF_HELPER_2(store_lpcr, void, env, tl)#endif DEF_HELPER_1(check_tlb_flush, void, env)#endif
target-ppc/mmu-hash64.c +58 -0
61 lines not on this page · raw message
target-ppc/translate_init.c +37 -19
75 lines not on this page · raw message
Signature · 1 line
2.5.0
PATCH 52/77 ppc: Cosmetic, align some comments
In reply to Benjamin Herrenschmidt--- target-ppc/mmu-hash32.c | 4 ++-- target-ppc/mmu_helper.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-)
target-ppc/mmu-hash32.c +2 -2
@@ -41,8 +41,8 @@struct mmu_ctx_hash32 {hwaddr raddr;/* Real address */ -int prot;/* Protection bits */ -int key;/* Access key */ +int prot;/* Protection bits */ +int key;/* Access key */ };static int ppc_hash32_pp_prot (int key,int pp,int nx)
target-ppc/mmu_helper.c +4 -4
@@ -58,11 +58,11 @@ typedef struct mmu_ctx_t mmu_ctx_t;struct mmu_ctx_t {hwaddr raddr;/* Real address */ hwaddr eaddr;/* Effective address */ -int prot;/* Protection bits */ +int prot;/* Protection bits */ hwaddr hash[2 ];/* Pagetable hash values */ -target_ulong ptem;/* Virtual segment ID | API */ -int key;/* Access key */ -int nx;/* Non-execute area */ +target_ulong ptem;/* Virtual segment ID | API */ +int key;/* Access key */ +int nx;/* Non-execute area */ };/* Common routines used by software and hardware TLBs emulation */
Signature · 1 line
2.5.0
PATCH 53/77 ppc: Add proper real mode translation support
In reply to Benjamin HerrenschmidtThis adds proper support for translating real mode addresses based on the combination of HV and LPCR bits. This handles HRMOR offset for hypervisor real mode, and both RMA and VRMA modes for guest real mode. PAPR mode adjusts the offsets appropriately to match the RMA used in TCG, but we need to limit to the max supported by the implementation (16G).
--- hw/ppc/spapr.c | 7 +++ target-ppc/mmu-hash64.c | 146 ++++++++++++++++++++++++++++++++++++++------ target-ppc/mmu-hash64.h | 1 + target-ppc/translate_init.c | 10 ++- 4 files changed, 144 insertions(+), 20 deletions(-)
hw/ppc/spapr.c +7 -0
@@ -1741,6 +1741,13 @@ static void ppc_spapr_init(MachineState *machine) spapr->vrma_adjust =1 ; spapr->rma_size =MIN (spapr->rma_size,0x10000000 ); } + +/* Actually we don't support unbounded RMA anymore since we +* added proper emulation of HV mode. The max we can get is +* 16G which also happens to be what we configure for PAPR +* mode so make sure we don't do anything bigger than that +*/ + spapr->rma_size =MIN (spapr->rma_size,0x400000000ull ); }if (spapr->rma_size > node0_size) {
target-ppc/mmu-hash64.c +127 -19
213 lines not on this page · raw message
target-ppc/mmu-hash64.h +1 -0
@@ -29,6 +29,7 @@ void ppc_hash64_store_hpte(CPUPPCState *env, target_ulong index,#define SLB_VSID_B_256M 0x0000000000000000ULL#define SLB_VSID_B_1T 0x4000000000000000ULL#define SLB_VSID_VSID 0x3FFFFFFFFFFFF000ULL +#define SLB_VSID_VRMA (0x0001FFFFFF000000ULL | SLB_VSID_B_1T)#define SLB_VSID_PTEM (SLB_VSID_B | SLB_VSID_VSID)#define SLB_VSID_KS 0x0000000000000800ULL#define SLB_VSID_KP 0x0000000000000400ULL
target-ppc/translate_init.c +9 -1
@@ -8558,11 +8558,19 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)/* Set emulated LPCR to not send interrupts to hypervisor. Note that * under KVM, the actual HW LPCR will be set differently by KVM itself, * the settings below ensure proper operations with TCG in absence of -* a real hypervisor +* a real hypervisor. +* +* Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for +* real mode accesses, which thankfully defaults to 0 and isn't +* accessible in guest mode. */ lpcr->default_value &= ~(LPCR_VPM0 |LPCR_VPM1 |LPCR_ISL |LPCR_KBV ); lpcr->default_value |=LPCR_LPES0 |LPCR_LPES1 ; +/* Set RMLS to the max (ie, 16G) */ + lpcr->default_value &= ~LPCR_RMLS ; + lpcr->default_value |=1ull <<LPCR_RMLS_SHIFT ; +/* P7 and P8 has slightly different PECE bits, mostly because P8 adds * bit 47 and 48 which are reserved on P7. Here we set them all, which * will work as expected for both implementations
Signature · 1 line
2.5.0
PATCH 54/77 ppc: Fix 64K pages support in full emulation
In reply to Benjamin HerrenschmidtWe were always advertising only 4K & 16M. Additionally the code wasn't properly matching the page size with the PTE content, which meant we could potentially hit an incorrect PTE if the guest used multiple sizes.
Finally, honor the CPU capabilities when decoding the size from the SLB so we don't try to use 64K pages on 970.
This still doesn't add support for MPSS (Multiple Page Sizes per Segment)
--- hw/ppc/spapr_hcall.c | 10 +++------ target-ppc/cpu.h | 7 ++++-- target-ppc/mmu-hash64.c | 54 +++++++++++++++++++++++++++++++++++---------- target-ppc/translate_init.c | 22 +++++++++++++++--- 4 files changed, 69 insertions(+), 24 deletions(-)
hw/ppc/spapr_hcall.c +3 -7
@@ -56,7 +56,6 @@ static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r, va_low &=0x7ff ;if (v &HPTE64_V_LARGE ) { rb |=1 ;/* L field */ -#if 0 /* Disable that P7 specific bit for now */ if (r &0xff000 ) {/* non-16MB large page, must be 64k */ /* (masks depend on page size) */
@@ -64,7 +63,6 @@ static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r, rb |= (va_low &0x7f ) <<16 ;/* 7b of VA in AVA/LP field */ rb |= (va_low &0xfe );/* AVAL field */ } -#endif }else {/* 4kB page */ rb |= (va_low &0x7ff ) <<12 ;/* remaining 11b of AVA */
@@ -98,14 +96,12 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,target_ulong index;uint64_t token; -/* only handle 4k and 16M pages for now */ +/* Handle non-4K pages */ if (pteh &HPTE64_V_LARGE ) { -#if 0 /* We don't support 64k pages yet */ if ((ptel &0xf000 ) ==0x1000 ) {/* 64k page */ - } else -#endif -if ((ptel &0xff000 ) ==0 ) { + page_shift =16 ; + }else if ((ptel &0xff000 ) ==0 ) {/* 16M page */ page_shift =24 ;/* lowest AVA bit must be 0 for 16M pages */
target-ppc/cpu.h +5 -2
@@ -115,16 +115,19 @@ enum powerpc_mmu_t {#define POWERPC_MMU_64 0x00010000#define POWERPC_MMU_1TSEG 0x00020000#define POWERPC_MMU_AMR 0x00040000 +#define POWERPC_MMU_64K 0x00080000/* 64 bits PowerPC MMU */ POWERPC_MMU_64B =POWERPC_MMU_64 |0x00000001 ,/* Architecture 2.03 and later (has LPCR) */ POWERPC_MMU_2_03 =POWERPC_MMU_64 |0x00000002 ,/* Architecture 2.06 variant */ POWERPC_MMU_2_06 =POWERPC_MMU_64 |POWERPC_MMU_1TSEG - |POWERPC_MMU_AMR |0x00000003 , + |POWERPC_MMU_AMR |POWERPC_MMU_64K + |0x00000003 ,/* Architecture 2.07 variant */ POWERPC_MMU_2_07 =POWERPC_MMU_64 |POWERPC_MMU_1TSEG - | POWERPC_MMU_AMR | 0x00000004, + |POWERPC_MMU_AMR |POWERPC_MMU_64K + | 0x00000004, #endif /* defined(TARGET_PPC64) */ };
target-ppc/mmu-hash64.c +42 -12
120 lines not on this page · raw message
target-ppc/translate_init.c +19 -3
@@ -9998,8 +9998,8 @@ static void ppc_cpu_initfn(Object *obj)if (pcc->sps) { env->sps = *pcc->sps; }else if (env->mmu_model &POWERPC_MMU_64 ) { -/* Use default sets of page sizes */ -static const struct ppc_segment_page_sizes defsps = { +/* Use default sets of page sizes. We don't support MPSS */ +static const struct ppc_segment_page_sizes defsps_4k = { .sps = { { .page_shift =12 ,/* 4K */ .slb_enc =0 ,
@@ -10011,7 +10011,23 @@ static void ppc_cpu_initfn(Object *obj) }, }, }; - env->sps = defsps; +static const struct ppc_segment_page_sizes defsps_64k = { + .sps = { + { .page_shift =12 ,/* 4K */ + .slb_enc =0 , + .enc = { { .page_shift =12 , .pte_enc =0 } } + }, + { .page_shift =16 ,/* 64K */ + .slb_enc =0x110 , + .enc = { { .page_shift =16 , .pte_enc =1 } } + }, + { .page_shift =24 ,/* 16M */ + .slb_enc =0x100 , + .enc = { { .page_shift =24 , .pte_enc =0 } } + }, + }, + }; + env->sps = (env->mmu_model &POWERPC_MMU_64K ) ? defsps_64k : defsps_4k; }#endif /* defined(TARGET_PPC64) */
Signature · 1 line
2.5.0
PATCH 55/77 ppc/pnv+spapr: Add "ibm, pa-features" property to the device-tree
In reply to Benjamin HerrenschmidtThis is currently missing on both PowerNV and PAPR
FIXME: Split patch & fix tabs
--- hw/ppc/pnv.c | 8 ++++++++ target-ppc/translate_init.c | 1 + 2 files changed, 9 insertions(+)
hw/ppc/pnv.c +8 -0
@@ -275,6 +275,11 @@ static void powernv_create_cpu_node(void *fdt, CPUState *cs, int smt_threads)uint32_t page_sizes_prop[64 ];size_t page_sizes_prop_size;char *nodename; +const uint8_t pa_features[] = {24 ,0 , +0xf6 ,0x3f ,0xc7 ,0xc0 ,0x80 ,0xf0 , +0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x80 ,0x00 , +0x80 ,0x00 ,0x80 ,0x00 ,0x80 ,0x00 };if ((index % smt_threads) !=0 ) {return ;
@@ -349,6 +354,9 @@ static void powernv_create_cpu_node(void *fdt, CPUState *cs, int smt_threads) page_sizes_prop, page_sizes_prop_size))); } +_FDT ((fdt_property (fdt,"ibm,pa-features" , + pa_features,sizeof (pa_features)))); +/* XXX Just a hack for now */ _FDT ((fdt_property_cell (fdt,"ibm,chip-id" ,0 )));
target-ppc/translate_init.c +1 -0
@@ -10028,6 +10028,7 @@ static void ppc_cpu_initfn(Object *obj) }, }; env->sps = (env->mmu_model &POWERPC_MMU_64K ) ? defsps_64k : defsps_4k; + env->ci_large_pages = env->mmu_model >=POWERPC_MMU_2_06 ; }#endif /* defined(TARGET_PPC64) */
Signature · 1 line
2.5.0
PATCH 56/77 ppc: Fix conditions for delivering external interrupts to a guest
In reply to Benjamin HerrenschmidtExternal interrupts can bypass the MSR_EE test if they occur in guest mode and LPES0 is clear. In that case they are directed to the hypervisor
--- target-ppc/excp_helper.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
target-ppc/excp_helper.c +8 -11
@@ -795,6 +795,14 @@ static void ppc_hw_interrupt(CPUPPCState *env)return ; } } +/* Extermal interrupt can ignore MSR:EE under some circumstances */ +if (env->pending_interrupts & (1 <<PPC_INTERRUPT_EXT )) { +bool lpes0 = !!(env->spr[SPR_LPCR ] &LPCR_LPES0 ); +if (msr_ee !=0 || (env->has_hv_mode && msr_hv ==0 && !lpes0)) { +powerpc_excp (cpu, env->excp_model,POWERPC_EXCP_EXTERNAL ); +return ; + } + }if (msr_ce !=0 ) {/* External critical interrupt */ if (env->pending_interrupts & (1 <<PPC_INTERRUPT_CEXT )) {
@@ -840,17 +848,6 @@ static void ppc_hw_interrupt(CPUPPCState *env)powerpc_excp (cpu, env->excp_model,POWERPC_EXCP_DECR );return ; } -/* External interrupt */ -if (env->pending_interrupts & (1 <<PPC_INTERRUPT_EXT )) { -/* Taking an external interrupt does not clear the external -* interrupt status -*/ -#if 0 - env->pending_interrupts &= ~(1 <<PPC_INTERRUPT_EXT ); -#endif -powerpc_excp (cpu, env->excp_model,POWERPC_EXCP_EXTERNAL ); -return ; - }if (env->pending_interrupts & (1 <<PPC_INTERRUPT_DOORBELL )) { env->pending_interrupts &= ~(1 <<PPC_INTERRUPT_DOORBELL );powerpc_excp (cpu, env->excp_model,POWERPC_EXCP_DOORI );
Signature · 1 line
2.5.0
PATCH 57/77 ppc: Enforce setting MSR:EE, IR and DR when MSR:PR is set
In reply to Benjamin HerrenschmidtThe architecture specifies that any instruction that sets MSR:PR will also set MSR:EE, IR and DR.
--- target-ppc/helper_regs.h | 4 ++++ 1 file changed, 4 insertions(+)
target-ppc/helper_regs.h +4 -0
@@ -136,6 +136,10 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,/* Change the exception prefix on PowerPC 601 */ env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000; } +/* If PR=1 then EE, IR and DR must be 1 */ +if ((value >>MSR_PR ) &1 ) { + value |= (1 <<MSR_EE ) | (1 <<MSR_DR ) | (1 <<MSR_IR ); + }#endif env->msr = value;hreg_compute_hflags (env);
Signature · 1 line
2.5.0
PATCH 58/77 ppc: Initial HDEC support
In reply to Benjamin HerrenschmidtThe current behaviour isn't completely right, as for the DEC, we don't properly re-arm when wrapping around, but I will fix this in a separate patch.
--- hw/ppc/ppc.c | 17 ++++++++++++----- target-ppc/excp_helper.c | 22 ++++++++++++---------- target-ppc/helper.h | 2 ++ target-ppc/timebase_helper.c | 10 ++++++++++ target-ppc/translate_init.c | 30 ++++++++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 15 deletions(-)
hw/ppc/ppc.c +12 -5
@@ -698,9 +698,18 @@ static inline void cpu_ppc_decr_lower(PowerPCCPU *cpu)static inline void cpu_ppc_hdecr_excp (PowerPCCPU *cpu) { +CPUPPCState *env = &cpu->env; +/* Raise it */ -LOG_TB ("raise decrementer exception\n" ); -ppc_set_irq (cpu,PPC_INTERRUPT_HDECR ,1 ); +LOG_TB ("raise hv decrementer exception\n" ); + +/* The architecture specifies that we don't deliver HDEC +* interrupts in a PM state. Not only they don't cause a +* wakeup but they also get effectively discarded. +*/ +if (!env->in_pm_state) { +ppc_set_irq (cpu,PPC_INTERRUPT_HDECR ,1 ); + } }static inline void cpu_ppc_hdecr_lower (PowerPCCPU *cpu)
@@ -927,9 +936,7 @@ clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq) }/* Create new timer */ tb_env->decr_timer =timer_new_ns (QEMU_CLOCK_VIRTUAL , &cpu_ppc_decr_cb, cpu); -if (0 ) { -/* XXX: find a suitable condition to enable the hypervisor decrementer -*/ +if (env->has_hv_mode) { tb_env->hdecr_timer =timer_new_ns (QEMU_CLOCK_VIRTUAL , &cpu_ppc_hdecr_cb, cpu); }else {
target-ppc/excp_helper.c +12 -10
@@ -753,7 +753,6 @@ void ppc_cpu_do_interrupt(CPUState *cs)static void ppc_hw_interrupt (CPUPPCState *env) {PowerPCCPU *cpu =ppc_env_get_cpu (env); -int hdice;#if 0 CPUState *cs =CPU (cpu);
@@ -782,15 +781,13 @@ static void ppc_hw_interrupt(CPUPPCState *env) return; }#endif -if (0 ) { -/* XXX: find a suitable condition to enable the hypervisor mode */ - hdice = env->spr[SPR_LPCR ] &1 ; - }else { - hdice =0 ; - } -if ((msr_ee !=0 || msr_hv ==0 || msr_pr !=0 ) && hdice !=0 ) { -/* Hypervisor decrementer exception */ -if (env->pending_interrupts & (1 <<PPC_INTERRUPT_HDECR )) { +/* Hypervisor decrementer exception */ +if (env->pending_interrupts & (1 <<PPC_INTERRUPT_HDECR )) { +/* LPCR will be clear when not supported so this will work */ +bool hdice = !!(env->spr[SPR_LPCR ] &LPCR_HDICE ); +if ((msr_ee !=0 || msr_hv ==0 ) && hdice) { +/* HDEC clears on delivery */ + env->pending_interrupts &= ~(1 <<PPC_INTERRUPT_HDECR );powerpc_excp (cpu, env->excp_model,POWERPC_EXCP_HDECR );return ; }
@@ -942,6 +939,11 @@ void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn) cs->halted =1 ; env->in_pm_state = true; +/* The architecture specifies that HDEC interrupts are +* discarded in PM states +*/ + env->pending_interrupts &= ~(1 <<PPC_INTERRUPT_HDECR ); +/* Technically, nap doesn't set EE, but if we don't set it * then ppc_hw_interrupt() won't deliver. We could add some * other tests there based on LPCR but it's simpler to just
target-ppc/helper.h +2 -0
@@ -598,6 +598,8 @@ DEF_HELPER_2(store_601_rtcl, void, env, tl) DEF_HELPER_2(store_601_rtcu, void, env, tl) DEF_HELPER_1(load_decr, tl, env) DEF_HELPER_2(store_decr, void, env, tl) +DEF_HELPER_1(load_hdecr, tl, env) +DEF_HELPER_2(store_hdecr, void, env, tl) DEF_HELPER_2(store_hid0_601, void, env, tl) DEF_HELPER_3(store_403_pbr, void, env, i32, tl)DEF_HELPER_1 (load_40x_pit, tl, env)
target-ppc/timebase_helper.c +10 -0
@@ -100,6 +100,16 @@ void helper_store_decr(CPUPPCState *env, target_ulong val)cpu_ppc_store_decr (env, val); } +target_ulong helper_load_hdecr (CPUPPCState *env) +{ +return cpu_ppc_load_hdecr (env); +} + +void helper_store_hdecr (CPUPPCState *env,target_ulong val) +{ +cpu_ppc_store_hdecr (env, val); +} +target_ulong helper_load_40x_pit (CPUPPCState *env) {return load_40x_pit (env);
target-ppc/translate_init.c +30 -0
@@ -292,6 +292,32 @@ static void spr_read_purr (DisasContext *ctx, int gprn, int sprn) {gen_helper_load_purr (cpu_gpr[gprn], cpu_env); } + +/* HDECR */ +static void spr_read_hdecr (DisasContext *ctx,int gprn,int sprn) +{ +if (ctx->tb->cflags &CF_USE_ICOUNT ) { +gen_io_start (); + } +gen_helper_load_hdecr (cpu_gpr[gprn], cpu_env); +if (ctx->tb->cflags &CF_USE_ICOUNT ) { +gen_io_end (); +gen_stop_exception (ctx); + } +} + +static void spr_write_hdecr (DisasContext *ctx,int sprn,int gprn) +{ +if (ctx->tb->cflags &CF_USE_ICOUNT ) { +gen_io_start (); + } +gen_helper_store_hdecr (cpu_env, cpu_gpr[gprn]); +if (ctx->tb->cflags &CF_USE_ICOUNT ) { +gen_io_end (); +gen_stop_exception (ctx); + } +} +#endif #endif
@@ -7716,6 +7742,10 @@ static void gen_spr_power5p_lpar(CPUPPCState *env)SPR_NOACCESS ,SPR_NOACCESS , &spr_read_generic, &spr_write_lpcr, KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1); +spr_register_hv (env,SPR_HDEC ,"HDEC" , +SPR_NOACCESS ,SPR_NOACCESS , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_hdecr, &spr_write_hdecr,0 );#endif }
Signature · 1 line
2.5.0
PATCH 59/77 ppc: Add placeholder SPRs for DPDES and DHDES on P8
In reply to Benjamin HerrenschmidtWe still need to eventually implement doorbells but at least this makes us not crash when the SPRs are accessed.
--- target-ppc/cpu.h | 2 ++ target-ppc/translate_init.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+)
target-ppc/cpu.h +2 -0
@@ -1395,6 +1395,8 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_UAMOR (0x09D)#define SPR_MPC_ICTRL (0x09E)#define SPR_MPC_BAR (0x09F) +#define SPR_DHDES (0x0B1) +#define SPR_DPDES (0x0B0)#define SPR_DAWR (0x0B4)#define SPR_RPR (0x0BA)#define SPR_DAWRX (0x0BC)
target-ppc/translate_init.c +17 -0
@@ -8059,6 +8059,22 @@ static void gen_spr_power8_rpr(CPUPPCState *env)#endif } +static void gen_spr_power8_dbell (CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY ) +spr_register_hv (env,SPR_DPDES ,"DPDES" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +0 ); +spr_register_hv (env,SPR_DHDES ,"DHDES" , +SPR_NOACCESS ,SPR_NOACCESS , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +0 ); +#endif +} +static void init_proc_book3s_64 (CPUPPCState *env,int version) {gen_spr_ne_601 (env);
@@ -8111,6 +8127,7 @@ static void init_proc_book3s_64(CPUPPCState *env, int version)gen_spr_power8_tm (env);gen_spr_vtb (env);gen_spr_power8_rpr (env); +gen_spr_power8_dbell (env); }if (version <BOOK3S_CPU_POWER8 ) {gen_spr_book3s_dbg (env);
Signature · 1 line
2.5.0
PATCH 60/77 ppc: LPCR is a HV resource
In reply to Benjamin HerrenschmidtDon't allow access in guest mode
--- target-ppc/translate_init.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
target-ppc/translate_init.c +5 -4
@@ -7738,10 +7738,11 @@ static void gen_spr_power5p_lpar(CPUPPCState *env) {#if !defined(CONFIG_USER_ONLY )/* Logical partitionning */ -spr_register_kvm (env,SPR_LPCR ,"LPCR" , -SPR_NOACCESS ,SPR_NOACCESS , - &spr_read_generic, &spr_write_lpcr, -KVM_REG_PPC_LPCR ,LPCR_LPES0 |LPCR_LPES1 ); +spr_register_kvm_hv (env,SPR_LPCR ,"LPCR" , +SPR_NOACCESS ,SPR_NOACCESS , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_lpcr, +KVM_REG_PPC_LPCR ,LPCR_LPES0 |LPCR_LPES1 ); spr_register_hv(env, SPR_HDEC, "HDEC", SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS,
Signature · 1 line
2.5.0
PATCH 61/77 ppc: SPURR & PURR are HV writeable and privileged
In reply to Benjamin HerrenschmidtThose are HV writeable, so we provide a dummy write. We eventually need to provide a better emulation but for now this will get us going.
We also make them non-user readable as per the architecture.
--- target-ppc/translate_init.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
target-ppc/translate_init.c +16 -8
@@ -293,6 +293,12 @@ static void spr_read_purr (DisasContext *ctx, int gprn, int sprn)gen_helper_load_purr (cpu_gpr[gprn], cpu_env); } +__attribute__ (( unused )) +static void spr_write_purr (DisasContext *ctx,int gprn,int sprn) +{ +// Temporary placeholder +} +/* HDECR */ static void spr_read_hdecr (DisasContext *ctx,int gprn,int sprn) {
@@ -7860,14 +7866,16 @@ static void gen_spr_book3s_purr(CPUPPCState *env) {#if !defined(CONFIG_USER_ONLY )/* PURR & SPURR: Hack - treat these as aliases for the TB for now */ -spr_register_kvm (env,SPR_PURR ,"PURR" , - &spr_read_purr,SPR_NOACCESS , - &spr_read_purr,SPR_NOACCESS , -KVM_REG_PPC_PURR ,0x00000000 ); -spr_register_kvm (env,SPR_SPURR ,"SPURR" , - &spr_read_purr,SPR_NOACCESS , - &spr_read_purr,SPR_NOACCESS , -KVM_REG_PPC_SPURR ,0x00000000 ); +spr_register_kvm_hv (env,SPR_PURR ,"PURR" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_purr,SPR_NOACCESS , + &spr_read_purr, &spr_write_purr, +KVM_REG_PPC_PURR ,0x00000000 ); +spr_register_kvm_hv (env,SPR_SPURR ,"SPURR" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_purr,SPR_NOACCESS , + &spr_read_purr, &spr_write_purr, +KVM_REG_PPC_SPURR ,0x00000000 );#endif }
Signature · 1 line
2.5.0
PATCH 62/77 ppc: Add dummy SPR_IC for POWER8
In reply to Benjamin HerrenschmidtIt's supposed to be an instruction counter. For now make us not crash when accessing it.
--- target-ppc/cpu.h | 1 + target-ppc/translate_init.c | 12 ++++++++++++ 2 files changed, 13 insertions(+)
target-ppc/cpu.h +1 -0
@@ -1690,6 +1690,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_MPC_MD_DBRAM1 (0x32A)#define SPR_RCPU_L2U_RA3 (0x32B)#define SPR_TAR (0x32F) +#define SPR_IC (0x350)#define SPR_VTB (0x351)#define SPR_MMCRC (0x353)#define SPR_440_INV0 (0x370)
target-ppc/translate_init.c +12 -0
@@ -8084,6 +8084,17 @@ static void gen_spr_power8_dbell(CPUPPCState *env)#endif } +static void gen_spr_power8_ic (CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY ) +spr_register_hv (env,SPR_IC ,"IC" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +0 ); +#endif +} +static void init_proc_book3s_64 (CPUPPCState *env,int version) {gen_spr_ne_601 (env);
@@ -8137,6 +8148,7 @@ static void init_proc_book3s_64(CPUPPCState *env, int version)gen_spr_vtb (env);gen_spr_power8_rpr (env);gen_spr_power8_dbell (env); +gen_spr_power8_ic (env); }if (version <BOOK3S_CPU_POWER8 ) {gen_spr_book3s_dbg (env);
Signature · 1 line
2.5.0
PATCH 63/77 ppc: Initialize AMOR in PAPR mode
In reply to Benjamin HerrenschmidtMake sure we give the guest full authorization
--- target-ppc/translate_init.c | 4 ++++ 1 file changed, 4 insertions(+)
target-ppc/translate_init.c +4 -0
@@ -8615,6 +8615,7 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu) {CPUPPCState *env = &cpu->env;ppc_spr_t *lpcr = &env->spr_cb[SPR_LPCR ]; +ppc_spr_t *amor = &env->spr_cb[SPR_AMOR ];/* PAPR always has exception vectors in RAM not ROM. To ensure this, * MSR[IP] should never be set.
@@ -8651,6 +8652,9 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)*/ env->spr[SPR_LPCR ] = lpcr->default_value; +/* Set a full AMOR so guest can use the AMR as it sees fit */ + env->spr[SPR_AMOR ] = amor->default_value =0xffffffffffffffffull ; +/* Tell KVM that we're in PAPR mode */ if (kvm_enabled ()) {kvmppc_set_papr (cpu);
Signature · 1 line
2.5.0
PATCH 64/77 ppc: Fix writing to AMR/UAMOR
In reply to Benjamin HerrenschmidtThe masks weren't chosen nor applied properly. The architecture specifies that writes to AMR are masked by UAMOR for PR=1, otherwise AMOR for HV=0.
The writes to UAMOR are masked by AMOR for HV=0
--- target-ppc/translate_init.c | 76 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 16 deletions(-)
target-ppc/translate_init.c +60 -16
@@ -1094,30 +1094,72 @@ static void gen_spr_7xx (CPUPPCState *env)#ifdef TARGET_PPC64 #ifndef CONFIG_USER_ONLY -static void spr_read_uamr (DisasContext *ctx,int gprn,int sprn) +static void spr_write_amr (DisasContext *ctx,int sprn,int gprn) { -gen_load_spr (cpu_gpr[gprn],SPR_AMR ); -spr_load_dump_spr (SPR_AMR ); -} +TCGv t0 =tcg_temp_new (); +TCGv t1 =tcg_temp_new (); +TCGv t2 =tcg_temp_new (); -static void spr_write_uamr (DisasContext *ctx,int sprn,int gprn) -{ -gen_store_spr (SPR_AMR , cpu_gpr[gprn]); +/* Note, the HV=1 PR=0 case is handled earlier by simply using +* spr_write_generic for HV mode in the SPR table +*/ + +/* Build insertion mask into t1 based on context */ +if (ctx->pr) { +gen_load_spr (t1,SPR_UAMOR ); + }else { +gen_load_spr (t1,SPR_AMOR ); + } + +/* Mask new bits into t2 */ +tcg_gen_and_tl (t2, t1, cpu_gpr[gprn]); + +/* Load AMR and clear new bits in t0 */ +gen_load_spr (t0,SPR_AMR ); +tcg_gen_andc_tl (t0, t0, t1); + +/* Or'in new bits and write it out */ +tcg_gen_or_tl (t0, t0, t2); +gen_store_spr (SPR_AMR , t0);spr_store_dump_spr (SPR_AMR ); + +tcg_temp_free (t0); +tcg_temp_free (t1); +tcg_temp_free (t2); } -static void spr_write_uamr_pr (DisasContext *ctx,int sprn,int gprn) +static void spr_write_uamor (DisasContext *ctx,int sprn,int gprn) {TCGv t0 =tcg_temp_new (); +TCGv t1 =tcg_temp_new (); +TCGv t2 =tcg_temp_new (); + +/* Note, the HV=1 case is handled earlier by simply using +* spr_write_generic for HV mode in the SPR table +*/ +/* Build insertion mask into t1 based on context */ +gen_load_spr (t1,SPR_AMOR ); + +/* Mask new bits into t2 */ +tcg_gen_and_tl (t2, t1, cpu_gpr[gprn]); + +/* Load AMR and clear new bits in t0 */ gen_load_spr (t0,SPR_UAMOR ); -tcg_gen_and_tl (t0, t0, cpu_gpr[gprn]); -gen_store_spr (SPR_AMR , t0); -spr_store_dump_spr (SPR_AMR ); +tcg_gen_andc_tl (t0, t0, t1); + +/* Or'in new bits and write it out */ +tcg_gen_or_tl (t0, t0, t2); +gen_store_spr (SPR_UAMOR , t0); +spr_store_dump_spr (SPR_UAMOR ); + +tcg_temp_free (t0); +tcg_temp_free (t1); +tcg_temp_free (t2); }#endif /* CONFIG_USER_ONLY */ -static void gen_spr_amr (CPUPPCState *env) +static void gen_spr_amr (CPUPPCState *env,bool has_iamr) {#ifndef CONFIG_USER_ONLY /* Virtual Page Class Key protection */
@@ -1125,15 +1167,17 @@ static void gen_spr_amr (CPUPPCState *env)* userspace accessible, 29 is privileged. So we only need to set * the kvm ONE_REG id on one of them, we use 29 */ spr_register (env,SPR_UAMR ,"UAMR" , - &spr_read_uamr, &spr_write_uamr_pr, - &spr_read_uamr, &spr_write_uamr, + &spr_read_generic, &spr_write_amr, + &spr_read_generic, &spr_write_amr,0 ); -spr_register_kvm (env,SPR_AMR ,"AMR" , +spr_register_kvm_hv (env,SPR_AMR ,"AMR" ,SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_amr, &spr_read_generic, &spr_write_generic,KVM_REG_PPC_AMR ,0 ); -spr_register_kvm (env,SPR_UAMOR ,"UAMOR" , +spr_register_kvm_hv (env,SPR_UAMOR ,"UAMOR" ,SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_uamor, &spr_read_generic, &spr_write_generic,KVM_REG_PPC_UAMOR ,0 ); spr_register_hv(env, SPR_AMOR, "AMOR",
Signature · 1 line
2.5.0
PATCH 65/77 ppc: Add POWER8 IAMR register
In reply to Benjamin HerrenschmidtWith appropriate AMR-like masks. Not actually used by the translation logic at that point
--- target-ppc/cpu.h | 1 + target-ppc/translate_init.c | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-)
target-ppc/cpu.h +1 -0
@@ -1366,6 +1366,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_BOOKE_CSRR0 (0x03A)#define SPR_BOOKE_CSRR1 (0x03B)#define SPR_BOOKE_DEAR (0x03D) +#define SPR_IAMR (0x03D)#define SPR_BOOKE_ESR (0x03E)#define SPR_BOOKE_IVPR (0x03F)#define SPR_MPC_EIE (0x050)
target-ppc/translate_init.c +39 -1
@@ -1157,6 +1157,36 @@ static void spr_write_uamor (DisasContext *ctx, int sprn, int gprn)tcg_temp_free (t1); tcg_temp_free(t2); } + +static void spr_write_iamr (DisasContext *ctx,int sprn,int gprn) +{ +TCGv t0 =tcg_temp_new (); +TCGv t1 =tcg_temp_new (); +TCGv t2 =tcg_temp_new (); + +/* Note, the HV=1 case is handled earlier by simply using +* spr_write_generic for HV mode in the SPR table +*/ + +/* Build insertion mask into t1 based on context */ +gen_load_spr (t1,SPR_AMOR ); + +/* Mask new bits into t2 */ +tcg_gen_and_tl (t2, t1, cpu_gpr[gprn]); + +/* Load AMR and clear new bits in t0 */ +gen_load_spr (t0,SPR_IAMR ); +tcg_gen_andc_tl (t0, t0, t1); + +/* Or'in new bits and write it out */ +tcg_gen_or_tl (t0, t0, t2); +gen_store_spr (SPR_IAMR , t0); +spr_store_dump_spr (SPR_IAMR ); + +tcg_temp_free (t0); +tcg_temp_free (t1); +tcg_temp_free (t2); +}#endif /* CONFIG_USER_ONLY */ static void gen_spr_amr (CPUPPCState *env,bool has_iamr)
@@ -1185,6 +1215,14 @@ static void gen_spr_amr (CPUPPCState *env, bool has_iamr)SPR_NOACCESS ,SPR_NOACCESS , &spr_read_generic, &spr_write_generic, 0); +if (!has_iamr) { +return ; + } +spr_register_hv (env,SPR_IAMR ,"IAMR" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_iamr, + &spr_read_generic, &spr_write_generic, +0 ); #endif /* !CONFIG_USER_ONLY */ }#endif /* TARGET_PPC64 */
@@ -8160,7 +8198,7 @@ static void init_proc_book3s_64(CPUPPCState *env, int version)case BOOK3S_CPU_POWER7 :case BOOK3S_CPU_POWER8 :gen_spr_book3s_ids (env); -gen_spr_amr (env); +gen_spr_amr (env, version >=BOOK3S_CPU_POWER8 );gen_spr_book3s_purr (env); env->ci_large_pages = true;break ;
Signature · 1 line
2.5.0
PATCH 66/77 ppc: Add a few more P8 PMU SPRs
In reply to Benjamin Herrenschmidt--- target-ppc/cpu.h | 7 +++++++ target-ppc/translate_init.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+)
target-ppc/cpu.h +7 -0
@@ -1591,6 +1591,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_PERF0 (0x300)#define SPR_RCPU_MI_RBA0 (0x300)#define SPR_MPC_MI_CTR (0x300) +#define SPR_POWER_USIER (0x300)#define SPR_PERF1 (0x301)#define SPR_RCPU_MI_RBA1 (0x301)#define SPR_POWER_UMMCR2 (0x301)
@@ -1640,6 +1641,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_PERFF (0x30F)#define SPR_MPC_MD_TW (0x30F)#define SPR_UPERF0 (0x310) +#define SPR_POWER_SIER (0x310)#define SPR_UPERF1 (0x311)#define SPR_POWER_MMCR2 (0x311)#define SPR_UPERF2 (0x312)
@@ -1703,7 +1705,12 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_440_ITV2 (0x376)#define SPR_440_ITV3 (0x377)#define SPR_440_CCR1 (0x378) +#define SPR_TACR (0x378) +#define SPR_TCSCR (0x379) +#define SPR_CSIGR (0x37a)#define SPR_DCRIPR (0x37B) +#define SPR_POWER_SPMC1 (0x37C) +#define SPR_POWER_SPMC2 (0x37D)#define SPR_POWER_MMCRS (0x37E)#define SPR_PPR (0x380)#define SPR_750_GQR0 (0x390)
target-ppc/translate_init.c +28 -0
@@ -7764,6 +7764,30 @@ static void gen_spr_power8_pmu_sup(CPUPPCState *env)SPR_NOACCESS ,SPR_NOACCESS , &spr_read_generic, &spr_write_generic, KVM_REG_PPC_MMCRS, 0x00000000); +spr_register_kvm (env,SPR_POWER_SIER ,"SIER" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_SIER ,0x00000000 ); +spr_register_kvm (env,SPR_POWER_SPMC1 ,"SPMC1" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_SPMC1 ,0x00000000 ); +spr_register_kvm (env,SPR_POWER_SPMC2 ,"SPMC2" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_SPMC2 ,0x00000000 ); +spr_register_kvm (env,SPR_TACR ,"TACR" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_TACR ,0x00000000 ); +spr_register_kvm (env,SPR_TCSCR ,"TCSCR" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_TCSCR ,0x00000000 ); +spr_register_kvm (env,SPR_CSIGR ,"CSIGR" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_CSIGR ,0x00000000 ); }static void gen_spr_power8_pmu_user (CPUPPCState *env)
@@ -7772,6 +7796,10 @@ static void gen_spr_power8_pmu_user(CPUPPCState *env) &spr_read_ureg,SPR_NOACCESS , &spr_read_ureg, &spr_write_ureg, 0x00000000); +spr_register (env,SPR_POWER_USIER ,"USIER" , + &spr_read_generic,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +0x00000000 ); }static void gen_spr_power5p_ear (CPUPPCState *env)
Signature · 1 line
2.5.0
PATCH 67/77 ppc: Add dummy write to VTB
In reply to Benjamin HerrenschmidtThe Hypervisor can write it. We don't handle that properly yet but at least let's not blow up when it is written.
--- target-ppc/translate_init.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
target-ppc/translate_init.c +11 -4
@@ -299,6 +299,12 @@ static void spr_write_purr (DisasContext *ctx, int gprn, int sprn)// Temporary placeholder } +__attribute__ (( unused )) +static void spr_write_vtb (DisasContext *ctx,int gprn,int sprn) +{ +// Temporary placeholder +} +/* HDECR */ static void spr_read_hdecr (DisasContext *ctx,int gprn,int sprn) {
@@ -8148,10 +8154,11 @@ static void gen_spr_power8_ebb(CPUPPCState *env)/* Virtual Time Base */ static void gen_spr_vtb (CPUPPCState *env) { -spr_register (env,SPR_VTB ,"VTB" , -SPR_NOACCESS ,SPR_NOACCESS , - &spr_read_tbl,SPR_NOACCESS , -0x00000000 ); +spr_register_hv (env,SPR_VTB ,"VTB" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_tbl,SPR_NOACCESS , + &spr_read_tbl, spr_write_vtb, +0x00000000 ); }static void gen_spr_power8_fscr (CPUPPCState *env)
Signature · 1 line
2.5.0
PATCH 68/77 ppc: Add dummy POWER8 MPPR register
In reply to Benjamin HerrenschmidtControls the micropartition prefetch, this is pretty much meaningless in full emulation (used for priming the caches on real HW).
--- target-ppc/cpu.h | 1 + target-ppc/translate_init.c | 13 +++++++++++++ 2 files changed, 14 insertions(+)
target-ppc/cpu.h +1 -0
@@ -1399,6 +1399,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_DHDES (0x0B1)#define SPR_DPDES (0x0B0)#define SPR_DAWR (0x0B4) +#define SPR_MPPR (0x0B8)#define SPR_RPR (0x0BA)#define SPR_DAWRX (0x0BC)#define SPR_HFSCR (0x0BE)
target-ppc/translate_init.c +13 -0
@@ -8212,6 +8212,18 @@ static void gen_spr_power8_ic(CPUPPCState *env)#endif } +static void gen_spr_power8_book4 (CPUPPCState *env) +{ +/* Add a number of P8 book4 registers */ +#if !defined(CONFIG_USER_ONLY ) +spr_register_hv (env,SPR_MPPR ,"MPPR" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +0 ); +#endif +} +static void init_proc_book3s_64 (CPUPPCState *env,int version) {gen_spr_ne_601 (env);
@@ -8266,6 +8278,7 @@ static void init_proc_book3s_64(CPUPPCState *env, int version)gen_spr_power8_rpr (env);gen_spr_power8_dbell (env);gen_spr_power8_ic (env); +gen_spr_power8_book4 (env); }if (version <BOOK3S_CPU_POWER8 ) {gen_spr_book3s_dbg (env);
Signature · 1 line
2.5.0
PATCH 69/77 ppc: Add dummy POWER8 PSPB SPR
In reply to Benjamin HerrenschmidtOn real hardware it allows temporary thread priority boosts, we don't do threads and implementing it would be fairly tricky, so we just dummy it or now.
--- target-ppc/cpu.h | 1 + target-ppc/translate_init.c | 11 +++++++++++ 2 files changed, 12 insertions(+)
target-ppc/cpu.h +1 -0
@@ -1396,6 +1396,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_UAMOR (0x09D)#define SPR_MPC_ICTRL (0x09E)#define SPR_MPC_BAR (0x09F) +#define SPR_PSPB (0x09F)#define SPR_DHDES (0x0B1)#define SPR_DPDES (0x0B0)#define SPR_DAWR (0x0B4)
target-ppc/translate_init.c +11 -0
@@ -8224,6 +8224,16 @@ static void gen_spr_power8_book4(CPUPPCState *env)#endif } +static void gen_spr_power8_pspb (CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY ) +spr_register (env,SPR_PSPB ,"PSPB" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +0 ); +#endif +} +static void init_proc_book3s_64 (CPUPPCState *env,int version) {gen_spr_ne_601 (env);
@@ -8278,6 +8288,7 @@ static void init_proc_book3s_64(CPUPPCState *env, int version)gen_spr_power8_rpr (env);gen_spr_power8_dbell (env);gen_spr_power8_ic (env); +gen_spr_power8_pspb (env);gen_spr_power8_book4 (env); }if (version <BOOK3S_CPU_POWER8 ) {
Signature · 1 line
2.5.0
PATCH 70/77 ppc: Add dummy CIABR SPR
In reply to Benjamin HerrenschmidtWe should implement HW breakpoint/watchpoint, qemu supports them...
--- target-ppc/cpu.h | 1 + target-ppc/translate_init.c | 5 +++++ 2 files changed, 6 insertions(+)
target-ppc/cpu.h +1 -0
@@ -1402,6 +1402,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_DAWR (0x0B4)#define SPR_MPPR (0x0B8)#define SPR_RPR (0x0BA) +#define SPR_CIABR (0x0BB)#define SPR_DAWRX (0x0BC)#define SPR_HFSCR (0x0BE)#define SPR_VRSAVE (0x100)
target-ppc/translate_init.c +5 -0
@@ -7629,6 +7629,11 @@ static void gen_spr_book3s_207_dbg(CPUPPCState *env)SPR_NOACCESS ,SPR_NOACCESS , &spr_read_generic, &spr_write_generic, 0x00000000); +spr_register_kvm_hv (env,SPR_CIABR ,"CIABR" , +SPR_NOACCESS ,SPR_NOACCESS , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_CIABR ,0x00000000 ); }static void gen_spr_970_dbg (CPUPPCState *env)
Signature · 1 line
2.5.0
Quoted 3 lines · Benjamin Herrenschmidt
This requires an OPAL firmware file which isn't included yet, will emulate enough to boot existing distros and run KVM inside TCG
Note that this doesn't migrate nor supports running under PR KVM, both are possible but will take significantly more work (the latter will need updates to PR KVM to emulate various aspects of the MMU that it ignores for now).
Cheers,
Ben.
Quoted 3 lines · Benjamin Herrenschmidt
This requires an OPAL firmware file which isn't included yet, will emulate enough to boot existing distros and run KVM inside TCG
[meta-comment]
It would be nice to include a diffstat (git defaults to doing this if you use 'git format-patch --cover-letter' for generating the 0/77 letter), so that we can see at a glance how big this series is and what files it touches.
In particular, I can't tell, without poking through 77 patches, if you update the MAINTAINERS file to claim any new files added here.
Also, for a series this big, it's nice to point to a scratch git repo that we can browse/clone from, without having to 'git am' all 77 mails.
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Quoted 5 lines · Eric Blake
It would be nice to include a diffstat (git defaults to doing this if you use 'git format-patch --cover-letter' for generating the 0/77 letter), so that we can see at a glance how big this series is and what files it touches.
Right. I'll do that next time. In the meantime, I've appended the diffstat below.
Quoted 2 lines
In particular, I can't tell, without poking through 77 patches, if you update the
MAINTAINERSfile to claim any new files added here.
I don't ... yet. I'll do it in the next spin. Thanks for pointing that out.
Quoted 3 lines
Also, for a series this big, it's nice to point to a scratch git repo that we can browse/clone from, without having to 'git am' all 77 mails.
https://github.com/ozbenh/qemu
Cheers,
Ben.
default-configs/ppc64-softmmu.mak | 5 +- hmp-commands-info.hx | 2 + hw/intc/Makefile.objs | 2 +
hw/intc/xics.c | 722 +++++++---------------- hw/intc/xics_kvm.c | 91 +-- hw/intc/xics_native.c | 294 ++++++++++ hw/intc/xics_spapr.c | 423 ++++++++++++++ hw/pci-bridge/pci_bridge_dev.c | 3 + hw/pci-host/Makefile.objs | 2 + hw/pci-host/pnv_phb3.c | 1083 +++++++++++++++++++++++++++++++++++ hw/pci-host/pnv_phb3_msi.c | 338 +++++++++++ hw/pci-host/pnv_phb3_pbcq.c | 314 ++++++++++ hw/pci-host/pnv_phb3_rc.c | 132 +++++
hw/pci/pci.c | 26 +- hw/ppc/Makefile.objs | 2 +
hw/ppc/pnv.c | 859 +++++++++++++++++++++++++++
hw/ppc/pnv_lpc.c | 527 +++++++++++++++++ hw/ppc/pnv_occ.c | 125 ++++ hw/ppc/pnv_psi.c | 594 +++++++++++++++++++
hw/ppc/pnv_xscom.c | 415 ++++++++++++++ hw/ppc/ppc.c | 31 +- hw/ppc/spapr.c | 41 +- hw/ppc/spapr_events.c | 8 +- hw/ppc/spapr_hcall.c | 22 +- hw/ppc/spapr_pci.c | 10 +- hw/ppc/spapr_vio.c | 2 +- include/hw/pci-host/pnv_phb3.h | 145 +++++ include/hw/pci-host/pnv_phb3_regs.h | 505 ++++++++++++++++ include/hw/pci-host/spapr.h | 2 +- include/hw/pci/pci_bus.h | 1 + include/hw/ppc/pnv.h | 67 +++ include/hw/ppc/pnv_xscom.h | 73 +++ include/hw/ppc/ppc.h | 2 + include/hw/ppc/spapr.h | 2 +- include/hw/ppc/spapr_vio.h | 2 +- include/hw/ppc/xics.h | 81 ++- include/hw/qdev-core.h | 1 + linux-user/main.c | 1 + monitor.c | 3 + qdev-monitor.c | 13 +- target-ppc/cpu-models.c | 12 +- target-ppc/cpu-models.h | 4 +- target-ppc/cpu-qom.h | 1 + target-ppc/cpu.h | 152 ++++- target-ppc/excp_helper.c | 324 +++++++---- target-ppc/helper.h | 6 + target-ppc/helper_regs.h | 75 ++- target-ppc/machine.c | 4 +-
target-ppc/mmu-hash32.c | 4 +- target-ppc/mmu-hash64.c | 356 ++++++++++-- target-ppc/mmu-hash64.h | 1 + target-ppc/mmu_helper.c | 17 +- target-ppc/timebase_helper.c | 10 + target-ppc/translate.c | 1009 +++++++++++++++++--------------- target-ppc/translate_init.c | 735 +++++++++++++++++++++--- 55 files changed, 8318 insertions(+), 1363 deletions(-)
create mode 100644 hw/intc/xics_native.c create mode 100644 hw/intc/xics_spapr.c create mode 100644 hw/pci-host/pnv_phb3.c create mode 100644 hw/pci-host/pnv_phb3_msi.c create mode 100644 hw/pci-host/pnv_phb3_pbcq.c create mode 100644 hw/pci-host/pnv_phb3_rc.c create mode 100644 hw/ppc/pnv.c
create mode 100644 hw/ppc/pnv_lpc.c
create mode 100644 hw/ppc/pnv_occ.c
create mode 100644 hw/ppc/pnv_psi.c
create mode 100644 hw/ppc/pnv_xscom.c
create mode 100644 include/hw/pci-host/pnv_phb3.h create mode 100644 include/hw/pci-host/pnv_phb3_regs.h create mode 100644 include/hw/ppc/pnv.h create mode 100644 include/hw/ppc/pnv_xscom.h
Quoted 9 lines · Benjamin Herrenschmidt
Quoted 5 lines · Eric Blake
It would be nice to include a diffstat (git defaults to doing this if you use 'git format-patch --cover-letter' for generating the 0/77 letter), so that we can see at a glance how big this series is and what files it touches.
Right. I'll do that next time. In the meantime, I've appended the diffstat below.
Some working example of qemu command line would not hurt. Known limitations as well. Like:
- it does not run under neither kvm-hv nor kvm-pr;
- cannot boot LE kernel;
...
Quoted 12 lines
Quoted 3 lines
In particular, I can't tell, without poking through 77 patches, if you update the
MAINTAINERSfile to claim any new files added here.I don't ... yet. I'll do it in the next spin. Thanks for pointing that out.
Quoted 3 lines
Also, for a series this big, it's nice to point to a scratch git repo that we can browse/clone from, without having to 'git am' all 77 mails.
Signature · 1 line
Alexey
Quoted 14 lines · Alexey Kardashevskiy
Quoted 11 lines · Benjamin Herrenschmidt
Quoted 7 lines · Eric Blake
It would be nice to include a diffstat (git defaults to doing this if
you use 'git format-patch --cover-letter' for generating the 0/77 letter), so that we can see at a glance how big this series is and
what files it touches.Right. I'll do that next time. In the meantime, I've appended the diffstat below.
Quoted 5 lines
Some working example of qemu command line would not hurt. Known limitations
as well. Like:- it does not run under neither kvm-hv nor kvm-pr;
It will never run under HV KVM, indeed. I did mention somewhere else that support for PR KVM was possible, just quite a bit of work. I will add it to next version's cover letter.
Quoted 2 lines
- cannot boot LE kernel;
...
It boots an LE kernel just fine :-)
Also next spin will have skiboot.lid
Cheers,
Ben.
Quoted 21 lines · Benjamin Herrenschmidt
Quoted 14 lines · Alexey Kardashevskiy
Quoted 11 lines · Benjamin Herrenschmidt
Quoted 7 lines · Eric Blake
It would be nice to include a diffstat (git defaults to doing this if
you use 'git format-patch --cover-letter' for generating the 0/77 letter), so that we can see at a glance how big this series is and
what files it touches.Right. I'll do that next time. In the meantime, I've appended the diffstat below.
Quoted 5 lines
Some working example of qemu command line would not hurt. Known limitations
as well. Like:- it does not run under neither kvm-hv nor kvm-pr;
Quoted 8 lines
It will never run under HV KVM, indeed. I did mention somewhere else that support for PR KVM was possible, just quite a bit of work. I will add it to next version's cover letter.
Quoted 2 lines
- cannot boot LE kernel;
...It boots an LE kernel just fine :-)
aaaaand there is still no working example ;)
This:
p/qemu-powernv/ppc64-softmmu/qemu-system-ppc64 -m 2048 -machine powernv \
-nographic -vga none -initrd t/le.cpio -kernel t/vml420le -bios \
skiboot.lid -smp 1,threads=1
just hangs at:
[1491287872,5] INIT: Waiting for kernel...
[1493257423,5] Assuming kernel at 0x20000000
[1494710040,5] INIT: Kernel loaded, size: 0 bytes (0 = unknown preload) [1497506414,5] INIT: 64-bit LE kernel discovered
[1500827972,5] INIT: 64-bit kernel entry at 0x20010000
[1505594383,3] OCC: No HOMER detected, assuming no pstates [1507983930,3] ELOG: Error getting buffer to log error
[1556792870,5] Free space in HEAP memory regions:
[1559724738,5] Region ibm,firmware-heap free: 12778984
[1561377946,5] Region ibm,firmware-allocs-memory@0000000000000000 free: 376992 [1563789914,5] Total free: 13155976
[1565066925,5] INIT: Starting kernel at 0x20010000, fdt at 0x30350610 (size 0x2ce4)
With BE kernel and initrd, it goes further and boots fine:
[1589979488,5] Total free: 13155976
[1591411784,5] INIT: Starting kernel at 0x20010000, fdt at 0x30350610 (size 0x2ce4) [1687534980,3] OPAL: Trying a CPU re-init with flags: 0x1
CPU maps initialized for 1 thread per core
....
If I try LE disk image (ubuntu 14), it just crashes:
p/qemu-powernv/ppc64-softmmu/qemu-system-ppc64 -m 2048 -machine powernv \
-nographic -vga none img/u14_32GB_cuda7.qcow2 -bios skiboot.lid \
-smp 1,threads=1
qemu: hardware error: qemu: could not load kernel'(null)'
CPU #0:
NIP 0000000000000000 LR 0000000000000000 CTR 0000000000000000 XER 0000000000000000 CPU#0
MSR 0000000000000000 HID0 0000000000000000 HF 0000000000000000 iidx 0 didx 0
TB 00000000 00000000 DECR 00000000
...
Quoted 2 lines
Also next spin will have skiboot.lid
Right. With the note that it goes with -bios :)
Signature · 1 line
Alexey
Quoted 8 lines · Alexey Kardashevskiy
p/qemu-powernv/ppc64-softmmu/qemu-system-ppc64 -m 2048 -machine powernv \
-nographic -vga none -initrd t/le.cpio -kernel t/vml420le -bios \
skiboot.lid -smp 1,threads=1just hangs at:
Quoted 16 lines
[1491287872,5] INIT: Waiting for kernel...
[1493257423,5] Assuming kernel at0x20000000[1494710040,5] INIT: Kernel loaded, size: 0 bytes (0 = unknown preload)
[1497506414,5] INIT: 64-bit LE kernel discovered [1500827972,5] INIT: 64-bit kernel entry at0x20010000[1505594383,3] OCC: No HOMER detected, assuming no pstates [1507983930,3] ELOG: Error getting buffer to log error [1556792870,5] Free space in HEAP memory regions:
[1559724738,5] Region ibm,firmware-heap free: 12778984 [1561377946,5] Region ibm,firmware-allocs-memory@0000000000000000
free: 376992
[1563789914,5] Total free: 13155976
[1565066925,5] INIT: Starting kernel at0x20010000, fdt at0x30350610(size0x2ce4)
Hrm, works for me, I've been testing various LE kernels including a full ubuntu distro in there, we need to debug that further. Does that same kernel actually work on real HW ?
Quoted 7 lines
If I try LE disk image (ubuntu 14), it just crashes:
p/qemu-powernv/ppc64-softmmu/qemu-system-ppc64 -m 2048 -machine powernv \
(quoted diff) +0
-2-nographic -vga none img/u14_32GB_cuda7.qcow2 -bios skiboot.lid \ -smp 1,threads=1qemu: hardware error: qemu: could not load kernel'(null)'
Right, we don't load kernels from disk, you need to pass a -kernel that typically is the openpower bootloader (Linux + petitboot). My plan is to make the pnv platform automatically extract these things from a ROM image of an openpower eval board (aka palmetto) which you can build from github. It's a bit too big to include as a binary in qemu however (about 16M).
Quoted 1 line
Right. With the note that it goes with -bios :)
Not necessarily, it will be in the right place and loaded without an explicit -bios.
Cheers,
Ben.
Quoted 26 lines · Benjamin Herrenschmidt
Quoted 8 lines · Alexey Kardashevskiy
p/qemu-powernv/ppc64-softmmu/qemu-system-ppc64 -m 2048 -machine powernv \
-nographic -vga none -initrd t/le.cpio -kernel t/vml420le -bios \
skiboot.lid -smp 1,threads=1just hangs at:
Quoted 16 lines
[1491287872,5] INIT: Waiting for kernel...
[1493257423,5] Assuming kernel at0x20000000[1494710040,5] INIT: Kernel loaded, size: 0 bytes (0 = unknown preload)
[1497506414,5] INIT: 64-bit LE kernel discovered [1500827972,5] INIT: 64-bit kernel entry at0x20010000[1505594383,3] OCC: No HOMER detected, assuming no pstates [1507983930,3] ELOG: Error getting buffer to log error [1556792870,5] Free space in HEAP memory regions:
[1559724738,5] Region ibm,firmware-heap free: 12778984 [1561377946,5] Region ibm,firmware-allocs-memory@0000000000000000
free: 376992
[1563789914,5] Total free: 13155976
[1565066925,5] INIT: Starting kernel at0x20010000, fdt at0x30350610(size0x2ce4)
Quoted 3 lines
Hrm, works for me, I've been testing various LE kernels including a full ubuntu distro in there, we need to debug that further. Does that same kernel actually work on real HW ?
Ok, as we figured out, CONFIG_PPC_EARLY_DEBUG is responsible for this as it does hypercalls in the very beginning.
Quoted 9 lines
Quoted 7 lines
If I try LE disk image (ubuntu 14), it just crashes:
p/qemu-powernv/ppc64-softmmu/qemu-system-ppc64 -m 2048 -machine powernv \
(quoted diff) +0
-2-nographic -vga none img/u14_32GB_cuda7.qcow2 -bios skiboot.lid \ -smp 1,threads=1qemu: hardware error: qemu: could not load kernel'(null)'
Right, we don't load kernels from disk, you need to pass a -kernel that
Worth mentioning as well ;)
Quoted 5 lines
typically is the openpower bootloader (Linux + petitboot). My plan is to make the pnv platform automatically extract these things from a ROM image of an openpower eval board (aka palmetto) which you can build from github. It's a bit too big to include as a binary in qemu however (about 16M).
git submodule?
Another note. I tried to know what the default devices are and got another crash:
(qemu) info qtree
bus: main-system-bus
type System
dev: phb3-msi, id ""
/home/aik/p/qemu-powernv/hw/core/sysbus.c:276:sysbus_dev_print: Object 0x100279e9500 is not an instance of type sys-bus-device
Signature · 1 line
Alexey
Quoted 11 lines · Alexey Kardashevskiy
Another note. I tried to know what the default devices are and got another
crash:(qemu) info qtree
bus: main-system-bus
type System
dev: phb3-msi, id "" /home/aik/p/qemu-powernv/hw/core/sysbus.c:276:sysbus_dev_print:
Object0x100279e9500is not an instance of type sys-bus-device
Hrm, that would be a new bug I introduced when adding MSIs yesterday, I'll look into it.
Cheers,
Ben.
Quoted 48 lines · Alexey Kardashevskiy
Quoted 26 lines · Benjamin Herrenschmidt
Quoted 8 lines · Alexey Kardashevskiy
p/qemu-powernv/ppc64-softmmu/qemu-system-ppc64 -m 2048 -machine powernv \
-nographic -vga none -initrd t/le.cpio -kernel t/vml420le -bios \
skiboot.lid -smp 1,threads=1just hangs at:
Quoted 16 lines
[1491287872,5] INIT: Waiting for kernel...
[1493257423,5] Assuming kernel at0x20000000[1494710040,5] INIT: Kernel loaded, size: 0 bytes (0 = unknown preload)
[1497506414,5] INIT: 64-bit LE kernel discovered [1500827972,5] INIT: 64-bit kernel entry at0x20010000[1505594383,3] OCC: No HOMER detected, assuming no pstates [1507983930,3] ELOG: Error getting buffer to log error [1556792870,5] Free space in HEAP memory regions:
[1559724738,5] Region ibm,firmware-heap free: 12778984 [1561377946,5] Region ibm,firmware-allocs-memory@0000000000000000
free: 376992
[1563789914,5] Total free: 13155976
[1565066925,5] INIT: Starting kernel at0x20010000, fdt at0x30350610(size0x2ce4)Quoted 3 lines
Hrm, works for me, I've been testing various LE kernels including a full ubuntu distro in there, we need to debug that further. Does that same kernel actually work on real HW ?
Ok, as we figured out,
CONFIG_PPC_EARLY_DEBUGis responsible for this as it does hypercalls in the very beginning.Quoted 9 lines
Quoted 7 lines
If I try LE disk image (ubuntu 14), it just crashes:
p/qemu-powernv/ppc64-softmmu/qemu-system-ppc64 -m 2048 -machine powernv \
(quoted diff) +0
-2-nographic -vga none img/u14_32GB_cuda7.qcow2 -bios skiboot.lid \ -smp 1,threads=1qemu: hardware error: qemu: could not load kernel'(null)'
Right, we don't load kernels from disk, you need to pass a -kernel that
Worth mentioning as well ;)
Quoted 7 lines
Quoted 5 lines
typically is the openpower bootloader (Linux + petitboot). My plan is to make the pnv platform automatically extract these things from a ROM image of an openpower eval board (aka palmetto) which you can build from github. It's a bit too big to include as a binary in qemu however (about 16M).
git submodule?
How does real hardware store petitboot? If it's flash, you could pass it in using -pflash and thus model things even more closely and allow users to just take the ROM image as is.
Alex
Quoted 4 lines · Alexander Graf
How does real hardware store petitboot? If it's flash, you could pass it in using -pflash and thus model things even more closely and allow users to just take the ROM image as is.
It is a flash image, we could use an Open Power machine flash image "as-is" provided we taught qemu to extract skiboot (aka OPAL) from it.
Cheers,
Ben.
Quoted 4 lines
Am 28.11.2015 um 08:59 schrieb Benjamin Herrenschmidt <[email protected]>:
Quoted 8 lines
Quoted 5 lines · Alexander Graf
How does real hardware store petitboot? If it's flash, you could pass it in using -pflash and thus model things even more closely and allow users to just take the ROM image as is.
It is a flash image, we could use an Open Power machine flash image "as-is" provided we taught qemu to extract skiboot (aka OPAL) from it.
That's probably the best way. If it's memory mapped, you might not even have to extract anything - just jump to its location ;).
The -kernel syntax is useful to have, but should really be something "on top" of the normal system boot rather than its primary boot interface.
Alex
Quoted 12 lines · Alexander Graf
Quoted 12 lines
Am 28.11.2015 um 08:59 schrieb Benjamin Herrenschmidt <benh@kernel. crashing.org>:
Quoted 7 lines · Alexander Graf
How does real hardware store petitboot? If it's flash, you could pass it
in using -pflash and thus model things even more closely and allow users
to just take the ROM image as is.
Quoted 6 lines
Quoted 3 lines
It is a flash image, we could use an Open Power machine flash image "as-is"
provided we taught qemu to extract skiboot (aka OPAL) from it.That's probably the best way. If it's memory mapped, you might not even have to extract anything - just jump to its location ;).
It's not memory mapped sadly (well not on P8...)
The way a real P8 boots is first a little internal uC executes code from a i2c seeprom to initialize a core and some cache. It then copies a payload from flash into that cache. That payload is HostBoot, which is a huge thing that initializes a pile of stuff such as the internal busses, SMP links, links to memory buffers, trains memory etc... it then constructs an embryo device-tree and loads & run OPAL (aka skiboot).
The model I chose for powernv is to simulate a boot at the hostboot -> skiboot transition point.
Quoted 3 lines
The -kernel syntax is useful to have, but should really be something "on top" of the normal system boot rather than its primary boot interface.
I know, I'm just not keen on committing a 16M "BIOS" to qemu tree ;-)
In any case, this is easy to change / fix. There's a lot more work on the rest of the series first.
Cheers,
Ben.
Quoted 8 lines · Benjamin Herrenschmidt
Quoted 4 lines · Alexander Graf
How does real hardware store petitboot? If it's flash, you could pass it in using -pflash and thus model things even more closely and allow users to just take the ROM image as is.
It is a flash image, we could use an Open Power machine flash image "as-is" provided we taught qemu to extract skiboot (aka OPAL) from it.
Couldn't we add an offset argument to load_image_targphys() or make that an extra routine ? If so, we could then load directly from an openpower pnor file.
I gave it a quick (and dirty) try and a powernv guest runs fine up to petitboot with just :
qemu-system-ppc64 -m 2G -M powernv -bios ~/work/open-power/images/palmetto.pnor -nographic -nodefaults -serial stdio
The pnor file is compiled from github. The patch is below (without the dirty cut and paste I did in loader.c). The offset for the PAYLOAD and BOOTKERNEL partitions are hard coded but I guess we don't need to read the flash partition table in qemu, not yet.
Cheers,
C.
hw/ppc/pnv.c +7 -3
@@ -69,7 +69,7 @@#define FDT_ADDR 0x01000000#define FDT_MAX_SIZE 0x00100000 -#define FW_MAX_SIZE 0x00400000 +#define FW_MAX_SIZE 0x04000000#define FW_FILE_NAME "skiboot.lid"#define KERNEL_FILE_NAME "skiroot.lid"#define KERNEL_LOAD_ADDR 0x20000000
@@ -902,7 +902,9 @@ static void ppc_powernv_init(MachineStat {ram_addr_t ram_size = machine->ram_size;const char *cpu_model = machine->cpu_model; +#if 0 const char *kernel_filename = machine->kernel_filename; +#endif const char *initrd_filename = machine->initrd_filename;uint32_t initrd_base =0 ;long initrd_size =0 ;
@@ -998,19 +1000,20 @@ static void ppc_powernv_init(MachineStat bios_name =FW_FILE_NAME ; } filename =qemu_find_file (QEMU_FILE_TYPE_BIOS , bios_name); - fw_size =load_image_targphys (filename,0 ,FW_MAX_SIZE ); + fw_size =load_image_targphys_offset (filename,0 ,FW_MAX_SIZE ,0x961000 );if (fw_size <0 ) {hw_error ("qemu: could not load OPAL '%s'\n" , filename);exit (1 ); } +#if 0 g_free (filename);if (kernel_filename ==NULL ) { kernel_filename =KERNEL_FILE_NAME ; } filename =qemu_find_file (QEMU_FILE_TYPE_BIOS , kernel_filename); - fw_size =load_image_targphys (filename,0x20000000 ,0x2000000 ); +#endif + fw_size =load_image_targphys_offset (filename,0x20000000 ,0x2000000 ,0xa61000 );if (fw_size <0 ) {hw_error ("qemu: could not load kernel'%s'\n" , filename);exit (1 );
Quoted 4 lines · Cédric Le Goater
The pnor file is compiled from github. The patch is below (without the dirty cut and paste I did in
loader.c). The offset for the PAYLOAD and BOOTKERNEL partitions are hard coded but I guess we don't need to read the flash partition table in qemu, not yet.
In practice we should read the partition tables, I don't like hard coded offsets... But we should probably create a proper "flash driver" that does a bunch of this, and also adds the BMC style flash interface so OPAL can write to nvram.
Cheers,
Ben.
Quoted 10 lines · Benjamin Herrenschmidt
Quoted 4 lines · Cédric Le Goater
The pnor file is compiled from github. The patch is below (without the dirty cut and paste I did in
loader.c). The offset for the PAYLOAD and BOOTKERNEL partitions are hard coded but I guess we don't need to read the flash partition table in qemu, not yet.In practice we should read the partition tables, I don't like hard coded offsets... But we should probably create a proper "flash driver" that does a bunch of this, and also adds the BMC style flash interface so OPAL can write to nvram.
yes that would be better but I don't measure what it takes to implement the LPC/AHB bridge to access the PNOR.
C.
Quoted 7 lines · Cédric Le Goater
Quoted 4 lines
In practice we should read the partition tables, I don't like hard coded offsets... But we should probably create a proper "flash driver" that does a bunch of this, and also adds the BMC style flash interface so OPAL can write to nvram.
yes that would be better but I don't measure what it takes to implement the LPC/AHB bridge to access the PNOR.
Yeah that's probably a little bit of work, but then there's also work being done to protect the flash using IPMI commands to do the flashing, so that could be an alternate option. I like emulating more of the BMC though, including the flash controller, as it would improve our testing coverage.
Cheers,
Ben.
Quoted 17 lines · Cédric Le Goater
Quoted 8 lines · Benjamin Herrenschmidt
Quoted 4 lines · Alexander Graf
How does real hardware store petitboot? If it's flash, you could pass it in using -pflash and thus model things even more closely and allow users to just take the ROM image as is.
It is a flash image, we could use an Open Power machine flash image "as-is" provided we taught qemu to extract skiboot (aka OPAL) from it.
Couldn't we add an offset argument to
load_image_targphys()or make that an extra routine ? If so, we could then load directly from an openpower pnor file.I gave it a quick (and dirty) try and a powernv guest runs fine up to petitboot with just :
Quoted 6 lines
qemu-system-ppc64 -m 2G -M powernv -bios ~/work/open-power/images/palmetto.pnor -nographic -nodefaults -serial stdio
The pnor file is compiled from github. The patch is below (without the dirty cut and paste I did in
loader.c). The offset for the PAYLOAD and BOOTKERNEL partitions are hard coded but I guess we don't need to read the flash partition table in qemu, not yet.
One downside to this is that if we don't fall back to being able to load skiboot.lid it becomes more annoying to boot a gcov enabled skiboot as typical PNOR layout only gives 1MB for skiboot, and gcov builds bloat that a *lot*.
We probably don't want NVRAM writes going back to a single system wide PNOR image too, so while using pnor file is great for simulating what hardware does, may not work as the solution for long term model.
Quoted 25 lines · Stewart Smith
Quoted 17 lines · Cédric Le Goater
Quoted 8 lines · Benjamin Herrenschmidt
Quoted 4 lines · Alexander Graf
How does real hardware store petitboot? If it's flash, you could pass it in using -pflash and thus model things even more closely and allow users to just take the ROM image as is.
It is a flash image, we could use an Open Power machine flash image "as-is" provided we taught qemu to extract skiboot (aka OPAL) from it.
Couldn't we add an offset argument to
load_image_targphys()or make that an extra routine ? If so, we could then load directly from an openpower pnor file.I gave it a quick (and dirty) try and a powernv guest runs fine up to petitboot with just :
Quoted 6 lines
qemu-system-ppc64 -m 2G -M powernv -bios ~/work/open-power/images/palmetto.pnor -nographic -nodefaults -serial stdio
The pnor file is compiled from github. The patch is below (without the dirty cut and paste I did in
loader.c). The offset for the PAYLOAD and BOOTKERNEL partitions are hard coded but I guess we don't need to read the flash partition table in qemu, not yet.
Quoted 4 lines
One downside to this is that if we don't fall back to being able to load skiboot.lid it becomes more annoying to boot a gcov enabled skiboot as typical PNOR layout only gives 1MB for skiboot, and gcov builds bloat that a *lot*.
I guess that what we can imagine having a bigger partition for skiboot in the case of gcov ? This will require a custom pnor build. Might be too complex. Or we could use a -pflash option to load the pnor and an optional -bios for skiboot if we want a custom one.
Quoted 3 lines
We probably don't want NVRAM writes going back to a single system wide PNOR image too, so while using pnor file is great for simulating what hardware does, may not work as the solution for long term model.
we can use a memory backend to start with, which is also much simpler than having to handle the block backend like the cfi pflash is doing. a guest could use its own private pnor if a block backend is needed.
C.
Quoted 3 lines · Benjamin Herrenschmidt
This requires an OPAL firmware file which isn't included yet, will emulate enough to boot existing distros and run KVM inside TCG
For anyone wanting to try out this patchset, to build skiboot.lid, grab https://github.com/open-power/skiboot.git and build.
You'll need ppc64 (big endian) cross compilers, available here:
https://www.kernel.org/pub/tools/crosstool/
and with that in your path everything should "just work".
The travis-ci test script for skiboot itself does build a qemu with these patches and boots skiboot, so see:
https://github.com/open-power/skiboot/blob/master/.travis.yml
for how that works.
PATCH 71/77 ppc: Add dummy ACOP SPR
In reply to Benjamin Herrenschmidt--- target-ppc/cpu.h | 1 + target-ppc/translate_init.c | 4 ++++ 2 files changed, 5 insertions(+)
target-ppc/cpu.h +1 -0
@@ -1361,6 +1361,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_SRR1 (0x01B)#define SPR_CFAR (0x01C)#define SPR_AMR (0x01D) +#define SPR_ACOP (0x01F)#define SPR_BOOKE_PID (0x030)#define SPR_BOOKE_DECAR (0x036)#define SPR_BOOKE_CSRR0 (0x03A)
target-ppc/translate_init.c +4 -0
@@ -8226,6 +8226,10 @@ static void gen_spr_power8_book4(CPUPPCState *env) &spr_read_generic,SPR_NOACCESS , &spr_read_generic, &spr_write_generic, 0); +spr_register (env,SPR_ACOP ,"ACOP" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +0 );#endif }
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH 71/77] ppc: Add dummy ACOP SPR
Quoted 23 lines · Benjamin Herrenschmidt
Signed-off-by Benjamin Herrenschmidt <[email protected]>--- target-ppc/cpu.h | 1 + target-ppc/translate_init.c | 4 ++++ 2 files changed, 5 insertions(+)target-ppc/cpu.h +1
-0@@ -1361,6 +1361,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_SRR1 (0x01B)#define SPR_CFAR (0x01C)#define SPR_AMR (0x01D) +#define SPR_ACOP (0x01F)#define SPR_BOOKE_PID (0x030)#define SPR_BOOKE_DECAR (0x036)#define SPR_BOOKE_CSRR0 (0x03A)target-ppc/translate_init.c +0
-0
target-ppc/translate_init.c static void gen_spr_power8_book4(CPUPPCState *env) · line 8234
Quoted 9 lines
target-ppc/translate_init.c +4
-0@@ -8226,6 +8226,10 @@ static void gen_spr_power8_book4(CPUPPCState *env) &spr_read_generic,SPR_NOACCESS , &spr_read_generic, &spr_write_generic, 0); +spr_register (env,SPR_ACOP ,"ACOP" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +0 );#endif }
I think this patch should be merged with the next one (where you change the ACOP hunk in translate_init.c again.
Thomas
PATCH 72/77 ppc: A couple more dummy POWER8 Book4 regs
In reply to Benjamin HerrenschmidtWORT and PID this time
--- target-ppc/cpu.h | 2 ++ target-ppc/translate_init.c | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-)
target-ppc/cpu.h +2 -0
@@ -1363,6 +1363,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_AMR (0x01D)#define SPR_ACOP (0x01F)#define SPR_BOOKE_PID (0x030) +#define SPR_BOOKS_PID (0x030)#define SPR_BOOKE_DECAR (0x036)#define SPR_BOOKE_CSRR0 (0x03A)#define SPR_BOOKE_CSRR1 (0x03B)
@@ -1716,6 +1717,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_POWER_SPMC1 (0x37C)#define SPR_POWER_SPMC2 (0x37D)#define SPR_POWER_MMCRS (0x37E) +#define SPR_WORT (0x37F)#define SPR_PPR (0x380)#define SPR_750_GQR0 (0x390)#define SPR_440_DNV0 (0x390)
target-ppc/translate_init.c +12 -4
@@ -8226,10 +8226,18 @@ static void gen_spr_power8_book4(CPUPPCState *env) &spr_read_generic,SPR_NOACCESS , &spr_read_generic, &spr_write_generic, 0); -spr_register (env,SPR_ACOP ,"ACOP" , -SPR_NOACCESS ,SPR_NOACCESS , - &spr_read_generic, &spr_write_generic, -0 ); +spr_register_kvm (env,SPR_ACOP ,"ACOP" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_ACOP ,0 ); +spr_register_kvm (env,SPR_BOOKS_PID ,"PID" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_PID ,0 ); +spr_register_kvm (env,SPR_WORT ,"WORT" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_WORT ,0 );#endif }
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH 72/77] ppc: A couple more dummy POWER8 Book4 regs
Quoted 44 lines · Benjamin Herrenschmidt
WORT and PID this time
Signed-off-by Benjamin Herrenschmidt <[email protected]>--- target-ppc/cpu.h | 2 ++ target-ppc/translate_init.c | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-)target-ppc/cpu.h +2
-0@@ -1363,6 +1363,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_AMR (0x01D)#define SPR_ACOP (0x01F)#define SPR_BOOKE_PID (0x030) +#define SPR_BOOKS_PID (0x030)#define SPR_BOOKE_DECAR (0x036)#define SPR_BOOKE_CSRR0 (0x03A)#define SPR_BOOKE_CSRR1 (0x03B)@@ -1716,6 +1717,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_POWER_SPMC1 (0x37C)#define SPR_POWER_SPMC2 (0x37D)#define SPR_POWER_MMCRS (0x37E) +#define SPR_WORT (0x37F)#define SPR_PPR (0x380)#define SPR_750_GQR0 (0x390)#define SPR_440_DNV0 (0x390)target-ppc/translate_init.c +4
-4@@ -8226,10 +8226,18 @@ static void gen_spr_power8_book4(CPUPPCState *env) &spr_read_generic,SPR_NOACCESS , &spr_read_generic, &spr_write_generic, 0); -spr_register (env,SPR_ACOP ,"ACOP" , -SPR_NOACCESS ,SPR_NOACCESS , - &spr_read_generic, &spr_write_generic, -0 ); +spr_register_kvm (env,SPR_ACOP ,"ACOP" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_ACOP ,0 );
target-ppc/translate_init.c static void gen_spr_power8_book4(CPUPPCState *env) · line 8242
Quoted 10 lines
target-ppc/translate_init.c +8
-0+spr_register_kvm (env,SPR_BOOKS_PID ,"PID" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_PID ,0 ); +spr_register_kvm (env,SPR_WORT ,"WORT" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_WORT ,0 );#endif }
AFAICT all patches where you define new SPRs with spr_register_kvm[_hv] are also important independently of the rest of your patch series - otherwise these registers are currently lost during migration since they are not sync'ed with the KVM part in the kernel right now.
So if you've got some spare time, could you maybe extract all those patches that define new SPRs with spr_register_kvm[_hv] and send them as a separate patch series? That could help to fix future migration issues, and also would decrease the size of your really huge "Add native POWER8 platform" patch series a little bit!
Thanks,
Thomas
Re: [Qemu-devel] [PATCH 72/77] ppc: A couple more dummy POWER8 Book4 regs
Quoted 5 lines · Thomas Huth
So if you've got some spare time, could you maybe extract all those patches that define new SPRs with spr_register_kvm[_hv] and send them as a separate patch series? That could help to fix future migration issues, and also would decrease the size of your really huge "Add native POWER8 platform" patch series a little bit!
Time is the problem :-) My tree is bitrotting right now, I am completely caught up with a few other things.
I'm trying to get somebody to pick up that work.
Cheers,
Ben.
Re: [Qemu-devel] [Qemu-ppc] [PATCH 72/77] ppc: A couple more dummy POWER8 Book4 regs
In reply to Thomas HuthQuoted 61 lines · Thomas Huth
Quoted 44 lines · Benjamin Herrenschmidt
WORT and PID this time
Signed-off-by Benjamin Herrenschmidt <[email protected]>--- target-ppc/cpu.h | 2 ++ target-ppc/translate_init.c | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-)target-ppc/cpu.h +2
-0@@ -1363,6 +1363,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_AMR (0x01D)#define SPR_ACOP (0x01F)#define SPR_BOOKE_PID (0x030) +#define SPR_BOOKS_PID (0x030)#define SPR_BOOKE_DECAR (0x036)#define SPR_BOOKE_CSRR0 (0x03A)#define SPR_BOOKE_CSRR1 (0x03B)@@ -1716,6 +1717,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)#define SPR_POWER_SPMC1 (0x37C)#define SPR_POWER_SPMC2 (0x37D)#define SPR_POWER_MMCRS (0x37E) +#define SPR_WORT (0x37F)#define SPR_PPR (0x380)#define SPR_750_GQR0 (0x390)#define SPR_440_DNV0 (0x390)target-ppc/translate_init.c +4
-4@@ -8226,10 +8226,18 @@ static void gen_spr_power8_book4(CPUPPCState *env) &spr_read_generic,SPR_NOACCESS , &spr_read_generic, &spr_write_generic, 0); -spr_register (env,SPR_ACOP ,"ACOP" , -SPR_NOACCESS ,SPR_NOACCESS , - &spr_read_generic, &spr_write_generic, -0 ); +spr_register_kvm (env,SPR_ACOP ,"ACOP" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_ACOP ,0 );target-ppc/translate_init.c static void gen_spr_power8_book4(CPUPPCState *env) · line 8242
Quoted 10 lines
target-ppc/translate_init.c +8
-0+spr_register_kvm (env,SPR_BOOKS_PID ,"PID" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_PID ,0 ); +spr_register_kvm (env,SPR_WORT ,"WORT" , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_WORT ,0 );#endif }AFAICT all patches where you define new SPRs with spr_register_kvm[_hv] are also important independently of the rest of your patch series - otherwise these registers are currently lost during migration since they are not sync'ed with the KVM part in the kernel right now.
Quoted 5 lines
So if you've got some spare time, could you maybe extract all those patches that define new SPRs with spr_register_kvm[_hv] and send them as a separate patch series? That could help to fix future migration issues, and also would decrease the size of your really huge "Add native POWER8 platform" patch series a little bit!
I have been maintaining a port of Ben's patchset on the latest qemu for other parts which should come after pnv is merged so I have a framework to test such sub-patchsets. I also have time to work on them but clearly not the expertise in all areas !
What would be nice is to identify the most obvious ones, non controversial that could be merged after a few iterations. I have a vague idea, the ones Reviewed-by David obviously being good candidates, the definition of new SPRs (even the dummy ones ?). That would remove 15/20 patches from the list below I believe. May be more. I will go through the email thread to see what can be taken.
Would follow the xics patches (plenty of conflicts lately), mmu patches (but David has been working on this so it is shrinking), some pci fixes and helpers (should ping maintainers). We would then be at a point where only the core pnv patches are left. I think I am being very optimistic :)
I can start with a first serie. Suggestions welcomed. List below.
065f7f9b1e15 ppc: Fix CFAR updates
f385d52fe9f2 ppc: Add slbfee. instruction
2bf0d4f4239a ppc: Add dummy logmpp instruction
8102a4cc9c30 ppc: Print HSRR0/HSRR1 in "info registers"
730a9b4dc941 ppc: Add KVM numbers to some P8 SPRs
48adf38e9cab ppc: A couple more dummy POWER8 Book4 regs
bce7c738ec1b ppc: Add dummy ACOP SPR
34f1af75e75e ppc: Add dummy CIABR SPR
64f92045e284 ppc: Add dummy POWER8 PSPB SPR
ab003604993b ppc: Add dummy POWER8 MPPR register
b81cf8c41288 ppc: Add dummy write to VTB
490af9c31d8b ppc: Add a few more P8 PMU SPRs
84886e8c188d ppc: Add POWER8 IAMR register
5046c10f9e58 ppc: Fix writing to AMR/UAMOR
c188b86cac90 ppc: Initialize AMOR in PAPR mode
ee62b5581094 ppc: Add dummy SPR_IC for POWER8
83e02b2026ef ppc: SPURR & PURR are HV writeable and privileged
906a513acb1a ppc: LPCR is a HV resource
27f45e80a104 ppc: Add placeholder SPRs for DPDES and DHDES on P8
c1fc6d316f87 ppc: Initial HDEC support
9f5d6c607af5 ppc: Enforce setting MSR:EE,IR and DR when MSR:PR is set
a356d76a11bb ppc: Fix conditions for delivering external interrupts to a guest 6ba5e576d1cc ppc/pnv+spapr: Add "ibm,pa-features" property to the device-tree cf768bc434e5 ppc: Fix 64K pages support in full emulation
dbd6e54fd9c5 ppc: Add proper real mode translation support
7250469a21ce ppc: Cosmetic, align some comments
d94d8c4e7b3f ppc: Use a helper to filter writes to LPCR
0694e0d87fe3 ppc: Update LPCR definitions
20596a008f27 ppc/pnv: Create a default PCI layout
4b393cbdb438 ppc/pnv: Add model for Power8 PHB3 PCIe Host bridge
fa93c24cd3dc pci: Don't call pci_irq_handler() for a negative intx
8872d909a8fb pci: Use the new pci_can_add_device() to enforce devfn_min/max 9204957062b8 qdev: Add a hook for a bus to device if it can add devices 00b55e345926 pci-bridge: Set a supported devfn_min for bridge
e53d84a2716a ppc/pnv: Add OCC model stub with interrupt support
0b6c38406589 ppc/pnv: Add cut down PSI bridge model and hookup external interrupt 2649daef3f73 ppc/pnv: Add LPC controller and hook it up with a UART and RTC 81fff5adcc87 ppc/pnv: Wire up XICS native with PowerNV platform
aed1f862f0cc ppc/xics: Add xics to the monitor "info pic" command
8a9d65a58764 ppc/xics: Add "native" XICS subclass
2f29b84050d0 ppc/xics: Split ICS into base class and "simple" implementation f16e1abac820 ppc/xics: Use a helper to add a new ICS
8311defd2daa ppc/xics: Move xics_set_nr_irqs() to xics_spapr.c and xics_kvm.c 80ff29cbe02c ppc/xics: An ICS with offset 0 is assumed to be uninitialized b051717058cd ppc/xics: Make the ICSState a list
c1498ed62ab9 ppc/xics: Replace "icp" with "xics" in most places
de147c5277ee ppc/xics: Remove unused xics_set_irq_type()
e8322cdda768 ppc/xics: Implement H_IPOLL using an accessor
14597dd4d7c5 ppc/xics: Move SPAPR specific code to a separate file
ea78b4729fe7 ppc/xics: Rename existing XICS classe to XICS_SPAPR
b68322388931 ppc/pnv: Add XSCOM infrastructure
e567fa64df0a ppc/pnv: Add skeletton PowerNV platform
a926d8369e26 ppc: Add P7/P8 Power Management instructions
bba3bf8362cf ppc: Move exception generation code out of line
15411d6de866 ppc: Turn a bunch of booleans from int to bool
554cf2e208d4 ppc: Add real mode CI load/store instructions for P7 and P8 e75b02f8786e ppc: Rework generation of priv and inval interrupts
ec7fde6eb1a6 ppc: Fix generation if ISI/DSI vs. HV mode
91d6d6b8c720 ppc: Fix POWER7 and POWER8 exception definitions
886802ba3a7b ppc: Rework POWER7 & POWER8 exception model
72a37f87f790 ppc: Add PPC_64H instruction flag to POWER7 and POWER8
036b3623c02d ppc: Get out of emulation on SMT "OR" ops
5bf1a7bf1e45 ppc: Fix sign extension issue in mtmsr(d) emulation
fbac2f43e655 ppc: Change 'invalid' bit mask of tlbiel and tlbie
f308c5b1006f ppc: tlbie, tlbia and tlbisync are HV only
317658992d97 ppc: Better figure out if processor has HV mode
e25b26973a4b ppc: Create cpu_ppc_set_papr() helper
14bffe9681df ppc: Fix rfi/rfid/hrfi/... emulation
fb21ea327c61 ppc: Fix hreg_store_msr() so that non-HV mode cannot alter MSR:HV 35fd16185bea ppc: Add number of threads per core to the processor definition e408897526e9 ppc: Add a bunch of hypervisor SPRs to Book3s
5b287e66c751 ppc: Add macros to register hypervisor mode SPRs
295ccb0507dc ppc: Update SPR definitions
ed011d4fb179 ppc: Do some batching of TCG tlb flushes
048a18af1c8d ppc: Use split I/D mmu modes to avoid flushes on interrupts 681fc8d20391 ppc: Remove MMU_MODEn_SUFFIX definitions
065f7f9b1e15 ppc: Fix CFAR updates
2d3b7c0164e1 Merge remote-tracking branch 'remotes/amit-virtio-rng/tags/rng-for-2.6-1' into staging
Quoted 1 line
From :
https://github.com/legoater/qemu/commits/powernv-ipmi
$ git diff 2d3b7c0164e1..065f7f9b1e15 | diffstat default-configs/ppc64-softmmu.mak | 5 hmp-commands-info.hx | 2 hw/intc/Makefile.objs | 2 hw/intc/xics.c | 727 +++++++----------------- hw/intc/xics_kvm.c | 91 +-- hw/intc/xics_native.c | 295 +++++++++ hw/intc/xics_spapr.c | 429 ++++++++++++++ hw/pci-bridge/pci_bridge_dev.c | 2 hw/pci-host/Makefile.objs | 2 hw/pci-host/pnv_phb3.c | 1084 ++++++++++++++++++++++++++++++++++++ hw/pci-host/pnv_phb3_msi.c | 354 +++++++++++ hw/pci-host/pnv_phb3_pbcq.c | 315 ++++++++++ hw/pci-host/pnv_phb3_rc.c | 130 ++++ hw/pci/pci.c | 26 hw/ppc/Makefile.objs | 2 hw/ppc/pnv.c | 864 ++++++++++++++++++++++++++++ hw/ppc/pnv_lpc.c | 527 +++++++++++++++++ hw/ppc/pnv_occ.c | 126 ++++ hw/ppc/pnv_psi.c | 594 +++++++++++++++++++ hw/ppc/pnv_xscom.c | 415 +++++++++++++ hw/ppc/ppc.c | 31 - hw/ppc/spapr.c | 28 hw/ppc/spapr_events.c | 8 hw/ppc/spapr_hcall.c | 14 hw/ppc/spapr_pci.c | 12 hw/ppc/spapr_vio.c | 2 include/hw/pci-host/pnv_phb3.h | 145 ++++ include/hw/pci-host/pnv_phb3_regs.h | 505 ++++++++++++++++ include/hw/pci-host/spapr.h | 2 include/hw/pci/pci_bus.h | 1 include/hw/ppc/pnv.h | 67 ++ include/hw/ppc/pnv_xscom.h | 73 ++ include/hw/ppc/ppc.h | 2 include/hw/ppc/spapr.h | 2 include/hw/ppc/spapr_vio.h | 2 include/hw/ppc/xics.h | 81 ++ include/hw/qdev-core.h | 1 linux-user/main.c | 1 monitor.c | 3 qdev-monitor.c | 13 target-ppc/cpu-qom.h | 1 target-ppc/cpu.h | 148 ++++ target-ppc/excp_helper.c | 369 +++++++----- target-ppc/helper.h | 6 target-ppc/helper_regs.h | 75 ++ target-ppc/machine.c | 5 target-ppc/mmu-hash32.c | 4 target-ppc/mmu-hash64.c | 344 +++++++++-- target-ppc/mmu-hash64.h | 1 target-ppc/mmu_helper.c | 17 target-ppc/timebase_helper.c | 10 target-ppc/translate.c | 1013 ++++++++++++++++++--------------- target-ppc/translate_init.c | 738 ++++++++++++++++++++++-- 53 files changed, 8350 insertions(+), 1366 deletions(-)
Thanks,
C.
Re: [Qemu-devel] [Qemu-ppc] [PATCH 72/77] ppc: A couple more dummy POWER8 Book4 regs
Quoted 4 lines · Cédric Le Goater
Quoted 3 lines · Thomas Huth
Quoted 2 lines · Benjamin Herrenschmidt
WORT and PID this time
...
Quoted 11 lines
Quoted 10 lines
AFAICT all patches where you define new SPRs with spr_register_kvm[_hv] are also important independently of the rest of your patch series - otherwise these registers are currently lost during migration since they are not sync'ed with the KVM part in the kernel right now.
So if you've got some spare time, could you maybe extract all those patches that define new SPRs with spr_register_kvm[_hv] and send them as a separate patch series? That could help to fix future migration issues, and also would decrease the size of your really huge "Add native POWER8 platform" patch series a little bit!
Quoted 4 lines
I have been maintaining a port of Ben's patchset on the latest qemu for other parts which should come after pnv is merged so I have a framework to test such sub-patchsets. I also have time to work on them but clearly not the expertise in all areas !
That would be great if you could take care of this!
Quoted 4 lines
What would be nice is to identify the most obvious ones, non controversial that could be merged after a few iterations. I have a vague idea, the ones Reviewed-by David obviously being good candidates, the definition of new SPRs (even the dummy ones ?).
I really like to see the KVM SPRs patches first - since they are fixing potential problems with migration of the _current_ KVM machines already! And being bug fixes, maybe these patches could even be included for QEMU 2.6 already? (i.e. before the hard freeze at the end of March)
So my wish-list for a first small patch series looks like this:
5b287e66c7513209 ppc: Add macros to register hypervisor mode SPRs 34f1af75e75e7ba0 ppc: Add dummy CIABR SPR 48adf38e9cab4663 ppc: A couple more dummy POWER8 Book4 regs 730a9b4dc9414818 ppc: Add KVM numbers to some P8 SPRs
There are a couple of other patches touching the SPRs initialization, but they are not important with regards to migration... so not sure whether it makes sense to include them now already...
Thomas
Re: [Qemu-devel] [Qemu-ppc] [PATCH 72/77] ppc: A couple more dummy POWER8 Book4 regs
Quoted 1 line · Thomas Huth
On 09.03.2016 21:04, Cédric Le Goater wrote:
....
Quoted 19 lines
Quoted 4 lines
I have been maintaining a port of Ben's patchset on the latest qemu for other parts which should come after pnv is merged so I have a framework to test such sub-patchsets. I also have time to work on them but clearly not the expertise in all areas !
That would be great if you could take care of this!
Quoted 4 lines
What would be nice is to identify the most obvious ones, non controversial that could be merged after a few iterations. I have a vague idea, the ones Reviewed-by David obviously being good candidates, the definition of new SPRs (even the dummy ones ?).
I really like to see the KVM SPRs patches first - since they are fixing potential problems with migration of the _current_ KVM machines already! And being bug fixes, maybe these patches could even be included for QEMU 2.6 already? (i.e. before the hard freeze at the end of March)
So my wish-list for a first small patch series looks like this:
Quoted 8 lines
5b287e66c7513209 ppc: Add macros to register hypervisor mode SPRs 34f1af75e75e7ba0 ppc: Add dummy CIABR SPR 48adf38e9cab4663 ppc: A couple more dummy POWER8 Book4 regs 730a9b4dc9414818 ppc: Add KVM numbers to some P8 SPRsThere are a couple of other patches touching the SPRs initialization, but they are not important with regards to migration... so not sure whether it makes sense to include them now already...
FWIW, I just saw today (by doing some more experiments with kvm-unit-tests) that the IAMR register is also not migrated yet ... so it would be nice if you could include the related patches for IAMR, too, and wire the KVM part up with KVM_REG_PPC_IAMR...
Thomas
Re: [Qemu-devel] [Qemu-ppc] [PATCH 72/77] ppc: A couple more dummy POWER8 Book4 regs
Quoted 27 lines · Thomas Huth
Quoted 1 line · Thomas Huth
On 09.03.2016 21:04, Cédric Le Goater wrote:
....
Quoted 24 lines
Quoted 4 lines
I have been maintaining a port of Ben's patchset on the latest qemu for other parts which should come after pnv is merged so I have a framework to test such sub-patchsets. I also have time to work on them but clearly not the expertise in all areas !
That would be great if you could take care of this!
Quoted 4 lines
What would be nice is to identify the most obvious ones, non controversial that could be merged after a few iterations. I have a vague idea, the ones Reviewed-by David obviously being good candidates, the definition of new SPRs (even the dummy ones ?).
I really like to see the KVM SPRs patches first - since they are fixing potential problems with migration of the _current_ KVM machines already! And being bug fixes, maybe these patches could even be included for QEMU 2.6 already? (i.e. before the hard freeze at the end of March)
So my wish-list for a first small patch series looks like this:
5b287e66c7513209 ppc: Add macros to register hypervisor mode SPRs 34f1af75e75e7ba0 ppc: Add dummy CIABR SPR 48adf38e9cab4663 ppc: A couple more dummy POWER8 Book4 regs 730a9b4dc9414818 ppc: Add KVM numbers to some P8 SPRs
Quoted 8 lines
Quoted 3 lines
There are a couple of other patches touching the SPRs initialization, but they are not important with regards to migration... so not sure whether it makes sense to include them now already...
FWIW, I just saw today (by doing some more experiments with kvm-unit-tests) that the IAMR register is also not migrated yet ... so it would be nice if you could include the related patches for IAMR, too, and wire the KVM part up with
KVM_REG_PPC_IAMR...
OK. So we should be targeting something like :
ppc: Update SPR definitions
ppc: Add macros to register hypervisor mode SPRs
ppc: Add a bunch of hypervisor SPRs to Book3s
ppc: LPCR is a HV resource
ppc: SPURR & PURR are HV writeable and privileged
ppc: Add dummy SPR_IC for POWER8
ppc: Initialize AMOR in PAPR mode
ppc: Fix writing to AMR/UAMOR
ppc: Add POWER8 IAMR register
ppc: Add a few more P8 PMU SPRs
ppc: Add dummy write to VTB
ppc: Add dummy POWER8 MPPR register
ppc: Add dummy POWER8 PSPB SPR
ppc: Add dummy CIABR SPR
ppc: Add dummy ACOP SPR
ppc: A couple more dummy POWER8 Book4 regs
ppc: Add KVM numbers to some P8 SPRs
Also, there seem to be an issue with qemu's HEAD on ppc64el with the random device :
-object rng-random,filename=/dev/urandom,id=gid0 -device spapr-rng,rng=gid0
qemu "hangs". This is a vague description for a symptom ... Does that ring a bell or do I need to dig in to get more info ?
Thanks,
C.
Re: [Qemu-devel] [Qemu-ppc] [PATCH 72/77] ppc: A couple more dummy POWER8 Book4 regs
Quoted 43 lines · Cédric Le Goater
Quoted 27 lines · Thomas Huth
Quoted 1 line · Thomas Huth
On 09.03.2016 21:04, Cédric Le Goater wrote:
....
Quoted 24 lines
Quoted 4 lines
I have been maintaining a port of Ben's patchset on the latest qemu for other parts which should come after pnv is merged so I have a framework to test such sub-patchsets. I also have time to work on them but clearly not the expertise in all areas !
That would be great if you could take care of this!
Quoted 4 lines
What would be nice is to identify the most obvious ones, non controversial that could be merged after a few iterations. I have a vague idea, the ones Reviewed-by David obviously being good candidates, the definition of new SPRs (even the dummy ones ?).
I really like to see the KVM SPRs patches first - since they are fixing potential problems with migration of the _current_ KVM machines already! And being bug fixes, maybe these patches could even be included for QEMU 2.6 already? (i.e. before the hard freeze at the end of March)
So my wish-list for a first small patch series looks like this:
5b287e66c7513209 ppc: Add macros to register hypervisor mode SPRs 34f1af75e75e7ba0 ppc: Add dummy CIABR SPR 48adf38e9cab4663 ppc: A couple more dummy POWER8 Book4 regs 730a9b4dc9414818 ppc: Add KVM numbers to some P8 SPRsQuoted 8 lines
Quoted 3 lines
There are a couple of other patches touching the SPRs initialization, but they are not important with regards to migration... so not sure whether it makes sense to include them now already...
FWIW, I just saw today (by doing some more experiments with kvm-unit-tests) that the IAMR register is also not migrated yet ... so it would be nice if you could include the related patches for IAMR, too, and wire the KVM part up with
KVM_REG_PPC_IAMR...OK. So we should be targeting something like :
ppc: Update SPR definitions
ppc: Add macros to register hypervisor mode SPRs
ppc: Add a bunch of hypervisor SPRs to Book3s
Quoted 14 lines
ppc: LPCR is a HV resource
ppc: SPURR & PURR are HV writeable and privileged
ppc: Add dummySPR_ICfor POWER8
ppc: Initialize AMOR in PAPR mode
ppc: Fix writing to AMR/UAMOR
ppc: Add POWER8 IAMR register
ppc: Add a few more P8 PMU SPRs
ppc: Add dummy write to VTB
ppc: Add dummy POWER8 MPPR register
ppc: Add dummy POWER8 PSPB SPR
ppc: Add dummy CIABR SPR
ppc: Add dummy ACOP SPR
ppc: A couple more dummy POWER8 Book4 regs
ppc: Add KVM numbers to some P8 SPRs
Sounds good - but you likely can drop the "Add a few more P8 PMU SPRs" from your list since it has already been queued by David already (see
https://github.com/dgibson/qemu/commits/ppc-for-2.6), and the PSPB patch is also not required anymore since I submitted a similar patch to David already when I discovered that it is lost during migration.
Quoted 7 lines
Also, there seem to be an issue with qemu's HEAD on ppc64el with the random device :
-object rng-random,filename=/dev/urandom,id=gid0 -device spapr-rng,rng=gid0
qemu "hangs". This is a vague description for a symptom ... Does that ring a bell or do I need to dig in to get more info ?
Works for me™ ... could you supply more information? Where does it hang? Which exact level of QEMU are you using? ... and please open a new mail thread for this, since it's off-topic to this mail thread.
Thomas
Re: [Qemu-devel] [Qemu-ppc] [PATCH 72/77] ppc: A couple more dummy POWER8 Book4 regs
Quoted 59 lines · Thomas Huth
Quoted 43 lines · Cédric Le Goater
Quoted 27 lines · Thomas Huth
Quoted 1 line · Thomas Huth
On 09.03.2016 21:04, Cédric Le Goater wrote:
....
Quoted 24 lines
Quoted 4 lines
I have been maintaining a port of Ben's patchset on the latest qemu for other parts which should come after pnv is merged so I have a framework to test such sub-patchsets. I also have time to work on them but clearly not the expertise in all areas !
That would be great if you could take care of this!
Quoted 4 lines
What would be nice is to identify the most obvious ones, non controversial that could be merged after a few iterations. I have a vague idea, the ones Reviewed-by David obviously being good candidates, the definition of new SPRs (even the dummy ones ?).
I really like to see the KVM SPRs patches first - since they are fixing potential problems with migration of the _current_ KVM machines already! And being bug fixes, maybe these patches could even be included for QEMU 2.6 already? (i.e. before the hard freeze at the end of March)
So my wish-list for a first small patch series looks like this:
5b287e66c7513209 ppc: Add macros to register hypervisor mode SPRs 34f1af75e75e7ba0 ppc: Add dummy CIABR SPR 48adf38e9cab4663 ppc: A couple more dummy POWER8 Book4 regs 730a9b4dc9414818 ppc: Add KVM numbers to some P8 SPRsQuoted 8 lines
Quoted 3 lines
There are a couple of other patches touching the SPRs initialization, but they are not important with regards to migration... so not sure whether it makes sense to include them now already...
FWIW, I just saw today (by doing some more experiments with kvm-unit-tests) that the IAMR register is also not migrated yet ... so it would be nice if you could include the related patches for IAMR, too, and wire the KVM part up with
KVM_REG_PPC_IAMR...OK. So we should be targeting something like :
ppc: Update SPR definitions
ppc: Add macros to register hypervisor mode SPRs
ppc: Add a bunch of hypervisor SPRs to Book3sQuoted 14 lines
ppc: LPCR is a HV resource
ppc: SPURR & PURR are HV writeable and privileged
ppc: Add dummySPR_ICfor POWER8
ppc: Initialize AMOR in PAPR mode
ppc: Fix writing to AMR/UAMOR
ppc: Add POWER8 IAMR register
ppc: Add a few more P8 PMU SPRs
ppc: Add dummy write to VTB
ppc: Add dummy POWER8 MPPR register
ppc: Add dummy POWER8 PSPB SPR
ppc: Add dummy CIABR SPR
ppc: Add dummy ACOP SPR
ppc: A couple more dummy POWER8 Book4 regs
ppc: Add KVM numbers to some P8 SPRs
Quoted 5 lines
Sounds good - but you likely can drop the "Add a few more P8 PMU SPRs" from your list since it has already been queued by David already (see
https://github.com/dgibson/qemu/commits/ppc-for-2.6), and the PSPB patch is also not required anymore since I submitted a similar patch to David already when I discovered that it is lost during migration.
Here is a first port on Dave's 2.6 branch. I tried to keep the patchset minimal but I had to pull a few extra patches to keep them more or less in sync with the original version from Ben.
ppc: Update SPR definitions
ppc: Add macros to register hypervisor mode SPRs
ppc: Add a bunch of hypervisor SPRs to Book3s
ppc: Add number of threads per core to the processor definition
ppc: Fix hreg_store_msr() so that non-HV mode cannot alter MSR:HV
ppc: Create cpu_ppc_set_papr() helper
ppc: Better figure out if processor has HV mode
ppc: Add placeholder SPRs for DPDES and DHDES on P8
ppc: SPURR & PURR are HV writeable and privileged
ppc: Add dummy SPR_IC for POWER8
ppc: Initialize AMOR in PAPR mode
ppc: Fix writing to AMR/UAMOR
ppc: Add POWER8 IAMR register
ppc: Add dummy write to VTB
ppc: Add dummy POWER8 MPPR register
ppc: Add dummy CIABR SPR
ppc: Add dummy ACOP SPR
ppc: A couple more dummy POWER8 Book4 regs
ppc: Add KVM numbers to some P8 SPRs
Available here:
https://github.com/legoater/qemu/commits/for-2.6
If you want to take a look, I did some quick test on KVM and TCG on a ppc64le ubuntu host but no migration.
These two will probably need a merge as the first breaks the compile, and I modified the second.
ppc: Fix writing to AMR/UAMOR
ppc: Add POWER8 IAMR register
I guess that I will send on the list for review after.
Thanks,
C.
Re: [Qemu-devel] [Qemu-ppc] [PATCH 72/77] ppc: A couple more dummy POWER8 Book4 regs
Quoted 94 lines · Cédric Le Goater
Quoted 59 lines · Thomas Huth
Quoted 43 lines · Cédric Le Goater
Quoted 27 lines · Thomas Huth
Quoted 1 line · Thomas Huth
On 09.03.2016 21:04, Cédric Le Goater wrote:
....
Quoted 24 lines
Quoted 4 lines
I have been maintaining a port of Ben's patchset on the latest qemu for other parts which should come after pnv is merged so I have a framework to test such sub-patchsets. I also have time to work on them but clearly not the expertise in all areas !
That would be great if you could take care of this!
Quoted 4 lines
What would be nice is to identify the most obvious ones, non controversial that could be merged after a few iterations. I have a vague idea, the ones Reviewed-by David obviously being good candidates, the definition of new SPRs (even the dummy ones ?).
I really like to see the KVM SPRs patches first - since they are fixing potential problems with migration of the _current_ KVM machines already! And being bug fixes, maybe these patches could even be included for QEMU 2.6 already? (i.e. before the hard freeze at the end of March)
So my wish-list for a first small patch series looks like this:
5b287e66c7513209 ppc: Add macros to register hypervisor mode SPRs 34f1af75e75e7ba0 ppc: Add dummy CIABR SPR 48adf38e9cab4663 ppc: A couple more dummy POWER8 Book4 regs 730a9b4dc9414818 ppc: Add KVM numbers to some P8 SPRsQuoted 8 lines
Quoted 3 lines
There are a couple of other patches touching the SPRs initialization, but they are not important with regards to migration... so not sure whether it makes sense to include them now already...
FWIW, I just saw today (by doing some more experiments with kvm-unit-tests) that the IAMR register is also not migrated yet ... so it would be nice if you could include the related patches for IAMR, too, and wire the KVM part up with
KVM_REG_PPC_IAMR...OK. So we should be targeting something like :
ppc: Update SPR definitions
ppc: Add macros to register hypervisor mode SPRs
ppc: Add a bunch of hypervisor SPRs to Book3sQuoted 14 lines
ppc: LPCR is a HV resource
ppc: SPURR & PURR are HV writeable and privileged
ppc: Add dummySPR_ICfor POWER8
ppc: Initialize AMOR in PAPR mode
ppc: Fix writing to AMR/UAMOR
ppc: Add POWER8 IAMR register
ppc: Add a few more P8 PMU SPRs
ppc: Add dummy write to VTB
ppc: Add dummy POWER8 MPPR register
ppc: Add dummy POWER8 PSPB SPR
ppc: Add dummy CIABR SPR
ppc: Add dummy ACOP SPR
ppc: A couple more dummy POWER8 Book4 regs
ppc: Add KVM numbers to some P8 SPRsQuoted 5 lines
Sounds good - but you likely can drop the "Add a few more P8 PMU SPRs" from your list since it has already been queued by David already (see
https://github.com/dgibson/qemu/commits/ppc-for-2.6), and the PSPB patch is also not required anymore since I submitted a similar patch to David already when I discovered that it is lost during migration.Here is a first port on Dave's 2.6 branch. I tried to keep the patchset minimal but I had to pull a few extra patches to keep them more or less in sync with the original version from Ben.
ppc: Update SPR definitions
ppc: Add macros to register hypervisor mode SPRs
ppc: Add a bunch of hypervisor SPRs to Book3s
ppc: Add number of threads per core to the processor definition
ppc: Fixhreg_store_msr()so that non-HV mode cannot alter MSR:HV
ppc: Createcpu_ppc_set_papr()helper
ppc: Better figure out if processor has HV mode
ppc: Add placeholder SPRs for DPDES and DHDES on P8
ppc: SPURR & PURR are HV writeable and privileged
ppc: Add dummySPR_ICfor POWER8
ppc: Initialize AMOR in PAPR mode
ppc: Fix writing to AMR/UAMOR
ppc: Add POWER8 IAMR register
ppc: Add dummy write to VTB
ppc: Add dummy POWER8 MPPR register
ppc: Add dummy CIABR SPR
ppc: Add dummy ACOP SPR
ppc: A couple more dummy POWER8 Book4 regs
ppc: Add KVM numbers to some P8 SPRsAvailable here:
Quoted 8 lines
If you want to take a look, I did some quick test on KVM and TCG on a ppc64le ubuntu host but no migration.
These two will probably need a merge as the first breaks the compile, and I modified the second.
ppc: Fix writing to AMR/UAMOR
ppc: Add POWER8 IAMR register
Modifying patches is fine as long as you mention the changes in the patch description (in square brackets) and add your Sob - looking at your tree, you already did this for the "ppc: Add POWER8 IAMR register" patch, so that should be OK.
I'd maybe also squash the "Add KVM numbers to some P8 SPRs" patch into the "Add a bunch of hypervisor SPRs to Book3s" to reduce the code churn a little bit (note that the patch description for the "Add a bunch of hypervisor SPRs to Book3s" patch is misleading - DAWR and DAWRX need to be synchronized for migration, since the guest can set this register via the H_SET_MODE hypercall).
You could maybe also merge "Add dummy ACOP SPR" with "A couple more dummy POWER8 Book4 regs" since the latter patch completely reworks the definition of the ACOP register.
Thomas
Re: [Qemu-devel] [Qemu-ppc] [PATCH 72/77] ppc: A couple more dummy POWER8 Book4 regs
Hello Thomas,
Quoted 6 lines · Thomas Huth
I'd maybe also squash the "Add KVM numbers to some P8 SPRs" patch into the "Add a bunch of hypervisor SPRs to Book3s" to reduce the code churn a little bit (note that the patch description for the "Add a bunch of hypervisor SPRs to Book3s" patch is misleading - DAWR and DAWRX need to be synchronized for migration, since the guest can set this register via the
H_SET_MODEhypercall).
So shall I just remove the comment :
"We don't give them a KVM reg number yet as no current KVM version
supports HV mode."
from patch "Add a bunch of hypervisor SPRs to Book3s" after squashing in "Add KVM numbers to some P8 SPRs" ?
Thanks,
C.
Re: [Qemu-devel] [Qemu-ppc] [PATCH 72/77] ppc: A couple more dummy POWER8 Book4 regs
Quoted 10 lines · Cédric Le Goater
Hello Thomas,
Quoted 6 lines · Thomas Huth
I'd maybe also squash the "Add KVM numbers to some P8 SPRs" patch into the "Add a bunch of hypervisor SPRs to Book3s" to reduce the code churn a little bit (note that the patch description for the "Add a bunch of hypervisor SPRs to Book3s" patch is misleading - DAWR and DAWRX need to be synchronized for migration, since the guest can set this register via the
H_SET_MODEhypercall).
Quoted 7 lines
So shall I just remove the comment :
"We don't give them a KVM reg number yet as no current KVM version
supports HV mode."from patch "Add a bunch of hypervisor SPRs to Book3s" after squashing in "Add KVM numbers to some P8 SPRs" ?
Either that, or change it into something like:
"We don't give them a KVM reg number to most of the registers yet as no current KVM version supports HV mode. For DAWR and DAWRX, the KVM reg number is needed since this register can be set by the guest via the H_SET_MODE hypercall."
?
Thomas
Re: [Qemu-devel] [Qemu-ppc] [PATCH 72/77] ppc: A couple more dummy POWER8 Book4 regs
Quoted 19 lines · Thomas Huth
Quoted 10 lines · Cédric Le Goater
Hello Thomas,
Quoted 6 lines · Thomas Huth
I'd maybe also squash the "Add KVM numbers to some P8 SPRs" patch into the "Add a bunch of hypervisor SPRs to Book3s" to reduce the code churn a little bit (note that the patch description for the "Add a bunch of hypervisor SPRs to Book3s" patch is misleading - DAWR and DAWRX need to be synchronized for migration, since the guest can set this register via the
H_SET_MODEhypercall).Quoted 7 lines
So shall I just remove the comment :
"We don't give them a KVM reg number yet as no current KVM version
supports HV mode."from patch "Add a bunch of hypervisor SPRs to Book3s" after squashing in "Add KVM numbers to some P8 SPRs" ?
Quoted 6 lines
Either that, or change it into something like:
"We don't give them a KVM reg number to most of the registers yet as no current KVM version supports HV mode. For DAWR and DAWRX, the KVM reg number is needed since this register can be set by the guest via the
H_SET_MODEhypercall."
OK. Good. I should be sending a first patchset soon the list, after a few checks.
Thanks,
C.
PATCH 73/77 ppc: Add KVM numbers to some P8 SPRs
In reply to Benjamin Herrenschmidt--- target-ppc/translate_init.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
target-ppc/translate_init.c +11 -11
@@ -7619,21 +7619,21 @@ static void gen_spr_book3s_dbg(CPUPPCState *env)static void gen_spr_book3s_207_dbg (CPUPPCState *env) { -spr_register_hv (env,SPR_DAWR ,"DAWR" , -SPR_NOACCESS ,SPR_NOACCESS , -SPR_NOACCESS ,SPR_NOACCESS , - &spr_read_generic, &spr_write_generic, -0x00000000 ); -spr_register_hv (env,SPR_DAWRX ,"DAWRX" , -SPR_NOACCESS ,SPR_NOACCESS , -SPR_NOACCESS ,SPR_NOACCESS , - &spr_read_generic, &spr_write_generic, -0x00000000 ); +spr_register_kvm_hv (env,SPR_DAWR ,"DAWR" , +SPR_NOACCESS ,SPR_NOACCESS , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_DAWR ,0x00000000 ); +spr_register_kvm_hv (env,SPR_DAWRX ,"DAWRX" , +SPR_NOACCESS ,SPR_NOACCESS , +SPR_NOACCESS ,SPR_NOACCESS , + &spr_read_generic, &spr_write_generic, +KVM_REG_PPC_DAWRX ,0x00000000 );spr_register_kvm_hv (env,SPR_CIABR ,"CIABR" ,SPR_NOACCESS ,SPR_NOACCESS ,SPR_NOACCESS ,SPR_NOACCESS , &spr_read_generic, &spr_write_generic, -KVM_REG_PPC_CIABR ,0x00000000 ); +KVM_REG_PPC_CIABR ,0x00000000 ); }static void gen_spr_970_dbg (CPUPPCState *env)
Signature · 1 line
2.5.0
PATCH 74/77 ppc: Print HSRR0/HSRR1 in "info registers"
In reply to Benjamin HerrenschmidtThey are generally useful when debugging HV mode stuff
--- target-ppc/translate.c | 7 +++++++ 1 file changed, 7 insertions(+)
target-ppc/translate.c +7 -0
@@ -11323,6 +11323,13 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, env->spr[SPR_SPRG4 ], env->spr[SPR_SPRG5 ], env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]); +#if defined(TARGET_PPC64 ) +if (env->excp_model ==POWERPC_EXCP_POWER7 || + env->excp_model ==POWERPC_EXCP_POWER8 ) { +cpu_fprintf (f,"HSRR0 " TARGET_FMT_lx" HSRR1 " TARGET_FMT_lx"\n" , + env->spr[SPR_HSRR0 ], env->spr[SPR_HSRR1 ]); + } +#endif if (env->excp_model ==POWERPC_EXCP_BOOKE ) { cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
Signature · 1 line
2.5.0
PATCH 75/77 ppc: Add dummy logmpp instruction
In reply to Benjamin HerrenschmidtIt's used by KVM for micropartition prefetch
--- target-ppc/translate.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
target-ppc/translate.c +18 -0
@@ -3627,6 +3627,16 @@ static void gen_rvwinkle(DisasContext *ctx)gen_stop_exception (ctx); #endif /* defined(CONFIG_USER_ONLY) */ } + +static void gen_logmpp (DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY ) +GEN_PRIV ; +#else +CHK_HV ; +/* This doesn't do anything in emulation */ +#endif /* defined(CONFIG_USER_ONLY) */ +}#endif /* #if defined(TARGET_PPC64) */ /*** Floating-point load ***/
@@ -9895,6 +9905,14 @@ GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),GEN_HANDLER_E (sleep,0x13 ,0x12 ,0x0e ,0x03FFF801 ,PPC_NONE ,PPC2_PM_ISA206 ),GEN_HANDLER_E (rvwinkle,0x13 ,0x12 ,0x0f ,0x03FFF801 ,PPC_NONE ,PPC2_PM_ISA206 ),GEN_HANDLER (hrfid,0x13 ,0x12 ,0x08 ,0x03FF8001 ,PPC_64H ), + +/* This should be P8 Book4, not ISA207S, but I don't want to add a bit for that +* one dummy instruction. Note also that there's a discrepancy between the +* P8 Book4 which documents it as using RA while KVM implementation uses RB, +* so for now mark both fields as valid +*/ +//GEN_HANDLER_E(logmpp, 0x1f, 0x12, 0x1f, 0x03E0F800, PPC_NONE, PPC2_ISA207S), +GEN_HANDLER_E (logmpp,0x1f ,0x12 ,0x1f ,0x03E00000 ,PPC_NONE ,PPC2_ISA207S ), #endifGEN_HANDLER (sc,0x11 ,0xFF ,0xFF ,0x03FFF01D ,PPC_FLOW ), GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
Signature · 1 line
2.5.0
PATCH 76/77 ppc: Add slbfee. instruction
In reply to Benjamin HerrenschmidtUsed to lookup SLB entries by address, for some reason it was missing.
--- target-ppc/helper.h | 1 + target-ppc/mmu-hash64.c | 24 ++++++++++++++++++++++++ target-ppc/translate.c | 25 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+)
target-ppc/helper.h +1 -0
@@ -551,6 +551,7 @@ DEF_HELPER_FLAGS_2(tlbie, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_3(store_slb, TCG_CALL_NO_RWG, void, env, tl, tl) DEF_HELPER_2(load_slb_esid, tl, env, tl) DEF_HELPER_2(load_slb_vsid, tl, env, tl) +DEF_HELPER_2(find_slb_esid, tl, env, tl) DEF_HELPER_FLAGS_1(slbia, TCG_CALL_NO_RWG, void, env) DEF_HELPER_FLAGS_2(slbie, TCG_CALL_NO_RWG, void, env, tl)#endif
target-ppc/mmu-hash64.c +24 -0
@@ -188,6 +188,19 @@ static int ppc_load_slb_vsid(CPUPPCState *env, target_ulong rb,return 0 ; } +static int ppc_find_slb_esid (CPUPPCState *env,target_ulong rb, +target_ulong *rt) +{ +ppc_slb_t *slb =slb_lookup (env, rb); + +if (!slb) { +return -1 ; + } + + *rt = slb->vsid; +return 0 ; +} +void helper_store_slb (CPUPPCState *env,target_ulong rb,target_ulong rs) {if (ppc_store_slb (env, rb, rs) <0 ) {
@@ -218,6 +231,17 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb)return rt; } +target_ulong helper_find_slb_esid (CPUPPCState *env,target_ulong rb) +{ +target_ulong rt =0 ; + +if (ppc_find_slb_esid (env, rb, &rt) <0 ) { +helper_raise_exception_err (env,POWERPC_EXCP_PROGRAM , +POWERPC_EXCP_INVAL ); + } +return rt; +} +/* * 64-bit hash table MMU handling */
target-ppc/translate.c +25 -0
@@ -4949,6 +4949,30 @@ static void gen_slbmfev(DisasContext *ctx) cpu_gpr[rB(ctx->opcode)]);#endif /* defined(CONFIG_USER_ONLY) */ } + +static void gen_slbfee_ (DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY ) +GEN_PRIV ; +#else +TCGLabel *l1; +TCGLabel *l2; + +CHK_SV ; + +gen_helper_find_slb_esid (cpu_gpr[rS (ctx->opcode)], cpu_env, + cpu_gpr[rB (ctx->opcode)]); + l1 =gen_new_label (); + l2 =gen_new_label (); +tcg_gen_trunc_tl_i32 (cpu_crf[0 ], cpu_so); +tcg_gen_brcondi_tl (TCG_COND_EQ , cpu_gpr[rS (ctx->opcode)],-1 , l1); +tcg_gen_ori_i32 (cpu_crf[0 ], cpu_crf[0 ],1 <<CRF_EQ ); +tcg_gen_br (l2); +gen_set_label (l1); +tcg_gen_movi_tl (cpu_gpr[rS (ctx->opcode)],0 ); +gen_set_label (l2); +#endif /* defined(CONFIG_USER_ONLY) */ +}#endif /* defined(TARGET_PPC64) */ /*** Lookaside buffer management ***/
@@ -9958,6 +9982,7 @@ GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,GEN_HANDLER2 (slbmte,"slbmte" ,0x1F ,0x12 ,0x0C ,0x001F0001 ,PPC_SEGMENT_64B ),GEN_HANDLER2 (slbmfee,"slbmfee" ,0x1F ,0x13 ,0x1C ,0x001F0001 ,PPC_SEGMENT_64B ),GEN_HANDLER2 (slbmfev,"slbmfev" ,0x1F ,0x13 ,0x1A ,0x001F0001 ,PPC_SEGMENT_64B ), +GEN_HANDLER2 (slbfee_,"slbfee." ,0x1F ,0x13 ,0x1E ,0x001F0000 ,PPC_SEGMENT_64B ), #endif GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),/* XXX Those instructions will need to be handled differently for
Signature · 1 line
2.5.0
PATCH 77/77 ppc: Fix CFAR updates
In reply to Benjamin HerrenschmidtWe need to remove 4 from the NIP since it's already been moved by 4 by the dispatcher before the helper is called
--- target-ppc/translate.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
target-ppc/translate.c +4 -4
@@ -4035,7 +4035,7 @@ static void gen_b(DisasContext *ctx)if (LK (ctx->opcode)) {gen_setlr (ctx, ctx->nip); } -gen_update_cfar (ctx, ctx->nip); +gen_update_cfar (ctx, ctx->nip -4 );gen_goto_tb (ctx,0 , target); }
@@ -4100,7 +4100,7 @@ static inline void gen_bcond(DisasContext *ctx, int type) }tcg_temp_free_i32 (temp); } -gen_update_cfar (ctx, ctx->nip); +gen_update_cfar (ctx, ctx->nip -4 );if (type ==BCOND_IM ) {target_ulong li = (target_long)((int16_t )(BD (ctx->opcode)));if (likely (AA (ctx->opcode) ==0 )) {
@@ -4211,7 +4211,7 @@ static void gen_rfi(DisasContext *ctx)#else /* Restore CPU state */ CHK_SV ; -gen_update_cfar (ctx, ctx->nip); +gen_update_cfar (ctx, ctx->nip -4 );gen_helper_rfi (cpu_env);gen_sync_exception (ctx);#endif
@@ -4225,7 +4225,7 @@ static void gen_rfid(DisasContext *ctx)#else /* Restore CPU state */ CHK_SV ; -gen_update_cfar (ctx, ctx->nip); +gen_update_cfar (ctx, ctx->nip -4 );gen_helper_rfid (cpu_env);gen_sync_exception (ctx);#endif
Signature · 1 line
2.5.0