Message ID | 1333376921-13834-2-git-send-email-i.mitsyanko@samsung.com |
---|---|
State | New |
Headers | show |
On 2 April 2012 15:28, Igor Mitsyanko <i.mitsyanko@samsung.com> wrote: > Representing each group write protection flag with only one bit instead of int > variable significantly reduces memory consumption. Can we use the bitmap.h functions here rather than doing things by hand? (scattered examples below, you get the idea) > Signed-off-by: Igor Mitsyanko <i.mitsyanko@samsung.com> > --- > hw/sd.c | 36 ++++++++++++++++++++++-------------- > 1 files changed, 22 insertions(+), 14 deletions(-) > > diff --git a/hw/sd.c b/hw/sd.c > index 07eb263..23e5f2f 100644 > --- a/hw/sd.c > +++ b/hw/sd.c > @@ -81,7 +81,7 @@ struct SDState { > uint8_t sd_status[64]; > uint32_t vhs; > int wp_switch; > - int *wp_groups; > + uint8_t *wp_groups; > uint64_t size; > int blk_len; > uint32_t erase_start; > @@ -415,7 +415,7 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv) > if (sd->wp_groups) > g_free(sd->wp_groups); > sd->wp_switch = bdrv ? bdrv_is_read_only(bdrv) : 0; > - sd->wp_groups = (int *) g_malloc0(sizeof(int) * sect); > + sd->wp_groups = (uint8_t *)g_malloc0((sect >> 3) + 1); sd->wp_groups = bitmap_new(sect); > memset(sd->function_group, 0, sizeof(int) * 6); > sd->erase_start = 0; > sd->erase_end = 0; > @@ -484,9 +484,11 @@ static void sd_erase(SDState *sd) > sd->erase_end = 0; > sd->csd[14] |= 0x40; > > - for (i = start; i <= end; i ++) > - if (sd->wp_groups[i]) > + for (i = start; i <= end; i++) { > + if (sd->wp_groups[i >> 3] & (1 << (i & 0x7))) { if (test_bit(i, sd->wp_groups)) { > sd->card_status |= WP_ERASE_SKIP; > + } > + } > } > > static uint32_t sd_wpbits(SDState *sd, uint64_t addr) > @@ -496,9 +498,12 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr) > > wpnum = addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT); > > - for (i = 0; i < 32; i ++, wpnum ++, addr += WPGROUP_SIZE) > - if (addr < sd->size && sd->wp_groups[wpnum]) > + for (i = 0; i < 32; i++, wpnum++, addr += WPGROUP_SIZE) { > + if (addr < sd->size && > + (sd->wp_groups[wpnum >> 3] & (1 << (wpnum & 0x7)))) { > ret |= (1 << i); > + } > + } > > return ret; > } > @@ -536,8 +541,9 @@ static void sd_function_switch(SDState *sd, uint32_t arg) > > static inline int sd_wp_addr(SDState *sd, uint32_t addr) > { > - return sd->wp_groups[addr >> > - (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)]; > + unsigned int grp = addr >> > + (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT); > + return sd->wp_groups[grp >> 3] & (1 << (grp & 0x7)) ? 1 : 0; > } > > static void sd_lock_command(SDState *sd) > @@ -560,8 +566,8 @@ static void sd_lock_command(SDState *sd) > sd->card_status |= LOCK_UNLOCK_FAILED; > return; > } > - memset(sd->wp_groups, 0, sizeof(int) * (sd->size >> > - (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT))); > + memset(sd->wp_groups, 0, 1 + (sd->size >> > + (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT + 3))); bitmap_zero(sd->wp_groups, number-of-bits-to-clear) > sd->csd[14] &= ~0x10; > sd->card_status &= ~CARD_IS_LOCKED; > sd->pwd_len = 0; > @@ -1007,8 +1013,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, > } > > sd->state = sd_programming_state; > - sd->wp_groups[addr >> (HWBLOCK_SHIFT + > - SECTOR_SHIFT + WPGROUP_SHIFT)] = 1; > + sd->wp_groups[addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + > + WPGROUP_SHIFT + 3)] |= 1 << ((addr >> (HWBLOCK_SHIFT + > + SECTOR_SHIFT + WPGROUP_SHIFT)) & 0x7); set_bit(addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT), sd->wp_groups); > /* Bzzzzzzztt .... Operation complete. */ > sd->state = sd_transfer_state; > return sd_r1b; > @@ -1027,8 +1034,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, > } > > sd->state = sd_programming_state; > - sd->wp_groups[addr >> (HWBLOCK_SHIFT + > - SECTOR_SHIFT + WPGROUP_SHIFT)] = 0; > + sd->wp_groups[addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + > + WPGROUP_SHIFT + 3)] &= ~(1 << ((addr >> (HWBLOCK_SHIFT + > + SECTOR_SHIFT + WPGROUP_SHIFT)) & 0x7)); > /* Bzzzzzzztt .... Operation complete. */ > sd->state = sd_transfer_state; > return sd_r1b; > -- > 1.7.4.1 >
On 02.04.2012 5:42 PM, Peter Maydell wrote: > On 2 April 2012 15:28, Igor Mitsyanko<i.mitsyanko@samsung.com> wrote: >> Representing each group write protection flag with only one bit instead of int >> variable significantly reduces memory consumption. > > Can we use the bitmap.h functions here rather than doing things > by hand? (scattered examples below, you get the idea) > That's pretty cool, I didn't know about this, thanks.
diff --git a/hw/sd.c b/hw/sd.c index 07eb263..23e5f2f 100644 --- a/hw/sd.c +++ b/hw/sd.c @@ -81,7 +81,7 @@ struct SDState { uint8_t sd_status[64]; uint32_t vhs; int wp_switch; - int *wp_groups; + uint8_t *wp_groups; uint64_t size; int blk_len; uint32_t erase_start; @@ -415,7 +415,7 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv) if (sd->wp_groups) g_free(sd->wp_groups); sd->wp_switch = bdrv ? bdrv_is_read_only(bdrv) : 0; - sd->wp_groups = (int *) g_malloc0(sizeof(int) * sect); + sd->wp_groups = (uint8_t *)g_malloc0((sect >> 3) + 1); memset(sd->function_group, 0, sizeof(int) * 6); sd->erase_start = 0; sd->erase_end = 0; @@ -484,9 +484,11 @@ static void sd_erase(SDState *sd) sd->erase_end = 0; sd->csd[14] |= 0x40; - for (i = start; i <= end; i ++) - if (sd->wp_groups[i]) + for (i = start; i <= end; i++) { + if (sd->wp_groups[i >> 3] & (1 << (i & 0x7))) { sd->card_status |= WP_ERASE_SKIP; + } + } } static uint32_t sd_wpbits(SDState *sd, uint64_t addr) @@ -496,9 +498,12 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr) wpnum = addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT); - for (i = 0; i < 32; i ++, wpnum ++, addr += WPGROUP_SIZE) - if (addr < sd->size && sd->wp_groups[wpnum]) + for (i = 0; i < 32; i++, wpnum++, addr += WPGROUP_SIZE) { + if (addr < sd->size && + (sd->wp_groups[wpnum >> 3] & (1 << (wpnum & 0x7)))) { ret |= (1 << i); + } + } return ret; } @@ -536,8 +541,9 @@ static void sd_function_switch(SDState *sd, uint32_t arg) static inline int sd_wp_addr(SDState *sd, uint32_t addr) { - return sd->wp_groups[addr >> - (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)]; + unsigned int grp = addr >> + (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT); + return sd->wp_groups[grp >> 3] & (1 << (grp & 0x7)) ? 1 : 0; } static void sd_lock_command(SDState *sd) @@ -560,8 +566,8 @@ static void sd_lock_command(SDState *sd) sd->card_status |= LOCK_UNLOCK_FAILED; return; } - memset(sd->wp_groups, 0, sizeof(int) * (sd->size >> - (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT))); + memset(sd->wp_groups, 0, 1 + (sd->size >> + (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT + 3))); sd->csd[14] &= ~0x10; sd->card_status &= ~CARD_IS_LOCKED; sd->pwd_len = 0; @@ -1007,8 +1013,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, } sd->state = sd_programming_state; - sd->wp_groups[addr >> (HWBLOCK_SHIFT + - SECTOR_SHIFT + WPGROUP_SHIFT)] = 1; + sd->wp_groups[addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + + WPGROUP_SHIFT + 3)] |= 1 << ((addr >> (HWBLOCK_SHIFT + + SECTOR_SHIFT + WPGROUP_SHIFT)) & 0x7); /* Bzzzzzzztt .... Operation complete. */ sd->state = sd_transfer_state; return sd_r1b; @@ -1027,8 +1034,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, } sd->state = sd_programming_state; - sd->wp_groups[addr >> (HWBLOCK_SHIFT + - SECTOR_SHIFT + WPGROUP_SHIFT)] = 0; + sd->wp_groups[addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + + WPGROUP_SHIFT + 3)] &= ~(1 << ((addr >> (HWBLOCK_SHIFT + + SECTOR_SHIFT + WPGROUP_SHIFT)) & 0x7)); /* Bzzzzzzztt .... Operation complete. */ sd->state = sd_transfer_state; return sd_r1b;
Representing each group write protection flag with only one bit instead of int variable significantly reduces memory consumption. Signed-off-by: Igor Mitsyanko <i.mitsyanko@samsung.com> --- hw/sd.c | 36 ++++++++++++++++++++++-------------- 1 files changed, 22 insertions(+), 14 deletions(-)