2 Copyright 2009, The AROS Development Team. All rights reserved.
6 #include "drm_compat_funcs.h"
7 #include "drm_aros_config.h"
9 #define PIO_RESERVED (IPTR)0x40000UL
11 void iowrite32(u32 val
, void * addr
)
13 if ((IPTR
)addr
>= PIO_RESERVED
)
19 unsigned int ioread32(void * addr
)
21 if ((IPTR
)addr
>= PIO_RESERVED
)
29 void iowrite16(u16 val
, void * addr
)
31 if ((IPTR
)addr
>= PIO_RESERVED
)
37 unsigned int ioread16(void * addr
)
39 if ((IPTR
)addr
>= PIO_RESERVED
)
47 void iowrite8(u8 val
, void * addr
)
49 if ((IPTR
)addr
>= PIO_RESERVED
)
55 unsigned int ioread8(void * addr
)
57 if ((IPTR
)addr
>= PIO_RESERVED
)
66 void clear_bit(int nr
, volatile void * addr
)
68 unsigned long mask
= 1 << nr
;
70 *(unsigned long*)addr
&= ~mask
;
73 void set_bit(int nr
, volatile void *addr
)
75 unsigned long mask
= 1 << nr
;
77 *(unsigned long*)addr
|= mask
;
80 int test_bit(int nr
, volatile void *addr
)
82 unsigned long mask
= 1 << nr
;
84 return (*(unsigned long*)addr
) & mask
;
88 #include <aros/symbolsets.h>
89 #include <devices/timer.h>
90 struct MsgPort
*p
= NULL
;
91 struct timerequest
*io
= NULL
;
93 void udelay(unsigned long usecs
)
95 /* Create local clone so that the function is task safe */
96 struct timerequest timerio
;
97 struct MsgPort timermp
;
99 memset(&timermp
, 0, sizeof(timermp
));
101 timermp
.mp_Node
.ln_Type
= NT_MSGPORT
;
102 timermp
.mp_Flags
= PA_SIGNAL
;
103 timermp
.mp_SigBit
= SIGB_SINGLE
;
104 timermp
.mp_SigTask
= FindTask(NULL
);
105 NEWLIST(&timermp
.mp_MsgList
);
109 timerio
.tr_node
.io_Message
.mn_Node
.ln_Type
= NT_REPLYMSG
;
110 timerio
.tr_node
.io_Message
.mn_ReplyPort
= &timermp
;
111 timerio
.tr_node
.io_Command
= TR_ADDREQUEST
;
112 timerio
.tr_time
.tv_secs
= usecs
/ 1000000;
113 timerio
.tr_time
.tv_micro
= usecs
- (timerio
.tr_time
.tv_secs
* 1000000);
115 SetSignal(0, SIGF_SINGLE
);
117 DoIO((struct IORequest
*)&timerio
);
120 static BOOL
init_timer()
127 io
= CreateIORequest(p
, sizeof(struct timerequest
));
135 if (OpenDevice("timer.device", UNIT_MICROHZ
, (struct IORequest
*)io
, 0) != 0)
144 static BOOL
deinit_timer()
148 CloseDevice((struct IORequest
*)io
);
149 DeleteIORequest((struct IORequest
*)io
);
162 ADD2INIT(init_timer
, 5);
163 ADD2EXIT(deinit_timer
, 5);
166 void __free_page(struct page
* p
)
168 if (p
->allocated_buffer
)
169 HIDDNouveauFree(p
->allocated_buffer
);
170 p
->allocated_buffer
= NULL
;
175 struct page
* create_page_helper()
178 p
= HIDDNouveauAlloc(sizeof(*p
));
179 p
->allocated_buffer
= HIDDNouveauAlloc(PAGE_SIZE
+ PAGE_SIZE
- 1);
180 p
->address
= PAGE_ALIGN(p
->allocated_buffer
);
185 int idr_pre_get_internal(struct idr
*idp
)
187 if (idp
->size
<= idp
->occupied
+ idp
->last_starting_id
)
189 /* Create new table */
190 ULONG newsize
= idp
->size
? idp
->size
* 2 : 128;
191 IPTR
* newtab
= HIDDNouveauAlloc(newsize
* sizeof(IPTR
));
199 /* Copy old table into new */
200 CopyMem(idp
->pointers
, newtab
, idp
->size
* sizeof(IPTR
));
202 /* Release old table */
203 HIDDNouveauFree(idp
->pointers
);
206 idp
->pointers
= newtab
;
213 int idr_get_new_above(struct idr
*idp
, void *ptr
, int starting_id
, int *id
)
216 idp
->last_starting_id
= starting_id
;
218 for(;i
< idp
->size
;i
++)
220 if (idp
->pointers
[i
] == (IPTR
)NULL
)
223 idp
->pointers
[i
] = (IPTR
)ptr
;
232 void *idr_find(struct idr
*idp
, int id
)
234 if ((id
< idp
->size
) && (id
>= 0))
235 return (APTR
)idp
->pointers
[id
];
240 void idr_remove(struct idr
*idp
, int id
)
242 if ((id
< idp
->size
) && (id
>= 0))
244 idp
->pointers
[id
] = (IPTR
)NULL
;
249 void idr_init(struct idr
*idp
)
252 idp
->pointers
= NULL
;
254 idp
->last_starting_id
= 0;
258 #include "drm_aros.h"
259 #include <aros/libcall.h>
260 #include <proto/oop.h>
261 #include <hidd/pci.h>
262 #include <hidd/hidd.h>
264 void *ioremap(resource_size_t offset
, unsigned long size
)
268 struct pHidd_PCIDriver_MapPCI mappci
,*msg
= &mappci
;
269 mappci
.mID
= OOP_GetMethodID(IID_Hidd_PCIDriver
, moHidd_PCIDriver_MapPCI
);
270 mappci
.PCIAddress
= (APTR
)offset
;
271 mappci
.Length
= size
;
272 return (APTR
)OOP_DoMethod(pciDriver
, (OOP_Msg
)msg
);
276 bug("BUG: ioremap used without acquiring pciDriver\n");
281 void iounmap(void * addr
)
285 struct pHidd_PCIDriver_UnmapPCI unmappci
,*msg
=&unmappci
;
287 unmappci
.mID
= OOP_GetMethodID(IID_Hidd_PCIDriver
, moHidd_PCIDriver_UnmapPCI
);
288 unmappci
.CPUAddress
= addr
;
289 unmappci
.Length
= 0; /* This works on i386 but may create problems on other archs */
291 OOP_DoMethod(pciDriver
, (OOP_Msg
)msg
);
295 resource_size_t
pci_resource_start(struct pci_dev
* pdev
, unsigned int resource
)
297 APTR start
= (APTR
)NULL
;
300 case(0): OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_Base0
, (APTR
)&start
); break;
301 case(1): OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_Base1
, (APTR
)&start
); break;
302 case(2): OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_Base2
, (APTR
)&start
); break;
303 case(3): OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_Base3
, (APTR
)&start
); break;
304 case(4): OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_Base4
, (APTR
)&start
); break;
305 case(5): OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_Base5
, (APTR
)&start
); break;
306 default: bug("ResourceID %d not supported\n", resource
);
309 return (resource_size_t
)start
;
312 unsigned long pci_resource_len(struct pci_dev
* pdev
, unsigned int resource
)
316 if (pci_resource_start(pdev
, resource
) != 0)
320 * The length reading is only correct when the resource actually exists.
321 * pci.hidd can however return a non 0 lenght for a resource that does
322 * not exsist. Possible fix in pci.hidd needed
327 case(0): OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_Size0
, (APTR
)&len
); break;
328 case(1): OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_Size1
, (APTR
)&len
); break;
329 case(2): OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_Size2
, (APTR
)&len
); break;
330 case(3): OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_Size3
, (APTR
)&len
); break;
331 case(4): OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_Size4
, (APTR
)&len
); break;
332 case(5): OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_Size5
, (APTR
)&len
); break;
333 default: bug("ResourceID %d not supported\n", resource
);
340 struct GetBusSlotEnumeratorData
345 OOP_Object
** pciDevice
;
348 AROS_UFH3(void, GetBusSlotEnumerator
,
349 AROS_UFHA(struct Hook
*, hook
, A0
),
350 AROS_UFHA(OOP_Object
*, pciDevice
, A2
),
351 AROS_UFHA(APTR
, message
, A1
))
355 struct GetBusSlotEnumeratorData
* data
= hook
->h_Data
;
361 if (*data
->pciDevice
)
362 return; /* Already found, should not happen */
364 /* Get the Device's properties */
365 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Bus
, &Bus
);
366 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Dev
, &Dev
);
367 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Sub
, &Sub
);
369 if (data
->Bus
== Bus
&&
373 (*data
->pciDevice
) = pciDevice
;
378 void * pci_get_bus_and_slot(unsigned int bus
, unsigned int dev
, unsigned int fun
)
380 OOP_Object
* pciDevice
= NULL
;
384 struct GetBusSlotEnumeratorData data
= {
388 pciDevice
: &pciDevice
,
391 struct Hook FindHook
= {
392 h_Entry
: (IPTR (*)())GetBusSlotEnumerator
,
396 struct TagItem Requirements
[] = {
400 struct pHidd_PCI_EnumDevices enummsg
= {
401 mID
: OOP_GetMethodID(IID_Hidd_PCI
, moHidd_PCI_EnumDevices
),
403 requirements
: (struct TagItem
*)&Requirements
,
406 OOP_DoMethod(pciBus
, (OOP_Msg
)msg
);
412 int pci_read_config_word(struct pci_dev
* pdev
, int where
, u16
*val
)
414 struct pHidd_PCIDevice_ReadConfigWord rcwmsg
= {
415 mID
: OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_ReadConfigWord
),
419 *val
= (UWORD
)OOP_DoMethod((OOP_Object
*)pdev
->oopdev
, (OOP_Msg
)msg
);
420 D(bug("pci_read_config_word: %d -> %d\n", where
, *val
));
425 int pci_read_config_dword(struct pci_dev
* pdev
, int where
, u32
*val
)
427 struct pHidd_PCIDevice_ReadConfigLong rclmsg
= {
428 mID
: OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_ReadConfigLong
),
432 *val
= (ULONG
)OOP_DoMethod((OOP_Object
*)pdev
->oopdev
, (OOP_Msg
)msg
);
433 D(bug("pci_read_config_dword: %d -> %d\n", where
, *val
));
438 int pci_write_config_dword(struct pci_dev
* pdev
, int where
, u32 val
)
440 struct pHidd_PCIDevice_WriteConfigLong wclmsg
= {
441 mID
: OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_ReadConfigLong
),
446 OOP_DoMethod((OOP_Object
*)pdev
->oopdev
, (OOP_Msg
)msg
);
447 D(bug("pci_write_config_dword: %d -> %d\n", where
, val
));
452 int pci_is_pcie(struct pci_dev
* pdev
)
455 OOP_GetAttr((OOP_Object
*)pdev
->oopdev
, aHidd_PCIDevice_CapabilityPCIE
, (APTR
)&PCIECap
);
459 #include <hidd/agp.h>
462 struct agp_bridge_data
* global_agp_bridge
= NULL
; /* TODO: implement freeing */
463 struct Library
* HiddAgpBase
= NULL
; /* TODO: Implement freeing */
464 OOP_AttrBase HiddAGPBridgeDeviceAttrBase
= 0; /* TODO: Implement freeing */
466 struct agp_bridge_data
*agp_backend_acquire(void * dev
)
469 if no bridge return NULL
470 if already acquired return NULL, else acquire
472 return agp_find_bridge(dev
);
475 void agp_backend_release(struct agp_bridge_data
* bridge
)
477 /* TODO: release acquired lock */
480 void agp_free_memory(struct agp_memory
* mem
)
482 HIDDNouveauFree(mem
->pages
);
483 HIDDNouveauFree(mem
);
486 struct agp_memory
*agp_allocate_memory(struct agp_bridge_data
* bridge
,
487 size_t num_pages
, u32 type
)
489 if ((type
!= AGP_USER_MEMORY
) && (type
!= AGP_USER_CACHED_MEMORY
))
491 IMPLEMENT("Unsupported memory type: %d\n", type
);
495 struct agp_memory
* mem
= HIDDNouveauAlloc(sizeof(struct agp_memory
));
496 mem
->pages
= HIDDNouveauAlloc(sizeof(struct page
*) * num_pages
);
497 mem
->page_count
= 0; /* Not a typo, will be filled later */
499 mem
->is_flushed
= FALSE
;
500 mem
->is_bound
= FALSE
;
505 int agp_copy_info(struct agp_bridge_data
* bridge
, struct agp_kern_info
* info
)
507 info
->chipset
= SUPPORTED
;
508 info
->cant_use_aperture
= 0;
509 info
->page_mask
= ~0UL;
510 if (bridge
->mode
& (1<<3) /* AGPSTAT_MODE_3_0 */)
511 info
->mode
= bridge
->mode
& ~(0x00ff00c4); /* AGP3_RESERVED_MASK */
513 info
->mode
= bridge
->mode
& ~(0x00fffcc8); /* AGP2_RESERVED_MASK */
515 info
->aper_base
= (unsigned long)bridge
->aperturebase
;
516 info
->aper_size
= (unsigned long)bridge
->aperturesize
;
521 struct agp_bridge_data
* agp_find_bridge(void * dev
)
523 OOP_Object
* agpbus
= NULL
;
525 if (global_agp_bridge
)
526 return global_agp_bridge
;
530 HiddAgpBase
= OpenLibrary("agp.hidd", 1);
531 HiddAGPBridgeDeviceAttrBase
= OOP_ObtainAttrBase((STRPTR
)IID_Hidd_AGPBridgeDevice
);
534 /* Get AGP bus object */
535 agpbus
= OOP_NewObject(NULL
, CLID_Hidd_AGP
, NULL
);
539 struct pHidd_AGP_GetBridgeDevice gbdmsg
= {
540 mID
: OOP_GetMethodID(IID_Hidd_AGP
, moHidd_AGP_GetBridgeDevice
)
542 OOP_Object
* bridgedevice
= NULL
;
544 bridgedevice
= (OOP_Object
*)OOP_DoMethod(agpbus
, (OOP_Msg
)&gbdmsg
);
546 OOP_DisposeObject(agpbus
);
548 /* AGP bridge was found and initialized */
551 IPTR mode
= 0, aperbase
= 0, apersize
= 0;
553 global_agp_bridge
= HIDDNouveauAlloc(sizeof(struct agp_bridge_data
));
554 global_agp_bridge
->agpbridgedevice
= (IPTR
)bridgedevice
;
556 OOP_GetAttr(bridgedevice
, aHidd_AGPBridgeDevice_Mode
, (APTR
)&mode
);
557 global_agp_bridge
->mode
= mode
;
559 OOP_GetAttr(bridgedevice
, aHidd_AGPBridgeDevice_ApertureBase
, (APTR
)&aperbase
);
560 global_agp_bridge
->aperturebase
= aperbase
;
562 OOP_GetAttr(bridgedevice
, aHidd_AGPBridgeDevice_ApertureSize
, (APTR
)&apersize
);
563 global_agp_bridge
->aperturesize
= apersize
;
567 return global_agp_bridge
;
570 void agp_enable(struct agp_bridge_data
* bridge
, u32 mode
)
572 if (!bridge
|| !bridge
->agpbridgedevice
)
575 struct pHidd_AGPBridgeDevice_Enable emsg
= {
576 mID
: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice
, moHidd_AGPBridgeDevice_Enable
),
580 OOP_DoMethod((OOP_Object
*)bridge
->agpbridgedevice
, (OOP_Msg
)&emsg
);
583 int agp_bind_memory(struct agp_memory
* mem
, off_t offset
)
585 if (!mem
|| mem
->is_bound
)
588 if ((mem
->type
!= AGP_USER_MEMORY
) && (mem
->type
!= AGP_USER_CACHED_MEMORY
))
590 IMPLEMENT("Unsupported memory type: %d\n", mem
->type
);
594 if (!mem
->is_flushed
)
596 /* TODO: Flush memory */
597 mem
->is_flushed
= TRUE
;
600 /* TODO: agp_map_memory */
601 /* TODO: Move flush/map into bind call on the side of agp.hidd */
603 struct pHidd_AGPBridgeDevice_BindMemory bmmsg
= {
604 mID
: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice
, moHidd_AGPBridgeDevice_BindMemory
),
605 address
: (IPTR
)(mem
->pages
[0]->address
),
606 size
: mem
->page_count
* PAGE_SIZE
,
608 type
: (mem
->type
== AGP_USER_MEMORY
? vHidd_AGP_NormalMemory
: vHidd_AGP_CachedMemory
)
611 OOP_DoMethod((OOP_Object
*)global_agp_bridge
->agpbridgedevice
, (OOP_Msg
)&bmmsg
);
613 mem
->is_bound
= TRUE
;
614 mem
->pg_start
= offset
;
618 int agp_unbind_memory(struct agp_memory
* mem
)
620 if (!mem
|| !mem
->is_bound
)
623 struct pHidd_AGPBridgeDevice_UnBindMemory ubmmsg
= {
624 mID
: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice
, moHidd_AGPBridgeDevice_UnBindMemory
),
625 offset
: mem
->pg_start
,
626 size
: mem
->page_count
* PAGE_SIZE
,
629 OOP_DoMethod((OOP_Object
*)global_agp_bridge
->agpbridgedevice
, (OOP_Msg
)&ubmmsg
);
631 /* TODO: agp_unmap_memory */
633 mem
->is_bound
= FALSE
;
638 void agp_flush_chipset(struct agp_bridge_data
* bridge
)
640 if (!bridge
|| !bridge
->agpbridgedevice
)
643 struct pHidd_AGPBridgeDevice_FlushChipset fcmsg
= {
644 mID
: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice
, moHidd_AGPBridgeDevice_FlushChipset
),
647 OOP_DoMethod((OOP_Object
*)bridge
->agpbridgedevice
, (OOP_Msg
)&fcmsg
);
650 /* jiffies handling */
651 #include <sys/time.h>
653 /* jiffies are supposed to be very precise time value. They are implemented
654 as rather very unprecise */
655 unsigned long get_jiffies()
658 unsigned long val
= 0;
660 gettimeofday(&tv
, NULL
);
662 val
= tv
.tv_sec
* 1000000 + tv
.tv_usec
; /* Yes, overflow */
664 /* TODO: Maybe make sure that each call to get_jiffies returns a different value? */
670 #include <hidd/i2c.h>
672 OOP_AttrBase HiddI2CDeviceAttrBase
= 0; /* TODO: Implement freeing */
674 int i2c_transfer(struct i2c_adapter
*adap
, struct i2c_msg
*msgs
, int num
)
676 /* FIXME: This function is not generic. It has hardcoded cases that are present in nouveau */
677 if (adap
->i2cdriver
== (IPTR
)0)
679 bug("ERROR: i2c_transfer called without driver present\n");
683 if (HiddI2CDeviceAttrBase
== 0)
684 HiddI2CDeviceAttrBase
= OOP_ObtainAttrBase((STRPTR
)IID_Hidd_I2CDevice
);
686 if (HiddI2CDeviceAttrBase
== 0)
688 bug("ERROR: i2c_trasfer not able to obtain HiddI2CDeviceAttrBase\n");
692 /* Go through supported cases */
693 if ((num
== 2) && (msgs
[0].addr
== 0x50) && (msgs
[1].addr
== 0x50) && (msgs
[0].len
== 1) && (msgs
[1].len
== 1))
695 /* This is probing for DDC */
696 D(bug("i2c_transfer - probing for DDC\n"));
697 if (HIDD_I2C_ProbeAddress((OOP_Object
*)adap
->i2cdriver
, 0xa0)) /* AROS has shifted addresses (<< 1) */
702 else if ((num
== 2) && (msgs
[0].addr
== 0x75) && (msgs
[1].addr
== 0x75) && (msgs
[0].len
== 1) && (msgs
[1].len
== 1))
704 /* This is probing for some hardware related to TV output on nv04 */
705 D(bug("i2c_transfer - probing for some hardware related to TV output on nv04\n"));
706 if (HIDD_I2C_ProbeAddress((OOP_Object
*)adap
->i2cdriver
, 0xea)) /* AROS has shifted addresses (<< 1) */
711 else if ((num
== 2) && (msgs
[0].addr
== 0x50) && (msgs
[1].addr
== 0x50) && (msgs
[0].len
== 1) && (msgs
[1].len
!= 1))
713 /* This is reading data from DDC */
714 struct pHidd_I2CDevice_WriteRead msg
;
717 struct TagItem attrs
[] =
719 { aHidd_I2CDevice_Driver
, (IPTR
)adap
->i2cdriver
},
720 { aHidd_I2CDevice_Address
, 0xa0 },
721 { aHidd_I2CDevice_Name
, (IPTR
)"Read DDC" },
725 D(bug("i2c_transfer - reading from DDC\n"));
727 OOP_Object
*obj
= OOP_NewObject(NULL
, CLID_Hidd_I2CDevice
, attrs
);
729 msg
.mID
= OOP_GetMethodID((STRPTR
)IID_Hidd_I2CDevice
, moHidd_I2CDevice_WriteRead
);
730 msg
.readBuffer
= msgs
[1].buf
;
731 msg
.readLength
= msgs
[1].len
;
732 msg
.writeBuffer
= msgs
[0].buf
;
733 msg
.writeLength
= msgs
[0].len
;
735 result
= OOP_DoMethod(obj
, &msg
.mID
);
737 OOP_DisposeObject(obj
);
744 else if ((num
== 2) && (msgs
[0].addr
== 0x54) && (msgs
[1].addr
== 0x54) && (msgs
[0].len
== 1) && (msgs
[1].len
== 1))
746 /* This is reading data from register 0x54 */
747 struct pHidd_I2CDevice_WriteRead msg
;
750 struct TagItem attrs
[] =
752 { aHidd_I2CDevice_Driver
, (IPTR
)adap
->i2cdriver
},
753 { aHidd_I2CDevice_Address
, 0xa8 },
754 { aHidd_I2CDevice_Name
, (IPTR
)"Read Register" },
758 D(bug("i2c_transfer - reading from register 0x54\n"));
760 OOP_Object
*obj
= OOP_NewObject(NULL
, CLID_Hidd_I2CDevice
, attrs
);
762 msg
.mID
= OOP_GetMethodID((STRPTR
)IID_Hidd_I2CDevice
, moHidd_I2CDevice_WriteRead
);
763 msg
.readBuffer
= msgs
[1].buf
;
764 msg
.readLength
= msgs
[1].len
;
765 msg
.writeBuffer
= msgs
[0].buf
;
766 msg
.writeLength
= msgs
[0].len
;
768 result
= OOP_DoMethod(obj
, &msg
.mID
);
770 OOP_DisposeObject(obj
);
779 /* Not supported case */
780 bug("i2c_transfer case not supported: num = %d\n", num
);
787 int i2c_del_adapter(struct i2c_adapter
* adap
)
794 unsigned int hweight32(unsigned int number
)
796 unsigned int result
= 0;
799 for (i
= 0; i
< 32; i
++)
801 if (number
& 0x1) result
++;
808 unsigned int hweight8(unsigned int number
)
810 unsigned int result
= 0;
813 for (i
= 0; i
< 8; i
++)
815 if (number
& 0x1) result
++;